@staix/agent-hub 0.7.0 → 0.7.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.
- package/CHANGELOG.md +5 -0
- package/README.md +2 -2
- package/docs/operations.md +7 -7
- package/docs/quickstart.md +1 -1
- package/docs/smoke.md +20 -0
- package/package.json +1 -1
- package/plugins/agent-hub/.claude-plugin/plugin.json +1 -1
- package/plugins/agent-hub/server.js +1 -1
- package/src/cli/terminal-recovery.ts +9 -34
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.7.1
|
|
4
|
+
|
|
5
|
+
- Restore native sessions while unrelated agents remain in the same worktree; the coordinator continues to fence uncertain terminal creations (#48).
|
|
6
|
+
- Allow a bounded inventory refresh after closing the captured terminal before reporting uncertain shutdown (#48).
|
|
7
|
+
|
|
3
8
|
## 0.7.0
|
|
4
9
|
|
|
5
10
|
- Persist queued deliveries and expose uncertain handoffs for explicit operator reconciliation (#46).
|
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ Native multi-agent hub for one developer's machine: Claude Code, Codex, Kimi Cod
|
|
|
4
4
|
hub-owned local-LLM worker collaborate as peers in independent project directories, with
|
|
5
5
|
task-aware model routing (Switchyard) in front of a self-hosted gateway (OmniRoute).
|
|
6
6
|
|
|
7
|
-
Status: 0.7.
|
|
7
|
+
Status: 0.7.1, control protocol 10. Durable delivery records distinguish queued
|
|
8
8
|
work from uncertain execution. The [smoke checklist](docs/smoke.md) records
|
|
9
9
|
verified paths and remaining prerequisites.
|
|
10
10
|
|
|
@@ -28,7 +28,7 @@ cd <your project> && ahub init && ahub up && ahub tail
|
|
|
28
28
|
Or install the same version from GitHub:
|
|
29
29
|
|
|
30
30
|
```bash
|
|
31
|
-
bun add -g github:STAIxBWLB/agent-hub#v0.7.
|
|
31
|
+
bun add -g github:STAIxBWLB/agent-hub#v0.7.1 && ahub setup
|
|
32
32
|
```
|
|
33
33
|
|
|
34
34
|
The installed commands remain `ahub` and `agent-hub`.
|
package/docs/operations.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Operations guide
|
|
2
2
|
|
|
3
|
-
This guide describes ahub 0.7.
|
|
3
|
+
This guide describes ahub 0.7.1 and control protocol 10. Live verification
|
|
4
4
|
results and remaining prerequisites are recorded separately in [the smoke ledger](smoke.md).
|
|
5
5
|
|
|
6
6
|
## Install and start
|
|
@@ -146,31 +146,31 @@ uncertain.
|
|
|
146
146
|
|
|
147
147
|
## Upgrade and crash recovery
|
|
148
148
|
|
|
149
|
-
For
|
|
149
|
+
For an upgrade from 0.6.4 (protocol 9) or 0.7.0, use the patched coordinator without
|
|
150
150
|
replacing the global CLI prematurely. Run from the project directory:
|
|
151
151
|
|
|
152
152
|
```bash
|
|
153
|
-
bunx --package @staix/agent-hub@0.7.
|
|
154
|
-
bunx --package @staix/agent-hub@0.7.
|
|
153
|
+
bunx --package @staix/agent-hub@0.7.1 ahub upgrade --to 0.7.1 --dry-run
|
|
154
|
+
bunx --package @staix/agent-hub@0.7.1 ahub upgrade --to 0.7.1 --yes
|
|
155
155
|
```
|
|
156
156
|
|
|
157
157
|
The coordinator verifies and retains the exact target package, preserves its
|
|
158
158
|
own source, and promotes the global CLI only after restored projects pass
|
|
159
159
|
readback. Do not use the old protocol-9 coordinator to target protocol 10.
|
|
160
160
|
|
|
161
|
-
Once the installed CLI is 0.7.
|
|
161
|
+
Once the installed CLI is 0.7.1, review the current project or all registered
|
|
162
162
|
projects first:
|
|
163
163
|
|
|
164
164
|
```bash
|
|
165
165
|
ahub restart --dry-run
|
|
166
|
-
ahub upgrade --to 0.7.
|
|
166
|
+
ahub upgrade --to 0.7.1 --dry-run
|
|
167
167
|
```
|
|
168
168
|
|
|
169
169
|
Apply only after reviewing the plan:
|
|
170
170
|
|
|
171
171
|
```bash
|
|
172
172
|
ahub restart --yes
|
|
173
|
-
ahub upgrade --to 0.7.
|
|
173
|
+
ahub upgrade --to 0.7.1 --yes
|
|
174
174
|
ahub recovery status <operation-id>
|
|
175
175
|
ahub recovery resume <operation-id>
|
|
176
176
|
ahub recovery abort <operation-id>
|
package/docs/quickstart.md
CHANGED
package/docs/smoke.md
CHANGED
|
@@ -523,3 +523,23 @@ pause.
|
|
|
523
523
|
with a correlated FYI. This does not establish a real Claude inference turn.
|
|
524
524
|
- Production application, attended Claude restoration and post-deploy readback
|
|
525
525
|
remain pending until the tagged artifact is installed. Issue #12 remains open.
|
|
526
|
+
|
|
527
|
+
|
|
528
|
+
## 0.7.0 attended production cutover and follow-up
|
|
529
|
+
|
|
530
|
+
The published 0.7.0 package passed integrity staging and completed protocol 9
|
|
531
|
+
to 10 recovery in the production project. Task/budget state and queued Codex
|
|
532
|
+
messages were retained. General status now displays the disconnected Codex
|
|
533
|
+
recipient and its two pending messages.
|
|
534
|
+
|
|
535
|
+
Attended recovery exposed #48: the pre-create terminal check treated unrelated
|
|
536
|
+
Codex/Qwen terminals as an ambiguous earlier Claude creation. The original
|
|
537
|
+
Claude conversation was manually reattached with the captured session identity,
|
|
538
|
+
the native development-channel confirmation was accepted, and recovery resume
|
|
539
|
+
verified the existing replacement without creating a duplicate. The operation
|
|
540
|
+
reached `completed` with its project `verified`.
|
|
541
|
+
|
|
542
|
+
0.7.1 removes the redundant worktree-wide create blocker while retaining the
|
|
543
|
+
coordinator's pending-create fence and returned terminal/session verification.
|
|
544
|
+
Regression tests include unrelated terminals and delayed close inventory.
|
|
545
|
+
The 0.7.1 attended repeat is recorded separately after application.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-hub",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.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",
|
|
@@ -15727,7 +15727,7 @@ class ControlClient {
|
|
|
15727
15727
|
// package.json
|
|
15728
15728
|
var package_default = {
|
|
15729
15729
|
name: "@staix/agent-hub",
|
|
15730
|
-
version: "0.7.
|
|
15730
|
+
version: "0.7.1",
|
|
15731
15731
|
description: "Native multi-agent hub: Claude Code, Codex, Kimi Code, Pi and local inference as peers in one project",
|
|
15732
15732
|
license: "MIT",
|
|
15733
15733
|
type: "module",
|
|
@@ -543,10 +543,13 @@ export async function closeTerminal(binding: TerminalBinding, timeoutMs = 600_00
|
|
|
543
543
|
try {
|
|
544
544
|
await showBinding(binding, config);
|
|
545
545
|
await run(config.runner, ["terminal", "close", "--terminal", binding.handle, "--json"]);
|
|
546
|
-
const
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
546
|
+
const deadline = Date.now() + 5000;
|
|
547
|
+
do {
|
|
548
|
+
const afterClose = listTerminals(await run(config.runner, ["terminal", "list", "--json"]));
|
|
549
|
+
if (!afterClose.some((terminal) => terminal.handle === binding.handle || terminal.incarnationId === binding.incarnationId)) return { closed: true, manualRequired: false, binding, blockers: [] };
|
|
550
|
+
await Bun.sleep(100);
|
|
551
|
+
} while (Date.now() < deadline);
|
|
552
|
+
return closeFailure(binding, [blocker("ambiguous-create", `close of terminal ${binding.handle} was not confirmed`, binding.peer, binding.handle)]);
|
|
550
553
|
} catch (error) {
|
|
551
554
|
return closeFailure(binding, [error instanceof OrcaCommandError ? error.blocker : blocker("command-error", String(error), binding.peer, binding.handle)]);
|
|
552
555
|
}
|
|
@@ -557,36 +560,8 @@ export async function createTerminal(binding: TerminalBinding, options?: Command
|
|
|
557
560
|
const config = normalizeOptions(options);
|
|
558
561
|
try {
|
|
559
562
|
const worktreeSelector = binding.worktreeId.startsWith("id:") ? binding.worktreeId : `id:${binding.worktreeId}`;
|
|
560
|
-
//
|
|
561
|
-
//
|
|
562
|
-
// session match is safe to adopt; any other occupant requires an operator
|
|
563
|
-
// decision rather than risking a duplicate native session.
|
|
564
|
-
const existing = listTerminals(await run(config.runner, ["terminal", "list", "--json"])).filter((terminal) =>
|
|
565
|
-
rootMatches(terminal.worktreePath ?? terminal.projectRoot, binding.projectRoot) &&
|
|
566
|
-
nestedString(terminal, ["worktreeId"]) === binding.worktreeId,
|
|
567
|
-
);
|
|
568
|
-
if (existing.length > 0) {
|
|
569
|
-
const matches: TerminalBinding[] = [];
|
|
570
|
-
for (const listed of existing) {
|
|
571
|
-
const handle = nestedString(listed, ["handle"]);
|
|
572
|
-
if (!handle) continue;
|
|
573
|
-
try {
|
|
574
|
-
const shown = terminalObject(await run(config.runner, ["terminal", "show", "--terminal", handle, "--json"]));
|
|
575
|
-
if (identityFrom(shown) === binding.peer && sessionFrom(shown) === binding.sessionId) {
|
|
576
|
-
const incarnationId = nestedString(shown, ["incarnationId"]);
|
|
577
|
-
const worktreeId = nestedString(shown, ["worktreeId"]);
|
|
578
|
-
if (incarnationId && worktreeId) matches.push({ ...binding, handle, incarnationId, worktreeId });
|
|
579
|
-
}
|
|
580
|
-
} catch { /* An unreadable candidate remains an ambiguity below. */ }
|
|
581
|
-
}
|
|
582
|
-
if (matches.length === 1) {
|
|
583
|
-
const recovered = matches[0]!;
|
|
584
|
-
const idle = await waitForIdle(recovered, timeoutMs, config);
|
|
585
|
-
if (!idle.satisfied) return { created: false, ready: false, manualRequired: true, blockers: idle.blockers };
|
|
586
|
-
return { created: true, ready: true, manualRequired: false, binding: recovered, newBinding: recovered, blockers: [] };
|
|
587
|
-
}
|
|
588
|
-
return { created: false, ready: false, manualRequired: true, blockers: [blocker("ambiguous-create", `an existing terminal in worktree ${binding.worktreeId} may be the result of an earlier create; refusing another create`, binding.peer)] };
|
|
589
|
-
}
|
|
563
|
+
// The coordinator journals a pending creation before this call and reconciles
|
|
564
|
+
// it on resume. Other agents in the worktree do not imply a prior create.
|
|
590
565
|
const value = await run(config.runner, ["terminal", "create", "--worktree", worktreeSelector, "--command", binding.launch.command, "--title", `${binding.peer} recovery`, "--json"]);
|
|
591
566
|
let created = terminalObject(value);
|
|
592
567
|
const createdHandle = nestedString(created, ["handle"]);
|