coding-agent-adapters 0.2.19 → 0.4.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 +98 -0
- package/dist/index.cjs +515 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +129 -9
- package/dist/index.d.ts +129 -9
- package/dist/index.js +504 -2
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -4,6 +4,364 @@ var promises = require('fs/promises');
|
|
|
4
4
|
var path = require('path');
|
|
5
5
|
var ptyManager = require('pty-manager');
|
|
6
6
|
|
|
7
|
+
// src/base-coding-adapter.ts
|
|
8
|
+
|
|
9
|
+
// src/approval-presets.ts
|
|
10
|
+
var TOOL_CATEGORIES = [
|
|
11
|
+
{ category: "file_read", risk: "low", description: "Read files, search, list directories" },
|
|
12
|
+
{ category: "file_write", risk: "medium", description: "Write, edit, and create files" },
|
|
13
|
+
{ category: "shell", risk: "high", description: "Execute shell commands" },
|
|
14
|
+
{ category: "web", risk: "medium", description: "Web search and fetch" },
|
|
15
|
+
{ category: "agent", risk: "medium", description: "Spawn sub-agents, skills, MCP tools" },
|
|
16
|
+
{ category: "planning", risk: "low", description: "Task planning and todo management" },
|
|
17
|
+
{ category: "user_interaction", risk: "low", description: "Ask user questions" }
|
|
18
|
+
];
|
|
19
|
+
var PRESET_DEFINITIONS = [
|
|
20
|
+
{
|
|
21
|
+
preset: "readonly",
|
|
22
|
+
description: "Read-only. Safe for auditing.",
|
|
23
|
+
autoApprove: ["file_read", "planning", "user_interaction"],
|
|
24
|
+
requireApproval: [],
|
|
25
|
+
blocked: ["file_write", "shell", "web", "agent"]
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
preset: "standard",
|
|
29
|
+
description: "Standard dev. Reads + web auto, writes/shell prompt.",
|
|
30
|
+
autoApprove: ["file_read", "planning", "user_interaction", "web"],
|
|
31
|
+
requireApproval: ["file_write", "shell", "agent"],
|
|
32
|
+
blocked: []
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
preset: "permissive",
|
|
36
|
+
description: "File ops auto-approved, shell still prompts.",
|
|
37
|
+
autoApprove: ["file_read", "file_write", "planning", "user_interaction", "web", "agent"],
|
|
38
|
+
requireApproval: ["shell"],
|
|
39
|
+
blocked: []
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
preset: "autonomous",
|
|
43
|
+
description: "Everything auto-approved. Use with sandbox.",
|
|
44
|
+
autoApprove: ["file_read", "file_write", "shell", "web", "agent", "planning", "user_interaction"],
|
|
45
|
+
requireApproval: [],
|
|
46
|
+
blocked: []
|
|
47
|
+
}
|
|
48
|
+
];
|
|
49
|
+
var CLAUDE_TOOL_CATEGORIES = {
|
|
50
|
+
// file_read
|
|
51
|
+
Read: "file_read",
|
|
52
|
+
Grep: "file_read",
|
|
53
|
+
Glob: "file_read",
|
|
54
|
+
LS: "file_read",
|
|
55
|
+
NotebookRead: "file_read",
|
|
56
|
+
// file_write
|
|
57
|
+
Write: "file_write",
|
|
58
|
+
Edit: "file_write",
|
|
59
|
+
MultiEdit: "file_write",
|
|
60
|
+
NotebookEdit: "file_write",
|
|
61
|
+
// shell
|
|
62
|
+
Bash: "shell",
|
|
63
|
+
BashOutput: "shell",
|
|
64
|
+
KillShell: "shell",
|
|
65
|
+
// web
|
|
66
|
+
WebSearch: "web",
|
|
67
|
+
WebFetch: "web",
|
|
68
|
+
// agent
|
|
69
|
+
Task: "agent",
|
|
70
|
+
Skill: "agent",
|
|
71
|
+
// planning
|
|
72
|
+
TodoWrite: "planning",
|
|
73
|
+
// user_interaction
|
|
74
|
+
AskUserQuestion: "user_interaction"
|
|
75
|
+
};
|
|
76
|
+
var GEMINI_TOOL_CATEGORIES = {
|
|
77
|
+
// file_read
|
|
78
|
+
read_file: "file_read",
|
|
79
|
+
read_many_files: "file_read",
|
|
80
|
+
list_directory: "file_read",
|
|
81
|
+
glob: "file_read",
|
|
82
|
+
search_file_content: "file_read",
|
|
83
|
+
// file_write
|
|
84
|
+
write_file: "file_write",
|
|
85
|
+
replace: "file_write",
|
|
86
|
+
// shell
|
|
87
|
+
run_shell_command: "shell",
|
|
88
|
+
// web
|
|
89
|
+
web_fetch: "web",
|
|
90
|
+
google_web_search: "web",
|
|
91
|
+
// agent
|
|
92
|
+
activate_skill: "agent",
|
|
93
|
+
get_internal_docs: "agent",
|
|
94
|
+
// planning
|
|
95
|
+
save_memory: "planning",
|
|
96
|
+
write_todos: "planning",
|
|
97
|
+
// user_interaction
|
|
98
|
+
ask_user: "user_interaction"
|
|
99
|
+
};
|
|
100
|
+
var CODEX_TOOL_CATEGORIES = {
|
|
101
|
+
// shell (codex uses shell for most operations)
|
|
102
|
+
exec_command: "shell",
|
|
103
|
+
write_stdin: "shell",
|
|
104
|
+
shell_command: "shell",
|
|
105
|
+
// file_write
|
|
106
|
+
apply_patch: "file_write",
|
|
107
|
+
// file_read
|
|
108
|
+
grep_files: "file_read",
|
|
109
|
+
read_file: "file_read",
|
|
110
|
+
list_dir: "file_read",
|
|
111
|
+
// web
|
|
112
|
+
web_search: "web",
|
|
113
|
+
view_image: "web",
|
|
114
|
+
// agent
|
|
115
|
+
spawn_agent: "agent",
|
|
116
|
+
send_input: "agent",
|
|
117
|
+
resume_agent: "agent",
|
|
118
|
+
wait: "agent",
|
|
119
|
+
close_agent: "agent",
|
|
120
|
+
// planning
|
|
121
|
+
update_plan: "planning",
|
|
122
|
+
// user_interaction
|
|
123
|
+
request_user_input: "user_interaction"
|
|
124
|
+
};
|
|
125
|
+
var AIDER_COMMAND_CATEGORIES = {
|
|
126
|
+
// file_read
|
|
127
|
+
"/read-only": "file_read",
|
|
128
|
+
"/ls": "file_read",
|
|
129
|
+
"/map": "file_read",
|
|
130
|
+
"/map-refresh": "file_read",
|
|
131
|
+
"/tokens": "file_read",
|
|
132
|
+
"/diff": "file_read",
|
|
133
|
+
"/context": "file_read",
|
|
134
|
+
// file_write
|
|
135
|
+
"/add": "file_write",
|
|
136
|
+
"/drop": "file_write",
|
|
137
|
+
"/edit": "file_write",
|
|
138
|
+
"/code": "file_write",
|
|
139
|
+
"/architect": "file_write",
|
|
140
|
+
"/undo": "file_write",
|
|
141
|
+
// shell
|
|
142
|
+
"/run": "shell",
|
|
143
|
+
"/test": "shell",
|
|
144
|
+
"/lint": "shell",
|
|
145
|
+
"/git": "shell",
|
|
146
|
+
// web
|
|
147
|
+
"/web": "web",
|
|
148
|
+
// planning
|
|
149
|
+
"/ask": "planning",
|
|
150
|
+
// user_interaction
|
|
151
|
+
"/voice": "user_interaction",
|
|
152
|
+
"/help": "user_interaction",
|
|
153
|
+
// config/other
|
|
154
|
+
"/model": "planning",
|
|
155
|
+
"/settings": "planning",
|
|
156
|
+
"/commit": "file_write",
|
|
157
|
+
"/clear": "planning",
|
|
158
|
+
"/reset": "planning"
|
|
159
|
+
};
|
|
160
|
+
function getToolsForCategories(mapping, categories) {
|
|
161
|
+
return Object.entries(mapping).filter(([, cat]) => categories.includes(cat)).map(([tool]) => tool);
|
|
162
|
+
}
|
|
163
|
+
function generateClaudeApprovalConfig(preset) {
|
|
164
|
+
const def = getPresetDefinition(preset);
|
|
165
|
+
const allowTools = getToolsForCategories(CLAUDE_TOOL_CATEGORIES, def.autoApprove);
|
|
166
|
+
const denyTools = getToolsForCategories(CLAUDE_TOOL_CATEGORIES, def.blocked);
|
|
167
|
+
const settings = {
|
|
168
|
+
permissions: {}
|
|
169
|
+
};
|
|
170
|
+
const permissions = settings.permissions;
|
|
171
|
+
if (allowTools.length > 0) {
|
|
172
|
+
permissions.allow = allowTools;
|
|
173
|
+
}
|
|
174
|
+
if (denyTools.length > 0) {
|
|
175
|
+
permissions.deny = denyTools;
|
|
176
|
+
}
|
|
177
|
+
if (preset === "autonomous") {
|
|
178
|
+
settings.sandbox = {
|
|
179
|
+
enabled: true,
|
|
180
|
+
autoAllowBashIfSandboxed: true
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
const cliFlags = [];
|
|
184
|
+
if (preset === "autonomous") {
|
|
185
|
+
const allTools = Object.keys(CLAUDE_TOOL_CATEGORIES);
|
|
186
|
+
cliFlags.push("--tools", allTools.join(","));
|
|
187
|
+
}
|
|
188
|
+
return {
|
|
189
|
+
preset,
|
|
190
|
+
cliFlags,
|
|
191
|
+
workspaceFiles: [
|
|
192
|
+
{
|
|
193
|
+
relativePath: ".claude/settings.json",
|
|
194
|
+
content: JSON.stringify(settings, null, 2),
|
|
195
|
+
format: "json"
|
|
196
|
+
}
|
|
197
|
+
],
|
|
198
|
+
envVars: {},
|
|
199
|
+
summary: `Claude Code: ${def.description}`
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
function generateGeminiApprovalConfig(preset) {
|
|
203
|
+
const def = getPresetDefinition(preset);
|
|
204
|
+
const cliFlags = [];
|
|
205
|
+
const allowedTools = getToolsForCategories(GEMINI_TOOL_CATEGORIES, def.autoApprove);
|
|
206
|
+
const excludeTools = getToolsForCategories(GEMINI_TOOL_CATEGORIES, def.blocked);
|
|
207
|
+
let approvalMode;
|
|
208
|
+
switch (preset) {
|
|
209
|
+
case "readonly":
|
|
210
|
+
approvalMode = "plan";
|
|
211
|
+
cliFlags.push("--approval-mode", "plan");
|
|
212
|
+
break;
|
|
213
|
+
case "standard":
|
|
214
|
+
approvalMode = "default";
|
|
215
|
+
break;
|
|
216
|
+
case "permissive":
|
|
217
|
+
approvalMode = "auto_edit";
|
|
218
|
+
cliFlags.push("--approval-mode", "auto_edit");
|
|
219
|
+
break;
|
|
220
|
+
case "autonomous":
|
|
221
|
+
approvalMode = "auto_edit";
|
|
222
|
+
cliFlags.push("-y");
|
|
223
|
+
break;
|
|
224
|
+
}
|
|
225
|
+
const settings = {
|
|
226
|
+
general: {
|
|
227
|
+
defaultApprovalMode: approvalMode
|
|
228
|
+
},
|
|
229
|
+
tools: {}
|
|
230
|
+
};
|
|
231
|
+
const tools = settings.tools;
|
|
232
|
+
if (allowedTools.length > 0) {
|
|
233
|
+
tools.allowed = allowedTools;
|
|
234
|
+
}
|
|
235
|
+
if (excludeTools.length > 0) {
|
|
236
|
+
tools.exclude = excludeTools;
|
|
237
|
+
}
|
|
238
|
+
return {
|
|
239
|
+
preset,
|
|
240
|
+
cliFlags,
|
|
241
|
+
workspaceFiles: [
|
|
242
|
+
{
|
|
243
|
+
relativePath: ".gemini/settings.json",
|
|
244
|
+
content: JSON.stringify(settings, null, 2),
|
|
245
|
+
format: "json"
|
|
246
|
+
}
|
|
247
|
+
],
|
|
248
|
+
envVars: {},
|
|
249
|
+
summary: `Gemini CLI: ${def.description}`
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
function generateCodexApprovalConfig(preset) {
|
|
253
|
+
const cliFlags = [];
|
|
254
|
+
let approvalPolicy;
|
|
255
|
+
let sandboxMode;
|
|
256
|
+
let webSearch;
|
|
257
|
+
switch (preset) {
|
|
258
|
+
case "readonly":
|
|
259
|
+
approvalPolicy = "untrusted";
|
|
260
|
+
sandboxMode = "workspace-read";
|
|
261
|
+
webSearch = false;
|
|
262
|
+
cliFlags.push("--sandbox", "workspace-read", "-a", "untrusted");
|
|
263
|
+
break;
|
|
264
|
+
case "standard":
|
|
265
|
+
approvalPolicy = "on-failure";
|
|
266
|
+
sandboxMode = "workspace-write";
|
|
267
|
+
webSearch = true;
|
|
268
|
+
cliFlags.push("--sandbox", "workspace-write");
|
|
269
|
+
break;
|
|
270
|
+
case "permissive":
|
|
271
|
+
approvalPolicy = "on-request";
|
|
272
|
+
sandboxMode = "workspace-write";
|
|
273
|
+
webSearch = true;
|
|
274
|
+
cliFlags.push("-a", "on-request");
|
|
275
|
+
break;
|
|
276
|
+
case "autonomous":
|
|
277
|
+
approvalPolicy = "never";
|
|
278
|
+
sandboxMode = "workspace-write";
|
|
279
|
+
webSearch = true;
|
|
280
|
+
cliFlags.push("--full-auto");
|
|
281
|
+
break;
|
|
282
|
+
}
|
|
283
|
+
const config = {
|
|
284
|
+
approval_policy: approvalPolicy,
|
|
285
|
+
sandbox_mode: sandboxMode,
|
|
286
|
+
tools: {
|
|
287
|
+
web_search: webSearch
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
return {
|
|
291
|
+
preset,
|
|
292
|
+
cliFlags,
|
|
293
|
+
workspaceFiles: [
|
|
294
|
+
{
|
|
295
|
+
relativePath: ".codex/config.json",
|
|
296
|
+
content: JSON.stringify(config, null, 2),
|
|
297
|
+
format: "json"
|
|
298
|
+
}
|
|
299
|
+
],
|
|
300
|
+
envVars: {},
|
|
301
|
+
summary: `Codex: ${getPresetDefinition(preset).description}`
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
function generateAiderApprovalConfig(preset) {
|
|
305
|
+
const def = getPresetDefinition(preset);
|
|
306
|
+
const cliFlags = [];
|
|
307
|
+
const lines = [];
|
|
308
|
+
switch (preset) {
|
|
309
|
+
case "readonly":
|
|
310
|
+
lines.push("yes-always: false");
|
|
311
|
+
lines.push("no-auto-commits: true");
|
|
312
|
+
cliFlags.push("--no-auto-commits");
|
|
313
|
+
break;
|
|
314
|
+
case "standard":
|
|
315
|
+
lines.push("yes-always: false");
|
|
316
|
+
break;
|
|
317
|
+
case "permissive":
|
|
318
|
+
lines.push("yes-always: true");
|
|
319
|
+
cliFlags.push("--yes-always");
|
|
320
|
+
break;
|
|
321
|
+
case "autonomous":
|
|
322
|
+
lines.push("yes-always: true");
|
|
323
|
+
cliFlags.push("--yes-always");
|
|
324
|
+
break;
|
|
325
|
+
}
|
|
326
|
+
return {
|
|
327
|
+
preset,
|
|
328
|
+
cliFlags,
|
|
329
|
+
workspaceFiles: [
|
|
330
|
+
{
|
|
331
|
+
relativePath: ".aider.conf.yml",
|
|
332
|
+
content: lines.join("\n") + "\n",
|
|
333
|
+
format: "yaml"
|
|
334
|
+
}
|
|
335
|
+
],
|
|
336
|
+
envVars: {},
|
|
337
|
+
summary: `Aider: ${def.description}`
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
function generateApprovalConfig(adapterType, preset) {
|
|
341
|
+
switch (adapterType) {
|
|
342
|
+
case "claude":
|
|
343
|
+
return generateClaudeApprovalConfig(preset);
|
|
344
|
+
case "gemini":
|
|
345
|
+
return generateGeminiApprovalConfig(preset);
|
|
346
|
+
case "codex":
|
|
347
|
+
return generateCodexApprovalConfig(preset);
|
|
348
|
+
case "aider":
|
|
349
|
+
return generateAiderApprovalConfig(preset);
|
|
350
|
+
default:
|
|
351
|
+
throw new Error(`Unknown adapter type: ${adapterType}`);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
function listPresets() {
|
|
355
|
+
return [...PRESET_DEFINITIONS];
|
|
356
|
+
}
|
|
357
|
+
function getPresetDefinition(preset) {
|
|
358
|
+
const def = PRESET_DEFINITIONS.find((d) => d.preset === preset);
|
|
359
|
+
if (!def) {
|
|
360
|
+
throw new Error(`Unknown preset: ${preset}`);
|
|
361
|
+
}
|
|
362
|
+
return def;
|
|
363
|
+
}
|
|
364
|
+
|
|
7
365
|
// src/base-coding-adapter.ts
|
|
8
366
|
var BaseCodingAdapter = class extends ptyManager.BaseCLIAdapter {
|
|
9
367
|
/**
|
|
@@ -114,6 +472,40 @@ Docs: ${this.installation.docsUrl}`
|
|
|
114
472
|
content = content.trim();
|
|
115
473
|
return content;
|
|
116
474
|
}
|
|
475
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
476
|
+
// Approval Presets
|
|
477
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
478
|
+
/**
|
|
479
|
+
* Extract the approval preset from a spawn config, if set.
|
|
480
|
+
*/
|
|
481
|
+
getApprovalPreset(config) {
|
|
482
|
+
const adapterConfig = config.adapterConfig;
|
|
483
|
+
return adapterConfig?.approvalPreset;
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* Generate the approval config for this adapter, if a preset is set.
|
|
487
|
+
*/
|
|
488
|
+
getApprovalConfig(config) {
|
|
489
|
+
const preset = this.getApprovalPreset(config);
|
|
490
|
+
if (!preset) return null;
|
|
491
|
+
return generateApprovalConfig(this.adapterType, preset);
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* Write approval config files to a workspace directory.
|
|
495
|
+
* Returns the list of files written (absolute paths).
|
|
496
|
+
*/
|
|
497
|
+
async writeApprovalConfig(workspacePath, config) {
|
|
498
|
+
const approvalConfig = this.getApprovalConfig(config);
|
|
499
|
+
if (!approvalConfig) return [];
|
|
500
|
+
const written = [];
|
|
501
|
+
for (const file of approvalConfig.workspaceFiles) {
|
|
502
|
+
const fullPath = path.join(workspacePath, file.relativePath);
|
|
503
|
+
await promises.mkdir(path.dirname(fullPath), { recursive: true });
|
|
504
|
+
await promises.writeFile(fullPath, file.content, "utf-8");
|
|
505
|
+
written.push(fullPath);
|
|
506
|
+
}
|
|
507
|
+
return written;
|
|
508
|
+
}
|
|
117
509
|
/**
|
|
118
510
|
* Write content to this agent's memory file in a workspace.
|
|
119
511
|
* Creates parent directories as needed.
|
|
@@ -248,6 +640,10 @@ var ClaudeAdapter = class extends BaseCodingAdapter {
|
|
|
248
640
|
args.push("--cwd", config.workdir);
|
|
249
641
|
}
|
|
250
642
|
}
|
|
643
|
+
const approvalConfig = this.getApprovalConfig(config);
|
|
644
|
+
if (approvalConfig) {
|
|
645
|
+
args.push(...approvalConfig.cliFlags);
|
|
646
|
+
}
|
|
251
647
|
return args;
|
|
252
648
|
}
|
|
253
649
|
getEnv(config) {
|
|
@@ -353,6 +749,29 @@ var ClaudeAdapter = class extends BaseCodingAdapter {
|
|
|
353
749
|
}
|
|
354
750
|
return super.detectBlockingPrompt(output);
|
|
355
751
|
}
|
|
752
|
+
/**
|
|
753
|
+
* Detect task completion for Claude Code.
|
|
754
|
+
*
|
|
755
|
+
* High-confidence pattern: turn duration summary + idle prompt.
|
|
756
|
+
* Claude Code shows "<Verb> for Xm Ys" (e.g. "Cooked for 3m 12s")
|
|
757
|
+
* when a turn completes, followed by the ❯ input prompt.
|
|
758
|
+
*
|
|
759
|
+
* Patterns from: AGENT_LOADING_STATUS_PATTERNS.json
|
|
760
|
+
* - claude_completed_turn_duration
|
|
761
|
+
* - claude_completed_turn_duration_custom_verb
|
|
762
|
+
*/
|
|
763
|
+
detectTaskComplete(output) {
|
|
764
|
+
const stripped = this.stripAnsi(output);
|
|
765
|
+
const hasDuration = /[A-Z][A-Za-z' -]{2,40}\s+for\s+\d+(?:h\s+\d{1,2}m\s+\d{1,2}s|m\s+\d{1,2}s|s)/.test(stripped);
|
|
766
|
+
const hasIdlePrompt = /❯\s*$/.test(stripped);
|
|
767
|
+
if (hasDuration && hasIdlePrompt) {
|
|
768
|
+
return true;
|
|
769
|
+
}
|
|
770
|
+
if (hasIdlePrompt && stripped.includes("for shortcuts")) {
|
|
771
|
+
return true;
|
|
772
|
+
}
|
|
773
|
+
return false;
|
|
774
|
+
}
|
|
356
775
|
detectReady(output) {
|
|
357
776
|
const stripped = this.stripAnsi(output);
|
|
358
777
|
if (/trust.*directory|do you want to|needs? your permission/i.test(stripped)) {
|
|
@@ -480,6 +899,10 @@ var GeminiAdapter = class extends BaseCodingAdapter {
|
|
|
480
899
|
args.push("--cwd", config.workdir);
|
|
481
900
|
}
|
|
482
901
|
}
|
|
902
|
+
const approvalConfig = this.getApprovalConfig(config);
|
|
903
|
+
if (approvalConfig) {
|
|
904
|
+
args.push(...approvalConfig.cliFlags);
|
|
905
|
+
}
|
|
483
906
|
return args;
|
|
484
907
|
}
|
|
485
908
|
getEnv(config) {
|
|
@@ -606,6 +1029,26 @@ var GeminiAdapter = class extends BaseCodingAdapter {
|
|
|
606
1029
|
}
|
|
607
1030
|
return super.detectBlockingPrompt(output);
|
|
608
1031
|
}
|
|
1032
|
+
/**
|
|
1033
|
+
* Detect task completion for Gemini CLI.
|
|
1034
|
+
*
|
|
1035
|
+
* High-confidence patterns:
|
|
1036
|
+
* - "◇ Ready" window title signal (OSC sequence, may survive ANSI stripping)
|
|
1037
|
+
* - "Type your message" composer placeholder after agent output
|
|
1038
|
+
*
|
|
1039
|
+
* Patterns from: AGENT_LOADING_STATUS_PATTERNS.json
|
|
1040
|
+
* - gemini_ready_title
|
|
1041
|
+
*/
|
|
1042
|
+
detectTaskComplete(output) {
|
|
1043
|
+
const stripped = this.stripAnsi(output);
|
|
1044
|
+
if (/◇\s+Ready/.test(stripped)) {
|
|
1045
|
+
return true;
|
|
1046
|
+
}
|
|
1047
|
+
if (/type.?your.?message/i.test(stripped)) {
|
|
1048
|
+
return true;
|
|
1049
|
+
}
|
|
1050
|
+
return false;
|
|
1051
|
+
}
|
|
609
1052
|
detectReady(output) {
|
|
610
1053
|
const stripped = this.stripAnsi(output);
|
|
611
1054
|
if (/type.?your.?message/i.test(stripped)) {
|
|
@@ -784,6 +1227,10 @@ var CodexAdapter = class extends BaseCodingAdapter {
|
|
|
784
1227
|
args.push("--cwd", config.workdir);
|
|
785
1228
|
}
|
|
786
1229
|
}
|
|
1230
|
+
const approvalConfig = this.getApprovalConfig(config);
|
|
1231
|
+
if (approvalConfig) {
|
|
1232
|
+
args.push(...approvalConfig.cliFlags);
|
|
1233
|
+
}
|
|
787
1234
|
return args;
|
|
788
1235
|
}
|
|
789
1236
|
getEnv(config) {
|
|
@@ -912,6 +1359,32 @@ var CodexAdapter = class extends BaseCodingAdapter {
|
|
|
912
1359
|
}
|
|
913
1360
|
return super.detectBlockingPrompt(output);
|
|
914
1361
|
}
|
|
1362
|
+
/**
|
|
1363
|
+
* Detect task completion for Codex CLI.
|
|
1364
|
+
*
|
|
1365
|
+
* High-confidence patterns:
|
|
1366
|
+
* - "Worked for Xm Ys" separator after work-heavy turns
|
|
1367
|
+
* - "› Ask Codex to do anything" ready prompt
|
|
1368
|
+
*
|
|
1369
|
+
* Patterns from: AGENT_LOADING_STATUS_PATTERNS.json
|
|
1370
|
+
* - codex_completed_worked_for_separator
|
|
1371
|
+
* - codex_ready_prompt
|
|
1372
|
+
*/
|
|
1373
|
+
detectTaskComplete(output) {
|
|
1374
|
+
const stripped = this.stripAnsi(output);
|
|
1375
|
+
const hasWorkedFor = /Worked\s+for\s+\d+(?:h\s+\d{2}m\s+\d{2}s|m\s+\d{2}s|s)/.test(stripped);
|
|
1376
|
+
const hasReadyPrompt = /›\s+Ask\s+Codex\s+to\s+do\s+anything/.test(stripped);
|
|
1377
|
+
if (hasWorkedFor && hasReadyPrompt) {
|
|
1378
|
+
return true;
|
|
1379
|
+
}
|
|
1380
|
+
if (hasReadyPrompt) {
|
|
1381
|
+
return true;
|
|
1382
|
+
}
|
|
1383
|
+
if (hasWorkedFor && /›\s+/m.test(stripped)) {
|
|
1384
|
+
return true;
|
|
1385
|
+
}
|
|
1386
|
+
return false;
|
|
1387
|
+
}
|
|
915
1388
|
detectReady(output) {
|
|
916
1389
|
const stripped = this.stripAnsi(output);
|
|
917
1390
|
if (/do.?you.?trust.?the.?contents/i.test(stripped) || /sign.?in.?with.?chatgpt/i.test(stripped) || /update.?available/i.test(stripped) || /enable.?full.?access/i.test(stripped) || /choose.?working.?directory/i.test(stripped)) {
|
|
@@ -1219,6 +1692,10 @@ var AiderAdapter = class extends BaseCodingAdapter {
|
|
|
1219
1692
|
if (credentials.anthropicKey) args.push("--api-key", `anthropic=${credentials.anthropicKey}`);
|
|
1220
1693
|
if (credentials.openaiKey) args.push("--api-key", `openai=${credentials.openaiKey}`);
|
|
1221
1694
|
if (credentials.googleKey) args.push("--api-key", `gemini=${credentials.googleKey}`);
|
|
1695
|
+
const approvalConfig = this.getApprovalConfig(config);
|
|
1696
|
+
if (approvalConfig) {
|
|
1697
|
+
args.push(...approvalConfig.cliFlags);
|
|
1698
|
+
}
|
|
1222
1699
|
return args;
|
|
1223
1700
|
}
|
|
1224
1701
|
getEnv(config) {
|
|
@@ -1312,6 +1789,31 @@ var AiderAdapter = class extends BaseCodingAdapter {
|
|
|
1312
1789
|
}
|
|
1313
1790
|
return super.detectBlockingPrompt(output);
|
|
1314
1791
|
}
|
|
1792
|
+
/**
|
|
1793
|
+
* Detect task completion for Aider.
|
|
1794
|
+
*
|
|
1795
|
+
* High-confidence patterns:
|
|
1796
|
+
* - "Aider is waiting for your input" notification (bell message)
|
|
1797
|
+
* - Edit-format mode prompts (ask>, code>, architect>) after output
|
|
1798
|
+
*
|
|
1799
|
+
* Patterns from: AGENT_LOADING_STATUS_PATTERNS.json
|
|
1800
|
+
* - aider_completed_llm_response_ready
|
|
1801
|
+
*/
|
|
1802
|
+
detectTaskComplete(output) {
|
|
1803
|
+
const stripped = this.stripAnsi(output);
|
|
1804
|
+
if (/Aider\s+is\s+waiting\s+for\s+your\s+input/.test(stripped)) {
|
|
1805
|
+
return true;
|
|
1806
|
+
}
|
|
1807
|
+
const hasPrompt = /(?:ask|code|architect)(?:\s+multi)?>\s*$/m.test(stripped);
|
|
1808
|
+
if (hasPrompt) {
|
|
1809
|
+
const hasEditMarkers = /Applied edit to|Commit [a-f0-9]+|wrote to|Updated/i.test(stripped);
|
|
1810
|
+
const hasTokenUsage = /Tokens:|Cost:/i.test(stripped);
|
|
1811
|
+
if (hasEditMarkers || hasTokenUsage) {
|
|
1812
|
+
return true;
|
|
1813
|
+
}
|
|
1814
|
+
}
|
|
1815
|
+
return false;
|
|
1816
|
+
}
|
|
1315
1817
|
detectReady(output) {
|
|
1316
1818
|
const stripped = this.stripAnsi(output);
|
|
1317
1819
|
if (/login to openrouter/i.test(stripped) || /open this url in your browser/i.test(stripped) || /waiting up to 5 minutes/i.test(stripped)) {
|
|
@@ -1575,18 +2077,31 @@ async function printMissingAdapters(types) {
|
|
|
1575
2077
|
}
|
|
1576
2078
|
|
|
1577
2079
|
exports.ADAPTER_TYPES = ADAPTER_TYPES;
|
|
2080
|
+
exports.AIDER_COMMAND_CATEGORIES = AIDER_COMMAND_CATEGORIES;
|
|
1578
2081
|
exports.AiderAdapter = AiderAdapter;
|
|
1579
2082
|
exports.BaseCodingAdapter = BaseCodingAdapter;
|
|
2083
|
+
exports.CLAUDE_TOOL_CATEGORIES = CLAUDE_TOOL_CATEGORIES;
|
|
2084
|
+
exports.CODEX_TOOL_CATEGORIES = CODEX_TOOL_CATEGORIES;
|
|
1580
2085
|
exports.ClaudeAdapter = ClaudeAdapter;
|
|
1581
2086
|
exports.CodexAdapter = CodexAdapter;
|
|
2087
|
+
exports.GEMINI_TOOL_CATEGORIES = GEMINI_TOOL_CATEGORIES;
|
|
1582
2088
|
exports.GeminiAdapter = GeminiAdapter;
|
|
2089
|
+
exports.PRESET_DEFINITIONS = PRESET_DEFINITIONS;
|
|
2090
|
+
exports.TOOL_CATEGORIES = TOOL_CATEGORIES;
|
|
1583
2091
|
exports.checkAdapters = checkAdapters;
|
|
1584
2092
|
exports.checkAllAdapters = checkAllAdapters;
|
|
1585
2093
|
exports.clearPatternCache = clearPatternCache;
|
|
1586
2094
|
exports.createAdapter = createAdapter;
|
|
1587
2095
|
exports.createAllAdapters = createAllAdapters;
|
|
2096
|
+
exports.generateAiderApprovalConfig = generateAiderApprovalConfig;
|
|
2097
|
+
exports.generateApprovalConfig = generateApprovalConfig;
|
|
2098
|
+
exports.generateClaudeApprovalConfig = generateClaudeApprovalConfig;
|
|
2099
|
+
exports.generateCodexApprovalConfig = generateCodexApprovalConfig;
|
|
2100
|
+
exports.generateGeminiApprovalConfig = generateGeminiApprovalConfig;
|
|
1588
2101
|
exports.getBaselinePatterns = getBaselinePatterns;
|
|
2102
|
+
exports.getPresetDefinition = getPresetDefinition;
|
|
1589
2103
|
exports.hasDynamicPatterns = hasDynamicPatterns;
|
|
2104
|
+
exports.listPresets = listPresets;
|
|
1590
2105
|
exports.loadPatterns = loadPatterns;
|
|
1591
2106
|
exports.loadPatternsSync = loadPatternsSync;
|
|
1592
2107
|
exports.preloadAllPatterns = preloadAllPatterns;
|