@dynamicagents/plugins 0.11.1 → 0.13.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 +59 -79
- package/dist/browser/index.d.ts +0 -2
- package/dist/browser/index.js +21 -27
- package/dist/claude-code/cards.d.ts +53 -0
- package/dist/claude-code/cards.js +272 -0
- package/dist/claude-code/config.d.ts +73 -31
- package/dist/claude-code/config.js +0 -2
- package/dist/claude-code/credentials.d.ts +21 -9
- package/dist/claude-code/credentials.js +43 -9
- package/dist/claude-code/egress.d.ts +15 -14
- package/dist/claude-code/egress.js +51 -14
- package/dist/claude-code/events.d.ts +153 -9
- package/dist/claude-code/events.js +289 -58
- package/dist/claude-code/github.d.ts +39 -0
- package/dist/claude-code/github.js +82 -0
- package/dist/claude-code/index.d.ts +24 -80
- package/dist/claude-code/index.js +19 -234
- package/dist/claude-code/model.d.ts +152 -0
- package/dist/claude-code/model.js +342 -0
- package/dist/claude-code/run.d.ts +283 -92
- package/dist/claude-code/run.js +620 -114
- package/dist/claude-code/session.d.ts +131 -0
- package/dist/claude-code/session.js +285 -0
- package/dist/claude-code/spec.d.ts +46 -0
- package/dist/claude-code/spec.js +83 -0
- package/dist/claude-code/verified.d.ts +15 -0
- package/dist/claude-code/verified.js +15 -0
- package/dist/computer/context.d.ts +19 -0
- package/dist/computer/context.js +222 -0
- package/dist/computer/file-lock.d.ts +5 -0
- package/dist/computer/file-lock.js +40 -0
- package/dist/computer/gate.d.ts +12 -12
- package/dist/computer/gate.js +12 -12
- package/dist/computer/index.d.ts +57 -255
- package/dist/computer/index.js +98 -1039
- package/dist/computer/paths.d.ts +47 -22
- package/dist/computer/paths.js +64 -49
- package/dist/computer/proxy.d.ts +45 -0
- package/dist/computer/proxy.js +234 -0
- package/dist/computer/render.d.ts +27 -38
- package/dist/computer/render.js +32 -65
- package/dist/computer/tools-exec.d.ts +3 -0
- package/dist/computer/tools-exec.js +268 -0
- package/dist/computer/tools-file.d.ts +12 -0
- package/dist/computer/tools-file.js +64 -0
- package/dist/computer/tools-grep.d.ts +3 -0
- package/dist/computer/tools-grep.js +129 -0
- package/dist/repo/checkout.d.ts +35 -6
- package/dist/repo/checkout.js +64 -6
- package/dist/repo/context.d.ts +135 -0
- package/dist/repo/context.js +582 -0
- package/dist/repo/index.d.ts +79 -57
- package/dist/repo/index.js +118 -1112
- package/dist/repo/tools-checks.d.ts +3 -0
- package/dist/repo/tools-checks.js +112 -0
- package/dist/repo/tools-clone.d.ts +4 -0
- package/dist/repo/tools-clone.js +192 -0
- package/dist/repo/tools-pr.d.ts +14 -0
- package/dist/repo/tools-pr.js +196 -0
- package/dist/repo/tools-review.d.ts +12 -0
- package/dist/repo/tools-review.js +393 -0
- package/dist/repo/tools-worktree.d.ts +4 -0
- package/dist/repo/tools-worktree.js +305 -0
- package/dist/repo/tools-worktrees.d.ts +12 -0
- package/dist/repo/tools-worktrees.js +48 -0
- package/dist/repo/url.d.ts +2 -2
- package/dist/repo/url.js +7 -7
- package/dist/scratch/index.d.ts +4 -4
- package/dist/scratch/index.js +12 -11
- package/dist/{computer → workspace}/advisory.d.ts +33 -20
- package/dist/{computer → workspace}/advisory.js +32 -7
- package/dist/workspace/ca-trust.d.ts +95 -0
- package/dist/workspace/ca-trust.js +312 -0
- package/dist/workspace/container-deps.d.ts +54 -0
- package/dist/workspace/container-deps.js +224 -0
- package/dist/workspace/container-fault.d.ts +38 -0
- package/dist/workspace/container-fault.js +73 -0
- package/dist/workspace/exec.d.ts +94 -0
- package/dist/workspace/exec.js +153 -0
- package/dist/workspace/format.d.ts +36 -0
- package/dist/workspace/format.js +57 -0
- package/dist/workspace/git-host.d.ts +79 -0
- package/dist/workspace/git-host.js +226 -0
- package/dist/workspace/git-identity.d.ts +57 -0
- package/dist/workspace/git-identity.js +147 -0
- package/dist/workspace/index.d.ts +43 -47
- package/dist/workspace/index.js +52 -112
- package/dist/workspace/install-job.d.ts +121 -0
- package/dist/workspace/install-job.js +866 -0
- package/dist/{computer → workspace}/install.d.ts +15 -19
- package/dist/{computer → workspace}/install.js +8 -11
- package/dist/workspace/object.d.ts +502 -0
- package/dist/workspace/object.js +1427 -0
- package/dist/workspace/open.d.ts +95 -0
- package/dist/workspace/open.js +63 -0
- package/dist/workspace/read.d.ts +16 -0
- package/dist/workspace/read.js +22 -0
- package/dist/workspace/shell.d.ts +45 -0
- package/dist/workspace/shell.js +80 -0
- package/dist/workspace/sync.d.ts +111 -0
- package/dist/workspace/sync.js +124 -0
- package/dist/workspace/wake.d.ts +19 -0
- package/dist/workspace/wake.js +10 -0
- package/package.json +28 -42
- package/dist/arc-agi/analysis.d.ts +0 -336
- package/dist/arc-agi/analysis.js +0 -829
- package/dist/arc-agi/client.d.ts +0 -82
- package/dist/arc-agi/client.js +0 -113
- package/dist/arc-agi/game-tools.d.ts +0 -25
- package/dist/arc-agi/game-tools.js +0 -26
- package/dist/arc-agi/index.d.ts +0 -42
- package/dist/arc-agi/index.js +0 -175
- package/dist/arc-agi/main-agent.d.ts +0 -27
- package/dist/arc-agi/main-agent.js +0 -65
- package/dist/arc-agi/recipe.d.ts +0 -51
- package/dist/arc-agi/recipe.js +0 -100
- package/dist/arc-agi/scorecard.d.ts +0 -118
- package/dist/arc-agi/scorecard.js +0 -163
- package/dist/arc-agi/soul.d.ts +0 -40
- package/dist/arc-agi/soul.js +0 -90
- package/dist/arc-agi/store.d.ts +0 -154
- package/dist/arc-agi/store.js +0 -216
- package/dist/arc-agi/tools.d.ts +0 -36
- package/dist/arc-agi/tools.js +0 -576
- package/dist/arc-agi/types.d.ts +0 -212
- package/dist/arc-agi/types.js +0 -19
- package/dist/claude-code/recipe.d.ts +0 -53
- package/dist/claude-code/recipe.js +0 -100
- package/dist/computer/read.d.ts +0 -137
- package/dist/computer/read.js +0 -203
- package/dist/recall/index.d.ts +0 -99
- package/dist/recall/index.js +0 -171
- package/dist/triage/index.d.ts +0 -355
- package/dist/triage/index.js +0 -302
package/dist/arc-agi/types.d.ts
DELETED
|
@@ -1,212 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ARC-AGI-3 REST API + session types. The API plays a visual-reasoning game on a
|
|
3
|
-
* 64×64 grid of color values 0–15; see https://docs.arcprize.org.
|
|
4
|
-
*
|
|
5
|
-
* Two lifecycles meet here, and neither belongs to a model:
|
|
6
|
-
*
|
|
7
|
-
* - The **scorecard** is a container that aggregates many plays. The API opens
|
|
8
|
-
* one on request and auto-closes it after ~15 minutes idle, so nothing here
|
|
9
|
-
* ever closes one: the parent leases the most recently used card and records it
|
|
10
|
-
* in its DO SQLite (`db.scorecards`) purely to know how fresh it is.
|
|
11
|
-
* - A **play** is one RESET→ACTION* run inside a scorecard, driven by a subagent.
|
|
12
|
-
* All state that must survive across durable chunks (cookies, guid, frames,
|
|
13
|
-
* metrics) lives in the workspace as {@link ArcSession}, written by the tool
|
|
14
|
-
* family. A subagent is handed a resolved card; it never opens or chooses one.
|
|
15
|
-
*/
|
|
16
|
-
/** Game lifecycle state as the API reports it. */
|
|
17
|
-
export type GameState = "NOT_STARTED" | "NOT_FINISHED" | "WIN" | "GAME_OVER";
|
|
18
|
-
/** Base URL of the ARC-AGI-3 API. */
|
|
19
|
-
export declare const ARC_BASE_URL = "https://three.arcprize.org";
|
|
20
|
-
/**
|
|
21
|
-
* One game as `GET /api/games` lists it. Ids look like `ls20-016295f7601e`.
|
|
22
|
-
* `tags` describes how it is played (`click`, `keyboard`, `keyboard_click`) and
|
|
23
|
-
* `baseline_actions` is the per-level human baseline — both are shown to the
|
|
24
|
-
* main agent so it can brief a play sensibly.
|
|
25
|
-
*/
|
|
26
|
-
export interface GameInfo {
|
|
27
|
-
game_id: string;
|
|
28
|
-
title?: string;
|
|
29
|
-
tags?: string[];
|
|
30
|
-
baseline_actions?: number[];
|
|
31
|
-
}
|
|
32
|
-
/** A frame response from RESET / ACTION*. `frame` is one or more 64×64 grids. */
|
|
33
|
-
export interface FrameResponse {
|
|
34
|
-
game_id: string;
|
|
35
|
-
guid: string;
|
|
36
|
-
frame: number[][][];
|
|
37
|
-
state: GameState;
|
|
38
|
-
levels_completed: number;
|
|
39
|
-
win_levels?: number;
|
|
40
|
-
available_actions: number[];
|
|
41
|
-
score?: number;
|
|
42
|
-
}
|
|
43
|
-
/** One RESET→terminal run of a game, as the scorecard reports it. */
|
|
44
|
-
export interface ScorecardRun {
|
|
45
|
-
guid: string;
|
|
46
|
-
actions: number;
|
|
47
|
-
completed: boolean;
|
|
48
|
-
levels_completed: number;
|
|
49
|
-
resets: number;
|
|
50
|
-
score: number;
|
|
51
|
-
state: GameState;
|
|
52
|
-
/** Actions spent on each level of this run. */
|
|
53
|
-
level_actions?: number[];
|
|
54
|
-
/** The human baseline each level is scored against. */
|
|
55
|
-
level_baseline_actions?: number[];
|
|
56
|
-
level_scores?: number[];
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* One game's aggregate within a scorecard — every run played against it.
|
|
60
|
-
*
|
|
61
|
-
* This is the **only** game-scoped part of the response: every top-level field of
|
|
62
|
-
* {@link ScorecardSummary} covers the whole card. Since several games share one
|
|
63
|
-
* card by design, reporting a card-level total as a game's own is a real
|
|
64
|
-
* mislabeling — so the renderer reads nothing but this entry.
|
|
65
|
-
*/
|
|
66
|
-
export interface ScorecardEnvironment {
|
|
67
|
-
id: string;
|
|
68
|
-
actions: number;
|
|
69
|
-
completed: boolean;
|
|
70
|
-
level_count: number;
|
|
71
|
-
levels_completed: number;
|
|
72
|
-
resets: number;
|
|
73
|
-
score: number;
|
|
74
|
-
runs: ScorecardRun[];
|
|
75
|
-
}
|
|
76
|
-
/** Per-tag rollup (`click`, `keyboard`, …) across the scorecard's games. */
|
|
77
|
-
export interface ScorecardTagScore {
|
|
78
|
-
id: string;
|
|
79
|
-
actions: number;
|
|
80
|
-
levels_completed: number;
|
|
81
|
-
number_of_environments: number;
|
|
82
|
-
number_of_levels: number;
|
|
83
|
-
score: number;
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* A whole scorecard as `GET /api/scorecard/{card_id}` reports it: one
|
|
87
|
-
* `environments` entry per game played, one `runs` entry per RESET within it.
|
|
88
|
-
*
|
|
89
|
-
* This is a **read**, not a terminal event — it works while the card is still
|
|
90
|
-
* open, which is what lets a result be reported without anything ever closing a
|
|
91
|
-
* card. (It is the same shape the retired close call returned, which is why it
|
|
92
|
-
* carries a real per-game `score`.)
|
|
93
|
-
*
|
|
94
|
-
* The narrower `GET /api/scorecard/{card_id}/{game_id}` is deliberately *not*
|
|
95
|
-
* used: it reports no score at all, and its top-level totals are card-wide
|
|
96
|
-
* despite the game filter — verified against the live API.
|
|
97
|
-
*/
|
|
98
|
-
export interface ScorecardSummary {
|
|
99
|
-
card_id: string;
|
|
100
|
-
score: number;
|
|
101
|
-
total_actions: number;
|
|
102
|
-
total_environments: number;
|
|
103
|
-
total_environments_completed: number;
|
|
104
|
-
total_levels: number;
|
|
105
|
-
total_levels_completed: number;
|
|
106
|
-
environments: ScorecardEnvironment[];
|
|
107
|
-
tags?: string[];
|
|
108
|
-
tags_scores?: ScorecardTagScore[];
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* One scorecard as the agent's DO SQLite records it (see `db/schema.ts`).
|
|
112
|
-
*
|
|
113
|
-
* There is no status: the API auto-closes an idle card, so liveness is inferred
|
|
114
|
-
* from {@link lastUsedAt} rather than tracked. A card is a lease, not an object
|
|
115
|
-
* with a lifecycle.
|
|
116
|
-
*/
|
|
117
|
-
export interface Scorecard {
|
|
118
|
-
cardId: string;
|
|
119
|
-
/**
|
|
120
|
-
* The jar `POST /api/scorecard/open` returned. The API pins the card to that
|
|
121
|
-
* session — every later RESET, ACTION, and scorecard read must echo these
|
|
122
|
-
* cookies, from whichever agent makes the call — so it is stored with the card,
|
|
123
|
-
* not held by whoever happened to open it.
|
|
124
|
-
*/
|
|
125
|
-
cookies: CookieJar;
|
|
126
|
-
/**
|
|
127
|
-
* `{ [gameId]: guid }` — the play this card has already opened per game, so a
|
|
128
|
-
* game resolving onto it a second time rejoins that play instead of RESETting
|
|
129
|
-
* a new one. See `resolvePlay` in `recipes/arc-game/scorecard.ts`.
|
|
130
|
-
*/
|
|
131
|
-
guids: Record<string, string>;
|
|
132
|
-
openedAt: number;
|
|
133
|
-
/** Last time a play resolved onto this card; the reuse clock. */
|
|
134
|
-
lastUsedAt: number;
|
|
135
|
-
}
|
|
136
|
-
/** Session-affinity cookie jar (AWSALB*), echoed on every request of a session. */
|
|
137
|
-
export type CookieJar = Record<string, string>;
|
|
138
|
-
/**
|
|
139
|
-
* Durable play session, persisted to the workspace at {@link ARC_SESSION_PATH}.
|
|
140
|
-
* The single grid we render/diff is the LAST grid of the frame array (the current
|
|
141
|
-
* board).
|
|
142
|
-
*
|
|
143
|
-
* One session file is one play, and one execution gets exactly one: the RESET
|
|
144
|
-
* that creates this file is implicit and fires once, so reaching WIN or GAME_OVER
|
|
145
|
-
* is a terminal result to report on this card, not a state the model can reset
|
|
146
|
-
* out of. Its presence on disk is what makes that guarantee — every later tool
|
|
147
|
-
* call loads it instead of starting.
|
|
148
|
-
*/
|
|
149
|
-
export interface ArcSession {
|
|
150
|
-
/**
|
|
151
|
-
* The scorecard this play belongs to, recorded from the lease the parent
|
|
152
|
-
* resolved at the opening RESET. Kept rather than re-read each chunk: if the
|
|
153
|
-
* lease rolls over onto a new card mid-execution, this play's runs still belong
|
|
154
|
-
* to the card that recorded them.
|
|
155
|
-
*/
|
|
156
|
-
cardId: string;
|
|
157
|
-
gameId: string;
|
|
158
|
-
guid: string;
|
|
159
|
-
cookies: CookieJar;
|
|
160
|
-
winLevels: number;
|
|
161
|
-
levelsCompleted: number;
|
|
162
|
-
state: GameState;
|
|
163
|
-
availableActions: number[];
|
|
164
|
-
/** Count of actions actually sent to the API (game moves) in this play. */
|
|
165
|
-
actionsSent: number;
|
|
166
|
-
/** Levels at which we have emitted a level-up progress note. */
|
|
167
|
-
levelsReported: number[];
|
|
168
|
-
/**
|
|
169
|
-
* The current board as bare hex rows (`serializeGrid`), not `number[][]`.
|
|
170
|
-
*
|
|
171
|
-
* The workspace pretty-prints its JSON, so a nested numeric array serializes to
|
|
172
|
-
* one integer per line — ~38 KB for a 64×64 board. Since the session is written
|
|
173
|
-
* twice per action (write-ahead intent, then the recorded result) and one
|
|
174
|
-
* `arc_act` call may carry several actions, that adds up to hundreds of KB of
|
|
175
|
-
* SQLite per tool call. Hex rows are ~4 KB.
|
|
176
|
-
*/
|
|
177
|
-
lastGridHex: string | null;
|
|
178
|
-
/** Write-ahead intent: set before an action is sent, cleared after it returns. */
|
|
179
|
-
pendingAction: {
|
|
180
|
-
action: number;
|
|
181
|
-
x?: number;
|
|
182
|
-
y?: number;
|
|
183
|
-
} | null;
|
|
184
|
-
}
|
|
185
|
-
/** Workspace path for the durable ARC session. */
|
|
186
|
-
export declare const ARC_SESSION_PATH = "arc/session.json";
|
|
187
|
-
/**
|
|
188
|
-
* This plugin's slice of a Subtask's runtime bag — what the parent resolves for
|
|
189
|
-
* an execution and no model could supply.
|
|
190
|
-
*
|
|
191
|
-
* Core's `SubtaskRuntime` is an open `Record<string, unknown>`, and these four
|
|
192
|
-
* fields are the reason. The predecessor declared them in core's own delegation
|
|
193
|
-
* types, which meant core imported a domain's vocabulary and every unrelated
|
|
194
|
-
* agent carried `cardId`, `cookies`, `guid` and `frame` in its bundle. The
|
|
195
|
-
* plugin that writes this slice is the plugin that reads it, so narrow it with
|
|
196
|
-
* `runtimeAs<ArcRuntime>` at the boundary and keep the cast's blast radius to
|
|
197
|
-
* this one module.
|
|
198
|
-
*/
|
|
199
|
-
export type ArcRuntime = {
|
|
200
|
-
/** The scorecard leased for this chunk. */
|
|
201
|
-
cardId?: string;
|
|
202
|
-
/** The session jar the ARC API pinned that card to. */
|
|
203
|
-
cookies?: CookieJar;
|
|
204
|
-
/** The play to join. Mintable only by RESET, which only the parent performs. */
|
|
205
|
-
guid?: string;
|
|
206
|
-
/**
|
|
207
|
-
* The opening frame — present **only** on the chunk that minted the guid.
|
|
208
|
-
* There is no ARC endpoint that reads a board back, so this is the one chance
|
|
209
|
-
* to hand one over; a later chunk learns the board from its first ACTION.
|
|
210
|
-
*/
|
|
211
|
-
frame?: FrameResponse;
|
|
212
|
-
};
|
package/dist/arc-agi/types.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ARC-AGI-3 REST API + session types. The API plays a visual-reasoning game on a
|
|
3
|
-
* 64×64 grid of color values 0–15; see https://docs.arcprize.org.
|
|
4
|
-
*
|
|
5
|
-
* Two lifecycles meet here, and neither belongs to a model:
|
|
6
|
-
*
|
|
7
|
-
* - The **scorecard** is a container that aggregates many plays. The API opens
|
|
8
|
-
* one on request and auto-closes it after ~15 minutes idle, so nothing here
|
|
9
|
-
* ever closes one: the parent leases the most recently used card and records it
|
|
10
|
-
* in its DO SQLite (`db.scorecards`) purely to know how fresh it is.
|
|
11
|
-
* - A **play** is one RESET→ACTION* run inside a scorecard, driven by a subagent.
|
|
12
|
-
* All state that must survive across durable chunks (cookies, guid, frames,
|
|
13
|
-
* metrics) lives in the workspace as {@link ArcSession}, written by the tool
|
|
14
|
-
* family. A subagent is handed a resolved card; it never opens or chooses one.
|
|
15
|
-
*/
|
|
16
|
-
/** Base URL of the ARC-AGI-3 API. */
|
|
17
|
-
export const ARC_BASE_URL = "https://three.arcprize.org";
|
|
18
|
-
/** Workspace path for the durable ARC session. */
|
|
19
|
-
export const ARC_SESSION_PATH = "arc/session.json";
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import type { ResolvedRecipe, SubtaskTypeSpec } from "@dynamicagents/core";
|
|
2
|
-
/** The Subtask type a "make this change" request decomposes into. */
|
|
3
|
-
export declare const CLAUDE_CODE_TYPE = "claude-code";
|
|
4
|
-
/**
|
|
5
|
-
* The key this plugin writes the workspace name under, for the facet to read
|
|
6
|
-
* back off `SubtaskRuntime`.
|
|
7
|
-
*
|
|
8
|
-
* **Deliberately a second declaration of `/computer`'s `WORKSPACE_RUNTIME_KEY`,
|
|
9
|
-
* not an import of it.** Importing one string constant across the subpath
|
|
10
|
-
* boundary would merge two realms `verify:exports` keeps apart, and pull the
|
|
11
|
-
* whole computer plugin into the graph of every agent that installs this one.
|
|
12
|
-
*
|
|
13
|
-
* The two must stay equal, because a host that installs both on its subagent
|
|
14
|
-
* gets them working off one runtime value — so `index.spec.ts` imports both and
|
|
15
|
-
* asserts it, which is where a cross-realm import costs nothing.
|
|
16
|
-
*/
|
|
17
|
-
export declare const WORKSPACE_RUNTIME_KEY = "workspaceName";
|
|
18
|
-
/**
|
|
19
|
-
* The recipe a Claude Code session runs under — and most of it is inert, which
|
|
20
|
-
* is worth saying plainly rather than letting a reader assume otherwise.
|
|
21
|
-
*
|
|
22
|
-
* Every other recipe in this package configures core's resumable model/tool
|
|
23
|
-
* loop: `soul` is the system prompt, `toolFamilies` names what the model may
|
|
24
|
-
* call, `historyWindow` bounds its context. **None of that applies here.** The
|
|
25
|
-
* host's subagent overrides `executeChunk` and never calls `runResumableChunk`
|
|
26
|
-
* at all — the loop, the tools, the context management and the system prompt are
|
|
27
|
-
* Claude Code's, inside the container.
|
|
28
|
-
*
|
|
29
|
-
* So the fields below exist because {@link ResolvedRecipe} requires them and
|
|
30
|
-
* `validateRecipe` checks them on the parent, not because anything reads them at
|
|
31
|
-
* runtime. They are set to the most honest values available:
|
|
32
|
-
*
|
|
33
|
-
* - `toolFamilies: []` — this plugin registers none. Claude Code brings its own
|
|
34
|
-
* tools and they are not core's to name.
|
|
35
|
-
* - `soul` — required and never defaulted, so it says what this recipe *is*.
|
|
36
|
-
* Nothing sends it to a model.
|
|
37
|
-
* - `limits.maxTurns` — the budget core would meter if it were driving. It is
|
|
38
|
-
* not, so what actually bounds a session is `timeoutMs`, enforced by the
|
|
39
|
-
* container runtime. Set to 1 to say so: one Dynamic Agents "turn" is one
|
|
40
|
-
* whole Claude Code session.
|
|
41
|
-
*/
|
|
42
|
-
export declare const CLAUDE_CODE_RECIPE: ResolvedRecipe;
|
|
43
|
-
/**
|
|
44
|
-
* What the main agent is told it can hand off.
|
|
45
|
-
*
|
|
46
|
-
* Sized deliberately. An invocation carries an 18.7-27k token cached prefix
|
|
47
|
-
* before it does anything — a ten-call burst billed twenty raw input tokens
|
|
48
|
-
* against 187,130 cache reads — so a session has to be worth starting. The
|
|
49
|
-
* guidance says that in the terms the delegating model can act on: one coherent
|
|
50
|
-
* change, not one file edit.
|
|
51
|
-
*/
|
|
52
|
-
export declare const CLAUDE_CODE_CAPABILITY: string;
|
|
53
|
-
export declare const CLAUDE_CODE_SPEC: SubtaskTypeSpec;
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
/** The Subtask type a "make this change" request decomposes into. */
|
|
2
|
-
export const CLAUDE_CODE_TYPE = "claude-code";
|
|
3
|
-
/**
|
|
4
|
-
* The key this plugin writes the workspace name under, for the facet to read
|
|
5
|
-
* back off `SubtaskRuntime`.
|
|
6
|
-
*
|
|
7
|
-
* **Deliberately a second declaration of `/computer`'s `WORKSPACE_RUNTIME_KEY`,
|
|
8
|
-
* not an import of it.** Importing one string constant across the subpath
|
|
9
|
-
* boundary would merge two realms `verify:exports` keeps apart, and pull the
|
|
10
|
-
* whole computer plugin into the graph of every agent that installs this one.
|
|
11
|
-
*
|
|
12
|
-
* The two must stay equal, because a host that installs both on its subagent
|
|
13
|
-
* gets them working off one runtime value — so `index.spec.ts` imports both and
|
|
14
|
-
* asserts it, which is where a cross-realm import costs nothing.
|
|
15
|
-
*/
|
|
16
|
-
export const WORKSPACE_RUNTIME_KEY = "workspaceName";
|
|
17
|
-
/**
|
|
18
|
-
* The recipe a Claude Code session runs under — and most of it is inert, which
|
|
19
|
-
* is worth saying plainly rather than letting a reader assume otherwise.
|
|
20
|
-
*
|
|
21
|
-
* Every other recipe in this package configures core's resumable model/tool
|
|
22
|
-
* loop: `soul` is the system prompt, `toolFamilies` names what the model may
|
|
23
|
-
* call, `historyWindow` bounds its context. **None of that applies here.** The
|
|
24
|
-
* host's subagent overrides `executeChunk` and never calls `runResumableChunk`
|
|
25
|
-
* at all — the loop, the tools, the context management and the system prompt are
|
|
26
|
-
* Claude Code's, inside the container.
|
|
27
|
-
*
|
|
28
|
-
* So the fields below exist because {@link ResolvedRecipe} requires them and
|
|
29
|
-
* `validateRecipe` checks them on the parent, not because anything reads them at
|
|
30
|
-
* runtime. They are set to the most honest values available:
|
|
31
|
-
*
|
|
32
|
-
* - `toolFamilies: []` — this plugin registers none. Claude Code brings its own
|
|
33
|
-
* tools and they are not core's to name.
|
|
34
|
-
* - `soul` — required and never defaulted, so it says what this recipe *is*.
|
|
35
|
-
* Nothing sends it to a model.
|
|
36
|
-
* - `limits.maxTurns` — the budget core would meter if it were driving. It is
|
|
37
|
-
* not, so what actually bounds a session is `timeoutMs`, enforced by the
|
|
38
|
-
* container runtime. Set to 1 to say so: one Dynamic Agents "turn" is one
|
|
39
|
-
* whole Claude Code session.
|
|
40
|
-
*/
|
|
41
|
-
export const CLAUDE_CODE_RECIPE = {
|
|
42
|
-
key: CLAUDE_CODE_TYPE,
|
|
43
|
-
version: 1,
|
|
44
|
-
soul: [
|
|
45
|
-
"This recipe does not drive a model loop.",
|
|
46
|
-
"",
|
|
47
|
-
"A subtask of this type runs the Claude Code CLI inside the agent's",
|
|
48
|
-
"workspace container, against the durable working tree. The system prompt, the",
|
|
49
|
-
"tool loop and the context management all belong to that process. Nothing",
|
|
50
|
-
"reads this text — it exists because a recipe must declare a soul, and a",
|
|
51
|
-
"placeholder that looked like a prompt would invite someone to tune it."
|
|
52
|
-
].join("\n"),
|
|
53
|
-
toolFamilies: [],
|
|
54
|
-
enabled: true,
|
|
55
|
-
limits: { maxTurns: 1 },
|
|
56
|
-
historyWindow: 1,
|
|
57
|
-
reportMetrics: false
|
|
58
|
-
};
|
|
59
|
-
/**
|
|
60
|
-
* What the main agent is told it can hand off.
|
|
61
|
-
*
|
|
62
|
-
* Sized deliberately. An invocation carries an 18.7-27k token cached prefix
|
|
63
|
-
* before it does anything — a ten-call burst billed twenty raw input tokens
|
|
64
|
-
* against 187,130 cache reads — so a session has to be worth starting. The
|
|
65
|
-
* guidance says that in the terms the delegating model can act on: one coherent
|
|
66
|
-
* change, not one file edit.
|
|
67
|
-
*/
|
|
68
|
-
export const CLAUDE_CODE_CAPABILITY = [
|
|
69
|
-
"## Writing code",
|
|
70
|
-
"",
|
|
71
|
-
"You can hand a coding task to a Claude Code session running in your",
|
|
72
|
-
"workspace container, in whatever you have open there — a repository you",
|
|
73
|
-
"checked out, or a scratchpad. It has its own tools — it reads, edits, runs the",
|
|
74
|
-
"test suite and iterates — and it reports back what it did.",
|
|
75
|
-
"",
|
|
76
|
-
"Give it **one coherent change**, described the way you would describe it to",
|
|
77
|
-
"an engineer: what should be true when it is done, and how to tell. It is",
|
|
78
|
-
"expensive to start and cheap to let run, so 'add the endpoint, its tests and",
|
|
79
|
-
"wire it up' is one subtask, not three. A session that is only asked to edit",
|
|
80
|
-
"a single line costs about what a substantial one costs.",
|
|
81
|
-
"",
|
|
82
|
-
"It cannot ask you anything mid-run. Anything it would need to ask, decide",
|
|
83
|
-
"first — or ask the user yourself before delegating."
|
|
84
|
-
].join("\n");
|
|
85
|
-
export const CLAUDE_CODE_SPEC = {
|
|
86
|
-
key: CLAUDE_CODE_TYPE,
|
|
87
|
-
description: "Run a coding task in the workspace with a Claude Code session — a checked-out repository, or a scratchpad.",
|
|
88
|
-
/**
|
|
89
|
-
* No params, and that is a decision rather than an omission.
|
|
90
|
-
*
|
|
91
|
-
* *Which* repository is not the delegating model's to choose: the workspace is
|
|
92
|
-
* one Durable Object, one container and one checkout, keyed by caller and
|
|
93
|
-
* repository, and the parent already tracks which one is active. Letting a
|
|
94
|
-
* model name a repository here would let it name somebody else's — the same
|
|
95
|
-
* reasoning that keeps `workspaceName` out of model input in `/computer`.
|
|
96
|
-
*/
|
|
97
|
-
params: null,
|
|
98
|
-
capability: CLAUDE_CODE_CAPABILITY,
|
|
99
|
-
recipe: CLAUDE_CODE_RECIPE
|
|
100
|
-
};
|
package/dist/computer/read.d.ts
DELETED
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import type { WorkspaceClient } from "@cloudflare/computer";
|
|
2
|
-
/**
|
|
3
|
-
* Reading the workspace without pulling more of it across the boundary than the
|
|
4
|
-
* model will be shown.
|
|
5
|
-
*
|
|
6
|
-
* The obvious version of each function here reads everything and throws most of
|
|
7
|
-
* it away, which is the wrong shape against a Durable Object's 128 MB. So the
|
|
8
|
-
* budget is applied at the source, and the offsets handed back are the *source's*
|
|
9
|
-
* rather than the rendered subset's — which is what makes the next page exact
|
|
10
|
-
* instead of a guess.
|
|
11
|
-
*/
|
|
12
|
-
/**
|
|
13
|
-
* Read a file without pulling more of it across the boundary than the model will
|
|
14
|
-
* be shown.
|
|
15
|
-
*
|
|
16
|
-
* `readFile(path, "utf8")` materialises the whole file in the isolate before
|
|
17
|
-
* `truncateOutput` throws most of it away. Harmless on a source file, and the
|
|
18
|
-
* wrong shape against a Durable Object's 128 MB — `sb_read` is one model decision
|
|
19
|
-
* away from a lockfile, a bundle or a captured build log. The read is
|
|
20
|
-
* range-addressable, so the budget is enforced at the source.
|
|
21
|
-
*
|
|
22
|
-
* Two reads rather than one, because the budget is spent from both ends for the
|
|
23
|
-
* reason {@link truncateOutput} documents — the first error is at the top of a
|
|
24
|
-
* file and the summary is at the bottom.
|
|
25
|
-
*
|
|
26
|
-
* ## The one place the budget is spent in bytes
|
|
27
|
-
*
|
|
28
|
-
* `maxChars` is a character ceiling everywhere else — see
|
|
29
|
-
* {@link ComputerConfig.maxOutputChars} — and here it is spent against
|
|
30
|
-
* `byteOffset`/`byteLength`, which are the only units the transport has. That is
|
|
31
|
-
* deliberate and it is safe in the direction that matters: a UTF-8 byte is never
|
|
32
|
-
* more than one UTF-16 code unit, so *N* bytes decode to at most *N* characters.
|
|
33
|
-
* Reading the character budget as bytes therefore always honours the ceiling,
|
|
34
|
-
* and errs low on a file that is mostly non-ASCII — a CJK source file is cut at
|
|
35
|
-
* about a third of the characters it could have shown. The alternative is a
|
|
36
|
-
* second round trip to measure what the first one returned, on every read, to
|
|
37
|
-
* recover a bound the marker already announces.
|
|
38
|
-
*
|
|
39
|
-
* The other reason it cannot be characters is the one this function exists for:
|
|
40
|
-
* bounding the *transport*. A byte range is what stops a 4 MB lockfile being
|
|
41
|
-
* materialised in a 128 MB isolate before anything is thrown away.
|
|
42
|
-
*
|
|
43
|
-
* ## Why `stat` first
|
|
44
|
-
*
|
|
45
|
-
* Sizing off the returned string instead would be wrong in a way that hides
|
|
46
|
-
* itself. `byteLength` counts bytes and `String.length` counts UTF-16 code units,
|
|
47
|
-
* so a file of two-byte characters comes back *under* a character budget while
|
|
48
|
-
* still being over the byte budget — and the read would look complete with half
|
|
49
|
-
* the file missing and no marker saying so. One extra round trip buys the
|
|
50
|
-
* distinction.
|
|
51
|
-
*
|
|
52
|
-
* A slice boundary can land mid-codepoint, which the decoder resolves to a single
|
|
53
|
-
* replacement character. That is one glyph of noise at a cut that already
|
|
54
|
-
* announces itself as a cut.
|
|
55
|
-
*/
|
|
56
|
-
export declare function readBounded(fs: WorkspaceClient["fs"], path: string, maxChars: number): Promise<string>;
|
|
57
|
-
/**
|
|
58
|
-
* A byte window the model asked for, with its coordinates stated.
|
|
59
|
-
*
|
|
60
|
-
* No middle-out here, deliberately: {@link readBounded} guesses at what matters when
|
|
61
|
-
* nobody said, but an explicit `offset` *is* the model saying. Trimming the middle
|
|
62
|
-
* of a region it chose would defeat the request and, worse, make the next offset
|
|
63
|
-
* unknowable.
|
|
64
|
-
*
|
|
65
|
-
* The window line is what makes paging work at all — the model needs to know where
|
|
66
|
-
* it landed and how much is left to compute the next `offset`.
|
|
67
|
-
*/
|
|
68
|
-
export declare function readWindow(fs: WorkspaceClient["fs"], path: string, offset: number, length: number, maxChars: number): Promise<string>;
|
|
69
|
-
/**
|
|
70
|
-
* Fetch a page, drop what is off-limits, and keep the source offsets that make the
|
|
71
|
-
* *next* page exact.
|
|
72
|
-
*
|
|
73
|
-
* The subtle part is why `rawIndex` exists at all. `offset` counts items at the
|
|
74
|
-
* source; the caller renders a filtered, budget-trimmed subset of them. So the
|
|
75
|
-
* obvious `nextOffset = offset + shown` is wrong — it silently skips or repeats
|
|
76
|
-
* whenever anything was dropped, which is precisely when `.git` is involved. Keeping
|
|
77
|
-
* each survivor's source index means the next page starts exactly after the last one
|
|
78
|
-
* the model actually saw.
|
|
79
|
-
*
|
|
80
|
-
* Retries because `.git` can outnumber a whole page on its own: at a repo root it is
|
|
81
|
-
* walked *first* (`.` sorts before alphanumerics) and holds thousands of objects, so
|
|
82
|
-
* one fetch can come back entirely excluded. `maxRounds` is the caller's, and the
|
|
83
|
-
* asymmetry is deliberate — a `find` retry re-walks dirents, which is cheap SQLite
|
|
84
|
-
* reads, while a `grep` retry re-reads and re-scans every file it already looked at.
|
|
85
|
-
*
|
|
86
|
-
* Deliberately no slicing to `want`: the caller needs the extra item to know a next
|
|
87
|
-
* page exists, and its index to say where.
|
|
88
|
-
*/
|
|
89
|
-
export declare function collectVisible<T>(fetch: (offset: number, limit: number) => Promise<T[]>, pathOf: (item: T) => string, want: number, offset: number, maxRounds: number): Promise<{
|
|
90
|
-
items: T[];
|
|
91
|
-
/** Source offset of `items[i]`. */
|
|
92
|
-
rawIndex: number[];
|
|
93
|
-
/** Source offset just past everything examined. */
|
|
94
|
-
rawEnd: number;
|
|
95
|
-
/** The source ran out; there is no next page. */
|
|
96
|
-
exhausted: boolean;
|
|
97
|
-
/** Rounds ran out while excluded paths still dominated. */
|
|
98
|
-
crowded: boolean;
|
|
99
|
-
}>;
|
|
100
|
-
/** What a page of a collected listing owes the caller once it knows how much fit. */
|
|
101
|
-
interface VisiblePage {
|
|
102
|
-
rawIndex: number[];
|
|
103
|
-
rawEnd: number;
|
|
104
|
-
exhausted: boolean;
|
|
105
|
-
crowded: boolean;
|
|
106
|
-
}
|
|
107
|
-
/**
|
|
108
|
-
* The "there is more, here is where" line, with an offset that is actually correct.
|
|
109
|
-
*
|
|
110
|
-
* `rawIndex[shown]` rather than `offset + shown`: the first item the model did *not*
|
|
111
|
-
* see, at its source coordinate. Anything else drifts by however many entries the
|
|
112
|
-
* `.git` filter removed, and drifts silently — the next page would repeat or skip
|
|
113
|
-
* with nothing to indicate it had.
|
|
114
|
-
*
|
|
115
|
-
* Narrowing is still offered, and still first-class, because it is cheaper than
|
|
116
|
-
* paging: `offset` does not skip the walk, it only discards its early results. It is
|
|
117
|
-
* offered as the better option rather than the only one, which is the thing the
|
|
118
|
-
* previous wording got wrong — "narrow it" is no answer at all when the model wants
|
|
119
|
-
* the next page of a list it is working through.
|
|
120
|
-
*/
|
|
121
|
-
export declare function listingNote(page: VisiblePage, shown: number, noun: string, narrower: string): string;
|
|
122
|
-
/**
|
|
123
|
-
* Does this path exist?
|
|
124
|
-
*
|
|
125
|
-
* `getWorkspace()` types `fs` as the in-process `WorkspaceFilesystem`, but the
|
|
126
|
-
* value on the far side of a Durable Object boundary is a
|
|
127
|
-
* `WorkspaceFilesystemStub`, which carries a few methods the local class does
|
|
128
|
-
* not — `exists` among them. So the fast path is asked for rather than cast to,
|
|
129
|
-
* and `stat` is the fallback for a host that hands back a local workspace.
|
|
130
|
-
*
|
|
131
|
-
* The fallback treats *any* `stat` failure as absence, which is the honest
|
|
132
|
-
* reading for a tool whose entire answer is a boolean: there is no error channel
|
|
133
|
-
* to distinguish "missing" from "unreadable", and the caller's next move — look
|
|
134
|
-
* somewhere else — is the same either way.
|
|
135
|
-
*/
|
|
136
|
-
export declare function pathExists(fs: WorkspaceClient["fs"], path: string): Promise<boolean>;
|
|
137
|
-
export {};
|