@remnic/core 9.3.630 → 9.3.631

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 (214) hide show
  1. package/dist/access-cli.js +15 -13
  2. package/dist/access-cli.js.map +1 -1
  3. package/dist/access-http.d.ts +4 -4
  4. package/dist/access-http.js +7 -6
  5. package/dist/access-mcp.d.ts +4 -4
  6. package/dist/access-mcp.js +6 -5
  7. package/dist/{access-service-C4v-eFjB.d.ts → access-service-C9_EpVHd.d.ts} +2 -2
  8. package/dist/access-service.d.ts +4 -4
  9. package/dist/access-service.js +5 -4
  10. package/dist/action-confidence.d.ts +1 -1
  11. package/dist/active-memory-bridge.d.ts +1 -1
  12. package/dist/active-recall.d.ts +1 -1
  13. package/dist/active-recall.js +1 -1
  14. package/dist/auto-sync-RFADEHIQ.js +75 -0
  15. package/dist/auto-sync-RFADEHIQ.js.map +1 -0
  16. package/dist/behavior-learner.d.ts +1 -1
  17. package/dist/behavior-signals.d.ts +1 -1
  18. package/dist/bootstrap.d.ts +3 -3
  19. package/dist/briefing.d.ts +1 -1
  20. package/dist/briefing.js +3 -2
  21. package/dist/buffer-surprise-report.d.ts +1 -1
  22. package/dist/buffer.d.ts +1 -1
  23. package/dist/calibration.d.ts +1 -1
  24. package/dist/causal-behavior.d.ts +1 -1
  25. package/dist/causal-consolidation.d.ts +1 -1
  26. package/dist/causal-consolidation.js +4 -3
  27. package/dist/causal-consolidation.js.map +1 -1
  28. package/dist/{chunk-BWK5EEKS.js → chunk-242XFZ36.js} +2 -2
  29. package/dist/{chunk-K3BTOW7N.js → chunk-32U3N7H5.js} +3 -3
  30. package/dist/{chunk-5S6IREG3.js → chunk-3RDYU3JS.js} +3 -3
  31. package/dist/{chunk-SACS6KE6.js → chunk-4S3N6HFG.js} +2 -2
  32. package/dist/{chunk-VUTPRX7K.js → chunk-5PT5I6JQ.js} +14 -14
  33. package/dist/{chunk-2VJ7AJFX.js → chunk-7A2QKUUA.js} +2 -2
  34. package/dist/{chunk-EORL2IDM.js → chunk-7H5WCPBS.js} +58 -5
  35. package/dist/{chunk-EORL2IDM.js.map → chunk-7H5WCPBS.js.map} +1 -1
  36. package/dist/{chunk-NRQJBK36.js → chunk-C4KKM62E.js} +2 -2
  37. package/dist/{chunk-GXWFZYSR.js → chunk-CMN5AWAZ.js} +2 -2
  38. package/dist/{chunk-F6USGHMO.js → chunk-DOBJH4I6.js} +4 -4
  39. package/dist/{chunk-ADOD7PJC.js → chunk-IFVFQRZ2.js} +5 -5
  40. package/dist/{chunk-6LBQL5US.js → chunk-JCLECECB.js} +2 -2
  41. package/dist/chunk-KVDUDYEN.js +1164 -0
  42. package/dist/chunk-KVDUDYEN.js.map +1 -0
  43. package/dist/{chunk-S5W37FPX.js → chunk-LEG7XWS2.js} +2 -2
  44. package/dist/chunk-M7XQSUBB.js +280 -0
  45. package/dist/chunk-M7XQSUBB.js.map +1 -0
  46. package/dist/{chunk-MQ24KOOR.js → chunk-PUEAEQSN.js} +2 -2
  47. package/dist/{chunk-RSKUUEBA.js → chunk-QYGIQ5NM.js} +140 -417
  48. package/dist/chunk-QYGIQ5NM.js.map +1 -0
  49. package/dist/{chunk-UE57H4MA.js → chunk-UXFOGILU.js} +2 -2
  50. package/dist/{chunk-OQMR2SDZ.js → chunk-VTR3MNYF.js} +2 -2
  51. package/dist/{chunk-4QEUKASL.js → chunk-W25I7G6U.js} +2 -2
  52. package/dist/{chunk-YJOWWRRS.js → chunk-WLZBVYC6.js} +125 -1206
  53. package/dist/chunk-WLZBVYC6.js.map +1 -0
  54. package/dist/{chunk-OOFBE62K.js → chunk-X7EJF46S.js} +2 -2
  55. package/dist/{chunk-BL33LBTN.js → chunk-XG4NAWAV.js} +3 -3
  56. package/dist/{chunk-ZZSXUZF3.js → chunk-YROCXMCK.js} +2 -2
  57. package/dist/{cli-B_6EMiQc.d.ts → cli-CuVEQWKr.d.ts} +3 -3
  58. package/dist/cli.d.ts +5 -5
  59. package/dist/cli.js +18 -17
  60. package/dist/compounding/engine.d.ts +1 -1
  61. package/dist/compounding/engine.js +3 -2
  62. package/dist/compounding/preference-consolidator.d.ts +1 -1
  63. package/dist/compression-optimizer.d.ts +1 -1
  64. package/dist/config.d.ts +1 -1
  65. package/dist/config.js +1 -1
  66. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  67. package/dist/connectors/codex-materialize-runner.js +3 -2
  68. package/dist/connectors/codex-materialize.d.ts +1 -1
  69. package/dist/connectors/index.d.ts +1 -1
  70. package/dist/connectors/index.js +3 -2
  71. package/dist/consolidation-provenance-check.d.ts +1 -1
  72. package/dist/consolidation-undo.d.ts +1 -1
  73. package/dist/contradiction/index.d.ts +1 -1
  74. package/dist/contradiction/index.js +4 -4
  75. package/dist/conversation-index/backend.d.ts +1 -1
  76. package/dist/conversation-index/chunker.d.ts +1 -1
  77. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  78. package/dist/conversation-index/indexer.d.ts +1 -1
  79. package/dist/conversation-index/search.d.ts +1 -1
  80. package/dist/day-summary.d.ts +1 -1
  81. package/dist/delinearize.d.ts +1 -1
  82. package/dist/direct-answer-wiring.d.ts +1 -1
  83. package/dist/direct-answer.d.ts +1 -1
  84. package/dist/embedding-fallback.d.ts +1 -1
  85. package/dist/enrichment/index.d.ts +1 -1
  86. package/dist/entity-retrieval.d.ts +1 -1
  87. package/dist/entity-retrieval.js +3 -2
  88. package/dist/entity-schema.d.ts +1 -1
  89. package/dist/explicit-capture.d.ts +3 -3
  90. package/dist/extraction-judge-telemetry.d.ts +1 -1
  91. package/dist/extraction-judge-training.d.ts +1 -1
  92. package/dist/extraction-judge.d.ts +1 -1
  93. package/dist/extraction.d.ts +1 -1
  94. package/dist/fallback-llm.d.ts +1 -1
  95. package/dist/identity-continuity.d.ts +1 -1
  96. package/dist/importance.d.ts +1 -1
  97. package/dist/index.d.ts +8 -8
  98. package/dist/index.js +49 -45
  99. package/dist/index.js.map +1 -1
  100. package/dist/intent.d.ts +1 -1
  101. package/dist/lcm/engine.d.ts +1 -1
  102. package/dist/lcm/index.d.ts +1 -1
  103. package/dist/lcm/tools.d.ts +1 -1
  104. package/dist/lifecycle.d.ts +1 -1
  105. package/dist/live-connectors-runner.d.ts +1 -1
  106. package/dist/local-llm.d.ts +1 -1
  107. package/dist/maintenance/memory-governance.d.ts +1 -1
  108. package/dist/maintenance/memory-governance.js +3 -2
  109. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +3 -2
  110. package/dist/maintenance/rebuild-memory-projection.js +4 -3
  111. package/dist/mcp-memory-inspector-app.d.ts +4 -4
  112. package/dist/memory-action-policy.d.ts +1 -1
  113. package/dist/memory-cache.d.ts +1 -1
  114. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  115. package/dist/memory-projection-store.d.ts +1 -1
  116. package/dist/memory-provenance.d.ts +1 -1
  117. package/dist/memory-worth-outcomes.d.ts +1 -1
  118. package/dist/models-json.d.ts +1 -1
  119. package/dist/namespaces/migrate.d.ts +1 -1
  120. package/dist/namespaces/migrate.js +4 -3
  121. package/dist/namespaces/principal.d.ts +1 -1
  122. package/dist/namespaces/search.d.ts +1 -1
  123. package/dist/namespaces/storage.d.ts +1 -1
  124. package/dist/namespaces/storage.js +3 -2
  125. package/dist/native-knowledge.d.ts +1 -1
  126. package/dist/operator-toolkit.d.ts +1 -1
  127. package/dist/operator-toolkit.js +7 -6
  128. package/dist/{orchestrator-Dlw3ae4B.d.ts → orchestrator-CoqytbK_.d.ts} +3 -2
  129. package/dist/orchestrator.d.ts +3 -3
  130. package/dist/orchestrator.js +12 -10
  131. package/dist/patterns-cli.d.ts +1 -1
  132. package/dist/policy-runtime.d.ts +1 -1
  133. package/dist/qmd-recall-cache.d.ts +1 -1
  134. package/dist/qmd.d.ts +1 -1
  135. package/dist/recall-disclosure-escalation.d.ts +1 -1
  136. package/dist/recall-explain-renderer.d.ts +1 -1
  137. package/dist/recall-planner-llm.d.ts +1 -1
  138. package/dist/recall-state.d.ts +1 -1
  139. package/dist/recall-tag-filter.d.ts +1 -1
  140. package/dist/recall-xray-cli.d.ts +1 -1
  141. package/dist/recall-xray-renderer.d.ts +1 -1
  142. package/dist/recall-xray.d.ts +1 -1
  143. package/dist/resolve-auth-token.d.ts +1 -1
  144. package/dist/resume-bundles.js +2 -2
  145. package/dist/retrieval-agents.d.ts +1 -1
  146. package/dist/retrieval-tiers.d.ts +1 -1
  147. package/dist/routing/engine.d.ts +1 -1
  148. package/dist/routing/store.d.ts +1 -1
  149. package/dist/schemas.d.ts +22 -22
  150. package/dist/search/embed-helper.d.ts +1 -1
  151. package/dist/search/factory.d.ts +1 -1
  152. package/dist/search/index.d.ts +1 -1
  153. package/dist/search/lancedb-backend.d.ts +1 -1
  154. package/dist/search/meilisearch-backend.d.ts +1 -1
  155. package/dist/search/noop-backend.d.ts +1 -1
  156. package/dist/search/orama-backend.d.ts +1 -1
  157. package/dist/search/port.d.ts +1 -1
  158. package/dist/search/remote-backend.d.ts +1 -1
  159. package/dist/{semantic-consolidation-C4sefXEI.d.ts → semantic-consolidation-BPs6BURk.d.ts} +1 -1
  160. package/dist/semantic-consolidation.d.ts +2 -2
  161. package/dist/semantic-consolidation.js +4 -3
  162. package/dist/semantic-rule-promotion.js +3 -2
  163. package/dist/semantic-rule-verifier.d.ts +1 -1
  164. package/dist/semantic-rule-verifier.js +3 -2
  165. package/dist/session-observer-bands.d.ts +1 -1
  166. package/dist/session-observer-state.d.ts +1 -1
  167. package/dist/shared-context/manager.d.ts +1 -1
  168. package/dist/signal.d.ts +1 -1
  169. package/dist/storage.d.ts +1 -1
  170. package/dist/storage.js +2 -1
  171. package/dist/summarizer.d.ts +1 -1
  172. package/dist/summary-snapshot.d.ts +1 -1
  173. package/dist/temporal-supersession.d.ts +1 -1
  174. package/dist/temporal-validity.d.ts +1 -1
  175. package/dist/threading.d.ts +1 -1
  176. package/dist/tier-migration.d.ts +1 -1
  177. package/dist/tier-routing.d.ts +1 -1
  178. package/dist/topics.d.ts +1 -1
  179. package/dist/transcript.d.ts +1 -1
  180. package/dist/transfer/types.d.ts +12 -12
  181. package/dist/{types-2vqxmO0j.d.ts → types-CpMPD8xl.d.ts} +20 -1
  182. package/dist/types.d.ts +1 -1
  183. package/dist/utility-runtime.d.ts +1 -1
  184. package/dist/verified-recall.js +3 -2
  185. package/package.json +1 -1
  186. package/src/orchestrator.ts +58 -0
  187. package/src/wearables/auto-sync.test.ts +181 -0
  188. package/src/wearables/auto-sync.ts +129 -0
  189. package/src/wearables/config.test.ts +58 -8
  190. package/src/wearables/config.ts +75 -5
  191. package/src/wearables/pipeline.test.ts +87 -4
  192. package/src/wearables/pipeline.ts +43 -13
  193. package/src/wearables/types.ts +20 -1
  194. package/dist/chunk-RSKUUEBA.js.map +0 -1
  195. package/dist/chunk-YJOWWRRS.js.map +0 -1
  196. /package/dist/{chunk-BWK5EEKS.js.map → chunk-242XFZ36.js.map} +0 -0
  197. /package/dist/{chunk-K3BTOW7N.js.map → chunk-32U3N7H5.js.map} +0 -0
  198. /package/dist/{chunk-5S6IREG3.js.map → chunk-3RDYU3JS.js.map} +0 -0
  199. /package/dist/{chunk-SACS6KE6.js.map → chunk-4S3N6HFG.js.map} +0 -0
  200. /package/dist/{chunk-VUTPRX7K.js.map → chunk-5PT5I6JQ.js.map} +0 -0
  201. /package/dist/{chunk-2VJ7AJFX.js.map → chunk-7A2QKUUA.js.map} +0 -0
  202. /package/dist/{chunk-NRQJBK36.js.map → chunk-C4KKM62E.js.map} +0 -0
  203. /package/dist/{chunk-GXWFZYSR.js.map → chunk-CMN5AWAZ.js.map} +0 -0
  204. /package/dist/{chunk-F6USGHMO.js.map → chunk-DOBJH4I6.js.map} +0 -0
  205. /package/dist/{chunk-ADOD7PJC.js.map → chunk-IFVFQRZ2.js.map} +0 -0
  206. /package/dist/{chunk-6LBQL5US.js.map → chunk-JCLECECB.js.map} +0 -0
  207. /package/dist/{chunk-S5W37FPX.js.map → chunk-LEG7XWS2.js.map} +0 -0
  208. /package/dist/{chunk-MQ24KOOR.js.map → chunk-PUEAEQSN.js.map} +0 -0
  209. /package/dist/{chunk-UE57H4MA.js.map → chunk-UXFOGILU.js.map} +0 -0
  210. /package/dist/{chunk-OQMR2SDZ.js.map → chunk-VTR3MNYF.js.map} +0 -0
  211. /package/dist/{chunk-4QEUKASL.js.map → chunk-W25I7G6U.js.map} +0 -0
  212. /package/dist/{chunk-OOFBE62K.js.map → chunk-X7EJF46S.js.map} +0 -0
  213. /package/dist/{chunk-BL33LBTN.js.map → chunk-XG4NAWAV.js.map} +0 -0
  214. /package/dist/{chunk-ZZSXUZF3.js.map → chunk-YROCXMCK.js.map} +0 -0
