@dynamicagents/plugins 0.12.0 → 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 (130) hide show
  1. package/README.md +58 -77
  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 +28 -63
  7. package/dist/claude-code/config.js +0 -11
  8. package/dist/claude-code/egress.d.ts +8 -1
  9. package/dist/claude-code/egress.js +42 -4
  10. package/dist/claude-code/events.d.ts +106 -9
  11. package/dist/claude-code/events.js +201 -56
  12. package/dist/claude-code/github.d.ts +39 -0
  13. package/dist/claude-code/github.js +82 -0
  14. package/dist/claude-code/index.d.ts +16 -90
  15. package/dist/claude-code/index.js +14 -276
  16. package/dist/claude-code/model.d.ts +152 -0
  17. package/dist/claude-code/model.js +342 -0
  18. package/dist/claude-code/run.d.ts +209 -112
  19. package/dist/claude-code/run.js +339 -138
  20. package/dist/claude-code/session.d.ts +131 -0
  21. package/dist/claude-code/session.js +285 -0
  22. package/dist/claude-code/spec.d.ts +46 -0
  23. package/dist/claude-code/spec.js +83 -0
  24. package/dist/claude-code/verified.d.ts +15 -0
  25. package/dist/claude-code/verified.js +15 -0
  26. package/dist/computer/context.d.ts +1 -5
  27. package/dist/computer/context.js +7 -10
  28. package/dist/computer/file-lock.js +5 -4
  29. package/dist/computer/gate.d.ts +4 -4
  30. package/dist/computer/gate.js +5 -5
  31. package/dist/computer/index.d.ts +40 -258
  32. package/dist/computer/index.js +71 -324
  33. package/dist/computer/paths.d.ts +36 -16
  34. package/dist/computer/paths.js +42 -29
  35. package/dist/computer/proxy.d.ts +45 -0
  36. package/dist/computer/proxy.js +234 -0
  37. package/dist/computer/render.d.ts +1 -40
  38. package/dist/computer/render.js +2 -68
  39. package/dist/computer/tools-exec.js +12 -13
  40. package/dist/computer/tools-file.d.ts +9 -1
  41. package/dist/computer/tools-file.js +22 -82
  42. package/dist/computer/{tools-find.d.ts → tools-grep.d.ts} +1 -1
  43. package/dist/computer/tools-grep.js +129 -0
  44. package/dist/repo/checkout.d.ts +4 -5
  45. package/dist/repo/checkout.js +31 -8
  46. package/dist/repo/context.d.ts +35 -9
  47. package/dist/repo/context.js +101 -49
  48. package/dist/repo/index.d.ts +73 -28
  49. package/dist/repo/index.js +112 -96
  50. package/dist/repo/tools-checks.d.ts +3 -0
  51. package/dist/repo/tools-checks.js +112 -0
  52. package/dist/repo/tools-clone.js +1 -1
  53. package/dist/repo/tools-pr.d.ts +14 -0
  54. package/dist/repo/{tools-forge.js → tools-pr.js} +53 -36
  55. package/dist/repo/tools-review.d.ts +9 -0
  56. package/dist/repo/tools-review.js +67 -47
  57. package/dist/repo/tools-worktree.js +144 -60
  58. package/dist/repo/tools-worktrees.d.ts +12 -0
  59. package/dist/repo/tools-worktrees.js +48 -0
  60. package/dist/repo/url.d.ts +2 -2
  61. package/dist/repo/url.js +7 -7
  62. package/dist/scratch/index.d.ts +4 -4
  63. package/dist/scratch/index.js +12 -11
  64. package/dist/{computer → workspace}/advisory.d.ts +4 -4
  65. package/dist/{computer → workspace}/advisory.js +2 -2
  66. package/dist/{computer/host → workspace}/ca-trust.d.ts +8 -1
  67. package/dist/{computer/host → workspace}/ca-trust.js +12 -3
  68. package/dist/{computer/host → workspace}/container-fault.d.ts +3 -3
  69. package/dist/{computer/host → workspace}/container-fault.js +23 -8
  70. package/dist/workspace/exec.d.ts +94 -0
  71. package/dist/workspace/exec.js +153 -0
  72. package/dist/workspace/format.d.ts +36 -0
  73. package/dist/workspace/format.js +57 -0
  74. package/dist/{computer/host → workspace}/git-host.d.ts +21 -4
  75. package/dist/{computer/host → workspace}/git-host.js +72 -2
  76. package/dist/{computer/host → workspace}/git-identity.d.ts +1 -1
  77. package/dist/{computer/host → workspace}/git-identity.js +1 -1
  78. package/dist/workspace/index.d.ts +43 -47
  79. package/dist/workspace/index.js +52 -112
  80. package/dist/{computer/host → workspace}/install-job.d.ts +4 -4
  81. package/dist/{computer/host → workspace}/install-job.js +276 -176
  82. package/dist/{computer → workspace}/install.d.ts +8 -8
  83. package/dist/{computer → workspace}/install.js +3 -3
  84. package/dist/{computer/host/workspace.d.ts → workspace/object.d.ts} +105 -27
  85. package/dist/{computer/host/workspace.js → workspace/object.js} +217 -48
  86. package/dist/workspace/open.d.ts +95 -0
  87. package/dist/workspace/open.js +63 -0
  88. package/dist/workspace/read.d.ts +16 -0
  89. package/dist/workspace/read.js +22 -0
  90. package/dist/{computer → workspace}/shell.d.ts +5 -5
  91. package/dist/{computer → workspace}/shell.js +6 -6
  92. package/dist/{computer/host → workspace}/wake.d.ts +1 -1
  93. package/package.json +16 -36
  94. package/dist/arc-agi/analysis.d.ts +0 -322
  95. package/dist/arc-agi/analysis.js +0 -802
  96. package/dist/arc-agi/client.d.ts +0 -82
  97. package/dist/arc-agi/client.js +0 -113
  98. package/dist/arc-agi/game-tools.d.ts +0 -24
  99. package/dist/arc-agi/game-tools.js +0 -26
  100. package/dist/arc-agi/index.d.ts +0 -40
  101. package/dist/arc-agi/index.js +0 -175
  102. package/dist/arc-agi/main-agent.d.ts +0 -24
  103. package/dist/arc-agi/main-agent.js +0 -62
  104. package/dist/arc-agi/recipe.d.ts +0 -48
  105. package/dist/arc-agi/recipe.js +0 -97
  106. package/dist/arc-agi/scorecard.d.ts +0 -118
  107. package/dist/arc-agi/scorecard.js +0 -163
  108. package/dist/arc-agi/soul.d.ts +0 -29
  109. package/dist/arc-agi/soul.js +0 -79
  110. package/dist/arc-agi/store.d.ts +0 -153
  111. package/dist/arc-agi/store.js +0 -215
  112. package/dist/arc-agi/tools.d.ts +0 -36
  113. package/dist/arc-agi/tools.js +0 -574
  114. package/dist/arc-agi/types.d.ts +0 -211
  115. package/dist/arc-agi/types.js +0 -19
  116. package/dist/claude-code/recipe.d.ts +0 -53
  117. package/dist/claude-code/recipe.js +0 -100
  118. package/dist/computer/read.d.ts +0 -133
  119. package/dist/computer/read.js +0 -200
  120. package/dist/computer/tools-find.js +0 -216
  121. package/dist/recall/index.d.ts +0 -105
  122. package/dist/recall/index.js +0 -181
  123. package/dist/repo/tools-forge.d.ts +0 -4
  124. package/dist/triage/index.d.ts +0 -360
  125. package/dist/triage/index.js +0 -311
  126. /package/dist/{computer/host → workspace}/container-deps.d.ts +0 -0
  127. /package/dist/{computer/host → workspace}/container-deps.js +0 -0
  128. /package/dist/{computer/host → workspace}/sync.d.ts +0 -0
  129. /package/dist/{computer/host → workspace}/sync.js +0 -0
  130. /package/dist/{computer/host → workspace}/wake.js +0 -0
