Skip to content

Commit f5e7f3b

Browse files
committed
feat(core): cc for desktop
1 parent 7055027 commit f5e7f3b

39 files changed

Lines changed: 4182 additions & 82 deletions

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"af": "yarn oa",
1919
"oa": "r oa.ts",
2020
"dev:web": "yarn workspace @afk/app dev",
21-
"dev:electron": "yarn workspace @afk/electron dev",
21+
"dev:electron": "yarn --cwd packages/frontend/electron dev",
2222
"dev:server": "yarn oa server dev",
2323
"dev": "concurrently --kill-others --success first \"yarn dev:web\" \"yarn dev:server\"",
2424
"build": "yarn oa build",
Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,267 @@
1+
# Client Implementation Guide for Computer-Use-CC Tool
2+
3+
## Overview
4+
5+
The client receives task parameters from the server and constructs a Claude CLI command to execute the task autonomously.
6+
7+
## Command Construction
8+
9+
### Basic Command Structure
10+
11+
```bash
12+
claude --add-dir <working-directory> [--yes] --max-turns {maxIterations} -p "{prompt}"
13+
```
14+
15+
### Parameters from Server
16+
17+
```typescript
18+
interface ComputerUseCCRequest {
19+
type: 'computer-use-cc-request';
20+
taskId: string;
21+
prompt: string; // Natural-language prompt for Claude Code CLI
22+
maxIterations?: number; // Default: 5
23+
autoApprove?: boolean; // Default: true
24+
}
25+
```
26+
27+
### Client Implementation Example
28+
29+
```typescript
30+
// Electron Handler
31+
export class ComputerUseCCHandler {
32+
@IpcHandler('executeComputerUseCC')
33+
async execute(event, data: ComputerUseCCRequest) {
34+
const { prompt, maxIterations, autoApprove, taskId } = data;
35+
36+
// Build Claude CLI command
37+
const args = [
38+
'chat',
39+
'--print', // Non-interactive mode
40+
'--max-turns',
41+
maxIterations.toString(),
42+
'-p',
43+
prompt, // The natural-language prompt
44+
];
45+
46+
if (autoApprove) {
47+
args.push('--yes'); // Auto-approve changes
48+
}
49+
50+
// Add context from current workspace
51+
const contextFiles = await this.getRelevantFiles();
52+
contextFiles.forEach(file => {
53+
args.push('--file', file);
54+
});
55+
56+
// Execute in current project directory
57+
const proc = spawn('claude', args, {
58+
cwd: this.getCurrentWorkspace(),
59+
env: { ...process.env },
60+
});
61+
62+
// Stream output back
63+
proc.stdout.on('data', chunk => {
64+
this.streamToServer(taskId, chunk.toString());
65+
});
66+
67+
// Handle completion
68+
proc.on('close', code => {
69+
if (code === 0) {
70+
this.sendCallback(taskId, 'completed', output);
71+
} else {
72+
this.sendCallback(taskId, 'failed', `Exit code: ${code}`);
73+
}
74+
});
75+
}
76+
}
77+
```
78+
79+
## Prompt Examples and Expected Commands
80+
81+
### Example 1 – List GitHub repositories
82+
83+
```typescript
84+
// Server sends:
85+
{
86+
prompt: "List all GitHub repositories under ~/Documents (max depth 2)",
87+
maxIterations: 3,
88+
autoApprove: true
89+
}
90+
91+
// Client executes:
92+
claude --add-dir ~/Documents --yes --max-turns 3 -p "List all GitHub repositories under ~/Documents (max depth 2)"
93+
```
94+
95+
### Example 2 – Find duplicate images
96+
97+
```typescript
98+
// Server sends:
99+
{
100+
prompt: "Find duplicate *.jpg or *.png files in ~/Pictures and show their paths",
101+
maxIterations: 4,
102+
autoApprove: false
103+
}
104+
105+
// Client executes:
106+
claude --add-dir ~/Pictures --max-turns 4 -p "Find duplicate *.jpg or *.png files in ~/Pictures and show their paths"
107+
```
108+
109+
### Example 3 – Organise downloads folder
110+
111+
```typescript
112+
// Server sends:
113+
{
114+
prompt: "Move every .zip file older than 30 days from ~/Downloads to ~/Archives/old-zips",
115+
maxIterations: 5,
116+
autoApprove: true
117+
}
118+
119+
// Client executes:
120+
claude --add-dir ~/Downloads --yes --max-turns 5 -p "Move every .zip file older than 30 days from ~/Downloads to ~/Archives/old-zips"
121+
```
122+
123+
## Client Responsibilities
124+
125+
### 1. Context Detection
126+
127+
The client should automatically:
128+
129+
- Detect current working directory
130+
- Find relevant files based on task content
131+
- Include open files in editor (if available)
132+
- Add project configuration files (package.json, tsconfig.json, etc.)
133+
134+
### 2. Environment Setup
135+
136+
```typescript
137+
const env = {
138+
...process.env,
139+
// Ensure Claude has access to tools
140+
PATH: process.env.PATH,
141+
// Add project-specific env vars if needed
142+
NODE_ENV: 'development',
143+
};
144+
```
145+
146+
### 3. Sending Results
147+
148+
Wait until the Claude CLI process exits, collect its full stdout, and send a single callback:
149+
150+
```typescript
151+
proc.on('close', code => {
152+
const status = code === 0 ? 'completed' : 'failed';
153+
sendCallback(taskId, status, output);
154+
});
155+
```
156+
157+
### 4. Error Handling
158+
159+
Handle various failure scenarios:
160+
161+
```typescript
162+
// Claude CLI not found
163+
if (!isClaudeInstalled()) {
164+
return sendError(taskId, 'Claude CLI is not installed. Please install it first.');
165+
}
166+
167+
// Process errors
168+
proc.on('error', err => {
169+
if (err.code === 'ENOENT') {
170+
sendError(taskId, 'Claude CLI not found in PATH');
171+
} else {
172+
sendError(taskId, `Process error: ${err.message}`);
173+
}
174+
});
175+
176+
// Timeout handling
177+
const timeout = setTimeout(
178+
() => {
179+
proc.kill();
180+
sendError(taskId, 'Task exceeded maximum execution time');
181+
},
182+
10 * 60 * 1000
183+
); // 10 minutes max
184+
```
185+
186+
## Best Practices
187+
188+
### 1. Task Precision
189+
190+
The server should generate precise, actionable tasks:
191+
192+
- ✅ "Fix the TypeScript error in auth.service.ts line 45 about missing return type"
193+
- ✅ "Add input validation to all POST endpoints in the user controller"
194+
- ❌ "Make the code better"
195+
- ❌ "Fix bugs"
196+
197+
### 2. Iteration Control
198+
199+
- Start with fewer iterations (3-5) for simple tasks
200+
- Use more iterations (7-10) for complex refactoring
201+
- Monitor progress through streaming output
202+
203+
### 3. Auto-Approval
204+
205+
- `autoApprove: true` for safe operations (adding tests, documentation)
206+
- `autoApprove: false` for risky operations (database migrations, API changes)
207+
208+
## Security Considerations
209+
210+
### 1. Command Injection Prevention
211+
212+
```typescript
213+
// Sanitize task input
214+
const sanitizedTask = task.replace(/[`$]/g, '\\$&');
215+
```
216+
217+
### 2. Working Directory Restrictions
218+
219+
```typescript
220+
// Ensure Claude only works in allowed directories
221+
const allowedPaths = ['/home/user/projects', '/Users/*/Documents'];
222+
if (!isPathAllowed(cwd, allowedPaths)) {
223+
throw new Error('Working directory not allowed');
224+
}
225+
```
226+
227+
### 3. Resource Limits
228+
229+
```typescript
230+
// Set resource limits for the Claude process
231+
const proc = spawn('claude', args, {
232+
cwd,
233+
env,
234+
// Limit memory and CPU
235+
stdio: ['ignore', 'pipe', 'pipe'],
236+
detached: false,
237+
});
238+
```
239+
240+
## Testing the Implementation
241+
242+
### Manual Test Command
243+
244+
```bash
245+
# Test the exact command that will be generated
246+
claude --add-dir . --yes --max-turns 5 -p "Add error handling to all async functions in src/"
247+
248+
# With specific files
249+
claude --add-dir . --yes --max-turns 3 -p "Add JSDoc comments to all exported functions" --file src/index.ts --file src/utils.ts
250+
```
251+
252+
### Integration Test
253+
254+
```typescript
255+
describe('ComputerUseCCHandler', () => {
256+
it('should construct correct Claude command', () => {
257+
const handler = new ComputerUseCCHandler();
258+
const command = handler.buildCommand({
259+
prompt: 'Fix TypeScript errors',
260+
maxIterations: 5,
261+
autoApprove: true,
262+
});
263+
264+
expect(command).toEqual(['claude', '--add-dir', '.', '--yes', '--max-turns', '5', '-p', 'Fix TypeScript errors']);
265+
});
266+
});
267+
```

0 commit comments

Comments
 (0)