synomem 0.1.0 → 0.2.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 (73) hide show
  1. package/ARCHITECTURE.md +2 -2
  2. package/CHANGELOG.md +37 -1
  3. package/README.md +28 -15
  4. package/dist/cli.d.ts.map +1 -1
  5. package/dist/cli.js +311 -70
  6. package/dist/cli.js.map +1 -1
  7. package/dist/client.d.ts +96 -17
  8. package/dist/client.d.ts.map +1 -1
  9. package/dist/client.js +333 -76
  10. package/dist/client.js.map +1 -1
  11. package/dist/config.d.ts +2 -2
  12. package/dist/config.js +8 -8
  13. package/dist/import.d.ts +207 -13
  14. package/dist/import.d.ts.map +1 -1
  15. package/dist/index.d.ts +2 -2
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +2 -2
  18. package/dist/index.js.map +1 -1
  19. package/dist/mcp/index.d.ts.map +1 -1
  20. package/dist/mcp/index.js +156 -31
  21. package/dist/mcp/index.js.map +1 -1
  22. package/dist/mcp-server.js +54 -8
  23. package/dist/mcp-server.js.map +1 -1
  24. package/dist/ports/repository.d.ts +18 -1
  25. package/dist/ports/repository.d.ts.map +1 -1
  26. package/dist/projections.d.ts +18 -1
  27. package/dist/projections.d.ts.map +1 -1
  28. package/dist/projections.js +137 -44
  29. package/dist/projections.js.map +1 -1
  30. package/dist/remote.d.ts +57 -9
  31. package/dist/remote.d.ts.map +1 -1
  32. package/dist/remote.js +43 -2
  33. package/dist/remote.js.map +1 -1
  34. package/dist/schemas.d.ts +302 -21
  35. package/dist/schemas.d.ts.map +1 -1
  36. package/dist/schemas.js +142 -26
  37. package/dist/schemas.js.map +1 -1
  38. package/dist/service.d.ts +57 -10
  39. package/dist/service.d.ts.map +1 -1
  40. package/dist/skill-install.d.ts +8 -2
  41. package/dist/skill-install.d.ts.map +1 -1
  42. package/dist/skill-install.js +6 -11
  43. package/dist/skill-install.js.map +1 -1
  44. package/dist/storage.d.ts +41 -1
  45. package/dist/storage.d.ts.map +1 -1
  46. package/dist/storage.js +254 -36
  47. package/dist/storage.js.map +1 -1
  48. package/dist/types.d.ts +213 -38
  49. package/dist/types.d.ts.map +1 -1
  50. package/docs/cli.md +53 -20
  51. package/docs/examples.md +4 -4
  52. package/docs/mcp.md +12 -4
  53. package/docs/skill.md +10 -7
  54. package/docs/storage-format.md +4 -4
  55. package/openapi/synomem-v1.yaml +24 -24
  56. package/package.json +1 -1
  57. package/skills/synomem/SKILL.md +24 -8
  58. package/skills/synomem/agents/openai.yaml +1 -1
  59. package/skills/synomem/references/examples.md +1 -1
  60. package/src/cli.ts +572 -173
  61. package/src/client.ts +391 -79
  62. package/src/config.ts +8 -8
  63. package/src/index.ts +11 -1
  64. package/src/mcp/index.ts +189 -30
  65. package/src/mcp-server.ts +58 -8
  66. package/src/ports/repository.ts +16 -0
  67. package/src/projections.ts +139 -44
  68. package/src/remote.ts +118 -8
  69. package/src/schemas.ts +147 -26
  70. package/src/service.ts +59 -7
  71. package/src/skill-install.ts +14 -17
  72. package/src/storage.ts +326 -34
  73. package/src/types.ts +228 -39
