@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.
Files changed (134) hide show
  1. package/README.md +59 -79
  2. package/dist/browser/index.d.ts +0 -2
  3. package/dist/browser/index.js +21 -27
  4. package/dist/claude-code/cards.d.ts +53 -0
  5. package/dist/claude-code/cards.js +272 -0
  6. package/dist/claude-code/config.d.ts +73 -31
  7. package/dist/claude-code/config.js +0 -2
  8. package/dist/claude-code/credentials.d.ts +21 -9
  9. package/dist/claude-code/credentials.js +43 -9
  10. package/dist/claude-code/egress.d.ts +15 -14
  11. package/dist/claude-code/egress.js +51 -14
  12. package/dist/claude-code/events.d.ts +153 -9
  13. package/dist/claude-code/events.js +289 -58
  14. package/dist/claude-code/github.d.ts +39 -0
  15. package/dist/claude-code/github.js +82 -0
  16. package/dist/claude-code/index.d.ts +24 -80
  17. package/dist/claude-code/index.js +19 -234
  18. package/dist/claude-code/model.d.ts +152 -0
  19. package/dist/claude-code/model.js +342 -0
  20. package/dist/claude-code/run.d.ts +283 -92
  21. package/dist/claude-code/run.js +620 -114
  22. package/dist/claude-code/session.d.ts +131 -0
  23. package/dist/claude-code/session.js +285 -0
  24. package/dist/claude-code/spec.d.ts +46 -0
  25. package/dist/claude-code/spec.js +83 -0
  26. package/dist/claude-code/verified.d.ts +15 -0
  27. package/dist/claude-code/verified.js +15 -0
  28. package/dist/computer/context.d.ts +19 -0
  29. package/dist/computer/context.js +222 -0
  30. package/dist/computer/file-lock.d.ts +5 -0
  31. package/dist/computer/file-lock.js +40 -0
  32. package/dist/computer/gate.d.ts +12 -12
  33. package/dist/computer/gate.js +12 -12
  34. package/dist/computer/index.d.ts +57 -255
  35. package/dist/computer/index.js +98 -1039
  36. package/dist/computer/paths.d.ts +47 -22
  37. package/dist/computer/paths.js +64 -49
  38. package/dist/computer/proxy.d.ts +45 -0
  39. package/dist/computer/proxy.js +234 -0
  40. package/dist/computer/render.d.ts +27 -38
  41. package/dist/computer/render.js +32 -65
  42. package/dist/computer/tools-exec.d.ts +3 -0
  43. package/dist/computer/tools-exec.js +268 -0
  44. package/dist/computer/tools-file.d.ts +12 -0
  45. package/dist/computer/tools-file.js +64 -0
  46. package/dist/computer/tools-grep.d.ts +3 -0
  47. package/dist/computer/tools-grep.js +129 -0
  48. package/dist/repo/checkout.d.ts +35 -6
  49. package/dist/repo/checkout.js +64 -6
  50. package/dist/repo/context.d.ts +135 -0
  51. package/dist/repo/context.js +582 -0
  52. package/dist/repo/index.d.ts +79 -57
  53. package/dist/repo/index.js +118 -1112
  54. package/dist/repo/tools-checks.d.ts +3 -0
  55. package/dist/repo/tools-checks.js +112 -0
  56. package/dist/repo/tools-clone.d.ts +4 -0
  57. package/dist/repo/tools-clone.js +192 -0
  58. package/dist/repo/tools-pr.d.ts +14 -0
  59. package/dist/repo/tools-pr.js +196 -0
  60. package/dist/repo/tools-review.d.ts +12 -0
  61. package/dist/repo/tools-review.js +393 -0
  62. package/dist/repo/tools-worktree.d.ts +4 -0
  63. package/dist/repo/tools-worktree.js +305 -0
  64. package/dist/repo/tools-worktrees.d.ts +12 -0
  65. package/dist/repo/tools-worktrees.js +48 -0
  66. package/dist/repo/url.d.ts +2 -2
  67. package/dist/repo/url.js +7 -7
  68. package/dist/scratch/index.d.ts +4 -4
  69. package/dist/scratch/index.js +12 -11
  70. package/dist/{computer → workspace}/advisory.d.ts +33 -20
  71. package/dist/{computer → workspace}/advisory.js +32 -7
  72. package/dist/workspace/ca-trust.d.ts +95 -0
  73. package/dist/workspace/ca-trust.js +312 -0
  74. package/dist/workspace/container-deps.d.ts +54 -0
  75. package/dist/workspace/container-deps.js +224 -0
  76. package/dist/workspace/container-fault.d.ts +38 -0
  77. package/dist/workspace/container-fault.js +73 -0
  78. package/dist/workspace/exec.d.ts +94 -0
  79. package/dist/workspace/exec.js +153 -0
  80. package/dist/workspace/format.d.ts +36 -0
  81. package/dist/workspace/format.js +57 -0
  82. package/dist/workspace/git-host.d.ts +79 -0
  83. package/dist/workspace/git-host.js +226 -0
  84. package/dist/workspace/git-identity.d.ts +57 -0
  85. package/dist/workspace/git-identity.js +147 -0
  86. package/dist/workspace/index.d.ts +43 -47
  87. package/dist/workspace/index.js +52 -112
  88. package/dist/workspace/install-job.d.ts +121 -0
  89. package/dist/workspace/install-job.js +866 -0
  90. package/dist/{computer → workspace}/install.d.ts +15 -19
  91. package/dist/{computer → workspace}/install.js +8 -11
  92. package/dist/workspace/object.d.ts +502 -0
  93. package/dist/workspace/object.js +1427 -0
  94. package/dist/workspace/open.d.ts +95 -0
  95. package/dist/workspace/open.js +63 -0
  96. package/dist/workspace/read.d.ts +16 -0
  97. package/dist/workspace/read.js +22 -0
  98. package/dist/workspace/shell.d.ts +45 -0
  99. package/dist/workspace/shell.js +80 -0
  100. package/dist/workspace/sync.d.ts +111 -0
  101. package/dist/workspace/sync.js +124 -0
  102. package/dist/workspace/wake.d.ts +19 -0
  103. package/dist/workspace/wake.js +10 -0
  104. package/package.json +28 -42
  105. package/dist/arc-agi/analysis.d.ts +0 -336
  106. package/dist/arc-agi/analysis.js +0 -829
  107. package/dist/arc-agi/client.d.ts +0 -82
  108. package/dist/arc-agi/client.js +0 -113
  109. package/dist/arc-agi/game-tools.d.ts +0 -25
  110. package/dist/arc-agi/game-tools.js +0 -26
  111. package/dist/arc-agi/index.d.ts +0 -42
  112. package/dist/arc-agi/index.js +0 -175
  113. package/dist/arc-agi/main-agent.d.ts +0 -27
  114. package/dist/arc-agi/main-agent.js +0 -65
  115. package/dist/arc-agi/recipe.d.ts +0 -51
  116. package/dist/arc-agi/recipe.js +0 -100
  117. package/dist/arc-agi/scorecard.d.ts +0 -118
  118. package/dist/arc-agi/scorecard.js +0 -163
  119. package/dist/arc-agi/soul.d.ts +0 -40
  120. package/dist/arc-agi/soul.js +0 -90
  121. package/dist/arc-agi/store.d.ts +0 -154
  122. package/dist/arc-agi/store.js +0 -216
  123. package/dist/arc-agi/tools.d.ts +0 -36
  124. package/dist/arc-agi/tools.js +0 -576
  125. package/dist/arc-agi/types.d.ts +0 -212
  126. package/dist/arc-agi/types.js +0 -19
  127. package/dist/claude-code/recipe.d.ts +0 -53
  128. package/dist/claude-code/recipe.js +0 -100
  129. package/dist/computer/read.d.ts +0 -137
  130. package/dist/computer/read.js +0 -203
  131. package/dist/recall/index.d.ts +0 -99
  132. package/dist/recall/index.js +0 -171
  133. package/dist/triage/index.d.ts +0 -355
  134. package/dist/triage/index.js +0 -302
