Skip to content

v0.1.6

Choose a tag to compare

@github-actions github-actions released this 25 Oct 19:15
· 95 commits to main since this release

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 working has 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 set waiting with 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 send stop_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 agent New 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-guard and --no-mail-nudge turn them off. See Stop guard and Task mail nudge.

  • The agent hooks support Pi 0.87 or later. a-stack hook install --pi writes the hook list a-stack-hooks.json and the extension extensions/a-stack.ts into Pi's agent folder (~/.pi/agent, or $PI_CODING_AGENT_DIR). The extension comes with the binary; it runs the same a-stack hook commands on Pi's events, so a Pi agent gets the reminder, the runtime state, the Stop guard and the Task mail nudge. --pi is not in the default, has no --project, and needs /bin/sh. hook uninstall --pi removes 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 bind binds 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.gz and a-stack_darwin_amd64.tar.gz, built on macOS runners and covered by SHA256SUMS, its signature and the attestations. The install script and a-stack update pick the archive of your system; under Rosetta, the script still takes the arm64 archive. The script uses shasum when sha256sum is 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 install sets 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 foreground a-stack serve answers; the log is ~/Library/Logs/a-stack.log. The browser opens with open, a-stack watch --notify shows notices through osascript, and hints that name systemctl --user name the launchctl command 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.zip and a-stack_windows_arm64.zip, cross-built on Linux with a pinned llvm-mingw, statically linked against the C runtime, smoke-tested on windows-latest and windows-11-arm before publishing, and covered by SHA256SUMS, its signature and the attestations. install.ps1 installs with irm https://github.com/mzmzeee/a-stack/releases/latest/download/install.ps1 | iex into %LOCALAPPDATA%\Programs\a-stack, checks the SHA-256 checksum (not the signature) and adds the folder to the user PATH; a Scoop manifest is prepared in contrib/scoop/. The state directory is %LOCALAPPDATA%\a-stack, created with a protected access list for your account, SYSTEM and Administrators; service.lock is held open without sharing. a-stack service install sets up the Task Scheduler task a-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 update downloads the .zip, renames the running a-stack.exe to a-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 through ShellExecute, and the hooks name paths with /. Herdr and the desktop notices of watch --notify are not available on Windows. The check workflow also builds, vets and tests on Windows and runs install.ps1 in 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_unavailable error 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 m in 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-Assets header) 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=1 makes 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 inspect run by an Agent shows that Agent's own ID as your_agent_id, so an Agent no longer needs to search agent list for itself.

