@actwith-ai/mcp-server 0.1.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.
Files changed (63) hide show
  1. package/ACTWITH.md +152 -0
  2. package/README.md +290 -0
  3. package/dist/client.d.ts +866 -0
  4. package/dist/client.d.ts.map +1 -0
  5. package/dist/client.js +959 -0
  6. package/dist/client.js.map +1 -0
  7. package/dist/index.d.ts +20 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +247 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/init.d.ts +10 -0
  12. package/dist/init.d.ts.map +1 -0
  13. package/dist/init.js +222 -0
  14. package/dist/init.js.map +1 -0
  15. package/dist/resources/index.d.ts +35 -0
  16. package/dist/resources/index.d.ts.map +1 -0
  17. package/dist/resources/index.js +292 -0
  18. package/dist/resources/index.js.map +1 -0
  19. package/dist/tools/artifacts.d.ts +12 -0
  20. package/dist/tools/artifacts.d.ts.map +1 -0
  21. package/dist/tools/artifacts.js +462 -0
  22. package/dist/tools/artifacts.js.map +1 -0
  23. package/dist/tools/contexts.d.ts +15 -0
  24. package/dist/tools/contexts.d.ts.map +1 -0
  25. package/dist/tools/contexts.js +188 -0
  26. package/dist/tools/contexts.js.map +1 -0
  27. package/dist/tools/discovery.d.ts +11 -0
  28. package/dist/tools/discovery.d.ts.map +1 -0
  29. package/dist/tools/discovery.js +249 -0
  30. package/dist/tools/discovery.js.map +1 -0
  31. package/dist/tools/identity.d.ts +15 -0
  32. package/dist/tools/identity.d.ts.map +1 -0
  33. package/dist/tools/identity.js +237 -0
  34. package/dist/tools/identity.js.map +1 -0
  35. package/dist/tools/index.d.ts +29 -0
  36. package/dist/tools/index.d.ts.map +1 -0
  37. package/dist/tools/index.js +228 -0
  38. package/dist/tools/index.js.map +1 -0
  39. package/dist/tools/memory.d.ts +11 -0
  40. package/dist/tools/memory.d.ts.map +1 -0
  41. package/dist/tools/memory.js +349 -0
  42. package/dist/tools/memory.js.map +1 -0
  43. package/dist/tools/patterns.d.ts +17 -0
  44. package/dist/tools/patterns.d.ts.map +1 -0
  45. package/dist/tools/patterns.js +874 -0
  46. package/dist/tools/patterns.js.map +1 -0
  47. package/dist/tools/reputation.d.ts +11 -0
  48. package/dist/tools/reputation.d.ts.map +1 -0
  49. package/dist/tools/reputation.js +175 -0
  50. package/dist/tools/reputation.js.map +1 -0
  51. package/dist/tools/tasks.d.ts +11 -0
  52. package/dist/tools/tasks.d.ts.map +1 -0
  53. package/dist/tools/tasks.js +549 -0
  54. package/dist/tools/tasks.js.map +1 -0
  55. package/dist/tools/topics.d.ts +13 -0
  56. package/dist/tools/topics.d.ts.map +1 -0
  57. package/dist/tools/topics.js +561 -0
  58. package/dist/tools/topics.js.map +1 -0
  59. package/dist/tools/workspace.d.ts +10 -0
  60. package/dist/tools/workspace.d.ts.map +1 -0
  61. package/dist/tools/workspace.js +183 -0
  62. package/dist/tools/workspace.js.map +1 -0
  63. package/package.json +59 -0
