@staix/agent-hub 0.12.22 → 0.12.24

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.
Files changed (183) hide show
  1. package/CHANGELOG.md +117 -0
  2. package/README.md +22 -9
  3. package/docs/addons/claude-mem.md +24 -0
  4. package/docs/addons/codex-plugin.md +8 -0
  5. package/docs/addons/dot-admit.md +8 -0
  6. package/docs/addons/open-code-review.md +8 -0
  7. package/docs/addons/ponytail.md +23 -0
  8. package/docs/addons/ripwire.md +22 -0
  9. package/docs/agent-notes/README.md +5 -0
  10. package/docs/agent-notes/adapters.md +18 -6
  11. package/docs/agent-notes/benchmarks.md +3 -0
  12. package/docs/agent-notes/budget.md +4 -0
  13. package/docs/agent-notes/bus.md +3 -1
  14. package/docs/agent-notes/daemon.md +14 -1
  15. package/docs/agent-notes/local-worker.md +6 -3
  16. package/docs/agent-notes/tasks.md +6 -1
  17. package/docs/agent-notes/tests.md +4 -1
  18. package/docs/bench.md +28 -3
  19. package/docs/cooperbench.md +4 -0
  20. package/docs/data-policy.md +36 -0
  21. package/docs/events.md +10 -3
  22. package/docs/gsd-collaboration-analysis.md +48 -0
  23. package/docs/memory.md +231 -0
  24. package/docs/operations.md +873 -30
  25. package/docs/plans/2026-10-11-issues-109-sequential.md +81 -0
  26. package/docs/plans/2026-10-11-routing-evaluation-proposal.md +30 -0
  27. package/docs/profiles.md +57 -0
  28. package/docs/quickstart.md +9 -4
  29. package/docs/research.md +31 -1
  30. package/docs/roles.md +85 -0
  31. package/docs/sdlc.md +170 -0
  32. package/docs/security.md +124 -8
  33. package/docs/smoke.md +354 -5
  34. package/docs/specs/2026-09-19-agent-hub-design.md +676 -15
  35. package/docs/specs/2026-10-12-backlog-implementation-plan.md +186 -0
  36. package/docs/specs/2026-10-12-office-view-design.md +212 -0
  37. package/docs/text-projection.md +19 -0
  38. package/docs/verification/2026-10-10-cli-output-phase1.md +309 -0
  39. package/docs/verification/2026-10-10-cli-output-phase2.md +672 -0
  40. package/docs/verification/2026-10-11-0.12.23.md +90 -0
  41. package/docs/verification/2026-10-11-acp-watch-t0.md +33 -0
  42. package/docs/verification/2026-10-11-agent-config-inventory.md +20 -0
  43. package/docs/verification/2026-10-11-jcode-peer-contract.md +27 -0
  44. package/docs/verification/2026-10-13-0.12.24.md +94 -0
  45. package/docs/verification/2026-10-13-board-phone.md +31 -0
  46. package/docs/verification/2026-10-13-fsmonitor-fixture-attribution.md +19 -0
  47. package/docs/verified.json +34 -16
  48. package/package.json +2 -1
  49. package/plugins/agent-hub/.claude-plugin/plugin.json +1 -1
  50. package/plugins/agent-hub/ROLE-NOTICE.md +26 -0
  51. package/plugins/agent-hub/server.js +1108 -261
  52. package/scripts/check-docs.mjs +129 -0
  53. package/src/adapters/acp-quota.ts +13 -0
  54. package/src/adapters/acp.ts +201 -20
  55. package/src/adapters/claude-channel.ts +48 -11
  56. package/src/adapters/codex-appserver.ts +54 -13
  57. package/src/adapters/jcode.ts +110 -0
  58. package/src/adapters/local-worker.ts +10 -7
  59. package/src/adapters/pi.ts +94 -20
  60. package/src/cli/attention.ts +60 -0
  61. package/src/cli/bench.ts +26 -6
  62. package/src/cli/board-read.ts +12 -0
  63. package/src/cli/console-state.ts +131 -39
  64. package/src/cli/console.ts +73 -17
  65. package/src/cli/facts-hook.ts +12 -4
  66. package/src/cli/help.ts +52 -21
  67. package/src/cli/identity.ts +19 -8
  68. package/src/cli/init.ts +48 -10
  69. package/src/cli/jcode-mcp.ts +58 -0
  70. package/src/cli/kimi-mcp.ts +53 -0
  71. package/src/cli/launch.ts +16 -1
  72. package/src/cli/main.ts +641 -193
  73. package/src/cli/memory.ts +193 -0
  74. package/src/cli/output.ts +404 -0
  75. package/src/cli/pet-config.ts +1 -0
  76. package/src/cli/pet.ts +83 -0
  77. package/src/cli/preview.ts +40 -6
  78. package/src/cli/reset.ts +3 -0
  79. package/src/cli/status-lines.ts +1 -29
  80. package/src/cli/tail-render.ts +1 -0
  81. package/src/cli/terminal-recovery.ts +27 -1
  82. package/src/cli/upgrade-runtime.ts +56 -10
  83. package/src/cli/upgrade.ts +23 -5
  84. package/src/cli/watch.ts +31 -0
  85. package/src/hub/activity.ts +53 -0
  86. package/src/hub/ask.ts +10 -5
  87. package/src/hub/bench.ts +10 -3
  88. package/src/hub/board.ts +224 -16
  89. package/src/hub/budget.ts +39 -7
  90. package/src/hub/bus.ts +58 -20
  91. package/src/hub/child-process.ts +11 -0
  92. package/src/hub/citations.ts +7 -0
  93. package/src/hub/conductor.ts +34 -17
  94. package/src/hub/config-trust.ts +20 -7
  95. package/src/hub/conflicts.ts +2 -0
  96. package/src/hub/context-window.ts +8 -1
  97. package/src/hub/crash.ts +11 -1
  98. package/src/hub/daemon.ts +1218 -113
  99. package/src/hub/db-timeout.ts +3 -0
  100. package/src/hub/delivery-journal.ts +7 -1
  101. package/src/hub/envelope.ts +1 -1
  102. package/src/hub/events.ts +14 -2
  103. package/src/hub/execution-budget.ts +2 -0
  104. package/src/hub/facts.ts +28 -8
  105. package/src/hub/git.ts +38 -0
  106. package/src/hub/github-import.ts +28 -0
  107. package/src/hub/hub-tools.ts +49 -10
  108. package/src/hub/inference.ts +1 -1
  109. package/src/hub/lifecycle-schema.ts +17 -0
  110. package/src/hub/lifecycle.ts +10 -4
  111. package/src/hub/listen.ts +15 -0
  112. package/src/hub/manager.ts +26 -6
  113. package/src/hub/path-policy.ts +96 -0
  114. package/src/hub/peer-catalog.ts +28 -0
  115. package/src/hub/peers.ts +5 -3
  116. package/src/hub/permission-mode.ts +33 -5
  117. package/src/hub/planning.ts +70 -0
  118. package/src/hub/profiles.ts +74 -0
  119. package/src/hub/project.ts +2 -1
  120. package/src/hub/projected-diff.ts +73 -0
  121. package/src/hub/projection-exec.ts +24 -0
  122. package/src/hub/recovery-error.ts +31 -0
  123. package/src/hub/recovery-store.ts +6 -5
  124. package/src/hub/registry.ts +2 -1
  125. package/src/hub/research.ts +144 -21
  126. package/src/hub/roles.ts +123 -0
  127. package/src/hub/roster.ts +23 -0
  128. package/src/hub/routing.ts +132 -18
  129. package/src/hub/sdlc-queue.ts +112 -0
  130. package/src/hub/sdlc-release.ts +125 -0
  131. package/src/hub/sdlc.ts +250 -0
  132. package/src/hub/settings.ts +411 -0
  133. package/src/hub/shipped-roles.ts +25 -0
  134. package/src/hub/snapshots.ts +92 -16
  135. package/src/hub/start-mode.ts +50 -0
  136. package/src/hub/supervision.ts +1 -0
  137. package/src/hub/task-sweep.ts +1 -1
  138. package/src/hub/tasks.ts +1014 -111
  139. package/src/hub/terminal-open.ts +64 -0
  140. package/src/hub/text-projection.ts +126 -0
  141. package/src/hub/tooling.ts +159 -0
  142. package/src/hub/ui.ts +40 -14
  143. package/src/hub/workflow.ts +71 -0
  144. package/src/local/deny.ts +29 -7
  145. package/src/local/sandbox.ts +50 -10
  146. package/src/local/tools.ts +11 -6
  147. package/src/memory/brief.ts +28 -14
  148. package/src/memory/import.ts +55 -0
  149. package/src/memory/recall.ts +86 -2
  150. package/src/memory/store.ts +750 -0
  151. package/src/memory/sync.ts +145 -0
  152. package/src/models/mlx.ts +2 -1
  153. package/src/pet/NOTICE.md +10 -0
  154. package/src/pet/characters.ts +1438 -0
  155. package/src/pet/config.ts +31 -0
  156. package/src/pet/frame.ts +17 -0
  157. package/src/pet/pixels.ts +28 -0
  158. package/src/pi/tool-receipts.ts +2 -1
  159. package/src/role-text.d.ts +1 -0
  160. package/src/ui/index.html +983 -40
  161. package/src/ui/needs.ts +58 -0
  162. package/src/ui/office-model.ts +440 -0
  163. package/src/ui/peer-palette.ts +16 -0
  164. package/src/ui/task-board.ts +49 -0
  165. package/src/ui/task-progress.ts +5 -1
  166. package/templates/AGENTS.block.md +3 -2
  167. package/templates/config.json +5 -1
  168. package/templates/profiles/dev.json +22 -0
  169. package/templates/profiles/general.json +26 -0
  170. package/templates/profiles/research.json +57 -0
  171. package/templates/profiles/writing.json +28 -0
  172. package/templates/roles/NOTICE.md +26 -0
  173. package/templates/roles/dev/backend-engineer.md +26 -0
  174. package/templates/roles/dev/code-reviewer.md +26 -0
  175. package/templates/roles/dev/frontend-engineer.md +26 -0
  176. package/templates/roles/dev/security-reviewer.md +26 -0
  177. package/templates/roles/dev/software-architect.md +26 -0
  178. package/templates/roles/dev/test-engineer.md +26 -0
  179. package/templates/roles/research/analyst.md +26 -0
  180. package/templates/roles/research/fact-checker.md +26 -0
  181. package/templates/roles/research/research-lead.md +26 -0
  182. package/templates/roles/research/researcher.md +26 -0
  183. package/templates/roles/research/statistician.md +26 -0
