Repository navigation
feat(stack): extension stacklets and stack update - #102
Merged
Merged
Conversation
Add a commit message section to docs/agent/dev.md, based on Conventional Commits and the Git and Linux kernel guidelines: - the allowed types and scopes, and how each one renders in the release notes - imperative subjects of at most 72 characters - a body that explains what changed and why, with guidance per type - the `Upgrade:` and `BREAKING CHANGE:` footers Release notes are generated from commit subjects, so every subject must parse. AGENTS.md links to the section.
Add `tools/commit-lint`, which checks commit headers against the format in docs/agent/dev.md. It runs in: - the `commit-msg` hook - CI, on the PR title and on every commit in the PR - the release gate, on the range being tagged Scopes are only checked for types that appear in the changelog. CI prints the number of checked subjects and fails on an empty range. A test verifies that the type and scope lists match dev.md. Scopes are now stacklet ids and bot names, rendered as "<id> Stacklet" and "<name> Bot".
Add `[core] extension_dirs`, a list of directories that are searched after `stacklets/` for stacklets that do not ship with the release. The default is `~/famstack-extensions`. The directory is not created automatically, and configured paths that do not exist are skipped. - Hooks, CLI plugins, secrets and env templates work the same way as for built-in stacklets. On an id clash the repo wins, then the first extension directory in the list. - Add a `stage` manifest field (`beta`, `incubating`). `stack list` shows it and `stack up` prints a warning. - `stack list` and `stack status` show extensions in a separate section, including the directory each one was loaded from. - The bot runner mounts the first extension directory. `stack up` warns when a stacklet in another directory ships a bot. Extensions are kept outside the repo and the data dir because the repo is replaced on update and the data dir is deleted by `stack uninstall`. They are not covered by the backup instructions for `~/famstack-data`.
Describe the limitations of the current git checkout install model and the options for packaging, updates and multiple instances per Mac. Rewrite the update procedure in the admin guide: - switch between release tags instead of running `git pull` - stash local changes before switching, and recover from conflicts - do not run `git pull origin main`, which moves the instance to unreleased code Remove `./stack updates` from the operator docs. The command does not exist. Also write `[core] name` to `stack.toml` during installation.
Add `stack update [<tag>]`. It fetches release tags from all remotes, shows the current and target release, and checks out the target tag. `--dry-run` shows the plan, `--yes` skips the confirmation. - No services are restarted. The command lists the stacklets that need a restart: running stacklets with changed files, or all running stacklets if `lib/` changed. - Local changes are stashed and re-applied. If they conflict with the release, the update is rolled back and the changes are restored. - A checkout that is already ahead of the newest release is not moved. - On a branch, the output explains that the tag checkout detaches HEAD and how to switch back. On a fork without release tags, the error lists the remotes it checked and how to add the upstream remote.
Label each container with the commit it was started from (`stack.commit`) during `stack up`. - `stack list` marks stacklets whose containers run an older commit. - `stack doctor` reports them. - `stack restart` without arguments restarts only those stacklets. Containers without the label are reported as unknown. Upgrade: containers created before this release have no label. Run `./stack restart all` once, or restart each stacklet when convenient.
Add a script that checks for Python 3.11+ and uv, runs `uv sync`, installs the language server and sets `core.hooksPath`. It can be run again safely. Git does not let a repository enable its own hooks on clone, so the `lint`, `typecheck` and `test-unit` make targets run `tools/init-repo --hooks-only` first. An existing `core.hooksPath` is not changed.
Keep one make target per test lane and remove the aliases. - `make` without a target prints each lane's duration, requirements, and whether it uses fixed container names and ports. - Add `make lint` for the whole tree. - Recommend `make test-unit` before a push instead of before every commit. Move the details to tests/README.md.
`stack doctor` compared a container's environment with the stacklet's rendered `.env`. Services that set a different value in their compose file, such as a container path or an internal hostname, were reported as drifted after every recreate. Compare with the environment that `docker compose config` resolves for the service. This also removes the special cases for image defaults and for variables a service does not receive.
Derive the version from `git describe --tags --dirty` instead of the `VERSION` constant, for example `0.3.0-beta.3-104-g9a5bdc9-dirty`. `version`, `status`, `list`, `doctor` and `update` print the same value. - `stack doctor` prints the version and warns when a newer release tag exists locally. It does not fetch. - `stack update` prints the current version first, and shows how many commits the checkout is ahead of the newest release. The release gate still uses `VERSION`. If it differs from the tag, both values are shown.
Prefix suggested fixes with "to fix:" and print stack commands with the `./` prefix, for example `./stack restart memory`. The JSON output keeps the command without the prefix.
arthware-dev
force-pushed
the
feat/extension-stacklets
branch
from
September 21, 2026 11:22
255b777 to
21e8861
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
~/famstack-extensionsby default, and a stacklet can declare astageso an unfinished one says so.stack listandstack statusgroup extensions in their own section, and every stacklet reportssourceandpathso a caller never infers an origin from a path../stack updatemoves the checkout between releases. It sets local edits aside and puts them back, winds the whole update back if they collide with the release, and names what to restart rather than restarting it: new code on disk is not new code running, and when a family loses a service is the admin's call.stack upwith the commit it started from (stack.commit), sostack list,stack doctorand a bare./stack restartcan tell when running code is behind the checkout. A container with no stamp is reported as unknown, never guessed about.Also in here, because the update work exposed them: a written commit convention with
tools/commit-lintenforcing it in thecommit-msghook and in CI,tools/init-repofor one-time clone setup, RFC-002 on installation and updates, and a correctedstack updescription in the operator docs (it force-recreates; the docs claimed otherwise).Scope added after review started, declared here rather than silently: the test lanes are consolidated to one name per lane (eighteen phony targets became six, and
test-allran only the lifecycle lane), withmakeprinting a table of what each costs, what it needs and whether it is exclusive.Larger than the one-PR-one-entry rule this branch itself introduces. Happy to split it into extensions / update / stamping if that reads better.
Upgrade: containers created before this release carry no stamp, so
./stack listreports "cannot tell" for them until each stacklet is next started. Run./stack restart allonce to stamp everything, or let it happen stacklet by stacklet.