@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.
- package/.claude/agent-memory/tester/MEMORY.md +3 -0
- package/.claude/agent-memory/tester/project-ppm-test-conventions.md +32 -0
- package/.env.example +1 -0
- package/.github/workflows/release.yml +46 -0
- package/README.md +349 -0
- package/bun.lock +1217 -0
- package/components.json +21 -0
- package/docs/code-standards.md +574 -0
- package/docs/codebase-summary.md +294 -0
- package/docs/deployment-guide.md +631 -0
- package/docs/design-guidelines.md +661 -0
- package/docs/project-overview-pdr.md +142 -0
- package/docs/project-roadmap.md +400 -0
- package/docs/system-architecture.md +459 -0
- package/package.json +68 -0
- package/plans/260314-2009-ppm-implementation/phase-01-project-skeleton.md +81 -0
- package/plans/260314-2009-ppm-implementation/phase-02-backend-core.md +148 -0
- package/plans/260314-2009-ppm-implementation/phase-03-frontend-shell.md +256 -0
- package/plans/260314-2009-ppm-implementation/phase-04-file-explorer-editor.md +120 -0
- package/plans/260314-2009-ppm-implementation/phase-05-web-terminal.md +174 -0
- package/plans/260314-2009-ppm-implementation/phase-06-git-integration.md +244 -0
- package/plans/260314-2009-ppm-implementation/phase-07-ai-chat.md +242 -0
- package/plans/260314-2009-ppm-implementation/phase-08-cli-commands.md +143 -0
- package/plans/260314-2009-ppm-implementation/phase-09-pwa-build-deploy.md +209 -0
- package/plans/260314-2009-ppm-implementation/phase-10-testing.md +311 -0
- package/plans/260314-2009-ppm-implementation/plan.md +202 -0
- package/plans/260315-0356-project-scoped-api-refactor/phase-01-backend-project-router.md +145 -0
- package/plans/260315-0356-project-scoped-api-refactor/phase-02-frontend-api-migration.md +107 -0
- package/plans/260315-0356-project-scoped-api-refactor/phase-03-per-project-tabs.md +100 -0
- package/plans/260315-0356-project-scoped-api-refactor/phase-04-websocket-migration.md +66 -0
- package/plans/260315-0356-project-scoped-api-refactor/plan.md +87 -0
- package/plans/reports/brainstorm-260314-1938-final-techstack.md +342 -0
- package/plans/reports/docs-manager-260315-1314-documentation-creation.md +386 -0
- package/plans/reports/fullstack-developer-260314-2252-phase-02-backend-core.md +57 -0
- package/plans/reports/fullstack-developer-260314-2253-phase-03-frontend-shell.md +70 -0
- package/plans/reports/fullstack-developer-260314-2300-phase-04-05-file-api-terminal-ws.md +49 -0
- package/plans/reports/fullstack-developer-260314-2300-phase-04-05-file-explorer-editor-terminal.md +52 -0
- package/plans/reports/fullstack-developer-260314-2307-ai-chat-phase7.md +58 -0
- package/plans/reports/fullstack-developer-260314-2307-phase-06-git-integration.md +33 -0
- package/plans/reports/research-260314-1911-ppm-tech-stack.md +318 -0
- package/plans/reports/research-260314-1930-claude-code-integration.md +293 -0
- package/plans/reports/researcher-260314-2232-node-pty-bun-crash-analysis.md +305 -0
- package/plans/reports/researcher-260314-2232-ui-style.md +942 -0
- package/plans/reports/researcher-260315-0300-opcode-claude-interaction.md +745 -0
- package/plans/reports/researcher-260315-0303-opcode-deep-analysis.md +742 -0
- package/plans/reports/researcher-260315-0305-claude-agent-sdk-github-research.md +423 -0
- package/plans/reports/tester-260314-2053-initial-test-suite.md +81 -0
- package/ppm.example.yaml +14 -0
- package/repomix-output.xml +23745 -0
- package/scripts/build.ts +13 -0
- package/src/cli/commands/chat-cmd.ts +259 -0
- package/src/cli/commands/config-cmd.ts +121 -0
- package/src/cli/commands/git-cmd.ts +315 -0
- package/src/cli/commands/init.ts +57 -0
- package/src/cli/commands/open.ts +19 -0
- package/src/cli/commands/projects.ts +100 -0
- package/src/cli/commands/start.ts +3 -0
- package/src/cli/commands/stop.ts +33 -0
- package/src/cli/utils/project-resolver.ts +27 -0
- package/src/index.ts +59 -0
- package/src/providers/claude-agent-sdk.ts +499 -0
- package/src/providers/claude-binary-finder.ts +256 -0
- package/src/providers/claude-code-cli.ts +413 -0
- package/src/providers/claude-process-registry.ts +106 -0
- package/src/providers/mock-provider.ts +171 -0
- package/src/providers/provider.interface.ts +10 -0
- package/src/providers/registry.ts +45 -0
- package/src/server/helpers/resolve-project.ts +22 -0
- package/src/server/index.ts +181 -0
- package/src/server/middleware/auth.ts +30 -0
- package/src/server/routes/chat.ts +153 -0
- package/src/server/routes/files.ts +168 -0
- package/src/server/routes/git.ts +261 -0
- package/src/server/routes/project-scoped.ts +27 -0
- package/src/server/routes/projects.ts +57 -0
- package/src/server/routes/static.ts +26 -0
- package/src/server/ws/chat.ts +130 -0
- package/src/server/ws/terminal.ts +89 -0
- package/src/services/chat.service.ts +110 -0
- package/src/services/claude-usage.service.ts +113 -0
- package/src/services/config.service.ts +90 -0
- package/src/services/file.service.ts +261 -0
- package/src/services/git-dirs.service.ts +112 -0
- package/src/services/git.service.ts +372 -0
- package/src/services/project.service.ts +107 -0
- package/src/services/slash-items.service.ts +184 -0
- package/src/services/terminal.service.ts +212 -0
- package/src/types/api.ts +37 -0
- package/src/types/chat.ts +92 -0
- package/src/types/config.ts +41 -0
- package/src/types/git.ts +50 -0
- package/src/types/project.ts +18 -0
- package/src/types/terminal.ts +20 -0
- package/src/web/app.tsx +168 -0
- package/src/web/components/auth/login-screen.tsx +88 -0
- package/src/web/components/chat/attachment-chips.tsx +55 -0
- package/src/web/components/chat/chat-placeholder.tsx +10 -0
- package/src/web/components/chat/chat-tab.tsx +301 -0
- package/src/web/components/chat/file-picker.tsx +126 -0
- package/src/web/components/chat/message-input.tsx +420 -0
- package/src/web/components/chat/message-list.tsx +838 -0
- package/src/web/components/chat/session-picker.tsx +139 -0
- package/src/web/components/chat/slash-command-picker.tsx +135 -0
- package/src/web/components/chat/usage-badge.tsx +186 -0
- package/src/web/components/editor/code-editor.tsx +329 -0
- package/src/web/components/editor/diff-viewer.tsx +276 -0
- package/src/web/components/editor/editor-placeholder.tsx +10 -0
- package/src/web/components/explorer/file-actions.tsx +191 -0
- package/src/web/components/explorer/file-tree.tsx +298 -0
- package/src/web/components/git/git-graph.tsx +727 -0
- package/src/web/components/git/git-placeholder.tsx +55 -0
- package/src/web/components/git/git-status-panel.tsx +850 -0
- package/src/web/components/layout/mobile-drawer.tsx +137 -0
- package/src/web/components/layout/mobile-nav.tsx +103 -0
- package/src/web/components/layout/sidebar.tsx +90 -0
- package/src/web/components/layout/tab-bar.tsx +152 -0
- package/src/web/components/layout/tab-content.tsx +85 -0
- package/src/web/components/projects/dir-suggest.tsx +152 -0
- package/src/web/components/projects/project-list.tsx +187 -0
- package/src/web/components/settings/settings-tab.tsx +57 -0
- package/src/web/components/terminal/terminal-placeholder.tsx +10 -0
- package/src/web/components/terminal/terminal-tab.tsx +133 -0
- package/src/web/components/ui/button.tsx +64 -0
- package/src/web/components/ui/context-menu.tsx +250 -0
- package/src/web/components/ui/dialog.tsx +156 -0
- package/src/web/components/ui/dropdown-menu.tsx +257 -0
- package/src/web/components/ui/input.tsx +21 -0
- package/src/web/components/ui/scroll-area.tsx +56 -0
- package/src/web/components/ui/separator.tsx +26 -0
- package/src/web/components/ui/sonner.tsx +40 -0
- package/src/web/components/ui/tabs.tsx +91 -0
- package/src/web/components/ui/tooltip.tsx +57 -0
- package/src/web/hooks/use-chat.ts +420 -0
- package/src/web/hooks/use-terminal.ts +182 -0
- package/src/web/hooks/use-url-sync.ts +66 -0
- package/src/web/hooks/use-websocket.ts +48 -0
- package/src/web/index.html +16 -0
- package/src/web/lib/api-client.ts +90 -0
- package/src/web/lib/file-support.ts +68 -0
- package/src/web/lib/utils.ts +6 -0
- package/src/web/lib/ws-client.ts +100 -0
- package/src/web/main.tsx +10 -0
- package/src/web/public/icon-192.svg +5 -0
- package/src/web/public/icon-512.svg +5 -0
- package/src/web/stores/file-store.ts +81 -0
- package/src/web/stores/project-store.ts +50 -0
- package/src/web/stores/settings-store.ts +65 -0
- package/src/web/stores/tab-store.ts +187 -0
- package/src/web/styles/globals.css +227 -0
- package/src/web/vite-env.d.ts +1 -0
- package/tests/integration/api/chat-routes.test.ts +95 -0
- package/tests/integration/claude-agent-sdk-integration.test.ts +228 -0
- package/tests/integration/ws/chat-websocket.test.ts +312 -0
- package/tests/test-setup.ts +5 -0
- package/tests/unit/providers/claude-agent-sdk.test.ts +339 -0
- package/tests/unit/providers/mock-provider.test.ts +143 -0
- package/tests/unit/services/chat-service.test.ts +100 -0
- package/tsconfig.json +32 -0
- 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**
|