@@ -1,206 +1,41 @@
1
1
  import type { ToolSet } from "ai";
2
2
  import type { AgentPlugin } from "@dynamicagents/core";
3
- import type { WorkspaceClient, WorkspaceStub } from "@cloudflare/computer";
4
- import type { WorkspaceAdvisory } from "./advisory.js";
3
+ import type { WorkspaceClient } from "@cloudflare/computer";
4
+ import type { WorkspaceAdvisory } from "../workspace/advisory.js";
5
+ import type { WorkspaceClientConfig } from "../workspace/exec.js";
5
6
  /**
6
- * `@dynamicagents/plugins/computer` — a Linux container whose filesystem outlives it.
7
- *
8
- * The filesystem **is** a Durable Object's SQLite, mounted into the container
9
- * over FUSE by `computerd`. Commands see a normal `/workspace`; the Worker reads
10
- * the same tree over RPC; and when the container is replaced the tree is pushed
11
- * back into the new one.
12
- *
13
- * Not to be confused with `@dynamicagents/plugins/workspace`, which is a virtual
14
- * filesystem with no processes and nothing to run. Install exactly one
15
- * filesystem plugin — an agent holding two gives the model no way to know which
16
- * one a path refers to.
17
- *
18
- * ## `node_modules` is **not** in the workspace
19
- *
20
- * The one thing to internalise before reading further. `computerd` excludes it
21
- * from the sync, and the exclusion is right: pushing a real one (429 MB, 22,470
22
- * files) into the object exceeds the Durable Object's 128 MB isolate memory
23
- * limit, leaving the tree silently short — and the reconciliation that follows
24
- * propagates the shortfall back into the container.
25
- *
26
- * So dependencies live in the container and die with it, while source and `.git`
27
- * are durable. Two consequences run through everything below: an install has to
28
- * be re-run on a cold container, and `sb_read` cannot see a path under
29
- * `node_modules` even though a shell in the same container can.
30
- *
31
- * Requires the Workers **Paid** plan (containers) and a Durable Object binding
32
- * whose class owns the workspace — see the README for the wrangler block.
33
- */
34
- /**
35
- * How a repository installs its dependencies — the mechanical half.
36
- *
37
- * Re-exported from the plugin's one entry point rather than given a subpath of
38
- * its own: `verify:exports` treats each subpath as an isolated realm, and a host
39
- * needs the resolver and the tools together anyway.
7
+ * `@dynamicagents/plugins/computer` — an agent's tools over a container
8
+ * workspace: `bash`, `grep` and `edit`, and `computerWorkspace`, the agent's own
9
+ * `this.workspace`, which Think's `read`, `write`, `delete`, `find` and `list`
10
+ * go through.
11
+ *
12
+ * The workspace itself — the Durable Object, its container, its git, its
13
+ * install — is `@dynamicagents/plugins/workspace`. This plugin reaches it only
14
+ * through that subpath's client modules, never its object, so an agent that
15
+ * holds the tools carries no container backend and no isomorphic-git.
16
+ *
17
+ * The agent's own workspace has to be this one — `computerWorkspace` — or
18
+ * Think's `read` and `write` would work on a different tree from `bash`. The
19
+ * plugin refuses to start otherwise; see `./proxy.ts`.
20
+ *
21
+ * ## The dependency tree is not in the workspace
22
+ *
23
+ * The one thing to internalise before reading further. A package root's
24
+ * `node_modules` is a bind mount of the container's disk, so installs never
25
+ * sync, and a new container reinstalls — see `/workspace`'s
26
+ * `container-deps.ts`. The file tools read the workspace, so they refuse it;
27
+ * `bash` reaches it. `paths.ts` owns what a path may be and what walks drop.
40
28
  */
