@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,423 @@
|
|
|
1
|
+
# Claude Agent SDK GitHub Research Report
|
|
2
|
+
**Date:** 2026-03-15 | **Researcher:** Claude Code Researcher
|
|
3
|
+
|
|
4
|
+
## Executive Summary
|
|
5
|
+
|
|
6
|
+
Found comprehensive GitHub ecosystem for `@anthropic-ai/claude-agent-sdk`: official Anthropic repos, 3+ notable integration projects, extensive documentation, and production-ready code examples. SDK enables programmatic Claude Code interaction with built-in tools, streaming message loops, and session persistence.
|
|
7
|
+
|
|
8
|
+
## Official Resources
|
|
9
|
+
|
|
10
|
+
### Core Repositories
|
|
11
|
+
1. **anthropics/claude-agent-sdk-typescript** - Official TypeScript SDK
|
|
12
|
+
- NPM: `@anthropic-ai/claude-agent-sdk`
|
|
13
|
+
- Latest v0.2.76 (as of Mar 14, 2026)
|
|
14
|
+
- Requires Node.js 18+
|
|
15
|
+
- Bundled Claude Code CLI included
|
|
16
|
+
|
|
17
|
+
2. **anthropics/claude-agent-sdk-python** - Official Python SDK
|
|
18
|
+
- PyPI: `claude-agent-sdk`
|
|
19
|
+
- Parallel implementation to TypeScript
|
|
20
|
+
- Python 3.10+ required
|
|
21
|
+
|
|
22
|
+
3. **anthropics/claude-agent-sdk-demos** - Official demo repository
|
|
23
|
+
- 8+ complete working examples
|
|
24
|
+
- V2 Session API examples
|
|
25
|
+
- Production-ready patterns
|
|
26
|
+
|
|
27
|
+
## Key SDK Capabilities
|
|
28
|
+
|
|
29
|
+
### Agent Loop Architecture
|
|
30
|
+
The SDK provides a **streaming agentic loop** that:
|
|
31
|
+
1. Sends prompt to Claude with tools available
|
|
32
|
+
2. Claude evaluates & requests tool calls (or responds with text)
|
|
33
|
+
3. SDK executes tools automatically
|
|
34
|
+
4. Results feed back to Claude automatically
|
|
35
|
+
5. Loop continues until Claude produces text-only response
|
|
36
|
+
6. Final `ResultMessage` contains output, cost, session ID
|
|
37
|
+
|
|
38
|
+
**Message Types Yielded:**
|
|
39
|
+
- `SystemMessage` - Session init/lifecycle events
|
|
40
|
+
- `AssistantMessage` - Claude responses (text + tool calls)
|
|
41
|
+
- `UserMessage` - Tool results sent back to Claude
|
|
42
|
+
- `StreamEvent` - Partial message updates (when enabled)
|
|
43
|
+
- `ResultMessage` - Final result with cost, usage, session ID
|
|
44
|
+
|
|
45
|
+
### Built-in Tools Available
|
|
46
|
+
- **File ops:** `Read`, `Edit`, `Write`
|
|
47
|
+
- **Search:** `Glob`, `Grep`
|
|
48
|
+
- **Execution:** `Bash`
|
|
49
|
+
- **Web:** `WebSearch`, `WebFetch`
|
|
50
|
+
- **Orchestration:** `Agent`, `Skill`, `AskUserQuestion`, `TodoWrite`
|
|
51
|
+
- **Discovery:** `ToolSearch` (load tools on-demand)
|
|
52
|
+
- **Custom:** MCP servers support, custom tool handlers
|
|
53
|
+
|
|
54
|
+
### Core Configuration Options
|
|
55
|
+
```typescript
|
|
56
|
+
// TypeScript Options interface
|
|
57
|
+
{
|
|
58
|
+
allowedTools: string[], // Auto-approve specific tools
|
|
59
|
+
disallowedTools: string[], // Block specific tools
|
|
60
|
+
permissionMode: "default" | "acceptEdits" | "plan" | "dontAsk" | "bypassPermissions",
|
|
61
|
+
systemPrompt?: string,
|
|
62
|
+
model?: string, // Pin specific Claude model
|
|
63
|
+
maxTurns?: number, // Limit tool-use rounds
|
|
64
|
+
maxBudgetUsd?: number, // Limit spend
|
|
65
|
+
effort?: "low" | "medium" | "high" | "max",
|
|
66
|
+
settingSources?: string[], // Load CLAUDE.md, skills
|
|
67
|
+
includePartialMessages?: boolean, // Enable streaming deltas
|
|
68
|
+
mcpServers?: MCP[], // Connect external services
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Real-World Integration Projects
|
|
73
|
+
|
|
74
|
+
### 1. claude-agent-kit (JimLiu)
|
|
75
|
+
**GitHub:** [JimLiu/claude-agent-kit](https://github.com/JimLiu/claude-agent-kit)
|
|
76
|
+
|
|
77
|
+
Utility layer providing session management, message parsing, WebSocket orchestration.
|
|
78
|
+
|
|
79
|
+
**Features:**
|
|
80
|
+
- `SessionManager` for lifecycle helpers
|
|
81
|
+
- `SimpleClaudeAgentSDKClient` wrapper
|
|
82
|
+
- WebSocket handlers (Node.js + Bun variants)
|
|
83
|
+
- Local state sync with Claude
|
|
84
|
+
- Multi-client real-time support
|
|
85
|
+
|
|
86
|
+
**Example Usage:**
|
|
87
|
+
```typescript
|
|
88
|
+
import { SessionManager, SimpleClaudeAgentSDKClient } from "@claude-agent-kit/server";
|
|
89
|
+
|
|
90
|
+
const sessionManager = new SessionManager();
|
|
91
|
+
const session = sessionManager.createSession(
|
|
92
|
+
new SimpleClaudeAgentSDKClient()
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
await session.send("List open pull requests", undefined);
|
|
96
|
+
|
|
97
|
+
for (const message of session.messages) {
|
|
98
|
+
console.log(`[${message.type}]`,
|
|
99
|
+
message.content.map(part => part.content));
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Packages:** 4 scoped packages (@claude-agent-kit/messages, /server, /websocket, /bun-websocket)
|
|
104
|
+
|
|
105
|
+
### 2. kenneth-liao/claude-agent-sdk-intro
|
|
106
|
+
**GitHub:** [kenneth-liao/claude-agent-sdk-intro](https://github.com/kenneth-liao/claude-agent-sdk-intro)
|
|
107
|
+
|
|
108
|
+
Educational repository teaching fundamentals + advanced patterns.
|
|
109
|
+
|
|
110
|
+
**Modules:**
|
|
111
|
+
- Basic querying & streaming
|
|
112
|
+
- Message parsing/display
|
|
113
|
+
- Custom tool creation (3-step process: define → MCP server → configure agent)
|
|
114
|
+
- Agent configuration (options, permissions, system prompts)
|
|
115
|
+
- Conversation loops
|
|
116
|
+
- MCP integration
|
|
117
|
+
- Multi-agent systems
|
|
118
|
+
|
|
119
|
+
**Learning Focus:** When to use `query()` vs `ClaudeSDKClient`, tool permissions, subagent orchestration
|
|
120
|
+
|
|
121
|
+
### 3. weidwonder/claude_agent_sdk_oauth_demo
|
|
122
|
+
**GitHub:** [weidwonder/claude_agent_sdk_oauth_demo](https://github.com/weidwonder/claude_agent_sdk_oauth_demo)
|
|
123
|
+
|
|
124
|
+
OAuth integration patterns for Claude Pro account access via agent SDK
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Official Code Examples
|
|
129
|
+
|
|
130
|
+
### Basic Agent Loop (TypeScript)
|
|
131
|
+
```typescript
|
|
132
|
+
import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
133
|
+
|
|
134
|
+
let sessionId: string | undefined;
|
|
135
|
+
|
|
136
|
+
for await (const message of query({
|
|
137
|
+
prompt: "Review utils.py for bugs that would cause crashes. Fix any issues you find.",
|
|
138
|
+
options: {
|
|
139
|
+
allowedTools: ["Read", "Edit", "Glob"],
|
|
140
|
+
permissionMode: "acceptEdits"
|
|
141
|
+
}
|
|
142
|
+
})) {
|
|
143
|
+
// Save session ID from init message
|
|
144
|
+
if (message.type === "system" && message.subtype === "init") {
|
|
145
|
+
sessionId = message.session_id;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Handle output
|
|
149
|
+
if (message.type === "assistant" && message.message?.content) {
|
|
150
|
+
for (const block of message.message.content) {
|
|
151
|
+
if ("text" in block) {
|
|
152
|
+
console.log(block.text); // Claude's reasoning
|
|
153
|
+
} else if ("name" in block) {
|
|
154
|
+
console.log(`Tool: ${block.name}`); // Tool being called
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Handle final result
|
|
160
|
+
if (message.type === "result") {
|
|
161
|
+
if (message.subtype === "success") {
|
|
162
|
+
console.log(`Done: ${message.result}`);
|
|
163
|
+
} else if (message.subtype === "error_max_turns") {
|
|
164
|
+
console.log(`Hit turn limit. Resume session ${sessionId} to continue.`);
|
|
165
|
+
}
|
|
166
|
+
console.log(`Cost: $${message.total_cost_usd.toFixed(4)}`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Message Type Checking (Python)
|
|
172
|
+
```python
|
|
173
|
+
from claude_agent_sdk import query, AssistantMessage, ResultMessage
|
|
174
|
+
|
|
175
|
+
async for message in query(prompt="Summarize this project"):
|
|
176
|
+
if isinstance(message, AssistantMessage):
|
|
177
|
+
print(f"Turn completed: {len(message.content)} content blocks")
|
|
178
|
+
|
|
179
|
+
if isinstance(message, ResultMessage):
|
|
180
|
+
if message.subtype == "success":
|
|
181
|
+
print(message.result)
|
|
182
|
+
else:
|
|
183
|
+
print(f"Stopped: {message.subtype}")
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Permission Modes Comparison
|
|
187
|
+
```typescript
|
|
188
|
+
// Mode 1: Auto-approve edits only
|
|
189
|
+
{ permissionMode: "acceptEdits" } // Edit files auto-approve, Bash prompts
|
|
190
|
+
|
|
191
|
+
// Mode 2: Require approval callback
|
|
192
|
+
{ permissionMode: "default", canUseTool: (tool) => userApproves(tool) }
|
|
193
|
+
|
|
194
|
+
// Mode 3: Plan only (no execution)
|
|
195
|
+
{ permissionMode: "plan" } // Claude produces plan, no tool execution
|
|
196
|
+
|
|
197
|
+
// Mode 4: Locked-down (TypeScript only)
|
|
198
|
+
{ permissionMode: "dontAsk" } // Deny anything not in allowedTools
|
|
199
|
+
|
|
200
|
+
// Mode 5: Full automation (sandboxed only)
|
|
201
|
+
{ permissionMode: "bypassPermissions" } // No prompts, all allowed tools run
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Official Demo Examples
|
|
205
|
+
|
|
206
|
+
**hello-world-v2** - Recommended modern example using V2 Session API
|
|
207
|
+
- `session.send()` and `session.stream()` methods (vs single `query()` generator)
|
|
208
|
+
- Multi-turn conversation patterns
|
|
209
|
+
- Session persistence examples
|
|
210
|
+
|
|
211
|
+
**email-agent** - IMAP email assistant with:
|
|
212
|
+
- Inbox display
|
|
213
|
+
- Agentic search
|
|
214
|
+
- AI-powered email assistance
|
|
215
|
+
|
|
216
|
+
**research-agent** - Multi-agent research system:
|
|
217
|
+
- Break research into subtopics
|
|
218
|
+
- Spawn parallel researcher subagents
|
|
219
|
+
- Aggregate findings into report
|
|
220
|
+
- Live activity tracking
|
|
221
|
+
|
|
222
|
+
**simple-chat-app** - React + Express with:
|
|
223
|
+
- WebSocket integration
|
|
224
|
+
- Streaming responses
|
|
225
|
+
- Full conversation loop
|
|
226
|
+
|
|
227
|
+
**resume-generator** - End-to-end example:
|
|
228
|
+
- Web-search person's name (LinkedIn, GitHub, news)
|
|
229
|
+
- Assemble findings into .docx resume
|
|
230
|
+
|
|
231
|
+
## Installation & Setup
|
|
232
|
+
|
|
233
|
+
### TypeScript
|
|
234
|
+
```bash
|
|
235
|
+
npm install @anthropic-ai/claude-agent-sdk
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Python
|
|
239
|
+
```bash
|
|
240
|
+
uv init && uv add claude-agent-sdk
|
|
241
|
+
# or
|
|
242
|
+
python3 -m venv .venv && source .venv/bin/activate
|
|
243
|
+
pip3 install claude-agent-sdk
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### Authentication
|
|
247
|
+
```bash
|
|
248
|
+
# API key (default)
|
|
249
|
+
export ANTHROPIC_API_KEY=sk-...
|
|
250
|
+
|
|
251
|
+
# Or cloud providers
|
|
252
|
+
export CLAUDE_CODE_USE_BEDROCK=1 # Amazon Bedrock
|
|
253
|
+
export CLAUDE_CODE_USE_VERTEX=1 # Google Vertex AI
|
|
254
|
+
export CLAUDE_CODE_USE_FOUNDRY=1 # Microsoft Azure
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
## Session Management Patterns
|
|
258
|
+
|
|
259
|
+
### Resume Session (Continue Conversation)
|
|
260
|
+
```typescript
|
|
261
|
+
// Capture session ID from ResultMessage
|
|
262
|
+
const sessionId = resultMessage.session_id;
|
|
263
|
+
|
|
264
|
+
// Later: resume the same session
|
|
265
|
+
for await (const message of query({
|
|
266
|
+
prompt: "Continue refactoring the auth module",
|
|
267
|
+
options: { sessionId } // Resume with all context
|
|
268
|
+
})) {
|
|
269
|
+
// ...
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### Session Persistence with Claude Agent Kit
|
|
274
|
+
```typescript
|
|
275
|
+
const sdkClient = new SimpleClaudeAgentSDKClient();
|
|
276
|
+
const wsHandler = new WebSocketHandler(sdkClient, {
|
|
277
|
+
thinkingLevel: 'default_on'
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
// Clients send: { type: "chat", content, attachments }
|
|
281
|
+
// Server broadcasts: message_added, messages_updated, session_state_changed
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
## Cost & Performance Control
|
|
285
|
+
|
|
286
|
+
**Turn Limits (prevent runaway loops):**
|
|
287
|
+
```typescript
|
|
288
|
+
options: { maxTurns: 30 } // Stop after 30 tool-use rounds
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
**Budget Limits (control spend):**
|
|
292
|
+
```typescript
|
|
293
|
+
options: { maxBudgetUsd: 2.50 } // Stop if exceeds $2.50
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
**Effort Levels (token efficiency):**
|
|
297
|
+
```typescript
|
|
298
|
+
options: { effort: "low" } // Fast, cheap, minimal reasoning
|
|
299
|
+
options: { effort: "high" } // Thorough analysis (default TypeScript)
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
**Context Window Optimization:**
|
|
303
|
+
- Subagents start fresh (no parent history, lower context cost)
|
|
304
|
+
- MCP tool search loads tools on-demand instead of preloading all
|
|
305
|
+
- Automatic compaction when context limit approaches
|
|
306
|
+
- Project CLAUDE.md loaded via prompt caching (cost amortized)
|
|
307
|
+
|
|
308
|
+
## Hooks for Custom Behavior
|
|
309
|
+
|
|
310
|
+
Available hooks (both SDKs):
|
|
311
|
+
- `PreToolUse` - Validate/block tool calls before execution
|
|
312
|
+
- `PostToolUse` - Audit outputs, trigger side effects
|
|
313
|
+
- `UserPromptSubmit` - Inject additional context
|
|
314
|
+
- `Stop` - Validate result, save session state
|
|
315
|
+
- `SubagentStart`/`SubagentStop` - Track parallel tasks
|
|
316
|
+
- `PreCompact` - Archive transcript before summarization
|
|
317
|
+
|
|
318
|
+
**Example:**
|
|
319
|
+
```typescript
|
|
320
|
+
const hooks = {
|
|
321
|
+
PreToolUse: (tool) => {
|
|
322
|
+
if (tool.name === "Bash") {
|
|
323
|
+
// Validate bash commands before execution
|
|
324
|
+
if (tool.input.command.includes("rm -rf")) {
|
|
325
|
+
throw new Error("Dangerous command blocked");
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
## Key Architecture Decisions
|
|
333
|
+
|
|
334
|
+
**Stream vs Single-Mode:**
|
|
335
|
+
- **Streaming (async for loop):** Real-time progress, show Claude's reasoning as it works
|
|
336
|
+
- **Single-mode:** Collect all messages, process batch
|
|
337
|
+
|
|
338
|
+
**Custom Tools:**
|
|
339
|
+
- 3-step process: (1) define tool, (2) create MCP server, (3) configure in agent options
|
|
340
|
+
- TypeScript: Use `Zod` schemas for type safety
|
|
341
|
+
- Python: Use function annotations
|
|
342
|
+
|
|
343
|
+
**MCP Integration:**
|
|
344
|
+
- Connect to databases, browsers, APIs, Slack, GitHub, etc.
|
|
345
|
+
- Tools loaded on-demand via `ToolSearch`
|
|
346
|
+
- Reduces context cost vs preloading all tools
|
|
347
|
+
|
|
348
|
+
## Documentation References
|
|
349
|
+
|
|
350
|
+
- **[Agent SDK Overview](https://platform.claude.com/docs/en/agent-sdk/overview)** - Concepts & features
|
|
351
|
+
- **[Agent Loop Architecture](https://platform.claude.com/docs/en/agent-sdk/agent-loop)** - Message types, context, hooks
|
|
352
|
+
- **[TypeScript Reference](https://platform.claude.com/docs/en/agent-sdk/typescript)** - Complete API
|
|
353
|
+
- **[Python Reference](https://platform.claude.com/docs/en/agent-sdk/python)** - Complete API
|
|
354
|
+
- **[Quickstart](https://platform.claude.com/docs/en/agent-sdk/quickstart)** - 5-minute start
|
|
355
|
+
- **[Permissions](https://platform.claude.com/docs/en/agent-sdk/permissions)** - Tool control
|
|
356
|
+
- **[Hooks](https://platform.claude.com/docs/en/agent-sdk/hooks)** - Custom callbacks
|
|
357
|
+
- **[Sessions](https://platform.claude.com/docs/en/agent-sdk/sessions)** - Resume/fork patterns
|
|
358
|
+
- **[MCP](https://platform.claude.com/docs/en/agent-sdk/mcp)** - External services
|
|
359
|
+
|
|
360
|
+
## Notable Integration Patterns
|
|
361
|
+
|
|
362
|
+
### WebSocket Chat Server
|
|
363
|
+
Tools like claude-agent-kit provide ready-made WebSocket orchestration:
|
|
364
|
+
```typescript
|
|
365
|
+
// Clients connect, send messages
|
|
366
|
+
// Server maintains session state, streams responses back
|
|
367
|
+
// Multi-client sync via broadcast events
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
### Express/Node.js Backend
|
|
371
|
+
```typescript
|
|
372
|
+
// Server instantiates SimpleClaudeAgentSDKClient
|
|
373
|
+
// Per-request or per-session instances
|
|
374
|
+
// Stream results back via Express response or WebSocket
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
### Bun Runtime Support
|
|
378
|
+
Several demos target Bun runtime (fast startup, native WebSocket).
|
|
379
|
+
|
|
380
|
+
## Summary for PPM Project Context
|
|
381
|
+
|
|
382
|
+
**Relevant for Claude Code CLI Integration:**
|
|
383
|
+
1. SDK provides programmatic access to Claude Code's loop
|
|
384
|
+
2. Session persistence enables multi-turn workflows
|
|
385
|
+
3. Streaming allows real-time progress UI feedback
|
|
386
|
+
4. Custom hooks enable validation/auditing of tool calls
|
|
387
|
+
5. Tool permission modes support various approval workflows
|
|
388
|
+
6. MCP servers can extend tool catalog (GitHub, Jira, etc.)
|
|
389
|
+
|
|
390
|
+
**Integration Points for PPM:**
|
|
391
|
+
- Use `query()` for one-shot agent tasks
|
|
392
|
+
- Use `ClaudeSDKClient` for conversation-based UI
|
|
393
|
+
- Enable streaming for real-time chat display
|
|
394
|
+
- Capture session IDs for multi-turn debugging workflows
|
|
395
|
+
- Implement hooks for security/validation if needed
|
|
396
|
+
- Consider WebSocket orchestration for multi-user scenarios
|
|
397
|
+
|
|
398
|
+
---
|
|
399
|
+
|
|
400
|
+
## Unresolved Questions
|
|
401
|
+
|
|
402
|
+
1. **Performance benchmarks:** No comparative latency data between Bun vs Node.js SDK versions
|
|
403
|
+
2. **Scalability limits:** Unknown max concurrent sessions per server, rate limit thresholds
|
|
404
|
+
3. **Error recovery:** How to handle mid-loop API failures and graceful degradation strategies
|
|
405
|
+
4. **Custom tool execution:** Performance/security implications of running untrusted tool code
|
|
406
|
+
5. **MCP server overhead:** Context cost of loading many MCP servers vs ToolSearch on-demand
|
|
407
|
+
|
|
408
|
+
---
|
|
409
|
+
|
|
410
|
+
## Sources
|
|
411
|
+
|
|
412
|
+
- [anthropics/claude-agent-sdk-typescript - GitHub](https://github.com/anthropics/claude-agent-sdk-typescript)
|
|
413
|
+
- [@anthropic-ai/claude-agent-sdk - npm](https://www.npmjs.com/package/@anthropic-ai/claude-agent-sdk)
|
|
414
|
+
- [anthropics/claude-agent-sdk-python - GitHub](https://github.com/anthropics/claude-agent-sdk-python)
|
|
415
|
+
- [anthropics/claude-agent-sdk-demos - GitHub](https://github.com/anthropics/claude-agent-sdk-demos)
|
|
416
|
+
- [JimLiu/claude-agent-kit - GitHub](https://github.com/JimLiu/claude-agent-kit)
|
|
417
|
+
- [kenneth-liao/claude-agent-sdk-intro - GitHub](https://github.com/kenneth-liao/claude-agent-sdk-intro)
|
|
418
|
+
- [Agent SDK overview - Claude API Docs](https://platform.claude.com/docs/en/agent-sdk/overview)
|
|
419
|
+
- [How the agent loop works - Claude API Docs](https://platform.claude.com/docs/en/agent-sdk/agent-loop)
|
|
420
|
+
- [Agent SDK Quickstart - Claude API Docs](https://platform.claude.com/docs/en/agent-sdk/quickstart)
|
|
421
|
+
- [Agent SDK TypeScript Reference - Claude API Docs](https://platform.claude.com/docs/en/agent-sdk/typescript)
|
|
422
|
+
- [Agent SDK Python Reference - Claude API Docs](https://platform.claude.com/docs/en/agent-sdk/python)
|
|
423
|
+
- [Building agents with the Claude Agent SDK - Anthropic](https://www.anthropic.com/engineering/building-agents-with-the-claude-agent-sdk)
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Tester Report — Initial Test Suite
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-03-14
|
|
4
|
+
**Runner:** bun test v1.3.6
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Test Results Overview
|
|
9
|
+
|
|
10
|
+
| Metric | Value |
|
|
11
|
+
|--------|-------|
|
|
12
|
+
| Total tests | 106 |
|
|
13
|
+
| Passed | 106 |
|
|
14
|
+
| Failed | 0 |
|
|
15
|
+
| Skipped | 0 |
|
|
16
|
+
| Execution time | 3.65s |
|
|
17
|
+
| expect() calls | 157 |
|
|
18
|
+
| Files | 7 |
|
|
19
|
+
|
|
20
|
+
All tests pass.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Files Created
|
|
25
|
+
|
|
26
|
+
**Setup**
|
|
27
|
+
- `tests/setup.ts` — shared helpers: `createTempDir`, `cleanupDir`, `createTempGitRepo`, `buildTestApp`
|
|
28
|
+
|
|
29
|
+
**Unit tests** (`tests/unit/services/`)
|
|
30
|
+
- `config-service.test.ts` — 18 tests
|
|
31
|
+
- `project-service.test.ts` — 17 tests
|
|
32
|
+
- `file-service.test.ts` — 22 tests
|
|
33
|
+
- `git-service.test.ts` — 14 tests
|
|
34
|
+
|
|
35
|
+
**Integration tests** (`tests/integration/api/`)
|
|
36
|
+
- `projects-api.test.ts` — 10 tests (incl. auth middleware)
|
|
37
|
+
- `files-api.test.ts` — 18 tests (incl. security/traversal)
|
|
38
|
+
- `git-api.test.ts` — 10 tests
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Coverage Areas
|
|
43
|
+
|
|
44
|
+
| Service | Happy path | Error/edge | Security |
|
|
45
|
+
|---------|-----------|------------|----------|
|
|
46
|
+
| ConfigService | load/save/get/set, env var fallback | missing file fallback | - |
|
|
47
|
+
| ProjectService | list/add/remove/resolve/scan | dup add, not-found remove, CWD resolve | - |
|
|
48
|
+
| FileService | tree/read/write/create/delete/rename | missing file, outside-project | `../` traversal (5 cases) |
|
|
49
|
+
| GitService | status/branches/graphData/stage/unstage/commit | - | - |
|
|
50
|
+
| Projects API | GET/POST/DELETE | 400/404 errors, dup add | 401 auth (3 cases) |
|
|
51
|
+
| Files API | all 6 endpoints | missing params, nonexistent paths | `../` traversal (2 cases) |
|
|
52
|
+
| Git API | status/branches/stage/commit/graph | unregistered project (500) | - |
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Issues Found & Fixed During Implementation
|
|
57
|
+
|
|
58
|
+
1. **`ConfigService.load(missingPath)` falls through to CWD `ppm.yaml`** — project root has a real `ppm.yaml` with `port: 5555`. Tests that pass a nonexistent path unintentionally loaded it. Fixed by always writing a real yaml file before calling `load()`.
|
|
59
|
+
|
|
60
|
+
2. **Global `configService` singleton in git routes** — `src/server/routes/git.ts` imports the global singleton, bypassing the injected config in `buildTestApp`. Fixed by mutating `configService.config.projects` directly in `beforeEach`/`afterEach`.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Build Status
|
|
65
|
+
|
|
66
|
+
No build step required for tests. TypeScript resolves via Bun's native TS support. No type errors encountered during test execution.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Recommendations
|
|
71
|
+
|
|
72
|
+
1. **Git service error paths** — no tests for invalid repo path (non-git dir). GitService throws from simple-git; worth adding negative cases.
|
|
73
|
+
2. **GitService.diff / fileDiff** — not covered. Low priority but used by git API routes.
|
|
74
|
+
3. **Auth middleware edge cases** — malformed `Authorization` header (no `Bearer ` prefix) not tested beyond the happy-path 401.
|
|
75
|
+
4. **`createGitRoutes()` uses global `configService`** — consider refactoring to accept injected service for better testability.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Unresolved Questions
|
|
80
|
+
|
|
81
|
+
- Coverage report (`bun test --coverage`) not generated — Bun 1.3.6 coverage flags were not confirmed available. Run `bun test --coverage` to get line/branch metrics if needed.
|
package/ppm.example.yaml
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
port: 8080
|
|
2
|
+
host: 0.0.0.0
|
|
3
|
+
auth:
|
|
4
|
+
enabled: true
|
|
5
|
+
token: "change-me-to-a-secure-token"
|
|
6
|
+
projects:
|
|
7
|
+
- path: /home/user/project-a
|
|
8
|
+
name: project-a
|
|
9
|
+
ai:
|
|
10
|
+
default_provider: claude
|
|
11
|
+
providers:
|
|
12
|
+
claude:
|
|
13
|
+
type: agent-sdk
|
|
14
|
+
api_key_env: ANTHROPIC_API_KEY
|