package/src/types.ts CHANGED
@@ -3,7 +3,7 @@ export type JsonValue = JsonPrimitive | JsonValue[] | { [key: string]: JsonValue
3
3
 
4
4
  export type ActorKind = 'human' | 'agent' | 'system';
5
5
  export type Visibility = 'private' | 'workspace' | 'public';
6
- export type RecordKind = 'kudos' | 'memo' | 'note' | 'todo';
6
+ export type RecordKind = 'kudos' | 'memo' | 'note' | 'task' | 'todo';
7
7
 
8
8
  export interface ActorIdentity {
9
9
  kind: ActorKind;
@@ -36,6 +36,53 @@ export interface AgentProfile {
36
36
  metadata?: Record<string, JsonValue>;
37
37
  }
38
38
 
39
+ /**
40
+ * Where an agent is currently reachable, as far as Synomem has been told.
41
+ *
42
+ * A binding is a claim made at registration, not a live connection. `lastSeenAt`
43
+ * is advisory: it says when Synomem last observed this binding act, never that
44
+ * the runtime is reachable now. Callers must not treat its absence as offline.
45
+ */
46
+ export interface AgentRuntimeBinding {
47
+ id: string;
48
+ agentId: string;
49
+ /** Hosted deployment this binding belongs to; absent for local installs. */
50
+ installationId?: string;
51
+ /** Runtime family, e.g. `claude-code`, `hermes`, `openai-agents`. */
52
+ runtime: string;
53
+ /** Named configuration within a runtime, when one runtime hosts several. */
54
+ profile?: string;
55
+ capabilities: Record<string, JsonValue>;
56
+ boundAt: string;
57
+ lastSeenAt?: string;
58
+ }
59
+
60
+ /**
61
+ * One agent as the directory exposes it: visible identity plus advisory
62
+ * reachability.
63
+ *
64
+ * Roles and capabilities are deliberately absent. Authorization is decided by
65
+ * the control plane against the caller's credential, so publishing a role here
66
+ * would only invite a reader to treat the directory as a permission check.
67
+ */
68
+ export interface AgentDirectoryEntry {
69
+ profile: AgentProfile;
70
+ runtimeBindings: AgentRuntimeBinding[];
71
+ }
72
+
73
+ /**
74
+ * The outcome of resolving a name, which may legitimately name no one or
75
+ * several.
76
+ *
77
+ * `match` is set only when exactly one agent answers to the name. Anything else
78
+ * hands back `candidates` so the caller can ask rather than pick.
79
+ */
80
+ export interface AgentResolution {
81
+ query: string;
82
+ match?: AgentProfile;
83
+ candidates: AgentProfile[];
84
+ }
85
+
39
86
  export interface BaseEvent {
40
87
  schemaVersion: 1;
41
88
  id: string;
@@ -115,30 +162,95 @@ export interface NoteArchivedEvent extends BaseEvent {
115
162
  noteId: string;
116
163
  }
117
164
 
118
- export type TodoPriority = 1 | 2 | 3 | 4;
119
- export type TodoDue =
165
+ export type TaskPriority = 1 | 2 | 3 | 4;
166
+ export type TaskDue =
120
167
  { kind: 'date'; date: string } | { kind: 'datetime'; datetime: string; timeZone: string };
121
- export interface TodoCreatedEvent extends BaseEvent {
122
- type: 'todo.created';
168
+ export interface TaskCreatedEvent extends BaseEvent {
169
+ type: 'task.created';
123
170
  assigneeAgentId: string;
124
171
  assigneeDisplayName: string;
125
172
  title: string;
126
173
  description?: string;
127
- priority: TodoPriority;
128
- due?: TodoDue;
174
+ priority: TaskPriority;
175
+ due?: TaskDue;
129
176
  tags?: string[];
130
177
  visibility: Visibility;
131
178
  requiresAcceptance: boolean;
132
179
  }
180
+ export interface TaskUpdatedEvent extends BaseEvent {
181
+ type: 'task.updated';
182
+ taskId: string;
183
+ title: string;
184
+ description?: string;
185
+ priority: TaskPriority;
186
+ due?: TaskDue;
187
+ tags?: string[];
188
+ visibility: Visibility;
189
+ }
190
+ export interface TaskCompletedEvent extends BaseEvent {
191
+ type: 'task.completed';
192
+ taskId: string;
193
+ note?: string;
194
+ }
195
+ export interface TaskReopenedEvent extends BaseEvent {
196
+ type: 'task.reopened';
197
+ taskId: string;
198
+ }
199
+ export interface TaskAcceptedEvent extends BaseEvent {
200
+ type: 'task.accepted';
201
+ taskId: string;
202
+ /**
203
+ * An optional note explaining conditions, timing, or partial capability.
204
+ * "Accepted; I can send email but do not have iMessage access."
205
+ */
206
+ response?: string;
207
+ }
208
+ export interface TaskRejectedEvent extends BaseEvent {
209
+ type: 'task.rejected';
210
+ taskId: string;
211
+ /**
212
+ * Required. A refusal without a reason is the least useful event the system
213
+ * can record: the assigner learns only that the work will not happen, not
214
+ * whether to reassign it, wait, or change the request.
215
+ * "Rejected; this Hermes profile has no outbound messaging connection."
216
+ */
217
+ response: string;
218
+ }
219
+ export interface TaskCanceledEvent extends BaseEvent {
220
+ type: 'task.canceled';
221
+ taskId: string;
222
+ reason?: string;
223
+ }
224
+
225
+ /**
226
+ * A Todo is a private reminder an agent creates for itself.
227
+ *
228
+ * The distinction from a Task is the whole point of having both:
229
+ *
230
+ * Task — something another actor asks an agent to do
231
+ * Todo — something an agent privately reminds itself to do
232
+ *
233
+ * So a Todo has no assignee separate from its owner, and no accept/reject
234
+ * lifecycle: there is nobody to negotiate with. It is visible only to its
235
+ * owner, and no ordinary role reads another actor's Todos.
236
+ */
237
+ export interface TodoCreatedEvent extends BaseEvent {
238
+ type: 'todo.created';
239
+ title: string;
240
+ /** Private working detail. Never surfaced to another actor. */
241
+ details?: string;
242
+ priority: TaskPriority;
243
+ due?: TaskDue;
244
+ tags?: string[];
245
+ }
133
246
  export interface TodoUpdatedEvent extends BaseEvent {
134
247
  type: 'todo.updated';
135
248
  todoId: string;
136
249
  title: string;
137
- description?: string;
138
- priority: TodoPriority;
139
- due?: TodoDue;
250
+ details?: string;
251
+ priority: TaskPriority;
252
+ due?: TaskDue;
140
253
  tags?: string[];
141
- visibility: Visibility;
142
254
  }
143
255
  export interface TodoCompletedEvent extends BaseEvent {
144
256
  type: 'todo.completed';
@@ -149,20 +261,49 @@ export interface TodoReopenedEvent extends BaseEvent {
149
261
  type: 'todo.reopened';
150
262
  todoId: string;
151
263
  }
152
- export interface TodoAcceptedEvent extends BaseEvent {
153
- type: 'todo.accepted';
264
+ export interface TodoCanceledEvent extends BaseEvent {
265
+ type: 'todo.canceled';
154
266
  todoId: string;
267
+ reason?: string;
155
268
  }
156
- export interface TodoRejectedEvent extends BaseEvent {
157
- type: 'todo.rejected';
269
+ export interface TodoArchivedEvent extends BaseEvent {
270
+ type: 'todo.archived';
158
271
  todoId: string;
159
- reason?: string;
160
272
  }
161
- export interface TodoCanceledEvent extends BaseEvent {
162
- type: 'todo.canceled';
273
+
274
+ export interface TodoRecord {
275
+ event: TodoCreatedEvent;
276
+ update?: TodoUpdatedEvent;
277
+ terminal?: TodoCompletedEvent | TodoCanceledEvent | TodoArchivedEvent;
278
+ reopened?: TodoReopenedEvent;
279
+ current: {
280
+ title: string;
281
+ details?: string;
282
+ priority: TaskPriority;
283
+ due?: TaskDue;
284
+ tags: string[];
285
+ version: number;
286
+ };
287
+ status: 'open' | 'completed' | 'canceled' | 'archived';
288
+ }
289
+
290
+ export interface CreateTodoInput extends MutationInput {
291
+ title: string;
292
+ details?: string;
293
+ priority?: TaskPriority;
294
+ due?: TaskDue;
295
+ tags?: string[];
296
+ }
297
+ export interface UpdateTodoInput extends MutationInput {
163
298
  todoId: string;
164
- reason?: string;
299
+ expectedVersion: number;
300
+ title?: string;
301
+ details?: string;
302
+ priority?: TaskPriority;
303
+ due?: TaskDue | null;
304
+ tags?: string[];
165
305
  }
306
+ export type CreateTodoResult = MutationResult<TodoRecord>;
166
307
 
167
308
  export interface AgentCreatedEvent extends BaseEvent {
168
309
  type: 'agent.created';
@@ -184,13 +325,19 @@ export type SynomemEvent =
184
325
  | NoteCreatedEvent
185
326
  | NoteRevisedEvent
186
327
  | NoteArchivedEvent
328
+ | TaskCreatedEvent
329
+ | TaskUpdatedEvent
330
+ | TaskCompletedEvent
331
+ | TaskReopenedEvent
332
+ | TaskAcceptedEvent
333
+ | TaskRejectedEvent
334
+ | TaskCanceledEvent
187
335
  | TodoCreatedEvent
188
336
  | TodoUpdatedEvent
189
337
  | TodoCompletedEvent
190
338
  | TodoReopenedEvent
191
- | TodoAcceptedEvent
192
- | TodoRejectedEvent
193
339
  | TodoCanceledEvent
340
+ | TodoArchivedEvent
194
341
  | AgentCreatedEvent
195
342
  | AgentUpdatedEvent;
196
343
 
@@ -216,23 +363,41 @@ export interface NoteRecord {
216
363
  current: { title: string; body: string; tags: string[]; visibility: Visibility; version: number };
217
364
  status: 'active' | 'archived';
218
365
  }
219
- export interface TodoRecord {
220
- event: TodoCreatedEvent;
221
- update?: TodoUpdatedEvent;
222
- terminal?: TodoCompletedEvent | TodoRejectedEvent | TodoCanceledEvent;
223
- reopened?: TodoReopenedEvent;
366
+ /**
367
+ * One entry in a task's response history.
368
+ *
369
+ * The plan calls for response notes to be part of the task's durable event
370
+ * history rather than private Notes, and for reads to expose that history. It
371
+ * is a list rather than a single field because a task can be rejected, reopened
372
+ * and answered again — and because a later general `task.respond` event for
373
+ * progress updates should extend this without changing its shape.
374
+ */
375
+ export interface TaskResponse {
376
+ kind: 'accepted' | 'rejected';
377
+ response?: string;
378
+ actor: ActorIdentity;
379
+ at: string;
380
+ }
381
+
382
+ export interface TaskRecord {
383
+ event: TaskCreatedEvent;
384
+ update?: TaskUpdatedEvent;
385
+ terminal?: TaskCompletedEvent | TaskRejectedEvent | TaskCanceledEvent;
386
+ reopened?: TaskReopenedEvent;
387
+ /** Every accept/reject answer, oldest first. */
388
+ responses: TaskResponse[];
224
389
  current: {
225
390
  title: string;
226
391
  description?: string;
227
- priority: TodoPriority;
228
- due?: TodoDue;
392
+ priority: TaskPriority;
393
+ due?: TaskDue;
229
394
  tags: string[];
230
395
  visibility: Visibility;
231
396
  version: number;
232
397
  };
233
398
  status: 'assigned' | 'open' | 'completed' | 'rejected' | 'canceled';
234
399
  }
235
- export type ItemRecord = KudosRecord | MemoRecord | NoteRecord | TodoRecord;
400
+ export type ItemRecord = KudosRecord | MemoRecord | NoteRecord | TaskRecord | TodoRecord;
236
401
 
237
402
  export interface ItemSummary {
238
403
  id: string;
@@ -273,6 +438,22 @@ export interface ItemListInput extends PaginationInput {
273
438
  to?: string;
274
439
  /** Limit results to actionable inbox states; intended for the participant's own inbox. */
275
440
  pending?: boolean;
441
+ /**
442
+ * Limit results to items still waiting for somebody to answer: tasks awaiting
443
+ * acceptance, unread memos, unacknowledged kudos.
444
+ *
445
+ * Narrower than `pending`, which also counts accepted work in progress. These
446
+ * are query states derived from durable events — they do not prove an agent
447
+ * was online, saw a notification, or possessed a claimed capability.
448
+ */
449
+ awaitingResponse?: boolean;
450
+ /** With `awaitingResponse`, only items created at or before this instant. */
451
+ awaitingSince?: string;
452
+ /**
453
+ * Items whose deadline has passed at this instant and which are still open.
454
+ * A date-only deadline counts as the end of that day.
455
+ */
456
+ overdueAsOf?: string;
276
457
  }
277
458
  export interface KudosListInput extends PaginationInput {
278
459
  recipientAgentId?: string;
@@ -361,22 +542,22 @@ export interface ReviseNoteInput extends MutationInput {
361
542
  body?: string;
362
543
  tags?: string[];
363
544
  }
364
- export interface CreateTodoInput extends MutationInput {
545
+ export interface CreateTaskInput extends MutationInput {
365
546
  assigneeAgentId?: string;
366
547
  title: string;
367
548
  description?: string;
368
- priority?: TodoPriority;
369
- due?: TodoDue;
549
+ priority?: TaskPriority;
550
+ due?: TaskDue;
370
551
  tags?: string[];
371
552
  visibility?: Visibility;
372
553
  }
373
- export interface UpdateTodoInput extends MutationInput {
374
- todoId: string;
554
+ export interface UpdateTaskInput extends MutationInput {
555
+ taskId: string;
375
556
  expectedVersion: number;
376
557
  title?: string;
377
558
  description?: string;
378
- priority?: TodoPriority;
379
- due?: TodoDue | null;
559
+ priority?: TaskPriority;
560
+ due?: TaskDue | null;
380
561
  tags?: string[];
381
562
  visibility?: Visibility;
382
563
  }
@@ -388,7 +569,15 @@ export interface MutationResult<T> {
388
569
  export type GiveKudosResult = MutationResult<KudosRecord>;
389
570
  export type SendMemoResult = MutationResult<MemoRecord>;
390
571
  export type CreateNoteResult = MutationResult<NoteRecord>;
391
- export type CreateTodoResult = MutationResult<TodoRecord>;
572
+ export type CreateTaskResult = MutationResult<TaskRecord>;
573
+
574
+ export interface BindRuntimeInput {
575
+ agentId: string;
576
+ runtime: string;
577
+ profile?: string;
578
+ installationId?: string;
579
+ capabilities?: Record<string, JsonValue>;
580
+ }
392
581
 
393
582
  export interface CreateAgentInput {
394
583
  id: string;
@@ -432,14 +621,14 @@ export interface SynomemConfig {
432
621
  workspaceId: string;
433
622
  defaultVisibility: Visibility;
434
623
  allowSelfAwards: boolean;
435
- allowCrossAgentTodos: boolean;
624
+ allowCrossAgentTasks: boolean;
436
625
  allowAgentCreationViaMcp: boolean;
437
626
  allowRebuildViaMcp: boolean;
438
627
  includePrivateInStats: boolean;
439
628
  projection: {
440
629
  writeWinsMarkdown: boolean;
441
630
  writeMemoryMarkdown: boolean;
442
- writeTodosMarkdown: boolean;
631
+ writeTasksMarkdown: boolean;
443
632
  writeInboxEntries: boolean;
444
633
  };
445
634
  }