41
- export { DEFAULT_INSTALL_PLAN, installFingerprint, resolveInstallCommand, type InstallPlan, type InstallProbe, type InstallResolution, type InstallRule, type InstallState } from "./install.js";
42
29
  /**
43
- * The helpers this plugin's own tests and hosts reach for, re-exported from the
44
- * one entry point.
45
- *
46
- * They live in sibling modules — `paths.ts`, `render.ts`, `gate.ts` — because
47
- * this file was 1,900 lines and the seams were obvious. The subpath is the unit a
48
- * consumer imports, so what it exports must not move when the files behind it do:
49
- * `verify:exports` treats `./computer` as one realm, and everything below stays
50
- * inside `dist/computer/`.
30
+ * The helpers this plugin's own tests reach for, re-exported from the one
31
+ * entry point. `verify:exports` treats `./computer` as one realm, so what it
32
+ * exports must not move when the files behind it do.
51
33
  */
52
- export { isContainerOnly, isGitInternal } from "./paths.js";
53
- export { cancelledNote, packBlocks, renderGrepMatches, renderResult, truncateOutput } from "./render.js";
34
+ export { isGitInternal, SESSION_STATE_DIR, WALK_SKIPS } from "./paths.js";
35
+ export { packBlocks, renderGrepMatches, renderResult, syncPendingNote } from "./render.js";
54
36
  export { execGate, needsDependencies, writeGate, type ExecGate } from "./gate.js";