Changed

  • Before a schema migration, serve checks that the state directory has room for the copy and the migration, up to three times the size of state.db for 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 the state.db.pre-vN copy 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 update tells you to restart the service only when the service runs the binary that it replaced. a-stack service status shows the unit or plist that systemd or launchd loaded, also when it is not the file that service install writes, such as /usr/lib/systemd/user/a-stack.service from a package. Before, it said "not installed" next to "enabled" and "active".

  • a-stack serve built without cgo, such as from a go install on a Mac without a C compiler, says that it was built without cgo, instead of the general storage error.

  • The Linux and macOS release archives name owner 0 and the time of the release commit, hold no extended attributes, and gzip stores no name or time, so the same binary gives the same archive.

  • The browser view's Agents tab is a grid of Agent cards. Each header counts the Agent's Tasks in chips ("1 needs you · 3 working · 7 waiting · 1 done"); Needs you and Working Tasks always show as compact rows, Waiting shows its 4 newest (all 5 when there are 5, since a fold would hide one row), and done Tasks fold away. A switch sorts the Agents "Most urgent first" or "By name", and a line on top sums them up. Archived Tasks follow the Archived toggle, which now also shows on the Agents tab. On the 2,000-Task fixture the tab has 39,619 elements instead of 83,823.

  • Graph cards out of view skip layout and paint, turned on only after the layout has measured them. On the 2,000-Task fixture, a zoom step above 50% takes 16–20 ms instead of 52–58 ms, below 20% 61–82 ms instead of 92–119 ms, and a pan frame at 33% 16–17 ms instead of 25–29 ms.

  • In a short or narrow window, the browser view page scrolls and only the tabs stay at the top, so the view gets the height. At 720×450 (200% zoom), the Graph now gets 324 of 450 pixels instead of 202; on a 375×812 phone, 663 instead of 477.

  • The browser view has a System theme button next to Light and Dark, and follows the system theme from the first paint, so a dark system no longer sees a light flash. Mentions in Task mail no longer break inside a name, card shadows are visible, the theme buttons are labelled "Theme", and duplicate CSS rules are gone.

  • The browser view's feed keeps the change on its own line, so a long title no longer hides it, and each kind of change has its own icon. The Needs you chooser lists the oldest request first, with the question and its age. A waiting card names up to three blockers and "+N more". A compact block in the Graph shows its full title on hover.

  • The Needs you button says "Needs you (2)", or "All clear" in neutral colors. An empty Session suggests to brief an Orchestrator with the a-stack skill, and the Agents tab of a Session with no Agents says "No Agents yet". "Clear filters" shows only when a filter is set.

  • The browser view's Task details start with a property grid (Status, Agents, Ticket, Requires, Required by, each dependency with its status icon), hide empty sections, put Task mail last with a "Load 13 more" button, and move the read revision into the footnote.

  • In the Graph tab, Tab moves through the cards in the order of the layout, column by column. Before, it followed the random Task IDs.

  • The browser view draws only the tab that you see, keeps the dependencies while the snapshot's graph_revision stays the same, and indexes Agents and prerequisites once per snapshot. On a 2,000-Task Session, a poll with a change took 2.3–3.9 seconds of main-thread time and now takes 0.2–0.5 seconds; it makes 54 requests and reads 2.4 MB instead of 79 requests and 3.3 MB. Ages tick only where they show, so an idle page no longer lays out every second.

  • Browser view cards have a left border in their status color, and a Task that needs you has a red border and ring, so status reads also at Fit on a big Session. When the Graph focuses a Task, a Task that needs you no longer fades, and the other cards fade their background and borders but keep readable text. Before, the fade failed the WCAG AA contrast check.

  • A new Task stores no text row for an empty description or for its starting reason Not started. Reads show the same texts as before; in the task.create history entry, these two texts have no id. In a test with 2,000 new Tasks, each took 1,059 bytes instead of 1,817 without a description, and 1,458 instead of 1,835 with a short one.

  • Schema 8 stores Task texts and Task mail in rowid tables and drops the extra (id, task_id) index on mail, with the same API output. A report or mail body of 1–3 KB no longer takes a 4 KB page of its own. A backup of the 2,000-Task stress fixture is 80.0 MB instead of 91.0 MB (12% smaller); with two 1–3 KB report versions per Task and some long mail, 14.6 MB instead of 18.5 MB (21% smaller). The migration rebuilds those tables once, 2 to 3 seconds for that fixture, and leaves the freed pages in the file for new data; restore a backup to get the smaller file at once.

  • The WAL file shrinks back to at most 8 MiB after a burst of writes (journal_size_limit). Before, it kept its largest size until the service stopped. The restore steps say that restoring a backup also compacts the database.

  • The browser keeps app.js and app.css and asks the service each time whether they changed (Cache-Control: no-cache with an ETag of their content). An unchanged file comes back as an empty 304 answer, which saves 76 KB on each page load. The page itself stays no-store.

  • The agent skill now asks the Orchestrator to make every piece of work a Task, its own included, and to link each Task to its dependencies when it creates it, then check prerequisite_count for missing links. Agents check task dependencies before they start, wait with a reason while a prerequisite is open, and ask the Orchestrator for a linked Task when they find new work. The brief from a-stack new --orchestrator asks for the links too, and for an Agent for each Task that the Orchestrator hands out instead of one per Task.

  • Command help marks --workspace and --session as "required unless the credential file names it". Before, it said "required", although an Agent whose credential file names them can leave both out.

  • A coding agent that you ask to use a-stack, with no brief, now sets itself up: the skill tells it to run a-stack new --orchestrator 01-orchestrator --no-browser --json itself and read the IDs from the output, instead of asking you for them. Running that command again returns the same hand-off (existing_orchestrator: true) and makes nothing, as long as the credential file belongs to that Session's Orchestrator. The Orchestrator's credential file is now in a-stack-agents/SESSION_ID/, so the same name works in every project; before, the second project failed with "already exists". A file in the v0.1.5 place still counts for a repeat. A repeat proves the file through your_agent_id, so another Agent's credential file never passes as the Orchestrator's. With --orchestrator, a-stack new refuses a subfolder of a project that already has a Workspace, so an agent started there does not make a second team. With --orchestrator, a-stack new never starts the service in the foreground, where it would hang the agent's shell; without a service it says to run a-stack service install. With --orchestrator and --no-browser, it also makes no view link, so no view secret enters the agent's context; the output says to open the view with a-stack.

