@artyfacts/claude 1.1.1 → 1.1.2
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.js +83 -0
- package/dist/cli.mjs +83 -0
- package/package.json +1 -1
- package/src/cli.ts +127 -0
package/dist/cli.js
CHANGED
|
@@ -637,6 +637,88 @@ program.command("status").description("Check authentication and connection statu
|
|
|
637
637
|
console.log(" Install: npm install -g @anthropic-ai/claude-code");
|
|
638
638
|
}
|
|
639
639
|
});
|
|
640
|
+
async function checkAndClaimTasks(baseUrl, apiKey, agentId, activeTasks, executor, dryRun) {
|
|
641
|
+
try {
|
|
642
|
+
const response = await fetch(`${baseUrl}/tasks/queue?limit=5`, {
|
|
643
|
+
headers: {
|
|
644
|
+
"Authorization": `Bearer ${apiKey}`
|
|
645
|
+
}
|
|
646
|
+
});
|
|
647
|
+
if (!response.ok) {
|
|
648
|
+
console.log("\u26A0\uFE0F Could not fetch task queue");
|
|
649
|
+
return;
|
|
650
|
+
}
|
|
651
|
+
const data = await response.json();
|
|
652
|
+
const tasks = data.tasks || [];
|
|
653
|
+
if (tasks.length === 0) {
|
|
654
|
+
console.log("\u{1F4ED} No claimable tasks in queue");
|
|
655
|
+
return;
|
|
656
|
+
}
|
|
657
|
+
console.log(`\u{1F4EC} Found ${tasks.length} claimable task(s)`);
|
|
658
|
+
for (const task of tasks) {
|
|
659
|
+
if (activeTasks.has(task.section_id)) {
|
|
660
|
+
continue;
|
|
661
|
+
}
|
|
662
|
+
console.log(`
|
|
663
|
+
[Claiming] ${task.heading}`);
|
|
664
|
+
const claimResponse = await fetch(`${baseUrl}/tasks/${task.section_id}/claim`, {
|
|
665
|
+
method: "POST",
|
|
666
|
+
headers: {
|
|
667
|
+
"Authorization": `Bearer ${apiKey}`,
|
|
668
|
+
"Content-Type": "application/json"
|
|
669
|
+
}
|
|
670
|
+
});
|
|
671
|
+
if (!claimResponse.ok) {
|
|
672
|
+
const error = await claimResponse.json().catch(() => ({}));
|
|
673
|
+
console.log(` \u26A0\uFE0F Could not claim: ${error.error || "Unknown error"}`);
|
|
674
|
+
continue;
|
|
675
|
+
}
|
|
676
|
+
activeTasks.add(task.section_id);
|
|
677
|
+
console.log(" \u2713 Claimed!");
|
|
678
|
+
if (dryRun) {
|
|
679
|
+
console.log(" \u{1F4CB} Dry run - not executing");
|
|
680
|
+
activeTasks.delete(task.section_id);
|
|
681
|
+
continue;
|
|
682
|
+
}
|
|
683
|
+
console.log(" \u2192 Executing with Claude...");
|
|
684
|
+
try {
|
|
685
|
+
const result = await executor.execute({
|
|
686
|
+
taskId: task.section_id,
|
|
687
|
+
heading: task.heading,
|
|
688
|
+
content: task.content,
|
|
689
|
+
artifactId: task.artifact_id,
|
|
690
|
+
artifactTitle: task.artifact_title,
|
|
691
|
+
priority: task.priority
|
|
692
|
+
});
|
|
693
|
+
if (result.success) {
|
|
694
|
+
await completeTask({
|
|
695
|
+
baseUrl,
|
|
696
|
+
apiKey,
|
|
697
|
+
taskId: task.section_id,
|
|
698
|
+
output: result.output,
|
|
699
|
+
summary: result.summary
|
|
700
|
+
});
|
|
701
|
+
console.log(` \u2192 \u2705 Completed! ${result.summary}`);
|
|
702
|
+
} else {
|
|
703
|
+
console.log(` \u2192 \u274C Failed: ${result.error}`);
|
|
704
|
+
await blockTask({
|
|
705
|
+
baseUrl,
|
|
706
|
+
apiKey,
|
|
707
|
+
taskId: task.section_id,
|
|
708
|
+
reason: result.error || "Execution failed"
|
|
709
|
+
});
|
|
710
|
+
}
|
|
711
|
+
} catch (error) {
|
|
712
|
+
console.error(` \u2192 \u274C Error:`, error instanceof Error ? error.message : error);
|
|
713
|
+
} finally {
|
|
714
|
+
activeTasks.delete(task.section_id);
|
|
715
|
+
}
|
|
716
|
+
break;
|
|
717
|
+
}
|
|
718
|
+
} catch (error) {
|
|
719
|
+
console.error("Error checking task queue:", error instanceof Error ? error.message : error);
|
|
720
|
+
}
|
|
721
|
+
}
|
|
640
722
|
async function runAgent(options) {
|
|
641
723
|
console.log("\u{1F517} Connecting to Artyfacts...");
|
|
642
724
|
let credentials;
|
|
@@ -677,6 +759,7 @@ async function runAgent(options) {
|
|
|
677
759
|
case "connected":
|
|
678
760
|
console.log(`\u2705 Connected as ${credentials.agentId}`);
|
|
679
761
|
console.log("\u{1F442} Listening for tasks...\n");
|
|
762
|
+
checkAndClaimTasks(options.baseUrl, credentials.apiKey, credentials.agentId, activeTasks, executor, options.dryRun);
|
|
680
763
|
break;
|
|
681
764
|
case "reconnecting":
|
|
682
765
|
console.log("\u{1F504} Reconnecting...");
|
package/dist/cli.mjs
CHANGED
|
@@ -65,6 +65,88 @@ program.command("status").description("Check authentication and connection statu
|
|
|
65
65
|
console.log(" Install: npm install -g @anthropic-ai/claude-code");
|
|
66
66
|
}
|
|
67
67
|
});
|
|
68
|
+
async function checkAndClaimTasks(baseUrl, apiKey, agentId, activeTasks, executor, dryRun) {
|
|
69
|
+
try {
|
|
70
|
+
const response = await fetch(`${baseUrl}/tasks/queue?limit=5`, {
|
|
71
|
+
headers: {
|
|
72
|
+
"Authorization": `Bearer ${apiKey}`
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
if (!response.ok) {
|
|
76
|
+
console.log("\u26A0\uFE0F Could not fetch task queue");
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
const data = await response.json();
|
|
80
|
+
const tasks = data.tasks || [];
|
|
81
|
+
if (tasks.length === 0) {
|
|
82
|
+
console.log("\u{1F4ED} No claimable tasks in queue");
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
console.log(`\u{1F4EC} Found ${tasks.length} claimable task(s)`);
|
|
86
|
+
for (const task of tasks) {
|
|
87
|
+
if (activeTasks.has(task.section_id)) {
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
console.log(`
|
|
91
|
+
[Claiming] ${task.heading}`);
|
|
92
|
+
const claimResponse = await fetch(`${baseUrl}/tasks/${task.section_id}/claim`, {
|
|
93
|
+
method: "POST",
|
|
94
|
+
headers: {
|
|
95
|
+
"Authorization": `Bearer ${apiKey}`,
|
|
96
|
+
"Content-Type": "application/json"
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
if (!claimResponse.ok) {
|
|
100
|
+
const error = await claimResponse.json().catch(() => ({}));
|
|
101
|
+
console.log(` \u26A0\uFE0F Could not claim: ${error.error || "Unknown error"}`);
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
activeTasks.add(task.section_id);
|
|
105
|
+
console.log(" \u2713 Claimed!");
|
|
106
|
+
if (dryRun) {
|
|
107
|
+
console.log(" \u{1F4CB} Dry run - not executing");
|
|
108
|
+
activeTasks.delete(task.section_id);
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
console.log(" \u2192 Executing with Claude...");
|
|
112
|
+
try {
|
|
113
|
+
const result = await executor.execute({
|
|
114
|
+
taskId: task.section_id,
|
|
115
|
+
heading: task.heading,
|
|
116
|
+
content: task.content,
|
|
117
|
+
artifactId: task.artifact_id,
|
|
118
|
+
artifactTitle: task.artifact_title,
|
|
119
|
+
priority: task.priority
|
|
120
|
+
});
|
|
121
|
+
if (result.success) {
|
|
122
|
+
await completeTask({
|
|
123
|
+
baseUrl,
|
|
124
|
+
apiKey,
|
|
125
|
+
taskId: task.section_id,
|
|
126
|
+
output: result.output,
|
|
127
|
+
summary: result.summary
|
|
128
|
+
});
|
|
129
|
+
console.log(` \u2192 \u2705 Completed! ${result.summary}`);
|
|
130
|
+
} else {
|
|
131
|
+
console.log(` \u2192 \u274C Failed: ${result.error}`);
|
|
132
|
+
await blockTask({
|
|
133
|
+
baseUrl,
|
|
134
|
+
apiKey,
|
|
135
|
+
taskId: task.section_id,
|
|
136
|
+
reason: result.error || "Execution failed"
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
} catch (error) {
|
|
140
|
+
console.error(` \u2192 \u274C Error:`, error instanceof Error ? error.message : error);
|
|
141
|
+
} finally {
|
|
142
|
+
activeTasks.delete(task.section_id);
|
|
143
|
+
}
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
} catch (error) {
|
|
147
|
+
console.error("Error checking task queue:", error instanceof Error ? error.message : error);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
68
150
|
async function runAgent(options) {
|
|
69
151
|
console.log("\u{1F517} Connecting to Artyfacts...");
|
|
70
152
|
let credentials;
|
|
@@ -105,6 +187,7 @@ async function runAgent(options) {
|
|
|
105
187
|
case "connected":
|
|
106
188
|
console.log(`\u2705 Connected as ${credentials.agentId}`);
|
|
107
189
|
console.log("\u{1F442} Listening for tasks...\n");
|
|
190
|
+
checkAndClaimTasks(options.baseUrl, credentials.apiKey, credentials.agentId, activeTasks, executor, options.dryRun);
|
|
108
191
|
break;
|
|
109
192
|
case "reconnecting":
|
|
110
193
|
console.log("\u{1F504} Reconnecting...");
|
package/package.json
CHANGED
package/src/cli.ts
CHANGED
|
@@ -126,6 +126,130 @@ program
|
|
|
126
126
|
}
|
|
127
127
|
});
|
|
128
128
|
|
|
129
|
+
// ============================================================================
|
|
130
|
+
// Task Queue Polling
|
|
131
|
+
// ============================================================================
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Check for claimable tasks and process them
|
|
135
|
+
*/
|
|
136
|
+
async function checkAndClaimTasks(
|
|
137
|
+
baseUrl: string,
|
|
138
|
+
apiKey: string,
|
|
139
|
+
agentId: string,
|
|
140
|
+
activeTasks: Set<string>,
|
|
141
|
+
executor: ClaudeExecutor,
|
|
142
|
+
dryRun: boolean
|
|
143
|
+
): Promise<void> {
|
|
144
|
+
try {
|
|
145
|
+
// Fetch claimable tasks from queue
|
|
146
|
+
const response = await fetch(`${baseUrl}/tasks/queue?limit=5`, {
|
|
147
|
+
headers: {
|
|
148
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
if (!response.ok) {
|
|
153
|
+
console.log('⚠️ Could not fetch task queue');
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const data = await response.json() as { tasks?: Array<{
|
|
158
|
+
id: string;
|
|
159
|
+
section_id: string;
|
|
160
|
+
heading: string;
|
|
161
|
+
content: string;
|
|
162
|
+
artifact_id: string;
|
|
163
|
+
artifact_title?: string;
|
|
164
|
+
priority?: number;
|
|
165
|
+
}> };
|
|
166
|
+
|
|
167
|
+
const tasks = data.tasks || [];
|
|
168
|
+
|
|
169
|
+
if (tasks.length === 0) {
|
|
170
|
+
console.log('📭 No claimable tasks in queue');
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
console.log(`📬 Found ${tasks.length} claimable task(s)`);
|
|
175
|
+
|
|
176
|
+
// Process first available task
|
|
177
|
+
for (const task of tasks) {
|
|
178
|
+
if (activeTasks.has(task.section_id)) {
|
|
179
|
+
continue; // Already processing
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Try to claim the task
|
|
183
|
+
console.log(`\n[Claiming] ${task.heading}`);
|
|
184
|
+
|
|
185
|
+
const claimResponse = await fetch(`${baseUrl}/tasks/${task.section_id}/claim`, {
|
|
186
|
+
method: 'POST',
|
|
187
|
+
headers: {
|
|
188
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
189
|
+
'Content-Type': 'application/json',
|
|
190
|
+
},
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
if (!claimResponse.ok) {
|
|
194
|
+
const error = await claimResponse.json().catch(() => ({})) as { error?: string };
|
|
195
|
+
console.log(` ⚠️ Could not claim: ${error.error || 'Unknown error'}`);
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Successfully claimed - now execute
|
|
200
|
+
activeTasks.add(task.section_id);
|
|
201
|
+
console.log(' ✓ Claimed!');
|
|
202
|
+
|
|
203
|
+
if (dryRun) {
|
|
204
|
+
console.log(' 📋 Dry run - not executing');
|
|
205
|
+
activeTasks.delete(task.section_id);
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
console.log(' → Executing with Claude...');
|
|
210
|
+
|
|
211
|
+
try {
|
|
212
|
+
const result = await executor.execute({
|
|
213
|
+
taskId: task.section_id,
|
|
214
|
+
heading: task.heading,
|
|
215
|
+
content: task.content,
|
|
216
|
+
artifactId: task.artifact_id,
|
|
217
|
+
artifactTitle: task.artifact_title,
|
|
218
|
+
priority: task.priority,
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
if (result.success) {
|
|
222
|
+
await completeTask({
|
|
223
|
+
baseUrl,
|
|
224
|
+
apiKey,
|
|
225
|
+
taskId: task.section_id,
|
|
226
|
+
output: result.output,
|
|
227
|
+
summary: result.summary,
|
|
228
|
+
});
|
|
229
|
+
console.log(` → ✅ Completed! ${result.summary}`);
|
|
230
|
+
} else {
|
|
231
|
+
console.log(` → ❌ Failed: ${result.error}`);
|
|
232
|
+
await blockTask({
|
|
233
|
+
baseUrl,
|
|
234
|
+
apiKey,
|
|
235
|
+
taskId: task.section_id,
|
|
236
|
+
reason: result.error || 'Execution failed',
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
} catch (error) {
|
|
240
|
+
console.error(` → ❌ Error:`, error instanceof Error ? error.message : error);
|
|
241
|
+
} finally {
|
|
242
|
+
activeTasks.delete(task.section_id);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Only process one task at a time for now
|
|
246
|
+
break;
|
|
247
|
+
}
|
|
248
|
+
} catch (error) {
|
|
249
|
+
console.error('Error checking task queue:', error instanceof Error ? error.message : error);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
129
253
|
// ============================================================================
|
|
130
254
|
// Main Agent Loop
|
|
131
255
|
// ============================================================================
|
|
@@ -183,6 +307,9 @@ async function runAgent(options: {
|
|
|
183
307
|
case 'connected':
|
|
184
308
|
console.log(`✅ Connected as ${credentials.agentId}`);
|
|
185
309
|
console.log('👂 Listening for tasks...\n');
|
|
310
|
+
|
|
311
|
+
// Check for existing claimable tasks on connect
|
|
312
|
+
checkAndClaimTasks(options.baseUrl, credentials.apiKey, credentials.agentId, activeTasks, executor!, options.dryRun);
|
|
186
313
|
break;
|
|
187
314
|
case 'reconnecting':
|
|
188
315
|
console.log('🔄 Reconnecting...');
|