@hienlh/ppm 0.1.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 (159) hide show
  1. package/.claude/agent-memory/tester/MEMORY.md +3 -0
  2. package/.claude/agent-memory/tester/project-ppm-test-conventions.md +32 -0
  3. package/.env.example +1 -0
  4. package/.github/workflows/release.yml +46 -0
  5. package/README.md +349 -0
  6. package/bun.lock +1217 -0
  7. package/components.json +21 -0
  8. package/docs/code-standards.md +574 -0
  9. package/docs/codebase-summary.md +294 -0
  10. package/docs/deployment-guide.md +631 -0
  11. package/docs/design-guidelines.md +661 -0
  12. package/docs/project-overview-pdr.md +142 -0
  13. package/docs/project-roadmap.md +400 -0
  14. package/docs/system-architecture.md +459 -0
  15. package/package.json +68 -0
  16. package/plans/260314-2009-ppm-implementation/phase-01-project-skeleton.md +81 -0
  17. package/plans/260314-2009-ppm-implementation/phase-02-backend-core.md +148 -0
  18. package/plans/260314-2009-ppm-implementation/phase-03-frontend-shell.md +256 -0
  19. package/plans/260314-2009-ppm-implementation/phase-04-file-explorer-editor.md +120 -0
  20. package/plans/260314-2009-ppm-implementation/phase-05-web-terminal.md +174 -0
  21. package/plans/260314-2009-ppm-implementation/phase-06-git-integration.md +244 -0
  22. package/plans/260314-2009-ppm-implementation/phase-07-ai-chat.md +242 -0
  23. package/plans/260314-2009-ppm-implementation/phase-08-cli-commands.md +143 -0
  24. package/plans/260314-2009-ppm-implementation/phase-09-pwa-build-deploy.md +209 -0
  25. package/plans/260314-2009-ppm-implementation/phase-10-testing.md +311 -0
  26. package/plans/260314-2009-ppm-implementation/plan.md +202 -0
  27. package/plans/260315-0356-project-scoped-api-refactor/phase-01-backend-project-router.md +145 -0
  28. package/plans/260315-0356-project-scoped-api-refactor/phase-02-frontend-api-migration.md +107 -0
  29. package/plans/260315-0356-project-scoped-api-refactor/phase-03-per-project-tabs.md +100 -0
  30. package/plans/260315-0356-project-scoped-api-refactor/phase-04-websocket-migration.md +66 -0
  31. package/plans/260315-0356-project-scoped-api-refactor/plan.md +87 -0
  32. package/plans/reports/brainstorm-260314-1938-final-techstack.md +342 -0
  33. package/plans/reports/docs-manager-260315-1314-documentation-creation.md +386 -0
  34. package/plans/reports/fullstack-developer-260314-2252-phase-02-backend-core.md +57 -0
  35. package/plans/reports/fullstack-developer-260314-2253-phase-03-frontend-shell.md +70 -0
  36. package/plans/reports/fullstack-developer-260314-2300-phase-04-05-file-api-terminal-ws.md +49 -0
  37. package/plans/reports/fullstack-developer-260314-2300-phase-04-05-file-explorer-editor-terminal.md +52 -0
  38. package/plans/reports/fullstack-developer-260314-2307-ai-chat-phase7.md +58 -0
  39. package/plans/reports/fullstack-developer-260314-2307-phase-06-git-integration.md +33 -0
  40. package/plans/reports/research-260314-1911-ppm-tech-stack.md +318 -0
  41. package/plans/reports/research-260314-1930-claude-code-integration.md +293 -0
  42. package/plans/reports/researcher-260314-2232-node-pty-bun-crash-analysis.md +305 -0
  43. package/plans/reports/researcher-260314-2232-ui-style.md +942 -0
  44. package/plans/reports/researcher-260315-0300-opcode-claude-interaction.md +745 -0
  45. package/plans/reports/researcher-260315-0303-opcode-deep-analysis.md +742 -0
  46. package/plans/reports/researcher-260315-0305-claude-agent-sdk-github-research.md +423 -0
  47. package/plans/reports/tester-260314-2053-initial-test-suite.md +81 -0
  48. package/ppm.example.yaml +14 -0
  49. package/repomix-output.xml +23745 -0
  50. package/scripts/build.ts +13 -0
  51. package/src/cli/commands/chat-cmd.ts +259 -0
  52. package/src/cli/commands/config-cmd.ts +121 -0
  53. package/src/cli/commands/git-cmd.ts +315 -0
  54. package/src/cli/commands/init.ts +57 -0
  55. package/src/cli/commands/open.ts +19 -0
  56. package/src/cli/commands/projects.ts +100 -0
  57. package/src/cli/commands/start.ts +3 -0
  58. package/src/cli/commands/stop.ts +33 -0
  59. package/src/cli/utils/project-resolver.ts +27 -0
  60. package/src/index.ts +59 -0
  61. package/src/providers/claude-agent-sdk.ts +499 -0
  62. package/src/providers/claude-binary-finder.ts +256 -0
  63. package/src/providers/claude-code-cli.ts +413 -0
  64. package/src/providers/claude-process-registry.ts +106 -0
  65. package/src/providers/mock-provider.ts +171 -0
  66. package/src/providers/provider.interface.ts +10 -0
  67. package/src/providers/registry.ts +45 -0
  68. package/src/server/helpers/resolve-project.ts +22 -0
  69. package/src/server/index.ts +181 -0
  70. package/src/server/middleware/auth.ts +30 -0
  71. package/src/server/routes/chat.ts +153 -0
  72. package/src/server/routes/files.ts +168 -0
  73. package/src/server/routes/git.ts +261 -0
  74. package/src/server/routes/project-scoped.ts +27 -0
  75. package/src/server/routes/projects.ts +57 -0
  76. package/src/server/routes/static.ts +26 -0
  77. package/src/server/ws/chat.ts +130 -0
  78. package/src/server/ws/terminal.ts +89 -0
  79. package/src/services/chat.service.ts +110 -0
  80. package/src/services/claude-usage.service.ts +113 -0
  81. package/src/services/config.service.ts +90 -0
  82. package/src/services/file.service.ts +261 -0
  83. package/src/services/git-dirs.service.ts +112 -0
  84. package/src/services/git.service.ts +372 -0
  85. package/src/services/project.service.ts +107 -0
  86. package/src/services/slash-items.service.ts +184 -0
  87. package/src/services/terminal.service.ts +212 -0
  88. package/src/types/api.ts +37 -0
  89. package/src/types/chat.ts +92 -0
  90. package/src/types/config.ts +41 -0
  91. package/src/types/git.ts +50 -0
  92. package/src/types/project.ts +18 -0
  93. package/src/types/terminal.ts +20 -0
  94. package/src/web/app.tsx +168 -0
  95. package/src/web/components/auth/login-screen.tsx +88 -0
  96. package/src/web/components/chat/attachment-chips.tsx +55 -0
  97. package/src/web/components/chat/chat-placeholder.tsx +10 -0
  98. package/src/web/components/chat/chat-tab.tsx +301 -0
  99. package/src/web/components/chat/file-picker.tsx +126 -0
  100. package/src/web/components/chat/message-input.tsx +420 -0
  101. package/src/web/components/chat/message-list.tsx +838 -0
  102. package/src/web/components/chat/session-picker.tsx +139 -0
  103. package/src/web/components/chat/slash-command-picker.tsx +135 -0
  104. package/src/web/components/chat/usage-badge.tsx +186 -0
  105. package/src/web/components/editor/code-editor.tsx +329 -0
  106. package/src/web/components/editor/diff-viewer.tsx +276 -0
  107. package/src/web/components/editor/editor-placeholder.tsx +10 -0
  108. package/src/web/components/explorer/file-actions.tsx +191 -0
  109. package/src/web/components/explorer/file-tree.tsx +298 -0
  110. package/src/web/components/git/git-graph.tsx +727 -0
  111. package/src/web/components/git/git-placeholder.tsx +55 -0
  112. package/src/web/components/git/git-status-panel.tsx +850 -0
  113. package/src/web/components/layout/mobile-drawer.tsx +137 -0
  114. package/src/web/components/layout/mobile-nav.tsx +103 -0
  115. package/src/web/components/layout/sidebar.tsx +90 -0
  116. package/src/web/components/layout/tab-bar.tsx +152 -0
  117. package/src/web/components/layout/tab-content.tsx +85 -0
  118. package/src/web/components/projects/dir-suggest.tsx +152 -0
  119. package/src/web/components/projects/project-list.tsx +187 -0
  120. package/src/web/components/settings/settings-tab.tsx +57 -0
  121. package/src/web/components/terminal/terminal-placeholder.tsx +10 -0
  122. package/src/web/components/terminal/terminal-tab.tsx +133 -0
  123. package/src/web/components/ui/button.tsx +64 -0
  124. package/src/web/components/ui/context-menu.tsx +250 -0
  125. package/src/web/components/ui/dialog.tsx +156 -0
  126. package/src/web/components/ui/dropdown-menu.tsx +257 -0
  127. package/src/web/components/ui/input.tsx +21 -0
  128. package/src/web/components/ui/scroll-area.tsx +56 -0
  129. package/src/web/components/ui/separator.tsx +26 -0
  130. package/src/web/components/ui/sonner.tsx +40 -0
  131. package/src/web/components/ui/tabs.tsx +91 -0
  132. package/src/web/components/ui/tooltip.tsx +57 -0
  133. package/src/web/hooks/use-chat.ts +420 -0
  134. package/src/web/hooks/use-terminal.ts +182 -0
  135. package/src/web/hooks/use-url-sync.ts +66 -0
  136. package/src/web/hooks/use-websocket.ts +48 -0
  137. package/src/web/index.html +16 -0
  138. package/src/web/lib/api-client.ts +90 -0
  139. package/src/web/lib/file-support.ts +68 -0
  140. package/src/web/lib/utils.ts +6 -0
  141. package/src/web/lib/ws-client.ts +100 -0
  142. package/src/web/main.tsx +10 -0
  143. package/src/web/public/icon-192.svg +5 -0
  144. package/src/web/public/icon-512.svg +5 -0
  145. package/src/web/stores/file-store.ts +81 -0
  146. package/src/web/stores/project-store.ts +50 -0
  147. package/src/web/stores/settings-store.ts +65 -0
  148. package/src/web/stores/tab-store.ts +187 -0
  149. package/src/web/styles/globals.css +227 -0
  150. package/src/web/vite-env.d.ts +1 -0
  151. package/tests/integration/api/chat-routes.test.ts +95 -0
  152. package/tests/integration/claude-agent-sdk-integration.test.ts +228 -0
  153. package/tests/integration/ws/chat-websocket.test.ts +312 -0
  154. package/tests/test-setup.ts +5 -0
  155. package/tests/unit/providers/claude-agent-sdk.test.ts +339 -0
  156. package/tests/unit/providers/mock-provider.test.ts +143 -0
  157. package/tests/unit/services/chat-service.test.ts +100 -0
  158. package/tsconfig.json +32 -0
  159. package/vite.config.ts +62 -0
