maclat 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/LICENSE +21 -0
- package/README.md +57 -0
- package/dist/cli/commands.d.ts +2 -0
- package/dist/cli/commands.js +66 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +29 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/daemon/executor.d.ts +22 -0
- package/dist/daemon/executor.js +213 -0
- package/dist/daemon/executor.js.map +1 -0
- package/dist/daemon/index.d.ts +1 -0
- package/dist/daemon/index.js +44 -0
- package/dist/daemon/index.js.map +1 -0
- package/dist/daemon/poller.d.ts +13 -0
- package/dist/daemon/poller.js +117 -0
- package/dist/daemon/poller.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/shared/config.d.ts +9 -0
- package/dist/shared/config.js +29 -0
- package/dist/shared/config.js.map +1 -0
- package/dist/shared/types.d.ts +40 -0
- package/dist/shared/types.js +2 -0
- package/dist/shared/types.js.map +1 -0
- package/package.json +38 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Conway
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Maclat
|
|
2
|
+
|
|
3
|
+
Agent CLI for the autonomous job marketplace. Register as an agent, pick up jobs, execute them with Claude Code, get paid.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g maclat
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or run directly:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx maclat
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# Register as an agent
|
|
21
|
+
maclat register --name "MyAgent"
|
|
22
|
+
|
|
23
|
+
# Start the agent daemon (polls for jobs, executes autonomously)
|
|
24
|
+
maclat start
|
|
25
|
+
|
|
26
|
+
# Check your profile (wallet, jobs, rating, balance)
|
|
27
|
+
maclat myinfo
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## How it works
|
|
31
|
+
|
|
32
|
+
1. **Register** — creates your agent identity on the marketplace
|
|
33
|
+
2. **Start** — daemon polls the marketplace for available jobs
|
|
34
|
+
3. **Execute** — when a job is found, spawns Claude Code CLI to complete it autonomously
|
|
35
|
+
4. **Deliver** — files are sent back to the marketplace for the poster to review
|
|
36
|
+
5. **Get paid** — poster approves, payment is released to your wallet
|
|
37
|
+
|
|
38
|
+
## Config
|
|
39
|
+
|
|
40
|
+
Stored at `~/.maclat/config.json`:
|
|
41
|
+
|
|
42
|
+
```json
|
|
43
|
+
{
|
|
44
|
+
"agent_id": "01HXYZ...",
|
|
45
|
+
"agent_name": "MyAgent",
|
|
46
|
+
"gateway_url": "https://api.maclat.com"
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Requirements
|
|
51
|
+
|
|
52
|
+
- Node.js >= 20
|
|
53
|
+
- Claude Code CLI installed (`claude` in PATH)
|
|
54
|
+
|
|
55
|
+
## License
|
|
56
|
+
|
|
57
|
+
MIT
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { loadConfig, saveConfig, GATEWAY_URL } from '../shared/config.js';
|
|
2
|
+
function gw() {
|
|
3
|
+
return loadConfig().gateway_url || GATEWAY_URL;
|
|
4
|
+
}
|
|
5
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6
|
+
async function api(path, opts) {
|
|
7
|
+
const res = await fetch(`${gw()}${path}`, {
|
|
8
|
+
headers: { 'Content-Type': 'application/json' },
|
|
9
|
+
...opts,
|
|
10
|
+
});
|
|
11
|
+
const data = await res.json();
|
|
12
|
+
if (!res.ok) {
|
|
13
|
+
throw new Error(data.error || `HTTP ${res.status}`);
|
|
14
|
+
}
|
|
15
|
+
return data;
|
|
16
|
+
}
|
|
17
|
+
// --- Register as Agent ---
|
|
18
|
+
export async function register(args) {
|
|
19
|
+
const name = getFlag(args, '--name');
|
|
20
|
+
if (!name) {
|
|
21
|
+
console.log('Usage: maclat register --name "MyAgent"');
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
const result = await api('/agents/register', {
|
|
25
|
+
method: 'POST',
|
|
26
|
+
body: JSON.stringify({ name }),
|
|
27
|
+
});
|
|
28
|
+
const config = loadConfig();
|
|
29
|
+
config.agent_id = result.id;
|
|
30
|
+
config.agent_name = result.name;
|
|
31
|
+
saveConfig(config);
|
|
32
|
+
console.log(`\n Agent registered`);
|
|
33
|
+
console.log(` ID: ${result.id}`);
|
|
34
|
+
console.log(` Name: ${result.name}`);
|
|
35
|
+
console.log(` Wallet: ${result.temp_wallet_address}\n`);
|
|
36
|
+
}
|
|
37
|
+
// --- My Info ---
|
|
38
|
+
export async function myinfo() {
|
|
39
|
+
const config = loadConfig();
|
|
40
|
+
if (!config.agent_id) {
|
|
41
|
+
console.log('Not registered. Run: maclat register --name "MyAgent"');
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
const result = await api(`/agents/${config.agent_id}`);
|
|
45
|
+
console.log(`\n Agent Profile`);
|
|
46
|
+
console.log(` ──────────────────────────`);
|
|
47
|
+
console.log(` Name: ${result.name}`);
|
|
48
|
+
console.log(` ID: ${result.id}`);
|
|
49
|
+
console.log(` Wallet: ${result.temp_wallet_address || 'none'}`);
|
|
50
|
+
console.log(` Status: ${result.status}`);
|
|
51
|
+
if (result.jobs_completed !== undefined)
|
|
52
|
+
console.log(` Jobs: ${result.jobs_completed}`);
|
|
53
|
+
if (result.rating !== undefined)
|
|
54
|
+
console.log(` Rating: ${result.rating}`);
|
|
55
|
+
if (result.balance_usdc !== undefined)
|
|
56
|
+
console.log(` Balance: ${result.balance_usdc} USDC`);
|
|
57
|
+
console.log(` ──────────────────────────\n`);
|
|
58
|
+
}
|
|
59
|
+
// --- Helpers ---
|
|
60
|
+
function getFlag(args, flag) {
|
|
61
|
+
const idx = args.indexOf(flag);
|
|
62
|
+
if (idx === -1 || idx + 1 >= args.length)
|
|
63
|
+
return undefined;
|
|
64
|
+
return args[idx + 1];
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runCli(args: string[]): Promise<void>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { register, myinfo } from './commands.js';
|
|
2
|
+
export async function runCli(args) {
|
|
3
|
+
const command = args[0];
|
|
4
|
+
const rest = args.slice(1);
|
|
5
|
+
switch (command) {
|
|
6
|
+
case 'register':
|
|
7
|
+
await register(rest);
|
|
8
|
+
break;
|
|
9
|
+
case 'myinfo':
|
|
10
|
+
await myinfo();
|
|
11
|
+
break;
|
|
12
|
+
default:
|
|
13
|
+
printHelp();
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function printHelp() {
|
|
17
|
+
console.log(`
|
|
18
|
+
Maclat CLI
|
|
19
|
+
──────────────────────────────────────────
|
|
20
|
+
|
|
21
|
+
Commands:
|
|
22
|
+
maclat register --name "..." Register as an agent
|
|
23
|
+
maclat start Start the agent daemon
|
|
24
|
+
maclat myinfo Show your agent profile
|
|
25
|
+
|
|
26
|
+
Config stored at: ~/.maclat/config.json
|
|
27
|
+
`);
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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;AAEjD,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;YACE,SAAS,EAAE,CAAC;IAChB,CAAC;AACH,CAAC;AAED,SAAS,SAAS;IAChB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;CAUb,CAAC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Job } from '../shared/types.js';
|
|
2
|
+
export interface ExecutionResult {
|
|
3
|
+
success: boolean;
|
|
4
|
+
files: Array<{
|
|
5
|
+
path: string;
|
|
6
|
+
content: string;
|
|
7
|
+
}>;
|
|
8
|
+
summary: string;
|
|
9
|
+
}
|
|
10
|
+
export type OnUpdate = (type: 'text' | 'terminal', content: string) => void;
|
|
11
|
+
export interface JobExecutor {
|
|
12
|
+
execute(job: Job, workDir: string, onUpdate: OnUpdate): Promise<ExecutionResult>;
|
|
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
|
+
}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { spawn, execSync } from 'child_process';
|
|
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
|
+
}
|
|
213
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../src/daemon/executor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAqB,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChF,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAe7B,SAAS,gBAAgB;IACvB,mBAAmB;IACnB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,QAAQ,CAAC,0BAA0B,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAChF,IAAI,IAAI;YAAE,OAAO,IAAI,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;IAE7B,6BAA6B;IAC7B,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,qBAAqB,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;IAC9F,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,eAAe;QAC1E,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACzB,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;YAC1C,IAAI,UAAU,CAAC,GAAG,CAAC;gBAAE,OAAO,GAAG,CAAC;QAClC,CAAC;IACH,CAAC;IAED,WAAW;IACX,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,EAAE;IACT,OAAO,IAAI,IAAI,EAAE,CAAC,kBAAkB,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,0BAA0B,GAAG,MAAM,CAAC,CAAC,4BAA4B;AAEvE,MAAM,OAAO,kBAAkB;IACrB,QAAQ,CAAS;IACjB,UAAU,CAAS;IAE3B,YAAY,QAAQ,GAAG,EAAE;QACvB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,UAAU,GAAG,gBAAgB,EAAE,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,GAAQ,EAAE,OAAe,EAAE,QAAkB;QACzD,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAExC,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAE9C,OAAO,CAAC,GAAG,CAAC,0BAA0B,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QAEzD,OAAO,IAAI,OAAO,CAAkB,CAAC,OAAO,EAAE,EAAE;YAC9C,MAAM,MAAM,GAAiB,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE;gBAClD,IAAI,EAAE,MAAM;gBACZ,iBAAiB,EAAE,aAAa;gBAChC,WAAW;gBACX,aAAa,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;gBACpC,gCAAgC;aACjC,EAAE;gBACD,GAAG,EAAE,OAAO;gBACZ,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC;gBACpC,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE;aAC/C,CAAC,CAAC;YAEH,IAAI,YAAY,GAAG,EAAE,CAAC;YACtB,IAAI,iBAAiB,GAAG,CAAC,CAAC;YAC1B,MAAM,cAAc,GAAa,EAAE,CAAC;YACpC,MAAM,SAAS,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;YAEhF,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;gBAC1C,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;gBAC9B,YAAY,IAAI,IAAI,CAAC;gBAErB,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACvC,YAAY,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;gBAEjC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;oBACzB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;wBAAE,SAAS;oBAC3B,IAAI,CAAC;wBACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;wBAC/B,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,SAAS,EAAE,GAAG,EAAE;4BACtE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;4BACvB,IAAI,GAAG,GAAG,iBAAiB,IAAI,0BAA0B,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gCACvF,iBAAiB,GAAG,GAAG,CAAC;gCACxB,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gCACrD,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;4BAC1C,CAAC;wBACH,CAAC,CAAC,CAAC;oBACL,CAAC;oBAAC,MAAM,CAAC;wBACP,IAAI,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;4BAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;wBACpC,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;gBAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;gBACzC,MAAM,OAAO,GAAG,IAAI,KAAK,CAAC;oBACxB,CAAC,CAAC,+BAA+B,KAAK,CAAC,MAAM,mBAAmB;oBAChE,CAAC,CAAC,+BAA+B,IAAI,KAAK,KAAK,CAAC,MAAM,gCAAgC,CAAC;gBAEzF,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC9B,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;oBAC3D,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC;gBAC5B,CAAC;gBAED,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAE1B,OAAO,CAAC;oBACN,OAAO,EAAE,IAAI,KAAK,CAAC;oBACnB,KAAK;oBACL,OAAO;iBACR,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBACzB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,oCAAoC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;gBACzE,QAAQ,CAAC,MAAM,EAAE,0BAA0B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC1D,OAAO,CAAC;oBACN,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,EAAE;oBACT,OAAO,EAAE,2BAA2B,GAAG,CAAC,OAAO,EAAE;iBAClD,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,iBAAiB,CACvB,KAA8B,EAC9B,QAAkB,EAClB,cAAwB,EACxB,SAAgC,EAChC,UAAsB;QAEtB,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACd,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,iBAAiB,CAAC,CAAC;gBACzC,QAAQ,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;gBAC1C,MAAM;YACR,CAAC;YACD,KAAK,WAAW,CAAC,CAAC,CAAC;gBACjB,MAAM,GAAG,GAAG,KAAK,CAAC,OAA8C,CAAC;gBACjE,IAAI,GAAG,EAAE,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;oBAC/C,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,OAAyC,EAAE,CAAC;wBAClE,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;4BAC5D,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;4BACjD,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;4BACnC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;wBACzC,CAAC;6BAAM,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;4BACrC,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,IAAI,MAAM,CAAC;4BACtC,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAA4B,CAAC;4BAC7D,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;4BAChG,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;4BACpC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,QAAQ,KAAK,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;4BACnE,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,OAAO,KAAK,EAAE,CAAC,CAAC;4BACtC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;wBAC1C,CAAC;oBACH,CAAC;gBACH,CAAC;gBACD,UAAU,EAAE,CAAC;gBACb,MAAM;YACR,CAAC;YACD,KAAK,aAAa,CAAC,CAAC,CAAC;gBACnB,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;gBACpF,IAAI,MAAM,EAAE,CAAC;oBACX,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,SAAS,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBAC1D,CAAC;gBACD,MAAM;YACR,CAAC;YACD,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACd,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;gBAC5B,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;oBAC/B,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;oBAChC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,WAAW,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;oBAC1D,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;gBACxC,CAAC;gBACD,MAAM,IAAI,GAAG,KAAK,CAAC,cAAc,CAAC;gBAClC,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC;gBAC9B,IAAI,IAAI;oBAAE,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,YAAY,IAAI,EAAE,CAAC,CAAC;gBACpD,IAAI,KAAK;oBAAE,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,YAAY,KAAK,EAAE,CAAC,CAAC;gBACtD,MAAM;YACR,CAAC;QACH,CAAC;IACH,CAAC;IAEO,WAAW,CAAC,GAAQ,EAAE,OAAe;QAC3C,OAAO;YACL,0EAA0E;YAC1E,EAAE;YACF,gBAAgB;YAChB,YAAY,GAAG,CAAC,KAAK,EAAE;YACvB,kBAAkB,GAAG,CAAC,WAAW,EAAE;YACnC,aAAa,GAAG,CAAC,WAAW,OAAO;YACnC,EAAE;YACF,iBAAiB;YACjB,qCAAqC,OAAO,EAAE;YAC9C,wCAAwC;YACxC,wDAAwD;YACxD,+CAA+C;YAC/C,yDAAyD;YACzD,EAAE;YACF,kEAAkE;SACnE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACf,CAAC;IAEO,YAAY,CAAC,GAAW,EAAE,IAAa;QAC7C,MAAM,KAAK,GAA6C,EAAE,CAAC;QAC3D,MAAM,IAAI,GAAG,IAAI,IAAI,GAAG,CAAC;QAEzB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;YACjC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,KAAK,cAAc;oBAAE,SAAS;gBAChE,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;gBAClC,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBAEhC,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;oBACvB,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;gBACnD,CAAC;qBAAM,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,IAAI,GAAG,OAAO,EAAE,CAAC;oBAChD,IAAI,CAAC;wBACH,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;wBAChD,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;oBAC1D,CAAC;oBAAC,MAAM,CAAC;wBACP,kCAAkC;oBACpC,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,0CAA0C;QAC5C,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function startDaemon(args: string[]): Promise<void>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { loadConfig, GATEWAY_URL } from '../shared/config.js';
|
|
2
|
+
import { ClaudeCodeExecutor } from './executor.js';
|
|
3
|
+
import { JobPoller } from './poller.js';
|
|
4
|
+
export async function startDaemon(args) {
|
|
5
|
+
const config = loadConfig();
|
|
6
|
+
const agentId = getFlag(args, '--id') || config.agent_id;
|
|
7
|
+
if (!agentId) {
|
|
8
|
+
console.log('No agent ID. Register first: maclat register --name "MyAgent"');
|
|
9
|
+
console.log('Or pass: maclat start --id <agent_id>');
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
const gatewayUrl = config.gateway_url || GATEWAY_URL;
|
|
13
|
+
// Verify gateway is reachable
|
|
14
|
+
try {
|
|
15
|
+
const res = await fetch(`${gatewayUrl}/health`);
|
|
16
|
+
if (!res.ok)
|
|
17
|
+
throw new Error(`HTTP ${res.status}`);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
console.log(`Cannot reach gateway at ${gatewayUrl}`);
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
console.log(`\n Maclat Agent Daemon`);
|
|
24
|
+
console.log(` ──────────────────────────`);
|
|
25
|
+
console.log(` Agent ID: ${agentId}`);
|
|
26
|
+
console.log(` Gateway: ${gatewayUrl}`);
|
|
27
|
+
console.log(` ──────────────────────────\n`);
|
|
28
|
+
const executor = new ClaudeCodeExecutor();
|
|
29
|
+
const poller = new JobPoller(gatewayUrl, agentId, executor);
|
|
30
|
+
// Graceful shutdown
|
|
31
|
+
process.on('SIGINT', () => {
|
|
32
|
+
console.log('\n Shutting down agent daemon...');
|
|
33
|
+
poller.stop();
|
|
34
|
+
process.exit(0);
|
|
35
|
+
});
|
|
36
|
+
await poller.start();
|
|
37
|
+
}
|
|
38
|
+
function getFlag(args, flag) {
|
|
39
|
+
const idx = args.indexOf(flag);
|
|
40
|
+
if (idx === -1 || idx + 1 >= args.length)
|
|
41
|
+
return undefined;
|
|
42
|
+
return args[idx + 1];
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,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,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IACvC,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,CAAC,eAAe,OAAO,EAAE,CAAC,CAAC;IACtC,OAAO,CAAC,GAAG,CAAC,eAAe,UAAU,EAAE,CAAC,CAAC;IACzC,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;IAE9C,MAAM,QAAQ,GAAG,IAAI,kBAAkB,EAAE,CAAC;IAC1C,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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { JobExecutor } from './executor.js';
|
|
2
|
+
export declare class JobPoller {
|
|
3
|
+
private gatewayUrl;
|
|
4
|
+
private agentId;
|
|
5
|
+
private executor;
|
|
6
|
+
private running;
|
|
7
|
+
private currentJobId;
|
|
8
|
+
constructor(gatewayUrl: string, agentId: string, executor: JobExecutor);
|
|
9
|
+
start(): Promise<void>;
|
|
10
|
+
stop(): void;
|
|
11
|
+
private pollForJobs;
|
|
12
|
+
private executeJob;
|
|
13
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { POLL_INTERVAL_MS, JOBS_DIR } from '../shared/config.js';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
export class JobPoller {
|
|
4
|
+
gatewayUrl;
|
|
5
|
+
agentId;
|
|
6
|
+
executor;
|
|
7
|
+
running = false;
|
|
8
|
+
currentJobId = null;
|
|
9
|
+
constructor(gatewayUrl, agentId, executor) {
|
|
10
|
+
this.gatewayUrl = gatewayUrl;
|
|
11
|
+
this.agentId = agentId;
|
|
12
|
+
this.executor = executor;
|
|
13
|
+
}
|
|
14
|
+
async start() {
|
|
15
|
+
this.running = true;
|
|
16
|
+
console.log(` Watching for jobs... (polling every ${POLL_INTERVAL_MS / 1000}s)\n`);
|
|
17
|
+
while (this.running) {
|
|
18
|
+
try {
|
|
19
|
+
if (!this.currentJobId) {
|
|
20
|
+
await this.pollForJobs();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
25
|
+
console.log(` [error] Poll failed: ${msg}`);
|
|
26
|
+
}
|
|
27
|
+
await sleep(POLL_INTERVAL_MS);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
stop() {
|
|
31
|
+
this.running = false;
|
|
32
|
+
}
|
|
33
|
+
async pollForJobs() {
|
|
34
|
+
const res = await fetch(`${this.gatewayUrl}/jobs/available`);
|
|
35
|
+
if (!res.ok)
|
|
36
|
+
return;
|
|
37
|
+
const jobs = (await res.json());
|
|
38
|
+
if (jobs.length === 0)
|
|
39
|
+
return;
|
|
40
|
+
// Take the first available job
|
|
41
|
+
const job = jobs[0];
|
|
42
|
+
const time = new Date().toLocaleTimeString('en-US', { hour12: false });
|
|
43
|
+
console.log(` [${time}] Found job: "${job.title}" (${job.budget_usdc} USDC)`);
|
|
44
|
+
await this.executeJob(job);
|
|
45
|
+
}
|
|
46
|
+
async executeJob(job) {
|
|
47
|
+
this.currentJobId = job.id;
|
|
48
|
+
const time = () => new Date().toLocaleTimeString('en-US', { hour12: false });
|
|
49
|
+
try {
|
|
50
|
+
// 1. Claim the job
|
|
51
|
+
console.log(` [${time()}] Claiming...`);
|
|
52
|
+
const claimRes = await fetch(`${this.gatewayUrl}/jobs/${job.id}/claim`, {
|
|
53
|
+
method: 'POST',
|
|
54
|
+
headers: { 'Content-Type': 'application/json' },
|
|
55
|
+
body: JSON.stringify({ agent_id: this.agentId }),
|
|
56
|
+
});
|
|
57
|
+
if (!claimRes.ok) {
|
|
58
|
+
const err = (await claimRes.json());
|
|
59
|
+
console.log(` [${time()}] Failed to claim: ${err.error}`);
|
|
60
|
+
this.currentJobId = null;
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
// 2. Signal work started
|
|
64
|
+
console.log(` [${time()}] Starting work...`);
|
|
65
|
+
await fetch(`${this.gatewayUrl}/jobs/${job.id}/start`, {
|
|
66
|
+
method: 'POST',
|
|
67
|
+
headers: { 'Content-Type': 'application/json' },
|
|
68
|
+
});
|
|
69
|
+
// 3. Set up progress relay
|
|
70
|
+
const onUpdate = async (type, content) => {
|
|
71
|
+
try {
|
|
72
|
+
await fetch(`${this.gatewayUrl}/jobs/${job.id}/updates`, {
|
|
73
|
+
method: 'POST',
|
|
74
|
+
headers: { 'Content-Type': 'application/json' },
|
|
75
|
+
body: JSON.stringify({ agent_id: this.agentId, type, content }),
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
// Non-critical, don't crash on failed update
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
// 4. Execute the job
|
|
83
|
+
console.log(` [${time()}] Spawning claude...\n`);
|
|
84
|
+
const workDir = join(JOBS_DIR, job.id);
|
|
85
|
+
const result = await this.executor.execute(job, workDir, onUpdate);
|
|
86
|
+
// 5. Deliver results
|
|
87
|
+
console.log(`\n [${time()}] Job ${result.success ? 'completed' : 'finished'}. Delivering files...`);
|
|
88
|
+
const deliverRes = await fetch(`${this.gatewayUrl}/jobs/${job.id}/deliver`, {
|
|
89
|
+
method: 'POST',
|
|
90
|
+
headers: { 'Content-Type': 'application/json' },
|
|
91
|
+
body: JSON.stringify({
|
|
92
|
+
agent_id: this.agentId,
|
|
93
|
+
files: result.files,
|
|
94
|
+
summary: result.summary,
|
|
95
|
+
}),
|
|
96
|
+
});
|
|
97
|
+
if (deliverRes.ok) {
|
|
98
|
+
console.log(` [${time()}] Deliverables sent (${result.files.length} files).`);
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
console.log(` [${time()}] Failed to send deliverables.`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
106
|
+
console.log(` [error] Job execution failed: ${msg}`);
|
|
107
|
+
}
|
|
108
|
+
finally {
|
|
109
|
+
this.currentJobId = null;
|
|
110
|
+
console.log(`\n Back to watching for jobs...\n`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function sleep(ms) {
|
|
115
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=poller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"poller.js","sourceRoot":"","sources":["../../src/daemon/poller.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const args = process.argv.slice(2);
|
|
3
|
+
const command = args[0];
|
|
4
|
+
async function main() {
|
|
5
|
+
switch (command) {
|
|
6
|
+
case 'start': {
|
|
7
|
+
const { startDaemon } = await import('./daemon/index.js');
|
|
8
|
+
await startDaemon(args.slice(1));
|
|
9
|
+
break;
|
|
10
|
+
}
|
|
11
|
+
case 'register':
|
|
12
|
+
case 'myinfo': {
|
|
13
|
+
const { runCli } = await import('./cli/index.js');
|
|
14
|
+
await runCli(args);
|
|
15
|
+
break;
|
|
16
|
+
}
|
|
17
|
+
default: {
|
|
18
|
+
const { runCli } = await import('./cli/index.js');
|
|
19
|
+
await runCli(args);
|
|
20
|
+
break;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
main().catch((err) => {
|
|
25
|
+
console.error(`\n Error: ${err.message}\n`);
|
|
26
|
+
process.exit(1);
|
|
27
|
+
});
|
|
28
|
+
export {};
|
|
29
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { MaclatConfig } from './types.js';
|
|
2
|
+
export declare const GATEWAY_URL = "https://api.maclat.com";
|
|
3
|
+
export declare const CONFIG_PATH: string;
|
|
4
|
+
export declare const POLL_INTERVAL_MS = 5000;
|
|
5
|
+
export declare const MAX_CLAUDE_TURNS = 50;
|
|
6
|
+
export declare const JOBS_DIR: string;
|
|
7
|
+
export declare function ensureMaclatDir(): void;
|
|
8
|
+
export declare function loadConfig(): MaclatConfig;
|
|
9
|
+
export declare function saveConfig(config: MaclatConfig): void;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
|
|
2
|
+
import { homedir } from 'os';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
export const GATEWAY_URL = 'https://api.maclat.com';
|
|
5
|
+
export const CONFIG_PATH = join(homedir(), '.maclat', 'config.json');
|
|
6
|
+
export const POLL_INTERVAL_MS = 5000;
|
|
7
|
+
export const MAX_CLAUDE_TURNS = 50;
|
|
8
|
+
export const JOBS_DIR = join(homedir(), '.maclat', 'jobs');
|
|
9
|
+
export function ensureMaclatDir() {
|
|
10
|
+
const dir = join(homedir(), '.maclat');
|
|
11
|
+
if (!existsSync(dir)) {
|
|
12
|
+
mkdirSync(dir, { recursive: true });
|
|
13
|
+
}
|
|
14
|
+
if (!existsSync(JOBS_DIR)) {
|
|
15
|
+
mkdirSync(JOBS_DIR, { recursive: true });
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export function loadConfig() {
|
|
19
|
+
ensureMaclatDir();
|
|
20
|
+
if (existsSync(CONFIG_PATH)) {
|
|
21
|
+
return JSON.parse(readFileSync(CONFIG_PATH, 'utf-8'));
|
|
22
|
+
}
|
|
23
|
+
return { gateway_url: GATEWAY_URL };
|
|
24
|
+
}
|
|
25
|
+
export function saveConfig(config) {
|
|
26
|
+
ensureMaclatDir();
|
|
27
|
+
writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2));
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/shared/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AACxE,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B,MAAM,CAAC,MAAM,WAAW,GAAG,wBAAwB,CAAC;AACpD,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC;AACrE,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC;AACrC,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,CAAC;AACnC,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;AAE3D,MAAM,UAAU,eAAe;IAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;IACvC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACrB,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtC,CAAC;IACD,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,eAAe,EAAE,CAAC;IAClB,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC5B,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAoB;IAC7C,eAAe,EAAE,CAAC;IAClB,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export type JobStatus = 'open' | 'claimed' | 'in_progress' | 'delivered' | 'completed' | 'cancelled';
|
|
2
|
+
export type UpdateType = 'text' | 'terminal' | 'file_diff';
|
|
3
|
+
export interface Agent {
|
|
4
|
+
id: string;
|
|
5
|
+
name: string;
|
|
6
|
+
temp_wallet_address: string | null;
|
|
7
|
+
status: 'active' | 'busy' | 'offline';
|
|
8
|
+
created_at: string;
|
|
9
|
+
}
|
|
10
|
+
export interface Job {
|
|
11
|
+
id: string;
|
|
12
|
+
poster_id: string;
|
|
13
|
+
title: string;
|
|
14
|
+
description: string;
|
|
15
|
+
budget_usdc: number;
|
|
16
|
+
status: JobStatus;
|
|
17
|
+
agent_id: string | null;
|
|
18
|
+
created_at: string;
|
|
19
|
+
}
|
|
20
|
+
export interface ProgressUpdate {
|
|
21
|
+
id: string;
|
|
22
|
+
job_id: string;
|
|
23
|
+
agent_id: string;
|
|
24
|
+
type: UpdateType;
|
|
25
|
+
content: string;
|
|
26
|
+
created_at: string;
|
|
27
|
+
}
|
|
28
|
+
export interface Deliverable {
|
|
29
|
+
id: string;
|
|
30
|
+
job_id: string;
|
|
31
|
+
agent_id: string;
|
|
32
|
+
files: string;
|
|
33
|
+
summary: string;
|
|
34
|
+
created_at: string;
|
|
35
|
+
}
|
|
36
|
+
export interface MaclatConfig {
|
|
37
|
+
agent_id?: string;
|
|
38
|
+
agent_name?: string;
|
|
39
|
+
gateway_url: string;
|
|
40
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/shared/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "maclat",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Maclat - Agent CLI for the autonomous job marketplace",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"maclat": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist/**/*"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc",
|
|
15
|
+
"dev": "tsx src/index.ts",
|
|
16
|
+
"clean": "rm -rf dist",
|
|
17
|
+
"prepublishOnly": "npm run clean && npm run build"
|
|
18
|
+
},
|
|
19
|
+
"engines": {
|
|
20
|
+
"node": ">=20.0.0"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"cli",
|
|
24
|
+
"autonomous-agent",
|
|
25
|
+
"job-marketplace",
|
|
26
|
+
"ai-agent",
|
|
27
|
+
"maclat"
|
|
28
|
+
],
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"ulid": "^2.3.0"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/node": "^20.10.0",
|
|
35
|
+
"tsx": "^4.7.0",
|
|
36
|
+
"typescript": "^5.9.3"
|
|
37
|
+
}
|
|
38
|
+
}
|