coding-agent-adapters 0.2.18 → 0.3.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 CHANGED
@@ -161,6 +161,134 @@ aider.getRecommendedModels({ googleKey: 'AIza...' });
161
161
  // { powerful: 'gemini/gemini-3-pro', fast: 'gemini/gemini-3-flash' }
162
162
  ```
163
163
 
164
+ ## Workspace Files & Memory
165
+
166
+ Each coding agent CLI has its own convention for project-level memory files (instructions the agent reads on startup) and config files. Adapters expose this knowledge so orchestration systems can write context to the correct files before spawning an agent.
167
+
168
+ ### Discovering Workspace Files
169
+
170
+ ```typescript
171
+ import { ClaudeAdapter, AiderAdapter } from 'coding-agent-adapters';
172
+
173
+ const claude = new ClaudeAdapter();
174
+ claude.getWorkspaceFiles();
175
+ // [
176
+ // { relativePath: 'CLAUDE.md', type: 'memory', autoLoaded: true, format: 'markdown', ... },
177
+ // { relativePath: '.claude/settings.json', type: 'config', autoLoaded: true, format: 'json', ... },
178
+ // { relativePath: '.claude/commands', type: 'config', autoLoaded: false, format: 'markdown', ... },
179
+ // ]
180
+
181
+ claude.memoryFilePath; // 'CLAUDE.md'
182
+
183
+ const aider = new AiderAdapter();
184
+ aider.memoryFilePath; // '.aider.conventions.md'
185
+ ```
186
+
187
+ ### Per-Adapter File Mappings
188
+
189
+ | Adapter | Memory File | Config | Other |
190
+ |---------|------------|--------|-------|
191
+ | Claude | `CLAUDE.md` | `.claude/settings.json` | `.claude/commands` |
192
+ | Gemini | `GEMINI.md` | `.gemini/settings.json` | `.gemini/styles` |
193
+ | Codex | `AGENTS.md` | `.codex/config.json` | `codex.md` |
194
+ | Aider | `.aider.conventions.md` | `.aider.conf.yml` | `.aiderignore` |
195
+
196
+ ### Writing Memory Files
197
+
198
+ Use `writeMemoryFile()` to write instructions into a workspace before spawning an agent. Parent directories are created automatically.
199
+
200
+ ```typescript
201
+ const adapter = new ClaudeAdapter();
202
+
203
+ // Write to the adapter's default memory file (CLAUDE.md)
204
+ await adapter.writeMemoryFile('/path/to/workspace', `# Project Context
205
+ This is a TypeScript monorepo using pnpm workspaces.
206
+ Always run tests before committing.
207
+ `);
208
+
209
+ // Append to an existing memory file
210
+ await adapter.writeMemoryFile('/path/to/workspace', '\n## Additional Rules\nUse snake_case.\n', {
211
+ append: true,
212
+ });
213
+
214
+ // Write to a custom file (e.g., template-specific context for sub-agents)
215
+ await adapter.writeMemoryFile('/path/to/workspace', '# Task-Specific Context\n...', {
216
+ fileName: 'TASK_CONTEXT.md',
217
+ });
218
+ ```
219
+
220
+ ## Approval Presets
221
+
222
+ Each coding agent CLI has its own config format for controlling tool permissions. The approval preset system provides 4 named levels that translate to the correct per-CLI config files and CLI flags.
223
+
224
+ ### Preset Levels
225
+
226
+ | Preset | Description | Auto-approve | Require approval | Blocked |
227
+ |--------|-------------|-------------|-----------------|---------|
228
+ | `readonly` | Read-only. Safe for auditing. | file_read, planning, user_interaction | — | file_write, shell, web, agent |
229
+ | `standard` | Standard dev. Reads + web auto, writes/shell prompt. | file_read, planning, user_interaction, web | file_write, shell, agent | — |
230
+ | `permissive` | File ops auto-approved, shell still prompts. | file_read, file_write, planning, user_interaction, web, agent | shell | — |
231
+ | `autonomous` | Everything auto-approved. Use with sandbox. | all categories | — | — |
232
+
233
+ ### Generating Configs
234
+
235
+ ```typescript
236
+ import { generateApprovalConfig, listPresets, getPresetDefinition } from 'coding-agent-adapters';
237
+
238
+ // List all available presets
239
+ const presets = listPresets();
240
+
241
+ // Generate CLI-specific config for a preset
242
+ const config = generateApprovalConfig('claude', 'permissive');
243
+ // {
244
+ // preset: 'permissive',
245
+ // cliFlags: [],
246
+ // workspaceFiles: [{ relativePath: '.claude/settings.json', content: '...', format: 'json' }],
247
+ // envVars: {},
248
+ // summary: 'Claude Code: File ops auto-approved, shell still prompts.',
249
+ // }
250
+
251
+ // Each CLI gets its own config format
252
+ generateApprovalConfig('gemini', 'readonly'); // → .gemini/settings.json + --approval-mode plan
253
+ generateApprovalConfig('codex', 'autonomous'); // → .codex/config.json + --full-auto
254
+ generateApprovalConfig('aider', 'permissive'); // → .aider.conf.yml + --yes-always
255
+ ```
256
+
257
+ ### Using Presets with Adapters
258
+
259
+ When `approvalPreset` is set in `adapterConfig`, the adapter's `getArgs()` automatically appends the correct CLI flags:
260
+
261
+ ```typescript
262
+ const session = await manager.spawn({
263
+ name: 'sandboxed-agent',
264
+ type: 'claude',
265
+ workdir: '/path/to/project',
266
+ adapterConfig: {
267
+ anthropicKey: process.env.ANTHROPIC_API_KEY,
268
+ approvalPreset: 'autonomous',
269
+ },
270
+ });
271
+ ```
272
+
273
+ You can also write the config files to a workspace manually using `writeApprovalConfig()`:
274
+
275
+ ```typescript
276
+ const adapter = new ClaudeAdapter();
277
+ const writtenFiles = await adapter.writeApprovalConfig('/path/to/workspace', {
278
+ adapterConfig: { approvalPreset: 'permissive' },
279
+ });
280
+ // writtenFiles: ['/path/to/workspace/.claude/settings.json']
281
+ ```
282
+
283
+ ### Per-CLI Output
284
+
285
+ | CLI | Config File | Key Controls |
286
+ |-----|------------|--------------|
287
+ | Claude Code | `.claude/settings.json` | `permissions.allow`, `permissions.deny`, `sandbox.*` |
288
+ | Gemini CLI | `.gemini/settings.json` | `general.defaultApprovalMode`, `tools.allowed`, `tools.exclude` |
289
+ | Codex | `.codex/config.json` | `approval_policy`, `sandbox_mode`, `tools.web_search` |
290
+ | Aider | `.aider.conf.yml` | `yes-always`, `no-auto-commits` |
291
+
164
292
  ## Preflight Check
165
293
 
166
294
  Before spawning agents, check if the required CLIs are installed:
@@ -218,12 +346,18 @@ Extend `BaseCodingAdapter` to create adapters for other coding CLIs:
218
346
 
219
347
  ```typescript