@@ -1,3 +1,10 @@
1
+ import {
2
+ WEARABLE_SOURCE_PREFIX,
3
+ defaultTimezone,
4
+ loadSyncState,
5
+ syncWearableSource,
6
+ wearableSourceLabel
7
+ } from "./chunk-KVDUDYEN.js";
1
8
  import {
2
9
  migrateFromEngram
3
10
  } from "./chunk-4HFJQCJZ.js";
@@ -22,7 +29,7 @@ import {
22
29
  import {
23
30
  CompoundingEngine,
24
31
  defaultTierMigrationCycleBudget
25
- } from "./chunk-UE57H4MA.js";
32
+ } from "./chunk-UXFOGILU.js";
26
33
  import {
27
34
  SharedContextManager
28
35
  } from "./chunk-DRD2Q7HQ.js";
@@ -168,7 +175,7 @@ import {
168
175
  buildEntityRecallSection,
169
176
  entityRecentTranscriptLookbackHours,
170
177
  readRecentEntityTranscriptEntries
171
- } from "./chunk-6LBQL5US.js";
178
+ } from "./chunk-JCLECECB.js";
172
179
  import {
173
180
  buildEventOrderRecallSection,
174
181
  shouldRecallEventOrderEvidence
@@ -203,7 +210,7 @@ import {
203
210
  materializeAfterSemanticConsolidation,
204
211
  parseConsolidationResponse,
205
212
  parseOperatorAwareConsolidationResponse
206
- } from "./chunk-OOFBE62K.js";
213
+ } from "./chunk-X7EJF46S.js";
207
214
  import {
208
215
  normalizeReplaySessionKey
209
216
  } from "./chunk-2PRQG7PV.js";
@@ -212,13 +219,13 @@ import {
212
219
  } from "./chunk-X6IRLNOO.js";
213
220
  import {
214
221
  searchVerifiedEpisodes
215
- } from "./chunk-ZZSXUZF3.js";
222
+ } from "./chunk-YROCXMCK.js";
216
223
  import {
217
224
  ThreadingManager
218
225
  } from "./chunk-W4RVMTHR.js";
219
226
  import {
220
227
  searchVerifiedSemanticRules
221
- } from "./chunk-SACS6KE6.js";
228
+ } from "./chunk-4S3N6HFG.js";
222
229
  import {
223
230
  searchWorkProductLedgerEntries
224
231
  } from "./chunk-ZRWB5D4H.js";
@@ -237,7 +244,7 @@ import {
237
244
  } from "./chunk-CYEPCZN5.js";
238
245
  import {
239
246
  NamespaceStorageRouter
240
- } from "./chunk-S5W37FPX.js";
247
+ } from "./chunk-LEG7XWS2.js";
241
248
  import {
242
249
  namespaceIdentityFromToken
243
250
  } from "./chunk-ZFXCQPNO.js";
@@ -286,14 +293,9 @@ import {
286
293
  fallbackLlmRuntimeContextFromConfig
287
294
  } from "./chunk-723OMPUI.js";
288
295
  import {
289
- applyCorrections,
290
- applyOffTheRecord,
291
296
  compileCorrectionRule,
292
- compileCorrectionRules,
293
- compileRedactionPatterns,
294
297
  correctionsFilePath,
295
298
  loadCorrectionsFile,
296
- redactText,
297
299
  saveCorrectionsFile
298
300
  } from "./chunk-NDAH7BJ5.js";
299
301
  import {
@@ -351,27 +353,24 @@ import {
351
353
  } from "./chunk-XL7FK7PJ.js";
352
354
  import {
353
355
  buildChainFollowupGenerator
354
- } from "./chunk-GXWFZYSR.js";
356
+ } from "./chunk-CMN5AWAZ.js";
355
357
  import {
356
358
  ContentHashIndex,
357
359
  StorageManager,
358
360
  compareEntityTimestamps,
359
- composeDayTranscriptBody,
360
- composeDayTranscriptMeta,
361
361
  fingerprintEntityStructuredFacts,
362
- hashTranscriptBody,
363
- isValidTranscriptDate,
364
- loadSpeakerRegistry,
365
362
  normalizeAttributePairs,
366
363
  normalizeEntityName,
367
- parseDayTranscript,
368
364
  parseEntityFile,
369
- resolveSpeaker,
370
- saveSpeakerRegistry,
371
- serializeDayTranscript,
372
- speakerRegistryKey,
373
365
  stripAttributesSuffix
374
- } from "./chunk-RSKUUEBA.js";
366
+ } from "./chunk-QYGIQ5NM.js";
367
+ import {
368
+ isValidTranscriptDate,
369
+ loadSpeakerRegistry,
370
+ parseDayTranscript,
371
+ saveSpeakerRegistry,
372
+ speakerRegistryKey
373
+ } from "./chunk-M7XQSUBB.js";
375
374
  import {
376
375
  attachCitation,
377
376
  hasCitationForTemplate,
@@ -410,10 +409,6 @@ import {
410
409
  decideLifecycleTransition,
411
410
  resolveLifecycleState
412
411
  } from "./chunk-TBBDFYXW.js";
413
- import {
414
- countRecallTokenOverlap,
415
- normalizeRecallTokens
416
- } from "./chunk-ZBJMUXZH.js";
417
412
  import {
418
413
  log
419
414
  } from "./chunk-2ODBA7MQ.js";
@@ -429,7 +424,7 @@ import {
429
424
  } from "./chunk-AC5LO7IU.js";
430
425
 
431
426
  // src/orchestrator.ts
432
- import path3 from "path";
427
+ import path2 from "path";
433
428
  import os from "os";
434
429
  import { createHash, randomBytes } from "crypto";
435
430
  import { existsSync } from "fs";
@@ -971,1096 +966,6 @@ function getTaxonomyFilePath(memoryDir) {
971
966
  return path.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);
972
967
  }
973
968
 
