maclat 0.1.0 → 0.2.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/dist/cli/commands.d.ts +2 -0
- package/dist/cli/commands.js +56 -0
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli/index.js +15 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/daemon/executor.d.ts +0 -9
- package/dist/daemon/executor.js +1 -212
- package/dist/daemon/executor.js.map +1 -1
- package/dist/daemon/executors/claude-code.d.ts +9 -0
- package/dist/daemon/executors/claude-code.js +154 -0
- package/dist/daemon/executors/claude-code.js.map +1 -0
- package/dist/daemon/executors/claude-sdk.d.ts +10 -0
- package/dist/daemon/executors/claude-sdk.js +99 -0
- package/dist/daemon/executors/claude-sdk.js.map +1 -0
- package/dist/daemon/executors/codex.d.ts +8 -0
- package/dist/daemon/executors/codex.js +82 -0
- package/dist/daemon/executors/codex.js.map +1 -0
- package/dist/daemon/executors/file-collector.d.ts +4 -0
- package/dist/daemon/executors/file-collector.js +32 -0
- package/dist/daemon/executors/file-collector.js.map +1 -0
- package/dist/daemon/executors/index.d.ts +3 -0
- package/dist/daemon/executors/index.js +33 -0
- package/dist/daemon/executors/index.js.map +1 -0
- package/dist/daemon/executors/prompt.d.ts +2 -0
- package/dist/daemon/executors/prompt.js +20 -0
- package/dist/daemon/executors/prompt.js.map +1 -0
- package/dist/daemon/index.js +8 -4
- package/dist/daemon/index.js.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/shared/types.d.ts +5 -0
- package/package.json +3 -2
package/dist/cli/commands.d.ts
CHANGED
package/dist/cli/commands.js
CHANGED
|
@@ -56,6 +56,62 @@ export async function myinfo() {
|
|
|
56
56
|
console.log(` Balance: ${result.balance_usdc} USDC`);
|
|
57
57
|
console.log(` ──────────────────────────\n`);
|
|
58
58
|
}
|
|
59
|
+
// --- Use (set executor) ---
|
|
60
|
+
const VALID_EXECUTORS = ['claude-code', 'anthropic', 'openrouter', 'codex'];
|
|
61
|
+
export function useExecutor(args) {
|
|
62
|
+
const executor = args[0];
|
|
63
|
+
if (!executor || !VALID_EXECUTORS.includes(executor)) {
|
|
64
|
+
console.log(`\n Usage: maclat use <provider> [api-key] [--model <model>]`);
|
|
65
|
+
console.log(`\n Providers:`);
|
|
66
|
+
console.log(` claude-code Claude Code subscription (no API key needed)`);
|
|
67
|
+
console.log(` anthropic Anthropic API (requires API key)`);
|
|
68
|
+
console.log(` openrouter OpenRouter (requires API key, 400+ models)`);
|
|
69
|
+
console.log(` codex OpenAI Codex CLI (no API key needed)`);
|
|
70
|
+
console.log(`\n Examples:`);
|
|
71
|
+
console.log(` maclat use claude-code`);
|
|
72
|
+
console.log(` maclat use anthropic sk-ant-xxx`);
|
|
73
|
+
console.log(` maclat use openrouter sk-or-xxx --model openai/gpt-4o`);
|
|
74
|
+
console.log(` maclat use codex\n`);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const config = loadConfig();
|
|
78
|
+
config.executor = executor;
|
|
79
|
+
// API key is the second positional arg (not a flag)
|
|
80
|
+
const apiKey = args[1] && !args[1].startsWith('--') ? args[1] : undefined;
|
|
81
|
+
if (apiKey) {
|
|
82
|
+
config.api_key = apiKey;
|
|
83
|
+
}
|
|
84
|
+
const model = getFlag(args, '--model');
|
|
85
|
+
if (model) {
|
|
86
|
+
config.model = model;
|
|
87
|
+
}
|
|
88
|
+
// Validate API key requirement
|
|
89
|
+
if ((executor === 'anthropic' || executor === 'openrouter') && !config.api_key) {
|
|
90
|
+
console.log(`\n Warning: ${executor} requires an API key.`);
|
|
91
|
+
console.log(` Run: maclat use ${executor} <your-api-key>\n`);
|
|
92
|
+
}
|
|
93
|
+
saveConfig(config);
|
|
94
|
+
console.log(`\n Executor set: ${executor}`);
|
|
95
|
+
if (config.api_key)
|
|
96
|
+
console.log(` API Key: ***${config.api_key.slice(-4)}`);
|
|
97
|
+
if (config.model)
|
|
98
|
+
console.log(` Model: ${config.model}`);
|
|
99
|
+
console.log('');
|
|
100
|
+
}
|
|
101
|
+
// --- Config (show) ---
|
|
102
|
+
export function showConfig() {
|
|
103
|
+
const config = loadConfig();
|
|
104
|
+
console.log(`\n Maclat Config`);
|
|
105
|
+
console.log(` ──────────────────────────`);
|
|
106
|
+
console.log(` Agent ID: ${config.agent_id || 'not registered'}`);
|
|
107
|
+
console.log(` Agent Name: ${config.agent_name || '-'}`);
|
|
108
|
+
console.log(` Gateway: ${config.gateway_url}`);
|
|
109
|
+
console.log(` Executor: ${config.executor || 'claude-code (default)'}`);
|
|
110
|
+
console.log(` API Key: ${config.api_key ? '***' + config.api_key.slice(-4) : 'not set'}`);
|
|
111
|
+
console.log(` Model: ${config.model || 'default'}`);
|
|
112
|
+
console.log(` Max Turns: ${config.max_turns || '50 (default)'}`);
|
|
113
|
+
console.log(` ──────────────────────────\n`);
|
|
114
|
+
}
|
|
59
115
|
// --- Helpers ---
|
|
60
116
|
function getFlag(args, flag) {
|
|
61
117
|
const idx = args.indexOf(flag);
|
package/dist/cli/commands.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { register, myinfo } from './commands.js';
|
|
1
|
+
import { register, myinfo, useExecutor, showConfig } from './commands.js';
|
|
2
2
|
export async function runCli(args) {
|
|
3
3
|
const command = args[0];
|
|
4
4
|
const rest = args.slice(1);
|
|
@@ -9,6 +9,12 @@ export async function runCli(args) {
|
|
|
9
9
|
case 'myinfo':
|
|
10
10
|
await myinfo();
|
|
11
11
|
break;
|
|
12
|
+
case 'use':
|
|
13
|
+
useExecutor(rest);
|
|
14
|
+
break;
|
|
15
|
+
case 'config':
|
|
16
|
+
showConfig();
|
|
17
|
+
break;
|
|
12
18
|
default:
|
|
13
19
|
printHelp();
|
|
14
20
|
}
|
|
@@ -22,6 +28,14 @@ function printHelp() {
|
|
|
22
28
|
maclat register --name "..." Register as an agent
|
|
23
29
|
maclat start Start the agent daemon
|
|
24
30
|
maclat myinfo Show your agent profile
|
|
31
|
+
maclat use <provider> [key] Set executor backend
|
|
32
|
+
maclat config Show current config
|
|
33
|
+
|
|
34
|
+
Providers:
|
|
35
|
+
claude-code Claude Code subscription (default)
|
|
36
|
+
anthropic Anthropic API
|
|
37
|
+
openrouter OpenRouter (400+ models)
|
|
38
|
+
codex OpenAI Codex CLI
|
|
25
39
|
|
|
26
40
|
Config stored at: ~/.maclat/config.json
|
|
27
41
|
`);
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE1E,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,IAAc;IACzC,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACxB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAE3B,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,UAAU;YACb,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;YACrB,MAAM;QACR,KAAK,QAAQ;YACX,MAAM,MAAM,EAAE,CAAC;YACf,MAAM;QACR,KAAK,KAAK;YACR,WAAW,CAAC,IAAI,CAAC,CAAC;YAClB,MAAM;QACR,KAAK,QAAQ;YACX,UAAU,EAAE,CAAC;YACb,MAAM;QACR;YACE,SAAS,EAAE,CAAC;IAChB,CAAC;AACH,CAAC;AAED,SAAS,SAAS;IAChB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;CAkBb,CAAC,CAAC;AACH,CAAC"}
|
|
@@ -11,12 +11,3 @@ export type OnUpdate = (type: 'text' | 'terminal', content: string) => void;
|
|
|
11
11
|
export interface JobExecutor {
|
|
12
12
|
execute(job: Job, workDir: string, onUpdate: OnUpdate): Promise<ExecutionResult>;
|
|
13
13
|
}
|
|
14
|
-
export declare class ClaudeCodeExecutor implements JobExecutor {
|
|
15
|
-
private maxTurns;
|
|
16
|
-
private claudePath;
|
|
17
|
-
constructor(maxTurns?: number);
|
|
18
|
-
execute(job: Job, workDir: string, onUpdate: OnUpdate): Promise<ExecutionResult>;
|
|
19
|
-
private handleStreamEvent;
|
|
20
|
-
private buildPrompt;
|
|
21
|
-
private collectFiles;
|
|
22
|
-
}
|
package/dist/daemon/executor.js
CHANGED
|
@@ -1,213 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
import { mkdirSync, readdirSync, readFileSync, statSync, existsSync } from 'fs';
|
|
3
|
-
import { join, relative } from 'path';
|
|
4
|
-
import { homedir } from 'os';
|
|
5
|
-
function findClaudeBinary() {
|
|
6
|
-
// Check PATH first
|
|
7
|
-
try {
|
|
8
|
-
const path = execSync('which claude 2>/dev/null', { encoding: 'utf-8' }).trim();
|
|
9
|
-
if (path)
|
|
10
|
-
return path;
|
|
11
|
-
}
|
|
12
|
-
catch { /* not in PATH */ }
|
|
13
|
-
// Check known macOS location
|
|
14
|
-
const appSupport = join(homedir(), 'Library', 'Application Support', 'Claude', 'claude-code');
|
|
15
|
-
if (existsSync(appSupport)) {
|
|
16
|
-
const versions = readdirSync(appSupport).sort().reverse(); // latest first
|
|
17
|
-
for (const v of versions) {
|
|
18
|
-
const bin = join(appSupport, v, 'claude');
|
|
19
|
-
if (existsSync(bin))
|
|
20
|
-
return bin;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
// Fallback
|
|
24
|
-
return 'claude';
|
|
25
|
-
}
|
|
26
|
-
function ts() {
|
|
27
|
-
return new Date().toLocaleTimeString('en-US', { hour12: false });
|
|
28
|
-
}
|
|
29
|
-
const GATEWAY_UPDATE_INTERVAL_MS = 60_000; // push to gateway every 60s
|
|
30
|
-
export class ClaudeCodeExecutor {
|
|
31
|
-
maxTurns;
|
|
32
|
-
claudePath;
|
|
33
|
-
constructor(maxTurns = 50) {
|
|
34
|
-
this.maxTurns = maxTurns;
|
|
35
|
-
this.claudePath = findClaudeBinary();
|
|
36
|
-
}
|
|
37
|
-
async execute(job, workDir, onUpdate) {
|
|
38
|
-
mkdirSync(workDir, { recursive: true });
|
|
39
|
-
const prompt = this.buildPrompt(job, workDir);
|
|
40
|
-
console.log(` Using claude binary: ${this.claudePath}`);
|
|
41
|
-
return new Promise((resolve) => {
|
|
42
|
-
const claude = spawn(this.claudePath, [
|
|
43
|
-
'-p', prompt,
|
|
44
|
-
'--output-format', 'stream-json',
|
|
45
|
-
'--verbose',
|
|
46
|
-
'--max-turns', String(this.maxTurns),
|
|
47
|
-
'--dangerously-skip-permissions',
|
|
48
|
-
], {
|
|
49
|
-
cwd: workDir,
|
|
50
|
-
stdio: ['ignore', 'pipe', 'inherit'],
|
|
51
|
-
env: { ...process.env, CLAUDECODE: undefined },
|
|
52
|
-
});
|
|
53
|
-
let outputBuffer = '';
|
|
54
|
-
let lastGatewayUpdate = 0;
|
|
55
|
-
const pendingActions = [];
|
|
56
|
-
const stripPath = (s) => s.replace(new RegExp(workDir + '/?', 'g'), '');
|
|
57
|
-
claude.stdout?.on('data', (chunk) => {
|
|
58
|
-
const text = chunk.toString();
|
|
59
|
-
outputBuffer += text;
|
|
60
|
-
const lines = outputBuffer.split('\n');
|
|
61
|
-
outputBuffer = lines.pop() || '';
|
|
62
|
-
for (const line of lines) {
|
|
63
|
-
if (!line.trim())
|
|
64
|
-
continue;
|
|
65
|
-
try {
|
|
66
|
-
const event = JSON.parse(line);
|
|
67
|
-
this.handleStreamEvent(event, onUpdate, pendingActions, stripPath, () => {
|
|
68
|
-
const now = Date.now();
|
|
69
|
-
if (now - lastGatewayUpdate >= GATEWAY_UPDATE_INTERVAL_MS && pendingActions.length > 0) {
|
|
70
|
-
lastGatewayUpdate = now;
|
|
71
|
-
const summary = pendingActions.splice(0).join(' → ');
|
|
72
|
-
onUpdate('text', summary.slice(0, 500));
|
|
73
|
-
}
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
catch {
|
|
77
|
-
if (line.trim()) {
|
|
78
|
-
process.stdout.write(line + '\n');
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
claude.on('close', (code) => {
|
|
84
|
-
const files = this.collectFiles(workDir);
|
|
85
|
-
const summary = code === 0
|
|
86
|
-
? `Job completed successfully. ${files.length} file(s) created.`
|
|
87
|
-
: `Job finished with exit code ${code}. ${files.length} file(s) in working directory.`;
|
|
88
|
-
if (pendingActions.length > 0) {
|
|
89
|
-
onUpdate('text', pendingActions.join(' → ').slice(0, 500));
|
|
90
|
-
pendingActions.length = 0;
|
|
91
|
-
}
|
|
92
|
-
onUpdate('text', summary);
|
|
93
|
-
resolve({
|
|
94
|
-
success: code === 0,
|
|
95
|
-
files,
|
|
96
|
-
summary,
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
claude.on('error', (err) => {
|
|
100
|
-
console.log(` [${ts()}] ERROR: Failed to spawn claude: ${err.message}`);
|
|
101
|
-
onUpdate('text', `Error spawning claude: ${err.message}`);
|
|
102
|
-
resolve({
|
|
103
|
-
success: false,
|
|
104
|
-
files: [],
|
|
105
|
-
summary: `Failed to spawn claude: ${err.message}`,
|
|
106
|
-
});
|
|
107
|
-
});
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
handleStreamEvent(event, onUpdate, pendingActions, stripPath, maybeFlush) {
|
|
111
|
-
switch (event.type) {
|
|
112
|
-
case 'system': {
|
|
113
|
-
console.log(` [${ts()}] Agent started`);
|
|
114
|
-
onUpdate('text', 'Agent started working');
|
|
115
|
-
break;
|
|
116
|
-
}
|
|
117
|
-
case 'assistant': {
|
|
118
|
-
const msg = event.message;
|
|
119
|
-
if (msg?.content && Array.isArray(msg.content)) {
|
|
120
|
-
for (const block of msg.content) {
|
|
121
|
-
if (block.type === 'text' && typeof block.text === 'string') {
|
|
122
|
-
const text = stripPath(block.text).slice(0, 500);
|
|
123
|
-
console.log(` [${ts()}] ${text}`);
|
|
124
|
-
pendingActions.push(text.slice(0, 80));
|
|
125
|
-
}
|
|
126
|
-
else if (block.type === 'tool_use') {
|
|
127
|
-
const toolName = block.name || 'tool';
|
|
128
|
-
const input = (block.input || {});
|
|
129
|
-
const rawTarget = String(input.file_path || input.path || input.command || input.pattern || '');
|
|
130
|
-
const target = stripPath(rawTarget);
|
|
131
|
-
const label = target ? `${toolName}: ${target}` : String(toolName);
|
|
132
|
-
console.log(` [${ts()}] > ${label}`);
|
|
133
|
-
pendingActions.push(label.slice(0, 80));
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
maybeFlush();
|
|
138
|
-
break;
|
|
139
|
-
}
|
|
140
|
-
case 'tool_result': {
|
|
141
|
-
const output = stripPath(String(event.output || event.content || '')).slice(0, 200);
|
|
142
|
-
if (output) {
|
|
143
|
-
console.log(` [${ts()}] → ${output.split('\n')[0]}`);
|
|
144
|
-
}
|
|
145
|
-
break;
|
|
146
|
-
}
|
|
147
|
-
case 'result': {
|
|
148
|
-
const result = event.result;
|
|
149
|
-
if (typeof result === 'string') {
|
|
150
|
-
const clean = stripPath(result);
|
|
151
|
-
console.log(`\n [${ts()}] DONE: ${clean.slice(0, 500)}`);
|
|
152
|
-
onUpdate('text', clean.slice(0, 200));
|
|
153
|
-
}
|
|
154
|
-
const cost = event.total_cost_usd;
|
|
155
|
-
const turns = event.num_turns;
|
|
156
|
-
if (cost)
|
|
157
|
-
console.log(` [${ts()}] Cost: $${cost}`);
|
|
158
|
-
if (turns)
|
|
159
|
-
console.log(` [${ts()}] Turns: ${turns}`);
|
|
160
|
-
break;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
buildPrompt(job, workDir) {
|
|
165
|
-
return [
|
|
166
|
-
`You are an autonomous agent executing a job from the Maclat marketplace.`,
|
|
167
|
-
``,
|
|
168
|
-
`## Job Details`,
|
|
169
|
-
`- Title: ${job.title}`,
|
|
170
|
-
`- Description: ${job.description}`,
|
|
171
|
-
`- Budget: ${job.budget_usdc} USDC`,
|
|
172
|
-
``,
|
|
173
|
-
`## Instructions`,
|
|
174
|
-
`1. Work in the current directory: ${workDir}`,
|
|
175
|
-
`2. Complete the job as described above`,
|
|
176
|
-
`3. Create all necessary files in the current directory`,
|
|
177
|
-
`4. Make sure everything works and is complete`,
|
|
178
|
-
`5. When done, provide a brief summary of what you built`,
|
|
179
|
-
``,
|
|
180
|
-
`Do your best work. The job poster will review your deliverables.`,
|
|
181
|
-
].join('\n');
|
|
182
|
-
}
|
|
183
|
-
collectFiles(dir, base) {
|
|
184
|
-
const files = [];
|
|
185
|
-
const root = base || dir;
|
|
186
|
-
try {
|
|
187
|
-
const entries = readdirSync(dir);
|
|
188
|
-
for (const entry of entries) {
|
|
189
|
-
if (entry.startsWith('.') || entry === 'node_modules')
|
|
190
|
-
continue;
|
|
191
|
-
const fullPath = join(dir, entry);
|
|
192
|
-
const stat = statSync(fullPath);
|
|
193
|
-
if (stat.isDirectory()) {
|
|
194
|
-
files.push(...this.collectFiles(fullPath, root));
|
|
195
|
-
}
|
|
196
|
-
else if (stat.isFile() && stat.size < 100_000) {
|
|
197
|
-
try {
|
|
198
|
-
const content = readFileSync(fullPath, 'utf-8');
|
|
199
|
-
files.push({ path: relative(root, fullPath), content });
|
|
200
|
-
}
|
|
201
|
-
catch {
|
|
202
|
-
// Binary file or unreadable, skip
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
catch {
|
|
208
|
-
// Directory doesn't exist or not readable
|
|
209
|
-
}
|
|
210
|
-
return files;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
1
|
+
export {};
|
|
213
2
|
//# sourceMappingURL=executor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../src/daemon/executor.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../src/daemon/executor.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Job } from '../../shared/types.js';
|
|
2
|
+
import type { JobExecutor, ExecutionResult, OnUpdate } from '../executor.js';
|
|
3
|
+
export declare class ClaudeCodeExecutor implements JobExecutor {
|
|
4
|
+
private maxTurns;
|
|
5
|
+
private claudePath;
|
|
6
|
+
constructor(maxTurns?: number);
|
|
7
|
+
execute(job: Job, workDir: string, onUpdate: OnUpdate): Promise<ExecutionResult>;
|
|
8
|
+
private handleStreamEvent;
|
|
9
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { spawn, execSync } from 'child_process';
|
|
2
|
+
import { mkdirSync, readdirSync, existsSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import { homedir } from 'os';
|
|
5
|
+
import { buildPrompt } from './prompt.js';
|
|
6
|
+
import { collectFiles } from './file-collector.js';
|
|
7
|
+
function findClaudeBinary() {
|
|
8
|
+
try {
|
|
9
|
+
const path = execSync('which claude 2>/dev/null', { encoding: 'utf-8' }).trim();
|
|
10
|
+
if (path)
|
|
11
|
+
return path;
|
|
12
|
+
}
|
|
13
|
+
catch { /* not in PATH */ }
|
|
14
|
+
const appSupport = join(homedir(), 'Library', 'Application Support', 'Claude', 'claude-code');
|
|
15
|
+
if (existsSync(appSupport)) {
|
|
16
|
+
const versions = readdirSync(appSupport).sort().reverse();
|
|
17
|
+
for (const v of versions) {
|
|
18
|
+
const bin = join(appSupport, v, 'claude');
|
|
19
|
+
if (existsSync(bin))
|
|
20
|
+
return bin;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return 'claude';
|
|
24
|
+
}
|
|
25
|
+
function ts() {
|
|
26
|
+
return new Date().toLocaleTimeString('en-US', { hour12: false });
|
|
27
|
+
}
|
|
28
|
+
const GATEWAY_UPDATE_INTERVAL_MS = 60_000;
|
|
29
|
+
export class ClaudeCodeExecutor {
|
|
30
|
+
maxTurns;
|
|
31
|
+
claudePath;
|
|
32
|
+
constructor(maxTurns = 50) {
|
|
33
|
+
this.maxTurns = maxTurns;
|
|
34
|
+
this.claudePath = findClaudeBinary();
|
|
35
|
+
}
|
|
36
|
+
async execute(job, workDir, onUpdate) {
|
|
37
|
+
mkdirSync(workDir, { recursive: true });
|
|
38
|
+
const prompt = buildPrompt(job, workDir);
|
|
39
|
+
console.log(` Using claude binary: ${this.claudePath}`);
|
|
40
|
+
return new Promise((resolve) => {
|
|
41
|
+
const claude = spawn(this.claudePath, [
|
|
42
|
+
'-p', prompt,
|
|
43
|
+
'--output-format', 'stream-json',
|
|
44
|
+
'--verbose',
|
|
45
|
+
'--max-turns', String(this.maxTurns),
|
|
46
|
+
'--dangerously-skip-permissions',
|
|
47
|
+
], {
|
|
48
|
+
cwd: workDir,
|
|
49
|
+
stdio: ['ignore', 'pipe', 'inherit'],
|
|
50
|
+
env: { ...process.env, CLAUDECODE: undefined },
|
|
51
|
+
});
|
|
52
|
+
let outputBuffer = '';
|
|
53
|
+
let lastGatewayUpdate = 0;
|
|
54
|
+
const pendingActions = [];
|
|
55
|
+
const stripPath = (s) => s.replace(new RegExp(workDir + '/?', 'g'), '');
|
|
56
|
+
claude.stdout?.on('data', (chunk) => {
|
|
57
|
+
const text = chunk.toString();
|
|
58
|
+
outputBuffer += text;
|
|
59
|
+
const lines = outputBuffer.split('\n');
|
|
60
|
+
outputBuffer = lines.pop() || '';
|
|
61
|
+
for (const line of lines) {
|
|
62
|
+
if (!line.trim())
|
|
63
|
+
continue;
|
|
64
|
+
try {
|
|
65
|
+
const event = JSON.parse(line);
|
|
66
|
+
this.handleStreamEvent(event, onUpdate, pendingActions, stripPath, () => {
|
|
67
|
+
const now = Date.now();
|
|
68
|
+
if (now - lastGatewayUpdate >= GATEWAY_UPDATE_INTERVAL_MS && pendingActions.length > 0) {
|
|
69
|
+
lastGatewayUpdate = now;
|
|
70
|
+
const summary = pendingActions.splice(0).join(' → ');
|
|
71
|
+
onUpdate('text', summary.slice(0, 500));
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
if (line.trim())
|
|
77
|
+
process.stdout.write(line + '\n');
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
claude.on('close', (code) => {
|
|
82
|
+
const files = collectFiles(workDir);
|
|
83
|
+
const summary = code === 0
|
|
84
|
+
? `Job completed successfully. ${files.length} file(s) created.`
|
|
85
|
+
: `Job finished with exit code ${code}. ${files.length} file(s) in working directory.`;
|
|
86
|
+
if (pendingActions.length > 0) {
|
|
87
|
+
onUpdate('text', pendingActions.join(' → ').slice(0, 500));
|
|
88
|
+
pendingActions.length = 0;
|
|
89
|
+
}
|
|
90
|
+
onUpdate('text', summary);
|
|
91
|
+
resolve({ success: code === 0, files, summary });
|
|
92
|
+
});
|
|
93
|
+
claude.on('error', (err) => {
|
|
94
|
+
console.log(` [${ts()}] ERROR: Failed to spawn claude: ${err.message}`);
|
|
95
|
+
onUpdate('text', `Error spawning claude: ${err.message}`);
|
|
96
|
+
resolve({ success: false, files: [], summary: `Failed to spawn claude: ${err.message}` });
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
handleStreamEvent(event, onUpdate, pendingActions, stripPath, maybeFlush) {
|
|
101
|
+
switch (event.type) {
|
|
102
|
+
case 'system': {
|
|
103
|
+
console.log(` [${ts()}] Agent started`);
|
|
104
|
+
onUpdate('text', 'Agent started working');
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
case 'assistant': {
|
|
108
|
+
const msg = event.message;
|
|
109
|
+
if (msg?.content && Array.isArray(msg.content)) {
|
|
110
|
+
for (const block of msg.content) {
|
|
111
|
+
if (block.type === 'text' && typeof block.text === 'string') {
|
|
112
|
+
const text = stripPath(block.text).slice(0, 500);
|
|
113
|
+
console.log(` [${ts()}] ${text}`);
|
|
114
|
+
pendingActions.push(text.slice(0, 80));
|
|
115
|
+
}
|
|
116
|
+
else if (block.type === 'tool_use') {
|
|
117
|
+
const toolName = block.name || 'tool';
|
|
118
|
+
const input = (block.input || {});
|
|
119
|
+
const rawTarget = String(input.file_path || input.path || input.command || input.pattern || '');
|
|
120
|
+
const target = stripPath(rawTarget);
|
|
121
|
+
const label = target ? `${toolName}: ${target}` : String(toolName);
|
|
122
|
+
console.log(` [${ts()}] > ${label}`);
|
|
123
|
+
pendingActions.push(label.slice(0, 80));
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
maybeFlush();
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
case 'tool_result': {
|
|
131
|
+
const output = stripPath(String(event.output || event.content || '')).slice(0, 200);
|
|
132
|
+
if (output)
|
|
133
|
+
console.log(` [${ts()}] → ${output.split('\n')[0]}`);
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
case 'result': {
|
|
137
|
+
const result = event.result;
|
|
138
|
+
if (typeof result === 'string') {
|
|
139
|
+
const clean = stripPath(result);
|
|
140
|
+
console.log(`\n [${ts()}] DONE: ${clean.slice(0, 500)}`);
|
|
141
|
+
onUpdate('text', clean.slice(0, 200));
|
|
142
|
+
}
|
|
143
|
+
const cost = event.total_cost_usd;
|
|
144
|
+
const turns = event.num_turns;
|
|
145
|
+
if (cost)
|
|
146
|
+
console.log(` [${ts()}] Cost: $${cost}`);
|
|
147
|
+
if (turns)
|
|
148
|
+
console.log(` [${ts()}] Turns: ${turns}`);
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=claude-code.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../../src/daemon/executors/claude-code.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Job } from '../../shared/types.js';
|
|
2
|
+
import type { JobExecutor, ExecutionResult, OnUpdate } from '../executor.js';
|
|
3
|
+
export declare class ClaudeSdkExecutor implements JobExecutor {
|
|
4
|
+
private apiKey;
|
|
5
|
+
private model;
|
|
6
|
+
private maxTurns;
|
|
7
|
+
private baseUrl?;
|
|
8
|
+
constructor(apiKey: string, model?: string, maxTurns?: number, baseUrl?: string);
|
|
9
|
+
execute(job: Job, workDir: string, onUpdate: OnUpdate): Promise<ExecutionResult>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { mkdirSync } from 'fs';
|
|
2
|
+
import { buildPrompt } from './prompt.js';
|
|
3
|
+
import { collectFiles } from './file-collector.js';
|
|
4
|
+
function ts() {
|
|
5
|
+
return new Date().toLocaleTimeString('en-US', { hour12: false });
|
|
6
|
+
}
|
|
7
|
+
export class ClaudeSdkExecutor {
|
|
8
|
+
apiKey;
|
|
9
|
+
model;
|
|
10
|
+
maxTurns;
|
|
11
|
+
baseUrl;
|
|
12
|
+
constructor(apiKey, model, maxTurns, baseUrl) {
|
|
13
|
+
this.apiKey = apiKey;
|
|
14
|
+
this.model = model || 'claude-sonnet-4-6';
|
|
15
|
+
this.maxTurns = maxTurns || 50;
|
|
16
|
+
this.baseUrl = baseUrl;
|
|
17
|
+
}
|
|
18
|
+
async execute(job, workDir, onUpdate) {
|
|
19
|
+
mkdirSync(workDir, { recursive: true });
|
|
20
|
+
const prompt = buildPrompt(job, workDir);
|
|
21
|
+
const provider = this.baseUrl ? 'OpenRouter' : 'Anthropic';
|
|
22
|
+
console.log(` [${ts()}] Starting ${provider} SDK (model: ${this.model})`);
|
|
23
|
+
onUpdate('text', `Agent started via ${provider} SDK`);
|
|
24
|
+
// Set env vars for the SDK
|
|
25
|
+
const prevKey = process.env.ANTHROPIC_API_KEY;
|
|
26
|
+
const prevBase = process.env.ANTHROPIC_BASE_URL;
|
|
27
|
+
process.env.ANTHROPIC_API_KEY = this.apiKey;
|
|
28
|
+
if (this.baseUrl) {
|
|
29
|
+
process.env.ANTHROPIC_BASE_URL = this.baseUrl;
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
const { query } = await import('@anthropic-ai/claude-agent-sdk');
|
|
33
|
+
let lastText = '';
|
|
34
|
+
for await (const message of query({
|
|
35
|
+
prompt,
|
|
36
|
+
options: {
|
|
37
|
+
allowedTools: ['Read', 'Write', 'Edit', 'Bash', 'Grep', 'Glob', 'WebSearch', 'WebFetch'],
|
|
38
|
+
permissionMode: 'bypassPermissions',
|
|
39
|
+
cwd: workDir,
|
|
40
|
+
model: this.model,
|
|
41
|
+
maxTurns: this.maxTurns,
|
|
42
|
+
},
|
|
43
|
+
})) {
|
|
44
|
+
const msg = message;
|
|
45
|
+
if (msg.type === 'assistant') {
|
|
46
|
+
const apiMsg = msg.message;
|
|
47
|
+
if (apiMsg?.content && Array.isArray(apiMsg.content)) {
|
|
48
|
+
for (const block of apiMsg.content) {
|
|
49
|
+
if (block.type === 'text' && typeof block.text === 'string') {
|
|
50
|
+
const text = block.text.slice(0, 200);
|
|
51
|
+
console.log(` [${ts()}] ${text}`);
|
|
52
|
+
lastText = text;
|
|
53
|
+
onUpdate('text', text);
|
|
54
|
+
}
|
|
55
|
+
else if (block.type === 'tool_use') {
|
|
56
|
+
const label = `${block.name}: ${String(block.input?.file_path || block.input?.command || '').slice(0, 80)}`;
|
|
57
|
+
console.log(` [${ts()}] > ${label}`);
|
|
58
|
+
onUpdate('terminal', label);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
else if (msg.type === 'result') {
|
|
64
|
+
const result = msg.result;
|
|
65
|
+
if (result) {
|
|
66
|
+
console.log(`\n [${ts()}] DONE: ${result.slice(0, 300)}`);
|
|
67
|
+
lastText = result.slice(0, 200);
|
|
68
|
+
}
|
|
69
|
+
const cost = msg.total_cost_usd;
|
|
70
|
+
if (cost)
|
|
71
|
+
console.log(` [${ts()}] Cost: $${cost}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const files = collectFiles(workDir);
|
|
75
|
+
const summary = lastText || `Job completed via ${provider}. ${files.length} file(s) created.`;
|
|
76
|
+
onUpdate('text', summary.slice(0, 200));
|
|
77
|
+
return { success: true, files, summary };
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
81
|
+
console.log(` [${ts()}] ERROR: ${errMsg}`);
|
|
82
|
+
onUpdate('text', `Error: ${errMsg}`);
|
|
83
|
+
const files = collectFiles(workDir);
|
|
84
|
+
return { success: false, files, summary: `Error: ${errMsg}` };
|
|
85
|
+
}
|
|
86
|
+
finally {
|
|
87
|
+
// Restore env vars
|
|
88
|
+
if (prevKey !== undefined)
|
|
89
|
+
process.env.ANTHROPIC_API_KEY = prevKey;
|
|
90
|
+
else
|
|
91
|
+
delete process.env.ANTHROPIC_API_KEY;
|
|
92
|
+
if (prevBase !== undefined)
|
|
93
|
+
process.env.ANTHROPIC_BASE_URL = prevBase;
|
|
94
|
+
else
|
|
95
|
+
delete process.env.ANTHROPIC_BASE_URL;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=claude-sdk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-sdk.js","sourceRoot":"","sources":["../../../src/daemon/executors/claude-sdk.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Job } from '../../shared/types.js';
|
|
2
|
+
import type { JobExecutor, ExecutionResult, OnUpdate } from '../executor.js';
|
|
3
|
+
export declare class CodexExecutor implements JobExecutor {
|
|
4
|
+
private codexPath;
|
|
5
|
+
constructor();
|
|
6
|
+
execute(job: Job, workDir: string, onUpdate: OnUpdate): Promise<ExecutionResult>;
|
|
7
|
+
private handleEvent;
|
|
8
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { spawn, execSync } from 'child_process';
|
|
2
|
+
import { mkdirSync } from 'fs';
|
|
3
|
+
import { buildPrompt } from './prompt.js';
|
|
4
|
+
import { collectFiles } from './file-collector.js';
|
|
5
|
+
function findCodexBinary() {
|
|
6
|
+
try {
|
|
7
|
+
const path = execSync('which codex 2>/dev/null', { encoding: 'utf-8' }).trim();
|
|
8
|
+
if (path)
|
|
9
|
+
return path;
|
|
10
|
+
}
|
|
11
|
+
catch { /* not in PATH */ }
|
|
12
|
+
return 'codex';
|
|
13
|
+
}
|
|
14
|
+
function ts() {
|
|
15
|
+
return new Date().toLocaleTimeString('en-US', { hour12: false });
|
|
16
|
+
}
|
|
17
|
+
export class CodexExecutor {
|
|
18
|
+
codexPath;
|
|
19
|
+
constructor() {
|
|
20
|
+
this.codexPath = findCodexBinary();
|
|
21
|
+
}
|
|
22
|
+
async execute(job, workDir, onUpdate) {
|
|
23
|
+
mkdirSync(workDir, { recursive: true });
|
|
24
|
+
const prompt = buildPrompt(job, workDir);
|
|
25
|
+
console.log(` Using codex binary: ${this.codexPath}`);
|
|
26
|
+
onUpdate('text', 'Agent started via Codex');
|
|
27
|
+
return new Promise((resolve) => {
|
|
28
|
+
const codex = spawn(this.codexPath, [
|
|
29
|
+
'exec', prompt,
|
|
30
|
+
'--json',
|
|
31
|
+
], {
|
|
32
|
+
cwd: workDir,
|
|
33
|
+
stdio: ['ignore', 'pipe', 'inherit'],
|
|
34
|
+
});
|
|
35
|
+
let outputBuffer = '';
|
|
36
|
+
codex.stdout?.on('data', (chunk) => {
|
|
37
|
+
const text = chunk.toString();
|
|
38
|
+
outputBuffer += text;
|
|
39
|
+
const lines = outputBuffer.split('\n');
|
|
40
|
+
outputBuffer = lines.pop() || '';
|
|
41
|
+
for (const line of lines) {
|
|
42
|
+
if (!line.trim())
|
|
43
|
+
continue;
|
|
44
|
+
try {
|
|
45
|
+
const event = JSON.parse(line);
|
|
46
|
+
this.handleEvent(event, onUpdate);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
process.stdout.write(line + '\n');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
codex.on('close', (code) => {
|
|
54
|
+
const files = collectFiles(workDir);
|
|
55
|
+
const summary = code === 0
|
|
56
|
+
? `Job completed via Codex. ${files.length} file(s) created.`
|
|
57
|
+
: `Job finished with exit code ${code}. ${files.length} file(s) in working directory.`;
|
|
58
|
+
onUpdate('text', summary);
|
|
59
|
+
resolve({ success: code === 0, files, summary });
|
|
60
|
+
});
|
|
61
|
+
codex.on('error', (err) => {
|
|
62
|
+
console.log(` [${ts()}] ERROR: Failed to spawn codex: ${err.message}`);
|
|
63
|
+
onUpdate('text', `Error spawning codex: ${err.message}`);
|
|
64
|
+
resolve({ success: false, files: [], summary: `Failed to spawn codex: ${err.message}` });
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
handleEvent(event, onUpdate) {
|
|
69
|
+
const type = event.type;
|
|
70
|
+
if (type === 'message' && typeof event.content === 'string') {
|
|
71
|
+
const text = event.content.slice(0, 200);
|
|
72
|
+
console.log(` [${ts()}] ${text}`);
|
|
73
|
+
onUpdate('text', text);
|
|
74
|
+
}
|
|
75
|
+
else if (type === 'command' && typeof event.command === 'string') {
|
|
76
|
+
const cmd = event.command.slice(0, 200);
|
|
77
|
+
console.log(` [${ts()}] > ${cmd}`);
|
|
78
|
+
onUpdate('terminal', cmd);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=codex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex.js","sourceRoot":"","sources":["../../../src/daemon/executors/codex.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { readdirSync, readFileSync, statSync } from 'fs';
|
|
2
|
+
import { join, relative } from 'path';
|
|
3
|
+
export function collectFiles(dir, base) {
|
|
4
|
+
const files = [];
|
|
5
|
+
const root = base || dir;
|
|
6
|
+
try {
|
|
7
|
+
const entries = readdirSync(dir);
|
|
8
|
+
for (const entry of entries) {
|
|
9
|
+
if (entry.startsWith('.') || entry === 'node_modules')
|
|
10
|
+
continue;
|
|
11
|
+
const fullPath = join(dir, entry);
|
|
12
|
+
const stat = statSync(fullPath);
|
|
13
|
+
if (stat.isDirectory()) {
|
|
14
|
+
files.push(...collectFiles(fullPath, root));
|
|
15
|
+
}
|
|
16
|
+
else if (stat.isFile() && stat.size < 100_000) {
|
|
17
|
+
try {
|
|
18
|
+
const content = readFileSync(fullPath, 'utf-8');
|
|
19
|
+
files.push({ path: relative(root, fullPath), content });
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
// Binary file or unreadable, skip
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
// Directory doesn't exist or not readable
|
|
29
|
+
}
|
|
30
|
+
return files;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=file-collector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-collector.js","sourceRoot":"","sources":["../../../src/daemon/executors/file-collector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AACzD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAEtC,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,IAAa;IACrD,MAAM,KAAK,GAA6C,EAAE,CAAC;IAC3D,MAAM,IAAI,GAAG,IAAI,IAAI,GAAG,CAAC;IAEzB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;QACjC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,KAAK,cAAc;gBAAE,SAAS;YAChE,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAClC,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAEhC,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;gBACvB,KAAK,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;YAC9C,CAAC;iBAAM,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,IAAI,GAAG,OAAO,EAAE,CAAC;gBAChD,IAAI,CAAC;oBACH,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;oBAChD,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;gBAC1D,CAAC;gBAAC,MAAM,CAAC;oBACP,kCAAkC;gBACpC,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,0CAA0C;IAC5C,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { ClaudeCodeExecutor } from './claude-code.js';
|
|
2
|
+
import { ClaudeSdkExecutor } from './claude-sdk.js';
|
|
3
|
+
import { CodexExecutor } from './codex.js';
|
|
4
|
+
export function createExecutor(config) {
|
|
5
|
+
const executor = config.executor || 'claude-code';
|
|
6
|
+
switch (executor) {
|
|
7
|
+
case 'claude-code':
|
|
8
|
+
return new ClaudeCodeExecutor(config.max_turns);
|
|
9
|
+
case 'anthropic': {
|
|
10
|
+
if (!config.api_key) {
|
|
11
|
+
console.error(' Error: anthropic executor requires an API key.');
|
|
12
|
+
console.error(' Run: maclat use anthropic <your-api-key>');
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
return new ClaudeSdkExecutor(config.api_key, config.model, config.max_turns);
|
|
16
|
+
}
|
|
17
|
+
case 'openrouter': {
|
|
18
|
+
if (!config.api_key) {
|
|
19
|
+
console.error(' Error: openrouter executor requires an API key.');
|
|
20
|
+
console.error(' Run: maclat use openrouter <your-api-key>');
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
return new ClaudeSdkExecutor(config.api_key, config.model || 'anthropic/claude-sonnet-4-6', config.max_turns, 'https://openrouter.ai/api');
|
|
24
|
+
}
|
|
25
|
+
case 'codex':
|
|
26
|
+
return new CodexExecutor();
|
|
27
|
+
default:
|
|
28
|
+
console.error(` Unknown executor: ${executor}`);
|
|
29
|
+
console.error(` Valid options: claude-code, anthropic, openrouter, codex`);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/daemon/executors/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,UAAU,cAAc,CAAC,MAAoB;IACjD,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,aAAa,CAAC;IAElD,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,aAAa;YAChB,OAAO,IAAI,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAElD,KAAK,WAAW,CAAC,CAAC,CAAC;YACjB,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,OAAO,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;gBAClE,OAAO,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;gBAC5D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YACD,OAAO,IAAI,iBAAiB,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;QAC/E,CAAC;QAED,KAAK,YAAY,CAAC,CAAC,CAAC;YAClB,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,OAAO,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAC;gBACnE,OAAO,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;gBAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YACD,OAAO,IAAI,iBAAiB,CAC1B,MAAM,CAAC,OAAO,EACd,MAAM,CAAC,KAAK,IAAI,6BAA6B,EAC7C,MAAM,CAAC,SAAS,EAChB,2BAA2B,CAC5B,CAAC;QACJ,CAAC;QAED,KAAK,OAAO;YACV,OAAO,IAAI,aAAa,EAAE,CAAC;QAE7B;YACE,OAAO,CAAC,KAAK,CAAC,uBAAuB,QAAQ,EAAE,CAAC,CAAC;YACjD,OAAO,CAAC,KAAK,CAAC,4DAA4D,CAAC,CAAC;YAC5E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export function buildPrompt(job, workDir) {
|
|
2
|
+
return [
|
|
3
|
+
`You are an autonomous agent executing a job from the Maclat marketplace.`,
|
|
4
|
+
``,
|
|
5
|
+
`## Job Details`,
|
|
6
|
+
`- Title: ${job.title}`,
|
|
7
|
+
`- Description: ${job.description}`,
|
|
8
|
+
`- Budget: ${job.budget_usdc} USDC`,
|
|
9
|
+
``,
|
|
10
|
+
`## Instructions`,
|
|
11
|
+
`1. Work in the current directory: ${workDir}`,
|
|
12
|
+
`2. Complete the job as described above`,
|
|
13
|
+
`3. Create all necessary files in the current directory`,
|
|
14
|
+
`4. Make sure everything works and is complete`,
|
|
15
|
+
`5. When done, provide a brief summary of what you built`,
|
|
16
|
+
``,
|
|
17
|
+
`Do your best work. The job poster will review your deliverables.`,
|
|
18
|
+
].join('\n');
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../../src/daemon/executors/prompt.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,WAAW,CAAC,GAAQ,EAAE,OAAe;IACnD,OAAO;QACL,0EAA0E;QAC1E,EAAE;QACF,gBAAgB;QAChB,YAAY,GAAG,CAAC,KAAK,EAAE;QACvB,kBAAkB,GAAG,CAAC,WAAW,EAAE;QACnC,aAAa,GAAG,CAAC,WAAW,OAAO;QACnC,EAAE;QACF,iBAAiB;QACjB,qCAAqC,OAAO,EAAE;QAC9C,wCAAwC;QACxC,wDAAwD;QACxD,+CAA+C;QAC/C,yDAAyD;QACzD,EAAE;QACF,kEAAkE;KACnE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
|
package/dist/daemon/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { loadConfig, GATEWAY_URL } from '../shared/config.js';
|
|
2
|
-
import {
|
|
2
|
+
import { createExecutor } from './executors/index.js';
|
|
3
3
|
import { JobPoller } from './poller.js';
|
|
4
4
|
export async function startDaemon(args) {
|
|
5
5
|
const config = loadConfig();
|
|
@@ -20,12 +20,16 @@ export async function startDaemon(args) {
|
|
|
20
20
|
console.log(`Cannot reach gateway at ${gatewayUrl}`);
|
|
21
21
|
process.exit(1);
|
|
22
22
|
}
|
|
23
|
+
const executorType = config.executor || 'claude-code';
|
|
23
24
|
console.log(`\n Maclat Agent Daemon`);
|
|
24
25
|
console.log(` ──────────────────────────`);
|
|
25
|
-
console.log(` Agent ID:
|
|
26
|
-
console.log(` Gateway:
|
|
26
|
+
console.log(` Agent ID: ${agentId}`);
|
|
27
|
+
console.log(` Gateway: ${gatewayUrl}`);
|
|
28
|
+
console.log(` Executor: ${executorType}`);
|
|
29
|
+
if (config.model)
|
|
30
|
+
console.log(` Model: ${config.model}`);
|
|
27
31
|
console.log(` ──────────────────────────\n`);
|
|
28
|
-
const executor =
|
|
32
|
+
const executor = createExecutor(config);
|
|
29
33
|
const poller = new JobPoller(gatewayUrl, agentId, executor);
|
|
30
34
|
// Graceful shutdown
|
|
31
35
|
process.on('SIGINT', () => {
|
package/dist/daemon/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/daemon/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/daemon/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAc;IAC9C,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC;IAEzD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAC;QAC7E,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;QACrD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,IAAI,WAAW,CAAC;IAErD,8BAA8B;IAC9B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,UAAU,SAAS,CAAC,CAAC;QAChD,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IACrD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,GAAG,CAAC,2BAA2B,UAAU,EAAE,CAAC,CAAC;QACrD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,YAAY,GAAG,MAAM,CAAC,QAAQ,IAAI,aAAa,CAAC;IAEtD,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IACvC,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,CAAC,gBAAgB,OAAO,EAAE,CAAC,CAAC;IACvC,OAAO,CAAC,GAAG,CAAC,gBAAgB,UAAU,EAAE,CAAC,CAAC;IAC1C,OAAO,CAAC,GAAG,CAAC,gBAAgB,YAAY,EAAE,CAAC,CAAC;IAC5C,IAAI,MAAM,CAAC,KAAK;QAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;IAC9D,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;IAE9C,MAAM,QAAQ,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,UAAU,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IAE5D,oBAAoB;IACpB,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;QACxB,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;QACjD,MAAM,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;AACvB,CAAC;AAED,SAAS,OAAO,CAAC,IAAc,EAAE,IAAY;IAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IAC3D,OAAO,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;AACvB,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnC,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AAExB,KAAK,UAAU,IAAI;IACjB,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC;YAC1D,MAAM,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YACjC,MAAM;QACR,CAAC;QACD,KAAK,UAAU,CAAC;QAChB,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;YAClD,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;YACnB,MAAM;QACR,CAAC;QACD,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;YAClD,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;YACnB,MAAM;QACR,CAAC;IACH,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,cAAc,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;IAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnC,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AAExB,KAAK,UAAU,IAAI;IACjB,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC;YAC1D,MAAM,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YACjC,MAAM;QACR,CAAC;QACD,KAAK,UAAU,CAAC;QAChB,KAAK,QAAQ,CAAC;QACd,KAAK,KAAK,CAAC;QACX,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;YAClD,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;YACnB,MAAM;QACR,CAAC;QACD,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;YAClD,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;YACnB,MAAM;QACR,CAAC;IACH,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,cAAc,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;IAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/dist/shared/types.d.ts
CHANGED
|
@@ -33,8 +33,13 @@ export interface Deliverable {
|
|
|
33
33
|
summary: string;
|
|
34
34
|
created_at: string;
|
|
35
35
|
}
|
|
36
|
+
export type ExecutorType = 'claude-code' | 'anthropic' | 'openrouter' | 'codex';
|
|
36
37
|
export interface MaclatConfig {
|
|
37
38
|
agent_id?: string;
|
|
38
39
|
agent_name?: string;
|
|
39
40
|
gateway_url: string;
|
|
41
|
+
executor?: ExecutorType;
|
|
42
|
+
api_key?: string;
|
|
43
|
+
model?: string;
|
|
44
|
+
max_turns?: number;
|
|
40
45
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "maclat",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Maclat - Agent CLI for the autonomous job marketplace",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"build": "tsc",
|
|
15
15
|
"dev": "tsx src/index.ts",
|
|
16
16
|
"clean": "rm -rf dist",
|
|
17
|
-
"prepublishOnly": "npm run clean && npm run build"
|
|
17
|
+
"prepublishOnly": "npm run clean && npm run build && chmod +x dist/index.js"
|
|
18
18
|
},
|
|
19
19
|
"engines": {
|
|
20
20
|
"node": ">=20.0.0"
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
],
|
|
29
29
|
"license": "MIT",
|
|
30
30
|
"dependencies": {
|
|
31
|
+
"@anthropic-ai/claude-agent-sdk": "^0.2.45",
|
|
31
32
|
"ulid": "^2.3.0"
|
|
32
33
|
},
|
|
33
34
|
"devDependencies": {
|