@@ -0,0 +1,31 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { characterId, type CharacterId, type PetSize, type PetGlyphs } from "./frame.ts";
4
+
5
+ export interface PetConfig { enabled: boolean; blink: boolean; bell: boolean; character?: CharacterId; size?: PetSize; glyphs?: PetGlyphs; notice?: string }
6
+ /** Console-local presentation only; this reader never writes config or grants authority. */
7
+ export function loadPetConfig(cwd: string): PetConfig {
8
+ let value: unknown;
9
+ for (const name of ["config.json", "config.local.json"]) {
10
+ try {
11
+ const file = JSON.parse(readFileSync(join(cwd, ".agenthub", name), "utf8"));
12
+ if (file.pet !== undefined) value = value && typeof value === "object" && file.pet && typeof file.pet === "object" ? { ...value, ...file.pet } : file.pet;
13
+ } catch (error) {
14
+ if ((error as NodeJS.ErrnoException).code !== "ENOENT") throw error;
15
+ }
16
+ }
17
+ if (value === false) return { enabled: false, blink: true, bell: false };
18
+ const defaults = { enabled: true, blink: true, bell: false };
19
+ if (value === undefined) return defaults;
20
+ if (!value || typeof value !== "object" || Array.isArray(value)) return { ...defaults, notice: "Unknown pet configuration; using stai line defaults." };
21
+ const row = value as Record<string, unknown>;
22
+ const invalid = Object.keys(row).some(key => !["character", "size", "glyphs", "blink", "bell"].includes(key)) ||
23
+ row.character !== undefined && !characterId(row.character) || row.size !== undefined && !["line", "mini", "full"].includes(row.size as string) ||
24
+ row.glyphs !== undefined && (typeof row.glyphs !== "string" || !["auto", "ascii", "blocks"].includes(row.glyphs)) ||
25
+ row.blink !== undefined && typeof row.blink !== "boolean" || row.bell !== undefined && typeof row.bell !== "boolean";
26
+ return { enabled: true, blink: typeof row.blink === "boolean" ? row.blink : true, bell: typeof row.bell === "boolean" ? row.bell : false,
27
+ ...(characterId(row.character) && row.character !== "stai" ? { character: row.character } : {}),
28
+ ...(row.size === "mini" || row.size === "full" ? { size: row.size } : {}),
29
+ ...(row.glyphs === "ascii" || row.glyphs === "blocks" ? { glyphs: row.glyphs } : {}),
30
+ ...(invalid ? { notice: "Unknown pet option; using stai line defaults for that option." } : {}) };
31
+ }
@@ -0,0 +1,17 @@
1
+ import { CHARACTERS, CHARACTER_IDS, type CharacterId, type PetGlyphs, type PetPose, type PetSize } from "./characters.ts";
2
+ export { CHARACTERS, CHARACTER_IDS };
3
+ export type { CharacterId, PetGlyphs, PetPose, PetSize };
4
+ export function characterId(value: unknown): value is CharacterId { return typeof value === "string" && (CHARACTER_IDS as readonly string[]).includes(value); }
5
+ export function petSize(requested: PetSize = "line", columns: number, rows: number): PetSize {
6
+ if (requested === "full" && columns >= 100 && rows >= 40) return "full";
7
+ return requested !== "line" && columns >= 100 ? "mini" : "line";
8
+ }
9
+ export function petGlyphs(requested: PetGlyphs = "auto", env: Record<string, string | undefined> = process.env): "ascii" | "blocks" {
10
+ const locale = env.LC_ALL || env.LC_CTYPE || env.LANG || "";
11
+ return requested !== "ascii" && /utf-?8/i.test(locale) && !!env.TERM && !["dumb", "linux"].includes(env.TERM) ? "blocks" : "ascii";
12
+ }
13
+ export function petFrame(character: CharacterId = "stai", pose: PetPose, size: PetSize = "line", glyphs: "ascii" | "blocks" = "ascii"): readonly string[] {
14
+ return CHARACTERS[character].frames[glyphs][pose][size];
15
+ }
16
+ /** A full footer reserves the catalog maximum, independent of state and session character cycling. */
17
+ export function petFooterRows(size: PetSize): number { return size === "full" ? 9 : 4; }
@@ -0,0 +1,28 @@
1
+ /** Self-contained glyph pixels for the shared literal frame data; browser injection needs no font/image decoder. */
2
+ export function petPixels(frame: readonly string[]): { width: number; height: number; pixels: [number, number][] } {
3
+ const font: Record<string, string[]> = {
4
+ O:["01110","10001","10001","10001","10001","10001","01110"],
5
+ o:["00000","00000","01110","10001","10001","01110","00000"],
6
+ X:["10001","10001","01010","00100","01010","10001","10001"],
7
+ S:["01111","10000","10000","01110","00001","00001","11110"],
8
+ T:["11111","00100","00100","00100","00100","00100","00100"],
9
+ A:["01110","10001","10001","11111","10001","10001","10001"],
10
+ I:["11111","00100","00100","00100","00100","00100","11111"],
11
+ ">": ["10000","01000","00100","00010","00100","01000","10000"],
12
+ "<": ["00001","00010","00100","01000","00100","00010","00001"],
13
+ "^": ["00100","01010","10001"],
14
+ "~": ["00000","01001","10110"],
15
+ "/": ["00001","00001","00010","00100","01000","10000","10000"],
16
+ "\\": ["10000","10000","01000","00100","00010","00001","00001"],
17
+ "-": ["00000","00000","00000","11111"],
18
+ "'": ["00100","00100"],
19
+ };
20
+ const pixels: [number, number][] = [];
21
+ for (const [row, text] of frame.entries()) for (const [column, glyph] of [...text].entries()) {
22
+ for (let y=0;y<8;y++) for (let x=0;x<5;x++) {
23
+ const on = glyph === "█" || glyph === "▀" && y<4 || glyph === "▄" && y>=4 || glyph === "▟" && (y>=4 || x>=2) || glyph === "▙" && (y>=4 || x<3) || font[glyph]?.[y]?.[x] === "1";
24
+ if (on) pixels.push([column*5+x,row*8+y]);
25
+ }
26
+ }
27
+ return { width: Math.max(0,...frame.map(row=>[...row].length))*5, height: frame.length*8, pixels };
28
+ }
@@ -2,6 +2,7 @@ import { chmodSync } from "node:fs";
2
2
  import { Database } from "bun:sqlite";
