@artyfacts/claude 1.3.23 → 1.3.25
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/chunk-7QRIXWMF.mjs +1085 -0
- package/dist/chunk-HPMSVN7C.mjs +1084 -0
- package/dist/cli.js +146 -78
- package/dist/cli.mjs +50 -33
- package/dist/index.d.mts +100 -29
- package/dist/index.d.ts +100 -29
- package/dist/index.js +231 -80
- package/dist/index.mjs +135 -35
- package/package.json +9 -9
- package/src/cli.ts +80 -46
- package/src/context.ts +117 -41
- package/src/executor.ts +52 -26
- package/src/listener.ts +42 -15
- package/src/tools/handlers.ts +90 -17
- package/src/tools/registry.ts +90 -20
- package/src/tools/types.ts +87 -0
package/dist/index.mjs
CHANGED
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
promptForApiKey,
|
|
15
15
|
runDeviceAuth,
|
|
16
16
|
saveCredentials
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-7QRIXWMF.mjs";
|
|
18
18
|
|
|
19
19
|
// node_modules/@anthropic-ai/sdk/internal/tslib.mjs
|
|
20
20
|
function __classPrivateFieldSet(receiver, state, value, kind, f) {
|
|
@@ -4220,7 +4220,7 @@ var schemas = {
|
|
|
4220
4220
|
}
|
|
4221
4221
|
},
|
|
4222
4222
|
// ---------------------------------------------------------------------------
|
|
4223
|
-
// Task Tools
|
|
4223
|
+
// Task Tools (v2 - tasks are first-class entities)
|
|
4224
4224
|
// ---------------------------------------------------------------------------
|
|
4225
4225
|
get_task: {
|
|
4226
4226
|
name: "get_task",
|
|
@@ -4230,7 +4230,7 @@ var schemas = {
|
|
|
4230
4230
|
properties: {
|
|
4231
4231
|
task_id: {
|
|
4232
4232
|
type: "string",
|
|
4233
|
-
description: "The task UUID
|
|
4233
|
+
description: "The task UUID"
|
|
4234
4234
|
}
|
|
4235
4235
|
},
|
|
4236
4236
|
required: ["task_id"]
|
|
@@ -4238,13 +4238,13 @@ var schemas = {
|
|
|
4238
4238
|
},
|
|
4239
4239
|
list_tasks: {
|
|
4240
4240
|
name: "list_tasks",
|
|
4241
|
-
description: "List tasks with
|
|
4241
|
+
description: "List tasks from the queue. Returns tasks from the tasks table with goal context.",
|
|
4242
4242
|
input_schema: {
|
|
4243
4243
|
type: "object",
|
|
4244
4244
|
properties: {
|
|
4245
|
-
|
|
4245
|
+
goal_id: {
|
|
4246
4246
|
type: "string",
|
|
4247
|
-
description: "Filter by
|
|
4247
|
+
description: "Filter by goal ID"
|
|
4248
4248
|
},
|
|
4249
4249
|
status: {
|
|
4250
4250
|
type: "string",
|
|
@@ -4266,19 +4266,19 @@ var schemas = {
|
|
|
4266
4266
|
},
|
|
4267
4267
|
create_task: {
|
|
4268
4268
|
name: "create_task",
|
|
4269
|
-
description: "Create a new task
|
|
4269
|
+
description: "Create a new task under a goal.",
|
|
4270
4270
|
input_schema: {
|
|
4271
4271
|
type: "object",
|
|
4272
4272
|
properties: {
|
|
4273
|
-
|
|
4273
|
+
goal_id: {
|
|
4274
4274
|
type: "string",
|
|
4275
|
-
description: "The
|
|
4275
|
+
description: "The goal UUID to add the task to"
|
|
4276
4276
|
},
|
|
4277
|
-
|
|
4277
|
+
title: {
|
|
4278
4278
|
type: "string",
|
|
4279
|
-
description: "Task title
|
|
4279
|
+
description: "Task title"
|
|
4280
4280
|
},
|
|
4281
|
-
|
|
4281
|
+
description: {
|
|
4282
4282
|
type: "string",
|
|
4283
4283
|
description: "Task description and requirements"
|
|
4284
4284
|
},
|
|
@@ -4289,26 +4289,41 @@ var schemas = {
|
|
|
4289
4289
|
depends_on: {
|
|
4290
4290
|
type: "array",
|
|
4291
4291
|
items: { type: "string" },
|
|
4292
|
-
description: "Optional:
|
|
4292
|
+
description: "Optional: task IDs this depends on"
|
|
4293
4293
|
},
|
|
4294
4294
|
priority: {
|
|
4295
|
-
type: "
|
|
4296
|
-
enum: [
|
|
4297
|
-
|
|
4295
|
+
type: "string",
|
|
4296
|
+
enum: ["low", "medium", "high"],
|
|
4297
|
+
default: "medium",
|
|
4298
|
+
description: "Optional: priority level"
|
|
4298
4299
|
}
|
|
4299
4300
|
},
|
|
4300
|
-
required: ["
|
|
4301
|
+
required: ["goal_id", "title"]
|
|
4302
|
+
}
|
|
4303
|
+
},
|
|
4304
|
+
claim_task: {
|
|
4305
|
+
name: "claim_task",
|
|
4306
|
+
description: "Claim a task for execution. Sets status to in_progress.",
|
|
4307
|
+
input_schema: {
|
|
4308
|
+
type: "object",
|
|
4309
|
+
properties: {
|
|
4310
|
+
task_id: {
|
|
4311
|
+
type: "string",
|
|
4312
|
+
description: "The task UUID to claim"
|
|
4313
|
+
}
|
|
4314
|
+
},
|
|
4315
|
+
required: ["task_id"]
|
|
4301
4316
|
}
|
|
4302
4317
|
},
|
|
4303
4318
|
complete_task: {
|
|
4304
4319
|
name: "complete_task",
|
|
4305
|
-
description: "Mark a task as completed
|
|
4320
|
+
description: "Mark a task as completed. Returns list of unblocked tasks that can now be worked on.",
|
|
4306
4321
|
input_schema: {
|
|
4307
4322
|
type: "object",
|
|
4308
4323
|
properties: {
|
|
4309
4324
|
task_id: {
|
|
4310
4325
|
type: "string",
|
|
4311
|
-
description: "The task UUID
|
|
4326
|
+
description: "The task UUID"
|
|
4312
4327
|
},
|
|
4313
4328
|
output: {
|
|
4314
4329
|
type: "string",
|
|
@@ -4334,7 +4349,7 @@ var schemas = {
|
|
|
4334
4349
|
properties: {
|
|
4335
4350
|
task_id: {
|
|
4336
4351
|
type: "string",
|
|
4337
|
-
description: "The task UUID
|
|
4352
|
+
description: "The task UUID"
|
|
4338
4353
|
},
|
|
4339
4354
|
reason: {
|
|
4340
4355
|
type: "string",
|
|
@@ -4350,6 +4365,56 @@ var schemas = {
|
|
|
4350
4365
|
}
|
|
4351
4366
|
},
|
|
4352
4367
|
// ---------------------------------------------------------------------------
|
|
4368
|
+
// Inbox Tools (v2)
|
|
4369
|
+
// ---------------------------------------------------------------------------
|
|
4370
|
+
list_inbox: {
|
|
4371
|
+
name: "list_inbox",
|
|
4372
|
+
description: "List pending inbox items (decisions, approvals, reviews).",
|
|
4373
|
+
input_schema: {
|
|
4374
|
+
type: "object",
|
|
4375
|
+
properties: {
|
|
4376
|
+
status: {
|
|
4377
|
+
type: "string",
|
|
4378
|
+
enum: ["pending", "resolved"],
|
|
4379
|
+
description: "Filter by status"
|
|
4380
|
+
},
|
|
4381
|
+
kind: {
|
|
4382
|
+
type: "string",
|
|
4383
|
+
enum: ["decision", "approval", "review"],
|
|
4384
|
+
description: "Filter by type"
|
|
4385
|
+
},
|
|
4386
|
+
limit: {
|
|
4387
|
+
type: "number",
|
|
4388
|
+
default: 20,
|
|
4389
|
+
description: "Max results"
|
|
4390
|
+
}
|
|
4391
|
+
},
|
|
4392
|
+
required: []
|
|
4393
|
+
}
|
|
4394
|
+
},
|
|
4395
|
+
resolve_inbox: {
|
|
4396
|
+
name: "resolve_inbox",
|
|
4397
|
+
description: "Resolve an inbox item with a decision. May trigger auto-execution.",
|
|
4398
|
+
input_schema: {
|
|
4399
|
+
type: "object",
|
|
4400
|
+
properties: {
|
|
4401
|
+
inbox_id: {
|
|
4402
|
+
type: "string",
|
|
4403
|
+
description: "The inbox item UUID"
|
|
4404
|
+
},
|
|
4405
|
+
decision: {
|
|
4406
|
+
type: "string",
|
|
4407
|
+
description: "The decision/resolution"
|
|
4408
|
+
},
|
|
4409
|
+
notes: {
|
|
4410
|
+
type: "string",
|
|
4411
|
+
description: "Optional: additional notes"
|
|
4412
|
+
}
|
|
4413
|
+
},
|
|
4414
|
+
required: ["inbox_id", "decision"]
|
|
4415
|
+
}
|
|
4416
|
+
},
|
|
4417
|
+
// ---------------------------------------------------------------------------
|
|
4353
4418
|
// Blocker Tools
|
|
4354
4419
|
// ---------------------------------------------------------------------------
|
|
4355
4420
|
get_blocker: {
|
|
@@ -4504,7 +4569,9 @@ var permissionToTools = {
|
|
|
4504
4569
|
"agents:read": ["get_agent", "list_agents"],
|
|
4505
4570
|
"agents:write": ["create_agent", "update_agent"],
|
|
4506
4571
|
"tasks:read": ["get_task", "list_tasks"],
|
|
4507
|
-
"tasks:write": ["create_task", "complete_task", "block_task"],
|
|
4572
|
+
"tasks:write": ["create_task", "claim_task", "complete_task", "block_task"],
|
|
4573
|
+
"inbox:read": ["list_inbox"],
|
|
4574
|
+
"inbox:write": ["resolve_inbox"],
|
|
4508
4575
|
"blockers:read": ["get_blocker", "list_blockers"],
|
|
4509
4576
|
"blockers:write": ["create_blocker", "resolve_blocker"],
|
|
4510
4577
|
"org:read": ["get_org_context", "get_project", "list_projects"]
|
|
@@ -4737,12 +4804,12 @@ var getTaskHandler = async (args, client) => {
|
|
|
4737
4804
|
var listTasksHandler = async (args, client) => {
|
|
4738
4805
|
try {
|
|
4739
4806
|
const params = new URLSearchParams();
|
|
4740
|
-
if (args.
|
|
4807
|
+
if (args.goal_id) params.set("goal_id", String(args.goal_id));
|
|
4741
4808
|
if (args.status) params.set("status", String(args.status));
|
|
4742
4809
|
if (args.assignee) params.set("assignee", String(args.assignee));
|
|
4743
4810
|
if (args.limit) params.set("limit", String(args.limit));
|
|
4744
4811
|
const query = params.toString();
|
|
4745
|
-
const path2 = `/tasks${query ? `?${query}` : ""}`;
|
|
4812
|
+
const path2 = `/tasks/queue${query ? `?${query}` : ""}`;
|
|
4746
4813
|
const data = await client.get(path2);
|
|
4747
4814
|
return { success: true, data };
|
|
4748
4815
|
} catch (error) {
|
|
@@ -4751,23 +4818,27 @@ var listTasksHandler = async (args, client) => {
|
|
|
4751
4818
|
};
|
|
4752
4819
|
var createTaskHandler = async (args, client) => {
|
|
4753
4820
|
try {
|
|
4754
|
-
const data = await client.post(
|
|
4755
|
-
|
|
4756
|
-
|
|
4757
|
-
|
|
4758
|
-
type: "task",
|
|
4759
|
-
task_status: "pending",
|
|
4821
|
+
const data = await client.post("/tasks", {
|
|
4822
|
+
goal_id: args.goal_id,
|
|
4823
|
+
title: args.title,
|
|
4824
|
+
description: args.description,
|
|
4760
4825
|
assignee_agent_id: args.assignee,
|
|
4761
4826
|
depends_on: args.depends_on,
|
|
4762
|
-
priority: args.priority
|
|
4763
|
-
agent_id: "system",
|
|
4764
|
-
agent_name: "System"
|
|
4827
|
+
priority: args.priority || "medium"
|
|
4765
4828
|
});
|
|
4766
4829
|
return { success: true, data };
|
|
4767
4830
|
} catch (error) {
|
|
4768
4831
|
return { success: false, error: String(error) };
|
|
4769
4832
|
}
|
|
4770
4833
|
};
|
|
4834
|
+
var claimTaskHandler = async (args, client) => {
|
|
4835
|
+
try {
|
|
4836
|
+
const data = await client.post(`/tasks/${args.task_id}/claim`, {});
|
|
4837
|
+
return { success: true, data };
|
|
4838
|
+
} catch (error) {
|
|
4839
|
+
return { success: false, error: String(error) };
|
|
4840
|
+
}
|
|
4841
|
+
};
|
|
4771
4842
|
var completeTaskHandler = async (args, client) => {
|
|
4772
4843
|
try {
|
|
4773
4844
|
const data = await client.post(`/tasks/${args.task_id}/complete`, {
|
|
@@ -4782,7 +4853,7 @@ var completeTaskHandler = async (args, client) => {
|
|
|
4782
4853
|
};
|
|
4783
4854
|
var blockTaskHandler = async (args, client) => {
|
|
4784
4855
|
try {
|
|
4785
|
-
const data = await client.post(`/tasks/${args.task_id}/
|
|
4856
|
+
const data = await client.post(`/tasks/${args.task_id}/block`, {
|
|
4786
4857
|
reason: args.reason,
|
|
4787
4858
|
blocker_type: args.blocker_type
|
|
4788
4859
|
});
|
|
@@ -4791,6 +4862,31 @@ var blockTaskHandler = async (args, client) => {
|
|
|
4791
4862
|
return { success: false, error: String(error) };
|
|
4792
4863
|
}
|
|
4793
4864
|
};
|
|
4865
|
+
var listInboxHandler = async (args, client) => {
|
|
4866
|
+
try {
|
|
4867
|
+
const params = new URLSearchParams();
|
|
4868
|
+
if (args.status) params.set("status", String(args.status));
|
|
4869
|
+
if (args.kind) params.set("kind", String(args.kind));
|
|
4870
|
+
if (args.limit) params.set("limit", String(args.limit));
|
|
4871
|
+
const query = params.toString();
|
|
4872
|
+
const path2 = `/inbox${query ? `?${query}` : ""}`;
|
|
4873
|
+
const data = await client.get(path2);
|
|
4874
|
+
return { success: true, data };
|
|
4875
|
+
} catch (error) {
|
|
4876
|
+
return { success: false, error: String(error) };
|
|
4877
|
+
}
|
|
4878
|
+
};
|
|
4879
|
+
var resolveInboxHandler = async (args, client) => {
|
|
4880
|
+
try {
|
|
4881
|
+
const data = await client.post(`/inbox/${args.inbox_id}/resolve`, {
|
|
4882
|
+
decision: args.decision,
|
|
4883
|
+
notes: args.notes
|
|
4884
|
+
});
|
|
4885
|
+
return { success: true, data };
|
|
4886
|
+
} catch (error) {
|
|
4887
|
+
return { success: false, error: String(error) };
|
|
4888
|
+
}
|
|
4889
|
+
};
|
|
4794
4890
|
var getBlockerHandler = async (args, client) => {
|
|
4795
4891
|
try {
|
|
4796
4892
|
const data = await client.get(`/blockers/${args.blocker_id}`);
|
|
@@ -4886,13 +4982,17 @@ var handlers = {
|
|
|
4886
4982
|
list_agents: listAgentsHandler,
|
|
4887
4983
|
create_agent: createAgentHandler,
|
|
4888
4984
|
update_agent: updateAgentHandler,
|
|
4889
|
-
// Tasks
|
|
4985
|
+
// Tasks (v2)
|
|
4890
4986
|
get_task: getTaskHandler,
|
|
4891
4987
|
list_tasks: listTasksHandler,
|
|
4892
4988
|
create_task: createTaskHandler,
|
|
4989
|
+
claim_task: claimTaskHandler,
|
|
4893
4990
|
complete_task: completeTaskHandler,
|
|
4894
4991
|
block_task: blockTaskHandler,
|
|
4895
|
-
//
|
|
4992
|
+
// Inbox (v2)
|
|
4993
|
+
list_inbox: listInboxHandler,
|
|
4994
|
+
resolve_inbox: resolveInboxHandler,
|
|
4995
|
+
// Blockers (legacy - kept for compatibility)
|
|
4896
4996
|
get_blocker: getBlockerHandler,
|
|
4897
4997
|
list_blockers: listBlockersHandler,
|
|
4898
4998
|
create_blocker: createBlockerHandler,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@artyfacts/claude",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.25",
|
|
4
4
|
"description": "Claude adapter for Artyfacts - Execute tasks using Claude Code CLI",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -15,13 +15,6 @@
|
|
|
15
15
|
"require": "./dist/index.js"
|
|
16
16
|
}
|
|
17
17
|
},
|
|
18
|
-
"scripts": {
|
|
19
|
-
"build": "tsup src/index.ts src/cli.ts --format cjs,esm --dts",
|
|
20
|
-
"dev": "tsup src/index.ts src/cli.ts --format cjs,esm --dts --watch",
|
|
21
|
-
"start": "node bin/artyfacts-claude.js",
|
|
22
|
-
"test": "vitest",
|
|
23
|
-
"lint": "eslint src/"
|
|
24
|
-
},
|
|
25
18
|
"keywords": [
|
|
26
19
|
"artyfacts",
|
|
27
20
|
"claude",
|
|
@@ -54,5 +47,12 @@
|
|
|
54
47
|
},
|
|
55
48
|
"engines": {
|
|
56
49
|
"node": ">=18.0.0"
|
|
50
|
+
},
|
|
51
|
+
"scripts": {
|
|
52
|
+
"build": "tsup src/index.ts src/cli.ts --format cjs,esm --dts",
|
|
53
|
+
"dev": "tsup src/index.ts src/cli.ts --format cjs,esm --dts --watch",
|
|
54
|
+
"start": "node bin/artyfacts-claude.js",
|
|
55
|
+
"test": "vitest",
|
|
56
|
+
"lint": "eslint src/"
|
|
57
57
|
}
|
|
58
|
-
}
|
|
58
|
+
}
|
package/src/cli.ts
CHANGED
|
@@ -227,12 +227,16 @@ async function checkAndClaimTasks(
|
|
|
227
227
|
|
|
228
228
|
const data = await response.json() as { tasks?: Array<{
|
|
229
229
|
id: string;
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
priority
|
|
230
|
+
goal_id: string;
|
|
231
|
+
goal_title?: string;
|
|
232
|
+
title: string;
|
|
233
|
+
description?: string;
|
|
234
|
+
status: string;
|
|
235
|
+
priority: string;
|
|
236
|
+
estimated_minutes?: number;
|
|
237
|
+
agent_id?: string;
|
|
238
|
+
agent_name?: string;
|
|
239
|
+
metadata?: Record<string, unknown>;
|
|
236
240
|
}> };
|
|
237
241
|
|
|
238
242
|
const tasks = data.tasks || [];
|
|
@@ -252,14 +256,18 @@ async function checkAndClaimTasks(
|
|
|
252
256
|
}
|
|
253
257
|
|
|
254
258
|
// Try to claim the task
|
|
255
|
-
console.log(`\n[Claiming] ${task.
|
|
259
|
+
console.log(`\n[Claiming] ${task.title} (as ${task.agent_name || task.agent_id || 'unknown'})`);
|
|
256
260
|
|
|
257
|
-
|
|
261
|
+
// Use task.id (UUID) for claiming, include agent_id from task
|
|
262
|
+
const claimResponse = await fetch(`${baseUrl}/tasks/${task.id}/claim`, {
|
|
258
263
|
method: 'POST',
|
|
259
264
|
headers: {
|
|
260
265
|
'Authorization': `Bearer ${apiKey}`,
|
|
261
266
|
'Content-Type': 'application/json',
|
|
262
267
|
},
|
|
268
|
+
body: JSON.stringify({
|
|
269
|
+
agent_id: task.agent_id,
|
|
270
|
+
}),
|
|
263
271
|
});
|
|
264
272
|
|
|
265
273
|
if (!claimResponse.ok) {
|
|
@@ -268,19 +276,17 @@ async function checkAndClaimTasks(
|
|
|
268
276
|
continue;
|
|
269
277
|
}
|
|
270
278
|
|
|
271
|
-
// Get the claimed task data
|
|
272
|
-
// Response format: { success: true, task: { id: ..., artifact_id: ..., ... } }
|
|
279
|
+
// Get the claimed task data
|
|
273
280
|
const claimData = await claimResponse.json().catch((e) => {
|
|
274
281
|
console.log(` ⚠️ Could not parse claim response: ${e}`);
|
|
275
282
|
return { task: { id: task.id } };
|
|
276
283
|
}) as {
|
|
277
|
-
|
|
278
|
-
task?: { id: string;
|
|
284
|
+
claimed?: boolean;
|
|
285
|
+
task?: { id: string; goal_id?: string; goal_title?: string };
|
|
279
286
|
};
|
|
280
287
|
|
|
281
|
-
// Use UUID for subsequent calls (globally unique, avoids org filter issues)
|
|
282
288
|
const taskUuid = claimData.task?.id || task.id;
|
|
283
|
-
|
|
289
|
+
const goalTitle = claimData.task?.goal_title || task.goal_title;
|
|
284
290
|
|
|
285
291
|
// Successfully claimed - now execute
|
|
286
292
|
activeTasks.add(task.id);
|
|
@@ -295,14 +301,20 @@ async function checkAndClaimTasks(
|
|
|
295
301
|
console.log(' → Executing with Claude...');
|
|
296
302
|
|
|
297
303
|
try {
|
|
298
|
-
//
|
|
304
|
+
// Execute the task (v2 schema)
|
|
305
|
+
const priorityMap: Record<string, 'low' | 'medium' | 'high'> = {
|
|
306
|
+
'urgent': 'high',
|
|
307
|
+
'high': 'high',
|
|
308
|
+
'medium': 'medium',
|
|
309
|
+
'low': 'low',
|
|
310
|
+
};
|
|
299
311
|
const result = await executor.execute({
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
priority: task.priority,
|
|
312
|
+
id: taskUuid,
|
|
313
|
+
title: task.title,
|
|
314
|
+
description: task.description || '',
|
|
315
|
+
goalId: task.goal_id,
|
|
316
|
+
goalTitle: goalTitle,
|
|
317
|
+
priority: priorityMap[task.priority] || 'medium',
|
|
306
318
|
});
|
|
307
319
|
|
|
308
320
|
if (result.success) {
|
|
@@ -451,36 +463,43 @@ async function runAgent(options: {
|
|
|
451
463
|
await mcpHandler.handleConnectRequest(event);
|
|
452
464
|
});
|
|
453
465
|
|
|
454
|
-
// Handle task assignments
|
|
466
|
+
// Handle task assignments (v2 schema)
|
|
455
467
|
listener.on<TaskAssignedEvent>('task_assigned', async (event) => {
|
|
456
468
|
const task = event.data;
|
|
457
469
|
|
|
458
|
-
//
|
|
459
|
-
|
|
470
|
+
// v2: use id, fallback to taskId for backwards compatibility
|
|
471
|
+
const taskId = task.id || task.taskId || '';
|
|
472
|
+
const taskTitle = task.title || task.heading || 'Untitled Task';
|
|
473
|
+
const taskDescription = task.description || task.content || '';
|
|
474
|
+
const goalId = task.goalId || task.artifactId || '';
|
|
475
|
+
const goalTitle = task.goalTitle || task.artifactTitle;
|
|
476
|
+
|
|
477
|
+
// Skip if already processing or no task ID
|
|
478
|
+
if (!taskId || activeTasks.has(taskId)) {
|
|
460
479
|
return;
|
|
461
480
|
}
|
|
462
|
-
activeTasks.add(
|
|
481
|
+
activeTasks.add(taskId);
|
|
463
482
|
|
|
464
|
-
console.log(`\n[Task received] ${
|
|
483
|
+
console.log(`\n[Task received] ${taskTitle}`);
|
|
465
484
|
|
|
466
485
|
if (options.dryRun) {
|
|
467
486
|
console.log(' 📋 Dry run - not executing');
|
|
468
|
-
console.log(` 📄
|
|
469
|
-
console.log(` 📝
|
|
470
|
-
activeTasks.delete(
|
|
487
|
+
console.log(` 📄 Goal: ${goalTitle || goalId}`);
|
|
488
|
+
console.log(` 📝 Description: ${taskDescription.substring(0, 100)}...`);
|
|
489
|
+
activeTasks.delete(taskId);
|
|
471
490
|
return;
|
|
472
491
|
}
|
|
473
492
|
|
|
474
493
|
console.log(' → Executing with Claude...');
|
|
475
494
|
|
|
476
495
|
try {
|
|
477
|
-
// Build task context
|
|
496
|
+
// Build task context (v2)
|
|
478
497
|
const taskContext: TaskContext = {
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
498
|
+
id: taskId,
|
|
499
|
+
title: taskTitle,
|
|
500
|
+
description: taskDescription,
|
|
501
|
+
goalId: goalId,
|
|
502
|
+
goalTitle: goalTitle,
|
|
484
503
|
priority: task.priority,
|
|
485
504
|
};
|
|
486
505
|
|
|
@@ -490,13 +509,21 @@ async function runAgent(options: {
|
|
|
490
509
|
if (result.success) {
|
|
491
510
|
// Complete task via API (Claude may have already done this via MCP tool)
|
|
492
511
|
try {
|
|
493
|
-
await completeTask({
|
|
512
|
+
const completionResult = await completeTask({
|
|
494
513
|
baseUrl: options.baseUrl,
|
|
495
514
|
apiKey: credentials.apiKey,
|
|
496
|
-
taskId:
|
|
515
|
+
taskId: taskId,
|
|
497
516
|
output: result.output,
|
|
498
517
|
summary: result.summary,
|
|
499
518
|
});
|
|
519
|
+
|
|
520
|
+
// v2: Log unblocked tasks if any
|
|
521
|
+
if (completionResult.unblocked_tasks && completionResult.unblocked_tasks.length > 0) {
|
|
522
|
+
console.log(` → 🔓 Unblocked ${completionResult.unblocked_tasks.length} task(s):`);
|
|
523
|
+
for (const unblocked of completionResult.unblocked_tasks) {
|
|
524
|
+
console.log(` - ${unblocked.title} (${unblocked.id})`);
|
|
525
|
+
}
|
|
526
|
+
}
|
|
500
527
|
} catch (err) {
|
|
501
528
|
// Ignore "already complete" - means Claude completed it via MCP
|
|
502
529
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
@@ -513,14 +540,14 @@ async function runAgent(options: {
|
|
|
513
540
|
await blockTask({
|
|
514
541
|
baseUrl: options.baseUrl,
|
|
515
542
|
apiKey: credentials.apiKey,
|
|
516
|
-
taskId:
|
|
543
|
+
taskId: taskId,
|
|
517
544
|
reason: result.error || 'Execution failed',
|
|
518
545
|
});
|
|
519
546
|
}
|
|
520
547
|
} catch (error) {
|
|
521
548
|
console.error(` → ❌ Error:`, error instanceof Error ? error.message : error);
|
|
522
549
|
} finally {
|
|
523
|
-
activeTasks.delete(
|
|
550
|
+
activeTasks.delete(taskId);
|
|
524
551
|
}
|
|
525
552
|
});
|
|
526
553
|
|
|
@@ -555,13 +582,21 @@ async function runAgent(options: {
|
|
|
555
582
|
// API Helpers
|
|
556
583
|
// ============================================================================
|
|
557
584
|
|
|
585
|
+
/**
|
|
586
|
+
* Complete task response type (v2)
|
|
587
|
+
*/
|
|
588
|
+
interface CompleteTaskResponse {
|
|
589
|
+
task?: { id: string; status: string };
|
|
590
|
+
unblocked_tasks?: Array<{ id: string; title: string }>;
|
|
591
|
+
}
|
|
592
|
+
|
|
558
593
|
async function completeTask(options: {
|
|
559
594
|
baseUrl: string;
|
|
560
595
|
apiKey: string;
|
|
561
596
|
taskId: string;
|
|
562
597
|
output: string;
|
|
563
598
|
summary: string;
|
|
564
|
-
}): Promise<
|
|
599
|
+
}): Promise<CompleteTaskResponse> {
|
|
565
600
|
const response = await fetch(`${options.baseUrl}/tasks/${options.taskId}/complete`, {
|
|
566
601
|
method: 'POST',
|
|
567
602
|
headers: {
|
|
@@ -569,10 +604,8 @@ async function completeTask(options: {
|
|
|
569
604
|
'Content-Type': 'application/json',
|
|
570
605
|
},
|
|
571
606
|
body: JSON.stringify({
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
summary: options.summary,
|
|
575
|
-
output: options.output,
|
|
607
|
+
output_text: options.summary || options.output,
|
|
608
|
+
output_url: options.output?.startsWith('http') ? options.output : undefined,
|
|
576
609
|
}),
|
|
577
610
|
});
|
|
578
611
|
|
|
@@ -580,6 +613,8 @@ async function completeTask(options: {
|
|
|
580
613
|
const error = await response.text();
|
|
581
614
|
throw new Error(`Failed to complete task: ${error}`);
|
|
582
615
|
}
|
|
616
|
+
|
|
617
|
+
return response.json() as Promise<CompleteTaskResponse>;
|
|
583
618
|
}
|
|
584
619
|
|
|
585
620
|
async function blockTask(options: {
|
|
@@ -595,8 +630,7 @@ async function blockTask(options: {
|
|
|
595
630
|
'Content-Type': 'application/json',
|
|
596
631
|
},
|
|
597
632
|
body: JSON.stringify({
|
|
598
|
-
|
|
599
|
-
blocked_reason: options.reason,
|
|
633
|
+
reason: options.reason,
|
|
600
634
|
}),
|
|
601
635
|
});
|
|
602
636
|
|