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