@sentropic/h2a-runtime 0.98.6 → 0.98.7-rc.10
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/agent-launch-args.d.ts.map +1 -1
- package/dist/agent-launch-args.js +5 -5
- package/dist/agent-launch-args.js.map +1 -1
- package/dist/agy-claude.d.ts +42 -0
- package/dist/agy-claude.d.ts.map +1 -0
- package/dist/agy-claude.js +148 -0
- package/dist/agy-claude.js.map +1 -0
- package/dist/agy-headless.d.ts +11 -0
- package/dist/agy-headless.d.ts.map +1 -0
- package/dist/agy-headless.js +104 -0
- package/dist/agy-headless.js.map +1 -0
- package/dist/attach.d.ts +5 -0
- package/dist/attach.d.ts.map +1 -1
- package/dist/attach.js +75 -6
- package/dist/attach.js.map +1 -1
- package/dist/auth-login.d.ts +24 -1
- package/dist/auth-login.d.ts.map +1 -1
- package/dist/auth-login.js +132 -4
- package/dist/auth-login.js.map +1 -1
- package/dist/central-mcp.d.ts +34 -0
- package/dist/central-mcp.d.ts.map +1 -1
- package/dist/central-mcp.js +275 -71
- package/dist/central-mcp.js.map +1 -1
- package/dist/claude-code-cli-isolation.d.ts +53 -0
- package/dist/claude-code-cli-isolation.d.ts.map +1 -0
- package/dist/claude-code-cli-isolation.js +277 -0
- package/dist/claude-code-cli-isolation.js.map +1 -0
- package/dist/claude-code-cli-lifecycle.d.ts +80 -0
- package/dist/claude-code-cli-lifecycle.d.ts.map +1 -0
- package/dist/claude-code-cli-lifecycle.js +402 -0
- package/dist/claude-code-cli-lifecycle.js.map +1 -0
- package/dist/claude-code-cli-runner.d.ts +89 -0
- package/dist/claude-code-cli-runner.d.ts.map +1 -0
- package/dist/claude-code-cli-runner.js +659 -0
- package/dist/claude-code-cli-runner.js.map +1 -0
- package/dist/claude-seat-input.d.ts +47 -0
- package/dist/claude-seat-input.d.ts.map +1 -0
- package/dist/claude-seat-input.js +272 -0
- package/dist/claude-seat-input.js.map +1 -0
- package/dist/claude-seat-mesh-contract.d.ts +88 -0
- package/dist/claude-seat-mesh-contract.d.ts.map +1 -0
- package/dist/claude-seat-mesh-contract.js +13 -0
- package/dist/claude-seat-mesh-contract.js.map +1 -0
- package/dist/cli-help-groups.js +1 -1
- package/dist/cli-help-groups.js.map +1 -1
- package/dist/cli-seat-codecs.d.ts +86 -0
- package/dist/cli-seat-codecs.d.ts.map +1 -0
- package/dist/cli-seat-codecs.js +255 -0
- package/dist/cli-seat-codecs.js.map +1 -0
- package/dist/cli-seat-fixtures.d.ts +86 -0
- package/dist/cli-seat-fixtures.d.ts.map +1 -0
- package/dist/cli-seat-fixtures.js +114 -0
- package/dist/cli-seat-fixtures.js.map +1 -0
- package/dist/cli-seat-materialization.d.ts +245 -0
- package/dist/cli-seat-materialization.d.ts.map +1 -0
- package/dist/cli-seat-materialization.js +646 -0
- package/dist/cli-seat-materialization.js.map +1 -0
- 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/crash-log.d.ts +112 -0
- package/dist/crash-log.d.ts.map +1 -0
- package/dist/crash-log.js +560 -0
- package/dist/crash-log.js.map +1 -0
- package/dist/delegate.d.ts +10 -0
- package/dist/delegate.d.ts.map +1 -1
- package/dist/delegate.js +29 -0
- package/dist/delegate.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/claude-seat-client.d.ts +32 -0
- package/dist/gateway-host/claude-seat-client.d.ts.map +1 -0
- package/dist/gateway-host/claude-seat-client.js +38 -0
- package/dist/gateway-host/claude-seat-client.js.map +1 -0
- 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/gateway-host/host.d.ts +6 -0
- package/dist/gateway-host/host.d.ts.map +1 -1
- package/dist/gateway-host/host.js +24 -3
- package/dist/gateway-host/host.js.map +1 -1
- package/dist/gateway-host/live-auth.d.ts +62 -0
- package/dist/gateway-host/live-auth.d.ts.map +1 -0
- package/dist/gateway-host/live-auth.js +87 -0
- package/dist/gateway-host/live-auth.js.map +1 -0
- package/dist/gateway-host/live-declarations.d.ts +58 -0
- package/dist/gateway-host/live-declarations.d.ts.map +1 -0
- package/dist/gateway-host/live-declarations.js +429 -0
- package/dist/gateway-host/live-declarations.js.map +1 -0
- package/dist/gateway-host/live-disclosure.d.ts +124 -0
- package/dist/gateway-host/live-disclosure.d.ts.map +1 -0
- package/dist/gateway-host/live-disclosure.js +347 -0
- package/dist/gateway-host/live-disclosure.js.map +1 -0
- package/dist/gateway-host/live-github.d.ts +11 -0
- package/dist/gateway-host/live-github.d.ts.map +1 -0
- package/dist/gateway-host/live-github.js +374 -0
- package/dist/gateway-host/live-github.js.map +1 -0
- package/dist/gateway-host/live-host.d.ts +20 -0
- package/dist/gateway-host/live-host.d.ts.map +1 -0
- package/dist/gateway-host/live-host.js +14 -0
- package/dist/gateway-host/live-host.js.map +1 -0
- package/dist/gateway-host/live-object-store.d.ts +35 -0
- package/dist/gateway-host/live-object-store.d.ts.map +1 -0
- package/dist/gateway-host/live-object-store.js +447 -0
- package/dist/gateway-host/live-object-store.js.map +1 -0
- package/dist/gateway-host/live-registration.d.ts +162 -0
- package/dist/gateway-host/live-registration.d.ts.map +1 -0
- package/dist/gateway-host/live-registration.js +455 -0
- package/dist/gateway-host/live-registration.js.map +1 -0
- package/dist/gateway-model-catalog/model-catalog.d.ts +38 -0
- package/dist/gateway-model-catalog/model-catalog.d.ts.map +1 -0
- package/dist/gateway-model-catalog/model-catalog.js +167 -0
- package/dist/gateway-model-catalog/model-catalog.js.map +1 -0
- 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 +8 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +525 -132
- package/dist/index.js.map +1 -1
- package/dist/launch-layout.d.ts.map +1 -1
- package/dist/launch-layout.js +10 -2
- package/dist/launch-layout.js.map +1 -1
- package/dist/llm-mesh-accounts.d.ts +128 -6
- package/dist/llm-mesh-accounts.d.ts.map +1 -1
- package/dist/llm-mesh-accounts.js +370 -14
- package/dist/llm-mesh-accounts.js.map +1 -1
- package/dist/native-host.d.ts +25 -1
- package/dist/native-host.d.ts.map +1 -1
- package/dist/native-host.js +211 -28
- package/dist/native-host.js.map +1 -1
- package/dist/native-restart.d.ts +2 -0
- package/dist/native-restart.d.ts.map +1 -1
- package/dist/native-restart.js +7 -0
- package/dist/native-restart.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 +7 -1
- package/dist/native-terminal/host.d.ts.map +1 -1
- package/dist/native-terminal/host.js +10 -26
- package/dist/native-terminal/host.js.map +1 -1
- package/dist/native-terminal/journal.d.ts +5 -0
- package/dist/native-terminal/journal.d.ts.map +1 -1
- package/dist/native-terminal/journal.js +28 -16
- package/dist/native-terminal/journal.js.map +1 -1
- package/dist/native-terminal/op.d.ts +49 -1
- package/dist/native-terminal/op.d.ts.map +1 -1
- package/dist/native-terminal/op.js +254 -38
- 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/proc-identity.d.ts +31 -0
- package/dist/proc-identity.d.ts.map +1 -1
- package/dist/proc-identity.js +54 -0
- package/dist/proc-identity.js.map +1 -1
- package/dist/prompt-delivery.d.ts +3 -0
- package/dist/prompt-delivery.d.ts.map +1 -1
- package/dist/prompt-delivery.js +8 -3
- package/dist/prompt-delivery.js.map +1 -1
- package/dist/protocol-local.d.ts +16 -0
- package/dist/protocol-local.d.ts.map +1 -1
- package/dist/protocol-local.js +14 -0
- package/dist/protocol-local.js.map +1 -1
- package/dist/registry.d.ts +16 -12
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +39 -5
- package/dist/registry.js.map +1 -1
- package/dist/relaunch.d.ts +16 -0
- package/dist/relaunch.d.ts.map +1 -1
- package/dist/relaunch.js +42 -1
- package/dist/relaunch.js.map +1 -1
- package/dist/restore.d.ts +4 -0
- package/dist/restore.d.ts.map +1 -1
- package/dist/restore.js +9 -37
- package/dist/restore.js.map +1 -1
- package/dist/resume-launch-options.d.ts +3 -3
- package/dist/resume-launch-options.d.ts.map +1 -1
- package/dist/resume-launch-options.js +7 -4
- package/dist/resume-launch-options.js.map +1 -1
- package/dist/run.d.ts +2 -0
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +88 -20
- package/dist/run.js.map +1 -1
- package/dist/soft-refresh.d.ts.map +1 -1
- package/dist/soft-refresh.js +6 -0
- package/dist/soft-refresh.js.map +1 -1
- package/dist/terminal-reset.d.ts +104 -0
- package/dist/terminal-reset.d.ts.map +1 -0
- package/dist/terminal-reset.js +229 -0
- package/dist/terminal-reset.js.map +1 -0
- package/dist/tmux.d.ts +54 -8
- package/dist/tmux.d.ts.map +1 -1
- package/dist/tmux.js +143 -36
- package/dist/tmux.js.map +1 -1
- package/dist/vendor/engram-live/contracts.d.ts +825 -0
- package/dist/vendor/engram-live/contracts.js +1734 -0
- package/dist/vendor/engram-live/integration.d.ts +113 -0
- package/dist/vendor/engram-live/integration.js +254 -0
- package/dist/vendor/engram-live/pr-sync.d.ts +144 -0
- package/dist/vendor/engram-live/pr-sync.js +411 -0
- package/dist/vendor/engram-live/registration.d.ts +138 -0
- package/dist/vendor/engram-live/registration.js +358 -0
- package/dist/vendor/engram-live/retention.d.ts +56 -0
- package/dist/vendor/engram-live/retention.js +179 -0
- package/package.json +6 -6
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code CLI lifecycle: process-tree supervision, TTL admission,
|
|
3
|
+
* and startup orphan sweeps. Account locking lives in the mesh account
|
|
4
|
+
* directory (common seat model) — never here.
|
|
5
|
+
*/
|
|
6
|
+
import { closeSync, constants, existsSync, openSync, readdirSync, readFileSync, readlinkSync, rmSync, unlinkSync, writeFileSync, } from "node:fs";
|
|
7
|
+
import { randomUUID } from "node:crypto";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
import { resolvePrivateRuntimeRoot } from "./claude-code-cli-isolation.js";
|
|
10
|
+
import { readBootId, readMachineId, readPidNamespaceId, readProcessStartTime } from "./proc-identity.js";
|
|
11
|
+
export const DEFAULT_ORPHAN_STALE_AFTER_MS = 5 * 60 * 1000; // 5 minutes
|
|
12
|
+
export const DEFAULT_MIN_REMAINING_TTL_MS = 60_000; // 1 minute
|
|
13
|
+
export const DEFAULT_MAX_REMAINING_TTL_MS = 86_400_000; // 24 hours
|
|
14
|
+
/**
|
|
15
|
+
* Prove a recorded holder dead. PID presence alone proves nothing across
|
|
16
|
+
* PID reuse: a live pid with a mismatched start-time is a different process
|
|
17
|
+
* (reclaim), a mismatched boot id means a reboot happened (reclaim), and an
|
|
18
|
+
* ESRCH signal check means the process is gone (reclaim). Anything
|
|
19
|
+
* unprovable — EPERM liveness, unreadable identity, foreign namespace or
|
|
20
|
+
* machine sharing this directory — fails closed as alive (wait, never
|
|
21
|
+
* reclaim), so a live holder can never lose its lock to a waiter.
|
|
22
|
+
*/
|
|
23
|
+
function isRecordedHolderProvenDead(holder) {
|
|
24
|
+
if (!holder || typeof holder !== "object")
|
|
25
|
+
return false;
|
|
26
|
+
if (typeof holder.pid !== "number" || !Number.isInteger(holder.pid) || holder.pid <= 0) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
const liveNamespace = readPidNamespaceId();
|
|
30
|
+
if (typeof holder.pidNamespace === "string" &&
|
|
31
|
+
liveNamespace !== undefined &&
|
|
32
|
+
holder.pidNamespace !== liveNamespace) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
const liveMachine = readMachineId();
|
|
36
|
+
if (typeof holder.machineId === "string" &&
|
|
37
|
+
liveMachine !== undefined &&
|
|
38
|
+
holder.machineId !== liveMachine) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
process.kill(holder.pid, 0);
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
if (err.code === "ESRCH")
|
|
46
|
+
return true;
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
const liveStartTime = readProcessStartTime(holder.pid);
|
|
50
|
+
if (typeof holder.startTime === "number" &&
|
|
51
|
+
liveStartTime !== undefined &&
|
|
52
|
+
liveStartTime !== holder.startTime) {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
const liveBootId = readBootId();
|
|
56
|
+
if (typeof holder.bootId === "string" &&
|
|
57
|
+
liveBootId !== undefined &&
|
|
58
|
+
liveBootId !== holder.bootId) {
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Positively prove that a live child process is the exact process spawned by this sandbox.
|
|
65
|
+
* Fails closed: never signals on PID presence alone, across reboot, across PID namespace
|
|
66
|
+
* boundary, across PID reuse, or when start-time was unrecorded or mismatched.
|
|
67
|
+
*/
|
|
68
|
+
export function isRecordedChildProvenTarget(childPid, rawMeta, parentMeta, runDir) {
|
|
69
|
+
if (typeof childPid !== "number" || !Number.isInteger(childPid) || childPid <= 0) {
|
|
70
|
+
return { proven: false, reason: "invalid_pid" };
|
|
71
|
+
}
|
|
72
|
+
// Must be alive to prove
|
|
73
|
+
try {
|
|
74
|
+
process.kill(childPid, 0);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return { proven: false, reason: "process_dead" };
|
|
78
|
+
}
|
|
79
|
+
// Linux-specific identity proofs: start-time, boot-id, pid-namespace
|
|
80
|
+
if (process.platform === "linux") {
|
|
81
|
+
const liveBootId = readBootId();
|
|
82
|
+
const recordedChildBoot = (typeof rawMeta.childBootId === "string" && rawMeta.childBootId) ||
|
|
83
|
+
parentMeta.bootId;
|
|
84
|
+
if (typeof recordedChildBoot !== "string" ||
|
|
85
|
+
!recordedChildBoot ||
|
|
86
|
+
liveBootId === undefined ||
|
|
87
|
+
liveBootId !== recordedChildBoot) {
|
|
88
|
+
return { proven: false, reason: "boot_id_mismatch_or_unrecorded" };
|
|
89
|
+
}
|
|
90
|
+
const liveNamespace = readPidNamespaceId();
|
|
91
|
+
const recordedChildNs = (typeof rawMeta.childPidNamespace === "string" && rawMeta.childPidNamespace) ||
|
|
92
|
+
parentMeta.pidNamespace;
|
|
93
|
+
if (typeof recordedChildNs !== "string" ||
|
|
94
|
+
!recordedChildNs ||
|
|
95
|
+
liveNamespace === undefined ||
|
|
96
|
+
liveNamespace !== recordedChildNs) {
|
|
97
|
+
return { proven: false, reason: "pid_namespace_mismatch_or_unrecorded" };
|
|
98
|
+
}
|
|
99
|
+
const liveMachine = readMachineId();
|
|
100
|
+
if (typeof parentMeta.machineId === "string" &&
|
|
101
|
+
(liveMachine === undefined || liveMachine !== parentMeta.machineId)) {
|
|
102
|
+
return { proven: false, reason: "machine_id_mismatch" };
|
|
103
|
+
}
|
|
104
|
+
if (typeof rawMeta.childStartTime !== "number" ||
|
|
105
|
+
!Number.isFinite(rawMeta.childStartTime) ||
|
|
106
|
+
rawMeta.childStartTime <= 0) {
|
|
107
|
+
return { proven: false, reason: "child_start_time_unrecorded" };
|
|
108
|
+
}
|
|
109
|
+
const liveStartTime = readProcessStartTime(childPid);
|
|
110
|
+
if (liveStartTime === undefined || liveStartTime !== rawMeta.childStartTime) {
|
|
111
|
+
return { proven: false, reason: "child_start_time_mismatched" };
|
|
112
|
+
}
|
|
113
|
+
// Optional cwd/marker ownership check if recorded
|
|
114
|
+
if (typeof rawMeta.childCwd === "string") {
|
|
115
|
+
try {
|
|
116
|
+
const liveCwd = readlinkSync(`/proc/${childPid}/cwd`);
|
|
117
|
+
const normalizedRunDir = runDir.endsWith("/") ? runDir : `${runDir}/`;
|
|
118
|
+
if (liveCwd !== rawMeta.childCwd && liveCwd !== runDir && !liveCwd.startsWith(normalizedRunDir)) {
|
|
119
|
+
return { proven: false, reason: "child_cwd_mismatched" };
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
catch (err) {
|
|
123
|
+
const code = err.code;
|
|
124
|
+
if (code === "ENOENT" || code === "ESRCH") {
|
|
125
|
+
return { proven: false, reason: "process_dead" };
|
|
126
|
+
}
|
|
127
|
+
return { proven: false, reason: "child_cwd_unreadable" };
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
// Non-Linux platforms: without /proc start-time and boot-id, cannot positively
|
|
133
|
+
// prove process identity to avoid PID reuse hazard. Fail closed: never signal.
|
|
134
|
+
return { proven: false, reason: "non_linux_process_identity_unprovable" };
|
|
135
|
+
}
|
|
136
|
+
return { proven: true };
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Account locking lives in the mesh account directory for every seat
|
|
140
|
+
* (owner decision 2026-10-13, realign on the common seat model): h2a holds
|
|
141
|
+
* no per-account lease. `acquireClaudeAccountLease` and
|
|
142
|
+
* `reclaimDeadAccountLock` were removed without replacement — the mesh route
|
|
143
|
+
* planner serializes acquisition and refresh. What follows is TTL admission,
|
|
144
|
+
* process reaping, and the orphan sweep (proven-dead sandboxes only).
|
|
145
|
+
*/
|
|
146
|
+
/**
|
|
147
|
+
* Validate token remaining TTL against admission boundaries.
|
|
148
|
+
* Preserves real provider expiry without rewriting or fabricating timestamps.
|
|
149
|
+
*/
|
|
150
|
+
export function checkTokenTtlAdmission(expiresAt, now = Date.now(), minTtlMs = DEFAULT_MIN_REMAINING_TTL_MS, maxTtlMs = DEFAULT_MAX_REMAINING_TTL_MS) {
|
|
151
|
+
if (!Number.isFinite(expiresAt) || expiresAt <= 0) {
|
|
152
|
+
return { admitted: false, reason: "invalid_token_expiry" };
|
|
153
|
+
}
|
|
154
|
+
const remaining = expiresAt - now;
|
|
155
|
+
if (remaining < minTtlMs) {
|
|
156
|
+
return { admitted: false, reason: "insufficient_remaining_ttl" };
|
|
157
|
+
}
|
|
158
|
+
if (remaining > maxTtlMs) {
|
|
159
|
+
return { admitted: false, reason: "excessive_remaining_ttl" };
|
|
160
|
+
}
|
|
161
|
+
return { admitted: true };
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Supervise process tree and guarantee reaping of child and all descendants.
|
|
165
|
+
*/
|
|
166
|
+
export async function reapProcessTree(pid, signal = "SIGTERM", gracePeriodMs = 500) {
|
|
167
|
+
if (pid <= 0)
|
|
168
|
+
return;
|
|
169
|
+
const sendSignal = (sig) => {
|
|
170
|
+
try {
|
|
171
|
+
// Kill process group (negative PID)
|
|
172
|
+
process.kill(-pid, sig);
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
try {
|
|
176
|
+
process.kill(pid, sig);
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
// Process might already be dead
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
sendSignal(signal);
|
|
184
|
+
// Await grace period
|
|
185
|
+
await new Promise((r) => setTimeout(r, gracePeriodMs));
|
|
186
|
+
// Escalate to SIGKILL if still running
|
|
187
|
+
try {
|
|
188
|
+
process.kill(pid, 0);
|
|
189
|
+
sendSignal("SIGKILL");
|
|
190
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
191
|
+
}
|
|
192
|
+
catch {
|
|
193
|
+
// Process exited successfully
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/** Sweep mutual-exclusion file inside the runtime root. */
|
|
197
|
+
export const CLAUDE_SWEEP_LOCK_FILENAME = ".sweep.lock";
|
|
198
|
+
/**
|
|
199
|
+
* Content-blind orphan sweep at host boot and runner start.
|
|
200
|
+
* A run is swept only when its run-meta.json carries a valid pid plus
|
|
201
|
+
* createdAt AND the holder is proven dead by pid/start-time/boot identity
|
|
202
|
+
* AND its age exceeds the stale threshold. Runs without valid metadata are
|
|
203
|
+
* always retained (never deleted blindly); live holders are skipped; a
|
|
204
|
+
* concurrent active sweeper makes this call a no-op.
|
|
205
|
+
*/
|
|
206
|
+
export async function sweepOrphanSandboxes(rootDir, options = {}) {
|
|
207
|
+
const root = resolvePrivateRuntimeRoot(rootDir);
|
|
208
|
+
const maxAgeMs = options.maxAgeMs ?? DEFAULT_ORPHAN_STALE_AFTER_MS;
|
|
209
|
+
const now = (options.now ?? Date.now)();
|
|
210
|
+
let swept = 0;
|
|
211
|
+
let retained = 0;
|
|
212
|
+
let skippedAlive = 0;
|
|
213
|
+
let skippedUnprovenChild = 0;
|
|
214
|
+
if (!existsSync(root)) {
|
|
215
|
+
return { swept, retained, skippedAlive };
|
|
216
|
+
}
|
|
217
|
+
// Sweep mutual exclusion: one active sweeper per root.
|
|
218
|
+
const sweepLockFile = join(root, CLAUDE_SWEEP_LOCK_FILENAME);
|
|
219
|
+
const sweepToken = randomUUID();
|
|
220
|
+
const readSweepHolder = () => {
|
|
221
|
+
try {
|
|
222
|
+
const parsed = JSON.parse(readFileSync(sweepLockFile, "utf8"));
|
|
223
|
+
if (!parsed || typeof parsed !== "object")
|
|
224
|
+
return null;
|
|
225
|
+
return parsed;
|
|
226
|
+
}
|
|
227
|
+
catch {
|
|
228
|
+
return null;
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
let sweepFd = null;
|
|
232
|
+
try {
|
|
233
|
+
sweepFd = openSync(sweepLockFile, constants.O_CREAT | constants.O_EXCL | constants.O_RDWR, 0o600);
|
|
234
|
+
writeFileSync(sweepFd, JSON.stringify({
|
|
235
|
+
pid: process.pid,
|
|
236
|
+
startTime: readProcessStartTime(process.pid) ?? null,
|
|
237
|
+
bootId: readBootId() ?? null,
|
|
238
|
+
pidNamespace: readPidNamespaceId() ?? null,
|
|
239
|
+
machineId: readMachineId() ?? null,
|
|
240
|
+
acquiredAt: now,
|
|
241
|
+
token: sweepToken,
|
|
242
|
+
}));
|
|
243
|
+
}
|
|
244
|
+
catch {
|
|
245
|
+
const holder = readSweepHolder();
|
|
246
|
+
const holderAge = holder && typeof holder.acquiredAt === "number"
|
|
247
|
+
? now - (holder.acquiredAt)
|
|
248
|
+
: 0;
|
|
249
|
+
if (holder && (isRecordedHolderProvenDead(holder) || holderAge > 2 * maxAgeMs)) {
|
|
250
|
+
try {
|
|
251
|
+
unlinkSync(sweepLockFile);
|
|
252
|
+
}
|
|
253
|
+
catch {
|
|
254
|
+
// Lost the race; skip this round.
|
|
255
|
+
return { swept, retained, skippedAlive };
|
|
256
|
+
}
|
|
257
|
+
try {
|
|
258
|
+
sweepFd = openSync(sweepLockFile, constants.O_CREAT | constants.O_EXCL | constants.O_RDWR, 0o600);
|
|
259
|
+
writeFileSync(sweepFd, JSON.stringify({ pid: process.pid, acquiredAt: now, token: sweepToken }));
|
|
260
|
+
}
|
|
261
|
+
catch {
|
|
262
|
+
return { swept, retained, skippedAlive };
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
return { swept, retained, skippedAlive };
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
try {
|
|
270
|
+
const entries = readdirSync(root, { withFileTypes: true });
|
|
271
|
+
for (const entry of entries) {
|
|
272
|
+
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
273
|
+
continue;
|
|
274
|
+
const runDir = join(root, entry.name);
|
|
275
|
+
const metaPath = join(runDir, "run-meta.json");
|
|
276
|
+
let meta = null;
|
|
277
|
+
try {
|
|
278
|
+
const parsed = JSON.parse(readFileSync(metaPath, "utf8"));
|
|
279
|
+
if (parsed && typeof parsed === "object") {
|
|
280
|
+
meta = parsed;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
catch {
|
|
284
|
+
meta = null;
|
|
285
|
+
}
|
|
286
|
+
// No valid identity metadata: retain, never delete blindly.
|
|
287
|
+
if (!meta || typeof meta.pid !== "number" || typeof meta.createdAt !== "number") {
|
|
288
|
+
retained++;
|
|
289
|
+
continue;
|
|
290
|
+
}
|
|
291
|
+
if (!isRecordedHolderProvenDead(meta)) {
|
|
292
|
+
skippedAlive++;
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
// Young orphan retry: do NOT delete if younger than stale threshold
|
|
296
|
+
if (now - meta.createdAt < maxAgeMs) {
|
|
297
|
+
retained++;
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
// Holder proven dead and age > maxAgeMs: reap detached child ONLY if positive identity is proven, then delete
|
|
301
|
+
const rawMeta = meta;
|
|
302
|
+
if (typeof rawMeta.childPid === "number" && rawMeta.childPid > 0) {
|
|
303
|
+
let childAlive = false;
|
|
304
|
+
try {
|
|
305
|
+
process.kill(rawMeta.childPid, 0);
|
|
306
|
+
childAlive = true;
|
|
307
|
+
}
|
|
308
|
+
catch {
|
|
309
|
+
childAlive = false;
|
|
310
|
+
}
|
|
311
|
+
if (childAlive) {
|
|
312
|
+
const proof = isRecordedChildProvenTarget(rawMeta.childPid, rawMeta, meta, runDir);
|
|
313
|
+
if (proof.proven) {
|
|
314
|
+
// Re-verify start-time immediately prior to signal to minimize
|
|
315
|
+
// the proof-to-signal window (c-m3). The window cannot be closed
|
|
316
|
+
// from Node: pidfd_open/pidfd_send_signal have no stdlib binding
|
|
317
|
+
// and a native addon is out of scope, so the re-read plus
|
|
318
|
+
// fail-closed retain on any divergence is the mitigation.
|
|
319
|
+
let raceDiverged = false;
|
|
320
|
+
if (process.platform === "linux") {
|
|
321
|
+
const liveNow = readProcessStartTime(rawMeta.childPid);
|
|
322
|
+
if (liveNow === undefined || liveNow !== rawMeta.childStartTime) {
|
|
323
|
+
raceDiverged = true;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
if (raceDiverged) {
|
|
327
|
+
skippedUnprovenChild++;
|
|
328
|
+
if (options.onUnprovenChild) {
|
|
329
|
+
options.onUnprovenChild({
|
|
330
|
+
runDir,
|
|
331
|
+
childPid: rawMeta.childPid,
|
|
332
|
+
reason: "child_start_time_mismatched",
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
else {
|
|
337
|
+
try {
|
|
338
|
+
const reaper = options.reapProcessTreeFn ?? reapProcessTree;
|
|
339
|
+
await reaper(rawMeta.childPid, "SIGKILL", 50);
|
|
340
|
+
}
|
|
341
|
+
catch {
|
|
342
|
+
// Best effort
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
// Identity not positively proven: NEVER signal! Skip child reap and report.
|
|
348
|
+
skippedUnprovenChild++;
|
|
349
|
+
if (options.onUnprovenChild) {
|
|
350
|
+
options.onUnprovenChild({
|
|
351
|
+
runDir,
|
|
352
|
+
childPid: rawMeta.childPid,
|
|
353
|
+
reason: proof.reason ?? "unproven_identity",
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
// Retain sandbox when the child might still be the legitimate seat process running
|
|
357
|
+
// (e.g. unrecorded start-time, non-Linux unprovable, pid namespace unprovable, cwd unreadable).
|
|
358
|
+
// Only sweep when identity proves it is definitely a different process (mismatched start-time, mismatched boot-id).
|
|
359
|
+
if (proof.reason === "child_start_time_unrecorded" ||
|
|
360
|
+
proof.reason === "non_linux_process_identity_unprovable" ||
|
|
361
|
+
proof.reason === "pid_namespace_mismatch_or_unrecorded" ||
|
|
362
|
+
proof.reason === "child_cwd_unreadable") {
|
|
363
|
+
retained++;
|
|
364
|
+
continue;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
try {
|
|
370
|
+
rmSync(runDir, { recursive: true, force: true });
|
|
371
|
+
swept++;
|
|
372
|
+
}
|
|
373
|
+
catch {
|
|
374
|
+
retained++;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
finally {
|
|
379
|
+
try {
|
|
380
|
+
if (sweepFd !== null) {
|
|
381
|
+
closeSync(sweepFd);
|
|
382
|
+
sweepFd = null;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
catch {
|
|
386
|
+
// Best effort
|
|
387
|
+
}
|
|
388
|
+
try {
|
|
389
|
+
const current = readSweepHolder();
|
|
390
|
+
if (current && current.token === sweepToken) {
|
|
391
|
+
unlinkSync(sweepLockFile);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
catch {
|
|
395
|
+
// Best effort
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
return skippedUnprovenChild > 0
|
|
399
|
+
? { swept, retained, skippedAlive, skippedUnprovenChild }
|
|
400
|
+
: { swept, retained, skippedAlive };
|
|
401
|
+
}
|
|
402
|
+
//# sourceMappingURL=claude-code-cli-lifecycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-code-cli-lifecycle.js","sourceRoot":"","sources":["../src/claude-code-cli-lifecycle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code CLI Runner: executes the official `claude` CLI (resolved
|
|
3
|
+
* from `PATH` at each attempt) with NDJSON streaming, strict isolation,
|
|
4
|
+
* process reaping, credential read-back, and static error handling.
|
|
5
|
+
* No version pin, no digest fingerprint, no attestation: no other seat
|
|
6
|
+
* carries such machinery, and none is claimed here.
|
|
7
|
+
*/
|
|
8
|
+
import { spawn } from "node:child_process";
|
|
9
|
+
import type { ClaudeCodeAccessProjection, ClaudeCodeCliCapabilities, ClaudeCodeCliEvent, ClaudeCodeCliRequest, ClaudeCodeCliRunner } from "./claude-seat-mesh-contract.js";
|
|
10
|
+
/**
|
|
11
|
+
* Resolve the official `claude` CLI from `PATH` (Linux-first; Windows
|
|
12
|
+
* resolves `claude` and `claude.exe` only — `.cmd`/`.bat` shims are
|
|
13
|
+
* excluded because spawn launches without a shell). Returns the first
|
|
14
|
+
* absolute regular executable candidate, or undefined when none is found.
|
|
15
|
+
* Never throws, never executes anything.
|
|
16
|
+
*/
|
|
17
|
+
export declare function resolveClaudeBinaryFromPath(env?: NodeJS.ProcessEnv): string | undefined;
|
|
18
|
+
export declare const DEFAULT_MAX_FRAME_BYTES = 65536;
|
|
19
|
+
export declare const DEFAULT_MAX_TOTAL_BYTES: number;
|
|
20
|
+
export declare const DEFAULT_RUN_DEADLINE_MS = 120000;
|
|
21
|
+
/**
|
|
22
|
+
* Strict allowlist of typed tool identifiers permitted for the CLI --tools flag.
|
|
23
|
+
* Caller-provided tool names are never passed to --tools.
|
|
24
|
+
*/
|
|
25
|
+
export declare const ALLOWED_TYPED_TOOL_IDENTIFIERS: readonly string[];
|
|
26
|
+
/**
|
|
27
|
+
* Known built-in tools of the Claude CLI. Callers cannot request these names.
|
|
28
|
+
*/
|
|
29
|
+
export declare const BUILTIN_CLI_TOOLS: Set<string>;
|
|
30
|
+
/**
|
|
31
|
+
* Top-level NDJSON frame types emitted by the official CLI stream-json
|
|
32
|
+
* output that are known transport or lifecycle events and should not be failed as unknown.
|
|
33
|
+
*/
|
|
34
|
+
export declare const KNOWN_IGNORED_TOP_LEVEL_TYPES: Set<string>;
|
|
35
|
+
export interface OfficialClaudeCodeCliRunnerOptions {
|
|
36
|
+
/**
|
|
37
|
+
* Explicit binary path override (test seam). When absent, the runner
|
|
38
|
+
* resolves `claude` from `PATH` at each attempt.
|
|
39
|
+
*/
|
|
40
|
+
readonly binaryPath?: string;
|
|
41
|
+
readonly capabilities?: ClaudeCodeCliCapabilities;
|
|
42
|
+
readonly maxFrameBytes?: number;
|
|
43
|
+
readonly maxTotalBytes?: number;
|
|
44
|
+
readonly timeoutMs?: number;
|
|
45
|
+
readonly spawnFn?: typeof spawn;
|
|
46
|
+
readonly now?: () => number;
|
|
47
|
+
/** Test seam directing sandbox roots away from the per-user runtime base. */
|
|
48
|
+
readonly sandboxRootDir?: string;
|
|
49
|
+
/** Allowlist of typed tool identifiers authorized for the CLI --tools flag. */
|
|
50
|
+
readonly allowedCliTools?: readonly string[];
|
|
51
|
+
/** Test seam injecting process group killer instead of process.kill(-childPid). */
|
|
52
|
+
readonly killProcessTreeFn?: (pid: number, signal?: NodeJS.Signals) => void;
|
|
53
|
+
/** Test seam injecting process tree reaper instead of reapProcessTree(childPid). */
|
|
54
|
+
readonly reapProcessTreeFn?: (pid: number, signal?: NodeJS.Signals, gracePeriodMs?: number) => Promise<void>;
|
|
55
|
+
}
|
|
56
|
+
export declare class OfficialClaudeCodeCliRunner implements ClaudeCodeCliRunner {
|
|
57
|
+
private readonly binaryPath;
|
|
58
|
+
private readonly capabilities;
|
|
59
|
+
private readonly maxFrameBytes;
|
|
60
|
+
private readonly maxTotalBytes;
|
|
61
|
+
private readonly timeoutMs;
|
|
62
|
+
private readonly spawnFn;
|
|
63
|
+
private readonly now;
|
|
64
|
+
private readonly sandboxRootDir;
|
|
65
|
+
private readonly allowedCliTools;
|
|
66
|
+
private readonly killProcessTreeFn;
|
|
67
|
+
private readonly reapProcessTreeFn;
|
|
68
|
+
constructor(options?: OfficialClaudeCodeCliRunnerOptions);
|
|
69
|
+
/**
|
|
70
|
+
* Resolve the spawn candidate: the explicit override when set,
|
|
71
|
+
* otherwise the official `claude` CLI from `PATH` (re-resolved at each
|
|
72
|
+
* attempt, so a later CLI install is picked up without a restart).
|
|
73
|
+
* Generic spawn safety only — absolute resolved path, regular executable
|
|
74
|
+
* file, supported protocol. No version pin, no fingerprint, no attestation.
|
|
75
|
+
*/
|
|
76
|
+
private resolveBinary;
|
|
77
|
+
/**
|
|
78
|
+
* Refuse to spawn unless the candidate resolves and the mesh protocol
|
|
79
|
+
* matches. Anything less is refused before spawn.
|
|
80
|
+
*/
|
|
81
|
+
private qualifyBinary;
|
|
82
|
+
run(input: {
|
|
83
|
+
access: ClaudeCodeAccessProjection;
|
|
84
|
+
request: ClaudeCodeCliRequest;
|
|
85
|
+
signal: AbortSignal;
|
|
86
|
+
}): AsyncIterable<ClaudeCodeCliEvent>;
|
|
87
|
+
private runInternal;
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=claude-code-cli-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-code-cli-runner.d.ts","sourceRoot":"","sources":["../src/claude-code-cli-runner.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAG3C,OAAO,KAAK,EACV,0BAA0B,EAC1B,yBAAyB,EAEzB,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,gCAAgC,CAAC;AA4BxC;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CACzC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,MAAM,GAAG,SAAS,CAgBpB;AAED,eAAO,MAAM,uBAAuB,QAAQ,CAAC;AAC7C,eAAO,MAAM,uBAAuB,QAAmB,CAAC;AACxD,eAAO,MAAM,uBAAuB,SAAU,CAAC;AAE/C;;;GAGG;AACH,eAAO,MAAM,8BAA8B,EAAE,SAAS,MAAM,EAAgB,CAAC;AAE7E;;GAEG;AACH,eAAO,MAAM,iBAAiB,aAiB5B,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,6BAA6B,aAQxC,CAAC;AAEH,MAAM,WAAW,kCAAkC;IACjD;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,YAAY,CAAC,EAAE,yBAAyB,CAAC;IAClD,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;IAChC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B,6EAA6E;IAC7E,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,+EAA+E;IAC/E,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7C,mFAAmF;IACnF,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,OAAO,KAAK,IAAI,CAAC;IAC5E,oFAAoF;IACpF,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,OAAO,EAAE,aAAa,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9G;AAED,qBAAa,2BAA4B,YAAW,mBAAmB;IACrE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAwC;IACrE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;IACvC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IACpD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAgC;IAChE,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA+D;IACjG,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAEpB;gBAEF,OAAO,GAAE,kCAAuC;IAc5D;;;;;;OAMG;IACH,OAAO,CAAC,aAAa;IAcrB;;;OAGG;IACH,OAAO,CAAC,aAAa;IAOrB,GAAG,CAAC,KAAK,EAAE;QACT,MAAM,EAAE,0BAA0B,CAAC;QACnC,OAAO,EAAE,oBAAoB,CAAC;QAC9B,MAAM,EAAE,WAAW,CAAC;KACrB,GAAG,aAAa,CAAC,kBAAkB,CAAC;YA4BtB,WAAW;CA6e3B"}
|