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.
- package/ARCHITECTURE.md +2 -2
- package/CHANGELOG.md +37 -1
- package/README.md +28 -15
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +311 -70
- package/dist/cli.js.map +1 -1
- package/dist/client.d.ts +96 -17
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +333 -76
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +2 -2
- package/dist/config.js +8 -8
- package/dist/import.d.ts +207 -13
- package/dist/import.d.ts.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +156 -31
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp-server.js +54 -8
- package/dist/mcp-server.js.map +1 -1
- package/dist/ports/repository.d.ts +18 -1
- package/dist/ports/repository.d.ts.map +1 -1
- package/dist/projections.d.ts +18 -1
- package/dist/projections.d.ts.map +1 -1
- package/dist/projections.js +137 -44
- package/dist/projections.js.map +1 -1
- package/dist/remote.d.ts +57 -9
- package/dist/remote.d.ts.map +1 -1
- package/dist/remote.js +43 -2
- package/dist/remote.js.map +1 -1
- package/dist/schemas.d.ts +302 -21
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +142 -26
- package/dist/schemas.js.map +1 -1
- package/dist/service.d.ts +57 -10
- package/dist/service.d.ts.map +1 -1
- package/dist/skill-install.d.ts +8 -2
- package/dist/skill-install.d.ts.map +1 -1
- package/dist/skill-install.js +6 -11
- package/dist/skill-install.js.map +1 -1
- package/dist/storage.d.ts +41 -1
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +254 -36
- package/dist/storage.js.map +1 -1
- package/dist/types.d.ts +213 -38
- package/dist/types.d.ts.map +1 -1
- package/docs/cli.md +53 -20
- package/docs/examples.md +4 -4
- package/docs/mcp.md +12 -4
- package/docs/skill.md +10 -7
- package/docs/storage-format.md +4 -4
- package/openapi/synomem-v1.yaml +24 -24
- package/package.json +1 -1
- package/skills/synomem/SKILL.md +24 -8
- package/skills/synomem/agents/openai.yaml +1 -1
- package/skills/synomem/references/examples.md +1 -1
- package/src/cli.ts +572 -173
- package/src/client.ts +391 -79
- package/src/config.ts +8 -8
- package/src/index.ts +11 -1
- package/src/mcp/index.ts +189 -30
- package/src/mcp-server.ts +58 -8
- package/src/ports/repository.ts +16 -0
- package/src/projections.ts +139 -44
- package/src/remote.ts +118 -8
- package/src/schemas.ts +147 -26
- package/src/service.ts +59 -7
- package/src/skill-install.ts +14 -17
- package/src/storage.ts +326 -34
- 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
|
|
119
|
-
export type
|
|
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
|
|
122
|
-
type: '
|
|
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:
|
|
128
|
-
due?:
|
|
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
|
-
|
|
138
|
-
priority:
|
|
139
|
-
due?:
|
|
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
|
|
153
|
-
type: 'todo.
|
|
264
|
+
export interface TodoCanceledEvent extends BaseEvent {
|
|
265
|
+
type: 'todo.canceled';
|
|
154
266
|
todoId: string;
|
|
267
|
+
reason?: string;
|
|
155
268
|
}
|
|
156
|
-
export interface
|
|
157
|
-
type: 'todo.
|
|
269
|
+
export interface TodoArchivedEvent extends BaseEvent {
|
|
270
|
+
type: 'todo.archived';
|
|
158
271
|
todoId: string;
|
|
159
|
-
reason?: string;
|
|
160
272
|
}
|
|
161
|
-
|
|
162
|
-
|
|
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
|
-
|
|
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
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
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:
|
|
228
|
-
due?:
|
|
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
|
|
545
|
+
export interface CreateTaskInput extends MutationInput {
|
|
365
546
|
assigneeAgentId?: string;
|
|
366
547
|
title: string;
|
|
367
548
|
description?: string;
|
|
368
|
-
priority?:
|
|
369
|
-
due?:
|
|
549
|
+
priority?: TaskPriority;
|
|
550
|
+
due?: TaskDue;
|
|
370
551
|
tags?: string[];
|
|
371
552
|
visibility?: Visibility;
|
|
372
553
|
}
|
|
373
|
-
export interface
|
|
374
|
-
|
|
554
|
+
export interface UpdateTaskInput extends MutationInput {
|
|
555
|
+
taskId: string;
|
|
375
556
|
expectedVersion: number;
|
|
376
557
|
title?: string;
|
|
377
558
|
description?: string;
|
|
378
|
-
priority?:
|
|
379
|
-
due?:
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
631
|
+
writeTasksMarkdown: boolean;
|
|
443
632
|
writeInboxEntries: boolean;
|
|
444
633
|
};
|
|
445
634
|
}
|