3
3
  import { createHash } from "node:crypto";
4
4
  import { PreEffectToolRefusal } from "../hub/tool-refusal.ts";
5
+ import { HUB_DB_BUSY_TIMEOUT_MS } from "../hub/db-timeout.ts";
5
6
 
6
7
  export const PI_TOOL_RESULT_CAP = 100_000;
7
8
  /** Bound encoded text before wrapping it so escaping never cuts off trusted exit metadata. */
@@ -27,8 +28,8 @@ export class PiToolReceipts {
27
28
  private readonly pending = new Map<string, Promise<string>>();
28
29
  constructor(file: string) {
29
30
  this.db = new Database(file, { create: true });
31
+ this.db.run(`PRAGMA busy_timeout = ${HUB_DB_BUSY_TIMEOUT_MS}`);
30
32
  chmodSync(file, 0o600);
31
- this.db.run("PRAGMA busy_timeout = 5000");
32
33
  this.db.run(`CREATE TABLE IF NOT EXISTS pi_tool_receipts (
33
34
  session TEXT NOT NULL, call_id TEXT NOT NULL, fingerprint TEXT NOT NULL,
34
35
  state TEXT NOT NULL, result TEXT, PRIMARY KEY(session, call_id))`);
@@ -0,0 +1 @@
1
+ declare module "*.md" { const text: string; export default text; }