coding-agent-adapters 0.8.8 → 0.11.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.
Files changed (2) hide show
  1. package/README.md +130 -5
  2. package/package.json +3 -2
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # coding-agent-adapters
2
2
 
3
- CLI adapters for AI coding agents. Works with [pty-manager](https://www.npmjs.com/package/pty-manager) to spawn and manage coding agents like Claude Code, Gemini CLI, OpenAI Codex, and Aider.
3
+ CLI adapters for AI coding agents. Works with [pty-manager](https://www.npmjs.com/package/pty-manager) to spawn and manage coding agents like Claude Code, Gemini CLI, OpenAI Codex, Aider, and Hermes Agent.
4
4
 
5
5
  Each adapter provides source-derived detection patterns for the full session lifecycle: login/auth, blocking prompts, ready state, exit conditions, and auto-response rules — all based on deep analysis of each CLI's open-source codebase.
6
6
 
@@ -14,13 +14,14 @@ npm install coding-agent-adapters pty-manager
14
14
 
15
15
  ```typescript
16
16
  import { PTYManager, AdapterRegistry } from 'pty-manager';
17
- import { ClaudeAdapter, GeminiAdapter, AiderAdapter } from 'coding-agent-adapters';
17
+ import { ClaudeAdapter, GeminiAdapter, AiderAdapter, HermesAdapter } from 'coding-agent-adapters';
18
18
 
19
19
  // Create adapter registry and register the adapters you need
20
20
  const registry = new AdapterRegistry();
21
21
  registry.register(new ClaudeAdapter());
22
22
  registry.register(new GeminiAdapter());
23
23
  registry.register(new AiderAdapter());
24
+ registry.register(new HermesAdapter());
24
25
 
25
26
  // Create PTY manager with the registry
26
27
  const manager = new PTYManager({ adapters: registry });
@@ -50,6 +51,7 @@ session.send('Help me refactor this function to use async/await');
50
51
  | `GeminiAdapter` | Gemini CLI | `gemini` | TUI menus | 3 rules | 300ms |
51
52
  | `CodexAdapter` | OpenAI Codex | `codex` | TUI menus | 6 rules | 300ms |
52
53
  | `AiderAdapter` | Aider | `aider` | Text `(Y)es/(N)o` | 17 rules | 200ms |
54
+ | `HermesAdapter` | Hermes Agent | `hermes` | TUI prompts | 0 rules | 400ms |
53
55
 
54
56
  ## Session Lifecycle Detection
55
57
 
@@ -73,6 +75,7 @@ const login = adapter.detectLogin(output);
73
75
  | Gemini | Google OAuth, API key entry, auth in-progress (ignores "Both keys set" success messages) | `AuthDialog.tsx`, `ApiAuthDialog.tsx`, `AuthInProgress.tsx` |
74
76
  | Codex | Device code flow, onboarding auth menu | `auth.rs`, `headless_chatgpt_login.rs` |
75
77
  | Aider | API key missing/invalid, OpenRouter OAuth | `onboarding.py`, `models.py` |
78
+ | Hermes | First-run setup gate (`no API keys/providers found`, `Run setup now?`) | `hermes_cli/setup.py`, `hermes_cli/main.py` |
76
79
 
77
80
  ### Ready State Detection
78
81
 
@@ -84,6 +87,7 @@ Each adapter knows exactly what "ready for input" looks like:
84
87
  | Gemini | Prompt glyphs (`>`, `!`, `*`, `(r:)`), composer placeholder | `InputPrompt.tsx`, `Composer.tsx` |
85
88
  | Codex | `>` glyph, placeholder suggestions | `chat_composer.rs` |
86
89
  | Aider | `ask>`, `code>`, `architect>`, `help>`, `multi>`, startup banner | `io.py`, `base_coder.py` |
90
+ | Hermes | Idle `❯` prompt when not working; completion response box | `cli.py`, `agent/display.py` |
87
91
 
88
92
  ### Ready Settle Delay
89
93
 
@@ -95,6 +99,7 @@ Each adapter sets `readySettleMs` to control how long pty-manager waits after `d
95
99
  | Gemini CLI | 300ms | Moderate Ink TUI (inherits base default) |
96
100
  | Codex | 300ms | Moderate Rust TUI (inherits base default) |
97
101
  | Aider | 200ms | Minimal TUI, mostly text output |
102
+ | Hermes Agent | 400ms | Prompt-toolkit UI with spinner + activity feed that settles after render |
98
103
 
99
104
  ### Blocking Prompt Detection
100
105
 
@@ -106,6 +111,7 @@ Adapters detect prompts that block the session and require user action:
106
111
  | Gemini | Folder trust, tool execution, validation dialogs, privacy consent |
107
112
  | Codex | Directory trust, tool approval, update available, model migration, CWD selection |
108
113
  | Aider | File operations, shell commands, git init, pip install, destructive operations |
114
+ | Hermes | Clarify prompts, sudo password prompts, dangerous command approval choices |
109
115
 
110
116
  ### Loading / Active-Work Detection
111
117
 
@@ -117,6 +123,7 @@ Each adapter implements `detectLoading(output)` to detect when the CLI is active
117
123
  | Gemini | `esc to cancel`, `Waiting for user confirmation` | `gemini_active_loading_line` |
118
124
  | Codex | `esc to interrupt`, `Booting MCP server`, `Searching the web` | `codex_active_status_row`, `codex_active_booting_mcp` |
119
125
  | Aider | `Waiting for LLM/<model>`, `Generating commit message with` | `aider_active_waiting_model`, `aider_active_waiting_llm_default` |
126
+ | Hermes | Thinking spinner verb + elapsed time (`deliberating... (2.4s)`), working prompt (`⚕ ❯`) | `HermesAdapter.detectLoading()` |
120
127
 
121
128
  ```typescript
122
129
  const claude = new ClaudeAdapter();
@@ -139,6 +146,7 @@ Each adapter implements `detectTaskComplete(output)` to recognize when the CLI h
139
146
  | Gemini | `◇ Ready` window title, `Type your message` composer | `gemini_ready_title` |
140
147
  | Codex | `Worked for 1m 05s` separator + `›` prompt | `codex_completed_worked_for_separator`, `codex_ready_prompt` |
141
148
  | Aider | `Aider is waiting for your input`, mode prompts (including plain `>`) with edit/cost markers | `aider_completed_llm_response_ready` |
149
+ | Hermes | Final response box (`╭─ ⚕ Hermes ... ╰`), or tool-feed line + idle prompt | `HermesAdapter.detectTaskComplete()` |
142
150
 
143
151
  ```typescript
144
152
  const claude = new ClaudeAdapter();
@@ -160,12 +168,13 @@ Adapters detect when a CLI session has ended:
160
168
  | Gemini | Folder trust rejection, logout confirmation |
161
169
  | Codex | Session end, update completion |
162
170
  | Aider | Ctrl+C / KeyboardInterrupt, version update requiring restart |
171
+ | Hermes | `Goodbye! ⚕` |
163
172
 
164
173
  ## Auto-Response Rules
165
174
 
166
175
  Adapters include pre-configured rules to automatically handle known prompts. Rules use two response modes depending on the CLI's input style.
167
176
 
168
- ### TUI Menu CLIs (Gemini, Codex, Claude)
177
+ ### TUI Menu CLIs (Gemini, Codex, Claude, Hermes)
169
178
 
170
179
  These CLIs use arrow-key menus rendered with Ink/Ratatui. Rules send key sequences:
171
180
 
@@ -200,7 +209,7 @@ aider.autoResponseRules;
200
209
 
201
210
  Adapters declare their input style via `usesTuiMenus`. This affects how auto-response rules with no explicit `responseType` are delivered:
202
211
 
203
- - `usesTuiMenus: true` (Gemini, Codex, Claude) — defaults to `sendKeys('enter')`
212
+ - `usesTuiMenus: true` (Gemini, Codex, Claude, Hermes) — defaults to `sendKeys('enter')`
204
213
  - `usesTuiMenus: false` (Aider) — defaults to `writeRaw(response + '\r')`
205
214
 
206
215
  ## Model Recommendations
@@ -248,6 +257,7 @@ aider.memoryFilePath; // '.aider.conventions.md'
248
257
  | Gemini | `GEMINI.md` | `.gemini/settings.json` | `.gemini/styles` |
249
258
  | Codex | `AGENTS.md` | `.codex/config.json` | `codex.md` |
250
259
  | Aider | `.aider.conventions.md` | `.aider.conf.yml` | `.aiderignore` |
260
+ | Hermes | `AGENTS.md` | `cli-config.yaml` | `SOUL.md` |
251
261
 
252
262
  ### Writing Memory Files
253
263
 
@@ -344,6 +354,7 @@ const writtenFiles = await adapter.writeApprovalConfig('/path/to/workspace', {
344
354
  | Gemini CLI | `.gemini/settings.json` | `general.defaultApprovalMode`, `tools.allowed`, `tools.exclude` |
345
355
  | Codex | `.codex/config.json` | `approval_policy`, `sandbox_mode`, `tools.web_search` |
346
356
  | Aider | `.aider.conf.yml` | `yes-always`, `no-auto-commits` |
357
+ | Hermes Agent | none (CLI-managed) | approvals currently handled in-session by Hermes safety prompts |
347
358
 
348
359
  ## Preflight Check
349
360
 
@@ -396,6 +407,120 @@ const session = await manager.spawn({
396
407
  });
397
408
  ```
398
409
 
410
+ ## Claude Hook Telemetry (Optional)
411
+
412
+ Claude Code hooks can emit deterministic lifecycle markers so PTY orchestration does not rely only on screen-text heuristics.
413
+
414
+ `ClaudeAdapter` supports this as an opt-in mode:
415
+
416
+ ```typescript
417
+ const session = await manager.spawn({
418
+ name: 'claude-agent',
419
+ type: 'claude',
420
+ workdir: '/project',
421
+ adapterConfig: {
422
+ anthropicKey: process.env.ANTHROPIC_API_KEY,
423
+ claudeHookTelemetry: true,
424
+ },
425
+ });
426
+ ```
427
+
428
+ When enabled, the adapter sets:
429
+ - `PARALLAX_CLAUDE_HOOK_TELEMETRY=1`
430
+ - `PARALLAX_CLAUDE_HOOK_MARKER_PREFIX=PARALLAX_CLAUDE_HOOK` (or your override)
431
+
432
+ ### Marker Protocol
433
+
434
+ Hook scripts should print single-line markers:
435
+
436
+ ```text
437
+ PARALLAX_CLAUDE_HOOK {"event":"Notification","notification_type":"permission_prompt","message":"..."}
438
+ ```
439
+
440
+ Supported high-value events:
441
+ - `Notification` (`permission_prompt`, `elicitation_dialog`, `idle_prompt`)
442
+ - `PreToolUse` (includes `tool_name`)
443
+ - `TaskCompleted`
444
+ - `SessionEnd`
445
+
446
+ The adapter consumes these markers in:
447
+ - `detectBlockingPrompt()`
448
+ - `detectLoading()`
449
+ - `detectToolRunning()`
450
+ - `detectTaskComplete()`
451
+ - `detectReady()`
452
+ - `detectExit()`
453
+
454
+ ### Generate Hook Config Template
455
+
456
+ ```typescript
457
+ const claude = new ClaudeAdapter();
458
+ const protocol = claude.getHookTelemetryProtocol();
459
+
460
+ // protocol.scriptPath
461
+ // protocol.scriptContent
462
+ // protocol.settingsHooks
463
+ ```
464
+
465
+ `settingsHooks` is ready to merge into `.claude/settings.json` under `hooks`.
466
+
467
+ ## Gemini Hook Telemetry (Optional)
468
+
469
+ Gemini CLI hooks can emit deterministic lifecycle markers so PTY orchestration does not rely only on screen-text heuristics.
470
+
471
+ `GeminiAdapter` supports this as an opt-in mode:
472
+
473
+ ```typescript
474
+ const session = await manager.spawn({
475
+ name: 'gemini-agent',
476
+ type: 'gemini',
477
+ workdir: '/project',
478
+ adapterConfig: {
479
+ googleKey: process.env.GEMINI_API_KEY,
480
+ geminiHookTelemetry: true,
481
+ },
482
+ });
483
+ ```
484
+
485
+ When enabled, the adapter sets:
486
+ - `PARALLAX_GEMINI_HOOK_TELEMETRY=1`
487
+ - `PARALLAX_GEMINI_HOOK_MARKER_PREFIX=PARALLAX_GEMINI_HOOK` (or your override)
488
+
489
+ ### Marker Protocol
490
+
491
+ Gemini hook command output must be valid JSON. The helper script emits marker lines via `systemMessage`:
492
+
493
+ ```text
494
+ PARALLAX_GEMINI_HOOK {"event":"BeforeTool","tool_name":"run_shell_command"}
495
+ ```
496
+
497
+ Supported high-value events:
498
+ - `Notification` (`ToolPermission`)
499
+ - `BeforeTool` (includes `tool_name`)
500
+ - `AfterAgent`
501
+ - `SessionEnd`
502
+
503
+ The adapter consumes these markers in:
504
+ - `detectBlockingPrompt()`
505
+ - `detectLoading()`
506
+ - `detectToolRunning()`
507
+ - `detectTaskComplete()`
508
+ - `detectReady()`
509
+ - `detectExit()`
510
+
511
+ ### Generate Hook Config Template
512
+
513
+ ```typescript
514
+ const gemini = new GeminiAdapter();
515
+ const protocol = gemini.getHookTelemetryProtocol();
516
+
517
+ // protocol.scriptPath
518
+ // protocol.scriptContent
519
+ // protocol.settingsHooks
520
+ ```
521
+
522
+ `settingsHooks` is ready to merge into `.gemini/settings.json` under `hooks`.
523
+
399
524
  ## Creating Custom Adapters
400
525
 
401
526
  Extend `BaseCodingAdapter` to create adapters for other coding CLIs:
@@ -479,7 +604,7 @@ const allAdapters = createAllAdapters();
479
604
  const claude = createAdapter('claude');
480
605
 
481
606
  // Available adapter types
482
- console.log(Object.keys(ADAPTER_TYPES)); // ['claude', 'gemini', 'codex', 'aider']
607
+ console.log(Object.keys(ADAPTER_TYPES)); // ['claude', 'gemini', 'codex', 'aider', 'hermes']
483
608
  ```
484
609
 
485
610
  ## License
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "coding-agent-adapters",
3
- "version": "0.8.8",
4
- "description": "CLI adapters for AI coding agents - Claude Code, Gemini CLI, OpenAI Codex, and Aider",
3
+ "version": "0.11.0",
4
+ "description": "CLI adapters for AI coding agents - Claude Code, Gemini CLI, OpenAI Codex, Aider, and Hermes Agent",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
7
7
  "module": "./dist/index.js",
@@ -33,6 +33,7 @@
33
33
  "gemini",
34
34
  "codex",
35
35
  "aider",
36
+ "hermes",
36
37
  "ai-agents",
37
38
  "coding-agents",
38
39
  "pty-manager"