Repository navigation
v0.1.5
Upgrading from v0.1.4: run a-stack update, then restart the service (systemctl --user restart a-stack, or Ctrl-C and a-stack serve). The first start copies the database to state.db.pre-v6 and moves it to schema 7. Open browser views lose access once, because old view links are revoked: run a-stack to open a new one. If you set up the systemd unit by hand, run a-stack service install once to update it.
Added
a-stack new --orchestrator NAMEalso registers that Agent, with a credential file ina-stack-agentsnext to the state directory, appoints it as the Orchestrator and prints a brief to paste into the coding agent. It checks the name and the credential file before it makes anything, and refuses a Session that already has an Orchestrator.a-stack statusprints one line per Session: how many Tasks need you, work, wait and finished.a-stack watchprints that once, then one line per change (new Tasks, status changes, Needs you, answers, reports) until Ctrl-C, and rings the terminal bell on a new Needs you.--notifyalso shows a desktop notice throughnotify-send, without the question unless you add--notify-text. Both use the Operator credential, only read, and show the current folder's Sessions, or--session IDor--all. Watch reads a Session's Tasks only when its read revision changed. See Watch from the terminal.a-stack statuslineprints a line for Claude Code's status line, such asa-stack OAuth login: 1 needs you · 2 working, for the Workspace of the session's folder. It never prints a view URL, and prints nothing on any error. See Claude Code status line.a-stack hook installadds hooks for one Agent to Claude Code (settings.json) and Codex (hooks.json), or with--projectto the current folder. At session start, also after a compaction, the agent gets a reminder of its a-stack name, its open Tasks and to runmail check. Prompts and tool calls record the runtime stateworking, a permission requestblocked, and a stopidle, when you give--runtime-id. The hook command names the credential file and the IDs explicitly; install takes them from a v0.1.5 credential file when you leave them out. Install keeps all other settings and hooks, anda-stack hook uninstallremoves only a-stack's hooks for the folder. The hook exits 0 silently on any error and stops itself after 2 seconds, so it never stops the agent. See Agent hooks.- The install guide shows
go install github.com/mzmzeee/a-stack/cmd/a-stack@latest, which needs a C compiler.contrib/has an AURPKGBUILDfora-stack-binand a Homebrew formula for Linux, both from the release archives and their checksums, with the steps to publish them. They are not published yet. - Each Agent has a write budget, so a runaway loop cannot fill the disk. A change costs the size of its request; an Agent can spend 8 MiB at once and 1 MiB more a minute. Past that, a change gets the new error code
rate_limited(HTTP 429, retryable) withretry_after_seconds. A replay of a committed operation ID and the Operator are never limited. In a rerun of the review's reproduction (16 parallelmail sendloops with 64 KiB bodies from one Agent for 20 seconds), the Agent stored 13,835 messages (925 MB) before and 132 messages (8 MB) now; another Agent could still send. a-stack service installsets up the systemd user service in one step, so a-stack keeps running after you close the terminal. It writes~/.config/systemd/user/a-stack.service(or below$XDG_CONFIG_HOME) from the unit in the binary, with the real path of the running binary and the CLI's state directory, then runsdaemon-reloadandenable --nowand waits until the service answers. It refuses while ana-stack serveoutside systemd holds the state directory, says when it updated a different unit, and prints theloginctl enable-lingercommand when linger is off.a-stack service statusshows the unit, enabled, active, binary, linger and health;a-stack service uninstalldisables the service and removes the unit, and never touches the state directory.- When
a-stack,a-stack -rora-stack newstart the service in the terminal, they say that closing the terminal stops a-stack and how to keep it running. storage statusreportsfree_bytes, andlow_diskwith awarningbelow 1 GiB of free space. The browser view footer then says that disk space is low.a-stack view revoke --workspace ID --session IDends browser view access to one Session, and--allto every Session. Open tabs say that they lost access at their next refresh. Only the Operator can run it.a-stack herdr bindlets an Agent that runs inside Herdr bind itself to its own pane, in place of a hand-written runtime file. It readsHERDR_PANE_IDandHERDR_SOCKET_PATH, asks Herdr for its pane's agent and native session, names an unnamed panea-<name>, reads the harness version fromclaude --versionorcodex --version, and sends the usualagent attach. Without Herdr's integration it fails with the new error codeintegration_missingand namesherdr integration install claudeorcodex. The agent skill has a short step for it.a-stack herdr focus --agent IDshows a bound Agent's pane in the Operator's Herdr. The service checks the binding against Herdr first, as before a notice, then runsherdr agent focus, orherdr tab focusif that fails. Only the Operator can run it.contrib/herdrholds a small Herdr plugin: the action "Open a-stack view" runsa-stack openfor the Session named in its config file, and the popup panewatchrunsa-stack watchfor it. Install it withherdr plugin install mzmzeee/a-stack/contrib/herdr.--body TEXTworks on every command that takes one inline text (task create,task edit,task status,task reopen,task report,task attention setandresolve), like--body-file. The specific flags such as--reportstay.- A mistyped command, help topic or flag gets a suggestion, such as
unknown command tsak list (did you mean task list?). A stray word getsunexpected argument abc for task show (did you mean --task abc?). a-stack taskand other first words alone print the commands of the group, likea-stack help task, and exit with 0. With flags, they fail withinvalid_inputand list the words that can follow.- Getting started has a section "Hand your Session to an Orchestrator", with the commands the Operator runs after
a-stack new. The README Quick start points to it. agent registerandagent rebindwrite the Workspace ID, the Session ID and the Agent name into the new credential file. These fields are not secret. With such a file, Agent commands can leave out--workspaceand--session; a flag that is given must match the file. Older credential files keep working with explicit flags.mail checkhas a top-levelmore, true when more mail is waiting than the response holds. Without--cursor-file, the output then has ahint.
Changed
- Schema 7 adds an expiry to credentials and a table of unused view links. It deletes every existing browser credential, because their secrets are in browser histories. After the upgrade, open views lose access once: run
a-stackora-stack openagain. - The Working status icon turns three times when a Task starts working, then stays still, and waits while the tab is hidden. An endless spin kept the browser busy: about 6.5% of a CPU core with 150 Tasks open.
serveruns SQLitePRAGMA quick_checkbefore it says ready. On a damaged database it stops with exit code 4, names the database file and points to the restore steps. On a 940 MB database the check adds about 0.2 seconds to the start.- A state database with a newer or unknown schema also stops
servewith exit code 4. The message names the schema version it found and the newest one it supports, and says how to get back: update a-stack, or restore a backup. The systemd unit now hasRestartPreventExitStatus=3 4, so it does not restart in a loop. Runa-stack service installto update the unit. - Before a schema migration,
servewrites a private copy of the database,state.db.pre-vN, withVACUUM INTO. It never replaces an earlier copy, and it does not migrate when it cannot write the copy. - The restore steps check the backup with
PRAGMA integrity_checkfirst. - When the service is not running, cannot be reached or its response is cut off, the CLI error has
retryable: true, because the change may have been made. The message also says to ask the Operator to start the service, which is what an Agent must do. a-stack updatesyncs the new binary to disk before it renames it into place, and syncs the folder after, so a power cut cannot leave an empty binary.a-stack update --versionwith an older version warns that the older a-stack may not open the current database, and says how to go back.- The release notes say to run
a-stack update. scripts/build-release.shpins the versions of the Alpine packages it installs (gcc,musl-dev,binutils).- Mention notices accept a harness release in the minor line of a fixture-verified version, from that version up: Codex 0.164.x from 0.164.0, where only 0.164.0 was accepted. Herdr is accepted when its running server reports protocol 22 and a compatible CLI and endpoint (
herdr status server --json), not only when the CLI printsherdr 0.9.5. A Herdr that is not running is nowherdr_unavailable. Claude Code stays mail-only: a partial check with Claude Code 2.1.310 showed bind and focus work, and a mention parks asunsupported_harnessuntil a full fixture run. See Claude Code: partial fixture. - With Herdr notices on, an Agent without a complete binding (
binding_incomplete) or with an unsupported harness (unsupported_harness) is no longer checked again every 30 seconds. Its notices wait until its binding is attached or changed, or the service starts, andnotifications statusshowsnext_attempt_unix_ms: -1. Each check was a committed write: on the 2,000-Task fixture with 23 such Agents and no clients, the idle service wrote 3,809,280 bytes in 120 seconds before (the WAL grew from 94,792 to 473,832 bytes, 13.7 wakeups a second), and now writes 0 bytes (2.7 wakeups a second). invalid_inputerrors name what is wrong: the flag that does not apply to the command, the unknown flag, the bad value (invalid value "abc" for --expected-revision), and the missing or bad text field (--reason is required for --progress waiting,title is required,reason exceeds 2048 bytes).- A bad operation ID gets
operation ID must be 8–128 letters, digits, _ or -, also onagent register, instead of a generic or misleading message. The--operation-idhelp states the rule. - A mail with a mention that is not a current assignee names each such mention and lists the assignee names.
- An ID flag (
--workspace,--session,--agent,--task,--from,--to,--reference) with a value that cannot be an ID fails before the CLI contacts the service, for example--agent takes an Agent ID; 01-orch looks like a name; see a-stack agent list. The CLI still never looks a name up. a-stack newopens the open Session of the same name in this folder's Workspace instead of making a second one. Another name still makes a new Session.- A flag given twice is rejected, except
--mention.versionand--versionreject flags that do not apply to them.help versionno longer lists credential flags. - The help lists
session snapshotandsession pagewith the Session commands. mail check --cursor-file FILEnow writes the file: it merges the returned cursors and the Task scan position into it, atomically and with mode 0600, and creates it if it is missing. The same command run again shows only new mail, and the output lists only the Tasks with new mail. Before, a plainmail checkstarted at message 1 every time and stopped at 100 messages, so an Agent on a busy Task never saw its newest mail (in the review's reproduction with 105 messages, messages 100–105 never appeared), and every check put old mail back into its context. Now the second check reaches message 105, and a third shows nothing. Two checks with the same file at once leave a whole file; the last write wins.--cursor-file -still only reads.- The agent skill uses
mail check --cursor-filein its work loop, and itsmehelper needs only the credential file. It no longer reads the Task before every change: it uses the revision of the Task it read or of its last receipt, and reads again only after aconflict, so the revision check catches changes by others again. One full work loop takes 8 commands instead of 11. Therevandgrevhelper scripts are gone.
Fixed
- When the service refuses
agent registeroragent rebindwith an error that is not retryable, the CLI deletes the new credential file that the command wrote. A file that existed before is kept. - JSON output from the service ends in one newline, not two.
- The docs say which commands take
--state-dir, and usea-stackinstead of./a-stackin examples.
Security
- Releases are signed. The release workflow signs
SHA256SUMSwith an Ed25519 key and uploads the raw signature asSHA256SUMS.sig.a-stack updatechecks it with the public key in the binary before it trusts the checksums, and the install script checks it with OpenSSL 3 when it is installed. For v0.1.5 and later, a missing or wrong signature stops the update or the install, and nothing changes. Older releases have no signature; they install with a warning, only when you name their version. - Every release file,
install.shincluded, has a build provenance attestation. The install guide shows how to check a file withgh attestation verifyand the signature withopenssl. - Only the Operator can open the browser view.
openwith an Agent credential fails withforbidden. Before, an Agent could open a view and read the Task mail of Tasks it was not assigned to. - A view link works once, within 60 seconds. The page trades the code in its fragment for a view token, which it keeps for the tab, so a reload works. Opening the same link again shows that it expired. A view token works for 30 days. Each new link deletes the expired links and view tokens.
a-stack,a-stack -r,a-stack newandopenprint or open a fresh link as before.
To update, run a-stack update and restart the service. See Update.
Full Changelog: v0.1.4...v0.1.5