@astrosheep/keiyaku 4.0.6 → 4.1.1
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 +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +3 -0
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +3 -0
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +3 -6
- package/build/src/akuma/akuma.d.ts +17 -14
- package/build/src/akuma/akuma.js +122 -114
- package/build/src/akuma/allowed.d.ts +1 -0
- package/build/src/akuma/allowed.js +6 -0
- package/build/src/akuma/archetype.js +12 -2
- package/build/src/akuma/body-turn.js +27 -15
- package/build/src/akuma/body.d.ts +44 -3
- package/build/src/akuma/body.js +142 -33
- package/build/src/akuma/coordinate.js +17 -7
- package/build/src/akuma/heart/facts.js +1 -1
- package/build/src/akuma/heart/index.d.ts +1 -1
- package/build/src/akuma/heart/index.js +2 -4
- package/build/src/akuma/heart/request-authority.js +4 -4
- package/build/src/akuma/heart/request-rows.js +27 -16
- package/build/src/akuma/heart/rows.js +79 -41
- package/build/src/akuma/heart/soul.js +1 -1
- package/build/src/akuma/heart/storage.d.ts +1 -0
- package/build/src/akuma/heart/storage.js +76 -11
- package/build/src/akuma/heart/tells.js +35 -18
- package/build/src/akuma/heart/timeline.js +19 -11
- package/build/src/akuma/identity.d.ts +1 -0
- package/build/src/akuma/identity.js +1 -0
- package/build/src/akuma/index.d.ts +3 -3
- package/build/src/akuma/index.js +1 -1
- package/build/src/akuma/nuke.js +106 -14
- package/build/src/akuma/projection.d.ts +11 -9
- package/build/src/akuma/projection.js +110 -53
- package/build/src/akuma/provider-recipe.d.ts +2 -0
- package/build/src/akuma/provider-recipe.js +21 -5
- package/build/src/akuma/provider.js +105 -62
- package/build/src/akuma/providers/acp/config.d.ts +2 -0
- package/build/src/akuma/providers/acp/config.js +13 -6
- package/build/src/akuma/providers/acp/core.d.ts +5 -2
- package/build/src/akuma/providers/acp/core.js +45 -25
- package/build/src/akuma/providers/acp/events.js +38 -29
- package/build/src/akuma/providers/acp/index.js +18 -8
- package/build/src/akuma/providers/claude/events.js +8 -12
- package/build/src/akuma/providers/claude/index.d.ts +2 -1
- package/build/src/akuma/providers/claude/index.js +59 -26
- package/build/src/akuma/providers/claude/input.js +6 -2
- package/build/src/akuma/providers/codex-app-server/events.js +61 -36
- package/build/src/akuma/providers/codex-app-server/index.js +29 -14
- package/build/src/akuma/providers/grok-build/index.js +28 -17
- package/build/src/akuma/providers/index.js +3 -19
- package/build/src/akuma/providers/opencode-sdk/events.js +32 -18
- package/build/src/akuma/providers/opencode-sdk/index.js +29 -17
- package/build/src/akuma/providers/opencode-sdk/session.js +21 -5
- package/build/src/akuma/providers/pi/events.js +26 -19
- package/build/src/akuma/providers/pi/index.js +58 -38
- package/build/src/akuma/publication.js +9 -9
- package/build/src/akuma/request-serve.js +37 -40
- package/build/src/akuma/request-wire.d.ts +2 -2
- package/build/src/akuma/request-wire.js +75 -102
- package/build/src/akuma/requests.js +2 -2
- package/build/src/akuma-body.js +6 -5
- package/build/src/body/amend.d.ts +4 -1
- package/build/src/body/amend.js +14 -15
- package/build/src/body/decode.js +2 -4
- package/build/src/body/envelope.js +2 -4
- package/build/src/body/region.d.ts +1 -2
- package/build/src/body/region.js +4 -72
- package/build/src/body/render.js +17 -12
- package/build/src/body/shape.js +1 -7
- package/build/src/cli/accepted.d.ts +1 -1
- package/build/src/cli/accepted.js +10 -1
- package/build/src/cli/commands/akuma-invoke.js +18 -6
- package/build/src/cli/commands/akuma.js +10 -13
- package/build/src/cli/commands/amend.d.ts +2 -2
- package/build/src/cli/commands/amend.js +2 -4
- package/build/src/cli/commands/bind.d.ts +4 -4
- package/build/src/cli/commands/bind.js +16 -6
- package/build/src/cli/commands/contract.d.ts +99 -10
- package/build/src/cli/commands/contract.js +128 -24
- package/build/src/cli/commands/install.d.ts +1 -1
- package/build/src/cli/commands/install.js +23 -15
- package/build/src/cli/commands/task-invoke.d.ts +4 -1
- package/build/src/cli/commands/task-invoke.js +191 -68
- package/build/src/cli/commands/task-query.js +48 -24
- package/build/src/cli/commands/task.js +150 -30
- package/build/src/cli/coordinates.js +2 -4
- package/build/src/cli/invoke.js +88 -44
- package/build/src/cli/main.js +4 -2
- package/build/src/cli/parse.d.ts +2 -89
- package/build/src/cli/parse.js +87 -79
- package/build/src/cli/render/akuma-tool-command.js +6 -7
- package/build/src/cli/render/akuma-tool.js +10 -8
- package/build/src/cli/render/akuma.js +149 -53
- package/build/src/cli/render/audit.js +5 -15
- package/build/src/cli/render/board.d.ts +1 -0
- package/build/src/cli/render/board.js +17 -0
- package/build/src/cli/render/catalog.js +84 -7
- package/build/src/cli/render/contract-observation.d.ts +10 -0
- package/build/src/cli/render/contract-observation.js +58 -0
- package/build/src/cli/render/contract.js +57 -54
- package/build/src/cli/render/kanshi.js +281 -209
- package/build/src/cli/render/receipt.d.ts +1 -0
- package/build/src/cli/render/receipt.js +20 -23
- package/build/src/cli/render/refusal.js +16 -15
- package/build/src/cli/render/region.js +22 -6
- package/build/src/cli/render/settings.js +4 -4
- package/build/src/cli/render/task.js +93 -21
- package/build/src/cli/render/terminal.js +16 -5
- package/build/src/cli/result.d.ts +11 -4
- package/build/src/cli/runtime.d.ts +6 -1
- package/build/src/cli/runtime.js +84 -63
- package/build/src/cli/selectors.js +2 -4
- package/build/src/cli/usage.js +6 -5
- package/build/src/contract-worktree.d.ts +1 -25
- package/build/src/contract-worktree.js +87 -174
- package/build/src/coordination/durable-file.js +7 -3
- package/build/src/coordination/sqlite-transaction-lock.js +29 -12
- package/build/src/core/facts/codec.js +7 -3
- package/build/src/core/facts/types.d.ts +1 -1
- package/build/src/core/subject.js +16 -9
- package/build/src/core/verbs/abandon.d.ts +1 -1
- package/build/src/core/verbs/abandon.js +1 -1
- package/build/src/core/verbs/amend.d.ts +1 -1
- package/build/src/core/verbs/amend.js +7 -7
- package/build/src/core/verbs/attestation.js +4 -1
- package/build/src/core/verbs/bind.d.ts +1 -1
- package/build/src/core/verbs/bind.js +1 -1
- package/build/src/core/verbs/placement.d.ts +1 -1
- package/build/src/core/verbs/placement.js +10 -8
- package/build/src/dispatch/index.js +8 -6
- package/build/src/duration.js +5 -1
- package/build/src/git/admission.js +5 -3
- package/build/src/git/hooks.d.ts +8 -0
- package/build/src/git/hooks.js +63 -14
- package/build/src/git/identity.js +1 -4
- package/build/src/git/integration.d.ts +2 -3
- package/build/src/git/integration.js +32 -39
- package/build/src/git/nuke.d.ts +1 -1
- package/build/src/git/nuke.js +110 -62
- package/build/src/git/observe.d.ts +13 -1
- package/build/src/git/observe.js +51 -44
- package/build/src/git/process.js +4 -2
- package/build/src/git/read-observation.js +10 -8
- package/build/src/git/reconcile.d.ts +14 -3
- package/build/src/git/reconcile.js +123 -102
- package/build/src/git/repository.d.ts +2 -0
- package/build/src/git/repository.js +13 -22
- package/build/src/git/target-placement.d.ts +9 -10
- package/build/src/git/target-placement.js +59 -62
- package/build/src/git/tender.d.ts +13 -2
- package/build/src/git/tender.js +28 -22
- package/build/src/git/terminal-seal.js +15 -12
- package/build/src/git/tree.js +5 -2
- package/build/src/git/workspace.d.ts +24 -2
- package/build/src/git/workspace.js +120 -16
- package/build/src/identity/coordinates.js +3 -1
- package/build/src/identity/selector.js +6 -3
- package/build/src/kanshi/fleet.d.ts +6 -0
- package/build/src/kanshi/fleet.js +27 -0
- package/build/src/kanshi/index.d.ts +1 -1
- package/build/src/kanshi/read.js +77 -45
- package/build/src/kanshi/report.d.ts +13 -24
- package/build/src/kanshi/select.js +25 -24
- package/build/src/library/address.d.ts +2 -1
- package/build/src/library/address.js +7 -8
- package/build/src/library/akuma-creation.js +20 -12
- package/build/src/library/audit.d.ts +0 -1
- package/build/src/library/audit.js +1 -2
- package/build/src/library/bind.d.ts +53 -5
- package/build/src/library/bind.js +98 -22
- package/build/src/library/catalog.d.ts +1 -0
- package/build/src/library/catalog.js +6 -3
- package/build/src/library/configuration.js +3 -1
- package/build/src/library/continuation.d.ts +37 -0
- package/build/src/library/continuation.js +86 -0
- package/build/src/library/contract.d.ts +39 -45
- package/build/src/library/contract.js +141 -118
- package/build/src/library/delivery.d.ts +18 -13
- package/build/src/library/fleet.d.ts +1 -1
- package/build/src/library/fleet.js +19 -11
- package/build/src/library/input.d.ts +2 -0
- package/build/src/library/input.js +14 -0
- package/build/src/library/keiyaku.d.ts +8 -7
- package/build/src/library/keiyaku.js +3 -3
- package/build/src/library/mutation.js +11 -4
- package/build/src/library/nuke.js +14 -5
- package/build/src/library/reconcile.d.ts +9 -4
- package/build/src/library/reconcile.js +30 -24
- package/build/src/library/refusal.d.ts +13 -5
- package/build/src/library/refusal.js +7 -0
- package/build/src/library/region.d.ts +8 -7
- package/build/src/library/region.js +31 -11
- package/build/src/library/repo.js +2 -2
- package/build/src/markdown/lex.js +9 -2
- package/build/src/markdown/parse.js +11 -7
- package/build/src/markdown/query.js +4 -2
- package/build/src/protocol/amend.js +3 -1
- package/build/src/protocol/attempt.d.ts +7 -3
- package/build/src/protocol/attempt.js +9 -5
- package/build/src/protocol/audit.d.ts +1 -1
- package/build/src/protocol/audit.js +4 -14
- package/build/src/protocol/bind.d.ts +19 -6
- package/build/src/protocol/bind.js +28 -13
- package/build/src/protocol/completion.d.ts +0 -1
- package/build/src/protocol/completion.js +1 -3
- package/build/src/protocol/deliver.d.ts +12 -4
- package/build/src/protocol/deliver.js +60 -51
- package/build/src/protocol/intent.d.ts +1 -0
- package/build/src/protocol/intent.js +9 -7
- package/build/src/protocol/operations.d.ts +10 -9
- package/build/src/protocol/operations.js +5 -3
- package/build/src/protocol/placement.d.ts +0 -1
- package/build/src/protocol/placement.js +6 -6
- package/build/src/protocol/read/observation.d.ts +11 -0
- package/build/src/protocol/read/observation.js +37 -0
- package/build/src/protocol/read/status.d.ts +23 -12
- package/build/src/protocol/read/status.js +90 -72
- package/build/src/protocol/reconcile.d.ts +1 -0
- package/build/src/protocol/reconcile.js +2 -3
- package/build/src/protocol/reintegrate.js +1 -1
- package/build/src/protocol/review.d.ts +0 -1
- package/build/src/protocol/review.js +15 -22
- package/build/src/protocol/run.d.ts +1 -0
- package/build/src/protocol/run.js +4 -5
- package/build/src/runtime/proc/launch.d.ts +33 -0
- package/build/src/runtime/proc/launch.js +98 -0
- package/build/src/runtime/proc/line-rpc.js +9 -3
- package/build/src/runtime/proc/run.d.ts +12 -6
- package/build/src/runtime/proc/run.js +78 -21
- package/build/src/runtime/proc/stdio.js +7 -10
- package/build/src/settings.js +6 -2
- package/build/src/settlement/fence.d.ts +0 -2
- package/build/src/settlement/fence.js +0 -24
- package/build/src/settlement/holder.js +13 -10
- package/build/src/settlement/settle.js +39 -6
- package/build/src/task/board.d.ts +21 -2
- package/build/src/task/board.js +35 -16
- package/build/src/task/compose.js +85 -22
- package/build/src/task/context.js +21 -8
- package/build/src/task/document.js +46 -10
- package/build/src/task/identity.js +19 -6
- package/build/src/task/index.js +118 -27
- package/build/src/task/input.js +29 -7
- package/build/src/task/mutation.js +61 -19
- package/build/src/task/operations.d.ts +8 -2
- package/build/src/task/operations.js +97 -32
- package/build/src/task/query.js +57 -28
- package/build/src/task/store.d.ts +5 -1
- package/build/src/task/store.js +88 -95
- package/build/src/verification/execution.js +14 -11
- package/build/src/workspace-place.js +19 -7
- package/build/src/world.js +16 -6
- package/package.json +8 -3
|
@@ -87,9 +87,9 @@ function decodeDiffstat(value) {
|
|
|
87
87
|
}
|
|
88
88
|
function decodeFileChangeMember(value) {
|
|
89
89
|
const change = object(value);
|
|
90
|
-
if (change === null ||
|
|
91
|
-
&& change.op !== "delete" && change.op !== "unspecified")
|
|
92
|
-
|
|
90
|
+
if (change === null ||
|
|
91
|
+
(change.op !== "add" && change.op !== "update" && change.op !== "delete" && change.op !== "unspecified") ||
|
|
92
|
+
typeof change.path !== "string")
|
|
93
93
|
return null;
|
|
94
94
|
const diffstat = decodeDiffstat(change.diffstat);
|
|
95
95
|
if (diffstat === null)
|
|
@@ -114,12 +114,18 @@ function decodeToolCall(value) {
|
|
|
114
114
|
if (call === null)
|
|
115
115
|
return null;
|
|
116
116
|
switch (call.kind) {
|
|
117
|
-
case "run":
|
|
118
|
-
|
|
119
|
-
case "
|
|
120
|
-
|
|
121
|
-
case "
|
|
122
|
-
|
|
117
|
+
case "run":
|
|
118
|
+
return decodeRunCall(call);
|
|
119
|
+
case "read":
|
|
120
|
+
return decodeReadCall(call);
|
|
121
|
+
case "search":
|
|
122
|
+
return decodeSearchCall(call);
|
|
123
|
+
case "fileChange":
|
|
124
|
+
return decodeFileChangeCall(call);
|
|
125
|
+
case "other":
|
|
126
|
+
return decodeOtherCall(call);
|
|
127
|
+
default:
|
|
128
|
+
return null;
|
|
123
129
|
}
|
|
124
130
|
}
|
|
125
131
|
function decodeToolResult(value) {
|
|
@@ -143,13 +149,26 @@ function decodeToolEvent(event) {
|
|
|
143
149
|
return null;
|
|
144
150
|
const call = decodeToolCall(event.call);
|
|
145
151
|
if (call !== null && event.phase === "started" && event.result === undefined) {
|
|
146
|
-
return {
|
|
147
|
-
|
|
152
|
+
return {
|
|
153
|
+
type: "tool",
|
|
154
|
+
phase: "started",
|
|
155
|
+
id: event.id,
|
|
156
|
+
name: event.name,
|
|
157
|
+
call,
|
|
158
|
+
...(event.truncated === true ? { truncated: true } : {}),
|
|
159
|
+
};
|
|
148
160
|
}
|
|
149
161
|
const result = decodeToolResult(event.result);
|
|
150
162
|
if (call !== null && event.phase === "completed" && result !== null) {
|
|
151
|
-
return {
|
|
152
|
-
|
|
163
|
+
return {
|
|
164
|
+
type: "tool",
|
|
165
|
+
phase: "completed",
|
|
166
|
+
id: event.id,
|
|
167
|
+
name: event.name,
|
|
168
|
+
call,
|
|
169
|
+
result,
|
|
170
|
+
...(event.truncated === true ? { truncated: true } : {}),
|
|
171
|
+
};
|
|
153
172
|
}
|
|
154
173
|
return null;
|
|
155
174
|
}
|
|
@@ -159,15 +178,20 @@ function decodeTypedEvent(type, event) {
|
|
|
159
178
|
const truncated = event.truncated === true ? { truncated: true } : {};
|
|
160
179
|
switch (type) {
|
|
161
180
|
case "assistant":
|
|
162
|
-
case "thought":
|
|
163
|
-
|
|
164
|
-
case "
|
|
181
|
+
case "thought":
|
|
182
|
+
return typeof event.text === "string" ? { type, text: event.text, ...truncated } : null;
|
|
183
|
+
case "note":
|
|
184
|
+
return typeof event.text === "string" ? { type, text: event.text, ...truncated } : null;
|
|
185
|
+
case "unknown":
|
|
186
|
+
return typeof event.kind === "string" ? { type, kind: event.kind, ...truncated } : null;
|
|
165
187
|
case "session": {
|
|
166
188
|
const coordinate = decodeResumeCoordinate(event.coordinate);
|
|
167
189
|
return coordinate === null ? null : { type, coordinate };
|
|
168
190
|
}
|
|
169
|
-
case "tool":
|
|
170
|
-
|
|
191
|
+
case "tool":
|
|
192
|
+
return decodeToolEvent(event);
|
|
193
|
+
default:
|
|
194
|
+
return type;
|
|
171
195
|
}
|
|
172
196
|
}
|
|
173
197
|
export function decodeAgentEvent(value) {
|
|
@@ -181,37 +205,49 @@ export function decodeAgentEvent(value) {
|
|
|
181
205
|
}
|
|
182
206
|
function boundedToolCall(call) {
|
|
183
207
|
switch (call.kind) {
|
|
184
|
-
case "run":
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
208
|
+
case "run":
|
|
209
|
+
return {
|
|
210
|
+
value: { kind: call.kind, command: boundedEventText(call.command) },
|
|
211
|
+
truncated: call.command.length > AGENT_EVENT_TEXT_LIMIT,
|
|
212
|
+
};
|
|
213
|
+
case "read":
|
|
214
|
+
return {
|
|
215
|
+
value: {
|
|
216
|
+
kind: call.kind,
|
|
217
|
+
path: boundedEventText(call.path),
|
|
218
|
+
...(call.offset === undefined ? {} : { offset: call.offset }),
|
|
219
|
+
...(call.limit === undefined ? {} : { limit: call.limit }),
|
|
220
|
+
},
|
|
221
|
+
truncated: call.path.length > AGENT_EVENT_TEXT_LIMIT,
|
|
222
|
+
};
|
|
223
|
+
case "search":
|
|
224
|
+
return {
|
|
225
|
+
value: {
|
|
226
|
+
kind: call.kind,
|
|
227
|
+
query: boundedEventText(call.query),
|
|
228
|
+
...(call.scope === undefined ? {} : { scope: call.scope }),
|
|
229
|
+
...(call.path === undefined ? {} : { path: boundedEventText(call.path) }),
|
|
230
|
+
...(call.glob === undefined ? {} : { glob: boundedEventText(call.glob) }),
|
|
231
|
+
},
|
|
232
|
+
truncated: call.query.length > AGENT_EVENT_TEXT_LIMIT ||
|
|
233
|
+
(call.path !== undefined && call.path.length > AGENT_EVENT_TEXT_LIMIT) ||
|
|
234
|
+
(call.glob !== undefined && call.glob.length > AGENT_EVENT_TEXT_LIMIT),
|
|
235
|
+
};
|
|
236
|
+
case "fileChange":
|
|
237
|
+
return {
|
|
238
|
+
value: {
|
|
239
|
+
kind: call.kind,
|
|
240
|
+
changes: call.changes.map((change) => ({ ...change, path: boundedEventText(change.path) })),
|
|
241
|
+
},
|
|
242
|
+
truncated: call.changes.some((change) => change.path.length > AGENT_EVENT_TEXT_LIMIT),
|
|
243
|
+
};
|
|
244
|
+
case "other":
|
|
245
|
+
return {
|
|
246
|
+
value: { kind: call.kind, display: boundedEventText(call.display) },
|
|
247
|
+
truncated: call.display.length > AGENT_EVENT_TEXT_LIMIT,
|
|
248
|
+
};
|
|
249
|
+
default:
|
|
250
|
+
return call;
|
|
215
251
|
}
|
|
216
252
|
}
|
|
217
253
|
function boundedToolResult(result) {
|
|
@@ -230,22 +266,28 @@ export function encodeAgentEvent(event) {
|
|
|
230
266
|
...(changed || ("truncated" in event && event.truncated === true) ? { truncated: true } : {}),
|
|
231
267
|
});
|
|
232
268
|
switch (event.type) {
|
|
233
|
-
case "session":
|
|
234
|
-
|
|
235
|
-
case "
|
|
236
|
-
|
|
237
|
-
case "
|
|
269
|
+
case "session":
|
|
270
|
+
return { type: event.type, coordinate: encodeResumeCoordinate(event.coordinate) };
|
|
271
|
+
case "assistant":
|
|
272
|
+
return marked({ type: event.type, text: boundedEventText(event.text) }, event.text.length > AGENT_EVENT_TEXT_LIMIT);
|
|
273
|
+
case "thought":
|
|
274
|
+
return marked({ type: event.type, text: boundedThoughtText(event.text) }, event.text.length > AGENT_THOUGHT_TEXT_LIMIT);
|
|
275
|
+
case "note":
|
|
276
|
+
return marked({ type: event.type, text: boundedEventText(event.text) }, event.text.length > AGENT_EVENT_TEXT_LIMIT);
|
|
277
|
+
case "unknown":
|
|
278
|
+
return marked({ type: event.type, kind: boundedEventText(event.kind) }, event.kind.length > AGENT_EVENT_TEXT_LIMIT);
|
|
238
279
|
case "tool": {
|
|
239
280
|
const call = boundedToolCall(event.call);
|
|
240
281
|
const name = boundedEventText(event.name);
|
|
241
282
|
const result = event.phase === "completed" ? boundedToolResult(event.result) : undefined;
|
|
242
|
-
return marked(event.phase === "started"
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
283
|
+
return marked(event.phase === "started"
|
|
284
|
+
? {
|
|
285
|
+
type: event.type,
|
|
286
|
+
id: event.id,
|
|
287
|
+
phase: event.phase,
|
|
288
|
+
name,
|
|
289
|
+
call: call.value,
|
|
290
|
+
}
|
|
249
291
|
: {
|
|
250
292
|
type: event.type,
|
|
251
293
|
id: event.id,
|
|
@@ -255,7 +297,8 @@ export function encodeAgentEvent(event) {
|
|
|
255
297
|
result: result.value,
|
|
256
298
|
}, name !== event.name || call.truncated || result?.truncated === true);
|
|
257
299
|
}
|
|
258
|
-
default:
|
|
300
|
+
default:
|
|
301
|
+
return event;
|
|
259
302
|
}
|
|
260
303
|
}
|
|
261
304
|
export function boundedEventText(value) {
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import type { SystemPromptMode } from "../../provider-recipe.js";
|
|
1
2
|
export type AcpExecutionConfig = Readonly<{
|
|
2
3
|
argvBefore: readonly string[];
|
|
3
4
|
argvAfter: readonly string[];
|
|
4
5
|
modelArg?: string;
|
|
5
6
|
effortArg?: string;
|
|
6
7
|
systemPromptArg?: string;
|
|
8
|
+
systemPromptMode?: SystemPromptMode;
|
|
7
9
|
}>;
|
|
8
10
|
export declare function decodeAcpConfig(value: unknown): AcpExecutionConfig;
|
|
@@ -12,26 +12,33 @@ export function decodeAcpConfig(value) {
|
|
|
12
12
|
throw new TypeError("ACP provider config must be an object");
|
|
13
13
|
}
|
|
14
14
|
const config = value;
|
|
15
|
-
const unknown = Object.keys(config)
|
|
16
|
-
.find((key) => !["argvBefore", "argvAfter", "effortArg", "modelArg", "systemPromptArg"].includes(key));
|
|
15
|
+
const unknown = Object.keys(config).find((key) => !["argvBefore", "argvAfter", "effortArg", "modelArg", "systemPromptArg", "systemPromptMode"].includes(key));
|
|
17
16
|
if (unknown !== undefined)
|
|
18
17
|
throw new TypeError(`ACP provider config has unknown field ${unknown}`);
|
|
19
|
-
if (!Array.isArray(config.argvBefore)
|
|
20
|
-
|
|
18
|
+
if (!Array.isArray(config.argvBefore) ||
|
|
19
|
+
config.argvBefore.some((arg) => typeof arg !== "string" || arg.trim().length === 0)) {
|
|
21
20
|
throw new TypeError("ACP provider config argvBefore must be an array of nonblank strings");
|
|
22
21
|
}
|
|
23
|
-
if (!Array.isArray(config.argvAfter)
|
|
24
|
-
|
|
22
|
+
if (!Array.isArray(config.argvAfter) ||
|
|
23
|
+
config.argvAfter.some((arg) => typeof arg !== "string" || arg.trim().length === 0)) {
|
|
25
24
|
throw new TypeError("ACP provider config argvAfter must be an array of nonblank strings");
|
|
26
25
|
}
|
|
27
26
|
const modelArg = argumentName(config, "modelArg");
|
|
28
27
|
const effortArg = argumentName(config, "effortArg");
|
|
29
28
|
const systemPromptArg = argumentName(config, "systemPromptArg");
|
|
29
|
+
const systemPromptMode = config.systemPromptMode;
|
|
30
|
+
if (systemPromptMode !== undefined && systemPromptMode !== "append" && systemPromptMode !== "replace") {
|
|
31
|
+
throw new TypeError("ACP provider config systemPromptMode must be append, replace");
|
|
32
|
+
}
|
|
33
|
+
if (systemPromptMode !== undefined && systemPromptArg === undefined) {
|
|
34
|
+
throw new TypeError("ACP provider config systemPromptMode requires systemPromptArg");
|
|
35
|
+
}
|
|
30
36
|
return Object.freeze({
|
|
31
37
|
argvBefore: Object.freeze([...config.argvBefore]),
|
|
32
38
|
argvAfter: Object.freeze([...config.argvAfter]),
|
|
33
39
|
...(modelArg === undefined ? {} : { modelArg }),
|
|
34
40
|
...(effortArg === undefined ? {} : { effortArg }),
|
|
35
41
|
...(systemPromptArg === undefined ? {} : { systemPromptArg }),
|
|
42
|
+
...(systemPromptMode === undefined ? {} : { systemPromptMode }),
|
|
36
43
|
});
|
|
37
44
|
}
|
|
@@ -1,16 +1,19 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import type * as AcpSdk from "@agentclientprotocol/sdk";
|
|
2
2
|
import { spawnStdioProcess } from "../../../runtime/proc/stdio.js";
|
|
3
3
|
import { type ProviderAdapter, type Session } from "../../provider.js";
|
|
4
4
|
import { type AcpToolInterpreter, type AcpToolUpdate } from "./events.js";
|
|
5
5
|
export type { AcpToolInterpreter, AcpToolUpdate };
|
|
6
6
|
export type AcpStartInput = Parameters<ProviderAdapter["start"]>[0] | Parameters<NonNullable<ProviderAdapter["resume"]>>[0];
|
|
7
|
+
export type AcpSessionMeta = Readonly<Record<string, unknown>>;
|
|
7
8
|
export type AcpDependencies = Readonly<{
|
|
8
9
|
spawnProcess?: typeof spawnStdioProcess;
|
|
9
10
|
interpretTool?: AcpToolInterpreter;
|
|
11
|
+
freshSessionMeta?: AcpSessionMeta;
|
|
12
|
+
loadSessionMeta?: AcpSessionMeta;
|
|
10
13
|
}>;
|
|
11
14
|
export type AcpLiveSession = Readonly<{
|
|
12
15
|
session: Session;
|
|
13
|
-
agent:
|
|
16
|
+
agent: AcpSdk.ClientContext;
|
|
14
17
|
sessionId: string;
|
|
15
18
|
open(): boolean;
|
|
16
19
|
}>;
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import * as acp from "@agentclientprotocol/sdk";
|
|
2
1
|
import { Readable, Writable } from "node:stream";
|
|
3
2
|
import { spawnStdioProcess } from "../../../runtime/proc/stdio.js";
|
|
4
3
|
import { abortable } from "../../abort.js";
|
|
5
4
|
import { AKUMA_REQUESTS_ENV, AgentEventChannel, } from "../../provider.js";
|
|
6
5
|
import { EMPTY_ACP_EVENT_STATE, flushAcpEvents, mapAcpUpdate, } from "./events.js";
|
|
7
|
-
function diagnostic(error) {
|
|
6
|
+
function diagnostic(acp, error) {
|
|
8
7
|
if (!(error instanceof Error))
|
|
9
8
|
return String(error);
|
|
10
9
|
if (!(error instanceof acp.RequestError) || error.data === undefined)
|
|
@@ -18,18 +17,23 @@ function diagnostic(error) {
|
|
|
18
17
|
}
|
|
19
18
|
return data.length === 0 ? `${error.message} [${error.code}]` : `${error.message} [${error.code}]: ${data}`;
|
|
20
19
|
}
|
|
21
|
-
function createAcpClient(onUpdate) {
|
|
22
|
-
return acp
|
|
20
|
+
function createAcpClient(acp, onUpdate) {
|
|
21
|
+
return acp
|
|
22
|
+
.client({ name: "keiyaku" })
|
|
23
23
|
.onNotification(acp.methods.client.session.update, ({ params }) => onUpdate(params));
|
|
24
24
|
}
|
|
25
25
|
function promptResult(response) {
|
|
26
|
-
if (response.stopReason === "end_turn" ||
|
|
27
|
-
|
|
26
|
+
if (response.stopReason === "end_turn" ||
|
|
27
|
+
response.stopReason === "max_tokens" ||
|
|
28
|
+
response.stopReason === "max_turn_requests") {
|
|
28
29
|
return { kind: "answered", answer: "" };
|
|
29
30
|
}
|
|
30
31
|
return { kind: "failed", diagnostic: `ACP prompt ended ${response.stopReason}` };
|
|
31
32
|
}
|
|
32
|
-
|
|
33
|
+
function requestMeta(meta) {
|
|
34
|
+
return meta === undefined || Object.keys(meta).length === 0 ? {} : { _meta: meta };
|
|
35
|
+
}
|
|
36
|
+
async function establishSession(acp, agent, input, dependencies) {
|
|
33
37
|
const initialized = await agent.request(acp.methods.agent.initialize, {
|
|
34
38
|
protocolVersion: acp.PROTOCOL_VERSION,
|
|
35
39
|
clientInfo: { name: "keiyaku", version: "4" },
|
|
@@ -38,20 +42,31 @@ async function establishSession(agent, input) {
|
|
|
38
42
|
throw new Error("ACP agent does not advertise session/load");
|
|
39
43
|
}
|
|
40
44
|
if (input.session.kind === "fresh") {
|
|
41
|
-
return (await agent.request(acp.methods.agent.session.new, {
|
|
45
|
+
return (await agent.request(acp.methods.agent.session.new, {
|
|
46
|
+
cwd: input.cwd,
|
|
47
|
+
mcpServers: [],
|
|
48
|
+
...requestMeta(dependencies.freshSessionMeta),
|
|
49
|
+
})).sessionId;
|
|
42
50
|
}
|
|
43
51
|
const sessionId = input.session.coordinate.sessionId;
|
|
44
52
|
if (sessionId === undefined)
|
|
45
53
|
throw new Error("ACP resume coordinate has no session id");
|
|
46
|
-
await agent.request(acp.methods.agent.session.load, {
|
|
54
|
+
await agent.request(acp.methods.agent.session.load, {
|
|
55
|
+
cwd: input.cwd,
|
|
56
|
+
mcpServers: [],
|
|
57
|
+
sessionId,
|
|
58
|
+
...requestMeta(dependencies.loadSessionMeta),
|
|
59
|
+
});
|
|
47
60
|
return sessionId;
|
|
48
61
|
}
|
|
49
|
-
function createAcpTurn(connection, interpret) {
|
|
62
|
+
function createAcpTurn(acp, connection, interpret) {
|
|
50
63
|
const events = new AgentEventChannel();
|
|
51
64
|
let state = EMPTY_ACP_EVENT_STATE;
|
|
52
65
|
let terminal = false;
|
|
53
66
|
let resolveCompletion;
|
|
54
|
-
const completion = new Promise((resolve) => {
|
|
67
|
+
const completion = new Promise((resolve) => {
|
|
68
|
+
resolveCompletion = resolve;
|
|
69
|
+
});
|
|
55
70
|
const update = (next) => {
|
|
56
71
|
if (terminal)
|
|
57
72
|
return;
|
|
@@ -66,7 +81,7 @@ function createAcpTurn(connection, interpret) {
|
|
|
66
81
|
terminal = true;
|
|
67
82
|
let completionResult = result;
|
|
68
83
|
const failCleanup = (error) => {
|
|
69
|
-
completionResult = { kind: "failed", diagnostic: `ACP cleanup failed: ${diagnostic(error)}` };
|
|
84
|
+
completionResult = { kind: "failed", diagnostic: `ACP cleanup failed: ${diagnostic(acp, error)}` };
|
|
70
85
|
};
|
|
71
86
|
try {
|
|
72
87
|
await cleanup();
|
|
@@ -84,9 +99,7 @@ function createAcpTurn(connection, interpret) {
|
|
|
84
99
|
for (const event of flushed.events)
|
|
85
100
|
events.emit(event);
|
|
86
101
|
events.end();
|
|
87
|
-
resolveCompletion(completionResult.kind === "answered"
|
|
88
|
-
? { ...completionResult, answer: flushed.state.answer }
|
|
89
|
-
: completionResult);
|
|
102
|
+
resolveCompletion(completionResult.kind === "answered" ? { ...completionResult, answer: flushed.state.answer } : completionResult);
|
|
90
103
|
};
|
|
91
104
|
return {
|
|
92
105
|
events,
|
|
@@ -96,11 +109,17 @@ function createAcpTurn(connection, interpret) {
|
|
|
96
109
|
open: () => !terminal,
|
|
97
110
|
};
|
|
98
111
|
}
|
|
99
|
-
function beginAcpPrompt(
|
|
100
|
-
|
|
112
|
+
function beginAcpPrompt(context, child, turn, sessionId, input) {
|
|
113
|
+
const { acp, agent } = context;
|
|
114
|
+
void agent
|
|
115
|
+
.request(acp.methods.agent.session.prompt, {
|
|
101
116
|
sessionId,
|
|
102
|
-
prompt: [
|
|
103
|
-
|
|
117
|
+
prompt: [
|
|
118
|
+
{ type: "text", text: input.body },
|
|
119
|
+
...input.launchTells.map(({ text }) => ({ type: "text", text })),
|
|
120
|
+
],
|
|
121
|
+
})
|
|
122
|
+
.then((response) => turn.finish(promptResult(response), () => child.endInputAndDrain()), (error) => turn.finish({ kind: "failed", diagnostic: diagnostic(acp, error) }, () => child.endInputAndDrain()));
|
|
104
123
|
void child.exited.then((exit) => turn.finish({
|
|
105
124
|
kind: "failed",
|
|
106
125
|
diagnostic: exit.stderr || `ACP process exited${exit.code === null ? "" : ` with code ${exit.code}`}`,
|
|
@@ -115,7 +134,7 @@ function beginAcpPrompt(agent, child, turn, sessionId, input) {
|
|
|
115
134
|
await agent.notify(acp.methods.agent.session.cancel, { sessionId });
|
|
116
135
|
}
|
|
117
136
|
catch (error) {
|
|
118
|
-
result = { kind: "failed", diagnostic: diagnostic(error) };
|
|
137
|
+
result = { kind: "failed", diagnostic: diagnostic(acp, error) };
|
|
119
138
|
}
|
|
120
139
|
if (!turn.open())
|
|
121
140
|
await child.close(true);
|
|
@@ -131,6 +150,7 @@ function beginAcpPrompt(agent, child, turn, sessionId, input) {
|
|
|
131
150
|
};
|
|
132
151
|
}
|
|
133
152
|
export async function startAcpSession(launch, input, dependencies = {}) {
|
|
153
|
+
const acp = await import("@agentclientprotocol/sdk");
|
|
134
154
|
const signal = input.signal ?? new AbortController().signal;
|
|
135
155
|
signal.throwIfAborted();
|
|
136
156
|
const child = (dependencies.spawnProcess ?? spawnStdioProcess)({
|
|
@@ -144,15 +164,15 @@ export async function startAcpSession(launch, input, dependencies = {}) {
|
|
|
144
164
|
});
|
|
145
165
|
let sessionId;
|
|
146
166
|
let turn;
|
|
147
|
-
const connection = createAcpClient((notification) => {
|
|
167
|
+
const connection = createAcpClient(acp, (notification) => {
|
|
148
168
|
if (notification.sessionId === sessionId)
|
|
149
169
|
turn.update(notification.update);
|
|
150
170
|
}).connect(acp.ndJsonStream(Writable.toWeb(child.input), Readable.toWeb(child.output)));
|
|
151
|
-
turn = createAcpTurn(connection, dependencies.interpretTool);
|
|
171
|
+
turn = createAcpTurn(acp, connection, dependencies.interpretTool);
|
|
152
172
|
try {
|
|
153
|
-
sessionId = await abortable(establishSession(connection.agent, input), signal);
|
|
173
|
+
sessionId = await abortable(establishSession(acp, connection.agent, input, dependencies), signal);
|
|
154
174
|
turn.events.emit({ type: "session", coordinate: { sessionId } });
|
|
155
|
-
const session = beginAcpPrompt(connection.agent, child, turn, sessionId, input);
|
|
175
|
+
const session = beginAcpPrompt({ acp, agent: connection.agent }, child, turn, sessionId, input);
|
|
156
176
|
return { session, agent: connection.agent, sessionId, open: turn.open };
|
|
157
177
|
}
|
|
158
178
|
catch (error) {
|
|
@@ -161,7 +181,7 @@ export async function startAcpSession(launch, input, dependencies = {}) {
|
|
|
161
181
|
await child.close(true);
|
|
162
182
|
}
|
|
163
183
|
catch (cleanup) {
|
|
164
|
-
throw new Error(`${diagnostic(error)}; ACP cleanup failed: ${diagnostic(cleanup)}`, { cause: error });
|
|
184
|
+
throw new Error(`${diagnostic(acp, error)}; ACP cleanup failed: ${diagnostic(acp, cleanup)}`, { cause: error });
|
|
165
185
|
}
|
|
166
186
|
turn.events.end();
|
|
167
187
|
throw error;
|
|
@@ -13,9 +13,7 @@ export function flushAcpEvents(state, boundary = []) {
|
|
|
13
13
|
};
|
|
14
14
|
}
|
|
15
15
|
function appendBlock(state, type, text, messageId) {
|
|
16
|
-
const newAssistantMessage = type === "assistant"
|
|
17
|
-
&& messageId !== undefined
|
|
18
|
-
&& state.assistantMessageId !== messageId;
|
|
16
|
+
const newAssistantMessage = type === "assistant" && messageId !== undefined && state.assistantMessageId !== messageId;
|
|
19
17
|
const flushed = state.open === null || (state.open.type === type && !newAssistantMessage)
|
|
20
18
|
? { events: [], state }
|
|
21
19
|
: flushAcpEvents(state);
|
|
@@ -23,12 +21,8 @@ function appendBlock(state, type, text, messageId) {
|
|
|
23
21
|
events: flushed.events,
|
|
24
22
|
state: {
|
|
25
23
|
...flushed.state,
|
|
26
|
-
answer: type === "assistant"
|
|
27
|
-
|
|
28
|
-
: flushed.state.answer,
|
|
29
|
-
assistantMessageId: type === "assistant" && messageId !== undefined
|
|
30
|
-
? messageId
|
|
31
|
-
: flushed.state.assistantMessageId,
|
|
24
|
+
answer: type === "assistant" ? `${newAssistantMessage ? "" : flushed.state.answer}${text}` : flushed.state.answer,
|
|
25
|
+
assistantMessageId: type === "assistant" && messageId !== undefined ? messageId : flushed.state.assistantMessageId,
|
|
32
26
|
open: { type, text: `${flushed.state.open?.text ?? ""}${text}` },
|
|
33
27
|
},
|
|
34
28
|
};
|
|
@@ -42,9 +36,7 @@ function object(value) {
|
|
|
42
36
|
: undefined;
|
|
43
37
|
}
|
|
44
38
|
function positiveLine(value) {
|
|
45
|
-
return typeof value === "number" && Number.isSafeInteger(value) && value >= 1
|
|
46
|
-
? value
|
|
47
|
-
: undefined;
|
|
39
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 1 ? value : undefined;
|
|
48
40
|
}
|
|
49
41
|
function otherCall(name) {
|
|
50
42
|
return { kind: "other", display: name };
|
|
@@ -84,9 +76,7 @@ function standardCall(update, name) {
|
|
|
84
76
|
const path = nonblank(input?.path);
|
|
85
77
|
const glob = nonblank(input?.glob);
|
|
86
78
|
const scope = input?.scope;
|
|
87
|
-
const searchScope = scope === "content" || scope === "files" || scope === "web"
|
|
88
|
-
? scope
|
|
89
|
-
: undefined;
|
|
79
|
+
const searchScope = scope === "content" || scope === "files" || scope === "web" ? scope : undefined;
|
|
90
80
|
return {
|
|
91
81
|
kind: "search",
|
|
92
82
|
query,
|
|
@@ -115,33 +105,52 @@ export function mapAcpUpdate(update, previous, interpret) {
|
|
|
115
105
|
const text = update.content.type === "text" ? update.content.text : undefined;
|
|
116
106
|
if (text === undefined)
|
|
117
107
|
return flushAcpEvents(previous, [unknownEvent(`${update.sessionUpdate}/${update.content.type}`)]);
|
|
118
|
-
return appendBlock(previous, update.sessionUpdate === "agent_message_chunk" ? "assistant" : "thought", text, update.sessionUpdate === "agent_message_chunk" && update.messageId !== null
|
|
119
|
-
? update.messageId
|
|
120
|
-
: undefined);
|
|
108
|
+
return appendBlock(previous, update.sessionUpdate === "agent_message_chunk" ? "assistant" : "thought", text, update.sessionUpdate === "agent_message_chunk" && update.messageId !== null ? update.messageId : undefined);
|
|
121
109
|
}
|
|
122
|
-
case "user_message_chunk":
|
|
110
|
+
case "user_message_chunk":
|
|
111
|
+
return flushAcpEvents(previous);
|
|
123
112
|
case "tool_call":
|
|
124
113
|
case "tool_call_update": {
|
|
125
114
|
const observed = observeTool(update, previous.tools.get(update.toolCallId), interpret);
|
|
126
115
|
const tools = new Map(previous.tools);
|
|
127
116
|
if (update.status === "completed" || update.status === "failed") {
|
|
128
117
|
tools.delete(update.toolCallId);
|
|
129
|
-
return flushAcpEvents({ ...previous, tools }, [
|
|
118
|
+
return flushAcpEvents({ ...previous, tools }, [
|
|
119
|
+
{
|
|
120
|
+
type: "tool",
|
|
121
|
+
phase: "completed",
|
|
122
|
+
id: update.toolCallId,
|
|
123
|
+
...observed,
|
|
124
|
+
result: { status: update.status === "completed" ? "ok" : "error" },
|
|
125
|
+
},
|
|
126
|
+
]);
|
|
130
127
|
}
|
|
131
128
|
const started = tools.has(update.toolCallId);
|
|
132
129
|
tools.set(update.toolCallId, observed);
|
|
133
130
|
return started
|
|
134
131
|
? flushAcpEvents({ ...previous, tools })
|
|
135
|
-
: flushAcpEvents({ ...previous, tools }, [
|
|
132
|
+
: flushAcpEvents({ ...previous, tools }, [
|
|
133
|
+
{ type: "tool", phase: "started", id: update.toolCallId, ...observed },
|
|
134
|
+
]);
|
|
136
135
|
}
|
|
137
|
-
case "plan":
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
case "
|
|
142
|
-
|
|
136
|
+
case "plan":
|
|
137
|
+
return flushAcpEvents(previous, [
|
|
138
|
+
noteEvent(`Plan updated: ${update.entries.map((entry) => entry.content).join("; ")}`),
|
|
139
|
+
]);
|
|
140
|
+
case "available_commands_update":
|
|
141
|
+
return flushAcpEvents(previous, [noteEvent("ACP commands updated")]);
|
|
142
|
+
case "current_mode_update":
|
|
143
|
+
return flushAcpEvents(previous, [noteEvent("ACP mode updated")]);
|
|
144
|
+
case "config_option_update":
|
|
145
|
+
return flushAcpEvents(previous, [noteEvent("ACP configuration updated")]);
|
|
146
|
+
case "session_info_update":
|
|
147
|
+
return flushAcpEvents(previous, [noteEvent("ACP session metadata updated")]);
|
|
148
|
+
case "usage_update":
|
|
149
|
+
return flushAcpEvents(previous);
|
|
143
150
|
case "plan_update":
|
|
144
|
-
case "plan_removed":
|
|
145
|
-
|
|
151
|
+
case "plan_removed":
|
|
152
|
+
return flushAcpEvents(previous, [unknownEvent(update.sessionUpdate)]);
|
|
153
|
+
default:
|
|
154
|
+
return { events: [unknownEvent(String(update.sessionUpdate))], state: previous };
|
|
146
155
|
}
|
|
147
156
|
}
|
|
@@ -11,18 +11,28 @@ function optionAdmission(options, config) {
|
|
|
11
11
|
if (options.effort !== undefined && config.effortArg === undefined) {
|
|
12
12
|
return { kind: "refused", diagnostic: "ACP provider has no effort argument mapping" };
|
|
13
13
|
}
|
|
14
|
-
if (options.systemPrompt !== undefined && options.systemPrompt.length > 0
|
|
15
|
-
|
|
14
|
+
if (options.systemPrompt !== undefined && options.systemPrompt.length > 0) {
|
|
15
|
+
if (config.systemPromptArg === undefined) {
|
|
16
|
+
return { kind: "refused", diagnostic: "ACP provider has no systemPrompt argument mapping" };
|
|
17
|
+
}
|
|
18
|
+
if (options.systemPromptMode !== undefined && options.systemPromptMode !== (config.systemPromptMode ?? "replace")) {
|
|
19
|
+
return {
|
|
20
|
+
kind: "refused",
|
|
21
|
+
diagnostic: "ACP provider systemPromptMode does not match the configured argument mode",
|
|
22
|
+
};
|
|
23
|
+
}
|
|
16
24
|
}
|
|
17
25
|
return {
|
|
18
26
|
kind: "admitted",
|
|
19
27
|
options,
|
|
20
|
-
...(options.readonly === undefined
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
28
|
+
...(options.readonly === undefined
|
|
29
|
+
? {}
|
|
30
|
+
: {
|
|
31
|
+
readonly: {
|
|
32
|
+
enforcement: "none",
|
|
33
|
+
diagnostic: "ACP cannot remove task-surface mutation capabilities",
|
|
34
|
+
},
|
|
35
|
+
}),
|
|
26
36
|
};
|
|
27
37
|
}
|
|
28
38
|
function argv(execution, config, options) {
|