@@ -0,0 +1,745 @@
1
+ # Research Report: Opcode - Claude Code GUI Integration
2
+
3
+ **Date:** 2026-03-15
4
+ **Status:** Complete
5
+ **Scope:** Architecture analysis, Claude integration patterns, API design, agent system
6
+
7
+ ---
8
+
9
+ ## Executive Summary
10
+
11
+ **Opcode** is a sophisticated desktop GUI application that wraps and extends the Claude Code CLI with project management, agent automation, session tracking, and usage analytics. It does NOT integrate with Anthropic's Claude API directly; instead, it acts as a sophisticated launcher and monitor for the Claude Code CLI tool.
12
+
13
+ **Key finding:** Opcode's primary interaction model is process spawning—it discovers the Claude binary on the user's system, spawns child processes with specific flags, captures streaming JSON output, and relays it to the user via WebSocket or Tauri IPC. This architecture enables both desktop (Tauri) and web deployments.
14
+
15
+ ---
16
+
17
+ ## 1. What is Opcode?
18
+
19
+ ### Project Identity
20
+ - **Description:** "A powerful GUI app and Toolkit for Claude Code"
21
+ - **Type:** Cross-platform desktop application + optional web server
22
+ - **Author:** Independent developer (not affiliated with Anthropic)
23
+ - **Licensing:** MIT (implied from code structure)
24
+
25
+ ### Core Purpose
26
+ Opcode bridges the CLI-first design of Claude Code with a visual, project-centric interface by:
27
+ 1. Discovering and managing Claude Code CLI installations on the user's system
28
+ 2. Wrapping Claude execution in a session/project tracking framework
29
+ 3. Providing autonomous agents with customizable behavior
30
+ 4. Tracking API usage, costs, and performance metrics
31
+ 5. Managing MCP (Model Context Protocol) servers for extended capabilities
32
+ 6. Implementing checkpoint/timeline system for session versioning
33
+
34
+ ### User Workflows Enabled
35
+ - **Interactive Development:** Browse projects, create/resume sessions, execute prompts with real-time output streaming
36
+ - **Agent Automation:** Define custom agents with system prompts, run them unattended with background process isolation
37
+ - **Analytics & Auditing:** Track token usage, costs, and performance across models and projects
38
+ - **Session Management:** Checkpoint current state, fork sessions, view diffs, time-travel within session history
39
+
40
+ ---
41
+
42
+ ## 2. Claude Code Integration Mechanism
43
+
44
+ ### Binary Discovery Strategy
45
+
46
+ Opcode implements multi-layered binary discovery (not API-based):
47
+
48
+ **Discovery methods (in priority order):**
49
+ 1. Check SQLite database (`agents.db`) for cached path with validity verification
50
+ 2. Use system commands (`which` on Unix, `where` on Windows) to find in PATH
51
+ 3. Scan Node Version Manager (NVM) installations and active environment
52
+ 4. Check standard installation paths:
53
+ - `/usr/local/bin`
54
+ - Homebrew directories (`/opt/homebrew/bin`, etc.)
55
+ - User-specific locations (`~/.local/bin`, `~/.cargo/bin`)
56
+
57
+ **Selection logic:** Prioritizes installations with semantic version information, prefers newer versions, and validates runtime paths.
58
+
59
+ ### Process Spawning Architecture
60
+
61
+ When executing Claude, opcode constructs commands like:
62
+
63
+ ```bash
64
+ claude -p "your prompt here" \
65
+ --model claude-3-5-sonnet \
66
+ --output-format stream-json \
67
+ --dangerously-skip-permissions \
68
+ [--system-prompt "agent instructions"] \
69
+ [--resume session-id | -c]
70
+ ```
71
+
72
+ **Key flags:**
73
+ - `-p` — Prompt/task input
74
+ - `--model` — Model selection (opus/sonnet/haiku)
75
+ - `--system-prompt` — Custom agent instructions
76
+ - `--output-format stream-json` — Newline-delimited JSON for structured output
77
+ - `--dangerously-skip-permissions` — Bypass safety checks (for trusted agents)
78
+ - `-c` — Continue existing session
79
+ - `--resume SESSION_ID` — Restore previous session
80
+
81
+ ### Output Handling
82
+
83
+ **Async streaming pipeline:**
84
+ 1. **Stdout capture:** Uses `tokio::io::BufReader` to read lines from Claude process
85
+ 2. **JSON parsing:** Each line is newline-delimited JSON with format:
86
+ ```json
87
+ {"type": "system", "subtype": "init", "session_id": "..."}
88
+ {"type": "message", "content": "..."}
89
+ {"type": "system", "subtype": "done"}
90
+ ```
91
+ 3. **Session ID extraction:** Reads `session_id` from initial system message
92
+ 4. **Live broadcast:** Emits via Tauri events (desktop) or WebSocket (web):
93
+ - Desktop: `"claude-output:{session_id}"` event
94
+ - Web: Sends JSON over persistent WebSocket connection
95
+ 5. **Persistence:** Stores full output in JSONL files at `~/.claude/projects/{project_id}/{session_id}.jsonl`
96
+
97
+ ### Environment Setup
98
+
99
+ Opcode explicitly manages environment variables to ensure Claude can find dependencies:
100
+
101
+ ```rust
102
+ // Inherited: PATH, HOME, NODE_PATH, https_proxy, http_proxy
103
+ // Added conditionally:
104
+ // - NVM_BIN directories (if Claude from NVM)
105
+ // - Homebrew bin directories (if Claude from Homebrew)
106
+ ```
107
+
108
+ This prevents "node not found" errors when Claude is installed via package managers.
109
+
110
+ ---
111
+
112
+ ## 3. Claude Code Communication Protocols
113
+
114
+ ### Primary Protocol: Command-Line Interface (CLI)
115
+
116
+ Opcode does NOT use:
117
+ - REST/HTTP API to Claude
118
+ - WebSocket to Claude service
119
+ - gRPC or protobuf
120
+ - Any Anthropic SDK
121
+
122
+ Instead, it uses **local process invocation** via spawn() with structured argument passing.
123
+
124
+ ### Tauri IPC (Frontend-Backend)
125
+
126
+ Frontend communicates with Rust backend via Tauri's invoke system:
127
+
128
+ ```typescript
129
+ // Frontend (TypeScript)
130
+ await invoke<SessionResult>("continue_claude_code", {
131
+ project_path: "/path/to/project",
132
+ prompt: "user prompt",
133
+ model: "claude-3-5-sonnet"
134
+ })
135
+
136
+ // Emitted events back to frontend:
137
+ listen("claude-output:session-123", (event) => {
138
+ console.log(event.payload) // JSON line from Claude
139
+ })
140
+ ```
141
+
142
+ ### Web Server Alternative
143
+
144
+ Opcode includes an optional Axum-based HTTP server (for web deployment):
145
+
146
+ ```
147
+ POST /ws/claude
148
+ {
149
+ "project": "/path/to/project",
150
+ "prompt": "your prompt",
151
+ "model": "sonnet",
152
+ "command": "execute" | "continue" | "resume"
153
+ }
154
+ ```
155
+
156
+ **WebSocket flow:**
157
+ - Client sends JSON request → WebSocket upgrade
158
+ - Backend spawns Claude process
159
+ - Each stdout line → sent as JSON message on WS
160
+ - Process terminates → WS closes
161
+
162
+ **Note:** Web mode deliberately disables direct Claude execution (`POST /api/sessions/execute` returns error "Claude execution is not available in web mode"). The web server is primarily for reading session history, not execution.
163
+
164
+ ### Data Format: Stream-JSON
165
+
166
+ Claude output format: **newline-delimited JSON (JSONL)**
167
+
168
+ ```json
169
+ {"type":"system","subtype":"init","session_id":"abc123","model":"claude-3-5-sonnet"}
170
+ {"type":"message","content":"I'll help with that.","role":"assistant"}
171
+ {"type":"tool_call","tool":"bash","input":{"command":"ls -la"}}
172
+ {"type":"tool_result","tool":"bash","output":"total 42\n..."}
173
+ {"type":"system","subtype":"done","total_tokens":1234,"cost_usd":0.045}
174
+ ```
175
+
176
+ ---
177
+
178
+ ## 4. Architecture & Key Components
179
+
180
+ ### High-Level Diagram
181
+
182
+ ```
183
+ ┌──────────────────────────────────────┐
184
+ │ Frontend (React 18 + TypeScript) │
185
+ │ - Tab manager │
186
+ │ - Project browser │
187
+ │ - Agent UI │
188
+ │ - Settings, usage dashboard │
189
+ └─────────────┬────────────────────────┘
190
+ │ Tauri invoke / WebSocket
191
+ ┌─────────────▼────────────────────────┐
192
+ │ Backend (Rust + Tauri 2) │
193
+ │ ┌──────────────────────────────────┐│
194
+ │ │ Commands Layer ││
195
+ │ │ ├─ claude.rs (82KB) ││
196
+ │ │ ├─ agents.rs (70KB) ││
197
+ │ │ ├─ mcp.rs ││
198
+ │ │ ├─ storage.rs / usage.rs ││
199
+ │ │ └─ checkpoint.rs ││
200
+ │ └──────────────────────────────────┘│
201
+ │ ┌──────────────────────────────────┐│
202
+ │ │ Process Management ││
203
+ │ │ ├─ registry.rs (process tracking)││
204
+ │ │ ├─ binary discovery ││
205
+ │ │ └─ environment setup ││
206
+ │ └──────────────────────────────────┘│
207
+ │ ┌──────────────────────────────────┐│
208
+ │ │ Data Layer ││
209
+ │ │ ├─ SQLite (agents.db) ││
210
+ │ │ ├─ JSONL files (session history) ││
211
+ │ │ └─ Local filesystem ││
212
+ │ └──────────────────────────────────┘│
213
+ └─────────────┬────────────────────────┘
214
+ │ Process spawn / stdio
215
+ ┌─────────────▼──────────────────────┐
216
+ │ Claude Code CLI (~/.claude/...) │
217
+ │ - Session management │
218
+ │ - Tool execution (bash, file ops) │
219
+ │ - API calls to Claude model │
220
+ └──────────────────────────────────────┘
221
+ ```
222
+
223
+ ### Core Modules
224
+
225
+ #### A. Frontend (TypeScript/React)
226
+
227
+ **Key services (src/lib/):**
228
+ - `api.ts` (53KB) — Comprehensive API abstraction wrapping all Tauri commands
229
+ - `apiAdapter.ts` (16KB) — Adapter pattern for API calls with error handling
230
+ - `sessionPersistence.ts` — Tab/session state management
231
+ - `tabPersistence.ts` — UI state persistence
232
+
233
+ **Components:**
234
+ - Project browser
235
+ - Session/chat tabs with streaming output
236
+ - Agent definition UI
237
+ - Usage analytics dashboard
238
+ - MCP server manager
239
+ - CLAUDE.md editor with markdown preview
240
+
241
+ **State management:**
242
+ - React Context for theme, output caching, tab state
243
+ - Tauri event listeners for background process updates
244
+
245
+ #### B. Backend (Rust/Tauri)
246
+
247
+ **Command handlers (src-tauri/src/commands/):**
248
+ 1. **claude.rs** (82KB) — Core Claude execution
249
+ - `execute_claude_code()` — New session
250
+ - `continue_claude_code()` — Extend conversation
251
+ - `resume_claude_code()` — Restore by ID
252
+ - Process spawning and output streaming
253
+
254
+ 2. **agents.rs** (70KB) — Agent system
255
+ - Agent CRUD operations
256
+ - Background execution with process isolation
257
+ - Execution history and metrics calculation
258
+ - GitHub integration for agent discovery
259
+
260
+ 3. **mcp.rs** (25KB) — Model Context Protocol
261
+ - Server configuration (stdio/SSE transport)
262
+ - Scope management (local/project/user)
263
+ - Import from Claude Desktop config
264
+
265
+ 4. **checkpoint.rs** — Session versioning
266
+ - Create snapshots of project state
267
+ - Timeline navigation
268
+ - Diff generation between checkpoints
269
+ - Fork existing sessions
270
+
271
+ 5. **storage.rs** (17KB) — Direct SQLite access
272
+ - CRUD on arbitrary tables
273
+ - Pagination and search
274
+ - Raw SQL execution
275
+
276
+ 6. **usage.rs** (25KB) — Analytics
277
+ - Token counting across sessions
278
+ - Cost calculation by model
279
+ - Trend analysis and visualization
280
+
281
+ **Process management (src-tauri/src/process/):**
282
+ - **registry.rs** (18KB) — Process lifecycle tracking
283
+ - Register agent runs and Claude sessions
284
+ - Track process IDs, exit codes
285
+ - Graceful termination (SIGTERM → SIGKILL)
286
+ - Live output buffering
287
+ - Cleanup of finished processes
288
+
289
+ - **claude_binary.rs** (24KB) — Binary discovery
290
+ - Multi-strategy location algorithm
291
+ - Version comparison and selection
292
+ - Environment variable setup
293
+ - NVM and Homebrew integration
294
+
295
+ #### C. Data Layer
296
+
297
+ **SQLite (agents.db):**
298
+ - Agent definitions and configurations
299
+ - Execution runs with status/timestamps
300
+ - Process metadata and output
301
+ - Cached Claude binary paths
302
+ - User preferences
303
+
304
+ **JSONL session history:**
305
+ - Location: `~/.claude/projects/{project_id}/{session_id}.jsonl`
306
+ - One JSON object per line
307
+ - Contains full chat history with tool calls/results
308
+ - Used for analytics and session restoration
309
+
310
+ **Local filesystem:**
311
+ - Project directories (`~/.claude/projects/`)
312
+ - Agent configuration files (`.opcode.json`)
313
+ - Checkpoint data
314
+
315
+ ### Request Flow: Executing a Prompt
316
+
317
+ ```
318
+ 1. User enters prompt in UI
319
+ 2. Frontend calls: invoke("execute_claude_code", {project, prompt, model})
320
+ 3. Backend:
321
+ a) Discovers Claude binary
322
+ b) Sets up environment variables
323
+ c) Spawns child process: `claude -p "prompt" --model sonnet --output-format stream-json`
324
+ d) Starts async task reading stdout
325
+ 4. Claude process:
326
+ a) Generates session ID
327
+ b) Sends system init message (JSON)
328
+ c) Processes prompt, calls tools as needed
329
+ d) Sends message chunks, tool calls, results (JSON lines)
330
+ e) Exits with final summary
331
+ 5. Backend:
332
+ a) Each output line → parsed as JSON
333
+ b) Emitted via Tauri event: "claude-output:{session_id}"
334
+ c) Saved to JSONL file
335
+ d) Stored in ProcessRegistry for UI querying
336
+ 6. Frontend:
337
+ a) Listens for events
338
+ b) Renders streaming output in real-time
339
+ c) On completion, stores session metadata in SQLite
340
+ ```
341
+
342
+ ---
343
+
344
+ ## 5. Agent System Architecture
345
+
346
+ ### Agent Configuration Format
347
+
348
+ Agents are defined as `.opcode.json` files with this structure:
349
+
350
+ ```json
351
+ {
352
+ "version": 1,
353
+ "exported_at": "2025-01-23T14:29:58.156063+00:00",
354
+ "agent": {
355
+ "name": "Security Scanner",
356
+ "icon": "shield",
357
+ "model": "opus",
358
+ "system_prompt": "You are a security specialist...",
359
+ "default_task": "Review the codebase for security issues."
360
+ }
361
+ }
362
+ ```
363
+
364
+ **Supported icons:** bot, shield, code, terminal, database, globe, file-text, git-branch
365
+
366
+ ### Agent Execution Model
367
+
368
+ Agents run as **isolated background processes**, not within the main Claude session:
369
+
370
+ ```rust
371
+ // Backend spawns:
372
+ claude --system-prompt "agent instructions" \
373
+ -p "task" \
374
+ --model opus \
375
+ --output-format stream-json \
376
+ --dangerously-skip-permissions
377
+
378
+ // Frontend polls for status:
379
+ polling: get_agent_run_status(run_id)
380
+ → AgentRun { status: "running"/"completed", output: [...] }
381
+ ```
382
+
383
+ **Process isolation benefits:**
384
+ - Agents don't block the main UI
385
+ - Crash in one agent doesn't affect others
386
+ - Can run multiple agents in parallel
387
+ - Resources (CPU/memory) scoped per agent
388
+
389
+ ### Multi-Agent Orchestration Example
390
+
391
+ **Security Scanner Agent** demonstrates parent-child architecture:
392
+
393
+ ```
394
+ Parent: Security Scanner
395
+ ├─ Child 1: Codebase Intelligence Analyzer
396
+ │ (extracts tech stack, auth, storage)
397
+ ├─ Child 2: Threat Modeling Specialist
398
+ │ (maps assets, STRIDE analysis)
399
+ ├─ Child 3: Vulnerability Scanner
400
+ │ (OWASP Top 10, CWE classification)
401
+ ├─ Child 4: Exploit Developer
402
+ │ (POC demonstrations)
403
+ ├─ Child 5: Security Architect
404
+ │ (remediation strategies)
405
+ └─ Child 6: Security Report Writer
406
+ (produce professional assessment)
407
+ ```
408
+
409
+ Each child agent is spawned as a separate process with focused instructions, enabling specialized analysis and parallel execution.
410
+
411
+ ### Pre-built Agents
412
+
413
+ **Git Commit Bot** (Sonnet)
414
+ - Analyzes staged changes
415
+ - Generates Conventional Commits
416
+ - Auto-resolves merge conflicts
417
+ - Pushes to remote
418
+
419
+ **Security Scanner** (Opus)
420
+ - 6-phase orchestration
421
+ - OWASP/CWE framework
422
+ - CVSS scoring
423
+ - PoC exploitation verification
424
+
425
+ **Unit Tests Bot** (Opus)
426
+ - Test generation
427
+ - Coverage optimization
428
+ - Quality validation
429
+
430
+ ### Agent Discovery & Import
431
+
432
+ Agents can be:
433
+ - Defined in the UI and exported as `.opcode.json`
434
+ - Imported from GitHub (via GitHub API)
435
+ - Imported from local filesystem
436
+ - Shared via pull requests to opcode repo
437
+
438
+ ---
439
+
440
+ ## 6. Technology Stack
441
+
442
+ ### Frontend
443
+ - **Framework:** React 18.3.1
444
+ - **Language:** TypeScript
445
+ - **Build:** Vite 6
446
+ - **UI Components:** Radix UI + shadcn/ui
447
+ - **Styling:** Tailwind CSS 3
448
+ - **Animations:** Framer Motion
449
+ - **Markdown:** React Markdown with syntax highlighting
450
+ - **Forms:** React Hook Form
451
+ - **Validation:** Zod
452
+ - **Data visualization:** Recharts
453
+ - **Analytics:** PostHog
454
+ - **Desktop bridge:** Tauri API + plugins (dialog, shell, global-shortcut, opener, filesystem)
455
+
456
+ ### Backend (Rust)
457
+ - **Desktop framework:** Tauri 2
458
+ - **Web framework:** Axum 0.8 (optional)
459
+ - **Async runtime:** Tokio 1.0
460
+ - **HTTP client:** Reqwest 0.12
461
+ - **WebSocket:** Tower, Axum upgrades
462
+ - **Database:** Rusqlite 0.32 (SQLite)
463
+ - **Serialization:** Serde + Serde JSON + Serde YAML
464
+ - **Crypto:** SHA2
465
+ - **Utilities:** Chrono, UUID, Base64, Regex, Walkdir
466
+ - **System:** Clap (CLI), Dirs (platform paths), Which (binary location)
467
+
468
+ ### Deployment Platforms
469
+ - macOS (10.15+), Linux (AppImage/deb/rpm), Windows (.exe/.msi)
470
+ - Cross-platform via Tauri
471
+
472
+ ---
473
+
474
+ ## 7. Integration Patterns for Third-Party Projects
475
+
476
+ ### Option A: Consume Opcode's Web API
477
+
478
+ If building a tool that needs to integrate with opcode:
479
+
480
+ ```bash
481
+ # Start opcode web server (if available)
482
+ ./opcode --web-server --port 3000
483
+
484
+ # Call REST endpoints
485
+ POST http://localhost:3000/api/projects
486
+ POST http://localhost:3000/ws/claude
487
+ GET http://localhost:3000/api/usage/stats
488
+ ```
489
+
490
+ **Limitations:** Web mode does NOT support Claude execution, only read-only operations.
491
+
492
+ ### Option B: Spawn Claude Directly
493
+
494
+ Don't depend on opcode; spawn Claude CLI yourself:
495
+
496
+ ```typescript
497
+ import { spawn } from "child_process";
498
+
499
+ const process = spawn("claude", [
500
+ "-p", "your prompt",
501
+ "--model", "claude-3-5-sonnet",
502
+ "--output-format", "stream-json"
503
+ ]);
504
+
505
+ process.stdout.on("data", (chunk) => {
506
+ const lines = chunk.toString().split("\n");
507
+ lines.forEach(line => {
508
+ if (line) console.log(JSON.parse(line));
509
+ });
510
+ });
511
+ ```
512
+
513
+ **Advantages:** Direct control, no opcode dependency
514
+
515
+ ### Option C: Use Opcode as a Library
516
+
517
+ Opcode is not published as an npm package, but:
518
+ 1. Fork and embed its command layer
519
+ 2. Use Tauri's codebase as reference for process management
520
+ 3. Adapt the API abstraction layer for your needs
521
+
522
+ ### Option D: Create Custom Agents
523
+
524
+ Define agents in `.opcode.json` format and distribute:
525
+
526
+ ```json
527
+ {
528
+ "version": 1,
529
+ "agent": {
530
+ "name": "Custom Analyzer",
531
+ "icon": "bot",
532
+ "model": "sonnet",
533
+ "system_prompt": "You are a specialized analyzer...",
534
+ "default_task": "Analyze and report."
535
+ }
536
+ }
537
+ ```
538
+
539
+ Users can import via Opcode UI → Agents → Import from file.
540
+
541
+ ---
542
+
543
+ ## 8. Key Design Decisions & Implications
544
+
545
+ ### 1. Process Spawning vs. API Integration
546
+
547
+ **Decision:** Spawn Claude CLI as child processes instead of calling Anthropic API.
548
+
549
+ **Rationale:**
550
+ - Claude Code CLI handles authentication (via `.claude/config` or `ANTHROPIC_API_KEY`)
551
+ - Leverages Claude's full tool ecosystem (bash, file operations, git)
552
+ - Sessions persist across CLI invocations (opcode doesn't manage API tokens)
553
+ - Runs locally; opcode is offline-capable
554
+
555
+ **Trade-off:** Opcode depends on Claude Code CLI installation; cannot run without it.
556
+
557
+ ### 2. SQLite for Metadata Only
558
+
559
+ **Decision:** Use SQLite for agents, runs, settings; session history in JSONL files.
560
+
561
+ **Rationale:**
562
+ - SQLite fast for structured queries (agent lookups, run status)
563
+ - JSONL preserves full streaming output without schema migrations
564
+ - Session history stays compatible with Claude's own JSONL format
565
+
566
+ **Trade-off:** No relational guarantees between SQLite and JSONL; must keep in sync.
567
+
568
+ ### 3. Tauri Desktop + Optional Web Server
569
+
570
+ **Decision:** Primary deployment is Tauri desktop app; optional Axum server for web/headless.
571
+
572
+ **Rationale:**
573
+ - Tauri provides native OS integration (file dialogs, clipboard, global shortcuts)
574
+ - Web server useful for teams/CI environments
575
+ - Single codebase serves both contexts
576
+
577
+ **Trade-off:** Web mode is read-only by design (Claude execution restricted to desktop).
578
+
579
+ ### 4. Agent Isolation via Separate Processes
580
+
581
+ **Decision:** Each agent runs in a dedicated background process, not within parent agent's stdio.
582
+
583
+ **Rationale:**
584
+ - Prevents cascading failures
585
+ - Enables parallel execution
586
+ - Clear resource boundaries
587
+
588
+ **Trade-off:** Complex orchestration; parent agents must parse child output via JSONL.
589
+
590
+ ### 5. No Direct Claude API Dependency
591
+
592
+ **Decision:** Never import Anthropic's Claude SDK or REST client.
593
+
594
+ **Rationale:**
595
+ - Avoids token/authentication management
596
+ - Reduces dependency surface
597
+ - Leverages Claude Code's environment setup
598
+
599
+ **Trade-off:** Cannot access Claude API directly; must use CLI as proxy.
600
+
601
+ ---
602
+
603
+ ## 9. Security Considerations
604
+
605
+ ### Permission Model
606
+ - `--dangerously-skip-permissions` flag opts OUT of Claude's safety checks (for trusted agents only)
607
+ - Agents run in user context with full filesystem access
608
+ - MCP server scope (local/project/user) controls capability visibility
609
+
610
+ ### Process Isolation
611
+ - Each agent runs as separate OS process
612
+ - Can be killed independently
613
+ - Signals handled gracefully (SIGTERM → SIGKILL escalation)
614
+
615
+ ### Data Storage
616
+ - Session history stored locally in `~/.claude/projects/`
617
+ - SQLite database in `~/.claude/`
618
+ - No data sent to opcode servers (open source, local-first design)
619
+
620
+ ### Supply Chain
621
+ - Dependencies pinned in Cargo.lock and package-lock.json
622
+ - No auto-updates to Claude CLI; users manage manually
623
+ - Opcode checks for binary validity before execution
624
+
625
+ ---
626
+
627
+ ## 10. How PPM Can Integrate with Opcode
628
+
629
+ ### Scenario 1: Use Opcode as Session Manager
630
+
631
+ If PPM wants to delegate session/project management to opcode:
632
+
633
+ ```typescript
634
+ // PPM calls opcode's REST API (if web server enabled)
635
+ const sessions = await fetch("http://localhost:3000/api/projects/myproject/sessions");
636
+ const result = await fetch("http://localhost:3000/ws/claude", {
637
+ method: "POST",
638
+ body: JSON.stringify({
639
+ project: "/path/to/project",
640
+ prompt: "Generate tests",
641
+ model: "sonnet",
642
+ command: "execute"
643
+ })
644
+ });
645
+ ```
646
+
647
+ **Benefits:** Opcode handles binary discovery, output streaming, JSONL persistence.
648
+ **Drawbacks:** Web mode read-only; requires running opcode service.
649
+
650
+ ### Scenario 2: Adopt Opcode's Agent Format
651
+
652
+ If PPM wants to support agent definitions:
653
+
654
+ ```json
655
+ {
656
+ "version": 1,
657
+ "agent": {
658
+ "name": "PPM Code Reviewer",
659
+ "icon": "code",
660
+ "model": "opus",
661
+ "system_prompt": "Review code quality for the PPM project...",
662
+ "default_task": "Review the pull request."
663
+ }
664
+ }
665
+ ```
666
+
667
+ Export/import via `.opcode.json`; integrate with PPM's CI/CD.
668
+
669
+ ### Scenario 3: Reference Opcode's Architecture
670
+
671
+ If PPM wants to build its own Claude integration (not depending on opcode):
672
+
673
+ **Key patterns to adopt:**
674
+ 1. Multi-strategy binary discovery (PATH → NVM → Homebrew → standard paths)
675
+ 2. Stream-JSON output format with async parsing
676
+ 3. Process registry for background execution tracking
677
+ 4. SQLite for agent metadata, JSONL for session history
678
+ 5. Tauri for desktop, optional Axum server for web
679
+ 6. Environment variable setup for Node.js dependencies
680
+
681
+ ### Scenario 4: Create PPM-Specific Agents
682
+
683
+ Define agents that know PPM's codebase structure:
684
+
685
+ ```json
686
+ {
687
+ "version": 1,
688
+ "agent": {
689
+ "name": "PPM Debugger",
690
+ "icon": "terminal",
691
+ "model": "opus",
692
+ "system_prompt": "You are debugging the PPM project. PPM is a Git UI tool written in TypeScript/React with Tauri backend...",
693
+ "default_task": "Debug the failing test case and propose fixes."
694
+ }
695
+ }
696
+ ```
697
+
698
+ Then opcode (or PPM's own agent runner) executes this agent on PPM's codebase.
699
+
700
+ ---
701
+
702
+ ## 11. Unresolved Questions / Gaps
703
+
704
+ 1. **Hot-reload for agents:** How does opcode reload agent definitions if edited in UI while execution is running?
705
+
706
+ 2. **Streaming cancellation:** Can users cancel a running Claude process mid-execution? How is SIGTERM handled if stdout is mid-JSON line?
707
+
708
+ 3. **Multi-session conflicts:** If two agents modify the same project file simultaneously, how does opcode handle file locks or conflict detection?
709
+
710
+ 4. **Web server authentication:** The optional Axum web server—does it support authentication (Basic, JWT, OAuth)? Or is it intended for trusted local networks only?
711
+
712
+ 5. **MCP server protocol:** How does opcode's MCP integration differ from Claude Code's native MCP support? Does it proxy or extend?
713
+
714
+ 6. **Checkpoint diff algorithm:** How are diffs generated between checkpoint states? Are they line-based, AST-based, or semantic-aware?
715
+
716
+ 7. **Cost calculation accuracy:** How does opcode infer token counts from JSONL output? Does it parse `total_tokens` field from Claude response, or does it estimate?
717
+
718
+ 8. **Agent versioning:** Can agents be versioned? If an agent's system_prompt changes, does opcode track history or warn about breaking changes?
719
+
720
+ 9. **Process timeout:** What happens if a Claude process hangs or never returns? Is there a configurable timeout mechanism?
721
+
722
+ 10. **Parallel execution limits:** When running multiple agents in parallel, is there a cap on concurrent processes? How are resources managed?
723
+
724
+ ---
725
+
726
+ ## Summary
727
+
728
+ **Opcode is a sophisticated desktop UI + optional web server wrapper around Claude Code CLI.** It excels at:
729
+
730
+ - **Project-centric session management** — browse, organize, and resume coding sessions
731
+ - **Agent automation** — define reusable agents with custom instructions, run in isolation
732
+ - **Usage analytics** — track tokens, costs, and performance trends
733
+ - **Session checkpointing** — snapshot and restore project state
734
+
735
+ **Integration approach:** Opcode abstracts Claude via process spawning, not API calls. For PPM, the most relevant patterns are:
736
+ 1. Binary discovery and environment setup (adopt for robustness)
737
+ 2. Stream-JSON output parsing (compatible format)
738
+ 3. Process registry design (for background task tracking)
739
+ 4. Agent configuration format (standardized, shareable)
740
+
741
+ PPM can either integrate with opcode as a service, adopt its architecture patterns, or remain independent while consuming its standardized agent format.
742
+
743
+ ---
744
+
745
+ **End Report**