@remnic/core 9.54.7 → 9.54.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access-admin-ops-surface.d.ts +5 -5
- package/dist/access-admin-ops-surface.js +42 -41
- package/dist/access-authorization-probe.d.ts +5 -5
- package/dist/access-authorization-probe.js +43 -42
- package/dist/access-boundary.d.ts +5 -5
- package/dist/access-boundary.js +42 -41
- package/dist/access-cli.js +92 -91
- package/dist/access-cli.js.map +1 -1
- package/dist/access-extraction-force-flush.d.ts +5 -5
- package/dist/access-extraction-force-flush.js +42 -41
- package/dist/access-http-lcm-compaction.d.ts +5 -5
- package/dist/access-http-lifecycle-flush.d.ts +5 -5
- package/dist/access-http-offline-stream.d.ts +5 -5
- package/dist/access-http-query.js +42 -41
- package/dist/access-http.d.ts +6 -6
- package/dist/access-http.js +56 -55
- package/dist/access-identity-continuity-surface.d.ts +4 -4
- package/dist/access-identity-continuity-surface.js +42 -41
- package/dist/access-lcm-surface.d.ts +5 -5
- package/dist/access-lcm-surface.js +42 -41
- package/dist/access-mcp.d.ts +5 -5
- package/dist/access-mcp.js +49 -48
- package/dist/access-namespace-preflight.js +42 -41
- package/dist/access-observe-write-surface.d.ts +5 -5
- package/dist/access-observe-write-surface.js +42 -41
- package/dist/access-offline-manifest.d.ts +4 -4
- package/dist/access-offline-manifest.js +1 -1
- package/dist/access-operations-batch.js +44 -43
- package/dist/access-operations.d.ts +5 -5
- package/dist/access-operations.js +48 -47
- package/dist/access-recall-concurrency.d.ts +5 -5
- package/dist/access-recall-concurrency.js +42 -41
- package/dist/access-recall-response.d.ts +5 -5
- package/dist/access-recall-response.js +42 -41
- package/dist/access-recall-surface.d.ts +5 -5
- package/dist/access-recall-surface.js +42 -41
- package/dist/access-schema.js +3 -3
- package/dist/{access-service-DK82xdNi.d.ts → access-service-PEduVt8q.d.ts} +3 -3
- package/dist/access-service-helpers.d.ts +5 -5
- package/dist/access-service.d.ts +5 -5
- package/dist/access-service.js +42 -41
- package/dist/access-surface-catalog.d.ts +5 -5
- package/dist/access-surface-catalog.js +44 -43
- package/dist/access-surface-catalog.js.map +1 -1
- package/dist/access-wearables-meetings-surface.d.ts +2 -2
- package/dist/adapters/index.js +4 -4
- package/dist/adapters/registry.js +2 -2
- package/dist/behavior-learner.js +1 -1
- package/dist/bootstrap.d.ts +4 -4
- package/dist/briefing-window.d.ts +36 -0
- package/dist/briefing-window.js +9 -0
- package/dist/briefing.d.ts +1 -1
- package/dist/briefing.js +15 -14
- package/dist/buffer.d.ts +1 -1
- package/dist/buffer.js +4 -4
- package/dist/causal-behavior.js +2 -2
- package/dist/causal-chain.js +2 -2
- package/dist/causal-consolidation.js +17 -17
- package/dist/causal-retrieval.js +2 -2
- package/dist/causal-trajectory-graph.js +2 -2
- package/dist/causal-trajectory.js +1 -1
- package/dist/{chunk-LEPOP46W.js → chunk-227UFSEQ.js} +4 -4
- package/dist/{chunk-ZUKIUXHQ.js → chunk-2GD6MLXD.js} +9 -9
- package/dist/{chunk-2FKEIPIT.js → chunk-2T5AWWMF.js} +2 -2
- package/dist/{chunk-HBUFQRIM.js → chunk-3DVG3GRQ.js} +2 -2
- package/dist/{chunk-QZLDRQ4I.js → chunk-47J4EDGR.js} +3 -3
- package/dist/{chunk-K26NWEOC.js → chunk-4ESX4WX2.js} +4 -4
- package/dist/{chunk-46SZBVDS.js → chunk-4GE3NA5I.js} +2 -2
- package/dist/{chunk-FPLM2TKD.js → chunk-5V64M56S.js} +2 -2
- package/dist/{chunk-37DZZFFM.js → chunk-6G4D222J.js} +2 -2
- package/dist/{chunk-FFRTNF3L.js → chunk-6PCND4O2.js} +2 -2
- package/dist/{chunk-26ZXBTYN.js → chunk-7DISPKXT.js} +4 -4
- package/dist/{chunk-JYG4OLWH.js → chunk-7SF5BAWF.js} +2 -2
- package/dist/{chunk-XZHE2DEN.js → chunk-BXIMH7MC.js} +2 -2
- package/dist/{chunk-FTPONF6B.js → chunk-E2GZSFR5.js} +2 -2
- package/dist/{chunk-I3MSGFGD.js → chunk-ELXP665P.js} +2 -2
- package/dist/{chunk-EKTP7MNS.js → chunk-F2BOUJUS.js} +6 -6
- package/dist/{chunk-3TIZPSJC.js → chunk-FEBHRT2I.js} +3 -3
- package/dist/{chunk-W5ZKPI34.js → chunk-FPKKFDO4.js} +124 -124
- package/dist/{chunk-UPLZNJKN.js → chunk-FYZKFLKY.js} +2 -2
- package/dist/{chunk-FWX7W5PM.js → chunk-G7YUH4WT.js} +2 -2
- package/dist/{chunk-PT54WISF.js → chunk-IEQCHXUS.js} +9 -9
- package/dist/{chunk-YXQEKCZM.js → chunk-IOYXIY7W.js} +2 -2
- package/dist/{chunk-CIAI24TQ.js → chunk-JKW663ZN.js} +2 -2
- package/dist/{chunk-V6ERBR7U.js → chunk-K44N3CFW.js} +2 -2
- package/dist/{chunk-TO7ZTWJW.js → chunk-KMWYZTIE.js} +2 -2
- package/dist/{chunk-IPLYGWQF.js → chunk-KQAFEZQX.js} +5 -5
- package/dist/{chunk-S354QO4R.js → chunk-LHIBA4G7.js} +2 -2
- package/dist/{chunk-UCTS3DDH.js → chunk-M3UYE6PS.js} +2 -2
- package/dist/{chunk-RUNORG2P.js → chunk-MANCJV6J.js} +6 -11
- package/dist/chunk-MANCJV6J.js.map +1 -0
- package/dist/{chunk-D3LBIUWV.js → chunk-MTF5EFFF.js} +39 -39
- package/dist/{chunk-IKP5OYQQ.js → chunk-NUA4VM46.js} +2 -2
- package/dist/{chunk-UYYW2KPU.js → chunk-OIOV4RJE.js} +2 -2
- package/dist/{chunk-BIJAWZYW.js → chunk-OLT3YTDH.js} +4 -4
- package/dist/{chunk-RZQ6W2W4.js → chunk-OS5DYALF.js} +23 -23
- package/dist/{chunk-IQ4NVWEF.js → chunk-OTUFRUV3.js} +2 -2
- package/dist/{chunk-KFBOPMF6.js → chunk-OWC42MDT.js} +4 -4
- package/dist/{chunk-GJ776BC2.js → chunk-P2FA65P2.js} +4 -3
- package/dist/{chunk-GJ776BC2.js.map → chunk-P2FA65P2.js.map} +1 -1
- package/dist/{chunk-43SEBY2M.js → chunk-PCRHFB75.js} +1 -1
- package/dist/{chunk-GN3WRFJY.js → chunk-QC6BILS7.js} +6 -6
- package/dist/{chunk-NISZQW72.js → chunk-QDWDVNWU.js} +2 -2
- package/dist/{chunk-6CYHUWCO.js → chunk-QGKCM7C4.js} +2 -2
- package/dist/{chunk-2QSZNTDO.js → chunk-RKNJBZ55.js} +4 -4
- package/dist/{chunk-QCECHYZL.js → chunk-RVO6TCTU.js} +6 -6
- package/dist/{chunk-MIH3CJPN.js → chunk-TPWBUKS3.js} +3 -3
- package/dist/chunk-UBCBDJOB.js +22 -0
- package/dist/chunk-UBCBDJOB.js.map +1 -0
- package/dist/{chunk-UKYS3NU5.js → chunk-UQWUDD7E.js} +2 -2
- package/dist/{chunk-7BD6O7ZV.js → chunk-XCO2NXPZ.js} +3 -3
- package/dist/{chunk-7TBXNYLO.js → chunk-XDBFSUHX.js} +2 -2
- package/dist/{chunk-W6FNX2LP.js → chunk-XWZ6KOL6.js} +2 -2
- package/dist/{chunk-M4YHAODQ.js → chunk-XXRRHING.js} +285 -232
- package/dist/chunk-XXRRHING.js.map +1 -0
- package/dist/{chunk-ZRZVLB7O.js → chunk-YZFPEHXF.js} +2 -2
- package/dist/{chunk-OUKBMQ2O.js → chunk-Z3SQEEB6.js} +2 -2
- package/dist/{chunk-BRR5EUTF.js → chunk-Z463UYI6.js} +2 -2
- package/dist/{chunk-5FD7JMTX.js → chunk-ZUJW327U.js} +2 -2
- package/dist/{chunk-AHZOMHWN.js → chunk-ZXGKQQ3L.js} +1 -1
- package/dist/{cli-BPDUXnAl.d.ts → cli-DNvGlD4i.d.ts} +3 -3
- package/dist/cli.d.ts +6 -6
- package/dist/cli.js +68 -67
- package/dist/coding/pre-action-gate.js +2 -2
- package/dist/compounding/engine.d.ts +1 -1
- package/dist/compounding/engine.js +14 -14
- package/dist/connectors/codex-materialize-runner.js +14 -14
- package/dist/connectors/index.js +14 -14
- package/dist/consolidation-provenance-check.d.ts +1 -1
- package/dist/consolidation-undo.d.ts +1 -1
- package/dist/contradiction/index.d.ts +1 -1
- package/dist/convergence-refresh.d.ts +1 -1
- package/dist/convergence-refresh.js +16 -16
- package/dist/conversation-index/backend.js +2 -2
- package/dist/corpus-watermark.js +16 -16
- package/dist/entity-retrieval.d.ts +1 -1
- package/dist/entity-retrieval.js +14 -14
- package/dist/explicit-capture.d.ts +4 -4
- package/dist/external-wiki-access.d.ts +5 -5
- package/dist/external-wiki-access.js +43 -42
- package/dist/external-wiki-mcp-tools.d.ts +5 -5
- package/dist/extraction.js +24 -24
- package/dist/{graph-edge-decay-65KMOJWY.js → graph-edge-decay-JI2XDCTY.js} +4 -4
- package/dist/graph-edge-decay-JI2XDCTY.js.map +1 -0
- package/dist/graph-snapshot.js +3 -3
- package/dist/graph.js +2 -2
- package/dist/harmonic-retrieval.js +1 -1
- package/dist/index.d.ts +11 -11
- package/dist/index.js +124 -123
- package/dist/local-llm.js +2 -2
- package/dist/maintenance/memory-governance.js +14 -14
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +1 -1
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +14 -14
- package/dist/maintenance/rebuild-memory-projection.d.ts +1 -1
- package/dist/maintenance/rebuild-memory-projection.js +15 -15
- package/dist/{maintenance-C8aRWfhq.d.ts → maintenance-laHYTo0s.d.ts} +1 -1
- package/dist/mcp-memory-inspector-app.d.ts +5 -5
- package/dist/memory-worth-outcomes.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +1 -1
- package/dist/namespaces/migrate.js +15 -15
- package/dist/namespaces/search.js +6 -6
- package/dist/namespaces/storage.d.ts +1 -1
- package/dist/namespaces/storage.js +14 -14
- package/dist/offline-sync-impression-drain.js +1 -1
- package/dist/operator-doctor-corpus.js +17 -17
- package/dist/operator-toolkit.d.ts +1 -1
- package/dist/operator-toolkit.js +24 -24
- package/dist/orchestration/compression-guideline-coordinator.d.ts +1 -1
- package/dist/orchestration/maintenance.d.ts +2 -2
- package/dist/orchestration/maintenance.js +20 -20
- package/dist/{orchestrator-D85CzDDY.d.ts → orchestrator-Cz2QmqsN.d.ts} +3 -3
- package/dist/orchestrator.d.ts +4 -4
- package/dist/orchestrator.js +127 -126
- package/dist/policy-runtime.js +1 -1
- package/dist/{public-http-D3GBeII4.d.ts → public-http-Dq2iqtcI.d.ts} +1 -1
- package/dist/qmd.js +4 -4
- package/dist/recall-planner-llm.js +3 -3
- package/dist/search/factory.js +5 -5
- package/dist/search/index.js +5 -5
- package/dist/semantic-consolidation.js +15 -15
- package/dist/semantic-rule-promotion.js +14 -14
- package/dist/semantic-rule-verifier.js +14 -14
- package/dist/{service-DT-pJyda.d.ts → service-D_ddZmpI.d.ts} +1 -1
- package/dist/source-agent-qualifier.js +19 -19
- package/dist/{storage-qOnaJ1Lw.d.ts → storage-Cdz7jb9t.d.ts} +14 -9
- package/dist/storage.d.ts +1 -1
- package/dist/storage.js +13 -13
- package/dist/summarizer.js +3 -3
- package/dist/support-passport/index.d.ts +8 -8
- package/dist/support-passport/index.js +45 -44
- package/dist/tier-migration.d.ts +1 -1
- package/dist/transfer/autodetect.js +1 -1
- package/dist/transfer/backup.js +1 -1
- package/dist/transfer/capsule-export.js +2 -2
- package/dist/verified-recall.js +14 -14
- package/package.json +2 -2
- package/src/briefing-window.ts +27 -0
- package/src/briefing.test.ts +29 -0
- package/src/briefing.ts +2 -9
- package/src/maintenance/memory-governance.ts +1 -0
- package/src/storage/memory-read-store.ts +1 -0
- package/src/storage/windowed-memory-read.ts +109 -0
- package/src/storage.ts +7 -13
- package/src/testing/subjects/windowed-memory-read.test.ts +146 -0
- package/dist/chunk-M4YHAODQ.js.map +0 -1
- package/dist/chunk-RUNORG2P.js.map +0 -1
- /package/dist/{graph-edge-decay-65KMOJWY.js.map → briefing-window.js.map} +0 -0
- /package/dist/{chunk-LEPOP46W.js.map → chunk-227UFSEQ.js.map} +0 -0
- /package/dist/{chunk-ZUKIUXHQ.js.map → chunk-2GD6MLXD.js.map} +0 -0
- /package/dist/{chunk-2FKEIPIT.js.map → chunk-2T5AWWMF.js.map} +0 -0
- /package/dist/{chunk-HBUFQRIM.js.map → chunk-3DVG3GRQ.js.map} +0 -0
- /package/dist/{chunk-QZLDRQ4I.js.map → chunk-47J4EDGR.js.map} +0 -0
- /package/dist/{chunk-K26NWEOC.js.map → chunk-4ESX4WX2.js.map} +0 -0
- /package/dist/{chunk-46SZBVDS.js.map → chunk-4GE3NA5I.js.map} +0 -0
- /package/dist/{chunk-FPLM2TKD.js.map → chunk-5V64M56S.js.map} +0 -0
- /package/dist/{chunk-37DZZFFM.js.map → chunk-6G4D222J.js.map} +0 -0
- /package/dist/{chunk-FFRTNF3L.js.map → chunk-6PCND4O2.js.map} +0 -0
- /package/dist/{chunk-26ZXBTYN.js.map → chunk-7DISPKXT.js.map} +0 -0
- /package/dist/{chunk-JYG4OLWH.js.map → chunk-7SF5BAWF.js.map} +0 -0
- /package/dist/{chunk-XZHE2DEN.js.map → chunk-BXIMH7MC.js.map} +0 -0
- /package/dist/{chunk-FTPONF6B.js.map → chunk-E2GZSFR5.js.map} +0 -0
- /package/dist/{chunk-I3MSGFGD.js.map → chunk-ELXP665P.js.map} +0 -0
- /package/dist/{chunk-EKTP7MNS.js.map → chunk-F2BOUJUS.js.map} +0 -0
- /package/dist/{chunk-3TIZPSJC.js.map → chunk-FEBHRT2I.js.map} +0 -0
- /package/dist/{chunk-W5ZKPI34.js.map → chunk-FPKKFDO4.js.map} +0 -0
- /package/dist/{chunk-UPLZNJKN.js.map → chunk-FYZKFLKY.js.map} +0 -0
- /package/dist/{chunk-FWX7W5PM.js.map → chunk-G7YUH4WT.js.map} +0 -0
- /package/dist/{chunk-PT54WISF.js.map → chunk-IEQCHXUS.js.map} +0 -0
- /package/dist/{chunk-YXQEKCZM.js.map → chunk-IOYXIY7W.js.map} +0 -0
- /package/dist/{chunk-CIAI24TQ.js.map → chunk-JKW663ZN.js.map} +0 -0
- /package/dist/{chunk-V6ERBR7U.js.map → chunk-K44N3CFW.js.map} +0 -0
- /package/dist/{chunk-TO7ZTWJW.js.map → chunk-KMWYZTIE.js.map} +0 -0
- /package/dist/{chunk-IPLYGWQF.js.map → chunk-KQAFEZQX.js.map} +0 -0
- /package/dist/{chunk-S354QO4R.js.map → chunk-LHIBA4G7.js.map} +0 -0
- /package/dist/{chunk-UCTS3DDH.js.map → chunk-M3UYE6PS.js.map} +0 -0
- /package/dist/{chunk-D3LBIUWV.js.map → chunk-MTF5EFFF.js.map} +0 -0
- /package/dist/{chunk-IKP5OYQQ.js.map → chunk-NUA4VM46.js.map} +0 -0
- /package/dist/{chunk-UYYW2KPU.js.map → chunk-OIOV4RJE.js.map} +0 -0
- /package/dist/{chunk-BIJAWZYW.js.map → chunk-OLT3YTDH.js.map} +0 -0
- /package/dist/{chunk-RZQ6W2W4.js.map → chunk-OS5DYALF.js.map} +0 -0
- /package/dist/{chunk-IQ4NVWEF.js.map → chunk-OTUFRUV3.js.map} +0 -0
- /package/dist/{chunk-KFBOPMF6.js.map → chunk-OWC42MDT.js.map} +0 -0
- /package/dist/{chunk-43SEBY2M.js.map → chunk-PCRHFB75.js.map} +0 -0
- /package/dist/{chunk-GN3WRFJY.js.map → chunk-QC6BILS7.js.map} +0 -0
- /package/dist/{chunk-NISZQW72.js.map → chunk-QDWDVNWU.js.map} +0 -0
- /package/dist/{chunk-6CYHUWCO.js.map → chunk-QGKCM7C4.js.map} +0 -0
- /package/dist/{chunk-2QSZNTDO.js.map → chunk-RKNJBZ55.js.map} +0 -0
- /package/dist/{chunk-QCECHYZL.js.map → chunk-RVO6TCTU.js.map} +0 -0
- /package/dist/{chunk-MIH3CJPN.js.map → chunk-TPWBUKS3.js.map} +0 -0
- /package/dist/{chunk-UKYS3NU5.js.map → chunk-UQWUDD7E.js.map} +0 -0
- /package/dist/{chunk-7BD6O7ZV.js.map → chunk-XCO2NXPZ.js.map} +0 -0
- /package/dist/{chunk-7TBXNYLO.js.map → chunk-XDBFSUHX.js.map} +0 -0
- /package/dist/{chunk-W6FNX2LP.js.map → chunk-XWZ6KOL6.js.map} +0 -0
- /package/dist/{chunk-ZRZVLB7O.js.map → chunk-YZFPEHXF.js.map} +0 -0
- /package/dist/{chunk-OUKBMQ2O.js.map → chunk-Z3SQEEB6.js.map} +0 -0
- /package/dist/{chunk-BRR5EUTF.js.map → chunk-Z463UYI6.js.map} +0 -0
- /package/dist/{chunk-5FD7JMTX.js.map → chunk-ZUJW327U.js.map} +0 -0
- /package/dist/{chunk-AHZOMHWN.js.map → chunk-ZXGKQQ3L.js.map} +0 -0
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
TombstoneStore,
|
|
3
|
-
applyTombstoneResurrectionGate,
|
|
4
|
-
buildRetiredFactTombstoneInputs,
|
|
5
|
-
collectRetiredMemoriesForRebuild
|
|
6
|
-
} from "./chunk-MLPTFODV.js";
|
|
7
1
|
import {
|
|
8
2
|
WEARABLES_DIR_NAME,
|
|
9
3
|
escapeSegmentText,
|
|
@@ -15,9 +9,15 @@ import {
|
|
|
15
9
|
unescapeSegmentText,
|
|
16
10
|
unescapeSpeakerLabel
|
|
17
11
|
} from "./chunk-UHVXE24Y.js";
|
|
12
|
+
import {
|
|
13
|
+
TombstoneStore,
|
|
14
|
+
applyTombstoneResurrectionGate,
|
|
15
|
+
buildRetiredFactTombstoneInputs,
|
|
16
|
+
collectRetiredMemoriesForRebuild
|
|
17
|
+
} from "./chunk-MLPTFODV.js";
|
|
18
18
|
import {
|
|
19
19
|
normalizeQmdResultPath
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-KMWYZTIE.js";
|
|
21
21
|
import {
|
|
22
22
|
withholdToolScopedFromSharedNamespace
|
|
23
23
|
} from "./chunk-S2V7RUCL.js";
|
|
@@ -247,7 +247,7 @@ import {
|
|
|
247
247
|
readdir as readdir6,
|
|
248
248
|
readFile as readFile2,
|
|
249
249
|
realpath as realpath3,
|
|
250
|
-
stat as
|
|
250
|
+
stat as stat3,
|
|
251
251
|
writeFile as writeFile2,
|
|
252
252
|
mkdir,
|
|
253
253
|
unlink as unlink4,
|
|
@@ -256,11 +256,11 @@ import {
|
|
|
256
256
|
} from "fs/promises";
|
|
257
257
|
import { appendFileSync, createReadStream, mkdirSync, statSync } from "fs";
|
|
258
258
|
import { createHash as createHash6 } from "crypto";
|
|
259
|
-
import
|
|
259
|
+
import path11 from "path";
|
|
260
260
|
|
|
261
261
|
// src/storage/memory-read-store.ts
|
|
262
|
-
import { lstat, readdir, realpath, stat } from "fs/promises";
|
|
263
|
-
import
|
|
262
|
+
import { lstat, readdir, realpath, stat as stat2 } from "fs/promises";
|
|
263
|
+
import path2 from "path";
|
|
264
264
|
|
|
265
265
|
// src/storage/memory-frontmatter-metadata.ts
|
|
266
266
|
var rawDocumentByMemory = /* @__PURE__ */ new WeakMap();
|
|
@@ -272,6 +272,59 @@ function readRawMemoryDocument(owner) {
|
|
|
272
272
|
return rawDocumentByMemory.get(owner);
|
|
273
273
|
}
|
|
274
274
|
|
|
275
|
+
// src/storage/windowed-memory-read.ts
|
|
276
|
+
import { stat } from "fs/promises";
|
|
277
|
+
import path from "path";
|
|
278
|
+
async function readWindowedMemories(store, options, hotCache, rememberMemorySnapshots) {
|
|
279
|
+
if (options.updatedAfter !== void 0 && (!(options.updatedAfter instanceof Date) || !Number.isFinite(options.updatedAfter.getTime()))) {
|
|
280
|
+
throw new TypeError("updatedAfter must be a valid Date");
|
|
281
|
+
}
|
|
282
|
+
if (hotCache.enabled && options.updatedAfter !== void 0 && options.maxMemories === void 0 && options.batchSize === void 0 && options.includeMalformedPaths !== true) {
|
|
283
|
+
const cached = getCachedMemories(hotCache.baseDir, hotCache.corpusVersion, hotCache.cacheKeyId, hotCache.ttlMs);
|
|
284
|
+
if (cached !== null) {
|
|
285
|
+
const updatedAfterMs = options.updatedAfter.getTime();
|
|
286
|
+
const selected = (await Promise.all(
|
|
287
|
+
cached.map(async (memory) => {
|
|
288
|
+
const timestampMs = await readWindowTimestamp(memory);
|
|
289
|
+
return timestampMs === null || timestampMs >= updatedAfterMs ? memory : null;
|
|
290
|
+
})
|
|
291
|
+
)).filter((memory) => memory !== null);
|
|
292
|
+
const memories = orderWindowMemories(selected, hotCache.baseDir);
|
|
293
|
+
return { memories: rememberMemorySnapshots(memories), filePaths: memories.map((memory) => memory.path) };
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
const result = await store.readMemoriesWindow(options);
|
|
297
|
+
return {
|
|
298
|
+
...result,
|
|
299
|
+
memories: rememberMemorySnapshots(result.memories)
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
async function readWindowTimestamp(memory) {
|
|
303
|
+
const rawDocument = readRawMemoryDocument(memory);
|
|
304
|
+
const frontmatterBlock = rawDocument?.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/)?.[1];
|
|
305
|
+
const rawTimestamp = frontmatterBlock?.match(/^[ \t]*updated:[ \t]*"?([^"\r\n]*)"?/m)?.[1] || frontmatterBlock?.match(/^[ \t]*created:[ \t]*"?([^"\r\n]*)"?/m)?.[1] || memory.frontmatter.updated || memory.frontmatter.created;
|
|
306
|
+
const timestampMs = typeof rawTimestamp === "string" ? Date.parse(rawTimestamp.trim()) : Number.NaN;
|
|
307
|
+
if (Number.isFinite(timestampMs)) return timestampMs;
|
|
308
|
+
try {
|
|
309
|
+
return (await stat(memory.path)).mtimeMs;
|
|
310
|
+
} catch {
|
|
311
|
+
return null;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
function orderWindowMemories(memories, baseDir) {
|
|
315
|
+
const correctionsRoot = path.join(baseDir, "corrections");
|
|
316
|
+
const corrections = memories.filter((memory) => memory.path === correctionsRoot || memory.path.startsWith(`${correctionsRoot}${path.sep}`)).sort((left, right) => right.path.localeCompare(left.path));
|
|
317
|
+
const facts = memories.filter((memory) => memory.path !== correctionsRoot && !memory.path.startsWith(`${correctionsRoot}${path.sep}`)).sort((left, right) => right.path.localeCompare(left.path));
|
|
318
|
+
const ordered = [];
|
|
319
|
+
for (let index = 0; index < Math.max(corrections.length, facts.length); index += 1) {
|
|
320
|
+
const correction = corrections[index];
|
|
321
|
+
if (correction) ordered.push(correction);
|
|
322
|
+
const fact = facts[index];
|
|
323
|
+
if (fact) ordered.push(fact);
|
|
324
|
+
}
|
|
325
|
+
return ordered;
|
|
326
|
+
}
|
|
327
|
+
|
|
275
328
|
// src/storage/memory-read-store.ts
|
|
276
329
|
function isPropagatableReadError(err) {
|
|
277
330
|
const code = err.code;
|
|
@@ -304,7 +357,7 @@ var MemoryReadStore = class {
|
|
|
304
357
|
if (!/^[a-z][a-z0-9-]{0,63}$/.test(source)) continue;
|
|
305
358
|
let entries;
|
|
306
359
|
try {
|
|
307
|
-
entries = await readdir(
|
|
360
|
+
entries = await readdir(path2.join(this.deps.wearablesDir, source));
|
|
308
361
|
} catch (err) {
|
|
309
362
|
if (err.code === "ENOENT") continue;
|
|
310
363
|
throw err;
|
|
@@ -337,7 +390,7 @@ var MemoryReadStore = class {
|
|
|
337
390
|
const entries = await readdir(dir, { withFileTypes: true });
|
|
338
391
|
for (const entry of entries) {
|
|
339
392
|
checkCorpusReadAbort(options);
|
|
340
|
-
const fullPath =
|
|
393
|
+
const fullPath = path2.join(dir, entry.name);
|
|
341
394
|
if (entry.isDirectory()) {
|
|
342
395
|
await readDir(fullPath);
|
|
343
396
|
continue;
|
|
@@ -416,7 +469,7 @@ var MemoryReadStore = class {
|
|
|
416
469
|
for (const entry of entries) {
|
|
417
470
|
checkCorpusReadAbort(options);
|
|
418
471
|
if (entry.isSymbolicLink()) continue;
|
|
419
|
-
const fullPath =
|
|
472
|
+
const fullPath = path2.join(dir, entry.name);
|
|
420
473
|
if (entry.isDirectory()) {
|
|
421
474
|
subdirs.push(fullPath);
|
|
422
475
|
} else if (entry.name.endsWith(".md")) {
|
|
@@ -440,7 +493,7 @@ var MemoryReadStore = class {
|
|
|
440
493
|
}
|
|
441
494
|
async collectActiveMemoryPaths(options) {
|
|
442
495
|
return this.collectContainedMarkdownPaths(
|
|
443
|
-
RECALL_FALLBACK_DIRS.map((dir) =>
|
|
496
|
+
RECALL_FALLBACK_DIRS.map((dir) => path2.join(this.deps.baseDir, dir)),
|
|
444
497
|
options?.propagateReadErrors ?? false,
|
|
445
498
|
options
|
|
446
499
|
);
|
|
@@ -465,7 +518,7 @@ var MemoryReadStore = class {
|
|
|
465
518
|
const tiers = await Promise.all([
|
|
466
519
|
this.collectActiveMemoryPaths(),
|
|
467
520
|
this.collectColdMemoryPaths(),
|
|
468
|
-
this.collectContainedMarkdownPaths([
|
|
521
|
+
this.collectContainedMarkdownPaths([path2.join(this.deps.baseDir, "archive")])
|
|
469
522
|
]);
|
|
470
523
|
return tiers.flat();
|
|
471
524
|
}
|
|
@@ -545,7 +598,7 @@ var MemoryReadStore = class {
|
|
|
545
598
|
const entries = await readdir(dir, { withFileTypes: true });
|
|
546
599
|
const subdirs = [];
|
|
547
600
|
for (const entry of entries) {
|
|
548
|
-
const fullPath =
|
|
601
|
+
const fullPath = path2.join(dir, entry.name);
|
|
549
602
|
if (entry.isDirectory()) {
|
|
550
603
|
subdirs.push(fullPath);
|
|
551
604
|
} else if (entry.name.endsWith(".md")) {
|
|
@@ -579,12 +632,12 @@ var MemoryReadStore = class {
|
|
|
579
632
|
content: parsed.content
|
|
580
633
|
}, raw);
|
|
581
634
|
}
|
|
582
|
-
const normalizedPath = filePath.split(
|
|
635
|
+
const normalizedPath = filePath.split(path2.sep).join("/");
|
|
583
636
|
if (normalizedPath.includes("/entities/") && filePath.endsWith(".md")) {
|
|
584
637
|
const entity = parseEntityFile(raw, this.deps.entitySchemas);
|
|
585
638
|
if (!entity.name) return null;
|
|
586
|
-
const nameWithoutExt =
|
|
587
|
-
const fileMtime = entity.updated || await
|
|
639
|
+
const nameWithoutExt = path2.basename(filePath, ".md");
|
|
640
|
+
const fileMtime = entity.updated || await stat2(filePath).then((s) => s.mtime.toISOString()).catch(() => (/* @__PURE__ */ new Date(0)).toISOString());
|
|
588
641
|
return {
|
|
589
642
|
path: filePath,
|
|
590
643
|
frontmatter: {
|
|
@@ -754,7 +807,7 @@ var MemoryReadStore = class {
|
|
|
754
807
|
const cached = this.deps.storageManagerClass.questionsCache.get(cacheKey);
|
|
755
808
|
if (cached && Date.now() - cached.loadedAt < this.deps.storageManagerClass.QUESTIONS_CACHE_TTL_MS) {
|
|
756
809
|
try {
|
|
757
|
-
const dirStat = await
|
|
810
|
+
const dirStat = await stat2(this.deps.questionsDir);
|
|
758
811
|
if (dirStat.mtimeMs <= cached.loadedAt) {
|
|
759
812
|
const all = cached.questions;
|
|
760
813
|
return opts?.unresolvedOnly ? all.filter((q) => !q.resolved) : all;
|
|
@@ -767,7 +820,7 @@ var MemoryReadStore = class {
|
|
|
767
820
|
const questions = [];
|
|
768
821
|
for (const file of files) {
|
|
769
822
|
if (!file.endsWith(".md")) continue;
|
|
770
|
-
const filePath =
|
|
823
|
+
const filePath = path2.join(this.deps.questionsDir, file);
|
|
771
824
|
const raw = await readMaybeEncryptedFile(filePath, this.deps._secureStoreKey, this.deps.baseDir);
|
|
772
825
|
const parsed = this.deps.parseQuestionFile(raw, filePath);
|
|
773
826
|
if (parsed) {
|
|
@@ -1494,7 +1547,7 @@ function selfDeps(self) {
|
|
|
1494
1547
|
|
|
1495
1548
|
// src/storage/entity-store.ts
|
|
1496
1549
|
import { readdir as readdir2, unlink } from "fs/promises";
|
|
1497
|
-
import
|
|
1550
|
+
import path3 from "path";
|
|
1498
1551
|
var EntityStore = class {
|
|
1499
1552
|
constructor(deps) {
|
|
1500
1553
|
this.deps = deps;
|
|
@@ -1514,7 +1567,7 @@ var EntityStore = class {
|
|
|
1514
1567
|
async readEntityForMutation(name, method, historicalIds) {
|
|
1515
1568
|
const canonical = resolveHistoricalEntityCanonicalId(name, historicalIds);
|
|
1516
1569
|
for (const candidate of canonical === name ? [name] : [canonical, name]) {
|
|
1517
|
-
const filePath =
|
|
1570
|
+
const filePath = path3.join(this.deps.entitiesDir, `${candidate}.md`);
|
|
1518
1571
|
try {
|
|
1519
1572
|
const entity = parseEntityFile(await this.deps.readStorageSecureFile(filePath), this.deps.entitySchemas);
|
|
1520
1573
|
return { filePath, entity };
|
|
@@ -1539,7 +1592,7 @@ var EntityStore = class {
|
|
|
1539
1592
|
* `mutate` returns false to skip the write. Resolves true when written.
|
|
1540
1593
|
*/
|
|
1541
1594
|
async mutateEntityFile(name, method, mutate) {
|
|
1542
|
-
const stateDir =
|
|
1595
|
+
const stateDir = path3.join(this.deps.baseDir, "state");
|
|
1543
1596
|
return withEntityCanonicalMutationLock(stateDir, async () => {
|
|
1544
1597
|
for (let attempt = 0; attempt < 3; attempt += 1) {
|
|
1545
1598
|
const idsAtResolve = this.deps.currentHistoricalIds();
|
|
@@ -1594,7 +1647,7 @@ var EntityStore = class {
|
|
|
1594
1647
|
async writeEntity(name, type, facts, options = {}) {
|
|
1595
1648
|
await this.deps.ensureDirectories();
|
|
1596
1649
|
return withEntityCanonicalMutationLock(
|
|
1597
|
-
|
|
1650
|
+
path3.join(this.deps.baseDir, "state"),
|
|
1598
1651
|
() => this.writeEntityUnlocked(name, type, facts, options)
|
|
1599
1652
|
);
|
|
1600
1653
|
}
|
|
@@ -1615,7 +1668,7 @@ var EntityStore = class {
|
|
|
1615
1668
|
log.debug(`fuzzy match: "${normalized}" \u2192 existing "${match}"`);
|
|
1616
1669
|
normalized = match;
|
|
1617
1670
|
}
|
|
1618
|
-
const filePath =
|
|
1671
|
+
const filePath = path3.join(this.deps.entitiesDir, `${normalized}.md`);
|
|
1619
1672
|
let entity = {
|
|
1620
1673
|
name,
|
|
1621
1674
|
type,
|
|
@@ -1726,7 +1779,7 @@ var EntityStore = class {
|
|
|
1726
1779
|
/** Re-serialize every entity file into the compiled-truth timeline shape. */
|
|
1727
1780
|
async migrateEntityFilesToCompiledTruthTimeline() {
|
|
1728
1781
|
const entityNames = await this.listEntityNames();
|
|
1729
|
-
const stateDir =
|
|
1782
|
+
const stateDir = path3.join(this.deps.baseDir, "state");
|
|
1730
1783
|
let migrated = 0;
|
|
1731
1784
|
for (const entityName of entityNames) {
|
|
1732
1785
|
const wrote = await withEntityCanonicalMutationLock(stateDir, async () => {
|
|
@@ -1753,12 +1806,12 @@ var EntityStore = class {
|
|
|
1753
1806
|
*/
|
|
1754
1807
|
async updateEntitySynthesis(name, synthesis, options = {}) {
|
|
1755
1808
|
return withEntityCanonicalMutationLock(
|
|
1756
|
-
|
|
1809
|
+
path3.join(this.deps.baseDir, "state"),
|
|
1757
1810
|
() => this.updateEntitySynthesisUnlocked(name, synthesis, options)
|
|
1758
1811
|
);
|
|
1759
1812
|
}
|
|
1760
1813
|
async updateEntitySynthesisUnlocked(name, synthesis, options = {}) {
|
|
1761
|
-
const filePath =
|
|
1814
|
+
const filePath = path3.join(this.deps.entitiesDir, `${name}.md`);
|
|
1762
1815
|
let entity;
|
|
1763
1816
|
try {
|
|
1764
1817
|
const content = await this.deps.readStorageSecureFile(filePath);
|
|
@@ -1816,7 +1869,7 @@ var EntityStore = class {
|
|
|
1816
1869
|
const results = await Promise.all(
|
|
1817
1870
|
batch.map(async (entry) => {
|
|
1818
1871
|
try {
|
|
1819
|
-
return await this.deps.readStorageSecureFile(
|
|
1872
|
+
return await this.deps.readStorageSecureFile(path3.join(this.deps.entitiesDir, entry));
|
|
1820
1873
|
} catch (err) {
|
|
1821
1874
|
if (err instanceof SecureStoreLockedError) throw err;
|
|
1822
1875
|
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
@@ -1891,7 +1944,7 @@ ${rows.join("\n")}
|
|
|
1891
1944
|
*/
|
|
1892
1945
|
async mergeFragmentedEntities() {
|
|
1893
1946
|
return withEntityCanonicalMutationLock(
|
|
1894
|
-
|
|
1947
|
+
path3.join(this.deps.baseDir, "state"),
|
|
1895
1948
|
() => this.mergeFragmentedEntitiesUnlocked()
|
|
1896
1949
|
);
|
|
1897
1950
|
}
|
|
@@ -1936,7 +1989,7 @@ ${rows.join("\n")}
|
|
|
1936
1989
|
extraSections: []
|
|
1937
1990
|
};
|
|
1938
1991
|
for (const file of files) {
|
|
1939
|
-
const filePath =
|
|
1992
|
+
const filePath = path3.join(this.deps.entitiesDir, file);
|
|
1940
1993
|
try {
|
|
1941
1994
|
const content = await this.deps.readStorageSecureFile(filePath);
|
|
1942
1995
|
const parsed = parseEntityFile(content, this.deps.entitySchemas);
|
|
@@ -2067,11 +2120,11 @@ ${rows.join("\n")}
|
|
|
2067
2120
|
}
|
|
2068
2121
|
mergedEntity.created = mergedEntity.created || mergedEntity.updated || (/* @__PURE__ */ new Date()).toISOString();
|
|
2069
2122
|
mergedEntity.updated = mergedEntity.updated || (/* @__PURE__ */ new Date()).toISOString();
|
|
2070
|
-
const canonicalPath =
|
|
2123
|
+
const canonicalPath = path3.join(this.deps.entitiesDir, `${canonical}.md`);
|
|
2071
2124
|
await this.deps.writeStorageSecureFile(canonicalPath, serializeEntityFile(mergedEntity, this.deps.entitySchemas));
|
|
2072
2125
|
this.deps.bumpEntityMutationVersion();
|
|
2073
2126
|
for (const file of files) {
|
|
2074
|
-
const filePath =
|
|
2127
|
+
const filePath = path3.join(this.deps.entitiesDir, file);
|
|
2075
2128
|
if (filePath !== canonicalPath) {
|
|
2076
2129
|
try {
|
|
2077
2130
|
await unlink(filePath);
|
|
@@ -2091,7 +2144,7 @@ ${rows.join("\n")}
|
|
|
2091
2144
|
|
|
2092
2145
|
// src/storage/identity-continuity-store.ts
|
|
2093
2146
|
import { readdir as readdir3 } from "fs/promises";
|
|
2094
|
-
import
|
|
2147
|
+
import path4 from "path";
|
|
2095
2148
|
var IdentityContinuityStore = class {
|
|
2096
2149
|
constructor(deps) {
|
|
2097
2150
|
this.deps = deps;
|
|
@@ -2116,7 +2169,7 @@ var IdentityContinuityStore = class {
|
|
|
2116
2169
|
const date = nowIso.slice(0, 10);
|
|
2117
2170
|
const id = this.deps.generateId("incident");
|
|
2118
2171
|
const incident = createContinuityIncidentRecord(id, input, nowIso);
|
|
2119
|
-
const filePath =
|
|
2172
|
+
const filePath = path4.join(this.deps.identityIncidentsDir, `${date}-${id}.md`);
|
|
2120
2173
|
await this.deps.writeStorageSecureFile(filePath, serializeContinuityIncident(incident));
|
|
2121
2174
|
return { ...incident, filePath };
|
|
2122
2175
|
}
|
|
@@ -2129,7 +2182,7 @@ var IdentityContinuityStore = class {
|
|
|
2129
2182
|
const incidents = [];
|
|
2130
2183
|
for (const file of candidates) {
|
|
2131
2184
|
if (incidents.length >= cappedLimit) break;
|
|
2132
|
-
const filePath =
|
|
2185
|
+
const filePath = path4.join(this.deps.identityIncidentsDir, file);
|
|
2133
2186
|
try {
|
|
2134
2187
|
const raw = await this.deps.readStorageSecureFile(filePath);
|
|
2135
2188
|
const parsed = parseContinuityIncident(raw);
|
|
@@ -2160,7 +2213,7 @@ var IdentityContinuityStore = class {
|
|
|
2160
2213
|
await this.deps.ensureDirectories();
|
|
2161
2214
|
const safeKey = this.sanitizeIdentityAuditKey(key);
|
|
2162
2215
|
const dir = period === "weekly" ? this.deps.identityAuditsWeeklyDir : this.deps.identityAuditsMonthlyDir;
|
|
2163
|
-
const filePath =
|
|
2216
|
+
const filePath = path4.join(dir, `${safeKey}.md`);
|
|
2164
2217
|
await this.deps.writeStorageSecureFile(filePath, content);
|
|
2165
2218
|
return filePath;
|
|
2166
2219
|
}
|
|
@@ -2168,7 +2221,7 @@ var IdentityContinuityStore = class {
|
|
|
2168
2221
|
try {
|
|
2169
2222
|
const safeKey = this.sanitizeIdentityAuditKey(key);
|
|
2170
2223
|
const dir = period === "weekly" ? this.deps.identityAuditsWeeklyDir : this.deps.identityAuditsMonthlyDir;
|
|
2171
|
-
return await this.deps.readStorageSecureFile(
|
|
2224
|
+
return await this.deps.readStorageSecureFile(path4.join(dir, `${safeKey}.md`));
|
|
2172
2225
|
} catch (err) {
|
|
2173
2226
|
if (err instanceof Error && err.message === "Invalid identity audit key") return null;
|
|
2174
2227
|
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
@@ -2224,12 +2277,12 @@ var IdentityContinuityStore = class {
|
|
|
2224
2277
|
const fileNames = await this.readContinuityIncidentFileNames();
|
|
2225
2278
|
const directMatch = fileNames.find((name) => name.endsWith(`-${id}.md`));
|
|
2226
2279
|
if (directMatch) {
|
|
2227
|
-
const directPath =
|
|
2280
|
+
const directPath = path4.join(this.deps.identityIncidentsDir, directMatch);
|
|
2228
2281
|
const parsed = await this.readContinuityIncidentFile(directPath);
|
|
2229
2282
|
if (parsed?.id === id) return directPath;
|
|
2230
2283
|
}
|
|
2231
2284
|
for (const fileName of fileNames) {
|
|
2232
|
-
const filePath =
|
|
2285
|
+
const filePath = path4.join(this.deps.identityIncidentsDir, fileName);
|
|
2233
2286
|
const parsed = await this.readContinuityIncidentFile(filePath);
|
|
2234
2287
|
if (parsed?.id === id) return filePath;
|
|
2235
2288
|
}
|
|
@@ -2257,7 +2310,7 @@ import {
|
|
|
2257
2310
|
unlink as unlink2,
|
|
2258
2311
|
writeFile
|
|
2259
2312
|
} from "fs/promises";
|
|
2260
|
-
import
|
|
2313
|
+
import path5 from "path";
|
|
2261
2314
|
import { z } from "zod";
|
|
2262
2315
|
var ENTITY_CANONICAL_ID_MIGRATION_VERSION = 1;
|
|
2263
2316
|
var ENTITY_CANONICAL_ID_MIGRATION_LOCK_STALE_MS = 6e4;
|
|
@@ -2291,7 +2344,7 @@ async function fingerprintPath(filePath) {
|
|
|
2291
2344
|
async function fingerprintEntityEntries(entitiesDir) {
|
|
2292
2345
|
let names;
|
|
2293
2346
|
try {
|
|
2294
|
-
names = (await readdir4(entitiesDir)).filter((name) =>
|
|
2347
|
+
names = (await readdir4(entitiesDir)).filter((name) => path5.extname(name) === ".md").sort();
|
|
2295
2348
|
} catch (error) {
|
|
2296
2349
|
if (isErrnoCode(error, "ENOENT")) return "missing";
|
|
2297
2350
|
throw error;
|
|
@@ -2300,7 +2353,7 @@ async function fingerprintEntityEntries(entitiesDir) {
|
|
|
2300
2353
|
for (const name of names) {
|
|
2301
2354
|
hash.update(`${name.length}:${name}:`);
|
|
2302
2355
|
try {
|
|
2303
|
-
const entry = await lstat2(
|
|
2356
|
+
const entry = await lstat2(path5.join(entitiesDir, name), { bigint: true });
|
|
2304
2357
|
hash.update(`${entry.dev}:${entry.ino}:${entry.size}:${entry.mtimeNs}:${entry.ctimeNs}`);
|
|
2305
2358
|
} catch (error) {
|
|
2306
2359
|
if (!isErrnoCode(error, "ENOENT")) throw error;
|
|
@@ -2320,9 +2373,9 @@ async function getFingerprint(baseDir, entitiesDir, getEntityMutationVersion) {
|
|
|
2320
2373
|
] = await Promise.all([
|
|
2321
2374
|
fingerprintPath(entitiesDir),
|
|
2322
2375
|
fingerprintEntityEntries(entitiesDir),
|
|
2323
|
-
fingerprintPath(
|
|
2324
|
-
fingerprintPath(
|
|
2325
|
-
fingerprintPath(
|
|
2376
|
+
fingerprintPath(path5.join(baseDir, "config", "aliases.json")),
|
|
2377
|
+
fingerprintPath(path5.join(baseDir, "state", ENTITY_CANONICAL_ID_RECONCILE_MARKER)),
|
|
2378
|
+
fingerprintPath(path5.join(baseDir, "state", ENTITY_CANONICAL_ID_RECONCILE_CONSUMING_MARKER))
|
|
2326
2379
|
]);
|
|
2327
2380
|
return [
|
|
2328
2381
|
entityDirectoryFingerprint,
|
|
@@ -2348,8 +2401,8 @@ async function validateRoots(baseDir, entitiesDir, stateDir, archiveDir) {
|
|
|
2348
2401
|
const roots = [
|
|
2349
2402
|
entitiesDir,
|
|
2350
2403
|
stateDir,
|
|
2351
|
-
...RECALL_FALLBACK_DIRS.map((directory) =>
|
|
2352
|
-
|
|
2404
|
+
...RECALL_FALLBACK_DIRS.map((directory) => path5.join(baseDir, directory)),
|
|
2405
|
+
path5.join(baseDir, "cold"),
|
|
2353
2406
|
archiveDir
|
|
2354
2407
|
];
|
|
2355
2408
|
for (const root of roots) {
|
|
@@ -2367,7 +2420,7 @@ async function validateRoots(baseDir, entitiesDir, stateDir, archiveDir) {
|
|
|
2367
2420
|
}
|
|
2368
2421
|
}
|
|
2369
2422
|
function statePath(deps) {
|
|
2370
|
-
return
|
|
2423
|
+
return path5.join(deps.stateDir, ENTITY_CANONICAL_ID_MIGRATION_FILE);
|
|
2371
2424
|
}
|
|
2372
2425
|
async function assertSafeMigrationStateFile(deps) {
|
|
2373
2426
|
const migrationStatePath = statePath(deps);
|
|
@@ -2410,7 +2463,7 @@ async function assertSafeTombstoneFile(deps, tombstonePath) {
|
|
|
2410
2463
|
return true;
|
|
2411
2464
|
}
|
|
2412
2465
|
function lockPath(deps) {
|
|
2413
|
-
return
|
|
2466
|
+
return path5.join(deps.stateDir, "entity-canonical-id-migration.lock");
|
|
2414
2467
|
}
|
|
2415
2468
|
async function readState(deps) {
|
|
2416
2469
|
await assertSafeMigrationStateFile(deps);
|
|
@@ -2472,26 +2525,26 @@ async function sameFileIdentity(leftPath, rightPath) {
|
|
|
2472
2525
|
}
|
|
2473
2526
|
}
|
|
2474
2527
|
async function assertNotSymlink(filePath, label) {
|
|
2475
|
-
let
|
|
2528
|
+
let stat4;
|
|
2476
2529
|
try {
|
|
2477
|
-
|
|
2530
|
+
stat4 = await lstat2(filePath);
|
|
2478
2531
|
} catch (error) {
|
|
2479
2532
|
if (isErrnoCode(error, "ENOENT")) return;
|
|
2480
2533
|
throw error;
|
|
2481
2534
|
}
|
|
2482
|
-
if (
|
|
2535
|
+
if (stat4.isSymbolicLink()) {
|
|
2483
2536
|
throw new Error(`Refusing entity canonical-id migration through symlink: ${label}.`);
|
|
2484
2537
|
}
|
|
2485
2538
|
}
|
|
2486
2539
|
async function assertNotMemorySymlink(filePath) {
|
|
2487
|
-
let
|
|
2540
|
+
let stat4;
|
|
2488
2541
|
try {
|
|
2489
|
-
|
|
2542
|
+
stat4 = await lstat2(filePath);
|
|
2490
2543
|
} catch (error) {
|
|
2491
2544
|
if (isErrnoCode(error, "ENOENT")) return;
|
|
2492
2545
|
throw error;
|
|
2493
2546
|
}
|
|
2494
|
-
if (
|
|
2547
|
+
if (stat4.isSymbolicLink()) {
|
|
2495
2548
|
throw new Error(`Refusing entity canonical-id migration through symlinked memory: ${filePath}.`);
|
|
2496
2549
|
}
|
|
2497
2550
|
}
|
|
@@ -2508,7 +2561,7 @@ async function readSafeEntityEntries(entitiesDir) {
|
|
|
2508
2561
|
}
|
|
2509
2562
|
const entries = await readdir4(entitiesDir);
|
|
2510
2563
|
for (const entry of entries) {
|
|
2511
|
-
await assertNotSymlink(
|
|
2564
|
+
await assertNotSymlink(path5.join(entitiesDir, entry), entry);
|
|
2512
2565
|
}
|
|
2513
2566
|
return entries;
|
|
2514
2567
|
}
|
|
@@ -2570,7 +2623,7 @@ async function rewriteReferences(deps, mappings, refreshLock) {
|
|
|
2570
2623
|
const seenPaths = /* @__PURE__ */ new Set();
|
|
2571
2624
|
let rewroteAny = false;
|
|
2572
2625
|
for (const memory of [...hotMemories, ...coldMemories, ...archivedMemories]) {
|
|
2573
|
-
const memoryPath =
|
|
2626
|
+
const memoryPath = path5.resolve(memory.path);
|
|
2574
2627
|
if (seenPaths.has(memoryPath)) continue;
|
|
2575
2628
|
seenPaths.add(memoryPath);
|
|
2576
2629
|
const previousEntityRef = memory.frontmatter.entityRef;
|
|
@@ -2602,7 +2655,7 @@ async function rewriteReferences(deps, mappings, refreshLock) {
|
|
|
2602
2655
|
latestCanonicalId
|
|
2603
2656
|
);
|
|
2604
2657
|
rewroteAny = true;
|
|
2605
|
-
rewroteColdMemory ||= latestMemory.path.includes(`${
|
|
2658
|
+
rewroteColdMemory ||= latestMemory.path.includes(`${path5.sep}cold${path5.sep}`);
|
|
2606
2659
|
}
|
|
2607
2660
|
if (!rewroteAny) return { rewroteColdMemory };
|
|
2608
2661
|
}
|
|
@@ -2641,7 +2694,7 @@ function rewriteTombstoneLine(line, mappings, normalizedMappings) {
|
|
|
2641
2694
|
return changed ? JSON.stringify(tombstone) : line;
|
|
2642
2695
|
}
|
|
2643
2696
|
async function rewriteTombstoneReferences(deps, mappings, refreshLock) {
|
|
2644
|
-
const tombstonePath =
|
|
2697
|
+
const tombstonePath = path5.join(deps.stateDir, "tombstones.jsonl");
|
|
2645
2698
|
const normalizedMappings = /* @__PURE__ */ new Map();
|
|
2646
2699
|
for (const [legacyId, canonicalId] of Object.entries(mappings)) {
|
|
2647
2700
|
const normalizedLegacyId = normalizeSupersessionKey(legacyId);
|
|
@@ -2650,7 +2703,7 @@ async function rewriteTombstoneReferences(deps, mappings, refreshLock) {
|
|
|
2650
2703
|
}
|
|
2651
2704
|
}
|
|
2652
2705
|
await withHeldFileLock(
|
|
2653
|
-
|
|
2706
|
+
path5.join(deps.stateDir, "tombstones.lock"),
|
|
2654
2707
|
{
|
|
2655
2708
|
staleMs: TOMBSTONE_LOCK_STALE_MS,
|
|
2656
2709
|
maxWaitMs: TOMBSTONE_LOCK_MAX_WAIT_MS
|
|
@@ -2889,8 +2942,8 @@ async function migrateLegacyEntityCanonicalIds(deps) {
|
|
|
2889
2942
|
if (!acquired) throw new Error("Timed out waiting for active entity canonical-id migration.");
|
|
2890
2943
|
await deps.validateMemoryScanRoots?.();
|
|
2891
2944
|
await readSafeEntityEntries(deps.entitiesDir);
|
|
2892
|
-
const reconcileMarkerPath =
|
|
2893
|
-
const consumingMarkerPath =
|
|
2945
|
+
const reconcileMarkerPath = path5.join(deps.stateDir, ENTITY_CANONICAL_ID_RECONCILE_MARKER);
|
|
2946
|
+
const consumingMarkerPath = path5.join(deps.stateDir, ENTITY_CANONICAL_ID_RECONCILE_CONSUMING_MARKER);
|
|
2894
2947
|
let reconcileRequested = await fileExists(consumingMarkerPath);
|
|
2895
2948
|
if (await fileExists(reconcileMarkerPath)) {
|
|
2896
2949
|
try {
|
|
@@ -3286,7 +3339,7 @@ import {
|
|
|
3286
3339
|
readFileSync,
|
|
3287
3340
|
realpathSync
|
|
3288
3341
|
} from "fs";
|
|
3289
|
-
import
|
|
3342
|
+
import path6 from "path";
|
|
3290
3343
|
function resolveSafeAliasRoots(baseDir, configDir) {
|
|
3291
3344
|
let baseStat;
|
|
3292
3345
|
try {
|
|
@@ -3313,8 +3366,8 @@ function resolveSafeAliasRoots(baseDir, configDir) {
|
|
|
3313
3366
|
return memoryRoot;
|
|
3314
3367
|
}
|
|
3315
3368
|
function readEntityAliasConfigSync(baseDir) {
|
|
3316
|
-
const configDir =
|
|
3317
|
-
const aliasPath =
|
|
3369
|
+
const configDir = path6.join(baseDir, "config");
|
|
3370
|
+
const aliasPath = path6.join(configDir, "aliases.json");
|
|
3318
3371
|
let memoryRoot = resolveSafeAliasRoots(baseDir, configDir);
|
|
3319
3372
|
if (memoryRoot === void 0) return void 0;
|
|
3320
3373
|
let aliasPreflight;
|
|
@@ -3375,7 +3428,7 @@ function decodeYamlScalar(value) {
|
|
|
3375
3428
|
}
|
|
3376
3429
|
|
|
3377
3430
|
// src/orchestration/qmd-result-resolver.ts
|
|
3378
|
-
import
|
|
3431
|
+
import path7 from "path";
|
|
3379
3432
|
var INTERNAL_QMD_ROOTS = /* @__PURE__ */ new Set([
|
|
3380
3433
|
...ALL_CATEGORY_DIRS,
|
|
3381
3434
|
"activity",
|
|
@@ -3396,7 +3449,7 @@ var INTERNAL_QMD_ROOTS = /* @__PURE__ */ new Set([
|
|
|
3396
3449
|
]);
|
|
3397
3450
|
var PRIVATE_RESULT_RESOLUTION_CONCURRENCY = 16;
|
|
3398
3451
|
function qmdCollectionPathParts(resultPath) {
|
|
3399
|
-
if (!resultPath ||
|
|
3452
|
+
if (!resultPath || path7.isAbsolute(resultPath)) return null;
|
|
3400
3453
|
if (resultPath.trim().startsWith("qmd://")) {
|
|
3401
3454
|
try {
|
|
3402
3455
|
const parsed = new URL(resultPath.trim());
|
|
@@ -3421,9 +3474,9 @@ function qmdCollectionPathParts(resultPath) {
|
|
|
3421
3474
|
}
|
|
3422
3475
|
function qmdResultPathCandidates(storageDir, resultPath) {
|
|
3423
3476
|
const candidates = /* @__PURE__ */ new Set();
|
|
3424
|
-
const storageRoot =
|
|
3477
|
+
const storageRoot = path7.resolve(storageDir);
|
|
3425
3478
|
const addCandidate = (candidate) => {
|
|
3426
|
-
const resolved =
|
|
3479
|
+
const resolved = path7.resolve(candidate);
|
|
3427
3480
|
if (isPathInsideStorageRoot(storageRoot, resolved)) {
|
|
3428
3481
|
candidates.add(resolved);
|
|
3429
3482
|
}
|
|
@@ -3431,18 +3484,18 @@ function qmdResultPathCandidates(storageDir, resultPath) {
|
|
|
3431
3484
|
const addRelativeCandidates = (relativePath) => {
|
|
3432
3485
|
const normalized = relativePath.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
3433
3486
|
if (!normalized) return;
|
|
3434
|
-
addCandidate(
|
|
3487
|
+
addCandidate(path7.join(storageRoot, normalized));
|
|
3435
3488
|
if (/^\d{4}-\d{2}-\d{2}\//.test(normalized)) {
|
|
3436
|
-
addCandidate(
|
|
3489
|
+
addCandidate(path7.join(storageRoot, "facts", normalized));
|
|
3437
3490
|
}
|
|
3438
3491
|
};
|
|
3439
|
-
if (
|
|
3492
|
+
if (path7.isAbsolute(resultPath)) {
|
|
3440
3493
|
addCandidate(resultPath);
|
|
3441
|
-
const relative2 =
|
|
3442
|
-
if (relative2 && !relative2.startsWith("..") && !
|
|
3443
|
-
const normalized = relative2.split(
|
|
3494
|
+
const relative2 = path7.relative(storageRoot, path7.resolve(resultPath));
|
|
3495
|
+
if (relative2 && !relative2.startsWith("..") && !path7.isAbsolute(relative2)) {
|
|
3496
|
+
const normalized = relative2.split(path7.sep).join("/");
|
|
3444
3497
|
if (/^\d{4}-\d{2}-\d{2}\//.test(normalized)) {
|
|
3445
|
-
addCandidate(
|
|
3498
|
+
addCandidate(path7.join(storageRoot, "facts", normalized));
|
|
3446
3499
|
}
|
|
3447
3500
|
}
|
|
3448
3501
|
} else {
|
|
@@ -3478,7 +3531,7 @@ var QmdResultResolver = class {
|
|
|
3478
3531
|
const seenStorageDirs = /* @__PURE__ */ new Set();
|
|
3479
3532
|
const addStorage = (storage) => {
|
|
3480
3533
|
const storageDir = storageDirOrNull(storage);
|
|
3481
|
-
const storageKey = storageDir ?
|
|
3534
|
+
const storageKey = storageDir ? path7.resolve(storageDir) : `storage-without-dir-${storages.length}`;
|
|
3482
3535
|
if (seenStorageDirs.has(storageKey)) return;
|
|
3483
3536
|
seenStorageDirs.add(storageKey);
|
|
3484
3537
|
storages.push(storage);
|
|
@@ -3508,7 +3561,7 @@ var QmdResultResolver = class {
|
|
|
3508
3561
|
continue;
|
|
3509
3562
|
}
|
|
3510
3563
|
try {
|
|
3511
|
-
const coldRoot =
|
|
3564
|
+
const coldRoot = path7.join(storageDir, "cold");
|
|
3512
3565
|
for (const candidate of qmdResultPathCandidates(coldRoot, parts.relativePath)) {
|
|
3513
3566
|
const memory = await storage.readMemoryByPath(candidate);
|
|
3514
3567
|
if (memory) return memory;
|
|
@@ -3558,9 +3611,9 @@ var QmdResultResolver = class {
|
|
|
3558
3611
|
error: err.message
|
|
3559
3612
|
});
|
|
3560
3613
|
}
|
|
3561
|
-
if (!
|
|
3614
|
+
if (!path7.isAbsolute(fallbackResultPath)) return null;
|
|
3562
3615
|
}
|
|
3563
|
-
if (
|
|
3616
|
+
if (path7.isAbsolute(fallbackResultPath)) {
|
|
3564
3617
|
if (!fallbackStorageDir) {
|
|
3565
3618
|
return await fallbackStorage.readMemoryByPath(fallbackResultPath);
|
|
3566
3619
|
}
|
|
@@ -3617,17 +3670,17 @@ var QmdResultResolver = class {
|
|
|
3617
3670
|
if (!memory && parts && !collectionIsKnownInternal && !collectionIsConfigured) {
|
|
3618
3671
|
memory = await this.readQmdResultMemory(parts.relativePath, fallbackStorage, namespaces, result.namespace);
|
|
3619
3672
|
}
|
|
3620
|
-
const absoluteInsideMemoryRoot =
|
|
3673
|
+
const absoluteInsideMemoryRoot = path7.isAbsolute(result.path) && isPathInsideStorageRoot(path7.resolve(config.memoryDir), path7.resolve(result.path));
|
|
3621
3674
|
const hasExplicitQmdCollection = result.path.trim().startsWith("qmd://");
|
|
3622
3675
|
const unresolvedInternalPath = !memory && (absoluteInsideMemoryRoot || collectionIsKnownInternal && (!preserveUnresolved || hasExplicitQmdCollection) || hasExplicitQmdCollection && collectionIsConfigured);
|
|
3623
|
-
const unresolvedExternalCollection = !memory && (parts !== null && !collectionIsKnownInternal && !collectionIsConfigured ||
|
|
3676
|
+
const unresolvedExternalCollection = !memory && (parts !== null && !collectionIsKnownInternal && !collectionIsConfigured || path7.isAbsolute(result.path) && !isPathInsideStorageRoot(path7.resolve(config.memoryDir), path7.resolve(result.path)));
|
|
3624
3677
|
return memory !== null && !isSupportPassportPrivateMemory(memory) || !memory && !unresolvedInternalPath && (preserveUnresolved || unresolvedExternalCollection);
|
|
3625
3678
|
}
|
|
3626
3679
|
async resolveColdQmdResultForRecall(result, fallbackStorage, recallNamespaces = []) {
|
|
3627
3680
|
const memory = await this.readQmdResultMemory(result.path, fallbackStorage, recallNamespaces, result.namespace);
|
|
3628
3681
|
if (!memory) return null;
|
|
3629
3682
|
let ownerNamespace = null;
|
|
3630
|
-
if (
|
|
3683
|
+
if (path7.isAbsolute(memory.path)) {
|
|
3631
3684
|
const ownerStorage = await this.storageForAbsoluteQmdResultPath(memory.path, fallbackStorage, recallNamespaces);
|
|
3632
3685
|
ownerNamespace = ownerStorage?.namespace ?? null;
|
|
3633
3686
|
if (!ownerNamespace && resolveNamespaceCapabilities(this.getConfig()).namespaces) return null;
|
|
@@ -3647,17 +3700,17 @@ var QmdResultResolver = class {
|
|
|
3647
3700
|
};
|
|
3648
3701
|
}
|
|
3649
3702
|
async storageForAbsoluteQmdResultPath(resultPath, fallbackStorage, recallNamespaces = []) {
|
|
3650
|
-
const resolvedPath =
|
|
3703
|
+
const resolvedPath = path7.resolve(resultPath);
|
|
3651
3704
|
const config = this.getConfig();
|
|
3652
|
-
const memoryRoot =
|
|
3653
|
-
const namespacesRoot =
|
|
3705
|
+
const memoryRoot = path7.resolve(config.memoryDir);
|
|
3706
|
+
const namespacesRoot = path7.join(memoryRoot, "namespaces");
|
|
3654
3707
|
const fallbackStorageDir = storageDirOrNull(fallbackStorage);
|
|
3655
3708
|
const matches = [];
|
|
3656
3709
|
const seenDirs = /* @__PURE__ */ new Set();
|
|
3657
3710
|
const maybeAddStorage = (storage, namespace) => {
|
|
3658
3711
|
const storageDir = storageDirOrNull(storage);
|
|
3659
3712
|
if (!storageDir) return;
|
|
3660
|
-
const candidateRoot =
|
|
3713
|
+
const candidateRoot = path7.resolve(storageDir);
|
|
3661
3714
|
if (seenDirs.has(candidateRoot)) return;
|
|
3662
3715
|
if (!isPathInsideStorageRoot(candidateRoot, resolvedPath)) return;
|
|
3663
3716
|
if (candidateRoot === memoryRoot && isPathInsideStorageRoot(namespacesRoot, resolvedPath)) {
|
|
@@ -3675,7 +3728,7 @@ var QmdResultResolver = class {
|
|
|
3675
3728
|
candidateNamespaces.add(ns);
|
|
3676
3729
|
}
|
|
3677
3730
|
if (isPathInsideStorageRoot(namespacesRoot, resolvedPath)) {
|
|
3678
|
-
const relativeToNamespaces =
|
|
3731
|
+
const relativeToNamespaces = path7.relative(namespacesRoot, resolvedPath);
|
|
3679
3732
|
const [namespaceSegment] = relativeToNamespaces.split(/[\\/]/);
|
|
3680
3733
|
if (namespaceSegment) {
|
|
3681
3734
|
candidateNamespaces.add(namespaceIdentityFromToken(namespaceSegment) ?? namespaceSegment);
|
|
@@ -4321,7 +4374,7 @@ function fuseDay(date, inputs, options = {}) {
|
|
|
4321
4374
|
|
|
4322
4375
|
// src/wearables/fusion/store.ts
|
|
4323
4376
|
import { createHash as createHash3 } from "crypto";
|
|
4324
|
-
import * as
|
|
4377
|
+
import * as path8 from "path";
|
|
4325
4378
|
var FUSION_KIND = "wearable-fusion";
|
|
4326
4379
|
function hashFusionBody(conversations) {
|
|
4327
4380
|
return createHash3("sha256").update(JSON.stringify(conversations), "utf-8").digest("hex");
|
|
@@ -4508,7 +4561,7 @@ var FusionArtifactStore = class {
|
|
|
4508
4561
|
`invalid wearable fusion date '${String(date)}' \u2014 expected YYYY-MM-DD`
|
|
4509
4562
|
);
|
|
4510
4563
|
}
|
|
4511
|
-
return
|
|
4564
|
+
return path8.join(this.wearablesDir, FUSION_DIR_NAME, `${date}.md`);
|
|
4512
4565
|
}
|
|
4513
4566
|
async writeFusedDay(date, serialized) {
|
|
4514
4567
|
const filePath = this.fusedDayPath(date);
|
|
@@ -4545,7 +4598,7 @@ var FusionArtifactStore = class {
|
|
|
4545
4598
|
}
|
|
4546
4599
|
/** List dates with stored fused artifacts, newest first. */
|
|
4547
4600
|
async listFusedDays() {
|
|
4548
|
-
const fusionDir =
|
|
4601
|
+
const fusionDir = path8.join(this.wearablesDir, FUSION_DIR_NAME);
|
|
4549
4602
|
await this.assertPathContained(fusionDir);
|
|
4550
4603
|
let entries;
|
|
4551
4604
|
try {
|
|
@@ -4589,10 +4642,10 @@ var FusionArtifactStore = class {
|
|
|
4589
4642
|
try {
|
|
4590
4643
|
rootReal = await this.io.realpath(this.memoryDir);
|
|
4591
4644
|
} catch {
|
|
4592
|
-
rootReal =
|
|
4645
|
+
rootReal = path8.resolve(this.memoryDir);
|
|
4593
4646
|
}
|
|
4594
4647
|
await this.assertNoEscape(rootReal, this.wearablesDir);
|
|
4595
|
-
await this.assertNoEscape(rootReal,
|
|
4648
|
+
await this.assertNoEscape(rootReal, path8.dirname(targetPath));
|
|
4596
4649
|
await this.assertNoEscape(rootReal, targetPath);
|
|
4597
4650
|
await this.assertFusionDirNotSymlinked();
|
|
4598
4651
|
}
|
|
@@ -4606,15 +4659,15 @@ var FusionArtifactStore = class {
|
|
|
4606
4659
|
* (a fresh write creates a real directory lexically under the root).
|
|
4607
4660
|
*/
|
|
4608
4661
|
async assertFusionDirNotSymlinked() {
|
|
4609
|
-
const fusionDir =
|
|
4610
|
-
let
|
|
4662
|
+
const fusionDir = path8.join(this.wearablesDir, FUSION_DIR_NAME);
|
|
4663
|
+
let stat4;
|
|
4611
4664
|
try {
|
|
4612
|
-
|
|
4665
|
+
stat4 = await this.io.lstat(fusionDir);
|
|
4613
4666
|
} catch (err) {
|
|
4614
4667
|
if (err.code === "ENOENT") return;
|
|
4615
4668
|
throw err;
|
|
4616
4669
|
}
|
|
4617
|
-
if (
|
|
4670
|
+
if (stat4.isSymbolicLink) {
|
|
4618
4671
|
throw new Error(
|
|
4619
4672
|
"wearable fusion dir '_fusion' is a symbolic link \u2014 refusing to follow it even when it resolves inside the memory dir (AGENTS.md pattern #3)"
|
|
4620
4673
|
);
|
|
@@ -4742,7 +4795,7 @@ function reconstructFusionInputs(date, dayTranscripts) {
|
|
|
4742
4795
|
|
|
4743
4796
|
// src/meetings/store.ts
|
|
4744
4797
|
import { createHash as createHash4 } from "crypto";
|
|
4745
|
-
import * as
|
|
4798
|
+
import * as path9 from "path";
|
|
4746
4799
|
var MEETINGS_DIR_NAME = "meetings";
|
|
4747
4800
|
var MEETING_KIND = "meeting";
|
|
4748
4801
|
var MEETING_FORMAT_VERSION = 1;
|
|
@@ -4911,7 +4964,7 @@ var MeetingRecordStore = class {
|
|
|
4911
4964
|
constructor(memoryDir, io) {
|
|
4912
4965
|
this.memoryDir = memoryDir;
|
|
4913
4966
|
this.io = io;
|
|
4914
|
-
this.meetingsDir =
|
|
4967
|
+
this.meetingsDir = path9.join(memoryDir, MEETINGS_DIR_NAME);
|
|
4915
4968
|
}
|
|
4916
4969
|
memoryDir;
|
|
4917
4970
|
io;
|
|
@@ -4927,7 +4980,7 @@ var MeetingRecordStore = class {
|
|
|
4927
4980
|
if (idDate !== date) {
|
|
4928
4981
|
throw new Error(`meeting id '${id}' does not belong to date '${date}'`);
|
|
4929
4982
|
}
|
|
4930
|
-
return
|
|
4983
|
+
return path9.join(this.meetingsDir, date, `${id}.md`);
|
|
4931
4984
|
}
|
|
4932
4985
|
/** Idempotently persist a record: skip the write when contentHash is unchanged. */
|
|
4933
4986
|
async saveMeetingRecord(record) {
|
|
@@ -4958,7 +5011,7 @@ var MeetingRecordStore = class {
|
|
|
4958
5011
|
if (!isValidTranscriptDate(date)) {
|
|
4959
5012
|
throw new Error(`invalid meeting date '${String(date)}' \u2014 expected YYYY-MM-DD`);
|
|
4960
5013
|
}
|
|
4961
|
-
const dayDir =
|
|
5014
|
+
const dayDir = path9.join(this.meetingsDir, date);
|
|
4962
5015
|
await this.assertPathContained(dayDir);
|
|
4963
5016
|
let entries;
|
|
4964
5017
|
try {
|
|
@@ -5026,10 +5079,10 @@ var MeetingRecordStore = class {
|
|
|
5026
5079
|
try {
|
|
5027
5080
|
rootReal = await this.io.realpath(this.memoryDir);
|
|
5028
5081
|
} catch {
|
|
5029
|
-
rootReal =
|
|
5082
|
+
rootReal = path9.resolve(this.memoryDir);
|
|
5030
5083
|
}
|
|
5031
5084
|
await this.assertNoEscape(rootReal, this.meetingsDir);
|
|
5032
|
-
await this.assertNoEscape(rootReal,
|
|
5085
|
+
await this.assertNoEscape(rootReal, path9.dirname(targetPath));
|
|
5033
5086
|
await this.assertNoEscape(rootReal, targetPath);
|
|
5034
5087
|
await this.assertNotSymlink(this.meetingsDir, "directory");
|
|
5035
5088
|
const dayDir = this.dayDirWithin(targetPath);
|
|
@@ -5039,22 +5092,22 @@ var MeetingRecordStore = class {
|
|
|
5039
5092
|
/** The `<meetings>/<date>` directory on the path to `targetPath`, or null when
|
|
5040
5093
|
* `targetPath` is the meetings root itself. */
|
|
5041
5094
|
dayDirWithin(targetPath) {
|
|
5042
|
-
const rel =
|
|
5043
|
-
if (rel === "" || rel.startsWith("..") ||
|
|
5044
|
-
const first = rel.split(
|
|
5095
|
+
const rel = path9.relative(this.meetingsDir, targetPath);
|
|
5096
|
+
if (rel === "" || rel.startsWith("..") || path9.isAbsolute(rel)) return null;
|
|
5097
|
+
const first = rel.split(path9.sep)[0];
|
|
5045
5098
|
if (first === void 0 || first.length === 0) return null;
|
|
5046
|
-
return
|
|
5099
|
+
return path9.join(this.meetingsDir, first);
|
|
5047
5100
|
}
|
|
5048
5101
|
async assertNotSymlink(target, kind) {
|
|
5049
|
-
let
|
|
5102
|
+
let stat4;
|
|
5050
5103
|
try {
|
|
5051
|
-
|
|
5104
|
+
stat4 = await this.io.lstat(target);
|
|
5052
5105
|
} catch (err) {
|
|
5053
5106
|
if (err.code === "ENOENT") return;
|
|
5054
5107
|
throw err;
|
|
5055
5108
|
}
|
|
5056
|
-
if (
|
|
5057
|
-
const label =
|
|
5109
|
+
if (stat4.isSymbolicLink) {
|
|
5110
|
+
const label = path9.relative(this.memoryDir, target) || MEETINGS_DIR_NAME;
|
|
5058
5111
|
throw new Error(
|
|
5059
5112
|
`meetings ${kind} '${label}' is a symbolic link \u2014 refusing to follow it even when it resolves inside the memory dir (AGENTS.md pattern #3)`
|
|
5060
5113
|
);
|
|
@@ -5078,7 +5131,7 @@ var SORT_STR = (a, b) => a < b ? -1 : a > b ? 1 : 0;
|
|
|
5078
5131
|
|
|
5079
5132
|
// src/storage/supersession-audit.ts
|
|
5080
5133
|
import { readdir as readdir5 } from "fs/promises";
|
|
5081
|
-
import
|
|
5134
|
+
import path10 from "path";
|
|
5082
5135
|
async function hasSupersessionAudit(lookup, oldMemoryId, newMemoryId, auditBody, structuredAttributes) {
|
|
5083
5136
|
let entries;
|
|
5084
5137
|
try {
|
|
@@ -5089,7 +5142,7 @@ async function hasSupersessionAudit(lookup, oldMemoryId, newMemoryId, auditBody,
|
|
|
5089
5142
|
}
|
|
5090
5143
|
for (const entry of entries) {
|
|
5091
5144
|
if (!entry.isFile() || !entry.name.endsWith(".md")) continue;
|
|
5092
|
-
const memory = await lookup.readMemoryByPath(
|
|
5145
|
+
const memory = await lookup.readMemoryByPath(path10.join(lookup.correctionsDir, entry.name));
|
|
5093
5146
|
if (memory?.frontmatter.category === "correction" && (memory.frontmatter.sourceMemoryId === oldMemoryId || memory.frontmatter.sourceMemoryId === void 0 && memory.frontmatter.lineage?.includes(oldMemoryId)) && memory.frontmatter.lineage?.includes(newMemoryId) && stripAttributesSuffix(memory.content) === auditBody && (structuredAttributes === void 0 || Object.entries(structuredAttributes).every(
|
|
5094
5147
|
([key, value]) => memory.frontmatter.structuredAttributes?.[key] === value
|
|
5095
5148
|
))) {
|
|
@@ -6098,17 +6151,17 @@ function inferEntityTypeFromContent(content) {
|
|
|
6098
6151
|
}
|
|
6099
6152
|
var KNOWN_ENTITY_FILENAME_PREFIXES = /* @__PURE__ */ new Set(["company", "other", "person", "place", "project", "tool", "topic"]);
|
|
6100
6153
|
function inferEntityTypeFromFilename(pathRel) {
|
|
6101
|
-
const basename =
|
|
6154
|
+
const basename = path11.basename(pathRel, ".md").toLowerCase();
|
|
6102
6155
|
const separator = basename.indexOf("-");
|
|
6103
6156
|
if (separator <= 0) return void 0;
|
|
6104
6157
|
const candidate = basename.slice(0, separator);
|
|
6105
6158
|
return KNOWN_ENTITY_FILENAME_PREFIXES.has(candidate) ? candidate : void 0;
|
|
6106
6159
|
}
|
|
6107
6160
|
function normalizeFrontmatterForPath(frontmatter, pathRel, content = "") {
|
|
6108
|
-
const normalizedPath = pathRel.split(
|
|
6161
|
+
const normalizedPath = pathRel.split(path11.sep).join("/");
|
|
6109
6162
|
let normalizedFrontmatter = frontmatter;
|
|
6110
6163
|
if (normalizedPath === "entities" || normalizedPath.startsWith("entities/") || normalizedPath.includes("/entities/")) {
|
|
6111
|
-
const basename =
|
|
6164
|
+
const basename = path11.basename(pathRel, ".md");
|
|
6112
6165
|
const inferredType = inferEntityTypeFromContent(content) || inferEntityTypeFromFilename(pathRel) || "entity";
|
|
6113
6166
|
const existingTags = Array.isArray(frontmatter.tags) ? frontmatter.tags : [];
|
|
6114
6167
|
normalizedFrontmatter = {
|
|
@@ -6575,9 +6628,9 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
6575
6628
|
this.entitySchemas = entitySchemas;
|
|
6576
6629
|
this.deletionRevisionStore = new DeletionRevisionStore({
|
|
6577
6630
|
baseDir,
|
|
6578
|
-
deletionRevisionMetadataPath:
|
|
6579
|
-
invalidationCommitMetadataPath:
|
|
6580
|
-
deletionRevisionLockPath:
|
|
6631
|
+
deletionRevisionMetadataPath: path11.join(baseDir, ".offline-sync", "deletion-revisions.v1.json"),
|
|
6632
|
+
invalidationCommitMetadataPath: path11.join(baseDir, ".offline-sync", "invalidation-commits.v1.json"),
|
|
6633
|
+
deletionRevisionLockPath: path11.join(baseDir, ".offline-sync", "deletion-revisions.v1.json.lock"),
|
|
6581
6634
|
assertManagedStoragePath: (filePath, method) => this.assertManagedStoragePath(filePath, method)
|
|
6582
6635
|
});
|
|
6583
6636
|
this.hotMemoriesCacheEnabled = hotMemoriesCacheEnabledOverride ?? _StorageManager.hotMemoriesCacheDefaultByDir.get(baseDir) ?? _StorageManager.hotMemoriesCacheDefault;
|
|
@@ -6765,8 +6818,8 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
6765
6818
|
}
|
|
6766
6819
|
/** Whether `filePath` resolves to `stateDir` itself or a path contained in it. */
|
|
6767
6820
|
isStateFilePath(filePath) {
|
|
6768
|
-
const rel =
|
|
6769
|
-
return rel === "" || !rel.startsWith("..") && !
|
|
6821
|
+
const rel = path11.relative(this.stateDir, path11.resolve(filePath));
|
|
6822
|
+
return rel === "" || !rel.startsWith("..") && !path11.isAbsolute(rel);
|
|
6770
6823
|
}
|
|
6771
6824
|
// ── Tombstone store (issue #1579) ───────────────────────────────────────
|
|
6772
6825
|
// Instance-scoped (rule 11) + namespace-scoped (rule 42) tombstone index.
|
|
@@ -6881,8 +6934,8 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
6881
6934
|
* /srv/cold/remnic), skipping the patch and stranding a stale hot entry.
|
|
6882
6935
|
*/
|
|
6883
6936
|
isColdOrArchiveTierPath(p) {
|
|
6884
|
-
const rel =
|
|
6885
|
-
return rel === "cold" || rel === "archive" || rel.startsWith(`cold${
|
|
6937
|
+
const rel = path11.relative(this.baseDir, p);
|
|
6938
|
+
return rel === "cold" || rel === "archive" || rel.startsWith(`cold${path11.sep}`) || rel.startsWith(`archive${path11.sep}`);
|
|
6886
6939
|
}
|
|
6887
6940
|
/**
|
|
6888
6941
|
* Mark the secure-store as required for this storage instance.
|
|
@@ -6969,7 +7022,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
6969
7022
|
void 0,
|
|
6970
7023
|
this.baseDir
|
|
6971
7024
|
);
|
|
6972
|
-
const rel =
|
|
7025
|
+
const rel = path11.relative(this.baseDir, filePath).split(path11.sep).join("/");
|
|
6973
7026
|
return `${rel}:${version.versionId}`;
|
|
6974
7027
|
} catch (err) {
|
|
6975
7028
|
log.warn(
|
|
@@ -7049,12 +7102,12 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7049
7102
|
}
|
|
7050
7103
|
identityFilePath(workspaceDir, namespace) {
|
|
7051
7104
|
const rawNamespace = typeof namespace === "string" ? namespace.trim() : "";
|
|
7052
|
-
if (!rawNamespace) return
|
|
7105
|
+
if (!rawNamespace) return path11.join(workspaceDir, "IDENTITY.md");
|
|
7053
7106
|
const safeNamespace = rawNamespace.replace(/[^a-zA-Z0-9._-]/g, "-");
|
|
7054
|
-
return
|
|
7107
|
+
return path11.join(workspaceDir, `IDENTITY.${safeNamespace}.md`);
|
|
7055
7108
|
}
|
|
7056
7109
|
versionFilePath(kind) {
|
|
7057
|
-
return
|
|
7110
|
+
return path11.join(this.stateDir, `.${kind}-version.log`);
|
|
7058
7111
|
}
|
|
7059
7112
|
bumpSharedVersion(kind, fallbackMap) {
|
|
7060
7113
|
const filePath = this.versionFilePath(kind);
|
|
@@ -7158,7 +7211,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7158
7211
|
// memories.
|
|
7159
7212
|
// -------------------------------------------------------------------------
|
|
7160
7213
|
get wearablesDir() {
|
|
7161
|
-
return
|
|
7214
|
+
return path11.join(this.baseDir, WEARABLES_DIR_NAME);
|
|
7162
7215
|
}
|
|
7163
7216
|
/**
|
|
7164
7217
|
* Resolve the on-disk path for a source/day transcript. Throws on
|
|
@@ -7174,7 +7227,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7174
7227
|
if (!isValidTranscriptDate(date)) {
|
|
7175
7228
|
throw new Error(`invalid wearable transcript date '${String(date)}' \u2014 expected YYYY-MM-DD`);
|
|
7176
7229
|
}
|
|
7177
|
-
return
|
|
7230
|
+
return path11.join(this.wearablesDir, sourceId, `${date}.md`);
|
|
7178
7231
|
}
|
|
7179
7232
|
async writeWearableDayTranscript(sourceId, date, serialized) {
|
|
7180
7233
|
const targetPath = this.wearableTranscriptPath(sourceId, date);
|
|
@@ -7290,25 +7343,25 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7290
7343
|
});
|
|
7291
7344
|
}
|
|
7292
7345
|
get factsDir() {
|
|
7293
|
-
return
|
|
7346
|
+
return path11.join(this.baseDir, "facts");
|
|
7294
7347
|
}
|
|
7295
7348
|
get correctionsDir() {
|
|
7296
|
-
return
|
|
7349
|
+
return path11.join(this.baseDir, "corrections");
|
|
7297
7350
|
}
|
|
7298
7351
|
get proceduresDir() {
|
|
7299
|
-
return
|
|
7352
|
+
return path11.join(this.baseDir, "procedures");
|
|
7300
7353
|
}
|
|
7301
7354
|
get reasoningTracesDir() {
|
|
7302
|
-
return
|
|
7355
|
+
return path11.join(this.baseDir, "reasoning-traces");
|
|
7303
7356
|
}
|
|
7304
7357
|
get entitiesDir() {
|
|
7305
|
-
return
|
|
7358
|
+
return path11.join(this.baseDir, "entities");
|
|
7306
7359
|
}
|
|
7307
7360
|
resolveEntityFilePath(name) {
|
|
7308
7361
|
if (typeof name !== "string") return null;
|
|
7309
|
-
const filePath =
|
|
7310
|
-
const relative2 =
|
|
7311
|
-
if (relative2 === "" || relative2.startsWith("..") ||
|
|
7362
|
+
const filePath = path11.resolve(this.entitiesDir, `${name}.md`);
|
|
7363
|
+
const relative2 = path11.relative(this.entitiesDir, filePath);
|
|
7364
|
+
if (relative2 === "" || relative2.startsWith("..") || path11.isAbsolute(relative2)) {
|
|
7312
7365
|
return null;
|
|
7313
7366
|
}
|
|
7314
7367
|
return filePath;
|
|
@@ -7319,7 +7372,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7319
7372
|
async readDependencyPropagationQueueFile(filePath) {
|
|
7320
7373
|
const target = await resolveSafeStoragePath(
|
|
7321
7374
|
this.baseDir,
|
|
7322
|
-
|
|
7375
|
+
path11.relative(
|
|
7323
7376
|
this.baseDir,
|
|
7324
7377
|
this.assertManagedStoragePath(filePath, "storage.readDependencyPropagationQueueFile")
|
|
7325
7378
|
)
|
|
@@ -7329,7 +7382,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7329
7382
|
async writeDependencyPropagationQueueFile(filePath, content) {
|
|
7330
7383
|
const target = await resolveSafeStoragePath(
|
|
7331
7384
|
this.baseDir,
|
|
7332
|
-
|
|
7385
|
+
path11.relative(
|
|
7333
7386
|
this.baseDir,
|
|
7334
7387
|
this.assertManagedStoragePath(filePath, "storage.writeDependencyPropagationQueueFile")
|
|
7335
7388
|
)
|
|
@@ -7343,10 +7396,10 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7343
7396
|
});
|
|
7344
7397
|
}
|
|
7345
7398
|
assertManagedStoragePath(filePath, method) {
|
|
7346
|
-
const resolved =
|
|
7347
|
-
const base =
|
|
7348
|
-
const rel =
|
|
7349
|
-
if (rel === "" || rel === ".." || rel.startsWith(`..${
|
|
7399
|
+
const resolved = path11.resolve(filePath);
|
|
7400
|
+
const base = path11.resolve(this.baseDir);
|
|
7401
|
+
const rel = path11.relative(base, resolved);
|
|
7402
|
+
if (rel === "" || rel === ".." || rel.startsWith(`..${path11.sep}`) || path11.isAbsolute(rel)) {
|
|
7350
7403
|
throw new Error(`${method}: file path escapes memory dir`);
|
|
7351
7404
|
}
|
|
7352
7405
|
return resolved;
|
|
@@ -7378,8 +7431,8 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7378
7431
|
}
|
|
7379
7432
|
async digestOfflineSyncFile(filePath) {
|
|
7380
7433
|
const target = this.assertManagedStoragePath(filePath, "storage.digestOfflineSyncFile");
|
|
7381
|
-
const st = await
|
|
7382
|
-
const relPath =
|
|
7434
|
+
const st = await stat3(target);
|
|
7435
|
+
const relPath = path11.relative(this.baseDir, target).split(path11.sep).join("/");
|
|
7383
7436
|
const cache = await this.loadOfflineSyncDigestCache();
|
|
7384
7437
|
const cached = cache.get(relPath);
|
|
7385
7438
|
if (cached && cached.statBytes === st.size && cached.mtimeMs === st.mtimeMs && cached.ctimeMs === st.ctimeMs && !cached.encrypted) {
|
|
@@ -7440,7 +7493,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7440
7493
|
const bytes = typeof record.bytes === "number" ? record.bytes : NaN;
|
|
7441
7494
|
const sha256 = typeof record.sha256 === "string" ? record.sha256 : "";
|
|
7442
7495
|
const encrypted = record.encrypted === true;
|
|
7443
|
-
if (cachePath.length === 0 || cachePath === ".." || cachePath.startsWith("../") ||
|
|
7496
|
+
if (cachePath.length === 0 || cachePath === ".." || cachePath.startsWith("../") || path11.isAbsolute(cachePath) || !Number.isFinite(statBytes) || !Number.isFinite(mtimeMs) || !Number.isFinite(ctimeMs) || !Number.isFinite(bytes) || !/^[a-f0-9]{64}$/i.test(sha256)) {
|
|
7444
7497
|
continue;
|
|
7445
7498
|
}
|
|
7446
7499
|
cache.set(cachePath, { statBytes, mtimeMs, ctimeMs, encrypted, sha256, bytes });
|
|
@@ -7482,7 +7535,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7482
7535
|
const cache = this.offlineSyncDigestCache;
|
|
7483
7536
|
if (!cache) return;
|
|
7484
7537
|
const entries = [...cache.entries()].sort(([a], [b]) => a.localeCompare(b)).map(([entryPath, entry]) => ({ path: entryPath, ...entry }));
|
|
7485
|
-
await mkdir(
|
|
7538
|
+
await mkdir(path11.dirname(this.offlineSyncDigestCachePath), { recursive: true });
|
|
7486
7539
|
await writeFile2(this.offlineSyncDigestCachePath, `${JSON.stringify({ version: 1, entries })}
|
|
7487
7540
|
`, "utf-8");
|
|
7488
7541
|
}).catch((err) => {
|
|
@@ -7540,7 +7593,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7540
7593
|
async isEncryptedFileHeader(filePath) {
|
|
7541
7594
|
let st;
|
|
7542
7595
|
try {
|
|
7543
|
-
st = await
|
|
7596
|
+
st = await stat3(filePath);
|
|
7544
7597
|
} catch (err) {
|
|
7545
7598
|
if (isErrnoCode(err, "ENOENT")) return false;
|
|
7546
7599
|
throw err;
|
|
@@ -7571,7 +7624,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7571
7624
|
}
|
|
7572
7625
|
async appendStorageSecureFileUnlocked(filePath, content) {
|
|
7573
7626
|
const writeKey = this.resolveWriteKey();
|
|
7574
|
-
await mkdir(
|
|
7627
|
+
await mkdir(path11.dirname(filePath), { recursive: true });
|
|
7575
7628
|
if (writeKey === null) {
|
|
7576
7629
|
try {
|
|
7577
7630
|
if (await this.isEncryptedFileHeader(filePath)) {
|
|
@@ -7597,13 +7650,13 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7597
7650
|
this.notifyCatalogWriteForPath(filePath);
|
|
7598
7651
|
}
|
|
7599
7652
|
get stateDir() {
|
|
7600
|
-
return
|
|
7653
|
+
return path11.join(this.baseDir, "state");
|
|
7601
7654
|
}
|
|
7602
7655
|
get offlineSyncDigestCachePath() {
|
|
7603
|
-
return
|
|
7656
|
+
return path11.join(this.baseDir, ".offline-sync", "digest-cache.v1.json");
|
|
7604
7657
|
}
|
|
7605
7658
|
get entitySynthesisQueuePath() {
|
|
7606
|
-
return
|
|
7659
|
+
return path11.join(this.stateDir, "entity-synthesis-queue.json");
|
|
7607
7660
|
}
|
|
7608
7661
|
// ── Tombstone store access (issue #1579) ─────────────────────────────────
|
|
7609
7662
|
/**
|
|
@@ -7613,7 +7666,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7613
7666
|
* helpers are injected into the store).
|
|
7614
7667
|
*/
|
|
7615
7668
|
get tombstonesPath() {
|
|
7616
|
-
return
|
|
7669
|
+
return path11.join(this.stateDir, "tombstones.jsonl");
|
|
7617
7670
|
}
|
|
7618
7671
|
/**
|
|
7619
7672
|
* Configure the tombstone invariant for this storage instance. Installed
|
|
@@ -7643,7 +7696,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7643
7696
|
const requested = new Set(sourceMemoryIds);
|
|
7644
7697
|
const sourcePaths = await (sourcePathsPromise ??= this.memoryReadStore.collectTombstoneMigrationPaths());
|
|
7645
7698
|
const directPaths = sourcePaths.filter(
|
|
7646
|
-
(filePath) => requested.has(
|
|
7699
|
+
(filePath) => requested.has(path11.basename(filePath, ".md"))
|
|
7647
7700
|
);
|
|
7648
7701
|
const contents = /* @__PURE__ */ new Map();
|
|
7649
7702
|
for (const memory of await this.readParsedMemoriesFromPaths(directPaths, 50)) {
|
|
@@ -7937,55 +7990,55 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
7937
7990
|
return legacyMatches.length > 0 ? [...new Set(legacyMatches.map((content) => ContentHashIndex.computeHash(content)))] : [persistedHash];
|
|
7938
7991
|
}
|
|
7939
7992
|
get questionsDir() {
|
|
7940
|
-
return
|
|
7993
|
+
return path11.join(this.baseDir, "questions");
|
|
7941
7994
|
}
|
|
7942
7995
|
get artifactsDir() {
|
|
7943
|
-
return
|
|
7996
|
+
return path11.join(this.baseDir, "artifacts");
|
|
7944
7997
|
}
|
|
7945
7998
|
get identityDir() {
|
|
7946
|
-
return
|
|
7999
|
+
return path11.join(this.baseDir, "identity");
|
|
7947
8000
|
}
|
|
7948
8001
|
get identityAnchorPath() {
|
|
7949
|
-
return
|
|
8002
|
+
return path11.join(this.identityDir, "identity-anchor.md");
|
|
7950
8003
|
}
|
|
7951
8004
|
get identityIncidentsDir() {
|
|
7952
|
-
return
|
|
8005
|
+
return path11.join(this.identityDir, "incidents");
|
|
7953
8006
|
}
|
|
7954
8007
|
get identityAuditsWeeklyDir() {
|
|
7955
|
-
return
|
|
8008
|
+
return path11.join(this.identityDir, "audits", "weekly");
|
|
7956
8009
|
}
|
|
7957
8010
|
get identityAuditsMonthlyDir() {
|
|
7958
|
-
return
|
|
8011
|
+
return path11.join(this.identityDir, "audits", "monthly");
|
|
7959
8012
|
}
|
|
7960
8013
|
get identityImprovementLoopsPath() {
|
|
7961
|
-
return
|
|
8014
|
+
return path11.join(this.identityDir, "improvement-loops.md");
|
|
7962
8015
|
}
|
|
7963
8016
|
get identityReflectionsPath() {
|
|
7964
|
-
return
|
|
8017
|
+
return path11.join(this.identityDir, "reflections.md");
|
|
7965
8018
|
}
|
|
7966
8019
|
get profilePath() {
|
|
7967
|
-
return
|
|
8020
|
+
return path11.join(this.baseDir, "profile.md");
|
|
7968
8021
|
}
|
|
7969
8022
|
get memoryActionsPath() {
|
|
7970
|
-
return
|
|
8023
|
+
return path11.join(this.stateDir, "memory-actions.jsonl");
|
|
7971
8024
|
}
|
|
7972
8025
|
get memoryLifecycleLedgerPath() {
|
|
7973
|
-
return
|
|
8026
|
+
return path11.join(this.stateDir, "memory-lifecycle-ledger.jsonl");
|
|
7974
8027
|
}
|
|
7975
8028
|
get compressionGuidelinesPath() {
|
|
7976
|
-
return
|
|
8029
|
+
return path11.join(this.stateDir, "compression-guidelines.md");
|
|
7977
8030
|
}
|
|
7978
8031
|
get compressionGuidelineDraftPath() {
|
|
7979
|
-
return
|
|
8032
|
+
return path11.join(this.stateDir, "compression-guidelines.draft.md");
|
|
7980
8033
|
}
|
|
7981
8034
|
get compressionGuidelineStatePath() {
|
|
7982
|
-
return
|
|
8035
|
+
return path11.join(this.stateDir, "compression-guideline-state.json");
|
|
7983
8036
|
}
|
|
7984
8037
|
get compressionGuidelineDraftStatePath() {
|
|
7985
|
-
return
|
|
8038
|
+
return path11.join(this.stateDir, "compression-guideline-draft-state.json");
|
|
7986
8039
|
}
|
|
7987
8040
|
get behaviorSignalsPath() {
|
|
7988
|
-
return
|
|
8041
|
+
return path11.join(this.stateDir, "behavior-signals.jsonl");
|
|
7989
8042
|
}
|
|
7990
8043
|
/**
|
|
7991
8044
|
* In-memory dedup key set for behavior-signals appends (issue #1909),
|
|
@@ -8017,7 +8070,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
8017
8070
|
* governance sweeps can treat it uniformly.
|
|
8018
8071
|
*/
|
|
8019
8072
|
get bufferSurpriseLedgerPath() {
|
|
8020
|
-
return
|
|
8073
|
+
return path11.join(this.stateDir, "buffer-surprise-ledger.jsonl");
|
|
8021
8074
|
}
|
|
8022
8075
|
/**
|
|
8023
8076
|
* Entity alias table loaded from THIS store's config/aliases.json.
|
|
@@ -8078,7 +8131,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
8078
8131
|
this.loadAliasesSync();
|
|
8079
8132
|
}
|
|
8080
8133
|
loadAliasesSync() {
|
|
8081
|
-
const aliasPath =
|
|
8134
|
+
const aliasPath = path11.join(this.baseDir, "config", "aliases.json");
|
|
8082
8135
|
this.userAliases = {};
|
|
8083
8136
|
const raw = readEntityAliasConfigSync(this.baseDir);
|
|
8084
8137
|
if (raw === void 0) return;
|
|
@@ -8116,9 +8169,9 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
8116
8169
|
await mkdir(this.baseDir, { recursive: true });
|
|
8117
8170
|
await validateRoots(this.baseDir, this.entitiesDir, this.stateDir, this.archiveDir);
|
|
8118
8171
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
8119
|
-
await mkdir(
|
|
8120
|
-
await mkdir(
|
|
8121
|
-
await mkdir(
|
|
8172
|
+
await mkdir(path11.join(this.factsDir, today), { recursive: true });
|
|
8173
|
+
await mkdir(path11.join(this.proceduresDir, today), { recursive: true });
|
|
8174
|
+
await mkdir(path11.join(this.reasoningTracesDir, today), { recursive: true });
|
|
8122
8175
|
await mkdir(this.correctionsDir, { recursive: true });
|
|
8123
8176
|
await mkdir(this.entitiesDir, { recursive: true });
|
|
8124
8177
|
await mkdir(this.stateDir, { recursive: true });
|
|
@@ -8128,7 +8181,7 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
8128
8181
|
await mkdir(this.identityIncidentsDir, { recursive: true });
|
|
8129
8182
|
await mkdir(this.identityAuditsWeeklyDir, { recursive: true });
|
|
8130
8183
|
await mkdir(this.identityAuditsMonthlyDir, { recursive: true });
|
|
8131
|
-
await mkdir(
|
|
8184
|
+
await mkdir(path11.join(this.baseDir, "config"), { recursive: true });
|
|
8132
8185
|
await this.entityCanonicalIdMigration.ensure();
|
|
8133
8186
|
if (this.hotMemoriesCacheEnabled && this.getMemoryCorpusVersion() === 0) {
|
|
8134
8187
|
this.bumpMemoryCorpusVersion();
|
|
@@ -8150,11 +8203,11 @@ var StorageManager3 = class _StorageManager extends TombstoneBlockedCaptureIndex
|
|
|
8150
8203
|
async resolveCategoryWritePath(category, id, today) {
|
|
8151
8204
|
if (category === "correction") {
|
|
8152
8205
|
await mkdir(this.correctionsDir, { recursive: true });
|
|
8153
|
-
return
|
|
8206
|
+
return path11.join(this.correctionsDir, `${id}.md`);
|
|
8154
8207
|
}
|
|
8155
|
-
const datedDir =
|
|
8208
|
+
const datedDir = path11.join(getCategoryDir(this.baseDir, category), today);
|
|
8156
8209
|
await mkdir(datedDir, { recursive: true });
|
|
8157
|
-
return
|
|
8210
|
+
return path11.join(datedDir, `${id}.md`);
|
|
8158
8211
|
}
|
|
8159
8212
|
async findExistingTombstoneBlockedMemory(content, category, sourceConnector) {
|
|
8160
8213
|
const identity = buildExplicitCaptureDedupKey(content, category, sourceConnector);
|
|
@@ -8519,7 +8572,7 @@ ${sanitized.text}
|
|
|
8519
8572
|
await this.ensureDirectories();
|
|
8520
8573
|
const now = /* @__PURE__ */ new Date();
|
|
8521
8574
|
const day = now.toISOString().slice(0, 10);
|
|
8522
|
-
const dir =
|
|
8575
|
+
const dir = path11.join(this.artifactsDir, day);
|
|
8523
8576
|
await mkdir(dir, { recursive: true });
|
|
8524
8577
|
const id = `artifact-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
|
|
8525
8578
|
const fm = {
|
|
@@ -8545,7 +8598,7 @@ ${sanitized.text}
|
|
|
8545
8598
|
log.warn(`artifact content rejected for ${id}; violations=${sanitized.violations.join(", ")}`);
|
|
8546
8599
|
return "";
|
|
8547
8600
|
}
|
|
8548
|
-
const filePath =
|
|
8601
|
+
const filePath = path11.join(dir, `${id}.md`);
|
|
8549
8602
|
await this.writeStorageSecureFile(filePath, `${serializeFrontmatter(fm)}
|
|
8550
8603
|
|
|
8551
8604
|
${sanitized.text}
|
|
@@ -8833,7 +8886,7 @@ ${sanitized.text}
|
|
|
8833
8886
|
* per-process in-memory cache safe across process boundaries.
|
|
8834
8887
|
*/
|
|
8835
8888
|
invalidateColdMemoriesCache() {
|
|
8836
|
-
const coldRoot =
|
|
8889
|
+
const coldRoot = path11.join(this.baseDir, "cold");
|
|
8837
8890
|
_StorageManager.coldMemoriesCache.delete(coldRoot);
|
|
8838
8891
|
this.bumpColdWriteVersion();
|
|
8839
8892
|
invalidateAllForDir(this.baseDir);
|
|
@@ -8922,11 +8975,11 @@ ${sanitized.text}
|
|
|
8922
8975
|
async readWindowUpdatedMs(filePath) {
|
|
8923
8976
|
try {
|
|
8924
8977
|
const raw = await readMaybeEncryptedFile(filePath, this._secureStoreKey, this.baseDir);
|
|
8925
|
-
const match = raw.match(/^---\n([\s\S]*?)\n
|
|
8978
|
+
const match = raw.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/);
|
|
8926
8979
|
if (!match) return null;
|
|
8927
8980
|
const frontmatterBlock = match[1];
|
|
8928
|
-
const rawUpdated = frontmatterBlock.match(/^updated
|
|
8929
|
-
const updatedMs = rawUpdated ? Date.parse(rawUpdated) : Number.NaN;
|
|
8981
|
+
const rawUpdated = frontmatterBlock.match(/^[ \t]*updated:[ \t]*"?([^"\r\n]*)"?/m)?.[1] || frontmatterBlock.match(/^[ \t]*created:[ \t]*"?([^"\r\n]*)"?/m)?.[1] || null;
|
|
8982
|
+
const updatedMs = rawUpdated ? Date.parse(rawUpdated.trim()) : Number.NaN;
|
|
8930
8983
|
return Number.isFinite(updatedMs) ? updatedMs : null;
|
|
8931
8984
|
} catch {
|
|
8932
8985
|
return null;
|
|
@@ -8940,7 +8993,7 @@ ${sanitized.text}
|
|
|
8940
8993
|
return updatedMs >= updatedAfterMs ? filePath : null;
|
|
8941
8994
|
}
|
|
8942
8995
|
try {
|
|
8943
|
-
const fileStat = await
|
|
8996
|
+
const fileStat = await stat3(filePath);
|
|
8944
8997
|
return fileStat.mtimeMs >= updatedAfterMs ? filePath : null;
|
|
8945
8998
|
} catch {
|
|
8946
8999
|
return filePath;
|
|
@@ -8953,7 +9006,7 @@ ${sanitized.text}
|
|
|
8953
9006
|
const correctionPaths = [];
|
|
8954
9007
|
const factPaths = [];
|
|
8955
9008
|
for (const filePath of filePaths) {
|
|
8956
|
-
if (filePath === this.correctionsDir || filePath.startsWith(`${this.correctionsDir}${
|
|
9009
|
+
if (filePath === this.correctionsDir || filePath.startsWith(`${this.correctionsDir}${path11.sep}`)) {
|
|
8957
9010
|
correctionPaths.push(filePath);
|
|
8958
9011
|
} else {
|
|
8959
9012
|
factPaths.push(filePath);
|
|
@@ -8996,7 +9049,7 @@ ${sanitized.text}
|
|
|
8996
9049
|
return { memories, filePaths };
|
|
8997
9050
|
}
|
|
8998
9051
|
async readMemoriesWindow(options = {}) {
|
|
8999
|
-
return this.memoryReadStore.
|
|
9052
|
+
return readWindowedMemories(this.memoryReadStore, options, { enabled: this.hotMemoriesCacheEnabled, baseDir: this.baseDir, corpusVersion: this.getMemoryCorpusVersion(), cacheKeyId: this.hotCacheKeyId(), ttlMs: this.hotCacheTtlMs() }, (memories) => this.rememberMemorySnapshots(memories));
|
|
9000
9053
|
}
|
|
9001
9054
|
async _readAllMemoriesFromDisk(options) {
|
|
9002
9055
|
const filePaths = await this.collectActiveMemoryPaths(options);
|
|
@@ -9016,7 +9069,7 @@ ${sanitized.text}
|
|
|
9016
9069
|
try {
|
|
9017
9070
|
const entries = await readdir6(dir, { withFileTypes: true });
|
|
9018
9071
|
for (const entry of entries) {
|
|
9019
|
-
const fullPath =
|
|
9072
|
+
const fullPath = path11.join(dir, entry.name);
|
|
9020
9073
|
if (entry.isDirectory()) {
|
|
9021
9074
|
await readDir(fullPath);
|
|
9022
9075
|
} else if (entry.name.endsWith(".md")) {
|
|
@@ -9059,7 +9112,7 @@ ${sanitized.text}
|
|
|
9059
9112
|
return this.rememberMemorySnapshot(await this.memoryReadStore.readMemoryByPath(filePath));
|
|
9060
9113
|
}
|
|
9061
9114
|
resolveTierRootDir(tier) {
|
|
9062
|
-
return tier === "cold" ?
|
|
9115
|
+
return tier === "cold" ? path11.join(this.baseDir, "cold") : this.baseDir;
|
|
9063
9116
|
}
|
|
9064
9117
|
resolveMemoryDateDir(memory) {
|
|
9065
9118
|
const preferred = memory.frontmatter.created || memory.frontmatter.updated;
|
|
@@ -9074,13 +9127,13 @@ ${sanitized.text}
|
|
|
9074
9127
|
buildTierMemoryPath(memory, tier) {
|
|
9075
9128
|
const root = this.resolveTierRootDir(tier);
|
|
9076
9129
|
if (this.isArtifactMemory(memory)) {
|
|
9077
|
-
return
|
|
9130
|
+
return path11.join(root, "artifacts", this.resolveMemoryDateDir(memory), `${memory.frontmatter.id}.md`);
|
|
9078
9131
|
}
|
|
9079
9132
|
if (memory.frontmatter.category === "correction") {
|
|
9080
|
-
return
|
|
9133
|
+
return path11.join(root, "corrections", `${memory.frontmatter.id}.md`);
|
|
9081
9134
|
}
|
|
9082
9135
|
const dir = categoryDirName(memory.frontmatter.category);
|
|
9083
|
-
return
|
|
9136
|
+
return path11.join(root, dir, this.resolveMemoryDateDir(memory), `${memory.frontmatter.id}.md`);
|
|
9084
9137
|
}
|
|
9085
9138
|
async writeMemoryFileAtomic(targetPath, memory) {
|
|
9086
9139
|
const refIdsAtWrite = this.currentHistoricalIds();
|
|
@@ -9158,8 +9211,8 @@ ${memory.content}
|
|
|
9158
9211
|
memory.frontmatter.entityRef = current.frontmatter.entityRef;
|
|
9159
9212
|
}
|
|
9160
9213
|
durable = true;
|
|
9161
|
-
const sourcePath =
|
|
9162
|
-
const destPath =
|
|
9214
|
+
const sourcePath = path11.resolve(current.path);
|
|
9215
|
+
const destPath = path11.resolve(targetPath);
|
|
9163
9216
|
if (sourcePath !== destPath) {
|
|
9164
9217
|
await recordArchiveDelete2(this.baseDir, current.path, () => this.deleteManagedStorageFile(current.path));
|
|
9165
9218
|
this.invalidateAllMemoriesCache();
|
|
@@ -9183,8 +9236,8 @@ ${memory.content}
|
|
|
9183
9236
|
}
|
|
9184
9237
|
async migrateMemoryToTier(memory, targetTier) {
|
|
9185
9238
|
const targetPath = this.buildTierMemoryPath(memory, targetTier);
|
|
9186
|
-
const sourcePath =
|
|
9187
|
-
const destPath =
|
|
9239
|
+
const sourcePath = path11.resolve(memory.path);
|
|
9240
|
+
const destPath = path11.resolve(targetPath);
|
|
9188
9241
|
if (sourcePath === destPath) {
|
|
9189
9242
|
return { changed: false, targetPath };
|
|
9190
9243
|
}
|
|
@@ -9194,7 +9247,7 @@ ${memory.content}
|
|
|
9194
9247
|
return { changed, targetPath };
|
|
9195
9248
|
}
|
|
9196
9249
|
get archiveDir() {
|
|
9197
|
-
return
|
|
9250
|
+
return path11.join(this.baseDir, "archive");
|
|
9198
9251
|
}
|
|
9199
9252
|
/**
|
|
9200
9253
|
* Archive a memory by moving it from facts/ to archive/YYYY-MM-DD/.
|
|
@@ -9207,7 +9260,7 @@ ${memory.content}
|
|
|
9207
9260
|
try {
|
|
9208
9261
|
const now = lifecycle?.at ?? /* @__PURE__ */ new Date();
|
|
9209
9262
|
const today = now.toISOString().slice(0, 10);
|
|
9210
|
-
const destDir =
|
|
9263
|
+
const destDir = path11.join(this.archiveDir, today);
|
|
9211
9264
|
await mkdir(destDir, { recursive: true });
|
|
9212
9265
|
const refIdsAtWrite = this.currentHistoricalIds();
|
|
9213
9266
|
const updatedFm = canonicalizeEntityRefOption(
|
|
@@ -9223,7 +9276,7 @@ ${memory.content}
|
|
|
9223
9276
|
|
|
9224
9277
|
${current.content}
|
|
9225
9278
|
`;
|
|
9226
|
-
const destPath =
|
|
9279
|
+
const destPath = path11.join(destDir, path11.basename(current.path));
|
|
9227
9280
|
const priorDest = await this.readStorageSecureFile(destPath).catch(() => null);
|
|
9228
9281
|
await recordArchiveWrite(this.baseDir, destPath, () => this.writeStorageSecureFile(destPath, fileContent));
|
|
9229
9282
|
if (typeof current.frontmatter.entityRef === "string") {
|
|
@@ -9456,7 +9509,7 @@ ${memory.content}
|
|
|
9456
9509
|
`;
|
|
9457
9510
|
await this.writeTombstoneBlockedFrontmatter(memory, fileContent, updated, async () => {
|
|
9458
9511
|
this.invalidateAllMemoriesCache();
|
|
9459
|
-
if (memory.path.includes(`${
|
|
9512
|
+
if (memory.path.includes(`${path11.sep}cold${path11.sep}`)) {
|
|
9460
9513
|
this.invalidateColdMemoriesCache();
|
|
9461
9514
|
}
|
|
9462
9515
|
});
|
|
@@ -9467,7 +9520,7 @@ ${memory.content}
|
|
|
9467
9520
|
});
|
|
9468
9521
|
}
|
|
9469
9522
|
await this.patchHotMemoriesCache({ addedPath: memory.path });
|
|
9470
|
-
if (memory.path.includes(`${
|
|
9523
|
+
if (memory.path.includes(`${path11.sep}cold${path11.sep}`)) {
|
|
9471
9524
|
this.invalidateColdMemoriesCache();
|
|
9472
9525
|
}
|
|
9473
9526
|
try {
|
|
@@ -9548,7 +9601,7 @@ ${memory.content}
|
|
|
9548
9601
|
return deleted;
|
|
9549
9602
|
}
|
|
9550
9603
|
async loadBuffer() {
|
|
9551
|
-
const bufferPath =
|
|
9604
|
+
const bufferPath = path11.join(this.stateDir, "buffer.json");
|
|
9552
9605
|
try {
|
|
9553
9606
|
const raw = await this.readStorageSecureFile(bufferPath);
|
|
9554
9607
|
return JSON.parse(raw);
|
|
@@ -9560,11 +9613,11 @@ ${memory.content}
|
|
|
9560
9613
|
}
|
|
9561
9614
|
async saveBuffer(state) {
|
|
9562
9615
|
await this.ensureDirectories();
|
|
9563
|
-
const bufferPath =
|
|
9616
|
+
const bufferPath = path11.join(this.stateDir, "buffer.json");
|
|
9564
9617
|
await this.writeStorageSecureFile(bufferPath, JSON.stringify(state, null, 2));
|
|
9565
9618
|
}
|
|
9566
9619
|
async loadMeta() {
|
|
9567
|
-
const metaPath =
|
|
9620
|
+
const metaPath = path11.join(this.stateDir, "meta.json");
|
|
9568
9621
|
try {
|
|
9569
9622
|
const raw = await this.readStorageSecureFile(metaPath);
|
|
9570
9623
|
const parsed = JSON.parse(raw);
|
|
@@ -9597,7 +9650,7 @@ ${memory.content}
|
|
|
9597
9650
|
}
|
|
9598
9651
|
async saveMeta(state) {
|
|
9599
9652
|
await this.ensureDirectories();
|
|
9600
|
-
const metaPath =
|
|
9653
|
+
const metaPath = path11.join(this.stateDir, "meta.json");
|
|
9601
9654
|
await this.writeStorageSecureFile(metaPath, JSON.stringify(state, null, 2));
|
|
9602
9655
|
}
|
|
9603
9656
|
async appendMemoryActionEvents(events) {
|
|
@@ -9661,7 +9714,7 @@ ${memory.content}
|
|
|
9661
9714
|
},
|
|
9662
9715
|
(payload) => this.appendStorageSecureFile(target, payload),
|
|
9663
9716
|
async () => {
|
|
9664
|
-
await mkdir(
|
|
9717
|
+
await mkdir(path11.dirname(target), { recursive: true });
|
|
9665
9718
|
}
|
|
9666
9719
|
);
|
|
9667
9720
|
}
|
|
@@ -9693,7 +9746,7 @@ ${memory.content}
|
|
|
9693
9746
|
let existingKeys;
|
|
9694
9747
|
let identity = null;
|
|
9695
9748
|
try {
|
|
9696
|
-
const st = await
|
|
9749
|
+
const st = await stat3(this.behaviorSignalsPath);
|
|
9697
9750
|
identity = { size: st.size, mtimeMs: st.mtimeMs };
|
|
9698
9751
|
if (this.behaviorSignalsKeyCache && this.behaviorSignalsKeyCache.identity.size === identity.size && this.behaviorSignalsKeyCache.identity.mtimeMs === identity.mtimeMs) {
|
|
9699
9752
|
existingKeys = this.behaviorSignalsKeyCache.keys;
|
|
@@ -9741,7 +9794,7 @@ ${memory.content}
|
|
|
9741
9794
|
await this.appendStorageSecureFile(this.behaviorSignalsPath, payload);
|
|
9742
9795
|
for (const key of pending) existingKeys.add(key);
|
|
9743
9796
|
try {
|
|
9744
|
-
const st = await
|
|
9797
|
+
const st = await stat3(this.behaviorSignalsPath);
|
|
9745
9798
|
const expectedSize = (identity?.size ?? 0) + Buffer.byteLength(payload, "utf-8");
|
|
9746
9799
|
if (st.size === expectedSize) {
|
|
9747
9800
|
this.behaviorSignalsKeyCache = {
|
|
@@ -9759,7 +9812,7 @@ ${memory.content}
|
|
|
9759
9812
|
async appendReextractJobs(events) {
|
|
9760
9813
|
if (events.length === 0) return 0;
|
|
9761
9814
|
await this.ensureDirectories();
|
|
9762
|
-
const filePath =
|
|
9815
|
+
const filePath = path11.join(this.stateDir, "reextract-jobs.jsonl");
|
|
9763
9816
|
const lines = events.map((event) => JSON.stringify(event)).join("\n") + "\n";
|
|
9764
9817
|
try {
|
|
9765
9818
|
await this.appendStorageSecureFile(filePath, lines);
|
|
@@ -9772,7 +9825,7 @@ ${memory.content}
|
|
|
9772
9825
|
}
|
|
9773
9826
|
async readReextractJobs(limit = 200) {
|
|
9774
9827
|
const safeLimit = Number.isFinite(limit) ? Math.max(1, Math.min(1e3, Math.floor(limit))) : 200;
|
|
9775
|
-
const filePath =
|
|
9828
|
+
const filePath = path11.join(this.stateDir, "reextract-jobs.jsonl");
|
|
9776
9829
|
try {
|
|
9777
9830
|
const raw = await this.readStorageSecureFile(filePath);
|
|
9778
9831
|
const lines = raw.split("\n").filter((line) => line.trim().length > 0);
|
|
@@ -9999,7 +10052,7 @@ ${question}
|
|
|
9999
10052
|
|
|
10000
10053
|
**Context:** ${context}
|
|
10001
10054
|
`;
|
|
10002
|
-
const filePath =
|
|
10055
|
+
const filePath = path11.join(this.questionsDir, `${id}.md`);
|
|
10003
10056
|
await this.writeStorageSecureFile(filePath, content);
|
|
10004
10057
|
log.debug(`wrote question ${id} to ${filePath}`);
|
|
10005
10058
|
this.invalidateQuestionsCache();
|
|
@@ -10017,7 +10070,7 @@ ${question}
|
|
|
10017
10070
|
if (!match) return null;
|
|
10018
10071
|
const frontmatterStr = match[1];
|
|
10019
10072
|
const body = match[2].trim();
|
|
10020
|
-
const id = this.extractFrontmatterValue(frontmatterStr, "id") ??
|
|
10073
|
+
const id = this.extractFrontmatterValue(frontmatterStr, "id") ?? path11.basename(filePath, ".md");
|
|
10021
10074
|
const created = this.extractFrontmatterValue(frontmatterStr, "created") ?? "";
|
|
10022
10075
|
const priority = parseFloat(this.extractFrontmatterValue(frontmatterStr, "priority") ?? "0.5");
|
|
10023
10076
|
const resolved = this.extractFrontmatterValue(frontmatterStr, "resolved") === "true";
|
|
@@ -10073,11 +10126,11 @@ ${question}
|
|
|
10073
10126
|
} catch {
|
|
10074
10127
|
}
|
|
10075
10128
|
const hygiene = opts?.hygiene;
|
|
10076
|
-
const rotateEnabled = hygiene?.enabled === true && hygiene.rotateEnabled === true && Array.isArray(hygiene.rotatePaths) && hygiene.rotatePaths.includes(
|
|
10129
|
+
const rotateEnabled = hygiene?.enabled === true && hygiene.rotateEnabled === true && Array.isArray(hygiene.rotatePaths) && hygiene.rotatePaths.includes(path11.basename(identityPath));
|
|
10077
10130
|
if (rotateEnabled) {
|
|
10078
10131
|
const maxBytes = hygiene.rotateMaxBytes;
|
|
10079
10132
|
if (existing.length > maxBytes) {
|
|
10080
|
-
const archiveDir =
|
|
10133
|
+
const archiveDir = path11.join(workspaceDir, hygiene.archiveDir);
|
|
10081
10134
|
const { newContent } = await rotateMarkdownFileToArchive({
|
|
10082
10135
|
filePath: identityPath,
|
|
10083
10136
|
archiveDir,
|
|
@@ -10337,14 +10390,14 @@ ${reflection}
|
|
|
10337
10390
|
if (entries.length === 0) return 0;
|
|
10338
10391
|
const memories = await this.readAllMemories();
|
|
10339
10392
|
const memoryMap = new Map(memories.map((m) => [m.frontmatter.id, m]));
|
|
10340
|
-
const memoryPathMap = new Map(memories.map((m) => [
|
|
10393
|
+
const memoryPathMap = new Map(memories.map((m) => [path11.resolve(m.path), m]));
|
|
10341
10394
|
let updated = 0;
|
|
10342
10395
|
const prevVersion = this.getMemoryCorpusVersion();
|
|
10343
10396
|
const keyId = this.hotCacheKeyId();
|
|
10344
10397
|
const warm = this.hotMemoriesCacheEnabled && getCachedMemories(this.baseDir, prevVersion, keyId, this.hotCacheTtlMs()) !== null;
|
|
10345
10398
|
const appliedPatches = /* @__PURE__ */ new Map();
|
|
10346
10399
|
for (const entry of entries) {
|
|
10347
|
-
const memory = entry.memoryPath ? memoryPathMap.get(
|
|
10400
|
+
const memory = entry.memoryPath ? memoryPathMap.get(path11.resolve(entry.memoryPath)) : memoryMap.get(entry.memoryId);
|
|
10348
10401
|
if (!memory) continue;
|
|
10349
10402
|
try {
|
|
10350
10403
|
const applied = await this.withTombstoneBlockedMemoryPathLock(memory.path, async (current) => {
|
|
@@ -10375,7 +10428,7 @@ ${current.content}
|
|
|
10375
10428
|
if (warm) {
|
|
10376
10429
|
updateCacheOnWrite(this.baseDir, { ...applied.current, frontmatter: applied.newFm }, keyId);
|
|
10377
10430
|
}
|
|
10378
|
-
appliedPatches.set(
|
|
10431
|
+
appliedPatches.set(path11.resolve(memory.path), {
|
|
10379
10432
|
accessCount: entry.newCount,
|
|
10380
10433
|
lastAccessed: entry.lastAccessed
|
|
10381
10434
|
});
|
|
@@ -10391,7 +10444,7 @@ ${current.content}
|
|
|
10391
10444
|
const cur = getCachedMemories(this.baseDir, prevVersion, keyId);
|
|
10392
10445
|
if (cur) {
|
|
10393
10446
|
const reapplied = cur.map((m) => {
|
|
10394
|
-
const patch = appliedPatches.get(
|
|
10447
|
+
const patch = appliedPatches.get(path11.resolve(m.path));
|
|
10395
10448
|
return patch ? {
|
|
10396
10449
|
...m,
|
|
10397
10450
|
frontmatter: { ...m.frontmatter, accessCount: patch.accessCount, lastAccessed: patch.lastAccessed }
|
|
@@ -10421,7 +10474,7 @@ ${current.content}
|
|
|
10421
10474
|
const pathsById = /* @__PURE__ */ new Map();
|
|
10422
10475
|
const filePathsById = /* @__PURE__ */ new Map();
|
|
10423
10476
|
for (const filePath of filePaths) {
|
|
10424
|
-
const memoryId =
|
|
10477
|
+
const memoryId = path11.basename(filePath, ".md");
|
|
10425
10478
|
if (!wantedIds.has(memoryId)) continue;
|
|
10426
10479
|
const paths = filePathsById.get(memoryId) ?? [];
|
|
10427
10480
|
paths.push(filePath);
|
|
@@ -10433,7 +10486,7 @@ ${current.content}
|
|
|
10433
10486
|
const preferredMatches = [];
|
|
10434
10487
|
for (const preferredPath of preferred) {
|
|
10435
10488
|
const directCandidates = new Set(qmdResultPathCandidates(this.baseDir, preferredPath));
|
|
10436
|
-
const directMatch = existingPaths.find((filePath) => directCandidates.has(
|
|
10489
|
+
const directMatch = existingPaths.find((filePath) => directCandidates.has(path11.resolve(filePath)));
|
|
10437
10490
|
if (directMatch) {
|
|
10438
10491
|
preferredMatches.push(directMatch);
|
|
10439
10492
|
continue;
|
|
@@ -10445,7 +10498,7 @@ ${current.content}
|
|
|
10445
10498
|
candidates.add(candidate);
|
|
10446
10499
|
}
|
|
10447
10500
|
}
|
|
10448
|
-
const match = existingPaths.find((filePath) => candidates.has(
|
|
10501
|
+
const match = existingPaths.find((filePath) => candidates.has(path11.resolve(filePath)));
|
|
10449
10502
|
if (match) preferredMatches.push(match);
|
|
10450
10503
|
}
|
|
10451
10504
|
if (preferredMatches.length > 0) {
|
|
@@ -10764,11 +10817,11 @@ ${current.content}
|
|
|
10764
10817
|
}
|
|
10765
10818
|
}
|
|
10766
10819
|
get summariesDir() {
|
|
10767
|
-
return
|
|
10820
|
+
return path11.join(this.baseDir, "summaries");
|
|
10768
10821
|
}
|
|
10769
10822
|
async writeSummary(summary) {
|
|
10770
10823
|
await mkdir(this.summariesDir, { recursive: true });
|
|
10771
|
-
const filePath =
|
|
10824
|
+
const filePath = path11.join(this.summariesDir, `${summary.id}.json`);
|
|
10772
10825
|
await this.writeStorageSecureFile(filePath, JSON.stringify(summary, null, 2));
|
|
10773
10826
|
log.debug(`wrote summary ${summary.id}`);
|
|
10774
10827
|
}
|
|
@@ -10778,7 +10831,7 @@ ${current.content}
|
|
|
10778
10831
|
const summaries = [];
|
|
10779
10832
|
for (const file of files) {
|
|
10780
10833
|
if (!file.endsWith(".json")) continue;
|
|
10781
|
-
const filePath =
|
|
10834
|
+
const filePath = path11.join(this.summariesDir, file);
|
|
10782
10835
|
const raw = await this.readStorageSecureFile(filePath);
|
|
10783
10836
|
summaries.push(JSON.parse(raw));
|
|
10784
10837
|
}
|
|
@@ -10848,7 +10901,7 @@ ${current.content}
|
|
|
10848
10901
|
return archived;
|
|
10849
10902
|
}
|
|
10850
10903
|
async saveTopics(topics) {
|
|
10851
|
-
const metaPath =
|
|
10904
|
+
const metaPath = path11.join(this.stateDir, "topics.json");
|
|
10852
10905
|
await mkdir(this.stateDir, { recursive: true });
|
|
10853
10906
|
await this.writeStorageSecureFile(
|
|
10854
10907
|
metaPath,
|
|
@@ -10857,7 +10910,7 @@ ${current.content}
|
|
|
10857
10910
|
log.debug(`saved ${topics.length} topic scores`);
|
|
10858
10911
|
}
|
|
10859
10912
|
async loadTopics() {
|
|
10860
|
-
const metaPath =
|
|
10913
|
+
const metaPath = path11.join(this.stateDir, "topics.json");
|
|
10861
10914
|
try {
|
|
10862
10915
|
const raw = await this.readStorageSecureFile(metaPath);
|
|
10863
10916
|
return JSON.parse(raw);
|
|
@@ -10972,4 +11025,4 @@ export {
|
|
|
10972
11025
|
isValidBufferSurpriseEvent,
|
|
10973
11026
|
StorageManager3 as StorageManager
|
|
10974
11027
|
};
|
|
10975
|
-
//# sourceMappingURL=chunk-
|
|
11028
|
+
//# sourceMappingURL=chunk-XXRRHING.js.map
|