@artyfacts/claude 1.2.6 → 1.3.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.
@@ -0,0 +1,460 @@
1
+ /**
2
+ * Tool Handlers for Artyfacts
3
+ *
4
+ * Each handler calls the corresponding Artyfacts API endpoint.
5
+ */
6
+
7
+ import { ApiClient, ToolResult, ToolHandler } from './types';
8
+
9
+ // =============================================================================
10
+ // Section Handlers
11
+ // =============================================================================
12
+
13
+ export const getSectionHandler: ToolHandler = async (args, client) => {
14
+ try {
15
+ const data = await client.get(`/artifacts/sections/${args.section_id}`);
16
+ return { success: true, data };
17
+ } catch (error) {
18
+ return { success: false, error: String(error) };
19
+ }
20
+ };
21
+
22
+ export const listSectionsHandler: ToolHandler = async (args, client) => {
23
+ try {
24
+ let path = `/artifacts/${args.artifact_id}/sections`;
25
+ if (args.type) {
26
+ path += `?type=${args.type}`;
27
+ }
28
+ const data = await client.get(path);
29
+ return { success: true, data };
30
+ } catch (error) {
31
+ return { success: false, error: String(error) };
32
+ }
33
+ };
34
+
35
+ export const createSectionHandler: ToolHandler = async (args, client) => {
36
+ try {
37
+ const data = await client.post(`/artifacts/${args.artifact_id}/sections`, {
38
+ section_id: args.section_id || `section-${Date.now()}`,
39
+ heading: args.heading,
40
+ content: args.content,
41
+ type: args.type || 'content',
42
+ position: args.position,
43
+ agent_id: args.agent_id || 'system',
44
+ agent_name: args.agent_name || 'System',
45
+ });
46
+ return { success: true, data };
47
+ } catch (error) {
48
+ return { success: false, error: String(error) };
49
+ }
50
+ };
51
+
52
+ export const updateSectionHandler: ToolHandler = async (args, client) => {
53
+ try {
54
+ const updates: Record<string, unknown> = {};
55
+ if (args.heading) updates.heading = args.heading;
56
+ if (args.content) updates.content = args.content;
57
+
58
+ const data = await client.patch(`/artifacts/sections/${args.section_id}`, updates);
59
+ return { success: true, data };
60
+ } catch (error) {
61
+ return { success: false, error: String(error) };
62
+ }
63
+ };
64
+
65
+ export const deleteSectionHandler: ToolHandler = async (args, client) => {
66
+ try {
67
+ await client.delete(`/artifacts/sections/${args.section_id}`);
68
+ return { success: true, data: { deleted: true } };
69
+ } catch (error) {
70
+ return { success: false, error: String(error) };
71
+ }
72
+ };
73
+
74
+ // =============================================================================
75
+ // Artifact Handlers
76
+ // =============================================================================
77
+
78
+ export const getArtifactHandler: ToolHandler = async (args, client) => {
79
+ try {
80
+ let path = `/artifacts/${args.artifact_id}`;
81
+ if (args.include_sections) {
82
+ path += '?include_sections=true';
83
+ }
84
+ const data = await client.get(path);
85
+ return { success: true, data };
86
+ } catch (error) {
87
+ return { success: false, error: String(error) };
88
+ }
89
+ };
90
+
91
+ export const listArtifactsHandler: ToolHandler = async (args, client) => {
92
+ try {
93
+ const params = new URLSearchParams();
94
+ if (args.type) params.set('type', String(args.type));
95
+ if (args.status) params.set('status', String(args.status));
96
+ if (args.parent_id) params.set('parent_id', String(args.parent_id));
97
+ if (args.limit) params.set('limit', String(args.limit));
98
+
99
+ const query = params.toString();
100
+ const path = `/artifacts${query ? `?${query}` : ''}`;
101
+ const data = await client.get(path);
102
+ return { success: true, data };
103
+ } catch (error) {
104
+ return { success: false, error: String(error) };
105
+ }
106
+ };
107
+
108
+ export const searchArtifactsHandler: ToolHandler = async (args, client) => {
109
+ try {
110
+ const params = new URLSearchParams();
111
+ params.set('q', String(args.query));
112
+ if (args.type) params.set('type', String(args.type));
113
+ if (args.limit) params.set('limit', String(args.limit));
114
+
115
+ const data = await client.get(`/artifacts/search?${params.toString()}`);
116
+ return { success: true, data };
117
+ } catch (error) {
118
+ return { success: false, error: String(error) };
119
+ }
120
+ };
121
+
122
+ export const createArtifactHandler: ToolHandler = async (args, client) => {
123
+ try {
124
+ const data = await client.post('/artifacts', {
125
+ title: args.title,
126
+ artifact_type: args.type,
127
+ content: args.content,
128
+ summary: args.summary,
129
+ parent_id: args.parent_id,
130
+ tags: args.tags,
131
+ });
132
+ return { success: true, data };
133
+ } catch (error) {
134
+ return { success: false, error: String(error) };
135
+ }
136
+ };
137
+
138
+ export const updateArtifactHandler: ToolHandler = async (args, client) => {
139
+ try {
140
+ const updates: Record<string, unknown> = {};
141
+ if (args.title) updates.title = args.title;
142
+ if (args.summary) updates.summary = args.summary;
143
+ if (args.status) updates.status = args.status;
144
+
145
+ const data = await client.patch(`/artifacts/${args.artifact_id}`, updates);
146
+ return { success: true, data };
147
+ } catch (error) {
148
+ return { success: false, error: String(error) };
149
+ }
150
+ };
151
+
152
+ export const linkArtifactsHandler: ToolHandler = async (args, client) => {
153
+ try {
154
+ const data = await client.post(`/artifacts/${args.parent_id}/link`, {
155
+ child_id: args.child_id,
156
+ });
157
+ return { success: true, data };
158
+ } catch (error) {
159
+ return { success: false, error: String(error) };
160
+ }
161
+ };
162
+
163
+ // =============================================================================
164
+ // Agent Handlers
165
+ // =============================================================================
166
+
167
+ export const getAgentHandler: ToolHandler = async (args, client) => {
168
+ try {
169
+ const data = await client.get(`/agents/${args.agent_id}`);
170
+ return { success: true, data };
171
+ } catch (error) {
172
+ return { success: false, error: String(error) };
173
+ }
174
+ };
175
+
176
+ export const listAgentsHandler: ToolHandler = async (args, client) => {
177
+ try {
178
+ const params = new URLSearchParams();
179
+ if (args.role) params.set('role', String(args.role));
180
+ if (args.status) params.set('status', String(args.status));
181
+
182
+ const query = params.toString();
183
+ const path = `/agents${query ? `?${query}` : ''}`;
184
+ const data = await client.get(path);
185
+ return { success: true, data };
186
+ } catch (error) {
187
+ return { success: false, error: String(error) };
188
+ }
189
+ };
190
+
191
+ export const createAgentHandler: ToolHandler = async (args, client) => {
192
+ try {
193
+ const data = await client.post('/agents', {
194
+ id: args.id,
195
+ name: args.name,
196
+ role: args.role,
197
+ description: args.description,
198
+ system_prompt: args.system_prompt,
199
+ capabilities: args.capabilities || [],
200
+ permissions: args.permissions || ['sections:read', 'artifacts:read'],
201
+ model: args.model,
202
+ });
203
+ return { success: true, data };
204
+ } catch (error) {
205
+ return { success: false, error: String(error) };
206
+ }
207
+ };
208
+
209
+ export const updateAgentHandler: ToolHandler = async (args, client) => {
210
+ try {
211
+ const updates: Record<string, unknown> = {};
212
+ if (args.name) updates.name = args.name;
213
+ if (args.role) updates.role = args.role;
214
+ if (args.description) updates.description = args.description;
215
+ if (args.system_prompt) updates.system_prompt = args.system_prompt;
216
+ if (args.capabilities) updates.capabilities = args.capabilities;
217
+ if (args.permissions) updates.permissions = args.permissions;
218
+ if (args.status) updates.status = args.status;
219
+
220
+ const data = await client.patch(`/agents/${args.agent_id}`, updates);
221
+ return { success: true, data };
222
+ } catch (error) {
223
+ return { success: false, error: String(error) };
224
+ }
225
+ };
226
+
227
+ // =============================================================================
228
+ // Task Handlers
229
+ // =============================================================================
230
+
231
+ export const getTaskHandler: ToolHandler = async (args, client) => {
232
+ try {
233
+ const data = await client.get(`/tasks/${args.task_id}/context`);
234
+ return { success: true, data };
235
+ } catch (error) {
236
+ return { success: false, error: String(error) };
237
+ }
238
+ };
239
+
240
+ export const listTasksHandler: ToolHandler = async (args, client) => {
241
+ try {
242
+ const params = new URLSearchParams();
243
+ if (args.artifact_id) params.set('artifact_id', String(args.artifact_id));
244
+ if (args.status) params.set('status', String(args.status));
245
+ if (args.assignee) params.set('assignee', String(args.assignee));
246
+ if (args.limit) params.set('limit', String(args.limit));
247
+
248
+ const query = params.toString();
249
+ const path = `/tasks${query ? `?${query}` : ''}`;
250
+ const data = await client.get(path);
251
+ return { success: true, data };
252
+ } catch (error) {
253
+ return { success: false, error: String(error) };
254
+ }
255
+ };
256
+
257
+ export const createTaskHandler: ToolHandler = async (args, client) => {
258
+ try {
259
+ const data = await client.post(`/artifacts/${args.artifact_id}/sections`, {
260
+ section_id: `task-${Date.now()}`,
261
+ heading: args.heading,
262
+ content: args.content,
263
+ type: 'task',
264
+ task_status: 'pending',
265
+ assignee_agent_id: args.assignee,
266
+ depends_on: args.depends_on,
267
+ priority: args.priority,
268
+ agent_id: 'system',
269
+ agent_name: 'System',
270
+ });
271
+ return { success: true, data };
272
+ } catch (error) {
273
+ return { success: false, error: String(error) };
274
+ }
275
+ };
276
+
277
+ export const completeTaskHandler: ToolHandler = async (args, client) => {
278
+ try {
279
+ const data = await client.post(`/tasks/${args.task_id}/complete`, {
280
+ output: args.output,
281
+ summary: args.summary,
282
+ output_url: args.output_url,
283
+ });
284
+ return { success: true, data };
285
+ } catch (error) {
286
+ return { success: false, error: String(error) };
287
+ }
288
+ };
289
+
290
+ export const blockTaskHandler: ToolHandler = async (args, client) => {
291
+ try {
292
+ const data = await client.post(`/tasks/${args.task_id}/fail`, {
293
+ reason: args.reason,
294
+ blocker_type: args.blocker_type,
295
+ });
296
+ return { success: true, data };
297
+ } catch (error) {
298
+ return { success: false, error: String(error) };
299
+ }
300
+ };
301
+
302
+ // =============================================================================
303
+ // Blocker Handlers
304
+ // =============================================================================
305
+
306
+ export const getBlockerHandler: ToolHandler = async (args, client) => {
307
+ try {
308
+ const data = await client.get(`/blockers/${args.blocker_id}`);
309
+ return { success: true, data };
310
+ } catch (error) {
311
+ return { success: false, error: String(error) };
312
+ }
313
+ };
314
+
315
+ export const listBlockersHandler: ToolHandler = async (args, client) => {
316
+ try {
317
+ const params = new URLSearchParams();
318
+ if (args.status) params.set('status', String(args.status));
319
+ if (args.artifact_id) params.set('artifact_id', String(args.artifact_id));
320
+ if (args.kind) params.set('kind', String(args.kind));
321
+
322
+ const query = params.toString();
323
+ const path = `/blockers${query ? `?${query}` : ''}`;
324
+ const data = await client.get(path);
325
+ return { success: true, data };
326
+ } catch (error) {
327
+ return { success: false, error: String(error) };
328
+ }
329
+ };
330
+
331
+ export const createBlockerHandler: ToolHandler = async (args, client) => {
332
+ try {
333
+ const data = await client.post('/blockers', {
334
+ title: args.title,
335
+ description: args.description,
336
+ kind: args.kind,
337
+ options: args.options,
338
+ artifact_id: args.artifact_id,
339
+ task_id: args.task_id,
340
+ });
341
+ return { success: true, data };
342
+ } catch (error) {
343
+ return { success: false, error: String(error) };
344
+ }
345
+ };
346
+
347
+ export const resolveBlockerHandler: ToolHandler = async (args, client) => {
348
+ try {
349
+ const data = await client.post(`/blockers/${args.blocker_id}/resolve`, {
350
+ decision: args.decision,
351
+ notes: args.notes,
352
+ });
353
+ return { success: true, data };
354
+ } catch (error) {
355
+ return { success: false, error: String(error) };
356
+ }
357
+ };
358
+
359
+ // =============================================================================
360
+ // Organization Handlers
361
+ // =============================================================================
362
+
363
+ export const getOrgContextHandler: ToolHandler = async (args, client) => {
364
+ try {
365
+ const data = await client.get('/org/context');
366
+ return { success: true, data };
367
+ } catch (error) {
368
+ return { success: false, error: String(error) };
369
+ }
370
+ };
371
+
372
+ export const getProjectHandler: ToolHandler = async (args, client) => {
373
+ try {
374
+ const data = await client.get(`/projects/${args.project_id}`);
375
+ return { success: true, data };
376
+ } catch (error) {
377
+ return { success: false, error: String(error) };
378
+ }
379
+ };
380
+
381
+ export const listProjectsHandler: ToolHandler = async (args, client) => {
382
+ try {
383
+ const params = new URLSearchParams();
384
+ if (args.status) params.set('status', String(args.status));
385
+
386
+ const query = params.toString();
387
+ const path = `/projects${query ? `?${query}` : ''}`;
388
+ const data = await client.get(path);
389
+ return { success: true, data };
390
+ } catch (error) {
391
+ return { success: false, error: String(error) };
392
+ }
393
+ };
394
+
395
+ // =============================================================================
396
+ // Handler Registry
397
+ // =============================================================================
398
+
399
+ export const handlers: Record<string, ToolHandler> = {
400
+ // Sections
401
+ get_section: getSectionHandler,
402
+ list_sections: listSectionsHandler,
403
+ create_section: createSectionHandler,
404
+ update_section: updateSectionHandler,
405
+ delete_section: deleteSectionHandler,
406
+
407
+ // Artifacts
408
+ get_artifact: getArtifactHandler,
409
+ list_artifacts: listArtifactsHandler,
410
+ search_artifacts: searchArtifactsHandler,
411
+ create_artifact: createArtifactHandler,
412
+ update_artifact: updateArtifactHandler,
413
+ link_artifacts: linkArtifactsHandler,
414
+
415
+ // Agents
416
+ get_agent: getAgentHandler,
417
+ list_agents: listAgentsHandler,
418
+ create_agent: createAgentHandler,
419
+ update_agent: updateAgentHandler,
420
+
421
+ // Tasks
422
+ get_task: getTaskHandler,
423
+ list_tasks: listTasksHandler,
424
+ create_task: createTaskHandler,
425
+ complete_task: completeTaskHandler,
426
+ block_task: blockTaskHandler,
427
+
428
+ // Blockers
429
+ get_blocker: getBlockerHandler,
430
+ list_blockers: listBlockersHandler,
431
+ create_blocker: createBlockerHandler,
432
+ resolve_blocker: resolveBlockerHandler,
433
+
434
+ // Organization
435
+ get_org_context: getOrgContextHandler,
436
+ get_project: getProjectHandler,
437
+ list_projects: listProjectsHandler,
438
+ };
439
+
440
+ /**
441
+ * Get handler for a tool
442
+ */
443
+ export function getHandler(toolName: string): ToolHandler | undefined {
444
+ return handlers[toolName];
445
+ }
446
+
447
+ /**
448
+ * Execute a tool with the given arguments
449
+ */
450
+ export async function executeTool(
451
+ toolName: string,
452
+ args: Record<string, unknown>,
453
+ client: ApiClient
454
+ ): Promise<ToolResult> {
455
+ const handler = handlers[toolName];
456
+ if (!handler) {
457
+ return { success: false, error: `Unknown tool: ${toolName}` };
458
+ }
459
+ return handler(args, client);
460
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Artyfacts Tools
3
+ *
4
+ * Tools registry for Claude to interact with Artyfacts API.
5
+ */
6
+
7
+ export * from './types';
8
+ export * from './registry';
9
+ export * from './handlers';
10
+ export * from './api-client';
11
+
12
+ // Re-export commonly used functions
13
+ export {
14
+ getAllToolSchemas,
15
+ getToolSchema,
16
+ getToolsForPermissions,
17
+ isToolAllowed,
18
+ getRequiredPermission,
19
+ permissionToTools,
20
+ } from './registry';
21
+
22
+ export {
23
+ handlers,
24
+ getHandler,
25
+ executeTool,
26
+ } from './handlers';
27
+
28
+ export {
29
+ createApiClient,
30
+ } from './api-client';