220
348
  import { BaseCodingAdapter } from 'coding-agent-adapters';
349
+ import type { AgentFileDescriptor, InstallationInfo, ModelRecommendations } from 'coding-agent-adapters';
221
350
  import type { SpawnConfig, ParsedOutput, LoginDetection, AutoResponseRule } from 'pty-manager';
222
351
 
223
352
  export class CursorAdapter extends BaseCodingAdapter {
224
353
  readonly adapterType = 'cursor';
225
354
  readonly displayName = 'Cursor';
226
355
 
356
+ readonly installation: InstallationInfo = {
357
+ command: 'npm install -g cursor-cli',
358
+ docsUrl: 'https://cursor.sh/docs',
359
+ };
360
+
227
361
  // Set to false if the CLI uses text prompts instead of TUI menus
228
362
  override readonly usesTuiMenus = false;
229
363
 
@@ -231,6 +365,16 @@ export class CursorAdapter extends BaseCodingAdapter {
231
365
  { pattern: /accept terms/i, type: 'tos', response: 'y', responseType: 'text', description: 'Accept TOS', safe: true, once: true },
232
366
  ];
233
367
 
368
+ getWorkspaceFiles(): AgentFileDescriptor[] {
369
+ return [
370
+ { relativePath: '.cursor/rules', description: 'Project rules', autoLoaded: true, type: 'memory', format: 'markdown' },
371
+ ];
372
+ }
373
+
374
+ getRecommendedModels(): ModelRecommendations {
375
+ return { powerful: 'claude-sonnet-4', fast: 'gpt-4o-mini' };
376
+ }
377
+
234
378
  getCommand(): string { return 'cursor'; }
235
379
  getArgs(config: SpawnConfig): string[] { return ['--cli']; }
236
380
  getEnv(config: SpawnConfig): Record<string, string> { return {}; }
package/dist/index.cjs CHANGED
@@ -4,6 +4,362 @@ 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
+ // 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
+
7
363
  // src/base-coding-adapter.ts
8
364
  var BaseCodingAdapter = class extends ptyManager.BaseCLIAdapter {
9
365
  /**
@@ -114,6 +470,40 @@ Docs: ${this.installation.docsUrl}`
114
470
  content = content.trim();
115
471
  return content;
116
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 = path.join(workspacePath, file.relativePath);
501
+ await promises.mkdir(path.dirname(fullPath), { recursive: true });
502
+ await promises.writeFile(fullPath, file.content, "utf-8");
503
+ written.push(fullPath);
504
+ }
505
+ return written;
506
+ }
117
507
  /**
118
508
  * Write content to this agent's memory file in a workspace.
119
509
  * Creates parent directories as needed.
@@ -248,6 +638,10 @@ var ClaudeAdapter = class extends BaseCodingAdapter {
248
638
  args.push("--cwd", config.workdir);
249
639
  }
250
640
  }
641
+ const approvalConfig = this.getApprovalConfig(config);
642
+ if (approvalConfig) {
643
+ args.push(...approvalConfig.cliFlags);
644
+ }
251
645
  return args;
252
646
  }
253
647
  getEnv(config) {
@@ -480,6 +874,10 @@ var GeminiAdapter = class extends BaseCodingAdapter {
480
874
  args.push("--cwd", config.workdir);
481
875
  }
482
876
  }
877
+ const approvalConfig = this.getApprovalConfig(config);
878
+ if (approvalConfig) {
879
+ args.push(...approvalConfig.cliFlags);
880
+ }
483
881
  return args;
484
882
  }
485
883
  getEnv(config) {
@@ -784,6 +1182,10 @@ var CodexAdapter = class extends BaseCodingAdapter {
784
1182
  args.push("--cwd", config.workdir);
785
1183
  }
786
1184
  }
1185
+ const approvalConfig = this.getApprovalConfig(config);
1186
+ if (approvalConfig) {
1187
+ args.push(...approvalConfig.cliFlags);
1188
+ }
787
1189
  return args;
788
1190
  }
789
1191
  getEnv(config) {
@@ -1219,6 +1621,10 @@ var AiderAdapter = class extends BaseCodingAdapter {
1219
1621
  if (credentials.anthropicKey) args.push("--api-key", `anthropic=${credentials.anthropicKey}`);
1220
1622
  if (credentials.openaiKey) args.push("--api-key", `openai=${credentials.openaiKey}`);
1221
1623
  if (credentials.googleKey) args.push("--api-key", `gemini=${credentials.googleKey}`);
1624
+ const approvalConfig = this.getApprovalConfig(config);
1625
+ if (approvalConfig) {
1626
+ args.push(...approvalConfig.cliFlags);
1627
+ }
1222
1628
  return args;
1223
1629
  }
1224
1630
  getEnv(config) {
@@ -1575,18 +1981,31 @@ async function printMissingAdapters(types) {
1575
1981
  }
1576
1982
 
1577
1983
  exports.ADAPTER_TYPES = ADAPTER_TYPES;
1984
+ exports.AIDER_COMMAND_CATEGORIES = AIDER_COMMAND_CATEGORIES;
1578
1985
  exports.AiderAdapter = AiderAdapter;
1579
1986
  exports.BaseCodingAdapter = BaseCodingAdapter;
1987
+ exports.CLAUDE_TOOL_CATEGORIES = CLAUDE_TOOL_CATEGORIES;
1988
+ exports.CODEX_TOOL_CATEGORIES = CODEX_TOOL_CATEGORIES;
1580
1989
  exports.ClaudeAdapter = ClaudeAdapter;
1581
1990
  exports.CodexAdapter = CodexAdapter;
1991
+ exports.GEMINI_TOOL_CATEGORIES = GEMINI_TOOL_CATEGORIES;
1582
1992
  exports.GeminiAdapter = GeminiAdapter;
1993
+ exports.PRESET_DEFINITIONS = PRESET_DEFINITIONS;
1994
+ exports.TOOL_CATEGORIES = TOOL_CATEGORIES;
1583
1995
  exports.checkAdapters = checkAdapters;
1584
1996
  exports.checkAllAdapters = checkAllAdapters;
1585
1997
  exports.clearPatternCache = clearPatternCache;
1586
1998
  exports.createAdapter = createAdapter;
1587
1999
  exports.createAllAdapters = createAllAdapters;
2000
+ exports.generateAiderApprovalConfig = generateAiderApprovalConfig;
2001
+ exports.generateApprovalConfig = generateApprovalConfig;
2002
+ exports.generateClaudeApprovalConfig = generateClaudeApprovalConfig;
2003
+ exports.generateCodexApprovalConfig = generateCodexApprovalConfig;
2004
+ exports.generateGeminiApprovalConfig = generateGeminiApprovalConfig;
1588
2005
  exports.getBaselinePatterns = getBaselinePatterns;
2006
+ exports.getPresetDefinition = getPresetDefinition;
1589
2007
  exports.hasDynamicPatterns = hasDynamicPatterns;
2008
+ exports.listPresets = listPresets;
1590
2009
  exports.loadPatterns = loadPatterns;
1591
2010
  exports.loadPatternsSync = loadPatternsSync;
1592
2011
  exports.preloadAllPatterns = preloadAllPatterns;