@pellux/goodvibes-sdk 1.1.0 → 1.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 (32) hide show
  1. package/dist/contracts/artifacts/operator-contract.json +1361 -57
  2. package/dist/platform/control-plane/method-catalog-runtime.d.ts.map +1 -1
  3. package/dist/platform/control-plane/method-catalog-runtime.js +95 -1
  4. package/dist/platform/control-plane/operator-contract-schemas-runtime.d.ts +7 -0
  5. package/dist/platform/control-plane/operator-contract-schemas-runtime.d.ts.map +1 -1
  6. package/dist/platform/control-plane/operator-contract-schemas-runtime.js +38 -0
  7. package/dist/platform/runtime/memory-spine/client.d.ts +125 -12
  8. package/dist/platform/runtime/memory-spine/client.d.ts.map +1 -1
  9. package/dist/platform/runtime/memory-spine/client.js +109 -1
  10. package/dist/platform/runtime/memory-spine/index.d.ts +7 -1
  11. package/dist/platform/runtime/memory-spine/index.d.ts.map +1 -1
  12. package/dist/platform/runtime/memory-spine/index.js +6 -0
  13. package/dist/platform/runtime/memory-spine/recall-snapshot.d.ts +74 -0
  14. package/dist/platform/runtime/memory-spine/recall-snapshot.d.ts.map +1 -0
  15. package/dist/platform/runtime/memory-spine/recall-snapshot.js +74 -0
  16. package/dist/platform/version.js +1 -1
  17. package/dist/platform/voice/index.d.ts +2 -0
  18. package/dist/platform/voice/index.d.ts.map +1 -1
  19. package/dist/platform/voice/index.js +3 -0
  20. package/dist/platform/voice/spoken-turn/audio-sink.d.ts +111 -0
  21. package/dist/platform/voice/spoken-turn/audio-sink.d.ts.map +1 -0
  22. package/dist/platform/voice/spoken-turn/audio-sink.js +1 -0
  23. package/dist/platform/voice/spoken-turn/controller.d.ts +117 -0
  24. package/dist/platform/voice/spoken-turn/controller.d.ts.map +1 -0
  25. package/dist/platform/voice/spoken-turn/controller.js +448 -0
  26. package/dist/platform/voice/spoken-turn/index.d.ts +16 -0
  27. package/dist/platform/voice/spoken-turn/index.d.ts.map +1 -0
  28. package/dist/platform/voice/spoken-turn/index.js +12 -0
  29. package/dist/platform/voice/spoken-turn/text-chunker.d.ts +33 -0
  30. package/dist/platform/voice/spoken-turn/text-chunker.d.ts.map +1 -0
  31. package/dist/platform/voice/spoken-turn/text-chunker.js +97 -0
  32. package/package.json +9 -9
