@sentropic/h2a-runtime 0.98.7-rc.4 → 0.98.7-rc.7
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/agy-claude.d.ts +41 -1
- package/dist/agy-claude.d.ts.map +1 -1
- package/dist/agy-claude.js +147 -2
- package/dist/agy-claude.js.map +1 -1
- package/dist/central-mcp.d.ts +32 -0
- package/dist/central-mcp.d.ts.map +1 -1
- package/dist/central-mcp.js +186 -69
- package/dist/central-mcp.js.map +1 -1
- package/dist/conv-guard.d.ts.map +1 -1
- package/dist/conv-guard.js +6 -2
- package/dist/conv-guard.js.map +1 -1
- package/dist/file-lock.d.ts +4 -2
- package/dist/file-lock.d.ts.map +1 -1
- package/dist/file-lock.js +24 -10
- package/dist/file-lock.js.map +1 -1
- package/dist/gateway-host/config-file.d.ts +2 -0
- package/dist/gateway-host/config-file.d.ts.map +1 -1
- package/dist/gateway-host/config-file.js +5 -1
- package/dist/gateway-host/config-file.js.map +1 -1
- package/dist/gateway-host/daemon.d.ts.map +1 -1
- package/dist/gateway-host/daemon.js +1 -2
- package/dist/gateway-host/daemon.js.map +1 -1
- package/dist/identity-cull/cull.js +1 -1
- package/dist/identity-cull/cull.js.map +1 -1
- package/dist/identity-cull/identity-fence.d.ts +48 -0
- package/dist/identity-cull/identity-fence.d.ts.map +1 -0
- package/dist/identity-cull/identity-fence.js +221 -0
- package/dist/identity-cull/identity-fence.js.map +1 -0
- package/dist/identity-operator-break.d.ts +43 -0
- package/dist/identity-operator-break.d.ts.map +1 -0
- package/dist/identity-operator-break.js +85 -0
- package/dist/identity-operator-break.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +59 -34
- package/dist/index.js.map +1 -1
- package/dist/llm-mesh-accounts.d.ts +2 -2
- package/dist/llm-mesh-accounts.d.ts.map +1 -1
- package/dist/llm-mesh-accounts.js +3 -5
- package/dist/llm-mesh-accounts.js.map +1 -1
- package/dist/native-host.d.ts +21 -0
- package/dist/native-host.d.ts.map +1 -1
- package/dist/native-host.js +163 -5
- package/dist/native-host.js.map +1 -1
- package/dist/native-terminal/fleet.d.ts +11 -0
- package/dist/native-terminal/fleet.d.ts.map +1 -1
- package/dist/native-terminal/fleet.js +58 -1
- package/dist/native-terminal/fleet.js.map +1 -1
- package/dist/native-terminal/host-scope.d.ts +18 -0
- package/dist/native-terminal/host-scope.d.ts.map +1 -0
- package/dist/native-terminal/host-scope.js +65 -0
- package/dist/native-terminal/host-scope.js.map +1 -0
- package/dist/native-terminal/host.d.ts +1 -0
- package/dist/native-terminal/host.d.ts.map +1 -1
- package/dist/native-terminal/host.js +4 -1
- package/dist/native-terminal/host.js.map +1 -1
- package/dist/native-terminal/op.d.ts +36 -1
- package/dist/native-terminal/op.d.ts.map +1 -1
- package/dist/native-terminal/op.js +190 -33
- package/dist/native-terminal/op.js.map +1 -1
- package/dist/native-terminal/process.d.ts.map +1 -1
- package/dist/native-terminal/process.js +10 -1
- package/dist/native-terminal/process.js.map +1 -1
- package/dist/native-terminal/screen.d.ts.map +1 -1
- package/dist/native-terminal/screen.js +1 -1
- package/dist/native-terminal/screen.js.map +1 -1
- package/dist/native-terminal/server.d.ts +12 -2
- package/dist/native-terminal/server.d.ts.map +1 -1
- package/dist/native-terminal/server.js +143 -42
- package/dist/native-terminal/server.js.map +1 -1
- package/dist/native-terminal/session-scope.d.ts +2 -0
- package/dist/native-terminal/session-scope.d.ts.map +1 -0
- package/dist/native-terminal/session-scope.js +32 -0
- package/dist/native-terminal/session-scope.js.map +1 -0
- package/dist/registry.d.ts +5 -12
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +20 -3
- package/dist/registry.js.map +1 -1
- package/dist/restore.d.ts.map +1 -1
- package/dist/restore.js +5 -37
- package/dist/restore.js.map +1 -1
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +3 -3
- package/dist/run.js.map +1 -1
- package/dist/tmux.d.ts +1 -1
- package/dist/tmux.d.ts.map +1 -1
- package/dist/tmux.js +34 -2
- package/dist/tmux.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime-owned fail-closed identity fence for the cull staging path.
|
|
3
|
+
*
|
|
4
|
+
* Why this file exists: `identity-cull/cull.ts` verifies a held-descriptor
|
|
5
|
+
* CAS while holding the canonical `identity/.lock`. That hold used to come
|
|
6
|
+
* from `@sentropic/h2a` (`withIdentityFenceSync`), an undeclared
|
|
7
|
+
* runtime→core edge that broke isolated installs of this package
|
|
8
|
+
* (`ERR_MODULE_NOT_FOUND` before any verb ran). This module gives the
|
|
9
|
+
* staging verification a runtime-owned hold instead: exclusive-create,
|
|
10
|
+
* protocol-compatible v2 records, still-held checks, bounded wait.
|
|
11
|
+
*
|
|
12
|
+
* What this module is NOT: it is not the succession protocol. It never
|
|
13
|
+
* elects a successor, never reaps legacy records, never retires anything.
|
|
14
|
+
* Every uncertain outcome fails closed (wait, then `LockTimeoutError`, which
|
|
15
|
+
* the caller maps to ABORTED) — never a takeover, never a silent pass.
|
|
16
|
+
*
|
|
17
|
+
* Interop contract with the core reader (pinned by
|
|
18
|
+
* `packages/h2a/test/identity-lock-v6.test.js` R1/R2 and by the parity test
|
|
19
|
+
* in `cull.test.ts`, which reads our held record through the core parser):
|
|
20
|
+
* the held file carries EXACTLY the v2 key set, `recordVersion: 2`,
|
|
21
|
+
* `protocol: "identity-binding-fence-v1"`, `publication: "link"`. A live
|
|
22
|
+
* holder pid makes core wait; a crashed holder is recovered by core's own
|
|
23
|
+
* dead-holder path. `hostKind: "weak"` with null anchors is deliberate:
|
|
24
|
+
* staging holds assert nothing about machine identity, and the core parser
|
|
25
|
+
* accepts weak records while treating them conservatively.
|
|
26
|
+
*
|
|
27
|
+
* Stale takeover is deliberately narrow: only a record that parses as valid
|
|
28
|
+
* v2 AND names a pid that `kill(pid, 0)` proves absent (ESRCH) is unlinked.
|
|
29
|
+
* EPERM (alive but unpermissioned), unparseable content, and non-positive
|
|
30
|
+
* pids are hands-off: wait for the timeout, then fail closed.
|
|
31
|
+
*/
|
|
32
|
+
import { closeSync, fsyncSync, openSync, readFileSync, unlinkSync, writeSync } from "node:fs";
|
|
33
|
+
export const IDENTITY_BINDING_FENCE_PROTOCOL = "identity-binding-fence-v1";
|
|
34
|
+
const LOCK_RECORD_MODE = 0o600;
|
|
35
|
+
const DEFAULT_TIMEOUT_MS = 5000;
|
|
36
|
+
const DEFAULT_POLL_MS = 50;
|
|
37
|
+
/** Thrown when the hold cannot be acquired within the bounded budget. The
|
|
38
|
+
* `name` matches the core fence timeout so callers mapping by name keep
|
|
39
|
+
* working across the layering boundary. */
|
|
40
|
+
export class FenceTimeoutError extends Error {
|
|
41
|
+
name = "LockTimeoutError";
|
|
42
|
+
constructor(lockPath, timeoutMs) {
|
|
43
|
+
super(`identity fence unavailable: ${lockPath} stayed held for ${timeoutMs} ms`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function newToken() {
|
|
47
|
+
const bytes = new Uint32Array(4);
|
|
48
|
+
crypto.getRandomValues(bytes);
|
|
49
|
+
return [...bytes].map((word) => word.toString(16).padStart(8, "0")).join("");
|
|
50
|
+
}
|
|
51
|
+
function readHeldToken(lockPath) {
|
|
52
|
+
let raw;
|
|
53
|
+
try {
|
|
54
|
+
raw = readFileSync(lockPath, "utf8");
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
let value;
|
|
60
|
+
try {
|
|
61
|
+
value = JSON.parse(raw);
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
67
|
+
return undefined;
|
|
68
|
+
const record = value;
|
|
69
|
+
const allowed = new Set([
|
|
70
|
+
"recordVersion", "protocol", "platform", "publication", "hostKind", "host",
|
|
71
|
+
"boot", "ns", "timeNs", "pid", "start", "token", "fenceEpoch", "at",
|
|
72
|
+
"target", "operator",
|
|
73
|
+
]);
|
|
74
|
+
if (!Object.keys(record).every((key) => allowed.has(key)))
|
|
75
|
+
return undefined;
|
|
76
|
+
if (record["recordVersion"] !== 2 || record["protocol"] !== IDENTITY_BINDING_FENCE_PROTOCOL)
|
|
77
|
+
return undefined;
|
|
78
|
+
if (record["publication"] !== "link" && record["publication"] !== "o-excl")
|
|
79
|
+
return undefined;
|
|
80
|
+
if (typeof record["token"] !== "string" || !/^[0-9a-f]{32}$/.test(record["token"]))
|
|
81
|
+
return undefined;
|
|
82
|
+
if (record["fenceEpoch"] !== record["token"])
|
|
83
|
+
return undefined;
|
|
84
|
+
if (typeof record["pid"] !== "number" || !Number.isSafeInteger(record["pid"]))
|
|
85
|
+
return undefined;
|
|
86
|
+
return record.token;
|
|
87
|
+
}
|
|
88
|
+
function recordPid(lockPath) {
|
|
89
|
+
let raw;
|
|
90
|
+
try {
|
|
91
|
+
raw = readFileSync(lockPath, "utf8");
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
96
|
+
try {
|
|
97
|
+
const value = JSON.parse(raw);
|
|
98
|
+
return typeof value.pid === "number" && Number.isSafeInteger(value.pid) && value.pid > 0
|
|
99
|
+
? value.pid
|
|
100
|
+
: undefined;
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
return undefined;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
function holderProvenDead(pid) {
|
|
107
|
+
try {
|
|
108
|
+
process.kill(pid, 0);
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
return error.code === "ESRCH";
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
function platform() {
|
|
116
|
+
const p = process.platform;
|
|
117
|
+
return p === "linux" || p === "darwin" || p === "win32" ? p : "other";
|
|
118
|
+
}
|
|
119
|
+
function writeHoldRecord(lockPath, token) {
|
|
120
|
+
// Exactly the v2 key set — no extras (the core reader rejects unknown
|
|
121
|
+
// fields), weak anchors (staging asserts no machine identity).
|
|
122
|
+
const record = {
|
|
123
|
+
recordVersion: 2,
|
|
124
|
+
protocol: IDENTITY_BINDING_FENCE_PROTOCOL,
|
|
125
|
+
platform: platform(),
|
|
126
|
+
publication: "link",
|
|
127
|
+
hostKind: "weak",
|
|
128
|
+
host: null,
|
|
129
|
+
boot: null,
|
|
130
|
+
ns: null,
|
|
131
|
+
timeNs: null,
|
|
132
|
+
pid: process.pid,
|
|
133
|
+
start: null,
|
|
134
|
+
token,
|
|
135
|
+
fenceEpoch: token,
|
|
136
|
+
at: Date.now(),
|
|
137
|
+
};
|
|
138
|
+
const fd = openSync(lockPath, "wx", LOCK_RECORD_MODE);
|
|
139
|
+
try {
|
|
140
|
+
writeSync(fd, JSON.stringify(record));
|
|
141
|
+
fsyncSync(fd);
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
try {
|
|
145
|
+
closeSync(fd);
|
|
146
|
+
}
|
|
147
|
+
catch { /* already closed */ }
|
|
148
|
+
try {
|
|
149
|
+
unlinkSync(lockPath);
|
|
150
|
+
}
|
|
151
|
+
catch { /* best-effort rollback */ }
|
|
152
|
+
throw error;
|
|
153
|
+
}
|
|
154
|
+
closeSync(fd);
|
|
155
|
+
}
|
|
156
|
+
function pollSlice(pollMs) {
|
|
157
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, pollMs);
|
|
158
|
+
}
|
|
159
|
+
function acquire(lockPath, timeoutMs, pollMs) {
|
|
160
|
+
const deadline = performance.now() + timeoutMs;
|
|
161
|
+
for (;;) {
|
|
162
|
+
const token = newToken();
|
|
163
|
+
try {
|
|
164
|
+
writeHoldRecord(lockPath, token);
|
|
165
|
+
return token;
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
if (error.code !== "EEXIST")
|
|
169
|
+
throw error;
|
|
170
|
+
}
|
|
171
|
+
// Held by someone: only an ESRCH-proven-dead valid record is taken over.
|
|
172
|
+
// Anything else (live holder, unparseable content, foreign shape) waits.
|
|
173
|
+
const pid = recordPid(lockPath);
|
|
174
|
+
if (pid !== undefined && holderProvenDead(pid)) {
|
|
175
|
+
try {
|
|
176
|
+
unlinkSync(lockPath);
|
|
177
|
+
}
|
|
178
|
+
catch { /* raced a release; retry below */ }
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
if (performance.now() >= deadline)
|
|
182
|
+
throw new FenceTimeoutError(lockPath, timeoutMs);
|
|
183
|
+
pollSlice(Math.min(pollMs, Math.max(0, deadline - performance.now())));
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
function release(lockPath, token) {
|
|
187
|
+
// Remove only our own hold: never unlink a successor's record.
|
|
188
|
+
try {
|
|
189
|
+
if (readHeldToken(lockPath) !== token)
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
catch {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
try {
|
|
196
|
+
unlinkSync(lockPath);
|
|
197
|
+
}
|
|
198
|
+
catch { /* already gone */ }
|
|
199
|
+
}
|
|
200
|
+
export function withIdentityFenceSync(lockPath, fn, options = {}) {
|
|
201
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
202
|
+
const pollMs = options.pollMs ?? DEFAULT_POLL_MS;
|
|
203
|
+
const token = acquire(lockPath, timeoutMs, pollMs);
|
|
204
|
+
const lease = {
|
|
205
|
+
stillHeld: () => {
|
|
206
|
+
try {
|
|
207
|
+
return readHeldToken(lockPath) === token;
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
},
|
|
213
|
+
};
|
|
214
|
+
try {
|
|
215
|
+
return fn(lease);
|
|
216
|
+
}
|
|
217
|
+
finally {
|
|
218
|
+
release(lockPath, token);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=identity-fence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity-fence.js","sourceRoot":"","sources":["../../src/identity-cull/identity-fence.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Operator break verbs (`identity unlock`, `lock break`) without a
|
|
3
|
+
* core import.
|
|
4
|
+
*
|
|
5
|
+
* Breaking an identity or succession lock needs the core lock protocols, so
|
|
6
|
+
* this package cannot implement it — but it also cannot import
|
|
7
|
+
* `@sentropic/h2a` (undeclared runtime→core edge: isolated installs crash
|
|
8
|
+
* with `ERR_MODULE_NOT_FOUND`). Instead the verbs delegate to the core CLI's
|
|
9
|
+
* hidden `__operator-break` plumbing over the `h2a` binary (the same spawn
|
|
10
|
+
* pattern `central-mcp.ts` already uses for `mcp-central-serve`) and relay
|
|
11
|
+
* stdio and the exit code byte-for-byte, so user-visible behavior is
|
|
12
|
+
* unchanged where core is installed.
|
|
13
|
+
*
|
|
14
|
+
* Fail-closed without core: a missing `h2a` binary (ENOENT) or an
|
|
15
|
+
* already-delegated call (the hop marker, which guards new-runtime/old-core
|
|
16
|
+
* skew where the hidden verb would dispatch back here and fork recursions)
|
|
17
|
+
* prints a clean refusal instead of a module crash.
|
|
18
|
+
*/
|
|
19
|
+
import { spawnSync } from "node:child_process";
|
|
20
|
+
export declare const OPERATOR_BREAK_VERB = "__operator-break";
|
|
21
|
+
export declare const OPERATOR_BREAK_HOP_ENV = "H2A_OPERATOR_BREAK_HOP";
|
|
22
|
+
/**
|
|
23
|
+
* Set by core on `process.env` when it dispatches to this runtime
|
|
24
|
+
* (same-process dispatch): the exact core entry implementing the hidden
|
|
25
|
+
* plumbing. Spawning it via `process.execPath` never depends on PATH and
|
|
26
|
+
* always hits the lockstep core — which matters in test/dev checkouts where
|
|
27
|
+
* no `h2a` binary is installed.
|
|
28
|
+
*/
|
|
29
|
+
export declare const CORE_ENTRY_ENV = "H2A_CORE_ENTRY";
|
|
30
|
+
export declare function coreSpawnTarget(env: NodeJS.ProcessEnv): {
|
|
31
|
+
command: string;
|
|
32
|
+
prefixArgs: string[];
|
|
33
|
+
};
|
|
34
|
+
export interface OperatorBreakRunner {
|
|
35
|
+
spawn: typeof spawnSync;
|
|
36
|
+
env: NodeJS.ProcessEnv;
|
|
37
|
+
stderr: {
|
|
38
|
+
write(chunk: string): unknown;
|
|
39
|
+
};
|
|
40
|
+
setExitCode: (code: number) => void;
|
|
41
|
+
}
|
|
42
|
+
export declare function operatorBreak(lockPath: string, token: string, assertDead: boolean, setExitCode: (code: number) => void, runner?: OperatorBreakRunner): void;
|
|
43
|
+
//# sourceMappingURL=identity-operator-break.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity-operator-break.d.ts","sourceRoot":"","sources":["../src/identity-operator-break.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,eAAO,MAAM,mBAAmB,qBAAqB,CAAC;AACtD,eAAO,MAAM,sBAAsB,2BAA2B,CAAC;AAC/D;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,mBAAmB,CAAC;AAE/C,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE,CAMjG;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,OAAO,SAAS,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,MAAM,EAAE;QAAE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAC1C,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AASD,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,OAAO,EACnB,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,EACnC,MAAM,GAAE,mBAA6C,GACpD,IAAI,CAyCN"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Operator break verbs (`identity unlock`, `lock break`) without a
|
|
3
|
+
* core import.
|
|
4
|
+
*
|
|
5
|
+
* Breaking an identity or succession lock needs the core lock protocols, so
|
|
6
|
+
* this package cannot implement it — but it also cannot import
|
|
7
|
+
* `@sentropic/h2a` (undeclared runtime→core edge: isolated installs crash
|
|
8
|
+
* with `ERR_MODULE_NOT_FOUND`). Instead the verbs delegate to the core CLI's
|
|
9
|
+
* hidden `__operator-break` plumbing over the `h2a` binary (the same spawn
|
|
10
|
+
* pattern `central-mcp.ts` already uses for `mcp-central-serve`) and relay
|
|
11
|
+
* stdio and the exit code byte-for-byte, so user-visible behavior is
|
|
12
|
+
* unchanged where core is installed.
|
|
13
|
+
*
|
|
14
|
+
* Fail-closed without core: a missing `h2a` binary (ENOENT) or an
|
|
15
|
+
* already-delegated call (the hop marker, which guards new-runtime/old-core
|
|
16
|
+
* skew where the hidden verb would dispatch back here and fork recursions)
|
|
17
|
+
* prints a clean refusal instead of a module crash.
|
|
18
|
+
*/
|
|
19
|
+
import { spawnSync } from "node:child_process";
|
|
20
|
+
export const OPERATOR_BREAK_VERB = "__operator-break";
|
|
21
|
+
export const OPERATOR_BREAK_HOP_ENV = "H2A_OPERATOR_BREAK_HOP";
|
|
22
|
+
/**
|
|
23
|
+
* Set by core on `process.env` when it dispatches to this runtime
|
|
24
|
+
* (same-process dispatch): the exact core entry implementing the hidden
|
|
25
|
+
* plumbing. Spawning it via `process.execPath` never depends on PATH and
|
|
26
|
+
* always hits the lockstep core — which matters in test/dev checkouts where
|
|
27
|
+
* no `h2a` binary is installed.
|
|
28
|
+
*/
|
|
29
|
+
export const CORE_ENTRY_ENV = "H2A_CORE_ENTRY";
|
|
30
|
+
export function coreSpawnTarget(env) {
|
|
31
|
+
const entry = env[CORE_ENTRY_ENV];
|
|
32
|
+
if (typeof entry === "string" && entry.length > 0) {
|
|
33
|
+
return { command: process.execPath, prefixArgs: [entry] };
|
|
34
|
+
}
|
|
35
|
+
return { command: "h2a", prefixArgs: [] };
|
|
36
|
+
}
|
|
37
|
+
const realRunner = (setExitCode) => ({
|
|
38
|
+
spawn: spawnSync,
|
|
39
|
+
env: process.env,
|
|
40
|
+
stderr: process.stderr,
|
|
41
|
+
setExitCode,
|
|
42
|
+
});
|
|
43
|
+
export function operatorBreak(lockPath, token, assertDead, setExitCode, runner = realRunner(setExitCode)) {
|
|
44
|
+
if (runner.env[OPERATOR_BREAK_HOP_ENV]) {
|
|
45
|
+
runner.stderr.write("[h2a] lock break unavailable: already delegated to the core CLI (version skew: update core and runtime lockstep)\n");
|
|
46
|
+
runner.setExitCode(1);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const target = coreSpawnTarget(runner.env);
|
|
50
|
+
const args = [
|
|
51
|
+
...target.prefixArgs,
|
|
52
|
+
OPERATOR_BREAK_VERB,
|
|
53
|
+
"--lock", lockPath,
|
|
54
|
+
"--token", token,
|
|
55
|
+
...(assertDead ? ["--assert-dead"] : []),
|
|
56
|
+
];
|
|
57
|
+
// NB: spawnSync reports a failed spawn on `result.error` — it only throws
|
|
58
|
+
// for invalid arguments. Both shapes mean the delegation cannot run.
|
|
59
|
+
let result;
|
|
60
|
+
try {
|
|
61
|
+
result = runner.spawn(target.command, args, {
|
|
62
|
+
stdio: "inherit",
|
|
63
|
+
env: { ...runner.env, [OPERATOR_BREAK_HOP_ENV]: "1" },
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
result = { status: null, error: error };
|
|
68
|
+
}
|
|
69
|
+
const spawnError = result.error;
|
|
70
|
+
if (spawnError) {
|
|
71
|
+
if (spawnError.code === "ENOENT") {
|
|
72
|
+
runner.stderr.write("[h2a] lock break unavailable: the core h2a CLI is not installed beside this runtime\n");
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
runner.stderr.write(`[h2a] lock break unavailable: cannot delegate to the core h2a CLI (${spawnError.code ?? spawnError.message})\n`);
|
|
76
|
+
}
|
|
77
|
+
runner.setExitCode(1);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (typeof result.status === "number")
|
|
81
|
+
runner.setExitCode(result.status);
|
|
82
|
+
else
|
|
83
|
+
runner.setExitCode(1);
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=identity-operator-break.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity-operator-break.js","sourceRoot":"","sources":["../src/identity-operator-break.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -197,7 +197,7 @@ export { ensureCentralMcp } from "./central-mcp.js";
|
|
|
197
197
|
export * from "./cli-seat-fixtures.js";
|
|
198
198
|
export * from "./cli-seat-codecs.js";
|
|
199
199
|
export * from "./cli-seat-materialization.js";
|
|
200
|
-
export
|
|
200
|
+
export declare const enrollSeatConsumerViaFacade: typeof import("./llm-mesh-accounts.js").enrollSeatConsumerViaFacade;
|
|
201
201
|
export type { LlmMeshSeatImporter, SeatConsumerProfileInput, SeatConsumerParsers, SeatConsumerEnrollmentOptions } from "./llm-mesh-accounts.js";
|
|
202
202
|
/**
|
|
203
203
|
* h2a-facing surface: the read-only remote-agents projection consumed by the
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAsFA,OAAO,EAsDL,KAAK,YAAY,EAClB,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -24,7 +24,7 @@ import { attachLocalSession, attachPodTmux, capturePane, capturePaneVisible, cle
|
|
|
24
24
|
import { deliverInitialPrompt, sleepSync, } from "./prompt-delivery.js";
|
|
25
25
|
import { startLaunchGuard } from "./launch-guard.js";
|
|
26
26
|
import { buildLaunchContext } from "./launch-context.js";
|
|
27
|
-
import { attachNativeSession, driveNativeInstruction, killNativeSessionIfIncarnation, killNativeSessionTree, nativeHostAvailable, nativePromptDeliveryDeps, nativeSessionLiveness, nativeSessionPid, nativeSessionState, nativeTreeCpuMs, nativeWorkerPid, preflightNativeLaunch, resolveSessionHostKind, startNativeH2aSidecar, startNativeHeadlessSession, startNativeSession, NativeHostCapabilityMismatchError, NativeLaunchAdmissionError, } from "./native-host.js";
|
|
27
|
+
import { attachNativeSession, driveNativeInstruction, killNativeSessionIfIncarnation, killNativeSessionTree, nativeHostAvailable, nativePromptDeliveryDeps, nativeSessionLiveness, nativeSessionPid, nativeSessionState, nativeSessionStateAsync, nativeTreeCpuMs, nativeWorkerPid, preflightNativeLaunch, resolveSessionHostKind, startNativeH2aSidecar, startNativeHeadlessSession, startNativeSession, startNativeSessionSingleShot, NativeHostCapabilityMismatchError, NativeLaunchAdmissionError, } from "./native-host.js";
|
|
28
28
|
import { executeNativeRestart, NativeRestartError, } from "./native-restart.js";
|
|
29
29
|
import { migrateTmuxNames } from "./tmux-name-migration.js";
|
|
30
30
|
import { projectStatusForH2a } from "./status-projection.js";
|
|
@@ -45,7 +45,11 @@ import { DEFAULT_FANOUT_MAX, mapWithConcurrency, planRemoteFanout, } from "./fan
|
|
|
45
45
|
import { authenticateJobEnvelopes, buildDecisionReply, dropEnvelope, emitJobDone, envelopeFileName, isAwaitingDecision, jobInstance, parentInstance, pendingDecisions, readInboxEnvelopes, renderPendingDecisions, repliedDecisionJobIds, } from "./h2a-jobs.js";
|
|
46
46
|
import { buildConductorTask, computeDurableWorkspaceId, normalizeRootCommits, detectAvailableHosts, freshestLaunchEnvelope, h2aReportsLiveConductor, markLaunchEnvelopeProcessed, readLastLaunchAt, readLaunchEnvelopes, recordLaunchAt, selectHost, shouldLaunch, } from "./conductor-launch.js";
|
|
47
47
|
import { defaultLocalH2aRoot } from "./h2a-bridge.js";
|
|
48
|
-
import {
|
|
48
|
+
import { operatorBreak as operatorBreakToCore } from "./identity-operator-break.js";
|
|
49
|
+
// identity-cull is imported lazily at its verb below: cull.js needs the
|
|
50
|
+
// core identity fence (`@sentropic/h2a`), which must never become a
|
|
51
|
+
// load-time edge of this barrel — isolated installs of this package have
|
|
52
|
+
// no core beside them.
|
|
49
53
|
import { guardConvWriters } from "./conv-guard.js";
|
|
50
54
|
import { handleClaudeHook, installClaudeHooks, manualEnroll, readStdin, } from "./enroll.js";
|
|
51
55
|
import { probePodCredHealth, softRefreshSession } from "./soft-refresh.js";
|
|
@@ -78,7 +82,6 @@ const H2A_RUN_API_VERSION = "h2a.run/v1";
|
|
|
78
82
|
const STRUCTURED_LAUNCH_PHASE_PREFIX = "[h2a] h2a.run.phase/v1 ";
|
|
79
83
|
const H2A_RUNTIME_VERSION = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")).version;
|
|
80
84
|
import { CLI_PROFILES, gatewayModeForProfile, profileUsesLlmMeshGateway, } from "./protocol-local.js";
|
|
81
|
-
import { enrollViaFacade, enrollSeatConsumerViaFacade, formatLlmMeshAccountError, formatLlmMeshAccountList, listAccountsViaFacade, removeAccountViaFacade, } from "./llm-mesh-accounts.js";
|
|
82
85
|
import { readLlmMeshConfig, updateLlmMeshRoutingConfig, } from "./gateway-host/config-file.js";
|
|
83
86
|
import { startGateway, stopGateway, readGatewayPid, llmMeshLogPath, replaceAnthropicGatewayEnvironment, acquireLlmMeshSessionEnv, } from "./gateway-host/daemon.js";
|
|
84
87
|
import { describeLlmMeshRoutingConfig, parseLlmMeshRoutingConfig, preferredRoutingConfig, strategyRoutingConfig, } from "./routing-preferences.js";
|
|
@@ -1832,19 +1835,12 @@ export async function main(argv) {
|
|
|
1832
1835
|
const identityCommand = program
|
|
1833
1836
|
.command("identity")
|
|
1834
1837
|
.description("Inspect identity bindings or unlock a token-fenced identity lock");
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
if (!result.broken) {
|
|
1842
|
-
process.stderr.write(`[h2a] lock break refused: ${result.reason}${result.pid !== undefined ? ` (pid ${result.pid})` : ""}\n`);
|
|
1843
|
-
if (result.reason === "assert-dead-required") {
|
|
1844
|
-
process.stderr.write("[h2a] verify the holder has stopped, then explicitly pass --assert-dead; no PID is killed\n");
|
|
1845
|
-
}
|
|
1846
|
-
process.exitCode = 1;
|
|
1847
|
-
}
|
|
1838
|
+
// Operator break delegates to the core CLI's hidden `__operator-break`
|
|
1839
|
+
// plumbing (same `h2a`-binary spawn pattern as central-mcp): this package
|
|
1840
|
+
// must not import `@sentropic/h2a`, and the relay keeps stdio/exit codes
|
|
1841
|
+
// byte-for-byte identical where core is installed.
|
|
1842
|
+
const operatorBreak = (lockPath, token, assertDead) => {
|
|
1843
|
+
operatorBreakToCore(lockPath, token, assertDead, (code) => { process.exitCode = code; });
|
|
1848
1844
|
};
|
|
1849
1845
|
identityCommand
|
|
1850
1846
|
.command("unlock")
|
|
@@ -1874,9 +1870,18 @@ export async function main(argv) {
|
|
|
1874
1870
|
.option("--execute", "refuse destructive execution; no bypass exists")
|
|
1875
1871
|
.option("--root <path>", "DEF h2a root (default: H2A_ROOT or ~/h2a-workspace/.h2a)")
|
|
1876
1872
|
.option("--output <path>", "new external directory for the proof packet")
|
|
1877
|
-
.action((opts) => {
|
|
1873
|
+
.action(async (opts) => {
|
|
1874
|
+
let cull;
|
|
1875
|
+
try {
|
|
1876
|
+
cull = await import("./identity-cull/cull.js");
|
|
1877
|
+
}
|
|
1878
|
+
catch (error) {
|
|
1879
|
+
process.stderr.write(`[h2a] identity cull unavailable: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
1880
|
+
process.exitCode = 1;
|
|
1881
|
+
return;
|
|
1882
|
+
}
|
|
1878
1883
|
if (opts.execute) {
|
|
1879
|
-
const refusal = refuseCullExecution();
|
|
1884
|
+
const refusal = cull.refuseCullExecution();
|
|
1880
1885
|
process.stderr.write(`[h2a] identity cull refused: ${refusal.refusalCodes.join(", ")}\n`);
|
|
1881
1886
|
process.exitCode = 2;
|
|
1882
1887
|
return;
|
|
@@ -1884,7 +1889,7 @@ export async function main(argv) {
|
|
|
1884
1889
|
const defRoot = opts.root ?? process.env.H2A_ROOT ?? defaultLocalH2aRoot();
|
|
1885
1890
|
const outputDir = opts.output ?? join(tmpdir(), `h2a-identity-cull-${randomUUID()}`);
|
|
1886
1891
|
try {
|
|
1887
|
-
const result = runIdentityCullDryRun({
|
|
1892
|
+
const result = cull.runIdentityCullDryRun({
|
|
1888
1893
|
defRoot,
|
|
1889
1894
|
pinRoot: join(homedir(), "src", "a2a-cli"),
|
|
1890
1895
|
outputDir,
|
|
@@ -4248,13 +4253,11 @@ export async function main(argv) {
|
|
|
4248
4253
|
}
|
|
4249
4254
|
};
|
|
4250
4255
|
try {
|
|
4251
|
-
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
|
|
4255
|
-
const reservedTmuxSlugs =
|
|
4256
|
-
? existingLocalSessionSlugs(labels, cwd)
|
|
4257
|
-
: [];
|
|
4256
|
+
// No separate preflight fork: the in-process name probe below prepares
|
|
4257
|
+
// the host for a native run. The single-shot launch still performs its
|
|
4258
|
+
// fenced admission with a fresh inventory before creating any session.
|
|
4259
|
+
void preflightNativeLaunch;
|
|
4260
|
+
const reservedTmuxSlugs = existingLocalSessionSlugs(labels, cwd);
|
|
4258
4261
|
// The inventory and this decision are separate reads: a structured
|
|
4259
4262
|
// launch can leave a name visible just before its last tmux process
|
|
4260
4263
|
// exits. Re-probe every canonical/legacy spelling and reclaim the slug
|
|
@@ -4289,14 +4292,16 @@ export async function main(argv) {
|
|
|
4289
4292
|
// twin over a live-but-unprovable native writer (sol-F3): the same
|
|
4290
4293
|
// fail-closed rule as resolveManagedHost's rule 4 applies — refuse
|
|
4291
4294
|
// to launch on an unprovable host state.
|
|
4292
|
-
const nativeExistence = labels
|
|
4295
|
+
const nativeExistence = await Promise.all(labels
|
|
4293
4296
|
.map((label) => slugify(label ?? cwd))
|
|
4294
|
-
.map((slug) => {
|
|
4295
|
-
const detail =
|
|
4297
|
+
.map(async (slug) => {
|
|
4298
|
+
const detail = sessionHost === "native"
|
|
4299
|
+
? await nativeSessionStateAsync(localSessionName(slug), true)
|
|
4300
|
+
: nativeSessionState(localSessionName(slug));
|
|
4296
4301
|
const probe = detail.state === "unknown" ? "unknown"
|
|
4297
4302
|
: detail.state === "found" && detail.session.status === "running" ? "live" : "dead";
|
|
4298
4303
|
return { slug, probe, reason: detail.state === "unknown" ? detail.reason : undefined };
|
|
4299
|
-
});
|
|
4304
|
+
}));
|
|
4300
4305
|
const unknownNativeSlugs = nativeExistence
|
|
4301
4306
|
.filter((probed) => probed.probe === "unknown");
|
|
4302
4307
|
if (unknownNativeSlugs.length > 0) {
|
|
@@ -4341,9 +4346,15 @@ export async function main(argv) {
|
|
|
4341
4346
|
// Single-writer guard: refuse to resume a conversation another live
|
|
4342
4347
|
// session (local registry / remote pod) is already writing.
|
|
4343
4348
|
if (opts.resume) {
|
|
4349
|
+
// Reuse this operation's certified name verdict for that SAME
|
|
4350
|
+
// session. Other conversation owners still require their own probe.
|
|
4351
|
+
// Creation rechecks the complete inventory and name admission at
|
|
4352
|
+
// the host, so this snapshot never authorizes a colliding create.
|
|
4353
|
+
const nativeLivenessByName = new Map(nativeExistence.map(({ slug, probe }) => [localSessionName(slug), probe === "dead" ? false : probe === "live" ? true : "unknown"]));
|
|
4344
4354
|
const ok = await guardConvWriters({
|
|
4345
4355
|
convId: opts.resume,
|
|
4346
4356
|
cwd,
|
|
4357
|
+
nativeSessionLiveness: name => nativeLivenessByName.get(name) ?? nativeSessionLiveness(name),
|
|
4347
4358
|
...(opts.force ? { force: true } : {}),
|
|
4348
4359
|
fetchRemoteSessions: async () => {
|
|
4349
4360
|
const url = getConfiguredRemoteOptional();
|
|
@@ -4459,6 +4470,10 @@ export async function main(argv) {
|
|
|
4459
4470
|
}
|
|
4460
4471
|
let name;
|
|
4461
4472
|
let slug;
|
|
4473
|
+
// R3 P1: pid/identity returned by the single-shot launch; the
|
|
4474
|
+
// re-probes below prefer these and skip their forks.
|
|
4475
|
+
let launchedPid;
|
|
4476
|
+
let launchedWorkerPid;
|
|
4462
4477
|
let outputLog;
|
|
4463
4478
|
let resultJson;
|
|
4464
4479
|
let agentPane;
|
|
@@ -4495,7 +4510,9 @@ export async function main(argv) {
|
|
|
4495
4510
|
}
|
|
4496
4511
|
}
|
|
4497
4512
|
else if (sessionHost === "native") {
|
|
4498
|
-
|
|
4513
|
+
// One in-process async operation, with a fresh admission inventory;
|
|
4514
|
+
// returns pid/identity so the re-probes below are skipped.
|
|
4515
|
+
({ name, slug, pid: launchedPid, workerPid: launchedWorkerPid } = await startNativeSessionSingleShot(profile, command, cwd, args, label, {
|
|
4499
4516
|
onCreateAttempt,
|
|
4500
4517
|
...(opts.resume !== undefined ? { resumeId: opts.resume } : {}),
|
|
4501
4518
|
...(initialPrompt !== undefined
|
|
@@ -4706,13 +4723,16 @@ export async function main(argv) {
|
|
|
4706
4723
|
sleepSync(50);
|
|
4707
4724
|
}
|
|
4708
4725
|
}
|
|
4726
|
+
// R3 P1: prefer the pid/identity returned by the single-shot
|
|
4727
|
+
// launch (no fork); fall back to probes only when absent (e.g.
|
|
4728
|
+
// tmux path or adopted pre-existing session without a fresh pid).
|
|
4709
4729
|
const pid = sessionHost === "native"
|
|
4710
|
-
? nativeSessionPid(name)
|
|
4730
|
+
? (launchedPid ?? nativeSessionPid(name))
|
|
4711
4731
|
: agentPane
|
|
4712
4732
|
? localSessionPanePid(agentPane)
|
|
4713
4733
|
: undefined;
|
|
4714
4734
|
const workerPid = sessionHost === "native"
|
|
4715
|
-
? nativeWorkerPid(name)
|
|
4735
|
+
? (launchedWorkerPid ?? nativeWorkerPid(name))
|
|
4716
4736
|
: agentPane !== undefined
|
|
4717
4737
|
? paneWorkerPid(agentPane)
|
|
4718
4738
|
: undefined;
|
|
@@ -7725,6 +7745,7 @@ export async function main(argv) {
|
|
|
7725
7745
|
}
|
|
7726
7746
|
try {
|
|
7727
7747
|
const source = opts.from ?? (opts.cli ? "cli" : opts.token ? "token" : "oauth");
|
|
7748
|
+
const { enrollViaFacade } = await import("./llm-mesh-accounts.js");
|
|
7728
7749
|
const account = source === "oauth"
|
|
7729
7750
|
? await enrollViaFacade(normalized, { ...(opts.configRef ? { configRef: opts.configRef } : {}), from: "oauth" })
|
|
7730
7751
|
: await enrollSeatConsumerViaFacade(normalized, { from: source, ...(opts.seatProfile ? { seatProfile: opts.seatProfile } : {}) });
|
|
@@ -7749,6 +7770,7 @@ export async function main(argv) {
|
|
|
7749
7770
|
.description("List public accounts owned by this local llm-mesh scope")
|
|
7750
7771
|
.option("--json", "emit public account metadata as JSON")
|
|
7751
7772
|
.action(async (opts) => {
|
|
7773
|
+
const { listAccountsViaFacade, formatLlmMeshAccountList, formatLlmMeshAccountError } = await import("./llm-mesh-accounts.js");
|
|
7752
7774
|
try {
|
|
7753
7775
|
const accounts = await listAccountsViaFacade();
|
|
7754
7776
|
process.stdout.write(`${formatLlmMeshAccountList(accounts, opts.json === true)}\n`);
|
|
@@ -7763,6 +7785,7 @@ export async function main(argv) {
|
|
|
7763
7785
|
.aliases(["rm", "unenroll"])
|
|
7764
7786
|
.description("Remove one account owned by this local llm-mesh scope")
|
|
7765
7787
|
.action(async (accountId) => {
|
|
7788
|
+
const { removeAccountViaFacade, formatLlmMeshAccountError } = await import("./llm-mesh-accounts.js");
|
|
7766
7789
|
try {
|
|
7767
7790
|
const result = await removeAccountViaFacade(accountId);
|
|
7768
7791
|
process.stdout.write(`[h2a] llm-mesh account: removed ${result.accountId}\n`);
|
|
@@ -8120,7 +8143,9 @@ export { ensureCentralMcp } from "./central-mcp.js";
|
|
|
8120
8143
|
export * from "./cli-seat-fixtures.js";
|
|
8121
8144
|
export * from "./cli-seat-codecs.js";
|
|
8122
8145
|
export * from "./cli-seat-materialization.js";
|
|
8123
|
-
|
|
8146
|
+
// Keep the public async consumer contract without loading account providers in
|
|
8147
|
+
// every local crash-recovery launcher before it can elect its native host.
|
|
8148
|
+
export const enrollSeatConsumerViaFacade = async (...args) => (await import("./llm-mesh-accounts.js")).enrollSeatConsumerViaFacade(...args);
|
|
8124
8149
|
/**
|
|
8125
8150
|
* h2a-facing surface: the read-only remote-agents projection consumed by the
|
|
8126
8151
|
* objective-loop tick's *agents adapter* in `@sentropic/h2a` (via lazy
|