@staix/agent-hub 0.12.44 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +40 -0
- package/README.md +83 -116
- package/THIRD_PARTY_NOTICES.md +29 -0
- package/docs/adding-an-ai-tool.md +102 -14
- package/docs/agent-notes/README.md +15 -0
- package/docs/agent-notes/adapters.md +63 -46
- package/docs/agent-notes/budget.md +7 -2
- package/docs/agent-notes/bus.md +6 -4
- package/docs/agent-notes/daemon.md +15 -8
- package/docs/agent-notes/local-worker.md +6 -4
- package/docs/agent-notes/tasks.md +18 -5
- package/docs/agent-notes/tests.md +11 -9
- package/docs/dogfood.md +92 -0
- package/docs/events.md +14 -1
- package/docs/operations.md +349 -26
- package/docs/profiles.md +2 -2
- package/docs/quickstart.md +12 -2
- package/docs/sdlc.md +61 -13
- package/docs/security.md +24 -12
- package/docs/smoke.md +9 -4
- package/docs/specs/2026-09-19-agent-hub-design.md +873 -13
- package/docs/verification/2026-10-19-reviewer-isolation.md +2 -0
- package/docs/verification/2026-10-21-469-r1-dashboard-tokens.md +43 -0
- package/docs/verification/2026-10-21-469-r2-dashboard-shell.md +54 -0
- package/docs/verification/2026-10-21-469-r3-dashboard-board.md +51 -0
- package/docs/verification/2026-10-21-469-r4-dashboard-views.md +77 -0
- package/docs/verification/2026-10-21-469-r6-dashboard-motion-states.md +82 -0
- package/docs/verification/2026-10-22-0.12.45.md +60 -0
- package/docs/verification/2026-10-22-code-facts.md +78 -0
- package/docs/verification/2026-10-22-codex-reviewer-isolation.md +47 -0
- package/docs/verification/2026-10-22-kimi-qwen-compat.md +79 -0
- package/docs/verification/2026-10-23-0.13.0.md +89 -0
- package/docs/verification/assets/469-r1-board-1440-dark.png +0 -0
- package/docs/verification/assets/469-r1-board-1440-light.png +0 -0
- package/docs/verification/assets/469-r1-board-390-dark.png +0 -0
- package/docs/verification/assets/469-r1-board-390-light.png +0 -0
- package/docs/verification/assets/469-r2-agents-1440-dark.png +0 -0
- package/docs/verification/assets/469-r2-agents-768-dark.png +0 -0
- package/docs/verification/assets/469-r2-board-1024-light.png +0 -0
- package/docs/verification/assets/469-r2-board-1440-dark.png +0 -0
- package/docs/verification/assets/469-r2-board-1440-light.png +0 -0
- package/docs/verification/assets/469-r2-board-390-dark.png +0 -0
- package/docs/verification/assets/469-r2-board-390-light.png +0 -0
- package/docs/verification/assets/469-r2-board-768-light.png +0 -0
- package/docs/verification/assets/469-r3-board-1440-dark.png +0 -0
- package/docs/verification/assets/469-r3-board-1440-light.png +0 -0
- package/docs/verification/assets/469-r3-board-390-light.png +0 -0
- package/docs/verification/assets/469-r3-detail-1440-dark.png +0 -0
- package/docs/verification/assets/469-r3-detail-1440-light.png +0 -0
- package/docs/verification/assets/469-r3-detail-390-dark.png +0 -0
- package/docs/verification/assets/469-r3-plan-1440-light.png +0 -0
- package/docs/verification/assets/469-r3-plan-390-light.png +0 -0
- package/docs/verification/assets/469-r4-agents-1440-dark.png +0 -0
- package/docs/verification/assets/469-r4-agents-1440-light.png +0 -0
- package/docs/verification/assets/469-r4-agents-390-dark.png +0 -0
- package/docs/verification/assets/469-r4-memory-1440-dark.png +0 -0
- package/docs/verification/assets/469-r4-memory-1440-light.png +0 -0
- package/docs/verification/assets/469-r4-memory-390-dark.png +0 -0
- package/docs/verification/assets/469-r4-message-1440-light.png +0 -0
- package/docs/verification/assets/469-r4-office-1440-dark.png +0 -0
- package/docs/verification/assets/469-r4-office-1440-light.png +0 -0
- package/docs/verification/assets/469-r4-settings-1440-dark.png +0 -0
- package/docs/verification/assets/469-r4-settings-1440-light.png +0 -0
- package/docs/verification/assets/469-r4-stream-1440-light.png +0 -0
- package/docs/verification/assets/469-r4-stream-390-light.png +0 -0
- package/docs/verification/assets/469-r6-agents-empty-390-dark.png +0 -0
- package/docs/verification/assets/469-r6-agents-empty-390-light.png +0 -0
- package/docs/verification/assets/469-r6-board-1440-light.png +0 -0
- package/docs/verification/assets/469-r6-board-390-dark.png +0 -0
- package/docs/verification/assets/469-r6-board-empty-1440-dark.png +0 -0
- package/docs/verification/assets/469-r6-board-empty-1440-light.png +0 -0
- package/docs/verification/assets/469-r6-disconnected-1440-dark.png +0 -0
- package/docs/verification/assets/469-r6-disconnected-1440-light.png +0 -0
- package/docs/verification/assets/469-r6-disconnected-390-dark.png +0 -0
- package/docs/verification/assets/469-r6-skeleton-1440-light.png +0 -0
- package/docs/verification/assets/469-r6-skeleton-390-dark.png +0 -0
- package/docs/verification/assets/469-r6-toasts-1440-dark.png +0 -0
- package/docs/verification/assets/469-r6-toasts-1440-light.png +0 -0
- package/docs/verification/assets/469-r6-toasts-390-light.png +0 -0
- package/docs/verification/dogfood/2026-10-22.md +3109 -0
- package/docs/verified.json +19 -16
- package/package.json +5 -1
- package/plugins/agent-hub/.claude-plugin/plugin.json +1 -1
- package/plugins/agent-hub/server.js +10120 -9623
- package/src/adapters/adapter-api.ts +2 -0
- package/src/adapters/agy/definition.ts +3 -1
- package/src/adapters/agy/entry.ts +5 -4
- package/src/adapters/claude-channel.ts +32 -12
- package/src/adapters/codex-appserver.ts +19 -2
- package/src/adapters/codex-review-isolation.ts +12 -5
- package/src/adapters/compat.ts +140 -0
- package/src/adapters/conformance/acp.ts +114 -0
- package/src/adapters/conformance/codex.ts +191 -0
- package/src/adapters/conformance/enrollment.ts +43 -0
- package/src/adapters/conformance/factories.ts +17 -0
- package/src/adapters/conformance/fake-paths.ts +12 -0
- package/src/adapters/conformance/fakes/acp-server.ts +267 -0
- package/src/adapters/conformance/fakes/acp-watchdog-agent.ts +10 -0
- package/src/adapters/conformance/fakes/app-server.ts +119 -0
- package/src/adapters/conformance/fakes/codex-bin.ts +15 -0
- package/src/adapters/conformance/fakes/jcode-agent.ts +91 -0
- package/src/adapters/conformance/fakes/model-server.ts +39 -0
- package/src/adapters/conformance/fakes/pi-rpc.ts +32 -0
- package/src/adapters/conformance/index.ts +11 -0
- package/src/adapters/conformance/kit.ts +50 -0
- package/src/adapters/conformance/local-pi.ts +100 -0
- package/src/adapters/conformance/owned-acp.ts +44 -0
- package/src/adapters/definitions/builtin-metadata.ts +25 -7
- package/src/adapters/definitions/native-cli-doctor.ts +12 -5
- package/src/adapters/definitions/native-cli-entry-jcode.ts +9 -6
- package/src/adapters/definitions/native-cli-entry-kimi.ts +7 -1
- package/src/adapters/definitions/native-cli-entry.ts +7 -19
- package/src/adapters/definitions/native-cli-jcode-mcp.ts +9 -2
- package/src/adapters/definitions/native-cli-preview-common.ts +2 -0
- package/src/adapters/definitions/native-cli-preview-jcode.ts +8 -2
- package/src/adapters/definitions/native-cli-preview-qwen.ts +2 -1
- package/src/adapters/definitions/native-cli-preview.ts +2 -11
- package/src/adapters/definitions/qwen-native.ts +7 -3
- package/src/adapters/definitions/qwen.ts +5 -1
- package/src/adapters/external-metadata.ts +48 -0
- package/src/adapters/external-module-scan.ts +126 -0
- package/src/adapters/external-modules.ts +240 -0
- package/src/adapters/jcode.ts +72 -31
- package/src/adapters/kimi-review.ts +6 -3
- package/src/adapters/pi.ts +2 -0
- package/src/adapters/public.ts +7 -0
- package/src/adapters/registry-types.ts +13 -1
- package/src/adapters/registry.ts +52 -15
- package/src/cli/agents.ts +40 -0
- package/src/cli/console-review.ts +54 -0
- package/src/cli/console-state.ts +124 -29
- package/src/cli/console-symbols.ts +74 -0
- package/src/cli/console-usage.ts +89 -0
- package/src/cli/console.ts +26 -1
- package/src/cli/help.ts +36 -21
- package/src/cli/identity.ts +30 -7
- package/src/cli/init.ts +109 -11
- package/src/cli/main.ts +145 -16
- package/src/cli/output.ts +44 -1
- package/src/cli/preview.ts +1 -1
- package/src/cli/sdlc-release-guard.ts +82 -0
- package/src/cli/upgrade-labels.ts +1 -1
- package/src/cli/upgrade-presentation.ts +1 -1
- package/src/cli/upgrade-restore-state.ts +3 -2
- package/src/cli/upgrade-runtime.ts +4 -1
- package/src/hub/action-class.ts +362 -0
- package/src/hub/action-policy.ts +106 -0
- package/src/hub/board.ts +72 -11
- package/src/hub/budget.ts +71 -2
- package/src/hub/bus.ts +43 -3
- package/src/hub/checks.ts +80 -31
- package/src/hub/code-facts.ts +223 -0
- package/src/hub/config-apply.ts +28 -11
- package/src/hub/config-reload.ts +8 -5
- package/src/hub/config-trust.ts +7 -4
- package/src/hub/control-client.ts +4 -1
- package/src/hub/daemon.ts +332 -61
- package/src/hub/dogfood-read.ts +199 -0
- package/src/hub/dogfood.ts +163 -0
- package/src/hub/envelope.ts +1 -1
- package/src/hub/events.ts +11 -2
- package/src/hub/facts.ts +76 -13
- package/src/hub/hub-tools.ts +45 -7
- package/src/hub/inbox-polling.ts +25 -0
- package/src/hub/instance-config.ts +17 -5
- package/src/hub/instance-execution.ts +20 -8
- package/src/hub/instances.ts +75 -2
- package/src/hub/peers.ts +9 -0
- package/src/hub/plan-conformance.ts +83 -0
- package/src/hub/profiles.ts +7 -2
- package/src/hub/release-worktree.ts +56 -0
- package/src/hub/review-brief.ts +36 -0
- package/src/hub/review-findings.ts +104 -0
- package/src/hub/roster.ts +31 -5
- package/src/hub/sdlc-queue.ts +48 -11
- package/src/hub/sdlc-release-authorization.ts +173 -0
- package/src/hub/sdlc-release.ts +16 -1
- package/src/hub/sdlc.ts +71 -18
- package/src/hub/settings.ts +10 -3
- package/src/hub/snapshots.ts +101 -14
- package/src/hub/symbol-normalizer.ts +26 -0
- package/src/hub/task-code-symbols.ts +90 -0
- package/src/hub/task-sweep.ts +3 -2
- package/src/hub/tasks.ts +556 -88
- package/src/hub/test-integrity.ts +162 -0
- package/src/hub/ui.ts +2 -2
- package/src/hub/usage-rollup.ts +361 -0
- package/src/local/sandbox.ts +5 -3
- package/src/ui/index.html +560 -78
- package/src/ui/office-model.ts +3 -1
- package/src/ui/peer-palette.ts +44 -0
- package/templates/AGENTS.block.md +1 -1
- package/templates/profiles/dev.json +6 -1
- package/templates/profiles/general.json +6 -1
- package/templates/profiles/research.json +6 -1
- package/templates/profiles/writing.json +6 -1
- package/templates/release-guard.block.md +6 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,46 @@
|
|
|
2
2
|
|
|
3
3
|
Issue and pull request numbers in the entries for 0.7.7 and earlier refer to the previous repository, archived on 2026-09-30 when this repository's history was rewritten; the one exception is the open smoke-check issue, formerly #12, which moved here as #1. Numbers in newer entries refer to this repository.
|
|
4
4
|
|
|
5
|
+
## Unreleased
|
|
6
|
+
|
|
7
|
+
## 0.13.0
|
|
8
|
+
|
|
9
|
+
- Add the #636 action-policy foundation: a pure classifier, machine-local always-ask configuration, session-bound approval budgets and explicit per-peer enforcement status. Adapter pre-tool gates remain pending; status reports that limit instead of claiming protection.
|
|
10
|
+
- Person-only release approval binds the candidate commit, version and fresh docs; an opt-in init-written Git tag pre-push guard refuses missing or mismatched approval and preserves existing hooks (#481 S6).
|
|
11
|
+
- Bug-labelled tasks gain source-labelled red-first receipts and PR test-integrity readbacks. Enforce blocks review and approval when proof is missing/unknown or a pre-existing test is modified/deleted; advise shows the findings. Status and merge queues retain private metadata screening (#481 S4).
|
|
12
|
+
- Version policy for native agent CLIs (#691): one verified/in-line/trusted/refused decision in `src/adapters/compat.ts` for the Codex and Kimi reviewers, Jcode, agy and Qwen; `ahub agents [--json]` shows it and the person-only `ahub agents trust <id> <version> [--revoke]` accepts an untested version on this machine; refusals name the version and the trust command; a weekly workflow reports upstream drift. Receipts add Codex reviewer 0.163.0 (#697), Kimi reviewer 2.3.0 and Qwen Code 0.26.0 (#714).
|
|
13
|
+
- Extra Jcode instances with their own home, socket and state; hub tools are bound to an owned launch (#685).
|
|
14
|
+
- Usage: ledger events for Codex usage breakdown, budget pause/resume and derived quota resets (#683 U1); an incremental roll-up in `hub.db`, the `usage` control op and `ahub usage [limits|total]` (U2); the console Usage panel (tab `7`) with windows, pauses, last resets and tokens per peer and per selected task (U3).
|
|
15
|
+
- Code structure (#682, #684): optional bounded code facts from ripwire 0.6.7 in the review brief (observed symbols, unknown change kinds, deleted definitions not covered); head-bound task symbol observations kept apart from the task row and dropped on a head, repository or privacy change; the console task detail shows changed symbols (matching, unplanned, untouched) and screened overlaps, and a completed-change notice says `same file, different symbols` only on complete disjoint evidence; plan symbols match by normalized name across overlap notices, grooming and the review brief (#682 phase 1b).
|
|
16
|
+
- SDLC: the hub links lifecycle issue and PR identity from what it can verify (#694); test integrity for bug fixes with red-first receipts and modified pre-existing test detection (#481 S4); `ahub report --dogfood`, a bounded weekly scorecard of real use (#687), with CI flow measured per recorded PR head (#704); a profile-selected review checklist and hub tool descriptions (#507).
|
|
17
|
+
- Console review guidance (#711): `r` on a task in review asks `a approve` or `c request changes`, shows a guide line, refuses an empty changes note and shows the result; an agent shell refused a person-only action is told why; the user-reviewed done notice names the console path.
|
|
18
|
+
- Pull-only peers catch up (#713): `hub_inbox` drains up to 64 KiB oldest first and says how many are waiting; completed-change notices are one per recipient per done, a newer one supersedes the queued one, and none go to unaccepted work; a queued delivery can be discarded while its peer is busy; refusals name their cause; the person's `ahub queue discard --peer <id> --reason <text> [--yes]` and the console Queue `D` clear a backlog. Empty pull-only polling is detected (#681).
|
|
19
|
+
- Fixes: a check's exit and pipes are read through Bun.spawn so an early exit is not lost (#558); snapshot attribution survives own-commit rebases and long reflogs (#612); readiness respects the reserved owner's WIP cap (#655); host timeout kill markers are preserved in the sandbox (#700); the Codex reviewer disables legacy notify (#697).
|
|
20
|
+
- Retired as announced (#481): `sdlc.workflow` (gsd-lite) no longer loads, and the `phase` receipt name is refused; record a `criteria` checklist with `hub_sdlc_record` instead. `local.bash_network: "direct"` still works and still warns; its removal moves to a later release.
|
|
21
|
+
- Releases: a release with any feature bumps the minor version; a fix-only release bumps the patch.
|
|
22
|
+
|
|
23
|
+
## 0.12.45
|
|
24
|
+
|
|
25
|
+
The dashboard is redesigned (#469), a machine-local, content-pinned adapter module can add an ACP agent (#451 A4), the peer lists and the CLI surface come from the adapter definitions (#625), and reviews gain structured findings with an Important gate (#481 S3) and plan conformance with a person-only departure acceptance (#481 S2).
|
|
26
|
+
|
|
27
|
+
- Load external adapter modules: `adapter_modules: [{ path, sha256 }]` in an untracked `.agenthub/config.local.json` names a self-contained ESM bundle that the daemon imports at startup from its hash-checked bytes, with `@staix/agent-hub/adapter` bound to the running hub. A module is refused on its own (bad pin, unsupported import, an import that does not settle within 2 s) while the builtins start; the CLI only sees bounded metadata. `@staix/agent-hub/adapter` and `@staix/agent-hub/conformance` are published for module authors. A pin authorizes code to run with daemon privileges; it is not a sandbox (#451 A4, #648, #653).
|
|
28
|
+
- The peer lists (`KNOWN_PEERS`, `OPTIONAL_PEERS`, `START_MODE_PEERS`, role, help and planner order) and each builtin's `ahub <kind>` entry, preview and help usage come from the adapter definitions; the orders shown are unchanged (#625, #656). The daemon reads optional peer capability members for session generation and permission mode instead of checking peer classes (#625, #667).
|
|
29
|
+
- `hub_review` and `ahub review --findings` take structured findings (id, pass, severity, disposition). In enforce, an open Important finding blocks approval and carries across later heads until a reviewer marks it fixed or false_positive or the person accepts it with a rationale; a supplied head must be the task's current head, and a finding id seen on a second task proposes one backlog card for an AGENTS.md or area-note amendment. `sdlc.max_nits` sets the nit cap (default 5) (#481 S3, #652, #657).
|
|
30
|
+
- Plan conformance: a task plan may carry `proof` and `risks`, and review, status and the merge queue compare the PR's changed files with the plan's literal file or directory entries (renames and copies read as unknown). In enforce, a departure needs an amended plan or the person's `ahub sdlc accept-departure <task> <head> <reason...>`, which binds the repository, PR, head, file inventory, plan and repository scope and expires on restart (#481 S2, #665).
|
|
31
|
+
- Review readiness keeps a lost reuse proof apart from quiet review drift, a delayed check that is refused tells its owner, and review-thread authors other than the person count as pending bot comments (#230, #641, #643, #644).
|
|
32
|
+
- A large file rewritten with the same size within one filesystem tick on Linux is now seen as changed: facts compare a recently written file by its bytes, within a bounded budget (#428, #646).
|
|
33
|
+
- When `ahub kimi --mode tui` fails because the running hub's retained `kimi_cmd` has no TUI form, the error says the command is the running hub's and that the file's value waits for `ahub settings reload` (#654, #658).
|
|
34
|
+
- The daemon's snapshot Git budget reads an injectable clock, a host-only `snapshotClock` option, so a test can hold it fixed and a slow CI disk cannot spend the 250 ms before a turn's end evidence is read (an exhausted budget records an unknown tree, and an unknown tree restarts the empty-turn stall count: the intermittent #661 failure of the #498 stall test). Nothing in the shipped daemon sets it, no configuration key or tool reaches it, and the share stays 250 ms.
|
|
35
|
+
- The dashboard board gets simpler cards (title, owner avatar, one state and priority badge, release), a task detail that opens as a right-hand sheet with its lines grouped into Status, People, Dates and Links, and a Plan sheet that holds the five board forms (plan, split, releases, delivery evidence, propose) with the fields and actions they had (#469 R3).
|
|
36
|
+
- The dashboard gets an app shell: from 1024px a sticky top bar and a left sidebar, below it a row of tabs that scrolls inside itself so the page never scrolls sideways; the connection status shows a coloured dot; keys `1`-`7` switch views, `?` lists the keys and `Esc` closes a sheet, ignored while typing; navigation icons come from an inline sprite of nine Tabler icons (MIT notice in `THIRD_PARTY_NOTICES.md`). View names, order, the cookie and ids are unchanged (#469 R2).
|
|
37
|
+
- The dashboard's style block is rewritten around one token block (colour, a 4px spacing scale, a type scale, a 6/10/full radius rule and two shadows), the dead rules are gone, the indigo accent replaces green for primary actions, focus and selection, and every peer colour has a light and a dark variant. The layout, views and behaviour are unchanged, and the contrast test now also covers the accent, dots, disabled controls and the peer palette in both themes (#469 R1).
|
|
38
|
+
- The dashboard's Agents rows become a summary line plus one folded details block, the Stream gets aligned event rows with its filters above the list, Memory rows and detail use the colour tokens, Settings groups are sections with a "restart pending" badge and Message uses the shared form styles. The star, arrow, checking and Office condition glyphs become Tabler icons and drawn shapes next to their words (three more icons, twelve in all), the Office scene's colours are checked through the same tokens in the contrast test, and a test now fails if a listed glyph comes back (#469 R4, R5).
|
|
39
|
+
- The dashboard keeps task cards, peer rows and memory rows per id across a poll, so hover, an open fold and a focused card survive an update that changed something else. It gets quiet motion on `transform` and `opacity` only (press, view fade, card arrival, toast, sheets) that is off under reduced motion, first-load skeletons for the board and the peers, empty views that name their command, a disconnected state with the time of the last snapshot, and notices as an `aria-live` toast stack where errors stay until dismissed and a success fades after 4 s (#469 R6).
|
|
40
|
+
- A board card's one badge now also says when the task is overdue or its check is running ("in progress P2, overdue, check running"), in its text and in the card's accessible name, instead of a second and third badge. An overdue card turns the badge warn unless the state is already an error, and the task detail keeps its own Overdue and Check running lines (#293).
|
|
41
|
+
- The dashboard keeps its first-load skeletons for the board and the peers after a project switch until that project's first snapshot renders (a slow or failed first snapshot no longer reads as "No project selected", which is now only for no running project), and a toast that is dismissed, expires or is pushed out no longer takes keyboard focus from another toast's Dismiss button (#469 R6 follow-ups).
|
|
42
|
+
- Four #450 I2 follow-ups: the interactive recovery screen and `--verbose` receipt now show a restored extra's recorded outcome after its declaration was revoked instead of throwing "invalid restore receipt"; a roster key left by an undeclared instance (`codex-2`) loads as inert and `ahub roster remove codex-2` deletes it, while any other unknown key is still an unsupported peer (only a kind that can declare an instance counts: `roster.jcode-worker` stays a typo). A key that lives only in the shared `.agenthub/config.json` is refused with "edit .agenthub/config.json" instead of reporting a removal that changes nothing, and the removal says "stale roster key removed" instead of a roster state; the `peer_instances` refusal text and the spec say it applies only while a declared instance may be live, and ask to end the extra sessions before removing a declaration; and the git calls behind an extra-instance start share one 5 s allowance instead of 5 s each (#225).
|
|
43
|
+
- A Claude channel tool result no longer tells a session to call `hub_inbox` while a delivery hold refuses its pulls (the counts and held rows stay), and a `hub_inbox` result states the queued count once (#221). Documented limit: mid-turn steer of a push-capable Claude session was proven only on Claude Code 2.1.302.
|
|
44
|
+
|
|
5
45
|
## 0.12.44
|
|
6
46
|
|
|
7
47
|
A standard ACP agent can join a project from config alone (#451 A3), adapter definitions become the single dispatch point (#451 A2b), agy stops reading Claude's state files (#624), and owner turns that write nothing are flagged (#498).
|
package/README.md
CHANGED
|
@@ -1,139 +1,106 @@
|
|
|
1
1
|
# agent-hub
|
|
2
2
|
|
|
3
|
-
A hub on
|
|
4
|
-
Codex, Kimi Code, Pi and a hub-owned local worker (Qwen Code, Jcode and
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
A hub on your own machine where coding agents work together as one team. Claude
|
|
4
|
+
Code, Codex, Kimi Code, Pi and a hub-owned local worker (plus Qwen Code, Jcode and
|
|
5
|
+
Antigravity if you want them) share a message bus, a task board and a memory, each
|
|
6
|
+
connected through its own native interface.
|
|
7
7
|
|
|
8
|
-
Status: 0.
|
|
8
|
+
Status: 0.13.0, control protocol 16. Bun + TypeScript, one loopback daemon per
|
|
9
9
|
project. Site: [agent-hub.staix.net](https://agent-hub.staix.net).
|
|
10
10
|
|
|
11
|
-
##
|
|
12
|
-
|
|
13
|
-
- **Peers, not a pipeline.** Every agent can message the others, and the hub
|
|
14
|
-
delivers to each through its native surface (Claude channel plugin, Codex
|
|
15
|
-
app-server, ACP, Pi RPC or TUI). Messages are batched into digests, priorities
|
|
16
|
-
decide what interrupts a turn, and delivery is durable across restarts.
|
|
17
|
-
- **A shared task board.** Tasks are proposed, accepted, done and reviewed through
|
|
18
|
-
hub tools. `routing.toml` assigns owners by task class, roles split planning,
|
|
19
|
-
implementation and review, and a designated planner can be changed live.
|
|
20
|
-
Cause-deduplicated stalls and unread pull-only offers need attention; cancellation
|
|
21
|
-
closes work without approving it or releasing its dependents. Owners of
|
|
22
|
-
overlapping work in the same repository are told what changed.
|
|
23
|
-
- **Shared memory.** Decisions, contracts, fails and findings go to the hub's own
|
|
24
|
-
store through the exact-pinned first-party `@staix/agent-mem` library (short-
|
|
25
|
-
and long-term tiers, a typed graph, git sync between machines),
|
|
26
|
-
next to optional claude-mem capture. Entries belong to their project unless
|
|
27
|
-
saved as shared, which makes them readable from every project on the machine.
|
|
28
|
-
Agents get memory as a recall preface, as briefs on a task, and through bounded
|
|
29
|
-
`hub_memory_search`, `hub_memory_show` and `hub_memory_graph` tools. Agents
|
|
30
|
-
can propose corrections; candidates stay outside evidence until a person acts.
|
|
31
|
-
- **Local and remote models.** Pi and the local worker run on DGX or local MLX
|
|
32
|
-
through an authenticated relay; in-process hub routes select models by task
|
|
33
|
-
through a self-hosted OmniRoute gateway. Tasks flagged as PII stay on the on-prem
|
|
34
|
-
worker.
|
|
35
|
-
- **Guard rails.** The local worker and Pi run in a sandbox, and by default their
|
|
36
|
-
writes and shell commands wait for the person's approval; a permission mode
|
|
37
|
-
the person picks (`ask-when-needed`, `never-ask`) skips some or all prompts.
|
|
38
|
-
Budgets pause a peer before it runs out of quota, and recovery never replays
|
|
39
|
-
an effect whose outcome is unknown.
|
|
40
|
-
- **Operations.** A terminal console and a local dashboard, one hub per
|
|
41
|
-
repository or worktree with a machine-wide view, and `ahub upgrade` that carries
|
|
42
|
-
running sessions across versions. Settings reload without a restart where their
|
|
43
|
-
apply class allows; guarded values wait for a person's confirmed
|
|
44
|
-
`ahub settings reload` in a terminal. The console supports revision-checked task
|
|
45
|
-
assignment/unassignment, delivery-queue resolution, per-peer planner WIP limits
|
|
46
|
-
and backlog management from the Tasks tab. Peers with independent
|
|
47
|
-
tool turns can request one uncertain redelivery; the delivery-only local worker
|
|
48
|
-
and headless ACP peers leave held deliveries for the person to resolve.
|
|
11
|
+
## Quick start
|
|
49
12
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
- **Curated memory** ([#412](https://github.com/STAIxBWLB/agent-hub/issues/412)).
|
|
53
|
-
The memory core now lives in [agent-mem](https://github.com/STAIxBWLB/agent-mem)
|
|
54
|
-
(`@staix/agent-mem`, with the `amem` CLI), which agent-hub uses as its one
|
|
55
|
-
exact-pinned first-party dependency. Next, memory becomes curated rather than
|
|
56
|
-
captured: compression, removal, correction
|
|
57
|
-
and failure-driven management, each shipped only after its contract and a
|
|
58
|
-
measurement.
|
|
59
|
-
- **Every peer able to do its share** ([#418](https://github.com/STAIxBWLB/agent-hub/issues/418)).
|
|
60
|
-
Bounded task-spec reads and opt-in isolated checks are implemented. Installed
|
|
61
|
-
managed-Pi verification (AC8) remains open; source and CI results do not certify
|
|
62
|
-
that live runtime.
|
|
63
|
-
- **Measured, not assumed.** Add-ons and memory are kept or dropped by controlled
|
|
64
|
-
comparisons ([#248](https://github.com/STAIxBWLB/agent-hub/issues/248),
|
|
65
|
-
[#258](https://github.com/STAIxBWLB/agent-hub/issues/258)).
|
|
13
|
+
You need [Bun](https://bun.sh) 1.4.2 or later on PATH.
|
|
66
14
|
|
|
67
|
-
|
|
15
|
+
```bash
|
|
16
|
+
bun add -g @staix/agent-hub && ahub setup
|
|
17
|
+
cd <your project> && ahub init && ahub up # daemon plus the operator console
|
|
18
|
+
```
|
|
68
19
|
|
|
69
|
-
|
|
20
|
+
Then start the agents you use, one terminal each, and talk to them:
|
|
70
21
|
|
|
71
22
|
```bash
|
|
72
|
-
|
|
73
|
-
|
|
23
|
+
ahub claude # Claude Code with the hub channel
|
|
24
|
+
ahub codex # Codex TUI, attached through the hub
|
|
25
|
+
ahub say "Each of you: reply with your name."
|
|
26
|
+
ahub ui # the web dashboard
|
|
74
27
|
```
|
|
75
28
|
|
|
76
|
-
`ahub init --dry-run --json` shows what init would write
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
29
|
+
`ahub init --dry-run --json` shows what init would write. The
|
|
30
|
+
[Quickstart](docs/quickstart.md) walks through a first session and a working day.
|
|
31
|
+
|
|
32
|
+
## What you get
|
|
33
|
+
|
|
34
|
+
- **Peers, not a pipeline.** Any agent can message the others. Messages are batched
|
|
35
|
+
into digests, priorities decide what interrupts a turn, and delivery survives
|
|
36
|
+
restarts.
|
|
37
|
+
- **A shared task board.** Work is proposed, accepted, done and reviewed through hub
|
|
38
|
+
tools. Roles split planning, implementation and review, `routing.toml` picks
|
|
39
|
+
owners by task class, and owners of overlapping work are told what changed.
|
|
40
|
+
- **Shared memory.** Decisions, contracts, fails and findings are kept through the
|
|
41
|
+
first-party [`@staix/agent-mem`](https://github.com/STAIxBWLB/agent-mem) library
|
|
42
|
+
(short- and long-term tiers, a typed graph, git sync between machines). Agents get
|
|
43
|
+
it as a recall preface, as briefs on a task, and through bounded search tools.
|
|
44
|
+
- **Local and on-prem models.** Pi and the local worker can run on DGX or local MLX
|
|
45
|
+
through an authenticated relay. Tasks marked as PII stay on the on-prem worker.
|
|
46
|
+
- **Guard rails.** The local worker and Pi run in a sandbox, and their writes and
|
|
47
|
+
shell commands wait for your approval unless you choose a looser permission mode.
|
|
48
|
+
Budgets pause an agent before it runs out of quota, and recovery never replays an
|
|
49
|
+
effect whose outcome is unknown.
|
|
50
|
+
- **Operations.** A terminal console and a local dashboard, one hub per repository or
|
|
51
|
+
worktree with a machine-wide view, live settings reload, token usage and quota
|
|
52
|
+
history (`ahub usage`), and `ahub upgrade`, which carries running sessions across
|
|
53
|
+
versions.
|
|
54
|
+
|
|
55
|
+
## Upgrading
|
|
56
|
+
|
|
57
|
+
Run `ahub upgrade` while your hubs are running. Read the notes for your version in
|
|
58
|
+
the [Quickstart](docs/quickstart.md) ("Upgrading to ...") and the
|
|
59
|
+
[Changelog](CHANGELOG.md) first: some releases need a one-time step, such as
|
|
60
|
+
refreshing an agent's MCP entry.
|
|
61
|
+
|
|
62
|
+
Agent CLIs update themselves. `ahub agents` shows which installed versions the hub
|
|
63
|
+
accepts, and `ahub agents trust <id> <version>` accepts an untested one on this
|
|
64
|
+
machine.
|
|
65
|
+
|
|
66
|
+
Before you migrate a memory home with `amem`, read
|
|
67
|
+
[memory profiles and rollout](docs/memory.md#selected-memory-profile). Every hub that
|
|
68
|
+
uses the home must run a version that understands the new layout.
|
|
69
|
+
|
|
70
|
+
## Where it is going
|
|
71
|
+
|
|
72
|
+
- **Curated memory** ([#412](https://github.com/STAIxBWLB/agent-hub/issues/412)):
|
|
73
|
+
compression, removal, correction and failure-driven management, each shipped only
|
|
74
|
+
after its contract and a measurement.
|
|
75
|
+
- **Every agent able to do its share** ([#418](https://github.com/STAIxBWLB/agent-hub/issues/418)).
|
|
76
|
+
- **Measured, not assumed.** Add-ons and memory are kept or dropped by controlled
|
|
77
|
+
comparisons ([#248](https://github.com/STAIxBWLB/agent-hub/issues/248),
|
|
78
|
+
[#258](https://github.com/STAIxBWLB/agent-hub/issues/258)).
|
|
79
|
+
|
|
80
|
+
Live checks that still need a real account or a person are listed in the
|
|
81
|
+
[release verification report](docs/verification/2026-10-23-0.13.0.md) and the
|
|
82
|
+
[smoke checklist](docs/smoke.md).
|
|
118
83
|
|
|
119
84
|
## Documentation
|
|
120
85
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
86
|
+
| Read | For |
|
|
87
|
+
| --- | --- |
|
|
88
|
+
| [Quickstart](docs/quickstart.md) | install, the first session, a working day, upgrade notes |
|
|
89
|
+
| [Operations guide](docs/operations.md) | console, task flow, Pi and models, dashboard, projects, upgrade and recovery |
|
|
90
|
+
| [Hub memory](docs/memory.md) | how memory is stored, shared and recalled |
|
|
91
|
+
| [Security notes](docs/security.md) | what the hub defends and what it does not |
|
|
92
|
+
| [Design spec](docs/specs/2026-09-19-agent-hub-design.md) | how it is built and why |
|
|
93
|
+
| [Smoke checklist](docs/smoke.md) | what has been verified against real agents |
|
|
94
|
+
| [Changelog](CHANGELOG.md), [Contributing](CONTRIBUTING.md) | releases and how to contribute |
|
|
128
95
|
|
|
129
|
-
`AGENTS.md`
|
|
130
|
-
|
|
96
|
+
Coding agents that work on this repository follow [`AGENTS.md`](AGENTS.md) and
|
|
97
|
+
[`docs/agent-notes/`](docs/agent-notes/).
|
|
131
98
|
|
|
132
99
|
## Origin
|
|
133
100
|
|
|
134
101
|
The first idea came from [agent-bridge](https://github.com/raysonmeng/agent-bridge),
|
|
135
|
-
which lets Claude Code and Codex talk to each other. agent-hub has since grown
|
|
136
|
-
|
|
102
|
+
which lets Claude Code and Codex talk to each other. agent-hub has since grown into a
|
|
103
|
+
different system with its own goals and shares no code with it.
|
|
137
104
|
|
|
138
105
|
## License
|
|
139
106
|
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -17,3 +17,32 @@ Unless required by applicable law or agreed to in writing, software distributed
|
|
|
17
17
|
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
18
18
|
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
19
19
|
specific language governing permissions and limitations under the License.
|
|
20
|
+
|
|
21
|
+
## Tabler Icons
|
|
22
|
+
|
|
23
|
+
The inline icon sprite in `src/ui/index.html` (the dashboard's navigation, help, close, star, arrow and checking icons) contains the SVG
|
|
24
|
+
path data of twelve icons from Tabler Icons (outline set, 24x24, stroke 2), copied unchanged from https://github.com/tabler/tabler-icons:
|
|
25
|
+
`layout-kanban`, `building-store`, `activity`, `users`, `message`, `brain`, `settings`, `help`, `x`, `star`, `arrow-right` and
|
|
26
|
+
`refresh`. No Tabler package is installed or bundled.
|
|
27
|
+
|
|
28
|
+
MIT License
|
|
29
|
+
|
|
30
|
+
Copyright (c) 2020-2026 Paweł Kuna
|
|
31
|
+
|
|
32
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
33
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
34
|
+
in the Software without restriction, including without limitation the rights
|
|
35
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
36
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
37
|
+
furnished to do so, subject to the following conditions:
|
|
38
|
+
|
|
39
|
+
The above copyright notice and this permission notice shall be included in all
|
|
40
|
+
copies or substantial portions of the Software.
|
|
41
|
+
|
|
42
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
43
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
44
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
45
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
46
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
47
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
48
|
+
SOFTWARE.
|
|
@@ -10,7 +10,7 @@ Under **Adapter API 1** (issue #451), every tool is integrated as an `AdapterDef
|
|
|
10
10
|
|
|
11
11
|
1. **One Definition per Kind**: Each tool is identified by a unique `kind` (e.g., `codex`, `kimi`, `agy`, `claude`, `jcode`, `pi`, `local`, `qwen`). Its capabilities, transport, launch argv, permission mappings, and recovery contracts are encapsulated in an `AdapterDefinition`.
|
|
12
12
|
2. **Core Independence**: Core daemon logic (`src/hub/daemon.ts`), task management (`src/hub/tasks.ts`), and routing (`src/hub/routing.ts`) inspect definition fields (such as `transport`, `identity`, `attach`, `budget`), never raw vendor names.
|
|
13
|
-
3. **Strict Conformance**: Every builtin adapter must run the conformance test kit (`test/conformance/`). Unsupported legs must provide explicit, documented reasons rather than silent test skips. (
|
|
13
|
+
3. **Strict Conformance**: Every builtin adapter must run the conformance test kit (`test/conformance/`). Unsupported legs must provide explicit, documented reasons rather than silent test skips. (A4 exports the same callable contracts for external package CI.)
|
|
14
14
|
4. **Trust & Security Boundaries**:
|
|
15
15
|
- **On-prem vs. Cloud**: `trust.onPrem` controls whether private/PII tasks may be routed to the agent. A cloud agent (`trust.onPrem: false`) never receives PII task text or memory entries.
|
|
16
16
|
- **Path Protection**: Any workspace configuration directory owned by the agent (e.g., `.agents/`, `.codex/`) must be listed in `AGENT_CONFIG_SEGMENTS` (`src/hub/permission-mode.ts`) so agents cannot self-modify their own hooks or plugins.
|
|
@@ -24,7 +24,7 @@ agent-hub supports five transport architectures (`transport` in `AdapterDefiniti
|
|
|
24
24
|
|
|
25
25
|
| Transport | Description | Best Suited For | Examples |
|
|
26
26
|
| :--- | :--- | :--- | :--- |
|
|
27
|
-
| **`acp`** | Agent Client Protocol over stdio JSON-RPC | Agents implementing the standard ACP specification | Kimi, Qwen |
|
|
27
|
+
| **`acp`** | Agent Client Protocol over stdio JSON-RPC | Agents implementing the standard ACP specification | Kimi, Qwen, Jcode |
|
|
28
28
|
| **`codex-appserver`** | Bidirectional JSON-RPC with proxy intercept and thread tracking | Tools with structured thread resume and proxy-injectable RPC | Codex |
|
|
29
29
|
| **`claude-channel`** | MCP plugin running inside the host agent with WebSocket control link | Agents with native plugin systems that push notifications | Claude Code |
|
|
30
30
|
| **`ws-pull`** | Workspace MCP plugin connecting to daemon WebSocket; pull-only message inbox | Agents with local plugin discovery and interactive TUIs | Google Antigravity (`agy`) |
|
|
@@ -65,9 +65,11 @@ Defines how the hub MCP server identity reaches the tool:
|
|
|
65
65
|
|
|
66
66
|
#### `permission`
|
|
67
67
|
Maps hub permission modes (`ask`, `ask-when-needed`, `never-ask`) to native flags or ACP mode IDs:
|
|
68
|
-
* `grants`:
|
|
69
|
-
* `
|
|
70
|
-
* `
|
|
68
|
+
* `grants`: the text that says what each hub mode does for this kind (`ahub permission` and the settings preview show it). It is a description, not the native flag: the native mode id or policy is applied by the adapter (an ACP mode id, Codex's `approvalPolicy`).
|
|
69
|
+
* `genericAcp`: for a configured ACP kind, the validated `modes` (hub mode to ACP mode id) and `readOnly` id that the runtime and the instance ceiling both read.
|
|
70
|
+
* `unmanaged`, `unmanagedNote`, `unmanagedStatusNote`: why the hub cannot manage native permissions, when it cannot.
|
|
71
|
+
* `unmanagedForms`: start forms where permissions remain unmanaged (e.g. `["tui"]`).
|
|
72
|
+
* `trackUnattended`: the daemon records whether a start was `--unattended` and refuses a second start with a different setting while one is in progress (Codex).
|
|
71
73
|
|
|
72
74
|
#### `session`
|
|
73
75
|
Controls session restoration, thread continuity, and crash recovery:
|
|
@@ -76,6 +78,18 @@ Controls session restoration, thread continuity, and crash recovery:
|
|
|
76
78
|
* `resumeArgv(binding, fresh)`: Builds CLI arguments to resume a persisted session.
|
|
77
79
|
* `transcriptPath(binding)`: Resolves local transcript file path for audit/usage tracking.
|
|
78
80
|
|
|
81
|
+
#### `projection`
|
|
82
|
+
Where the kind sits in the host's derived lists: `roleRank`, `startRank`, `helpRank` and `plannerEligible`. `KNOWN_PEERS`, `OPTIONAL_PEERS`, `START_MODE_PEERS`, `ROLE_ORDER`, `HELP_ORDER` and `PLANNER_PEERS` are derived from `ADAPTERS` and these ranks (`deriveAdapterLists`). The only hand-kept lists are the cross-release copies in `src/hub/peer-catalog.ts` (`KNOWN_PEERS`, `OPTIONAL_PEERS`) and `src/hub/start-mode.ts` (`START_MODE_PEERS`, for a dual-form kind): a new native kind is added there too, and `test/registry-guard.test.ts` fails until those copies equal the derived lists. A configured or external definition cannot set `projection`.
|
|
83
|
+
|
|
84
|
+
#### `cli`
|
|
85
|
+
The `ahub <kind>` surface: `command`, `startWords(form)`, and for a fixed builtin `entry` (the launcher and whether it needs lifecycle admission), `preview`, `usage` (help lines) and `launchConfigKeys`. `builtinCliEntries(definitions)` projects the entries; no configuration or module can register one.
|
|
86
|
+
|
|
87
|
+
#### `instances` and `attach`
|
|
88
|
+
`instances.mode` is `headless` (needs a headless `start.create` factory) or `external` (a channel instance started from the person's terminal). A kind with no `instances` policy (Jcode) takes no extra instance, and `validateInstances` refuses a declaration of one. `attach` holds the pull-only forms, external-hello admission and the refusal texts for a TUI that attaches without a driven peer.
|
|
89
|
+
|
|
90
|
+
#### Peer capability members
|
|
91
|
+
The runtime peer (`PeerAdapter`, `src/hub/peers.ts`) exposes optional members that the daemon reads instead of checking its class (#625 phase 6): `sessionGeneration` (native session identity: absent keeps the owner-token fallback, present but undefined is unknown and refuses bounded checks), `checkpointUsesSessionGeneration` (opt out of generation-fenced checkpoints, as Pi does), `permissionModeState` (the effective native approval state, or `unknown` / `unmanaged`) and `setPermissionMode(mode)` (resolves only after the native side acknowledges). Native safety proofs (Codex proxy and restoration, Claude launch generation) stay in the daemon.
|
|
92
|
+
|
|
79
93
|
#### `budget`
|
|
80
94
|
Defines quota and context window consumption readers:
|
|
81
95
|
* `account`: Account identifier for quota grouping.
|
|
@@ -94,20 +108,94 @@ Grok declarations require explicit `--no-leader`, since native defaults can inhe
|
|
|
94
108
|
|
|
95
109
|
---
|
|
96
110
|
|
|
97
|
-
## 5.
|
|
111
|
+
## 5. External Adapter Modules (#451 A4)
|
|
112
|
+
|
|
113
|
+
A person can authorize a bundled adapter in an untracked
|
|
114
|
+
`.agenthub/config.local.json`:
|
|
115
|
+
|
|
116
|
+
```json
|
|
117
|
+
{
|
|
118
|
+
"adapter_modules": [
|
|
119
|
+
{ "path": ".agenthub/adapters/my-tool.mjs", "sha256": "<64 hex digits from the exact bundle>" }
|
|
120
|
+
]
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
The daemon imports the module at startup. Settings, reload, previews and ordinary
|
|
125
|
+
CLI reads never import it. A changed declaration requires restart; it cannot be
|
|
126
|
+
written through a hub tool or Settings. The CLI sees only the running daemon's
|
|
127
|
+
bounded kind and display name. Tracked/shared/cloned configuration cannot enable
|
|
128
|
+
code. A wrong hash, API mismatch, builtin collision, symlink component, path
|
|
129
|
+
outside the project, nonregular/world-writable file, oversized file or unsupported
|
|
130
|
+
module construct refuses loading without exposing source text in the error.
|
|
131
|
+
|
|
132
|
+
Publish a single self-contained ESM JavaScript bundle. Bundle third-party
|
|
133
|
+
implementation into that file; do not add runtime dependencies to the hub.
|
|
134
|
+
Runtime imports may use Node/Bun builtins except `bun:ffi` and `bun:test`, plus
|
|
135
|
+
`@staix/agent-hub/adapter`, bound to the running daemon's own SDK rather than
|
|
136
|
+
project packages. `/conformance` is available to module CI, not runtime modules.
|
|
137
|
+
Relative or other package imports, dynamic imports, require (including
|
|
138
|
+
`import.meta.require`), eval and Function-based loading
|
|
139
|
+
are refused. The scanner also refuses any `require`, `eval` or `Function` word token, including non-loading uses such as `o.require` or `instanceof Function`. String literal contents are not word tokens. The scan is conservative, not a sandbox. Authorized module code runs
|
|
140
|
+
with daemon privileges; inspect the full bundle before recording its hash. Each import must settle within two seconds or that module is refused while startup continues. This deadline stops waiting; it does not cancel module code or undo its side effects.
|
|
141
|
+
Dependencies must be ESM-only. The loader verifies the captured original bytes,
|
|
142
|
+
rewrites only scanned SDK imports to host-owned file URLs, and imports that result
|
|
143
|
+
rather than reopening a mutable source path after the hash check. A refused
|
|
144
|
+
module appears in bounded status diagnostics while other adapters keep working.
|
|
145
|
+
Its roster row stays inert; CLI config reads also retain inert unknown rows when
|
|
146
|
+
trusted module declarations exist but daemon metadata is unavailable.
|
|
147
|
+
|
|
148
|
+
The module exports `definition` with `api: ADAPTER_API`. Import the version,
|
|
149
|
+
`AcpPeer`, `BasePeer` and definition/context types from
|
|
150
|
+
`@staix/agent-hub/adapter`. The initial executable subset uses a headless ACP
|
|
151
|
+
factory, its own kind/family, `optional: true`, `defaultOnRoster: false` and
|
|
152
|
+
`trust: { onPrem: false, hubSandboxed: false }`. Preserve the host's factory
|
|
153
|
+
options and instance id when constructing the transport. Supply a launch plan,
|
|
154
|
+
start/identity/session/CLI/display metadata and only supported native mode
|
|
155
|
+
mappings; no mapping means unmanaged. By default the host disables native
|
|
156
|
+
hub-tool title auto-approval for external kinds. A cooperating module must preserve
|
|
157
|
+
that factory option; approved module code runs with daemon privileges, so this is
|
|
158
|
+
a host default rather than isolation from a module that overrides its options. The loader refuses fixed-builtin capabilities and unsupported
|
|
159
|
+
fields rather than silently ignoring them. See `validateExternalDefinition` for
|
|
160
|
+
the exact accepted subset.
|
|
161
|
+
|
|
162
|
+
External kind instances are explicitly unsupported in A4. Follow-up board task
|
|
163
|
+
#287 owns execution roots, CLI identity and recovery for them. Broadening the
|
|
164
|
+
module transport beyond the existing headless ACP host port also needs a reviewed
|
|
165
|
+
host contract (#625 phase 6); selecting a different native engine is not a generic extension.
|
|
166
|
+
|
|
167
|
+
For example, bundle an ESM definition with its dependencies and record its digest:
|
|
98
168
|
|
|
99
|
-
|
|
169
|
+
```bash
|
|
170
|
+
bun build ./adapter.ts --target bun --format esm --external @staix/agent-hub/adapter --outfile .agenthub/adapters/my-tool.mjs
|
|
171
|
+
shasum -a 256 .agenthub/adapters/my-tool.mjs
|
|
172
|
+
```
|
|
100
173
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
* **Conformance Requirement**: External modules must pass the conformance kit before admission.
|
|
174
|
+
Enable its roster row only after loading it and exercising the applicable
|
|
175
|
+
conformance contracts. Source and target recovery runtimes must advertise
|
|
176
|
+
`external_adapter_modules`; old runtimes cannot preserve the verified catalog.
|
|
105
177
|
|
|
106
178
|
---
|
|
107
179
|
|
|
108
180
|
## 6. The Conformance Kit
|
|
109
181
|
|
|
110
|
-
The
|
|
182
|
+
The exported Bun kit (`@staix/agent-hub/conformance`) supplies callable transport
|
|
183
|
+
registrations, `createFromDefinition`, `registerConformance`, explicit unsupported
|
|
184
|
+
leg validation and immutable `fakePaths`. Importing it starts no fake transport;
|
|
185
|
+
call a registration in your own Bun test file. The hub's `test/conformance/`
|
|
186
|
+
wrappers run the same implementation against every applicable builtin.
|
|
187
|
+
|
|
188
|
+
An external adapter test imports its definition and calls
|
|
189
|
+
`registerConformance` with its real factory and a fake transport fixture. ACP
|
|
190
|
+
adapters also call `registerAcpConformance({ definition, ... })`; unsupported native
|
|
191
|
+
approval, mode or quota legs require concrete reasons, never silent skips. Other
|
|
192
|
+
exports cover Codex, owned ACP, Pi, local and external-channel fixture contracts.
|
|
193
|
+
Those exports do not grant an external runtime access to a builtin-only engine.
|
|
194
|
+
The shipped fake assets live under `src/adapters/conformance/fakes`, so package CI needs
|
|
195
|
+
no development-tree files. Native account/TUI probes remain separate from these
|
|
196
|
+
synthetic protocol contracts.
|
|
197
|
+
|
|
198
|
+
The kit validates that an adapter satisfies hub invariants:
|
|
111
199
|
|
|
112
200
|
```bash
|
|
113
201
|
# Run the complete conformance suite
|
|
@@ -120,7 +208,7 @@ bun test test/conformance/agy.test.ts
|
|
|
120
208
|
|
|
121
209
|
### Invariants Verified by the Kit:
|
|
122
210
|
1. **Enrollment & Coherence (`enrollment.test.ts`)**: Every definition in `ADAPTERS` and reviewer variant must be enrolled. A kind without kit coverage needs a reason in `UNSUPPORTED` (`test/conformance/enrollment.ts`), and an ACP kind that skips one of the shared `ACP_LEGS` needs a reason per leg in `UNSUPPORTED_LEGS`.
|
|
123
|
-
2. **Delivery Occupancy**: Sending messages updates driven peer state to `busy` synchronously, delivering digests reliably.
|
|
211
|
+
2. **Delivery Occupancy**: Sending messages updates driven peer state to `busy` synchronously, delivering digests reliably. A channel peer whose native hooks own occupancy (Claude) stays idle on insertion by design.
|
|
124
212
|
3. **Recovery Metadata Hygiene**: No prompt text or credentials leaked into `recoveryMetadata`.
|
|
125
213
|
4. **Watchdog Cancellation & Generation Fencing**: Expiry of the turn watchdog cancels prompts cleanly and generation fences prevent stale late answers from publishing.
|
|
126
214
|
5. **Teardown & Cleanup**: When an adapter is stopped (`peer.stop()`), all owned child processes in the process group stop with it (the peer reaches offline).
|
|
@@ -132,7 +220,7 @@ bun test test/conformance/agy.test.ts
|
|
|
132
220
|
When adding or updating an adapter, verify each item before opening a PR:
|
|
133
221
|
|
|
134
222
|
- [ ] **T0 Receipt Recorded**: Document native CLI version, observed hook payloads, and protocol outputs in `docs/verification/YYYY-MM-DD-<kind>-t0.md`.
|
|
135
|
-
- [ ] **Registered in ADAPTERS**:
|
|
223
|
+
- [ ] **Registered in ADAPTERS**: the definition is declared under `src/adapters/definitions/` (or its own directory) with explicit `displayName`, `family`, `transport`, `trust` and `projection`, and listed in `ADAPTERS` (`src/adapters/registry.ts`). The peer lists are derived from it. The hand-kept cross-release copies in `src/hub/peer-catalog.ts` and `src/hub/start-mode.ts` and the pinned tests listed in `docs/agent-notes/adapters.md` change with it, and the PR names them as expected test changes.
|
|
136
224
|
- [ ] **Config Path Protection**: Agent configuration directories added to `AGENT_CONFIG_SEGMENTS` in `src/hub/permission-mode.ts`.
|
|
137
225
|
- [ ] **PII Safety Verified**: Cloud models have `trust.onPrem: false`; verify PII markers refuse routing to this peer.
|
|
138
226
|
- [ ] **Process Group Teardown**: Daemon-spawned processes use process groups and exit cleanly on stop.
|
|
@@ -20,3 +20,18 @@ The #451 predicate and identity-lookup moves exposed unbound names in a VM fixtu
|
|
|
20
20
|
that extracts daemon closures. Reconnecting imported helpers and deterministic
|
|
21
21
|
identity ports preserved the fixture's existing assertions; changing the asserted
|
|
22
22
|
behavior would have hidden the missing dependency.
|
|
23
|
+
|
|
24
|
+
Background moved out of the area notes for 0.12.45:
|
|
25
|
+
|
|
26
|
+
- Instance execution git budget (#225, daemon.md): `resolveInstanceExecutionCwd` runs synchronously on the daemon's event loop (an extra-instance start, `turn_revert`) with up to four git calls, measured at about 15 ms on a warm local repository. One shared 5 s allowance holds the loop at most 5 s, not 4 x 5 s. It stays synchronous because the CLI and recovery callers are; an async twin for the two daemon call sites is the upgrade if a typical resolution ever costs more than a few ms.
|
|
27
|
+
- Claude steer version gate (#493, #221, daemon.md): mid-turn consumption of a steered important message was proven only on Claude Code 2.1.302 (`docs/verification/2026-10-18-493-claude-busy-channel.md`); on an older client a dropped mid-turn notification stays `accepted` until a person resolves it. The hello does not carry the client version, and the oldest working version is unknown, so a gate would be a guess that could disable a working path.
|
|
28
|
+
- Planner reservation and done gates (tasks.md): in #378 a same-value planner write laundered a person's reservation; in #382 advise recorded overlapping dones, and an owner could neither relink a PR nor be stopped from carrying a head to a new PR.
|
|
29
|
+
- Process-tree stops (adapters.md): three review rounds of #113 found snapshot gaps while the tree ran (groups of its own, an unreadable first read, a child started during the grace period).
|
|
30
|
+
- Local worker (local-worker.md): a bare `private/` deny entry once denied all of `/private/var`; `existsSync` made a dangling link look like a new file, so a write landed at its target.
|
|
31
|
+
- Suite watchdog (tests.md): macOS CI hit `AHUB_CHECK_HANG_S` while tests still passed (#378, #593).
|
|
32
|
+
|
|
33
|
+
Background moved out of the area notes for 0.13.0:
|
|
34
|
+
|
|
35
|
+
- Jcode MCP entry (#685, adapters.md): jcode gives an MCP entry's own env precedence over the process env (probed on 0.99.0), so a peer id in the shared `.jcode/mcp.json` entry would make every extra instance act as `jcode`.
|
|
36
|
+
- Bulk queue discard (#713, bus.md): a queued row with no journal record of its own carries the journal's global revision, which every discard moves, so a revision read once at the start goes stale after the first discard.
|
|
37
|
+
- Usage roll-up (#683 U2, budget.md): a pass cap smaller than one log line once hung the fold.
|