@@ -1 +1 @@
1
- {"version":3,"file":"method-catalog-runtime.d.ts","sourceRoot":"","sources":["../../../src/platform/control-plane/method-catalog-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AA6H1E,eAAO,MAAM,sCAAsC,EAAE,SAAS,uBAAuB,EA2cpF,CAAC"}
1
+ {"version":3,"file":"method-catalog-runtime.d.ts","sourceRoot":"","sources":["../../../src/platform/control-plane/method-catalog-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAkJ1E,eAAO,MAAM,sCAAsC,EAAE,SAAS,uBAAuB,EA2hBpF,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import { EMPTY_OBJECT_SCHEMA, BOOLEAN_SCHEMA, STRING_SCHEMA, NUMBER_SCHEMA, objectSchema, listOutputSchema, entityOutputSchema, bodyEnvelopeSchema, methodDescriptor, runtimeEventId, arraySchema, } from './method-catalog-shared.js';
2
2
  import { enumSchema, nullableSchema } from './operator-contract-schemas-shared.js';
3
- import { CONTINUITY_SNAPSHOT_SCHEMA, DISTRIBUTED_NODE_HOST_CONTRACT_SCHEMA, HEALTH_SNAPSHOT_SCHEMA, INTELLIGENCE_SNAPSHOT_SCHEMA, MEMORY_DOCTOR_REPORT_SCHEMA, MEMORY_VECTOR_STATS_SCHEMA, MEMORY_CLASS_SCHEMA, MEMORY_SCOPE_SCHEMA, MEMORY_REVIEW_STATE_SCHEMA, MEMORY_PROVENANCE_KIND_SCHEMA, MEMORY_PROVENANCE_LINK_SCHEMA, MEMORY_RECORD_SCHEMA, MEMORY_RECORD_SEARCH_OUTPUT_SCHEMA, MEMORY_RECORD_DELETE_OUTPUT_SCHEMA, PROVIDER_ACCOUNT_SNAPSHOT_SCHEMA, PROVIDER_RUNTIME_SNAPSHOT_SCHEMA, PROVIDER_USAGE_SNAPSHOT_SCHEMA, REMOTE_PAIR_APPROVAL_OUTPUT_SCHEMA, REMOTE_PAIR_REQUEST_OUTPUT_SCHEMA, REMOTE_PAIR_REQUESTS_OUTPUT_SCHEMA, REMOTE_PEERS_OUTPUT_SCHEMA, REMOTE_PAIR_REQUEST_ACTION_INPUT_SCHEMA, REMOTE_PEER_DISCONNECT_INPUT_SCHEMA, REMOTE_PEER_INVOKE_INPUT_SCHEMA, REMOTE_PEER_INVOKE_OUTPUT_SCHEMA, REMOTE_PEER_OUTPUT_SCHEMA, REMOTE_PEER_TOKEN_REVOKE_INPUT_SCHEMA, REMOTE_PEER_TOKEN_ROTATE_INPUT_SCHEMA, REMOTE_PEER_TOKEN_ROTATE_OUTPUT_SCHEMA, REMOTE_SNAPSHOT_SCHEMA, REMOTE_WORK_LIST_OUTPUT_SCHEMA, REMOTE_WORK_CANCEL_INPUT_SCHEMA, REMOTE_WORK_OUTPUT_SCHEMA, SECURITY_SETTINGS_REPORT_SCHEMA, SETTINGS_SNAPSHOT_SCHEMA, WORKTREE_SNAPSHOT_SCHEMA, } from './operator-contract-schemas.js';
3
+ import { CONTINUITY_SNAPSHOT_SCHEMA, DISTRIBUTED_NODE_HOST_CONTRACT_SCHEMA, HEALTH_SNAPSHOT_SCHEMA, INTELLIGENCE_SNAPSHOT_SCHEMA, MEMORY_DOCTOR_REPORT_SCHEMA, MEMORY_VECTOR_STATS_SCHEMA, MEMORY_CLASS_SCHEMA, MEMORY_SCOPE_SCHEMA, MEMORY_REVIEW_STATE_SCHEMA, MEMORY_PROVENANCE_KIND_SCHEMA, MEMORY_PROVENANCE_LINK_SCHEMA, MEMORY_RECORD_SCHEMA, MEMORY_RECORD_SEARCH_OUTPUT_SCHEMA, MEMORY_RECORD_DELETE_OUTPUT_SCHEMA, MEMORY_LINK_SCHEMA, MEMORY_BUNDLE_SCHEMA, MEMORY_IMPORT_RESULT_SCHEMA, MEMORY_RECORD_LIST_OUTPUT_SCHEMA, MEMORY_RECORD_SEMANTIC_OUTPUT_SCHEMA, MEMORY_RECORD_LINKS_OUTPUT_SCHEMA, PROVIDER_ACCOUNT_SNAPSHOT_SCHEMA, PROVIDER_RUNTIME_SNAPSHOT_SCHEMA, PROVIDER_USAGE_SNAPSHOT_SCHEMA, REMOTE_PAIR_APPROVAL_OUTPUT_SCHEMA, REMOTE_PAIR_REQUEST_OUTPUT_SCHEMA, REMOTE_PAIR_REQUESTS_OUTPUT_SCHEMA, REMOTE_PEERS_OUTPUT_SCHEMA, REMOTE_PAIR_REQUEST_ACTION_INPUT_SCHEMA, REMOTE_PEER_DISCONNECT_INPUT_SCHEMA, REMOTE_PEER_INVOKE_INPUT_SCHEMA, REMOTE_PEER_INVOKE_OUTPUT_SCHEMA, REMOTE_PEER_OUTPUT_SCHEMA, REMOTE_PEER_TOKEN_REVOKE_INPUT_SCHEMA, REMOTE_PEER_TOKEN_ROTATE_INPUT_SCHEMA, REMOTE_PEER_TOKEN_ROTATE_OUTPUT_SCHEMA, REMOTE_SNAPSHOT_SCHEMA, REMOTE_WORK_LIST_OUTPUT_SCHEMA, REMOTE_WORK_CANCEL_INPUT_SCHEMA, REMOTE_WORK_OUTPUT_SCHEMA, SECURITY_SETTINGS_REPORT_SCHEMA, SETTINGS_SNAPSHOT_SCHEMA, WORKTREE_SNAPSHOT_SCHEMA, } from './operator-contract-schemas.js';
4
4
  const MCP_SCOPE_SCHEMA = enumSchema(['project', 'global']);
5
5
  const MCP_SERVER_CONFIG_SCHEMA = objectSchema({
6
6
  name: STRING_SCHEMA,
@@ -71,6 +71,20 @@ const MCP_TOOL_SCHEMA = objectSchema({
71
71
  const MCP_TOOLS_RESPONSE_SCHEMA = objectSchema({
72
72
  tools: arraySchema(MCP_TOOL_SCHEMA),
73
73
  }, ['tools']);
74
+ /** The shared memory search-filter fields (no `recall` — that is search-only). Reused by list / search-semantic / export. */
75
+ const MEMORY_SEARCH_FILTER_FIELDS = {
76
+ scope: MEMORY_SCOPE_SCHEMA,
77
+ cls: MEMORY_CLASS_SCHEMA,
78
+ tags: arraySchema(STRING_SCHEMA),
79
+ query: STRING_SCHEMA,
80
+ semantic: BOOLEAN_SCHEMA,
81
+ since: NUMBER_SCHEMA,
82
+ reviewState: arraySchema(MEMORY_REVIEW_STATE_SCHEMA),
83
+ minConfidence: NUMBER_SCHEMA,
84
+ provenanceKinds: arraySchema(MEMORY_PROVENANCE_KIND_SCHEMA),
85
+ staleOnly: BOOLEAN_SCHEMA,
86
+ limit: NUMBER_SCHEMA,
87
+ };
74
88
  export const builtinGatewayRuntimeMethodDescriptors = [
75
89
  methodDescriptor({
76
90
  id: 'mcp.config.get',
@@ -515,6 +529,86 @@ export const builtinGatewayRuntimeMethodDescriptors = [
515
529
  inputSchema: objectSchema({ id: STRING_SCHEMA }, ['id']),
516
530
  outputSchema: MEMORY_RECORD_DELETE_OUTPUT_SCHEMA,
517
531
  }),
532
+ methodDescriptor({
533
+ id: 'memory.records.list',
534
+ title: 'List Memory Records',
535
+ description: 'Bulk read from the canonical store: a literal (non-semantic) search returning the matching records as a plain array. An empty filter returns every record (getAll). This is the read a client surface uses instead of opening the store file for its browse/list and knowledge-injection paths.',
536
+ category: 'memory',
537
+ scopes: ['read:memory'],
538
+ http: { method: 'POST', path: '/api/memory/records/list' },
539
+ inputSchema: bodyEnvelopeSchema({ ...MEMORY_SEARCH_FILTER_FIELDS }),
540
+ outputSchema: MEMORY_RECORD_LIST_OUTPUT_SCHEMA,
541
+ }),
542
+ methodDescriptor({
543
+ id: 'memory.records.search-semantic',
544
+ title: 'Semantic Search Memory Records',
545
+ description: 'Rank records by semantic similarity against the query, returning scored results (distance, similarity, score). When the query has no vector match the store falls back to a lexical ranking rather than a silent empty. distance is null for a fallback (non-vector) result. Read-only against the daemon\'s canonical index.',
546
+ category: 'memory',
547
+ scopes: ['read:memory'],
548
+ http: { method: 'POST', path: '/api/memory/records/search-semantic' },
549
+ inputSchema: bodyEnvelopeSchema({ ...MEMORY_SEARCH_FILTER_FIELDS }),
550
+ outputSchema: MEMORY_RECORD_SEMANTIC_OUTPUT_SCHEMA,
551
+ }),
552
+ methodDescriptor({
553
+ id: 'memory.records.export',
554
+ title: 'Export Memory Bundle',
555
+ description: 'Export a no-loss bundle (records + links) for the given filter from the canonical store. The bundle round-trips through import id-keyed, so it is the wire form of the cross-surface fold/reconcile seam. Read-only.',
556
+ category: 'memory',
557
+ scopes: ['read:memory'],
558
+ http: { method: 'POST', path: '/api/memory/records/export' },
559
+ inputSchema: bodyEnvelopeSchema({ ...MEMORY_SEARCH_FILTER_FIELDS }),
560
+ outputSchema: entityOutputSchema('bundle', MEMORY_BUNDLE_SCHEMA),
561
+ }),
562
+ methodDescriptor({
563
+ id: 'memory.records.import',
564
+ title: 'Import Memory Bundle',
565
+ description: 'Import a bundle into the canonical store as an id-keyed union: an id already present is left untouched (counted skipped), a new id is added; a link is added only when both its endpoints exist. Never overwrites, never deletes, idempotent on re-run. The daemon is the single writer, so a client imports here instead of writing the store file.',
566
+ category: 'memory',
567
+ scopes: ['write:memory'],
568
+ http: { method: 'POST', path: '/api/memory/records/import' },
569
+ inputSchema: bodyEnvelopeSchema({ bundle: MEMORY_BUNDLE_SCHEMA }, ['bundle']),
570
+ outputSchema: entityOutputSchema('result', MEMORY_IMPORT_RESULT_SCHEMA),
571
+ }),
572
+ methodDescriptor({
573
+ id: 'memory.records.update',
574
+ title: 'Update Memory Record',
575
+ description: 'Edit a record\'s content fields (scope, summary, detail, tags) in the canonical store. This is distinct from the review update: it changes the record itself — e.g. moving scope project→team promotes a record to the shared surface. Returns 404 when no record with that id exists.',
576
+ category: 'memory',
577
+ scopes: ['write:memory'],
578
+ http: { method: 'POST', path: '/api/memory/records/{id}/update' },
579
+ inputSchema: bodyEnvelopeSchema({
580
+ id: STRING_SCHEMA,
581
+ scope: MEMORY_SCOPE_SCHEMA,
582
+ summary: STRING_SCHEMA,
583
+ detail: STRING_SCHEMA,
584
+ tags: arraySchema(STRING_SCHEMA),
585
+ }, ['id']),
586
+ outputSchema: entityOutputSchema('record', MEMORY_RECORD_SCHEMA),
587
+ }),
588
+ methodDescriptor({
589
+ id: 'memory.records.links.list',
590
+ title: 'List Memory Record Links',
591
+ description: 'Return every link where the record is the source or the target. Returns 404 when no record with that id exists — an honest not-found, distinct from a record that exists but has no links (an empty array).',
592
+ category: 'memory',
593
+ scopes: ['read:memory'],
594
+ http: { method: 'GET', path: '/api/memory/records/{id}/links' },
595
+ inputSchema: objectSchema({ id: STRING_SCHEMA }, ['id']),
596
+ outputSchema: MEMORY_RECORD_LINKS_OUTPUT_SCHEMA,
597
+ }),
598
+ methodDescriptor({
599
+ id: 'memory.records.links.add',
600
+ title: 'Link Memory Records',
601
+ description: 'Create a directed relation (e.g. "supersedes", "caused") from the path record to a target record. Returns 404 when either endpoint does not exist — never a 200 that pretends a link was made between records that do not both exist.',
602
+ category: 'memory',
603
+ scopes: ['write:memory'],
604
+ http: { method: 'POST', path: '/api/memory/records/{id}/links' },
605
+ inputSchema: bodyEnvelopeSchema({
606
+ id: STRING_SCHEMA,
607
+ toId: STRING_SCHEMA,
608
+ relation: STRING_SCHEMA,
609
+ }, ['id', 'toId', 'relation']),
610
+ outputSchema: entityOutputSchema('link', MEMORY_LINK_SCHEMA),
611
+ }),
518
612
  methodDescriptor({
519
613
  id: 'scheduler.capacity',
520
614
  title: 'Scheduler Capacity',
@@ -73,4 +73,11 @@ export declare const MEMORY_PROVENANCE_LINK_SCHEMA: Record<string, unknown>;
73
73
  export declare const MEMORY_RECORD_SCHEMA: Record<string, unknown>;
74
74
  export declare const MEMORY_RECORD_SEARCH_OUTPUT_SCHEMA: Record<string, unknown>;
75
75
  export declare const MEMORY_RECORD_DELETE_OUTPUT_SCHEMA: Record<string, unknown>;
76
+ export declare const MEMORY_LINK_SCHEMA: Record<string, unknown>;
77
+ export declare const MEMORY_SEMANTIC_RESULT_SCHEMA: Record<string, unknown>;
78
+ export declare const MEMORY_BUNDLE_SCHEMA: Record<string, unknown>;
79
+ export declare const MEMORY_IMPORT_RESULT_SCHEMA: Record<string, unknown>;
80
+ export declare const MEMORY_RECORD_LIST_OUTPUT_SCHEMA: Record<string, unknown>;
81
+ export declare const MEMORY_RECORD_SEMANTIC_OUTPUT_SCHEMA: Record<string, unknown>;
82
+ export declare const MEMORY_RECORD_LINKS_OUTPUT_SCHEMA: Record<string, unknown>;
76
83
  //# sourceMappingURL=operator-contract-schemas-runtime.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"operator-contract-schemas-runtime.d.ts","sourceRoot":"","sources":["../../../src/platform/control-plane/operator-contract-schemas-runtime.ts"],"names":[],"mappings":"AAmCA;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,+BAA+B,EAAyB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AA6B7F,eAAO,MAAM,iCAAiC,yBAQA,CAAC;AAE/C;;;;;GAKG;AACH,eAAO,MAAM,oCAAoC,yBAOe,CAAC;AAEjE,eAAO,MAAM,6BAA6B,yBAasB,CAAC;AAEjE,eAAO,MAAM,4BAA4B,yBAuBqI,CAAC;AAE/K,eAAO,MAAM,6BAA6B,yBAYsF,CAAC;AAEjI,eAAO,MAAM,6BAA6B,yBAO4B,CAAC;AAEvE,eAAO,MAAM,2CAA2C,yBAG7B,CAAC;AAE5B,eAAO,MAAM,mCAAmC,yBAOtB,CAAC;AAE3B,eAAO,MAAM,mCAAmC,yBAGnB,CAAC;AAE9B,eAAO,MAAM,oCAAoC,yBAkB/C,CAAC;AAEH,eAAO,MAAM,kCAAkC,yBAqB0D,CAAC;AAE1G,eAAO,MAAM,uBAAuB,yBAWoE,CAAC;AAEzG,eAAO,MAAM,8BAA8B,yBAOjB,CAAC;AAE3B,eAAO,MAAM,mCAAmC,yBAGrB,CAAC;AAE5B,eAAO,MAAM,iCAAiC,yBAGrB,CAAC;AAE1B,eAAO,MAAM,mCAAmC,yBAEjC,CAAC;AAEhB;;;;;;GAMG;AACH,eAAO,MAAM,qCAAqC,yBAIvB,CAAC;AAE5B,eAAO,MAAM,+CAA+C,yBAIlB,CAAC;AAE3C,eAAO,MAAM,2CAA2C,yBAMF,CAAC;AAEvD,eAAO,MAAM,0CAA0C;;CAK7C,CAAC;AAUX,eAAO,MAAM,mBAAmB,yBAqByD,CAAC;AAE1F,eAAO,MAAM,oBAAoB,yBAsBsB,CAAC;AAExD,eAAO,MAAM,wBAAwB,yBAgBO,CAAC;AAE7C,eAAO,MAAM,yBAAyB,yBASc,CAAC;AAErD,eAAO,MAAM,kBAAkB,yBAEnB,CAAC;AAEb,eAAO,MAAM,yBAAyB,yBAIM,CAAC;AAE7C,eAAO,MAAM,yBAAyB,yBAUiE,CAAC;AAWxG,eAAO,MAAM,6BAA6B,yBAgB8C,CAAC;AAEzF,eAAO,MAAM,wBAAwB,yBASuG,CAAC;AAE7I,eAAO,MAAM,4BAA4B,yBAIU,CAAC;AAOpD,eAAO,MAAM,6BAA6B,yBAKS,CAAC;AAEpD,eAAO,MAAM,6BAA6B,yBAE1B,CAAC;AA0EjB,eAAO,MAAM,gCAAgC,yBAMkB,CAAC;AAEhE,eAAO,MAAM,8BAA8B,yBAcqD,CAAC;AAqEjG,eAAO,MAAM,gCAAgC,yBAKmB,CAAC;AAEjE,eAAO,MAAM,sBAAsB,yBAcyF,CAAC;AAE7H,eAAO,MAAM,4BAA4B,yBASyG,CAAC;AAqBnJ,eAAO,MAAM,0BAA0B,yBAUyH,CAAC;AAEjK,eAAO,MAAM,2BAA2B,yBAIC,CAAC;AAG1C,eAAO,MAAM,mBAAmB,yBAA6C,CAAC;AAC9E,eAAO,MAAM,mBAAmB,yBAE9B,CAAC;AACH,eAAO,MAAM,0BAA0B,yBAA6D,CAAC;AACrG,eAAO,MAAM,6BAA6B,yBAA2D,CAAC;AAEtG,eAAO,MAAM,6BAA6B,yBAIvB,CAAC;AAEpB,eAAO,MAAM,oBAAoB,yBAeiH,CAAC;AAEnJ,eAAO,MAAM,kCAAkC,yBAUiI,CAAC;AAEjL,eAAO,MAAM,kCAAkC,yBAG1B,CAAC"}
1
+ {"version":3,"file":"operator-contract-schemas-runtime.d.ts","sourceRoot":"","sources":["../../../src/platform/control-plane/operator-contract-schemas-runtime.ts"],"names":[],"mappings":"AAmCA;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,+BAA+B,EAAyB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AA6B7F,eAAO,MAAM,iCAAiC,yBAQA,CAAC;AAE/C;;;;;GAKG;AACH,eAAO,MAAM,oCAAoC,yBAOe,CAAC;AAEjE,eAAO,MAAM,6BAA6B,yBAasB,CAAC;AAEjE,eAAO,MAAM,4BAA4B,yBAuBqI,CAAC;AAE/K,eAAO,MAAM,6BAA6B,yBAYsF,CAAC;AAEjI,eAAO,MAAM,6BAA6B,yBAO4B,CAAC;AAEvE,eAAO,MAAM,2CAA2C,yBAG7B,CAAC;AAE5B,eAAO,MAAM,mCAAmC,yBAOtB,CAAC;AAE3B,eAAO,MAAM,mCAAmC,yBAGnB,CAAC;AAE9B,eAAO,MAAM,oCAAoC,yBAkB/C,CAAC;AAEH,eAAO,MAAM,kCAAkC,yBAqB0D,CAAC;AAE1G,eAAO,MAAM,uBAAuB,yBAWoE,CAAC;AAEzG,eAAO,MAAM,8BAA8B,yBAOjB,CAAC;AAE3B,eAAO,MAAM,mCAAmC,yBAGrB,CAAC;AAE5B,eAAO,MAAM,iCAAiC,yBAGrB,CAAC;AAE1B,eAAO,MAAM,mCAAmC,yBAEjC,CAAC;AAEhB;;;;;;GAMG;AACH,eAAO,MAAM,qCAAqC,yBAIvB,CAAC;AAE5B,eAAO,MAAM,+CAA+C,yBAIlB,CAAC;AAE3C,eAAO,MAAM,2CAA2C,yBAMF,CAAC;AAEvD,eAAO,MAAM,0CAA0C;;CAK7C,CAAC;AAUX,eAAO,MAAM,mBAAmB,yBAqByD,CAAC;AAE1F,eAAO,MAAM,oBAAoB,yBAsBsB,CAAC;AAExD,eAAO,MAAM,wBAAwB,yBAgBO,CAAC;AAE7C,eAAO,MAAM,yBAAyB,yBASc,CAAC;AAErD,eAAO,MAAM,kBAAkB,yBAEnB,CAAC;AAEb,eAAO,MAAM,yBAAyB,yBAIM,CAAC;AAE7C,eAAO,MAAM,yBAAyB,yBAUiE,CAAC;AAWxG,eAAO,MAAM,6BAA6B,yBAgB8C,CAAC;AAEzF,eAAO,MAAM,wBAAwB,yBASuG,CAAC;AAE7I,eAAO,MAAM,4BAA4B,yBAIU,CAAC;AAOpD,eAAO,MAAM,6BAA6B,yBAKS,CAAC;AAEpD,eAAO,MAAM,6BAA6B,yBAE1B,CAAC;AA0EjB,eAAO,MAAM,gCAAgC,yBAMkB,CAAC;AAEhE,eAAO,MAAM,8BAA8B,yBAcqD,CAAC;AAqEjG,eAAO,MAAM,gCAAgC,yBAKmB,CAAC;AAEjE,eAAO,MAAM,sBAAsB,yBAcyF,CAAC;AAE7H,eAAO,MAAM,4BAA4B,yBASyG,CAAC;AAqBnJ,eAAO,MAAM,0BAA0B,yBAUyH,CAAC;AAEjK,eAAO,MAAM,2BAA2B,yBAIC,CAAC;AAG1C,eAAO,MAAM,mBAAmB,yBAA6C,CAAC;AAC9E,eAAO,MAAM,mBAAmB,yBAE9B,CAAC;AACH,eAAO,MAAM,0BAA0B,yBAA6D,CAAC;AACrG,eAAO,MAAM,6BAA6B,yBAA2D,CAAC;AAEtG,eAAO,MAAM,6BAA6B,yBAIvB,CAAC;AAEpB,eAAO,MAAM,oBAAoB,yBAeiH,CAAC;AAEnJ,eAAO,MAAM,kCAAkC,yBAUiI,CAAC;AAEjL,eAAO,MAAM,kCAAkC,yBAG1B,CAAC;AAItB,eAAO,MAAM,kBAAkB,yBAKgB,CAAC;AAIhD,eAAO,MAAM,6BAA6B,yBAKL,CAAC;AAEtC,eAAO,MAAM,oBAAoB,yBAQ2D,CAAC;AAE7F,eAAO,MAAM,2BAA2B,yBAIkB,CAAC;AAE3D,eAAO,MAAM,gCAAgC,yBAE9B,CAAC;AAEhB,eAAO,MAAM,oCAAoC,yBAElC,CAAC;AAEhB,eAAO,MAAM,iCAAiC,yBAEjC,CAAC"}
@@ -663,3 +663,41 @@ export const MEMORY_RECORD_DELETE_OUTPUT_SCHEMA = objectSchema({
663
663
  id: STRING_SCHEMA,
664
664
  deleted: BOOLEAN_SCHEMA,
665
665
  }, ['id', 'deleted']);
666
+ // ── Full-detach catalog wire schemas (1.2.0) ──────────────────────────────────
667
+ export const MEMORY_LINK_SCHEMA = objectSchema({
668
+ fromId: STRING_SCHEMA,
669
+ toId: STRING_SCHEMA,
670
+ relation: STRING_SCHEMA,
671
+ createdAt: NUMBER_SCHEMA,
672
+ }, ['fromId', 'toId', 'relation', 'createdAt']);
673
+ // distance may be Infinity for a no-vector-match fallback; JSON serializes that to
674
+ // null, so the wire field is nullable — honest about the "not ranked by vector" case.
675
+ export const MEMORY_SEMANTIC_RESULT_SCHEMA = objectSchema({
676
+ record: MEMORY_RECORD_SCHEMA,
677
+ distance: nullableSchema(NUMBER_SCHEMA),
678
+ similarity: NUMBER_SCHEMA,
679
+ score: NUMBER_SCHEMA,
680
+ }, ['record', 'similarity', 'score']);
681
+ export const MEMORY_BUNDLE_SCHEMA = objectSchema({
682
+ schemaVersion: enumSchema(['v1']),
683
+ exportedAt: NUMBER_SCHEMA,
684
+ scope: enumSchema(['session', 'project', 'team', 'all']),
685
+ recordCount: NUMBER_SCHEMA,
686
+ linkCount: NUMBER_SCHEMA,
687
+ records: arraySchema(MEMORY_RECORD_SCHEMA),
688
+ links: arraySchema(MEMORY_LINK_SCHEMA),
689
+ }, ['schemaVersion', 'exportedAt', 'scope', 'recordCount', 'linkCount', 'records', 'links']);
690
+ export const MEMORY_IMPORT_RESULT_SCHEMA = objectSchema({
691
+ importedRecords: NUMBER_SCHEMA,
692
+ skippedRecords: NUMBER_SCHEMA,
693
+ importedLinks: NUMBER_SCHEMA,
694
+ }, ['importedRecords', 'skippedRecords', 'importedLinks']);
695
+ export const MEMORY_RECORD_LIST_OUTPUT_SCHEMA = objectSchema({
696
+ records: arraySchema(MEMORY_RECORD_SCHEMA),
697
+ }, ['records']);
698
+ export const MEMORY_RECORD_SEMANTIC_OUTPUT_SCHEMA = objectSchema({
699
+ results: arraySchema(MEMORY_SEMANTIC_RESULT_SCHEMA),
700
+ }, ['results']);
701
+ export const MEMORY_RECORD_LINKS_OUTPUT_SCHEMA = objectSchema({
702
+ links: arraySchema(MEMORY_LINK_SCHEMA),
703
+ }, ['links']);
@@ -19,6 +19,14 @@
19
19
  * NEVER opens the file. Enforced structurally here — the active branch only ever
20
20
  * touches `this.transport`, never `this.local`.
21
21
  *
22
+ * FULL DETACH (SDK 1.2.0). The 1.1.0 wire family covered five verbs (add,
23
+ * honestSearch, get, updateReview, delete). That was enough for a surface to store
24
+ * and recall a fact over the wire, but NOT enough to fully detach every consumer
25
+ * from the store file: the agent's `list`/`update`/semantic-search paths and the
26
+ * TUI's `/recall` browse/link/queue/export paths still fell back to a local file.
27
+ * This client now exposes the FULL read/write catalog those consumers need
28
+ * (see MemoryExtendedAccess), so a wire client never opens the file for ANY of them.
29
+ *
22
30
  * ONE-WRITER ENFORCEMENT RULING. The platform's convention (see canonical-memory.ts
23
31
  * and the session spine) is honest sequential/owned access plus stated posture, NOT
24
32
  * an OS advisory lock — sql.js exposes no lock and a cross-process flock would be a
@@ -38,30 +46,84 @@
38
46
  * would be the exact dishonest-recall failure this whole design exists to prevent.
39
47
  * A sustained daemon loss is handled by `deactivate()`, which returns the surface
40
48
  * to owned-local mode explicitly.
49
+ *
50
+ * VERSION TOLERANCE. The five CORE verbs are required of every transport. The
51
+ * EXTENDED verbs are OPTIONAL on the transport (`MemoryTransport`) so a surface
52
+ * pinned to an older SDK/daemon pair that predates a verb still satisfies the type.
53
+ * When a client in wire mode calls an extended verb its adopted daemon does not
54
+ * implement, the call REJECTS with a stated reason — it never silently reaches into
55
+ * the local file, which would break the one-writer invariant and lie about which
56
+ * store answered.
41
57
  */
42
58
  import { logger } from '../../utils/logger.js';
43
- import type { MemoryAddOptions, MemoryRecord, MemoryReviewPatch, MemorySearchFilter } from '../../state/memory-store.js';
59
+ import type { MemoryAddOptions, MemoryBundle, MemoryDoctorReport, MemoryImportResult, MemoryLink, MemoryRecord, MemoryReviewPatch, MemoryScope, MemorySearchFilter, MemorySemanticSearchResult } from '../../state/memory-store.js';
60
+ import type { MemoryVectorStats } from '../../state/memory-vector-store.js';
44
61
  import type { HonestMemorySearchOptions, HonestMemorySearchResult } from '../../state/memory-recall-contract.js';
62
+ import { type MemoryRecallSnapshot, type MemoryRecallRefreshOptions } from './recall-snapshot.js';
63
+ /** Patch shape accepted by an editable-field update (scope/summary/detail/tags). */
64
+ export interface MemoryUpdatePatch {
65
+ readonly scope?: MemoryScope | undefined;
66
+ readonly summary?: string | undefined;
67
+ readonly detail?: string | undefined;
68
+ readonly tags?: string[] | undefined;
69
+ }
45
70
  /**
46
- * The memory read/write surface a caller uses without caring whether it resolves
47
- * locally or over the wire. Every method is async so a local (sync store) and a
48
- * wire (async) backend present the SAME shape.
71
+ * The five CORE verbs, shipped in 1.1.0. Every transport must implement all five —
72
+ * they are the minimum that lets a surface store and recall a fact over the wire.
49
73
  */
50
- export interface MemoryAccess {
74
+ export interface MemoryCoreAccess {
51
75
  add(opts: MemoryAddOptions): Promise<MemoryRecord>;
52
76
  honestSearch(filter: MemorySearchFilter, options?: HonestMemorySearchOptions): Promise<HonestMemorySearchResult>;
53
77
  get(id: string): Promise<MemoryRecord | null>;
54
78
  updateReview(id: string, patch: MemoryReviewPatch): Promise<MemoryRecord | null>;
55
79
  delete(id: string): Promise<boolean>;
56
80
  }
81
+ /**
82
+ * The EXTENDED verbs added in 1.2.0 so a wire client can fully detach from the file.
83
+ * Each maps to a MemoryRegistry read/write the consumers were still doing locally:
84
+ * - `list` — bulk read (getAll / literal browse): knowledge injection + agent `list`.
85
+ * - `searchSemantic`— scored semantic recall: agent semantic path + TUI `/recall --semantic`.
86
+ * - `update` — edit scope/summary/detail/tags (a scope edit is how a record is "promoted" project→team).
87
+ * - `link`/`linksFor` — relate records / read a record's links.
88
+ * - `reviewQueue` — records prioritised for review (the curator/queue surface).
89
+ * - `exportBundle`/`importBundle` — the no-loss bundle seam over the wire.
90
+ * - `vectorStats`/`doctor` — read the daemon's canonical index diagnostics.
91
+ *
92
+ * DELIBERATELY NOT HERE (host-only, ruled in the full-detach decision record):
93
+ * `rebuildVectors`/`rebuildVectorsAsync`. Rebuilding the vector index is maintenance
94
+ * a store performs on its OWN index; the daemon keeps its canonical index current on
95
+ * every add/import and exposes an admin `POST /api/memory/vector/rebuild` for a forced
96
+ * rebuild. A wire client owns no index to rebuild, so a client-initiated rebuild is an
97
+ * admin/diagnostic action against a store it does not own — it stays out of band, not
98
+ * a per-record detach need.
99
+ */
100
+ export interface MemoryExtendedAccess {
101
+ list(filter?: MemorySearchFilter): Promise<readonly MemoryRecord[]>;
102
+ searchSemantic(filter?: MemorySearchFilter): Promise<readonly MemorySemanticSearchResult[]>;
103
+ update(id: string, patch: MemoryUpdatePatch): Promise<MemoryRecord | null>;
104
+ link(fromId: string, toId: string, relation: string): Promise<MemoryLink | null>;
105
+ linksFor(id: string): Promise<readonly MemoryLink[]>;
106
+ reviewQueue(limit?: number, scope?: MemoryScope): Promise<readonly MemoryRecord[]>;
107
+ exportBundle(filter?: MemorySearchFilter): Promise<MemoryBundle>;
108
+ importBundle(bundle: MemoryBundle): Promise<MemoryImportResult>;
109
+ vectorStats(): Promise<MemoryVectorStats>;
110
+ doctor(): Promise<MemoryDoctorReport>;
111
+ }
112
+ /**
113
+ * The full memory read/write surface a caller uses without caring whether it
114
+ * resolves locally or over the wire. Every method is async so a local (sync store)
115
+ * and a wire (async) backend present the SAME shape.
116
+ */
117
+ export interface MemoryAccess extends MemoryCoreAccess, MemoryExtendedAccess {
118
+ }
57
119
  /**
58
120
  * The injected wire transport. A consumer builds a thin adapter over the daemon's
59
- * memory.records.* routes (POST /api/memory/records, /search, GET/DELETE
60
- * /api/memory/records/:id, POST /api/memory/records/:id/review). The core only ever
61
- * calls these methods it never assumes a typed client exists, so a surface pinned
62
- * to an older SDK can still adapt raw REST, exactly like the session spine.
121
+ * memory.records.* routes. The five CORE verbs are required; the EXTENDED verbs are
122
+ * optional so a surface pinned to an older SDK/daemon still satisfies the type — a
123
+ * client calling an extended verb the adopted daemon lacks gets an honest rejection,
124
+ * never a silent local-file read.
63
125
  */
64
- export type MemoryTransport = MemoryAccess;
126
+ export type MemoryTransport = MemoryCoreAccess & Partial<MemoryExtendedAccess>;
65
127
  /**
66
128
  * The local embedded store surface. The SDK's `MemoryRegistry` satisfies this
67
129
  * structurally (its methods are mostly synchronous; the facade normalizes them to
@@ -73,8 +135,18 @@ export interface LocalMemoryStore {
73
135
  get(id: string): MemoryRecord | null;
74
136
  review(id: string, patch: MemoryReviewPatch): MemoryRecord | null;
75
137
  delete(id: string): boolean;
138
+ search(filter?: MemorySearchFilter): MemoryRecord[];
139
+ searchSemantic(filter?: MemorySearchFilter): MemorySemanticSearchResult[];
140
+ update(id: string, patch: MemoryUpdatePatch): MemoryRecord | null;
141
+ link(fromId: string, toId: string, relation: string): Promise<MemoryLink | null> | MemoryLink | null;
142
+ linksFor(id: string): MemoryLink[];
143
+ reviewQueue(limit?: number, scope?: MemoryScope): MemoryRecord[];
144
+ exportBundle(filter?: MemorySearchFilter): MemoryBundle;
145
+ importBundle(bundle: MemoryBundle): Promise<MemoryImportResult> | MemoryImportResult;
146
+ vectorStats(): MemoryVectorStats;
147
+ doctor(): Promise<MemoryDoctorReport> | MemoryDoctorReport;
76
148
  }
77
- /** Wrap a local embedded store (e.g. a MemoryRegistry) as a MemoryAccess. */
149
+ /** Wrap a local embedded store (e.g. a MemoryRegistry) as a full MemoryAccess. */
78
150
  export declare function createLocalMemoryAccess(store: LocalMemoryStore): MemoryAccess;
79
151
  /** Current access posture — honest, reportable, never guessed. */
80
152
  export type MemoryAccessMode = 'local' | 'client';
@@ -88,8 +160,14 @@ export interface MemorySpineClientOptions {
88
160
  * (a surface that adopts a daemon later, or runs offline forever).
89
161
  */
90
162
  readonly transport?: MemoryTransport | undefined;
163
+ /**
164
+ * How long a recall snapshot stays "fresh" before `recallSnapshot()` reports it
165
+ * stale. Defaults to {@link DEFAULT_RECALL_SNAPSHOT_STALE_AFTER_MS}.
166
+ */
167
+ readonly recallSnapshotStaleAfterMs?: number | undefined;
91
168
  readonly log?: SpineLogger;
92
169
  }
170
+ export type { MemoryRecallSnapshot, MemoryRecallRefreshOptions } from './recall-snapshot.js';
93
171
  /**
94
172
  * Routes memory access to the LOCAL embedded store or, when a daemon has been
95
173
  * adopted, THROUGH the wire — never both. Implements {@link MemoryAccess} so a
@@ -99,6 +177,9 @@ export declare class MemorySpineClient implements MemoryAccess {
99
177
  private readonly local;
100
178
  private transport;
101
179
  private readonly log;
180
+ private readonly staleAfterMs;
181
+ /** Last recall snapshot captured by refreshRecallSnapshot(); null until first refresh. */
182
+ private snapshot;
102
183
  constructor(options: MemorySpineClientOptions);
103
184
  /** The current posture: 'client' when routing over the wire, 'local' otherwise. */
104
185
  mode(): MemoryAccessMode;
@@ -117,11 +198,43 @@ export declare class MemorySpineClient implements MemoryAccess {
117
198
  get(id: string): Promise<MemoryRecord | null>;
118
199
  updateReview(id: string, patch: MemoryReviewPatch): Promise<MemoryRecord | null>;
119
200
  delete(id: string): Promise<boolean>;
201
+ list(filter?: MemorySearchFilter): Promise<readonly MemoryRecord[]>;
202
+ searchSemantic(filter?: MemorySearchFilter): Promise<readonly MemorySemanticSearchResult[]>;
203
+ update(id: string, patch: MemoryUpdatePatch): Promise<MemoryRecord | null>;
204
+ link(fromId: string, toId: string, relation: string): Promise<MemoryLink | null>;
205
+ linksFor(id: string): Promise<readonly MemoryLink[]>;
206
+ reviewQueue(limit?: number, scope?: MemoryScope): Promise<readonly MemoryRecord[]>;
207
+ exportBundle(filter?: MemorySearchFilter): Promise<MemoryBundle>;
208
+ importBundle(bundle: MemoryBundle): Promise<MemoryImportResult>;
209
+ vectorStats(): Promise<MemoryVectorStats>;
210
+ doctor(): Promise<MemoryDoctorReport>;
211
+ /**
212
+ * Refresh the cached recall snapshot ASYNCHRONOUSLY over the CURRENT route (wire
213
+ * when adopted, local otherwise). Call this from an async pre-turn hook so a
214
+ * SYNCHRONOUS prompt builder can read the result via {@link recallSnapshot}
215
+ * without awaiting the wire. Runs the honest recall search (recall-injection
216
+ * contract ON by default), stamps the capture time and mode, and stores it.
217
+ */
218
+ refreshRecallSnapshot(filter?: MemorySearchFilter, options?: MemoryRecallRefreshOptions): Promise<MemoryRecallSnapshot>;
219
+ /**
220
+ * Read the last recall snapshot SYNCHRONOUSLY (for a sync prompt builder). Never
221
+ * opens the file and never awaits: it returns whatever the last async refresh
222
+ * captured, with a freshly-computed age, a `stale` flag, and an HONEST `note`. If
223
+ * no refresh has happened yet it returns an EMPTY snapshot whose note says exactly
224
+ * that — never a silent empty that reads as "nothing was ever stored."
225
+ */
226
+ recallSnapshot(now?: number): MemoryRecallSnapshot;
120
227
  /**
121
228
  * The single choke point that realizes the one-writer invariant: in client mode
122
229
  * EVERY op resolves through the transport and the local store is never reached.
123
230
  */
124
231
  private route;
232
+ /**
233
+ * Route an extended verb. Local mode → the local store. Client mode → the
234
+ * transport's verb if it implements it, otherwise an HONEST rejection stating the
235
+ * adopted daemon does not support it (never a silent local-file read, which would
236
+ * break the single-writer invariant and misreport which store answered).
237
+ */
238
+ private routeExtended;
125
239
  }
126
- export {};
127
240
  //# sourceMappingURL=client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../../src/platform/runtime/memory-spine/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../../src/platform/runtime/memory-spine/client.ts"],"names":[],"mappings":"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"}
@@ -19,6 +19,14 @@
19
19
  * NEVER opens the file. Enforced structurally here — the active branch only ever
20
20
  * touches `this.transport`, never `this.local`.
21
21
  *
22
+ * FULL DETACH (SDK 1.2.0). The 1.1.0 wire family covered five verbs (add,
23
+ * honestSearch, get, updateReview, delete). That was enough for a surface to store
24
+ * and recall a fact over the wire, but NOT enough to fully detach every consumer
25
+ * from the store file: the agent's `list`/`update`/semantic-search paths and the
26
+ * TUI's `/recall` browse/link/queue/export paths still fell back to a local file.
27
+ * This client now exposes the FULL read/write catalog those consumers need
28
+ * (see MemoryExtendedAccess), so a wire client never opens the file for ANY of them.
29
+ *
22
30
  * ONE-WRITER ENFORCEMENT RULING. The platform's convention (see canonical-memory.ts
23
31
  * and the session spine) is honest sequential/owned access plus stated posture, NOT
24
32
  * an OS advisory lock — sql.js exposes no lock and a cross-process flock would be a
@@ -38,9 +46,18 @@
38
46
  * would be the exact dishonest-recall failure this whole design exists to prevent.
39
47
  * A sustained daemon loss is handled by `deactivate()`, which returns the surface
40
48
  * to owned-local mode explicitly.
49
+ *
50
+ * VERSION TOLERANCE. The five CORE verbs are required of every transport. The
51
+ * EXTENDED verbs are OPTIONAL on the transport (`MemoryTransport`) so a surface
52
+ * pinned to an older SDK/daemon pair that predates a verb still satisfies the type.
53
+ * When a client in wire mode calls an extended verb its adopted daemon does not
54
+ * implement, the call REJECTS with a stated reason — it never silently reaches into
55
+ * the local file, which would break the one-writer invariant and lie about which
56
+ * store answered.
41
57
  */
42
58
  import { logger } from '../../utils/logger.js';
43
- /** Wrap a local embedded store (e.g. a MemoryRegistry) as a MemoryAccess. */
59
+ import { buildRecallSnapshot, emptyRecallSnapshot, DEFAULT_RECALL_SNAPSHOT_STALE_AFTER_MS, } from './recall-snapshot.js';
60
+ /** Wrap a local embedded store (e.g. a MemoryRegistry) as a full MemoryAccess. */
44
61
  export function createLocalMemoryAccess(store) {
45
62
  return {
46
63
  add: (opts) => Promise.resolve(store.add(opts)),
@@ -48,6 +65,16 @@ export function createLocalMemoryAccess(store) {
48
65
  get: (id) => Promise.resolve(store.get(id)),
49
66
  updateReview: (id, patch) => Promise.resolve(store.review(id, patch)),
50
67
  delete: (id) => Promise.resolve(store.delete(id)),
68
+ list: (filter) => Promise.resolve(store.search(filter ?? {})),
69
+ searchSemantic: (filter) => Promise.resolve(store.searchSemantic(filter ?? {})),
70
+ update: (id, patch) => Promise.resolve(store.update(id, patch)),
71
+ link: (fromId, toId, relation) => Promise.resolve(store.link(fromId, toId, relation)),
72
+ linksFor: (id) => Promise.resolve(store.linksFor(id)),
73
+ reviewQueue: (limit, scope) => Promise.resolve(store.reviewQueue(limit, scope)),
74
+ exportBundle: (filter) => Promise.resolve(store.exportBundle(filter ?? {})),
75
+ importBundle: (bundle) => Promise.resolve(store.importBundle(bundle)),
76
+ vectorStats: () => Promise.resolve(store.vectorStats()),
77
+ doctor: () => Promise.resolve(store.doctor()),
51
78
  };
52
79
  }
53
80
  /**
@@ -59,10 +86,14 @@ export class MemorySpineClient {
59
86
  local;
60
87
  transport;
61
88
  log;
89
+ staleAfterMs;
90
+ /** Last recall snapshot captured by refreshRecallSnapshot(); null until first refresh. */
91
+ snapshot = null;
62
92
  constructor(options) {
63
93
  this.local = options.local;
64
94
  this.transport = options.transport ?? null;
65
95
  this.log = options.log ?? logger;
96
+ this.staleAfterMs = options.recallSnapshotStaleAfterMs ?? DEFAULT_RECALL_SNAPSHOT_STALE_AFTER_MS;
66
97
  }
67
98
  /** The current posture: 'client' when routing over the wire, 'local' otherwise. */
68
99
  mode() {
@@ -88,6 +119,7 @@ export class MemorySpineClient {
88
119
  this.transport = null;
89
120
  this.log.info('memory spine deactivated — reverting to owned-local memory access', { reason });
90
121
  }
122
+ // ── Core verbs (routed local-or-wire) ─────────────────────────────────────────
91
123
  add(opts) {
92
124
  return this.route().add(opts);
93
125
  }
@@ -103,6 +135,64 @@ export class MemorySpineClient {
103
135
  delete(id) {
104
136
  return this.route().delete(id);
105
137
  }
138
+ // ── Extended verbs (routed local-or-wire; honest reject if the daemon lacks one) ─
139
+ list(filter) {
140
+ return this.routeExtended('list', (a) => a.list(filter), (t) => t.list?.(filter));
141
+ }
142
+ searchSemantic(filter) {
143
+ return this.routeExtended('searchSemantic', (a) => a.searchSemantic(filter), (t) => t.searchSemantic?.(filter));
144
+ }
145
+ update(id, patch) {
146
+ return this.routeExtended('update', (a) => a.update(id, patch), (t) => t.update?.(id, patch));
147
+ }
148
+ link(fromId, toId, relation) {
149
+ return this.routeExtended('link', (a) => a.link(fromId, toId, relation), (t) => t.link?.(fromId, toId, relation));
150
+ }
151
+ linksFor(id) {
152
+ return this.routeExtended('linksFor', (a) => a.linksFor(id), (t) => t.linksFor?.(id));
153
+ }
154
+ reviewQueue(limit, scope) {
155
+ return this.routeExtended('reviewQueue', (a) => a.reviewQueue(limit, scope), (t) => t.reviewQueue?.(limit, scope));
156
+ }
157
+ exportBundle(filter) {
158
+ return this.routeExtended('exportBundle', (a) => a.exportBundle(filter), (t) => t.exportBundle?.(filter));
159
+ }
160
+ importBundle(bundle) {
161
+ return this.routeExtended('importBundle', (a) => a.importBundle(bundle), (t) => t.importBundle?.(bundle));
162
+ }
163
+ vectorStats() {
164
+ return this.routeExtended('vectorStats', (a) => a.vectorStats(), (t) => t.vectorStats?.());
165
+ }
166
+ doctor() {
167
+ return this.routeExtended('doctor', (a) => a.doctor(), (t) => t.doctor?.());
168
+ }
169
+ // ── The sync-recall seam ──────────────────────────────────────────────────────
170
+ /**
171
+ * Refresh the cached recall snapshot ASYNCHRONOUSLY over the CURRENT route (wire
172
+ * when adopted, local otherwise). Call this from an async pre-turn hook so a
173
+ * SYNCHRONOUS prompt builder can read the result via {@link recallSnapshot}
174
+ * without awaiting the wire. Runs the honest recall search (recall-injection
175
+ * contract ON by default), stamps the capture time and mode, and stores it.
176
+ */
177
+ async refreshRecallSnapshot(filter = {}, options = {}) {
178
+ const recall = options.recall ?? true;
179
+ const result = await this.route().honestSearch(filter, { recall });
180
+ this.snapshot = buildRecallSnapshot(result, this.mode(), Date.now(), this.staleAfterMs);
181
+ return this.snapshot;
182
+ }
183
+ /**
184
+ * Read the last recall snapshot SYNCHRONOUSLY (for a sync prompt builder). Never
185
+ * opens the file and never awaits: it returns whatever the last async refresh
186
+ * captured, with a freshly-computed age, a `stale` flag, and an HONEST `note`. If
187
+ * no refresh has happened yet it returns an EMPTY snapshot whose note says exactly
188
+ * that — never a silent empty that reads as "nothing was ever stored."
189
+ */
190
+ recallSnapshot(now = Date.now()) {
191
+ const cached = this.snapshot;
192
+ if (cached === null || cached.search === null || cached.capturedAt === null)
193
+ return emptyRecallSnapshot(this.mode());
194
+ return buildRecallSnapshot(cached.search, cached.mode, cached.capturedAt, this.staleAfterMs, now);
195
+ }
106
196
  /**
107
197
  * The single choke point that realizes the one-writer invariant: in client mode
108
198
  * EVERY op resolves through the transport and the local store is never reached.
@@ -110,4 +200,22 @@ export class MemorySpineClient {
110
200
  route() {
111
201
  return this.transport ?? this.local;
112
202
  }
203
+ /**
204
+ * Route an extended verb. Local mode → the local store. Client mode → the
205
+ * transport's verb if it implements it, otherwise an HONEST rejection stating the
206
+ * adopted daemon does not support it (never a silent local-file read, which would
207
+ * break the single-writer invariant and misreport which store answered).
208
+ */
209
+ routeExtended(verb, local, wire) {
210
+ if (this.transport === null)
211
+ return local(this.local);
212
+ const call = wire(this.transport);
213
+ if (call === undefined) {
214
+ return Promise.reject(new Error(`memory spine: the adopted daemon does not support the '${verb}' memory verb over the wire — `
215
+ + 'upgrade the daemon to a build that serves it, or run this surface offline (no daemon adopted). '
216
+ + 'A wire client will not read its own local store for this op, because that would break the '
217
+ + 'single-writer invariant and report a divergent local copy as if it were the canonical store.'));
218
+ }
219
+ return call;
220
+ }
113
221
  }
@@ -6,6 +6,12 @@
6
6
  * directly; a surface that has adopted a compatible daemon routes memory THROUGH
7
7
  * the wire and never opens the store file. Mirrors the session-spine pattern; the
8
8
  * offline fallback stays, so the agent and TUI keep working with no daemon running.
9
+ *
10
+ * As of 1.2.0 the client exposes the FULL read/write catalog (see
11
+ * MemoryExtendedAccess) so a wire client fully detaches from the file, plus a
12
+ * freshness-stamped recall snapshot (recall-snapshot.ts) for the synchronous
13
+ * per-turn prompt-injection seam.
9
14
  */
10
- export { MemorySpineClient, createLocalMemoryAccess, type MemoryAccess, type MemoryAccessMode, type MemoryTransport, type LocalMemoryStore, type MemorySpineClientOptions, } from './client.js';
15
+ export { MemorySpineClient, createLocalMemoryAccess, type MemoryAccess, type MemoryCoreAccess, type MemoryExtendedAccess, type MemoryAccessMode, type MemoryTransport, type MemoryUpdatePatch, type LocalMemoryStore, type MemorySpineClientOptions, type MemoryRecallSnapshot, type MemoryRecallRefreshOptions, } from './client.js';
16
+ export { buildRecallSnapshot, emptyRecallSnapshot, DEFAULT_RECALL_SNAPSHOT_STALE_AFTER_MS, } from './recall-snapshot.js';
11
17
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/platform/runtime/memory-spine/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,iBAAiB,EACjB,uBAAuB,EACvB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,wBAAwB,GAC9B,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/platform/runtime/memory-spine/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,iBAAiB,EACjB,uBAAuB,EACvB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,GAChC,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,sCAAsC,GACvC,MAAM,sBAAsB,CAAC"}
@@ -6,5 +6,11 @@
6
6
  * directly; a surface that has adopted a compatible daemon routes memory THROUGH
7
7
  * the wire and never opens the store file. Mirrors the session-spine pattern; the
8
8
  * offline fallback stays, so the agent and TUI keep working with no daemon running.
9
+ *
10
+ * As of 1.2.0 the client exposes the FULL read/write catalog (see
11
+ * MemoryExtendedAccess) so a wire client fully detaches from the file, plus a
12
+ * freshness-stamped recall snapshot (recall-snapshot.ts) for the synchronous
13
+ * per-turn prompt-injection seam.
9
14
  */
10
15
  export { MemorySpineClient, createLocalMemoryAccess, } from './client.js';
16
+ export { buildRecallSnapshot, emptyRecallSnapshot, DEFAULT_RECALL_SNAPSHOT_STALE_AFTER_MS, } from './recall-snapshot.js';