@dynamicagents/plugins 0.13.0 → 0.15.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/README.md +14 -14
- package/dist/claude-code/cards.d.ts +4 -0
- package/dist/claude-code/cards.js +22 -0
- package/dist/claude-code/config.d.ts +10 -83
- package/dist/claude-code/config.js +0 -2
- package/dist/claude-code/credentials.d.ts +32 -50
- package/dist/claude-code/credentials.js +115 -74
- package/dist/claude-code/daemon/index.d.ts +24 -0
- package/dist/claude-code/daemon/index.js +203 -0
- package/dist/claude-code/egress.d.ts +35 -117
- package/dist/claude-code/egress.js +80 -325
- package/dist/claude-code/events.d.ts +14 -17
- package/dist/claude-code/events.js +19 -15
- package/dist/claude-code/harness-wire.d.ts +45 -0
- package/dist/claude-code/harness-wire.js +47 -0
- package/dist/claude-code/index.d.ts +19 -29
- package/dist/claude-code/index.js +17 -25
- package/dist/claude-code/language-model.d.ts +19 -0
- package/dist/claude-code/language-model.js +71 -0
- package/dist/claude-code/model.d.ts +77 -70
- package/dist/claude-code/model.js +328 -304
- package/dist/claude-code/placeholder.d.ts +12 -0
- package/dist/claude-code/placeholder.js +12 -0
- package/dist/claude-code/spec.d.ts +4 -4
- package/dist/claude-code/spec.js +4 -4
- package/dist/claude-code/verified.d.ts +1 -1
- package/dist/claude-code/verified.js +1 -1
- package/dist/computer/client.d.ts +88 -0
- package/dist/computer/client.js +6 -0
- package/dist/computer/context.d.ts +7 -7
- package/dist/computer/context.js +14 -18
- package/dist/computer/gate.d.ts +4 -23
- package/dist/computer/gate.js +1 -37
- package/dist/computer/index.d.ts +44 -43
- package/dist/computer/index.js +29 -50
- package/dist/computer/paths.d.ts +5 -27
- package/dist/computer/paths.js +7 -30
- package/dist/computer/proxy.d.ts +17 -31
- package/dist/computer/proxy.js +9 -44
- package/dist/computer/render.d.ts +3 -40
- package/dist/computer/render.js +3 -36
- package/dist/computer/sandbox.d.ts +55 -0
- package/dist/computer/sandbox.js +236 -0
- package/dist/computer/shell.d.ts +36 -0
- package/dist/computer/shell.js +41 -0
- package/dist/computer/tools-exec.js +3 -9
- package/dist/computer/tools-file.d.ts +1 -1
- package/dist/computer/tools-file.js +1 -1
- package/dist/{repo → repo-github}/checkout.d.ts +3 -4
- package/dist/{repo → repo-github}/checkout.js +3 -4
- package/dist/{repo → repo-github}/context.d.ts +14 -32
- package/dist/{repo → repo-github}/context.js +46 -81
- package/dist/{repo → repo-github}/index.d.ts +30 -13
- package/dist/{repo → repo-github}/index.js +25 -6
- package/dist/repo-github/mcp.d.ts +95 -0
- package/dist/repo-github/mcp.js +107 -0
- package/dist/repo-github/sandbox-egress.d.ts +68 -0
- package/dist/repo-github/sandbox-egress.js +272 -0
- package/dist/repo-github/sandbox-git.d.ts +30 -0
- package/dist/repo-github/sandbox-git.js +113 -0
- package/dist/{repo → repo-github}/tools-checks.js +43 -4
- package/dist/{repo → repo-github}/tools-clone.js +2 -21
- package/dist/{repo → repo-github}/tools-pr.d.ts +0 -1
- package/dist/{repo → repo-github}/tools-pr.js +85 -20
- package/dist/{repo → repo-github}/tools-review.d.ts +6 -0
- package/dist/{repo → repo-github}/tools-review.js +62 -176
- package/dist/{repo → repo-github}/url.d.ts +11 -0
- package/dist/{repo → repo-github}/url.js +12 -1
- package/dist/{workspace → sandbox}/advisory.d.ts +16 -35
- package/dist/{workspace → sandbox}/advisory.js +2 -29
- package/dist/sandbox/agent-exec.d.ts +31 -0
- package/dist/sandbox/agent-exec.js +62 -0
- package/dist/sandbox/ca-trust.d.ts +9 -0
- package/dist/sandbox/ca-trust.js +21 -0
- package/dist/sandbox/constants.d.ts +22 -0
- package/dist/sandbox/constants.js +22 -0
- package/dist/sandbox/daemon/composite.d.ts +9 -0
- package/dist/sandbox/daemon/composite.js +35 -0
- package/dist/sandbox/daemon/index.d.ts +47 -0
- package/dist/sandbox/daemon/index.js +116 -0
- package/dist/sandbox/egress.d.ts +81 -0
- package/dist/sandbox/egress.js +109 -0
- package/dist/sandbox/exec.d.ts +57 -0
- package/dist/sandbox/exec.js +52 -0
- package/dist/sandbox/format.d.ts +2 -0
- package/dist/sandbox/format.js +7 -0
- package/dist/sandbox/header.d.ts +50 -0
- package/dist/sandbox/header.js +94 -0
- package/dist/sandbox/index.d.ts +17 -0
- package/dist/sandbox/index.js +17 -0
- package/dist/{workspace/install.d.ts → sandbox/install-plan.d.ts} +10 -1
- package/dist/{workspace/install.js → sandbox/install-plan.js} +22 -4
- package/dist/sandbox/name.d.ts +27 -0
- package/dist/sandbox/name.js +32 -0
- package/dist/sandbox/object.d.ts +244 -0
- package/dist/sandbox/object.js +1139 -0
- package/dist/scratch/index.d.ts +1 -9
- package/dist/scratch/index.js +2 -18
- package/package.json +26 -22
- package/dist/claude-code/github.d.ts +0 -39
- package/dist/claude-code/github.js +0 -82
- package/dist/claude-code/run.d.ts +0 -474
- package/dist/claude-code/run.js +0 -901
- package/dist/claude-code/session.d.ts +0 -131
- package/dist/claude-code/session.js +0 -285
- package/dist/workspace/ca-trust.d.ts +0 -95
- package/dist/workspace/ca-trust.js +0 -312
- package/dist/workspace/container-deps.d.ts +0 -54
- package/dist/workspace/container-deps.js +0 -224
- package/dist/workspace/container-fault.d.ts +0 -38
- package/dist/workspace/container-fault.js +0 -73
- package/dist/workspace/exec.d.ts +0 -94
- package/dist/workspace/exec.js +0 -153
- package/dist/workspace/format.d.ts +0 -36
- package/dist/workspace/format.js +0 -57
- package/dist/workspace/git-host.d.ts +0 -79
- package/dist/workspace/git-host.js +0 -226
- package/dist/workspace/git-identity.d.ts +0 -57
- package/dist/workspace/git-identity.js +0 -147
- package/dist/workspace/index.d.ts +0 -49
- package/dist/workspace/index.js +0 -58
- package/dist/workspace/install-job.d.ts +0 -121
- package/dist/workspace/install-job.js +0 -866
- package/dist/workspace/object.d.ts +0 -502
- package/dist/workspace/object.js +0 -1427
- package/dist/workspace/open.d.ts +0 -95
- package/dist/workspace/open.js +0 -63
- package/dist/workspace/read.d.ts +0 -16
- package/dist/workspace/read.js +0 -22
- package/dist/workspace/shell.d.ts +0 -45
- package/dist/workspace/shell.js +0 -80
- package/dist/workspace/sync.d.ts +0 -111
- package/dist/workspace/sync.js +0 -124
- package/dist/workspace/wake.d.ts +0 -19
- package/dist/workspace/wake.js +0 -10
- /package/dist/{repo → repo-github}/tools-checks.d.ts +0 -0
- /package/dist/{repo → repo-github}/tools-clone.d.ts +0 -0
- /package/dist/{repo → repo-github}/tools-worktree.d.ts +0 -0
- /package/dist/{repo → repo-github}/tools-worktree.js +0 -0
- /package/dist/{repo → repo-github}/tools-worktrees.d.ts +0 -0
- /package/dist/{repo → repo-github}/tools-worktrees.js +0 -0
|
@@ -1,474 +0,0 @@
|
|
|
1
|
-
import type { WorkspaceRuntimeExecHandle, WorkspaceRuntimeExecOptions, WorkspaceRuntimeGetOptions, WorkspaceRuntimeKillOptions } from "@cloudflare/computer";
|
|
2
|
-
import type { NoteData } from "@dynamicagents/core/subagent";
|
|
3
|
-
import { type ClaudeCodeResult, type RateLimitInfo } from "./events.js";
|
|
4
|
-
import { type EffortLevel, type PermissionMode } from "./config.js";
|
|
5
|
-
/**
|
|
6
|
-
* Launching Claude Code in the workspace container, and draining it to its end.
|
|
7
|
-
*
|
|
8
|
-
* ## One sub-agent run is one `claude -p` session
|
|
9
|
-
*
|
|
10
|
-
* Not one turn, and not one tool call. The unit has to be substantial because of
|
|
11
|
-
* what an invocation costs before it does anything: the harness carries an
|
|
12
|
-
* 18.7-27k token cached prefix, and a ten-call burst billed **twenty** raw input
|
|
13
|
-
* tokens against 187,130 cache reads. On anything short the prefix is the bill.
|
|
14
|
-
*
|
|
15
|
-
* ## Detached, then re-attached — never owned by a request
|
|
16
|
-
*
|
|
17
|
-
* The run is spawned under an exec id and left running, and a drain reads it to
|
|
18
|
-
* its exit. A drain cut short — an eviction, a deploy — does not take the
|
|
19
|
-
* session with it: the next one re-attaches under the same id. That shape is
|
|
20
|
-
* not a preference: a session owned by the request that started it dies with
|
|
21
|
-
* that request — the same way a dependency install dies halfway through
|
|
22
|
-
* `npm ci`.
|
|
23
|
-
*
|
|
24
|
-
* ## The cursor
|
|
25
|
-
*
|
|
26
|
-
* `getExec(id, { resume })` accepts `"tail"`, `"full"` **or an event sequence
|
|
27
|
-
* number**, and the number is what this uses. The caller stores the last `seq`
|
|
28
|
-
* consumed, so a resumed drain starts exactly there instead of replaying an
|
|
29
|
-
* arbitrary tail. Replay still happens when a drain dies before the cursor is
|
|
30
|
-
* stored, which is why the note keys stay positional (see `toProgress`); the
|
|
31
|
-
* cursor makes replay rare, the keys make it harmless.
|
|
32
|
-
*
|
|
33
|
-
* The cursor also carries the **exec id** and the **parsed result**, and both
|
|
34
|
-
* are there for reasons that only show up under concurrency or retry — see
|
|
35
|
-
* {@link DrainCursor}.
|
|
36
|
-
*/
|
|
37
|
-
/**
|
|
38
|
-
* Just enough of a workspace runtime to drive one detached session.
|
|
39
|
-
*
|
|
40
|
-
* Structural rather than `@cloudflare/computer`'s `WorkspaceRuntime`, for the
|
|
41
|
-
* reason `InstallProbe` is structural one folder over: the class is not exported
|
|
42
|
-
* as a type, it carries a dozen members none of this needs, and a spec that has
|
|
43
|
-
* to construct one cannot test a drain without a container. Three methods is the
|
|
44
|
-
* whole dependency.
|
|
45
|
-
*/
|
|
46
|
-
export interface SessionRuntime {
|
|
47
|
-
exec(source: string, options: WorkspaceRuntimeExecOptions<"utf8">): Promise<WorkspaceRuntimeExecHandle<"utf8">>;
|
|
48
|
-
getExec(id: string, options: WorkspaceRuntimeGetOptions<"utf8">): Promise<WorkspaceRuntimeExecHandle<"utf8">>;
|
|
49
|
-
killExec(id: string, options?: WorkspaceRuntimeKillOptions): Promise<void>;
|
|
50
|
-
}
|
|
51
|
-
/** Namespace for every session exec id in a workspace. */
|
|
52
|
-
export declare const CLAUDE_EXEC_PREFIX = "claude-code-run";
|
|
53
|
-
/**
|
|
54
|
-
* The exec id one session occupies.
|
|
55
|
-
*
|
|
56
|
-
* **Per run, not fixed**, and the difference is load-bearing. A workspace is
|
|
57
|
-
* one Durable Object and one container, but runs are concurrent — sessions in a
|
|
58
|
-
* scratchpad share their parent's container — so under a single shared id they would spawn
|
|
59
|
-
* over one another, each drain would attach to whichever exec won, and
|
|
60
|
-
* `killRun` would stop somebody else's session. That is the displacement bug the
|
|
61
|
-
* coder's install guard exists to prevent, in a new place; here the answer is
|
|
62
|
-
* simply not to share the id.
|
|
63
|
-
*
|
|
64
|
-
* Fixed *per run*, though, because the point is still to find it again: an
|
|
65
|
-
* isolate that dies mid-drain leaves the session running in the container, and
|
|
66
|
-
* `getExec` is how the next drain re-attaches instead of starting a second one.
|
|
67
|
-
*/
|
|
68
|
-
export declare function execIdFor(runId: string): string;
|
|
69
|
-
/**
|
|
70
|
-
* The id a run's follow-up turn runs under — its own, because the session's exec
|
|
71
|
-
* has already finished under {@link execIdFor} and an id names one process.
|
|
72
|
-
*/
|
|
73
|
-
export declare function followUpExecIdFor(runId: string): string;
|
|
74
|
-
/**
|
|
75
|
-
* What the container is given instead of a credential.
|
|
76
|
-
*
|
|
77
|
-
* Claude Code does not validate it locally: a run with this exact value
|
|
78
|
-
* succeeds, and the container only ever sends the placeholder. The egress
|
|
79
|
-
* gateway swaps in the real credential on the way out, so a `postinstall` script
|
|
80
|
-
* that dumps the environment learns this and nothing else.
|
|
81
|
-
*
|
|
82
|
-
* Shaped like a real token deliberately: something that looks obviously fake
|
|
83
|
-
* invites a future reader to "fix" it by putting the real one there.
|
|
84
|
-
*/
|
|
85
|
-
export declare const CREDENTIAL_PLACEHOLDER: string;
|
|
86
|
-
/**
|
|
87
|
-
* Where every session keeps Claude Code's own state — its `CLAUDE_CONFIG_DIR`.
|
|
88
|
-
*
|
|
89
|
-
* The whole config directory moves, created if absent: the transcripts under
|
|
90
|
-
* `projects/<cwd-with-/-as-->/<session-id>.jsonl`, the session index,
|
|
91
|
-
* `.claude.json` and the auto-memory directory. None of it is a credential.
|
|
92
|
-
*
|
|
93
|
-
* This is what decides how long a session stays resumable. The CLI's own
|
|
94
|
-
* `$HOME/.claude` is on the container's disk, so a conversation there dies with
|
|
95
|
-
* the container — which a deploy, a rollout and the workspace's own idle timer
|
|
96
|
-
* all end. Under the workspace mount it is the Durable Object's storage, and the
|
|
97
|
-
* conversation outlives the container that held it; a later run can continue it
|
|
98
|
-
* from that same workspace object, and from no other.
|
|
99
|
-
*
|
|
100
|
-
* **Fixed, and never a host's to choose.** A transcript is found only where it
|
|
101
|
-
* was written, so every second place a session could write one is a resume that
|
|
102
|
-
* cannot find it. `env` cannot move it either: {@link buildLaunch} refuses the
|
|
103
|
-
* key.
|
|
104
|
-
*
|
|
105
|
-
* The directory is named {@link file://../computer/paths.ts SESSION_STATE_DIR},
|
|
106
|
-
* which is the name the file tools' walk steps over: a transcript records every
|
|
107
|
-
* line the session read, so a walk that descended into it would answer the
|
|
108
|
-
* parent's `grep` for a line of source with the session that quoted it. The
|
|
109
|
-
* name is written out here rather than imported, because `/claude-code` does
|
|
110
|
-
* not reach `/computer` — a spec holds the two to the same spelling.
|
|
111
|
-
*/
|
|
112
|
-
export declare const SESSION_CONFIG_DIR = "/workspace/.claude-sessions";
|
|
113
|
-
export interface LaunchOptions {
|
|
114
|
-
/** The run's prompt — the whole of what this session is asked to do. */
|
|
115
|
-
prompt: string;
|
|
116
|
-
/** Where the checkout is. The session runs with this as its cwd. */
|
|
117
|
-
dir: string;
|
|
118
|
-
model?: string;
|
|
119
|
-
/**
|
|
120
|
-
* How hard the model thinks, per turn. Unset, the model's own default.
|
|
121
|
-
*
|
|
122
|
-
* See {@link file://./config.ts ClaudeCodeConfig.effort} for what a level
|
|
123
|
-
* costs, and why an unrecognised one is worse here than a rejected one.
|
|
124
|
-
*/
|
|
125
|
-
effort?: EffortLevel;
|
|
126
|
-
/**
|
|
127
|
-
* Caps on Claude Code's own subagent tree — advisory, for the reason
|
|
128
|
-
* {@link file://./config.ts ClaudeCodeConfig.maxSubagentDepth} gives.
|
|
129
|
-
*/
|
|
130
|
-
maxSubagentDepth?: number;
|
|
131
|
-
maxConcurrentSubagents?: number;
|
|
132
|
-
/**
|
|
133
|
-
* How the session answers its own permission prompts.
|
|
134
|
-
*
|
|
135
|
-
* Defaults to {@link DEFAULT_PERMISSION_MODE}. See
|
|
136
|
-
* {@link file://./config.ts ClaudeCodeConfig.permissionMode} for why the
|
|
137
|
-
* default is the permissive one, and {@link buildLaunch} for the root guard
|
|
138
|
-
* that decides how it has to be passed.
|
|
139
|
-
*/
|
|
140
|
-
permissionMode?: PermissionMode;
|
|
141
|
-
/**
|
|
142
|
-
* Merged last, so a host can add what a repository needs.
|
|
143
|
-
*
|
|
144
|
-
* **Never secrets**, and {@link RESERVED_ENV_KEY} is refused outright rather
|
|
145
|
-
* than trusted to the reader of that sentence.
|
|
146
|
-
*/
|
|
147
|
-
env?: Record<string, string>;
|
|
148
|
-
/**
|
|
149
|
-
* Who this session's commits are attributed to — see
|
|
150
|
-
* {@link file://./config.ts ClaudeCodeConfig.author}.
|
|
151
|
-
*/
|
|
152
|
-
author?: {
|
|
153
|
-
name: string;
|
|
154
|
-
email: string;
|
|
155
|
-
};
|
|
156
|
-
/**
|
|
157
|
-
* A JSON Schema the session's answer must match, as `--json-schema`. The CLI
|
|
158
|
-
* gives the model a `StructuredOutput` tool and holds the run until it is
|
|
159
|
-
* called, and the result line carries the call's input as
|
|
160
|
-
* `structured_output` — see {@link file://./events.ts ClaudeCodeResult}.
|
|
161
|
-
*/
|
|
162
|
-
jsonSchema?: Record<string, unknown>;
|
|
163
|
-
/**
|
|
164
|
-
* A Claude Code session id to continue — the handle an earlier session left on
|
|
165
|
-
* its {@link DrainCursor}, or reported on its `result` line.
|
|
166
|
-
*
|
|
167
|
-
* {@link LaunchOptions.prompt} is then the **next user turn** rather than a new
|
|
168
|
-
* task: the conversation is already in the session's context, so a brief that
|
|
169
|
-
* restates it pays for it twice.
|
|
170
|
-
*
|
|
171
|
-
* Not scoped to the working directory — a session recorded against one cwd
|
|
172
|
-
* resumes under another and goes on appending to the original transcript — so
|
|
173
|
-
* what decides whether this works is where the transcript is, which is
|
|
174
|
-
* {@link SESSION_CONFIG_DIR} in the workspace the session ran in.
|
|
175
|
-
*
|
|
176
|
-
* **An id whose transcript is not there is not a failed session.** The CLI
|
|
177
|
-
* prints `No conversation found with session ID`, emits a `result` line
|
|
178
|
-
* carrying that as {@link file://./events.ts ClaudeCodeResult.errors}, and
|
|
179
|
-
* exits in milliseconds; its client still makes its own startup requests, but
|
|
180
|
-
* nothing is inferred and nothing is billed. The honest report is "not
|
|
181
|
-
* resumable", and the retry is the same delegation without this.
|
|
182
|
-
*
|
|
183
|
-
* **An empty id is refused rather than dropped.** That retry is launching
|
|
184
|
-
* without this option, not passing it empty.
|
|
185
|
-
*/
|
|
186
|
-
resume?: string;
|
|
187
|
-
/**
|
|
188
|
-
* Fork the resumed conversation: continue it under a **new** session id,
|
|
189
|
-
* leaving the original transcript whole and resumable.
|
|
190
|
-
*
|
|
191
|
-
* What a change of mode wants — a planning session, run under `plan`,
|
|
192
|
-
* continued under the mode that writes — so that the plan's own conversation
|
|
193
|
-
* can still be resumed for an edit afterwards. Continuing in the same mode
|
|
194
|
-
* takes no fork: one conversation accumulating is what "continue" means.
|
|
195
|
-
*
|
|
196
|
-
* Refused without {@link LaunchOptions.resume}: on its own the flag has no
|
|
197
|
-
* conversation to fork, and a caller that set it meant to resume one.
|
|
198
|
-
*/
|
|
199
|
-
fork?: boolean;
|
|
200
|
-
/**
|
|
201
|
-
* Present GitHub's placeholder as `GH_TOKEN` and as git's credential, for a
|
|
202
|
-
* gateway holding the real token — see {@link file://./github.ts}.
|
|
203
|
-
*/
|
|
204
|
-
github?: boolean;
|
|
205
|
-
}
|
|
206
|
-
export interface Launch {
|
|
207
|
-
command: string;
|
|
208
|
-
env: Record<string, string>;
|
|
209
|
-
}
|
|
210
|
-
/**
|
|
211
|
-
* Build the command and environment for one session.
|
|
212
|
-
*
|
|
213
|
-
* `--output-format stream-json` with `--verbose`, because the stream is the only
|
|
214
|
-
* way to report progress before the run ends, and a run lasts for minutes.
|
|
215
|
-
* `--verbose` is required: without it Claude Code emits
|
|
216
|
-
* only the final result even in stream mode.
|
|
217
|
-
*
|
|
218
|
-
* Note what is **absent**. No `--bare` and no `--settings` override: a cloned
|
|
219
|
-
* repository's `CLAUDE.md`, skills and hooks are exactly the material that makes
|
|
220
|
-
* the agent good at that repository, and the container is already an
|
|
221
|
-
* arbitrary-code-execution environment by design — the install runs the repo's
|
|
222
|
-
* `postinstall`, the agent runs its test suite. Stripping one door while the
|
|
223
|
-
* others stand open buys nothing and costs the agent its context.
|
|
224
|
-
* `CLAUDE_CONFIG_DIR` is not that kind of flag, and every session gets it: it
|
|
225
|
-
* moves where the *client* keeps its own state, touching nothing a repository
|
|
226
|
-
* ships — see {@link SESSION_CONFIG_DIR}.
|
|
227
|
-
*
|
|
228
|
-
* No `ANTHROPIC_BASE_URL` either: `http-gateway` egress intercepts
|
|
229
|
-
* transparently, so the client talks to the real hostname and the gateway sees
|
|
230
|
-
* it. Nothing has to be told to use a proxy, which means nothing in the
|
|
231
|
-
* container can be told *not* to.
|
|
232
|
-
*
|
|
233
|
-
* ## `--permission-mode`, and the root guard behind it
|
|
234
|
-
*
|
|
235
|
-
* The mode is always passed explicitly, never left to the CLI's `default` — see
|
|
236
|
-
* {@link file://./config.ts ClaudeCodeConfig.permissionMode} for what an
|
|
237
|
-
* unset mode does to a headless session, and why
|
|
238
|
-
* {@link DEFAULT_PERMISSION_MODE} is the permissive value rather than a
|
|
239
|
-
* concession.
|
|
240
|
-
*
|
|
241
|
-
* **`IS_SANDBOX=1` ships in the same branch as the flag, and separating the two
|
|
242
|
-
* breaks a session harder than passing no flag at all.** The container runs as
|
|
243
|
-
* root, and the CLI refuses to bypass its permission checks under uid 0 unless
|
|
244
|
-
* that variable is set: it calls `process.exit(1)` **before the first JSON
|
|
245
|
-
* line**, with the only explanation on stderr. The failure then surfaces as
|
|
246
|
-
* "exited with code 1 without reporting a result" and names nothing. One branch
|
|
247
|
-
* below writes both so they cannot drift, and the variable is applied *after* a
|
|
248
|
-
* host's `env` so a host cannot unset the thing making its own mode work.
|
|
249
|
-
*
|
|
250
|
-
* `IS_SANDBOX` has one other documented effect in this client: a repeated API
|
|
251
|
-
* `529` stops raising the custom overload error and keeps retrying instead.
|
|
252
|
-
* Harmless here — the egress gateway is what decides when to give up.
|
|
253
|
-
*
|
|
254
|
-
* The alternative is an image that does not run as root, which is a real option
|
|
255
|
-
* and a much larger one: the FUSE mount, the checkout and every install path
|
|
256
|
-
* currently assume uid 0. If that ever changes, this variable is the line to
|
|
257
|
-
* delete.
|
|
258
|
-
*/
|
|
259
|
-
export declare function buildLaunch(options: LaunchOptions): Launch;
|
|
260
|
-
/** Where a drain got to. Stored by the caller, so a cut-short drain resumes. */
|
|
261
|
-
export interface DrainCursor {
|
|
262
|
-
/**
|
|
263
|
-
* The exec id this session occupies.
|
|
264
|
-
*
|
|
265
|
-
* Carried rather than derived so a re-attach cannot compute a different one
|
|
266
|
-
* from the run id it happens to have in hand — and because a run's follow-up
|
|
267
|
-
* is a second exec, and the cursor says which of the two it names.
|
|
268
|
-
*/
|
|
269
|
-
execId: string;
|
|
270
|
-
/** The last event sequence consumed; a resumed drain starts here. */
|
|
271
|
-
seq: number;
|
|
272
|
-
/**
|
|
273
|
-
* The Claude Code session id, from the `init` line — the handle that continues
|
|
274
|
-
* this conversation later.
|
|
275
|
-
*
|
|
276
|
-
* Carried here rather than read off the `result` line alone because the runs
|
|
277
|
-
* that most need continuing are the ones that never reach a result: a session
|
|
278
|
-
* stopped by its time limit, a cancel or a container rollout reports no result
|
|
279
|
-
* at all, and without this the conversation it got half-way through would be
|
|
280
|
-
* unreachable. The `init` line arrives in the first seconds, so a session has a
|
|
281
|
-
* handle almost from the start — which is why {@link drainRun} offers the
|
|
282
|
-
* cursor the moment the id appears instead of waiting out
|
|
283
|
-
* {@link CHECKPOINT_MIN_MS}.
|
|
284
|
-
*/
|
|
285
|
-
sessionId?: string;
|
|
286
|
-
/** Bytes after the last newline — an incomplete line the next read finishes. */
|
|
287
|
-
carry: string;
|
|
288
|
-
/** Progress notes emitted so far. The base for the positional keys. */
|
|
289
|
-
emitted: number;
|
|
290
|
-
/**
|
|
291
|
-
* The `result` line, once seen.
|
|
292
|
-
*
|
|
293
|
-
* Carried because it and the `exit` event are two separate events and a
|
|
294
|
-
* drain can be cut short between them. Without this a run whose result
|
|
295
|
-
* arrived just before an eviction reports a terminal outcome with **no
|
|
296
|
-
* result** after it resumes — and a successful session would be reported as
|
|
297
|
-
* one that died without a word.
|
|
298
|
-
*/
|
|
299
|
-
result?: ClaudeCodeResult;
|
|
300
|
-
/**
|
|
301
|
-
* A bounded slice of the session's stderr, for the runs that explain
|
|
302
|
-
* themselves nowhere else.
|
|
303
|
-
*
|
|
304
|
-
* stderr is not the protocol stream and is never parsed as one — see
|
|
305
|
-
* `consume` below. It is kept for exactly one case: a process that exits
|
|
306
|
-
* **before** emitting a `result` line, where the JSON stream holds nothing and
|
|
307
|
-
* the only account of what happened is the text the CLI printed on its way
|
|
308
|
-
* out. A bad flag, a refused permission mode under root, a Node crash. Without
|
|
309
|
-
* this the caller can only report an exit code.
|
|
310
|
-
*
|
|
311
|
-
* Carried on the cursor rather than kept local because the death and the exit
|
|
312
|
-
* event can land either side of an eviction.
|
|
313
|
-
*/
|
|
314
|
-
stderr?: string;
|
|
315
|
-
/**
|
|
316
|
-
* When the pending thinking block began streaming, on this drain's clock —
|
|
317
|
-
* see `ParsedStream.thinkingFrom` in `./events.ts`.
|
|
318
|
-
*/
|
|
319
|
-
thinkingFrom?: number;
|
|
320
|
-
}
|
|
321
|
-
/** A cursor for a session that has not started yet. */
|
|
322
|
-
export declare function freshCursor(execId: string): DrainCursor;
|
|
323
|
-
export type DrainOutcome = {
|
|
324
|
-
done: false;
|
|
325
|
-
cursor: DrainCursor;
|
|
326
|
-
progress: NoteData[];
|
|
327
|
-
/**
|
|
328
|
-
* The bucket as the client reported it **during this drain**, if it did.
|
|
329
|
-
*
|
|
330
|
-
* Deliberately not carried on the cursor the way `result` is. A caller
|
|
331
|
-
* acts on this against whichever credential is leading *now*, so a reading
|
|
332
|
-
* replayed on every resumed drain would let one old observation retire a
|
|
333
|
-
* credential that was not even in use when it was taken. Absent means
|
|
334
|
-
* "this drain learned nothing", which is the honest answer.
|
|
335
|
-
*/
|
|
336
|
-
rateLimit?: RateLimitInfo;
|
|
337
|
-
} | {
|
|
338
|
-
done: true;
|
|
339
|
-
cursor: DrainCursor;
|
|
340
|
-
progress: NoteData[];
|
|
341
|
-
/** The bucket as reported **in this drain**. See the `done: false` arm. */
|
|
342
|
-
rateLimit?: RateLimitInfo;
|
|
343
|
-
exitCode: number;
|
|
344
|
-
/** Absent when the process died without ever emitting a `result` line. */
|
|
345
|
-
result?: ClaudeCodeResult;
|
|
346
|
-
/**
|
|
347
|
-
* What the process printed on stderr, bounded — only when there is no
|
|
348
|
-
* `result` to explain the exit. Present on the terminal outcome alone
|
|
349
|
-
* because that is the only place a caller has nothing else to report.
|
|
350
|
-
*/
|
|
351
|
-
stderr?: string;
|
|
352
|
-
};
|
|
353
|
-
export interface DrainOptions {
|
|
354
|
-
/**
|
|
355
|
-
* Called with each note as it is parsed, rather than with all of them when the
|
|
356
|
-
* drain ends — a session runs for minutes, and a caller with nothing but the
|
|
357
|
-
* outcome would learn everything at once, once the work is over.
|
|
358
|
-
*
|
|
359
|
-
* Notes are still returned on the outcome as well, so a caller that files them
|
|
360
|
-
* from here must drop what it is handed back, or the same note is filed twice.
|
|
361
|
-
* The keys are positional, so the transcript would dedupe it, but paying for
|
|
362
|
-
* the second one to be discarded is not a plan.
|
|
363
|
-
*
|
|
364
|
-
* **Never awaited inside the read loop.** Calls are chained instead, so they
|
|
365
|
-
* stay in order without stalling the read of the container's stream for as
|
|
366
|
-
* long as the session is talkative, and the chain is settled before the drain
|
|
367
|
-
* returns.
|
|
368
|
-
*/
|
|
369
|
-
onProgress?: (note: NoteData) => void | Promise<void>;
|
|
370
|
-
/**
|
|
371
|
-
* Called with a cursor that is safe to store, no more often than
|
|
372
|
-
* {@link CHECKPOINT_MIN_MS}.
|
|
373
|
-
*
|
|
374
|
-
* **Only meaningful alongside `onProgress`, and that coupling is the whole
|
|
375
|
-
* point.** A cursor names a position whose notes have *already been handed to
|
|
376
|
-
* the sink* — it rides the same chain, after them — so resuming from it loses
|
|
377
|
-
* nothing the parent was sent. A note the sink **rejects** ends the
|
|
378
|
-
* checkpoints for the rest of the drain, so no stored cursor passes it: a
|
|
379
|
-
* drain cut after that resumes from before it, and files it again.
|
|
380
|
-
*
|
|
381
|
-
* Without it, a drain that dies mid-stream resumes from the start of the
|
|
382
|
-
* session. One production run lost six and a half minutes of a session that
|
|
383
|
-
* way and re-derived it by replaying the whole stream.
|
|
384
|
-
*/
|
|
385
|
-
onCheckpoint?: (cursor: DrainCursor) => void | Promise<void>;
|
|
386
|
-
/**
|
|
387
|
-
* Stops the drain now: the cursor comes back as `done: false`, and the
|
|
388
|
-
* session goes on running — stopping *it* is the caller's, with
|
|
389
|
-
* {@link killRun}. Not honoured once the process has exited, because the read
|
|
390
|
-
* to the end carries the filesystem sync; see the loop in {@link drainRun}.
|
|
391
|
-
*/
|
|
392
|
-
signal?: AbortSignal;
|
|
393
|
-
now?: () => number;
|
|
394
|
-
}
|
|
395
|
-
/** Whether a thrown value is the runtime refusing to reuse a live exec id. */
|
|
396
|
-
export declare function isExecBusy(err: unknown): boolean;
|
|
397
|
-
/**
|
|
398
|
-
* Whether a thrown value means the session this cursor names is gone for good.
|
|
399
|
-
*
|
|
400
|
-
* `EEXEC_LOST` is the runtime saying the container that held the execution was
|
|
401
|
-
* replaced. The session died with it, and no attachment will ever find it — so
|
|
402
|
-
* unlike `EEXEC_BUSY`, which is a live session reached the wrong way, there is
|
|
403
|
-
* nothing to recover and retrying only discovers that again.
|
|
404
|
-
*/
|
|
405
|
-
export declare function isExecLost(err: unknown): boolean;
|
|
406
|
-
/**
|
|
407
|
-
* Start a session, detached.
|
|
408
|
-
*
|
|
409
|
-
* **Falls back to attaching when the id is already live**, which is not a
|
|
410
|
-
* nicety. `start` spawns and then drains for minutes, so a turn cut anywhere
|
|
411
|
-
* after the spawn is recovered with no cursor stored yet — and
|
|
412
|
-
* `@cloudflare/computer` refuses to reuse an id whose execution is still
|
|
413
|
-
* running (`EEXEC_BUSY`). Without this the recovery throws, every later one
|
|
414
|
-
* throws the same way, and a perfectly healthy session in the container becomes
|
|
415
|
-
* unreachable.
|
|
416
|
-
*
|
|
417
|
-
* **The sync stays on the default, and `defer` is not an option here.** A
|
|
418
|
-
* deferred exec skips the post-command pull entirely and settles the outcome
|
|
419
|
-
* from the cursor instead — and its `cancel` reads the stream to the end first,
|
|
420
|
-
* so stopping a drain would block until the session exits. Both halves are
|
|
421
|
-
* exactly what this drain is built not to do.
|
|
422
|
-
*/
|
|
423
|
-
export declare function startRun(runtime: SessionRuntime, options: LaunchOptions & {
|
|
424
|
-
execId: string;
|
|
425
|
-
timeoutMs: number;
|
|
426
|
-
/** Stops the fallback's wait — see {@link AttachOptions.signal}. */
|
|
427
|
-
signal?: AbortSignal;
|
|
428
|
-
}): Promise<WorkspaceRuntimeExecHandle<"utf8">>;
|
|
429
|
-
/** The clock and the wait, injectable so a spec can drive the bound. */
|
|
430
|
-
export interface AttachOptions {
|
|
431
|
-
now?: () => number;
|
|
432
|
-
wait?: (ms: number) => Promise<void>;
|
|
433
|
-
/** Stops the wait — see `DrainOptions.signal`. */
|
|
434
|
-
signal?: AbortSignal;
|
|
435
|
-
}
|
|
436
|
-
/**
|
|
437
|
-
* Re-attach to a session this isolate did not start.
|
|
438
|
-
*
|
|
439
|
-
* **Waits out a subscriber the previous drain has not released yet**, and that
|
|
440
|
-
* wait is the point of this function rather than a refinement of it. The
|
|
441
|
-
* alternative is not "fail fast" — it is spending a recovery to discover a
|
|
442
|
-
* condition that clears on its own in a second, when recoveries are what a
|
|
443
|
-
* deploy, a severed stub and a network drop have to be covered out of. A
|
|
444
|
-
* deployment lost a twenty-one-minute session exactly that way — consecutive
|
|
445
|
-
* attach races used the retries up, and the redeploy that followed had no
|
|
446
|
-
* attempt left to be retried on. See {@link isExecSubscribed}.
|
|
447
|
-
*
|
|
448
|
-
* Everything else is rethrown on the first look, `EEXEC_LOST` above all: it is
|
|
449
|
-
* the runtime saying the container was replaced, `resume` turns it into a report
|
|
450
|
-
* for the model, and a retry loop would sit on it for {@link ATTACH_MAX_MS}
|
|
451
|
-
* learning nothing.
|
|
452
|
-
*/
|
|
453
|
-
export declare function attachRun(runtime: SessionRuntime, cursor: DrainCursor, options?: AttachOptions): Promise<WorkspaceRuntimeExecHandle<"utf8">>;
|
|
454
|
-
/**
|
|
455
|
-
* Drain a session to its end.
|
|
456
|
-
*
|
|
457
|
-
* Returns `done: true` once the stream has finished, or `done: false` when the
|
|
458
|
-
* caller's signal stopped the drain with the process still running.
|
|
459
|
-
*/
|
|
460
|
-
export declare function drainRun(handle: WorkspaceRuntimeExecHandle<"utf8">, cursor: DrainCursor, options?: DrainOptions): Promise<DrainOutcome>;
|
|
461
|
-
/**
|
|
462
|
-
* What a session reports on `stderr` when its container went away under it:
|
|
463
|
-
* the stream ended with no `exit` event, or a re-attach found the exec gone.
|
|
464
|
-
*/
|
|
465
|
-
export declare function containerLost(printed?: string): string;
|
|
466
|
-
/**
|
|
467
|
-
* Stop a session.
|
|
468
|
-
*
|
|
469
|
-
* `SIGTERM` rather than `SIGKILL`: Claude Code aborts the turn, kills its own
|
|
470
|
-
* Bash process tree, runs its `SessionEnd` hooks and exits 143. A `SIGKILL`
|
|
471
|
-
* leaves whatever the session had spawned still running in a container the
|
|
472
|
-
* workspace will keep using.
|
|
473
|
-
*/
|
|
474
|
-
export declare function killRun(runtime: SessionRuntime, execId: string): Promise<void>;
|