Repository navigation
Releases: mzmzeee/a-stack
Release list
v0.1.6
Upgrading from v0.1.5: 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-v7 (state.db.pre-v6 from v0.1.4), moves it to schema 8 and prints one line that names the copy. It needs free space of up to three times the size of state.db; with less, it stops before it changes anything and says how much it needs. After the upgrade, v0.1.5 cannot open the database. To go back, run a-stack update --version v0.1.5, stop the service, and put state.db.pre-v7 back as state.db in a new state directory in the same place, as in Go back to an older version; changes made after the upgrade are lost. The database file keeps the pages that the migration freed; a backup and a restore make it small again.
Added
-
The agent hooks have a Stop guard and a Task mail nudge, both on by default. The Stop guard blocks a stop once while a Task that this Agent set
workinghas no report since. It names the Task and gives the two ways out as whole commands with the Task ID, its revision and operation IDs: report and finish, or setwaitingwith a reason. Other assignees, such as a helper or an Orchestrator that follows the Task, are not blocked, and on a shared Task the reason says to read the report first and, when only your part is done, to say so in Task mail. It never blocks in a closed Session, never twice in a row (also in a harness that does not sendstop_hook_active, through a marker file), and lets the agent stop on any error. The nudge checks the Agent's Task mail after a tool call or a prompt, at most every 30 seconds per harness session, with its own cursor file in~/.cache/a-stack/hooks/, and tells the agentNew Task mail on "TITLE"; run mail check.without sender or text. The first check of a harness session reads up to the newest message and reports nothing, also when it runs out of time and goes on at the next hook run. The Agent's own cursor file does not move. A check adds about 5 to 13 ms to a tool call, a skipped one under 1 ms. Hooks installed with v0.1.5 get both with the new binary;hook install --no-stop-guardand--no-mail-nudgeturn them off. See Stop guard and Task mail nudge. -
The agent hooks support Pi 0.87 or later.
a-stack hook install --piwrites the hook lista-stack-hooks.jsonand the extensionextensions/a-stack.tsinto Pi's agent folder (~/.pi/agent, or$PI_CODING_AGENT_DIR). The extension comes with the binary; it runs the samea-stack hookcommands on Pi's events, so a Pi agent gets the reminder, the runtime state, the Stop guard and the Task mail nudge.--piis not in the default, has no--project, and needs/bin/sh.hook uninstall --piremoves the extension with the last hooks. Tested end to end with Pi 1.4.0 and its scripted test model. See Pi. -
a-stack herdr bindbinds Pi panes. Herdr's Pi integration reports the path of Pi's session file instead of a session ID, and a-stack keeps that path as the native session. Mention notices stay off for Pi until a native fixture verifies them. -
a-stack runs on macOS 13 or later, on Apple silicon and Intel. Releases have
a-stack_darwin_arm64.tar.gzanda-stack_darwin_amd64.tar.gz, built on macOS runners and covered bySHA256SUMS, its signature and the attestations. The install script anda-stack updatepick the archive of your system; under Rosetta, the script still takes thearm64archive. The script usesshasumwhensha256sumis missing. macOS has LibreSSL instead of OpenSSL 3, so there the script checks the signature with OpenSSL 3 from Homebrew (brew install openssl@3); without it, it checks only the checksum, says so on stderr and links to how to check the signature by hand. On macOS,a-stack service installsets up the launchd agent~/Library/LaunchAgents/dev.a-stack.plist, which starts at login and again after a crash, with the same three commands and the same refusal while a foregrounda-stack serveanswers; the log is~/Library/Logs/a-stack.log. The browser opens withopen,a-stack watch --notifyshows notices throughosascript, and hints that namesystemctl --username thelaunchctlcommand instead. The state directory stays~/.local/state/a-stack(or$XDG_STATE_HOME/a-stack). The check workflow also builds, vets and tests on macOS. See Install and On macOS with launchd. -
a-stack runs on Windows 10 or later, on x64 and Arm. Releases have
a-stack_windows_amd64.zipanda-stack_windows_arm64.zip, cross-built on Linux with a pinned llvm-mingw, statically linked against the C runtime, smoke-tested onwindows-latestandwindows-11-armbefore publishing, and covered bySHA256SUMS, its signature and the attestations.install.ps1installs withirm https://github.com/mzmzeee/a-stack/releases/latest/download/install.ps1 | iexinto%LOCALAPPDATA%\Programs\a-stack, checks the SHA-256 checksum (not the signature) and adds the folder to the userPATH; a Scoop manifest is prepared incontrib/scoop/. The state directory is%LOCALAPPDATA%\a-stack, created with a protected access list for your account, SYSTEM and Administrators;service.lockis held open without sharing.a-stack service installsets up the Task Scheduler taska-stack-<SID>, which starts at logon and again within a minute after it stops, and the service then writes to%LOCALAPPDATA%\a-stack\service.log.a-stack updatedownloads the.zip, renames the runninga-stack.exetoa-stack.exe.old(removed at the next start) and refuses Scoop and WinGet folders. The view picker uses the console's VT mode, the browser opens throughShellExecute, and the hooks name paths with/. Herdr and the desktop notices ofwatch --notifyare not available on Windows. The check workflow also builds, vets and tests on Windows and runsinstall.ps1in PowerShell 5.1 and 7. Native Windows tests and smoke checks run in CI before the release is published; see On Windows for what still needs a real Windows machine. -
The service logs the cause of each
storage_unavailableerror to stderr, one line per error: the operation, and the Go error type, SQLite result codes or system error number, never a body, an ID, a credential or SQL text. The same line is logged at most once every 10 seconds. Before, a code bug looked like a full disk, and the real cause was lost. -
The browser view's Graph has a semantic zoom: below 50%, cards become blocks in their status color with only the title, at a constant size on screen; below 30%, where a block is too narrow for more than one cut word, blocks without text. Needs you keeps a red ring, and forced colors keep the borders. The blocks keep the cards' size and place, so zooming never runs the layout again.
-
The Graph has a minimap at the bottom right: every card as a block in its status color, Needs you ringed, and a box around the part you see. Click or drag on it to move the view. It hides while the graph fits. A Minimap button in the Graph tab's footer, or
min the graph, turns it off or on, and the button shows which, also while the graph fits. Screen readers skip the minimap and it never takes the focus. -
Browser view cards and Agent rows show the Task mail count, an envelope and a number, also in their screen reader label. Compact Graph blocks leave it out.
-
A browser tab that was open while a-stack was updated says so once the service is back, such as "a-stack was updated to v0.1.7", with a Reload button. The page compares the service's version and its view files (the new
X-A-Stack-Assetsheader) with its own. A reload keeps the view's access. Tabs opened from v0.1.5 or older cannot show this. -
A background browser tab now shows Needs you: it polls every 30 seconds, the tab title counts the requests (
(2) Needs you · Session – a-stack) and the tab icon gets a red dot. An opt-in "Notify me" button shows a system notification when a Task newly needs you; it names the Session and the number of requests, never the question, and sends nothing to the service. -
A_STACK_REQUIRE_SIGNATURE=1makes the install script stop and install nothing when it cannot check the release signature: without OpenSSL 3, or for a release before v0.1.5. Without it, the script still installs after the checksum check, and its warning now goes to stderr. See Install script. -
session inspectrun by an Agent shows that Agent's own ID asyour_agent_id, so an Agent no longer needs to searchagent listfor itself.
Changed
- Before a schema migration,
servechecks that the state directory has room for the copy and the migration, up to three times the size ofstate.dbfor schema 8, and otherwise stops before it writes anything and says how much space it needs. After a migration, it prints one line that names thestate.db.pre-vNcopy and says that an older a-stack cannot open the database now. See Update. - The restore steps restore into the state directory that the CLI uses, after moving the old one aside, instead of into a new folder from
mktemp -d. In/tmp, the restored database could be gone after a reboot, and the CLI, the Agents and the hooks did not find the service there. Go back to an older version has the steps for each service manager. a-stack updatetells you to restart the service only when the service runs the binary that it replaced.a-stack service statusshows the unit or plist that systemd or launchd loaded, also when it is not the file thatservice installwrites, such as/usr/lib/systemd/user/a-stack.servicefrom a package. Before, it said "not installed" next to "enabled" and "active".- `a-stack s...
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 se...
v0.1.4
Added
a-stack skill installinstalls the agent skill in one step. The binary carries the skill of its own version, so it needs no Node.js and no network. It writes~/.claude/skills/a-stack(or$CLAUDE_CONFIG_DIR/skills/a-stack) and~/.agents/skills/a-stack, or with--projectthe same folders in the current folder. It replaces an older copy whole and leaves other skills alone.a-stack skill uninstallremoves the copies.- The agent skill docs also describe
npx skills add mzmzeee/a-stack. - The install script ends with a hint to run
a-stack skill install, and says thata-stack updateupdates a-stack next time. a-stack updateinstalls the latest release in place of the running binary. It finds the latest version from the/releases/latestredirect, without the GitHub API, so it skips prereleases. It downloads over HTTPS only, checks the SHA-256 checksum, takes only thea-stackfile from the archive, checks that the new binary runs and then renames it into place with the same mode. On any failure it changes nothing.--checkonly compares the versions, and--version vX.Y.Zinstalls one release, also an older one. It updates skill copies thata-stack skill installwrote, prints how to restart the service, and needs no service and no credential. A build from source updates only with--version.A_STACK_BASE_URLnames a mirror, as for the install script.a-stack skill install --refreshreplaces only the skill copies that exist.
Changed
- The README demo shows every feature, Task mail included, and holds each step twice as long. Short clips in the browser view guide show the graph, the archive and the Agents tab.
To update, run the install script again and restart the service. See Update.
Full Changelog: v0.1.3...v0.1.4
v0.1.3
Added
- The browser view has a Now tab, the new default. Its columns show the Tasks that need you (with the question), are working, are waiting (with the prerequisites they wait for) and finished recently, and a feed lists the latest changes. The view remembers the last tab.
- The Task read data has
question_preview, the start of the open Needs you question, andlast_action, the action of the Task's latest change. The schema does not change. - In the Graph tab, selecting a Task highlights it, its direct prerequisites and dependents, and dims the rest. Escape or a click on empty space clears it.
- The Working status icon spins, unless the system asks for reduced motion.
- The Task details in the browser view have a Task mail section. It loads nothing until you open it, then shows the messages oldest first as plain text, with the sender, the age and styled mentions, and "Load more" for long threads. New messages appear on the next poll.
- The Task read data has
mail_count, and each mail message hassender_name. task archiveandtask unarchivearchive a Finished or Cancelled Task, or undo it. The Orchestrator or the Operator runs them;task reopenclears the archive. a-stack also counts a done Task as archived when every Task that depends on it is done, or 24 hours after it ended. The Task read data hasarchived,archived_reason,archived_atandended_at, and the details in the view say why a Task is archived.- Each Task history entry has
actor_kind,agentoroperator.
Changed
- The graph runs left to right with one column per rank, and each Task is centered on its prerequisites, so a chain runs level. Lines are curves from an output port on the right edge of a card. Finished and cancelled Tasks are compact one-line blocks with the Agent names above. Tasks without lines sit below or to the right, whichever Fits larger. The graph draws a dependency line only when no other path connects the two Tasks; the details still list every dependency.
- A selected Task's lines turn the accent color and move on top. Other lines fade to 22% and other cards to 42%.
- Finished and cancelled Tasks show in the graph again, unless they are archived. The graph hides archived Tasks by default and shows them dimmed with the Archived (N) toggle. On the Now board, archived Tasks leave Recently finished and appear under "Show archive".
- The database schema is version 6. It adds
archived_atandended_atto Tasks and lets the Task history name the Operator. The upgrade runs once, in one transaction. - The browser view credential can read the Task mail of its own Session with
POST /v1/mail/read. It still cannot send or check mail. The Operator credential still has no mail access. - A mail send raises the Session read revision, so a polling view sees the new
mail_count. - The service is faster under heavy use. It keeps prepared SQLite statements,
mail checkno longer checks each scanned Task's assignment a second time, and the dependency cycle check searches only the edges it follows. The service process sets the Go garbage collector target to 400 unlessGOGCis set. With 20 Agents, 2,000 Tasks and 50,000 messages, service CPU per CLI call fell from 5.6-6.3 ms to 1.5-1.7 ms, and the service memory high-water mark rose from 35-37 MB to 48-50 MB. A worst-casedependency addtook 0.8 ms instead of 70 ms. No contract or schema changes. mail checkchecks a saved cursor only when it reads that Task. A malformed cursor for a Task that you are no longer assigned to is ignored, not rejected.- When the browser view stays stale for thirty seconds but the service still answers, the footer says that the service is busy instead of unreachable.
Fixed
- Dragging the graph pans it also when the drag starts on a Task card, so a zoomed-in graph can be moved. A click without a drag still opens the Task.
To update, run the install script again and restart the service. See Update.
Full Changelog: v0.1.2...v0.1.3
v0.1.2
The database schema does not change (schema version 5). One change can affect scripts: serve now exits with 3, not 1, when another serve owns the state directory.
Added
a-stackwithout a command opens your last Session in the browser. If no service runs, it starts one in the foreground first.a-stack -r(or--resume) picks a Session in the terminal. Without a terminal, or with--json, it prints the Session list.a-stack new [NAME]creates the Workspace for the current folder if needed, creates a Session and opens it. The CLI generates the operation IDs and prints them.a-stack help COMMANDanda-stack COMMAND --helplist the flags of one command.-h,helpand--versionwork.servewithout--listentries the port of its last run first. It keeps the port inlast-port.jsonin the state directory. An open browser tab finds the service again after a restart.- The running version is in the
serveready line, inhealthand in the browser view's footer. After an update, compare it witha-stack version. - The Session snapshot has
workspace_name, the last part of the Workspace path. The view's header shows it. - An agent skill in
skills/a-stackteaches a coding agent to work in an a-stack Session. See docs/agent-skill.md. - Each release includes the systemd user unit
a-stack.serviceand the agent skilla-stack-skill.tar.gz, andSHA256SUMSlists both. - docs/install.md has an Update section. Release notes come from this file.
Changed
serveexits with 3 when anotherserveowns the state directory. The error code is stillconflict. Scripts that check for exit code 1 must check for 3.- The systemd unit sets
RestartPreventExitStatus=3. If anotherserveholds the state directory, the unit fails at once and does not restart every 2 seconds. - The
conflicterror and the errors when no service runs say what to do. The error codes do not change. - After 30 seconds without the service, the browser view says to run
a-stack openagain if you restarted the service. a-stack --helplists the commands in groups and fits in 80 columns.--help --jsonkeeps its fields and appendsnew.- The install script says whether it installed, updated or reinstalled a-stack, with the old and the new version. After an update, it tells you how to restart the service.
- The install script stops with an error if the installed binary does not run.
- The release workflow leaves an existing release unchanged when it runs again for the same tag.
- docs/install.md downloads the systemd unit from the release, and docs/agent-skill.md downloads the skill from the release, instead of from the
mainbranch. - The README Quick start uses
a-stack new,a-stackanda-stack -r. A new live demo shows a terminal next to the browser view, with new screenshots.
Fixed
- The browser view remembers the theme you picked after the browser restarts. Until you pick one, it follows your system's light or dark setting.
- Browser view: each group of lines gets its own track in wrapped rows.
- Browser view: the header showed "a-stack" twice. The second label is now the Workspace name.
- Browser view: "1 agent · 1 task" uses the singular.
- The
a-stack -rpicker escapes U+FFFD and U+202E in the names it shows.
To update, run the install script again and restart the service. See Update.
Full Changelog: v0.1.1...v0.1.2
v0.1.1
v0.1.0
Full Changelog: https://github.com/mzmzeee/a-stack/commits/v0.1.0