974
- // src/wearables/trust.ts
975
- var TRUST_JUDGE_ACCEPT_BOOST = 0.15;
976
- var TRUST_CROSS_SOURCE_BOOST = 0.15;
977
- var TRUST_SUPPORTING_MEMORY_BOOST = 0.1;
978
- var MIN_FACT_TOKENS = 4;
979
- var CROSS_SOURCE_COVERAGE = 0.6;
980
- var MEMORY_SUPPORT_COVERAGE = 0.7;
981
- var MAX_MEMORIES_SCANNED = 5e3;
982
- function computeTrustScore(input) {
983
- const confidence = typeof input.extractionConfidence === "number" && Number.isFinite(input.extractionConfidence) ? Math.min(1, Math.max(0, input.extractionConfidence)) : 0.7;
984
- let trust = confidence * Math.min(1, Math.max(0, input.sourceTrust));
985
- if (input.judgeVerdict === "accept") trust += TRUST_JUDGE_ACCEPT_BOOST;
986
- if (input.evidence.corroboratedBySources.length > 0) {
987
- trust += TRUST_CROSS_SOURCE_BOOST;
988
- }
989
- if (input.evidence.supportingMemoryId !== void 0) {
990
- trust += TRUST_SUPPORTING_MEMORY_BOOST;
991
- }
992
- return Math.min(1, Math.max(0, trust));
993
- }
994
- function tokenizeDayBody(body) {
995
- return new Set(normalizeRecallTokens(body));
996
- }
997
- function findCorroboration(factText, context) {
998
- const factTokens = normalizeRecallTokens(factText);
999
- const evidence = { corroboratedBySources: [] };
1000
- if (factTokens.length < MIN_FACT_TOKENS) return evidence;
1001
- const factTokenSet = new Set(factTokens);
1002
- for (const [sourceId, dayTokens] of context.otherSourceDayTokens) {
1003
- let matches = 0;
1004
- for (const token of factTokenSet) {
1005
- if (dayTokens.has(token)) matches += 1;
1006
- }
1007
- if (matches / factTokenSet.size >= CROSS_SOURCE_COVERAGE) {
1008
- evidence.corroboratedBySources.push(sourceId);
1009
- }
1010
- }
1011
- evidence.corroboratedBySources.sort();
1012
- let scanned = 0;
1013
- for (const memory of context.existingMemories) {
1014
- if (scanned >= MAX_MEMORIES_SCANNED) break;
1015
- scanned += 1;
1016
- const matches = countRecallTokenOverlap(factTokenSet, memory.content);
1017
- if (matches / factTokenSet.size >= MEMORY_SUPPORT_COVERAGE) {
1018
- evidence.supportingMemoryId = memory.id;
1019
- break;
1020
- }
1021
- }
1022
- return evidence;
1023
- }
1024
- function decideSmart(trust, judgeVerdict, thresholds) {
1025
- if (judgeVerdict === "reject") {
1026
- return { outcome: "drop", reason: "judge-rejected", trust };
1027
- }
1028
- if (judgeVerdict === "defer") {
1029
- return { outcome: "review", reason: "judge-deferred", trust };
1030
- }
1031
- if (trust >= thresholds.autoApproveTrust) {
1032
- return { outcome: "active", reason: "auto-approved", trust };
1033
- }
1034
- if (trust >= thresholds.reviewTrust) {
1035
- return { outcome: "review", reason: "queued-for-review", trust };
1036
- }
1037
- return { outcome: "drop", reason: "below-trust", trust };
1038
- }
1039
-
1040
- // src/wearables/memory-gen.ts
1041
- function memoryStatusForMode(mode) {
1042
- return mode === "auto" || mode === "smart" ? "active" : "pending_review";
1043
- }
1044
- var WEARABLE_SOURCE_PREFIX = "wearable";
1045
- function wearableSourceLabel(sourceId) {
1046
- return `${WEARABLE_SOURCE_PREFIX}:${sourceId}`;
1047
- }
1048
- function wearableDayTag(date) {
1049
- return `wearable-day:${date}`;
1050
- }
1051
- var IMPORTANCE_RANK = {
1052
- trivial: 0,
1053
- low: 1,
1054
- normal: 2,
1055
- high: 3,
1056
- critical: 4
1057
- };
1058
- var MAX_EXTRACTION_CHUNK_CHARS = 6e3;
1059
- var MIN_CONVERSATION_CHARS = 80;
1060
- function buildExtractionTurns(sourceId, date, conversation, registry) {
1061
- const headerParts = [
1062
- `Wearable transcript (${sourceId}) \u2014 ${date}`,
1063
- conversation.title ? `"${conversation.title}"` : void 0,
1064
- conversation.location ? `at ${conversation.location}` : void 0
1065
- ].filter((part) => typeof part === "string");
1066
- const header = `[${headerParts.join(" \u2014 ")}]`;
1067
- const lines = [];
1068
- for (const segment of conversation.segments) {
1069
- const { label } = resolveSpeaker(sourceId, segment, registry);
1070
- lines.push(`${label}: ${segment.text}`);
1071
- }
1072
- const transcript = lines.join("\n");
1073
- if (transcript.trim().length < MIN_CONVERSATION_CHARS) return [];
1074
- const sessionKey = `wearables:${sourceId}:${date}:${conversation.id}`;
1075
- const timestamp = conversation.startIso;
1076
- const turns = [];
1077
- let chunkLines = [];
1078
- let chunkChars = 0;
1079
- const flush = () => {
1080
- if (chunkLines.length === 0) return;
1081
- turns.push({
1082
- role: "user",
1083
- content: `${header}
1084
- ${chunkLines.join("\n")}`,
1085
- timestamp,
1086
- sourceValidAt: timestamp,
1087
- sessionKey
1088
- });
1089
- chunkLines = [];
1090
- chunkChars = 0;
1091
- };
1092
- for (const line of transcript.split("\n")) {
1093
- if (chunkChars + line.length + 1 > MAX_EXTRACTION_CHUNK_CHARS) flush();
1094
- chunkLines.push(line);
1095
- chunkChars += line.length + 1;
1096
- }
1097
- flush();
1098
- return turns;
1099
- }
1100
- async function scoreCandidates(novel, settings, deps, result) {
1101
- const scored = /* @__PURE__ */ new Map();
1102
- if (novel.length === 0) return scored;
1103
- let verdicts;
1104
- if (deps.judgeFacts) {
1105
- const judgeCandidates = novel.map((candidate) => ({
1106
- text: candidate.fact.content,
1107
- category: candidate.fact.category,
1108
- confidence: typeof candidate.fact.confidence === "number" ? candidate.fact.confidence : 0.7,
1109
- tags: candidate.fact.tags ?? [],
1110
- importanceLevel: candidate.importance.level
1111
- }));
1112
- try {
1113
- const judgeResult = await deps.judgeFacts(judgeCandidates);
1114
- verdicts = /* @__PURE__ */ new Map();
1115
- for (const [index, verdict] of judgeResult.verdicts) {
1116
- verdicts.set(index, getVerdictKind(verdict));
1117
- }
1118
- } catch (err) {
1119
- result.warnings.push(
1120
- `extraction judge unavailable for this pass: ${describeErrorForOperator(err)} \u2014 trust scoring continued without judge verdicts`
1121
- );
1122
- }
1123
- }
1124
- const corroboration = deps.corroboration ?? {
1125
- otherSourceDayTokens: /* @__PURE__ */ new Map(),
1126
- existingMemories: []
1127
- };
1128
- novel.forEach((candidate, index) => {
1129
- const evidence = findCorroboration(candidate.fact.content, corroboration);
1130
- const verdict = verdicts?.get(index);
1131
- const trust = computeTrustScore({
1132
- extractionConfidence: candidate.fact.confidence,
1133
- sourceTrust: settings.sourceTrust,
1134
- judgeVerdict: verdict,
1135
- evidence
1136
- });
1137
- scored.set(index, { trust, ...verdict !== void 0 ? { verdict } : {}, evidence });
1138
- });
1139
- return scored;
1140
- }
1141
- async function generateWearableMemories(sourceId, date, conversations, settings, registry, deps) {
1142
- const result = {
1143
- created: 0,
1144
- promoted: 0,
1145
- demoted: 0,
1146
- skipped: 0,
1147
- skippedByReason: {},
1148
- warnings: [],
1149
- completed: true
1150
- };
1151
- if (settings.memoryMode === "off") return result;
1152
- const skip = (reason, count = 1) => {
1153
- result.skipped += count;
1154
- result.skippedByReason[reason] = (result.skippedByReason[reason] ?? 0) + count;
1155
- };
1156
- const candidates = [];
1157
- const seenContent = /* @__PURE__ */ new Set();
1158
- for (const conversation of conversations) {
1159
- const turns = buildExtractionTurns(sourceId, date, conversation, registry);
1160
- if (turns.length === 0) continue;
1161
- let extraction;
1162
- try {
1163
- extraction = await deps.extract(turns);
1164
- } catch (err) {
1165
- result.warnings.push(
1166
- `extraction failed for ${sourceId}/${date} (conversation ${conversation.id}): ${describeErrorForOperator(err)} \u2014 the memory pass for this day retries on the next sync`
1167
- );
1168
- result.completed = false;
1169
- break;
1170
- }
1171
- for (const fact of extraction.facts) {
1172
- const content = fact.content?.trim();
1173
- if (!content) {
1174
- skip("empty");
1175
- continue;
1176
- }
1177
- if (fact.category === "procedure" || fact.category === "reasoning_trace") {
1178
- skip("unsupported-category");
1179
- continue;
1180
- }
1181
- if (settings.memoryMode !== "smart" && typeof fact.confidence === "number" && fact.confidence < settings.minConfidence) {
1182
- skip("below-confidence");
1183
- continue;
1184
- }
1185
- const importance = scoreImportance(content, fact.category, fact.tags ?? []);
1186
- if (IMPORTANCE_RANK[importance.level] < IMPORTANCE_RANK[settings.minImportance]) {
1187
- skip("below-importance");
1188
- continue;
1189
- }
1190
- const dedupKey = content.toLowerCase();
1191
- if (seenContent.has(dedupKey)) {
1192
- skip("duplicate-in-run");
1193
- continue;
1194
- }
1195
- seenContent.add(dedupKey);
1196
- candidates.push({ fact: { ...fact, content }, importance, conversation });
1197
- }
1198
- }
1199
- const novel = [];
1200
- const promotable = [];
1201
- for (const candidate of candidates) {
1202
- if (await deps.writer.hasFactContentHash(candidate.fact.content)) {
1203
- if (settings.memoryMode === "smart" && deps.writer.findWearableMemoryByContent !== void 0 && deps.writer.promoteWearableMemory !== void 0) {
1204
- promotable.push(candidate);
1205
- } else {
1206
- skip("duplicate-existing");
1207
- }
1208
- continue;
1209
- }
1210
- novel.push(candidate);
1211
- }
1212
- if (promotable.length > 0) {
1213
- const promoteScores = await scoreCandidates(promotable, settings, deps, result);
1214
- for (const [index, candidate] of promotable.entries()) {
1215
- const scored = promoteScores.get(index);
1216
- const decision = scored ? decideSmart(scored.trust, scored.verdict, settings) : void 0;
1217
- if (!scored || !decision) {
1218
- skip("duplicate-existing");
1219
- continue;
1220
- }
1221
- if (scored.verdict === "reject") {
1222
- if (deps.writer.demoteWearableMemory !== void 0) {
1223
- const existingForDemote = await deps.writer.findWearableMemoryByContent(
1224
- candidate.fact.content
1225
- );
1226
- if (existingForDemote && existingForDemote.status === "pending_review" && await deps.writer.demoteWearableMemory(existingForDemote.id, {
1227
- trustScore: scored.trust.toFixed(3),
1228
- trustDecision: "demoted-by-rejection",
1229
- judgeVerdict: "reject"
1230
- })) {
1231
- result.demoted += 1;
1232
- continue;
1233
- }
1234
- }
1235
- skip("duplicate-existing");
1236
- continue;
1237
- }
1238
- if (decision.outcome !== "active") {
1239
- skip("duplicate-existing");
1240
- continue;
1241
- }
1242
- const existing = await deps.writer.findWearableMemoryByContent(
1243
- candidate.fact.content
1244
- );
1245
- if (!existing || existing.status !== "pending_review") {
1246
- skip("duplicate-existing");
1247
- continue;
1248
- }
1249
- const promoted = await deps.writer.promoteWearableMemory(
1250
- existing.id,
1251
- {
1252
- trustScore: scored.trust.toFixed(3),
1253
- trustDecision: "promoted-by-corroboration",
1254
- ...scored.verdict !== void 0 ? { judgeVerdict: scored.verdict } : {},
1255
- ...scored.evidence.corroboratedBySources.length > 0 ? { corroboratedBySources: scored.evidence.corroboratedBySources.join(",") } : {},
1256
- ...scored.evidence.supportingMemoryId !== void 0 ? { supportingMemoryId: scored.evidence.supportingMemoryId } : {}
1257
- },
1258
- scored.trust
1259
- );
1260
- if (promoted) {
1261
- result.promoted += 1;
1262
- } else {
1263
- skip("duplicate-existing");
1264
- }
1265
- }
1266
- }
1267
- let trustById = /* @__PURE__ */ new Map();
1268
- if (settings.memoryMode === "smart") {
1269
- trustById = await scoreCandidates(novel, settings, deps, result);
1270
- }
1271
- const modeStatus = memoryStatusForMode(settings.memoryMode);
1272
- const writable = [];
1273
- novel.forEach((candidate, index) => {
1274
- if (settings.memoryMode !== "smart") {
1275
- writable.push({ candidate, index, status: modeStatus, trustAttributes: {} });
1276
- return;
1277
- }
1278
- const scored = trustById.get(index);
1279
- if (!scored) return;
1280
- const decision = decideSmart(scored.trust, scored.verdict, settings);
1281
- if (decision.outcome === "drop") {
1282
- skip(decision.reason);
1283
- return;
1284
- }
1285
- writable.push({
1286
- candidate,
1287
- index,
1288
- status: decision.outcome === "active" ? "active" : "pending_review",
1289
- trustAttributes: {
1290
- trustScore: scored.trust.toFixed(3),
1291
- trustDecision: decision.reason,
1292
- ...scored.verdict !== void 0 ? { judgeVerdict: scored.verdict } : {},
1293
- ...scored.evidence.corroboratedBySources.length > 0 ? { corroboratedBySources: scored.evidence.corroboratedBySources.join(",") } : {},
1294
- ...scored.evidence.supportingMemoryId !== void 0 ? { supportingMemoryId: scored.evidence.supportingMemoryId } : {}
1295
- }
1296
- });
1297
- });
1298
- const strength = (entry) => settings.memoryMode === "smart" ? trustById.get(entry.index)?.trust ?? 0 : entry.candidate.importance.score;
1299
- writable.sort((a, b) => {
1300
- const sa = strength(a);
1301
- const sb = strength(b);
1302
- if (sa > sb) return -1;
1303
- if (sa < sb) return 1;
1304
- if (a.candidate.fact.content < b.candidate.fact.content) return -1;
1305
- if (a.candidate.fact.content > b.candidate.fact.content) return 1;
1306
- return 0;
1307
- });
1308
- const cap = settings.maxMemoriesPerDay;
1309
- const kept = cap > 0 ? writable.slice(0, cap) : writable;
1310
- if (writable.length > kept.length) {
1311
- skip("over-day-cap", writable.length - kept.length);
1312
- }
1313
- for (const { candidate, index, status, trustAttributes } of kept) {
1314
- const tags = [
1315
- .../* @__PURE__ */ new Set([
1316
- ...candidate.fact.tags ?? [],
1317
- WEARABLE_SOURCE_PREFIX,
1318
- wearableSourceLabel(sourceId),
1319
- wearableDayTag(date)
1320
- ])
1321
- ];
1322
- await deps.writer.writeMemory(candidate.fact.category, candidate.fact.content, {
1323
- confidence: settings.memoryMode === "smart" ? trustById.get(index)?.trust : candidate.fact.confidence,
1324
- tags,
1325
- source: wearableSourceLabel(sourceId),
1326
- importance: candidate.importance,
1327
- validAt: candidate.conversation.startIso,
1328
- structuredAttributes: {
1329
- ...candidate.fact.structuredAttributes ?? {},
1330
- wearableSource: sourceId,
1331
- wearableDate: date,
1332
- wearableConversationId: candidate.conversation.id,
1333
- ...trustAttributes
1334
- },
1335
- contentHashSource: candidate.fact.content,
1336
- status
1337
- });
1338
- result.created += 1;
1339
- }
1340
- return result;
1341
- }
1342
- async function writeDailyDigestMemory(sourceId, date, conversations, settings, registry, writer) {
1343
- if (settings.memoryMode === "off") return false;
1344
- if (conversations.length === 0) return false;
1345
- const lines = conversations.map((conversation) => {
1346
- const title = conversation.title?.trim() || "Untitled conversation";
1347
- const speakers = new Set(
1348
- conversation.segments.map(
1349
- (segment) => resolveSpeaker(sourceId, segment, registry).label
1350
- )
1351
- );
1352
- return `- ${title} (${speakers.size} speaker${speakers.size === 1 ? "" : "s"})`;
1353
- });
1354
- const content = `Wearable day digest \u2014 ${sourceId}, ${date}: ${conversations.length} recorded conversation${conversations.length === 1 ? "" : "s"}.
1355
- ` + lines.join("\n");
1356
- if (await writer.hasFactContentHash(content)) return false;
1357
- await writer.writeMemory("moment", content, {
1358
- confidence: 0.9,
1359
- tags: [
1360
- WEARABLE_SOURCE_PREFIX,
1361
- wearableSourceLabel(sourceId),
1362
- wearableDayTag(date),
1363
- "daily-digest"
1364
- ],
1365
- source: wearableSourceLabel(sourceId),
1366
- importance: scoreImportance(content, "moment", ["daily-digest"]),
1367
- validAt: `${date}T00:00:00.000Z`,
1368
- structuredAttributes: {
1369
- wearableSource: sourceId,
1370
- wearableDate: date
1371
- },
1372
- contentHashSource: content,
1373
- status: memoryStatusForMode(settings.memoryMode),
1374
- memoryKind: "episode"
1375
- });
1376
- return true;
1377
- }
1378
- var NATIVE_TRUST_FACTOR = 0.9;
1379
- async function importNativeMemories(sourceId, memories, alreadyImportedIds, settings, deps) {
1380
- let imported = 0;
1381
- const importedIds = [];
1382
- const warnings = [];
1383
- const seenContent = /* @__PURE__ */ new Set();
1384
- const smart = settings.importNativeMemories === "smart";
1385
- const novel = [];
1386
- for (const memory of memories) {
1387
- const content = memory.content?.trim();
1388
- if (!content) continue;
1389
- if (alreadyImportedIds.has(memory.id)) continue;
1390
- if (seenContent.has(content) || await deps.writer.hasFactContentHash(content)) {
1391
- importedIds.push(memory.id);
1392
- continue;
1393
- }
1394
- seenContent.add(content);
1395
- novel.push({ ...memory, content });
1396
- }
1397
- let verdicts;
1398
- if (smart && deps.judgeFacts && novel.length > 0) {
1399
- try {
1400
- const judgeResult = await deps.judgeFacts(
1401
- novel.map((memory) => ({
1402
- text: memory.content,
1403
- category: "fact",
1404
- confidence: 0.7,
1405
- tags: memory.tags ?? []
1406
- }))
1407
- );
1408
- verdicts = /* @__PURE__ */ new Map();
1409
- for (const [index, verdict] of judgeResult.verdicts) {
1410
- verdicts.set(index, getVerdictKind(verdict));
1411
- }
1412
- } catch (err) {
1413
- warnings.push(
1414
- `extraction judge unavailable for native import: ${describeErrorForOperator(err)} \u2014 trust scoring continued without judge verdicts`
1415
- );
1416
- }
1417
- }
1418
- const corroboration = deps.corroboration ?? {
1419
- otherSourceDayTokens: /* @__PURE__ */ new Map(),
1420
- existingMemories: []
1421
- };
1422
- for (const [index, memory] of novel.entries()) {
1423
- const content = memory.content;
1424
- let status = "pending_review";
1425
- let trustAttributes = {};
1426
- let confidence = 0.6;
1427
- if (smart) {
1428
- const evidence = findCorroboration(content, corroboration);
1429
- const verdict = verdicts?.get(index);
1430
- const trust = computeTrustScore({
1431
- extractionConfidence: void 0,
1432
- sourceTrust: settings.sourceTrust * NATIVE_TRUST_FACTOR,
1433
- judgeVerdict: verdict,
1434
- evidence
1435
- });
1436
- const decision = decideSmart(trust, verdict, settings);
1437
- if (decision.outcome === "drop") {
1438
- continue;
1439
- }
1440
- status = decision.outcome === "active" ? "active" : "pending_review";
1441
- confidence = trust;
1442
- trustAttributes = {
1443
- trustScore: trust.toFixed(3),
1444
- trustDecision: decision.reason,
1445
- ...verdict !== void 0 ? { judgeVerdict: verdict } : {},
1446
- ...evidence.corroboratedBySources.length > 0 ? { corroboratedBySources: evidence.corroboratedBySources.join(",") } : {},
1447
- ...evidence.supportingMemoryId !== void 0 ? { supportingMemoryId: evidence.supportingMemoryId } : {}
1448
- };
1449
- }
1450
- await deps.writer.writeMemory("fact", content, {
1451
- confidence,
1452
- tags: [
1453
- .../* @__PURE__ */ new Set([
1454
- ...memory.tags ?? [],
1455
- WEARABLE_SOURCE_PREFIX,
1456
- wearableSourceLabel(sourceId),
1457
- "native-import"
1458
- ])
1459
- ],
1460
- source: `${wearableSourceLabel(sourceId)}:native`,
1461
- importance: scoreImportance(content, "fact", memory.tags ?? []),
1462
- validAt: memory.createdIso,
1463
- structuredAttributes: {
1464
- wearableSource: sourceId,
1465
- wearableNativeId: memory.id,
1466
- ...trustAttributes
1467
- },
1468
- contentHashSource: content,
1469
- status
1470
- });
1471
- imported += 1;
1472
- importedIds.push(memory.id);
1473
- }
1474
- return { imported, importedIds, warnings };
1475
- }
1476
-
1477
- // src/wearables/cleanup.ts
1478
- var MERGE_GAP_MS = 3e4;
1479
- var FILLER_TOKENS = ["um", "uh", "uhm", "umm", "uhh", "erm", "hmm", "mhm"];
1480
- var FILLER_PATTERN = new RegExp(
1481
- // Leading/trailing punctuation around the filler collapses with it so
1482
- // "Um, so we should" -> "so we should" rather than ", so we should".
1483
- `(?:^|\\s)(?:${FILLER_TOKENS.join("|")})[,.]?(?=\\s|$)`,
1484
- "gi"
1485
- );
1486
- function cleanConversation(conversation, settings) {
1487
- let segments = conversation.segments.map((segment) => ({ ...segment }));
1488
- let droppedSegments = 0;
1489
- let mergedSegments = 0;
1490
- if (settings.stripFillers) {
1491
- for (const segment of segments) {
1492
- segment.text = stripFillerTokens(segment.text);
1493
- }
1494
- }
1495
- if (settings.collapseRepeats) {
1496
- for (const segment of segments) {
1497
- segment.text = collapseImmediateRepeats(segment.text);
1498
- }
1499
- }
1500
- for (const segment of segments) {
1501
- segment.text = normalizeWhitespace(segment.text);
1502
- }
1503
- if (settings.dropLowQuality) {
1504
- const kept = [];
1505
- for (const segment of segments) {
1506
- if (isLowQualitySegment(segment.text)) {
1507
- droppedSegments += 1;
1508
- } else {
1509
- kept.push(segment);
1510
- }
1511
- }
1512
- segments = kept;
1513
- } else {
1514
- const kept = segments.filter((segment) => segment.text.length > 0);
1515
- droppedSegments += segments.length - kept.length;
1516
- segments = kept;
1517
- }
1518
- if (settings.mergeSameSpeaker) {
1519
- const merged = [];
1520
- for (const segment of segments) {
1521
- const previous = merged[merged.length - 1];
1522
- if (previous && canMerge(previous, segment)) {
1523
- previous.text = `${previous.text} ${segment.text}`.trim();
1524
- if (segment.endIso) previous.endIso = segment.endIso;
1525
- mergedSegments += 1;
1526
- } else {
1527
- merged.push(segment);
1528
- }
1529
- }
1530
- segments = merged;
1531
- }
1532
- return {
1533
- conversation: { ...conversation, segments },
1534
- droppedSegments,
1535
- mergedSegments
1536
- };
1537
- }
1538
- function canMerge(previous, next) {
1539
- if (previous.speakerKey !== next.speakerKey) return false;
1540
- const previousEnd = previous.endIso ? Date.parse(previous.endIso) : NaN;
1541
- const nextStart = next.startIso ? Date.parse(next.startIso) : NaN;
1542
- if (Number.isNaN(previousEnd) || Number.isNaN(nextStart)) return true;
1543
- return nextStart - previousEnd <= MERGE_GAP_MS;
1544
- }
1545
- function stripFillerTokens(text) {
1546
- return normalizeWhitespace(text.replace(FILLER_PATTERN, " "));
1547
- }
1548
- function collapseImmediateRepeats(text) {
1549
- const words = text.split(/\s+/).filter((word) => word.length > 0);
1550
- if (words.length < 2) return text.trim();
1551
- const out = [];
1552
- let index = 0;
1553
- while (index < words.length) {
1554
- out.push(words[index]);
1555
- index += 1;
1556
- let matched = true;
1557
- while (matched) {
1558
- matched = false;
1559
- for (let size = 4; size >= 1; size--) {
1560
- if (out.length < size || index + size > words.length) continue;
1561
- const tail = out.slice(-size).join(" ").toLowerCase();
1562
- if (!/\p{L}/u.test(tail)) continue;
1563
- const ahead = words.slice(index, index + size).join(" ").toLowerCase();
1564
- if (tail === ahead) {
1565
- index += size;
1566
- matched = true;
1567
- break;
1568
- }
1569
- }
1570
- }
1571
- }
1572
- return out.join(" ");
1573
- }
1574
- function isLowQualitySegment(text) {
1575
- const trimmed = text.trim();
1576
- if (trimmed.length === 0) return true;
1577
- if (/^(.)\1{4,}$/.test(trimmed)) return true;
1578
- const letters = trimmed.replace(/[^\p{L}\p{N}]/gu, "");
1579
- if (letters.length === 0) return true;
1580
- if (trimmed.length >= 12 && letters.length / trimmed.length < 0.3) {
1581
- return true;
1582
- }
1583
- const words = trimmed.toLowerCase().split(/\s+/);
1584
- if (words.length >= 5) {
1585
- const unique = new Set(words);
1586
- if (unique.size === 1) return true;
1587
- }
1588
- return false;
1589
- }
1590
- function normalizeWhitespace(text) {
1591
- return text.replace(/\s+/g, " ").trim();
1592
- }
1593
-
1594
- // src/wearables/sync-state.ts
1595
- import { promises as fsPromises } from "fs";
1596
- import * as path2 from "path";
1597
- var MAX_TRACKED_NATIVE_IDS = 5e3;
1598
- var MAX_TRACKED_DAY_HASHES = 800;
1599
- function syncStateFilePath(memoryDir) {
1600
- return path2.join(memoryDir, "state", "wearables", "sync.json");
1601
- }
1602
- function emptySyncState() {
1603
- return { version: 1, sources: {} };
1604
- }
1605
- async function loadSyncState(memoryDir) {
1606
- const filePath = syncStateFilePath(memoryDir);
1607
- let raw;
1608
- try {
1609
- raw = await fsPromises.readFile(filePath, "utf-8");
1610
- } catch (err) {
1611
- if (err.code === "ENOENT") {
1612
- return emptySyncState();
1613
- }
1614
- throw err;
1615
- }
1616
- let parsed;
1617
- try {
1618
- parsed = JSON.parse(raw);
1619
- } catch {
1620
- return emptySyncState();
1621
- }
1622
- if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed) || typeof parsed.sources !== "object" || parsed.sources === null) {
1623
- return emptySyncState();
1624
- }
1625
- return { version: 1, sources: parsed.sources };
1626
- }
1627
- async function saveSyncState(memoryDir, state) {
1628
- const filePath = syncStateFilePath(memoryDir);
1629
- await fsPromises.mkdir(path2.dirname(filePath), { recursive: true });
1630
- const tmpPath = `${filePath}.tmp-${process.pid}-${Date.now().toString(36)}`;
1631
- await fsPromises.writeFile(
1632
- tmpPath,
1633
- `${JSON.stringify(state, null, 2)}
1634
- `,
1635
- "utf-8"
1636
- );
1637
- try {
1638
- await fsPromises.rename(tmpPath, filePath);
1639
- } catch (err) {
1640
- await fsPromises.unlink(tmpPath).catch(() => void 0);
1641
- throw err;
1642
- }
1643
- }
1644
- function updateSourceSyncState(state, sourceId, update) {
1645
- const previous = state.sources[sourceId];
1646
- const mergedHashes = {
1647
- ...previous?.dayHashes ?? {},
1648
- ...update.dayHashes
1649
- };
1650
- const hashKeys = Object.keys(mergedHashes).sort();
1651
- while (hashKeys.length > MAX_TRACKED_DAY_HASHES) {
1652
- const oldest = hashKeys.shift();
1653
- if (oldest === void 0) break;
1654
- delete mergedHashes[oldest];
1655
- }
1656
- const mergedMemoryHashes = {
1657
- ...previous?.memoryDayHashes ?? {},
1658
- ...update.memoryDayHashes ?? {}
1659
- };
1660
- for (const day of update.clearMemoryDays ?? []) {
1661
- if (!(day in (update.memoryDayHashes ?? {}))) {
1662
- delete mergedMemoryHashes[day];
1663
- }
1664
- }
1665
- const memoryHashKeys = Object.keys(mergedMemoryHashes).sort();
1666
- while (memoryHashKeys.length > MAX_TRACKED_DAY_HASHES) {
1667
- const oldest = memoryHashKeys.shift();
1668
- if (oldest === void 0) break;
1669
- delete mergedMemoryHashes[oldest];
1670
- }
1671
- const mergedNativeIds = [
1672
- ...previous?.importedNativeMemoryIds ?? [],
1673
- ...update.importedNativeMemoryIds ?? []
1674
- ];
1675
- const dedupedNativeIds = [...new Set(mergedNativeIds)];
1676
- const boundedNativeIds = dedupedNativeIds.length > MAX_TRACKED_NATIVE_IDS ? dedupedNativeIds.slice(dedupedNativeIds.length - MAX_TRACKED_NATIVE_IDS) : dedupedNativeIds;
1677
- const sortedDays = [...update.days].sort();
1678
- const latestDay = sortedDays[sortedDays.length - 1];
1679
- const lastDateSynced = latestDay !== void 0 && (!previous || previous.lastDateSynced < latestDay) ? latestDay : previous?.lastDateSynced ?? latestDay ?? "";
1680
- return {
1681
- version: 1,
1682
- sources: {
1683
- ...state.sources,
1684
- [sourceId]: {
1685
- lastSyncAt: update.syncedAt,
1686
- lastDateSynced,
1687
- dayHashes: mergedHashes,
1688
- memoryDayHashes: mergedMemoryHashes,
1689
- importedNativeMemoryIds: boundedNativeIds
1690
- }
1691
- }
1692
- };
1693
- }
1694
-
1695
- // src/wearables/pipeline.ts
1696
- var MAX_PAGES_PER_DAY = 50;
1697
- var MAX_NATIVE_PAGES = 20;
1698
- var DEFAULT_SYNC_DAYS = 2;
1699
- var MAX_SYNC_DAYS = 90;
1700
- function dateInTimezone(date, timezone) {
1701
- try {
1702
- const parts = new Intl.DateTimeFormat("en-CA", {
1703
- timeZone: timezone,
1704
- year: "numeric",
1705
- month: "2-digit",
1706
- day: "2-digit"
1707
- }).formatToParts(date);
1708
- const get = (type) => parts.find((part) => part.type === type)?.value ?? "";
1709
- return `${get("year")}-${get("month")}-${get("day")}`;
1710
- } catch {
1711
- return date.toISOString().slice(0, 10);
1712
- }
1713
- }
1714
- function resolveSyncDates(options, timezone, now) {
1715
- if (options.date !== void 0) {
1716
- if (!isValidTranscriptDate(options.date)) {
1717
- throw new WearablesInputError(
1718
- `wearables sync: invalid date '${options.date}' \u2014 expected YYYY-MM-DD`
1719
- );
1720
- }
1721
- return [options.date];
1722
- }
1723
- let days = DEFAULT_SYNC_DAYS;
1724
- if (options.days !== void 0) {
1725
- if (!Number.isFinite(options.days) || !Number.isInteger(options.days) || options.days < 1 || options.days > MAX_SYNC_DAYS) {
1726
- throw new WearablesInputError(
1727
- `wearables sync: invalid days '${options.days}' \u2014 expected an integer between 1 and ${MAX_SYNC_DAYS}`
1728
- );
1729
- }
1730
- days = options.days;
1731
- }
1732
- const dates = [];
1733
- let cursor = dateInTimezone(now, timezone);
1734
- for (let count = 0; count < days; count++) {
1735
- dates.unshift(cursor);
1736
- cursor = previousIsoDate(cursor);
1737
- }
1738
- return dates;
1739
- }
1740
- function previousIsoDate(date) {
1741
- const parsed = /* @__PURE__ */ new Date(`${date}T00:00:00Z`);
1742
- parsed.setUTCDate(parsed.getUTCDate() - 1);
1743
- return parsed.toISOString().slice(0, 10);
1744
- }
1745
- async function fetchAllConversationsForDate(connector, date, timezone, signal, warnings) {
1746
- const conversations = [];
1747
- let cursor = void 0;
1748
- for (let page = 0; page < MAX_PAGES_PER_DAY; page++) {
1749
- const result = await connector.fetchConversations({
1750
- date,
1751
- timezone,
1752
- cursor,
1753
- signal
1754
- });
1755
- conversations.push(...result.conversations);
1756
- if (!result.nextCursor) return { conversations, partial: false };
1757
- cursor = result.nextCursor;
1758
- }
1759
- warnings.push(
1760
- `${connector.id}: stopped paginating ${date} after ${MAX_PAGES_PER_DAY} pages \u2014 day may be partially synced (every sync refetches and re-warns until the provider day fits the cap)`
1761
- );
1762
- return { conversations, partial: true };
1763
- }
1764
- var PARTIAL_DAY_MARKER = "\n*Note: pagination safety cap reached during sync \u2014 this day may be incomplete.*\n";
1765
- function emptyDayBody(sourceId, date) {
1766
- return `# ${sourceId} transcript \u2014 ${date}
1767
-
1768
- _No storable conversation content for this day (all segments were elided or dropped)._
1769
- `;
1770
- }
1771
- function cleanDay(raw, sourceId, settings, config, userRedaction, correctionRules) {
1772
- const out = {
1773
- conversations: [],
1774
- segmentsKept: 0,
1775
- segmentsDropped: 0,
1776
- redactions: 0,
1777
- correctionsApplied: 0
1778
- };
1779
- for (const conversation of raw) {
1780
- let current = conversation;
1781
- if (config.offTheRecordEnabled) {
1782
- const otr = applyOffTheRecord(current);
1783
- current = otr.conversation;
1784
- out.segmentsDropped += otr.droppedSegments;
1785
- }
1786
- const cleaned = cleanConversation(current, settings.cleanup);
1787
- current = cleaned.conversation;
1788
- out.segmentsDropped += cleaned.droppedSegments;
1789
- const segments = current.segments.map((segment) => {
1790
- let text = segment.text;
1791
- if (config.redactionEnabled) {
1792
- const redacted = redactText(text, userRedaction);
1793
- text = redacted.text;
1794
- out.redactions += redacted.redactions;
1795
- }
1796
- const corrected = applyCorrections(text, correctionRules, sourceId);
1797
- out.correctionsApplied += corrected.applied;
1798
- return { ...segment, text: corrected.text };
1799
- });
1800
- current = { ...current, segments };
1801
- if (current.segments.length > 0) {
1802
- out.conversations.push(current);
1803
- out.segmentsKept += current.segments.length;
1804
- }
1805
- }
1806
- return out;
1807
- }
1808
- async function syncWearableSource(connector, settings, config, options, deps) {
1809
- const now = deps.now ? deps.now() : /* @__PURE__ */ new Date();
1810
- const timezone = config.timezone ?? defaultTimezone();
1811
- const dates = resolveSyncDates(options, timezone, now);
1812
- const summary = {
1813
- source: connector.id,
1814
- days: dates,
1815
- conversations: 0,
1816
- segmentsKept: 0,
1817
- segmentsDropped: 0,
1818
- redactions: 0,
1819
- correctionsApplied: 0,
1820
- transcriptsWritten: [],
1821
- memoriesCreated: 0,
1822
- memoriesPromoted: 0,
1823
- memoriesDemoted: 0,
1824
- memoriesSkipped: 0,
1825
- nativeMemoriesImported: 0,
1826
- warnings: []
1827
- };
1828
- const registry = await loadSpeakerRegistry(deps.memoryDir);
1829
- const stateRules = await loadCorrectionsFile(deps.memoryDir);
1830
- const correctionRules = [
1831
- ...compileCorrectionRules(config.corrections, "wearables.corrections"),
1832
- ...compileCorrectionRules(stateRules, "state corrections")
1833
- ];
1834
- const userRedaction = compileRedactionPatterns(config.redactionPatterns);
1835
- let syncState = await loadSyncState(deps.memoryDir);
1836
- const previousState = syncState.sources[connector.id];
1837
- const dayHashes = {};
1838
- const memoryDayHashes = {};
1839
- const failedMemoryDays = [];
1840
- const importedNativeIds = [];
1841
- for (const date of dates) {
1842
- const fetched = await fetchAllConversationsForDate(
1843
- connector,
1844
- date,
1845
- timezone,
1846
- options.signal,
1847
- summary.warnings
1848
- );
1849
- const cleaned = cleanDay(
1850
- fetched.conversations,
1851
- connector.id,
1852
- settings,
1853
- config,
1854
- userRedaction,
1855
- correctionRules
1856
- );
1857
- summary.conversations += cleaned.conversations.length;
1858
- summary.segmentsKept += cleaned.segmentsKept;
1859
- summary.segmentsDropped += cleaned.segmentsDropped;
1860
- summary.redactions += cleaned.redactions;
1861
- summary.correctionsApplied += cleaned.correctionsApplied;
1862
- if (fetched.conversations.length === 0) {
1863
- const existing = await deps.readDayContentHash(connector.id, date);
1864
- if (existing !== null) {
1865
- summary.warnings.push(
1866
- `${connector.id}: provider returned no conversations for ${date} but a stored transcript exists \u2014 leaving it in place; delete the day file manually if the recordings were intentionally removed upstream`
1867
- );
1868
- }
1869
- continue;
1870
- }
1871
- const allElided = cleaned.conversations.length === 0;
1872
- let body = allElided ? emptyDayBody(connector.id, date) : composeDayTranscriptBody(
1873
- connector.id,
1874
- date,
1875
- timezone,
1876
- cleaned.conversations,
1877
- registry
1878
- );
1879
- if (fetched.partial && !allElided) {
1880
- body += PARTIAL_DAY_MARKER;
1881
- }
1882
- const bodyHash = hashTranscriptBody(body);
1883
- const existingHash = await deps.readDayContentHash(connector.id, date);
1884
- const changed = existingHash !== bodyHash;
1885
- const shouldWrite = changed && (!allElided || existingHash !== null);
1886
- if (shouldWrite) {
1887
- const meta = composeDayTranscriptMeta(
1888
- connector.id,
1889
- date,
1890
- timezone,
1891
- cleaned.conversations,
1892
- registry,
1893
- body,
1894
- now.toISOString()
1895
- );
1896
- await deps.writeDayTranscript(
1897
- connector.id,
1898
- date,
1899
- serializeDayTranscript(meta, body)
1900
- );
1901
- summary.transcriptsWritten.push(date);
1902
- }
1903
- dayHashes[date] = bodyHash;
1904
- if (allElided) continue;
1905
- const needsSmartContext = settings.memoryMode === "smart" || settings.importNativeMemories === "smart";
1906
- const memoryPassComplete = previousState?.memoryDayHashes?.[date] === bodyHash;
1907
- if (settings.memoryMode !== "off" && (changed || options.forceMemories === true || !memoryPassComplete)) {
1908
- if (!deps.memoryGen) {
1909
- summary.warnings.push(
1910
- `${connector.id}: memoryMode is '${settings.memoryMode}' but no extraction engine is available in this context \u2014 transcripts synced, memories skipped`
1911
- );
1912
- } else {
1913
- let passClean = false;
1914
- try {
1915
- const corroboration = needsSmartContext ? await buildCorroborationContext(connector.id, date, deps) : void 0;
1916
- const dayMemoryGen = {
1917
- ...deps.memoryGen,
1918
- ...corroboration !== void 0 ? { corroboration } : {}
1919
- };
1920
- const generated = await generateWearableMemories(
1921
- connector.id,
1922
- date,
1923
- cleaned.conversations,
1924
- settings,
1925
- registry,
1926
- dayMemoryGen
1927
- );
1928
- summary.memoriesCreated += generated.created;
1929
- summary.memoriesPromoted += generated.promoted;
1930
- summary.memoriesDemoted += generated.demoted;
1931
- summary.memoriesSkipped += generated.skipped;
1932
- summary.warnings.push(...generated.warnings);
1933
- passClean = generated.completed;
1934
- if (config.digestEnabled) {
1935
- const wrote = await writeDailyDigestMemory(
1936
- connector.id,
1937
- date,
1938
- cleaned.conversations,
1939
- settings,
1940
- registry,
1941
- deps.memoryGen.writer
1942
- );
1943
- if (wrote) summary.memoriesCreated += 1;
1944
- }
1945
- } catch (err) {
1946
- passClean = false;
1947
- summary.warnings.push(
1948
- `${connector.id}: memory pass failed for ${date}: ${describeErrorForOperator(err)} \u2014 retries on the next sync`
1949
- );
1950
- }
1951
- if (passClean) {
1952
- memoryDayHashes[date] = bodyHash;
1953
- } else {
1954
- failedMemoryDays.push(date);
1955
- }
1956
- }
1957
- } else if (settings.memoryMode !== "off" && memoryPassComplete) {
1958
- memoryDayHashes[date] = bodyHash;
1959
- }
1960
- }
1961
- if (settings.importNativeMemories !== "off" && typeof connector.fetchNativeMemories === "function") {
1962
- if (!deps.memoryGen) {
1963
- summary.warnings.push(
1964
- `${connector.id}: importNativeMemories is enabled but no memory writer is available in this context`
1965
- );
1966
- } else {
1967
- const alreadyImported = new Set(
1968
- previousState?.importedNativeMemoryIds ?? []
1969
- );
1970
- const nativeCorroboration = settings.importNativeMemories === "smart" ? {
1971
- otherSourceDayTokens: /* @__PURE__ */ new Map(),
1972
- existingMemories: deps.listSupportMemories ? await deps.listSupportMemories() : []
1973
- } : void 0;
1974
- const nativeMemoryGen = {
1975
- ...deps.memoryGen,
1976
- ...nativeCorroboration !== void 0 ? { corroboration: nativeCorroboration } : {}
1977
- };
1978
- let cursor = void 0;
1979
- for (let page = 0; page < MAX_NATIVE_PAGES; page++) {
1980
- const result = await connector.fetchNativeMemories({
1981
- cursor,
1982
- signal: options.signal
1983
- });
1984
- const imported = await importNativeMemories(
1985
- connector.id,
1986
- result.memories,
1987
- alreadyImported,
1988
- settings,
1989
- nativeMemoryGen
1990
- );
1991
- summary.warnings.push(...imported.warnings);
1992
- summary.nativeMemoriesImported += imported.imported;
1993
- importedNativeIds.push(...imported.importedIds);
1994
- for (const id of imported.importedIds) alreadyImported.add(id);
1995
- if (!result.nextCursor) break;
1996
- cursor = result.nextCursor;
1997
- if (page === MAX_NATIVE_PAGES - 1) {
1998
- summary.warnings.push(
1999
- `${connector.id}: stopped native-memory import after ${MAX_NATIVE_PAGES} pages \u2014 remaining items import on the next sync`
2000
- );
2001
- }
2002
- }
2003
- }
2004
- }
2005
- const wroteAnything = summary.transcriptsWritten.length > 0 || summary.memoriesCreated > 0 || summary.memoriesPromoted > 0 || summary.memoriesDemoted > 0 || summary.nativeMemoriesImported > 0;
2006
- if (wroteAnything && deps.afterWrites) {
2007
- try {
2008
- await deps.afterWrites();
2009
- } catch (err) {
2010
- summary.warnings.push(
2011
- `search reindex failed (writes are stored and will index on the next update): ${describeErrorForOperator(err)}`
2012
- );
2013
- }
2014
- }
2015
- syncState = updateSourceSyncState(syncState, connector.id, {
2016
- syncedAt: now.toISOString(),
2017
- days: dates,
2018
- dayHashes,
2019
- memoryDayHashes,
2020
- clearMemoryDays: failedMemoryDays,
2021
- importedNativeMemoryIds: importedNativeIds
2022
- });
2023
- if (summary.transcriptsWritten.length > 0) {
2024
- const cleared = {};
2025
- for (const [otherId, otherState] of Object.entries(syncState.sources)) {
2026
- if (otherId === connector.id || otherState.memoryDayHashes === void 0) {
2027
- cleared[otherId] = otherState;
2028
- continue;
2029
- }
2030
- const memoryDays = { ...otherState.memoryDayHashes };
2031
- let touched = false;
2032
- for (const date of summary.transcriptsWritten) {
2033
- if (date in memoryDays) {
2034
- delete memoryDays[date];
2035
- touched = true;
2036
- }
2037
- }
2038
- cleared[otherId] = touched ? { ...otherState, memoryDayHashes: memoryDays } : otherState;
2039
- }
2040
- syncState = { version: 1, sources: cleared };
2041
- }
2042
- await saveSyncState(deps.memoryDir, syncState);
2043
- return summary;
2044
- }
2045
- async function buildCorroborationContext(sourceId, date, deps) {
2046
- const otherSourceDayTokens = /* @__PURE__ */ new Map();
2047
- if (deps.readOtherSourceDayBodies) {
2048
- const bodies = await deps.readOtherSourceDayBodies(date, sourceId);
2049
- for (const [otherSource, body] of bodies) {
2050
- otherSourceDayTokens.set(otherSource, tokenizeDayBody(body));
2051
- }
2052
- }
2053
- const existingMemories = deps.listSupportMemories ? await deps.listSupportMemories() : [];
2054
- return { otherSourceDayTokens, existingMemories };
2055
- }
2056
- function defaultTimezone() {
2057
- try {
2058
- return Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC";
2059
- } catch {
2060
- return "UTC";
2061
- }
2062
- }
2063
-
2064
969
  // src/wearables/registry.ts
