coding-agent-adapters 0.5.0 → 0.7.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 +47 -6
- package/dist/index.cjs +87 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +50 -0
- package/dist/index.d.ts +50 -0
- package/dist/index.js +87 -0
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -44,12 +44,12 @@ session.send('Help me refactor this function to use async/await');
|
|
|
44
44
|
|
|
45
45
|
## Available Adapters
|
|
46
46
|
|
|
47
|
-
| Adapter | CLI | Type | Input Style | Auto-Response Rules |
|
|
48
|
-
|
|
49
|
-
| `ClaudeAdapter` | Claude Code | `claude` | TUI menus | 5 rules |
|
|
50
|
-
| `GeminiAdapter` | Gemini CLI | `gemini` | TUI menus | 3 rules |
|
|
51
|
-
| `CodexAdapter` | OpenAI Codex | `codex` | TUI menus | 6 rules |
|
|
52
|
-
| `AiderAdapter` | Aider | `aider` | Text `(Y)es/(N)o` | 17 rules |
|
|
47
|
+
| Adapter | CLI | Type | Input Style | Auto-Response Rules | Ready Settle |
|
|
48
|
+
|---------|-----|------|-------------|---------------------|-------------|
|
|
49
|
+
| `ClaudeAdapter` | Claude Code | `claude` | TUI menus | 5 rules | 500ms |
|
|
50
|
+
| `GeminiAdapter` | Gemini CLI | `gemini` | TUI menus | 3 rules | 300ms |
|
|
51
|
+
| `CodexAdapter` | OpenAI Codex | `codex` | TUI menus | 6 rules | 300ms |
|
|
52
|
+
| `AiderAdapter` | Aider | `aider` | Text `(Y)es/(N)o` | 17 rules | 200ms |
|
|
53
53
|
|
|
54
54
|
## Session Lifecycle Detection
|
|
55
55
|
|
|
@@ -83,6 +83,17 @@ Each adapter knows exactly what "ready for input" looks like:
|
|
|
83
83
|
| Codex | `>` glyph, placeholder suggestions | `chat_composer.rs` |
|
|
84
84
|
| Aider | `ask>`, `code>`, `architect>`, `help>`, `multi>`, startup banner | `io.py`, `base_coder.py` |
|
|
85
85
|
|
|
86
|
+
### Ready Settle Delay
|
|
87
|
+
|
|
88
|
+
Each adapter sets `readySettleMs` to control how long pty-manager waits after `detectReady()` matches before emitting `session_ready`. This prevents the orchestrator from sending input while the TUI is still rendering (status bar, shortcuts, update notices). The base default is 300ms; adapters override based on their rendering weight.
|
|
89
|
+
|
|
90
|
+
| Adapter | `readySettleMs` | Rationale |
|
|
91
|
+
|---------|----------------|-----------|
|
|
92
|
+
| Claude Code | 500ms | Heaviest TUI — status bar, shortcuts, update notices, /ide suggestions |
|
|
93
|
+
| Gemini CLI | 300ms | Moderate Ink TUI (inherits base default) |
|
|
94
|
+
| Codex | 300ms | Moderate Rust TUI (inherits base default) |
|
|
95
|
+
| Aider | 200ms | Minimal TUI, mostly text output |
|
|
96
|
+
|
|
86
97
|
### Blocking Prompt Detection
|
|
87
98
|
|
|
88
99
|
Adapters detect prompts that block the session and require user action:
|
|
@@ -94,6 +105,28 @@ Adapters detect prompts that block the session and require user action:
|
|
|
94
105
|
| Codex | Directory trust, tool approval, update available, model migration, CWD selection |
|
|
95
106
|
| Aider | File operations, shell commands, git init, pip install, destructive operations |
|
|
96
107
|
|
|
108
|
+
### Loading / Active-Work Detection
|
|
109
|
+
|
|
110
|
+
Each adapter implements `detectLoading(output)` to detect when the CLI is actively processing — thinking spinners, file reading, model streaming. When loading is detected, pty-manager suppresses stall detection entirely, avoiding unnecessary LLM classifier calls during normal operation.
|
|
111
|
+
|
|
112
|
+
| Adapter | Loading Indicators | Source Patterns |
|
|
113
|
+
|---------|-------------------|----------------|
|
|
114
|
+
| Claude | `esc to interrupt`, `Reading N files` | `claude_active_reading_files` |
|
|
115
|
+
| Gemini | `esc to cancel`, `Waiting for user confirmation` | `gemini_active_loading_line` |
|
|
116
|
+
| Codex | `esc to interrupt`, `Booting MCP server`, `Searching the web` | `codex_active_status_row`, `codex_active_booting_mcp` |
|
|
117
|
+
| Aider | `Waiting for LLM/<model>`, `Generating commit message with` | `aider_active_waiting_model`, `aider_active_waiting_llm_default` |
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
const claude = new ClaudeAdapter();
|
|
121
|
+
claude.detectLoading('• Working (5s • esc to interrupt)'); // true
|
|
122
|
+
claude.detectLoading('Reading 42 files…'); // true
|
|
123
|
+
claude.detectLoading('❯ '); // false
|
|
124
|
+
|
|
125
|
+
const aider = new AiderAdapter();
|
|
126
|
+
aider.detectLoading('Waiting for claude-sonnet-4-20250514'); // true
|
|
127
|
+
aider.detectLoading('code> '); // false
|
|
128
|
+
```
|
|
129
|
+
|
|
97
130
|
### Task Completion Detection
|
|
98
131
|
|
|
99
132
|
Each adapter implements `detectTaskComplete(output)` to recognize when the CLI has finished a task and returned to its idle prompt. This is more specific than `detectReady()` — it matches high-confidence completion indicators (duration summaries, explicit done messages) that short-circuit the LLM stall classifier in pty-manager.
|
|
@@ -382,6 +415,9 @@ export class CursorAdapter extends BaseCodingAdapter {
|
|
|
382
415
|
// Set to false if the CLI uses text prompts instead of TUI menus
|
|
383
416
|
override readonly usesTuiMenus = false;
|
|
384
417
|
|
|
418
|
+
// Tune ready settle delay for this CLI's rendering speed (base default: 300ms)
|
|
419
|
+
override readonly readySettleMs = 250;
|
|
420
|
+
|
|
385
421
|
readonly autoResponseRules: AutoResponseRule[] = [
|
|
386
422
|
{ pattern: /accept terms/i, type: 'tos', response: 'y', responseType: 'text', description: 'Accept TOS', safe: true, once: true },
|
|
387
423
|
];
|
|
@@ -411,6 +447,11 @@ export class CursorAdapter extends BaseCodingAdapter {
|
|
|
411
447
|
return /cursor>\s*$/m.test(output);
|
|
412
448
|
}
|
|
413
449
|
|
|
450
|
+
detectLoading(output: string): boolean {
|
|
451
|
+
// Active loading indicator — suppresses stall detection
|
|
452
|
+
return /processing|thinking/i.test(output);
|
|
453
|
+
}
|
|
454
|
+
|
|
414
455
|
detectTaskComplete(output: string): boolean {
|
|
415
456
|
// High-confidence: task summary + idle prompt
|
|
416
457
|
return /completed in \d+s/.test(output) && /cursor>\s*$/m.test(output);
|
package/dist/index.cjs
CHANGED
|
@@ -368,6 +368,12 @@ var BaseCodingAdapter = class extends ptyManager.BaseCLIAdapter {
|
|
|
368
368
|
* Coding agent CLIs use TUI menus that require arrow-key navigation.
|
|
369
369
|
*/
|
|
370
370
|
usesTuiMenus = true;
|
|
371
|
+
/**
|
|
372
|
+
* Ms of output silence after detectReady match before emitting session_ready.
|
|
373
|
+
* Allows TUI rendering (status bar, shortcuts, update notices) to complete
|
|
374
|
+
* before the orchestrator sends input.
|
|
375
|
+
*/
|
|
376
|
+
readySettleMs = 300;
|
|
371
377
|
/**
|
|
372
378
|
* The primary memory file for this CLI (the one it reads for project instructions).
|
|
373
379
|
* Returns the relativePath of the first 'memory' type file from getWorkspaceFiles().
|
|
@@ -535,6 +541,8 @@ Docs: ${this.installation.docsUrl}`
|
|
|
535
541
|
var ClaudeAdapter = class extends BaseCodingAdapter {
|
|
536
542
|
adapterType = "claude";
|
|
537
543
|
displayName = "Claude Code";
|
|
544
|
+
/** Heaviest TUI — status bar, shortcuts, update notices, /ide suggestions */
|
|
545
|
+
readySettleMs = 500;
|
|
538
546
|
installation = {
|
|
539
547
|
command: "npm install -g @anthropic-ai/claude-code",
|
|
540
548
|
alternatives: [
|
|
@@ -752,6 +760,24 @@ var ClaudeAdapter = class extends BaseCodingAdapter {
|
|
|
752
760
|
}
|
|
753
761
|
return super.detectBlockingPrompt(output);
|
|
754
762
|
}
|
|
763
|
+
/**
|
|
764
|
+
* Detect if Claude Code is actively loading/processing.
|
|
765
|
+
*
|
|
766
|
+
* Patterns from: AGENT_LOADING_STATUS_PATTERNS.json
|
|
767
|
+
* - claude_active_reading_files: "Reading N files…"
|
|
768
|
+
* - General: "esc to interrupt" spinner status line
|
|
769
|
+
*/
|
|
770
|
+
detectLoading(output) {
|
|
771
|
+
const stripped = this.stripAnsi(output);
|
|
772
|
+
const tail = stripped.slice(-500);
|
|
773
|
+
if (/esc\s+to\s+interrupt/i.test(tail)) {
|
|
774
|
+
return true;
|
|
775
|
+
}
|
|
776
|
+
if (/Reading\s+\d+\s+files/i.test(tail)) {
|
|
777
|
+
return true;
|
|
778
|
+
}
|
|
779
|
+
return false;
|
|
780
|
+
}
|
|
755
781
|
/**
|
|
756
782
|
* Detect task completion for Claude Code.
|
|
757
783
|
*
|
|
@@ -1043,6 +1069,24 @@ var GeminiAdapter = class extends BaseCodingAdapter {
|
|
|
1043
1069
|
}
|
|
1044
1070
|
return super.detectBlockingPrompt(output);
|
|
1045
1071
|
}
|
|
1072
|
+
/**
|
|
1073
|
+
* Detect if Gemini CLI is actively loading/processing.
|
|
1074
|
+
*
|
|
1075
|
+
* Patterns from: AGENT_LOADING_STATUS_PATTERNS.json
|
|
1076
|
+
* - gemini_active_loading_line: "(esc to cancel, Xs)"
|
|
1077
|
+
* - gemini_active_waiting_user_confirmation: "Waiting for user confirmation..."
|
|
1078
|
+
*/
|
|
1079
|
+
detectLoading(output) {
|
|
1080
|
+
const stripped = this.stripAnsi(output);
|
|
1081
|
+
const tail = stripped.slice(-500);
|
|
1082
|
+
if (/esc\s+to\s+cancel/i.test(tail)) {
|
|
1083
|
+
return true;
|
|
1084
|
+
}
|
|
1085
|
+
if (/Waiting\s+for\s+user\s+confirmation/i.test(tail)) {
|
|
1086
|
+
return true;
|
|
1087
|
+
}
|
|
1088
|
+
return false;
|
|
1089
|
+
}
|
|
1046
1090
|
/**
|
|
1047
1091
|
* Detect task completion for Gemini CLI.
|
|
1048
1092
|
*
|
|
@@ -1379,6 +1423,28 @@ var CodexAdapter = class extends BaseCodingAdapter {
|
|
|
1379
1423
|
}
|
|
1380
1424
|
return super.detectBlockingPrompt(output);
|
|
1381
1425
|
}
|
|
1426
|
+
/**
|
|
1427
|
+
* Detect if Codex CLI is actively loading/processing.
|
|
1428
|
+
*
|
|
1429
|
+
* Patterns from: AGENT_LOADING_STATUS_PATTERNS.json
|
|
1430
|
+
* - codex_active_status_row: "• Working (0s • esc to interrupt)"
|
|
1431
|
+
* - codex_active_booting_mcp: "Booting MCP server: ..."
|
|
1432
|
+
* - codex_active_web_search: "Searching the web"
|
|
1433
|
+
*/
|
|
1434
|
+
detectLoading(output) {
|
|
1435
|
+
const stripped = this.stripAnsi(output);
|
|
1436
|
+
const tail = stripped.slice(-500);
|
|
1437
|
+
if (/esc\s+to\s+interrupt/i.test(tail)) {
|
|
1438
|
+
return true;
|
|
1439
|
+
}
|
|
1440
|
+
if (/Booting\s+MCP\s+server/i.test(tail)) {
|
|
1441
|
+
return true;
|
|
1442
|
+
}
|
|
1443
|
+
if (/Searching\s+the\s+web/i.test(tail)) {
|
|
1444
|
+
return true;
|
|
1445
|
+
}
|
|
1446
|
+
return false;
|
|
1447
|
+
}
|
|
1382
1448
|
/**
|
|
1383
1449
|
* Detect task completion for Codex CLI.
|
|
1384
1450
|
*
|
|
@@ -1466,6 +1532,8 @@ var CodexAdapter = class extends BaseCodingAdapter {
|
|
|
1466
1532
|
var AiderAdapter = class extends BaseCodingAdapter {
|
|
1467
1533
|
adapterType = "aider";
|
|
1468
1534
|
displayName = "Aider";
|
|
1535
|
+
/** Minimal TUI, mostly text output — shorter settle delay */
|
|
1536
|
+
readySettleMs = 200;
|
|
1469
1537
|
/**
|
|
1470
1538
|
* Aider uses plain text [y/n] prompts, NOT TUI arrow-key menus.
|
|
1471
1539
|
*/
|
|
@@ -1809,6 +1877,25 @@ var AiderAdapter = class extends BaseCodingAdapter {
|
|
|
1809
1877
|
}
|
|
1810
1878
|
return super.detectBlockingPrompt(output);
|
|
1811
1879
|
}
|
|
1880
|
+
/**
|
|
1881
|
+
* Detect if Aider is actively loading/processing.
|
|
1882
|
+
*
|
|
1883
|
+
* Patterns from: AGENT_LOADING_STATUS_PATTERNS.json
|
|
1884
|
+
* - aider_active_waiting_model: "Waiting for <model>"
|
|
1885
|
+
* - aider_active_waiting_llm_default: "Waiting for LLM"
|
|
1886
|
+
* - aider_active_generating_commit_message: "Generating commit message with ..."
|
|
1887
|
+
*/
|
|
1888
|
+
detectLoading(output) {
|
|
1889
|
+
const stripped = this.stripAnsi(output);
|
|
1890
|
+
const tail = stripped.slice(-500);
|
|
1891
|
+
if (/Waiting\s+for\s+(?:LLM|[A-Za-z0-9_./:@-]+)/i.test(tail)) {
|
|
1892
|
+
return true;
|
|
1893
|
+
}
|
|
1894
|
+
if (/Generating\s+commit\s+message\s+with\s+/i.test(tail)) {
|
|
1895
|
+
return true;
|
|
1896
|
+
}
|
|
1897
|
+
return false;
|
|
1898
|
+
}
|
|
1812
1899
|
/**
|
|
1813
1900
|
* Detect task completion for Aider.
|
|
1814
1901
|
*
|