|
| 1 | +--- |
| 2 | +phase: design |
| 3 | +title: "Agent Manager Package - Design" |
| 4 | +feature: agent-manager |
| 5 | +description: Architecture and design for the @ai-devkit/agent-manager package |
| 6 | +--- |
| 7 | + |
| 8 | +# Design: @ai-devkit/agent-manager Package |
| 9 | + |
| 10 | +## Architecture Overview |
| 11 | + |
| 12 | +```mermaid |
| 13 | +graph TD |
| 14 | + subgraph "@ai-devkit/agent-manager" |
| 15 | + AM[AgentManager] -->|registers| AA[AgentAdapter Interface] |
| 16 | + AA -->|implemented by| CCA[ClaudeCodeAdapter] |
| 17 | + AA -->|implemented by| FutureAdapter["Future Adapters..."] |
| 18 | +
|
| 19 | + CCA -->|uses| PU[Process Utils] |
| 20 | + CCA -->|uses| FU[File Utils] |
| 21 | +
|
| 22 | + TFM[TerminalFocusManager] -->|uses| PU |
| 23 | +
|
| 24 | + Types[Types & Enums] -->|consumed by| AM |
| 25 | + Types -->|consumed by| CCA |
| 26 | + Types -->|consumed by| TFM |
| 27 | + end |
| 28 | +
|
| 29 | + subgraph "CLI Package (consumer)" |
| 30 | + CMD[agent command] -->|imports| AM |
| 31 | + CMD -->|imports| CCA |
| 32 | + CMD -->|imports| TFM |
| 33 | + CMD -->|imports| Types |
| 34 | + end |
| 35 | +``` |
| 36 | + |
| 37 | +### Package Directory Structure |
| 38 | + |
| 39 | +``` |
| 40 | +packages/agent-manager/ |
| 41 | +├── src/ |
| 42 | +│ ├── index.ts # Public API barrel export |
| 43 | +│ ├── AgentManager.ts # Core orchestrator |
| 44 | +│ ├── adapters/ |
| 45 | +│ │ ├── AgentAdapter.ts # Interface, types, enums |
| 46 | +│ │ ├── ClaudeCodeAdapter.ts # Claude Code detection |
| 47 | +│ │ └── index.ts # Adapter barrel export |
| 48 | +│ ├── terminal/ |
| 49 | +│ │ ├── TerminalFocusManager.ts # Terminal focus (macOS) |
| 50 | +│ │ └── index.ts # Terminal barrel export |
| 51 | +│ └── utils/ |
| 52 | +│ ├── process.ts # Process detection utilities |
| 53 | +│ ├── file.ts # File reading utilities |
| 54 | +│ └── index.ts # Utils barrel export |
| 55 | +├── src/__tests__/ |
| 56 | +│ ├── AgentManager.test.ts |
| 57 | +│ └── adapters/ |
| 58 | +│ └── ClaudeCodeAdapter.test.ts |
| 59 | +├── package.json |
| 60 | +├── tsconfig.json |
| 61 | +├── jest.config.js |
| 62 | +├── project.json |
| 63 | +└── .eslintrc.json |
| 64 | +``` |
| 65 | + |
| 66 | +## Data Models |
| 67 | + |
| 68 | +Types are adapted for a data-first package contract: |
| 69 | + |
| 70 | +- **AgentType**: `'claude' | 'gemini_cli' | 'codex' | 'other'` |
| 71 | +- **AgentStatus**: Enum (`RUNNING`, `WAITING`, `IDLE`, `UNKNOWN`) |
| 72 | +- **AgentInfo**: Full agent information (name, type, status, pid, projectPath, sessionId, slug, lastActive, etc.) |
| 73 | +- **ProcessInfo**: `{ pid, command, cwd, tty }` |
| 74 | +- **AgentAdapter**: Interface with `type`, `detectAgents()`, `canHandle()` |
| 75 | +- **TerminalType**: Enum (`TMUX`, `ITERM2`, `TERMINAL_APP`, `UNKNOWN`) |
| 76 | +- **TerminalLocation**: `{ type: TerminalType, identifier, tty }` (from TerminalFocusManager) |
| 77 | + |
| 78 | +## API Design |
| 79 | + |
| 80 | +### Public Exports (`index.ts`) |
| 81 | + |
| 82 | +```typescript |
| 83 | +// Core |
| 84 | +export { AgentManager } from './AgentManager'; |
| 85 | + |
| 86 | +// Adapters |
| 87 | +export { ClaudeCodeAdapter } from './adapters/ClaudeCodeAdapter'; |
| 88 | +export type { AgentAdapter } from './adapters/AgentAdapter'; |
| 89 | +export { AgentStatus } from './adapters/AgentAdapter'; |
| 90 | +export type { AgentType, AgentInfo, ProcessInfo } from './adapters/AgentAdapter'; |
| 91 | + |
| 92 | +// Terminal |
| 93 | +export { TerminalFocusManager, TerminalType } from './terminal/TerminalFocusManager'; |
| 94 | +export type { TerminalLocation } from './terminal/TerminalFocusManager'; |
| 95 | + |
| 96 | +// Utilities |
| 97 | +export { listProcesses, getProcessCwd, getProcessTty, isProcessRunning, getProcessInfo } from './utils/process'; |
| 98 | +export type { ListProcessesOptions } from './utils/process'; |
| 99 | +export { readLastLines, readJsonLines, fileExists, readJson } from './utils/file'; |
| 100 | +``` |
| 101 | + |
| 102 | +### Usage Example |
| 103 | + |
| 104 | +```typescript |
| 105 | +import { AgentManager, ClaudeCodeAdapter } from '@ai-devkit/agent-manager'; |
| 106 | + |
| 107 | +const manager = new AgentManager(); |
| 108 | +manager.registerAdapter(new ClaudeCodeAdapter()); |
| 109 | + |
| 110 | +const agents = await manager.listAgents(); |
| 111 | +agents.forEach(agent => { |
| 112 | + console.log(`${agent.name}: ${agent.status}`); |
| 113 | +}); |
| 114 | +``` |
| 115 | + |
| 116 | +### Migration Notes |
| 117 | + |
| 118 | +- `AgentType` values are now normalized codes (`claude`, `gemini_cli`, `codex`, `other`) |
| 119 | +- `AgentInfo` no longer includes UI/display fields (`statusDisplay`, `lastActiveDisplay`) |
| 120 | +- `STATUS_CONFIG` / `StatusConfig` were removed; consumers should map presentation in their own layer |
| 121 | + |
| 122 | +## Component Breakdown |
| 123 | + |
| 124 | +### 1. AgentManager (core orchestrator) |
| 125 | +- Adapter registration/unregistration |
| 126 | +- Agent listing with parallel adapter queries |
| 127 | +- Agent resolution (exact/partial name matching) |
| 128 | +- Status-based sorting |
| 129 | +- **Extracted from**: `packages/cli/src/lib/AgentManager.ts` |
| 130 | +- **Changes**: None — direct copy |
| 131 | + |
| 132 | +### 2. AgentAdapter + Types (interface layer) |
| 133 | +- Interface contract for adapters |
| 134 | +- Type definitions and enums |
| 135 | +- Normalized agent type codes for machine-friendly integrations |
| 136 | +- **Extracted from**: `packages/cli/src/lib/adapters/AgentAdapter.ts` |
| 137 | +- **Changes**: Agent type literals normalized; display-oriented fields removed from core model |
| 138 | + |
| 139 | +### 3. ClaudeCodeAdapter (concrete adapter) |
| 140 | +- Claude Code process detection via `ps aux` |
| 141 | +- Session file reading from `~/.claude/projects/` |
| 142 | +- Status determination from JSONL entries |
| 143 | +- History-based summary extraction |
| 144 | +- **Extracted from**: `packages/cli/src/lib/adapters/ClaudeCodeAdapter.ts` |
| 145 | +- **Changes**: Import paths updated to use local `utils/` instead of `../../util/` |
| 146 | + |
| 147 | +### 4. TerminalFocusManager (terminal control) |
| 148 | +- Terminal emulator detection (tmux, iTerm2, Terminal.app) |
| 149 | +- Terminal window/pane focusing |
| 150 | +- macOS-specific AppleScript integration |
| 151 | +- **Extracted from**: `packages/cli/src/lib/TerminalFocusManager.ts` |
| 152 | +- **Changes**: Import paths updated to use local `utils/process` |
| 153 | + |
| 154 | +### 5. Process Utilities |
| 155 | +- `listProcesses()` — system process listing with filtering |
| 156 | +- `getProcessCwd()` — process working directory lookup |
| 157 | +- `getProcessTty()` — process TTY device lookup |
| 158 | +- `isProcessRunning()` — process existence check |
| 159 | +- `getProcessInfo()` — detailed single-process info |
| 160 | +- **Extracted from**: `packages/cli/src/util/process.ts` |
| 161 | +- **Changes**: `ProcessInfo` type import updated (now from `../adapters/AgentAdapter`) |
| 162 | + |
| 163 | +### 6. File Utilities |
| 164 | +- `readLastLines()` — efficient last-N-lines reading |
| 165 | +- `readJsonLines()` — JSONL file parsing |
| 166 | +- `fileExists()` — file existence check |
| 167 | +- `readJson()` — safe JSON file parsing |
| 168 | +- **Extracted from**: `packages/cli/src/util/file.ts` |
| 169 | +- **Changes**: None — direct copy |
| 170 | + |
| 171 | +## Design Decisions |
| 172 | + |
| 173 | +| Decision | Choice | Rationale | |
| 174 | +|----------|--------|-----------| |
| 175 | +| Package name | `@ai-devkit/agent-manager` | Consistent with `@ai-devkit/memory` naming | |
| 176 | +| Build system | `tsc` (not SWC) | Simpler setup; no special transforms needed; consistent with CLI package | |
| 177 | +| Runtime deps | Zero | Only Node.js built-ins used; keeps package lightweight | |
| 178 | +| Include TerminalFocusManager | Yes, as separate module | Useful for consumers; closely related to agent management | |
| 179 | +| Include utilities | Yes, within package | They're tightly coupled to adapter implementation; not general-purpose enough for a separate package | |
| 180 | +| Test framework | Jest with ts-jest | Matches existing monorepo conventions | |
| 181 | + |
| 182 | +## Non-Functional Requirements |
| 183 | + |
| 184 | +### Performance |
| 185 | +- Process listing uses `ps aux` (single exec, ~50ms typical) |
| 186 | +- Session file reading limited to last 100 lines for large JSONL files |
| 187 | +- Adapter queries run in parallel via `Promise.all` |
| 188 | + |
| 189 | +### Platform Support |
| 190 | +- Process detection: macOS and Linux (uses `ps aux`, `lsof`, `pwdx`) |
| 191 | +- Terminal focus: macOS only (AppleScript for iTerm2/Terminal.app, tmux universal) |
| 192 | + |
| 193 | +### Security |
| 194 | +- No external network calls |
| 195 | +- Reads only from `~/.claude/` directory (user-owned) |
| 196 | +- Process inspection uses standard OS tools |
| 197 | +- No secrets or credentials handled |
0 commit comments