55
- /**
56
- * The workspace-advisory vocabulary, which a host needs all of: the type to
57
- * return over RPC, `deriveAdvisories` to build it from what it already knows,
58
- * and `sessionAdvisory` for a host driving a whole session rather than one
59
- * command. `shapeOf` and `renderAdvisory` are exported for the specs that hold
60
- * their exhaustiveness — a host has no reason to call either, since calling them
61
- * would mean writing policy or wording that has one home already.
62
- */
63
- export { deriveAdvisories, renderAdvisory, sessionAdvisory, shapeOf, type AdvisoryAudience, type AdvisoryInput, type AdvisoryShape, type WorkspaceAdvisory } from "./advisory.js";
64
- export { pathExists } from "./read.js";
65
- /**
66
- * This plugin's tool-family name, as a recipe's `toolFamilies` lists it.
67
- *
68
- * `"sandbox"` names the capability — a shell and a filesystem — rather than the
69
- * package providing it, and it appears in recipes, souls and allowlists that
70
- * have nothing to do with either. Renaming it would have `validateRecipe`
71
- * silently drop the family from every recipe that still says `sandbox`: a
72
- * subagent with no tools and no error explaining why.
73
- */
74
- export declare const SANDBOX_FAMILY = "sandbox";
75
- /**
76
- * Where a parent puts the workspace name so its subagents reach the same one.
77
- *
78
- * A subagent cannot compute this itself. The name is derived from the verified
79
- * caller and the repository, and core deliberately gives a subagent execution a
80
- * `callerKey` thunk that **throws** — "a subagent execution has no caller
81
- * identity". So a facet running a `code` subtask would fail at its first tool
82
- * call, with the parent's checkout sitting in a workspace it cannot name.
83
- *
84
- * `resolveRuntime` runs on the parent, where the name resolves, and its return
85
- * value reaches every tool family as `ToolFamilyContext.runtime`. That is the
86
- * channel core built for exactly this, and it is emphatically *not* `params`,
87
- * which are declared in the subtask type's schema and rendered to the delegating
88
- * model — a workspace name there would be model-authored, and a model naming
89
- * another caller's workspace would get that caller's files.
90
- */
91
- export declare const WORKSPACE_RUNTIME_KEY = "workspaceName";
92
- /**
93
- * Read a parent-resolved workspace name off a subtask's runtime state.
94
- *
95
- * Returns `undefined` rather than throwing on anything unexpected: the main
96
- * agent's tools have no runtime at all, and falling back to the configured thunk
97
- * is right there.
98
- */
99
- export declare function workspaceNameFromRuntime(runtime: unknown): string | undefined;
100
- /**
101
- * The Durable Object the workspace lives in, as this plugin needs to see it.
102
- *
103
- * Structural rather than imported: the class is the host's — it owns the
104
- * container binding, the alarm and the install job — and a plugin that imported
105
- * it would stop a second host from bringing its own. `__getWorkspaceStub` is the
106
- * one method `getWorkspace()` calls across the boundary, and it is what
107
- * `withWorkspace` installs (or what a host that constructs `Workspace` itself
108
- * reimplements, which is the same three lines).
109
- */
110
- export interface WorkspaceHost extends Rpc.DurableObjectBranded {
111
- __getWorkspaceStub(): Promise<WorkspaceStub>;
112
- /**
113
- * Everything currently true about the workspace that a caller must not assume
114
- * away — see {@link file://./advisory.ts}. An empty array is the good case.
115
- *
116
- * Required rather than optional, and not only because Workers RPC types an
117
- * optional method as a union nothing can call. A host with nothing to report
118
- * returns `[]` in one line; a host that forgot to expose it gets a compile
119
- * error instead of an `sb_exec` that silently runs against a half-built
120
- * `node_modules`, or against a workspace whose writes are being dropped.
121
- *
122
- * `deriveAdvisories` builds the array from what the host already knows, so
123
- * implementing this is gathering three values rather than writing policy.
124
- */
125
- advisories(): Promise<readonly WorkspaceAdvisory[]>;
126
- }
127
- /**
128
- * Run a command under {@link ComputerConfig.shell} with its two output streams
129
- * left as they are, or hand it back untouched when no shell is configured.
130
- *
131
- * This is the variant for a caller that **reads the result in code**: `stdout` is
132
- * a data channel it compares or parses, and `stderr` is a separate diagnostic.
133
- * {@link computerExec} is that caller, on behalf of `@dynamicagents/plugins/repo`,
134
- * which asks git questions like `symbolic-ref --short refs/remotes/origin/HEAD`
135
- * and `rev-list --count` and needs the answer alone.
136
- *
137
- * Two functions rather than one with a flag, because the difference is a change
138
- * to the *output contract* and a boolean hides it at the call site. Merging the
139
- * streams here would give every `/repo` git command an empty `stderr` and a
140
- * `stdout` that is a transcript rather than an answer — which fails silently,
141
- * since the commands `/repo` parses are quiet ones and a single `warning:` is
142
- * enough to skip the empty-branch guard.
143
- */
144
- export declare function withShell(command: string, shell: string | undefined): string;
145
- /**
146
- * Run a command under {@link ComputerConfig.shell} with its two output streams
147
- * merged into one transcript, in the order they were written.
148
- *
149
- * This is the variant for a caller whose consumer is **a model reading output**.
150
- * `sb_exec` is that caller. A project's check is a chain — `wrangler types &&
151
- * prettier && eslint && tsc` — and *which tool spoke last* is how you know which
152
- * one failed. A stdout block and a separate stderr block destroy that ordering,
153
- * and a model that wants it back re-runs the whole gate as
154
- * `npm run check > /tmp/out 2>&1; cat /tmp/out`. This is that workaround, done
155
- * once, for free.
156
- *
157
- * The redirect binds to the wrapper process, so it applies to everything the
158
- * command writes however deeply nested — and there is no inner brace group or
159
- * subshell to mis-parse a command that already contains `&&`, quotes or redirects
160
- * of its own.
161
- *
162
- * With no shell configured there is no wrapper process to redirect, so the
163
- * command goes to the runtime untouched and the two streams arrive separate.
164
- * That is not a gap: {@link renderResult} renders them as a labelled
165
- * `--- stderr ---` block for exactly this case. The transcript is the better
166
- * answer, not the only supported one.
167
- */
168
- export declare function withShellTranscript(command: string, shell: string | undefined): string;
169
- export interface ComputerConfig {
170
- /**
171
- * The Durable Object namespace holding workspaces, closed over at
172
- * instantiation so it is never model input.
173
- */
174
- binding: DurableObjectNamespace<WorkspaceHost>;
175
- /**
176
- * Which workspace this agent gets, by name. A thunk because the useful name —
177
- * caller plus repository — does not exist when the plugin list is built.
178
- *
179
- * One workspace is one container is one repository: `@cloudflare/computer`
180
- * pairs a Durable Object with exactly one container, so "never mix two
181
- * repositories" is structural here rather than a convention to maintain.
182
- */
183
- workspaceName: () => string;
184
- /** Working directory for every command. Defaults to `/workspace`. */
185
- cwd?: string;
186
- /**
187
- * Run every command through this shell, e.g. `"bash"`. Unset, the command
188
- * string goes to the runtime as-is and lands on whatever `/bin/sh` is.
189
- *
190
- * Worth setting, because "whatever `/bin/sh` is" is **dash** on Debian and
191
- * Ubuntu, and a model writing shell writes *bash*. `${PIPESTATUS[0]}` is the
192
- * one that costs most — a bash builtin a model reaches for to read a piped exit
193
- * code, which dash fails with exit 2, after the command it wrapped has already
194
- * run. It is one member of a family (`[[ ]]`, arrays, `set -o pipefail`,
195
- * process substitution), so the fix is the shell rather than a note in a prompt
196
- * telling the model to write POSIX.
197
- *
198
- * Set it only if the image actually has that shell: a missing one fails *every*
199
- * command rather than the bash-flavoured ones.
200
- */
201
- shell?: string;
202
- /** Per-command timeout. Defaults to ten minutes. */
203
- timeoutMs?: number;
37
+ export { computerWorkspace, isComputerWorkspace } from "./proxy.js";
38
+ export interface ComputerConfig extends WorkspaceClientConfig {
204
39
  /**
205
40
  * Output ceiling per command, in **characters**. Defaults to 16,000.
206
41
  *
@@ -215,33 +50,31 @@ export interface ComputerConfig {
215
50
  * characters far better than they track UTF-8 bytes. So the name moved to meet
216
51
  * the implementation rather than the other way round.
217
52
  *
218
- * `sb_read` is the one place a byte bound survives, and it is derived from
219
- * this rather than separate — see `readBounded`.
220
53
  */
221
54
  maxOutputChars?: number;
222
55
  /**
223
- * How long `sb_exec` waits for a running dependency install before giving the
56
+ * How long `bash` waits for a running dependency install before giving the
224
57
  * turn back. Defaults to 90 seconds.
225
58
  *
226
- * Bounded rather than open-ended because the wait happens inside a subagent's
227
- * chunk, and a tool call that blocks for the length of an `npm ci` is exactly
228
- * the thing moving the install out of the round loop was meant to prevent. On
229
- * expiry the tool runs nothing and says so, which costs one cheap turn.
59
+ * Bounded rather than open-ended because the wait happens inside a turn, and
60
+ * a tool call that blocks for the length of an `npm ci` is exactly what
61
+ * running the install as the host's own job was meant to prevent. On expiry
62
+ * the tool runs nothing and says so, which costs one cheap step.
230
63
  */
231
64
  installGateMs?: number;
232
65
  /**
233
66
  * Environment merged into every command **these tools** run — a registry host,
234
67
  * a `CI` flag, proxy settings. Host-supplied and never model input.
235
68
  *
236
- * "These tools" is exact: {@link computerExec} deliberately does not merge it,
237
- * so a proxy set here does not reach the git that `@dynamicagents/plugins/repo`
238
- * runs through that export. The reasoning, and how a host opts in explicitly,
239
- * is written up there.
69
+ * "These tools" is exact: `/workspace`'s `workspaceExec` deliberately does not
70
+ * merge it, so a proxy set here does not reach the git that
71
+ * `@dynamicagents/plugins/repo` runs through that export. The reasoning, and
72
+ * how a host opts in explicitly, is written up there.
240
73
  *
241
74
  * ## Put no secret here
242
75
  *
243
- * *Every* command gets this environment, and `sb_exec`'s command is written by
244
- * the model: `sb_exec("printenv")` prints all of it, and so does a
76
+ * *Every* command gets this environment, and `bash`'s command is written by
77
+ * the model: `bash("printenv")` prints all of it, and so does a
245
78
  * `postinstall` script in a repository the agent was asked to clone, which
246
79
  * nobody vetted.
247
80
  *
@@ -255,57 +88,26 @@ export interface ComputerConfig {
255
88
  *
256
89
  * Do not hand the agent the credential; hand it the *action*. Keep the secret
257
90
  * on the Worker and expose one tool that makes the call it is for.
258
- * `@dynamicagents/plugins/repo` is the worked example: it holds a forge token, calls
91
+ * `@dynamicagents/plugins/repo` is the worked example: it holds a GitHub token, calls
259
92
  * the API from the Worker, and runs clone, fetch and push on the host's side of
260
93
  * the boundary. **No command in its container is ever given that token.**
261
94
  */
262
95
  env?: () => Record<string, string | undefined>;
263
96
  }
264
- export declare function buildComputerTools(workspace: () => Promise<WorkspaceClient>, config: ComputerConfig, advisories?: () => Promise<readonly WorkspaceAdvisory[]>): ToolSet;
265
97
  /**
266
- * An `exec` bound to this workspace, for plugins that need a shell but should
267
- * not own a container.
268
- *
269
- * `@dynamicagents/plugins/repo` is the reason this exists: it needs `git` on a real
270
- * shell, but depending on this module would weld the two together and stop a
271
- * host from pointing it at its own container. Structurally typed for the same
272
- * reason — the two plugins compose without either importing the other.
273
- *
274
- * ## {@link ComputerConfig.env} is deliberately **not** merged here
275
- *
276
- * {@link buildComputerTools} merges it into every command; this does not.
277
- *
278
- * What this hands out is a raw shell to *another plugin*, whose commands this
279
- * module neither writes nor sees. `/repo` runs its unauthenticated git through
280
- * it and pins the environment those need — `GIT_TERMINAL_PROMPT=0` plus the
281
- * model-authored values it passes as variables. A host environment merged
282
- * underneath lets through every key it does *not* pin: `http_proxy`,
283
- * `GIT_PROXY_COMMAND`, `GIT_SSL_CAINFO`, `GIT_CONFIG_GLOBAL`, `GIT_EXEC_PATH` —
284
- * the last two redirect the config git reads and relocate its helper binaries.
285
- *
286
- * No token is at stake, since the credentialed operations do not run here at
287
- * all. The point is that changing what git does inside another plugin's commands
288
- * should not be something a container plugin's config field does by accident,
289
- * from a host that only meant to set a registry. A host that wants it composes
290
- * it where the merge is visible:
291
- *
292
- * ```ts
293
- * exec: (command, options) =>
294
- * computerExec(config)(command, {
295
- * ...options,
296
- * env: { ...mine, ...options?.env }
297
- * });
298
- * ```
98
+ * @param workspace Opens the workspace for a command: container started, CA
99
+ * installed.
100
+ * @param fsWorkspace Opens it for the file tools, which touch nothing but the
101
+ * host's SQLite. Defaults to {@link workspace}, so a host with one way in
102
+ * behaves as before. See {@link openWorkspaceFs}.
103
+ * @param lockScope Names the workspace a write locks within — see
104
+ * {@link file://./file-lock.ts}. Defaults to this tool set alone.
105
+ */
106
+ export declare function buildComputerTools(workspace: () => Promise<WorkspaceClient>, config: ComputerConfig, advisories?: () => Promise<readonly WorkspaceAdvisory[]>, fsWorkspace?: () => Promise<WorkspaceClient>, lockScope?: () => string): ToolSet;
107
+ /**
108
+ * The container plugin. Its tools reach the workspace through the agent's own
109
+ * `computerWorkspace` — the one Think's `read` and `write` use — so the two can
110
+ * never resolve different ones. `config` answers everything else: the shell,
111
+ * the limits, the environment.
299
112
  */
300
- export declare function computerExec(config: ComputerConfig): (command: string, options?: {
301
- cwd?: string;
302
- env?: Record<string, string | undefined>;
303
- timeout?: number;
304
- runtime?: unknown;
305
- }) => Promise<{
306
- success: boolean;
307
- stdout: string;
308
- stderr: string;
309
- exitCode: number;
310
- }>;
311
113
  export declare function computer(config: ComputerConfig): AgentPlugin;