2065
970
  var registrations = /* @__PURE__ */ new Map();
2066
971
  function registerWearableConnector(registration) {
@@ -2763,7 +1668,7 @@ async function qmdStartupCollectionCheckWithTimeout(promise, controller, label)
2763
1668
  return await Promise.race([checkedPromise, timeoutPromise]);
2764
1669
  }
2765
1670
  function defaultWorkspaceDir() {
2766
- return path3.join(os.homedir(), ".openclaw", "workspace");
1671
+ return path2.join(os.homedir(), ".openclaw", "workspace");
2767
1672
  }
2768
1673
  function sanitizeSessionKeyForFilename(sessionKey) {
2769
1674
  const readable = sessionKey.replace(/[^a-zA-Z0-9._-]/g, "_");
@@ -3072,11 +1977,11 @@ function mergeGraphExpandedResults(primary, expanded) {
3072
1977
  return Array.from(mergedByPath.values());
3073
1978
  }
3074
1979
  function graphPathRelativeToStorage(storageDir, candidatePath) {
3075
- const absolutePath = path3.isAbsolute(candidatePath) ? candidatePath : path3.resolve(storageDir, candidatePath);
3076
- const rel = path3.relative(storageDir, absolutePath);
1980
+ const absolutePath = path2.isAbsolute(candidatePath) ? candidatePath : path2.resolve(storageDir, candidatePath);
1981
+ const rel = path2.relative(storageDir, absolutePath);
3077
1982
  if (!rel || rel === ".") return null;
3078
1983
  if (rel.startsWith("..")) return null;
3079
- return rel.split(path3.sep).join("/");
1984
+ return rel.split(path2.sep).join("/");
3080
1985
  }
3081
1986
  function normalizeGraphActivationScore(score) {
3082
1987
  const bounded = Number.isFinite(score) && score > 0 ? score : 0;
@@ -3218,7 +2123,7 @@ function buildMemoryPathById(allMemsForGraph, storageDir) {
3218
2123
  for (const mem of allMemsForGraph ?? []) {
3219
2124
  const id = mem.frontmatter.id;
3220
2125
  if (!id) continue;
3221
- pathById.set(id, path3.relative(storageDir, mem.path));
2126
+ pathById.set(id, path2.relative(storageDir, mem.path));
3222
2127
  }
3223
2128
  return pathById;
3224
2129
  }
@@ -3226,7 +2131,7 @@ function appendMemoryToGraphContext(options) {
3226
2131
  if (!Array.isArray(options.allMemsForGraph)) return;
3227
2132
  const nowIso = (/* @__PURE__ */ new Date()).toISOString();
3228
2133
  options.allMemsForGraph.push({
3229
- path: path3.join(options.storageDir, options.memoryRelPath),
2134
+ path: path2.join(options.storageDir, options.memoryRelPath),
3230
2135
  content: options.content,
3231
2136
  frontmatter: {
3232
2137
  id: options.memoryId,
@@ -3246,16 +2151,16 @@ function resolvePersistedMemoryRelativePath(options) {
3246
2151
  const persisted = options.pathById.get(options.memoryId);
3247
2152
  if (persisted) return persisted;
3248
2153
  if (options.category === "correction") {
3249
- return path3.join("corrections", `${options.memoryId}.md`);
2154
+ return path2.join("corrections", `${options.memoryId}.md`);
3250
2155
  }
3251
2156
  const subtree = options.category === "procedure" ? "procedures" : options.category === "reasoning_trace" ? "reasoning-traces" : "facts";
3252
2157
  const idParts = options.memoryId.split("-");
3253
2158
  const maybeTimestamp = Number(idParts[1]);
3254
2159
  if (Number.isFinite(maybeTimestamp) && maybeTimestamp > 0) {
3255
2160
  const day = new Date(maybeTimestamp).toISOString().slice(0, 10);
3256
- return path3.join(subtree, day, `${options.memoryId}.md`);
2161
+ return path2.join(subtree, day, `${options.memoryId}.md`);
3257
2162
  }
3258
- return path3.join(subtree, `${options.memoryId}.md`);
2163
+ return path2.join(subtree, `${options.memoryId}.md`);
3259
2164
  }
3260
2165
  var Orchestrator = class _Orchestrator {
3261
2166
  storage;
@@ -3375,6 +2280,7 @@ var Orchestrator = class _Orchestrator {
3375
2280
  consolidationObservers = /* @__PURE__ */ new Set();
3376
2281
  qmdMaintenanceTimer = null;
3377
2282
  wearablesServiceInstance = null;
2283
+ wearablesAutoSyncHandle = null;
3378
2284
  qmdMaintenancePending = false;
3379
2285
  qmdMaintenanceInFlight = false;
3380
2286
  lastQmdEmbedAtMs = 0;
@@ -3449,6 +2355,10 @@ var Orchestrator = class _Orchestrator {
3449
2355
  */
3450
2356
  async destroy() {
3451
2357
  this.abortDeferredInit();
2358
+ if (this.wearablesAutoSyncHandle) {
2359
+ await this.wearablesAutoSyncHandle.stop();
2360
+ this.wearablesAutoSyncHandle = null;
2361
+ }
3452
2362
  if (this.qmdMaintenanceTimer) {
3453
2363
  clearTimeout(this.qmdMaintenanceTimer);
3454
2364
  this.qmdMaintenanceTimer = null;
@@ -3693,7 +2603,7 @@ var Orchestrator = class _Orchestrator {
3693
2603
  this.config = config;
3694
2604
  this.profiler = new ProfilingCollector({
3695
2605
  enabled: config.profilingEnabled,
3696
- storageDir: config.profilingStorageDir || path3.join(config.memoryDir, "profiling"),
2606
+ storageDir: config.profilingStorageDir || path2.join(config.memoryDir, "profiling"),
3697
2607
  maxTraces: config.profilingMaxTraces
3698
2608
  });
3699
2609
  this.storageRouter = new NamespaceStorageRouter(config);
@@ -3728,7 +2638,7 @@ var Orchestrator = class _Orchestrator {
3728
2638
  this.compounding = config.compoundingEnabled ? new CompoundingEngine(config, this.storage) : void 0;
3729
2639
  this.buffer = new SmartBuffer(config, this.storage);
3730
2640
  this.transcript = new TranscriptManager(config);
3731
- this.conversationIndexDir = path3.join(
2641
+ this.conversationIndexDir = path2.join(
3732
2642
  config.memoryDir,
3733
2643
  "conversation-index",
3734
2644
  "chunks"
@@ -3785,7 +2695,7 @@ var Orchestrator = class _Orchestrator {
3785
2695
  this.modelRegistry
3786
2696
  );
3787
2697
  this.threading = new ThreadingManager(
3788
- path3.join(config.memoryDir, "threads"),
2698
+ path2.join(config.memoryDir, "threads"),
3789
2699
  config.threadingGapMinutes
3790
2700
  );
3791
2701
  this.tmtBuilder = new TmtBuilder(config.memoryDir, {
@@ -4083,7 +2993,7 @@ var Orchestrator = class _Orchestrator {
4083
2993
  const files = await readdir(wsDir).catch(() => []);
4084
2994
  for (const f of files) {
4085
2995
  if (!f.startsWith(".compaction-reset-signal-")) continue;
4086
- const fp = path3.join(wsDir, f);
2996
+ const fp = path2.join(wsDir, f);
4087
2997
  const s = await stat(fp).catch(() => null);
4088
2998
  if (s && Date.now() - s.mtimeMs >= COMPACTION_SIGNAL_MAX_AGE_MS) {
4089
2999
  await unlink(fp).catch(() => {
@@ -4338,6 +3248,36 @@ var Orchestrator = class _Orchestrator {
4338
3248
  log.warn(`first-start lifecycle migration failed (non-fatal): ${err}`);
4339
3249
  }
4340
3250
  }
3251
+ if (signal.aborted) return;
3252
+ if (!this.wearablesAutoSyncHandle && this.config.wearables.enabled && this.config.wearables.autoSyncEnabled && Object.values(this.config.wearables.sources).some((source) => source.enabled)) {
3253
+ try {
3254
+ const { startWearablesAutoSync } = await import("./auto-sync-RFADEHIQ.js");
3255
+ if (signal.aborted) return;
3256
+ this.wearablesAutoSyncHandle = startWearablesAutoSync(
3257
+ {
3258
+ intervalMinutes: this.config.wearables.autoSyncIntervalMinutes,
3259
+ days: this.config.wearables.autoSyncDays,
3260
+ deepDays: this.config.wearables.autoSyncDeepDays,
3261
+ ...this.config.wearables.timezone !== void 0 ? { timezone: this.config.wearables.timezone } : {}
3262
+ },
3263
+ {
3264
+ sync: (options) => this.getWearablesService().sync(options),
3265
+ log: {
3266
+ info: (message) => log.info(message),
3267
+ warn: (message) => log.warn(message)
3268
+ }
3269
+ }
3270
+ );
3271
+ log.info(
3272
+ `wearables auto-sync started: every ${this.config.wearables.autoSyncIntervalMinutes}m over ${this.config.wearables.autoSyncDays}d (deep ${this.config.wearables.autoSyncDeepDays}d daily)`
3273
+ );
3274
+ } catch (err) {
3275
+ const { displayErrorDetail } = await import("./runtime/better-sqlite.js");
3276
+ log.warn(
3277
+ `wearables auto-sync failed to start (non-fatal): ${displayErrorDetail(err)}`
3278
+ );
3279
+ }
3280
+ }
4341
3281
  log.info("orchestrator initialized (full \u2014 deferred steps complete)");
4342
3282
  }
4343
3283
  /**
@@ -4445,7 +3385,7 @@ var Orchestrator = class _Orchestrator {
4445
3385
  */
4446
3386
  async autoRegisterDaySummaryCron() {
4447
3387
  const home = resolveHomeDir();
4448
- const jobsPath = path3.join(home, ".openclaw", "cron", "jobs.json");
3388
+ const jobsPath = path2.join(home, ".openclaw", "cron", "jobs.json");
4449
3389
  try {
4450
3390
  if (!existsSync(jobsPath)) {
4451
3391
  log.debug(
@@ -4469,7 +3409,7 @@ var Orchestrator = class _Orchestrator {
4469
3409
  }
4470
3410
  async autoRegisterNightlyGovernanceCron() {
4471
3411
  const home = resolveHomeDir();
4472
- const jobsPath = path3.join(home, ".openclaw", "cron", "jobs.json");
3412
+ const jobsPath = path2.join(home, ".openclaw", "cron", "jobs.json");
4473
3413
  try {
4474
3414
  if (!existsSync(jobsPath)) {
4475
3415
  log.debug("nightly governance cron: jobs.json not found, skipping auto-register");
@@ -4491,7 +3431,7 @@ var Orchestrator = class _Orchestrator {
4491
3431
  }
4492
3432
  async autoRegisterProceduralMiningCron() {
4493
3433
  const home = resolveHomeDir();
4494
- const jobsPath = path3.join(home, ".openclaw", "cron", "jobs.json");
3434
+ const jobsPath = path2.join(home, ".openclaw", "cron", "jobs.json");
4495
3435
  try {
4496
3436
  if (!existsSync(jobsPath)) {
4497
3437
  log.debug("procedural mining cron: jobs.json not found, skipping auto-register");
@@ -4511,7 +3451,7 @@ var Orchestrator = class _Orchestrator {
4511
3451
  }
4512
3452
  async autoRegisterContradictionScanCron() {
4513
3453
  const home = resolveHomeDir();
4514
- const jobsPath = path3.join(home, ".openclaw", "cron", "jobs.json");
3454
+ const jobsPath = path2.join(home, ".openclaw", "cron", "jobs.json");
4515
3455
  try {
4516
3456
  if (!existsSync(jobsPath)) {
4517
3457
  log.debug("contradiction scan cron: jobs.json not found, skipping auto-register");
@@ -4531,7 +3471,7 @@ var Orchestrator = class _Orchestrator {
4531
3471
  }
4532
3472
  async autoRegisterPatternReinforcementCron() {
4533
3473
  const home = resolveHomeDir();
4534
- const jobsPath = path3.join(home, ".openclaw", "cron", "jobs.json");
3474
+ const jobsPath = path2.join(home, ".openclaw", "cron", "jobs.json");
4535
3475
  try {
4536
3476
  if (!existsSync(jobsPath)) {
4537
3477
  log.debug("pattern reinforcement cron: jobs.json not found, skipping auto-register");
@@ -4593,7 +3533,7 @@ var Orchestrator = class _Orchestrator {
4593
3533
  }
4594
3534
  async autoRegisterGraphEdgeDecayCron() {
4595
3535
  const home = resolveHomeDir();
4596
- const jobsPath = path3.join(home, ".openclaw", "cron", "jobs.json");
3536
+ const jobsPath = path2.join(home, ".openclaw", "cron", "jobs.json");
4597
3537
  try {
4598
3538
  if (!existsSync(jobsPath)) {
4599
3539
  log.debug("graph edge decay cron: jobs.json not found, skipping auto-register");
@@ -4650,15 +3590,15 @@ ${doc.content}` : doc.content,
4650
3590
  this.lastFileHygieneRunAtMs = now;
4651
3591
  if (hygiene.rotateEnabled) {
4652
3592
  for (const rel of hygiene.rotatePaths) {
4653
- const abs = path3.isAbsolute(rel) ? rel : path3.join(this.config.workspaceDir, rel);
3593
+ const abs = path2.isAbsolute(rel) ? rel : path2.join(this.config.workspaceDir, rel);
4654
3594
  try {
4655
3595
  const raw = await readFile2(abs, "utf-8");
4656
3596
  if (raw.length > hygiene.rotateMaxBytes) {
4657
- const archiveDir = path3.join(
3597
+ const archiveDir = path2.join(
4658
3598
  this.config.workspaceDir,
4659
3599
  hygiene.archiveDir
4660
3600
  );
4661
- const base = path3.basename(abs);
3601
+ const base = path2.basename(abs);
4662
3602
  const prefix = base.toUpperCase().replace(/\.MD$/i, "").replace(/[^A-Z0-9]+/g, "-") || "FILE";
4663
3603
  const { newContent } = await rotateMarkdownFileToArchive({
4664
3604
  filePath: abs,
@@ -4683,8 +3623,8 @@ ${doc.content}` : doc.content,
4683
3623
  log.warn(w.message);
4684
3624
  }
4685
3625
  if (hygiene.warningsLogEnabled && warnings.length > 0) {
4686
- const fp = path3.join(this.config.memoryDir, hygiene.warningsLogPath);
4687
- await mkdir2(path3.dirname(fp), { recursive: true });
3626
+ const fp = path2.join(this.config.memoryDir, hygiene.warningsLogPath);
3627
+ await mkdir2(path2.dirname(fp), { recursive: true });
4688
3628
  const stamp = (/* @__PURE__ */ new Date()).toISOString();
4689
3629
  const block = `
4690
3630
 
@@ -5153,16 +4093,16 @@ ${evidenceText}`
5153
4093
  const datesToScan = [yesterday, utcToday].filter(
5154
4094
  (v, i, a) => a.indexOf(v) === i
5155
4095
  );
5156
- const factsBaseDir = path3.join(storage.dir, "facts");
4096
+ const factsBaseDir = path2.join(storage.dir, "facts");
5157
4097
  const MAX_CHARS = 1e5;
5158
4098
  const facts = [];
5159
4099
  for (const date of datesToScan) {
5160
- const factsDir = path3.join(factsBaseDir, date);
4100
+ const factsDir = path2.join(factsBaseDir, date);
5161
4101
  try {
5162
4102
  const entries = await readdir(factsDir, { withFileTypes: true });
5163
4103
  for (const entry of entries) {
5164
4104
  if (!entry.name.endsWith(".md")) continue;
5165
- const fullPath = path3.join(factsDir, entry.name);
4105
+ const fullPath = path2.join(factsDir, entry.name);
5166
4106
  try {
5167
4107
  const raw = await readFile2(fullPath, "utf-8");
5168
4108
  const fmMatch = raw.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
@@ -5178,7 +4118,7 @@ ${evidenceText}`
5178
4118
  facts.push({
5179
4119
  path: fullPath,
5180
4120
  frontmatter: {
5181
- id: fm.id || path3.basename(entry.name, ".md"),
4121
+ id: fm.id || path2.basename(entry.name, ".md"),
5182
4122
  category: fm.category || "fact",
5183
4123
  created: fm.created || "unknown",
5184
4124
  updated: fm.updated || fm.created || "unknown",
@@ -5199,13 +4139,13 @@ ${evidenceText}`
5199
4139
  (a, b) => a.frontmatter.created < b.frontmatter.created ? -1 : 1
5200
4140
  );
5201
4141
  const hourlySummaries = [];
5202
- const hourlyBaseDir = path3.join(storage.dir, "summaries", "hourly");
4142
+ const hourlyBaseDir = path2.join(storage.dir, "summaries", "hourly");
5203
4143
  try {
5204
4144
  const sessionKeys = await readdir(hourlyBaseDir, { withFileTypes: true });
5205
4145
  for (const sk of sessionKeys) {
5206
4146
  if (!sk.isDirectory()) continue;
5207
4147
  for (const date of datesToScan) {
5208
- const summaryFile = path3.join(hourlyBaseDir, sk.name, `${date}.md`);
4148
+ const summaryFile = path2.join(hourlyBaseDir, sk.name, `${date}.md`);
5209
4149
  try {
5210
4150
  const raw = await readFile2(summaryFile, "utf-8");
5211
4151
  if (raw.trim().length > 0) {
@@ -5303,7 +4243,7 @@ ${evidenceText}`
5303
4243
  }
5304
4244
  async getLastGraphRecallSnapshot(namespace) {
5305
4245
  const storage = await this.getStorage(namespace);
5306
- const snapshotPath = path3.join(
4246
+ const snapshotPath = path2.join(
5307
4247
  storage.dir,
5308
4248
  "state",
5309
4249
  "last_graph_recall.json"
@@ -5342,7 +4282,7 @@ ${evidenceText}`
5342
4282
  }
5343
4283
  async getLastIntentSnapshot(namespace) {
5344
4284
  const storage = await this.getStorage(namespace);
5345
- const snapshotPath = path3.join(storage.dir, "state", "last_intent.json");
4285
+ const snapshotPath = path2.join(storage.dir, "state", "last_intent.json");
5346
4286
  try {
5347
4287
  const raw = await readFile2(snapshotPath, "utf-8");
5348
4288
  const parsed = JSON.parse(raw);
@@ -5375,7 +4315,7 @@ ${evidenceText}`
5375
4315
  }
5376
4316
  async getLastQmdRecallSnapshot(namespace) {
5377
4317
  const storage = await this.getStorage(namespace);
5378
- const snapshotPath = path3.join(
4318
+ const snapshotPath = path2.join(
5379
4319
  storage.dir,
5380
4320
  "state",
5381
4321
  "last_qmd_recall.json"
@@ -5528,7 +4468,7 @@ ${r.snippet.trim()}
5528
4468
  const entries = await readdir(dir, { withFileTypes: true });
5529
4469
  let total = 0;
5530
4470
  for (const entry of entries) {
5531
- const fullPath = path3.join(dir, entry.name);
4471
+ const fullPath = path2.join(dir, entry.name);
5532
4472
  if (entry.isDirectory()) {
5533
4473
  total += await this.countConversationChunkDocs(fullPath);
5534
4474
  continue;
@@ -6424,7 +5364,7 @@ ${r.snippet.trim()}
6424
5364
  0
6425
5365
  );
6426
5366
  seedPaths.push(
6427
- ...seedRelativePaths.map((rel) => path3.join(storage.dir, rel))
5367
+ ...seedRelativePaths.map((rel) => path2.join(storage.dir, rel))
6428
5368
  );
6429
5369
  const seedSet = new Set(seedRelativePaths);
6430
5370
  const expanded = await this.graphIndexFor(storage).spreadingActivation(
@@ -6435,7 +5375,7 @@ ${r.snippet.trim()}
6435
5375
  if (expanded.length === 0) continue;
6436
5376
  for (const candidate of expanded.slice(0, perNamespaceExpandedCap)) {
6437
5377
  if (seedSet.has(candidate.path)) continue;
6438
- const memoryPath = path3.resolve(storage.dir, candidate.path);
5378
+ const memoryPath = path2.resolve(storage.dir, candidate.path);
6439
5379
  const memory = await storage.readMemoryByPath(memoryPath);
6440
5380
  if (!memory) continue;
6441
5381
  if (isArtifactMemoryPath(memory.path)) continue;
@@ -6459,7 +5399,7 @@ ${r.snippet.trim()}
6459
5399
  path: memory.path,
6460
5400
  score,
6461
5401
  namespace,
6462
- seed: path3.resolve(storage.dir, candidate.seed),
5402
+ seed: path2.resolve(storage.dir, candidate.seed),
6463
5403
  hopDepth: candidate.hopDepth,
6464
5404
  decayedWeight: candidate.decayedWeight,
6465
5405
  graphType: candidate.graphType,
@@ -6480,12 +5420,12 @@ ${r.snippet.trim()}
6480
5420
  }
6481
5421
  async recordLastGraphRecallSnapshot(options) {
6482
5422
  try {
6483
- const snapshotPath = path3.join(
5423
+ const snapshotPath = path2.join(
6484
5424
  options.storage.dir,
6485
5425
  "state",
6486
5426
  "last_graph_recall.json"
6487
5427
  );
6488
- await mkdir2(path3.dirname(snapshotPath), { recursive: true });
5428
+ await mkdir2(path2.dirname(snapshotPath), { recursive: true });
6489
5429
  const now = (/* @__PURE__ */ new Date()).toISOString();
6490
5430
  const totalSeedCount = options.seedPaths.length;
6491
5431
  const totalExpandedCount = options.expandedPaths.length;
@@ -6519,12 +5459,12 @@ ${r.snippet.trim()}
6519
5459
  }
6520
5460
  async recordLastIntentSnapshot(options) {
6521
5461
  try {
6522
- const snapshotPath = path3.join(
5462
+ const snapshotPath = path2.join(
6523
5463
  options.storage.dir,
6524
5464
  "state",
6525
5465
  "last_intent.json"
6526
5466
  );
6527
- await mkdir2(path3.dirname(snapshotPath), { recursive: true });
5467
+ await mkdir2(path2.dirname(snapshotPath), { recursive: true });
6528
5468
  await writeFile2(
6529
5469
  snapshotPath,
6530
5470
  JSON.stringify(options.snapshot, null, 2),
@@ -6536,12 +5476,12 @@ ${r.snippet.trim()}
6536
5476
  }
6537
5477
  async recordLastQmdRecallSnapshot(options) {
6538
5478
  try {
6539
- const snapshotPath = path3.join(
5479
+ const snapshotPath = path2.join(
6540
5480
  options.storage.dir,
6541
5481
  "state",
6542
5482
  "last_qmd_recall.json"
6543
5483
  );
6544
- await mkdir2(path3.dirname(snapshotPath), { recursive: true });
5484
+ await mkdir2(path2.dirname(snapshotPath), { recursive: true });
6545
5485
  await writeFile2(
6546
5486
  snapshotPath,
6547
5487
  JSON.stringify(options.snapshot, null, 2),
@@ -6556,8 +5496,8 @@ ${r.snippet.trim()}
6556
5496
  const stateDir = await this.resolveStateDirForNamespace(
6557
5497
  options.namespace
6558
5498
  );
6559
- const snapshotPath = path3.join(stateDir, "last_intent.json");
6560
- await mkdir2(path3.dirname(snapshotPath), { recursive: true });
5499
+ const snapshotPath = path2.join(stateDir, "last_intent.json");
5500
+ await mkdir2(path2.dirname(snapshotPath), { recursive: true });
6561
5501
  await writeFile2(
6562
5502
  snapshotPath,
6563
5503
  JSON.stringify(options.snapshot, null, 2),
@@ -6569,12 +5509,12 @@ ${r.snippet.trim()}
6569
5509
  }
6570
5510
  async resolveStateDirForNamespace(namespace) {
6571
5511
  if (!this.config.namespacesEnabled) {
6572
- return path3.join(this.config.memoryDir, "state");
5512
+ return path2.join(this.config.memoryDir, "state");
6573
5513
  }
6574
5514
  if (namespace !== this.config.defaultNamespace) {
6575
- return path3.join(this.config.memoryDir, "namespaces", namespace, "state");
5515
+ return path2.join(this.config.memoryDir, "namespaces", namespace, "state");
6576
5516
  }
6577
- const candidate = path3.join(
5517
+ const candidate = path2.join(
6578
5518
  this.config.memoryDir,
6579
5519
  "namespaces",
6580
5520
  this.config.defaultNamespace
@@ -6582,11 +5522,11 @@ ${r.snippet.trim()}
6582
5522
  try {
6583
5523
  const candidateStat = await stat(candidate);
6584
5524
  if (candidateStat.isDirectory()) {
6585
- return path3.join(candidate, "state");
5525
+ return path2.join(candidate, "state");
6586
5526
  }
6587
5527
  } catch {
6588
5528
  }
6589
- return path3.join(this.config.memoryDir, "state");
5529
+ return path2.join(this.config.memoryDir, "state");
6590
5530
  }
6591
5531
  buildGraphRecallRankedResults(results, sourceLabelResolver, limit = 64) {
6592
5532
  return results.slice(0, limit).map((result) => ({
@@ -6972,7 +5912,7 @@ ${r.snippet.trim()}
6972
5912
  const graphExpandedResultPaths = /* @__PURE__ */ new Set();
6973
5913
  const graphSourceLabelsForPath = (resultPath) => {
6974
5914
  const labels = [];
6975
- const normalizedPath = resultPath.split(path3.sep).join("/");
5915
+ const normalizedPath = resultPath.split(path2.sep).join("/");
6976
5916
  const isEntityPath = normalizedPath.startsWith("entities/") || normalizedPath.includes("/entities/");
6977
5917
  if (graphBaselinePaths.has(resultPath)) labels.push("baseline");
6978
5918
  if (graphExpandedResultPaths.has(resultPath))
@@ -8287,11 +7227,11 @@ ${formatted}`;
8287
7227
  if (!this.config.compactionResetEnabled) return null;
8288
7228
  const workspaceDir = compactionWorkspaceDir || this.config.workspaceDir || defaultWorkspaceDir();
8289
7229
  const safeSessionKey = sanitizeSessionKeyForFilename(effectiveSessionKey);
8290
- const signalPath = path3.join(
7230
+ const signalPath = path2.join(
8291
7231
  workspaceDir,
8292
7232
  `.compaction-reset-signal-${safeSessionKey}`
8293
7233
  );
8294
- const bootPath = path3.join(workspaceDir, "BOOT.md");
7234
+ const bootPath = path2.join(workspaceDir, "BOOT.md");
8295
7235
  try {
8296
7236
  const signalStat = await stat(signalPath).catch(() => null);
8297
7237
  if (!signalStat) return null;
@@ -10772,7 +9712,7 @@ ${normalized}`).digest("hex");
10772
9712
  );
10773
9713
  this.tierMigrationInFlight = true;
10774
9714
  try {
10775
- const coldStorage = new StorageManager(path3.join(storage.dir, "cold"));
9715
+ const coldStorage = new StorageManager(path2.join(storage.dir, "cold"));
10776
9716
  const [hotMemories, coldMemories] = await Promise.all([
10777
9717
  storage.readAllMemories(),
10778
9718
  coldStorage.readAllMemories()
@@ -11975,7 +10915,7 @@ ${normalized}`).digest("hex");
11975
10915
  const allMems = allMemsForGraph ?? [];
11976
10916
  for (const m of allMems) {
11977
10917
  if (m.frontmatter.entityRef === entityRef) {
11978
- const rel = path3.relative(storage.dir, m.path);
10918
+ const rel = path2.relative(storage.dir, m.path);
11979
10919
  if (rel !== memoryRelPath) entitySiblings.push(rel);
11980
10920
  }
11981
10921
  }
@@ -12275,7 +11215,7 @@ ${normalized}`).digest("hex");
12275
11215
  }
12276
11216
  if (this.config.semanticConsolidationEnabled) {
12277
11217
  try {
12278
- const stateFilePath = path3.join(
11218
+ const stateFilePath = path2.join(
12279
11219
  this.config.memoryDir,
12280
11220
  "state",
12281
11221
  "semantic-consolidation-last-run.json"
@@ -12323,7 +11263,7 @@ ${normalized}`).digest("hex");
12323
11263
  );
12324
11264
  }
12325
11265
  if (semResult.errors === 0 || semResult.memoriesArchived > 0) {
12326
- const stateDir = path3.join(this.config.memoryDir, "state");
11266
+ const stateDir = path2.join(this.config.memoryDir, "state");
12327
11267
  await mkdir2(stateDir, { recursive: true });
12328
11268
  await writeFile2(
12329
11269
  stateFilePath,
@@ -12818,12 +11758,12 @@ ${texts.map((t, i) => `[${i + 1}] ${t}`).join("\n\n")}`;
12818
11758
  protectedCategories: this.config.lifecycleProtectedCategories
12819
11759
  }
12820
11760
  };
12821
- const metricsPath = path3.join(
11761
+ const metricsPath = path2.join(
12822
11762
  storage.dir,
12823
11763
  "state",
12824
11764
  "lifecycle-metrics.json"
12825
11765
  );
12826
- await mkdir2(path3.dirname(metricsPath), { recursive: true });
11766
+ await mkdir2(path2.dirname(metricsPath), { recursive: true });
12827
11767
  await writeFile2(metricsPath, JSON.stringify(metrics, null, 2), "utf-8");
12828
11768
  }
12829
11769
  /**
@@ -13351,7 +12291,7 @@ ${lines.join("\n\n")}`;
13351
12291
  nsMap = buildMemoryWorthCounterMap(memories);
13352
12292
  this.memoryWorthCounterCache.set(ns, { at: nowMs, counters: nsMap });
13353
12293
  }
13354
- for (const [path4, c] of nsMap) counters.set(path4, c);
12294
+ for (const [path3, c] of nsMap) counters.set(path3, c);
13355
12295
  } catch (err) {
13356
12296
  log.debug("memory-worth: failed to read namespace, skipping", {
13357
12297
  namespace: ns,
@@ -13522,12 +12462,12 @@ ${lines.join("\n\n")}`;
13522
12462
  */
13523
12463
  semanticDedupScopeFor(targetStorage) {
13524
12464
  if (!this.config.namespacesEnabled) return {};
13525
- const memoryDir = path3.resolve(this.config.memoryDir);
13526
- const storageDir = path3.resolve(targetStorage.dir);
12465
+ const memoryDir = path2.resolve(this.config.memoryDir);
12466
+ const storageDir = path2.resolve(targetStorage.dir);
13527
12467
  if (storageDir === memoryDir) {
13528
12468
  return { pathExcludePrefixes: ["namespaces/"] };
13529
12469
  }
13530
- let rel = path3.relative(memoryDir, storageDir);
12470
+ let rel = path2.relative(memoryDir, storageDir);
13531
12471
  if (!rel || rel.startsWith("..")) {
13532
12472
  log.debug(
13533
12473
  `semantic dedup: target storage dir ${storageDir} is outside memoryDir ${memoryDir}; scoping lookup to absolute path prefix`
@@ -13546,7 +12486,7 @@ ${lines.join("\n\n")}`;
13546
12486
  if (hits.length === 0) return [];
13547
12487
  const results = [];
13548
12488
  for (const hit of hits) {
13549
- const fullPath = path3.isAbsolute(hit.path) ? hit.path : path3.join(this.config.memoryDir, hit.path);
12489
+ const fullPath = path2.isAbsolute(hit.path) ? hit.path : path2.join(this.config.memoryDir, hit.path);
13550
12490
  const memory = await this.storage.readMemoryByPath(fullPath);
13551
12491
  if (!memory) continue;
13552
12492
  results.push({
@@ -14189,8 +13129,8 @@ ${lines.join("\n\n")}`;
14189
13129
  }
14190
13130
  namespaceFromStorageDir(storageDir) {
14191
13131
  if (!this.config.namespacesEnabled) return this.config.defaultNamespace;
14192
- const resolvedStorageDir = path3.resolve(storageDir);
14193
- const resolvedMemoryDir = path3.resolve(this.config.memoryDir);
13132
+ const resolvedStorageDir = path2.resolve(storageDir);
13133
+ const resolvedMemoryDir = path2.resolve(this.config.memoryDir);
14194
13134
  if (resolvedStorageDir === resolvedMemoryDir)
14195
13135
  return this.config.defaultNamespace;
14196
13136
  const m = resolvedStorageDir.match(/[\\/]namespaces[\\/]([^\\/]+)$/);
@@ -14230,27 +13170,6 @@ export {
14230
13170
  saveTaxonomy,
14231
13171
  getTaxonomyDir,
14232
13172
  getTaxonomyFilePath,
14233
- memoryStatusForMode,
14234
- WEARABLE_SOURCE_PREFIX,
14235
- wearableSourceLabel,
14236
- wearableDayTag,
14237
- buildExtractionTurns,
14238
- generateWearableMemories,
14239
- writeDailyDigestMemory,
14240
- importNativeMemories,
14241
- cleanConversation,
14242
- stripFillerTokens,
14243
- collapseImmediateRepeats,
14244
- isLowQualitySegment,
14245
- syncStateFilePath,
14246
- emptySyncState,
14247
- loadSyncState,
14248
- saveSyncState,
14249
- updateSourceSyncState,
14250
- dateInTimezone,
14251
- resolveSyncDates,
14252
- syncWearableSource,
14253
- defaultTimezone,
14254
13173
  registerWearableConnector,
14255
13174
  getWearableConnector,
14256
13175
  listWearableConnectors,
@@ -14287,4 +13206,4 @@ export {
14287
13206
  resolvePersistedMemoryRelativePath,
14288
13207
  Orchestrator
14289
13208
  };
14290
- //# sourceMappingURL=chunk-YJOWWRRS.js.map
13209
+ //# sourceMappingURL=chunk-WLZBVYC6.js.map