@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/src/context.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Context fetcher for Artyfacts tasks
|
|
3
3
|
*
|
|
4
|
-
* Fetches full context including organization, project,
|
|
4
|
+
* Fetches full context including organization, project, goal, and related tasks.
|
|
5
|
+
* Updated for Schema v2 - tasks are first-class entities linked to goals.
|
|
5
6
|
*/
|
|
6
7
|
|
|
7
8
|
// ============================================================================
|
|
@@ -20,6 +21,19 @@ export interface ProjectContext {
|
|
|
20
21
|
description?: string;
|
|
21
22
|
}
|
|
22
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Related task summary (v2)
|
|
26
|
+
*/
|
|
27
|
+
export interface RelatedTaskContext {
|
|
28
|
+
id: string;
|
|
29
|
+
title: string;
|
|
30
|
+
status: 'pending' | 'in_progress' | 'blocked' | 'done';
|
|
31
|
+
priority?: 'low' | 'medium' | 'high';
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Section context (kept for artifact content)
|
|
36
|
+
*/
|
|
23
37
|
export interface SectionContext {
|
|
24
38
|
id: string;
|
|
25
39
|
heading: string;
|
|
@@ -28,27 +42,54 @@ export interface SectionContext {
|
|
|
28
42
|
task_status?: string;
|
|
29
43
|
}
|
|
30
44
|
|
|
31
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Goal context (v2 - replaces artifact context for task work)
|
|
47
|
+
*/
|
|
48
|
+
export interface GoalContext {
|
|
32
49
|
id: string;
|
|
33
50
|
title: string;
|
|
51
|
+
objective?: string;
|
|
34
52
|
summary?: string;
|
|
35
53
|
description?: string;
|
|
36
54
|
artifact_type?: string;
|
|
37
|
-
|
|
55
|
+
/** Related tasks on this goal */
|
|
56
|
+
tasks?: RelatedTaskContext[];
|
|
57
|
+
/** Legacy: sections for content-based artifacts */
|
|
58
|
+
sections?: SectionContext[];
|
|
38
59
|
}
|
|
39
60
|
|
|
61
|
+
/** @deprecated Use GoalContext instead */
|
|
62
|
+
export interface ArtifactContext extends GoalContext {}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Full task context (v2)
|
|
66
|
+
*/
|
|
40
67
|
export interface TaskFullContext {
|
|
41
68
|
task: {
|
|
69
|
+
/** Task UUID */
|
|
42
70
|
id: string;
|
|
43
|
-
|
|
44
|
-
|
|
71
|
+
/** Task title */
|
|
72
|
+
title: string;
|
|
73
|
+
/** @deprecated Use title instead */
|
|
74
|
+
heading?: string;
|
|
75
|
+
/** Task description */
|
|
76
|
+
description?: string;
|
|
77
|
+
/** @deprecated Use description instead */
|
|
78
|
+
content?: string;
|
|
79
|
+
/** Expected output format and requirements */
|
|
45
80
|
expected_output?: {
|
|
46
81
|
format?: string;
|
|
47
82
|
requirements?: string[];
|
|
48
83
|
};
|
|
49
|
-
|
|
84
|
+
/** Priority level */
|
|
85
|
+
priority?: 'low' | 'medium' | 'high';
|
|
86
|
+
/** Dependencies */
|
|
87
|
+
depends_on?: string[];
|
|
50
88
|
};
|
|
51
|
-
|
|
89
|
+
/** The goal this task belongs to */
|
|
90
|
+
goal: GoalContext;
|
|
91
|
+
/** @deprecated Use goal instead */
|
|
92
|
+
artifact?: GoalContext;
|
|
52
93
|
project?: ProjectContext;
|
|
53
94
|
organization: OrganizationContext;
|
|
54
95
|
}
|
|
@@ -98,7 +139,7 @@ export class ContextFetcher {
|
|
|
98
139
|
// ============================================================================
|
|
99
140
|
|
|
100
141
|
/**
|
|
101
|
-
* Build a rich prompt with full context
|
|
142
|
+
* Build a rich prompt with full context (v2)
|
|
102
143
|
*/
|
|
103
144
|
export function buildPromptWithContext(context: TaskFullContext): string {
|
|
104
145
|
const parts: string[] = [];
|
|
@@ -115,12 +156,13 @@ You have access to Artyfacts MCP tools. USE THEM to complete your task:
|
|
|
115
156
|
- **create_artifact** - Create new artifacts (documents, specs, reports)
|
|
116
157
|
- **create_section** - Add sections to artifacts (content, tasks, decisions)
|
|
117
158
|
- **update_section** - Update existing sections
|
|
118
|
-
- **
|
|
119
|
-
- **
|
|
120
|
-
- **
|
|
121
|
-
- **complete_task** - Mark a task as complete
|
|
159
|
+
- **create_task** - Create new tasks under a goal
|
|
160
|
+
- **claim_task** - Claim a task for execution
|
|
161
|
+
- **complete_task** - Mark a task as complete (returns unblocked tasks)
|
|
122
162
|
- **block_task** - Block a task with a reason
|
|
123
|
-
- **
|
|
163
|
+
- **list_tasks** - Query tasks from the queue
|
|
164
|
+
- **list_inbox** - Check pending decisions/approvals
|
|
165
|
+
- **resolve_inbox** - Resolve an inbox item
|
|
124
166
|
|
|
125
167
|
IMPORTANT: When asked to create agents or update artifacts, USE THE TOOLS. Don't just describe what you would do - actually do it with the tools.
|
|
126
168
|
|
|
@@ -129,7 +171,7 @@ IMPORTANT: When asked to create agents or update artifacts, USE THE TOOLS. Don't
|
|
|
129
171
|
- Be thorough but concise
|
|
130
172
|
- USE THE TOOLS to take action, don't just analyze
|
|
131
173
|
- If the task requires creating something, use create_artifact or create_section
|
|
132
|
-
- If
|
|
174
|
+
- If you complete a task, check the response for unblocked_tasks to see follow-up work
|
|
133
175
|
- If you cannot complete the task, explain why
|
|
134
176
|
|
|
135
177
|
Format your response as follows:
|
|
@@ -159,47 +201,81 @@ Format your response as follows:
|
|
|
159
201
|
parts.push('');
|
|
160
202
|
}
|
|
161
203
|
|
|
162
|
-
//
|
|
163
|
-
|
|
164
|
-
if (
|
|
165
|
-
parts.push(
|
|
166
|
-
|
|
167
|
-
|
|
204
|
+
// Goal context (v2 - was artifact)
|
|
205
|
+
const goal = context.goal || context.artifact;
|
|
206
|
+
if (goal) {
|
|
207
|
+
parts.push(`## Goal: ${goal.title}`);
|
|
208
|
+
if (goal.objective) {
|
|
209
|
+
parts.push(`**Objective:** ${goal.objective}`);
|
|
210
|
+
}
|
|
211
|
+
if (goal.summary) {
|
|
212
|
+
parts.push(goal.summary);
|
|
213
|
+
}
|
|
214
|
+
if (goal.description) {
|
|
215
|
+
parts.push('');
|
|
216
|
+
parts.push(goal.description);
|
|
217
|
+
}
|
|
168
218
|
parts.push('');
|
|
169
|
-
parts.push(context.artifact.description);
|
|
170
|
-
}
|
|
171
|
-
parts.push('');
|
|
172
219
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
220
|
+
// Related tasks on this goal (v2)
|
|
221
|
+
if (goal.tasks && goal.tasks.length > 0) {
|
|
222
|
+
const relatedTasks = goal.tasks.filter(t => t.id !== context.task.id);
|
|
223
|
+
if (relatedTasks.length > 0) {
|
|
224
|
+
parts.push('### Related Tasks:');
|
|
225
|
+
for (const task of relatedTasks) {
|
|
226
|
+
const statusEmoji = {
|
|
227
|
+
pending: '⏳',
|
|
228
|
+
in_progress: '🔄',
|
|
229
|
+
blocked: '🚫',
|
|
230
|
+
done: '✅',
|
|
231
|
+
}[task.status] || '❓';
|
|
232
|
+
const priorityBadge = task.priority ? ` [${task.priority}]` : '';
|
|
233
|
+
parts.push(`- ${statusEmoji} **${task.title}**${priorityBadge}`);
|
|
234
|
+
}
|
|
235
|
+
parts.push('');
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Legacy: related sections (for content-based artifacts)
|
|
240
|
+
if (goal.sections && goal.sections.length > 0) {
|
|
241
|
+
const relatedSections = goal.sections.filter(s => s.id !== context.task.id);
|
|
242
|
+
if (relatedSections.length > 0) {
|
|
243
|
+
parts.push('### Related Sections:');
|
|
244
|
+
for (const section of relatedSections) {
|
|
245
|
+
const preview = section.content
|
|
246
|
+
? section.content.substring(0, 200) + (section.content.length > 200 ? '...' : '')
|
|
247
|
+
: 'No content';
|
|
248
|
+
const statusBadge = section.task_status ? ` [${section.task_status}]` : '';
|
|
249
|
+
parts.push(`- **${section.heading}**${statusBadge}: ${preview}`);
|
|
250
|
+
}
|
|
251
|
+
parts.push('');
|
|
252
|
+
}
|
|
186
253
|
}
|
|
187
|
-
parts.push('');
|
|
188
254
|
}
|
|
189
255
|
|
|
190
256
|
// The task itself
|
|
191
257
|
parts.push('---');
|
|
192
258
|
parts.push('');
|
|
193
|
-
|
|
259
|
+
const taskTitle = context.task.title || context.task.heading;
|
|
260
|
+
parts.push(`## Your Task: ${taskTitle}`);
|
|
194
261
|
|
|
195
262
|
if (context.task.priority) {
|
|
196
|
-
const
|
|
197
|
-
|
|
263
|
+
const priorityEmoji = {
|
|
264
|
+
high: '🔴 High',
|
|
265
|
+
medium: '🟡 Medium',
|
|
266
|
+
low: '🟢 Low',
|
|
267
|
+
}[context.task.priority] || '🟡 Medium';
|
|
268
|
+
parts.push(`**Priority:** ${priorityEmoji}`);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
if (context.task.depends_on && context.task.depends_on.length > 0) {
|
|
272
|
+
parts.push(`**Dependencies:** ${context.task.depends_on.length} task(s)`);
|
|
198
273
|
}
|
|
199
274
|
parts.push('');
|
|
200
275
|
|
|
201
276
|
parts.push('### Description');
|
|
202
|
-
|
|
277
|
+
const taskDescription = context.task.description || context.task.content;
|
|
278
|
+
parts.push(taskDescription || 'No additional description provided.');
|
|
203
279
|
parts.push('');
|
|
204
280
|
|
|
205
281
|
// Expected output
|
package/src/executor.ts
CHANGED
|
@@ -15,19 +15,32 @@ import { ContextFetcher, createContextFetcher, buildPromptWithContext, TaskFullC
|
|
|
15
15
|
// Types
|
|
16
16
|
// ============================================================================
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Task context for execution (v2)
|
|
20
|
+
*/
|
|
18
21
|
export interface TaskContext {
|
|
19
|
-
/** Task
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
|
|
23
|
-
/** Task
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
|
|
27
|
-
/**
|
|
22
|
+
/** Task UUID */
|
|
23
|
+
id: string;
|
|
24
|
+
/** @deprecated Use id instead */
|
|
25
|
+
taskId?: string;
|
|
26
|
+
/** Task title */
|
|
27
|
+
title: string;
|
|
28
|
+
/** @deprecated Use title instead */
|
|
29
|
+
heading?: string;
|
|
30
|
+
/** Task description */
|
|
31
|
+
description?: string;
|
|
32
|
+
/** @deprecated Use description instead */
|
|
33
|
+
content?: string;
|
|
34
|
+
/** Goal UUID this task belongs to */
|
|
35
|
+
goalId: string;
|
|
36
|
+
/** @deprecated Use goalId instead */
|
|
37
|
+
artifactId?: string;
|
|
38
|
+
/** Goal title for context */
|
|
39
|
+
goalTitle?: string;
|
|
40
|
+
/** @deprecated Use goalTitle instead */
|
|
28
41
|
artifactTitle?: string;
|
|
29
|
-
/** Task priority
|
|
30
|
-
priority?:
|
|
42
|
+
/** Task priority */
|
|
43
|
+
priority?: 'low' | 'medium' | 'high';
|
|
31
44
|
/** Additional context */
|
|
32
45
|
context?: Record<string, unknown>;
|
|
33
46
|
}
|
|
@@ -138,9 +151,14 @@ export class ClaudeExecutor {
|
|
|
138
151
|
|
|
139
152
|
if (useFullContext) {
|
|
140
153
|
try {
|
|
141
|
-
|
|
154
|
+
// v2: use id, fallback to taskId for backwards compatibility
|
|
155
|
+
const taskId = task.id || task.taskId;
|
|
156
|
+
if (!taskId) {
|
|
157
|
+
throw new Error('Task ID required for context fetch');
|
|
158
|
+
}
|
|
159
|
+
fullContext = await this.contextFetcher!.fetchTaskContext(taskId);
|
|
142
160
|
prompt = buildPromptWithContext(fullContext);
|
|
143
|
-
console.log(' 📚 Using full context (org, project,
|
|
161
|
+
console.log(' 📚 Using full context (org, project, goal, related tasks)');
|
|
144
162
|
} catch (contextError) {
|
|
145
163
|
console.warn(' ⚠️ Could not fetch full context, using minimal prompt');
|
|
146
164
|
console.warn(` ${contextError instanceof Error ? contextError.message : contextError}`);
|
|
@@ -153,8 +171,9 @@ export class ClaudeExecutor {
|
|
|
153
171
|
// Execute via Claude Code CLI
|
|
154
172
|
const output = await this.runClaude(prompt);
|
|
155
173
|
|
|
156
|
-
// Extract summary if present
|
|
157
|
-
const
|
|
174
|
+
// Extract summary if present (v2: use title, fallback to heading)
|
|
175
|
+
const taskTitle = task.title || task.heading || 'Task';
|
|
176
|
+
const { content, summary } = this.parseResponse(output, taskTitle);
|
|
158
177
|
|
|
159
178
|
return {
|
|
160
179
|
success: true,
|
|
@@ -247,7 +266,7 @@ export class ClaudeExecutor {
|
|
|
247
266
|
}
|
|
248
267
|
|
|
249
268
|
/**
|
|
250
|
-
* Build the task prompt
|
|
269
|
+
* Build the task prompt (v2)
|
|
251
270
|
*/
|
|
252
271
|
private buildTaskPrompt(task: TaskContext): string {
|
|
253
272
|
const parts: string[] = [];
|
|
@@ -262,25 +281,32 @@ export class ClaudeExecutor {
|
|
|
262
281
|
parts.push('---');
|
|
263
282
|
parts.push('');
|
|
264
283
|
|
|
265
|
-
// Task header
|
|
266
|
-
|
|
284
|
+
// Task header (v2: use title, fallback to heading)
|
|
285
|
+
const taskTitle = task.title || task.heading;
|
|
286
|
+
parts.push(`# Task: ${taskTitle}`);
|
|
267
287
|
parts.push('');
|
|
268
288
|
|
|
269
|
-
//
|
|
270
|
-
|
|
271
|
-
|
|
289
|
+
// Goal context (v2: was artifact)
|
|
290
|
+
const goalTitle = task.goalTitle || task.artifactTitle;
|
|
291
|
+
if (goalTitle) {
|
|
292
|
+
parts.push(`**Goal:** ${goalTitle}`);
|
|
272
293
|
}
|
|
273
294
|
|
|
274
|
-
// Priority
|
|
295
|
+
// Priority (v2: string-based)
|
|
275
296
|
if (task.priority) {
|
|
276
|
-
const
|
|
277
|
-
|
|
297
|
+
const priorityEmoji = {
|
|
298
|
+
high: '🔴 High',
|
|
299
|
+
medium: '🟡 Medium',
|
|
300
|
+
low: '🟢 Low',
|
|
301
|
+
}[task.priority] || '🟡 Medium';
|
|
302
|
+
parts.push(`**Priority:** ${priorityEmoji}`);
|
|
278
303
|
}
|
|
279
304
|
parts.push('');
|
|
280
305
|
|
|
281
|
-
// Task content
|
|
306
|
+
// Task description (v2: use description, fallback to content)
|
|
282
307
|
parts.push('## Description');
|
|
283
|
-
|
|
308
|
+
const taskDescription = task.description || task.content;
|
|
309
|
+
parts.push(taskDescription || 'No additional description provided.');
|
|
284
310
|
parts.push('');
|
|
285
311
|
|
|
286
312
|
// Additional context
|
package/src/listener.ts
CHANGED
|
@@ -11,18 +11,39 @@ import EventSource from 'eventsource';
|
|
|
11
11
|
// Types
|
|
12
12
|
// ============================================================================
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Task assigned event (v2)
|
|
16
|
+
* Uses task ID and goal ID (not section_id/artifact_id)
|
|
17
|
+
*/
|
|
14
18
|
export interface TaskAssignedEvent {
|
|
15
19
|
type: 'task_assigned';
|
|
16
20
|
timestamp: string;
|
|
17
21
|
data: {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
/** Task UUID (primary identifier) */
|
|
23
|
+
id: string;
|
|
24
|
+
/** @deprecated Use id instead */
|
|
25
|
+
taskId?: string;
|
|
26
|
+
/** Goal UUID this task belongs to */
|
|
27
|
+
goalId: string;
|
|
28
|
+
/** @deprecated Use goalId instead */
|
|
29
|
+
artifactId?: string;
|
|
30
|
+
/** Task title */
|
|
31
|
+
title: string;
|
|
32
|
+
/** @deprecated Use title instead */
|
|
33
|
+
heading?: string;
|
|
34
|
+
/** Task description */
|
|
35
|
+
description?: string;
|
|
36
|
+
/** @deprecated Use description instead */
|
|
37
|
+
content?: string;
|
|
38
|
+
/** Goal title for context */
|
|
39
|
+
goalTitle?: string;
|
|
40
|
+
/** @deprecated Use goalTitle instead */
|
|
23
41
|
artifactTitle?: string;
|
|
24
|
-
|
|
42
|
+
/** Priority level */
|
|
43
|
+
priority?: 'low' | 'medium' | 'high';
|
|
44
|
+
/** Assigned agent ID */
|
|
25
45
|
assignedTo: string;
|
|
46
|
+
/** Assignment timestamp */
|
|
26
47
|
assignedAt: string;
|
|
27
48
|
};
|
|
28
49
|
}
|
|
@@ -242,18 +263,24 @@ export class ArtyfactsListener {
|
|
|
242
263
|
try {
|
|
243
264
|
const data = JSON.parse(event.data);
|
|
244
265
|
|
|
245
|
-
// Normalize snake_case to camelCase for task data
|
|
266
|
+
// Normalize snake_case to camelCase for task data (v2 schema)
|
|
246
267
|
const rawData = data.data || data;
|
|
247
|
-
const normalizedData = rawData.task_id ? {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
268
|
+
const normalizedData = (rawData.id || rawData.task_id) ? {
|
|
269
|
+
// v2 fields (primary)
|
|
270
|
+
id: rawData.id || rawData.task_id,
|
|
271
|
+
goalId: rawData.goal_id || rawData.artifact_id,
|
|
272
|
+
goalTitle: rawData.goal_title || rawData.artifact_title,
|
|
273
|
+
title: rawData.title || rawData.heading,
|
|
274
|
+
description: rawData.description || rawData.content,
|
|
275
|
+
priority: rawData.priority,
|
|
254
276
|
assignedTo: rawData.assigned_to,
|
|
255
277
|
assignedAt: rawData.assigned_at,
|
|
256
|
-
|
|
278
|
+
// Deprecated fields for backwards compatibility
|
|
279
|
+
taskId: rawData.id || rawData.task_id,
|
|
280
|
+
artifactId: rawData.goal_id || rawData.artifact_id,
|
|
281
|
+
artifactTitle: rawData.goal_title || rawData.artifact_title,
|
|
282
|
+
heading: rawData.title || rawData.heading,
|
|
283
|
+
content: rawData.description || rawData.content,
|
|
257
284
|
...rawData, // Keep original fields too
|
|
258
285
|
} : rawData;
|
|
259
286
|
|
package/src/tools/handlers.ts
CHANGED
|
@@ -225,9 +225,11 @@ export const updateAgentHandler: ToolHandler = async (args, client) => {
|
|
|
225
225
|
};
|
|
226
226
|
|
|
227
227
|
// =============================================================================
|
|
228
|
-
// Task Handlers
|
|
228
|
+
// Task Handlers (v2 - tasks are first-class entities)
|
|
229
229
|
// =============================================================================
|
|
230
230
|
|
|
231
|
+
import type { TaskQueueResponse, TaskClaimResponse, TaskCompleteResponse, InboxResponse, InboxResolveResponse } from './types';
|
|
232
|
+
|
|
231
233
|
export const getTaskHandler: ToolHandler = async (args, client) => {
|
|
232
234
|
try {
|
|
233
235
|
const data = await client.get(`/tasks/${args.task_id}/context`);
|
|
@@ -237,36 +239,40 @@ export const getTaskHandler: ToolHandler = async (args, client) => {
|
|
|
237
239
|
}
|
|
238
240
|
};
|
|
239
241
|
|
|
242
|
+
/**
|
|
243
|
+
* List tasks from the queue (v2)
|
|
244
|
+
* Uses GET /api/v1/tasks/queue - returns tasks from tasks table
|
|
245
|
+
*/
|
|
240
246
|
export const listTasksHandler: ToolHandler = async (args, client) => {
|
|
241
247
|
try {
|
|
242
248
|
const params = new URLSearchParams();
|
|
243
|
-
if (args.
|
|
249
|
+
if (args.goal_id) params.set('goal_id', String(args.goal_id));
|
|
244
250
|
if (args.status) params.set('status', String(args.status));
|
|
245
251
|
if (args.assignee) params.set('assignee', String(args.assignee));
|
|
246
252
|
if (args.limit) params.set('limit', String(args.limit));
|
|
247
253
|
|
|
248
254
|
const query = params.toString();
|
|
249
|
-
const path = `/tasks${query ? `?${query}` : ''}`;
|
|
250
|
-
const data = await client.get(path);
|
|
255
|
+
const path = `/tasks/queue${query ? `?${query}` : ''}`;
|
|
256
|
+
const data = await client.get<TaskQueueResponse>(path);
|
|
251
257
|
return { success: true, data };
|
|
252
258
|
} catch (error) {
|
|
253
259
|
return { success: false, error: String(error) };
|
|
254
260
|
}
|
|
255
261
|
};
|
|
256
262
|
|
|
263
|
+
/**
|
|
264
|
+
* Create a task (v2)
|
|
265
|
+
* Uses POST /api/v1/tasks - creates in tasks table
|
|
266
|
+
*/
|
|
257
267
|
export const createTaskHandler: ToolHandler = async (args, client) => {
|
|
258
268
|
try {
|
|
259
|
-
const data = await client.post(
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
type: 'task',
|
|
264
|
-
task_status: 'pending',
|
|
269
|
+
const data = await client.post('/tasks', {
|
|
270
|
+
goal_id: args.goal_id,
|
|
271
|
+
title: args.title,
|
|
272
|
+
description: args.description,
|
|
265
273
|
assignee_agent_id: args.assignee,
|
|
266
274
|
depends_on: args.depends_on,
|
|
267
|
-
priority: args.priority,
|
|
268
|
-
agent_id: 'system',
|
|
269
|
-
agent_name: 'System',
|
|
275
|
+
priority: args.priority || 'medium',
|
|
270
276
|
});
|
|
271
277
|
return { success: true, data };
|
|
272
278
|
} catch (error) {
|
|
@@ -274,9 +280,27 @@ export const createTaskHandler: ToolHandler = async (args, client) => {
|
|
|
274
280
|
}
|
|
275
281
|
};
|
|
276
282
|
|
|
283
|
+
/**
|
|
284
|
+
* Claim a task (v2)
|
|
285
|
+
* Uses POST /api/v1/tasks/:id/claim
|
|
286
|
+
*/
|
|
287
|
+
export const claimTaskHandler: ToolHandler = async (args, client) => {
|
|
288
|
+
try {
|
|
289
|
+
const data = await client.post<TaskClaimResponse>(`/tasks/${args.task_id}/claim`, {});
|
|
290
|
+
return { success: true, data };
|
|
291
|
+
} catch (error) {
|
|
292
|
+
return { success: false, error: String(error) };
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Complete a task (v2)
|
|
298
|
+
* Uses POST /api/v1/tasks/:id/complete
|
|
299
|
+
* Returns unblocked_tasks for follow-up work
|
|
300
|
+
*/
|
|
277
301
|
export const completeTaskHandler: ToolHandler = async (args, client) => {
|
|
278
302
|
try {
|
|
279
|
-
const data = await client.post(`/tasks/${args.task_id}/complete`, {
|
|
303
|
+
const data = await client.post<TaskCompleteResponse>(`/tasks/${args.task_id}/complete`, {
|
|
280
304
|
output: args.output,
|
|
281
305
|
summary: args.summary,
|
|
282
306
|
output_url: args.output_url,
|
|
@@ -287,9 +311,13 @@ export const completeTaskHandler: ToolHandler = async (args, client) => {
|
|
|
287
311
|
}
|
|
288
312
|
};
|
|
289
313
|
|
|
314
|
+
/**
|
|
315
|
+
* Block a task (v2)
|
|
316
|
+
* Uses POST /api/v1/tasks/:id/block
|
|
317
|
+
*/
|
|
290
318
|
export const blockTaskHandler: ToolHandler = async (args, client) => {
|
|
291
319
|
try {
|
|
292
|
-
const data = await client.post(`/tasks/${args.task_id}/
|
|
320
|
+
const data = await client.post(`/tasks/${args.task_id}/block`, {
|
|
293
321
|
reason: args.reason,
|
|
294
322
|
blocker_type: args.blocker_type,
|
|
295
323
|
});
|
|
@@ -299,6 +327,46 @@ export const blockTaskHandler: ToolHandler = async (args, client) => {
|
|
|
299
327
|
}
|
|
300
328
|
};
|
|
301
329
|
|
|
330
|
+
// =============================================================================
|
|
331
|
+
// Inbox Handlers (v2)
|
|
332
|
+
// =============================================================================
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* List inbox items (v2)
|
|
336
|
+
* Uses GET /api/v1/inbox
|
|
337
|
+
*/
|
|
338
|
+
export const listInboxHandler: ToolHandler = async (args, client) => {
|
|
339
|
+
try {
|
|
340
|
+
const params = new URLSearchParams();
|
|
341
|
+
if (args.status) params.set('status', String(args.status));
|
|
342
|
+
if (args.kind) params.set('kind', String(args.kind));
|
|
343
|
+
if (args.limit) params.set('limit', String(args.limit));
|
|
344
|
+
|
|
345
|
+
const query = params.toString();
|
|
346
|
+
const path = `/inbox${query ? `?${query}` : ''}`;
|
|
347
|
+
const data = await client.get<InboxResponse>(path);
|
|
348
|
+
return { success: true, data };
|
|
349
|
+
} catch (error) {
|
|
350
|
+
return { success: false, error: String(error) };
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Resolve an inbox item (v2)
|
|
356
|
+
* Uses POST /api/v1/inbox/:id/resolve with auto-execute
|
|
357
|
+
*/
|
|
358
|
+
export const resolveInboxHandler: ToolHandler = async (args, client) => {
|
|
359
|
+
try {
|
|
360
|
+
const data = await client.post<InboxResolveResponse>(`/inbox/${args.inbox_id}/resolve`, {
|
|
361
|
+
decision: args.decision,
|
|
362
|
+
notes: args.notes,
|
|
363
|
+
});
|
|
364
|
+
return { success: true, data };
|
|
365
|
+
} catch (error) {
|
|
366
|
+
return { success: false, error: String(error) };
|
|
367
|
+
}
|
|
368
|
+
};
|
|
369
|
+
|
|
302
370
|
// =============================================================================
|
|
303
371
|
// Blocker Handlers
|
|
304
372
|
// =============================================================================
|
|
@@ -418,14 +486,19 @@ export const handlers: Record<string, ToolHandler> = {
|
|
|
418
486
|
create_agent: createAgentHandler,
|
|
419
487
|
update_agent: updateAgentHandler,
|
|
420
488
|
|
|
421
|
-
// Tasks
|
|
489
|
+
// Tasks (v2)
|
|
422
490
|
get_task: getTaskHandler,
|
|
423
491
|
list_tasks: listTasksHandler,
|
|
424
492
|
create_task: createTaskHandler,
|
|
493
|
+
claim_task: claimTaskHandler,
|
|
425
494
|
complete_task: completeTaskHandler,
|
|
426
495
|
block_task: blockTaskHandler,
|
|
427
496
|
|
|
428
|
-
//
|
|
497
|
+
// Inbox (v2)
|
|
498
|
+
list_inbox: listInboxHandler,
|
|
499
|
+
resolve_inbox: resolveInboxHandler,
|
|
500
|
+
|
|
501
|
+
// Blockers (legacy - kept for compatibility)
|
|
429
502
|
get_blocker: getBlockerHandler,
|
|
430
503
|
list_blockers: listBlockersHandler,
|
|
431
504
|
create_blocker: createBlockerHandler,
|