@artyfacts/claude 1.3.24 → 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 +145 -77
- package/dist/cli.mjs +49 -32
- 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 +79 -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,15 +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
|
-
// Use
|
|
261
|
+
// Use task.id (UUID) for claiming, include agent_id from task
|
|
258
262
|
const claimResponse = await fetch(`${baseUrl}/tasks/${task.id}/claim`, {
|
|
259
263
|
method: 'POST',
|
|
260
264
|
headers: {
|
|
261
265
|
'Authorization': `Bearer ${apiKey}`,
|
|
262
266
|
'Content-Type': 'application/json',
|
|
263
267
|
},
|
|
268
|
+
body: JSON.stringify({
|
|
269
|
+
agent_id: task.agent_id,
|
|
270
|
+
}),
|
|
264
271
|
});
|
|
265
272
|
|
|
266
273
|
if (!claimResponse.ok) {
|
|
@@ -269,19 +276,17 @@ async function checkAndClaimTasks(
|
|
|
269
276
|
continue;
|
|
270
277
|
}
|
|
271
278
|
|
|
272
|
-
// Get the claimed task data
|
|
273
|
-
// Response format: { success: true, task: { id: ..., artifact_id: ..., ... } }
|
|
279
|
+
// Get the claimed task data
|
|
274
280
|
const claimData = await claimResponse.json().catch((e) => {
|
|
275
281
|
console.log(` ⚠️ Could not parse claim response: ${e}`);
|
|
276
282
|
return { task: { id: task.id } };
|
|
277
283
|
}) as {
|
|
278
|
-
|
|
279
|
-
task?: { id: string;
|
|
284
|
+
claimed?: boolean;
|
|
285
|
+
task?: { id: string; goal_id?: string; goal_title?: string };
|
|
280
286
|
};
|
|
281
287
|
|
|
282
|
-
// Use UUID for subsequent calls (globally unique, avoids org filter issues)
|
|
283
288
|
const taskUuid = claimData.task?.id || task.id;
|
|
284
|
-
|
|
289
|
+
const goalTitle = claimData.task?.goal_title || task.goal_title;
|
|
285
290
|
|
|
286
291
|
// Successfully claimed - now execute
|
|
287
292
|
activeTasks.add(task.id);
|
|
@@ -296,14 +301,20 @@ async function checkAndClaimTasks(
|
|
|
296
301
|
console.log(' → Executing with Claude...');
|
|
297
302
|
|
|
298
303
|
try {
|
|
299
|
-
//
|
|
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
|
+
};
|
|
300
311
|
const result = await executor.execute({
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
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',
|
|
307
318
|
});
|
|
308
319
|
|
|
309
320
|
if (result.success) {
|
|
@@ -452,36 +463,43 @@ async function runAgent(options: {
|
|
|
452
463
|
await mcpHandler.handleConnectRequest(event);
|
|
453
464
|
});
|
|
454
465
|
|
|
455
|
-
// Handle task assignments
|
|
466
|
+
// Handle task assignments (v2 schema)
|
|
456
467
|
listener.on<TaskAssignedEvent>('task_assigned', async (event) => {
|
|
457
468
|
const task = event.data;
|
|
458
469
|
|
|
459
|
-
//
|
|
460
|
-
|
|
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)) {
|
|
461
479
|
return;
|
|
462
480
|
}
|
|
463
|
-
activeTasks.add(
|
|
481
|
+
activeTasks.add(taskId);
|
|
464
482
|
|
|
465
|
-
console.log(`\n[Task received] ${
|
|
483
|
+
console.log(`\n[Task received] ${taskTitle}`);
|
|
466
484
|
|
|
467
485
|
if (options.dryRun) {
|
|
468
486
|
console.log(' 📋 Dry run - not executing');
|
|
469
|
-
console.log(` 📄
|
|
470
|
-
console.log(` 📝
|
|
471
|
-
activeTasks.delete(
|
|
487
|
+
console.log(` 📄 Goal: ${goalTitle || goalId}`);
|
|
488
|
+
console.log(` 📝 Description: ${taskDescription.substring(0, 100)}...`);
|
|
489
|
+
activeTasks.delete(taskId);
|
|
472
490
|
return;
|
|
473
491
|
}
|
|
474
492
|
|
|
475
493
|
console.log(' → Executing with Claude...');
|
|
476
494
|
|
|
477
495
|
try {
|
|
478
|
-
// Build task context
|
|
496
|
+
// Build task context (v2)
|
|
479
497
|
const taskContext: TaskContext = {
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
498
|
+
id: taskId,
|
|
499
|
+
title: taskTitle,
|
|
500
|
+
description: taskDescription,
|
|
501
|
+
goalId: goalId,
|
|
502
|
+
goalTitle: goalTitle,
|
|
485
503
|
priority: task.priority,
|
|
486
504
|
};
|
|
487
505
|
|
|
@@ -491,13 +509,21 @@ async function runAgent(options: {
|
|
|
491
509
|
if (result.success) {
|
|
492
510
|
// Complete task via API (Claude may have already done this via MCP tool)
|
|
493
511
|
try {
|
|
494
|
-
await completeTask({
|
|
512
|
+
const completionResult = await completeTask({
|
|
495
513
|
baseUrl: options.baseUrl,
|
|
496
514
|
apiKey: credentials.apiKey,
|
|
497
|
-
taskId:
|
|
515
|
+
taskId: taskId,
|
|
498
516
|
output: result.output,
|
|
499
517
|
summary: result.summary,
|
|
500
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
|
+
}
|
|
501
527
|
} catch (err) {
|
|
502
528
|
// Ignore "already complete" - means Claude completed it via MCP
|
|
503
529
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
@@ -514,14 +540,14 @@ async function runAgent(options: {
|
|
|
514
540
|
await blockTask({
|
|
515
541
|
baseUrl: options.baseUrl,
|
|
516
542
|
apiKey: credentials.apiKey,
|
|
517
|
-
taskId:
|
|
543
|
+
taskId: taskId,
|
|
518
544
|
reason: result.error || 'Execution failed',
|
|
519
545
|
});
|
|
520
546
|
}
|
|
521
547
|
} catch (error) {
|
|
522
548
|
console.error(` → ❌ Error:`, error instanceof Error ? error.message : error);
|
|
523
549
|
} finally {
|
|
524
|
-
activeTasks.delete(
|
|
550
|
+
activeTasks.delete(taskId);
|
|
525
551
|
}
|
|
526
552
|
});
|
|
527
553
|
|
|
@@ -556,13 +582,21 @@ async function runAgent(options: {
|
|
|
556
582
|
// API Helpers
|
|
557
583
|
// ============================================================================
|
|
558
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
|
+
|
|
559
593
|
async function completeTask(options: {
|
|
560
594
|
baseUrl: string;
|
|
561
595
|
apiKey: string;
|
|
562
596
|
taskId: string;
|
|
563
597
|
output: string;
|
|
564
598
|
summary: string;
|
|
565
|
-
}): Promise<
|
|
599
|
+
}): Promise<CompleteTaskResponse> {
|
|
566
600
|
const response = await fetch(`${options.baseUrl}/tasks/${options.taskId}/complete`, {
|
|
567
601
|
method: 'POST',
|
|
568
602
|
headers: {
|
|
@@ -570,10 +604,8 @@ async function completeTask(options: {
|
|
|
570
604
|
'Content-Type': 'application/json',
|
|
571
605
|
},
|
|
572
606
|
body: JSON.stringify({
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
summary: options.summary,
|
|
576
|
-
output: options.output,
|
|
607
|
+
output_text: options.summary || options.output,
|
|
608
|
+
output_url: options.output?.startsWith('http') ? options.output : undefined,
|
|
577
609
|
}),
|
|
578
610
|
});
|
|
579
611
|
|
|
@@ -581,6 +613,8 @@ async function completeTask(options: {
|
|
|
581
613
|
const error = await response.text();
|
|
582
614
|
throw new Error(`Failed to complete task: ${error}`);
|
|
583
615
|
}
|
|
616
|
+
|
|
617
|
+
return response.json() as Promise<CompleteTaskResponse>;
|
|
584
618
|
}
|
|
585
619
|
|
|
586
620
|
async function blockTask(options: {
|
|
@@ -596,8 +630,7 @@ async function blockTask(options: {
|
|
|
596
630
|
'Content-Type': 'application/json',
|
|
597
631
|
},
|
|
598
632
|
body: JSON.stringify({
|
|
599
|
-
|
|
600
|
-
blocked_reason: options.reason,
|
|
633
|
+
reason: options.reason,
|
|
601
634
|
}),
|
|
602
635
|
});
|
|
603
636
|
|