@cat-factory/local-server 0.14.2 → 0.16.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/LocalContainerRunnerTransport.d.ts +97 -9
- package/dist/LocalContainerRunnerTransport.d.ts.map +1 -1
- package/dist/LocalContainerRunnerTransport.js +355 -93
- package/dist/LocalContainerRunnerTransport.js.map +1 -1
- package/dist/LocalProcessRunnerTransport.d.ts +63 -0
- package/dist/LocalProcessRunnerTransport.d.ts.map +1 -0
- package/dist/LocalProcessRunnerTransport.js +188 -0
- package/dist/LocalProcessRunnerTransport.js.map +1 -0
- package/dist/NativeRoutingRunnerTransport.d.ts +20 -0
- package/dist/NativeRoutingRunnerTransport.d.ts.map +1 -0
- package/dist/NativeRoutingRunnerTransport.js +50 -0
- package/dist/NativeRoutingRunnerTransport.js.map +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +6 -0
- package/dist/config.js.map +1 -1
- package/dist/container.d.ts +13 -0
- package/dist/container.d.ts.map +1 -1
- package/dist/container.js +244 -17
- package/dist/container.js.map +1 -1
- package/dist/harnessHttp.d.ts +58 -0
- package/dist/harnessHttp.d.ts.map +1 -0
- package/dist/harnessHttp.js +95 -0
- package/dist/harnessHttp.js.map +1 -0
- package/dist/runtimes/appleContainerRuntime.d.ts +3 -0
- package/dist/runtimes/appleContainerRuntime.d.ts.map +1 -1
- package/dist/runtimes/appleContainerRuntime.js +8 -1
- package/dist/runtimes/appleContainerRuntime.js.map +1 -1
- package/dist/runtimes/containerRuntime.d.ts +30 -1
- package/dist/runtimes/containerRuntime.d.ts.map +1 -1
- package/dist/runtimes/containerRuntime.js +5 -0
- package/dist/runtimes/containerRuntime.js.map +1 -1
- package/dist/runtimes/dockerRuntime.d.ts +4 -0
- package/dist/runtimes/dockerRuntime.d.ts.map +1 -1
- package/dist/runtimes/dockerRuntime.js +21 -2
- package/dist/runtimes/dockerRuntime.js.map +1 -1
- package/dist/runtimes/index.d.ts.map +1 -1
- package/dist/runtimes/index.js +1 -0
- package/dist/runtimes/index.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +4 -14
- package/dist/server.js.map +1 -1
- package/package.json +9 -8
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import type { RunnerDispatchKind, RunnerJobRef, RunnerJobView, RunnerTransport } from '@cat-factory/kernel';
|
|
3
|
+
export interface LocalProcessRunnerTransportOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Path to the executor-harness HTTP server entry (its `server.js`/`server.ts`). Spawned
|
|
6
|
+
* as `node <entry>`; with a `.ts` entry, Node's type-stripping (Node 24+) runs it.
|
|
7
|
+
*/
|
|
8
|
+
harnessEntry: string;
|
|
9
|
+
/** Node executable to spawn the harness with. Default `process.execPath`. */
|
|
10
|
+
nodePath?: string;
|
|
11
|
+
/** Extra args to pass to node before the entry (e.g. `--experimental-strip-types`). */
|
|
12
|
+
nodeArgs?: string[];
|
|
13
|
+
/** Shared secret injected as `HARNESS_SHARED_SECRET` + sent on every call. Default random. */
|
|
14
|
+
sharedSecret?: string;
|
|
15
|
+
/** Extra env for the harness process (e.g. GITHUB_ALLOWED_HOSTS). */
|
|
16
|
+
env?: Record<string, string>;
|
|
17
|
+
/** Injectable fetch — defaults to the global. */
|
|
18
|
+
fetchImpl?: typeof fetch;
|
|
19
|
+
/** Injectable spawn — defaults to node:child_process.spawn (overridable in tests). */
|
|
20
|
+
spawnImpl?: typeof spawn;
|
|
21
|
+
/** Injectable free-port picker — defaults to an ephemeral OS port (overridable in tests). */
|
|
22
|
+
pickPort?: () => Promise<number>;
|
|
23
|
+
/** How long to wait for the harness `/health` after spawn. Default 30s. */
|
|
24
|
+
readyTimeoutMs?: number;
|
|
25
|
+
/** Per-HTTP-call timeout. Default 30s. */
|
|
26
|
+
requestTimeoutMs?: number;
|
|
27
|
+
}
|
|
28
|
+
export declare class LocalProcessRunnerTransport implements RunnerTransport {
|
|
29
|
+
private readonly harnessEntry;
|
|
30
|
+
private readonly nodePath;
|
|
31
|
+
private readonly nodeArgs;
|
|
32
|
+
private readonly sharedSecret;
|
|
33
|
+
private readonly extraEnv;
|
|
34
|
+
private readonly fetchImpl;
|
|
35
|
+
private readonly spawnImpl;
|
|
36
|
+
private readonly pickPort;
|
|
37
|
+
private readonly readyTimeoutMs;
|
|
38
|
+
private readonly requestTimeoutMs;
|
|
39
|
+
/** The single long-lived harness process, started lazily and reused across all runs. */
|
|
40
|
+
private proc;
|
|
41
|
+
private starting;
|
|
42
|
+
constructor(options: LocalProcessRunnerTransportOptions);
|
|
43
|
+
dispatch(ref: RunnerJobRef, spec: Record<string, unknown>, kind?: RunnerDispatchKind): Promise<void>;
|
|
44
|
+
poll(ref: RunnerJobRef): Promise<RunnerJobView>;
|
|
45
|
+
/**
|
|
46
|
+
* No per-run teardown: the harness host process is long-lived and reused across runs
|
|
47
|
+
* (the harness already removes each job's ephemeral workspace itself). Provided so the
|
|
48
|
+
* port contract is satisfied; kept idempotent.
|
|
49
|
+
*/
|
|
50
|
+
release(): Promise<void>;
|
|
51
|
+
/** Stop the harness process (for shutdown / tests). Idempotent. */
|
|
52
|
+
shutdown(): Promise<void>;
|
|
53
|
+
private ensureProcess;
|
|
54
|
+
private startProcess;
|
|
55
|
+
private waitForHealth;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Build a {@link LocalProcessRunnerTransport} from the environment. Requires
|
|
59
|
+
* `LOCAL_HARNESS_ENTRY` (the path to the executor-harness server entry to run as a host
|
|
60
|
+
* process). The native CLIs (`claude` / `codex`) must already be installed on the host.
|
|
61
|
+
*/
|
|
62
|
+
export declare function createLocalProcessTransportFromEnv(env: NodeJS.ProcessEnv): LocalProcessRunnerTransport;
|
|
63
|
+
//# sourceMappingURL=LocalProcessRunnerTransport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LocalProcessRunnerTransport.d.ts","sourceRoot":"","sources":["../src/LocalProcessRunnerTransport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAG7D,OAAO,KAAK,EACV,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,eAAe,EAChB,MAAM,qBAAqB,CAAA;AA0B5B,MAAM,WAAW,kCAAkC;IACjD;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAA;IACpB,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,uFAAuF;IACvF,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,8FAA8F;IAC9F,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,qEAAqE;IACrE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC5B,iDAAiD;IACjD,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;IACxB,sFAAsF;IACtF,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;IACxB,6FAA6F;IAC7F,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAA;IAChC,2EAA2E;IAC3E,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,0CAA0C;IAC1C,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B;AAeD,qBAAa,2BAA4B,YAAW,eAAe;IACjE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAQ;IACrC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAQ;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAU;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAQ;IACrC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwB;IACjD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;IACxC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;IACxC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAuB;IAChD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAQ;IACvC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAQ;IAEzC,wFAAwF;IACxF,OAAO,CAAC,IAAI,CAAoE;IAChF,OAAO,CAAC,QAAQ,CAA6E;IAE7F,YAAY,OAAO,EAAE,kCAAkC,EAWtD;IAEK,QAAQ,CACZ,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,IAAI,GAAE,kBAA4B,GACjC,OAAO,CAAC,IAAI,CAAC,CAYf;IAEK,IAAI,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,CAapD;IAED;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAE7B;IAED,mEAAmE;IAC7D,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAK9B;YAIa,aAAa;YAWb,YAAY;IAoC1B,OAAO,CAAC,aAAa;CAYtB;AAED;;;;GAIG;AACH,wBAAgB,kCAAkC,CAChD,GAAG,EAAE,MAAM,CAAC,UAAU,GACrB,2BAA2B,CAmB7B"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { randomBytes } from 'node:crypto';
|
|
3
|
+
import { createServer } from 'node:net';
|
|
4
|
+
import { EVICTION_ERROR, pollHarnessJob, postHarnessJob, waitForHarnessHealth, } from './harnessHttp.js';
|
|
5
|
+
// The NATIVE local runner backend (opt-in via `LOCAL_NATIVE_AGENTS`): instead of a Docker
|
|
6
|
+
// container per run, it runs the SAME executor-harness as a long-lived HOST PROCESS on
|
|
7
|
+
// 127.0.0.1 and drives it through the harness's existing HTTP API. So all the harness
|
|
8
|
+
// machinery — git clone/push/PR, structured-output, watchdogs, the JobRegistry, progress —
|
|
9
|
+
// is reused unchanged; the only difference from the container transport is WHERE the harness
|
|
10
|
+
// runs (a host `node` process vs a container) and that the agent uses the developer's OWN
|
|
11
|
+
// installed `claude` / `codex` CLI with its ambient login (the executor sets `ambientAuth`
|
|
12
|
+
// on the job, so no credential is leased). This bypasses Docker entirely.
|
|
13
|
+
//
|
|
14
|
+
// SECURITY: the agent runs as a plain host subprocess with the developer's full shell/file
|
|
15
|
+
// access and their personal subscription — no container sandbox, no spend metering, no
|
|
16
|
+
// model-locking. Acceptable ONLY because local mode is the developer's own machine; it is
|
|
17
|
+
// therefore opt-in (default off) and reachable only from `buildLocalContainer`.
|
|
18
|
+
/** The harness is always on loopback for the native host-process transport. */
|
|
19
|
+
const endpointFor = (port) => ({ host: '127.0.0.1', port });
|
|
20
|
+
/** An ephemeral free localhost port (best-effort; a tiny TOCTOU window is fine for dev). */
|
|
21
|
+
function ephemeralPort() {
|
|
22
|
+
return new Promise((resolve, reject) => {
|
|
23
|
+
const srv = createServer();
|
|
24
|
+
srv.on('error', reject);
|
|
25
|
+
srv.listen(0, '127.0.0.1', () => {
|
|
26
|
+
const addr = srv.address();
|
|
27
|
+
const port = typeof addr === 'object' && addr ? addr.port : 0;
|
|
28
|
+
srv.close(() => (port ? resolve(port) : reject(new Error('could not pick a free port'))));
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
export class LocalProcessRunnerTransport {
|
|
33
|
+
harnessEntry;
|
|
34
|
+
nodePath;
|
|
35
|
+
nodeArgs;
|
|
36
|
+
sharedSecret;
|
|
37
|
+
extraEnv;
|
|
38
|
+
fetchImpl;
|
|
39
|
+
spawnImpl;
|
|
40
|
+
pickPort;
|
|
41
|
+
readyTimeoutMs;
|
|
42
|
+
requestTimeoutMs;
|
|
43
|
+
/** The single long-lived harness process, started lazily and reused across all runs. */
|
|
44
|
+
proc;
|
|
45
|
+
starting;
|
|
46
|
+
constructor(options) {
|
|
47
|
+
this.harnessEntry = options.harnessEntry;
|
|
48
|
+
this.nodePath = options.nodePath ?? process.execPath;
|
|
49
|
+
this.nodeArgs = options.nodeArgs ?? [];
|
|
50
|
+
this.sharedSecret = options.sharedSecret ?? randomBytes(24).toString('hex');
|
|
51
|
+
this.extraEnv = options.env ?? {};
|
|
52
|
+
this.fetchImpl = options.fetchImpl ?? fetch;
|
|
53
|
+
this.spawnImpl = options.spawnImpl ?? spawn;
|
|
54
|
+
this.pickPort = options.pickPort ?? ephemeralPort;
|
|
55
|
+
this.readyTimeoutMs = options.readyTimeoutMs ?? 30_000;
|
|
56
|
+
this.requestTimeoutMs = options.requestTimeoutMs ?? 30_000;
|
|
57
|
+
}
|
|
58
|
+
async dispatch(ref, spec, kind = 'agent') {
|
|
59
|
+
const proc = await this.ensureProcess();
|
|
60
|
+
// The harness keys jobs by the per-step `ref.jobId` in the body; a re-dispatch
|
|
61
|
+
// (durable-driver replay) re-POSTs, which the JobRegistry treats as a re-attach.
|
|
62
|
+
await postHarnessJob({
|
|
63
|
+
fetchImpl: this.fetchImpl,
|
|
64
|
+
endpoint: endpointFor(proc.port),
|
|
65
|
+
secret: this.sharedSecret,
|
|
66
|
+
body: { ...spec, kind },
|
|
67
|
+
timeoutMs: this.requestTimeoutMs,
|
|
68
|
+
label: 'Native harness',
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
async poll(ref) {
|
|
72
|
+
const proc = this.proc;
|
|
73
|
+
// The process died (or was never started) → report an eviction so the run can recover.
|
|
74
|
+
if (!proc || proc.exited)
|
|
75
|
+
return { state: 'failed', error: EVICTION_ERROR };
|
|
76
|
+
return pollHarnessJob({
|
|
77
|
+
fetchImpl: this.fetchImpl,
|
|
78
|
+
endpoint: endpointFor(proc.port),
|
|
79
|
+
jobId: ref.jobId,
|
|
80
|
+
secret: this.sharedSecret,
|
|
81
|
+
timeoutMs: this.requestTimeoutMs,
|
|
82
|
+
label: 'Native harness',
|
|
83
|
+
isDead: () => proc.exited,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* No per-run teardown: the harness host process is long-lived and reused across runs
|
|
88
|
+
* (the harness already removes each job's ephemeral workspace itself). Provided so the
|
|
89
|
+
* port contract is satisfied; kept idempotent.
|
|
90
|
+
*/
|
|
91
|
+
async release() {
|
|
92
|
+
// intentionally a no-op
|
|
93
|
+
}
|
|
94
|
+
/** Stop the harness process (for shutdown / tests). Idempotent. */
|
|
95
|
+
async shutdown() {
|
|
96
|
+
const proc = this.proc;
|
|
97
|
+
this.proc = undefined;
|
|
98
|
+
this.starting = undefined;
|
|
99
|
+
if (proc && !proc.exited)
|
|
100
|
+
proc.child.kill();
|
|
101
|
+
}
|
|
102
|
+
// --- internals ----------------------------------------------------------
|
|
103
|
+
async ensureProcess() {
|
|
104
|
+
if (this.proc && !this.proc.exited)
|
|
105
|
+
return this.proc;
|
|
106
|
+
this.starting ??= this.startProcess();
|
|
107
|
+
try {
|
|
108
|
+
this.proc = await this.starting;
|
|
109
|
+
return this.proc;
|
|
110
|
+
}
|
|
111
|
+
finally {
|
|
112
|
+
this.starting = undefined;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
async startProcess() {
|
|
116
|
+
const port = await this.pickPort();
|
|
117
|
+
const child = this.spawnImpl(this.nodePath, [...this.nodeArgs, this.harnessEntry], {
|
|
118
|
+
env: {
|
|
119
|
+
...process.env,
|
|
120
|
+
...this.extraEnv,
|
|
121
|
+
PORT: String(port),
|
|
122
|
+
HARNESS_SHARED_SECRET: this.sharedSecret,
|
|
123
|
+
// The harness only auto-listens when NODE_ENV !== 'test'.
|
|
124
|
+
NODE_ENV: 'production',
|
|
125
|
+
},
|
|
126
|
+
stdio: 'ignore',
|
|
127
|
+
});
|
|
128
|
+
const handle = { child, port, exited: false };
|
|
129
|
+
// The harness child is long-lived and not detached, but Node does NOT auto-kill a
|
|
130
|
+
// child when the parent exits — without this, every dev restart orphans a `node
|
|
131
|
+
// <harness>` process still bound to its port (and possibly mid-run on the developer's
|
|
132
|
+
// live Claude/Codex login). `shutdown()` covers the graceful path; this `exit` hook is
|
|
133
|
+
// the backstop for SIGTERM/SIGINT/uncaught exits that reach `process.exit` directly.
|
|
134
|
+
const killOnParentExit = () => {
|
|
135
|
+
try {
|
|
136
|
+
child.kill();
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
// best-effort
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
process.once('exit', killOnParentExit);
|
|
143
|
+
child.on('exit', () => {
|
|
144
|
+
handle.exited = true;
|
|
145
|
+
process.removeListener('exit', killOnParentExit);
|
|
146
|
+
if (this.proc === handle)
|
|
147
|
+
this.proc = undefined;
|
|
148
|
+
});
|
|
149
|
+
await this.waitForHealth(port, handle);
|
|
150
|
+
return handle;
|
|
151
|
+
}
|
|
152
|
+
waitForHealth(port, handle) {
|
|
153
|
+
return waitForHarnessHealth({
|
|
154
|
+
fetchImpl: this.fetchImpl,
|
|
155
|
+
endpoint: endpointFor(port),
|
|
156
|
+
readyTimeoutMs: this.readyTimeoutMs,
|
|
157
|
+
requestTimeoutMs: this.requestTimeoutMs,
|
|
158
|
+
intervalMs: 200,
|
|
159
|
+
isDead: () => handle.exited,
|
|
160
|
+
deadError: 'the native harness process exited before becoming healthy',
|
|
161
|
+
timeoutError: `Timed out waiting for the native harness on 127.0.0.1:${port} to become healthy`,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Build a {@link LocalProcessRunnerTransport} from the environment. Requires
|
|
167
|
+
* `LOCAL_HARNESS_ENTRY` (the path to the executor-harness server entry to run as a host
|
|
168
|
+
* process). The native CLIs (`claude` / `codex`) must already be installed on the host.
|
|
169
|
+
*/
|
|
170
|
+
export function createLocalProcessTransportFromEnv(env) {
|
|
171
|
+
const harnessEntry = env.LOCAL_HARNESS_ENTRY?.trim();
|
|
172
|
+
if (!harnessEntry) {
|
|
173
|
+
throw new Error('LOCAL_HARNESS_ENTRY is required for native local mode (LOCAL_NATIVE_AGENTS): set it to ' +
|
|
174
|
+
'the executor-harness server entry path (its built server.js, or src/server.ts run via ' +
|
|
175
|
+
'Node type-stripping).');
|
|
176
|
+
}
|
|
177
|
+
const nodeArgs = env.LOCAL_HARNESS_NODE_ARGS?.trim()
|
|
178
|
+
? env.LOCAL_HARNESS_NODE_ARGS.trim().split(/\s+/)
|
|
179
|
+
: undefined;
|
|
180
|
+
const allowedHosts = env.GITHUB_ALLOWED_HOSTS?.trim();
|
|
181
|
+
return new LocalProcessRunnerTransport({
|
|
182
|
+
harnessEntry,
|
|
183
|
+
...(nodeArgs ? { nodeArgs } : {}),
|
|
184
|
+
sharedSecret: env.HARNESS_SHARED_SECRET?.trim() || undefined,
|
|
185
|
+
...(allowedHosts ? { env: { GITHUB_ALLOWED_HOSTS: allowedHosts } } : {}),
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
//# sourceMappingURL=LocalProcessRunnerTransport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LocalProcessRunnerTransport.js","sourceRoot":"","sources":["../src/LocalProcessRunnerTransport.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { RunnerDispatchKind, RunnerDispatchOptions, RunnerJobRef, RunnerJobView, RunnerTransport } from '@cat-factory/kernel';
|
|
2
|
+
export declare class NativeRoutingRunnerTransport implements RunnerTransport {
|
|
3
|
+
/** Host-process transport for ambient (native CLI) steps — built lazily, cached. */
|
|
4
|
+
private readonly ambient;
|
|
5
|
+
/** Per-run container transport for everything else — built lazily, cached (the
|
|
6
|
+
* container transport resolves its pool config from the DB, so this may be async). */
|
|
7
|
+
private readonly managed;
|
|
8
|
+
/** ref → the transport that handled its dispatch, so poll/release hit the same backend. */
|
|
9
|
+
private readonly routed;
|
|
10
|
+
constructor(
|
|
11
|
+
/** Host-process transport for ambient (native CLI) steps — built lazily, cached. */
|
|
12
|
+
ambient: () => RunnerTransport | Promise<RunnerTransport>,
|
|
13
|
+
/** Per-run container transport for everything else — built lazily, cached (the
|
|
14
|
+
* container transport resolves its pool config from the DB, so this may be async). */
|
|
15
|
+
managed: () => RunnerTransport | Promise<RunnerTransport>);
|
|
16
|
+
dispatch(ref: RunnerJobRef, spec: Record<string, unknown>, kind?: RunnerDispatchKind, options?: RunnerDispatchOptions): Promise<void>;
|
|
17
|
+
poll(ref: RunnerJobRef): Promise<RunnerJobView>;
|
|
18
|
+
release(ref: RunnerJobRef): Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=NativeRoutingRunnerTransport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NativeRoutingRunnerTransport.d.ts","sourceRoot":"","sources":["../src/NativeRoutingRunnerTransport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,qBAAqB,EACrB,YAAY,EACZ,aAAa,EACb,eAAe,EAChB,MAAM,qBAAqB,CAAA;AAqB5B,qBAAa,4BAA6B,YAAW,eAAe;IAKhE,oFAAoF;IACpF,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB;0FACsF;IACtF,OAAO,CAAC,QAAQ,CAAC,OAAO;IAR1B,2FAA2F;IAC3F,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqC;IAE5D;IACE,oFAAoF;IACnE,OAAO,EAAE,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;IAC1E;0FACsF;IACrE,OAAO,EAAE,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,EACxE;IAEE,QAAQ,CACZ,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,IAAI,GAAE,kBAA4B,EAClC,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,IAAI,CAAC,CAIf;IAEK,IAAI,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,CAMpD;IAEK,OAAO,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAI9C;CACF"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// NATIVE-MODE transport router (local facade, `LOCAL_NATIVE_AGENTS`): native mode runs the
|
|
2
|
+
// developer's OWN `claude` / `codex` CLI as a host process (no sandbox), which is only
|
|
3
|
+
// appropriate for the steps that actually use that ambient login. The executor flags such a
|
|
4
|
+
// step with `ambientAuth: true` on its job body; everything else (a proxy/`pi` model, or a
|
|
5
|
+
// non-native vendor reusing the claude-code harness) MUST still run in a sandboxed per-run
|
|
6
|
+
// container, exactly as the README promises ("proxy-only models still need the container
|
|
7
|
+
// path"). Previously native mode sent EVERY dispatch to the host process, silently running
|
|
8
|
+
// proxy-model steps unsandboxed.
|
|
9
|
+
//
|
|
10
|
+
// So this routes per JOB (not per run — a single run legitimately mixes an ambient Claude
|
|
11
|
+
// step with a proxy step): `ambientAuth` jobs → the host-process transport; the rest → the
|
|
12
|
+
// container transport (built lazily, so a native deployment that only runs Claude/Codex
|
|
13
|
+
// never needs LOCAL_HARNESS_IMAGE; a proxy step without an image fails loudly there). The
|
|
14
|
+
// chosen transport is remembered per ref so poll/release reach the same backend.
|
|
15
|
+
const EVICTION_ERROR = 'Job not found (container evicted or crashed)';
|
|
16
|
+
const refKey = (ref) => `${ref.runId}:${ref.jobId}`;
|
|
17
|
+
export class NativeRoutingRunnerTransport {
|
|
18
|
+
ambient;
|
|
19
|
+
managed;
|
|
20
|
+
/** ref → the transport that handled its dispatch, so poll/release hit the same backend. */
|
|
21
|
+
routed = new Map();
|
|
22
|
+
constructor(
|
|
23
|
+
/** Host-process transport for ambient (native CLI) steps — built lazily, cached. */
|
|
24
|
+
ambient,
|
|
25
|
+
/** Per-run container transport for everything else — built lazily, cached (the
|
|
26
|
+
* container transport resolves its pool config from the DB, so this may be async). */
|
|
27
|
+
managed) {
|
|
28
|
+
this.ambient = ambient;
|
|
29
|
+
this.managed = managed;
|
|
30
|
+
}
|
|
31
|
+
async dispatch(ref, spec, kind = 'agent', options) {
|
|
32
|
+
const transport = await (spec.ambientAuth === true ? this.ambient() : this.managed());
|
|
33
|
+
this.routed.set(refKey(ref), transport);
|
|
34
|
+
await transport.dispatch(ref, spec, kind, options);
|
|
35
|
+
}
|
|
36
|
+
async poll(ref) {
|
|
37
|
+
// Unknown ref (a fresh process after a durable replay): report an eviction so the
|
|
38
|
+
// sweeper re-drives — the re-dispatch (idempotent) re-populates the routing map.
|
|
39
|
+
const transport = this.routed.get(refKey(ref));
|
|
40
|
+
if (!transport)
|
|
41
|
+
return { state: 'failed', error: EVICTION_ERROR };
|
|
42
|
+
return transport.poll(ref);
|
|
43
|
+
}
|
|
44
|
+
async release(ref) {
|
|
45
|
+
const transport = this.routed.get(refKey(ref));
|
|
46
|
+
this.routed.delete(refKey(ref));
|
|
47
|
+
await transport?.release?.(ref);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=NativeRoutingRunnerTransport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NativeRoutingRunnerTransport.js","sourceRoot":"","sources":["../src/NativeRoutingRunnerTransport.ts"],"names":[],"mappings":"AAQA,2FAA2F;AAC3F,uFAAuF;AACvF,4FAA4F;AAC5F,2FAA2F;AAC3F,2FAA2F;AAC3F,yFAAyF;AACzF,2FAA2F;AAC3F,iCAAiC;AACjC,EAAE;AACF,0FAA0F;AAC1F,2FAA2F;AAC3F,wFAAwF;AACxF,0FAA0F;AAC1F,iFAAiF;AAEjF,MAAM,cAAc,GAAG,8CAA8C,CAAA;AAErE,MAAM,MAAM,GAAG,CAAC,GAAiB,EAAU,EAAE,CAAC,GAAG,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,KAAK,EAAE,CAAA;AAEzE,MAAM,OAAO,4BAA4B;IAMpB,OAAO;IAGP,OAAO;IAR1B,2FAA2F;IAC1E,MAAM,GAAG,IAAI,GAAG,EAA2B,CAAA;IAE5D;IACE,oFAAoF;IACnE,OAAyD;IAC1E;0FACsF;IACrE,OAAyD;uBAHzD,OAAO;uBAGP,OAAO;IACvB,CAAC;IAEJ,KAAK,CAAC,QAAQ,CACZ,GAAiB,EACjB,IAA6B,EAC7B,IAAI,GAAuB,OAAO,EAClC,OAA+B;QAE/B,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAA;QACrF,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,SAAS,CAAC,CAAA;QACvC,MAAM,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;IACpD,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,GAAiB;QAC1B,kFAAkF;QAClF,iFAAiF;QACjF,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;QAC9C,IAAI,CAAC,SAAS;YAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,cAAc,EAAE,CAAA;QACjE,OAAO,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAC5B,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,GAAiB;QAC7B,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;QAC9C,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;QAC/B,MAAM,SAAS,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,CAAA;IACjC,CAAC;CACF"}
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAgBpD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAgBpD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CA6B5E;AAED,qEAAqE;AACrE,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,SAAS,CAEjE"}
|
package/dist/config.js
CHANGED
|
@@ -38,6 +38,12 @@ export function applyLocalDefaults(env) {
|
|
|
38
38
|
// alias routes back to this service on the host. The docker-family transport
|
|
39
39
|
// publishes that alias on Linux via `--add-host=<alias>:host-gateway`.
|
|
40
40
|
PUBLIC_URL: env.PUBLIC_URL?.trim() || `http://${hostAlias}:${port}`,
|
|
41
|
+
// Assemble the ephemeral-environment module by default so the Tester's "delegate test
|
|
42
|
+
// environments to a provider" opt-in works once a developer registers a provider — the
|
|
43
|
+
// module is inert (and the local default stays host DinD) until they connect one AND
|
|
44
|
+
// flip the toggle, so defaulting it on has no behavioural cost. Set ENVIRONMENTS_ENABLED
|
|
45
|
+
// explicitly to override.
|
|
46
|
+
ENVIRONMENTS_ENABLED: env.ENVIRONMENTS_ENABLED?.trim() || 'true',
|
|
41
47
|
};
|
|
42
48
|
}
|
|
43
49
|
/** The shared {@link AppConfig} with local-mode defaults applied. */
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAEzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAEtD,mFAAmF;AACnF,mFAAmF;AACnF,gDAAgD;AAChD,iFAAiF;AACjF,+DAA+D;AAC/D,uFAAuF;AACvF,6EAA6E;AAC7E,oFAAoF;AACpF,yDAAyD;AACzD,wEAAwE;AAExE,MAAM,YAAY,GAAG,MAAM,CAAA;AAE3B;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAsB;IACvD,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,YAAY,CAAA;IAC7C,gFAAgF;IAChF,qFAAqF;IACrF,qFAAqF;IACrF,MAAM,SAAS,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAA;IACvC,OAAO;QACL,GAAG,GAAG;QACN,oFAAoF;QACpF,sFAAsF;QACtF,aAAa,EAAE,GAAG,CAAC,aAAa,EAAE,IAAI,EAAE,IAAI,MAAM;QAClD,+EAA+E;QAC/E,mBAAmB,EAAE,GAAG,CAAC,mBAAmB,EAAE,IAAI,EAAE,IAAI,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;QACvF,mFAAmF;QACnF,qFAAqF;QACrF,sFAAsF;QACtF,gFAAgF;QAChF,cAAc,EAAE,GAAG,CAAC,cAAc,EAAE,IAAI,EAAE,IAAI,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAChF,qFAAqF;QACrF,6EAA6E;QAC7E,uEAAuE;QACvE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,UAAU,SAAS,IAAI,IAAI,EAAE;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAEzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAEtD,mFAAmF;AACnF,mFAAmF;AACnF,gDAAgD;AAChD,iFAAiF;AACjF,+DAA+D;AAC/D,uFAAuF;AACvF,6EAA6E;AAC7E,oFAAoF;AACpF,yDAAyD;AACzD,wEAAwE;AAExE,MAAM,YAAY,GAAG,MAAM,CAAA;AAE3B;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAsB;IACvD,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,YAAY,CAAA;IAC7C,gFAAgF;IAChF,qFAAqF;IACrF,qFAAqF;IACrF,MAAM,SAAS,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAA;IACvC,OAAO;QACL,GAAG,GAAG;QACN,oFAAoF;QACpF,sFAAsF;QACtF,aAAa,EAAE,GAAG,CAAC,aAAa,EAAE,IAAI,EAAE,IAAI,MAAM;QAClD,+EAA+E;QAC/E,mBAAmB,EAAE,GAAG,CAAC,mBAAmB,EAAE,IAAI,EAAE,IAAI,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;QACvF,mFAAmF;QACnF,qFAAqF;QACrF,sFAAsF;QACtF,gFAAgF;QAChF,cAAc,EAAE,GAAG,CAAC,cAAc,EAAE,IAAI,EAAE,IAAI,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAChF,qFAAqF;QACrF,6EAA6E;QAC7E,uEAAuE;QACvE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,UAAU,SAAS,IAAI,IAAI,EAAE;QACnE,sFAAsF;QACtF,uFAAuF;QACvF,qFAAqF;QACrF,yFAAyF;QACzF,0BAA0B;QAC1B,oBAAoB,EAAE,GAAG,CAAC,oBAAoB,EAAE,IAAI,EAAE,IAAI,MAAM;KACjE,CAAA;AACH,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,eAAe,CAAC,GAAsB;IACpD,OAAO,cAAc,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAA;AAChD,CAAC"}
|
package/dist/container.d.ts
CHANGED
|
@@ -1,4 +1,17 @@
|
|
|
1
1
|
import type { NodeContainerOptions } from '@cat-factory/node-server';
|
|
2
2
|
import type { ServerContainer } from '@cat-factory/server';
|
|
3
|
+
import type { HarnessKind } from '@cat-factory/kernel';
|
|
3
4
|
export declare function buildLocalContainer(options: NodeContainerOptions): ServerContainer;
|
|
5
|
+
/**
|
|
6
|
+
* Parse `LOCAL_NATIVE_AGENTS` into the set of subscription harnesses to run natively. The
|
|
7
|
+
* documented form is a comma-separated list of harness ids (`claude-code,codex`); `claude`
|
|
8
|
+
* is accepted as an alias for `claude-code`. Blank/unset OR an explicit off value
|
|
9
|
+
* (`false`/`0`/`off`/`no`/`none`/`disabled`) ⇒ off (`[]`) — so disabling native mode never
|
|
10
|
+
* accidentally enables it. An affirmative value naming no harness (`true`/`1`/`on`/…) ⇒ BOTH
|
|
11
|
+
* native harnesses. Only `claude-code` / `codex` are ever native; any other unrecognised
|
|
12
|
+
* token is ignored. A value with neither a recognised harness nor an affirmative keyword
|
|
13
|
+
* (e.g. a typo) ⇒ off, so an unintelligible setting fails safe rather than enabling an
|
|
14
|
+
* unsandboxed, unmetered mode.
|
|
15
|
+
*/
|
|
16
|
+
export declare function parseNativeHarnesses(raw: string | undefined): HarnessKind[];
|
|
4
17
|
//# sourceMappingURL=container.d.ts.map
|
package/dist/container.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAA;AAIpE,OAAO,KAAK,EAAqC,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAG7F,OAAO,KAAK,EAAE,WAAW,EAAmB,MAAM,qBAAqB,CAAA;AAuCvE,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,eAAe,CA2RlF;AAOD;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,WAAW,EAAE,CAc3E"}
|