coding-agent-adapters 0.6.0 → 0.7.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/dist/index.d.cts CHANGED
@@ -187,11 +187,17 @@ declare abstract class BaseCodingAdapter extends BaseCLIAdapter {
187
187
  */
188
188
  abstract getRecommendedModels(credentials?: AgentCredentials): ModelRecommendations;
189
189
  /**
190
- * Override stripAnsi to handle TUI cursor movement codes.
190
+ * Override stripAnsi to handle TUI cursor movement codes, spinner/box-drawing
191
+ * characters, bare control characters, and extra whitespace.
192
+ *
191
193
  * TUI CLIs (Claude Code, Gemini CLI, Codex) use cursor positioning
192
- * sequences instead of literal spaces. Replace ALL cursor movement
193
- * codes with spaces before stripping other ANSI codes so regex
194
- * patterns can match the visible text.
194
+ * sequences instead of literal spaces, and render decorative Unicode
195
+ * characters (spinners, box-drawing). All of these must be stripped so
196
+ * adapter detection methods (detectReady, detectTaskComplete, etc.) can
197
+ * match visible text with their regex patterns.
198
+ *
199
+ * Note: ❯ and › are preserved — they are prompt indicators used by
200
+ * detectReady / detectTaskComplete.
195
201
  */
196
202
  protected stripAnsi(str: string): string;
197
203
  /**
@@ -214,6 +220,12 @@ declare abstract class BaseCodingAdapter extends BaseCLIAdapter {
214
220
  * Extract the main content from CLI output, removing common artifacts
215
221
  */
216
222
  protected extractContent(output: string, promptPattern: RegExp): string;
223
+ /**
224
+ * Detect if the CLI is actively loading/processing (thinking spinner,
225
+ * file reading, model streaming, etc.). When true, stall detection is
226
+ * suppressed because the agent is provably working.
227
+ */
228
+ abstract detectLoading(output: string): boolean;
217
229
  /**
218
230
  * Detect if the CLI has completed a task and returned to its idle prompt.
219
231
  * More specific than detectReady() — matches high-confidence completion indicators
@@ -275,6 +287,14 @@ declare class ClaudeAdapter extends BaseCodingAdapter {
275
287
  * Detect blocking prompts specific to Claude Code CLI
276
288
  */
277
289
  detectBlockingPrompt(output: string): BlockingPromptDetection;
290
+ /**
291
+ * Detect if Claude Code is actively loading/processing.
292
+ *
293
+ * Patterns from: AGENT_LOADING_STATUS_PATTERNS.json
294
+ * - claude_active_reading_files: "Reading N files…"
295
+ * - General: "esc to interrupt" spinner status line
296
+ */
297
+ detectLoading(output: string): boolean;
278
298
  /**
279
299
  * Detect task completion for Claude Code.
280
300
  *
@@ -316,6 +336,14 @@ declare class GeminiAdapter extends BaseCodingAdapter {
316
336
  getEnv(config: SpawnConfig): Record<string, string>;
317
337
  detectLogin(output: string): LoginDetection;
318
338
  detectBlockingPrompt(output: string): BlockingPromptDetection;
339
+ /**
340
+ * Detect if Gemini CLI is actively loading/processing.
341
+ *
342
+ * Patterns from: AGENT_LOADING_STATUS_PATTERNS.json
343
+ * - gemini_active_loading_line: "(esc to cancel, Xs)"
344
+ * - gemini_active_waiting_user_confirmation: "Waiting for user confirmation..."
345
+ */
346
+ detectLoading(output: string): boolean;
319
347
  /**
320
348
  * Detect task completion for Gemini CLI.
321
349
  *
@@ -369,6 +397,15 @@ declare class CodexAdapter extends BaseCodingAdapter {
369
397
  * Source: approval_overlay.rs, chatwidget.rs, request_user_input/mod.rs
370
398
  */
371
399
  detectBlockingPrompt(output: string): BlockingPromptDetection;
400
+ /**
401
+ * Detect if Codex CLI is actively loading/processing.
402
+ *
403
+ * Patterns from: AGENT_LOADING_STATUS_PATTERNS.json
404
+ * - codex_active_status_row: "• Working (0s • esc to interrupt)"
405
+ * - codex_active_booting_mcp: "Booting MCP server: ..."
406
+ * - codex_active_web_search: "Searching the web"
407
+ */
408
+ detectLoading(output: string): boolean;
372
409
  /**
373
410
  * Detect task completion for Codex CLI.
374
411
  *
@@ -432,6 +469,15 @@ declare class AiderAdapter extends BaseCodingAdapter {
432
469
  * Source: io.py, onboarding.py, base_coder.py, report.py
433
470
  */
434
471
  detectBlockingPrompt(output: string): BlockingPromptDetection;
472
+ /**
473
+ * Detect if Aider is actively loading/processing.
474
+ *
475
+ * Patterns from: AGENT_LOADING_STATUS_PATTERNS.json
476
+ * - aider_active_waiting_model: "Waiting for <model>"
477
+ * - aider_active_waiting_llm_default: "Waiting for LLM"
478
+ * - aider_active_generating_commit_message: "Generating commit message with ..."
479
+ */
480
+ detectLoading(output: string): boolean;
435
481
  /**
436
482
  * Detect task completion for Aider.
437
483
  *
package/dist/index.d.ts CHANGED
@@ -187,11 +187,17 @@ declare abstract class BaseCodingAdapter extends BaseCLIAdapter {
187
187
  */
188
188
  abstract getRecommendedModels(credentials?: AgentCredentials): ModelRecommendations;
189
189
  /**
190
- * Override stripAnsi to handle TUI cursor movement codes.
190
+ * Override stripAnsi to handle TUI cursor movement codes, spinner/box-drawing
191
+ * characters, bare control characters, and extra whitespace.
192
+ *
191
193
  * TUI CLIs (Claude Code, Gemini CLI, Codex) use cursor positioning
192
- * sequences instead of literal spaces. Replace ALL cursor movement
193
- * codes with spaces before stripping other ANSI codes so regex
194
- * patterns can match the visible text.
194
+ * sequences instead of literal spaces, and render decorative Unicode
195
+ * characters (spinners, box-drawing). All of these must be stripped so
196
+ * adapter detection methods (detectReady, detectTaskComplete, etc.) can
197
+ * match visible text with their regex patterns.
198
+ *
199
+ * Note: ❯ and › are preserved — they are prompt indicators used by
200
+ * detectReady / detectTaskComplete.
195
201
  */
196
202
  protected stripAnsi(str: string): string;
197
203
  /**
@@ -214,6 +220,12 @@ declare abstract class BaseCodingAdapter extends BaseCLIAdapter {
214
220
  * Extract the main content from CLI output, removing common artifacts
215
221
  */
216
222
  protected extractContent(output: string, promptPattern: RegExp): string;
223
+ /**
224
+ * Detect if the CLI is actively loading/processing (thinking spinner,
225
+ * file reading, model streaming, etc.). When true, stall detection is
226
+ * suppressed because the agent is provably working.
227
+ */
228
+ abstract detectLoading(output: string): boolean;
217
229
  /**
218
230
  * Detect if the CLI has completed a task and returned to its idle prompt.
219
231
  * More specific than detectReady() — matches high-confidence completion indicators
@@ -275,6 +287,14 @@ declare class ClaudeAdapter extends BaseCodingAdapter {
275
287
  * Detect blocking prompts specific to Claude Code CLI
276
288
  */
277
289
  detectBlockingPrompt(output: string): BlockingPromptDetection;
290
+ /**
291
+ * Detect if Claude Code is actively loading/processing.
292
+ *
293
+ * Patterns from: AGENT_LOADING_STATUS_PATTERNS.json
294
+ * - claude_active_reading_files: "Reading N files…"
295
+ * - General: "esc to interrupt" spinner status line
296
+ */
297
+ detectLoading(output: string): boolean;
278
298
  /**
279
299
  * Detect task completion for Claude Code.
280
300
  *
@@ -316,6 +336,14 @@ declare class GeminiAdapter extends BaseCodingAdapter {
316
336
  getEnv(config: SpawnConfig): Record<string, string>;
317
337
  detectLogin(output: string): LoginDetection;
318
338
  detectBlockingPrompt(output: string): BlockingPromptDetection;
339
+ /**
340
+ * Detect if Gemini CLI is actively loading/processing.
341
+ *
342
+ * Patterns from: AGENT_LOADING_STATUS_PATTERNS.json
343
+ * - gemini_active_loading_line: "(esc to cancel, Xs)"
344
+ * - gemini_active_waiting_user_confirmation: "Waiting for user confirmation..."
345
+ */
346
+ detectLoading(output: string): boolean;
319
347
  /**
320
348
  * Detect task completion for Gemini CLI.
321
349
  *
@@ -369,6 +397,15 @@ declare class CodexAdapter extends BaseCodingAdapter {
369
397
  * Source: approval_overlay.rs, chatwidget.rs, request_user_input/mod.rs
370
398
  */
371
399
  detectBlockingPrompt(output: string): BlockingPromptDetection;
400
+ /**
401
+ * Detect if Codex CLI is actively loading/processing.
402
+ *
403
+ * Patterns from: AGENT_LOADING_STATUS_PATTERNS.json
404
+ * - codex_active_status_row: "• Working (0s • esc to interrupt)"
405
+ * - codex_active_booting_mcp: "Booting MCP server: ..."
406
+ * - codex_active_web_search: "Searching the web"
407
+ */
408
+ detectLoading(output: string): boolean;
372
409
  /**
373
410
  * Detect task completion for Codex CLI.
374
411
  *
@@ -432,6 +469,15 @@ declare class AiderAdapter extends BaseCodingAdapter {
432
469
  * Source: io.py, onboarding.py, base_coder.py, report.py
433
470
  */
434
471
  detectBlockingPrompt(output: string): BlockingPromptDetection;
472
+ /**
473
+ * Detect if Aider is actively loading/processing.
474
+ *
475
+ * Patterns from: AGENT_LOADING_STATUS_PATTERNS.json
476
+ * - aider_active_waiting_model: "Waiting for <model>"
477
+ * - aider_active_waiting_llm_default: "Waiting for LLM"
478
+ * - aider_active_generating_commit_message: "Generating commit message with ..."
479
+ */
480
+ detectLoading(output: string): boolean;
435
481
  /**
436
482
  * Detect task completion for Aider.
437
483
  *
package/dist/index.js CHANGED
@@ -399,17 +399,27 @@ var BaseCodingAdapter = class extends BaseCLIAdapter {
399
399
  return adapterConfig?.interactive === true;
400
400
  }
401
401
  /**
402
- * Override stripAnsi to handle TUI cursor movement codes.
402
+ * Override stripAnsi to handle TUI cursor movement codes, spinner/box-drawing
403
+ * characters, bare control characters, and extra whitespace.
404
+ *
403
405
  * TUI CLIs (Claude Code, Gemini CLI, Codex) use cursor positioning
404
- * sequences instead of literal spaces. Replace ALL cursor movement
405
- * codes with spaces before stripping other ANSI codes so regex
406
- * patterns can match the visible text.
406
+ * sequences instead of literal spaces, and render decorative Unicode
407
+ * characters (spinners, box-drawing). All of these must be stripped so
408
+ * adapter detection methods (detectReady, detectTaskComplete, etc.) can
409
+ * match visible text with their regex patterns.
410
+ *
411
+ * Note: ❯ and › are preserved — they are prompt indicators used by
412
+ * detectReady / detectTaskComplete.
407
413
  */
408
414
  stripAnsi(str) {
409
415
  let result = str.replace(/\x1b\[\d*[CDABGdEF]/g, " ");
410
416
  result = result.replace(/\x1b\[\d*(?:;\d+)?[Hf]/g, " ");
411
417
  result = result.replace(/\x1b\[\d*[JK]/g, " ");
412
- return super.stripAnsi(result);
418
+ result = super.stripAnsi(result);
419
+ result = result.replace(/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/g, "");
420
+ result = result.replace(/[│╭╰╮╯─═╌║╔╗╚╝╠╣╦╩╬┌┐└┘├┤┬┴┼●○❮▶◀⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏⣾⣽⣻⢿⡿⣟⣯⣷✻✶✳✢⏺←→↑↓⬆⬇◆▪▫■□▲△▼▽◈⟨⟩⌘⏎⏏⌫⌦⇧⇪⌥]/g, " ");
421
+ result = result.replace(/ {2,}/g, " ");
422
+ return result;
413
423
  }
414
424
  /**
415
425
  * Override detectExit to include installation instructions
@@ -758,6 +768,24 @@ var ClaudeAdapter = class extends BaseCodingAdapter {
758
768
  }
759
769
  return super.detectBlockingPrompt(output);
760
770
  }
771
+ /**
772
+ * Detect if Claude Code is actively loading/processing.
773
+ *
774
+ * Patterns from: AGENT_LOADING_STATUS_PATTERNS.json
775
+ * - claude_active_reading_files: "Reading N files…"
776
+ * - General: "esc to interrupt" spinner status line
777
+ */
778
+ detectLoading(output) {
779
+ const stripped = this.stripAnsi(output);
780
+ const tail = stripped.slice(-500);
781
+ if (/esc\s+to\s+interrupt/i.test(tail)) {
782
+ return true;
783
+ }
784
+ if (/Reading\s+\d+\s+files/i.test(tail)) {
785
+ return true;
786
+ }
787
+ return false;
788
+ }
761
789
  /**
762
790
  * Detect task completion for Claude Code.
763
791
  *
@@ -1049,6 +1077,24 @@ var GeminiAdapter = class extends BaseCodingAdapter {
1049
1077
  }
1050
1078
  return super.detectBlockingPrompt(output);
1051
1079
  }
1080
+ /**
1081
+ * Detect if Gemini CLI is actively loading/processing.
1082
+ *
1083
+ * Patterns from: AGENT_LOADING_STATUS_PATTERNS.json
1084
+ * - gemini_active_loading_line: "(esc to cancel, Xs)"
1085
+ * - gemini_active_waiting_user_confirmation: "Waiting for user confirmation..."
1086
+ */
1087
+ detectLoading(output) {
1088
+ const stripped = this.stripAnsi(output);
1089
+ const tail = stripped.slice(-500);
1090
+ if (/esc\s+to\s+cancel/i.test(tail)) {
1091
+ return true;
1092
+ }
1093
+ if (/Waiting\s+for\s+user\s+confirmation/i.test(tail)) {
1094
+ return true;
1095
+ }
1096
+ return false;
1097
+ }
1052
1098
  /**
1053
1099
  * Detect task completion for Gemini CLI.
1054
1100
  *
@@ -1385,6 +1431,28 @@ var CodexAdapter = class extends BaseCodingAdapter {
1385
1431
  }
1386
1432
  return super.detectBlockingPrompt(output);
1387
1433
  }
1434
+ /**
1435
+ * Detect if Codex CLI is actively loading/processing.
1436
+ *
1437
+ * Patterns from: AGENT_LOADING_STATUS_PATTERNS.json
1438
+ * - codex_active_status_row: "• Working (0s • esc to interrupt)"
1439
+ * - codex_active_booting_mcp: "Booting MCP server: ..."
1440
+ * - codex_active_web_search: "Searching the web"
1441
+ */
1442
+ detectLoading(output) {
1443
+ const stripped = this.stripAnsi(output);
1444
+ const tail = stripped.slice(-500);
1445
+ if (/esc\s+to\s+interrupt/i.test(tail)) {
1446
+ return true;
1447
+ }
1448
+ if (/Booting\s+MCP\s+server/i.test(tail)) {
1449
+ return true;
1450
+ }
1451
+ if (/Searching\s+the\s+web/i.test(tail)) {
1452
+ return true;
1453
+ }
1454
+ return false;
1455
+ }
1388
1456
  /**
1389
1457
  * Detect task completion for Codex CLI.
1390
1458
  *
@@ -1817,6 +1885,25 @@ var AiderAdapter = class extends BaseCodingAdapter {
1817
1885
  }
1818
1886
  return super.detectBlockingPrompt(output);
1819
1887
  }
1888
+ /**
1889
+ * Detect if Aider is actively loading/processing.
1890
+ *
1891
+ * Patterns from: AGENT_LOADING_STATUS_PATTERNS.json
1892
+ * - aider_active_waiting_model: "Waiting for <model>"
1893
+ * - aider_active_waiting_llm_default: "Waiting for LLM"
1894
+ * - aider_active_generating_commit_message: "Generating commit message with ..."
1895
+ */
1896
+ detectLoading(output) {
1897
+ const stripped = this.stripAnsi(output);
1898
+ const tail = stripped.slice(-500);
1899
+ if (/Waiting\s+for\s+(?:LLM|[A-Za-z0-9_./:@-]+)/i.test(tail)) {
1900
+ return true;
1901
+ }
1902
+ if (/Generating\s+commit\s+message\s+with\s+/i.test(tail)) {
1903
+ return true;
1904
+ }
1905
+ return false;
1906
+ }
1820
1907
  /**
1821
1908
  * Detect task completion for Aider.
1822
1909
  *