@@ -0,0 +1,342 @@
1
+ var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
2
+ if (value !== null && value !== void 0) {
3
+ if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
4
+ var dispose, inner;
5
+ if (async) {
6
+ if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
7
+ dispose = value[Symbol.asyncDispose];
8
+ }
9
+ if (dispose === void 0) {
10
+ if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
11
+ dispose = value[Symbol.dispose];
12
+ if (async) inner = dispose;
13
+ }
14
+ if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
15
+ if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
16
+ env.stack.push({ value: value, dispose: dispose, async: async });
17
+ }
18
+ else if (async) {
19
+ env.stack.push({ async: true });
20
+ }
21
+ return value;
22
+ };
23
+ var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
24
+ return function (env) {
25
+ function fail(e) {
26
+ env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
27
+ env.hasError = true;
28
+ }
29
+ var r, s = 0;
30
+ function next() {
31
+ while (r = env.stack.pop()) {
32
+ try {
33
+ if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
34
+ if (r.dispose) {
35
+ var result = r.dispose.call(r.value);
36
+ if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
37
+ }
38
+ else s |= 1;
39
+ }
40
+ catch (e) {
41
+ fail(e);
42
+ }
43
+ }
44
+ if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
45
+ if (env.hasError) throw env.error;
46
+ }
47
+ return next();
48
+ };
49
+ })(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
50
+ var e = new Error(message);
51
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
52
+ });
53
+ import { isPlatformTransientError } from "agents";
54
+ import { claudeCodeSession, requireCredentials } from "./session.js";
55
+ import { execIdFor, followUpExecIdFor } from "./run.js";
56
+ /** Zeroed: the session's tokens are the CLI's context, not this conversation's. */
57
+ const USAGE = {
58
+ inputTokens: {
59
+ total: 0,
60
+ noCache: 0,
61
+ cacheRead: 0,
62
+ cacheWrite: 0
63
+ },
64
+ outputTokens: { total: 0, text: 0, reasoning: 0 }
65
+ };
66
+ export function claudeCodeModel(options) {
67
+ requireCredentials(options.config);
68
+ const { storage, runId } = options;
69
+ const session = claudeCodeSession(options.config);
70
+ const key = (name) => `claude-code:${runId}:${name}`;
71
+ const KEYS = {
72
+ brief: key("brief"),
73
+ cursor: key("cursor"),
74
+ session: key("session"),
75
+ followUp: key("follow-up"),
76
+ followUpEnd: key("follow-up-end"),
77
+ report: key("report")
78
+ };
79
+ const run = async (call) => {
80
+ const env_1 = { stack: [], error: void 0, hasError: false };
81
+ try {
82
+ // The once-guarantee: a run that already reported says so again.
83
+ const reported = await storage.get(KEYS.report);
84
+ if (reported !== undefined)
85
+ return reported;
86
+ const signal = call.abortSignal;
87
+ // Opened again after a cut stream — see `drain`. Whichever is current is
88
+ // released when the run ends.
89
+ let workspace = await options.workspace();
90
+ const _release = __addDisposableResource(env_1, { [Symbol.dispose]: () => workspace[Symbol.dispose]() }, false);
91
+ /** The exec being drained, which leads each note's key. */
92
+ let current = "";
93
+ /**
94
+ * The handle already recorded, so one id is not announced twice over — and
95
+ * set only once the host has taken it, so a record that failed is tried
96
+ * again at the next checkpoint rather than given up on.
97
+ */
98
+ let announced = "";
99
+ /**
100
+ * Tell the host the session's handle, and never fail the run over it.
101
+ *
102
+ * Not on the note chain: a note is one line of a transcript, and this is the
103
+ * only way back to the conversation. It is awaited where it is called so a
104
+ * handle is recorded before whatever comes next can lose it.
105
+ */
106
+ const announce = async (record) => {
107
+ const sink = options.onSession;
108
+ if (!sink)
109
+ return;
110
+ try {
111
+ await sink(record);
112
+ announced = record.sessionId;
113
+ }
114
+ catch (err) {
115
+ console.warn("[claude-code] the session's handle was not recorded", {
116
+ runId,
117
+ sessionId: record.sessionId,
118
+ err: String(err)
119
+ });
120
+ }
121
+ };
122
+ /**
123
+ * Each note, filed as it is parsed, then the cursor behind it. Keyed on the
124
+ * exec as well as the position: the parent's transcript is one per task and
125
+ * dedupes on the key, so a run's notes must not collide with another run's
126
+ * — or with its own follow-up's, which counts from zero again.
127
+ */
128
+ const sinks = {
129
+ onProgress: (note) => options.note(`${current}:${note.key}`, note.text, note.detail),
130
+ // The drain offers a cursor the moment the session id appears, which is
131
+ // what makes this the earliest the handle can be recorded — seconds in,
132
+ // rather than at the end a killed session never reaches.
133
+ onCheckpoint: async (cursor) => {
134
+ await storage.put(KEYS.cursor, cursor);
135
+ if (cursor.sessionId && cursor.sessionId !== announced) {
136
+ await announce({ sessionId: cursor.sessionId });
137
+ }
138
+ },
139
+ ...(signal ? { signal } : {})
140
+ };
141
+ /**
142
+ * Drain one exec to its end, starting it or re-attaching from the cursor.
143
+ *
144
+ * **A cut stream is re-attached here, not failed.** The session is still
145
+ * running, and a failed run is stopped — the one outcome that loses it. The
146
+ * retry opens the workspace afresh, since the stub the stream came over may
147
+ * not survive the cut. Two attempts in a row that end in a cut with no
148
+ * checkpoint stored fail the run as before: a stream that breaks every time
149
+ * it opens is not a blip.
150
+ */
151
+ const drain = async (execId, begin) => {
152
+ current = execId;
153
+ let outcome;
154
+ let stalled = false;
155
+ while (!outcome) {
156
+ const cursor = await storage.get(KEYS.cursor);
157
+ try {
158
+ outcome =
159
+ cursor?.execId === execId
160
+ ? await session.resume(workspace.runtime, cursor, sinks)
161
+ : await begin(workspace.runtime);
162
+ }
163
+ catch (err) {
164
+ const after = await storage.get(KEYS.cursor);
165
+ const moved = after?.execId === execId &&
166
+ (cursor?.execId !== execId || after.seq > cursor.seq);
167
+ if (!isStreamCut(err) || signal?.aborted || (stalled && !moved))
168
+ throw err;
169
+ stalled = !moved;
170
+ console.warn("[claude-code] the session's stream was cut — re-attaching", {
171
+ execId,
172
+ err: String(err)
173
+ });
174
+ const fresh = await options.workspace();
175
+ workspace[Symbol.dispose]();
176
+ workspace = fresh;
177
+ }
178
+ }
179
+ await storage.put(KEYS.cursor, outcome.cursor);
180
+ if (!outcome.done) {
181
+ // Only the signal stops a drain short of the end: the turn was
182
+ // cancelled, so the session goes with it.
183
+ await session.stop(workspace.runtime, runId).catch((err) => console.warn("[claude-code] could not stop a cancelled session", {
184
+ runId,
185
+ err: String(err)
186
+ }));
187
+ throw signal?.reason ?? new Error("the session was stopped");
188
+ }
189
+ return {
190
+ exitCode: outcome.exitCode,
191
+ ...(outcome.result ? { result: outcome.result } : {}),
192
+ ...(outcome.stderr ? { stderr: outcome.stderr } : {}),
193
+ ...(outcome.rateLimit ? { rateLimit: outcome.rateLimit } : {}),
194
+ ...(outcome.cursor.sessionId
195
+ ? { sessionId: outcome.cursor.sessionId }
196
+ : {})
197
+ };
198
+ };
199
+ let ended = await storage.get(KEYS.session);
200
+ if (!ended) {
201
+ let prompt = await storage.get(KEYS.brief);
202
+ if (prompt === undefined) {
203
+ const task = lastUserText(call.prompt);
204
+ prompt = options.brief ? await options.brief(task) : task;
205
+ await storage.put(KEYS.brief, prompt);
206
+ }
207
+ const brief = prompt;
208
+ ended = await drain(execIdFor(runId), (runtime) => session.start(runtime, runId, {
209
+ prompt: brief,
210
+ dir: options.dir,
211
+ ...(options.jsonSchema ? { jsonSchema: options.jsonSchema } : {}),
212
+ ...(options.permissionMode
213
+ ? { permissionMode: options.permissionMode }
214
+ : {}),
215
+ ...(options.resume ? { resume: options.resume } : {})
216
+ }, sinks));
217
+ await storage.put(KEYS.session, ended);
218
+ }
219
+ // After the end is stored, so a turn that dies here does not report an end
220
+ // the run has not kept — and outside the guard above, so a turn cut between
221
+ // storing the end and telling the host tells it on the next attempt. Telling
222
+ // it twice is harmless: its record is keyed on the id, see `SessionRecord`.
223
+ if (ended.sessionId)
224
+ await announce({ sessionId: ended.sessionId, end: ended });
225
+ let followUpEnd = await storage.get(KEYS.followUpEnd);
226
+ if (!followUpEnd && options.followUp) {
227
+ let asked = await storage.get(KEYS.followUp);
228
+ if (!asked) {
229
+ const prompt = await options.followUp(ended);
230
+ asked = prompt ? { prompt } : {};
231
+ await storage.put(KEYS.followUp, asked);
232
+ }
233
+ // The cursor's id as well as the result's: a session that was stopped
234
+ // before it reported still has a conversation worth one more turn.
235
+ const sessionId = ended.result?.sessionId ?? ended.sessionId;
236
+ if (asked.prompt && sessionId) {
237
+ const prompt = asked.prompt;
238
+ followUpEnd = await drain(followUpExecIdFor(runId), (runtime) => session.followUp(runtime, runId, {
239
+ sessionId,
240
+ prompt,
241
+ dir: options.dir,
242
+ ...(options.permissionMode
243
+ ? { permissionMode: options.permissionMode }
244
+ : {})
245
+ }, sinks));
246
+ await storage.put(KEYS.followUpEnd, followUpEnd);
247
+ }
248
+ }
249
+ const text = await options.report({
250
+ session: ended,
251
+ ...(followUpEnd ? { followUp: followUpEnd } : {})
252
+ });
253
+ await storage.put(KEYS.report, text);
254
+ return text;
255
+ }
256
+ catch (e_1) {
257
+ env_1.error = e_1;
258
+ env_1.hasError = true;
259
+ }
260
+ finally {
261
+ __disposeResources(env_1);
262
+ }
263
+ };
264
+ return {
265
+ specificationVersion: "v3",
266
+ provider: "claude-code",
267
+ modelId: options.config.model ?? "claude-code",
268
+ supportedUrls: {},
269
+ async doStream(call) {
270
+ // The stream is returned at once and the session runs inside it, so
271
+ // nothing waits on a promise for the length of a session.
272
+ const stream = new ReadableStream({
273
+ async start(controller) {
274
+ controller.enqueue({ type: "stream-start", warnings: [] });
275
+ try {
276
+ const text = await run(call);
277
+ controller.enqueue({ type: "text-start", id: "report" });
278
+ controller.enqueue({
279
+ type: "text-delta",
280
+ id: "report",
281
+ delta: text
282
+ });
283
+ controller.enqueue({ type: "text-end", id: "report" });
284
+ controller.enqueue({
285
+ type: "finish",
286
+ usage: USAGE,
287
+ finishReason: { unified: "stop", raw: undefined }
288
+ });
289
+ controller.close();
290
+ }
291
+ catch (err) {
292
+ controller.error(err);
293
+ }
294
+ }
295
+ });
296
+ return { stream };
297
+ },
298
+ async doGenerate(call) {
299
+ const text = await run(call);
300
+ return {
301
+ content: [{ type: "text", text }],
302
+ finishReason: { unified: "stop", raw: undefined },
303
+ usage: USAGE,
304
+ warnings: []
305
+ };
306
+ }
307
+ };
308
+ }
309
+ /**
310
+ * Whether a drain failed because the transport under a live session gave way.
311
+ *
312
+ * An exec's events reach the sub-agent as a stream over RPC, relayed by the
313
+ * workspace object from the container's own RPC session — so a drop anywhere on
314
+ * that path cuts the stream while the session runs on. Measured: a container's
315
+ * session dropped after 21 minutes and was attached again within a second, the
316
+ * process untouched. The message is workerd's for a stream whose far side went
317
+ * away, and it carries no code.
318
+ */
319
+ function isStreamCut(err) {
320
+ if (isPlatformTransientError(err))
321
+ return true;
322
+ for (let e = err; e instanceof Error; e = e.cause) {
323
+ if (e.message.includes("ReadableStream received over RPC disconnected"))
324
+ return true;
325
+ }
326
+ return false;
327
+ }
328
+ /**
329
+ * The task: the last user message's text. On a continued turn the prompt ends
330
+ * with the interrupted assistant message, so the last message is not it.
331
+ */
332
+ function lastUserText(prompt) {
333
+ for (let i = prompt.length - 1; i >= 0; i--) {
334
+ const message = prompt[i];
335
+ if (message.role !== "user")
336
+ continue;
337
+ return message.content
338
+ .map((part) => (part.type === "text" ? part.text : ""))
339
+ .join("");
340
+ }
341
+ throw new Error("claude-code: the run has no task — no user message");
342
+ }