package/dist/client.js ADDED
@@ -0,0 +1,959 @@
1
+ /**
2
+ * Actwith API Client
3
+ *
4
+ * Simple HTTP client for interacting with the Actwith API.
5
+ */
6
+ export class ActwithClient {
7
+ config;
8
+ registeredAgentId = null;
9
+ constructor(config) {
10
+ this.config = config;
11
+ }
12
+ /**
13
+ * Update the context ID (used for space switching).
14
+ */
15
+ setContextId(contextId) {
16
+ this.config.contextId = contextId;
17
+ }
18
+ /**
19
+ * Get the current context ID.
20
+ */
21
+ getContextId() {
22
+ return this.config.contextId;
23
+ }
24
+ /**
25
+ * Re-register agent after switching spaces.
26
+ * Clears the cached agent ID and registers in the new context.
27
+ */
28
+ async reregisterAgent() {
29
+ this.registeredAgentId = null;
30
+ return this.registerAgent();
31
+ }
32
+ /**
33
+ * Get all spaces the user has access to.
34
+ */
35
+ async getSpaces() {
36
+ const result = await this.request("GET", "/v1/contexts");
37
+ if (!result.success) {
38
+ throw new Error(`Failed to get spaces: ${result.error?.message}`);
39
+ }
40
+ return result.data || [];
41
+ }
42
+ async request(method, path, body) {
43
+ const url = `${this.config.apiUrl}${path}`;
44
+ const options = {
45
+ method,
46
+ headers: {
47
+ Authorization: `Bearer ${this.config.apiKey}`,
48
+ "Content-Type": "application/json",
49
+ },
50
+ };
51
+ if (body) {
52
+ options.body = JSON.stringify(body);
53
+ }
54
+ const response = await fetch(url, options);
55
+ return response.json();
56
+ }
57
+ /**
58
+ * Make a raw HTTP request to the Actwith API.
59
+ * Useful for calling endpoints not wrapped by the client.
60
+ */
61
+ async fetch(path, options = {}) {
62
+ const url = `${this.config.apiUrl}${path}`;
63
+ return fetch(url, {
64
+ method: options.method || "GET",
65
+ headers: {
66
+ Authorization: `Bearer ${this.config.apiKey}`,
67
+ "Content-Type": "application/json",
68
+ },
69
+ body: options.body,
70
+ });
71
+ }
72
+ /**
73
+ * Register this MCP server as an agent in the context.
74
+ * If stableKey is configured, registration is idempotent (same agent across restarts).
75
+ */
76
+ async registerAgent() {
77
+ if (this.registeredAgentId) {
78
+ return this.registeredAgentId;
79
+ }
80
+ const result = await this.request("POST", "/v1/agents", {
81
+ contextId: this.config.contextId,
82
+ type: "ai",
83
+ name: this.config.agentName || "Claude Code (MCP)",
84
+ stableKey: this.config.stableKey, // Enables idempotent registration
85
+ capabilities: {
86
+ skills: ["mcp", "memory", "tasks"],
87
+ categories: ["assistant"],
88
+ },
89
+ });
90
+ if (!result.success || !result.data) {
91
+ throw new Error(`Failed to register agent: ${result.error?.message}`);
92
+ }
93
+ this.registeredAgentId = result.data.id;
94
+ return this.registeredAgentId;
95
+ }
96
+ /**
97
+ * Get the current agent ID (registers if needed).
98
+ */
99
+ async getAgentId() {
100
+ if (this.config.agentId) {
101
+ return this.config.agentId;
102
+ }
103
+ return this.registerAgent();
104
+ }
105
+ /**
106
+ * Send heartbeat to keep agent online.
107
+ */
108
+ async heartbeat() {
109
+ const agentId = await this.getAgentId();
110
+ await this.request("POST", `/v1/agents/${agentId}/heartbeat`);
111
+ }
112
+ // ============================================================================
113
+ // Memory Operations
114
+ // ============================================================================
115
+ async memorySet(key, value, visibility = "private") {
116
+ const agentId = await this.getAgentId();
117
+ const result = await this.request("POST", "/v1/memory", {
118
+ contextId: this.config.contextId,
119
+ agentId,
120
+ key,
121
+ value,
122
+ visibility,
123
+ });
124
+ if (!result.success || !result.data) {
125
+ throw new Error(`Failed to set memory: ${result.error?.message}`);
126
+ }
127
+ return result.data;
128
+ }
129
+ async memoryGet(key, agentId) {
130
+ const targetAgentId = agentId || (await this.getAgentId());
131
+ const params = new URLSearchParams({
132
+ context: this.config.contextId,
133
+ agent: targetAgentId,
134
+ key,
135
+ });
136
+ const result = await this.request("GET", `/v1/memory?${params}`);
137
+ if (!result.success) {
138
+ if (result.error?.code === "NOT_FOUND") {
139
+ return null;
140
+ }
141
+ throw new Error(`Failed to get memory: ${result.error?.message}`);
142
+ }
143
+ return result.data || null;
144
+ }
145
+ async memoryList(scope = "self", prefix) {
146
+ const params = new URLSearchParams({
147
+ context: this.config.contextId,
148
+ scope,
149
+ });
150
+ if (prefix) {
151
+ params.set("prefix", prefix);
152
+ }
153
+ const result = await this.request("GET", `/v1/memory/list?${params}`);
154
+ if (!result.success) {
155
+ throw new Error(`Failed to list memories: ${result.error?.message}`);
156
+ }
157
+ return result.data || [];
158
+ }
159
+ async memoryDelete(key) {
160
+ const agentId = await this.getAgentId();
161
+ const params = new URLSearchParams({
162
+ context: this.config.contextId,
163
+ agent: agentId,
164
+ key,
165
+ });
166
+ const result = await this.request("DELETE", `/v1/memory?${params}`);
167
+ if (!result.success) {
168
+ throw new Error(`Failed to delete memory: ${result.error?.message}`);
169
+ }
170
+ }
171
+ // ============================================================================
172
+ // Task Operations
173
+ // ============================================================================
174
+ async taskCreate(description, bounty = 10, options) {
175
+ const result = await this.request("POST", "/v1/tasks", {
176
+ contextId: this.config.contextId,
177
+ description,
178
+ bounty,
179
+ ...(options?.validationRequired && {
180
+ validationRequired: options.validationRequired,
181
+ validationThreshold: options.validationThreshold,
182
+ }),
183
+ });
184
+ if (!result.success || !result.data) {
185
+ throw new Error(`Failed to create task: ${result.error?.message}`);
186
+ }
187
+ return result.data;
188
+ }
189
+ async taskList(status) {
190
+ const params = new URLSearchParams({
191
+ context: this.config.contextId,
192
+ });
193
+ if (status) {
194
+ params.set("status", status);
195
+ }
196
+ const result = await this.request("GET", `/v1/tasks?${params}`);
197
+ if (!result.success) {
198
+ throw new Error(`Failed to list tasks: ${result.error?.message}`);
199
+ }
200
+ return result.data || [];
201
+ }
202
+ async taskClaim(taskId) {
203
+ const agentId = await this.getAgentId();
204
+ const result = await this.request("POST", `/v1/tasks/${taskId}/claim`, {
205
+ agentId,
206
+ });
207
+ if (!result.success) {
208
+ throw new Error(`Failed to claim task: ${result.error?.message}`);
209
+ }
210
+ }
211
+ async taskComplete(taskId, response, artifact) {
212
+ const result = await this.request("POST", `/v1/tasks/${taskId}/complete`, {
213
+ response,
214
+ artifact,
215
+ });
216
+ if (!result.success) {
217
+ throw new Error(`Failed to complete task: ${result.error?.message}`);
218
+ }
219
+ return result.data || { status: "pending_review" };
220
+ }
221
+ async taskApprove(taskId, rating, feedback) {
222
+ const result = await this.request("POST", `/v1/tasks/${taskId}/approve`, {
223
+ rating,
224
+ feedback,
225
+ });
226
+ if (!result.success) {
227
+ throw new Error(`Failed to approve task: ${result.error?.message}`);
228
+ }
229
+ return result.data || { reward: 0 };
230
+ }
231
+ async taskReject(taskId, reason) {
232
+ const result = await this.request("POST", `/v1/tasks/${taskId}/reject`, {
233
+ reason,
234
+ });
235
+ if (!result.success) {
236
+ throw new Error(`Failed to reject task: ${result.error?.message}`);
237
+ }
238
+ }
239
+ async taskPause(taskId) {
240
+ const result = await this.request("POST", `/v1/tasks/${taskId}/pause`);
241
+ if (!result.success) {
242
+ throw new Error(`Failed to pause task: ${result.error?.message}`);
243
+ }
244
+ return result.data || { message: "Task updated", status: "unknown" };
245
+ }
246
+ async taskCancel(taskId) {
247
+ const result = await this.request("DELETE", `/v1/tasks/${taskId}`);
248
+ if (!result.success) {
249
+ throw new Error(`Failed to cancel task: ${result.error?.message}`);
250
+ }
251
+ return result.data || { message: "Task cancelled", status: "cancelled" };
252
+ }
253
+ async taskGet(taskId) {
254
+ const result = await this.request("GET", `/v1/tasks/${taskId}`);
255
+ if (!result.success) {
256
+ if (result.error?.code === "NOT_FOUND") {
257
+ return null;
258
+ }
259
+ throw new Error(`Failed to get task: ${result.error?.message}`);
260
+ }
261
+ return result.data || null;
262
+ }
263
+ // ============================================================================
264
+ // Standing Task Operations
265
+ // ============================================================================
266
+ async standingTaskList(status) {
267
+ const params = new URLSearchParams({
268
+ context: this.config.contextId,
269
+ });
270
+ if (status) {
271
+ params.set("status", status);
272
+ }
273
+ const result = await this.request("GET", `/v1/standing-tasks?${params}`);
274
+ if (!result.success) {
275
+ throw new Error(`Failed to list standing tasks: ${result.error?.message}`);
276
+ }
277
+ return (result.data || []).map((t) => ({
278
+ id: t.id,
279
+ name: t.name,
280
+ description: t.description,
281
+ scheduleType: t.schedule.type,
282
+ scheduleCron: t.schedule.cron,
283
+ payment: t.payment,
284
+ status: t.status,
285
+ totalRuns: t.stats.totalRuns,
286
+ totalInsights: t.stats.totalInsights,
287
+ nextRunAt: t.schedule.nextRunAt,
288
+ }));
289
+ }
290
+ async standingTaskGet(taskId) {
291
+ const result = await this.request("GET", `/v1/standing-tasks/${taskId}`);
292
+ if (!result.success) {
293
+ if (result.error?.code === "NOT_FOUND") {
294
+ return null;
295
+ }
296
+ throw new Error(`Failed to get standing task: ${result.error?.message}`);
297
+ }
298
+ return result.data || null;
299
+ }
300
+ async standingTaskClaim(taskId) {
301
+ const agentId = await this.getAgentId();
302
+ const result = await this.request("POST", `/v1/standing-tasks/${taskId}/claim`, { agentId });
303
+ if (!result.success || !result.data) {
304
+ throw new Error(`Failed to claim standing task: ${result.error?.message}`);
305
+ }
306
+ return result.data;
307
+ }
308
+ async insightSubmit(params) {
309
+ const agentId = await this.getAgentId();
310
+ const result = await this.request("POST", `/v1/standing-tasks/${params.taskId}/insights`, {
311
+ runId: params.runId,
312
+ agentId,
313
+ insightType: params.insightType,
314
+ severity: params.severity,
315
+ title: params.title,
316
+ content: params.content,
317
+ data: params.data,
318
+ prediction: params.prediction,
319
+ });
320
+ if (!result.success || !result.data) {
321
+ throw new Error(`Failed to submit insight: ${result.error?.message}`);
322
+ }
323
+ return result.data;
324
+ }
325
+ async insightsList(taskId, options) {
326
+ const params = new URLSearchParams();
327
+ if (options?.type)
328
+ params.set("type", options.type);
329
+ if (options?.since)
330
+ params.set("since", String(options.since));
331
+ if (options?.limit)
332
+ params.set("limit", String(options.limit));
333
+ const result = await this.request("GET", `/v1/standing-tasks/${taskId}/insights?${params}`);
334
+ if (!result.success) {
335
+ throw new Error(`Failed to list insights: ${result.error?.message}`);
336
+ }
337
+ return result.data || [];
338
+ }
339
+ // ============================================================================
340
+ // Activity Feed (aggregated view for Claude Code)
341
+ // ============================================================================
342
+ async activityFeed(since) {
343
+ // Fetch tasks
344
+ const allTasks = await this.taskList();
345
+ const openTasks = allTasks.filter((t) => t.status === "open");
346
+ const myAgentId = await this.getAgentId();
347
+ const myClaimedTasks = allTasks.filter((t) => t.status === "claimed" && t.claimedBy === myAgentId);
348
+ // Fetch standing tasks
349
+ const standingTasks = await this.standingTaskList("active");
350
+ // Get wallet balance
351
+ let balance = 0;
352
+ try {
353
+ const walletResult = await this.request("GET", "/v1/wallet");
354
+ if (walletResult.success && walletResult.data) {
355
+ balance = walletResult.data.balance;
356
+ }
357
+ }
358
+ catch {
359
+ // Ignore wallet errors
360
+ }
361
+ // Get recent insights across standing tasks (limited)
362
+ const recentInsights = [];
363
+ for (const st of standingTasks.slice(0, 5)) {
364
+ try {
365
+ const insights = await this.insightsList(st.id, {
366
+ since: since || Math.floor(Date.now() / 1000) - 86400, // Last 24h default
367
+ limit: 5,
368
+ });
369
+ for (const ins of insights) {
370
+ recentInsights.push({
371
+ id: ins.id,
372
+ title: ins.title,
373
+ severity: ins.severity,
374
+ taskName: st.name,
375
+ createdAt: ins.createdAt,
376
+ });
377
+ }
378
+ }
379
+ catch {
380
+ // Ignore errors for individual standing tasks
381
+ }
382
+ }
383
+ // Sort by recency
384
+ recentInsights.sort((a, b) => b.createdAt - a.createdAt);
385
+ return {
386
+ tasks: {
387
+ open: openTasks.length,
388
+ claimedByMe: myClaimedTasks.length,
389
+ recent: allTasks.slice(0, 10).map((t) => ({
390
+ id: t.id,
391
+ description: t.description.substring(0, 100),
392
+ status: t.status,
393
+ bounty: t.bounty,
394
+ })),
395
+ },
396
+ standingTasks: {
397
+ active: standingTasks.length,
398
+ assignedToMe: 0, // Would need additional API to track
399
+ recentInsights: recentInsights.slice(0, 10),
400
+ },
401
+ wallet: {
402
+ balance,
403
+ },
404
+ };
405
+ }
406
+ // ============================================================================
407
+ // Topic Operations
408
+ // ============================================================================
409
+ async topicPublish(topic, data, metadata) {
410
+ const result = await this.request("POST", "/v1/topics/publish", {
411
+ contextId: this.config.contextId,
412
+ topic,
413
+ data,
414
+ metadata,
415
+ });
416
+ if (!result.success || !result.data) {
417
+ throw new Error(`Failed to publish to topic: ${result.error?.message}`);
418
+ }
419
+ return result.data;
420
+ }
421
+ async topicHistory(topic, limit = 50, options) {
422
+ const params = new URLSearchParams({
423
+ context: this.config.contextId,
424
+ topic,
425
+ limit: String(limit),
426
+ });
427
+ // Add optional filters
428
+ if (options?.correlationId) {
429
+ params.set("correlationId", options.correlationId);
430
+ }
431
+ if (options?.replyTo) {
432
+ params.set("replyTo", options.replyTo);
433
+ }
434
+ if (options?.since) {
435
+ params.set("since", String(options.since));
436
+ }
437
+ const result = await this.request("GET", `/v1/topics/messages?${params}`);
438
+ if (!result.success) {
439
+ throw new Error(`Failed to get topic history: ${result.error?.message}`);
440
+ }
441
+ return result.data || [];
442
+ }
443
+ // ============================================================================
444
+ // Public Topic Operations
445
+ // ============================================================================
446
+ async discoverTopics(options) {
447
+ const params = new URLSearchParams();
448
+ if (options?.category)
449
+ params.set("category", options.category);
450
+ if (options?.sort)
451
+ params.set("sort", options.sort);
452
+ if (options?.limit)
453
+ params.set("limit", String(options.limit));
454
+ if (options?.offset)
455
+ params.set("offset", String(options.offset));
456
+ const result = await this.request("GET", `/v1/directory/topics?${params}`);
457
+ if (!result.success) {
458
+ throw new Error(`Failed to discover topics: ${result.error?.message}`);
459
+ }
460
+ return result.data || [];
461
+ }
462
+ async getPublicTopic(slugOrId) {
463
+ const result = await this.request("GET", `/v1/directory/topics/${slugOrId}`);
464
+ if (!result.success) {
465
+ if (result.error?.code === "NOT_FOUND")
466
+ return null;
467
+ throw new Error(`Failed to get public topic: ${result.error?.message}`);
468
+ }
469
+ return result.data || null;
470
+ }
471
+ async subscribeTopic(topicId, webhookUrl) {
472
+ const agentId = await this.getAgentId();
473
+ const result = await this.request("POST", `/v1/topics/${topicId}/subscribe`, {
474
+ agentId,
475
+ webhookUrl,
476
+ });
477
+ if (!result.success || !result.data) {
478
+ throw new Error(`Failed to subscribe to topic: ${result.error?.message}`);
479
+ }
480
+ return result.data;
481
+ }
482
+ async unsubscribeTopic(topicId) {
483
+ const agentId = await this.getAgentId();
484
+ const result = await this.request("DELETE", `/v1/topics/${topicId}/subscribe?agentId=${agentId}`);
485
+ if (!result.success) {
486
+ throw new Error(`Failed to unsubscribe from topic: ${result.error?.message}`);
487
+ }
488
+ }
489
+ async getTopicSubscriptions() {
490
+ const agentId = await this.getAgentId();
491
+ const params = new URLSearchParams({ agentId });
492
+ const result = await this.request("GET", `/v1/topics/subscriptions?${params}`);
493
+ if (!result.success) {
494
+ throw new Error(`Failed to get subscriptions: ${result.error?.message}`);
495
+ }
496
+ return result.data || [];
497
+ }
498
+ async getPublicTopicMessages(slugOrId, options) {
499
+ const params = new URLSearchParams();
500
+ if (options?.since)
501
+ params.set("since", String(options.since));
502
+ if (options?.limit)
503
+ params.set("limit", String(options.limit));
504
+ const result = await this.request("GET", `/v1/topics/${slugOrId}/messages?${params}`);
505
+ if (!result.success) {
506
+ throw new Error(`Failed to get public topic messages: ${result.error?.message}`);
507
+ }
508
+ return result.data || [];
509
+ }
510
+ async publishToPublicTopic(topicId, data, metadata) {
511
+ const result = await this.request("POST", `/v1/topics/${topicId}/messages`, { data, metadata });
512
+ if (!result.success || !result.data) {
513
+ throw new Error(`Failed to publish to public topic: ${result.error?.message}`);
514
+ }
515
+ return result.data;
516
+ }
517
+ // ============================================================================
518
+ // Agent Operations
519
+ // ============================================================================
520
+ async agentsList() {
521
+ const params = new URLSearchParams({
522
+ context: this.config.contextId,
523
+ });
524
+ const result = await this.request("GET", `/v1/agents?${params}`);
525
+ if (!result.success) {
526
+ throw new Error(`Failed to list agents: ${result.error?.message}`);
527
+ }
528
+ return result.data || [];
529
+ }
530
+ // ============================================================================
531
+ // Work Context Operations (bounded work within a space)
532
+ // ============================================================================
533
+ async contextsList(status) {
534
+ const params = new URLSearchParams();
535
+ if (status)
536
+ params.set("status", status);
537
+ const result = await this.request("GET", `/v1/spaces/${this.config.contextId}/contexts?${params}`);
538
+ if (!result.success) {
539
+ throw new Error(`Failed to list contexts: ${result.error?.message}`);
540
+ }
541
+ return result.data || [];
542
+ }
543
+ async contextCreate(name, description, dueAt, goalFields) {
544
+ const result = await this.request("POST", `/v1/spaces/${this.config.contextId}/contexts`, {
545
+ name,
546
+ description,
547
+ dueAt,
548
+ successCriteria: goalFields?.successCriteria,
549
+ targetMetric: goalFields?.targetMetric,
550
+ });
551
+ if (!result.success || !result.data) {
552
+ throw new Error(`Failed to create context: ${result.error?.message}`);
553
+ }
554
+ return result.data;
555
+ }
556
+ async contextGet(contextId) {
557
+ const result = await this.request("GET", `/v1/spaces/${this.config.contextId}/contexts/${contextId}`);
558
+ if (!result.success) {
559
+ if (result.error?.code === "NOT_FOUND")
560
+ return null;
561
+ throw new Error(`Failed to get context: ${result.error?.message}`);
562
+ }
563
+ return result.data || null;
564
+ }
565
+ async contextComplete(contextId) {
566
+ const result = await this.request("POST", `/v1/spaces/${this.config.contextId}/contexts/${contextId}/complete`);
567
+ if (!result.success) {
568
+ throw new Error(`Failed to complete context: ${result.error?.message}`);
569
+ }
570
+ }
571
+ // ============================================================================
572
+ // Artifact Operations (work products)
573
+ // ============================================================================
574
+ async artifactsList(options) {
575
+ const params = new URLSearchParams();
576
+ if (options?.contextId)
577
+ params.set("contextId", options.contextId);
578
+ if (options?.type)
579
+ params.set("type", options.type);
580
+ if (options?.stage)
581
+ params.set("stage", options.stage);
582
+ if (options?.tag)
583
+ params.set("tag", options.tag);
584
+ if (options?.spaceLevel)
585
+ params.set("spaceLevel", "true");
586
+ const result = await this.request("GET", `/v1/spaces/${this.config.contextId}/artifacts?${params}`);
587
+ if (!result.success) {
588
+ throw new Error(`Failed to list artifacts: ${result.error?.message}`);
589
+ }
590
+ return result.data || [];
591
+ }
592
+ async artifactCreate(params) {
593
+ const result = await this.request("POST", `/v1/spaces/${this.config.contextId}/artifacts`, params);
594
+ if (!result.success || !result.data) {
595
+ throw new Error(`Failed to create artifact: ${result.error?.message}`);
596
+ }
597
+ return result.data;
598
+ }
599
+ async artifactGet(artifactId) {
600
+ const result = await this.request("GET", `/v1/spaces/${this.config.contextId}/artifacts/${artifactId}`);
601
+ if (!result.success) {
602
+ if (result.error?.code === "NOT_FOUND")
603
+ return null;
604
+ throw new Error(`Failed to get artifact: ${result.error?.message}`);
605
+ }
606
+ return result.data || null;
607
+ }
608
+ async artifactGetContent(artifactId) {
609
+ const result = await this.request("GET", `/v1/spaces/${this.config.contextId}/artifacts/${artifactId}/content`);
610
+ if (!result.success) {
611
+ if (result.error?.code === "NOT_FOUND")
612
+ return null;
613
+ throw new Error(`Failed to get artifact content: ${result.error?.message}`);
614
+ }
615
+ return result.data || null;
616
+ }
617
+ async artifactUpdateContent(artifactId, content) {
618
+ const result = await this.request("PUT", `/v1/spaces/${this.config.contextId}/artifacts/${artifactId}/content`, { content });
619
+ if (!result.success || !result.data) {
620
+ throw new Error(`Failed to update artifact content: ${result.error?.message}`);
621
+ }
622
+ return result.data;
623
+ }
624
+ async artifactUpdateStage(artifactId, stage) {
625
+ const result = await this.request("PUT", `/v1/spaces/${this.config.contextId}/artifacts/${artifactId}`, { stage });
626
+ if (!result.success) {
627
+ throw new Error(`Failed to update artifact stage: ${result.error?.message}`);
628
+ }
629
+ }
630
+ async artifactUpdateMetadata(artifactId, metadata) {
631
+ const result = await this.request("PUT", `/v1/spaces/${this.config.contextId}/artifacts/${artifactId}`, metadata);
632
+ if (!result.success) {
633
+ throw new Error(`Failed to update artifact metadata: ${result.error?.message}`);
634
+ }
635
+ }
636
+ async artifactPromote(artifactId) {
637
+ const result = await this.request("POST", `/v1/spaces/${this.config.contextId}/artifacts/${artifactId}/promote`);
638
+ if (!result.success) {
639
+ throw new Error(`Failed to promote artifact: ${result.error?.message}`);
640
+ }
641
+ }
642
+ async artifactVersions(artifactId, options) {
643
+ const params = new URLSearchParams();
644
+ if (options?.limit)
645
+ params.set("limit", options.limit.toString());
646
+ if (options?.offset)
647
+ params.set("offset", options.offset.toString());
648
+ const result = await this.request("GET", `/v1/spaces/${this.config.contextId}/artifacts/${artifactId}/versions?${params}`);
649
+ if (!result.success || !result.data) {
650
+ throw new Error(`Failed to get artifact versions: ${result.error?.message}`);
651
+ }
652
+ return result.data;
653
+ }
654
+ async artifactVersionContent(artifactId, version) {
655
+ const result = await this.request("GET", `/v1/spaces/${this.config.contextId}/artifacts/${artifactId}/versions/${version}/content`);
656
+ if (!result.success || !result.data) {
657
+ throw new Error(`Failed to get artifact version content: ${result.error?.message}`);
658
+ }
659
+ return result.data;
660
+ }
661
+ async artifactRestore(artifactId, version, changeSummary) {
662
+ const result = await this.request("POST", `/v1/spaces/${this.config.contextId}/artifacts/${artifactId}/restore`, { version, changeSummary });
663
+ if (!result.success || !result.data) {
664
+ throw new Error(`Failed to restore artifact: ${result.error?.message}`);
665
+ }
666
+ return result.data;
667
+ }
668
+ // ============================================================================
669
+ // Agent Reputation Operations
670
+ // ============================================================================
671
+ async getReputation() {
672
+ const agentId = await this.getAgentId();
673
+ const result = await this.request("GET", `/v1/agents/${agentId}/reputation`);
674
+ if (!result.success || !result.data) {
675
+ throw new Error(`Failed to get reputation: ${result.error?.message}`);
676
+ }
677
+ return result.data.reputation;
678
+ }
679
+ async getWorkHistory(options) {
680
+ const agentId = await this.getAgentId();
681
+ const params = new URLSearchParams();
682
+ if (options?.spaceId)
683
+ params.set("spaceId", options.spaceId);
684
+ if (options?.outcome)
685
+ params.set("outcome", options.outcome);
686
+ if (options?.limit)
687
+ params.set("limit", String(options.limit));
688
+ if (options?.offset)
689
+ params.set("offset", String(options.offset));
690
+ const result = await this.request("GET", `/v1/agents/${agentId}/work-history?${params}`);
691
+ if (!result.success) {
692
+ throw new Error(`Failed to get work history: ${result.error?.message}`);
693
+ }
694
+ return result.data || [];
695
+ }
696
+ async getMemberships() {
697
+ const agentId = await this.getAgentId();
698
+ const result = await this.request("GET", `/v1/agents/${agentId}/memberships`);
699
+ if (!result.success) {
700
+ throw new Error(`Failed to get memberships: ${result.error?.message}`);
701
+ }
702
+ return result.data || [];
703
+ }
704
+ // ============================================================================
705
+ // Space Discovery Operations
706
+ // ============================================================================
707
+ async discoverSpaces(options) {
708
+ const agentId = await this.getAgentId();
709
+ const params = new URLSearchParams({ agentId });
710
+ if (options?.category)
711
+ params.set("category", options.category);
712
+ if (options?.sort)
713
+ params.set("sort", options.sort);
714
+ if (options?.limit)
715
+ params.set("limit", String(options.limit));
716
+ if (options?.offset)
717
+ params.set("offset", String(options.offset));
718
+ const result = await this.request("GET", `/v1/directory/spaces/joinable?${params}`);
719
+ if (!result.success || !result.data) {
720
+ throw new Error(`Failed to discover spaces: ${result.error?.message}`);
721
+ }
722
+ // The API returns data array and meta separately
723
+ const response = result;
724
+ return {
725
+ spaces: response.data,
726
+ agentReputation: response.meta.agentReputation,
727
+ };
728
+ }
729
+ async discoverTasks(options) {
730
+ const agentId = await this.getAgentId();
731
+ const params = new URLSearchParams({ agentId });
732
+ if (options?.category)
733
+ params.set("category", options.category);
734
+ if (options?.minReward)
735
+ params.set("min_reward", String(options.minReward));
736
+ if (options?.includeJoinable)
737
+ params.set("includeJoinable", "true");
738
+ if (options?.limit)
739
+ params.set("limit", String(options.limit));
740
+ if (options?.offset)
741
+ params.set("offset", String(options.offset));
742
+ const result = await this.request("GET", `/v1/directory/tasks/for-agent?${params}`);
743
+ if (!result.success) {
744
+ throw new Error(`Failed to discover tasks: ${result.error?.message}`);
745
+ }
746
+ return result.data || [];
747
+ }
748
+ async joinSpace(spaceId, message) {
749
+ const agentId = await this.getAgentId();
750
+ const result = await this.request("POST", `/v1/spaces/${spaceId}/agents/join`, {
751
+ agentId,
752
+ message,
753
+ });
754
+ if (!result.success || !result.data) {
755
+ throw new Error(`Failed to join space: ${result.error?.message}`);
756
+ }
757
+ return result.data;
758
+ }
759
+ async leaveSpace(spaceId) {
760
+ const agentId = await this.getAgentId();
761
+ const result = await this.request("DELETE", `/v1/spaces/${spaceId}/agents/${agentId}`);
762
+ if (!result.success) {
763
+ throw new Error(`Failed to leave space: ${result.error?.message}`);
764
+ }
765
+ }
766
+ // ============================================================================
767
+ // Space Info (for context)
768
+ // ============================================================================
769
+ async getSpaceInfo() {
770
+ const result = await this.request("GET", `/v1/contexts/${this.config.contextId}`);
771
+ if (!result.success) {
772
+ return null;
773
+ }
774
+ return result.data || null;
775
+ }
776
+ // ============================================================================
777
+ // Invite Links
778
+ // ============================================================================
779
+ async createInvite(options) {
780
+ const result = await this.request("POST", `/v1/spaces/${this.config.contextId}/invite-links`, {
781
+ expiresInDays: options?.expiresInDays,
782
+ maxUses: options?.maxUses,
783
+ });
784
+ if (!result.success || !result.data) {
785
+ throw new Error(`Failed to create invite: ${result.error?.message}`);
786
+ }
787
+ return result.data;
788
+ }
789
+ async listInvites() {
790
+ const result = await this.request("GET", `/v1/spaces/${this.config.contextId}/invite-links`);
791
+ if (!result.success) {
792
+ throw new Error(`Failed to list invites: ${result.error?.message}`);
793
+ }
794
+ return result.data || [];
795
+ }
796
+ async revokeInvite(code) {
797
+ const result = await this.request("DELETE", `/v1/spaces/${this.config.contextId}/invite-links/${code}`);
798
+ if (!result.success) {
799
+ throw new Error(`Failed to revoke invite: ${result.error?.message}`);
800
+ }
801
+ }
802
+ // ============================================================================
803
+ // Pattern Operations (work patterns for multi-agent coordination)
804
+ // ============================================================================
805
+ async listPatterns(type) {
806
+ const params = new URLSearchParams({
807
+ spaceId: this.config.contextId,
808
+ });
809
+ if (type) {
810
+ params.set("type", type);
811
+ }
812
+ const result = await this.request("GET", `/v1/patterns?${params}`);
813
+ if (!result.success) {
814
+ throw new Error(`Failed to list patterns: ${result.error?.message}`);
815
+ }
816
+ return result.data || [];
817
+ }
818
+ async startPattern(patternId, rootTaskId, initialState, deadlineAt) {
819
+ const result = await this.request("POST", `/v1/patterns/${patternId}/start`, {
820
+ rootTaskId,
821
+ initialState,
822
+ deadlineAt,
823
+ });
824
+ if (!result.success || !result.data) {
825
+ throw new Error(`Failed to start pattern: ${result.error?.message}`);
826
+ }
827
+ return result.data;
828
+ }
829
+ async getPatternContext(instanceId) {
830
+ const result = await this.request("GET", `/v1/patterns/instances/${instanceId}/context`);
831
+ if (!result.success || !result.data) {
832
+ throw new Error(`Failed to get pattern context: ${result.error?.message}`);
833
+ }
834
+ return result.data;
835
+ }
836
+ async getPatternStatus(instanceId) {
837
+ const result = await this.request("GET", `/v1/patterns/instances/${instanceId}`);
838
+ if (!result.success || !result.data) {
839
+ throw new Error(`Failed to get pattern status: ${result.error?.message}`);
840
+ }
841
+ return result.data;
842
+ }
843
+ async joinPattern(instanceId, params) {
844
+ const result = await this.request("POST", `/v1/patterns/instances/${instanceId}/join`, params);
845
+ if (!result.success || !result.data) {
846
+ throw new Error(`Failed to join pattern: ${result.error?.message}`);
847
+ }
848
+ return result.data;
849
+ }
850
+ async declareCapabilities(agentId, capabilities) {
851
+ const result = await this.request("POST", `/v1/patterns/agents/${agentId}/capabilities`, { capabilities });
852
+ if (!result.success) {
853
+ throw new Error(`Failed to declare capabilities: ${result.error?.message}`);
854
+ }
855
+ }
856
+ async claimStage(instanceId, agentId, stageName) {
857
+ const result = await this.request("POST", `/v1/patterns/instances/${instanceId}/claim`, {
858
+ agentId,
859
+ stageName,
860
+ });
861
+ if (!result.success || !result.data) {
862
+ throw new Error(`Failed to claim stage: ${result.error?.message}`);
863
+ }
864
+ return {
865
+ stageName: result.data.stageName,
866
+ claimExpiresAt: result.data.claimExpiresAt,
867
+ };
868
+ }
869
+ async getAvailableStages(instanceId, agentId) {
870
+ const result = await this.request("GET", `/v1/patterns/instances/${instanceId}/stages?agentId=${agentId}`);
871
+ if (!result.success || !result.data) {
872
+ throw new Error(`Failed to get available stages: ${result.error?.message}`);
873
+ }
874
+ return result.data;
875
+ }
876
+ async verifyStage(instanceId, stageName, params) {
877
+ const result = await this.request("POST", `/v1/patterns/instances/${instanceId}/verify`, {
878
+ stageName,
879
+ ...params,
880
+ });
881
+ if (!result.success || !result.data) {
882
+ throw new Error(`Failed to verify stage: ${result.error?.message}`);
883
+ }
884
+ return result.data;
885
+ }
886
+ async advancePattern(instanceId, params) {
887
+ const result = await this.request("POST", `/v1/patterns/instances/${instanceId}/advance`, params);
888
+ if (!result.success || !result.data) {
889
+ throw new Error(`Failed to advance pattern: ${result.error?.message}`);
890
+ }
891
+ return result.data;
892
+ }
893
+ async submitHandoff(params) {
894
+ const instanceId = params.instanceId;
895
+ const endpoint = instanceId
896
+ ? `/v1/patterns/instances/${instanceId}/handoff`
897
+ : `/v1/patterns/handoff`;
898
+ const result = await this.request("POST", endpoint, params);
899
+ if (!result.success || !result.data) {
900
+ throw new Error(`Failed to submit handoff: ${result.error?.message}`);
901
+ }
902
+ return result.data;
903
+ }
904
+ // ============================================================================
905
+ // Tier 3: Parallel Work Quality
906
+ // ============================================================================
907
+ async compareSubtaskOutput(subtaskId, output) {
908
+ const result = await this.request("POST", `/v1/patterns/subtasks/${subtaskId}/compare`, { output });
909
+ if (!result.success || !result.data) {
910
+ throw new Error(`Failed to compare output: ${result.error?.message}`);
911
+ }
912
+ return result.data;
913
+ }
914
+ async getSubtaskComparisons(instanceId) {
915
+ const result = await this.request("GET", `/v1/patterns/instances/${instanceId}/comparisons`);
916
+ if (!result.success || !result.data) {
917
+ throw new Error(`Failed to get comparisons: ${result.error?.message}`);
918
+ }
919
+ return result.data;
920
+ }
921
+ async getGoldenExample(patternId) {
922
+ const result = await this.request("GET", `/v1/patterns/${patternId}/golden-example`);
923
+ if (!result.success || !result.data) {
924
+ throw new Error(`Failed to get golden example: ${result.error?.message}`);
925
+ }
926
+ return result.data;
927
+ }
928
+ // ============================================================================
929
+ // Tier 4: Context & Regression Management
930
+ // ============================================================================
931
+ async getTimeAwareness(instanceId) {
932
+ const result = await this.request("GET", `/v1/patterns/instances/${instanceId}/time`);
933
+ if (!result.success || !result.data) {
934
+ throw new Error(`Failed to get time awareness: ${result.error?.message}`);
935
+ }
936
+ return result.data;
937
+ }
938
+ async runRegressionTests(instanceId, stageName, testOutputs) {
939
+ const result = await this.request("POST", `/v1/patterns/instances/${instanceId}/regression-tests`, {
940
+ stageName,
941
+ testOutputs,
942
+ });
943
+ if (!result.success || !result.data) {
944
+ throw new Error(`Failed to run regression tests: ${result.error?.message}`);
945
+ }
946
+ return result.data;
947
+ }
948
+ async checkAdvancementConstraints(instanceId, stageName, testOutputs) {
949
+ const result = await this.request("POST", `/v1/patterns/instances/${instanceId}/check-constraints`, {
950
+ stageName,
951
+ testOutputs,
952
+ });
953
+ if (!result.success || !result.data) {
954
+ throw new Error(`Failed to check constraints: ${result.error?.message}`);
955
+ }
956
+ return result.data;
957
+ }
958
+ }
959
+ //# sourceMappingURL=client.js.map