harnery 0.41.0 → 0.43.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/dist/commander.d.ts +16 -0
- package/dist/commander.d.ts.map +1 -1
- package/dist/commander.js +21 -0
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +63 -5
- package/dist/commands/artifacts.d.ts.map +1 -1
- package/dist/commands/artifacts.js +113 -12
- package/dist/commands/browse.d.ts +164 -0
- package/dist/commands/browse.d.ts.map +1 -1
- package/dist/commands/browse.js +263 -51
- package/dist/commands/claude-desktop.d.ts.map +1 -1
- package/dist/commands/claude-desktop.js +52 -0
- package/dist/commands/disk.d.ts +6 -0
- package/dist/commands/disk.d.ts.map +1 -0
- package/dist/commands/disk.js +80 -0
- package/dist/commands/doctor.d.ts +8 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +48 -1
- package/dist/commands/files.d.ts +16 -0
- package/dist/commands/files.d.ts.map +1 -1
- package/dist/commands/files.js +54 -2
- package/dist/commands/init.d.ts +2 -2
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +43 -9
- package/dist/commands/rm.d.ts +4 -0
- package/dist/commands/rm.d.ts.map +1 -0
- package/dist/commands/rm.js +87 -0
- package/dist/commands/servers.d.ts +7 -0
- package/dist/commands/servers.d.ts.map +1 -0
- package/dist/commands/servers.js +394 -0
- package/dist/commands/tunnel.d.ts +65 -0
- package/dist/commands/tunnel.d.ts.map +1 -1
- package/dist/commands/tunnel.js +372 -103
- package/dist/commands/web-fetch.d.ts +3 -2
- package/dist/commands/web-fetch.d.ts.map +1 -1
- package/dist/commands/web-fetch.js +25 -19
- package/dist/commands/web.d.ts +7 -1
- package/dist/commands/web.d.ts.map +1 -1
- package/dist/commands/web.js +9 -3
- package/dist/core/adapters/profiles.d.ts +9 -0
- package/dist/core/adapters/profiles.d.ts.map +1 -1
- package/dist/core/adapters/profiles.js +22 -1
- package/dist/core/adapters/types.d.ts +9 -0
- package/dist/core/adapters/types.d.ts.map +1 -1
- package/dist/core/agents/cli.js +13 -6
- package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
- package/dist/core/agents/render/prompt-context.js +11 -5
- package/dist/core/agents/render/session-context.d.ts.map +1 -1
- package/dist/core/agents/render/session-context.js +59 -13
- package/dist/core/agents/state/live-coordination-view.d.ts +20 -0
- package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -1
- package/dist/core/agents/state/live-coordination-view.js +60 -0
- package/dist/core/agents/state/names.d.ts +43 -3
- package/dist/core/agents/state/names.d.ts.map +1 -1
- package/dist/core/agents/state/names.js +87 -3
- package/dist/core/artifacts/delivery-card.js +9 -2
- package/dist/core/artifacts/index.d.ts +140 -4
- package/dist/core/artifacts/index.d.ts.map +1 -1
- package/dist/core/artifacts/index.js +522 -49
- package/dist/core/config.d.ts +68 -11
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +128 -3
- package/dist/core/diagnostics/bundle.d.ts.map +1 -1
- package/dist/core/diagnostics/bundle.js +2 -2
- package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/recorder.js +16 -0
- package/dist/core/events/v3/projection.js +9 -1
- package/dist/core/events/v3/support-storage/pack-reader.d.ts.map +1 -1
- package/dist/core/events/v3/support-storage/pack-reader.js +42 -16
- package/dist/core/hooks/adapter/events.d.ts +17 -0
- package/dist/core/hooks/adapter/events.d.ts.map +1 -1
- package/dist/core/hooks/adapter/events.js +5 -0
- package/dist/core/hooks/adapter/runtime-telemetry.js +3 -1
- package/dist/core/hooks/adapter/wiring.d.ts +37 -7
- package/dist/core/hooks/adapter/wiring.d.ts.map +1 -1
- package/dist/core/hooks/adapter/wiring.js +62 -4
- package/dist/core/hooks/cli.js +131 -23
- package/dist/core/hooks/fork-lineage.d.ts +40 -0
- package/dist/core/hooks/fork-lineage.d.ts.map +1 -0
- package/dist/core/hooks/fork-lineage.js +62 -0
- package/dist/core/hooks/resolve/transcript.d.ts +16 -0
- package/dist/core/hooks/resolve/transcript.d.ts.map +1 -1
- package/dist/core/hooks/resolve/transcript.js +84 -0
- package/dist/core/hooks/run-markers.d.ts +37 -0
- package/dist/core/hooks/run-markers.d.ts.map +1 -0
- package/dist/core/hooks/run-markers.js +109 -0
- package/dist/core/hooks/shell-rm.d.ts +2 -0
- package/dist/core/hooks/shell-rm.d.ts.map +1 -0
- package/dist/core/hooks/shell-rm.js +105 -0
- package/dist/core/hooks/shell-tokens.d.ts +12 -0
- package/dist/core/hooks/shell-tokens.d.ts.map +1 -0
- package/dist/core/hooks/shell-tokens.js +97 -0
- package/dist/core/hooks/shell-waiter.d.ts.map +1 -1
- package/dist/core/hooks/shell-waiter.js +3 -93
- package/dist/core/semantic/contract.d.ts +5 -5
- package/dist/core/servers/index.d.ts +211 -0
- package/dist/core/servers/index.d.ts.map +1 -0
- package/dist/core/servers/index.js +560 -0
- package/dist/core/servers/net.d.ts +58 -0
- package/dist/core/servers/net.d.ts.map +1 -0
- package/dist/core/servers/net.js +270 -0
- package/dist/core/servers/tunnels.d.ts +14 -0
- package/dist/core/servers/tunnels.d.ts.map +1 -0
- package/dist/core/servers/tunnels.js +33 -0
- package/dist/core/storage/builtins.js +1 -0
- package/dist/core/storage/process-log.d.ts +12 -0
- package/dist/core/storage/process-log.d.ts.map +1 -1
- package/dist/core/storage/process-log.js +10 -2
- package/dist/core/workflow/engine.d.ts.map +1 -1
- package/dist/core/workflow/engine.js +30 -1
- package/dist/core/workflow/sandbox-projection.d.ts +13 -2
- package/dist/core/workflow/sandbox-projection.d.ts.map +1 -1
- package/dist/core/workflow/sandbox-projection.js +23 -0
- package/dist/core/workflow/spawn-claude.d.ts.map +1 -1
- package/dist/core/workflow/spawn-claude.js +6 -1
- package/dist/core/workflow/spawn-codex.d.ts +2 -0
- package/dist/core/workflow/spawn-codex.d.ts.map +1 -1
- package/dist/core/workflow/spawn-codex.js +20 -1
- package/dist/core/workflow/spawn-cursor.d.ts.map +1 -1
- package/dist/core/workflow/spawn-cursor.js +6 -1
- package/dist/core/workflow/spawn-opencode.d.ts.map +1 -1
- package/dist/core/workflow/spawn-opencode.js +4 -1
- package/dist/core/workflow/types.d.ts +47 -2
- package/dist/core/workflow/types.d.ts.map +1 -1
- package/dist/core/workflow/worker-access.d.ts +92 -0
- package/dist/core/workflow/worker-access.d.ts.map +1 -0
- package/dist/core/workflow/worker-access.js +450 -0
- package/dist/lib/browser/batch-steps.d.ts +18 -0
- package/dist/lib/browser/batch-steps.d.ts.map +1 -0
- package/dist/lib/browser/batch-steps.js +82 -0
- package/dist/lib/browser/collect/collector.d.ts +99 -0
- package/dist/lib/browser/collect/collector.d.ts.map +1 -0
- package/dist/lib/browser/collect/collector.js +202 -0
- package/dist/lib/browser/collect/fields.d.ts +31 -0
- package/dist/lib/browser/collect/fields.d.ts.map +1 -0
- package/dist/lib/browser/collect/fields.js +75 -0
- package/dist/lib/browser/collect/index.d.ts +6 -0
- package/dist/lib/browser/collect/index.d.ts.map +1 -0
- package/dist/lib/browser/collect/index.js +5 -0
- package/dist/lib/browser/collect/page-driver.d.ts +14 -0
- package/dist/lib/browser/collect/page-driver.d.ts.map +1 -0
- package/dist/lib/browser/collect/page-driver.js +306 -0
- package/dist/lib/browser/collect/presets.d.ts +52 -0
- package/dist/lib/browser/collect/presets.d.ts.map +1 -0
- package/dist/lib/browser/collect/presets.js +176 -0
- package/dist/lib/browser/collect/scroll-plan.d.ts +85 -0
- package/dist/lib/browser/collect/scroll-plan.d.ts.map +1 -0
- package/dist/lib/browser/collect/scroll-plan.js +118 -0
- package/dist/lib/browser/index.d.ts +1 -1
- package/dist/lib/browser/index.d.ts.map +1 -1
- package/dist/lib/browser/page-review-judge.d.ts +2 -0
- package/dist/lib/browser/page-review-judge.d.ts.map +1 -1
- package/dist/lib/browser/page-review-judge.js +13 -0
- package/dist/lib/browser/qa-run-contracts.d.ts +10 -0
- package/dist/lib/browser/qa-run-contracts.d.ts.map +1 -1
- package/dist/lib/browser/qa-run.d.ts.map +1 -1
- package/dist/lib/browser/qa-run.js +1 -0
- package/dist/lib/browser/windows-chrome.d.ts +59 -0
- package/dist/lib/browser/windows-chrome.d.ts.map +1 -0
- package/dist/lib/browser/windows-chrome.js +179 -0
- package/dist/lib/claude-desktop-share.d.ts +136 -0
- package/dist/lib/claude-desktop-share.d.ts.map +1 -0
- package/dist/lib/claude-desktop-share.js +394 -0
- package/dist/lib/disk-usage.d.ts +50 -0
- package/dist/lib/disk-usage.d.ts.map +1 -0
- package/dist/lib/disk-usage.js +303 -0
- package/dist/lib/docs-lint.d.ts +6 -0
- package/dist/lib/docs-lint.d.ts.map +1 -1
- package/dist/lib/docs-lint.js +8 -3
- package/dist/lib/guarded-remove.d.ts +34 -0
- package/dist/lib/guarded-remove.d.ts.map +1 -0
- package/dist/lib/guarded-remove.js +310 -0
- package/dist/lib/instructions/templates.js +8 -8
- package/dist/lib/tunnel/allowlist.d.ts +44 -0
- package/dist/lib/tunnel/allowlist.d.ts.map +1 -0
- package/dist/lib/tunnel/allowlist.js +204 -0
- package/dist/lib/tunnel/current-address.d.ts +41 -0
- package/dist/lib/tunnel/current-address.d.ts.map +1 -0
- package/dist/lib/tunnel/current-address.js +123 -0
- package/dist/lib/tunnel/error-page.d.ts +1 -1
- package/dist/lib/tunnel/error-page.d.ts.map +1 -1
- package/dist/lib/tunnel/error-page.js +19 -8
- package/dist/lib/tunnel/gate.js +33 -7
- package/dist/lib/tunnel/path-scope.d.ts +22 -0
- package/dist/lib/tunnel/path-scope.d.ts.map +1 -0
- package/dist/lib/tunnel/path-scope.js +62 -0
- package/dist/lib/tunnel/processes.d.ts +39 -0
- package/dist/lib/tunnel/processes.d.ts.map +1 -0
- package/dist/lib/tunnel/processes.js +121 -0
- package/dist/lib/tunnel/state.d.ts +33 -3
- package/dist/lib/tunnel/state.d.ts.map +1 -1
- package/dist/lib/tunnel/state.js +115 -30
- package/package.json +7 -1
- package/schemas/config.schema.json +91 -0
- package/src/commander.ts +51 -0
- package/src/commands/agents.ts +111 -11
- package/src/commands/artifacts.ts +171 -19
- package/src/commands/browse.ts +400 -57
- package/src/commands/claude-desktop.ts +61 -0
- package/src/commands/disk.ts +114 -0
- package/src/commands/doctor.ts +52 -1
- package/src/commands/files.ts +93 -2
- package/src/commands/init.ts +55 -5
- package/src/commands/rm.ts +115 -0
- package/src/commands/servers.ts +506 -0
- package/src/commands/tunnel.ts +494 -116
- package/src/commands/web-fetch.ts +30 -19
- package/src/commands/web.ts +9 -3
- package/src/core/adapters/profiles.ts +22 -1
- package/src/core/adapters/types.ts +10 -0
- package/src/core/agents/cli.ts +14 -6
- package/src/core/agents/render/prompt-context.ts +25 -8
- package/src/core/agents/render/session-context.ts +84 -16
- package/src/core/agents/state/live-coordination-view.ts +73 -0
- package/src/core/agents/state/names.ts +117 -6
- package/src/core/artifacts/delivery-card.ts +10 -2
- package/src/core/artifacts/index.ts +697 -44
- package/src/core/config.ts +183 -4
- package/src/core/diagnostics/bundle.ts +2 -1
- package/src/core/events/v3/producers/recorder.ts +16 -0
- package/src/core/events/v3/projection.ts +11 -1
- package/src/core/events/v3/support-storage/pack-reader.ts +45 -19
- package/src/core/hooks/adapter/events.ts +19 -0
- package/src/core/hooks/adapter/runtime-telemetry.ts +3 -1
- package/src/core/hooks/adapter/wiring.ts +116 -8
- package/src/core/hooks/cli.ts +152 -22
- package/src/core/hooks/fork-lineage.ts +82 -0
- package/src/core/hooks/resolve/transcript.ts +88 -0
- package/src/core/hooks/run-markers.ts +132 -0
- package/src/core/hooks/shell-rm.ts +103 -0
- package/src/core/hooks/shell-tokens.ts +96 -0
- package/src/core/hooks/shell-waiter.ts +4 -91
- package/src/core/servers/index.ts +712 -0
- package/src/core/servers/net.ts +283 -0
- package/src/core/servers/tunnels.ts +39 -0
- package/src/core/storage/builtins.ts +1 -0
- package/src/core/storage/process-log.ts +17 -2
- package/src/core/workflow/engine.ts +38 -1
- package/src/core/workflow/sandbox-projection.ts +38 -2
- package/src/core/workflow/spawn-claude.ts +5 -1
- package/src/core/workflow/spawn-codex.ts +18 -1
- package/src/core/workflow/spawn-cursor.ts +5 -1
- package/src/core/workflow/spawn-opencode.ts +4 -1
- package/src/core/workflow/types.ts +62 -2
- package/src/core/workflow/worker-access.ts +525 -0
- package/src/lib/browser/batch-steps.ts +79 -0
- package/src/lib/browser/collect/collector.ts +306 -0
- package/src/lib/browser/collect/fields.ts +87 -0
- package/src/lib/browser/collect/index.ts +47 -0
- package/src/lib/browser/collect/page-driver.ts +327 -0
- package/src/lib/browser/collect/presets.ts +237 -0
- package/src/lib/browser/collect/scroll-plan.ts +179 -0
- package/src/lib/browser/index.ts +1 -0
- package/src/lib/browser/page-review-judge.ts +16 -0
- package/src/lib/browser/qa-run-contracts.ts +11 -0
- package/src/lib/browser/qa-run.ts +1 -0
- package/src/lib/browser/windows-chrome.ts +227 -0
- package/src/lib/claude-desktop-share.ts +511 -0
- package/src/lib/disk-usage.ts +347 -0
- package/src/lib/docs-lint.ts +8 -3
- package/src/lib/guarded-remove.ts +376 -0
- package/src/lib/instructions/templates.ts +8 -8
- package/src/lib/tunnel/allowlist.ts +208 -0
- package/src/lib/tunnel/current-address.ts +158 -0
- package/src/lib/tunnel/error-page.ts +25 -9
- package/src/lib/tunnel/gate.ts +38 -9
- package/src/lib/tunnel/path-scope.ts +73 -0
- package/src/lib/tunnel/processes.ts +149 -0
- package/src/lib/tunnel/state.ts +143 -30
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
1
2
|
import type { EmitContext } from "../commander.js";
|
|
2
3
|
/** bun if available (preferred), else npm. Both support `<runner> install` and `<runner> run <script>`. */
|
|
3
|
-
export declare function webRunner(): "bun" | "npm";
|
|
4
|
+
export declare function webRunner(spawn?: typeof spawnSync): "bun" | "npm";
|
|
4
5
|
/**
|
|
5
6
|
* Ensure a cached harnery checkout's `web/` exists for this version and return
|
|
6
7
|
* its path, fetching (clone + install) on first use. Returns null on failure
|
|
7
8
|
* (after emitting an actionable error).
|
|
8
9
|
*/
|
|
9
|
-
export declare function lazyFetchWebRoot(emit: EmitContext): string | null;
|
|
10
|
+
export declare function lazyFetchWebRoot(emit: EmitContext, spawn?: typeof spawnSync): string | null;
|
|
10
11
|
//# sourceMappingURL=web-fetch.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-fetch.d.ts","sourceRoot":"","sources":["../../src/commands/web-fetch.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"web-fetch.d.ts","sourceRoot":"","sources":["../../src/commands/web-fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAK/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAmDnD,2GAA2G;AAC3G,wBAAgB,SAAS,CAAC,KAAK,GAAE,OAAO,SAAqB,GAAG,KAAK,GAAG,KAAK,CAG5E;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,WAAW,EACjB,KAAK,GAAE,OAAO,SAAqB,GAClC,MAAM,GAAG,IAAI,CAyDf"}
|
|
@@ -14,9 +14,11 @@ import { fileURLToPath } from "node:url";
|
|
|
14
14
|
* harnery repo at the *matching version tag* into a cache dir and install the
|
|
15
15
|
* web app's deps. Subsequent runs reuse the cache.
|
|
16
16
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
17
|
+
* `web/` imports readers from `src/`, and `web/next.config.ts` resolves the
|
|
18
|
+
* root `playwright` package, so the install covers the repository root and
|
|
19
|
+
* then `web/`. Installing the `playwright` package downloads no browsers.
|
|
20
|
+
* Installing `web/` alone left `harn web up` failing with
|
|
21
|
+
* `Cannot find module 'playwright/package.json'`.
|
|
20
22
|
*/
|
|
21
23
|
const DEFAULT_REPO_URL = "https://github.com/ryanjkelly/harnery.git";
|
|
22
24
|
/** harnery's own package root: src/commands/ -> ../.. ; valid in both src/ and dist/. */
|
|
@@ -46,8 +48,8 @@ function webCacheRoot(ref) {
|
|
|
46
48
|
return path.join(base, "harnery", "web", safeRef);
|
|
47
49
|
}
|
|
48
50
|
/** bun if available (preferred), else npm. Both support `<runner> install` and `<runner> run <script>`. */
|
|
49
|
-
export function webRunner() {
|
|
50
|
-
const r =
|
|
51
|
+
export function webRunner(spawn = spawnSync) {
|
|
52
|
+
const r = spawn("bun", ["--version"], { stdio: "ignore" });
|
|
51
53
|
return r.status === 0 ? "bun" : "npm";
|
|
52
54
|
}
|
|
53
55
|
/**
|
|
@@ -55,13 +57,14 @@ export function webRunner() {
|
|
|
55
57
|
* its path, fetching (clone + install) on first use. Returns null on failure
|
|
56
58
|
* (after emitting an actionable error).
|
|
57
59
|
*/
|
|
58
|
-
export function lazyFetchWebRoot(emit) {
|
|
60
|
+
export function lazyFetchWebRoot(emit, spawn = spawnSync) {
|
|
59
61
|
const { version, repoUrl } = readPkg();
|
|
60
62
|
const ref = resolveRef(version);
|
|
61
63
|
const cacheRoot = webCacheRoot(ref);
|
|
62
64
|
const webDir = path.join(cacheRoot, "web");
|
|
63
|
-
// node_modules in the cached web/ is the "fetched + installed" marker.
|
|
64
|
-
if (existsSync(path.join(
|
|
65
|
+
// node_modules in both the cached root and web/ is the "fetched + installed" marker.
|
|
66
|
+
if (existsSync(path.join(cacheRoot, "node_modules")) &&
|
|
67
|
+
existsSync(path.join(webDir, "node_modules"))) {
|
|
65
68
|
emit.log(`harn web · using cached dashboard (${ref})`, "info");
|
|
66
69
|
return webDir;
|
|
67
70
|
}
|
|
@@ -71,7 +74,7 @@ export function lazyFetchWebRoot(emit) {
|
|
|
71
74
|
if (existsSync(cacheRoot))
|
|
72
75
|
rmSync(cacheRoot, { recursive: true, force: true });
|
|
73
76
|
mkdirSync(path.dirname(cacheRoot), { recursive: true });
|
|
74
|
-
const clone =
|
|
77
|
+
const clone = spawn("git", ["clone", "--depth", "1", "--branch", ref, repoUrl, cacheRoot], {
|
|
75
78
|
stdio: "inherit",
|
|
76
79
|
});
|
|
77
80
|
if (clone.status !== 0) {
|
|
@@ -84,16 +87,19 @@ export function lazyFetchWebRoot(emit) {
|
|
|
84
87
|
});
|
|
85
88
|
return null;
|
|
86
89
|
}
|
|
87
|
-
const runner = webRunner();
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
90
|
+
const runner = webRunner(spawn);
|
|
91
|
+
for (const dir of [cacheRoot, webDir]) {
|
|
92
|
+
const where = dir === webDir ? "web/" : "the harnery root";
|
|
93
|
+
emit.log(`harn web · installing dashboard deps (${runner} install in ${where})`, "info");
|
|
94
|
+
const install = spawn(runner, ["install"], { cwd: dir, stdio: "inherit" });
|
|
95
|
+
if (install.status !== 0) {
|
|
96
|
+
emit.error({
|
|
97
|
+
code: "web_fetch_failed",
|
|
98
|
+
message: `${runner} install in ${dir} failed (status ${install.status})`,
|
|
99
|
+
hint: `Try manually: cd ${dir} && ${runner} install`,
|
|
100
|
+
});
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
97
103
|
}
|
|
98
104
|
emit.log(`harn web · dashboard ready (cached at ${webDir})`, "info");
|
|
99
105
|
return webDir;
|
package/dist/commands/web.d.ts
CHANGED
|
@@ -19,7 +19,13 @@ export declare function resolveMaxOldSpaceMb(flag?: string): number;
|
|
|
19
19
|
* wins without clobbering flags the caller set (source maps, inspector, …).
|
|
20
20
|
*/
|
|
21
21
|
export declare function nodeOptionsWithHeapCap(mb: number): string | undefined;
|
|
22
|
-
/**
|
|
22
|
+
/**
|
|
23
|
+
* Preload the dashboard's server hooks (keep-alive and request diagnostics)
|
|
24
|
+
* without replacing Next's HTTP server. NODE_OPTIONS reaches the child that
|
|
25
|
+
* `next dev` forks, but Next re-parses every `--import` into one value, so
|
|
26
|
+
* this names the single combined preload; a second, different `--import`
|
|
27
|
+
* would collapse into an unloadable path (web/server-preload.mjs).
|
|
28
|
+
*/
|
|
23
29
|
export declare function nodeOptionsWithWebDiagnostics(webDir: string, mb: number): string;
|
|
24
30
|
export declare function webPerformanceLogDestination(coordRoot: string, env?: Readonly<Record<string, string | undefined>>): string;
|
|
25
31
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../../src/commands/web.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AA8CnD;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAM1D;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAKrE;AAED
|
|
1
|
+
{"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../../src/commands/web.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AA8CnD;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAM1D;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAKrE;AAED;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAKhF;AAED,wBAAgB,4BAA4B,CAC1C,SAAS,EAAE,MAAM,EACjB,GAAG,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAe,GAC9D,MAAM,CAQR;AAmDD;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAevE;AAsBD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CA2N5E"}
|
package/dist/commands/web.js
CHANGED
|
@@ -71,12 +71,18 @@ export function nodeOptionsWithHeapCap(mb) {
|
|
|
71
71
|
return inherited;
|
|
72
72
|
return `${inherited} --max-old-space-size=${mb}`.trim();
|
|
73
73
|
}
|
|
74
|
-
/**
|
|
74
|
+
/**
|
|
75
|
+
* Preload the dashboard's server hooks (keep-alive and request diagnostics)
|
|
76
|
+
* without replacing Next's HTTP server. NODE_OPTIONS reaches the child that
|
|
77
|
+
* `next dev` forks, but Next re-parses every `--import` into one value, so
|
|
78
|
+
* this names the single combined preload; a second, different `--import`
|
|
79
|
+
* would collapse into an unloadable path (web/server-preload.mjs).
|
|
80
|
+
*/
|
|
75
81
|
export function nodeOptionsWithWebDiagnostics(webDir, mb) {
|
|
76
82
|
const inherited = nodeOptionsWithHeapCap(mb) ?? "";
|
|
77
|
-
if (inherited.includes("server-
|
|
83
|
+
if (inherited.includes("server-preload.mjs"))
|
|
78
84
|
return inherited;
|
|
79
|
-
const preload = pathToFileURL(path.join(webDir, "server-
|
|
85
|
+
const preload = pathToFileURL(path.join(webDir, "server-preload.mjs")).href;
|
|
80
86
|
return `${inherited} --import=${preload}`.trim();
|
|
81
87
|
}
|
|
82
88
|
export function webPerformanceLogDestination(coordRoot, env = process.env) {
|
|
@@ -17,6 +17,9 @@ export declare const BUILTIN_ADAPTER_PROFILES: {
|
|
|
17
17
|
readonly date: "2026-08-18";
|
|
18
18
|
readonly version: "2.1.233 (Claude Code)";
|
|
19
19
|
};
|
|
20
|
+
readonly fullAccess: {
|
|
21
|
+
readonly argv: readonly ["--permission-mode", "bypassPermissions", "--settings", "{\"sandbox\":{\"enabled\":false}}"];
|
|
22
|
+
};
|
|
20
23
|
readonly capabilities: AdapterCapabilities;
|
|
21
24
|
};
|
|
22
25
|
readonly codex: {
|
|
@@ -41,6 +44,9 @@ export declare const BUILTIN_ADAPTER_PROFILES: {
|
|
|
41
44
|
};
|
|
42
45
|
readonly writableRoots: true;
|
|
43
46
|
};
|
|
47
|
+
readonly fullAccess: {
|
|
48
|
+
readonly argv: readonly ["--sandbox", "danger-full-access"];
|
|
49
|
+
};
|
|
44
50
|
readonly capabilities: AdapterCapabilities;
|
|
45
51
|
};
|
|
46
52
|
readonly cursor: {
|
|
@@ -58,6 +64,9 @@ export declare const BUILTIN_ADAPTER_PROFILES: {
|
|
|
58
64
|
readonly date: "2026-09-20";
|
|
59
65
|
readonly version: "2026.09.18-9a7762b";
|
|
60
66
|
};
|
|
67
|
+
readonly fullAccess: {
|
|
68
|
+
readonly argv: readonly ["--sandbox", "disabled"];
|
|
69
|
+
};
|
|
61
70
|
readonly capabilities: AdapterCapabilities;
|
|
62
71
|
};
|
|
63
72
|
readonly opencode: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"profiles.d.ts","sourceRoot":"","sources":["../../../src/core/adapters/profiles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAmB,MAAM,YAAY,CAAC;AAgCvF;gFACgF;AAChF,eAAO,MAAM,wBAAwB
|
|
1
|
+
{"version":3,"file":"profiles.d.ts","sourceRoot":"","sources":["../../../src/core/adapters/profiles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAmB,MAAM,YAAY,CAAC;AAgCvF;gFACgF;AAChF,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuJc,CAAC;AAEpD,MAAM,MAAM,gBAAgB,GAAG,MAAM,OAAO,wBAAwB,CAAC;AAErE,eAAO,MAAM,mBAAmB,8DAE/B,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,EAAE,IAAI,gBAAgB,CAEnE;AAED,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAE5E;AAED,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAUlF"}
|
|
@@ -41,6 +41,18 @@ export const BUILTIN_ADAPTER_PROFILES = {
|
|
|
41
41
|
modelFamily: "claude",
|
|
42
42
|
effortValues: ["low", "medium", "high", "xhigh", "max"],
|
|
43
43
|
verified: { date: "2026-08-18", version: "2.1.233 (Claude Code)" },
|
|
44
|
+
// Checked against 2.1.283 (ADR 0192). Claude Code has no sandbox mode flag;
|
|
45
|
+
// its permission mode and its optional Bash sandbox are separate, so full
|
|
46
|
+
// access needs both: bypass permissions, and a settings layer that turns
|
|
47
|
+
// the Bash sandbox off in case a user or project settings file enabled it.
|
|
48
|
+
fullAccess: {
|
|
49
|
+
argv: [
|
|
50
|
+
"--permission-mode",
|
|
51
|
+
"bypassPermissions",
|
|
52
|
+
"--settings",
|
|
53
|
+
'{"sandbox":{"enabled":false}}',
|
|
54
|
+
],
|
|
55
|
+
},
|
|
44
56
|
capabilities: capabilities({
|
|
45
57
|
effortSelection: supported("Mapped to `--effort <level>`."),
|
|
46
58
|
maxTurns: supported("Mapped to `--max-turns <n>`."),
|
|
@@ -70,6 +82,9 @@ export const BUILTIN_ADAPTER_PROFILES = {
|
|
|
70
82
|
modes: { "read-only": "read-only", "workspace-write": "workspace-write" },
|
|
71
83
|
writableRoots: true,
|
|
72
84
|
},
|
|
85
|
+
// Checked against codex-cli 0.155.1 (ADR 0192): `--sandbox` accepts
|
|
86
|
+
// danger-full-access, and `codex exec` never prompts for approval.
|
|
87
|
+
fullAccess: { argv: ["--sandbox", "danger-full-access"] },
|
|
73
88
|
capabilities: capabilities({
|
|
74
89
|
effortSelection: supported('Mapped to `-c model_reasoning_effort="<level>"`.'),
|
|
75
90
|
filesystemPolicyProjection: supported("Mode renders to --sandbox; writable roots to sandbox_workspace_write.writable_roots."),
|
|
@@ -93,6 +108,10 @@ export const BUILTIN_ADAPTER_PROFILES = {
|
|
|
93
108
|
modelFamily: "multi",
|
|
94
109
|
effortValues: [],
|
|
95
110
|
verified: { date: "2026-09-20", version: "2026.09.18-9a7762b" },
|
|
111
|
+
// Checked against 2026.09.26-dd393fe (ADR 0192): `--sandbox disabled`
|
|
112
|
+
// overrides the configured sandbox. Cursor carries effort inside the model
|
|
113
|
+
// id, so a full-access floor for it names exact model ids.
|
|
114
|
+
fullAccess: { argv: ["--sandbox", "disabled"] },
|
|
96
115
|
capabilities: capabilities({
|
|
97
116
|
effortSelection: unsupported("Cursor embeds effort in some parameterized model ids; Harnery does not rewrite model ids."),
|
|
98
117
|
maxTurns: unsupported("cursor-agent exposes no turn-ceiling flag."),
|
|
@@ -118,7 +137,9 @@ export const BUILTIN_ADAPTER_PROFILES = {
|
|
|
118
137
|
authModel: "own-auth",
|
|
119
138
|
modelFamily: "multi",
|
|
120
139
|
// Model reasoning is selected through the `provider/model#variant` id;
|
|
121
|
-
// OpenCode exposes no separate effort dial for Harnery to map.
|
|
140
|
+
// OpenCode exposes no separate effort dial for Harnery to map. It also has
|
|
141
|
+
// no vendor sandbox to remove, so it declares no full-access rendering and
|
|
142
|
+
// a worker on it is never granted one (ADR 0192).
|
|
122
143
|
effortValues: [],
|
|
123
144
|
verified: { date: "2026-09-20", version: "opencode v2.0.11" },
|
|
124
145
|
capabilities: capabilities({
|
|
@@ -42,6 +42,15 @@ export interface AdapterProfile {
|
|
|
42
42
|
/** How this adapter projects host filesystem policy into the vendor's own
|
|
43
43
|
* sandbox (ADR 0039). Absent means it cannot project any of it. */
|
|
44
44
|
sandboxProjection?: AdapterSandboxProjection;
|
|
45
|
+
/** Vendor-native arguments that launch a worker with no vendor sandbox
|
|
46
|
+
* (ADR 0192). Absent means the adapter has no distinguishable full-access
|
|
47
|
+
* mode, so a worker on it never qualifies for one. */
|
|
48
|
+
fullAccess?: AdapterFullAccessRendering;
|
|
49
|
+
}
|
|
50
|
+
/** How an adapter renders an unsandboxed launch (ADR 0192). The spawner emits
|
|
51
|
+
* exactly these arguments, so the declaration and the argv cannot drift. */
|
|
52
|
+
export interface AdapterFullAccessRendering {
|
|
53
|
+
argv: readonly string[];
|
|
45
54
|
}
|
|
46
55
|
/** Fully planned child invocation. `resultFile` is used by adapters such as
|
|
47
56
|
* Codex that deliver the authoritative final answer out-of-band. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/adapters/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAE/E;uDACuD;AACvD,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC;AAE/B,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG,SAAS,GAAG,aAAa,GAAG,SAAS,CAAC;AAEpF,eAAO,MAAM,6BAA6B,2TAoBhC,CAAC;AAEX,MAAM,MAAM,0BAA0B,GAAG,CAAC,OAAO,6BAA6B,CAAC,CAAC,MAAM,CAAC,CAAC;AAExF,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,iBAAiB,CAAC;IAC3B;iFAC6E;IAC7E,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,0BAA0B,EAAE,eAAe,CAAC,CAAC;AAEtF;;;0DAG0D;AAC1D,MAAM,WAAW,wBAAwB;IACvC,8EAA8E;IAC9E,KAAK,EAAE,MAAM,CAAC,WAAW,GAAG,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;IAC9D,iEAAiE;IACjE,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,SAAS,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,gBAAgB,CAAC;IAClC,SAAS,EAAE,UAAU,CAAC;IACtB,WAAW,EAAE,QAAQ,GAAG,KAAK,GAAG,OAAO,CAAC;IACxC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,YAAY,EAAE,mBAAmB,CAAC;IAClC,2EAA2E;IAC3E,QAAQ,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C;uEACmE;IACnE,iBAAiB,CAAC,EAAE,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/adapters/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAE/E;uDACuD;AACvD,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC;AAE/B,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG,SAAS,GAAG,aAAa,GAAG,SAAS,CAAC;AAEpF,eAAO,MAAM,6BAA6B,2TAoBhC,CAAC;AAEX,MAAM,MAAM,0BAA0B,GAAG,CAAC,OAAO,6BAA6B,CAAC,CAAC,MAAM,CAAC,CAAC;AAExF,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,iBAAiB,CAAC;IAC3B;iFAC6E;IAC7E,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,0BAA0B,EAAE,eAAe,CAAC,CAAC;AAEtF;;;0DAG0D;AAC1D,MAAM,WAAW,wBAAwB;IACvC,8EAA8E;IAC9E,KAAK,EAAE,MAAM,CAAC,WAAW,GAAG,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;IAC9D,iEAAiE;IACjE,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,SAAS,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,gBAAgB,CAAC;IAClC,SAAS,EAAE,UAAU,CAAC;IACtB,WAAW,EAAE,QAAQ,GAAG,KAAK,GAAG,OAAO,CAAC;IACxC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,YAAY,EAAE,mBAAmB,CAAC;IAClC,2EAA2E;IAC3E,QAAQ,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C;uEACmE;IACnE,iBAAiB,CAAC,EAAE,wBAAwB,CAAC;IAC7C;;0DAEsD;IACtD,UAAU,CAAC,EAAE,0BAA0B,CAAC;CACzC;AAED;4EAC4E;AAC5E,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;CACzB;AAED;oEACoE;AACpE,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,yEAAyE;AACzE,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;0BAGsB;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;kFAG8E;IAC9E,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,gBAAgB,CAAC;IACtB,QAAQ,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,GAAG,MAAM,CAAC,GAAG;QAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED;;wDAEwD;AACxD,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,cAAc,CAAC;IACxB,KAAK,EAAE,OAAO,CAAC;IACf,eAAe,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,iBAAiB,CAAC;IACnF,eAAe,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,WAAW,CAAC;IACxD,OAAO,EAAE,mBAAmB,CAAC;CAC9B"}
|
package/dist/core/agents/cli.js
CHANGED
|
@@ -279,12 +279,19 @@ async function handleStateAction(root, action, rest) {
|
|
|
279
279
|
}
|
|
280
280
|
catch (error) {
|
|
281
281
|
const detail = error instanceof Error ? error.message : String(error);
|
|
282
|
-
// A missing heartbeat
|
|
283
|
-
// while its process lived on
|
|
284
|
-
//
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
282
|
+
// A missing heartbeat usually means the session's generation ended
|
|
283
|
+
// while its process lived on, so name the reopen command (ADR 0088).
|
|
284
|
+
// A still-live generation whose authority the ledger withholds looks
|
|
285
|
+
// the same here; name its diagnostics instead, since reopen cannot apply.
|
|
286
|
+
const { describeLiveAuthorityBlockV3, liveAuthorityBlockHintV3, liveAuthorityBlockV3 } = await import("./state/live-coordination-view.js");
|
|
287
|
+
const block = detail.includes("heartbeat_missing:")
|
|
288
|
+
? liveAuthorityBlockV3(root, owner)
|
|
289
|
+
: null;
|
|
290
|
+
const hint = block
|
|
291
|
+
? `; ${describeLiveAuthorityBlockV3(block)}; ${liveAuthorityBlockHintV3(resolveBinName(root))}`
|
|
292
|
+
: detail.includes("heartbeat_missing:")
|
|
293
|
+
? `; run \`${resolveBinName(root)} agents lifecycle active\` to open a fresh generation for this continuing session`
|
|
294
|
+
: "";
|
|
288
295
|
process.stderr.write(`agent-coord set-task: V3 authority refused (${detail})${hint}\n`);
|
|
289
296
|
return 1;
|
|
290
297
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt-context.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/render/prompt-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;
|
|
1
|
+
{"version":3,"file":"prompt-context.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/render/prompt-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAiDH,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;8EAC0E;IAC1E,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;kFAC8E;IAC9E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;kFAC8E;IAC9E,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;uEACmE;IACnE,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;wBAIoB;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAkFnE;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CA6CtF"}
|
|
@@ -43,6 +43,7 @@ import { drainMailbox, formatMailboxDelivery } from "../mailbox.js";
|
|
|
43
43
|
import { sessionNameDisplayBlock, sessionNameDisplayPending } from "../session-name-display.js";
|
|
44
44
|
import { heartbeatPath } from "../state/heartbeat-reader.js";
|
|
45
45
|
import { readLiveCoordinationRow, readLiveCoordinationRows, } from "../state/live-coordination-view.js";
|
|
46
|
+
import { forkRelationLabels } from "../state/names.js";
|
|
46
47
|
import { formatPendingCouncils, recordDeliveredMessages } from "./session-context.js";
|
|
47
48
|
/**
|
|
48
49
|
* Build the combined UserPromptSubmit additionalContext string. Returns "" when
|
|
@@ -337,7 +338,7 @@ function computePeerTableIfChanged(coordRoot, selfInstanceId, selfSessionIdFallb
|
|
|
337
338
|
if (oldHash && oldHash === newHash)
|
|
338
339
|
return "";
|
|
339
340
|
// Render peer table via the same formatter used at SessionStart.
|
|
340
|
-
const local = formatPeerTable(peers, mySessionId);
|
|
341
|
+
const local = formatPeerTable(peers, mySessionId, forkRelationLabels(coordRoot, selfInstanceId, new Set(peers.map((p) => p.instance_id ?? ""))));
|
|
341
342
|
const remoteTable = formatRemoteTable(remote);
|
|
342
343
|
const table = [local, remoteTable].filter(Boolean).join("\n\n");
|
|
343
344
|
if (!table)
|
|
@@ -458,7 +459,7 @@ function writeHashFile(path, value) {
|
|
|
458
459
|
* intentionally co-located here so the prompt-context renderer is self-contained
|
|
459
460
|
* (no cross-file imports of formatting internals). If both renderers diverge,
|
|
460
461
|
* pull the shared bits into a small util module. */
|
|
461
|
-
function formatPeerTable(peers, mySessionId) {
|
|
462
|
+
function formatPeerTable(peers, mySessionId, relations = new Map()) {
|
|
462
463
|
if (peers.length === 0)
|
|
463
464
|
return "";
|
|
464
465
|
const nowSec = Math.floor(Date.now() / 1000);
|
|
@@ -474,9 +475,13 @@ function formatPeerTable(peers, mySessionId) {
|
|
|
474
475
|
.map((p) => {
|
|
475
476
|
const folded = fold[p.instance_id ?? ""] ?? [];
|
|
476
477
|
const display = Array.from(new Set([...(p.files_touched ?? []), ...folded])).sort();
|
|
477
|
-
|
|
478
|
+
const relation = relations.get(p.instance_id ?? "");
|
|
479
|
+
return { ...p, display_files: display, ...(relation ? { relation } : {}) };
|
|
478
480
|
});
|
|
479
|
-
|
|
481
|
+
// Related sessions sort first so a fork parent never hides in "+N more".
|
|
482
|
+
const blocking = rows
|
|
483
|
+
.filter((p) => p.session_id !== mySessionId)
|
|
484
|
+
.sort((a, b) => Number(!!b.relation) - Number(!!a.relation) || byStartedAt(a, b));
|
|
480
485
|
const group = rows.filter((p) => p.session_id === mySessionId).sort(byStartedAt);
|
|
481
486
|
const out = [];
|
|
482
487
|
const blk = renderSubtable(blocking, "Other agent groups active (their files block you):", nowSec);
|
|
@@ -508,7 +513,8 @@ function formatRow(r, nowSec) {
|
|
|
508
513
|
// Prefer a short instance_id over a bare "unknown" so an incomplete row is
|
|
509
514
|
// still identifiable.
|
|
510
515
|
const label = r.name ?? (r.instance_id ? r.instance_id.slice(0, 8) : "unknown");
|
|
511
|
-
|
|
516
|
+
const relation = r.relation ? ` [${r.relation}]` : "";
|
|
517
|
+
return ` - agent-${label}${relation}${taskPart} (${statePart}, ${ageFrom}, ${filesPart})`;
|
|
512
518
|
}
|
|
513
519
|
function formatState(r) {
|
|
514
520
|
const activity = r.activity ?? "unknown";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-context.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/render/session-context.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAyC,QAAQ,EAAE,MAAM,SAAS,CAAC;AAM1E,OAAO,EAAuC,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAoB3F,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;+BAC2B;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"session-context.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/render/session-context.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAyC,QAAQ,EAAE,MAAM,SAAS,CAAC;AAM1E,OAAO,EAAuC,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAoB3F,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;+BAC2B;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAiG7D;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,SAAS,gBAAgB,EAAE,GACpC,IAAI,CAUN;AA6LD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAwBvD;AA0DD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAiDlF;AAED;;;GAGG;AACH,eAAO,MAAM,uBAAuB,iBAAW,CAAC"}
|
|
@@ -15,7 +15,7 @@ import { appendEntry } from "../../journal/index.js";
|
|
|
15
15
|
import { readRemoteMachines } from "../../presence/index.js";
|
|
16
16
|
import { drainMailbox, formatMailboxDelivery } from "../mailbox.js";
|
|
17
17
|
import { readLiveCoordinationRows } from "../state/live-coordination-view.js";
|
|
18
|
-
import {
|
|
18
|
+
import { forkRelationLabels, readForkState } from "../state/names.js";
|
|
19
19
|
/**
|
|
20
20
|
* Build the combined SessionStart systemMessage. Returns the additionalContext
|
|
21
21
|
* string (or "" if there's nothing to say).
|
|
@@ -25,7 +25,13 @@ export function renderSessionContext(opts) {
|
|
|
25
25
|
const messages = [];
|
|
26
26
|
// 1. Self-name line + peer table (folded if peers present)
|
|
27
27
|
const peers = readActivePeers(coordRoot, instanceId);
|
|
28
|
-
const
|
|
28
|
+
const forkState = readForkState(coordRoot, instanceId);
|
|
29
|
+
const forkParent = forkState?.parent ?? null;
|
|
30
|
+
const parentRow = forkParent
|
|
31
|
+
? peers.find((peer) => peer.instance_id === forkParent.instance_id)
|
|
32
|
+
: undefined;
|
|
33
|
+
const relations = forkRelationLabels(coordRoot, instanceId, new Set(peers.map((peer) => peer.instance_id ?? "")));
|
|
34
|
+
const localTable = formatPeerTable(peers, sessionId, relations);
|
|
29
35
|
// Cross-machine presence (ADR 0016): sessions on other machines (advisory).
|
|
30
36
|
const peerTable = [localTable, formatRemoteMachines(coordRoot)].filter(Boolean).join("\n\n");
|
|
31
37
|
if (agentName) {
|
|
@@ -35,13 +41,11 @@ export function renderSessionContext(opts) {
|
|
|
35
41
|
// asserts the parent's name, claims, and task. When recorded fork lineage
|
|
36
42
|
// (.name-history forked_from) names the parent, say so specifically — the
|
|
37
43
|
// fork is about to read a transcript full of that exact name. Otherwise
|
|
38
|
-
// fall back to the generic clause, which needs no fork detection.
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
? `This conversation was branched from another session (${forkParent.instance_id}); any agent name in earlier context belongs to that session, not to you.`
|
|
44
|
-
: "Any different agent name in earlier context was inherited from another session; this one is authoritative.";
|
|
44
|
+
// fall back to the generic clause, which needs no fork detection. A live
|
|
45
|
+
// parent is the dangerous case (2026-10-07: a fork read its running
|
|
46
|
+
// parent as its own earlier self and offered to close it), so the notice
|
|
47
|
+
// names what the parent is doing and forbids ending it.
|
|
48
|
+
const authority = forkAuthorityClause(forkParent, forkState?.fork === true, parentRow);
|
|
45
49
|
const selfLine = `You are agent-${agentName}${suffix}. ${authority}`;
|
|
46
50
|
messages.push(peerTable ? `${selfLine}\n\n${peerTable}` : selfLine);
|
|
47
51
|
}
|
|
@@ -93,6 +97,8 @@ export function renderSessionContext(opts) {
|
|
|
93
97
|
bits.push(`missing: ${d.missing.map((m) => m.subcommand).join(", ")}`);
|
|
94
98
|
if (d.orphans.length > 0)
|
|
95
99
|
bits.push(`orphaned: ${d.orphans.join(", ")}`);
|
|
100
|
+
if (d.stale.length > 0)
|
|
101
|
+
bits.push(`outdated: ${d.stale.map((m) => m.subcommand).join(", ")}`);
|
|
96
102
|
return ` - ${d.settingsFile} — ${bits.join("; ")}`;
|
|
97
103
|
});
|
|
98
104
|
messages.push(`Harnery hook wiring is out of date${verPart}: an upgrade changed the hook set but the adapter ` +
|
|
@@ -149,13 +155,48 @@ function formatRemoteMachines(coordRoot) {
|
|
|
149
155
|
function readActivePeers(coordRoot, selfInstanceId) {
|
|
150
156
|
return readLiveCoordinationRows(coordRoot).filter((heartbeat) => heartbeat.instance_id && heartbeat.instance_id !== selfInstanceId);
|
|
151
157
|
}
|
|
158
|
+
const DO_NOT_END = "Do not end, release, or finalize that session unless the operator explicitly tells you to.";
|
|
159
|
+
function forkAuthorityClause(parent, fork, parentRow) {
|
|
160
|
+
if (parent?.name && parentRow) {
|
|
161
|
+
const files = parentRow.files_touched ?? [];
|
|
162
|
+
const task = parentRow.task ? ` on "${parentRow.task.slice(0, 80)}"` : "";
|
|
163
|
+
const holds = files.length > 0
|
|
164
|
+
? ` and holds ${files.length} file${files.length === 1 ? "" : "s"} (${fmtFileList(files)})`
|
|
165
|
+
: "";
|
|
166
|
+
const owned = files.length > 0
|
|
167
|
+
? parentRow.task
|
|
168
|
+
? "That name, task, and those files"
|
|
169
|
+
: "That name and those files"
|
|
170
|
+
: parentRow.task
|
|
171
|
+
? "That name and task"
|
|
172
|
+
: "That name";
|
|
173
|
+
return (`This conversation was forked from agent-${parent.name}, which is still running as a separate session${task}${holds}. ` +
|
|
174
|
+
`${owned} belong${owned === "That name" ? "s" : ""} to agent-${parent.name}, not to you. ${DO_NOT_END}`);
|
|
175
|
+
}
|
|
176
|
+
if (parent?.name) {
|
|
177
|
+
return `This conversation was branched from agent-${parent.name}'s session: earlier context showing agent-${parent.name}'s name, task, or file claims belongs to the pre-fork session, not to you.`;
|
|
178
|
+
}
|
|
179
|
+
if (parent) {
|
|
180
|
+
return `This conversation was branched from another session (${parent.instance_id}); any agent name in earlier context belongs to that session, not to you.`;
|
|
181
|
+
}
|
|
182
|
+
if (fork) {
|
|
183
|
+
return `This conversation was forked from another session, which may still be running. Any agent name, task, or file claim in earlier context belongs to that session, not to you. ${DO_NOT_END}`;
|
|
184
|
+
}
|
|
185
|
+
return "Any different agent name in earlier context was inherited from another session; this one is authoritative.";
|
|
186
|
+
}
|
|
187
|
+
function fmtFileList(files) {
|
|
188
|
+
const sorted = [...files].sort();
|
|
189
|
+
return sorted.length <= 3
|
|
190
|
+
? sorted.join(", ")
|
|
191
|
+
: `${sorted.slice(0, 3).join(", ")}, +${sorted.length - 3} more`;
|
|
192
|
+
}
|
|
152
193
|
/**
|
|
153
194
|
* Renders the peer table as
|
|
154
195
|
* two subsections: "Other agent groups active" (blocking) and "Your group"
|
|
155
196
|
* (subagents/siblings, no mutual block). Folds transient subagents' files
|
|
156
197
|
* into their parent session.
|
|
157
198
|
*/
|
|
158
|
-
function formatPeerTable(peers, mySessionId) {
|
|
199
|
+
function formatPeerTable(peers, mySessionId, relations = new Map()) {
|
|
159
200
|
if (peers.length === 0)
|
|
160
201
|
return "";
|
|
161
202
|
const nowSec = Math.floor(Date.now() / 1000);
|
|
@@ -172,9 +213,13 @@ function formatPeerTable(peers, mySessionId) {
|
|
|
172
213
|
.map((p) => {
|
|
173
214
|
const folded = fold[p.instance_id ?? ""] ?? [];
|
|
174
215
|
const display = Array.from(new Set([...(p.files_touched ?? []), ...folded])).sort();
|
|
175
|
-
|
|
216
|
+
const relation = relations.get(p.instance_id ?? "");
|
|
217
|
+
return { ...p, display_files: display, ...(relation ? { relation } : {}) };
|
|
176
218
|
});
|
|
177
|
-
|
|
219
|
+
// Related sessions sort first so the parent never hides in "+N more".
|
|
220
|
+
const blocking = rows
|
|
221
|
+
.filter((p) => p.session_id !== mySessionId)
|
|
222
|
+
.sort((a, b) => Number(!!b.relation) - Number(!!a.relation) || byStartedAt(a, b));
|
|
178
223
|
const group = rows.filter((p) => p.session_id === mySessionId).sort(byStartedAt);
|
|
179
224
|
const sections = [];
|
|
180
225
|
const blockingSection = renderSubtable(blocking, "Other agent groups active (their files block you):", nowSec);
|
|
@@ -202,7 +247,8 @@ function formatRow(r, nowSec) {
|
|
|
202
247
|
const reason = lifecycle === "blocked" && r.task_state_reason ? `: ${r.task_state_reason.slice(0, 80)}` : "";
|
|
203
248
|
const ageFrom = fmtAge(nowSec - parseIsoSec(r.started_at));
|
|
204
249
|
const filesPart = fmtFiles(r.display_files);
|
|
205
|
-
|
|
250
|
+
const relation = r.relation ? ` [${r.relation}]` : "";
|
|
251
|
+
return ` - agent-${r.name ?? "unknown"}${relation}${taskPart} (activity=${activity}, lifecycle=${lifecycle}${reason}, ${ageFrom}, ${filesPart})`;
|
|
206
252
|
}
|
|
207
253
|
function fmtFiles(files) {
|
|
208
254
|
if (files.length === 0)
|
|
@@ -26,4 +26,24 @@ export declare function isCurrentV3HeartbeatCache(cache: Heartbeat | null | unde
|
|
|
26
26
|
export declare function projectHeartbeatV3(coordRoot: string, generation: CoordinationGenerationViewV3, cache: Heartbeat | undefined, nativeInstanceId: string | undefined, parent?: CoordinationGenerationViewV3): V3HeartbeatMaterialization;
|
|
27
27
|
export declare function observedAdapterV3(generation: CoordinationGenerationViewV3): string | undefined;
|
|
28
28
|
export declare function isAdapterV3(value: string | undefined): value is EventAdapterIdV3;
|
|
29
|
+
/** Why a still-live V3 generation has lost coordination authority. */
|
|
30
|
+
export interface LiveAuthorityBlockV3 {
|
|
31
|
+
generation_id: string;
|
|
32
|
+
scope: "generation" | "ledger";
|
|
33
|
+
diagnostics: {
|
|
34
|
+
code: string;
|
|
35
|
+
event_id?: string;
|
|
36
|
+
}[];
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Explain an authority refusal for a generation that is still live. Callers
|
|
40
|
+
* reach this after a lookup came back empty; without it the caller sees only
|
|
41
|
+
* "missing", which reads like an ended session and points at a reopen that
|
|
42
|
+
* cannot apply. Returns null when no live generation exists or nothing blocks.
|
|
43
|
+
*/
|
|
44
|
+
export declare function liveAuthorityBlockV3(coordRoot: string, nativeInstanceId: string): LiveAuthorityBlockV3 | null;
|
|
45
|
+
/** One-line description of a live authority block, naming codes and events. */
|
|
46
|
+
export declare function describeLiveAuthorityBlockV3(block: LiveAuthorityBlockV3): string;
|
|
47
|
+
/** Recovery pointer for a live authority block, in place of the reopen hint. */
|
|
48
|
+
export declare function liveAuthorityBlockHintV3(binName: string): string;
|
|
29
49
|
//# sourceMappingURL=live-coordination-view.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"live-coordination-view.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/live-coordination-view.ts"],"names":[],"mappings":"AAEA,OAAO,EAAwB,KAAK,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAC5F,OAAO,EACL,KAAK,4BAA4B,EAIlC,MAAM,sCAAsC,CAAC;AAM9C,OAAO,EAAE,KAAK,SAAS,EAAiB,MAAM,uBAAuB,CAAC;AAGtE;;;GAGG;AACH,MAAM,WAAW,0BAA2B,SAAQ,SAAS;IAC3D,cAAc,EAAE,CAAC,CAAC;IAClB,cAAc,EAAE,QAAQ,MAAM,EAAE,CAAC;IACjC,gBAAgB,EAAE,OAAO,MAAM,EAAE,CAAC;IAClC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,aAAa,EAAE,KAAK,GAAG,SAAS,CAAC;CAClC;AAED,yEAAyE;AACzE,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,0BAA0B,EAAE,CA2BxF;AAED,kEAAkE;AAClE,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,GACvB,0BAA0B,GAAG,IAAI,CAuBnC;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,GACvB,gBAAgB,GAAG,IAAI,CAWzB;AA8BD,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,EACnC,UAAU,EAAE,4BAA4B,GACvC,KAAK,IAAI,SAAS,CAMpB;AAED,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,4BAA4B,EACxC,KAAK,EAAE,SAAS,GAAG,SAAS,EAC5B,gBAAgB,EAAE,MAAM,GAAG,SAAS,EACpC,MAAM,CAAC,EAAE,4BAA4B,GACpC,0BAA0B,CAuD5B;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,4BAA4B,GAAG,MAAM,GAAG,SAAS,CAG9F;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,KAAK,IAAI,gBAAgB,CAEhF"}
|
|
1
|
+
{"version":3,"file":"live-coordination-view.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/live-coordination-view.ts"],"names":[],"mappings":"AAEA,OAAO,EAAwB,KAAK,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAC5F,OAAO,EACL,KAAK,4BAA4B,EAIlC,MAAM,sCAAsC,CAAC;AAM9C,OAAO,EAAE,KAAK,SAAS,EAAiB,MAAM,uBAAuB,CAAC;AAGtE;;;GAGG;AACH,MAAM,WAAW,0BAA2B,SAAQ,SAAS;IAC3D,cAAc,EAAE,CAAC,CAAC;IAClB,cAAc,EAAE,QAAQ,MAAM,EAAE,CAAC;IACjC,gBAAgB,EAAE,OAAO,MAAM,EAAE,CAAC;IAClC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,aAAa,EAAE,KAAK,GAAG,SAAS,CAAC;CAClC;AAED,yEAAyE;AACzE,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,0BAA0B,EAAE,CA2BxF;AAED,kEAAkE;AAClE,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,GACvB,0BAA0B,GAAG,IAAI,CAuBnC;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,GACvB,gBAAgB,GAAG,IAAI,CAWzB;AA8BD,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,EACnC,UAAU,EAAE,4BAA4B,GACvC,KAAK,IAAI,SAAS,CAMpB;AAED,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,4BAA4B,EACxC,KAAK,EAAE,SAAS,GAAG,SAAS,EAC5B,gBAAgB,EAAE,MAAM,GAAG,SAAS,EACpC,MAAM,CAAC,EAAE,4BAA4B,GACpC,0BAA0B,CAuD5B;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,4BAA4B,GAAG,MAAM,GAAG,SAAS,CAG9F;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,KAAK,IAAI,gBAAgB,CAEhF;AAWD,sEAAsE;AACtE,MAAM,WAAW,oBAAoB;IACnC,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,YAAY,GAAG,QAAQ,CAAC;IAC/B,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACpD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,GACvB,oBAAoB,GAAG,IAAI,CA2B7B;AAED,+EAA+E;AAC/E,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,oBAAoB,GAAG,MAAM,CAiBhF;AAED,gFAAgF;AAChF,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAKhE"}
|
|
@@ -159,3 +159,63 @@ function observedModel(generation) {
|
|
|
159
159
|
function isLifecycleState(value) {
|
|
160
160
|
return value === "active" || value === "blocked" || value === "done";
|
|
161
161
|
}
|
|
162
|
+
/**
|
|
163
|
+
* Explain an authority refusal for a generation that is still live. Callers
|
|
164
|
+
* reach this after a lookup came back empty; without it the caller sees only
|
|
165
|
+
* "missing", which reads like an ended session and points at a reopen that
|
|
166
|
+
* cannot apply. Returns null when no live generation exists or nothing blocks.
|
|
167
|
+
*/
|
|
168
|
+
export function liveAuthorityBlockV3(coordRoot, nativeInstanceId) {
|
|
169
|
+
let view;
|
|
170
|
+
try {
|
|
171
|
+
if (observeLiveEventLedgerRouteV3(coordRoot).state === "blocked")
|
|
172
|
+
return null;
|
|
173
|
+
view = readCoordinationViewV3(coordRoot);
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
const generation = view.instances[liveInstanceIdV3(nativeInstanceId)];
|
|
179
|
+
if (generation?.phase !== "live" || generation.authority_eligible)
|
|
180
|
+
return null;
|
|
181
|
+
const own = (view.diagnostics_by_generation[generation.generation_id] ?? []).filter((diagnostic) => diagnostic.authority_blocking);
|
|
182
|
+
const blocking = own.length
|
|
183
|
+
? own
|
|
184
|
+
: view.global_diagnostics.filter((diagnostic) => diagnostic.authority_blocking);
|
|
185
|
+
if (!blocking.length)
|
|
186
|
+
return null;
|
|
187
|
+
return {
|
|
188
|
+
generation_id: generation.generation_id,
|
|
189
|
+
scope: own.length ? "generation" : "ledger",
|
|
190
|
+
diagnostics: blocking.map((diagnostic) => ({
|
|
191
|
+
code: diagnostic.source_code
|
|
192
|
+
? `${diagnostic.code}:${diagnostic.source_code}`
|
|
193
|
+
: diagnostic.code,
|
|
194
|
+
...(diagnostic.event_id ? { event_id: diagnostic.event_id } : {}),
|
|
195
|
+
})),
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
/** One-line description of a live authority block, naming codes and events. */
|
|
199
|
+
export function describeLiveAuthorityBlockV3(block) {
|
|
200
|
+
const byCode = new Map();
|
|
201
|
+
for (const { code, event_id } of block.diagnostics) {
|
|
202
|
+
const events = byCode.get(code) ?? [];
|
|
203
|
+
if (event_id)
|
|
204
|
+
events.push(event_id);
|
|
205
|
+
byCode.set(code, events);
|
|
206
|
+
}
|
|
207
|
+
const parts = [...byCode].map(([code, events]) => {
|
|
208
|
+
const shown = events.slice(0, 2).join(", ");
|
|
209
|
+
const more = events.length > 2 ? `, +${events.length - 2} more` : "";
|
|
210
|
+
return events.length ? `${code} ×${events.length} (${shown}${more})` : code;
|
|
211
|
+
});
|
|
212
|
+
const where = block.scope === "generation"
|
|
213
|
+
? `the event ledger holds ${block.diagnostics.length} authority-blocking diagnostic(s) for it`
|
|
214
|
+
: "the event ledger holds authority-blocking diagnostics that block every generation";
|
|
215
|
+
return `generation ${block.generation_id} is still live, but ${where}: ${parts.join("; ")}`;
|
|
216
|
+
}
|
|
217
|
+
/** Recovery pointer for a live authority block, in place of the reopen hint. */
|
|
218
|
+
export function liveAuthorityBlockHintV3(binName) {
|
|
219
|
+
return (`\`${binName} agents lifecycle active\` cannot help because it only reopens an ended ` +
|
|
220
|
+
`generation; \`${binName} agents health\` lists the diagnostics`);
|
|
221
|
+
}
|