@staix/agent-hub 0.23.0 → 0.23.1

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.
@@ -0,0 +1,57 @@
1
+ # Qwen Code 0.26.4 ACP receipt
2
+
3
+ Date: 2026-10-31. Scope: issue #888, task 578, `qwen` row only. This repeats the [0.26.1 ACP receipt](2026-10-26-qwen-0261-acp.md) using a private npm prefix, isolated HOME and fixed synthetic configuration. No account, real credential, provider inference or ACP prompt was used. This receipt does not admit the separate `qwen-dual` contract.
4
+
5
+ ## Artifact and isolation
6
+
7
+ The published `@qwen-code/qwen-code@0.26.4` was installed under `scratchpad/temp/agent-hub-578/qwen-prefix`, with scratch HOME, cache, temporary directory and separate empty npm user/global config files. The person's global prefix and `~/.qwen` were not installation targets. npm's pending lifecycle script for the optional audio package was read and replayed under the same isolated environment; it completed. No install scripts were disabled to make the probe pass.
8
+
9
+ | Artifact | Binding |
10
+ | --- | --- |
11
+ | npm release | 0.26.4, `gitHead` and upstream `v0.26.4` tag `715a550cfca0135e00d4015d1ca82a8167e81fff` |
12
+ | npm integrity | `sha512-YeRiUaH3d+JxPiYUS4eGalsKRTuIEUo75JWPWdVBoptdbAH3FJdWbGtjs/syECEUTH5qk0nu8tRb1HMEKn0I2Q==` |
13
+ | `cli-entry.js` SHA-256 | `113efe4104a9fc66f507d34bfd6abbd896ceb77de47f4b468a0825a327fdc6a5` |
14
+ | `chunks/acpAgent-D7OFGHAI.js` SHA-256 | `67d040491bb04e33a2f91df3f142ba09a100333edb1e5f92ed0a84edb1c499b9` |
15
+ | Host | macOS arm64, Node 24.18.1 |
16
+
17
+ Every native process received a fresh ordinary OS temporary HOME/cwd, private QWEN_HOME/QWEN_RUNTIME_DIR/XDG_CONFIG_HOME, a synthetic API key and `--auth-type openai --model fixture-model --openai-base-url http://127.0.0.1:9/v1 --telemetry=false`. A Node preload denied application network APIs and recorded six blocked startup attempts; none connected through those guarded APIs. A separate reserved-address positive control proved the guard blocks. This is preload evidence, not a kernel network sandbox or a claim about arbitrary native subprocess sockets.
18
+
19
+ ## Native ACP, no prompts
20
+
21
+ `qwen --acp --bare --advisor off` initialized with protocol version 1 and `agentInfo` name `qwen-code`, title `Qwen Code`, version `0.26.4`. The only offered authentication method was the synthetic OpenAI terminal method. No prompt was sent.
22
+
23
+ `session/new` succeeded. Available modes were `plan`, `default`, `auto-edit`, `auto` and `yolo`, with current mode `default`. Each transition in `default -> auto-edit -> yolo -> default` returned an acknowledgement. Thus the hub's existing ask/default, ask-when-needed/auto-edit and never-ask/yolo map remains a subset of the native advertised ids; neither `plan` nor `auto` is newly mapped. The session exposed only the fixture model. Additional native mode-update notifications remain outside the hub's mapped protocol.
24
+
25
+ The native leader exited after its owned group received SIGTERM, and the producer confirmed `groupGone: true`. Six startup network attempts were blocked; the input contained zero model prompts.
26
+
27
+ ## Actual published permission handler
28
+
29
+ An exports-only scratch copy of the published ACP chunk was placed beside the original inside the private package, preserving its relative imports. The original chunk was not edited. The fixture invoked the actual `SubAgentTracker.createApprovalHandler` with synthetic client/tool/event ports, not a reimplementation or a model-generated tool turn.
30
+
31
+ - A request carried the fixture session, pending tool-call id, raw input, native MCP tool metadata and permission progress updates.
32
+ - The exact options were `proceed_always_project` and `proceed_always_user` as `allow_always`, `proceed_once` as `allow_once`, and `cancel` as `reject_once`.
33
+ - An offered allow-once response reached `event.respond` as `proceed_once`.
34
+ - A second actual callback with a cancelled outcome reached `event.respond` as `cancel`.
35
+ - The real outcome helper rejected an unoffered option. No permission-fixture network attempt was recorded.
36
+
37
+ ## Source review and boundary
38
+
39
+ The published npm `gitHead` matches upstream `v0.26.4`; `v0.26.1` remains `b475278c4a300acebe6cfc990a9e1b1d18819bfc`. Release notes for 0.26.2, 0.26.3 and 0.26.4 were read, together with the relevant source regions at both commits. This was a scoped contract review, not a review of every changed file.
40
+
41
+ - [`SubAgentTracker`](https://github.com/QwenLM/qwen-code/blob/715a550cfca0135e00d4015d1ca82a8167e81fff/packages/cli/src/acp-integration/session/SubAgentTracker.ts#L312) adds subagent identity to emitted progress metadata. The permission request construction and offered-outcome translation remain exercised by the native chunk fixture above.
42
+ - [`acpAgent`](https://github.com/QwenLM/qwen-code/blob/715a550cfca0135e00d4015d1ca82a8167e81fff/packages/cli/src/acp-integration/acpAgent.ts#L6979) still routes mode changes to the selected session. New workflow options, workspace controls and shared fresh-prompt execution are outside the mode ids the hub maps. The idle native mode acknowledgements above are observed; a fresh model prompt through the new chain is not claimed.
43
+ - `DualOutputBridge.ts` and `RemoteInputWatcher.ts` were byte-identical between these tags. That source fact is not native dual-output acceptance; its separate receipt owns that decision.
44
+
45
+ Every required ACP leg passed. Exactly 0.26.4 may join `COMPAT.qwen.verified`; no intermediate release, compatible range or dual-output version is inferred. A real model-generated permission turn, real login/provider, model behavior, Linux and Intel macOS remain unverified. Host changed-source checks and exact-head CI are separate PR evidence.
46
+
47
+ ## Evidence fingerprints
48
+
49
+ Producers and result JSONs remain outside git under `scratchpad/temp/agent-hub-578`.
50
+
51
+ | File | SHA-256 |
52
+ | --- | --- |
53
+ | `qwen-acp-probe.py` | `f36a03010af657f5cc453c4dbfa70ee03014a09d8bf144f6d8c5441de80ccea8` |
54
+ | `qwen-acp-result.json` | `b3a53e394f9234ba8e2c8744e2b892cbbdffe1eac28623d13815efaa7ab7a44d` |
55
+ | `qwen-permission.mjs` | `00d9b68f4a23f3efc84bf657f5c57cea476e36d0469e356b943abb8dcc417587` |
56
+ | `qwen-permission-result.json` | `958a77ea7618e0efd04a78520aadf83654e5b74a0158a05061d0bed4406d7c31` |
57
+ | `deny-network.cjs` | `361148af658dd4b65ed35308622ec99bb882ec5a25fab54581776546f139e892` |
@@ -0,0 +1,52 @@
1
+ # Qwen 0.26.4 dual-output attempt, not qualified
2
+
3
+ Date: 2026-10-31. Scope: issue #888, task 578, the separate `qwen-dual` row. The [ACP receipt](2026-10-31-qwen-0264-acp.md) does not qualify the TUI contract. This attempted the [earlier Q2-Q7 procedure](2026-10-25-qwen-dual-output-t0.md) using fixed OpenAI-compatible loopback responses, no real model, account or credential. Exactly 0.26.1 remains in `COMPAT["qwen-dual"].verified`; 0.26.4 is not admitted.
4
+
5
+ ## Artifact, scope and controls
6
+
7
+ The candidate is the private-prefix npm `@qwen-code/qwen-code@0.26.4`, upstream tag/gitHead `715a550cfca0135e00d4015d1ca82a8167e81fff`, Node 24.18.1 on macOS arm64. Artifact integrity and entry/chunk hashes are in the ACP receipt. The retained global 0.26.1 executable was used only as a read-only matched control, always with a fresh temporary HOME/cwd and the same producer/flags; no code was injected into that installation. Its `cli-entry.js` SHA-256 `113efe4104a9fc66f507d34bfd6abbd896ceb77de47f4b468a0825a327fdc6a5` matches the earlier receipt.
8
+
9
+ Each fixture used PTY 120x40, private input/event files, a scratch git project, synthetic OpenAI-compatible key/model, and a loopback server emitting fixed text/tool-use responses. Native shell and stdio-MCP effects were confined to synthetic marker files. Node builtin TCP/DNS/fetch/UDP guards allowed only loopback and fixture-local IPC. Positive controls passed, every launched native Node PID and observed Node child had a preload record, every owned process group was confirmed gone, and temporary roots were removed. These are application-preload and bounded process observations, not a kernel network sandbox or universal subprocess audit.
10
+
11
+ ## Corrected fixture and observed outcomes
12
+
13
+ The first producer reported Q2/Q4/Q6 failures on both 0.26.4 and matched 0.26.1. Its Q2 error combined two conditions without retaining which failed; its Q4 required bootstrap-leader survival in addition to the original turn-continuation criterion and signalled the entire group; its Q6 stopped at assistant text before the documented message_stop/persistence boundary and selected the first matching fixture marker from provider input. Those results did not establish new-version regressions and were retained.
14
+
15
+ The second producer kept the required assertions and added causal observations: wait for a native stream delta before the second submit; require final assistant plus following message_stop; wait until the owned session recording contains the final assistant before restart; classify the latest matching fixture marker and retain all marker matches; bind SIGINT to the actual native TUI PID by input-file argv, process group and start identity. It recorded the separate Q2 diagnostics and event chronology. No timeout was increased and no assertion for a separate queued user turn was removed.
16
+
17
+ | Check | 0.26.4 corrected producer | Matched 0.26.1 control |
18
+ | --- | --- | --- |
19
+ | Q7 version and guard positive control | pass, 0.26.4 | bound separately to installed 0.26.1; not selected in diagnostic run |
20
+ | Q2 second submit becomes a separate user turn after the first completes | **not reproduced** | **not reproduced with the same fixture** |
21
+ | Q3 shell allow/deny, TUI Enter, duplicate reply, read-only control | pass | not selected |
22
+ | Q3 native MCP can_use_tool, exact input and one handler effect after allow, duplicate refused | pass | not selected |
23
+ | Q4 external cancel/SIGINT leaves turn running; person Esc stops it and next turn works | pass, existing ceiling retained | pass |
24
+ | Q5 unread output FIFO does not block the TUI answer | pass | not selected |
25
+ | Q6 resume id, no old-submit replay and prior context present in resumed provider request | pass | pass |
26
+
27
+ For Q2 the corrected results in both versions report `prematureSecondUser: false` and `userCount: 1`. The one final assistant carries responses to both submitted markers and one completion boundary; the required second distinct user event is absent. This supports a coalescing/steering observation for this held-stream workload, not a new 0.26.4 regression. The earlier receipt's queued-submit observation was not reproduced by this fixture, so this row cannot be called fully verified.
28
+
29
+ Q3 saw actual shell and `mcp__t0__t0_echo` requests with request id, tool_use_id, exact input and permission_suggestions. Allow and TUI Enter produced the effect and success response; duplicate responses were errors without a second effect. The denied file was absent, the legacy no-event ceiling was observed and a subsequent turn worked. The read-only command ran without approval. MCP execution reached the tiny fixture's handler only after allow and exactly once.
30
+
31
+ Q4 records an identity-bound native TUI signal, not a promise that the hub may signal a person's terminal. The hub's existing report-only watchdog remains unchanged. Q6 rotated the event file like the production adapter, retained old input bytes without replay and observed the remembered token in the resumed provider request. Model recall quality is unverified because all responses were deterministic fixtures.
32
+
33
+ ## Source review and decision
34
+
35
+ At 0.26.1 `b475278c4a300acebe6cfc990a9e1b1d18819bfc` and 0.26.4 `715a550cfca0135e00d4015d1ca82a8167e81fff`, `DualOutputBridge.ts` and `RemoteInputWatcher.ts` were byte-identical. The installed UI callback/queue regions also retain direct addMessage and mid-turn steering paths. This is scoped supporting source evidence; the matched native control above determines the attribution limit.
36
+
37
+ Because Q2 is not established, the conditional task gate does not permit a qwen-dual bump. Only the independently passing ACP and Kimi rows are changed. No TUI adapter, queue, cancellation policy or existing 0.26.1 admission is modified. Resolving this stronger queued-turn workload is separate from declaring a new-version regression.
38
+
39
+ Real account/provider, inference, model choices/quality, token/quota behavior and non-macOS platforms remain unverified. The evidence includes explicit failed and unselected diagnostic legs; none is relabelled as a pass. Host unit tests/changed gate and exact-head CI are separate PR evidence.
40
+
41
+ ## Evidence fingerprints
42
+
43
+ Files remain outside git under `scratchpad/temp/agent-hub-578`.
44
+
45
+ | File | SHA-256 |
46
+ | --- | --- |
47
+ | `qwen-dual-probe.py` | `6111ed0364a498b15d8abbf5353d00ec9289add7dcbc8a57ac0441a2c815af3c` |
48
+ | `qwen-dual-result.json` | `247e7ade2eb001e14b6492cdeb570e6a899b7b83c4873571e5624821d1f0f44b` |
49
+ | `qwen-dual-0261-control-result.json` | `fa47606403a642bda78ea71d810b837c807bc5a36f7b1097ec54c9d7f64d099f` |
50
+ | `qwen-dual-probe-v2.py` | `114c032afce5caef4f59072f0a1730bc78a70788fd49ad17e5ff2f1eef4c947e` |
51
+ | `qwen-dual-v2-0261-control-result.json` | `9b3a9940e43d73c2223d51aec8826053ff24a13b08e1fee4db854d2197053564` |
52
+ | `qwen-dual-v2-0264-result.json` | `15f9b3971f0de3eb48cd6f5735927592b6a20a782641fddb5ca070846b628844` |
@@ -68,7 +68,7 @@ results=[]
68
68
  for raw_binary in args.claude:
69
69
  binary=pathlib.Path(raw_binary).resolve(); identity=ROOT/('identity-'+binary.name); identity.mkdir()
70
70
  version=subprocess.run([str(binary),'--version'],env={'HOME':str(identity),'CLAUDE_CONFIG_DIR':str(identity/'config'),'PATH':'/usr/bin:/bin'},capture_output=True,text=True,timeout=10)
71
- assert version.returncode==0 and version.stdout.strip().split()[0] in ('2.1.309','2.1.310'),(version.returncode,version.stdout)
71
+ assert version.returncode==0 and version.stdout.strip().split()[0] in ('2.1.309','2.1.310','2.1.314'),(version.returncode,version.stdout)
72
72
  label=version.stdout.strip().split()[0]; digest=sha(binary)
73
73
  for mode in ('context','normalized'):
74
74
  d=ROOT/(label+'-'+mode); d.mkdir(); home=d/'home';home.mkdir(); work=d/"work 'quoted'";work.mkdir();(work/'sub').mkdir()
@@ -2,7 +2,7 @@
2
2
  "schemaVersion": 1,
3
3
  "documents": {
4
4
  "README.md": {
5
- "verifiedAgainst": "ce8da3ec141f7ef17e2e1cd6a8104ddc36304efe",
5
+ "verifiedAgainst": "5b63fa3809f5bee0002d01685abac8b2fadc0cdd",
6
6
  "paths": [
7
7
  "package.json",
8
8
  "src/",
@@ -11,14 +11,14 @@
11
11
  ]
12
12
  },
13
13
  "docs/security.md": {
14
- "verifiedAgainst": "ce8da3ec141f7ef17e2e1cd6a8104ddc36304efe",
14
+ "verifiedAgainst": "5b63fa3809f5bee0002d01685abac8b2fadc0cdd",
15
15
  "paths": [
16
16
  "src/",
17
17
  "templates/"
18
18
  ]
19
19
  },
20
20
  "docs/operations.md": {
21
- "verifiedAgainst": "ce8da3ec141f7ef17e2e1cd6a8104ddc36304efe",
21
+ "verifiedAgainst": "5b63fa3809f5bee0002d01685abac8b2fadc0cdd",
22
22
  "paths": [
23
23
  "package.json",
24
24
  "src/",
@@ -35,7 +35,7 @@
35
35
  ]
36
36
  },
37
37
  "docs/quickstart.md": {
38
- "verifiedAgainst": "ce8da3ec141f7ef17e2e1cd6a8104ddc36304efe",
38
+ "verifiedAgainst": "5b63fa3809f5bee0002d01685abac8b2fadc0cdd",
39
39
  "paths": [
40
40
  "package.json",
41
41
  "src/",
@@ -43,7 +43,7 @@
43
43
  ]
44
44
  },
45
45
  "docs/agent-notes/adapters.md": {
46
- "verifiedAgainst": "ce8da3ec141f7ef17e2e1cd6a8104ddc36304efe",
46
+ "verifiedAgainst": "5b63fa3809f5bee0002d01685abac8b2fadc0cdd",
47
47
  "paths": [
48
48
  "src/adapters/",
49
49
  "src/pi/",
@@ -264,7 +264,7 @@
264
264
  ]
265
265
  },
266
266
  "docs/agent-notes/tests.md": {
267
- "verifiedAgainst": "ce8da3ec141f7ef17e2e1cd6a8104ddc36304efe",
267
+ "verifiedAgainst": "5b63fa3809f5bee0002d01685abac8b2fadc0cdd",
268
268
  "paths": [
269
269
  "test/",
270
270
  "scripts/check.sh",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@staix/agent-hub",
3
- "version": "0.23.0",
3
+ "version": "0.23.1",
4
4
  "description": "Native multi-agent hub: Claude Code, Codex, Kimi Code, Pi and local inference as peers in one project",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -17,7 +17,7 @@
17
17
  "bun": ">=1.4.2"
18
18
  },
19
19
  "dependencies": {
20
- "@staix/agent-mem": "0.13.0"
20
+ "@staix/agent-mem": "0.14.0"
21
21
  },
22
22
  "devDependencies": {
23
23
  "@modelcontextprotocol/sdk": "^1.27.1",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-hub",
3
- "version": "0.23.0",
3
+ "version": "0.23.1",
4
4
  "description": "Channel between Claude Code and the agent-hub daemon: peer messages from Codex, Kimi and the local worker arrive as channel events; hub_send replies.",
5
5
  "author": {
6
6
  "name": "Young Joon Lee",
@@ -308,12 +308,12 @@ var init_compat = __esm(() => {
308
308
  },
309
309
  "claude-implementer": {
310
310
  label: "Claude headless implementer",
311
- verified: ["2.1.309", "2.1.310"],
311
+ verified: ["2.1.309", "2.1.310", "2.1.314"],
312
312
  gate: "contract",
313
313
  probe: ["claude", "--version"],
314
314
  parse: (out) => plain(out.trim().replace(/ \(Claude Code\)$/, "")),
315
315
  trustNote: "The native prompt-tool transport and host-wrapper rewrite, environment isolation and replay contract have isolated receipts. No dontAsk/bypass fallback exists; another version's permission or rewrite behavior is unverified.",
316
- receipt: "docs/verification/2026-10-26-headless-claude-shell-context.md"
316
+ receipt: "docs/verification/2026-10-31-claude-implementer-2.1.314.md"
317
317
  },
318
318
  "codex-review": {
319
319
  label: "Codex reviewer (codex-cli)",
@@ -323,16 +323,16 @@ var init_compat = __esm(() => {
323
323
  config: "codex_bin",
324
324
  parse: (out) => plain(out.trim().replace(/^codex-cli /, "")),
325
325
  trustNote: "Every launch still proves the MCP inventory, Apps/plugins/hooks disabled, sandbox read/write denial and the binary fence; a failed leg still refuses. Trust covers only the source-level claims those probes cannot see (docs/verification/2026-10-19-reviewer-isolation.md).",
326
- receipt: "docs/verification/2026-10-24-codex-0164-reviewer-isolation.md"
326
+ receipt: "docs/verification/2026-10-31-codex-0166-reviewer-isolation.md"
327
327
  },
328
328
  "kimi-review": {
329
329
  label: "Kimi reviewer (kimi-code)",
330
- verified: ["2.2.0", "2.3.0", "2.3.1", "2.3.2"],
330
+ verified: ["2.2.0", "2.3.0", "2.3.1", "2.3.2", "2.4.1"],
331
331
  gate: "isolation",
332
332
  probe: ["kimi", "--version"],
333
333
  parse: (out) => plain(out.trim()),
334
334
  trustNote: "Every launch still builds the private config, exact two-tool agent file and task-bound MCP; the native tool allowlist behaviour of an untested version is not re-proven.",
335
- receipt: "docs/verification/2026-10-26-kimi-232-reviewer-compat.md"
335
+ receipt: "docs/verification/2026-10-31-kimi-241-reviewer-compat.md"
336
336
  },
337
337
  jcode: {
338
338
  label: "Jcode",
@@ -364,13 +364,13 @@ var init_compat = __esm(() => {
364
364
  },
365
365
  qwen: {
366
366
  label: "Qwen Code",
367
- verified: ["0.25.0", "0.26.0", "0.26.1"],
367
+ verified: ["0.25.0", "0.26.0", "0.26.1", "0.26.4"],
368
368
  gate: "contract",
369
369
  probe: ["qwen", "--version"],
370
370
  config: "qwen_cmd",
371
371
  parse: (out) => plain(out.trim()),
372
- trustNote: "Native ACP identity, mode ids and permission callbacks were re-checked without inference on 0.26.1; its two ACP fixes were judged not to change the hub contract. Another version may change those contracts.",
373
- receipt: "docs/verification/2026-10-26-qwen-0261-acp.md"
372
+ trustNote: "Native ACP identity, mode ids and permission callbacks were re-checked without inference on 0.26.4; real model turns remain unverified. Another version may change those contracts.",
373
+ receipt: "docs/verification/2026-10-31-qwen-0264-acp.md"
374
374
  },
375
375
  "qwen-dual": {
376
376
  label: "Qwen Code dual-output TUI",
@@ -14838,54 +14838,13 @@ var init_registry = __esm(() => {
14838
14838
  }));
14839
14839
  });
14840
14840
 
14841
- // node_modules/@staix/agent-mem/src/memory/cli-attribution.ts
14842
- import { AsyncLocalStorage } from "async_hooks";
14843
- var scope;
14844
- var init_cli_attribution = __esm(() => {
14845
- scope = new AsyncLocalStorage;
14846
- });
14847
-
14848
- // node_modules/@staix/agent-mem/src/memory/private-spans.ts
14849
- var init_private_spans = () => {};
14850
-
14851
- // node_modules/@staix/agent-mem/src/memory/screen.ts
14852
- var init_screen = () => {};
14853
-
14854
14841
  // node_modules/@staix/agent-mem/src/memory/mutation.ts
14855
- var init_mutation = () => {};
14856
-
14857
- // node_modules/@staix/agent-mem/src/memory/project.ts
14858
- var init_project2 = __esm(() => {
14859
- init_platform();
14860
- });
14861
-
14862
- // node_modules/@staix/agent-mem/src/memory/policy.ts
14863
- var MAX_BYTES3, MAX_STRING_BYTES, flags;
14864
- var init_policy = __esm(() => {
14865
- init_screen();
14866
- init_platform();
14867
- init_project2();
14868
- MAX_BYTES3 = 256 * 1024;
14869
- MAX_STRING_BYTES = 16 * 1024;
14870
- flags = new Set(["private", "pii", "privateturn", "isprivate", "ispii"]);
14871
- });
14872
-
14873
- // node_modules/@staix/agent-mem/src/memory/config.ts
14874
- var MAX_CONFIG_BYTES2;
14875
- var init_config2 = __esm(() => {
14876
- init_policy();
14877
- MAX_CONFIG_BYTES2 = 64 * 1024;
14878
- });
14879
-
14880
- // node_modules/@staix/agent-mem/src/memory/home.ts
14881
- var init_home = __esm(() => {
14842
+ var mutations;
14843
+ var init_mutation = __esm(() => {
14882
14844
  init_platform();
14883
- init_config2();
14845
+ mutations = new WeakMap;
14884
14846
  });
14885
14847
 
14886
- // node_modules/@staix/agent-mem/src/memory/machine.ts
14887
- var init_machine = () => {};
14888
-
14889
14848
  // node_modules/@staix/agent-mem/src/memory/lifecycle-log.ts
14890
14849
  var MAX_LOG_BYTES;
14891
14850
  var init_lifecycle_log = __esm(() => {
@@ -14897,91 +14856,35 @@ var init_aliases = __esm(() => {
14897
14856
  init_lifecycle_log();
14898
14857
  });
14899
14858
 
14900
- // node_modules/@staix/agent-mem/src/memory/generation.ts
14901
- var init_generation = __esm(() => {
14902
- init_mutation();
14903
- init_platform();
14904
- });
14905
-
14906
14859
  // node_modules/@staix/agent-mem/src/memory/shard.ts
14907
14860
  var init_shard = __esm(() => {
14861
+ init_public_prune_view();
14908
14862
  init_generation();
14909
14863
  init_aliases();
14910
14864
  init_aliases();
14911
14865
  });
14912
14866
 
14913
- // node_modules/@staix/agent-mem/src/memory/lifecycle.ts
14914
- var init_lifecycle = __esm(() => {
14915
- init_aliases();
14916
- init_lifecycle_log();
14917
- init_shard();
14918
- });
14919
-
14920
- // node_modules/@staix/agent-mem/src/memory/search-score.ts
14921
- function sql(expr, rank) {
14922
- const get = (part) => sql(part, rank);
14923
- switch (expr.op) {
14924
- case "rank":
14925
- return rank;
14926
- case "tier":
14927
- return `CASE tier ${Object.entries(TIER_WEIGHTS).map(([name, value]) => `WHEN '${name}' THEN ${real(value)}`).join(" ")} ELSE ${real(DEFAULT_TIER_WEIGHT)} END`;
14928
- case "age":
14929
- return `((julianday(?) - julianday(at)) / ${real(MONTH_DAYS)})`;
14930
- case "constant":
14931
- return real(expr.value);
14932
- case "negative":
14933
- return `(-(${get(expr.value)}))`;
14934
- case "reciprocal":
14935
- return `(1.0 / ${get(expr.value)})`;
14936
- case "add":
14937
- return `(${get(expr.left)} + ${get(expr.right)})`;
14938
- case "multiply":
14939
- return expr.right.op === "reciprocal" ? `(${get(expr.left)} / ${get(expr.right.value)})` : `(${get(expr.left)} * ${get(expr.right)})`;
14940
- case "max":
14941
- return `max(${get(expr.left)}, ${get(expr.right)})`;
14942
- }
14943
- }
14944
- function rankedScoreSql(rank = "bm25(docs)") {
14945
- return sql(SCORE, rank);
14946
- }
14947
- var MONTH_DAYS = 30, TIER_WEIGHTS, DEFAULT_TIER_WEIGHT = 0.9, TIER_FACTOR, DENOMINATOR, RECENCY_FACTOR, SCORE, real = (value) => Number.isInteger(value) ? `${value}.0` : String(value);
14948
- var init_search_score = __esm(() => {
14949
- TIER_WEIGHTS = { long: 1, capture: 0.5 };
14950
- TIER_FACTOR = { op: "tier" };
14951
- DENOMINATOR = { op: "add", left: { op: "constant", value: 1 }, right: { op: "max", left: { op: "constant", value: 0 }, right: { op: "age" } } };
14952
- RECENCY_FACTOR = { op: "reciprocal", value: DENOMINATOR };
14953
- SCORE = { op: "multiply", left: { op: "multiply", left: { op: "negative", value: { op: "rank" } }, right: TIER_FACTOR }, right: RECENCY_FACTOR };
14954
- });
14955
-
14956
- // node_modules/@staix/agent-mem/src/memory/search-fts.ts
14957
- var SCREENED_SCORE, SCREENED_SUBSTRING_SCORE;
14958
- var init_search_fts = __esm(() => {
14959
- init_search_score();
14960
- SCREENED_SCORE = rankedScoreSql();
14961
- SCREENED_SUBSTRING_SCORE = rankedScoreSql("-1.0");
14867
+ // node_modules/@staix/agent-mem/src/memory/public-prune-input-chain.ts
14868
+ var PUBLIC_PRUNE_REPLAY_MAX_BYTES;
14869
+ var init_public_prune_input_chain = __esm(() => {
14870
+ init_generation();
14871
+ init_platform();
14872
+ PUBLIC_PRUNE_REPLAY_MAX_BYTES = 256 * 1024 * 1024;
14962
14873
  });
14963
14874
 
14964
- // node_modules/@staix/agent-mem/src/memory/capture-input.ts
14965
- var init_capture_input = __esm(() => {
14966
- init_screen();
14875
+ // node_modules/@staix/agent-mem/src/memory/generation.ts
14876
+ var init_generation = __esm(() => {
14877
+ init_public_prune_view();
14878
+ init_mutation();
14967
14879
  init_platform();
14968
- init_private_spans();
14880
+ init_shard();
14881
+ init_public_prune_input_chain();
14969
14882
  });
14970
14883
 
14971
- // node_modules/@staix/agent-mem/src/memory/capture.ts
14972
- var SPOOL_MAX_BYTES;
14973
- var init_capture = __esm(() => {
14974
- init_screen();
14975
- init_capture_input();
14976
- init_capture_input();
14977
- init_home();
14978
- init_shard();
14979
- init_lifecycle();
14980
- init_machine();
14981
- init_config2();
14982
- init_policy();
14983
- init_search_fts();
14984
- SPOOL_MAX_BYTES = 256 * 1024;
14884
+ // node_modules/@staix/agent-mem/src/memory/public-prune-view.ts
14885
+ var init_public_prune_view = __esm(() => {
14886
+ init_generation();
14887
+ init_platform();
14985
14888
  });
14986
14889
 
14987
14890
  // node_modules/@staix/agent-mem/src/memory/ops-contract.ts
@@ -15171,6 +15074,125 @@ var init_shard_bridge = __esm(() => {
15171
15074
  init_bridge();
15172
15075
  });
15173
15076
 
15077
+ // node_modules/@staix/agent-mem/src/memory/cli-attribution.ts
15078
+ import { AsyncLocalStorage } from "async_hooks";
15079
+ var scope;
15080
+ var init_cli_attribution = __esm(() => {
15081
+ scope = new AsyncLocalStorage;
15082
+ });
15083
+
15084
+ // node_modules/@staix/agent-mem/src/memory/private-spans.ts
15085
+ var init_private_spans = () => {};
15086
+
15087
+ // node_modules/@staix/agent-mem/src/memory/screen.ts
15088
+ var init_screen = () => {};
15089
+
15090
+ // node_modules/@staix/agent-mem/src/memory/project.ts
15091
+ var init_project2 = __esm(() => {
15092
+ init_platform();
15093
+ });
15094
+
15095
+ // node_modules/@staix/agent-mem/src/memory/policy.ts
15096
+ var MAX_BYTES3, MAX_STRING_BYTES, flags;
15097
+ var init_policy = __esm(() => {
15098
+ init_screen();
15099
+ init_platform();
15100
+ init_project2();
15101
+ MAX_BYTES3 = 256 * 1024;
15102
+ MAX_STRING_BYTES = 16 * 1024;
15103
+ flags = new Set(["private", "pii", "privateturn", "isprivate", "ispii"]);
15104
+ });
15105
+
15106
+ // node_modules/@staix/agent-mem/src/memory/config.ts
15107
+ var MAX_CONFIG_BYTES2;
15108
+ var init_config2 = __esm(() => {
15109
+ init_policy();
15110
+ MAX_CONFIG_BYTES2 = 64 * 1024;
15111
+ });
15112
+
15113
+ // node_modules/@staix/agent-mem/src/memory/home.ts
15114
+ var init_home = __esm(() => {
15115
+ init_platform();
15116
+ init_config2();
15117
+ });
15118
+
15119
+ // node_modules/@staix/agent-mem/src/memory/machine.ts
15120
+ var init_machine = () => {};
15121
+
15122
+ // node_modules/@staix/agent-mem/src/memory/lifecycle.ts
15123
+ var init_lifecycle = __esm(() => {
15124
+ init_aliases();
15125
+ init_lifecycle_log();
15126
+ init_shard();
15127
+ });
15128
+
15129
+ // node_modules/@staix/agent-mem/src/memory/search-score.ts
15130
+ function sql(expr, rank) {
15131
+ const get = (part) => sql(part, rank);
15132
+ switch (expr.op) {
15133
+ case "rank":
15134
+ return rank;
15135
+ case "tier":
15136
+ return `CASE tier ${Object.entries(TIER_WEIGHTS).map(([name, value]) => `WHEN '${name}' THEN ${real(value)}`).join(" ")} ELSE ${real(DEFAULT_TIER_WEIGHT)} END`;
15137
+ case "age":
15138
+ return `((julianday(?) - julianday(at)) / ${real(MONTH_DAYS)})`;
15139
+ case "constant":
15140
+ return real(expr.value);
15141
+ case "negative":
15142
+ return `(-(${get(expr.value)}))`;
15143
+ case "reciprocal":
15144
+ return `(1.0 / ${get(expr.value)})`;
15145
+ case "add":
15146
+ return `(${get(expr.left)} + ${get(expr.right)})`;
15147
+ case "multiply":
15148
+ return expr.right.op === "reciprocal" ? `(${get(expr.left)} / ${get(expr.right.value)})` : `(${get(expr.left)} * ${get(expr.right)})`;
15149
+ case "max":
15150
+ return `max(${get(expr.left)}, ${get(expr.right)})`;
15151
+ }
15152
+ }
15153
+ function rankedScoreSql(rank = "bm25(docs)") {
15154
+ return sql(SCORE, rank);
15155
+ }
15156
+ var MONTH_DAYS = 30, TIER_WEIGHTS, DEFAULT_TIER_WEIGHT = 0.9, TIER_FACTOR, DENOMINATOR, RECENCY_FACTOR, SCORE, real = (value) => Number.isInteger(value) ? `${value}.0` : String(value);
15157
+ var init_search_score = __esm(() => {
15158
+ TIER_WEIGHTS = { long: 1, capture: 0.5 };
15159
+ TIER_FACTOR = { op: "tier" };
15160
+ DENOMINATOR = { op: "add", left: { op: "constant", value: 1 }, right: { op: "max", left: { op: "constant", value: 0 }, right: { op: "age" } } };
15161
+ RECENCY_FACTOR = { op: "reciprocal", value: DENOMINATOR };
15162
+ SCORE = { op: "multiply", left: { op: "multiply", left: { op: "negative", value: { op: "rank" } }, right: TIER_FACTOR }, right: RECENCY_FACTOR };
15163
+ });
15164
+
15165
+ // node_modules/@staix/agent-mem/src/memory/search-fts.ts
15166
+ var SCREENED_SCORE, SCREENED_SUBSTRING_SCORE;
15167
+ var init_search_fts = __esm(() => {
15168
+ init_search_score();
15169
+ SCREENED_SCORE = rankedScoreSql();
15170
+ SCREENED_SUBSTRING_SCORE = rankedScoreSql("-1.0");
15171
+ });
15172
+
15173
+ // node_modules/@staix/agent-mem/src/memory/capture-input.ts
15174
+ var init_capture_input = __esm(() => {
15175
+ init_screen();
15176
+ init_platform();
15177
+ init_private_spans();
15178
+ });
15179
+
15180
+ // node_modules/@staix/agent-mem/src/memory/capture.ts
15181
+ var SPOOL_MAX_BYTES;
15182
+ var init_capture = __esm(() => {
15183
+ init_screen();
15184
+ init_capture_input();
15185
+ init_capture_input();
15186
+ init_home();
15187
+ init_shard();
15188
+ init_lifecycle();
15189
+ init_machine();
15190
+ init_config2();
15191
+ init_policy();
15192
+ init_search_fts();
15193
+ SPOOL_MAX_BYTES = 256 * 1024;
15194
+ });
15195
+
15174
15196
  // node_modules/@staix/agent-mem/src/memory/style.ts
15175
15197
  function style(color) {
15176
15198
  return { color, ok: wrap(color, 32, 39), attention: wrap(color, 33, 39), error: wrap(color, 31, 39), dim: wrap(color, 2, 22), bold: wrap(color, 1, 22) };
@@ -15187,8 +15209,46 @@ var init_prune = __esm(() => {
15187
15209
  init_style();
15188
15210
  });
15189
15211
 
15212
+ // node_modules/@staix/agent-mem/src/memory/public-prune-witness.ts
15213
+ var init_public_prune_witness = __esm(() => {
15214
+ init_generation();
15215
+ init_prune();
15216
+ init_shard_sync_format();
15217
+ });
15218
+
15219
+ // node_modules/@staix/agent-mem/src/memory/shard-sync-format.ts
15220
+ var SHARD_PACK_MAX_BYTES;
15221
+ var init_shard_sync_format = __esm(() => {
15222
+ init_bridge();
15223
+ init_generation();
15224
+ init_prune();
15225
+ init_shard();
15226
+ init_public_prune_witness();
15227
+ SHARD_PACK_MAX_BYTES = 1024 * 1024;
15228
+ });
15229
+
15230
+ // node_modules/@staix/agent-mem/src/memory/public-prune-inputs.ts
15231
+ var PUBLIC_PRUNE_GRAPH_MAX_BYTES, OBJECT_MAX, plans, batches;
15232
+ var init_public_prune_inputs = __esm(() => {
15233
+ init_generation();
15234
+ init_mutation();
15235
+ init_platform();
15236
+ init_store();
15237
+ init_prune();
15238
+ init_shard_sync_format();
15239
+ init_public_prune_witness();
15240
+ init_public_prune_input_chain();
15241
+ init_public_prune_input_chain();
15242
+ PUBLIC_PRUNE_GRAPH_MAX_BYTES = 80 * 1024 * 1024;
15243
+ OBJECT_MAX = 1024 * 1024 + 64;
15244
+ plans = new WeakMap;
15245
+ batches = new WeakMap;
15246
+ });
15247
+
15190
15248
  // node_modules/@staix/agent-mem/src/memory/generation-index.ts
15191
15249
  var init_generation_index = __esm(() => {
15250
+ init_public_prune_inputs();
15251
+ init_public_prune_view();
15192
15252
  init_shard();
15193
15253
  init_shard_bridge();
15194
15254
  init_generation();
@@ -15212,12 +15272,15 @@ var init_reader_lease = __esm(() => {
15212
15272
  init_generation();
15213
15273
  init_mutation();
15214
15274
  init_platform();
15275
+ init_public_prune_view();
15215
15276
  open = new Map;
15216
15277
  });
15217
15278
 
15218
15279
  // node_modules/@staix/agent-mem/src/memory/store.ts
15219
15280
  var DEFAULT_TTL_MS, UNSETTLED_MS, DEFAULT_LEASE_MS, MIGRATION_BOOTSTRAP;
15220
15281
  var init_store = __esm(() => {
15282
+ init_public_prune_view();
15283
+ init_shard_bridge();
15221
15284
  init_cli_attribution();
15222
15285
  init_platform();
15223
15286
  init_private_spans();
@@ -15288,6 +15351,7 @@ var init_sync_screen = __esm(() => {
15288
15351
  // node_modules/@staix/agent-mem/src/memory/sync.ts
15289
15352
  var liveGroups;
15290
15353
  var init_sync = __esm(() => {
15354
+ init_generation();
15291
15355
  init_platform();
15292
15356
  init_mutation();
15293
15357
  init_generation_sync();
@@ -22977,7 +23041,7 @@ init_security_baseline();
22977
23041
  // package.json
22978
23042
  var package_default = {
22979
23043
  name: "@staix/agent-hub",
22980
- version: "0.23.0",
23044
+ version: "0.23.1",
22981
23045
  description: "Native multi-agent hub: Claude Code, Codex, Kimi Code, Pi and local inference as peers in one project",
22982
23046
  license: "MIT",
22983
23047
  type: "module",
@@ -22994,7 +23058,7 @@ var package_default = {
22994
23058
  bun: ">=1.4.2"
22995
23059
  },
22996
23060
  dependencies: {
22997
- "@staix/agent-mem": "0.13.0"
23061
+ "@staix/agent-mem": "0.14.0"
22998
23062
  },
22999
23063
  devDependencies: {
23000
23064
  "@modelcontextprotocol/sdk": "^1.27.1",