@remnic/core 9.3.751 → 9.3.752
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-boundary.d.ts +5 -5
- package/dist/access-boundary.js +29 -29
- package/dist/access-cli.js +88 -88
- package/dist/access-http.d.ts +5 -5
- package/dist/access-http.js +35 -35
- package/dist/access-mcp.d.ts +5 -5
- package/dist/access-mcp.js +34 -34
- package/dist/access-operations-batch.js +31 -31
- package/dist/access-operations.d.ts +5 -5
- package/dist/access-operations.js +33 -33
- package/dist/access-recall-surface.d.ts +363 -0
- package/dist/access-recall-surface.js +128 -0
- package/dist/access-schema.js +7 -7
- package/dist/{access-service-DmAEOJdJ.d.ts → access-service-C2cOHQvg.d.ts} +7 -26
- package/dist/access-service.d.ts +5 -5
- package/dist/access-service.js +28 -28
- package/dist/access-surface-catalog.d.ts +5 -5
- package/dist/action-confidence.d.ts +1 -1
- package/dist/active-memory-bridge.d.ts +1 -1
- package/dist/active-recall.d.ts +1 -1
- package/dist/active-recall.js +1 -1
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +4 -4
- package/dist/briefing.d.ts +1 -1
- package/dist/briefing.js +4 -4
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer.d.ts +1 -1
- package/dist/buffer.js +2 -2
- package/dist/calibration.d.ts +1 -1
- package/dist/capabilities.d.ts +1 -1
- package/dist/{capsule-crypto-7FJQINUR.js → capsule-crypto-CZJSLEFG.js} +3 -3
- package/dist/{catalog-BpOcwHdE.d.ts → catalog-D_FvzTM0.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-behavior.js +2 -2
- package/dist/causal-chain.js +2 -2
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-consolidation.js +9 -9
- package/dist/causal-retrieval.js +2 -2
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/causal-trajectory.js +1 -1
- package/dist/{chunk-2NLLXCJG.js → chunk-2BFLDH5F.js} +2 -2
- package/dist/{chunk-UU32EAIY.js → chunk-2DPCAW2T.js} +5 -5
- package/dist/{chunk-5PZCDUJ6.js → chunk-2U4E34Y3.js} +4 -4
- package/dist/{chunk-JRZV3767.js → chunk-33NX5BLR.js} +4 -4
- package/dist/{chunk-X7Y7WX73.js → chunk-437S3G37.js} +2 -2
- package/dist/{chunk-HAZVVOYT.js → chunk-5DXUE7GB.js} +2 -2
- package/dist/{chunk-4DLFJJOQ.js → chunk-5JAT4ZJD.js} +4 -4
- package/dist/{chunk-RS25QOKZ.js → chunk-64SE4X5G.js} +2 -2
- package/dist/{chunk-QRRBXD24.js → chunk-67JRXV6Z.js} +7 -7
- package/dist/{chunk-WA7FECSG.js → chunk-6ROCH5JV.js} +7 -7
- package/dist/{chunk-5QANTTY2.js → chunk-BIAMJUUJ.js} +4 -4
- package/dist/{chunk-IKHKHADN.js → chunk-C4LNKQ3M.js} +5 -5
- package/dist/{chunk-B35L45HZ.js → chunk-DC5OBZS3.js} +2 -2
- package/dist/{chunk-ORAK3LNZ.js → chunk-ER3CCWK2.js} +2 -2
- package/dist/{chunk-SD34EK4Z.js → chunk-FEELYTRT.js} +5 -5
- package/dist/{chunk-KQAFEZQX.js → chunk-FLVL4L3L.js} +2 -2
- package/dist/{chunk-WIWPSQYU.js → chunk-FXRFFYWD.js} +4 -4
- package/dist/{chunk-W3M34XT4.js → chunk-GECEETQ3.js} +4 -4
- package/dist/{chunk-WWSXVOGY.js → chunk-GFGYHLON.js} +2 -2
- package/dist/{chunk-BJMBJZ2Y.js → chunk-GWTFLF2P.js} +59 -59
- package/dist/chunk-GWTFLF2P.js.map +1 -0
- package/dist/{chunk-WOX2UW4K.js → chunk-IBPEVGP5.js} +2 -2
- package/dist/{chunk-JZ7P26GF.js → chunk-IQWFWSCP.js} +4 -4
- package/dist/{chunk-6SXNQFHB.js → chunk-J2JB6BHT.js} +8 -8
- package/dist/{chunk-K2JM4DZZ.js → chunk-JHZ3LEM7.js} +2 -2
- package/dist/{chunk-YGGXUNS4.js → chunk-JNKSFIAY.js} +45 -45
- package/dist/{chunk-CGZWGVQF.js → chunk-K5CWCJKJ.js} +6 -6
- package/dist/{chunk-TPLE6SNY.js → chunk-KFNG72W7.js} +7 -7
- package/dist/{chunk-4NWIGAIC.js → chunk-KT2VQLP7.js} +8 -8
- package/dist/{chunk-6FNZ3NMS.js → chunk-L3VSTJ2V.js} +2 -2
- package/dist/{chunk-ARV3AUOM.js → chunk-M5QKGHCR.js} +2 -2
- package/dist/{chunk-E4PFDD3N.js → chunk-MEPWWSTD.js} +4 -4
- package/dist/{chunk-V5RVMULT.js → chunk-MLDAD27I.js} +7 -7
- package/dist/{chunk-K2R3DEEH.js → chunk-MTN2G4DT.js} +2 -2
- package/dist/{chunk-DBSMLRTO.js → chunk-MW7UUXTA.js} +5 -5
- package/dist/{chunk-OSMBC3JU.js → chunk-OKOF7ITI.js} +6 -6
- package/dist/{chunk-DBRVU5PR.js → chunk-OVMLS7TN.js} +3 -3
- package/dist/{chunk-NNL4LJAD.js → chunk-QMMCMV2L.js} +5 -5
- package/dist/{chunk-RNWWAS5V.js → chunk-QRM3K3XT.js} +5 -5
- package/dist/{chunk-HM6UJPPO.js → chunk-R7TGDLV3.js} +4 -4
- package/dist/{chunk-EEKDRAWX.js → chunk-RBYV3WSB.js} +4 -4
- package/dist/{chunk-LOPZ2DWR.js → chunk-RRRZ3CLN.js} +4 -4
- package/dist/{chunk-7TWA7DKP.js → chunk-S5UYWK3O.js} +6 -6
- package/dist/{chunk-QOGXUNWL.js → chunk-SC5AEZLU.js} +9 -9
- package/dist/{chunk-SNEXVX3U.js → chunk-UFNQKZV7.js} +15 -15
- package/dist/{chunk-W3BFT5OJ.js → chunk-V4ZPLQLC.js} +2 -2
- package/dist/{chunk-SQNED75R.js → chunk-V5UV7BOA.js} +1 -1
- package/dist/{chunk-RWZB6MAY.js → chunk-VQL22SHO.js} +891 -1002
- package/dist/chunk-VQL22SHO.js.map +1 -0
- package/dist/{chunk-UETBEHBA.js → chunk-VX2RYM2K.js} +2232 -1942
- package/dist/chunk-VX2RYM2K.js.map +1 -0
- package/dist/{chunk-K5LLP4CY.js → chunk-XKAOT4ZB.js} +4 -4
- package/dist/{chunk-ZBVQ4ZM4.js → chunk-YGNQG4Q6.js} +8 -8
- package/dist/{chunk-EZ25VE3G.js → chunk-YNDLCWXS.js} +4 -4
- package/dist/{chunk-HYI2GP3F.js → chunk-ZGGI3COG.js} +9 -9
- package/dist/{cli-lmf5RGyQ.d.ts → cli-DFUU9WYu.d.ts} +3 -3
- package/dist/cli.d.ts +6 -6
- package/dist/cli.js +60 -60
- package/dist/compounding/engine.d.ts +1 -1
- package/dist/compounding/engine.js +6 -6
- package/dist/compounding/preference-consolidator.d.ts +1 -1
- package/dist/compression-optimizer.d.ts +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js +1 -1
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +5 -5
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +7 -7
- 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/contradiction/index.js +2 -2
- package/dist/{contradiction-scan-3FJYWS3G.js → contradiction-scan-KO4WWCS4.js} +3 -3
- package/dist/contradiction-scan-KO4WWCS4.js.map +1 -0
- package/dist/conversation-index/backend.d.ts +1 -1
- package/dist/conversation-index/chunker.d.ts +1 -1
- package/dist/conversation-index/faiss-adapter.d.ts +1 -1
- package/dist/conversation-index/indexer.d.ts +1 -1
- package/dist/conversation-index/search.d.ts +1 -1
- package/dist/dashboard-runtime.js +2 -2
- package/dist/day-summary.d.ts +1 -1
- package/dist/day-summary.js +2 -2
- package/dist/delinearize.d.ts +1 -1
- package/dist/direct-answer-wiring.d.ts +1 -1
- package/dist/direct-answer.d.ts +1 -1
- package/dist/embedding-fallback.d.ts +1 -1
- package/dist/embedding-fallback.js +2 -2
- package/dist/enrichment/index.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +1 -1
- package/dist/entity-retrieval.js +5 -5
- package/dist/entity-schema.d.ts +1 -1
- package/dist/explicit-capture.d.ts +4 -4
- package/dist/explicit-capture.js +2 -2
- package/dist/extraction-faithfulness.d.ts +1 -1
- package/dist/extraction-judge-telemetry.d.ts +1 -1
- package/dist/extraction-judge-training.d.ts +1 -1
- package/dist/extraction-judge.d.ts +1 -1
- package/dist/extraction.d.ts +1 -1
- package/dist/extraction.js +4 -4
- package/dist/fallback-llm.d.ts +1 -1
- package/dist/graph-dashboard-diff.d.ts +1 -1
- package/dist/graph-dashboard-key.d.ts +1 -1
- package/dist/graph-dashboard-parser.d.ts +1 -1
- package/dist/graph-edge-reinforcement.d.ts +1 -1
- package/dist/graph-snapshot.d.ts +1 -1
- package/dist/graph.d.ts +1 -1
- package/dist/identity-continuity.d.ts +1 -1
- package/dist/importance.d.ts +1 -1
- package/dist/index.d.ts +9 -9
- package/dist/index.js +142 -142
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/engine.js +3 -3
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/index.js +8 -8
- package/dist/lcm/tools.d.ts +1 -1
- package/dist/lifecycle.d.ts +1 -1
- package/dist/live-connectors-runner.d.ts +1 -1
- package/dist/local-llm.d.ts +1 -1
- package/dist/local-llm.js +2 -2
- package/dist/local-model-endpoint.d.ts +1 -1
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/maintenance/memory-governance.js +4 -4
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +4 -4
- package/dist/maintenance/rebuild-memory-projection.js +5 -5
- package/dist/mcp-memory-inspector-app.d.ts +5 -5
- package/dist/memory-action-policy.d.ts +1 -1
- package/dist/memory-cache.d.ts +1 -1
- package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
- package/dist/memory-projection-store.d.ts +1 -1
- package/dist/memory-provenance.d.ts +1 -1
- package/dist/memory-worth-outcomes.d.ts +1 -1
- package/dist/models-json.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +2 -2
- package/dist/namespaces/migrate.js +10 -10
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/search.js +4 -4
- package/dist/namespaces/storage.d.ts +2 -2
- package/dist/namespaces/storage.js +6 -6
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +1 -1
- package/dist/operator-toolkit.js +17 -17
- package/dist/orchestration/compression-guideline-coordinator.d.ts +1 -1
- package/dist/orchestration/compression-guideline-coordinator.js +2 -2
- package/dist/orchestration/maintenance.d.ts +2 -2
- package/dist/orchestration/maintenance.js +10 -10
- package/dist/{orchestrator-D7bb8ZGp.d.ts → orchestrator-BhxMxtQJ.d.ts} +27 -106
- package/dist/orchestrator.d.ts +4 -4
- package/dist/orchestrator.js +86 -86
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/policy-runtime.d.ts +1 -1
- package/dist/provenance.d.ts +1 -1
- package/dist/qmd-recall-cache.d.ts +1 -1
- package/dist/qmd.d.ts +1 -1
- package/dist/recall-disclosure-escalation.d.ts +1 -1
- package/dist/recall-explain-renderer.d.ts +1 -1
- package/dist/recall-planner-llm.d.ts +1 -1
- package/dist/recall-state.d.ts +1 -1
- package/dist/recall-tag-filter.d.ts +1 -1
- package/dist/recall-xray-cli.d.ts +1 -1
- package/dist/recall-xray-renderer.d.ts +1 -1
- package/dist/recall-xray.d.ts +1 -1
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/resume-bundles.js +1 -1
- package/dist/retrieval-agents.d.ts +1 -1
- package/dist/retrieval-tiers.d.ts +1 -1
- package/dist/routing/engine.d.ts +1 -1
- package/dist/routing/store.d.ts +1 -1
- package/dist/routing/store.js +2 -2
- package/dist/schemas.d.ts +22 -22
- package/dist/search/embed-helper.d.ts +1 -1
- package/dist/search/embed-helper.js +2 -2
- package/dist/search/factory.d.ts +1 -1
- package/dist/search/factory.js +3 -3
- package/dist/search/index.d.ts +1 -1
- package/dist/search/index.js +3 -3
- package/dist/search/lancedb-backend.d.ts +1 -1
- package/dist/search/meilisearch-backend.d.ts +1 -1
- package/dist/search/noop-backend.d.ts +1 -1
- package/dist/search/orama-backend.d.ts +1 -1
- package/dist/search/port.d.ts +1 -1
- package/dist/search/remote-backend.d.ts +1 -1
- package/dist/secure-store/index.js +2 -2
- package/dist/{semantic-consolidation-CTfbVwCA.d.ts → semantic-consolidation-BrsoFeMP.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +7 -7
- package/dist/semantic-rule-promotion.js +4 -4
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +4 -4
- package/dist/session-observer-bands.d.ts +1 -1
- package/dist/session-observer-state.d.ts +1 -1
- package/dist/shared-context/manager.d.ts +1 -1
- package/dist/shared-context/manager.js +2 -2
- package/dist/signal.d.ts +1 -1
- package/dist/storage.d.ts +1 -1
- package/dist/storage.js +3 -3
- package/dist/summarizer.d.ts +1 -1
- package/dist/summarizer.js +3 -3
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/temporal-supersession.d.ts +1 -1
- package/dist/temporal-validity.d.ts +1 -1
- package/dist/threading.d.ts +1 -1
- package/dist/tier-migration.d.ts +1 -1
- package/dist/tier-routing.d.ts +1 -1
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/transfer/backup.js +3 -3
- package/dist/transfer/capsule-export.js +3 -3
- package/dist/transfer/capsule-import.js +3 -3
- package/dist/transfer/types.d.ts +12 -12
- package/dist/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/{types-D4NYDtXI.d.ts → types-BfI4uJeb.d.ts} +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/utility-runtime.d.ts +1 -1
- package/dist/verified-recall.js +4 -4
- package/package.json +2 -2
- package/src/access-recall-surface.ts +1552 -0
- package/src/access-service.ts +29 -1219
- package/src/orchestration/recall-entry.ts +290 -0
- package/src/orchestration/session-context.ts +407 -0
- package/src/orchestrator.ts +125 -462
- package/dist/chunk-BJMBJZ2Y.js.map +0 -1
- package/dist/chunk-RWZB6MAY.js.map +0 -1
- package/dist/chunk-UETBEHBA.js.map +0 -1
- /package/dist/{capsule-crypto-7FJQINUR.js.map → access-recall-surface.js.map} +0 -0
- /package/dist/{contradiction-scan-3FJYWS3G.js.map → capsule-crypto-CZJSLEFG.js.map} +0 -0
- /package/dist/{chunk-2NLLXCJG.js.map → chunk-2BFLDH5F.js.map} +0 -0
- /package/dist/{chunk-UU32EAIY.js.map → chunk-2DPCAW2T.js.map} +0 -0
- /package/dist/{chunk-5PZCDUJ6.js.map → chunk-2U4E34Y3.js.map} +0 -0
- /package/dist/{chunk-JRZV3767.js.map → chunk-33NX5BLR.js.map} +0 -0
- /package/dist/{chunk-X7Y7WX73.js.map → chunk-437S3G37.js.map} +0 -0
- /package/dist/{chunk-HAZVVOYT.js.map → chunk-5DXUE7GB.js.map} +0 -0
- /package/dist/{chunk-4DLFJJOQ.js.map → chunk-5JAT4ZJD.js.map} +0 -0
- /package/dist/{chunk-RS25QOKZ.js.map → chunk-64SE4X5G.js.map} +0 -0
- /package/dist/{chunk-QRRBXD24.js.map → chunk-67JRXV6Z.js.map} +0 -0
- /package/dist/{chunk-WA7FECSG.js.map → chunk-6ROCH5JV.js.map} +0 -0
- /package/dist/{chunk-5QANTTY2.js.map → chunk-BIAMJUUJ.js.map} +0 -0
- /package/dist/{chunk-IKHKHADN.js.map → chunk-C4LNKQ3M.js.map} +0 -0
- /package/dist/{chunk-B35L45HZ.js.map → chunk-DC5OBZS3.js.map} +0 -0
- /package/dist/{chunk-ORAK3LNZ.js.map → chunk-ER3CCWK2.js.map} +0 -0
- /package/dist/{chunk-SD34EK4Z.js.map → chunk-FEELYTRT.js.map} +0 -0
- /package/dist/{chunk-KQAFEZQX.js.map → chunk-FLVL4L3L.js.map} +0 -0
- /package/dist/{chunk-WIWPSQYU.js.map → chunk-FXRFFYWD.js.map} +0 -0
- /package/dist/{chunk-W3M34XT4.js.map → chunk-GECEETQ3.js.map} +0 -0
- /package/dist/{chunk-WWSXVOGY.js.map → chunk-GFGYHLON.js.map} +0 -0
- /package/dist/{chunk-WOX2UW4K.js.map → chunk-IBPEVGP5.js.map} +0 -0
- /package/dist/{chunk-JZ7P26GF.js.map → chunk-IQWFWSCP.js.map} +0 -0
- /package/dist/{chunk-6SXNQFHB.js.map → chunk-J2JB6BHT.js.map} +0 -0
- /package/dist/{chunk-K2JM4DZZ.js.map → chunk-JHZ3LEM7.js.map} +0 -0
- /package/dist/{chunk-YGGXUNS4.js.map → chunk-JNKSFIAY.js.map} +0 -0
- /package/dist/{chunk-CGZWGVQF.js.map → chunk-K5CWCJKJ.js.map} +0 -0
- /package/dist/{chunk-TPLE6SNY.js.map → chunk-KFNG72W7.js.map} +0 -0
- /package/dist/{chunk-4NWIGAIC.js.map → chunk-KT2VQLP7.js.map} +0 -0
- /package/dist/{chunk-6FNZ3NMS.js.map → chunk-L3VSTJ2V.js.map} +0 -0
- /package/dist/{chunk-ARV3AUOM.js.map → chunk-M5QKGHCR.js.map} +0 -0
- /package/dist/{chunk-E4PFDD3N.js.map → chunk-MEPWWSTD.js.map} +0 -0
- /package/dist/{chunk-V5RVMULT.js.map → chunk-MLDAD27I.js.map} +0 -0
- /package/dist/{chunk-K2R3DEEH.js.map → chunk-MTN2G4DT.js.map} +0 -0
- /package/dist/{chunk-DBSMLRTO.js.map → chunk-MW7UUXTA.js.map} +0 -0
- /package/dist/{chunk-OSMBC3JU.js.map → chunk-OKOF7ITI.js.map} +0 -0
- /package/dist/{chunk-DBRVU5PR.js.map → chunk-OVMLS7TN.js.map} +0 -0
- /package/dist/{chunk-NNL4LJAD.js.map → chunk-QMMCMV2L.js.map} +0 -0
- /package/dist/{chunk-RNWWAS5V.js.map → chunk-QRM3K3XT.js.map} +0 -0
- /package/dist/{chunk-HM6UJPPO.js.map → chunk-R7TGDLV3.js.map} +0 -0
- /package/dist/{chunk-EEKDRAWX.js.map → chunk-RBYV3WSB.js.map} +0 -0
- /package/dist/{chunk-LOPZ2DWR.js.map → chunk-RRRZ3CLN.js.map} +0 -0
- /package/dist/{chunk-7TWA7DKP.js.map → chunk-S5UYWK3O.js.map} +0 -0
- /package/dist/{chunk-QOGXUNWL.js.map → chunk-SC5AEZLU.js.map} +0 -0
- /package/dist/{chunk-SNEXVX3U.js.map → chunk-UFNQKZV7.js.map} +0 -0
- /package/dist/{chunk-W3BFT5OJ.js.map → chunk-V4ZPLQLC.js.map} +0 -0
- /package/dist/{chunk-SQNED75R.js.map → chunk-V5UV7BOA.js.map} +0 -0
- /package/dist/{chunk-K5LLP4CY.js.map → chunk-XKAOT4ZB.js.map} +0 -0
- /package/dist/{chunk-ZBVQ4ZM4.js.map → chunk-YGNQG4Q6.js.map} +0 -0
- /package/dist/{chunk-EZ25VE3G.js.map → chunk-YNDLCWXS.js.map} +0 -0
- /package/dist/{chunk-HYI2GP3F.js.map → chunk-ZGGI3COG.js.map} +0 -0
|
@@ -7,10 +7,10 @@ import {
|
|
|
7
7
|
} from "./chunk-EHYB325U.js";
|
|
8
8
|
import {
|
|
9
9
|
CompressionGuidelineCoordinator
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-BIAMJUUJ.js";
|
|
11
11
|
import {
|
|
12
12
|
MaintenanceScheduler
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-KT2VQLP7.js";
|
|
14
14
|
import {
|
|
15
15
|
runPeerProfileReasoner
|
|
16
16
|
} from "./chunk-I74SUMNI.js";
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
} from "./chunk-7HYPN2GC.js";
|
|
20
20
|
import {
|
|
21
21
|
LcmEngine
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-MLDAD27I.js";
|
|
23
23
|
import {
|
|
24
24
|
chunkTranscriptEntries
|
|
25
25
|
} from "./chunk-TECVW3JP.js";
|
|
@@ -29,10 +29,10 @@ import {
|
|
|
29
29
|
import {
|
|
30
30
|
CompoundingEngine,
|
|
31
31
|
defaultTierMigrationCycleBudget
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-J2JB6BHT.js";
|
|
33
33
|
import {
|
|
34
34
|
SharedContextManager
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-33NX5BLR.js";
|
|
36
36
|
import {
|
|
37
37
|
applyTrustScoreStage,
|
|
38
38
|
buildTrustSignalsForRerank,
|
|
@@ -63,7 +63,7 @@ import {
|
|
|
63
63
|
} from "./chunk-UHGBNIOS.js";
|
|
64
64
|
import {
|
|
65
65
|
HourlySummarizer
|
|
66
|
-
} from "./chunk-
|
|
66
|
+
} from "./chunk-QMMCMV2L.js";
|
|
67
67
|
import {
|
|
68
68
|
buildTargetedFactRecallSection,
|
|
69
69
|
shouldRecallTargetedFactEvidence
|
|
@@ -106,6 +106,9 @@ import {
|
|
|
106
106
|
RerankCache,
|
|
107
107
|
rerankLocalOrNoop
|
|
108
108
|
} from "./chunk-E3VODCC3.js";
|
|
109
|
+
import {
|
|
110
|
+
reorderRecallResultsWithMmr
|
|
111
|
+
} from "./chunk-YDBIWGNI.js";
|
|
109
112
|
import {
|
|
110
113
|
createRecallSectionMetricRecorder
|
|
111
114
|
} from "./chunk-VQ34TERH.js";
|
|
@@ -119,24 +122,15 @@ import {
|
|
|
119
122
|
applyReasoningTraceBoost
|
|
120
123
|
} from "./chunk-ZZTOURJI.js";
|
|
121
124
|
import {
|
|
122
|
-
|
|
123
|
-
} from "./chunk-
|
|
125
|
+
NegativeExampleStore
|
|
126
|
+
} from "./chunk-EXM3CQTZ.js";
|
|
124
127
|
import {
|
|
125
128
|
applyMemoryWorthFilter,
|
|
126
129
|
buildMemoryWorthCounterMap
|
|
127
130
|
} from "./chunk-3GPTTA4J.js";
|
|
128
|
-
import {
|
|
129
|
-
NegativeExampleStore
|
|
130
|
-
} from "./chunk-EXM3CQTZ.js";
|
|
131
131
|
import {
|
|
132
132
|
evaluateMemoryActionPolicy
|
|
133
133
|
} from "./chunk-H63EDPFJ.js";
|
|
134
|
-
import {
|
|
135
|
-
runLiveConnectorsOnce
|
|
136
|
-
} from "./chunk-VU3SVYMA.js";
|
|
137
|
-
import {
|
|
138
|
-
classifyMemoryKind
|
|
139
|
-
} from "./chunk-YAZNBMNF.js";
|
|
140
134
|
import {
|
|
141
135
|
hasBroadGraphIntent,
|
|
142
136
|
inferIntentFromText,
|
|
@@ -144,6 +138,12 @@ import {
|
|
|
144
138
|
isTaskInitiationIntent,
|
|
145
139
|
planRecallMode
|
|
146
140
|
} from "./chunk-PD6O7AXF.js";
|
|
141
|
+
import {
|
|
142
|
+
runLiveConnectorsOnce
|
|
143
|
+
} from "./chunk-VU3SVYMA.js";
|
|
144
|
+
import {
|
|
145
|
+
classifyMemoryKind
|
|
146
|
+
} from "./chunk-YAZNBMNF.js";
|
|
147
147
|
import {
|
|
148
148
|
recordJudgeTrainingPair
|
|
149
149
|
} from "./chunk-XHYGJVXL.js";
|
|
@@ -160,7 +160,7 @@ import {
|
|
|
160
160
|
} from "./chunk-LTHVM4XN.js";
|
|
161
161
|
import {
|
|
162
162
|
ExtractionEngine
|
|
163
|
-
} from "./chunk-
|
|
163
|
+
} from "./chunk-SC5AEZLU.js";
|
|
164
164
|
import {
|
|
165
165
|
parseMemoryActionEligibilityContext
|
|
166
166
|
} from "./chunk-5GSUBCZM.js";
|
|
@@ -169,7 +169,7 @@ import {
|
|
|
169
169
|
} from "./chunk-PWFWCGOO.js";
|
|
170
170
|
import {
|
|
171
171
|
LocalLlmClient
|
|
172
|
-
} from "./chunk-
|
|
172
|
+
} from "./chunk-MW7UUXTA.js";
|
|
173
173
|
import {
|
|
174
174
|
buildFocusedListRecallSection,
|
|
175
175
|
shouldRecallFocusedListEvidence
|
|
@@ -187,35 +187,35 @@ import {
|
|
|
187
187
|
} from "./chunk-4463LUIE.js";
|
|
188
188
|
import {
|
|
189
189
|
formatDaySummaryMemories
|
|
190
|
-
} from "./chunk-
|
|
190
|
+
} from "./chunk-RRRZ3CLN.js";
|
|
191
191
|
import {
|
|
192
192
|
tryDirectAnswer
|
|
193
193
|
} from "./chunk-Q6IP2ARR.js";
|
|
194
194
|
import {
|
|
195
195
|
EmbeddingFallback
|
|
196
|
-
} from "./chunk-
|
|
196
|
+
} from "./chunk-OKOF7ITI.js";
|
|
197
197
|
import {
|
|
198
198
|
buildEntityRecallSection,
|
|
199
199
|
entityRecentTranscriptLookbackHours,
|
|
200
200
|
readRecentEntityTranscriptEntries
|
|
201
|
-
} from "./chunk-
|
|
201
|
+
} from "./chunk-67JRXV6Z.js";
|
|
202
202
|
import {
|
|
203
203
|
RoutingRulesStore
|
|
204
|
-
} from "./chunk-
|
|
204
|
+
} from "./chunk-FXRFFYWD.js";
|
|
205
205
|
import {
|
|
206
206
|
normalizeReplaySessionKey
|
|
207
207
|
} from "./chunk-2PRQG7PV.js";
|
|
208
208
|
import {
|
|
209
209
|
compareVerifiedEpisodeResults,
|
|
210
210
|
searchVerifiedEpisodes
|
|
211
|
-
} from "./chunk-
|
|
211
|
+
} from "./chunk-L3VSTJ2V.js";
|
|
212
212
|
import {
|
|
213
213
|
ThreadingManager
|
|
214
214
|
} from "./chunk-QRDOSYOR.js";
|
|
215
215
|
import {
|
|
216
216
|
compareVerifiedSemanticRuleResults,
|
|
217
217
|
searchVerifiedSemanticRules
|
|
218
|
-
} from "./chunk-
|
|
218
|
+
} from "./chunk-V4ZPLQLC.js";
|
|
219
219
|
import {
|
|
220
220
|
searchWorkProductLedgerEntries
|
|
221
221
|
} from "./chunk-ZRWB5D4H.js";
|
|
@@ -228,14 +228,14 @@ import {
|
|
|
228
228
|
import {
|
|
229
229
|
runNamespaceMaintenanceFanout,
|
|
230
230
|
summarizeNamespaceMaintenanceHealth
|
|
231
|
-
} from "./chunk-
|
|
231
|
+
} from "./chunk-UFNQKZV7.js";
|
|
232
232
|
import {
|
|
233
233
|
NamespaceCatalog,
|
|
234
234
|
planNamespaceMaintenance
|
|
235
|
-
} from "./chunk-
|
|
235
|
+
} from "./chunk-K5CWCJKJ.js";
|
|
236
236
|
import {
|
|
237
237
|
NamespaceStorageRouter
|
|
238
|
-
} from "./chunk-
|
|
238
|
+
} from "./chunk-2DPCAW2T.js";
|
|
239
239
|
import {
|
|
240
240
|
searchHarmonicRetrieval
|
|
241
241
|
} from "./chunk-AV5ZEH4M.js";
|
|
@@ -243,13 +243,13 @@ import {
|
|
|
243
243
|
isAboveImportanceThreshold,
|
|
244
244
|
scoreImportance
|
|
245
245
|
} from "./chunk-JXS5PDQ7.js";
|
|
246
|
-
import {
|
|
247
|
-
recordEvalShadowRecall
|
|
248
|
-
} from "./chunk-3PY7VHV7.js";
|
|
249
246
|
import {
|
|
250
247
|
EXTRACTION_JUDGE_VERDICT_CATEGORY,
|
|
251
248
|
recordJudgeVerdict
|
|
252
249
|
} from "./chunk-BVKCV2ZY.js";
|
|
250
|
+
import {
|
|
251
|
+
recordEvalShadowRecall
|
|
252
|
+
} from "./chunk-3PY7VHV7.js";
|
|
253
253
|
import {
|
|
254
254
|
collectNativeKnowledgeChunks,
|
|
255
255
|
formatNativeKnowledgeSection,
|
|
@@ -261,6 +261,9 @@ import {
|
|
|
261
261
|
import {
|
|
262
262
|
buildCompressionGuidelinesMarkdown
|
|
263
263
|
} from "./chunk-OD4FM2U7.js";
|
|
264
|
+
import {
|
|
265
|
+
SmartBuffer
|
|
266
|
+
} from "./chunk-IQWFWSCP.js";
|
|
264
267
|
import {
|
|
265
268
|
buildConsolidationPrompt,
|
|
266
269
|
buildExtensionsBlockForConsolidation,
|
|
@@ -270,7 +273,13 @@ import {
|
|
|
270
273
|
materializeAfterSemanticConsolidation,
|
|
271
274
|
parseConsolidationResponse,
|
|
272
275
|
parseOperatorAwareConsolidationResponse
|
|
273
|
-
} from "./chunk-
|
|
276
|
+
} from "./chunk-C4LNKQ3M.js";
|
|
277
|
+
import {
|
|
278
|
+
compileCorrectionRule,
|
|
279
|
+
correctionsFilePath,
|
|
280
|
+
loadCorrectionsFile,
|
|
281
|
+
saveCorrectionsFile
|
|
282
|
+
} from "./chunk-NDAH7BJ5.js";
|
|
274
283
|
import {
|
|
275
284
|
buildRecallQueryPolicy
|
|
276
285
|
} from "./chunk-LBJBNWS2.js";
|
|
@@ -281,6 +290,9 @@ import {
|
|
|
281
290
|
import {
|
|
282
291
|
BootstrapEngine
|
|
283
292
|
} from "./chunk-VGUOEDTU.js";
|
|
293
|
+
import {
|
|
294
|
+
isDisagreementPrompt
|
|
295
|
+
} from "./chunk-H3FZVNRN.js";
|
|
284
296
|
import {
|
|
285
297
|
BoxBuilder
|
|
286
298
|
} from "./chunk-7FL4CNPV.js";
|
|
@@ -290,18 +302,6 @@ import {
|
|
|
290
302
|
import {
|
|
291
303
|
chunkContent
|
|
292
304
|
} from "./chunk-UQ7RN5HK.js";
|
|
293
|
-
import {
|
|
294
|
-
SmartBuffer
|
|
295
|
-
} from "./chunk-JZ7P26GF.js";
|
|
296
|
-
import {
|
|
297
|
-
isDisagreementPrompt
|
|
298
|
-
} from "./chunk-H3FZVNRN.js";
|
|
299
|
-
import {
|
|
300
|
-
compileCorrectionRule,
|
|
301
|
-
correctionsFilePath,
|
|
302
|
-
loadCorrectionsFile,
|
|
303
|
-
saveCorrectionsFile
|
|
304
|
-
} from "./chunk-NDAH7BJ5.js";
|
|
305
305
|
import {
|
|
306
306
|
WearablesInputError,
|
|
307
307
|
describeErrorForOperator
|
|
@@ -310,14 +310,17 @@ import {
|
|
|
310
310
|
recordDreamsPhaseRun
|
|
311
311
|
} from "./chunk-YF6FMLBT.js";
|
|
312
312
|
import {
|
|
313
|
+
QmdResultResolver,
|
|
313
314
|
capturePassiveCorrections,
|
|
314
315
|
clusterByKey,
|
|
315
316
|
createCorrectionService,
|
|
316
|
-
detectPassiveCorrections
|
|
317
|
-
|
|
317
|
+
detectPassiveCorrections,
|
|
318
|
+
qmdCollectionPathParts,
|
|
319
|
+
selfDeps
|
|
320
|
+
} from "./chunk-VX2RYM2K.js";
|
|
318
321
|
import {
|
|
319
322
|
importCapsule
|
|
320
|
-
} from "./chunk-
|
|
323
|
+
} from "./chunk-M5QKGHCR.js";
|
|
321
324
|
import {
|
|
322
325
|
isCodingGraphInstalled
|
|
323
326
|
} from "./chunk-VQ7B2Q6M.js";
|
|
@@ -342,14 +345,14 @@ import {
|
|
|
342
345
|
resolveNamespaceFromStorageDir,
|
|
343
346
|
resolveScopePlan,
|
|
344
347
|
resolveScopeProfilePlan
|
|
345
|
-
} from "./chunk-
|
|
348
|
+
} from "./chunk-GECEETQ3.js";
|
|
346
349
|
import {
|
|
347
350
|
NamespaceSearchRouter
|
|
348
|
-
} from "./chunk-
|
|
351
|
+
} from "./chunk-5DXUE7GB.js";
|
|
349
352
|
import {
|
|
350
353
|
createConversationIndexRuntime,
|
|
351
354
|
createSearchBackend
|
|
352
|
-
} from "./chunk-
|
|
355
|
+
} from "./chunk-QRM3K3XT.js";
|
|
353
356
|
import {
|
|
354
357
|
NoopSearchBackend
|
|
355
358
|
} from "./chunk-CYEPCZN5.js";
|
|
@@ -372,20 +375,20 @@ import {
|
|
|
372
375
|
} from "./chunk-QDW3E4RD.js";
|
|
373
376
|
import {
|
|
374
377
|
shouldSkipImplicitExtraction
|
|
375
|
-
} from "./chunk-
|
|
376
|
-
import {
|
|
377
|
-
searchCausalTrajectories
|
|
378
|
-
} from "./chunk-SQNED75R.js";
|
|
378
|
+
} from "./chunk-XKAOT4ZB.js";
|
|
379
379
|
import {
|
|
380
380
|
GraphIndex
|
|
381
381
|
} from "./chunk-EHQ5HO5T.js";
|
|
382
|
+
import {
|
|
383
|
+
searchCausalTrajectories
|
|
384
|
+
} from "./chunk-V5UV7BOA.js";
|
|
382
385
|
import {
|
|
383
386
|
decideLifecycleTransition,
|
|
384
387
|
resolveLifecycleState
|
|
385
388
|
} from "./chunk-TBBDFYXW.js";
|
|
386
389
|
import {
|
|
387
390
|
buildChainFollowupGenerator
|
|
388
|
-
} from "./chunk-
|
|
391
|
+
} from "./chunk-MTN2G4DT.js";
|
|
389
392
|
import {
|
|
390
393
|
ContentHashIndex,
|
|
391
394
|
StorageManager,
|
|
@@ -393,7 +396,10 @@ import {
|
|
|
393
396
|
fingerprintEntityStructuredFacts,
|
|
394
397
|
normalizeAttributePairs,
|
|
395
398
|
parseEntityFile
|
|
396
|
-
} from "./chunk-
|
|
399
|
+
} from "./chunk-YGNQG4Q6.js";
|
|
400
|
+
import {
|
|
401
|
+
buildRetiredFactTombstoneInputs
|
|
402
|
+
} from "./chunk-L2B3EE7B.js";
|
|
397
403
|
import {
|
|
398
404
|
isValidTranscriptDate,
|
|
399
405
|
loadSpeakerRegistry,
|
|
@@ -401,9 +407,6 @@ import {
|
|
|
401
407
|
saveSpeakerRegistry,
|
|
402
408
|
speakerRegistryKey
|
|
403
409
|
} from "./chunk-M7XQSUBB.js";
|
|
404
|
-
import {
|
|
405
|
-
buildRetiredFactTombstoneInputs
|
|
406
|
-
} from "./chunk-L2B3EE7B.js";
|
|
407
410
|
import {
|
|
408
411
|
assertPathInsideRoot
|
|
409
412
|
} from "./chunk-5GPPACXK.js";
|
|
@@ -451,13 +454,43 @@ import {
|
|
|
451
454
|
fallbackLlmRuntimeContextFromConfig,
|
|
452
455
|
gatewayTaskChainOptions
|
|
453
456
|
} from "./chunk-VUA4S7P6.js";
|
|
457
|
+
import {
|
|
458
|
+
sanitizeMemoryContent
|
|
459
|
+
} from "./chunk-5GKPFL3S.js";
|
|
460
|
+
import {
|
|
461
|
+
expandTildePath
|
|
462
|
+
} from "./chunk-EYIEWJNI.js";
|
|
463
|
+
import {
|
|
464
|
+
readEnvVar,
|
|
465
|
+
resolveHomeDir
|
|
466
|
+
} from "./chunk-JUC24CTX.js";
|
|
467
|
+
import {
|
|
468
|
+
log
|
|
469
|
+
} from "./chunk-NU3CSQ4H.js";
|
|
454
470
|
import {
|
|
455
471
|
CAPSULE_ID_PATTERN
|
|
456
472
|
} from "./chunk-WEHSQBFR.js";
|
|
457
473
|
import {
|
|
458
474
|
keyring_exports,
|
|
459
475
|
secureStoreDir
|
|
460
|
-
} from "./chunk-
|
|
476
|
+
} from "./chunk-GWTFLF2P.js";
|
|
477
|
+
import {
|
|
478
|
+
assertIsDirectoryNotSymlink,
|
|
479
|
+
assertRealpathInsideRoot
|
|
480
|
+
} from "./chunk-GCGJW34D.js";
|
|
481
|
+
import {
|
|
482
|
+
SecureStoreLockedError
|
|
483
|
+
} from "./chunk-J2HSAU72.js";
|
|
484
|
+
import {
|
|
485
|
+
parseFlexibleIsoTimestamp
|
|
486
|
+
} from "./chunk-P7FMDTKL.js";
|
|
487
|
+
import {
|
|
488
|
+
ALL_CATEGORY_DIRS,
|
|
489
|
+
ALL_CATEGORY_KEYS,
|
|
490
|
+
RECALL_FALLBACK_DIRS,
|
|
491
|
+
categoryDirName,
|
|
492
|
+
getCategoryDir
|
|
493
|
+
} from "./chunk-VS2IYZRU.js";
|
|
461
494
|
import {
|
|
462
495
|
buildRetrievedMemoryProvenance
|
|
463
496
|
} from "./chunk-I4WBNM3M.js";
|
|
@@ -494,36 +527,6 @@ import {
|
|
|
494
527
|
resolveSecurityCapabilities,
|
|
495
528
|
resolveUtilityLearningCapabilities
|
|
496
529
|
} from "./chunk-VSF7AAGE.js";
|
|
497
|
-
import {
|
|
498
|
-
sanitizeMemoryContent
|
|
499
|
-
} from "./chunk-5GKPFL3S.js";
|
|
500
|
-
import {
|
|
501
|
-
expandTildePath
|
|
502
|
-
} from "./chunk-EYIEWJNI.js";
|
|
503
|
-
import {
|
|
504
|
-
readEnvVar,
|
|
505
|
-
resolveHomeDir
|
|
506
|
-
} from "./chunk-JUC24CTX.js";
|
|
507
|
-
import {
|
|
508
|
-
log
|
|
509
|
-
} from "./chunk-NU3CSQ4H.js";
|
|
510
|
-
import {
|
|
511
|
-
assertIsDirectoryNotSymlink,
|
|
512
|
-
assertRealpathInsideRoot
|
|
513
|
-
} from "./chunk-GCGJW34D.js";
|
|
514
|
-
import {
|
|
515
|
-
SecureStoreLockedError
|
|
516
|
-
} from "./chunk-J2HSAU72.js";
|
|
517
|
-
import {
|
|
518
|
-
parseFlexibleIsoTimestamp
|
|
519
|
-
} from "./chunk-P7FMDTKL.js";
|
|
520
|
-
import {
|
|
521
|
-
ALL_CATEGORY_DIRS,
|
|
522
|
-
ALL_CATEGORY_KEYS,
|
|
523
|
-
RECALL_FALLBACK_DIRS,
|
|
524
|
-
categoryDirName,
|
|
525
|
-
getCategoryDir
|
|
526
|
-
} from "./chunk-VS2IYZRU.js";
|
|
527
530
|
import {
|
|
528
531
|
MEMORY_ID_PATTERN,
|
|
529
532
|
buildHandleIndexForResults,
|
|
@@ -538,7 +541,7 @@ import {
|
|
|
538
541
|
} from "./chunk-PVGDJXVK.js";
|
|
539
542
|
|
|
540
543
|
// src/orchestrator.ts
|
|
541
|
-
import
|
|
544
|
+
import path15 from "path";
|
|
542
545
|
import { createHash as createHash8 } from "crypto";
|
|
543
546
|
|
|
544
547
|
// src/orchestration/tier-migration-coordinator.ts
|
|
@@ -2157,7 +2160,7 @@ var RecallRerankCoordinator = class _RecallRerankCoordinator {
|
|
|
2157
2160
|
nsMap = buildMemoryWorthCounterMap(memories);
|
|
2158
2161
|
this.memoryWorthCounterCache.set(ns, { at: nowMs, counters: nsMap });
|
|
2159
2162
|
}
|
|
2160
|
-
for (const [
|
|
2163
|
+
for (const [path30, c] of nsMap) counters.set(path30, c);
|
|
2161
2164
|
} catch (err) {
|
|
2162
2165
|
log.debug("memory-worth: failed to read namespace, skipping", {
|
|
2163
2166
|
namespace: ns,
|
|
@@ -2242,7 +2245,7 @@ var RecallRerankCoordinator = class _RecallRerankCoordinator {
|
|
|
2242
2245
|
namespaces,
|
|
2243
2246
|
{
|
|
2244
2247
|
readNamespaceMemories: async (ns) => (await this.getStorage(ns)).readAllMemories(),
|
|
2245
|
-
readMemoryFrontmatter: async (
|
|
2248
|
+
readMemoryFrontmatter: async (path30) => {
|
|
2246
2249
|
if (!fallbackReader) {
|
|
2247
2250
|
for (const ns of namespaces) {
|
|
2248
2251
|
try {
|
|
@@ -2253,7 +2256,7 @@ var RecallRerankCoordinator = class _RecallRerankCoordinator {
|
|
|
2253
2256
|
}
|
|
2254
2257
|
}
|
|
2255
2258
|
if (!fallbackReader) return null;
|
|
2256
|
-
const memory = await this.readQmdResultMemory(
|
|
2259
|
+
const memory = await this.readQmdResultMemory(path30, fallbackReader, namespaces);
|
|
2257
2260
|
return memory ? memory.frontmatter : null;
|
|
2258
2261
|
}
|
|
2259
2262
|
},
|
|
@@ -2556,257 +2559,6 @@ var RecallSectionCoordinator = class {
|
|
|
2556
2559
|
}
|
|
2557
2560
|
};
|
|
2558
2561
|
|
|
2559
|
-
// src/orchestration/qmd-result-resolver.ts
|
|
2560
|
-
import path4 from "path";
|
|
2561
|
-
function qmdCollectionPathParts(resultPath) {
|
|
2562
|
-
if (!resultPath || path4.isAbsolute(resultPath)) return null;
|
|
2563
|
-
const normalized = resultPath.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
2564
|
-
const slashIndex = normalized.indexOf("/");
|
|
2565
|
-
if (slashIndex <= 0 || slashIndex >= normalized.length - 1) return null;
|
|
2566
|
-
const collection = normalized.slice(0, slashIndex);
|
|
2567
|
-
if (/^\d{4}-\d{2}-\d{2}$/.test(collection)) return null;
|
|
2568
|
-
return {
|
|
2569
|
-
collection,
|
|
2570
|
-
relativePath: normalized.slice(slashIndex + 1)
|
|
2571
|
-
};
|
|
2572
|
-
}
|
|
2573
|
-
function qmdResultPathCandidates(storageDir, resultPath) {
|
|
2574
|
-
const candidates = /* @__PURE__ */ new Set();
|
|
2575
|
-
const storageRoot = path4.resolve(storageDir);
|
|
2576
|
-
const addCandidate = (candidate) => {
|
|
2577
|
-
const resolved = path4.resolve(candidate);
|
|
2578
|
-
if (isPathInsideStorageRoot(storageRoot, resolved)) {
|
|
2579
|
-
candidates.add(resolved);
|
|
2580
|
-
}
|
|
2581
|
-
};
|
|
2582
|
-
const addRelativeCandidates = (relativePath) => {
|
|
2583
|
-
const normalized = relativePath.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
2584
|
-
if (!normalized) return;
|
|
2585
|
-
addCandidate(path4.join(storageRoot, normalized));
|
|
2586
|
-
if (/^\d{4}-\d{2}-\d{2}\//.test(normalized)) {
|
|
2587
|
-
addCandidate(path4.join(storageRoot, "facts", normalized));
|
|
2588
|
-
}
|
|
2589
|
-
};
|
|
2590
|
-
if (path4.isAbsolute(resultPath)) {
|
|
2591
|
-
addCandidate(resultPath);
|
|
2592
|
-
} else {
|
|
2593
|
-
addRelativeCandidates(resultPath);
|
|
2594
|
-
}
|
|
2595
|
-
return [...candidates];
|
|
2596
|
-
}
|
|
2597
|
-
function storageDirOrNull(storage) {
|
|
2598
|
-
const dir = storage.dir;
|
|
2599
|
-
return typeof dir === "string" && dir.length > 0 ? dir : null;
|
|
2600
|
-
}
|
|
2601
|
-
var QmdResultResolver = class {
|
|
2602
|
-
getConfig;
|
|
2603
|
-
storageFor;
|
|
2604
|
-
storageDirNamespace;
|
|
2605
|
-
qmdCollectionNamespaceFromPrefix;
|
|
2606
|
-
namespaceFromPath;
|
|
2607
|
-
constructor(options) {
|
|
2608
|
-
this.getConfig = options.getConfig;
|
|
2609
|
-
this.storageFor = options.storageFor;
|
|
2610
|
-
this.storageDirNamespace = options.storageDirNamespace;
|
|
2611
|
-
this.qmdCollectionNamespaceFromPrefix = options.qmdCollectionNamespaceFromPrefix;
|
|
2612
|
-
this.namespaceFromPath = options.namespaceFromPath;
|
|
2613
|
-
}
|
|
2614
|
-
async readQmdResultMemory(resultPath, fallbackStorage, recallNamespaces = []) {
|
|
2615
|
-
const parts = qmdCollectionPathParts(resultPath);
|
|
2616
|
-
const fallbackStorageDir = storageDirOrNull(fallbackStorage);
|
|
2617
|
-
const config = this.getConfig();
|
|
2618
|
-
const coldCollection = config.qmdColdCollection ?? "openclaw-engram-cold";
|
|
2619
|
-
if (parts && parts.collection === coldCollection) {
|
|
2620
|
-
const storages = [];
|
|
2621
|
-
const seenStorageDirs = /* @__PURE__ */ new Set();
|
|
2622
|
-
const addStorage = (storage) => {
|
|
2623
|
-
const storageDir = storageDirOrNull(storage);
|
|
2624
|
-
const storageKey = storageDir ? path4.resolve(storageDir) : `storage-without-dir-${storages.length}`;
|
|
2625
|
-
if (seenStorageDirs.has(storageKey)) return;
|
|
2626
|
-
seenStorageDirs.add(storageKey);
|
|
2627
|
-
storages.push(storage);
|
|
2628
|
-
};
|
|
2629
|
-
const fallbackNamespace = fallbackStorageDir !== null ? this.storageDirNamespace(fallbackStorageDir) : config.defaultNamespace;
|
|
2630
|
-
if (recallNamespaces.length === 0 || !resolveNamespaceCapabilities(config).namespaces || recallNamespaces.includes(fallbackNamespace)) {
|
|
2631
|
-
addStorage(fallbackStorage);
|
|
2632
|
-
}
|
|
2633
|
-
if (recallNamespaces.length > 0) {
|
|
2634
|
-
for (const namespace of recallNamespaces) {
|
|
2635
|
-
try {
|
|
2636
|
-
addStorage(await this.storageFor(namespace));
|
|
2637
|
-
} catch (err) {
|
|
2638
|
-
log.debug("qmd cold result namespace storage lookup skipped", {
|
|
2639
|
-
path: resultPath,
|
|
2640
|
-
namespace,
|
|
2641
|
-
error: err.message
|
|
2642
|
-
});
|
|
2643
|
-
}
|
|
2644
|
-
}
|
|
2645
|
-
}
|
|
2646
|
-
for (const storage of storages) {
|
|
2647
|
-
const storageDir = storageDirOrNull(storage);
|
|
2648
|
-
if (!storageDir) {
|
|
2649
|
-
const memory = await storage.readMemoryByPath(resultPath);
|
|
2650
|
-
if (memory) return memory;
|
|
2651
|
-
continue;
|
|
2652
|
-
}
|
|
2653
|
-
try {
|
|
2654
|
-
const coldRoot = path4.join(storageDir, "cold");
|
|
2655
|
-
for (const candidate of qmdResultPathCandidates(
|
|
2656
|
-
coldRoot,
|
|
2657
|
-
parts.relativePath
|
|
2658
|
-
)) {
|
|
2659
|
-
const memory = await storage.readMemoryByPath(candidate);
|
|
2660
|
-
if (memory) return memory;
|
|
2661
|
-
}
|
|
2662
|
-
} catch (err) {
|
|
2663
|
-
if (err instanceof SecureStoreLockedError) throw err;
|
|
2664
|
-
log.debug("qmd cold result path lookup failed open", {
|
|
2665
|
-
path: resultPath,
|
|
2666
|
-
collection: coldCollection,
|
|
2667
|
-
error: err.message
|
|
2668
|
-
});
|
|
2669
|
-
}
|
|
2670
|
-
}
|
|
2671
|
-
return null;
|
|
2672
|
-
}
|
|
2673
|
-
const collectionNamespace = parts ? this.qmdCollectionNamespaceFromPrefix(parts.collection) : null;
|
|
2674
|
-
if (parts && collectionNamespace) {
|
|
2675
|
-
try {
|
|
2676
|
-
const collectionStorage = await this.storageFor(collectionNamespace);
|
|
2677
|
-
for (const candidate of qmdResultPathCandidates(
|
|
2678
|
-
collectionStorage.dir,
|
|
2679
|
-
parts.relativePath
|
|
2680
|
-
)) {
|
|
2681
|
-
const memory = await collectionStorage.readMemoryByPath(candidate);
|
|
2682
|
-
if (memory) return memory;
|
|
2683
|
-
}
|
|
2684
|
-
return null;
|
|
2685
|
-
} catch (err) {
|
|
2686
|
-
if (err instanceof SecureStoreLockedError) throw err;
|
|
2687
|
-
log.debug("qmd result namespace path lookup failed open", {
|
|
2688
|
-
path: resultPath,
|
|
2689
|
-
namespace: collectionNamespace,
|
|
2690
|
-
error: err.message
|
|
2691
|
-
});
|
|
2692
|
-
return null;
|
|
2693
|
-
}
|
|
2694
|
-
}
|
|
2695
|
-
if (path4.isAbsolute(resultPath)) {
|
|
2696
|
-
if (!fallbackStorageDir) {
|
|
2697
|
-
return await fallbackStorage.readMemoryByPath(resultPath);
|
|
2698
|
-
}
|
|
2699
|
-
const ownerStorage = await this.storageForAbsoluteQmdResultPath(
|
|
2700
|
-
resultPath,
|
|
2701
|
-
fallbackStorage,
|
|
2702
|
-
recallNamespaces
|
|
2703
|
-
);
|
|
2704
|
-
if (!ownerStorage) return null;
|
|
2705
|
-
for (const candidate of qmdResultPathCandidates(
|
|
2706
|
-
ownerStorage.dir,
|
|
2707
|
-
resultPath
|
|
2708
|
-
)) {
|
|
2709
|
-
const memory = await ownerStorage.storage.readMemoryByPath(candidate);
|
|
2710
|
-
if (memory) return memory;
|
|
2711
|
-
}
|
|
2712
|
-
return null;
|
|
2713
|
-
}
|
|
2714
|
-
if (!fallbackStorageDir) {
|
|
2715
|
-
return await fallbackStorage.readMemoryByPath(resultPath);
|
|
2716
|
-
}
|
|
2717
|
-
for (const candidate of qmdResultPathCandidates(
|
|
2718
|
-
fallbackStorageDir,
|
|
2719
|
-
resultPath
|
|
2720
|
-
)) {
|
|
2721
|
-
const memory = await fallbackStorage.readMemoryByPath(candidate);
|
|
2722
|
-
if (memory) return memory;
|
|
2723
|
-
}
|
|
2724
|
-
return null;
|
|
2725
|
-
}
|
|
2726
|
-
async resolveColdQmdResultForRecall(result, fallbackStorage, recallNamespaces = []) {
|
|
2727
|
-
const memory = await this.readQmdResultMemory(
|
|
2728
|
-
result.path,
|
|
2729
|
-
fallbackStorage,
|
|
2730
|
-
recallNamespaces
|
|
2731
|
-
);
|
|
2732
|
-
if (!memory) return null;
|
|
2733
|
-
let ownerNamespace = null;
|
|
2734
|
-
if (path4.isAbsolute(memory.path)) {
|
|
2735
|
-
const ownerStorage = await this.storageForAbsoluteQmdResultPath(
|
|
2736
|
-
memory.path,
|
|
2737
|
-
fallbackStorage,
|
|
2738
|
-
recallNamespaces
|
|
2739
|
-
);
|
|
2740
|
-
ownerNamespace = ownerStorage?.namespace ?? null;
|
|
2741
|
-
if (!ownerNamespace && resolveNamespaceCapabilities(this.getConfig()).namespaces) return null;
|
|
2742
|
-
}
|
|
2743
|
-
ownerNamespace ??= this.namespaceFromPath(memory.path);
|
|
2744
|
-
if (recallNamespaces.length > 0 && !recallNamespaces.includes(ownerNamespace)) {
|
|
2745
|
-
return null;
|
|
2746
|
-
}
|
|
2747
|
-
return {
|
|
2748
|
-
namespace: ownerNamespace,
|
|
2749
|
-
result: {
|
|
2750
|
-
...result,
|
|
2751
|
-
docid: result.docid || memory.frontmatter.id,
|
|
2752
|
-
path: memory.path,
|
|
2753
|
-
snippet: result.snippet || memory.content.slice(0, 400)
|
|
2754
|
-
}
|
|
2755
|
-
};
|
|
2756
|
-
}
|
|
2757
|
-
async storageForAbsoluteQmdResultPath(resultPath, fallbackStorage, recallNamespaces = []) {
|
|
2758
|
-
const resolvedPath = path4.resolve(resultPath);
|
|
2759
|
-
const config = this.getConfig();
|
|
2760
|
-
const memoryRoot = path4.resolve(config.memoryDir);
|
|
2761
|
-
const namespacesRoot = path4.join(memoryRoot, "namespaces");
|
|
2762
|
-
const fallbackStorageDir = storageDirOrNull(fallbackStorage);
|
|
2763
|
-
const matches = [];
|
|
2764
|
-
const seenDirs = /* @__PURE__ */ new Set();
|
|
2765
|
-
const maybeAddStorage = (storage, namespace) => {
|
|
2766
|
-
const storageDir = storageDirOrNull(storage);
|
|
2767
|
-
if (!storageDir) return;
|
|
2768
|
-
const candidateRoot = path4.resolve(storageDir);
|
|
2769
|
-
if (seenDirs.has(candidateRoot)) return;
|
|
2770
|
-
if (!isPathInsideStorageRoot(candidateRoot, resolvedPath)) return;
|
|
2771
|
-
if (candidateRoot === memoryRoot && isPathInsideStorageRoot(namespacesRoot, resolvedPath)) {
|
|
2772
|
-
return;
|
|
2773
|
-
}
|
|
2774
|
-
seenDirs.add(candidateRoot);
|
|
2775
|
-
matches.push({ storage, dir: candidateRoot, namespace });
|
|
2776
|
-
};
|
|
2777
|
-
const fallbackNamespace = fallbackStorageDir !== null ? this.storageDirNamespace(fallbackStorageDir) : config.defaultNamespace;
|
|
2778
|
-
maybeAddStorage(fallbackStorage, fallbackNamespace);
|
|
2779
|
-
const candidateNamespaces = /* @__PURE__ */ new Set();
|
|
2780
|
-
candidateNamespaces.add(config.defaultNamespace);
|
|
2781
|
-
candidateNamespaces.add(config.sharedNamespace);
|
|
2782
|
-
for (const ns of recallNamespaces) {
|
|
2783
|
-
candidateNamespaces.add(ns);
|
|
2784
|
-
}
|
|
2785
|
-
if (isPathInsideStorageRoot(namespacesRoot, resolvedPath)) {
|
|
2786
|
-
const relativeToNamespaces = path4.relative(namespacesRoot, resolvedPath);
|
|
2787
|
-
const [namespaceSegment] = relativeToNamespaces.split(/[\\/]/);
|
|
2788
|
-
if (namespaceSegment) {
|
|
2789
|
-
candidateNamespaces.add(
|
|
2790
|
-
namespaceIdentityFromToken(namespaceSegment) ?? namespaceSegment
|
|
2791
|
-
);
|
|
2792
|
-
}
|
|
2793
|
-
}
|
|
2794
|
-
for (const policy of config.namespacePolicies ?? []) {
|
|
2795
|
-
candidateNamespaces.add(policy.name);
|
|
2796
|
-
}
|
|
2797
|
-
for (const ns of candidateNamespaces) {
|
|
2798
|
-
if (!ns) continue;
|
|
2799
|
-
try {
|
|
2800
|
-
maybeAddStorage(await this.storageFor(ns), ns);
|
|
2801
|
-
} catch {
|
|
2802
|
-
continue;
|
|
2803
|
-
}
|
|
2804
|
-
}
|
|
2805
|
-
matches.sort((a, b) => b.dir.length - a.dir.length);
|
|
2806
|
-
return matches[0] ?? null;
|
|
2807
|
-
}
|
|
2808
|
-
};
|
|
2809
|
-
|
|
2810
2562
|
// src/orchestration/contradiction-linking-coordinator.ts
|
|
2811
2563
|
var ContradictionLinkingCoordinator = class {
|
|
2812
2564
|
getConfig;
|
|
@@ -2983,7 +2735,7 @@ import { createHash as createHash3 } from "crypto";
|
|
|
2983
2735
|
// src/orchestration/orchestrator-helpers.ts
|
|
2984
2736
|
import { createHash as createHash2 } from "crypto";
|
|
2985
2737
|
import os from "os";
|
|
2986
|
-
import
|
|
2738
|
+
import path4 from "path";
|
|
2987
2739
|
var BulkImportBatchPartialFailureError = class extends Error {
|
|
2988
2740
|
partialResult;
|
|
2989
2741
|
originalError;
|
|
@@ -3138,7 +2890,7 @@ async function qmdStartupCollectionCheckWithTimeout(promise, controller, label)
|
|
|
3138
2890
|
return await Promise.race([checkedPromise, timeoutPromise]);
|
|
3139
2891
|
}
|
|
3140
2892
|
function defaultWorkspaceDir() {
|
|
3141
|
-
return
|
|
2893
|
+
return path4.join(os.homedir(), ".openclaw", "workspace");
|
|
3142
2894
|
}
|
|
3143
2895
|
function sanitizeSessionKeyForFilename(sessionKey) {
|
|
3144
2896
|
const readable = sessionKey.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
@@ -3499,7 +3251,7 @@ function buildMemoryPathById(allMemsForGraph, storageDir) {
|
|
|
3499
3251
|
for (const mem of allMemsForGraph ?? []) {
|
|
3500
3252
|
const id = mem.frontmatter.id;
|
|
3501
3253
|
if (!id) continue;
|
|
3502
|
-
pathById.set(id,
|
|
3254
|
+
pathById.set(id, path4.relative(storageDir, mem.path));
|
|
3503
3255
|
}
|
|
3504
3256
|
return pathById;
|
|
3505
3257
|
}
|
|
@@ -3507,7 +3259,7 @@ function appendMemoryToGraphContext(options) {
|
|
|
3507
3259
|
if (!Array.isArray(options.allMemsForGraph)) return;
|
|
3508
3260
|
const nowIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
3509
3261
|
options.allMemsForGraph.push({
|
|
3510
|
-
path:
|
|
3262
|
+
path: path4.join(options.storageDir, options.memoryRelPath),
|
|
3511
3263
|
content: options.content,
|
|
3512
3264
|
frontmatter: {
|
|
3513
3265
|
id: options.memoryId,
|
|
@@ -3527,16 +3279,16 @@ function resolvePersistedMemoryRelativePath(options) {
|
|
|
3527
3279
|
const persisted = options.pathById.get(options.memoryId);
|
|
3528
3280
|
if (persisted) return persisted;
|
|
3529
3281
|
if (options.category === "correction") {
|
|
3530
|
-
return
|
|
3282
|
+
return path4.join("corrections", `${options.memoryId}.md`);
|
|
3531
3283
|
}
|
|
3532
3284
|
const subtree = categoryDirName(options.category);
|
|
3533
3285
|
const idParts = options.memoryId.split("-");
|
|
3534
3286
|
const maybeTimestamp = Number(idParts[1]);
|
|
3535
3287
|
if (Number.isFinite(maybeTimestamp) && maybeTimestamp > 0) {
|
|
3536
3288
|
const day = new Date(maybeTimestamp).toISOString().slice(0, 10);
|
|
3537
|
-
return
|
|
3289
|
+
return path4.join(subtree, day, `${options.memoryId}.md`);
|
|
3538
3290
|
}
|
|
3539
|
-
return
|
|
3291
|
+
return path4.join(subtree, `${options.memoryId}.md`);
|
|
3540
3292
|
}
|
|
3541
3293
|
|
|
3542
3294
|
// src/orchestration/extraction-run.ts
|
|
@@ -4024,7 +3776,7 @@ ${normalized}`).digest("hex");
|
|
|
4024
3776
|
};
|
|
4025
3777
|
|
|
4026
3778
|
// src/orchestration/consolidation-run.ts
|
|
4027
|
-
import
|
|
3779
|
+
import path5 from "path";
|
|
4028
3780
|
import { mkdir as mkdir2, readFile, writeFile as writeFile2 } from "fs/promises";
|
|
4029
3781
|
var ConsolidationRunCoordinator = class {
|
|
4030
3782
|
constructor(deps) {
|
|
@@ -4252,7 +4004,7 @@ var ConsolidationRunCoordinator = class {
|
|
|
4252
4004
|
}
|
|
4253
4005
|
if (resolveConsolidationCapabilities(config).semanticConsolidation) {
|
|
4254
4006
|
try {
|
|
4255
|
-
const stateFilePath =
|
|
4007
|
+
const stateFilePath = path5.join(
|
|
4256
4008
|
config.memoryDir,
|
|
4257
4009
|
"state",
|
|
4258
4010
|
"semantic-consolidation-last-run.json"
|
|
@@ -4300,7 +4052,7 @@ var ConsolidationRunCoordinator = class {
|
|
|
4300
4052
|
);
|
|
4301
4053
|
}
|
|
4302
4054
|
if (semResult.errors === 0 || semResult.memoriesArchived > 0) {
|
|
4303
|
-
const stateDir =
|
|
4055
|
+
const stateDir = path5.join(config.memoryDir, "state");
|
|
4304
4056
|
await mkdir2(stateDir, { recursive: true });
|
|
4305
4057
|
await writeFile2(
|
|
4306
4058
|
stateFilePath,
|
|
@@ -5985,12 +5737,12 @@ var ExtractionPersistCoordinator = class {
|
|
|
5985
5737
|
// src/orchestration/recall-internal.ts
|
|
5986
5738
|
import { createHash as createHash5 } from "crypto";
|
|
5987
5739
|
import { readFile as readFile2, stat, unlink } from "fs/promises";
|
|
5988
|
-
import
|
|
5740
|
+
import path7 from "path";
|
|
5989
5741
|
|
|
5990
5742
|
// src/orchestration/graph-recall-coordinator.ts
|
|
5991
5743
|
import { createHash as createHash4 } from "crypto";
|
|
5992
5744
|
import { mkdir as mkdir3, writeFile as writeFile3 } from "fs/promises";
|
|
5993
|
-
import
|
|
5745
|
+
import path6 from "path";
|
|
5994
5746
|
function mergeGraphExpandedResults(primary, expanded) {
|
|
5995
5747
|
const mergedByPath = /* @__PURE__ */ new Map();
|
|
5996
5748
|
for (const item of [...primary, ...expanded]) {
|
|
@@ -6006,11 +5758,11 @@ function mergeGraphExpandedResults(primary, expanded) {
|
|
|
6006
5758
|
return Array.from(mergedByPath.values());
|
|
6007
5759
|
}
|
|
6008
5760
|
function graphPathRelativeToStorage(storageDir, candidatePath) {
|
|
6009
|
-
const absolutePath =
|
|
6010
|
-
const rel =
|
|
5761
|
+
const absolutePath = path6.isAbsolute(candidatePath) ? candidatePath : path6.resolve(storageDir, candidatePath);
|
|
5762
|
+
const rel = path6.relative(storageDir, absolutePath);
|
|
6011
5763
|
if (!rel || rel === ".") return null;
|
|
6012
5764
|
if (rel.startsWith("..")) return null;
|
|
6013
|
-
return rel.split(
|
|
5765
|
+
return rel.split(path6.sep).join("/");
|
|
6014
5766
|
}
|
|
6015
5767
|
function normalizeGraphActivationScore(score) {
|
|
6016
5768
|
const bounded = Number.isFinite(score) && score > 0 ? score : 0;
|
|
@@ -6081,7 +5833,7 @@ var GraphRecallCoordinator = class {
|
|
|
6081
5833
|
resolvedPath = resolvedCold.result.path;
|
|
6082
5834
|
resolvedResult = resolvedCold.result;
|
|
6083
5835
|
}
|
|
6084
|
-
if (!
|
|
5836
|
+
if (!path6.isAbsolute(resolvedPath)) {
|
|
6085
5837
|
resolvedAmbiguousSeeds.set(result.path, null);
|
|
6086
5838
|
return null;
|
|
6087
5839
|
}
|
|
@@ -6106,7 +5858,7 @@ var GraphRecallCoordinator = class {
|
|
|
6106
5858
|
}
|
|
6107
5859
|
continue;
|
|
6108
5860
|
}
|
|
6109
|
-
if (
|
|
5861
|
+
if (path6.isAbsolute(result.path)) {
|
|
6110
5862
|
const resolved = await resolveAmbiguousSeedOwner(result, null);
|
|
6111
5863
|
if (resolved) {
|
|
6112
5864
|
addResultForNamespace(resolved.namespace, resolved.result);
|
|
@@ -6149,7 +5901,7 @@ var GraphRecallCoordinator = class {
|
|
|
6149
5901
|
0
|
|
6150
5902
|
);
|
|
6151
5903
|
seedPaths.push(
|
|
6152
|
-
...seedRelativePaths.map((rel) =>
|
|
5904
|
+
...seedRelativePaths.map((rel) => path6.join(storage.dir, rel))
|
|
6153
5905
|
);
|
|
6154
5906
|
const seedSet = new Set(seedRelativePaths);
|
|
6155
5907
|
const expanded = await this.graphIndexFor(storage).spreadingActivation(
|
|
@@ -6165,7 +5917,7 @@ var GraphRecallCoordinator = class {
|
|
|
6165
5917
|
for (const candidate of expanded.slice(0, perNamespaceExpandedCap)) {
|
|
6166
5918
|
if (deadlineExpired()) break;
|
|
6167
5919
|
if (seedSet.has(candidate.path)) continue;
|
|
6168
|
-
const memoryPath =
|
|
5920
|
+
const memoryPath = path6.resolve(storage.dir, candidate.path);
|
|
6169
5921
|
const memory = await storage.readMemoryByPath(memoryPath);
|
|
6170
5922
|
if (deadlineExpired()) break;
|
|
6171
5923
|
if (!memory) continue;
|
|
@@ -6190,7 +5942,7 @@ var GraphRecallCoordinator = class {
|
|
|
6190
5942
|
path: memory.path,
|
|
6191
5943
|
score,
|
|
6192
5944
|
namespace,
|
|
6193
|
-
seed:
|
|
5945
|
+
seed: path6.resolve(storage.dir, candidate.seed),
|
|
6194
5946
|
hopDepth: candidate.hopDepth,
|
|
6195
5947
|
decayedWeight: candidate.decayedWeight,
|
|
6196
5948
|
graphType: candidate.graphType,
|
|
@@ -6211,12 +5963,12 @@ var GraphRecallCoordinator = class {
|
|
|
6211
5963
|
}
|
|
6212
5964
|
async recordLastGraphRecallSnapshot(options) {
|
|
6213
5965
|
try {
|
|
6214
|
-
const snapshotPath =
|
|
5966
|
+
const snapshotPath = path6.join(
|
|
6215
5967
|
options.storage.dir,
|
|
6216
5968
|
"state",
|
|
6217
5969
|
"last_graph_recall.json"
|
|
6218
5970
|
);
|
|
6219
|
-
await mkdir3(
|
|
5971
|
+
await mkdir3(path6.dirname(snapshotPath), { recursive: true });
|
|
6220
5972
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
6221
5973
|
const totalSeedCount = options.seedPaths.length;
|
|
6222
5974
|
const totalExpandedCount = options.expandedPaths.length;
|
|
@@ -6549,7 +6301,7 @@ var RecallInternalCoordinator = class {
|
|
|
6549
6301
|
const graphExpandedResultPaths = /* @__PURE__ */ new Set();
|
|
6550
6302
|
const graphSourceLabelsForPath = (resultPath) => {
|
|
6551
6303
|
const labels = [];
|
|
6552
|
-
const normalizedPath = resultPath.split(
|
|
6304
|
+
const normalizedPath = resultPath.split(path7.sep).join("/");
|
|
6553
6305
|
const isEntityPath = normalizedPath.startsWith("entities/") || normalizedPath.includes("/entities/");
|
|
6554
6306
|
if (graphBaselinePaths.has(resultPath)) labels.push("baseline");
|
|
6555
6307
|
if (graphExpandedResultPaths.has(resultPath))
|
|
@@ -6699,7 +6451,7 @@ var RecallInternalCoordinator = class {
|
|
|
6699
6451
|
profileStorageNamespaces.map((namespace) => this.deps.storageRouter.storageFor(namespace))
|
|
6700
6452
|
);
|
|
6701
6453
|
const emptyProfileStorage = new Proxy(
|
|
6702
|
-
{ dir:
|
|
6454
|
+
{ dir: path7.join(this.deps.config.memoryDir, ".empty-scope-profile") },
|
|
6703
6455
|
{
|
|
6704
6456
|
get(target, prop) {
|
|
6705
6457
|
if (prop in target) return target[prop];
|
|
@@ -8175,11 +7927,11 @@ ${formatted}`;
|
|
|
8175
7927
|
if (!resolveRecallAuxiliaryCapabilities(this.deps.config).compactionReset) return null;
|
|
8176
7928
|
const workspaceDir = compactionWorkspaceDir || this.deps.config.workspaceDir || defaultWorkspaceDir();
|
|
8177
7929
|
const safeSessionKey = sanitizeSessionKeyForFilename(effectiveSessionKey);
|
|
8178
|
-
const signalPath =
|
|
7930
|
+
const signalPath = path7.join(
|
|
8179
7931
|
workspaceDir,
|
|
8180
7932
|
`.compaction-reset-signal-${safeSessionKey}`
|
|
8181
7933
|
);
|
|
8182
|
-
const bootPath =
|
|
7934
|
+
const bootPath = path7.join(workspaceDir, "BOOT.md");
|
|
8183
7935
|
try {
|
|
8184
7936
|
const signalStat = await stat(signalPath).catch(() => null);
|
|
8185
7937
|
if (!signalStat) return null;
|
|
@@ -10194,7 +9946,7 @@ _Context: ${topQuestion.context}_`
|
|
|
10194
9946
|
|
|
10195
9947
|
// src/orchestration/recall-search-pipeline.ts
|
|
10196
9948
|
import { createHash as createHash6 } from "crypto";
|
|
10197
|
-
import
|
|
9949
|
+
import path8 from "path";
|
|
10198
9950
|
|
|
10199
9951
|
// src/recall/archive-scoring.ts
|
|
10200
9952
|
import os2 from "os";
|
|
@@ -10796,7 +10548,7 @@ var RecallSearchPipelineCoordinator = class {
|
|
|
10796
10548
|
if (hits.length === 0) return [];
|
|
10797
10549
|
const results = [];
|
|
10798
10550
|
for (const hit of hits) {
|
|
10799
|
-
const fullPath =
|
|
10551
|
+
const fullPath = path8.isAbsolute(hit.path) ? hit.path : path8.join(this.deps.config.memoryDir, hit.path);
|
|
10800
10552
|
const memory = await this.deps.storage.readMemoryByPath(fullPath);
|
|
10801
10553
|
if (!memory) continue;
|
|
10802
10554
|
results.push({
|
|
@@ -10993,7 +10745,7 @@ var RecallSearchPipelineCoordinator = class {
|
|
|
10993
10745
|
const storage = await this.deps.storageRouter.storageFor(namespace);
|
|
10994
10746
|
const storageDir = typeof storage.dir === "string" && storage.dir ? storage.dir : null;
|
|
10995
10747
|
if (!storageDir) continue;
|
|
10996
|
-
const recallRoot =
|
|
10748
|
+
const recallRoot = path8.resolve(storageDir);
|
|
10997
10749
|
if (seenRecallRoots.has(recallRoot)) continue;
|
|
10998
10750
|
seenRecallRoots.add(recallRoot);
|
|
10999
10751
|
recallRoots.push(recallRoot);
|
|
@@ -11017,8 +10769,8 @@ var RecallSearchPipelineCoordinator = class {
|
|
|
11017
10769
|
if (resolvedCold) scopedResults.push(resolvedCold.result);
|
|
11018
10770
|
continue;
|
|
11019
10771
|
}
|
|
11020
|
-
if (
|
|
11021
|
-
const resolvedPath =
|
|
10772
|
+
if (path8.isAbsolute(result.path)) {
|
|
10773
|
+
const resolvedPath = path8.resolve(result.path);
|
|
11022
10774
|
if (recallRoots.some(
|
|
11023
10775
|
(recallRoot) => isPathInsideStorageRoot(recallRoot, resolvedPath)
|
|
11024
10776
|
)) {
|
|
@@ -12041,7 +11793,7 @@ var TurnIngestionCoordinator = class {
|
|
|
12041
11793
|
|
|
12042
11794
|
// src/orchestration/recall-introspection.ts
|
|
12043
11795
|
import { mkdir as mkdir5, readFile as readFile4, writeFile as writeFile5 } from "fs/promises";
|
|
12044
|
-
import
|
|
11796
|
+
import path10 from "path";
|
|
12045
11797
|
|
|
12046
11798
|
// src/taxonomy/default-taxonomy.ts
|
|
12047
11799
|
var DEFAULT_TAXONOMY = {
|
|
@@ -12164,7 +11916,7 @@ function generateResolverDocument(taxonomy) {
|
|
|
12164
11916
|
|
|
12165
11917
|
// src/taxonomy/taxonomy-loader.ts
|
|
12166
11918
|
import { readFile as readFile3, mkdir as mkdir4, writeFile as writeFile4 } from "fs/promises";
|
|
12167
|
-
import
|
|
11919
|
+
import path9 from "path";
|
|
12168
11920
|
var TAXONOMY_DIR = ".taxonomy";
|
|
12169
11921
|
var TAXONOMY_FILE = "taxonomy.json";
|
|
12170
11922
|
var MAX_SLUG_LENGTH = 32;
|
|
@@ -12262,7 +12014,7 @@ function validateTaxonomy(taxonomy) {
|
|
|
12262
12014
|
}
|
|
12263
12015
|
}
|
|
12264
12016
|
async function loadTaxonomy(memoryDir) {
|
|
12265
|
-
const taxonomyPath =
|
|
12017
|
+
const taxonomyPath = path9.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);
|
|
12266
12018
|
let raw;
|
|
12267
12019
|
try {
|
|
12268
12020
|
raw = await readFile3(taxonomyPath, "utf-8");
|
|
@@ -12312,16 +12064,16 @@ async function loadTaxonomy(memoryDir) {
|
|
|
12312
12064
|
}
|
|
12313
12065
|
async function saveTaxonomy(memoryDir, taxonomy) {
|
|
12314
12066
|
validateTaxonomy(taxonomy);
|
|
12315
|
-
const dir =
|
|
12067
|
+
const dir = path9.join(memoryDir, TAXONOMY_DIR);
|
|
12316
12068
|
await mkdir4(dir, { recursive: true });
|
|
12317
|
-
const filePath =
|
|
12069
|
+
const filePath = path9.join(dir, TAXONOMY_FILE);
|
|
12318
12070
|
await writeFile4(filePath, JSON.stringify(taxonomy, null, 2) + "\n", "utf-8");
|
|
12319
12071
|
}
|
|
12320
12072
|
function getTaxonomyDir(memoryDir) {
|
|
12321
|
-
return
|
|
12073
|
+
return path9.join(memoryDir, TAXONOMY_DIR);
|
|
12322
12074
|
}
|
|
12323
12075
|
function getTaxonomyFilePath(memoryDir) {
|
|
12324
|
-
return
|
|
12076
|
+
return path9.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);
|
|
12325
12077
|
}
|
|
12326
12078
|
|
|
12327
12079
|
// src/orchestration/recall-introspection.ts
|
|
@@ -12345,7 +12097,7 @@ var RecallIntrospectionCoordinator = class {
|
|
|
12345
12097
|
}
|
|
12346
12098
|
async getLastGraphRecallSnapshot(namespace) {
|
|
12347
12099
|
const storage = await this.deps.getStorage(namespace);
|
|
12348
|
-
const snapshotPath =
|
|
12100
|
+
const snapshotPath = path10.join(
|
|
12349
12101
|
storage.dir,
|
|
12350
12102
|
"state",
|
|
12351
12103
|
"last_graph_recall.json"
|
|
@@ -12384,7 +12136,7 @@ var RecallIntrospectionCoordinator = class {
|
|
|
12384
12136
|
}
|
|
12385
12137
|
async getLastIntentSnapshot(namespace) {
|
|
12386
12138
|
const storage = await this.deps.getStorage(namespace);
|
|
12387
|
-
const snapshotPath =
|
|
12139
|
+
const snapshotPath = path10.join(storage.dir, "state", "last_intent.json");
|
|
12388
12140
|
try {
|
|
12389
12141
|
const raw = await readFile4(snapshotPath, "utf-8");
|
|
12390
12142
|
const parsed = JSON.parse(raw);
|
|
@@ -12417,7 +12169,7 @@ var RecallIntrospectionCoordinator = class {
|
|
|
12417
12169
|
}
|
|
12418
12170
|
async getLastQmdRecallSnapshot(namespace) {
|
|
12419
12171
|
const storage = await this.deps.getStorage(namespace);
|
|
12420
|
-
const snapshotPath =
|
|
12172
|
+
const snapshotPath = path10.join(
|
|
12421
12173
|
storage.dir,
|
|
12422
12174
|
"state",
|
|
12423
12175
|
"last_qmd_recall.json"
|
|
@@ -12703,12 +12455,12 @@ var RecallIntrospectionCoordinator = class {
|
|
|
12703
12455
|
}
|
|
12704
12456
|
async recordLastIntentSnapshot(options) {
|
|
12705
12457
|
try {
|
|
12706
|
-
const snapshotPath =
|
|
12458
|
+
const snapshotPath = path10.join(
|
|
12707
12459
|
options.storage.dir,
|
|
12708
12460
|
"state",
|
|
12709
12461
|
"last_intent.json"
|
|
12710
12462
|
);
|
|
12711
|
-
await mkdir5(
|
|
12463
|
+
await mkdir5(path10.dirname(snapshotPath), { recursive: true });
|
|
12712
12464
|
await writeFile5(
|
|
12713
12465
|
snapshotPath,
|
|
12714
12466
|
JSON.stringify(options.snapshot, null, 2),
|
|
@@ -12720,12 +12472,12 @@ var RecallIntrospectionCoordinator = class {
|
|
|
12720
12472
|
}
|
|
12721
12473
|
async recordLastQmdRecallSnapshot(options) {
|
|
12722
12474
|
try {
|
|
12723
|
-
const snapshotPath =
|
|
12475
|
+
const snapshotPath = path10.join(
|
|
12724
12476
|
options.storage.dir,
|
|
12725
12477
|
"state",
|
|
12726
12478
|
"last_qmd_recall.json"
|
|
12727
12479
|
);
|
|
12728
|
-
await mkdir5(
|
|
12480
|
+
await mkdir5(path10.dirname(snapshotPath), { recursive: true });
|
|
12729
12481
|
await writeFile5(
|
|
12730
12482
|
snapshotPath,
|
|
12731
12483
|
JSON.stringify(options.snapshot, null, 2),
|
|
@@ -12740,8 +12492,8 @@ var RecallIntrospectionCoordinator = class {
|
|
|
12740
12492
|
const stateDir = await this.deps.resolveStateDirForNamespace(
|
|
12741
12493
|
options.namespace
|
|
12742
12494
|
);
|
|
12743
|
-
const snapshotPath =
|
|
12744
|
-
await mkdir5(
|
|
12495
|
+
const snapshotPath = path10.join(stateDir, "last_intent.json");
|
|
12496
|
+
await mkdir5(path10.dirname(snapshotPath), { recursive: true });
|
|
12745
12497
|
await writeFile5(
|
|
12746
12498
|
snapshotPath,
|
|
12747
12499
|
JSON.stringify(options.snapshot, null, 2),
|
|
@@ -12755,7 +12507,7 @@ var RecallIntrospectionCoordinator = class {
|
|
|
12755
12507
|
|
|
12756
12508
|
// src/orchestration/orchestrator-init.ts
|
|
12757
12509
|
import { readdir as readdir2, stat as stat2, unlink as unlink2 } from "fs/promises";
|
|
12758
|
-
import
|
|
12510
|
+
import path11 from "path";
|
|
12759
12511
|
var OrchestratorInitCoordinator = class {
|
|
12760
12512
|
constructor(deps) {
|
|
12761
12513
|
this.deps = deps;
|
|
@@ -12845,7 +12597,7 @@ var OrchestratorInitCoordinator = class {
|
|
|
12845
12597
|
const files = await readdir2(wsDir).catch(() => []);
|
|
12846
12598
|
for (const f of files) {
|
|
12847
12599
|
if (!f.startsWith(".compaction-reset-signal-")) continue;
|
|
12848
|
-
const fp =
|
|
12600
|
+
const fp = path11.join(wsDir, f);
|
|
12849
12601
|
const s = await stat2(fp).catch(() => null);
|
|
12850
12602
|
if (s && Date.now() - s.mtimeMs >= COMPACTION_SIGNAL_MAX_AGE_MS) {
|
|
12851
12603
|
await unlink2(fp).catch(() => {
|
|
@@ -13194,7 +12946,7 @@ var OrchestratorInitCoordinator = class {
|
|
|
13194
12946
|
};
|
|
13195
12947
|
|
|
13196
12948
|
// src/orchestration/persistence-index.ts
|
|
13197
|
-
import
|
|
12949
|
+
import path12 from "path";
|
|
13198
12950
|
var PersistenceIndexCoordinator = class {
|
|
13199
12951
|
constructor(deps) {
|
|
13200
12952
|
this.deps = deps;
|
|
@@ -13336,7 +13088,7 @@ var PersistenceIndexCoordinator = class {
|
|
|
13336
13088
|
const allMems = allMemsForGraph ?? [];
|
|
13337
13089
|
for (const m of allMems) {
|
|
13338
13090
|
if (m.frontmatter.entityRef === entityRef) {
|
|
13339
|
-
const rel =
|
|
13091
|
+
const rel = path12.relative(storage.dir, m.path);
|
|
13340
13092
|
if (rel !== memoryRelPath) entitySiblings.push(rel);
|
|
13341
13093
|
}
|
|
13342
13094
|
}
|
|
@@ -13467,7 +13219,7 @@ var PersistenceIndexCoordinator = class {
|
|
|
13467
13219
|
|
|
13468
13220
|
// src/orchestration/workspace-ops.ts
|
|
13469
13221
|
import { lstat, mkdir as mkdir6, readFile as readFile5, readdir as readdir3, realpath, writeFile as writeFile6 } from "fs/promises";
|
|
13470
|
-
import
|
|
13222
|
+
import path13 from "path";
|
|
13471
13223
|
|
|
13472
13224
|
// src/maintenance/pattern-reinforcement.ts
|
|
13473
13225
|
function patternReinforcementKey(content) {
|
|
@@ -14265,15 +14017,15 @@ var WorkspaceOpsCoordinator = class {
|
|
|
14265
14017
|
this.deps.lastFileHygieneRunAtMs = now;
|
|
14266
14018
|
if (hygiene.rotateEnabled) {
|
|
14267
14019
|
for (const rel of hygiene.rotatePaths) {
|
|
14268
|
-
const abs =
|
|
14020
|
+
const abs = path13.isAbsolute(rel) ? rel : path13.join(this.deps.config.workspaceDir, rel);
|
|
14269
14021
|
try {
|
|
14270
14022
|
const raw = await readFile5(abs, "utf-8");
|
|
14271
14023
|
if (raw.length > hygiene.rotateMaxBytes) {
|
|
14272
|
-
const archiveDir =
|
|
14024
|
+
const archiveDir = path13.join(
|
|
14273
14025
|
this.deps.config.workspaceDir,
|
|
14274
14026
|
hygiene.archiveDir
|
|
14275
14027
|
);
|
|
14276
|
-
const base =
|
|
14028
|
+
const base = path13.basename(abs);
|
|
14277
14029
|
const prefix = base.toUpperCase().replace(/\.MD$/i, "").replace(/[^A-Z0-9]+/g, "-") || "FILE";
|
|
14278
14030
|
const { newContent } = await rotateMarkdownFileToArchive({
|
|
14279
14031
|
filePath: abs,
|
|
@@ -14298,8 +14050,8 @@ var WorkspaceOpsCoordinator = class {
|
|
|
14298
14050
|
log.warn(w.message);
|
|
14299
14051
|
}
|
|
14300
14052
|
if (hygiene.warningsLogEnabled && warnings.length > 0) {
|
|
14301
|
-
const fp =
|
|
14302
|
-
await mkdir6(
|
|
14053
|
+
const fp = path13.join(this.deps.config.memoryDir, hygiene.warningsLogPath);
|
|
14054
|
+
await mkdir6(path13.dirname(fp), { recursive: true });
|
|
14303
14055
|
const stamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
14304
14056
|
const block = `
|
|
14305
14057
|
|
|
@@ -14339,7 +14091,7 @@ var WorkspaceOpsCoordinator = class {
|
|
|
14339
14091
|
for (const categoryDir of RECALL_FALLBACK_DIRS) {
|
|
14340
14092
|
if (memoryRootReal === null) break;
|
|
14341
14093
|
for (const date of datesToScan) {
|
|
14342
|
-
const dateDir =
|
|
14094
|
+
const dateDir = path13.join(storage.dir, categoryDir, date);
|
|
14343
14095
|
try {
|
|
14344
14096
|
const dirStat = await lstat(dateDir);
|
|
14345
14097
|
if (dirStat.isSymbolicLink() || !dirStat.isDirectory()) continue;
|
|
@@ -14348,7 +14100,7 @@ var WorkspaceOpsCoordinator = class {
|
|
|
14348
14100
|
for (const entry of entries) {
|
|
14349
14101
|
if (entry.isSymbolicLink()) continue;
|
|
14350
14102
|
if (!entry.name.endsWith(".md")) continue;
|
|
14351
|
-
const fullPath =
|
|
14103
|
+
const fullPath = path13.join(dateDir, entry.name);
|
|
14352
14104
|
try {
|
|
14353
14105
|
assertPathInsideRoot(memoryRootReal, await realpath(fullPath), fullPath);
|
|
14354
14106
|
const raw = await readFile5(fullPath, "utf-8");
|
|
@@ -14370,7 +14122,7 @@ var WorkspaceOpsCoordinator = class {
|
|
|
14370
14122
|
facts.push({
|
|
14371
14123
|
path: fullPath,
|
|
14372
14124
|
frontmatter: {
|
|
14373
|
-
id: fm.id ||
|
|
14125
|
+
id: fm.id || path13.basename(entry.name, ".md"),
|
|
14374
14126
|
category: fm.category || "fact",
|
|
14375
14127
|
created,
|
|
14376
14128
|
updated: fm.updated || created,
|
|
@@ -14393,13 +14145,13 @@ var WorkspaceOpsCoordinator = class {
|
|
|
14393
14145
|
return a.frontmatter.created < b.frontmatter.created ? -1 : 1;
|
|
14394
14146
|
});
|
|
14395
14147
|
const hourlySummaries = [];
|
|
14396
|
-
const hourlyBaseDir =
|
|
14148
|
+
const hourlyBaseDir = path13.join(storage.dir, "summaries", "hourly");
|
|
14397
14149
|
try {
|
|
14398
14150
|
const sessionKeys = await readdir3(hourlyBaseDir, { withFileTypes: true });
|
|
14399
14151
|
for (const sk of sessionKeys) {
|
|
14400
14152
|
if (!sk.isDirectory()) continue;
|
|
14401
14153
|
for (const date of datesToScan) {
|
|
14402
|
-
const summaryFile =
|
|
14154
|
+
const summaryFile = path13.join(hourlyBaseDir, sk.name, `${date}.md`);
|
|
14403
14155
|
try {
|
|
14404
14156
|
const raw = await readFile5(summaryFile, "utf-8");
|
|
14405
14157
|
const filtered = filterHourlySummaryMarkdownForLocalDay(
|
|
@@ -14677,7 +14429,7 @@ ${reflectionsContent.trim()}
|
|
|
14677
14429
|
// src/orchestration/namespace-read-fanout.ts
|
|
14678
14430
|
import { existsSync, readFileSync } from "fs";
|
|
14679
14431
|
import { stat as stat3 } from "fs/promises";
|
|
14680
|
-
import
|
|
14432
|
+
import path14 from "path";
|
|
14681
14433
|
var NamespaceReadFanoutCoordinator = class {
|
|
14682
14434
|
constructor(deps) {
|
|
14683
14435
|
this.deps = deps;
|
|
@@ -14704,7 +14456,7 @@ var NamespaceReadFanoutCoordinator = class {
|
|
|
14704
14456
|
loadNamespaceStorageDirHintsFromCatalog() {
|
|
14705
14457
|
if (this.deps.namespaceStorageDirHintsLoaded || !this.deps.namespaceCatalog.enabled) return;
|
|
14706
14458
|
this.deps.namespaceStorageDirHintsLoaded = true;
|
|
14707
|
-
const catalogPath =
|
|
14459
|
+
const catalogPath = path14.join(this.deps.config.memoryDir, "state", "namespaces.jsonl");
|
|
14708
14460
|
if (!existsSync(catalogPath)) return;
|
|
14709
14461
|
let body;
|
|
14710
14462
|
try {
|
|
@@ -14741,7 +14493,7 @@ var NamespaceReadFanoutCoordinator = class {
|
|
|
14741
14493
|
if (!this.deps.storageDirMatchesNamespaceHint(record.namespace, record.storageDir)) {
|
|
14742
14494
|
continue;
|
|
14743
14495
|
}
|
|
14744
|
-
const resolvedStorageDir =
|
|
14496
|
+
const resolvedStorageDir = path14.resolve(record.storageDir);
|
|
14745
14497
|
const current = preferredByStorageDir.get(resolvedStorageDir);
|
|
14746
14498
|
preferredByStorageDir.set(
|
|
14747
14499
|
resolvedStorageDir,
|
|
@@ -14918,12 +14670,12 @@ var NamespaceReadFanoutCoordinator = class {
|
|
|
14918
14670
|
}
|
|
14919
14671
|
async resolveStateDirForNamespace(namespace) {
|
|
14920
14672
|
if (!resolveNamespaceCapabilities(this.deps.config).namespaces) {
|
|
14921
|
-
return
|
|
14673
|
+
return path14.join(this.deps.config.memoryDir, "state");
|
|
14922
14674
|
}
|
|
14923
14675
|
if (namespace !== this.deps.config.defaultNamespace) {
|
|
14924
|
-
return
|
|
14676
|
+
return path14.join(this.deps.config.memoryDir, "namespaces", namespace, "state");
|
|
14925
14677
|
}
|
|
14926
|
-
const candidate =
|
|
14678
|
+
const candidate = path14.join(
|
|
14927
14679
|
this.deps.config.memoryDir,
|
|
14928
14680
|
"namespaces",
|
|
14929
14681
|
this.deps.config.defaultNamespace
|
|
@@ -14931,11 +14683,11 @@ var NamespaceReadFanoutCoordinator = class {
|
|
|
14931
14683
|
try {
|
|
14932
14684
|
const candidateStat = await stat3(candidate);
|
|
14933
14685
|
if (candidateStat.isDirectory()) {
|
|
14934
|
-
return
|
|
14686
|
+
return path14.join(candidate, "state");
|
|
14935
14687
|
}
|
|
14936
14688
|
} catch {
|
|
14937
14689
|
}
|
|
14938
|
-
return
|
|
14690
|
+
return path14.join(this.deps.config.memoryDir, "state");
|
|
14939
14691
|
}
|
|
14940
14692
|
namespaceFromPath(p) {
|
|
14941
14693
|
if (!resolveNamespaceCapabilities(this.deps.config).namespaces) return this.deps.config.defaultNamespace;
|
|
@@ -14976,30 +14728,426 @@ var NamespaceReadFanoutCoordinator = class {
|
|
|
14976
14728
|
}
|
|
14977
14729
|
};
|
|
14978
14730
|
|
|
14979
|
-
// src/orchestration/
|
|
14980
|
-
|
|
14981
|
-
|
|
14982
|
-
|
|
14983
|
-
|
|
14984
|
-
|
|
14985
|
-
|
|
14986
|
-
|
|
14987
|
-
|
|
14988
|
-
|
|
14989
|
-
|
|
14990
|
-
|
|
14991
|
-
}
|
|
14992
|
-
|
|
14993
|
-
|
|
14994
|
-
}
|
|
14995
|
-
|
|
14996
|
-
}
|
|
14997
|
-
|
|
14998
|
-
|
|
14999
|
-
|
|
15000
|
-
|
|
15001
|
-
|
|
15002
|
-
|
|
14731
|
+
// src/orchestration/recall-entry.ts
|
|
14732
|
+
var RecallEntryCoordinator = class {
|
|
14733
|
+
constructor(deps) {
|
|
14734
|
+
this.deps = deps;
|
|
14735
|
+
}
|
|
14736
|
+
deps;
|
|
14737
|
+
async recall(prompt, sessionKey, options = {}) {
|
|
14738
|
+
const caps = resolveCapabilities(this.deps.config);
|
|
14739
|
+
const graphCaps = resolveGraphConstructionCapabilities(this.deps.config);
|
|
14740
|
+
const abortController = new AbortController();
|
|
14741
|
+
const onAbort = () => {
|
|
14742
|
+
abortController.abort();
|
|
14743
|
+
};
|
|
14744
|
+
if (options.abortSignal?.aborted) {
|
|
14745
|
+
abortController.abort();
|
|
14746
|
+
} else {
|
|
14747
|
+
options.abortSignal?.addEventListener("abort", onAbort, { once: true });
|
|
14748
|
+
}
|
|
14749
|
+
const principal = typeof options.principalOverride === "string" && options.principalOverride.length > 0 ? options.principalOverride : resolvePrincipal(sessionKey, this.deps.config);
|
|
14750
|
+
const namespacesEnabled = resolveNamespaceCapabilities(this.deps.config).namespaces;
|
|
14751
|
+
if (namespacesEnabled && !principal) {
|
|
14752
|
+
throw new Error("authentication required: namespaces are enabled and no principal was supplied");
|
|
14753
|
+
}
|
|
14754
|
+
let initGateTimeoutHandle = null;
|
|
14755
|
+
let onInitGateAbort = null;
|
|
14756
|
+
if (this.deps.initPromise) {
|
|
14757
|
+
const gateResult = await Promise.race([
|
|
14758
|
+
this.deps.initPromise.then(() => "ok"),
|
|
14759
|
+
new Promise((resolve) => {
|
|
14760
|
+
initGateTimeoutHandle = setTimeout(
|
|
14761
|
+
() => resolve("timeout"),
|
|
14762
|
+
this.deps.config.initGateTimeoutMs
|
|
14763
|
+
);
|
|
14764
|
+
}),
|
|
14765
|
+
abortController.signal.aborted ? Promise.resolve("aborted") : new Promise((resolve) => {
|
|
14766
|
+
onInitGateAbort = () => resolve("aborted");
|
|
14767
|
+
abortController.signal.addEventListener(
|
|
14768
|
+
"abort",
|
|
14769
|
+
onInitGateAbort,
|
|
14770
|
+
{ once: true }
|
|
14771
|
+
);
|
|
14772
|
+
})
|
|
14773
|
+
]);
|
|
14774
|
+
if (initGateTimeoutHandle) clearTimeout(initGateTimeoutHandle);
|
|
14775
|
+
if (onInitGateAbort)
|
|
14776
|
+
abortController.signal.removeEventListener("abort", onInitGateAbort);
|
|
14777
|
+
if (gateResult === "aborted") {
|
|
14778
|
+
this.deps.logRecallFailure(abortRecallError("recall aborted before init"));
|
|
14779
|
+
return "";
|
|
14780
|
+
}
|
|
14781
|
+
if (gateResult === "timeout") {
|
|
14782
|
+
log.warn("recall: init gate timed out \u2014 proceeding without full init");
|
|
14783
|
+
}
|
|
14784
|
+
}
|
|
14785
|
+
if (resolveRecallAuxiliaryCapabilities(this.deps.config).secureStore && !this.deps.storage.isSecureStoreUnlocked()) {
|
|
14786
|
+
const lockedMsg = "[secure-store locked] Memory store is encrypted and locked. Unlock the secure-store inside this daemon process, or restart the daemon through a secure-store aware launcher that installs the key.";
|
|
14787
|
+
log.warn("recall blocked: secure-store is locked");
|
|
14788
|
+
return lockedMsg;
|
|
14789
|
+
}
|
|
14790
|
+
try {
|
|
14791
|
+
const recallPromise = this.deps.recallInternal(prompt, sessionKey, {
|
|
14792
|
+
...options,
|
|
14793
|
+
abortSignal: abortController.signal
|
|
14794
|
+
}, caps, graphCaps);
|
|
14795
|
+
const RECALL_TIMEOUT_MS = this.deps.config.recallOuterTimeoutMs ?? 75e3;
|
|
14796
|
+
if (RECALL_TIMEOUT_MS <= 0) {
|
|
14797
|
+
return await recallPromise;
|
|
14798
|
+
}
|
|
14799
|
+
let timeoutHandle = null;
|
|
14800
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
14801
|
+
timeoutHandle = setTimeout(() => {
|
|
14802
|
+
abortController.abort();
|
|
14803
|
+
reject(new Error("recall timeout"));
|
|
14804
|
+
}, RECALL_TIMEOUT_MS);
|
|
14805
|
+
});
|
|
14806
|
+
let recallResult;
|
|
14807
|
+
try {
|
|
14808
|
+
recallResult = await Promise.race([recallPromise, timeoutPromise]);
|
|
14809
|
+
} finally {
|
|
14810
|
+
if (timeoutHandle) clearTimeout(timeoutHandle);
|
|
14811
|
+
}
|
|
14812
|
+
if (caps.recallDirectAnswer && sessionKey) {
|
|
14813
|
+
try {
|
|
14814
|
+
this.deps.enqueueDirectAnswerObservation(
|
|
14815
|
+
prompt,
|
|
14816
|
+
sessionKey,
|
|
14817
|
+
options.namespace?.trim() || void 0,
|
|
14818
|
+
options.principalOverride,
|
|
14819
|
+
caps,
|
|
14820
|
+
namespacesEnabled
|
|
14821
|
+
);
|
|
14822
|
+
} catch (err) {
|
|
14823
|
+
log.debug(`direct-answer observation setup failed: ${err}`);
|
|
14824
|
+
}
|
|
14825
|
+
}
|
|
14826
|
+
return recallResult;
|
|
14827
|
+
} catch (err) {
|
|
14828
|
+
this.deps.logRecallFailure(err);
|
|
14829
|
+
this.deps.profiler.endTrace();
|
|
14830
|
+
return "";
|
|
14831
|
+
} finally {
|
|
14832
|
+
options.abortSignal?.removeEventListener("abort", onAbort);
|
|
14833
|
+
}
|
|
14834
|
+
}
|
|
14835
|
+
logRecallFailure(err) {
|
|
14836
|
+
const now = Date.now();
|
|
14837
|
+
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
14838
|
+
const LOG_WINDOW_MS = 6e4;
|
|
14839
|
+
const idleSinceLastFailureMs = now - this.deps.lastRecallFailureAtMs;
|
|
14840
|
+
this.deps.lastRecallFailureAtMs = now;
|
|
14841
|
+
if (idleSinceLastFailureMs >= LOG_WINDOW_MS) {
|
|
14842
|
+
this.deps.suppressedRecallFailures = 0;
|
|
14843
|
+
}
|
|
14844
|
+
if (now - this.deps.lastRecallFailureLogAtMs >= LOG_WINDOW_MS) {
|
|
14845
|
+
const suffix = this.deps.suppressedRecallFailures > 0 ? ` (suppressed ${this.deps.suppressedRecallFailures} similar failures in last minute)` : "";
|
|
14846
|
+
log.warn(`recall timed out or failed: ${errorMsg}${suffix}`);
|
|
14847
|
+
this.deps.lastRecallFailureLogAtMs = now;
|
|
14848
|
+
this.deps.suppressedRecallFailures = 0;
|
|
14849
|
+
return;
|
|
14850
|
+
}
|
|
14851
|
+
this.deps.suppressedRecallFailures += 1;
|
|
14852
|
+
log.debug(`recall timed out or failed (suppressed): ${errorMsg}`);
|
|
14853
|
+
}
|
|
14854
|
+
queueEvalShadowRecall(record) {
|
|
14855
|
+
if (!resolveEvalCapabilities(this.deps.config).evalHarness || !resolveEvalCapabilities(this.deps.config).evalShadowMode)
|
|
14856
|
+
return;
|
|
14857
|
+
this.deps.evalShadowWriteChain = this.deps.evalShadowWriteChain.catch(() => void 0).then(async () => {
|
|
14858
|
+
try {
|
|
14859
|
+
await recordEvalShadowRecall({
|
|
14860
|
+
memoryDir: this.deps.config.memoryDir,
|
|
14861
|
+
evalStoreDir: this.deps.config.evalStoreDir,
|
|
14862
|
+
record: {
|
|
14863
|
+
schemaVersion: 1,
|
|
14864
|
+
...record
|
|
14865
|
+
}
|
|
14866
|
+
});
|
|
14867
|
+
} catch (err) {
|
|
14868
|
+
log.debug(`eval shadow recall write failed: ${err}`);
|
|
14869
|
+
}
|
|
14870
|
+
});
|
|
14871
|
+
}
|
|
14872
|
+
publishRecallResults(options) {
|
|
14873
|
+
const sectionId = "memories";
|
|
14874
|
+
const trustByPath = options.trustByPath ?? null;
|
|
14875
|
+
const injectable = trustByPath ? options.results.filter((r) => !trustByPath.get(r.path)?.quarantined) : options.results;
|
|
14876
|
+
const memoryIds = this.deps.extractMemoryIdsFromResults(injectable);
|
|
14877
|
+
this.deps.trackMemoryAccess(memoryIds);
|
|
14878
|
+
this.deps.appendRecallSection(
|
|
14879
|
+
options.sectionBuckets,
|
|
14880
|
+
sectionId,
|
|
14881
|
+
this.deps.formatQmdResults(options.title, injectable, options.sessionKey, trustByPath)
|
|
14882
|
+
);
|
|
14883
|
+
}
|
|
14884
|
+
};
|
|
14885
|
+
|
|
14886
|
+
// src/orchestration/session-context.ts
|
|
14887
|
+
var SessionContextCoordinator = class {
|
|
14888
|
+
constructor(deps) {
|
|
14889
|
+
this.deps = deps;
|
|
14890
|
+
}
|
|
14891
|
+
deps;
|
|
14892
|
+
/**
|
|
14893
|
+
* Effective namespace a same-session LCM/structured-history READER must use
|
|
14894
|
+
* to find what the access `observe` surface WROTE (#1495 thread 2).
|
|
14895
|
+
*
|
|
14896
|
+
* This MUST mirror the `observe` scope plan's write-namespace resolution, NOT
|
|
14897
|
+
* `resolveSelfNamespace`: when no coding overlay applies, `observe` archives
|
|
14898
|
+
* under `config.defaultNamespace` (an unqualified observed turn is NOT moved
|
|
14899
|
+
* to the principal self namespace — identical to
|
|
14900
|
+
* `resolveCodingScopedWriteNamespace`/`memory_store`, rule 39). Only when a
|
|
14901
|
+
* coding overlay actually changes the namespace does the writer (and so the
|
|
14902
|
+
* reader) use the overlaid `project-*` namespace. Returning the self base for
|
|
14903
|
+
* the no-overlay case would prefix the read key with a namespace the writer
|
|
14904
|
+
* never used, so the reader would miss its own evidence.
|
|
14905
|
+
*
|
|
14906
|
+
* Honours the access-surface `principalOverride` (#1505 thread 2, codex): when
|
|
14907
|
+
* a recall supplies an authenticated principal NOT encoded in the raw
|
|
14908
|
+
* `sessionKey`, `observe` archived LCM under THAT principal's base namespace.
|
|
14909
|
+
* Deriving the base from `resolvePrincipal(sessionKey)` alone could fall back
|
|
14910
|
+
* to `default`, so principal `alice` observing `sess-1` would write under
|
|
14911
|
+
* `alice` but READ under `default`. Threading the override here keeps the read
|
|
14912
|
+
* base identical to the write base.
|
|
14913
|
+
*
|
|
14914
|
+
* READ-AUTHORIZATION gate (#1505 round 3, codex P2 "Gate LCM recall keys by
|
|
14915
|
+
* readable namespaces"): the overlay LCM read key is a `<principal>-project-*`
|
|
14916
|
+
* sub-namespace of the principal SELF base. The normal recall namespace set
|
|
14917
|
+
* below only substitutes the coding overlay when the principal SELF base is
|
|
14918
|
+
* actually in the readable recall set (`recallNamespacesForPrincipal` — gated
|
|
14919
|
+
* by `defaultRecallNamespaces.includes("self")` AND `canReadNamespace`). If a
|
|
14920
|
+
* principal can WRITE but not READ its self namespace (or `defaultRecall-
|
|
14921
|
+
* Namespaces` omits `self`), QMD/file recall never touches those overlay rows,
|
|
14922
|
+
* so neither may the LCM read key. When the self base is NOT readable, fall
|
|
14923
|
+
* back to the default store — exactly what an unqualified, unauthorized recall
|
|
14924
|
+
* resolves to — rather than injecting overlay rows the rest of recall excludes
|
|
14925
|
+
* (rule 42 read/write parity; rule 48 least-privilege).
|
|
14926
|
+
*/
|
|
14927
|
+
lcmReadNamespaceForSession(sessionKey, principalOverride) {
|
|
14928
|
+
const principal = typeof principalOverride === "string" && principalOverride.length > 0 ? principalOverride : this.deps.resolvePrincipal(sessionKey);
|
|
14929
|
+
const base = defaultNamespaceForPrincipal(principal, this.deps.config);
|
|
14930
|
+
const overlaid = this.deps.applyCodingNamespaceOverlay(sessionKey, base);
|
|
14931
|
+
if (overlaid === base) return this.deps.config.defaultNamespace;
|
|
14932
|
+
const selfReadableInRecall = recallNamespacesForPrincipal(
|
|
14933
|
+
principal,
|
|
14934
|
+
this.deps.config
|
|
14935
|
+
).includes(base);
|
|
14936
|
+
return selfReadableInRecall ? overlaid : this.deps.config.defaultNamespace;
|
|
14937
|
+
}
|
|
14938
|
+
/**
|
|
14939
|
+
* Attach a coding-agent context to a session (issue #569). Called by the
|
|
14940
|
+
* Claude Code / Codex / Cursor connectors at session start after
|
|
14941
|
+
* `resolveGitContext(cwd)`. The context is consulted by the recall path
|
|
14942
|
+
* and the write path so that memories route to a project- (and optionally
|
|
14943
|
+
* branch-) scoped namespace.
|
|
14944
|
+
*
|
|
14945
|
+
* Pass `null` to clear.
|
|
14946
|
+
*/
|
|
14947
|
+
setCodingContextForSession(sessionKey, codingContext) {
|
|
14948
|
+
if (typeof sessionKey !== "string" || sessionKey.length === 0) return;
|
|
14949
|
+
this.deps.ensureSessionBindingMaps();
|
|
14950
|
+
if (codingContext === null) {
|
|
14951
|
+
this.deps._codingContextBySession.delete(sessionKey);
|
|
14952
|
+
return;
|
|
14953
|
+
}
|
|
14954
|
+
this.deps._codingContextBySession.set(sessionKey, codingContext);
|
|
14955
|
+
}
|
|
14956
|
+
/**
|
|
14957
|
+
* Read-only accessor for the coding context attached to a session. Returns
|
|
14958
|
+
* `null` when none is set. Used by `remnic doctor` and by tests.
|
|
14959
|
+
*
|
|
14960
|
+
* Defensive `_codingContextBySession` lookup — legacy orchestrator-flush
|
|
14961
|
+
* tests use `Object.create(Orchestrator.prototype)` which does not run
|
|
14962
|
+
* class-field initializers, so the Map may be undefined on stubs.
|
|
14963
|
+
*/
|
|
14964
|
+
getCodingContextForSession(sessionKey) {
|
|
14965
|
+
if (typeof sessionKey !== "string" || sessionKey.length === 0) return null;
|
|
14966
|
+
return this.deps._codingContextBySession?.get(sessionKey) ?? null;
|
|
14967
|
+
}
|
|
14968
|
+
/**
|
|
14969
|
+
* Shared helper used by both the recall path and the write path (rule 42).
|
|
14970
|
+
*
|
|
14971
|
+
* Given a base namespace computed from the principal, returns the overlaid
|
|
14972
|
+
* coding namespace when the session has a coding context AND
|
|
14973
|
+
* `codingMode.projectScope` is true AND `namespacesEnabled` is true.
|
|
14974
|
+
* Otherwise returns `baseNamespace` unchanged — CLAUDE.md #30 escape hatch.
|
|
14975
|
+
*
|
|
14976
|
+
* Principal isolation (CLAUDE.md rule 42): the overlay is COMBINED with
|
|
14977
|
+
* the principal-derived `baseNamespace` rather than replacing it, so two
|
|
14978
|
+
* principals working in the same repository do not share memories through
|
|
14979
|
+
* a common `project-*` namespace.
|
|
14980
|
+
*
|
|
14981
|
+
* Namespaces-disabled gate: when `namespacesEnabled` is false, the
|
|
14982
|
+
* storage router maps every namespace to the same `memoryDir`. Returning
|
|
14983
|
+
* `project-*` in that mode would create apparent route separation with
|
|
14984
|
+
* no actual storage isolation — a false-isolation trap. In that mode we
|
|
14985
|
+
* return `baseNamespace` unchanged so coding mode degrades to the existing
|
|
14986
|
+
* unscoped behavior.
|
|
14987
|
+
*
|
|
14988
|
+
* @internal
|
|
14989
|
+
*/
|
|
14990
|
+
applyCodingNamespaceOverlay(sessionKey, baseNamespace) {
|
|
14991
|
+
if (!resolveNamespaceCapabilities(this.deps.config).namespaces) return baseNamespace;
|
|
14992
|
+
const codingContext = this.deps.getCodingContextForSession(sessionKey);
|
|
14993
|
+
const overlay = resolveCodingNamespaceOverlay(codingContext, this.deps.config.codingMode, this.deps.config.defaultNamespace);
|
|
14994
|
+
if (!overlay) return baseNamespace;
|
|
14995
|
+
return combineNamespaces(baseNamespace, overlay.namespace);
|
|
14996
|
+
}
|
|
14997
|
+
/**
|
|
14998
|
+
* Register a peer ID for a session so recall can inject the peer's
|
|
14999
|
+
* profile into context (issue #679 PR 3/5). Pass `null` to clear.
|
|
15000
|
+
*
|
|
15001
|
+
* Connectors and the `before_agent_start` hook call this when the
|
|
15002
|
+
* session's counter-party is known. The ID is validated against
|
|
15003
|
+
* `PEER_ID_PATTERN` before storing.
|
|
15004
|
+
*
|
|
15005
|
+
* Fail-closed (Codex P1 review): an invalid peerId clears any
|
|
15006
|
+
* previously registered mapping for the session rather than silently
|
|
15007
|
+
* keeping stale data. This prevents a malformed metadata update from
|
|
15008
|
+
* mixing one peer's profile context into another session.
|
|
15009
|
+
*
|
|
15010
|
+
* Defensive init (Cursor review + rule 16): `Object.create(
|
|
15011
|
+
* Orchestrator.prototype)` stubs in legacy tests skip class-field
|
|
15012
|
+
* initializers, so `_peerIdBySession` may be undefined. Mirror the
|
|
15013
|
+
* same guard used by `setCodingContextForSession`.
|
|
15014
|
+
*/
|
|
15015
|
+
setPeerIdForSession(sessionKey, peerId) {
|
|
15016
|
+
if (typeof sessionKey !== "string" || sessionKey.length === 0) return;
|
|
15017
|
+
this.deps.ensureSessionBindingMaps();
|
|
15018
|
+
if (peerId === null) {
|
|
15019
|
+
this.deps._peerIdBySession.delete(sessionKey);
|
|
15020
|
+
return;
|
|
15021
|
+
}
|
|
15022
|
+
if (typeof peerId !== "string" || peerId.length === 0 || peerId.length > 64 || !/^[A-Za-z0-9]+(?:[._-][A-Za-z0-9]+)*$/.test(peerId)) {
|
|
15023
|
+
log.warn(`setPeerIdForSession: invalid peerId \u2014 clearing session mapping`);
|
|
15024
|
+
this.deps._peerIdBySession.delete(sessionKey);
|
|
15025
|
+
return;
|
|
15026
|
+
}
|
|
15027
|
+
this.deps._peerIdBySession.set(sessionKey, peerId);
|
|
15028
|
+
}
|
|
15029
|
+
/**
|
|
15030
|
+
* Return the peer ID registered for a session, or `null` when none
|
|
15031
|
+
* is set. Used by `recallInternal` to inject the peer profile section.
|
|
15032
|
+
* Defensive `_peerIdBySession` lookup — legacy orchestrator-flush tests
|
|
15033
|
+
* use `Object.create(Orchestrator.prototype)` which skips class-field
|
|
15034
|
+
* initializers, so the Map may be undefined on stubs.
|
|
15035
|
+
*/
|
|
15036
|
+
getPeerIdForSession(sessionKey) {
|
|
15037
|
+
if (typeof sessionKey !== "string" || sessionKey.length === 0) return null;
|
|
15038
|
+
return this.deps._peerIdBySession?.get(sessionKey) ?? null;
|
|
15039
|
+
}
|
|
15040
|
+
async runDeepSleepGovernanceNow(options) {
|
|
15041
|
+
const targetStorage = options?.storage ?? this.deps.storage;
|
|
15042
|
+
const { runMemoryGovernance } = await import("./maintenance/memory-governance.js");
|
|
15043
|
+
const { summarizeGovernanceResultForDreams } = await import("./dreams-ledger-6UODQOX6.js");
|
|
15044
|
+
const govResult = await runMemoryGovernance({
|
|
15045
|
+
memoryDir: targetStorage.dir,
|
|
15046
|
+
mode: options?.dryRun === true ? "shadow" : "apply"
|
|
15047
|
+
});
|
|
15048
|
+
if (options?.dryRun !== true) {
|
|
15049
|
+
try {
|
|
15050
|
+
await this.deps.processEntitySynthesisQueue(
|
|
15051
|
+
this.deps.storageDirNamespace(targetStorage.dir),
|
|
15052
|
+
5
|
|
15053
|
+
);
|
|
15054
|
+
} catch (error) {
|
|
15055
|
+
log.debug(`deep-sleep governance: entity synthesis refresh failed after apply: ${error}`);
|
|
15056
|
+
}
|
|
15057
|
+
}
|
|
15058
|
+
return summarizeGovernanceResultForDreams(govResult, options?.dryRun === true);
|
|
15059
|
+
}
|
|
15060
|
+
async generateDaySummary(memories) {
|
|
15061
|
+
if (this.deps.initPromise) {
|
|
15062
|
+
let initGateTimeoutHandle;
|
|
15063
|
+
try {
|
|
15064
|
+
await Promise.race([
|
|
15065
|
+
this.deps.initPromise.catch(() => void 0),
|
|
15066
|
+
new Promise((resolve) => {
|
|
15067
|
+
initGateTimeoutHandle = setTimeout(
|
|
15068
|
+
resolve,
|
|
15069
|
+
this.deps.config.initGateTimeoutMs
|
|
15070
|
+
);
|
|
15071
|
+
})
|
|
15072
|
+
]);
|
|
15073
|
+
} finally {
|
|
15074
|
+
if (initGateTimeoutHandle) clearTimeout(initGateTimeoutHandle);
|
|
15075
|
+
}
|
|
15076
|
+
}
|
|
15077
|
+
return this.deps.extraction.generateDaySummary(memories);
|
|
15078
|
+
}
|
|
15079
|
+
async flushSession(sessionKey, options) {
|
|
15080
|
+
const explicitBufferKey = typeof options.bufferKey === "string" && options.bufferKey.length > 0 ? options.bufferKey : null;
|
|
15081
|
+
const discoveredBufferKeys = explicitBufferKey || typeof sessionKey !== "string" || sessionKey.length === 0 || typeof this.deps.buffer.findBufferKeysForSession !== "function" ? [] : await this.deps.buffer.findBufferKeysForSession(sessionKey);
|
|
15082
|
+
const bufferKeys = explicitBufferKey ? [explicitBufferKey] : discoveredBufferKeys.length > 0 ? discoveredBufferKeys : typeof sessionKey === "string" && sessionKey.length > 0 ? [sessionKey] : ["default"];
|
|
15083
|
+
for (const bufferKey of bufferKeys) {
|
|
15084
|
+
const turns = this.deps.buffer.getTurns(bufferKey);
|
|
15085
|
+
if (turns.length === 0) continue;
|
|
15086
|
+
await new Promise((resolve, reject) => {
|
|
15087
|
+
void this.deps.queueBufferedExtraction(turns, "trigger_mode", {
|
|
15088
|
+
bufferKey,
|
|
15089
|
+
clearBufferAfterExtraction: true,
|
|
15090
|
+
skipDedupeCheck: true,
|
|
15091
|
+
abortSignal: options.abortSignal,
|
|
15092
|
+
onTaskSettled: (error) => error ? reject(error) : resolve()
|
|
15093
|
+
}).catch(reject);
|
|
15094
|
+
});
|
|
15095
|
+
}
|
|
15096
|
+
}
|
|
15097
|
+
/** Lazily construct the CorrectionService for passive capture. Stateless
|
|
15098
|
+
* across requests (per #1580 design); cached for the orchestrator's life. */
|
|
15099
|
+
passiveCorrectionService() {
|
|
15100
|
+
if (this.deps._passiveCorrectionService) return this.deps._passiveCorrectionService;
|
|
15101
|
+
this.deps._passiveCorrectionService = createCorrectionService({
|
|
15102
|
+
orchestrator: this.deps.orchestratorSelf,
|
|
15103
|
+
// Session-scoped write ACL (review: "passive capture bypasses write
|
|
15104
|
+
// ACL"). A correction detected in session S plans only against S readable
|
|
15105
|
+
// namespaces and applies only to writable ones (rule 42) — passive
|
|
15106
|
+
// capture never becomes a cross-tenant mutation vector. Mirrors the
|
|
15107
|
+
// access-service createCorrectionService wiring rather than bypassing it.
|
|
15108
|
+
resolveAuthorizedNamespace: async (req) => {
|
|
15109
|
+
const principal = req.principal || resolvePrincipal(req.sessionKey, this.deps.config);
|
|
15110
|
+
const ns = req.namespace ?? defaultNamespaceForPrincipal(principal, this.deps.config);
|
|
15111
|
+
if (!canWriteNamespace(principal, ns, this.deps.config)) {
|
|
15112
|
+
throw new Error(
|
|
15113
|
+
`passive correction: namespace "${ns}" is not writable for principal ${principal ?? "(none)"}`
|
|
15114
|
+
);
|
|
15115
|
+
}
|
|
15116
|
+
return ns;
|
|
15117
|
+
},
|
|
15118
|
+
resolveReadableNamespaces: (req) => {
|
|
15119
|
+
const principal = req.principal || resolvePrincipal(req.sessionKey, this.deps.config);
|
|
15120
|
+
return recallNamespacesForPrincipal(principal, this.deps.config);
|
|
15121
|
+
},
|
|
15122
|
+
canWriteNamespace: async (req) => {
|
|
15123
|
+
const principal = req.principal || resolvePrincipal(req.sessionKey, this.deps.config);
|
|
15124
|
+
return canWriteNamespace(principal, req.namespace, this.deps.config);
|
|
15125
|
+
},
|
|
15126
|
+
llmComplete: async ({ system, user }) => {
|
|
15127
|
+
const llmResult = await this.deps.localLlm.chatCompletion(
|
|
15128
|
+
[
|
|
15129
|
+
{ role: "system", content: system },
|
|
15130
|
+
{ role: "user", content: user }
|
|
15131
|
+
],
|
|
15132
|
+
{ operation: "correction-classify", priority: "background" }
|
|
15133
|
+
);
|
|
15134
|
+
if (!llmResult) {
|
|
15135
|
+
throw new Error(
|
|
15136
|
+
"passive correction classify+draft: local LLM unavailable (disabled or in cooldown)"
|
|
15137
|
+
);
|
|
15138
|
+
}
|
|
15139
|
+
return llmResult.content;
|
|
15140
|
+
}
|
|
15141
|
+
});
|
|
15142
|
+
return this.deps._passiveCorrectionService;
|
|
15143
|
+
}
|
|
15144
|
+
};
|
|
15145
|
+
|
|
15146
|
+
// src/orchestrator.ts
|
|
15147
|
+
var Orchestrator = class {
|
|
15148
|
+
storage;
|
|
15149
|
+
storageRouter;
|
|
15150
|
+
/** Rebuildable namespace catalog (issue #1499). Inert unless namespaces enabled. */
|
|
15003
15151
|
namespaceCatalog;
|
|
15004
15152
|
namespaceStorageDirHints = /* @__PURE__ */ new Map();
|
|
15005
15153
|
namespaceStorageDirHintsLoaded = false;
|
|
@@ -15115,6 +15263,18 @@ var Orchestrator = class {
|
|
|
15115
15263
|
* (rule 11 — scope globals per plugin ID / session).
|
|
15116
15264
|
*/
|
|
15117
15265
|
_peerIdBySession = /* @__PURE__ */ new Map();
|
|
15266
|
+
/**
|
|
15267
|
+
* Defensive init for the session-binding maps (issue #1526 seam 28
|
|
15268
|
+
* review). `Object.create(Orchestrator.prototype)` stubs in legacy
|
|
15269
|
+
* tests skip class-field initializers, so the maps may be undefined on
|
|
15270
|
+
* fakes; SessionContextCoordinator calls this before writing so the
|
|
15271
|
+
* maps are created ON THE ORCHESTRATOR (or fake), never on the
|
|
15272
|
+
* coordinator.
|
|
15273
|
+
*/
|
|
15274
|
+
ensureSessionBindingMaps() {
|
|
15275
|
+
this._codingContextBySession ??= /* @__PURE__ */ new Map();
|
|
15276
|
+
this._peerIdBySession ??= /* @__PURE__ */ new Map();
|
|
15277
|
+
}
|
|
15118
15278
|
routingRulesStore = null;
|
|
15119
15279
|
contentHashIndex = null;
|
|
15120
15280
|
contentHashIndexesByStorageDir = /* @__PURE__ */ new Map();
|
|
@@ -15367,157 +15527,51 @@ var Orchestrator = class {
|
|
|
15367
15527
|
);
|
|
15368
15528
|
return this.applyCodingNamespaceOverlay(sessionKey, base);
|
|
15369
15529
|
}
|
|
15370
|
-
/**
|
|
15371
|
-
* Effective namespace a same-session LCM/structured-history READER must use
|
|
15372
|
-
* to find what the access `observe` surface WROTE (#1495 thread 2).
|
|
15373
|
-
*
|
|
15374
|
-
* This MUST mirror the `observe` scope plan's write-namespace resolution, NOT
|
|
15375
|
-
* `resolveSelfNamespace`: when no coding overlay applies, `observe` archives
|
|
15376
|
-
* under `config.defaultNamespace` (an unqualified observed turn is NOT moved
|
|
15377
|
-
* to the principal self namespace — identical to
|
|
15378
|
-
* `resolveCodingScopedWriteNamespace`/`memory_store`, rule 39). Only when a
|
|
15379
|
-
* coding overlay actually changes the namespace does the writer (and so the
|
|
15380
|
-
* reader) use the overlaid `project-*` namespace. Returning the self base for
|
|
15381
|
-
* the no-overlay case would prefix the read key with a namespace the writer
|
|
15382
|
-
* never used, so the reader would miss its own evidence.
|
|
15383
|
-
*
|
|
15384
|
-
* Honours the access-surface `principalOverride` (#1505 thread 2, codex): when
|
|
15385
|
-
* a recall supplies an authenticated principal NOT encoded in the raw
|
|
15386
|
-
* `sessionKey`, `observe` archived LCM under THAT principal's base namespace.
|
|
15387
|
-
* Deriving the base from `resolvePrincipal(sessionKey)` alone could fall back
|
|
15388
|
-
* to `default`, so principal `alice` observing `sess-1` would write under
|
|
15389
|
-
* `alice` but READ under `default`. Threading the override here keeps the read
|
|
15390
|
-
* base identical to the write base.
|
|
15391
|
-
*
|
|
15392
|
-
* READ-AUTHORIZATION gate (#1505 round 3, codex P2 "Gate LCM recall keys by
|
|
15393
|
-
* readable namespaces"): the overlay LCM read key is a `<principal>-project-*`
|
|
15394
|
-
* sub-namespace of the principal SELF base. The normal recall namespace set
|
|
15395
|
-
* below only substitutes the coding overlay when the principal SELF base is
|
|
15396
|
-
* actually in the readable recall set (`recallNamespacesForPrincipal` — gated
|
|
15397
|
-
* by `defaultRecallNamespaces.includes("self")` AND `canReadNamespace`). If a
|
|
15398
|
-
* principal can WRITE but not READ its self namespace (or `defaultRecall-
|
|
15399
|
-
* Namespaces` omits `self`), QMD/file recall never touches those overlay rows,
|
|
15400
|
-
* so neither may the LCM read key. When the self base is NOT readable, fall
|
|
15401
|
-
* back to the default store — exactly what an unqualified, unauthorized recall
|
|
15402
|
-
* resolves to — rather than injecting overlay rows the rest of recall excludes
|
|
15403
|
-
* (rule 42 read/write parity; rule 48 least-privilege).
|
|
15404
|
-
*/
|
|
15405
15530
|
lcmReadNamespaceForSession(sessionKey, principalOverride) {
|
|
15406
|
-
|
|
15407
|
-
|
|
15408
|
-
|
|
15409
|
-
|
|
15410
|
-
|
|
15411
|
-
|
|
15412
|
-
this.config
|
|
15413
|
-
).includes(base);
|
|
15414
|
-
return selfReadableInRecall ? overlaid : this.config.defaultNamespace;
|
|
15531
|
+
return (this.sessionContextCoordinator ?? new SessionContextCoordinator(
|
|
15532
|
+
selfDeps(this)
|
|
15533
|
+
)).lcmReadNamespaceForSession(
|
|
15534
|
+
sessionKey,
|
|
15535
|
+
principalOverride
|
|
15536
|
+
);
|
|
15415
15537
|
}
|
|
15416
|
-
/**
|
|
15417
|
-
* Attach a coding-agent context to a session (issue #569). Called by the
|
|
15418
|
-
* Claude Code / Codex / Cursor connectors at session start after
|
|
15419
|
-
* `resolveGitContext(cwd)`. The context is consulted by the recall path
|
|
15420
|
-
* and the write path so that memories route to a project- (and optionally
|
|
15421
|
-
* branch-) scoped namespace.
|
|
15422
|
-
*
|
|
15423
|
-
* Pass `null` to clear.
|
|
15424
|
-
*/
|
|
15425
15538
|
setCodingContextForSession(sessionKey, codingContext) {
|
|
15426
|
-
|
|
15427
|
-
|
|
15428
|
-
|
|
15429
|
-
|
|
15430
|
-
|
|
15431
|
-
|
|
15432
|
-
return;
|
|
15433
|
-
}
|
|
15434
|
-
this._codingContextBySession.set(sessionKey, codingContext);
|
|
15539
|
+
return (this.sessionContextCoordinator ?? new SessionContextCoordinator(
|
|
15540
|
+
selfDeps(this)
|
|
15541
|
+
)).setCodingContextForSession(
|
|
15542
|
+
sessionKey,
|
|
15543
|
+
codingContext
|
|
15544
|
+
);
|
|
15435
15545
|
}
|
|
15436
|
-
/**
|
|
15437
|
-
* Read-only accessor for the coding context attached to a session. Returns
|
|
15438
|
-
* `null` when none is set. Used by `remnic doctor` and by tests.
|
|
15439
|
-
*
|
|
15440
|
-
* Defensive `_codingContextBySession` lookup — legacy orchestrator-flush
|
|
15441
|
-
* tests use `Object.create(Orchestrator.prototype)` which does not run
|
|
15442
|
-
* class-field initializers, so the Map may be undefined on stubs.
|
|
15443
|
-
*/
|
|
15444
15546
|
getCodingContextForSession(sessionKey) {
|
|
15445
|
-
|
|
15446
|
-
|
|
15547
|
+
return (this.sessionContextCoordinator ?? new SessionContextCoordinator(
|
|
15548
|
+
selfDeps(this)
|
|
15549
|
+
)).getCodingContextForSession(
|
|
15550
|
+
sessionKey
|
|
15551
|
+
);
|
|
15447
15552
|
}
|
|
15448
|
-
/**
|
|
15449
|
-
* Shared helper used by both the recall path and the write path (rule 42).
|
|
15450
|
-
*
|
|
15451
|
-
* Given a base namespace computed from the principal, returns the overlaid
|
|
15452
|
-
* coding namespace when the session has a coding context AND
|
|
15453
|
-
* `codingMode.projectScope` is true AND `namespacesEnabled` is true.
|
|
15454
|
-
* Otherwise returns `baseNamespace` unchanged — CLAUDE.md #30 escape hatch.
|
|
15455
|
-
*
|
|
15456
|
-
* Principal isolation (CLAUDE.md rule 42): the overlay is COMBINED with
|
|
15457
|
-
* the principal-derived `baseNamespace` rather than replacing it, so two
|
|
15458
|
-
* principals working in the same repository do not share memories through
|
|
15459
|
-
* a common `project-*` namespace.
|
|
15460
|
-
*
|
|
15461
|
-
* Namespaces-disabled gate: when `namespacesEnabled` is false, the
|
|
15462
|
-
* storage router maps every namespace to the same `memoryDir`. Returning
|
|
15463
|
-
* `project-*` in that mode would create apparent route separation with
|
|
15464
|
-
* no actual storage isolation — a false-isolation trap. In that mode we
|
|
15465
|
-
* return `baseNamespace` unchanged so coding mode degrades to the existing
|
|
15466
|
-
* unscoped behavior.
|
|
15467
|
-
*
|
|
15468
|
-
* @internal
|
|
15469
|
-
*/
|
|
15470
15553
|
applyCodingNamespaceOverlay(sessionKey, baseNamespace) {
|
|
15471
|
-
|
|
15472
|
-
|
|
15473
|
-
|
|
15474
|
-
|
|
15475
|
-
|
|
15554
|
+
return (this.sessionContextCoordinator ?? new SessionContextCoordinator(
|
|
15555
|
+
selfDeps(this)
|
|
15556
|
+
)).applyCodingNamespaceOverlay(
|
|
15557
|
+
sessionKey,
|
|
15558
|
+
baseNamespace
|
|
15559
|
+
);
|
|
15476
15560
|
}
|
|
15477
|
-
|
|
15478
|
-
|
|
15479
|
-
|
|
15480
|
-
|
|
15481
|
-
|
|
15482
|
-
|
|
15483
|
-
|
|
15484
|
-
*
|
|
15485
|
-
* Fail-closed (Codex P1 review): an invalid peerId clears any
|
|
15486
|
-
* previously registered mapping for the session rather than silently
|
|
15487
|
-
* keeping stale data. This prevents a malformed metadata update from
|
|
15488
|
-
* mixing one peer's profile context into another session.
|
|
15489
|
-
*
|
|
15490
|
-
* Defensive init (Cursor review + rule 16): `Object.create(
|
|
15491
|
-
* Orchestrator.prototype)` stubs in legacy tests skip class-field
|
|
15492
|
-
* initializers, so `_peerIdBySession` may be undefined. Mirror the
|
|
15493
|
-
* same guard used by `setCodingContextForSession`.
|
|
15494
|
-
*/
|
|
15495
|
-
setPeerIdForSession(sessionKey, peerId) {
|
|
15496
|
-
if (typeof sessionKey !== "string" || sessionKey.length === 0) return;
|
|
15497
|
-
if (!this._peerIdBySession) {
|
|
15498
|
-
this._peerIdBySession = /* @__PURE__ */ new Map();
|
|
15499
|
-
}
|
|
15500
|
-
if (peerId === null) {
|
|
15501
|
-
this._peerIdBySession.delete(sessionKey);
|
|
15502
|
-
return;
|
|
15503
|
-
}
|
|
15504
|
-
if (typeof peerId !== "string" || peerId.length === 0 || peerId.length > 64 || !/^[A-Za-z0-9]+(?:[._-][A-Za-z0-9]+)*$/.test(peerId)) {
|
|
15505
|
-
log.warn(`setPeerIdForSession: invalid peerId \u2014 clearing session mapping`);
|
|
15506
|
-
this._peerIdBySession.delete(sessionKey);
|
|
15507
|
-
return;
|
|
15508
|
-
}
|
|
15509
|
-
this._peerIdBySession.set(sessionKey, peerId);
|
|
15561
|
+
setPeerIdForSession(sessionKey, peerId) {
|
|
15562
|
+
return (this.sessionContextCoordinator ?? new SessionContextCoordinator(
|
|
15563
|
+
selfDeps(this)
|
|
15564
|
+
)).setPeerIdForSession(
|
|
15565
|
+
sessionKey,
|
|
15566
|
+
peerId
|
|
15567
|
+
);
|
|
15510
15568
|
}
|
|
15511
|
-
/**
|
|
15512
|
-
* Return the peer ID registered for a session, or `null` when none
|
|
15513
|
-
* is set. Used by `recallInternal` to inject the peer profile section.
|
|
15514
|
-
* Defensive `_peerIdBySession` lookup — legacy orchestrator-flush tests
|
|
15515
|
-
* use `Object.create(Orchestrator.prototype)` which skips class-field
|
|
15516
|
-
* initializers, so the Map may be undefined on stubs.
|
|
15517
|
-
*/
|
|
15518
15569
|
getPeerIdForSession(sessionKey) {
|
|
15519
|
-
|
|
15520
|
-
|
|
15570
|
+
return (this.sessionContextCoordinator ?? new SessionContextCoordinator(
|
|
15571
|
+
selfDeps(this)
|
|
15572
|
+
)).getPeerIdForSession(
|
|
15573
|
+
sessionKey
|
|
15574
|
+
);
|
|
15521
15575
|
}
|
|
15522
15576
|
/**
|
|
15523
15577
|
* Read-side overlay: returns the list of namespaces a session should read
|
|
@@ -15556,7 +15610,7 @@ var Orchestrator = class {
|
|
|
15556
15610
|
const defaultNs = normalizeNamespaceIdentity(this.config.defaultNamespace);
|
|
15557
15611
|
if (ns !== defaultNs && !isSafeRouteNamespace(ns)) return;
|
|
15558
15612
|
if (!this.storageDirMatchesNamespaceHint(ns, storageDir)) return;
|
|
15559
|
-
const resolvedStorageDir =
|
|
15613
|
+
const resolvedStorageDir = path15.resolve(storageDir);
|
|
15560
15614
|
let hints = this.namespaceStorageDirHints.get(resolvedStorageDir);
|
|
15561
15615
|
if (!hints) {
|
|
15562
15616
|
hints = /* @__PURE__ */ new Set();
|
|
@@ -15567,21 +15621,21 @@ var Orchestrator = class {
|
|
|
15567
15621
|
storageDirMatchesNamespaceHint(namespace, storageDir) {
|
|
15568
15622
|
const ns = normalizeNamespaceIdentity(namespace);
|
|
15569
15623
|
if (!ns) return false;
|
|
15570
|
-
const resolvedStorageDir =
|
|
15571
|
-
const resolvedMemoryDir =
|
|
15624
|
+
const resolvedStorageDir = path15.resolve(storageDir);
|
|
15625
|
+
const resolvedMemoryDir = path15.resolve(this.config.memoryDir);
|
|
15572
15626
|
const defaultNs = normalizeNamespaceIdentity(this.config.defaultNamespace);
|
|
15573
15627
|
if (resolvedStorageDir === resolvedMemoryDir) return ns === defaultNs;
|
|
15574
|
-
const resolvedNamespacesDir =
|
|
15628
|
+
const resolvedNamespacesDir = path15.join(resolvedMemoryDir, "namespaces");
|
|
15575
15629
|
if (!isPathInsideStorageRoot(resolvedNamespacesDir, resolvedStorageDir)) return false;
|
|
15576
|
-
const rawRoot =
|
|
15577
|
-
const tokenRoot =
|
|
15630
|
+
const rawRoot = path15.resolve(resolvedNamespacesDir, ns);
|
|
15631
|
+
const tokenRoot = path15.resolve(resolvedNamespacesDir, namespaceIdentityToken(ns));
|
|
15578
15632
|
return resolvedStorageDir === rawRoot || resolvedStorageDir === tokenRoot;
|
|
15579
15633
|
}
|
|
15580
15634
|
namespaceStorageDirHintOwnershipRank(record, resolvedStorageDir, configured) {
|
|
15581
|
-
if (resolvedStorageDir ===
|
|
15635
|
+
if (resolvedStorageDir === path15.resolve(this.config.memoryDir)) {
|
|
15582
15636
|
return record.namespace === normalizeNamespaceIdentity(this.config.defaultNamespace) ? 0 : 3;
|
|
15583
15637
|
}
|
|
15584
|
-
const leaf =
|
|
15638
|
+
const leaf = path15.basename(resolvedStorageDir);
|
|
15585
15639
|
const tokenOwnsRoot = namespaceIdentityToken(record.namespace) === leaf;
|
|
15586
15640
|
if (tokenOwnsRoot && configured.has(record.namespace)) return 0;
|
|
15587
15641
|
if (record.namespace === leaf) return 1;
|
|
@@ -15718,7 +15772,7 @@ var Orchestrator = class {
|
|
|
15718
15772
|
this.config = config;
|
|
15719
15773
|
this.profiler = new ProfilingCollector({
|
|
15720
15774
|
enabled: resolvePipelineProcessingCapabilities(this.config).profiling,
|
|
15721
|
-
storageDir: config.profilingStorageDir ||
|
|
15775
|
+
storageDir: config.profilingStorageDir || path15.join(config.memoryDir, "profiling"),
|
|
15722
15776
|
maxTraces: config.profilingMaxTraces
|
|
15723
15777
|
});
|
|
15724
15778
|
this.namespaceCatalog = new NamespaceCatalog(config);
|
|
@@ -15788,7 +15842,7 @@ var Orchestrator = class {
|
|
|
15788
15842
|
this.compounding = resolveConsolidationCapabilities(config).compounding ? new CompoundingEngine(config, this.storage) : void 0;
|
|
15789
15843
|
this.buffer = new SmartBuffer(config, this.storage);
|
|
15790
15844
|
this.transcript = new TranscriptManager(config);
|
|
15791
|
-
this.conversationIndexDir =
|
|
15845
|
+
this.conversationIndexDir = path15.join(
|
|
15792
15846
|
config.memoryDir,
|
|
15793
15847
|
"conversation-index",
|
|
15794
15848
|
"chunks"
|
|
@@ -15924,7 +15978,7 @@ var Orchestrator = class {
|
|
|
15924
15978
|
saveContentHashIndexes: () => this.saveContentHashIndexes()
|
|
15925
15979
|
});
|
|
15926
15980
|
this.threading = new ThreadingManager(
|
|
15927
|
-
|
|
15981
|
+
path15.join(config.memoryDir, "threads"),
|
|
15928
15982
|
config.threadingGapMinutes
|
|
15929
15983
|
);
|
|
15930
15984
|
const lifecycleCaps = resolveMemoryLifecycleCapabilities(config);
|
|
@@ -16242,24 +16296,11 @@ ${doc.content}` : doc.content,
|
|
|
16242
16296
|
return this.runSemanticConsolidation({ ...options, force: true });
|
|
16243
16297
|
}
|
|
16244
16298
|
async runDeepSleepGovernanceNow(options) {
|
|
16245
|
-
|
|
16246
|
-
|
|
16247
|
-
|
|
16248
|
-
|
|
16249
|
-
|
|
16250
|
-
mode: options?.dryRun === true ? "shadow" : "apply"
|
|
16251
|
-
});
|
|
16252
|
-
if (options?.dryRun !== true) {
|
|
16253
|
-
try {
|
|
16254
|
-
await this.processEntitySynthesisQueue(
|
|
16255
|
-
this.storageDirNamespace(targetStorage.dir),
|
|
16256
|
-
5
|
|
16257
|
-
);
|
|
16258
|
-
} catch (error) {
|
|
16259
|
-
log.debug(`deep-sleep governance: entity synthesis refresh failed after apply: ${error}`);
|
|
16260
|
-
}
|
|
16261
|
-
}
|
|
16262
|
-
return summarizeGovernanceResultForDreams(govResult, options?.dryRun === true);
|
|
16299
|
+
return (this.sessionContextCoordinator ?? new SessionContextCoordinator(
|
|
16300
|
+
selfDeps(this)
|
|
16301
|
+
)).runDeepSleepGovernanceNow(
|
|
16302
|
+
options
|
|
16303
|
+
);
|
|
16263
16304
|
}
|
|
16264
16305
|
// Issue #1526 (seam 5): semantic consolidation moved to
|
|
16265
16306
|
// SemanticConsolidationCoordinator. Thin delegation keeps all
|
|
@@ -16290,23 +16331,11 @@ ${doc.content}` : doc.content,
|
|
|
16290
16331
|
return this.entitySynthesisCoordinator.processQueue(namespace, maxEntities);
|
|
16291
16332
|
}
|
|
16292
16333
|
async generateDaySummary(memories) {
|
|
16293
|
-
|
|
16294
|
-
|
|
16295
|
-
|
|
16296
|
-
|
|
16297
|
-
|
|
16298
|
-
new Promise((resolve) => {
|
|
16299
|
-
initGateTimeoutHandle = setTimeout(
|
|
16300
|
-
resolve,
|
|
16301
|
-
this.config.initGateTimeoutMs
|
|
16302
|
-
);
|
|
16303
|
-
})
|
|
16304
|
-
]);
|
|
16305
|
-
} finally {
|
|
16306
|
-
if (initGateTimeoutHandle) clearTimeout(initGateTimeoutHandle);
|
|
16307
|
-
}
|
|
16308
|
-
}
|
|
16309
|
-
return this.extraction.generateDaySummary(memories);
|
|
16334
|
+
return (this.sessionContextCoordinator ?? new SessionContextCoordinator(
|
|
16335
|
+
selfDeps(this)
|
|
16336
|
+
)).generateDaySummary(
|
|
16337
|
+
memories
|
|
16338
|
+
);
|
|
16310
16339
|
}
|
|
16311
16340
|
/**
|
|
16312
16341
|
* Auto-gather today's facts and hourly summaries from storage, then generate a day summary.
|
|
@@ -16402,102 +16431,13 @@ ${doc.content}` : doc.content,
|
|
|
16402
16431
|
return this.workspaceOpsCoordinator.validateLocalLlmModel();
|
|
16403
16432
|
}
|
|
16404
16433
|
async recall(prompt, sessionKey, options = {}) {
|
|
16405
|
-
|
|
16406
|
-
|
|
16407
|
-
|
|
16408
|
-
|
|
16409
|
-
|
|
16410
|
-
|
|
16411
|
-
|
|
16412
|
-
abortController.abort();
|
|
16413
|
-
} else {
|
|
16414
|
-
options.abortSignal?.addEventListener("abort", onAbort, { once: true });
|
|
16415
|
-
}
|
|
16416
|
-
const principal = typeof options.principalOverride === "string" && options.principalOverride.length > 0 ? options.principalOverride : resolvePrincipal(sessionKey, this.config);
|
|
16417
|
-
const namespacesEnabled = resolveNamespaceCapabilities(this.config).namespaces;
|
|
16418
|
-
if (namespacesEnabled && !principal) {
|
|
16419
|
-
throw new Error("authentication required: namespaces are enabled and no principal was supplied");
|
|
16420
|
-
}
|
|
16421
|
-
let initGateTimeoutHandle = null;
|
|
16422
|
-
let onInitGateAbort = null;
|
|
16423
|
-
if (this.initPromise) {
|
|
16424
|
-
const gateResult = await Promise.race([
|
|
16425
|
-
this.initPromise.then(() => "ok"),
|
|
16426
|
-
new Promise((resolve) => {
|
|
16427
|
-
initGateTimeoutHandle = setTimeout(
|
|
16428
|
-
() => resolve("timeout"),
|
|
16429
|
-
this.config.initGateTimeoutMs
|
|
16430
|
-
);
|
|
16431
|
-
}),
|
|
16432
|
-
abortController.signal.aborted ? Promise.resolve("aborted") : new Promise((resolve) => {
|
|
16433
|
-
onInitGateAbort = () => resolve("aborted");
|
|
16434
|
-
abortController.signal.addEventListener(
|
|
16435
|
-
"abort",
|
|
16436
|
-
onInitGateAbort,
|
|
16437
|
-
{ once: true }
|
|
16438
|
-
);
|
|
16439
|
-
})
|
|
16440
|
-
]);
|
|
16441
|
-
if (initGateTimeoutHandle) clearTimeout(initGateTimeoutHandle);
|
|
16442
|
-
if (onInitGateAbort)
|
|
16443
|
-
abortController.signal.removeEventListener("abort", onInitGateAbort);
|
|
16444
|
-
if (gateResult === "aborted") {
|
|
16445
|
-
this.logRecallFailure(abortRecallError("recall aborted before init"));
|
|
16446
|
-
return "";
|
|
16447
|
-
}
|
|
16448
|
-
if (gateResult === "timeout") {
|
|
16449
|
-
log.warn("recall: init gate timed out \u2014 proceeding without full init");
|
|
16450
|
-
}
|
|
16451
|
-
}
|
|
16452
|
-
if (resolveRecallAuxiliaryCapabilities(this.config).secureStore && !this.storage.isSecureStoreUnlocked()) {
|
|
16453
|
-
const lockedMsg = "[secure-store locked] Memory store is encrypted and locked. Unlock the secure-store inside this daemon process, or restart the daemon through a secure-store aware launcher that installs the key.";
|
|
16454
|
-
log.warn("recall blocked: secure-store is locked");
|
|
16455
|
-
return lockedMsg;
|
|
16456
|
-
}
|
|
16457
|
-
try {
|
|
16458
|
-
const recallPromise = this.recallInternal(prompt, sessionKey, {
|
|
16459
|
-
...options,
|
|
16460
|
-
abortSignal: abortController.signal
|
|
16461
|
-
}, caps, graphCaps);
|
|
16462
|
-
const RECALL_TIMEOUT_MS = this.config.recallOuterTimeoutMs ?? 75e3;
|
|
16463
|
-
if (RECALL_TIMEOUT_MS <= 0) {
|
|
16464
|
-
return await recallPromise;
|
|
16465
|
-
}
|
|
16466
|
-
let timeoutHandle = null;
|
|
16467
|
-
const timeoutPromise = new Promise((_, reject) => {
|
|
16468
|
-
timeoutHandle = setTimeout(() => {
|
|
16469
|
-
abortController.abort();
|
|
16470
|
-
reject(new Error("recall timeout"));
|
|
16471
|
-
}, RECALL_TIMEOUT_MS);
|
|
16472
|
-
});
|
|
16473
|
-
let recallResult;
|
|
16474
|
-
try {
|
|
16475
|
-
recallResult = await Promise.race([recallPromise, timeoutPromise]);
|
|
16476
|
-
} finally {
|
|
16477
|
-
if (timeoutHandle) clearTimeout(timeoutHandle);
|
|
16478
|
-
}
|
|
16479
|
-
if (caps.recallDirectAnswer && sessionKey) {
|
|
16480
|
-
try {
|
|
16481
|
-
this.enqueueDirectAnswerObservation(
|
|
16482
|
-
prompt,
|
|
16483
|
-
sessionKey,
|
|
16484
|
-
options.namespace?.trim() || void 0,
|
|
16485
|
-
options.principalOverride,
|
|
16486
|
-
caps,
|
|
16487
|
-
namespacesEnabled
|
|
16488
|
-
);
|
|
16489
|
-
} catch (err) {
|
|
16490
|
-
log.debug(`direct-answer observation setup failed: ${err}`);
|
|
16491
|
-
}
|
|
16492
|
-
}
|
|
16493
|
-
return recallResult;
|
|
16494
|
-
} catch (err) {
|
|
16495
|
-
this.logRecallFailure(err);
|
|
16496
|
-
this.profiler.endTrace();
|
|
16497
|
-
return "";
|
|
16498
|
-
} finally {
|
|
16499
|
-
options.abortSignal?.removeEventListener("abort", onAbort);
|
|
16500
|
-
}
|
|
16434
|
+
return (this.recallEntryCoordinator ?? new RecallEntryCoordinator(
|
|
16435
|
+
selfDeps(this)
|
|
16436
|
+
)).recall(
|
|
16437
|
+
prompt,
|
|
16438
|
+
sessionKey,
|
|
16439
|
+
options
|
|
16440
|
+
);
|
|
16501
16441
|
}
|
|
16502
16442
|
/**
|
|
16503
16443
|
* Return the most recent X-ray snapshot captured during a
|
|
@@ -16540,23 +16480,11 @@ ${doc.content}` : doc.content,
|
|
|
16540
16480
|
);
|
|
16541
16481
|
}
|
|
16542
16482
|
logRecallFailure(err) {
|
|
16543
|
-
|
|
16544
|
-
|
|
16545
|
-
|
|
16546
|
-
|
|
16547
|
-
|
|
16548
|
-
if (idleSinceLastFailureMs >= LOG_WINDOW_MS) {
|
|
16549
|
-
this.suppressedRecallFailures = 0;
|
|
16550
|
-
}
|
|
16551
|
-
if (now - this.lastRecallFailureLogAtMs >= LOG_WINDOW_MS) {
|
|
16552
|
-
const suffix = this.suppressedRecallFailures > 0 ? ` (suppressed ${this.suppressedRecallFailures} similar failures in last minute)` : "";
|
|
16553
|
-
log.warn(`recall timed out or failed: ${errorMsg}${suffix}`);
|
|
16554
|
-
this.lastRecallFailureLogAtMs = now;
|
|
16555
|
-
this.suppressedRecallFailures = 0;
|
|
16556
|
-
return;
|
|
16557
|
-
}
|
|
16558
|
-
this.suppressedRecallFailures += 1;
|
|
16559
|
-
log.debug(`recall timed out or failed (suppressed): ${errorMsg}`);
|
|
16483
|
+
return (this.recallEntryCoordinator ?? new RecallEntryCoordinator(
|
|
16484
|
+
selfDeps(this)
|
|
16485
|
+
)).logRecallFailure(
|
|
16486
|
+
err
|
|
16487
|
+
);
|
|
16560
16488
|
}
|
|
16561
16489
|
artifactTypeForCategory(category) {
|
|
16562
16490
|
if (category === "decision") return "decision";
|
|
@@ -16828,6 +16756,35 @@ ${doc.content}` : doc.content,
|
|
|
16828
16756
|
}
|
|
16829
16757
|
return this._namespaceReadFanoutCoordinator;
|
|
16830
16758
|
}
|
|
16759
|
+
/** RecallEntryCoordinator (issue #1526 seam 28). Lazy; selfDeps live wiring. */
|
|
16760
|
+
_recallEntryCoordinator;
|
|
16761
|
+
get recallEntryCoordinator() {
|
|
16762
|
+
if (!this._recallEntryCoordinator) {
|
|
16763
|
+
this._recallEntryCoordinator = new RecallEntryCoordinator(
|
|
16764
|
+
selfDeps(this)
|
|
16765
|
+
);
|
|
16766
|
+
}
|
|
16767
|
+
return this._recallEntryCoordinator;
|
|
16768
|
+
}
|
|
16769
|
+
/** SessionContextCoordinator (issue #1526 seam 28). Lazy; selfDeps live wiring. */
|
|
16770
|
+
_sessionContextCoordinator;
|
|
16771
|
+
/**
|
|
16772
|
+
* Self-handle read through the selfDeps proxy (seam 28): coordinators
|
|
16773
|
+
* that construct services against the orchestrator instance (e.g. the
|
|
16774
|
+
* passive-correction CorrectionService) receive it via deps instead of
|
|
16775
|
+
* capturing the coordinator's own `this`.
|
|
16776
|
+
*/
|
|
16777
|
+
get orchestratorSelf() {
|
|
16778
|
+
return this;
|
|
16779
|
+
}
|
|
16780
|
+
get sessionContextCoordinator() {
|
|
16781
|
+
if (!this._sessionContextCoordinator) {
|
|
16782
|
+
this._sessionContextCoordinator = new SessionContextCoordinator(
|
|
16783
|
+
selfDeps(this)
|
|
16784
|
+
);
|
|
16785
|
+
}
|
|
16786
|
+
return this._sessionContextCoordinator;
|
|
16787
|
+
}
|
|
16831
16788
|
async recallInternal(prompt, sessionKey, options = {}, caps = resolveCapabilities(this.config), graphCaps = resolveGraphConstructionCapabilities(this.config), lifecycleCaps = resolveMemoryLifecycleCapabilities(this.config)) {
|
|
16832
16789
|
return this.recallInternalCoordinator.recallInternal(
|
|
16833
16790
|
prompt,
|
|
@@ -16847,22 +16804,12 @@ ${doc.content}` : doc.content,
|
|
|
16847
16804
|
);
|
|
16848
16805
|
}
|
|
16849
16806
|
async flushSession(sessionKey, options) {
|
|
16850
|
-
|
|
16851
|
-
|
|
16852
|
-
|
|
16853
|
-
|
|
16854
|
-
|
|
16855
|
-
|
|
16856
|
-
await new Promise((resolve, reject) => {
|
|
16857
|
-
void this.queueBufferedExtraction(turns, "trigger_mode", {
|
|
16858
|
-
bufferKey,
|
|
16859
|
-
clearBufferAfterExtraction: true,
|
|
16860
|
-
skipDedupeCheck: true,
|
|
16861
|
-
abortSignal: options.abortSignal,
|
|
16862
|
-
onTaskSettled: (error) => error ? reject(error) : resolve()
|
|
16863
|
-
}).catch(reject);
|
|
16864
|
-
});
|
|
16865
|
-
}
|
|
16807
|
+
return (this.sessionContextCoordinator ?? new SessionContextCoordinator(
|
|
16808
|
+
selfDeps(this)
|
|
16809
|
+
)).flushSession(
|
|
16810
|
+
sessionKey,
|
|
16811
|
+
options
|
|
16812
|
+
);
|
|
16866
16813
|
}
|
|
16867
16814
|
async ingestReplayBatch(turns, options = {}) {
|
|
16868
16815
|
return this.turnIngestionCoordinator.ingestReplayBatch(
|
|
@@ -16923,52 +16870,10 @@ ${doc.content}` : doc.content,
|
|
|
16923
16870
|
opts
|
|
16924
16871
|
);
|
|
16925
16872
|
}
|
|
16926
|
-
/** Lazily construct the CorrectionService for passive capture. Stateless
|
|
16927
|
-
* across requests (per #1580 design); cached for the orchestrator's life. */
|
|
16928
16873
|
passiveCorrectionService() {
|
|
16929
|
-
|
|
16930
|
-
|
|
16931
|
-
|
|
16932
|
-
// Session-scoped write ACL (review: "passive capture bypasses write
|
|
16933
|
-
// ACL"). A correction detected in session S plans only against S readable
|
|
16934
|
-
// namespaces and applies only to writable ones (rule 42) — passive
|
|
16935
|
-
// capture never becomes a cross-tenant mutation vector. Mirrors the
|
|
16936
|
-
// access-service createCorrectionService wiring rather than bypassing it.
|
|
16937
|
-
resolveAuthorizedNamespace: async (req) => {
|
|
16938
|
-
const principal = req.principal || resolvePrincipal(req.sessionKey, this.config);
|
|
16939
|
-
const ns = req.namespace ?? defaultNamespaceForPrincipal(principal, this.config);
|
|
16940
|
-
if (!canWriteNamespace(principal, ns, this.config)) {
|
|
16941
|
-
throw new Error(
|
|
16942
|
-
`passive correction: namespace "${ns}" is not writable for principal ${principal ?? "(none)"}`
|
|
16943
|
-
);
|
|
16944
|
-
}
|
|
16945
|
-
return ns;
|
|
16946
|
-
},
|
|
16947
|
-
resolveReadableNamespaces: (req) => {
|
|
16948
|
-
const principal = req.principal || resolvePrincipal(req.sessionKey, this.config);
|
|
16949
|
-
return recallNamespacesForPrincipal(principal, this.config);
|
|
16950
|
-
},
|
|
16951
|
-
canWriteNamespace: async (req) => {
|
|
16952
|
-
const principal = req.principal || resolvePrincipal(req.sessionKey, this.config);
|
|
16953
|
-
return canWriteNamespace(principal, req.namespace, this.config);
|
|
16954
|
-
},
|
|
16955
|
-
llmComplete: async ({ system, user }) => {
|
|
16956
|
-
const llmResult = await this.localLlm.chatCompletion(
|
|
16957
|
-
[
|
|
16958
|
-
{ role: "system", content: system },
|
|
16959
|
-
{ role: "user", content: user }
|
|
16960
|
-
],
|
|
16961
|
-
{ operation: "correction-classify", priority: "background" }
|
|
16962
|
-
);
|
|
16963
|
-
if (!llmResult) {
|
|
16964
|
-
throw new Error(
|
|
16965
|
-
"passive correction classify+draft: local LLM unavailable (disabled or in cooldown)"
|
|
16966
|
-
);
|
|
16967
|
-
}
|
|
16968
|
-
return llmResult.content;
|
|
16969
|
-
}
|
|
16970
|
-
});
|
|
16971
|
-
return this._passiveCorrectionService;
|
|
16874
|
+
return (this.sessionContextCoordinator ?? new SessionContextCoordinator(
|
|
16875
|
+
selfDeps(this)
|
|
16876
|
+
)).passiveCorrectionService();
|
|
16972
16877
|
}
|
|
16973
16878
|
async runExtraction(...args) {
|
|
16974
16879
|
return this.extractionRunCoordinator.runExtraction(...args);
|
|
@@ -17156,33 +17061,17 @@ ${doc.content}` : doc.content,
|
|
|
17156
17061
|
}
|
|
17157
17062
|
}
|
|
17158
17063
|
queueEvalShadowRecall(record) {
|
|
17159
|
-
|
|
17160
|
-
|
|
17161
|
-
|
|
17162
|
-
|
|
17163
|
-
|
|
17164
|
-
memoryDir: this.config.memoryDir,
|
|
17165
|
-
evalStoreDir: this.config.evalStoreDir,
|
|
17166
|
-
record: {
|
|
17167
|
-
schemaVersion: 1,
|
|
17168
|
-
...record
|
|
17169
|
-
}
|
|
17170
|
-
});
|
|
17171
|
-
} catch (err) {
|
|
17172
|
-
log.debug(`eval shadow recall write failed: ${err}`);
|
|
17173
|
-
}
|
|
17174
|
-
});
|
|
17064
|
+
return (this.recallEntryCoordinator ?? new RecallEntryCoordinator(
|
|
17065
|
+
selfDeps(this)
|
|
17066
|
+
)).queueEvalShadowRecall(
|
|
17067
|
+
record
|
|
17068
|
+
);
|
|
17175
17069
|
}
|
|
17176
17070
|
publishRecallResults(options) {
|
|
17177
|
-
|
|
17178
|
-
|
|
17179
|
-
|
|
17180
|
-
|
|
17181
|
-
this.trackMemoryAccess(memoryIds);
|
|
17182
|
-
this.appendRecallSection(
|
|
17183
|
-
options.sectionBuckets,
|
|
17184
|
-
sectionId,
|
|
17185
|
-
this.formatQmdResults(options.title, injectable, options.sessionKey, trustByPath)
|
|
17071
|
+
return (this.recallEntryCoordinator ?? new RecallEntryCoordinator(
|
|
17072
|
+
selfDeps(this)
|
|
17073
|
+
)).publishRecallResults(
|
|
17074
|
+
options
|
|
17186
17075
|
);
|
|
17187
17076
|
}
|
|
17188
17077
|
/**
|
|
@@ -17268,12 +17157,12 @@ ${doc.content}` : doc.content,
|
|
|
17268
17157
|
*/
|
|
17269
17158
|
semanticDedupScopeFor(targetStorage) {
|
|
17270
17159
|
if (!resolveNamespaceCapabilities(this.config).namespaces) return {};
|
|
17271
|
-
const memoryDir =
|
|
17272
|
-
const storageDir =
|
|
17160
|
+
const memoryDir = path15.resolve(this.config.memoryDir);
|
|
17161
|
+
const storageDir = path15.resolve(targetStorage.dir);
|
|
17273
17162
|
if (storageDir === memoryDir) {
|
|
17274
17163
|
return { pathExcludePrefixes: ["namespaces/"] };
|
|
17275
17164
|
}
|
|
17276
|
-
let rel =
|
|
17165
|
+
let rel = path15.relative(memoryDir, storageDir);
|
|
17277
17166
|
if (!rel || rel.startsWith("..")) {
|
|
17278
17167
|
log.debug(
|
|
17279
17168
|
`semantic dedup: target storage dir ${storageDir} is outside memoryDir ${memoryDir}; scoping lookup to absolute path prefix`
|
|
@@ -17963,9 +17852,9 @@ function readStructuralSymbol(entry) {
|
|
|
17963
17852
|
const rec = entry;
|
|
17964
17853
|
const symbol = typeof rec.symbol === "string" ? rec.symbol.trim() : "";
|
|
17965
17854
|
if (!symbol) return null;
|
|
17966
|
-
const
|
|
17855
|
+
const path30 = typeof rec.path === "string" && rec.path.length > 0 ? rec.path : void 0;
|
|
17967
17856
|
const kind = typeof rec.kind === "string" && rec.kind.length > 0 ? rec.kind : void 0;
|
|
17968
|
-
const item =
|
|
17857
|
+
const item = path30 !== void 0 && kind !== void 0 ? { symbol, path: path30, kind } : path30 !== void 0 ? { symbol, path: path30 } : kind !== void 0 ? { symbol, kind } : { symbol };
|
|
17969
17858
|
return item;
|
|
17970
17859
|
}
|
|
17971
17860
|
function classifySpawnError(err) {
|
|
@@ -18039,7 +17928,7 @@ var DEFAULT_GRACE_PERIOD_DAYS = 7;
|
|
|
18039
17928
|
|
|
18040
17929
|
// src/binary-lifecycle/backend.ts
|
|
18041
17930
|
import fsp from "fs/promises";
|
|
18042
|
-
import
|
|
17931
|
+
import path16 from "path";
|
|
18043
17932
|
var FilesystemBackend = class {
|
|
18044
17933
|
type = "filesystem";
|
|
18045
17934
|
basePath;
|
|
@@ -18047,19 +17936,19 @@ var FilesystemBackend = class {
|
|
|
18047
17936
|
if (!basePath || basePath.trim().length === 0) {
|
|
18048
17937
|
throw new Error("FilesystemBackend requires a non-empty basePath");
|
|
18049
17938
|
}
|
|
18050
|
-
this.basePath =
|
|
17939
|
+
this.basePath = path16.resolve(basePath);
|
|
18051
17940
|
}
|
|
18052
17941
|
resolveRemotePath(remotePath) {
|
|
18053
|
-
const resolved =
|
|
18054
|
-
const relative =
|
|
18055
|
-
if (relative === ".." || relative.startsWith(`..${
|
|
17942
|
+
const resolved = path16.isAbsolute(remotePath) ? path16.resolve(remotePath) : path16.resolve(this.basePath, remotePath);
|
|
17943
|
+
const relative = path16.relative(this.basePath, resolved);
|
|
17944
|
+
if (relative === ".." || relative.startsWith(`..${path16.sep}`) || path16.isAbsolute(relative)) {
|
|
18056
17945
|
throw new Error(`FilesystemBackend remotePath escapes basePath: ${JSON.stringify(remotePath)}`);
|
|
18057
17946
|
}
|
|
18058
17947
|
return resolved;
|
|
18059
17948
|
}
|
|
18060
17949
|
isInsideBase(candidate, realBase) {
|
|
18061
|
-
const relative =
|
|
18062
|
-
return relative === "" || relative !== ".." && !relative.startsWith(`..${
|
|
17950
|
+
const relative = path16.relative(realBase, candidate);
|
|
17951
|
+
return relative === "" || relative !== ".." && !relative.startsWith(`..${path16.sep}`) && !path16.isAbsolute(relative);
|
|
18063
17952
|
}
|
|
18064
17953
|
async realBasePathIfExists() {
|
|
18065
17954
|
try {
|
|
@@ -18088,13 +17977,13 @@ var FilesystemBackend = class {
|
|
|
18088
17977
|
}
|
|
18089
17978
|
async ensureSafeParentDirectory(dest) {
|
|
18090
17979
|
const realBase = await this.ensureBaseDirectory();
|
|
18091
|
-
const destDir =
|
|
18092
|
-
const relativeDir =
|
|
18093
|
-
const segments = relativeDir === "" ? [] : relativeDir.split(
|
|
17980
|
+
const destDir = path16.dirname(dest);
|
|
17981
|
+
const relativeDir = path16.relative(this.basePath, destDir);
|
|
17982
|
+
const segments = relativeDir === "" ? [] : relativeDir.split(path16.sep);
|
|
18094
17983
|
let current = this.basePath;
|
|
18095
17984
|
for (const segment of segments) {
|
|
18096
17985
|
if (segment === "." || segment === "") continue;
|
|
18097
|
-
current =
|
|
17986
|
+
current = path16.join(current, segment);
|
|
18098
17987
|
try {
|
|
18099
17988
|
const stat5 = await fsp.lstat(current);
|
|
18100
17989
|
if (stat5.isSymbolicLink()) {
|
|
@@ -18122,13 +18011,13 @@ var FilesystemBackend = class {
|
|
|
18122
18011
|
if (realBase === null) {
|
|
18123
18012
|
return null;
|
|
18124
18013
|
}
|
|
18125
|
-
const destDir =
|
|
18126
|
-
const relativeDir =
|
|
18127
|
-
const segments = relativeDir === "" ? [] : relativeDir.split(
|
|
18014
|
+
const destDir = path16.dirname(dest);
|
|
18015
|
+
const relativeDir = path16.relative(this.basePath, destDir);
|
|
18016
|
+
const segments = relativeDir === "" ? [] : relativeDir.split(path16.sep);
|
|
18128
18017
|
let current = this.basePath;
|
|
18129
18018
|
for (const segment of segments) {
|
|
18130
18019
|
if (segment === "." || segment === "") continue;
|
|
18131
|
-
current =
|
|
18020
|
+
current = path16.join(current, segment);
|
|
18132
18021
|
let stat5;
|
|
18133
18022
|
try {
|
|
18134
18023
|
stat5 = await fsp.lstat(current);
|
|
@@ -18176,7 +18065,7 @@ var FilesystemBackend = class {
|
|
|
18176
18065
|
return dest;
|
|
18177
18066
|
}
|
|
18178
18067
|
async upload(localPath, remotePath) {
|
|
18179
|
-
if (
|
|
18068
|
+
if (path16.isAbsolute(remotePath)) {
|
|
18180
18069
|
throw new Error(`FilesystemBackend upload remotePath must be relative: ${JSON.stringify(remotePath)}`);
|
|
18181
18070
|
}
|
|
18182
18071
|
const dest = this.resolveRemotePath(remotePath);
|
|
@@ -18249,7 +18138,7 @@ function createBackend(cfg) {
|
|
|
18249
18138
|
|
|
18250
18139
|
// src/binary-lifecycle/scanner.ts
|
|
18251
18140
|
import fsp2 from "fs/promises";
|
|
18252
|
-
import
|
|
18141
|
+
import path17 from "path";
|
|
18253
18142
|
import crypto from "crypto";
|
|
18254
18143
|
function matchesPatterns(filename, patterns) {
|
|
18255
18144
|
const lower = filename.toLowerCase();
|
|
@@ -18274,8 +18163,8 @@ async function scanForBinaries(memoryDir, config, manifest) {
|
|
|
18274
18163
|
return;
|
|
18275
18164
|
}
|
|
18276
18165
|
for (const entry of entries) {
|
|
18277
|
-
const fullPath =
|
|
18278
|
-
const relativePath =
|
|
18166
|
+
const fullPath = path17.join(dir, entry.name);
|
|
18167
|
+
const relativePath = path17.relative(memoryDir, fullPath).split(path17.sep).join("/");
|
|
18279
18168
|
if (entry.isDirectory()) {
|
|
18280
18169
|
if (entry.name === ".binary-lifecycle") continue;
|
|
18281
18170
|
await walk(fullPath);
|
|
@@ -18315,15 +18204,15 @@ async function hashFile(filePath) {
|
|
|
18315
18204
|
|
|
18316
18205
|
// src/binary-lifecycle/manifest.ts
|
|
18317
18206
|
import fsp3 from "fs/promises";
|
|
18318
|
-
import
|
|
18207
|
+
import path18 from "path";
|
|
18319
18208
|
import crypto2 from "crypto";
|
|
18320
18209
|
var MANIFEST_DIR = ".binary-lifecycle";
|
|
18321
18210
|
var MANIFEST_FILE = "manifest.json";
|
|
18322
18211
|
function manifestDir(memoryDir) {
|
|
18323
|
-
return
|
|
18212
|
+
return path18.join(memoryDir, MANIFEST_DIR);
|
|
18324
18213
|
}
|
|
18325
18214
|
function manifestPath(memoryDir) {
|
|
18326
|
-
return
|
|
18215
|
+
return path18.join(memoryDir, MANIFEST_DIR, MANIFEST_FILE);
|
|
18327
18216
|
}
|
|
18328
18217
|
async function readManifest(memoryDir) {
|
|
18329
18218
|
const filePath = manifestPath(memoryDir);
|
|
@@ -18375,7 +18264,7 @@ function emptyManifest() {
|
|
|
18375
18264
|
|
|
18376
18265
|
// src/binary-lifecycle/pipeline.ts
|
|
18377
18266
|
import fsp4 from "fs/promises";
|
|
18378
|
-
import
|
|
18267
|
+
import path19 from "path";
|
|
18379
18268
|
import crypto3 from "crypto";
|
|
18380
18269
|
async function hashFile2(filePath) {
|
|
18381
18270
|
const content = await fsp4.readFile(filePath);
|
|
@@ -18398,13 +18287,13 @@ function escapeRegex(s) {
|
|
|
18398
18287
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
18399
18288
|
}
|
|
18400
18289
|
function resolveManifestAssetPath(memoryDir, originalPath) {
|
|
18401
|
-
if (originalPath.length === 0 || originalPath.includes("\0") || originalPath.includes("\\") ||
|
|
18290
|
+
if (originalPath.length === 0 || originalPath.includes("\0") || originalPath.includes("\\") || path19.isAbsolute(originalPath) || path19.win32.isAbsolute(originalPath)) {
|
|
18402
18291
|
return null;
|
|
18403
18292
|
}
|
|
18404
|
-
const memoryRoot =
|
|
18405
|
-
const fullPath =
|
|
18406
|
-
const relative =
|
|
18407
|
-
if (relative === "" || relative === ".." || relative.startsWith(`..${
|
|
18293
|
+
const memoryRoot = path19.resolve(memoryDir);
|
|
18294
|
+
const fullPath = path19.resolve(memoryRoot, originalPath);
|
|
18295
|
+
const relative = path19.relative(memoryRoot, fullPath);
|
|
18296
|
+
if (relative === "" || relative === ".." || relative.startsWith(`..${path19.sep}`) || path19.isAbsolute(relative)) {
|
|
18408
18297
|
return null;
|
|
18409
18298
|
}
|
|
18410
18299
|
return fullPath;
|
|
@@ -18415,7 +18304,7 @@ function validateBinaryLifecycleConfig(config) {
|
|
|
18415
18304
|
}
|
|
18416
18305
|
}
|
|
18417
18306
|
function remotePathForAsset(backend, relPath) {
|
|
18418
|
-
const normalized = relPath.split(
|
|
18307
|
+
const normalized = relPath.split(path19.sep).join("/");
|
|
18419
18308
|
if (backend.type === "filesystem") {
|
|
18420
18309
|
return `.binary-lifecycle/mirrors/${normalized}`;
|
|
18421
18310
|
}
|
|
@@ -18428,11 +18317,11 @@ async function stageMirror(memoryDir, newPaths, backend, assets, log2, dryRun) {
|
|
|
18428
18317
|
let mirrored = 0;
|
|
18429
18318
|
const errors = [];
|
|
18430
18319
|
for (const relPath of newPaths) {
|
|
18431
|
-
const fullPath =
|
|
18320
|
+
const fullPath = path19.join(memoryDir, relPath);
|
|
18432
18321
|
try {
|
|
18433
18322
|
const stat5 = await fsp4.stat(fullPath);
|
|
18434
18323
|
const contentHash = await hashFile2(fullPath);
|
|
18435
|
-
const ext =
|
|
18324
|
+
const ext = path19.extname(relPath);
|
|
18436
18325
|
const mimeType = guessMimeType(ext);
|
|
18437
18326
|
const remotePath = remotePathForAsset(backend, relPath);
|
|
18438
18327
|
let backendLocation = remotePath;
|
|
@@ -18632,10 +18521,10 @@ async function countRemainingLocalReferences(memoryDir, asset, assetAbsolute, md
|
|
|
18632
18521
|
return { remaining, errors };
|
|
18633
18522
|
}
|
|
18634
18523
|
function markdownReferencePattern(asset, assetAbsolute, mdPath) {
|
|
18635
|
-
const mdDir =
|
|
18524
|
+
const mdDir = path19.dirname(mdPath);
|
|
18636
18525
|
const candidates = /* @__PURE__ */ new Set();
|
|
18637
18526
|
const addCandidate = (candidate) => {
|
|
18638
|
-
const normalized = candidate.split(
|
|
18527
|
+
const normalized = candidate.split(path19.sep).join("/");
|
|
18639
18528
|
if (normalized.length === 0) return;
|
|
18640
18529
|
candidates.add(normalized);
|
|
18641
18530
|
const isParentTraversal = normalized === ".." || normalized.startsWith("../");
|
|
@@ -18643,10 +18532,10 @@ function markdownReferencePattern(asset, assetAbsolute, mdPath) {
|
|
|
18643
18532
|
candidates.add(`./${normalized}`);
|
|
18644
18533
|
}
|
|
18645
18534
|
};
|
|
18646
|
-
addCandidate(
|
|
18647
|
-
const originalPath = asset.originalPath.split(
|
|
18648
|
-
const originalAsFileRelative =
|
|
18649
|
-
if (
|
|
18535
|
+
addCandidate(path19.relative(mdDir, assetAbsolute));
|
|
18536
|
+
const originalPath = asset.originalPath.split(path19.sep).join("/");
|
|
18537
|
+
const originalAsFileRelative = path19.resolve(mdDir, ...originalPath.split("/"));
|
|
18538
|
+
if (path19.resolve(originalAsFileRelative) === path19.resolve(assetAbsolute)) {
|
|
18650
18539
|
addCandidate(originalPath);
|
|
18651
18540
|
}
|
|
18652
18541
|
addCandidate(`/${originalPath}`);
|
|
@@ -18742,7 +18631,7 @@ async function findMarkdownFiles(dir) {
|
|
|
18742
18631
|
return;
|
|
18743
18632
|
}
|
|
18744
18633
|
for (const entry of entries) {
|
|
18745
|
-
const full =
|
|
18634
|
+
const full = path19.join(current, entry.name);
|
|
18746
18635
|
if (entry.isDirectory()) {
|
|
18747
18636
|
if (entry.name === ".binary-lifecycle") continue;
|
|
18748
18637
|
await walk(full);
|
|
@@ -18817,7 +18706,7 @@ async function runBinaryLifecyclePipeline(memoryDir, config, backend, log2, opts
|
|
|
18817
18706
|
|
|
18818
18707
|
// src/projection/index.ts
|
|
18819
18708
|
import fs from "fs";
|
|
18820
|
-
import
|
|
18709
|
+
import path20 from "path";
|
|
18821
18710
|
var VALID_PROJECTION_CATEGORIES = new Set(ALL_CATEGORY_KEYS);
|
|
18822
18711
|
async function generateContextTree(options) {
|
|
18823
18712
|
const startTime = Date.now();
|
|
@@ -18832,8 +18721,8 @@ async function generateContextTree(options) {
|
|
|
18832
18721
|
let nodesGenerated = 0;
|
|
18833
18722
|
let nodesSkipped = 0;
|
|
18834
18723
|
const categoryCounts = {};
|
|
18835
|
-
const resolvedMemoryDir =
|
|
18836
|
-
const resolvedOutputDir =
|
|
18724
|
+
const resolvedMemoryDir = path20.resolve(memoryDir);
|
|
18725
|
+
const resolvedOutputDir = path20.resolve(outputDir);
|
|
18837
18726
|
const requestedCategories = validateProjectionCategories(filterCategories);
|
|
18838
18727
|
const realMemoryDir = assertSafeMemoryRoot(resolvedMemoryDir);
|
|
18839
18728
|
assertNotSymlink(resolvedOutputDir, "context tree outputDir");
|
|
@@ -18871,7 +18760,7 @@ async function generateContextTree(options) {
|
|
|
18871
18760
|
}
|
|
18872
18761
|
}
|
|
18873
18762
|
if (includeEntities) {
|
|
18874
|
-
const entitiesDir =
|
|
18763
|
+
const entitiesDir = path20.join(memoryDir, "entities");
|
|
18875
18764
|
if (fs.existsSync(entitiesDir)) {
|
|
18876
18765
|
assertSafeInputRoot(realMemoryDir, entitiesDir, "entities root");
|
|
18877
18766
|
categoryCounts["entity"] = 0;
|
|
@@ -18883,7 +18772,7 @@ async function generateContextTree(options) {
|
|
|
18883
18772
|
continue;
|
|
18884
18773
|
}
|
|
18885
18774
|
const content = fs.readFileSync(filePath, "utf8");
|
|
18886
|
-
const fileName =
|
|
18775
|
+
const fileName = path20.basename(filePath, ".md");
|
|
18887
18776
|
const node = projectEntityNode(fileName, content);
|
|
18888
18777
|
const outputPath = resolveContainedOutputPath(realOutputDir, "entities", `${fileName}.md`);
|
|
18889
18778
|
writeProjectedContent(realOutputDir, outputPath, node.content);
|
|
@@ -18895,7 +18784,7 @@ async function generateContextTree(options) {
|
|
|
18895
18784
|
}
|
|
18896
18785
|
const shouldIncludeQuestions = includeQuestions && (requestedCategories === void 0 || requestedCategories.includes("question"));
|
|
18897
18786
|
if (shouldIncludeQuestions) {
|
|
18898
|
-
const questionsDir =
|
|
18787
|
+
const questionsDir = path20.join(memoryDir, "questions");
|
|
18899
18788
|
if (fs.existsSync(questionsDir)) {
|
|
18900
18789
|
assertSafeInputRoot(realMemoryDir, questionsDir, "questions root");
|
|
18901
18790
|
categoryCounts["question"] = 0;
|
|
@@ -18936,8 +18825,8 @@ async function generateContextTree(options) {
|
|
|
18936
18825
|
};
|
|
18937
18826
|
}
|
|
18938
18827
|
function isPathInside(root, candidate) {
|
|
18939
|
-
const relative =
|
|
18940
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
18828
|
+
const relative = path20.relative(root, candidate);
|
|
18829
|
+
return relative === "" || !relative.startsWith("..") && !path20.isAbsolute(relative);
|
|
18941
18830
|
}
|
|
18942
18831
|
function assertNotSymlink(targetPath, label) {
|
|
18943
18832
|
try {
|
|
@@ -18974,12 +18863,12 @@ function assertSafeInputRoot(realMemoryDir, targetPath, label) {
|
|
|
18974
18863
|
}
|
|
18975
18864
|
function assertSafeOutputTarget(realOutputDir, outputPath) {
|
|
18976
18865
|
let current = realOutputDir;
|
|
18977
|
-
const relative =
|
|
18978
|
-
if (relative.startsWith("..") ||
|
|
18866
|
+
const relative = path20.relative(realOutputDir, outputPath);
|
|
18867
|
+
if (relative.startsWith("..") || path20.isAbsolute(relative)) {
|
|
18979
18868
|
throw new Error(`context tree output path escapes outputDir: ${outputPath}`);
|
|
18980
18869
|
}
|
|
18981
|
-
for (const segment of relative.split(
|
|
18982
|
-
current =
|
|
18870
|
+
for (const segment of relative.split(path20.sep).filter(Boolean)) {
|
|
18871
|
+
current = path20.join(current, segment);
|
|
18983
18872
|
try {
|
|
18984
18873
|
const stat5 = fs.lstatSync(current);
|
|
18985
18874
|
if (stat5.isSymbolicLink()) {
|
|
@@ -19009,17 +18898,17 @@ function validateProjectionCategories(categories) {
|
|
|
19009
18898
|
return validated;
|
|
19010
18899
|
}
|
|
19011
18900
|
function resolveContainedOutputPath(outputRoot, ...segments) {
|
|
19012
|
-
const resolved =
|
|
19013
|
-
const relative =
|
|
19014
|
-
if (relative === "" || !relative.startsWith("..") && !
|
|
18901
|
+
const resolved = path20.resolve(outputRoot, ...segments);
|
|
18902
|
+
const relative = path20.relative(outputRoot, resolved);
|
|
18903
|
+
if (relative === "" || !relative.startsWith("..") && !path20.isAbsolute(relative)) {
|
|
19015
18904
|
return resolved;
|
|
19016
18905
|
}
|
|
19017
18906
|
throw new Error(`context tree output path escapes outputDir: ${segments.join("/")}`);
|
|
19018
18907
|
}
|
|
19019
18908
|
function writeProjectedContent(realOutputDir, outputPath, generatedContent) {
|
|
19020
18909
|
assertSafeOutputTarget(realOutputDir, outputPath);
|
|
19021
|
-
fs.mkdirSync(
|
|
19022
|
-
const realParent = fs.realpathSync(
|
|
18910
|
+
fs.mkdirSync(path20.dirname(outputPath), { recursive: true });
|
|
18911
|
+
const realParent = fs.realpathSync(path20.dirname(outputPath));
|
|
19023
18912
|
if (!isPathInside(realOutputDir, realParent)) {
|
|
19024
18913
|
throw new Error(`context tree output path escapes outputDir: ${outputPath}`);
|
|
19025
18914
|
}
|
|
@@ -19058,7 +18947,7 @@ function walkR(dir, realMemoryDir) {
|
|
|
19058
18947
|
const results = [];
|
|
19059
18948
|
function walk(directory) {
|
|
19060
18949
|
for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
|
|
19061
|
-
const fullPath =
|
|
18950
|
+
const fullPath = path20.join(directory, entry.name);
|
|
19062
18951
|
if (entry.isSymbolicLink()) {
|
|
19063
18952
|
throw new Error(`context tree input path contains symlink: ${fullPath}`);
|
|
19064
18953
|
}
|
|
@@ -19111,13 +19000,13 @@ function extractBody(content) {
|
|
|
19111
19000
|
}
|
|
19112
19001
|
function projectNode(filePath, category, fm, rawContent) {
|
|
19113
19002
|
const body = extractBody(rawContent);
|
|
19114
|
-
const fileName =
|
|
19115
|
-
const dateDir =
|
|
19003
|
+
const fileName = path20.basename(filePath, ".md");
|
|
19004
|
+
const dateDir = path20.basename(path20.dirname(filePath));
|
|
19116
19005
|
let relPath;
|
|
19117
19006
|
if (/^\d{4}-\d{2}-\d{2}$/.test(dateDir)) {
|
|
19118
|
-
relPath =
|
|
19007
|
+
relPath = path20.join(category, dateDir, `${fileName}.md`);
|
|
19119
19008
|
} else {
|
|
19120
|
-
relPath =
|
|
19009
|
+
relPath = path20.join(category, `${fileName}.md`);
|
|
19121
19010
|
}
|
|
19122
19011
|
const generatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
19123
19012
|
const md = `# ${fm.id}
|
|
@@ -19163,7 +19052,7 @@ function projectEntityNode(fileName, content) {
|
|
|
19163
19052
|
${content}
|
|
19164
19053
|
`;
|
|
19165
19054
|
return {
|
|
19166
|
-
path:
|
|
19055
|
+
path: path20.join("entities", `${fileName}.md`),
|
|
19167
19056
|
category: "entity",
|
|
19168
19057
|
title: fileName,
|
|
19169
19058
|
content: md,
|
|
@@ -19216,7 +19105,7 @@ function generateIndex(categoryCounts, outputDir) {
|
|
|
19216
19105
|
|
|
19217
19106
|
// src/onboarding/index.ts
|
|
19218
19107
|
import fs2 from "fs";
|
|
19219
|
-
import
|
|
19108
|
+
import path21 from "path";
|
|
19220
19109
|
var LANGUAGE_RULES = [
|
|
19221
19110
|
{
|
|
19222
19111
|
language: "TypeScript",
|
|
@@ -19318,7 +19207,7 @@ function onboard(options) {
|
|
|
19318
19207
|
maxDepth = 6,
|
|
19319
19208
|
excludeDirs = []
|
|
19320
19209
|
} = options;
|
|
19321
|
-
const directory =
|
|
19210
|
+
const directory = path21.resolve(options.directory ?? process.cwd());
|
|
19322
19211
|
let rootStat;
|
|
19323
19212
|
try {
|
|
19324
19213
|
rootStat = fs2.statSync(directory);
|
|
@@ -19360,7 +19249,7 @@ function walkDir(root, exclude, maxDepth) {
|
|
|
19360
19249
|
}
|
|
19361
19250
|
for (const entry of entries) {
|
|
19362
19251
|
if (exclude.has(entry.name)) continue;
|
|
19363
|
-
const fullPath =
|
|
19252
|
+
const fullPath = path21.join(dir, entry.name);
|
|
19364
19253
|
if (entry.isDirectory()) {
|
|
19365
19254
|
walk(fullPath, depth + 1);
|
|
19366
19255
|
} else if (entry.isFile()) {
|
|
@@ -19375,11 +19264,11 @@ function detectLanguages(files, root) {
|
|
|
19375
19264
|
const results = [];
|
|
19376
19265
|
const extCounts = /* @__PURE__ */ new Map();
|
|
19377
19266
|
for (const f of files) {
|
|
19378
|
-
const ext =
|
|
19267
|
+
const ext = path21.extname(f).toLowerCase();
|
|
19379
19268
|
if (ext) extCounts.set(ext, (extCounts.get(ext) ?? 0) + 1);
|
|
19380
19269
|
}
|
|
19381
19270
|
const rootFiles = new Set(
|
|
19382
|
-
files.filter((f) =>
|
|
19271
|
+
files.filter((f) => path21.dirname(f) === root).map((f) => path21.basename(f))
|
|
19383
19272
|
);
|
|
19384
19273
|
for (const rule of LANGUAGE_RULES) {
|
|
19385
19274
|
const evidence = [];
|
|
@@ -19423,7 +19312,7 @@ function detectLanguages(files, root) {
|
|
|
19423
19312
|
}
|
|
19424
19313
|
function detectShape(files, root) {
|
|
19425
19314
|
const rootFiles = new Set(
|
|
19426
|
-
files.filter((f) =>
|
|
19315
|
+
files.filter((f) => path21.dirname(f) === root).map((f) => path21.basename(f))
|
|
19427
19316
|
);
|
|
19428
19317
|
const rootDirs = /* @__PURE__ */ new Set();
|
|
19429
19318
|
try {
|
|
@@ -19434,7 +19323,7 @@ function detectShape(files, root) {
|
|
|
19434
19323
|
}
|
|
19435
19324
|
const evidence = [];
|
|
19436
19325
|
if (rootFiles.has("package.json")) {
|
|
19437
|
-
const pkg = readJsonSafe(
|
|
19326
|
+
const pkg = readJsonSafe(path21.join(root, "package.json"));
|
|
19438
19327
|
if (pkg?.workspaces) {
|
|
19439
19328
|
evidence.push("package.json has workspaces");
|
|
19440
19329
|
return { shape: "monorepo", evidence };
|
|
@@ -19448,13 +19337,13 @@ function detectShape(files, root) {
|
|
|
19448
19337
|
evidence.push("workspace manifest found");
|
|
19449
19338
|
return { shape: "workspace", evidence };
|
|
19450
19339
|
}
|
|
19451
|
-
const cargoToml = readTomlWorkspace(
|
|
19340
|
+
const cargoToml = readTomlWorkspace(path21.join(root, "Cargo.toml"));
|
|
19452
19341
|
if (cargoToml) {
|
|
19453
19342
|
evidence.push("Cargo.toml has workspace");
|
|
19454
19343
|
return { shape: "workspace", evidence };
|
|
19455
19344
|
}
|
|
19456
19345
|
if (rootFiles.has("package.json")) {
|
|
19457
|
-
const pkg = readJsonSafe(
|
|
19346
|
+
const pkg = readJsonSafe(path21.join(root, "package.json"));
|
|
19458
19347
|
if (pkg?.exports || pkg?.main) {
|
|
19459
19348
|
if (pkg?.bin) {
|
|
19460
19349
|
evidence.push("package.json has bin");
|
|
@@ -19488,8 +19377,8 @@ function discoverDocs(files, root) {
|
|
|
19488
19377
|
{ pattern: /^\.editorconfig$/i, kind: "config" }
|
|
19489
19378
|
];
|
|
19490
19379
|
for (const filePath of files) {
|
|
19491
|
-
const basename =
|
|
19492
|
-
const relPath =
|
|
19380
|
+
const basename = path21.basename(filePath).toLowerCase();
|
|
19381
|
+
const relPath = path21.relative(root, filePath);
|
|
19493
19382
|
let kind;
|
|
19494
19383
|
for (const { pattern, kind: k } of docPatterns) {
|
|
19495
19384
|
if (pattern.test(basename)) {
|
|
@@ -19501,7 +19390,7 @@ function discoverDocs(files, root) {
|
|
|
19501
19390
|
kind = "docs";
|
|
19502
19391
|
}
|
|
19503
19392
|
if (!kind && (basename.endsWith(".md") || basename.endsWith(".mdx"))) {
|
|
19504
|
-
if (
|
|
19393
|
+
if (path21.dirname(relPath) === "." || isUnderDocsDir(relPath)) {
|
|
19505
19394
|
kind = "docs";
|
|
19506
19395
|
}
|
|
19507
19396
|
}
|
|
@@ -19522,7 +19411,7 @@ function discoverDocs(files, root) {
|
|
|
19522
19411
|
return docs;
|
|
19523
19412
|
}
|
|
19524
19413
|
function isUnderDocsDir(relPath) {
|
|
19525
|
-
const parts = relPath.split(
|
|
19414
|
+
const parts = relPath.split(path21.sep);
|
|
19526
19415
|
return parts[0] === "docs" || parts[0] === "doc" || parts[0] === "documentation";
|
|
19527
19416
|
}
|
|
19528
19417
|
function buildPlan(languages, shape, docs, _root) {
|
|
@@ -19566,7 +19455,7 @@ function readTomlWorkspace(filePath) {
|
|
|
19566
19455
|
|
|
19567
19456
|
// src/curation/index.ts
|
|
19568
19457
|
import fs3 from "fs";
|
|
19569
|
-
import
|
|
19458
|
+
import path22 from "path";
|
|
19570
19459
|
import crypto4 from "crypto";
|
|
19571
19460
|
async function curate(options) {
|
|
19572
19461
|
const startTime = Date.now();
|
|
@@ -19657,12 +19546,12 @@ function resolveTargets(targetPath) {
|
|
|
19657
19546
|
const extensions = /* @__PURE__ */ new Set([".md", ".txt", ".mdx", ".rst"]);
|
|
19658
19547
|
function walk(dir) {
|
|
19659
19548
|
for (const entry of fs3.readdirSync(dir, { withFileTypes: true })) {
|
|
19660
|
-
const fullPath =
|
|
19549
|
+
const fullPath = path22.join(dir, entry.name);
|
|
19661
19550
|
if (entry.isDirectory()) {
|
|
19662
19551
|
if (entry.name !== "node_modules" && entry.name !== ".git") {
|
|
19663
19552
|
walk(fullPath);
|
|
19664
19553
|
}
|
|
19665
|
-
} else if (extensions.has(
|
|
19554
|
+
} else if (extensions.has(path22.extname(entry.name).toLowerCase())) {
|
|
19666
19555
|
results.push(fullPath);
|
|
19667
19556
|
}
|
|
19668
19557
|
}
|
|
@@ -19671,12 +19560,12 @@ function resolveTargets(targetPath) {
|
|
|
19671
19560
|
return results;
|
|
19672
19561
|
}
|
|
19673
19562
|
function resolveProvenanceRoot(targetPath) {
|
|
19674
|
-
const resolvedTarget =
|
|
19563
|
+
const resolvedTarget = path22.resolve(targetPath);
|
|
19675
19564
|
const stat5 = fs3.statSync(resolvedTarget);
|
|
19676
|
-
return stat5.isFile() ?
|
|
19565
|
+
return stat5.isFile() ? path22.dirname(resolvedTarget) : resolvedTarget;
|
|
19677
19566
|
}
|
|
19678
19567
|
function extractStatements(content, filePath, projectRoot, source, sourceFileHash, categoryOverride, confidence, entityRef, tags) {
|
|
19679
|
-
const relativePath =
|
|
19568
|
+
const relativePath = path22.relative(projectRoot, path22.resolve(filePath)) || path22.basename(filePath);
|
|
19680
19569
|
const statements = [];
|
|
19681
19570
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
19682
19571
|
const paragraphs = content.split(/\n{2,}/).map((p) => p.trim()).filter((p) => p.length > 20 && p.length < 2e3);
|
|
@@ -19770,7 +19659,7 @@ function loadExistingMemories(memoryDir) {
|
|
|
19770
19659
|
if (!fs3.existsSync(memoryDir)) return result;
|
|
19771
19660
|
const dirs = ALL_CATEGORY_DIRS;
|
|
19772
19661
|
for (const dir of dirs) {
|
|
19773
|
-
const fullDir =
|
|
19662
|
+
const fullDir = path22.join(memoryDir, dir);
|
|
19774
19663
|
if (!fs3.existsSync(fullDir)) continue;
|
|
19775
19664
|
walkFiles(fullDir, (filePath) => {
|
|
19776
19665
|
const content = readFileSafe(filePath);
|
|
@@ -19792,10 +19681,10 @@ function writeStatement(stmt, memoryDir) {
|
|
|
19792
19681
|
const now = /* @__PURE__ */ new Date();
|
|
19793
19682
|
const dateDir = now.toISOString().split("T")[0];
|
|
19794
19683
|
const categoryDir = getCategoryDir(memoryDir, stmt.category);
|
|
19795
|
-
const dir =
|
|
19684
|
+
const dir = path22.join(categoryDir, dateDir);
|
|
19796
19685
|
fs3.mkdirSync(dir, { recursive: true });
|
|
19797
19686
|
const fileName = `${stmt.category}-${Date.now()}-${stmt.id.slice(0, 8)}.md`;
|
|
19798
|
-
const filePath =
|
|
19687
|
+
const filePath = path22.join(dir, fileName);
|
|
19799
19688
|
const frontmatter = [
|
|
19800
19689
|
"---",
|
|
19801
19690
|
`id: ${stmt.id}`,
|
|
@@ -19862,7 +19751,7 @@ function extractBody2(content) {
|
|
|
19862
19751
|
}
|
|
19863
19752
|
function walkFiles(dir, callback) {
|
|
19864
19753
|
for (const entry of fs3.readdirSync(dir, { withFileTypes: true })) {
|
|
19865
|
-
const fullPath =
|
|
19754
|
+
const fullPath = path22.join(dir, entry.name);
|
|
19866
19755
|
if (entry.isDirectory()) {
|
|
19867
19756
|
walkFiles(fullPath, callback);
|
|
19868
19757
|
} else if (entry.name.endsWith(".md")) {
|
|
@@ -19873,7 +19762,7 @@ function walkFiles(dir, callback) {
|
|
|
19873
19762
|
|
|
19874
19763
|
// src/dedup/index.ts
|
|
19875
19764
|
import fs4 from "fs";
|
|
19876
|
-
import
|
|
19765
|
+
import path23 from "path";
|
|
19877
19766
|
import crypto5 from "crypto";
|
|
19878
19767
|
var DEFAULT_DEDUP_THRESHOLD = 0.85;
|
|
19879
19768
|
var DEFAULT_MAX_LOAD = 1e4;
|
|
@@ -20015,7 +19904,7 @@ function loadMemories(memoryDir, categories, maxLoad = 1e4) {
|
|
|
20015
19904
|
const memoryRootReal = fs4.realpathSync(memoryDir);
|
|
20016
19905
|
for (const category of allCategories) {
|
|
20017
19906
|
if (result.length >= maxLoad) break;
|
|
20018
|
-
const dir =
|
|
19907
|
+
const dir = path23.join(memoryDir, category);
|
|
20019
19908
|
if (!fs4.existsSync(dir)) continue;
|
|
20020
19909
|
const categoryStat = fs4.lstatSync(dir);
|
|
20021
19910
|
if (categoryStat.isSymbolicLink()) {
|
|
@@ -20076,15 +19965,15 @@ function extractBody3(content) {
|
|
|
20076
19965
|
return match ? match[1].trim() : content.trim();
|
|
20077
19966
|
}
|
|
20078
19967
|
function assertPathInsideRoot2(rootReal, targetReal, sourcePath) {
|
|
20079
|
-
const rel =
|
|
20080
|
-
if (rel === "" || !rel.startsWith("..") && !
|
|
19968
|
+
const rel = path23.relative(rootReal, targetReal);
|
|
19969
|
+
if (rel === "" || !rel.startsWith("..") && !path23.isAbsolute(rel)) {
|
|
20081
19970
|
return;
|
|
20082
19971
|
}
|
|
20083
19972
|
throw new Error(`Refusing to scan memory path outside root: ${sourcePath}`);
|
|
20084
19973
|
}
|
|
20085
19974
|
function walkMdFiles(dir, memoryRootReal, categoryRootReal, callback) {
|
|
20086
19975
|
for (const entry of fs4.readdirSync(dir, { withFileTypes: true })) {
|
|
20087
|
-
const fullPath =
|
|
19976
|
+
const fullPath = path23.join(dir, entry.name);
|
|
20088
19977
|
const entryStat = fs4.lstatSync(fullPath);
|
|
20089
19978
|
if (entryStat.isSymbolicLink()) {
|
|
20090
19979
|
throw new Error(`Refusing to scan symlinked memory path: ${fullPath}`);
|
|
@@ -20102,7 +19991,7 @@ function walkMdFiles(dir, memoryRootReal, categoryRootReal, callback) {
|
|
|
20102
19991
|
|
|
20103
19992
|
// src/review/index.ts
|
|
20104
19993
|
import fs5 from "fs";
|
|
20105
|
-
import
|
|
19994
|
+
import path24 from "path";
|
|
20106
19995
|
var DEFAULT_CONFIDENCE_THRESHOLD = 0.7;
|
|
20107
19996
|
function realMemoryRoot(memoryDir) {
|
|
20108
19997
|
try {
|
|
@@ -20114,8 +20003,8 @@ function realMemoryRoot(memoryDir) {
|
|
|
20114
20003
|
}
|
|
20115
20004
|
}
|
|
20116
20005
|
function isPathInside2(rootReal, candidateReal) {
|
|
20117
|
-
const relative =
|
|
20118
|
-
return relative === "" || !!relative && !relative.startsWith("..") && !
|
|
20006
|
+
const relative = path24.relative(rootReal, candidateReal);
|
|
20007
|
+
return relative === "" || !!relative && !relative.startsWith("..") && !path24.isAbsolute(relative);
|
|
20119
20008
|
}
|
|
20120
20009
|
function isSafeDirectory(rootReal, dir) {
|
|
20121
20010
|
try {
|
|
@@ -20158,7 +20047,7 @@ function listReviewItems(options) {
|
|
|
20158
20047
|
if (filterReason && item.reviewReason !== filterReason) return;
|
|
20159
20048
|
items.push(item);
|
|
20160
20049
|
};
|
|
20161
|
-
const suggestionsDir =
|
|
20050
|
+
const suggestionsDir = path24.join(memoryDir, "suggestions");
|
|
20162
20051
|
if (!isLimitReached() && fs5.existsSync(suggestionsDir) && isSafeDirectory(rootReal, suggestionsDir)) {
|
|
20163
20052
|
walkMd(rootReal, suggestionsDir, (filePath, content) => {
|
|
20164
20053
|
if (isLimitReached()) return true;
|
|
@@ -20179,7 +20068,7 @@ function listReviewItems(options) {
|
|
|
20179
20068
|
return isLimitReached();
|
|
20180
20069
|
});
|
|
20181
20070
|
}
|
|
20182
|
-
const reviewDir =
|
|
20071
|
+
const reviewDir = path24.join(memoryDir, "review");
|
|
20183
20072
|
if (!isLimitReached() && fs5.existsSync(reviewDir) && isSafeDirectory(rootReal, reviewDir)) {
|
|
20184
20073
|
walkMd(rootReal, reviewDir, (filePath, content) => {
|
|
20185
20074
|
if (isLimitReached()) return true;
|
|
@@ -20204,7 +20093,7 @@ function listReviewItems(options) {
|
|
|
20204
20093
|
const categories = ALL_CATEGORY_DIRS;
|
|
20205
20094
|
for (const category of categories) {
|
|
20206
20095
|
if (isLimitReached()) break;
|
|
20207
|
-
const dir =
|
|
20096
|
+
const dir = path24.join(memoryDir, category);
|
|
20208
20097
|
if (!fs5.existsSync(dir) || !isSafeDirectory(rootReal, dir)) continue;
|
|
20209
20098
|
walkMd(rootReal, dir, (filePath, content) => {
|
|
20210
20099
|
if (isLimitReached()) return true;
|
|
@@ -20289,8 +20178,8 @@ function approveItem(memoryDir, itemId, options) {
|
|
|
20289
20178
|
const targetDir = getCategoryDir(memoryDir, category);
|
|
20290
20179
|
const dateDir = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
20291
20180
|
ensureSafeDirectory(rootReal, targetDir);
|
|
20292
|
-
const outputPath =
|
|
20293
|
-
ensureSafeDirectory(rootReal,
|
|
20181
|
+
const outputPath = path24.join(targetDir, dateDir, path24.basename(found.filePath));
|
|
20182
|
+
ensureSafeDirectory(rootReal, path24.dirname(outputPath));
|
|
20294
20183
|
const promotedPath = writeFileWithoutClobber(outputPath, updatedContent, itemId);
|
|
20295
20184
|
fs5.unlinkSync(found.filePath);
|
|
20296
20185
|
return {
|
|
@@ -20348,13 +20237,13 @@ function findReviewFileById(memoryDir, id, options = {}) {
|
|
|
20348
20237
|
const rootReal = realMemoryRoot(memoryDir);
|
|
20349
20238
|
if (!rootReal) return null;
|
|
20350
20239
|
for (const loc of ["suggestions", "review"]) {
|
|
20351
|
-
const dir =
|
|
20240
|
+
const dir = path24.join(memoryDir, loc);
|
|
20352
20241
|
if (!fs5.existsSync(dir) || !isSafeDirectory(rootReal, dir)) continue;
|
|
20353
20242
|
const found = findFileById(rootReal, dir, id);
|
|
20354
20243
|
if (found) return { filePath: found, location: "queue" };
|
|
20355
20244
|
}
|
|
20356
20245
|
for (const category of ALL_CATEGORY_DIRS) {
|
|
20357
|
-
const dir =
|
|
20246
|
+
const dir = path24.join(memoryDir, category);
|
|
20358
20247
|
if (!fs5.existsSync(dir) || !isSafeDirectory(rootReal, dir)) continue;
|
|
20359
20248
|
const found = findFileById(rootReal, dir, id, (fm) => isLowConfidenceReviewCandidate(fm, options));
|
|
20360
20249
|
if (found) return { filePath: found, location: "category" };
|
|
@@ -20430,10 +20319,10 @@ function readFileSafe3(filePath) {
|
|
|
20430
20319
|
}
|
|
20431
20320
|
}
|
|
20432
20321
|
function writeFileWithoutClobber(basePath, content, discriminator) {
|
|
20433
|
-
const parsed =
|
|
20322
|
+
const parsed = path24.parse(basePath);
|
|
20434
20323
|
const safeDiscriminator = sanitizeFilePart(discriminator);
|
|
20435
20324
|
for (let attempt = 0; attempt < 1e3; attempt++) {
|
|
20436
|
-
const candidate = attempt === 0 ? basePath :
|
|
20325
|
+
const candidate = attempt === 0 ? basePath : path24.join(
|
|
20437
20326
|
parsed.dir,
|
|
20438
20327
|
`${parsed.name}-${safeDiscriminator}${attempt === 1 ? "" : `-${attempt}`}${parsed.ext || ".md"}`
|
|
20439
20328
|
);
|
|
@@ -20489,7 +20378,7 @@ function extractBody4(content) {
|
|
|
20489
20378
|
function walkMd(rootReal, dir, callback) {
|
|
20490
20379
|
if (!isSafeDirectory(rootReal, dir)) return false;
|
|
20491
20380
|
for (const entry of fs5.readdirSync(dir, { withFileTypes: true })) {
|
|
20492
|
-
const fullPath =
|
|
20381
|
+
const fullPath = path24.join(dir, entry.name);
|
|
20493
20382
|
if (entry.isSymbolicLink()) continue;
|
|
20494
20383
|
if (entry.isDirectory()) {
|
|
20495
20384
|
if (walkMd(rootReal, fullPath, callback)) return true;
|
|
@@ -20504,7 +20393,7 @@ function walkMdPaths(rootReal, dir) {
|
|
|
20504
20393
|
const results = [];
|
|
20505
20394
|
if (!isSafeDirectory(rootReal, dir)) return results;
|
|
20506
20395
|
for (const entry of fs5.readdirSync(dir, { withFileTypes: true })) {
|
|
20507
|
-
const fullPath =
|
|
20396
|
+
const fullPath = path24.join(dir, entry.name);
|
|
20508
20397
|
if (entry.isSymbolicLink()) continue;
|
|
20509
20398
|
if (entry.isDirectory()) {
|
|
20510
20399
|
results.push(...walkMdPaths(rootReal, fullPath));
|
|
@@ -20517,7 +20406,7 @@ function walkMdPaths(rootReal, dir) {
|
|
|
20517
20406
|
|
|
20518
20407
|
// src/sync/index.ts
|
|
20519
20408
|
import fs6 from "fs";
|
|
20520
|
-
import
|
|
20409
|
+
import path25 from "path";
|
|
20521
20410
|
import crypto6 from "crypto";
|
|
20522
20411
|
var DEFAULT_EXTENSIONS = /* @__PURE__ */ new Set([".md", ".txt", ".mdx", ".rst"]);
|
|
20523
20412
|
var DEFAULT_EXCLUDE2 = /* @__PURE__ */ new Set([
|
|
@@ -20539,7 +20428,7 @@ function syncChanges(options) {
|
|
|
20539
20428
|
} = options;
|
|
20540
20429
|
const extSet = new Set(extensions);
|
|
20541
20430
|
const excludeSet = /* @__PURE__ */ new Set([...DEFAULT_EXCLUDE2, ...excludeDirs]);
|
|
20542
|
-
const stateFilePath = options.stateFile ??
|
|
20431
|
+
const stateFilePath = options.stateFile ?? path25.join(memoryDir, ".sync-state.json");
|
|
20543
20432
|
const prevState = loadState(stateFilePath);
|
|
20544
20433
|
const currentFiles = scanFiles(sourceDir, extSet, excludeSet);
|
|
20545
20434
|
const changes = computeDiff(currentFiles, prevState.fileHashes, sourceDir);
|
|
@@ -20555,7 +20444,7 @@ function syncChanges(options) {
|
|
|
20555
20444
|
for (const [relPath, hash] of Object.entries(currentFiles)) {
|
|
20556
20445
|
newState.fileHashes[relPath] = hash;
|
|
20557
20446
|
}
|
|
20558
|
-
fs6.mkdirSync(
|
|
20447
|
+
fs6.mkdirSync(path25.dirname(stateFilePath), { recursive: true });
|
|
20559
20448
|
fs6.writeFileSync(stateFilePath, JSON.stringify(newState, null, 2));
|
|
20560
20449
|
}
|
|
20561
20450
|
return {
|
|
@@ -20621,13 +20510,13 @@ function scanFiles(root, extensions, exclude) {
|
|
|
20621
20510
|
}
|
|
20622
20511
|
for (const entry of entries) {
|
|
20623
20512
|
if (exclude.has(entry.name)) continue;
|
|
20624
|
-
const fullPath =
|
|
20513
|
+
const fullPath = path25.join(dir, entry.name);
|
|
20625
20514
|
if (entry.isDirectory()) {
|
|
20626
20515
|
walk(fullPath);
|
|
20627
20516
|
} else if (entry.isFile()) {
|
|
20628
|
-
const ext =
|
|
20517
|
+
const ext = path25.extname(entry.name).toLowerCase();
|
|
20629
20518
|
if (!extensions.has(ext)) continue;
|
|
20630
|
-
const relPath =
|
|
20519
|
+
const relPath = path25.relative(root, fullPath);
|
|
20631
20520
|
try {
|
|
20632
20521
|
const content = fs6.readFileSync(fullPath, "utf8");
|
|
20633
20522
|
result[relPath] = hashContent3(content);
|
|
@@ -20642,7 +20531,7 @@ function scanFiles(root, extensions, exclude) {
|
|
|
20642
20531
|
function computeDiff(current, previous, sourceDir) {
|
|
20643
20532
|
const changes = [];
|
|
20644
20533
|
for (const [relPath, hash] of Object.entries(current)) {
|
|
20645
|
-
const fullPath =
|
|
20534
|
+
const fullPath = path25.join(sourceDir, relPath);
|
|
20646
20535
|
if (!(relPath in previous)) {
|
|
20647
20536
|
let size = 0;
|
|
20648
20537
|
try {
|
|
@@ -20675,7 +20564,7 @@ function computeDiff(current, previous, sourceDir) {
|
|
|
20675
20564
|
for (const relPath of Object.keys(previous)) {
|
|
20676
20565
|
if (!(relPath in current)) {
|
|
20677
20566
|
changes.push({
|
|
20678
|
-
filePath:
|
|
20567
|
+
filePath: path25.join(sourceDir, relPath),
|
|
20679
20568
|
relativePath: relPath,
|
|
20680
20569
|
type: "deleted",
|
|
20681
20570
|
currentHash: "",
|
|
@@ -20705,20 +20594,20 @@ function hashContent3(content) {
|
|
|
20705
20594
|
import { spawnSync } from "child_process";
|
|
20706
20595
|
import crypto7 from "crypto";
|
|
20707
20596
|
import fs7 from "fs";
|
|
20708
|
-
import
|
|
20597
|
+
import path26 from "path";
|
|
20709
20598
|
var MANIFEST_VERSION = 1;
|
|
20710
20599
|
var MANIFEST_LOCK_STALE_MS = 3e4;
|
|
20711
20600
|
var MANIFEST_LOCK_TIMEOUT_MS = MANIFEST_LOCK_STALE_MS + 1e4;
|
|
20712
20601
|
var MANIFEST_LOCK_SLEEP_MS = 20;
|
|
20713
20602
|
function normalizeSpaceMemoryDir(memoryDir) {
|
|
20714
|
-
return
|
|
20603
|
+
return path26.resolve(memoryDir);
|
|
20715
20604
|
}
|
|
20716
20605
|
function getSpacesDir(baseDir) {
|
|
20717
20606
|
const homeDir = baseDir ?? resolveHomeDir();
|
|
20718
|
-
return
|
|
20607
|
+
return path26.join(homeDir, ".config", "engram", "spaces");
|
|
20719
20608
|
}
|
|
20720
20609
|
function getManifestPath(baseDir) {
|
|
20721
|
-
return
|
|
20610
|
+
return path26.join(getSpacesDir(baseDir), "manifest.json");
|
|
20722
20611
|
}
|
|
20723
20612
|
function loadManifest(baseDir, memoryDirOverride) {
|
|
20724
20613
|
if (fs7.existsSync(getManifestPath(baseDir))) {
|
|
@@ -20765,9 +20654,9 @@ function readManifestUnlocked(baseDir, memoryDirOverride, options = {}) {
|
|
|
20765
20654
|
}
|
|
20766
20655
|
function saveManifestUnlocked(manifest, baseDir) {
|
|
20767
20656
|
const manifestPath2 = getManifestPath(baseDir);
|
|
20768
|
-
const manifestDir2 =
|
|
20657
|
+
const manifestDir2 = path26.dirname(manifestPath2);
|
|
20769
20658
|
fs7.mkdirSync(manifestDir2, { recursive: true });
|
|
20770
|
-
const tempPath =
|
|
20659
|
+
const tempPath = path26.join(manifestDir2, `.manifest.${process.pid}.${Date.now()}.${crypto7.randomUUID()}.tmp`);
|
|
20771
20660
|
try {
|
|
20772
20661
|
fs7.writeFileSync(tempPath, `${JSON.stringify(manifest, null, 2)}
|
|
20773
20662
|
`, { flag: "wx" });
|
|
@@ -20782,7 +20671,7 @@ function saveManifestUnlocked(manifest, baseDir) {
|
|
|
20782
20671
|
}
|
|
20783
20672
|
function withManifestLock(baseDir, operation) {
|
|
20784
20673
|
const lockDir = `${getManifestPath(baseDir)}.lock`;
|
|
20785
|
-
fs7.mkdirSync(
|
|
20674
|
+
fs7.mkdirSync(path26.dirname(lockDir), { recursive: true });
|
|
20786
20675
|
const lockOwner = acquireManifestLock(lockDir);
|
|
20787
20676
|
try {
|
|
20788
20677
|
return operation();
|
|
@@ -20808,7 +20697,7 @@ function acquireManifestLock(lockDir) {
|
|
|
20808
20697
|
try {
|
|
20809
20698
|
fs7.mkdirSync(lockDir, { recursive: false });
|
|
20810
20699
|
try {
|
|
20811
|
-
fs7.writeFileSync(
|
|
20700
|
+
fs7.writeFileSync(path26.join(lockDir, "owner"), `${owner}
|
|
20812
20701
|
`, { flag: "wx" });
|
|
20813
20702
|
} catch (error) {
|
|
20814
20703
|
fs7.rmSync(lockDir, { recursive: true, force: true });
|
|
@@ -20838,7 +20727,7 @@ function acquireManifestLock(lockDir) {
|
|
|
20838
20727
|
}
|
|
20839
20728
|
function releaseManifestLock(lockDir, owner) {
|
|
20840
20729
|
try {
|
|
20841
|
-
const ownerPath =
|
|
20730
|
+
const ownerPath = path26.join(lockDir, "owner");
|
|
20842
20731
|
if (fs7.readFileSync(ownerPath, "utf8").trim() === owner) {
|
|
20843
20732
|
fs7.rmSync(lockDir, { recursive: true, force: true });
|
|
20844
20733
|
}
|
|
@@ -20854,7 +20743,7 @@ function removeStaleManifestLock(lockDir) {
|
|
|
20854
20743
|
try {
|
|
20855
20744
|
fs7.mkdirSync(reclaimDir, { recursive: false });
|
|
20856
20745
|
try {
|
|
20857
|
-
fs7.writeFileSync(
|
|
20746
|
+
fs7.writeFileSync(path26.join(reclaimDir, "owner"), `${reclaimOwner}
|
|
20858
20747
|
`, { flag: "wx" });
|
|
20859
20748
|
} catch (error) {
|
|
20860
20749
|
fs7.rmSync(reclaimDir, { recursive: true, force: true });
|
|
@@ -20929,7 +20818,7 @@ function readManifestLockSnapshot(lockDir) {
|
|
|
20929
20818
|
throw error;
|
|
20930
20819
|
}
|
|
20931
20820
|
try {
|
|
20932
|
-
const owner = fs7.readFileSync(
|
|
20821
|
+
const owner = fs7.readFileSync(path26.join(lockDir, "owner"), "utf8").trim();
|
|
20933
20822
|
return { mtimeMs: stat5.mtimeMs, owner };
|
|
20934
20823
|
} catch (error) {
|
|
20935
20824
|
if (error.code === "ENOENT") {
|
|
@@ -21001,8 +20890,8 @@ function sleepSync(ms) {
|
|
|
21001
20890
|
}
|
|
21002
20891
|
function createPersonalSpace(baseDir, memoryDirOverride) {
|
|
21003
20892
|
const homeDir = baseDir ?? resolveHomeDir();
|
|
21004
|
-
const standalonePath =
|
|
21005
|
-
const openclawPath =
|
|
20893
|
+
const standalonePath = path26.join(homeDir, ".engram", "memory");
|
|
20894
|
+
const openclawPath = path26.join(homeDir, ".openclaw", "workspace", "memory", "local");
|
|
21006
20895
|
const memoryDir = memoryDirOverride ?? readEnvVar("REMNIC_MEMORY_DIR") ?? readEnvVar("ENGRAM_MEMORY_DIR") ?? (fs7.existsSync(standalonePath) ? standalonePath : fs7.existsSync(openclawPath) ? openclawPath : standalonePath);
|
|
21007
20896
|
const normalizedMemoryDir = normalizeSpaceMemoryDir(memoryDir);
|
|
21008
20897
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -21031,7 +20920,7 @@ function createSpace(options) {
|
|
|
21031
20920
|
const id = options.name.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-");
|
|
21032
20921
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
21033
20922
|
const memoryDir = normalizeSpaceMemoryDir(
|
|
21034
|
-
options.memoryDir ??
|
|
20923
|
+
options.memoryDir ?? path26.join(getSpacesDir(options.baseDir), id, "memory")
|
|
21035
20924
|
);
|
|
21036
20925
|
const space = updateManifest(options.baseDir, (manifest) => {
|
|
21037
20926
|
if (manifest.spaces.some((s) => s.id === id)) {
|
|
@@ -21252,14 +21141,14 @@ function mergeSpaces(sourceSpaceId, targetSpaceId, options) {
|
|
|
21252
21141
|
};
|
|
21253
21142
|
}
|
|
21254
21143
|
function getAuditLog(baseDir) {
|
|
21255
|
-
const auditPath =
|
|
21144
|
+
const auditPath = path26.join(getSpacesDir(baseDir), "audit.jsonl");
|
|
21256
21145
|
if (!fs7.existsSync(auditPath)) return [];
|
|
21257
21146
|
const lines = fs7.readFileSync(auditPath, "utf8").trim().split("\n");
|
|
21258
21147
|
return lines.filter((l) => l.trim()).map((l) => JSON.parse(l));
|
|
21259
21148
|
}
|
|
21260
21149
|
function appendAudit(entry, baseDir) {
|
|
21261
|
-
const auditPath =
|
|
21262
|
-
fs7.mkdirSync(
|
|
21150
|
+
const auditPath = path26.join(getSpacesDir(baseDir), "audit.jsonl");
|
|
21151
|
+
fs7.mkdirSync(path26.dirname(auditPath), { recursive: true });
|
|
21263
21152
|
const full = {
|
|
21264
21153
|
id: crypto7.randomUUID(),
|
|
21265
21154
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -21291,8 +21180,8 @@ function copyMemories(sourceDir, targetDir, options) {
|
|
|
21291
21180
|
continue;
|
|
21292
21181
|
}
|
|
21293
21182
|
const content = fs7.readFileSync(sourcePath, "utf8");
|
|
21294
|
-
const relativePath =
|
|
21295
|
-
const targetPath =
|
|
21183
|
+
const relativePath = path26.relative(sourceRoot, sourceRealPath);
|
|
21184
|
+
const targetPath = path26.resolve(targetRoot, relativePath);
|
|
21296
21185
|
if (!isPathInsideRoot(targetPath, targetRoot)) {
|
|
21297
21186
|
skipped++;
|
|
21298
21187
|
continue;
|
|
@@ -21334,8 +21223,8 @@ function copyMemories(sourceDir, targetDir, options) {
|
|
|
21334
21223
|
skipped++;
|
|
21335
21224
|
continue;
|
|
21336
21225
|
}
|
|
21337
|
-
fs7.mkdirSync(
|
|
21338
|
-
const targetParentRealPath = safeRealpath(
|
|
21226
|
+
fs7.mkdirSync(path26.dirname(targetPath), { recursive: true });
|
|
21227
|
+
const targetParentRealPath = safeRealpath(path26.dirname(targetPath));
|
|
21339
21228
|
if (!targetParentRealPath || !isPathInsideRoot(targetParentRealPath, targetRoot)) {
|
|
21340
21229
|
skipped++;
|
|
21341
21230
|
continue;
|
|
@@ -21352,7 +21241,7 @@ function walkMd2(dir) {
|
|
|
21352
21241
|
const results = [];
|
|
21353
21242
|
function walk(d) {
|
|
21354
21243
|
for (const entry of fs7.readdirSync(d, { withFileTypes: true })) {
|
|
21355
|
-
const fullPath =
|
|
21244
|
+
const fullPath = path26.join(d, entry.name);
|
|
21356
21245
|
if (entry.isSymbolicLink()) {
|
|
21357
21246
|
continue;
|
|
21358
21247
|
}
|
|
@@ -21381,8 +21270,8 @@ function safeRealpath(filePath) {
|
|
|
21381
21270
|
}
|
|
21382
21271
|
}
|
|
21383
21272
|
function isPathInsideRoot(candidatePath, rootPath) {
|
|
21384
|
-
const relative =
|
|
21385
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
21273
|
+
const relative = path26.relative(rootPath, candidatePath);
|
|
21274
|
+
return relative === "" || !relative.startsWith("..") && !path26.isAbsolute(relative);
|
|
21386
21275
|
}
|
|
21387
21276
|
function parseSimpleFrontmatter(content) {
|
|
21388
21277
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
@@ -21503,7 +21392,7 @@ var REMNIC_RECALL_DECISION_RULES = `## When to Use Recall vs Direct Read
|
|
|
21503
21392
|
// src/memory-extension/codex-publisher.ts
|
|
21504
21393
|
import fs8 from "fs";
|
|
21505
21394
|
import os3 from "os";
|
|
21506
|
-
import
|
|
21395
|
+
import path27 from "path";
|
|
21507
21396
|
var REMNIC_EXTENSION_DIR_NAME = "remnic";
|
|
21508
21397
|
function resolveEnvHome(env) {
|
|
21509
21398
|
if (env === void 0) return resolveHomeDir();
|
|
@@ -21512,12 +21401,12 @@ function resolveEnvHome(env) {
|
|
|
21512
21401
|
function expandTildeWithHome(input, homeDir) {
|
|
21513
21402
|
if (input === "~") return homeDir;
|
|
21514
21403
|
if (input.startsWith("~/") || input.startsWith("~\\")) {
|
|
21515
|
-
return
|
|
21404
|
+
return path27.join(homeDir, input.slice(2));
|
|
21516
21405
|
}
|
|
21517
21406
|
return input;
|
|
21518
21407
|
}
|
|
21519
21408
|
function normalizeHostRoot(input, homeDir) {
|
|
21520
|
-
return
|
|
21409
|
+
return path27.resolve(expandTildeWithHome(input.trim(), homeDir));
|
|
21521
21410
|
}
|
|
21522
21411
|
var CodexMemoryExtensionPublisher = class {
|
|
21523
21412
|
hostId = "codex";
|
|
@@ -21531,12 +21420,12 @@ var CodexMemoryExtensionPublisher = class {
|
|
|
21531
21420
|
async resolveExtensionRoot(env) {
|
|
21532
21421
|
const homeDir = resolveEnvHome(env);
|
|
21533
21422
|
const codexHomeInput = env === void 0 ? readEnvVar("CODEX_HOME")?.trim() : env.CODEX_HOME?.trim();
|
|
21534
|
-
const codexHome = codexHomeInput ? normalizeHostRoot(codexHomeInput, homeDir) :
|
|
21535
|
-
return
|
|
21423
|
+
const codexHome = codexHomeInput ? normalizeHostRoot(codexHomeInput, homeDir) : path27.resolve(homeDir, ".codex");
|
|
21424
|
+
return path27.join(codexHome, "memories_extensions", REMNIC_EXTENSION_DIR_NAME);
|
|
21536
21425
|
}
|
|
21537
21426
|
async isHostAvailable() {
|
|
21538
21427
|
try {
|
|
21539
|
-
const home = readEnvVar("CODEX_HOME")?.trim() ||
|
|
21428
|
+
const home = readEnvVar("CODEX_HOME")?.trim() || path27.join(resolveHomeDir(), ".codex");
|
|
21540
21429
|
return fs8.existsSync(home);
|
|
21541
21430
|
} catch {
|
|
21542
21431
|
return false;
|
|
@@ -21587,7 +21476,7 @@ When running inside the Codex phase-2 consolidation sandbox:
|
|
|
21587
21476
|
}
|
|
21588
21477
|
async publish(ctx) {
|
|
21589
21478
|
const extensionRoot = await this.resolveExtensionRoot();
|
|
21590
|
-
const instructionsPath =
|
|
21479
|
+
const instructionsPath = path27.join(extensionRoot, "instructions.md");
|
|
21591
21480
|
const filesWritten = [];
|
|
21592
21481
|
const skipped = [];
|
|
21593
21482
|
ctx.log.info(`Publishing Codex memory extension to ${extensionRoot}`);
|
|
@@ -21707,7 +21596,7 @@ function publisherForConnector(connectorId) {
|
|
|
21707
21596
|
// src/session-summaries/index.ts
|
|
21708
21597
|
import { createHash as createHash9 } from "crypto";
|
|
21709
21598
|
import { lstat as lstat2, mkdir as mkdir7, readFile as readFile6, readdir as readdir4, rename, rm, stat as stat4, writeFile as writeFile7 } from "fs/promises";
|
|
21710
|
-
import
|
|
21599
|
+
import path28 from "path";
|
|
21711
21600
|
|
|
21712
21601
|
// src/session-summaries/adapters.ts
|
|
21713
21602
|
var VALID_ROLES = /* @__PURE__ */ new Set(["user", "assistant", "tool", "system", "other"]);
|
|
@@ -22212,7 +22101,7 @@ function shortHash(value, length = 16) {
|
|
|
22212
22101
|
async function listTranscriptFiles(root, maxFiles) {
|
|
22213
22102
|
const out = [];
|
|
22214
22103
|
let truncated = false;
|
|
22215
|
-
const entrySortKey = (entryName, isDirectory) => isDirectory ? `${entryName}${
|
|
22104
|
+
const entrySortKey = (entryName, isDirectory) => isDirectory ? `${entryName}${path28.sep}` : entryName;
|
|
22216
22105
|
async function visit(dir) {
|
|
22217
22106
|
if (truncated) return;
|
|
22218
22107
|
const entries = (await readdir4(dir, { withFileTypes: true })).sort(
|
|
@@ -22222,13 +22111,13 @@ async function listTranscriptFiles(root, maxFiles) {
|
|
|
22222
22111
|
if (truncated) return;
|
|
22223
22112
|
if (entry.name.startsWith(".")) continue;
|
|
22224
22113
|
if (entry.isSymbolicLink()) continue;
|
|
22225
|
-
const fullPath =
|
|
22114
|
+
const fullPath = path28.join(dir, entry.name);
|
|
22226
22115
|
if (entry.isDirectory()) {
|
|
22227
22116
|
await visit(fullPath);
|
|
22228
22117
|
continue;
|
|
22229
22118
|
}
|
|
22230
22119
|
if (!entry.isFile()) continue;
|
|
22231
|
-
const ext =
|
|
22120
|
+
const ext = path28.extname(entry.name).toLowerCase();
|
|
22232
22121
|
if (!SUPPORTED_EXTENSIONS.has(ext)) continue;
|
|
22233
22122
|
out.push(fullPath);
|
|
22234
22123
|
if (out.length > maxFiles) {
|
|
@@ -22255,7 +22144,7 @@ function normalizeInputDir(inputDir) {
|
|
|
22255
22144
|
if (typeof inputDir !== "string" || inputDir.trim().length === 0) {
|
|
22256
22145
|
throw new Error("inputDir must be a non-empty string");
|
|
22257
22146
|
}
|
|
22258
|
-
return
|
|
22147
|
+
return path28.resolve(expandTildePath(inputDir.trim()));
|
|
22259
22148
|
}
|
|
22260
22149
|
function initRoleCounts() {
|
|
22261
22150
|
return {
|
|
@@ -22412,11 +22301,11 @@ async function collectLocalSessionSummaries(options) {
|
|
|
22412
22301
|
continue;
|
|
22413
22302
|
}
|
|
22414
22303
|
seenFileHashes.add(fileHash);
|
|
22415
|
-
const fileExtension =
|
|
22304
|
+
const fileExtension = path28.extname(filePath).toLowerCase();
|
|
22416
22305
|
const parsed = await adapter.parseFile(
|
|
22417
22306
|
{
|
|
22418
22307
|
content,
|
|
22419
|
-
fileName:
|
|
22308
|
+
fileName: path28.basename(filePath),
|
|
22420
22309
|
fileExtension,
|
|
22421
22310
|
fileRef: fileHash
|
|
22422
22311
|
},
|
|
@@ -22472,7 +22361,7 @@ async function collectLocalSessionSummaries(options) {
|
|
|
22472
22361
|
}
|
|
22473
22362
|
async function readRedactionConfig(pathLike) {
|
|
22474
22363
|
if (!pathLike) return void 0;
|
|
22475
|
-
const raw = await readFile6(
|
|
22364
|
+
const raw = await readFile6(path28.resolve(expandTildePath(pathLike)), "utf-8");
|
|
22476
22365
|
const parsed = JSON.parse(raw);
|
|
22477
22366
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
22478
22367
|
throw new Error("redaction config must be a JSON object");
|
|
@@ -22485,15 +22374,15 @@ function toJsonl(drafts) {
|
|
|
22485
22374
|
}
|
|
22486
22375
|
function defaultDraftOutputPath(memoryDir, generatedAt) {
|
|
22487
22376
|
const stamp = generatedAt.replace(/[:.]/g, "-");
|
|
22488
|
-
return
|
|
22489
|
-
|
|
22377
|
+
return path28.join(
|
|
22378
|
+
path28.resolve(expandTildePath(memoryDir)),
|
|
22490
22379
|
"state",
|
|
22491
22380
|
"session-summary-drafts",
|
|
22492
22381
|
`session-summaries-${stamp}.jsonl`
|
|
22493
22382
|
);
|
|
22494
22383
|
}
|
|
22495
22384
|
async function writeDrafts(filePath, drafts) {
|
|
22496
|
-
await mkdir7(
|
|
22385
|
+
await mkdir7(path28.dirname(filePath), { recursive: true });
|
|
22497
22386
|
const tempPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
22498
22387
|
try {
|
|
22499
22388
|
await writeFile7(tempPath, toJsonl(drafts), "utf-8");
|
|
@@ -22511,7 +22400,7 @@ async function runLocalSessionSummaryCliCommand(options) {
|
|
|
22511
22400
|
});
|
|
22512
22401
|
const wroteFiles = [];
|
|
22513
22402
|
if (options.output) {
|
|
22514
|
-
const outputPath =
|
|
22403
|
+
const outputPath = path28.resolve(expandTildePath(options.output));
|
|
22515
22404
|
await writeDrafts(outputPath, report.drafts);
|
|
22516
22405
|
wroteFiles.push(outputPath);
|
|
22517
22406
|
}
|
|
@@ -22546,19 +22435,19 @@ async function runLocalSessionSummaryCliCommand(options) {
|
|
|
22546
22435
|
|
|
22547
22436
|
// src/transfer/capsule-fork.ts
|
|
22548
22437
|
import { lstat as lstat3, mkdir as mkdir8, readFile as readFile7, realpath as realpath2, writeFile as writeFile8 } from "fs/promises";
|
|
22549
|
-
import
|
|
22438
|
+
import path29 from "path";
|
|
22550
22439
|
async function forkCapsule(opts) {
|
|
22551
22440
|
validateForkId(opts.forkId);
|
|
22552
|
-
const rootAbs =
|
|
22441
|
+
const rootAbs = path29.resolve(opts.targetRoot);
|
|
22553
22442
|
await assertIsDirectoryNotSymlink(rootAbs, "forkCapsule", "targetRoot");
|
|
22554
|
-
const forkDirAbs =
|
|
22443
|
+
const forkDirAbs = path29.join(rootAbs, "forks", opts.forkId);
|
|
22555
22444
|
const forkEntryExists = await pathEntryExists(forkDirAbs);
|
|
22556
22445
|
if (forkEntryExists) {
|
|
22557
22446
|
throw new Error(
|
|
22558
22447
|
`forkCapsule: fork path already exists \u2014 forkId "${opts.forkId}" is already in use at: ${forkDirAbs}`
|
|
22559
22448
|
);
|
|
22560
22449
|
}
|
|
22561
|
-
const archiveAbs =
|
|
22450
|
+
const archiveAbs = path29.resolve(opts.sourceArchive);
|
|
22562
22451
|
const importResult = await importCapsule({
|
|
22563
22452
|
archivePath: archiveAbs,
|
|
22564
22453
|
root: rootAbs,
|
|
@@ -22580,10 +22469,10 @@ async function forkCapsule(opts) {
|
|
|
22580
22469
|
importedRecords: importResult.imported.length,
|
|
22581
22470
|
skippedRecords: importResult.skipped.length
|
|
22582
22471
|
};
|
|
22583
|
-
const lineagePath =
|
|
22472
|
+
const lineagePath = path29.join(forkDirAbs, "lineage.json");
|
|
22584
22473
|
const rootReal = await realpath2(rootAbs);
|
|
22585
22474
|
await assertRealpathInsideRoot(rootReal, lineagePath, `forks/${opts.forkId}/lineage.json`, "forkCapsule");
|
|
22586
|
-
await mkdir8(
|
|
22475
|
+
await mkdir8(path29.dirname(lineagePath), { recursive: true });
|
|
22587
22476
|
await writeFile8(lineagePath, JSON.stringify(lineage, null, 2) + "\n", "utf-8");
|
|
22588
22477
|
return {
|
|
22589
22478
|
archivePath: archiveAbs,
|
|
@@ -22597,11 +22486,11 @@ async function readForkLineage(targetRoot, forkId) {
|
|
|
22597
22486
|
if (typeof forkId !== "string" || forkId.length === 0 || forkId.length > 64 || !CAPSULE_ID_PATTERN.test(forkId)) {
|
|
22598
22487
|
return null;
|
|
22599
22488
|
}
|
|
22600
|
-
const rootAbs =
|
|
22489
|
+
const rootAbs = path29.resolve(targetRoot);
|
|
22601
22490
|
const rootReal = await realpath2(rootAbs).catch(() => rootAbs);
|
|
22602
|
-
const lineagePath =
|
|
22603
|
-
const rel =
|
|
22604
|
-
if (rel.startsWith("..") ||
|
|
22491
|
+
const lineagePath = path29.join(rootReal, "forks", forkId, "lineage.json");
|
|
22492
|
+
const rel = path29.relative(rootReal, lineagePath);
|
|
22493
|
+
if (rel.startsWith("..") || path29.isAbsolute(rel)) {
|
|
22605
22494
|
return null;
|
|
22606
22495
|
}
|
|
22607
22496
|
if (!await isLineagePathContained(rootReal, lineagePath)) {
|
|
@@ -22642,19 +22531,19 @@ async function pathEntryExists(absPath) {
|
|
|
22642
22531
|
async function isLineagePathContained(rootReal, lineagePath) {
|
|
22643
22532
|
let existing = lineagePath;
|
|
22644
22533
|
const suffix = [];
|
|
22645
|
-
while (existing !==
|
|
22534
|
+
while (existing !== path29.dirname(existing)) {
|
|
22646
22535
|
const st = await lstat3(existing).catch(() => null);
|
|
22647
22536
|
if (st !== null) break;
|
|
22648
|
-
suffix.unshift(
|
|
22649
|
-
existing =
|
|
22537
|
+
suffix.unshift(path29.basename(existing));
|
|
22538
|
+
existing = path29.dirname(existing);
|
|
22650
22539
|
}
|
|
22651
22540
|
const existingReal = await realpath2(existing).catch(() => existing);
|
|
22652
|
-
const targetReal = suffix.length > 0 ?
|
|
22653
|
-
const rel =
|
|
22541
|
+
const targetReal = suffix.length > 0 ? path29.join(existingReal, ...suffix) : existingReal;
|
|
22542
|
+
const rel = path29.relative(rootReal, targetReal);
|
|
22654
22543
|
if (rel === "") return true;
|
|
22655
22544
|
if (rel === "..") return false;
|
|
22656
|
-
if (rel.startsWith(`..${
|
|
22657
|
-
if (
|
|
22545
|
+
if (rel.startsWith(`..${path29.sep}`)) return false;
|
|
22546
|
+
if (path29.isAbsolute(rel)) return false;
|
|
22658
22547
|
return true;
|
|
22659
22548
|
}
|
|
22660
22549
|
|
|
@@ -22795,4 +22684,4 @@ export {
|
|
|
22795
22684
|
blendGraphExpandedRecallScore,
|
|
22796
22685
|
Orchestrator
|
|
22797
22686
|
};
|
|
22798
|
-
//# sourceMappingURL=chunk-
|
|
22687
|
+
//# sourceMappingURL=chunk-VQL22SHO.js.map
|