Fixed

  • Orchestrator setup rejects an existing Agent name before creating another Session, and resumes an interrupted appointment only after authenticating the already registered Agent’s credential.

  • Orchestrator setup with --json never creates a browser view link or launches a browser, even without --no-browser.

  • Windows release builds stop if DLL inspection fails.

  • Windows checks the owner and access list of existing state, credential and backup folders and private files. Service logs stay inside state and are checked before truncation. UNC and device state paths are refused, including resolved network ancestors.

  • Windows resolves directory junctions in project, state and update paths. Scoop tasks retain their stable current path, and updates recognize custom SCOOP and SCOOP_GLOBAL roots. Task names include the account SID; executable paths are quoted, and restart hints require waiting for the old task to stop.

  • The PowerShell installer verifies that the downloaded executable runs successfully before replacing the installed one. Failed update rollbacks report the saved binary path instead of claiming nothing changed.

  • A start that failed after the copy before a schema migration, for example at the foreign key check or on a full disk, wrote another full state.db.pre-vN copy on every try, up to 100. Under launchd that was one copy every 10 seconds. A start now uses the copy again when the database has not changed since.

  • A crash while serve wrote the copy before a migration left a cut-off state.db.pre-vN. Opening it rolled it back to an empty database that passed the integrity check, so restoring it gave an empty a-stack. The copy is now written as state.db.pre-vN.tmp and renamed when it is complete.

  • When daemon-reload or enable failed, a-stack service install left the new unit file behind. It now removes a unit file, plist or task that it just created when the service manager does not take it.

  • a-stack watch --notify-text passed a question that starts with - to notify-send as an option.

  • The SessionStart reminder of the agent hooks is printed as hookSpecificOutput.additionalContext JSON, which Claude Code and Codex read like the plain text before, and which harnesses that parse hook output as JSON no longer drop. Its example command is now a Task command (… task list), since --as agent does not apply to commands such as version.

  • a-stack help hook install describes --project (.claude and .codex), --name (the Agent name) and --credential-file (the Agent's file) for the hook commands. hook install without --runtime-id no longer says that the hooks only print the reminder; they record no runtime state, and the reminder, Stop guard and mail nudge still work.

  • An open browser view of a quiet Session now hides a Task when it becomes 24 hours old (the age rule), at its next poll. Before, it showed the Task until something else changed or the page was reloaded. The snapshot ETag now includes the number of Tasks that the age rule archives.

  • A second Ctrl-C (or SIGTERM) while serve waits up to 10 seconds for open requests ends it at once. Before, the second signal was ignored.

  • Before its first snapshot, the browser view said "Nothing needs you" and showed an active Needs you button. It now says that it is loading.

  • A browser view that cannot reach the service shows a banner above the view after ten seconds, and "Stale" in the tab title, also when the first load fails. Before, only a small footer line said so, after thirty seconds.

  • A browser view whose token the service no longer knows, for example after a restore from an older backup, says within about four seconds of the service answering again that it lost access, why, and to run a-stack. The tab title then starts with "No access". Before, it could say for up to 30 seconds that the service had not answered, and the title said "Stale". While the service does not answer at all, the page now tries every four seconds instead of backing off to 30.

  • Screen reader labels of browser view cards and rows no longer end a question with "?.", and name three or more Agents as "A, B and C" instead of "A and B and C".

  • A card's Needs you label sits next to its progress without a "·", and the Now tab's cards, which are in the Needs you column already, leave it out, so the status line of a card with Task mail no longer wraps.

To update, run a-stack update and restart the service. See Update.

Full Changelog: v0.1.5...v0.1.6