@remnic/core 1.1.2 → 1.1.3
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/abort-error.js +1 -0
- package/dist/abstraction-nodes.js +1 -0
- package/dist/access-audit.js +1 -0
- package/dist/access-cli.js +70 -45
- package/dist/access-cli.js.map +1 -1
- package/dist/access-http.d.ts +50 -5
- package/dist/access-http.js +37 -15
- package/dist/access-idempotency.js +1 -0
- package/dist/access-mcp.d.ts +10 -5
- package/dist/access-mcp.js +36 -13
- package/dist/access-schema.d.ts +133 -13
- package/dist/access-schema.js +20 -1
- package/dist/access-service-_AEUMVyX.d.ts +1981 -0
- package/dist/access-service.d.ts +11 -6
- package/dist/access-service.js +38 -14
- package/dist/active-memory-bridge.js +1 -0
- package/dist/active-recall.js +1 -0
- package/dist/active-recall.js.map +1 -1
- package/dist/behavior-learner.js +1 -0
- package/dist/behavior-learner.js.map +1 -1
- package/dist/behavior-signals.js +1 -0
- package/dist/bootstrap.d.ts +6 -4
- package/dist/bootstrap.js +1 -0
- package/dist/boxes.js +1 -0
- package/dist/briefing.d.ts +9 -5
- package/dist/briefing.js +9 -6
- package/dist/buffer-surprise-report.js +1 -0
- package/dist/buffer-surprise.js +1 -0
- package/dist/buffer.d.ts +1 -1
- package/dist/buffer.js +1 -0
- package/dist/calibration.d.ts +8 -1
- package/dist/calibration.js +10 -2
- package/dist/calibration.js.map +1 -1
- package/dist/capsule-cli.d.ts +137 -0
- package/dist/capsule-cli.js +34 -0
- package/dist/capsule-crypto-5CYAGVC5.js +18 -0
- package/dist/capsule-export-NZQPOTQ4.js +17 -0
- package/dist/capsule-export-NZQPOTQ4.js.map +1 -0
- package/dist/capsule-import-SDCUXLEV.js +16 -0
- package/dist/capsule-import-SDCUXLEV.js.map +1 -0
- package/dist/capsule-merge-DI7PNQ2H.js +189 -0
- package/dist/capsule-merge-DI7PNQ2H.js.map +1 -0
- package/dist/causal-behavior.js +1 -0
- package/dist/causal-behavior.js.map +1 -1
- package/dist/causal-chain.js +1 -0
- package/dist/causal-consolidation.js +11 -8
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/causal-retrieval.js +2 -1
- package/dist/causal-retrieval.js.map +1 -1
- package/dist/causal-trajectory-graph.js +4 -1
- package/dist/causal-trajectory-graph.js.map +1 -1
- package/dist/causal-trajectory.js +2 -1
- package/dist/chunk-2LSZVONP.js +67 -0
- package/dist/chunk-2LSZVONP.js.map +1 -0
- package/dist/chunk-32KD5IHZ.js +245 -0
- package/dist/chunk-32KD5IHZ.js.map +1 -0
- package/dist/{chunk-VDX363PS.js → chunk-34F3PLWZ.js} +10 -3
- package/dist/chunk-34F3PLWZ.js.map +1 -0
- package/dist/chunk-3KIS4VGT.js +228 -0
- package/dist/chunk-3KIS4VGT.js.map +1 -0
- package/dist/chunk-3LCWFNVS.js +350 -0
- package/dist/chunk-3LCWFNVS.js.map +1 -0
- package/dist/chunk-43EKP2UK.js +26 -0
- package/dist/chunk-43EKP2UK.js.map +1 -0
- package/dist/chunk-457A4P3L.js +119 -0
- package/dist/chunk-457A4P3L.js.map +1 -0
- package/dist/{chunk-TMYO7B5P.js → chunk-47WOM4YW.js} +2 -2
- package/dist/{chunk-OC5OXUQ4.js → chunk-4PLGJRBV.js} +653 -17
- package/dist/chunk-4PLGJRBV.js.map +1 -0
- package/dist/{chunk-PVICZTKG.js → chunk-55FXRRSJ.js} +5 -5
- package/dist/{chunk-PVICZTKG.js.map → chunk-55FXRRSJ.js.map} +1 -1
- package/dist/{chunk-ULYOGL6R.js → chunk-5HRY2WRF.js} +7 -3
- package/dist/chunk-5HRY2WRF.js.map +1 -0
- package/dist/chunk-6TBWYBJ3.js +236 -0
- package/dist/chunk-6TBWYBJ3.js.map +1 -0
- package/dist/chunk-74EMIVE4.js +329 -0
- package/dist/chunk-74EMIVE4.js.map +1 -0
- package/dist/chunk-74WWN7ZW.js +82 -0
- package/dist/chunk-74WWN7ZW.js.map +1 -0
- package/dist/{chunk-6YJHX2DL.js → chunk-7GCMLT7J.js} +242 -22
- package/dist/chunk-7GCMLT7J.js.map +1 -0
- package/dist/chunk-A6XUJE5D.js +126 -0
- package/dist/chunk-A6XUJE5D.js.map +1 -0
- package/dist/chunk-AJA46VX5.js +393 -0
- package/dist/chunk-AJA46VX5.js.map +1 -0
- package/dist/{chunk-UWB5LMWY.js → chunk-AKUCB2OG.js} +525 -24
- package/dist/chunk-AKUCB2OG.js.map +1 -0
- package/dist/chunk-ASIQZXYO.js +277 -0
- package/dist/chunk-ASIQZXYO.js.map +1 -0
- package/dist/{chunk-DG6YMRDC.js → chunk-B2TL6GA2.js} +2 -2
- package/dist/chunk-BJMBJZ2Y.js +290 -0
- package/dist/chunk-BJMBJZ2Y.js.map +1 -0
- package/dist/chunk-BT7NVCML.js +79 -0
- package/dist/chunk-BT7NVCML.js.map +1 -0
- package/dist/chunk-CK5NTM2S.js +454 -0
- package/dist/chunk-CK5NTM2S.js.map +1 -0
- package/dist/{chunk-AYXIPSZO.js → chunk-CRU27Q4J.js} +2 -2
- package/dist/{chunk-F5VP6YCB.js → chunk-DCE6SQLA.js} +572 -155
- package/dist/chunk-DCE6SQLA.js.map +1 -0
- package/dist/{chunk-CUPFXL3J.js → chunk-DHRQHX36.js} +4 -4
- package/dist/chunk-DHRQHX36.js.map +1 -0
- package/dist/{chunk-STGWEHYR.js → chunk-DR7MCMPS.js} +981 -61
- package/dist/chunk-DR7MCMPS.js.map +1 -0
- package/dist/chunk-FP2373TW.js +149 -0
- package/dist/chunk-FP2373TW.js.map +1 -0
- package/dist/{chunk-RBBWYEFJ.js → chunk-G2WADRQ3.js} +1 -1
- package/dist/chunk-G7D6GZ5J.js +48 -0
- package/dist/chunk-G7D6GZ5J.js.map +1 -0
- package/dist/chunk-H7XKCNR6.js +60 -0
- package/dist/chunk-H7XKCNR6.js.map +1 -0
- package/dist/{chunk-3YGHKTBF.js → chunk-IM3JSE73.js} +953 -322
- package/dist/chunk-IM3JSE73.js.map +1 -0
- package/dist/chunk-IXEJRKCZ.js +18 -0
- package/dist/chunk-IXEJRKCZ.js.map +1 -0
- package/dist/chunk-IYY4MCPG.js +275 -0
- package/dist/chunk-IYY4MCPG.js.map +1 -0
- package/dist/{chunk-BECYBZLX.js → chunk-JWSENLQI.js} +502 -22
- package/dist/chunk-JWSENLQI.js.map +1 -0
- package/dist/chunk-KNKUID7G.js +183 -0
- package/dist/chunk-KNKUID7G.js.map +1 -0
- package/dist/chunk-L2IO2QPY.js +2036 -0
- package/dist/chunk-L2IO2QPY.js.map +1 -0
- package/dist/{chunk-SPI27QT6.js → chunk-L5IIGA5V.js} +9 -4
- package/dist/chunk-L5IIGA5V.js.map +1 -0
- package/dist/{chunk-XXVWLXSG.js → chunk-LVYGDT5V.js} +56 -82
- package/dist/chunk-LVYGDT5V.js.map +1 -0
- package/dist/{chunk-ZAIM4TUE.js → chunk-LW2NMHDW.js} +46 -1
- package/dist/chunk-LW2NMHDW.js.map +1 -0
- package/dist/{chunk-3OGMS3PE.js → chunk-LZRYQK6L.js} +3 -2
- package/dist/chunk-LZRYQK6L.js.map +1 -0
- package/dist/chunk-MDYG7VI7.js +48 -0
- package/dist/chunk-MDYG7VI7.js.map +1 -0
- package/dist/chunk-MXC3AP5I.js +74 -0
- package/dist/chunk-MXC3AP5I.js.map +1 -0
- package/dist/{chunk-DIXB44VE.js → chunk-N7X62G74.js} +25 -10
- package/dist/chunk-N7X62G74.js.map +1 -0
- package/dist/chunk-NN3TS5BM.js +147 -0
- package/dist/chunk-NN3TS5BM.js.map +1 -0
- package/dist/chunk-OA3L7BFR.js +183 -0
- package/dist/chunk-OA3L7BFR.js.map +1 -0
- package/dist/chunk-OZHRDTDX.js +240 -0
- package/dist/chunk-OZHRDTDX.js.map +1 -0
- package/dist/chunk-PCUKNJAZ.js +165 -0
- package/dist/chunk-PCUKNJAZ.js.map +1 -0
- package/dist/{chunk-6PFRXT4K.js → chunk-PFV5C235.js} +11 -6
- package/dist/chunk-PFV5C235.js.map +1 -0
- package/dist/chunk-PZ5AY32C.js +10 -0
- package/dist/chunk-PZ5AY32C.js.map +1 -0
- package/dist/{chunk-Y7R2XJ5Q.js → chunk-Q7FJ5ZHM.js} +6 -2
- package/dist/chunk-Q7FJ5ZHM.js.map +1 -0
- package/dist/{chunk-NBVAS5MT.js → chunk-R2L7SUX2.js} +6 -6
- package/dist/{chunk-WCLICCGB.js → chunk-RILIVK4O.js} +91 -4
- package/dist/chunk-RILIVK4O.js.map +1 -0
- package/dist/{chunk-C2EFFULQ.js → chunk-RK2Y4XOM.js} +163 -20
- package/dist/chunk-RK2Y4XOM.js.map +1 -0
- package/dist/{chunk-TP4FZJIZ.js → chunk-RULE4VG5.js} +5 -1
- package/dist/chunk-RULE4VG5.js.map +1 -0
- package/dist/{chunk-PVPWZSSI.js → chunk-SMA4IMHV.js} +19 -3
- package/dist/chunk-SMA4IMHV.js.map +1 -0
- package/dist/{chunk-L7IXWRYE.js → chunk-SS253RXF.js} +22 -13
- package/dist/chunk-SS253RXF.js.map +1 -0
- package/dist/chunk-TUFG6VXY.js +875 -0
- package/dist/chunk-TUFG6VXY.js.map +1 -0
- package/dist/chunk-TYEOAFH3.js +251 -0
- package/dist/chunk-TYEOAFH3.js.map +1 -0
- package/dist/chunk-UKJAGEXH.js +260 -0
- package/dist/chunk-UKJAGEXH.js.map +1 -0
- package/dist/{chunk-KVBLZUKV.js → chunk-USFPPRAF.js} +93 -3
- package/dist/chunk-USFPPRAF.js.map +1 -0
- package/dist/{chunk-GA5P7RST.js → chunk-VTJVUHRK.js} +22 -36
- package/dist/chunk-VTJVUHRK.js.map +1 -0
- package/dist/chunk-WIICJPET.js +45 -0
- package/dist/chunk-WIICJPET.js.map +1 -0
- package/dist/{chunk-VBVG2M5G.js → chunk-WPGJYVUH.js} +6 -2
- package/dist/chunk-WPGJYVUH.js.map +1 -0
- package/dist/{chunk-4HQS2HPX.js → chunk-WSZIHQBK.js} +29 -9
- package/dist/{chunk-4HQS2HPX.js.map → chunk-WSZIHQBK.js.map} +1 -1
- package/dist/{chunk-NZLQTHS5.js → chunk-WW3QQF4H.js} +4 -1
- package/dist/chunk-WW3QQF4H.js.map +1 -0
- package/dist/{chunk-FVA6TGI3.js → chunk-Y3WQ4ZWK.js} +42 -2
- package/dist/chunk-Y3WQ4ZWK.js.map +1 -0
- package/dist/chunk-YNJHCGDT.js +309 -0
- package/dist/chunk-YNJHCGDT.js.map +1 -0
- package/dist/{chunk-LOIMBRDE.js → chunk-ZGXSCMQN.js} +1993 -411
- package/dist/chunk-ZGXSCMQN.js.map +1 -0
- package/dist/{chunk-W6SL7OFG.js → chunk-ZTSE2ZJ6.js} +12 -2
- package/dist/{chunk-W6SL7OFG.js.map → chunk-ZTSE2ZJ6.js.map} +1 -1
- package/dist/chunking.js +1 -0
- package/dist/cipher-GVE2GQ5H.js +28 -0
- package/dist/cipher-GVE2GQ5H.js.map +1 -0
- package/dist/citations.js +1 -0
- package/dist/{cli-BkeRaYfk.d.ts → cli-x2APT9a6.d.ts} +26 -7
- package/dist/cli.d.ts +11 -6
- package/dist/cli.js +67 -33
- package/dist/codex-thread-key.js +1 -0
- package/dist/commitment-ledger.js +1 -0
- package/dist/compression-optimizer.js +1 -0
- package/dist/config.d.ts +2 -1
- package/dist/config.js +4 -1
- package/dist/connectors-cli-DFGtY2DB.d.ts +257 -0
- package/dist/connectors-cli.d.ts +2 -0
- package/dist/connectors-cli.js +22 -0
- package/dist/connectors-cli.js.map +1 -0
- package/dist/consolidation-operator.d.ts +65 -5
- package/dist/consolidation-operator.js +6 -1
- package/dist/consolidation-provenance-check.d.ts +1 -1
- package/dist/consolidation-provenance-check.js +3 -2
- package/dist/consolidation-undo.d.ts +1 -1
- package/dist/consolidation-undo.js +1 -0
- package/dist/consolidation-undo.js.map +1 -1
- package/dist/{contradiction-review-WIUBAR52.js → contradiction-review-5LTTVDQV.js} +2 -1
- package/dist/contradiction-review-5LTTVDQV.js.map +1 -0
- package/dist/{contradiction-scan-E3GJTI4F.js → contradiction-scan-3Z6YW7YA.js} +2 -1
- package/dist/{contradiction-scan-E3GJTI4F.js.map → contradiction-scan-3Z6YW7YA.js.map} +1 -1
- package/dist/cross-namespace-budget.js +1 -0
- package/dist/cue-anchors.js +1 -0
- package/dist/dashboard-runtime.js +1 -0
- package/dist/day-summary.js +1 -0
- package/dist/delinearize.js +1 -0
- package/dist/direct-answer-wiring.js +1 -0
- package/dist/direct-answer.js +1 -0
- package/dist/dreams-ledger-LR2NBAZE.js +286 -0
- package/dist/dreams-ledger-LR2NBAZE.js.map +1 -0
- package/dist/embedding-fallback.js +1 -0
- package/dist/{engine-72LSIWQP.js → engine-ICC2DSQF.js} +10 -7
- package/dist/engine-ICC2DSQF.js.map +1 -0
- package/dist/entity-retrieval.d.ts +1 -1
- package/dist/entity-retrieval.js +9 -6
- package/dist/entity-schema.js +1 -0
- package/dist/evals.js +1 -0
- package/dist/evidence-pack.d.ts +16 -0
- package/dist/evidence-pack.js +8 -0
- package/dist/evidence-pack.js.map +1 -0
- package/dist/explicit-capture.d.ts +6 -4
- package/dist/explicit-capture.js +1 -0
- package/dist/extraction-judge-telemetry.js +1 -0
- package/dist/extraction-judge-training.js +1 -0
- package/dist/extraction-judge.js +1 -0
- package/dist/extraction.js +7 -6
- package/dist/fallback-llm.js +3 -2
- package/dist/first-start-migration-4MHQEOSD.js +263 -0
- package/dist/first-start-migration-4MHQEOSD.js.map +1 -0
- package/dist/forget-PLR6J5DN.js +69 -0
- package/dist/forget-PLR6J5DN.js.map +1 -0
- package/dist/framework-CyHYDcri.d.ts +153 -0
- package/dist/fs-utils-IRVUFB6G.js +30 -0
- package/dist/fs-utils-IRVUFB6G.js.map +1 -0
- package/dist/graph-dashboard-diff.js +1 -0
- package/dist/graph-dashboard-key.js +1 -0
- package/dist/graph-dashboard-parser.js +1 -0
- package/dist/graph-edge-decay-PWB63GRE.js +207 -0
- package/dist/graph-edge-decay-PWB63GRE.js.map +1 -0
- package/dist/graph-edge-reinforcement.d.ts +81 -0
- package/dist/graph-edge-reinforcement.js +24 -0
- package/dist/graph-edge-reinforcement.js.map +1 -0
- package/dist/graph-events.d.ts +87 -0
- package/dist/graph-events.js +14 -0
- package/dist/graph-events.js.map +1 -0
- package/dist/graph-recall.js +1 -0
- package/dist/graph-retrieval.js +1 -0
- package/dist/graph-snapshot.d.ts +112 -0
- package/dist/graph-snapshot.js +19 -0
- package/dist/graph-snapshot.js.map +1 -0
- package/dist/graph.d.ts +105 -7
- package/dist/graph.js +20 -3
- package/dist/harmonic-retrieval.js +1 -0
- package/dist/himem.js +1 -0
- package/dist/hygiene.js +1 -0
- package/dist/identity-continuity.js +1 -0
- package/dist/importance.js +1 -0
- package/dist/index.d.ts +562 -13
- package/dist/index.js +329 -67
- package/dist/index.js.map +1 -1
- package/dist/intent.js +1 -0
- package/dist/json-extract.js +1 -0
- package/dist/json-store.js +1 -0
- package/dist/kdf-7S6RWKLZ.js +26 -0
- package/dist/kdf-7S6RWKLZ.js.map +1 -0
- package/dist/legacy-hook-compat.js +1 -0
- package/dist/legacy-hook-compat.js.map +1 -1
- package/dist/lifecycle.js +1 -0
- package/dist/live-connectors-runner.d.ts +48 -0
- package/dist/live-connectors-runner.js +17 -0
- package/dist/live-connectors-runner.js.map +1 -0
- package/dist/local-llm.js +1 -0
- package/dist/logger.js +1 -0
- package/dist/memory-action-policy.js +1 -0
- package/dist/memory-cache.d.ts +2 -1
- package/dist/memory-cache.js +4 -1
- package/dist/memory-governance-KG52RITE.js +37 -0
- package/dist/memory-governance-KG52RITE.js.map +1 -0
- package/dist/memory-lifecycle-ledger-utils.d.ts +2 -1
- package/dist/memory-lifecycle-ledger-utils.js +4 -1
- package/dist/memory-projection-format.js +1 -0
- package/dist/{memory-projection-store-DeSXPh1j.d.ts → memory-projection-store-D3vBHS4J.d.ts} +1 -0
- package/dist/memory-projection-store.d.ts +1 -1
- package/dist/memory-projection-store.js +1 -0
- package/dist/memory-worth-bench.js +1 -0
- package/dist/memory-worth-bench.js.map +1 -1
- package/dist/memory-worth-filter.js +1 -0
- package/dist/memory-worth-outcomes.d.ts +1 -1
- package/dist/memory-worth-outcomes.js +1 -0
- package/dist/memory-worth.js +1 -0
- package/dist/metadata-FC3XPDRQ.js +21 -0
- package/dist/metadata-FC3XPDRQ.js.map +1 -0
- package/dist/migrate-from-identity-anchor-TTEDEJGX.js +8 -0
- package/dist/migrate-from-identity-anchor-TTEDEJGX.js.map +1 -0
- package/dist/model-registry.js +1 -0
- package/dist/models-json.js +1 -0
- package/dist/native-knowledge.js +1 -0
- package/dist/negative.js +1 -0
- package/dist/objective-state-writers.js +1 -0
- package/dist/objective-state-writers.js.map +1 -1
- package/dist/objective-state.js +1 -0
- package/dist/openai-chat-compat.js +1 -0
- package/dist/operator-toolkit.d.ts +46 -2
- package/dist/operator-toolkit.js +28 -16
- package/dist/opik-exporter.js +1 -0
- package/dist/opik-exporter.js.map +1 -1
- package/dist/{orchestrator-CmJ-NTdJ.d.ts → orchestrator-ChkesB8U.d.ts} +177 -13
- package/dist/orchestrator.d.ts +6 -4
- package/dist/orchestrator.js +55 -39
- package/dist/page-versioning.js +1 -0
- package/dist/path-RMTY5Y5A.js +9 -0
- package/dist/path-RMTY5Y5A.js.map +1 -0
- package/dist/patterns-cli.d.ts +160 -0
- package/dist/patterns-cli.js +29 -0
- package/dist/patterns-cli.js.map +1 -0
- package/dist/peers-6OSQ3NK6.js +44 -0
- package/dist/peers-6OSQ3NK6.js.map +1 -0
- package/dist/plugin-id.js +1 -0
- package/dist/policy-runtime.js +1 -0
- package/dist/{port-BADbLZU5.d.ts → port-hqGnoStS.d.ts} +6 -0
- package/dist/profiling.js +1 -0
- package/dist/purge-6ATBGT77.js +205 -0
- package/dist/purge-6ATBGT77.js.map +1 -0
- package/dist/qmd-recall-cache.d.ts +1 -1
- package/dist/qmd-recall-cache.js +1 -0
- package/dist/qmd.d.ts +2 -1
- package/dist/qmd.js +4 -3
- package/dist/reasoning-trace-recall.js +1 -0
- package/dist/reasoning-trace-types.js +1 -0
- package/dist/recall-audit-anomaly.js +1 -0
- package/dist/recall-audit.js +1 -0
- package/dist/recall-disclosure-escalation.d.ts +84 -0
- package/dist/recall-disclosure-escalation.js +14 -0
- package/dist/recall-disclosure-escalation.js.map +1 -0
- package/dist/recall-explain-renderer.js +4 -1
- package/dist/recall-mmr.js +1 -0
- package/dist/recall-qos.js +1 -0
- package/dist/recall-query-policy.js +1 -0
- package/dist/recall-state.d.ts +7 -0
- package/dist/recall-state.js +2 -1
- package/dist/recall-tag-filter.d.ts +56 -0
- package/dist/recall-tag-filter.js +14 -0
- package/dist/recall-tag-filter.js.map +1 -0
- package/dist/recall-tokenization.js +1 -0
- package/dist/recall-xray-cli.d.ts +9 -2
- package/dist/recall-xray-cli.js +9 -4
- package/dist/recall-xray-renderer.js +4 -1
- package/dist/recall-xray.d.ts +116 -2
- package/dist/recall-xray.js +9 -3
- package/dist/reconstruct.js +1 -0
- package/dist/release-changelog.js +2 -0
- package/dist/release-changelog.js.map +1 -1
- package/dist/relevance.js +1 -0
- package/dist/rerank.js +1 -0
- package/dist/{resolution-QBTDHTG7.js → resolution-YGIBORXI.js} +2 -1
- package/dist/{resolution-QBTDHTG7.js.map → resolution-YGIBORXI.js.map} +1 -1
- package/dist/resolve-auth-token.d.ts +51 -0
- package/dist/resolve-auth-token.js +12 -0
- package/dist/resolve-auth-token.js.map +1 -0
- package/dist/resolve-provider-secret.d.ts +9 -1
- package/dist/resolve-provider-secret.js +4 -1
- package/dist/resume-bundles.js +4 -3
- package/dist/retrieval-agents.d.ts +1 -1
- package/dist/retrieval-agents.js +1 -0
- package/dist/retrieval-tiers.js +1 -0
- package/dist/retrieval.js +1 -0
- package/dist/sanitize.js +1 -0
- package/dist/schemas.d.ts +37 -24
- package/dist/schemas.js +2 -1
- package/dist/sdk-compat.js +1 -0
- package/dist/sdk-compat.js.map +1 -1
- package/dist/secure-store-4R2GSO7S.js +156 -0
- package/dist/secure-store-4R2GSO7S.js.map +1 -0
- package/dist/semantic-chunking.js +1 -0
- package/dist/{semantic-consolidation-CxJU6MJk.d.ts → semantic-consolidation-ByBXb-sf.d.ts} +3 -3
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +11 -6
- package/dist/semantic-rule-promotion.d.ts +1 -1
- package/dist/semantic-rule-promotion.js +9 -6
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +9 -6
- package/dist/session-integrity.js +1 -0
- package/dist/session-observer-bands.js +1 -0
- package/dist/session-observer-state.js +1 -0
- package/dist/session-toggles.js +2 -0
- package/dist/session-toggles.js.map +1 -1
- package/dist/signal.js +1 -0
- package/dist/skills-registry.js +2 -0
- package/dist/skills-registry.js.map +1 -1
- package/dist/source-attribution.js +1 -0
- package/dist/state-NCHQ4TRG.js +8 -0
- package/dist/state-NCHQ4TRG.js.map +1 -0
- package/dist/state-store-3EH7HYIN.js +16 -0
- package/dist/state-store-3EH7HYIN.js.map +1 -0
- package/dist/storage.d.ts +76 -2
- package/dist/storage.js +8 -5
- package/dist/store-contract.js +1 -0
- package/dist/summarizer.js +5 -4
- package/dist/summary-snapshot.js +1 -0
- package/dist/temporal-index.js +1 -0
- package/dist/temporal-supersession.d.ts +1 -1
- package/dist/temporal-supersession.js +2 -1
- package/dist/temporal-validity.d.ts +52 -0
- package/dist/temporal-validity.js +14 -0
- package/dist/temporal-validity.js.map +1 -0
- package/dist/threading.js +1 -0
- package/dist/tier-migration.d.ts +2 -2
- package/dist/tier-migration.js +1 -0
- package/dist/tier-routing.js +1 -0
- package/dist/tier-stats-62ZVDFKS.js +152 -0
- package/dist/tier-stats-62ZVDFKS.js.map +1 -0
- package/dist/tmt.js +1 -0
- package/dist/tokens.js +1 -0
- package/dist/topics.js +1 -0
- package/dist/trace-C5ETWBEF.js +290 -0
- package/dist/trace-C5ETWBEF.js.map +1 -0
- package/dist/transcript.js +1 -0
- package/dist/trust-zones.js +1 -0
- package/dist/tui-RI7P6PBS.js +13 -0
- package/dist/tui-RI7P6PBS.js.map +1 -0
- package/dist/types-V3FJ26TF.js +30 -0
- package/dist/types-V3FJ26TF.js.map +1 -0
- package/dist/types.d.ts +634 -9
- package/dist/types.js +10 -3
- package/dist/utility-learner.js +1 -0
- package/dist/utility-runtime.js +1 -0
- package/dist/utility-telemetry.js +1 -0
- package/dist/verified-recall.js +9 -6
- package/dist/version-utils.js +1 -0
- package/dist/whitespace.js +1 -0
- package/dist/work-product-ledger.js +1 -0
- package/package.json +2 -1
- package/dist/access-service-Br8ZydTK.d.ts +0 -827
- package/dist/chunk-3OGMS3PE.js.map +0 -1
- package/dist/chunk-3YGHKTBF.js.map +0 -1
- package/dist/chunk-6PFRXT4K.js.map +0 -1
- package/dist/chunk-6YJHX2DL.js.map +0 -1
- package/dist/chunk-BECYBZLX.js.map +0 -1
- package/dist/chunk-C2EFFULQ.js.map +0 -1
- package/dist/chunk-CUPFXL3J.js.map +0 -1
- package/dist/chunk-DIXB44VE.js.map +0 -1
- package/dist/chunk-F5VP6YCB.js.map +0 -1
- package/dist/chunk-FVA6TGI3.js.map +0 -1
- package/dist/chunk-GA5P7RST.js.map +0 -1
- package/dist/chunk-KVBLZUKV.js.map +0 -1
- package/dist/chunk-L7IXWRYE.js.map +0 -1
- package/dist/chunk-LOIMBRDE.js.map +0 -1
- package/dist/chunk-LTCGGW2D.js +0 -14
- package/dist/chunk-LTCGGW2D.js.map +0 -1
- package/dist/chunk-NZLQTHS5.js.map +0 -1
- package/dist/chunk-OC5OXUQ4.js.map +0 -1
- package/dist/chunk-PVPWZSSI.js.map +0 -1
- package/dist/chunk-SPI27QT6.js.map +0 -1
- package/dist/chunk-STGWEHYR.js.map +0 -1
- package/dist/chunk-TP4FZJIZ.js.map +0 -1
- package/dist/chunk-ULYOGL6R.js.map +0 -1
- package/dist/chunk-UWB5LMWY.js.map +0 -1
- package/dist/chunk-VBVG2M5G.js.map +0 -1
- package/dist/chunk-VDX363PS.js.map +0 -1
- package/dist/chunk-WCLICCGB.js.map +0 -1
- package/dist/chunk-X6GF3FX2.js +0 -26
- package/dist/chunk-X6GF3FX2.js.map +0 -1
- package/dist/chunk-XXVWLXSG.js.map +0 -1
- package/dist/chunk-Y7R2XJ5Q.js.map +0 -1
- package/dist/chunk-ZAIM4TUE.js.map +0 -1
- /package/dist/{contradiction-review-WIUBAR52.js.map → capsule-cli.js.map} +0 -0
- /package/dist/{engine-72LSIWQP.js.map → capsule-crypto-5CYAGVC5.js.map} +0 -0
- /package/dist/{chunk-TMYO7B5P.js.map → chunk-47WOM4YW.js.map} +0 -0
- /package/dist/{chunk-DG6YMRDC.js.map → chunk-B2TL6GA2.js.map} +0 -0
- /package/dist/{chunk-AYXIPSZO.js.map → chunk-CRU27Q4J.js.map} +0 -0
- /package/dist/{chunk-RBBWYEFJ.js.map → chunk-G2WADRQ3.js.map} +0 -0
- /package/dist/{chunk-NBVAS5MT.js.map → chunk-R2L7SUX2.js.map} +0 -0
|
@@ -0,0 +1,875 @@
|
|
|
1
|
+
// src/peers/migrate-from-identity-anchor.ts
|
|
2
|
+
import { promises as fs2, constants as fsConstants2 } from "fs";
|
|
3
|
+
import path2 from "path";
|
|
4
|
+
|
|
5
|
+
// src/peers/storage.ts
|
|
6
|
+
import { promises as fs, constants as fsConstants } from "fs";
|
|
7
|
+
import path from "path";
|
|
8
|
+
|
|
9
|
+
// src/peers/types.ts
|
|
10
|
+
var PEER_ID_PATTERN = /^[A-Za-z0-9]+(?:[._-][A-Za-z0-9]+)*$/;
|
|
11
|
+
var PEER_ID_MAX_LENGTH = 64;
|
|
12
|
+
|
|
13
|
+
// src/peers/storage.ts
|
|
14
|
+
async function openNoFollow(file, flags) {
|
|
15
|
+
return fs.open(file, flags | fsConstants.O_NOFOLLOW);
|
|
16
|
+
}
|
|
17
|
+
async function readFileNoFollow(file) {
|
|
18
|
+
await assertParentDirInodeStable(file);
|
|
19
|
+
const fh = await openNoFollow(file, fsConstants.O_RDONLY);
|
|
20
|
+
try {
|
|
21
|
+
return await fh.readFile("utf8");
|
|
22
|
+
} finally {
|
|
23
|
+
await fh.close();
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
async function assertParentDirInodeStable(filePath) {
|
|
27
|
+
const parent = path.dirname(filePath);
|
|
28
|
+
const dh = await fs.open(
|
|
29
|
+
parent,
|
|
30
|
+
fsConstants.O_RDONLY | fsConstants.O_DIRECTORY | fsConstants.O_NOFOLLOW
|
|
31
|
+
);
|
|
32
|
+
try {
|
|
33
|
+
const fstatInfo = await dh.stat();
|
|
34
|
+
const lstatInfo = await fs.lstat(parent);
|
|
35
|
+
if (fstatInfo.ino !== lstatInfo.ino || fstatInfo.dev !== lstatInfo.dev) {
|
|
36
|
+
throw new Error(
|
|
37
|
+
`parent directory "${parent}" was swapped between checks (inode mismatch)`
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
if (lstatInfo.isSymbolicLink()) {
|
|
41
|
+
throw new Error(`parent directory "${parent}" is a symlink and is rejected`);
|
|
42
|
+
}
|
|
43
|
+
} finally {
|
|
44
|
+
await dh.close();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async function writeFileNoFollow(file, data) {
|
|
48
|
+
await assertParentDirInodeStable(file);
|
|
49
|
+
const fh = await openNoFollow(
|
|
50
|
+
file,
|
|
51
|
+
fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_TRUNC
|
|
52
|
+
);
|
|
53
|
+
try {
|
|
54
|
+
await fh.writeFile(data, "utf8");
|
|
55
|
+
} finally {
|
|
56
|
+
await fh.close();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
async function appendFileNoFollow(file, data) {
|
|
60
|
+
await assertParentDirInodeStable(file);
|
|
61
|
+
const fh = await openNoFollow(
|
|
62
|
+
file,
|
|
63
|
+
fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_APPEND
|
|
64
|
+
);
|
|
65
|
+
try {
|
|
66
|
+
await fh.writeFile(data, "utf8");
|
|
67
|
+
} finally {
|
|
68
|
+
await fh.close();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
var ALLOWED_KINDS = /* @__PURE__ */ new Set([
|
|
72
|
+
"self",
|
|
73
|
+
"human",
|
|
74
|
+
"agent",
|
|
75
|
+
"integration"
|
|
76
|
+
]);
|
|
77
|
+
function assertValidPeerId(peerId) {
|
|
78
|
+
if (typeof peerId !== "string") {
|
|
79
|
+
throw new Error("peerId must be a string");
|
|
80
|
+
}
|
|
81
|
+
if (peerId.length === 0) {
|
|
82
|
+
throw new Error("peerId must not be empty");
|
|
83
|
+
}
|
|
84
|
+
if (peerId.length > PEER_ID_MAX_LENGTH) {
|
|
85
|
+
throw new Error(`peerId must be \u2264 ${PEER_ID_MAX_LENGTH} characters`);
|
|
86
|
+
}
|
|
87
|
+
if (!PEER_ID_PATTERN.test(peerId)) {
|
|
88
|
+
throw new Error(
|
|
89
|
+
`peerId "${peerId}" is invalid \u2014 must match ${PEER_ID_PATTERN}`
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
if (/[.\-_]{2,}/.test(peerId)) {
|
|
93
|
+
throw new Error(
|
|
94
|
+
`peerId "${peerId}" is invalid \u2014 must not contain consecutive separators`
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function isPlainObject(value) {
|
|
99
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
const proto = Object.getPrototypeOf(value);
|
|
103
|
+
return proto === Object.prototype || proto === null;
|
|
104
|
+
}
|
|
105
|
+
function assertValidKind(kind) {
|
|
106
|
+
if (typeof kind !== "string" || !ALLOWED_KINDS.has(kind)) {
|
|
107
|
+
throw new Error(
|
|
108
|
+
`peer kind must be one of ${Array.from(ALLOWED_KINDS).join(", ")}`
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
var PEERS_DIR_NAME = "peers";
|
|
113
|
+
function peersRoot(memoryDir) {
|
|
114
|
+
return path.join(memoryDir, PEERS_DIR_NAME);
|
|
115
|
+
}
|
|
116
|
+
function peerDir(memoryDir, peerId) {
|
|
117
|
+
assertValidPeerId(peerId);
|
|
118
|
+
const candidate = path.join(peersRoot(memoryDir), peerId);
|
|
119
|
+
const root = peersRoot(memoryDir);
|
|
120
|
+
const relative = path.relative(root, candidate);
|
|
121
|
+
if (relative.startsWith("..") || path.isAbsolute(relative)) {
|
|
122
|
+
throw new Error(`peerId "${peerId}" resolves outside peers root`);
|
|
123
|
+
}
|
|
124
|
+
return candidate;
|
|
125
|
+
}
|
|
126
|
+
async function assertPeersRootNotSymlink(memoryDir) {
|
|
127
|
+
const root = peersRoot(memoryDir);
|
|
128
|
+
let rootStat = null;
|
|
129
|
+
try {
|
|
130
|
+
rootStat = await fs.lstat(root);
|
|
131
|
+
} catch (err) {
|
|
132
|
+
if (err.code !== "ENOENT") throw err;
|
|
133
|
+
}
|
|
134
|
+
if (rootStat && rootStat.isSymbolicLink()) {
|
|
135
|
+
throw new Error(`peers root "${root}" is a symlink and is rejected`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
async function mkdirPeerDirAtomic(memoryDir, peerId) {
|
|
139
|
+
const root = peersRoot(memoryDir);
|
|
140
|
+
await fs.mkdir(memoryDir, { recursive: true });
|
|
141
|
+
try {
|
|
142
|
+
await fs.mkdir(root);
|
|
143
|
+
} catch (err) {
|
|
144
|
+
if (err.code !== "EEXIST") throw err;
|
|
145
|
+
}
|
|
146
|
+
const rootLstat = await fs.lstat(root);
|
|
147
|
+
if (rootLstat.isSymbolicLink()) {
|
|
148
|
+
throw new Error(`peers root "${root}" is a symlink and is rejected`);
|
|
149
|
+
}
|
|
150
|
+
if (!rootLstat.isDirectory()) {
|
|
151
|
+
throw new Error(`peers root "${root}" exists but is not a directory`);
|
|
152
|
+
}
|
|
153
|
+
const rootHandle = await fs.open(
|
|
154
|
+
root,
|
|
155
|
+
fsConstants.O_RDONLY | fsConstants.O_DIRECTORY | fsConstants.O_NOFOLLOW
|
|
156
|
+
);
|
|
157
|
+
try {
|
|
158
|
+
const candidate = peerDir(memoryDir, peerId);
|
|
159
|
+
await fs.mkdir(candidate, { recursive: true });
|
|
160
|
+
const fstatRoot = await rootHandle.stat();
|
|
161
|
+
const lstatRoot = await fs.lstat(root);
|
|
162
|
+
if (fstatRoot.ino !== lstatRoot.ino || fstatRoot.dev !== lstatRoot.dev) {
|
|
163
|
+
throw new Error(`peers root "${root}" was swapped during mkdir`);
|
|
164
|
+
}
|
|
165
|
+
const peerLstat = await fs.lstat(candidate);
|
|
166
|
+
if (peerLstat.isSymbolicLink()) {
|
|
167
|
+
throw new Error(`peer directory "${peerId}" is a symlink and is rejected`);
|
|
168
|
+
}
|
|
169
|
+
} finally {
|
|
170
|
+
await rootHandle.close();
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
async function assertPeerDirNotEscaped(memoryDir, peerId) {
|
|
174
|
+
const candidate = peerDir(memoryDir, peerId);
|
|
175
|
+
const root = peersRoot(memoryDir);
|
|
176
|
+
await assertPeersRootNotSymlink(memoryDir);
|
|
177
|
+
let candidateStat = null;
|
|
178
|
+
try {
|
|
179
|
+
candidateStat = await fs.lstat(candidate);
|
|
180
|
+
} catch (err) {
|
|
181
|
+
if (err.code !== "ENOENT") throw err;
|
|
182
|
+
}
|
|
183
|
+
if (candidateStat && candidateStat.isSymbolicLink()) {
|
|
184
|
+
throw new Error(`peer directory "${peerId}" is a symlink and is rejected`);
|
|
185
|
+
}
|
|
186
|
+
if (candidateStat) {
|
|
187
|
+
const realRoot = await fs.realpath(root);
|
|
188
|
+
const realCandidate = await fs.realpath(candidate);
|
|
189
|
+
const rel = path.relative(realRoot, realCandidate);
|
|
190
|
+
if (rel === "" || rel.startsWith("..") || path.isAbsolute(rel)) {
|
|
191
|
+
throw new Error(`peer directory "${peerId}" escapes the peers root`);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
function identityPath(memoryDir, peerId) {
|
|
196
|
+
return path.join(peerDir(memoryDir, peerId), "identity.md");
|
|
197
|
+
}
|
|
198
|
+
function profilePath(memoryDir, peerId) {
|
|
199
|
+
return path.join(peerDir(memoryDir, peerId), "profile.md");
|
|
200
|
+
}
|
|
201
|
+
function interactionsPath(memoryDir, peerId) {
|
|
202
|
+
return path.join(peerDir(memoryDir, peerId), "interactions.log.md");
|
|
203
|
+
}
|
|
204
|
+
function escapeYamlString(value) {
|
|
205
|
+
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t")}"`;
|
|
206
|
+
}
|
|
207
|
+
function unescapeYamlString(quoted) {
|
|
208
|
+
const body = quoted.slice(1, -1);
|
|
209
|
+
let out = "";
|
|
210
|
+
for (let i = 0; i < body.length; i++) {
|
|
211
|
+
const ch = body[i];
|
|
212
|
+
if (ch === "\\" && i + 1 < body.length) {
|
|
213
|
+
const next = body[i + 1];
|
|
214
|
+
if (next === "\\" || next === '"') {
|
|
215
|
+
out += next;
|
|
216
|
+
i++;
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
if (next === "n") {
|
|
220
|
+
out += "\n";
|
|
221
|
+
i++;
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
if (next === "r") {
|
|
225
|
+
out += "\r";
|
|
226
|
+
i++;
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
if (next === "t") {
|
|
230
|
+
out += " ";
|
|
231
|
+
i++;
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
out += ch;
|
|
236
|
+
}
|
|
237
|
+
return out;
|
|
238
|
+
}
|
|
239
|
+
function parsePeerFrontmatter(raw) {
|
|
240
|
+
const text = raw.replace(/^/, "");
|
|
241
|
+
if (!text.startsWith("---")) {
|
|
242
|
+
throw new Error("peer file is missing YAML frontmatter delimiter");
|
|
243
|
+
}
|
|
244
|
+
const after = text.slice(3);
|
|
245
|
+
const close = after.indexOf("\n---");
|
|
246
|
+
if (close === -1) {
|
|
247
|
+
throw new Error("peer file frontmatter is not terminated");
|
|
248
|
+
}
|
|
249
|
+
const fmBlock = after.slice(0, close).replace(/^\n/, "");
|
|
250
|
+
const body = after.slice(close + 4).replace(/^\n/, "");
|
|
251
|
+
const fields = {};
|
|
252
|
+
for (const lineRaw of fmBlock.split("\n")) {
|
|
253
|
+
const line = lineRaw.trim();
|
|
254
|
+
if (line === "" || line.startsWith("#")) continue;
|
|
255
|
+
const colon = line.indexOf(":");
|
|
256
|
+
if (colon === -1) {
|
|
257
|
+
throw new Error(`peer frontmatter line is malformed: ${line}`);
|
|
258
|
+
}
|
|
259
|
+
const key = line.slice(0, colon).trim();
|
|
260
|
+
const valueRaw = line.slice(colon + 1).trim();
|
|
261
|
+
if (key === "") {
|
|
262
|
+
throw new Error(`peer frontmatter has empty key: ${line}`);
|
|
263
|
+
}
|
|
264
|
+
let value;
|
|
265
|
+
if (valueRaw.startsWith('"') && valueRaw.endsWith('"') && valueRaw.length >= 2) {
|
|
266
|
+
value = unescapeYamlString(valueRaw);
|
|
267
|
+
} else {
|
|
268
|
+
value = valueRaw;
|
|
269
|
+
}
|
|
270
|
+
fields[key] = value;
|
|
271
|
+
}
|
|
272
|
+
return { fields, body };
|
|
273
|
+
}
|
|
274
|
+
function emitPeerIdentity(peer) {
|
|
275
|
+
const lines = ["---"];
|
|
276
|
+
lines.push(`id: ${escapeYamlString(peer.id)}`);
|
|
277
|
+
lines.push(`kind: ${peer.kind}`);
|
|
278
|
+
lines.push(`displayName: ${escapeYamlString(peer.displayName)}`);
|
|
279
|
+
lines.push(`createdAt: ${escapeYamlString(peer.createdAt)}`);
|
|
280
|
+
lines.push(`updatedAt: ${escapeYamlString(peer.updatedAt)}`);
|
|
281
|
+
lines.push("---");
|
|
282
|
+
lines.push("");
|
|
283
|
+
lines.push(peer.notes ?? "");
|
|
284
|
+
let out = lines.join("\n");
|
|
285
|
+
while (out.endsWith("\n")) out = out.slice(0, -1);
|
|
286
|
+
return out + "\n";
|
|
287
|
+
}
|
|
288
|
+
async function readPeer(memoryDir, peerId) {
|
|
289
|
+
assertValidPeerId(peerId);
|
|
290
|
+
await assertPeerDirNotEscaped(memoryDir, peerId);
|
|
291
|
+
const file = identityPath(memoryDir, peerId);
|
|
292
|
+
let raw;
|
|
293
|
+
try {
|
|
294
|
+
raw = await readFileNoFollow(file);
|
|
295
|
+
} catch (err) {
|
|
296
|
+
if (err.code === "ENOENT") {
|
|
297
|
+
return null;
|
|
298
|
+
}
|
|
299
|
+
throw err;
|
|
300
|
+
}
|
|
301
|
+
const { fields, body } = parsePeerFrontmatter(raw);
|
|
302
|
+
const id = fields.id ?? peerId;
|
|
303
|
+
if (id !== peerId) {
|
|
304
|
+
throw new Error(
|
|
305
|
+
`peer identity file mismatch \u2014 expected id "${peerId}", file claims "${id}"`
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
const kind = fields.kind;
|
|
309
|
+
assertValidKind(kind);
|
|
310
|
+
const displayName = fields.displayName ?? "";
|
|
311
|
+
const createdAt = fields.createdAt ?? "";
|
|
312
|
+
if (createdAt === "") {
|
|
313
|
+
throw new Error(`peer "${peerId}" is missing createdAt`);
|
|
314
|
+
}
|
|
315
|
+
const rawUpdatedAt = fields.updatedAt;
|
|
316
|
+
const updatedAt = typeof rawUpdatedAt === "string" && rawUpdatedAt.length > 0 ? rawUpdatedAt : createdAt;
|
|
317
|
+
let trimmedBody = body;
|
|
318
|
+
if (trimmedBody.startsWith("\r\n")) trimmedBody = trimmedBody.slice(2);
|
|
319
|
+
else if (trimmedBody.startsWith("\n")) trimmedBody = trimmedBody.slice(1);
|
|
320
|
+
if (trimmedBody.endsWith("\r\n")) trimmedBody = trimmedBody.slice(0, -2);
|
|
321
|
+
else if (trimmedBody.endsWith("\n")) trimmedBody = trimmedBody.slice(0, -1);
|
|
322
|
+
return {
|
|
323
|
+
id: peerId,
|
|
324
|
+
kind,
|
|
325
|
+
displayName,
|
|
326
|
+
createdAt,
|
|
327
|
+
updatedAt,
|
|
328
|
+
notes: trimmedBody === "" ? void 0 : trimmedBody
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
async function writePeer(memoryDir, peer) {
|
|
332
|
+
assertValidPeerId(peer.id);
|
|
333
|
+
assertValidKind(peer.kind);
|
|
334
|
+
if (typeof peer.displayName !== "string") {
|
|
335
|
+
throw new Error("peer.displayName must be a string");
|
|
336
|
+
}
|
|
337
|
+
if (typeof peer.createdAt !== "string" || peer.createdAt === "") {
|
|
338
|
+
throw new Error("peer.createdAt must be a non-empty ISO-8601 string");
|
|
339
|
+
}
|
|
340
|
+
if (typeof peer.updatedAt !== "string" || peer.updatedAt === "") {
|
|
341
|
+
throw new Error("peer.updatedAt must be a non-empty ISO-8601 string");
|
|
342
|
+
}
|
|
343
|
+
if (peer.notes !== void 0 && typeof peer.notes !== "string") {
|
|
344
|
+
throw new Error("peer.notes must be a string when provided");
|
|
345
|
+
}
|
|
346
|
+
await mkdirPeerDirAtomic(memoryDir, peer.id);
|
|
347
|
+
await assertPeerDirNotEscaped(memoryDir, peer.id);
|
|
348
|
+
const file = identityPath(memoryDir, peer.id);
|
|
349
|
+
await writeFileNoFollow(file, emitPeerIdentity(peer));
|
|
350
|
+
}
|
|
351
|
+
async function deletePeer(memoryDir, peerId) {
|
|
352
|
+
assertValidPeerId(peerId);
|
|
353
|
+
await assertPeerDirNotEscaped(memoryDir, peerId);
|
|
354
|
+
const file = identityPath(memoryDir, peerId);
|
|
355
|
+
let lstatBefore;
|
|
356
|
+
try {
|
|
357
|
+
lstatBefore = await fs.lstat(file);
|
|
358
|
+
} catch (err) {
|
|
359
|
+
if (err.code === "ENOENT") {
|
|
360
|
+
return false;
|
|
361
|
+
}
|
|
362
|
+
throw err;
|
|
363
|
+
}
|
|
364
|
+
if (lstatBefore.isSymbolicLink()) {
|
|
365
|
+
throw new Error(`refusing to unlink "${file}": target is a symlink`);
|
|
366
|
+
}
|
|
367
|
+
if (!lstatBefore.isFile()) {
|
|
368
|
+
throw new Error(`refusing to unlink "${file}": target is not a regular file`);
|
|
369
|
+
}
|
|
370
|
+
await assertParentDirInodeStable(file);
|
|
371
|
+
try {
|
|
372
|
+
await fs.unlink(file);
|
|
373
|
+
} catch (err) {
|
|
374
|
+
if (err.code === "ENOENT") {
|
|
375
|
+
return false;
|
|
376
|
+
}
|
|
377
|
+
throw err;
|
|
378
|
+
}
|
|
379
|
+
return true;
|
|
380
|
+
}
|
|
381
|
+
async function forgetPeer(memoryDir, peerId, opts) {
|
|
382
|
+
if (opts.confirm !== "yes") {
|
|
383
|
+
throw new Error("forgetPeer requires confirm: 'yes'");
|
|
384
|
+
}
|
|
385
|
+
assertValidPeerId(peerId);
|
|
386
|
+
await assertPeersRootNotSymlink(memoryDir);
|
|
387
|
+
await assertPeerDirNotEscaped(memoryDir, peerId);
|
|
388
|
+
const dir = peerDir(memoryDir, peerId);
|
|
389
|
+
let dirStat;
|
|
390
|
+
try {
|
|
391
|
+
dirStat = await fs.lstat(dir);
|
|
392
|
+
} catch (err) {
|
|
393
|
+
if (err.code === "ENOENT") {
|
|
394
|
+
return { purged: false };
|
|
395
|
+
}
|
|
396
|
+
throw err;
|
|
397
|
+
}
|
|
398
|
+
if (dirStat.isSymbolicLink()) {
|
|
399
|
+
throw new Error(
|
|
400
|
+
`refusing to purge peer directory "${peerId}": target is a symlink`
|
|
401
|
+
);
|
|
402
|
+
}
|
|
403
|
+
if (!dirStat.isDirectory()) {
|
|
404
|
+
throw new Error(
|
|
405
|
+
`refusing to purge peer directory "${peerId}": target is not a directory`
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
await fs.rm(dir, { recursive: true, force: true });
|
|
409
|
+
return { purged: true };
|
|
410
|
+
}
|
|
411
|
+
async function listPeers(memoryDir) {
|
|
412
|
+
const root = peersRoot(memoryDir);
|
|
413
|
+
let entries;
|
|
414
|
+
let dh = null;
|
|
415
|
+
try {
|
|
416
|
+
dh = await fs.open(
|
|
417
|
+
root,
|
|
418
|
+
fsConstants.O_RDONLY | fsConstants.O_DIRECTORY | fsConstants.O_NOFOLLOW
|
|
419
|
+
);
|
|
420
|
+
const fstatBefore = await dh.stat();
|
|
421
|
+
entries = await fs.readdir(root);
|
|
422
|
+
const lstatAfter = await fs.lstat(root);
|
|
423
|
+
if (fstatBefore.ino !== lstatAfter.ino || fstatBefore.dev !== lstatAfter.dev || lstatAfter.isSymbolicLink()) {
|
|
424
|
+
throw new Error(`peers root "${root}" was swapped during readdir`);
|
|
425
|
+
}
|
|
426
|
+
} catch (err) {
|
|
427
|
+
if (err.code === "ENOENT") {
|
|
428
|
+
return [];
|
|
429
|
+
}
|
|
430
|
+
throw err;
|
|
431
|
+
} finally {
|
|
432
|
+
if (dh) await dh.close();
|
|
433
|
+
}
|
|
434
|
+
const peers = [];
|
|
435
|
+
entries.sort();
|
|
436
|
+
for (const name of entries) {
|
|
437
|
+
if (!PEER_ID_PATTERN.test(name) || name.length > PEER_ID_MAX_LENGTH) {
|
|
438
|
+
continue;
|
|
439
|
+
}
|
|
440
|
+
let stat;
|
|
441
|
+
try {
|
|
442
|
+
stat = await fs.lstat(path.join(root, name));
|
|
443
|
+
} catch (err) {
|
|
444
|
+
if (err.code === "ENOENT") continue;
|
|
445
|
+
throw err;
|
|
446
|
+
}
|
|
447
|
+
if (!stat.isDirectory() || stat.isSymbolicLink()) continue;
|
|
448
|
+
let peer = null;
|
|
449
|
+
try {
|
|
450
|
+
peer = await readPeer(memoryDir, name);
|
|
451
|
+
} catch (err) {
|
|
452
|
+
const code = err.code;
|
|
453
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
454
|
+
const isSecurityFailure = message.startsWith("peers root") || message.startsWith("peer directory") || message.startsWith("parent directory") || message.startsWith("path ") || message.includes("escapes the peers root") || message.includes("inode mismatch") || message.includes("is a symlink and is rejected") || message.includes("was swapped");
|
|
455
|
+
if (isSecurityFailure) throw err;
|
|
456
|
+
if (code && code !== "ENOENT") throw err;
|
|
457
|
+
continue;
|
|
458
|
+
}
|
|
459
|
+
if (peer !== null) {
|
|
460
|
+
peers.push(peer);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
return peers;
|
|
464
|
+
}
|
|
465
|
+
function sanitizeLogField(value) {
|
|
466
|
+
return value.replace(/[\r\n\t]+/g, " ").trim();
|
|
467
|
+
}
|
|
468
|
+
function formatLogEntry(entry) {
|
|
469
|
+
const ts = sanitizeLogField(entry.timestamp);
|
|
470
|
+
const kind = sanitizeLogField(entry.kind);
|
|
471
|
+
const summary = sanitizeLogField(entry.summary);
|
|
472
|
+
const session = entry.sessionId ? ` [session=${sanitizeLogField(entry.sessionId)}]` : "";
|
|
473
|
+
return `- [${ts}] (${kind})${session} ${summary}`;
|
|
474
|
+
}
|
|
475
|
+
async function appendInteractionLog(memoryDir, peerId, entry) {
|
|
476
|
+
assertValidPeerId(peerId);
|
|
477
|
+
if (typeof entry.timestamp !== "string" || entry.timestamp.trim() === "") {
|
|
478
|
+
throw new Error("interaction entry must have a non-whitespace timestamp");
|
|
479
|
+
}
|
|
480
|
+
if (typeof entry.kind !== "string" || entry.kind.trim() === "") {
|
|
481
|
+
throw new Error("interaction entry must have a non-whitespace kind");
|
|
482
|
+
}
|
|
483
|
+
if (typeof entry.summary !== "string") {
|
|
484
|
+
throw new Error("interaction entry must have a string summary");
|
|
485
|
+
}
|
|
486
|
+
if (entry.sessionId !== void 0) {
|
|
487
|
+
if (typeof entry.sessionId !== "string" || entry.sessionId.trim() === "") {
|
|
488
|
+
throw new Error("interaction entry sessionId must be a non-whitespace string when provided");
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
await mkdirPeerDirAtomic(memoryDir, peerId);
|
|
492
|
+
await assertPeerDirNotEscaped(memoryDir, peerId);
|
|
493
|
+
const file = interactionsPath(memoryDir, peerId);
|
|
494
|
+
const line = formatLogEntry(entry) + "\n";
|
|
495
|
+
await appendFileNoFollow(file, line);
|
|
496
|
+
return file;
|
|
497
|
+
}
|
|
498
|
+
function emitPeerProfile(profile) {
|
|
499
|
+
const payload = {
|
|
500
|
+
updatedAt: profile.updatedAt,
|
|
501
|
+
fields: { ...profile.fields },
|
|
502
|
+
provenance: Object.fromEntries(
|
|
503
|
+
Object.entries(profile.provenance).map(([k, v]) => [k, [...v]])
|
|
504
|
+
)
|
|
505
|
+
};
|
|
506
|
+
const json = JSON.stringify(payload, null, 2);
|
|
507
|
+
return [
|
|
508
|
+
"---",
|
|
509
|
+
`peerId: ${escapeYamlString(profile.peerId)}`,
|
|
510
|
+
`updatedAt: ${escapeYamlString(profile.updatedAt)}`,
|
|
511
|
+
"---",
|
|
512
|
+
"",
|
|
513
|
+
"<!-- peer profile \u2014 managed by the async reasoner. Manual edits will be overwritten. -->",
|
|
514
|
+
"",
|
|
515
|
+
"```json",
|
|
516
|
+
json,
|
|
517
|
+
"```",
|
|
518
|
+
""
|
|
519
|
+
].join("\n");
|
|
520
|
+
}
|
|
521
|
+
function parsePeerProfile(raw, peerId) {
|
|
522
|
+
const { fields: fm, body } = parsePeerFrontmatter(raw);
|
|
523
|
+
if (fm.peerId !== void 0 && fm.peerId !== peerId) {
|
|
524
|
+
throw new Error(
|
|
525
|
+
`peer profile mismatch \u2014 expected "${peerId}", file claims "${fm.peerId}"`
|
|
526
|
+
);
|
|
527
|
+
}
|
|
528
|
+
const fenceMatch = body.match(/```json\s*\n([\s\S]*?)\n```/);
|
|
529
|
+
if (!fenceMatch) {
|
|
530
|
+
throw new Error(`peer profile for "${peerId}" is missing JSON payload`);
|
|
531
|
+
}
|
|
532
|
+
let parsed;
|
|
533
|
+
try {
|
|
534
|
+
parsed = JSON.parse(fenceMatch[1]);
|
|
535
|
+
} catch (err) {
|
|
536
|
+
throw new Error(
|
|
537
|
+
`peer profile for "${peerId}" has invalid JSON: ${err.message}`
|
|
538
|
+
);
|
|
539
|
+
}
|
|
540
|
+
if (typeof parsed !== "object" || parsed === null) {
|
|
541
|
+
throw new Error(`peer profile for "${peerId}" is not an object`);
|
|
542
|
+
}
|
|
543
|
+
const payload = parsed;
|
|
544
|
+
const payloadUpdatedAt = typeof payload.updatedAt === "string" ? payload.updatedAt : void 0;
|
|
545
|
+
const updatedAt = payloadUpdatedAt ?? fm.updatedAt ?? "";
|
|
546
|
+
if (typeof updatedAt !== "string" || updatedAt === "") {
|
|
547
|
+
throw new Error(`peer profile for "${peerId}" is missing updatedAt`);
|
|
548
|
+
}
|
|
549
|
+
let fieldsObj;
|
|
550
|
+
if (payload.fields === void 0) {
|
|
551
|
+
fieldsObj = {};
|
|
552
|
+
} else if (typeof payload.fields === "object" && payload.fields !== null && !Array.isArray(payload.fields)) {
|
|
553
|
+
fieldsObj = payload.fields;
|
|
554
|
+
} else {
|
|
555
|
+
throw new Error(`peer profile for "${peerId}" has malformed fields section`);
|
|
556
|
+
}
|
|
557
|
+
let provenanceObj;
|
|
558
|
+
if (payload.provenance === void 0) {
|
|
559
|
+
provenanceObj = {};
|
|
560
|
+
} else if (typeof payload.provenance === "object" && payload.provenance !== null && !Array.isArray(payload.provenance)) {
|
|
561
|
+
provenanceObj = payload.provenance;
|
|
562
|
+
} else {
|
|
563
|
+
throw new Error(`peer profile for "${peerId}" has malformed provenance section`);
|
|
564
|
+
}
|
|
565
|
+
const DANGEROUS_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
566
|
+
const fields = {};
|
|
567
|
+
for (const [k, v] of Object.entries(fieldsObj)) {
|
|
568
|
+
if (DANGEROUS_KEYS.has(k)) continue;
|
|
569
|
+
if (typeof v === "string") fields[k] = v;
|
|
570
|
+
}
|
|
571
|
+
const provenance = {};
|
|
572
|
+
for (const [k, v] of Object.entries(provenanceObj)) {
|
|
573
|
+
if (DANGEROUS_KEYS.has(k)) continue;
|
|
574
|
+
if (!Array.isArray(v)) continue;
|
|
575
|
+
const list = [];
|
|
576
|
+
for (const item of v) {
|
|
577
|
+
if (typeof item !== "object" || item === null || Array.isArray(item)) {
|
|
578
|
+
continue;
|
|
579
|
+
}
|
|
580
|
+
const r = item;
|
|
581
|
+
if (typeof r.observedAt !== "string" || r.observedAt === "") continue;
|
|
582
|
+
if (typeof r.signal !== "string" || r.signal === "") continue;
|
|
583
|
+
const clean = {
|
|
584
|
+
observedAt: r.observedAt,
|
|
585
|
+
signal: r.signal,
|
|
586
|
+
...typeof r.sourceSessionId === "string" && r.sourceSessionId.length > 0 ? { sourceSessionId: r.sourceSessionId } : {},
|
|
587
|
+
...typeof r.note === "string" && r.note.length > 0 ? { note: r.note } : {}
|
|
588
|
+
};
|
|
589
|
+
list.push(clean);
|
|
590
|
+
}
|
|
591
|
+
provenance[k] = list;
|
|
592
|
+
}
|
|
593
|
+
return { peerId, updatedAt, fields, provenance };
|
|
594
|
+
}
|
|
595
|
+
async function readPeerProfile(memoryDir, peerId) {
|
|
596
|
+
assertValidPeerId(peerId);
|
|
597
|
+
await assertPeerDirNotEscaped(memoryDir, peerId);
|
|
598
|
+
const file = profilePath(memoryDir, peerId);
|
|
599
|
+
let raw;
|
|
600
|
+
try {
|
|
601
|
+
raw = await readFileNoFollow(file);
|
|
602
|
+
} catch (err) {
|
|
603
|
+
if (err.code === "ENOENT") {
|
|
604
|
+
return null;
|
|
605
|
+
}
|
|
606
|
+
throw err;
|
|
607
|
+
}
|
|
608
|
+
return parsePeerProfile(raw, peerId);
|
|
609
|
+
}
|
|
610
|
+
async function writePeerProfile(memoryDir, profile) {
|
|
611
|
+
assertValidPeerId(profile.peerId);
|
|
612
|
+
if (typeof profile.updatedAt !== "string" || profile.updatedAt === "") {
|
|
613
|
+
throw new Error("profile.updatedAt must be a non-empty ISO-8601 string");
|
|
614
|
+
}
|
|
615
|
+
if (!isPlainObject(profile.fields)) {
|
|
616
|
+
throw new Error("profile.fields must be a plain object");
|
|
617
|
+
}
|
|
618
|
+
const RESERVED_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
619
|
+
for (const [key, value] of Object.entries(profile.fields)) {
|
|
620
|
+
if (RESERVED_KEYS.has(key)) {
|
|
621
|
+
throw new Error(`profile.fields key "${key}" is reserved and cannot be persisted`);
|
|
622
|
+
}
|
|
623
|
+
if (typeof value !== "string") {
|
|
624
|
+
throw new Error(`profile.fields["${key}"] must be a string`);
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
if (!isPlainObject(profile.provenance)) {
|
|
628
|
+
throw new Error("profile.provenance must be a plain object");
|
|
629
|
+
}
|
|
630
|
+
for (const [key, list] of Object.entries(profile.provenance)) {
|
|
631
|
+
if (RESERVED_KEYS.has(key)) {
|
|
632
|
+
throw new Error(`profile.provenance key "${key}" is reserved and cannot be persisted`);
|
|
633
|
+
}
|
|
634
|
+
if (!Array.isArray(list)) {
|
|
635
|
+
throw new Error(`profile.provenance["${key}"] must be an array`);
|
|
636
|
+
}
|
|
637
|
+
for (let i = 0; i < list.length; i++) {
|
|
638
|
+
const item = list[i];
|
|
639
|
+
if (typeof item !== "object" || item === null || Array.isArray(item)) {
|
|
640
|
+
throw new Error(`profile.provenance["${key}"][${i}] must be an object`);
|
|
641
|
+
}
|
|
642
|
+
const r = item;
|
|
643
|
+
if (typeof r.observedAt !== "string" || r.observedAt === "") {
|
|
644
|
+
throw new Error(`profile.provenance["${key}"][${i}].observedAt must be a non-empty string`);
|
|
645
|
+
}
|
|
646
|
+
if (typeof r.signal !== "string" || r.signal === "") {
|
|
647
|
+
throw new Error(`profile.provenance["${key}"][${i}].signal must be a non-empty string`);
|
|
648
|
+
}
|
|
649
|
+
if (r.sourceSessionId !== void 0) {
|
|
650
|
+
if (typeof r.sourceSessionId !== "string" || r.sourceSessionId === "") {
|
|
651
|
+
throw new Error(`profile.provenance["${key}"][${i}].sourceSessionId must be a non-empty string when provided`);
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
if (r.note !== void 0) {
|
|
655
|
+
if (typeof r.note !== "string" || r.note === "") {
|
|
656
|
+
throw new Error(`profile.provenance["${key}"][${i}].note must be a non-empty string when provided`);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
await mkdirPeerDirAtomic(memoryDir, profile.peerId);
|
|
662
|
+
await assertPeerDirNotEscaped(memoryDir, profile.peerId);
|
|
663
|
+
const file = profilePath(memoryDir, profile.peerId);
|
|
664
|
+
await writeFileNoFollow(file, emitPeerProfile(profile));
|
|
665
|
+
}
|
|
666
|
+
async function readInteractionLogRaw(memoryDir, peerId) {
|
|
667
|
+
assertValidPeerId(peerId);
|
|
668
|
+
await assertPeerDirNotEscaped(memoryDir, peerId);
|
|
669
|
+
const file = interactionsPath(memoryDir, peerId);
|
|
670
|
+
try {
|
|
671
|
+
return await readFileNoFollow(file);
|
|
672
|
+
} catch (err) {
|
|
673
|
+
if (err.code === "ENOENT") {
|
|
674
|
+
return "";
|
|
675
|
+
}
|
|
676
|
+
throw err;
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
function parseLogLine(line) {
|
|
680
|
+
if (!line.startsWith("- [")) return null;
|
|
681
|
+
const tsClose = line.indexOf("]", 3);
|
|
682
|
+
if (tsClose === -1) return null;
|
|
683
|
+
const timestamp = line.slice(3, tsClose).trim();
|
|
684
|
+
if (timestamp === "") return null;
|
|
685
|
+
let cursor = tsClose + 1;
|
|
686
|
+
while (cursor < line.length && line[cursor] === " ") cursor += 1;
|
|
687
|
+
if (line[cursor] !== "(") return null;
|
|
688
|
+
const kindOpen = cursor;
|
|
689
|
+
const kindClose = line.indexOf(")", kindOpen + 1);
|
|
690
|
+
if (kindClose === -1) return null;
|
|
691
|
+
const kind = line.slice(kindOpen + 1, kindClose).trim();
|
|
692
|
+
if (kind === "") return null;
|
|
693
|
+
cursor = kindClose + 1;
|
|
694
|
+
let sessionId;
|
|
695
|
+
while (cursor < line.length && line[cursor] === " ") cursor += 1;
|
|
696
|
+
if (line.startsWith("[session=", cursor)) {
|
|
697
|
+
const close = line.indexOf("]", cursor + "[session=".length);
|
|
698
|
+
if (close > -1) {
|
|
699
|
+
const sid = line.slice(cursor + "[session=".length, close).trim();
|
|
700
|
+
if (sid.length > 0) sessionId = sid;
|
|
701
|
+
cursor = close + 1;
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
while (cursor < line.length && line[cursor] === " ") cursor += 1;
|
|
705
|
+
const summary = line.slice(cursor);
|
|
706
|
+
return sessionId === void 0 ? { timestamp, kind, summary } : { timestamp, kind, sessionId, summary };
|
|
707
|
+
}
|
|
708
|
+
async function readPeerInteractionLog(memoryDir, peerId, options = {}) {
|
|
709
|
+
const raw = await readInteractionLogRaw(memoryDir, peerId);
|
|
710
|
+
if (raw === "") return [];
|
|
711
|
+
const entries = [];
|
|
712
|
+
for (const lineRaw of raw.split(/\r?\n/)) {
|
|
713
|
+
const line = lineRaw.trimEnd();
|
|
714
|
+
if (line === "") continue;
|
|
715
|
+
const parsed = parseLogLine(line);
|
|
716
|
+
if (parsed === null) continue;
|
|
717
|
+
entries.push(parsed);
|
|
718
|
+
}
|
|
719
|
+
let filtered = entries;
|
|
720
|
+
if (typeof options.afterTimestamp === "string" && options.afterTimestamp.length > 0) {
|
|
721
|
+
const cutoff = options.afterTimestamp;
|
|
722
|
+
filtered = filtered.filter((e) => e.timestamp > cutoff);
|
|
723
|
+
}
|
|
724
|
+
if (typeof options.limit === "number" && options.limit > 0) {
|
|
725
|
+
if (filtered.length > options.limit) {
|
|
726
|
+
filtered = filtered.slice(filtered.length - options.limit);
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
return filtered;
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
// src/peers/migrate-from-identity-anchor.ts
|
|
733
|
+
async function safeReadLegacyFile(filePath) {
|
|
734
|
+
const parent = path2.dirname(filePath);
|
|
735
|
+
try {
|
|
736
|
+
const parentStat = await fs2.lstat(parent);
|
|
737
|
+
if (parentStat.isSymbolicLink()) {
|
|
738
|
+
return { content: null, filePath: null };
|
|
739
|
+
}
|
|
740
|
+
} catch (err) {
|
|
741
|
+
if (err.code === "ENOENT") {
|
|
742
|
+
return { content: null, filePath: null };
|
|
743
|
+
}
|
|
744
|
+
throw err;
|
|
745
|
+
}
|
|
746
|
+
let fh;
|
|
747
|
+
try {
|
|
748
|
+
fh = await fs2.open(filePath, fsConstants2.O_RDONLY | fsConstants2.O_NOFOLLOW);
|
|
749
|
+
} catch (err) {
|
|
750
|
+
const code = err.code;
|
|
751
|
+
if (code === "ENOENT" || code === "ELOOP" || code === "ENOTDIR") {
|
|
752
|
+
return { content: null, filePath: null };
|
|
753
|
+
}
|
|
754
|
+
throw err;
|
|
755
|
+
}
|
|
756
|
+
try {
|
|
757
|
+
const stat = await fh.stat();
|
|
758
|
+
if (!stat.isFile()) {
|
|
759
|
+
return { content: null, filePath: null };
|
|
760
|
+
}
|
|
761
|
+
const content = await fh.readFile("utf8");
|
|
762
|
+
return { content, filePath };
|
|
763
|
+
} finally {
|
|
764
|
+
await fh.close();
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
function buildSelfNotes(anchorContent, identityMdContent) {
|
|
768
|
+
const parts = [];
|
|
769
|
+
if (anchorContent !== null && anchorContent.trim().length > 0) {
|
|
770
|
+
parts.push(
|
|
771
|
+
"## Migrated from identity-anchor.md\n\n" + anchorContent.trim()
|
|
772
|
+
);
|
|
773
|
+
}
|
|
774
|
+
if (identityMdContent !== null && identityMdContent.trim().length > 0) {
|
|
775
|
+
parts.push(
|
|
776
|
+
"## Migrated from IDENTITY.md\n\n" + identityMdContent.trim()
|
|
777
|
+
);
|
|
778
|
+
}
|
|
779
|
+
if (parts.length === 0) return void 0;
|
|
780
|
+
return parts.join("\n\n");
|
|
781
|
+
}
|
|
782
|
+
async function migrateFromIdentityAnchor(options) {
|
|
783
|
+
const { memoryDir, dryRun = false } = options;
|
|
784
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
785
|
+
const createdAt = options.createdAt ?? now;
|
|
786
|
+
const displayName = options.displayName ?? "Self";
|
|
787
|
+
const existing = await readPeer(memoryDir, "self");
|
|
788
|
+
if (existing !== null) {
|
|
789
|
+
return {
|
|
790
|
+
peer: existing,
|
|
791
|
+
written: false,
|
|
792
|
+
skipped: true,
|
|
793
|
+
// P2 (codex): preserve the caller-requested dryRun flag even on the
|
|
794
|
+
// skip path. Previously hard-coded `false`, which contradicted the
|
|
795
|
+
// MigrateFromIdentityAnchorResult contract for dry-run callers.
|
|
796
|
+
dryRun,
|
|
797
|
+
identityAnchorSource: null,
|
|
798
|
+
identityMdSource: null
|
|
799
|
+
};
|
|
800
|
+
}
|
|
801
|
+
const anchorPath = path2.join(memoryDir, "identity", "identity-anchor.md");
|
|
802
|
+
const identityMdPath = path2.join(memoryDir, "IDENTITY.md");
|
|
803
|
+
const [anchorResult, identityMdResult] = await Promise.all([
|
|
804
|
+
safeReadLegacyFile(anchorPath),
|
|
805
|
+
safeReadLegacyFile(identityMdPath)
|
|
806
|
+
]);
|
|
807
|
+
const notes = buildSelfNotes(
|
|
808
|
+
anchorResult.content,
|
|
809
|
+
identityMdResult.content
|
|
810
|
+
);
|
|
811
|
+
const peer = {
|
|
812
|
+
id: "self",
|
|
813
|
+
kind: "self",
|
|
814
|
+
displayName,
|
|
815
|
+
createdAt,
|
|
816
|
+
updatedAt: now,
|
|
817
|
+
...notes !== void 0 ? { notes } : {}
|
|
818
|
+
};
|
|
819
|
+
if (!dryRun) {
|
|
820
|
+
const selfPeerDir = path2.join(memoryDir, PEERS_DIR_NAME, "self");
|
|
821
|
+
await fs2.mkdir(selfPeerDir, { recursive: true });
|
|
822
|
+
const identityFilePath = path2.join(selfPeerDir, "identity.md");
|
|
823
|
+
let exclusiveFh = null;
|
|
824
|
+
try {
|
|
825
|
+
exclusiveFh = await fs2.open(
|
|
826
|
+
identityFilePath,
|
|
827
|
+
fsConstants2.O_WRONLY | fsConstants2.O_CREAT | fsConstants2.O_EXCL | fsConstants2.O_NOFOLLOW
|
|
828
|
+
);
|
|
829
|
+
} catch (err) {
|
|
830
|
+
const code = err.code;
|
|
831
|
+
if (code === "EEXIST") {
|
|
832
|
+
const raceWinner = await readPeer(memoryDir, "self");
|
|
833
|
+
return {
|
|
834
|
+
peer: raceWinner ?? peer,
|
|
835
|
+
written: false,
|
|
836
|
+
skipped: true,
|
|
837
|
+
dryRun,
|
|
838
|
+
identityAnchorSource: null,
|
|
839
|
+
identityMdSource: null
|
|
840
|
+
};
|
|
841
|
+
}
|
|
842
|
+
throw err;
|
|
843
|
+
} finally {
|
|
844
|
+
if (exclusiveFh !== null) await exclusiveFh.close();
|
|
845
|
+
}
|
|
846
|
+
await writePeer(memoryDir, peer);
|
|
847
|
+
}
|
|
848
|
+
return {
|
|
849
|
+
peer,
|
|
850
|
+
written: !dryRun,
|
|
851
|
+
skipped: false,
|
|
852
|
+
dryRun,
|
|
853
|
+
identityAnchorSource: anchorResult.filePath,
|
|
854
|
+
identityMdSource: identityMdResult.filePath
|
|
855
|
+
};
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
export {
|
|
859
|
+
PEER_ID_PATTERN,
|
|
860
|
+
PEER_ID_MAX_LENGTH,
|
|
861
|
+
assertValidPeerId,
|
|
862
|
+
PEERS_DIR_NAME,
|
|
863
|
+
readPeer,
|
|
864
|
+
writePeer,
|
|
865
|
+
deletePeer,
|
|
866
|
+
forgetPeer,
|
|
867
|
+
listPeers,
|
|
868
|
+
appendInteractionLog,
|
|
869
|
+
readPeerProfile,
|
|
870
|
+
writePeerProfile,
|
|
871
|
+
readInteractionLogRaw,
|
|
872
|
+
readPeerInteractionLog,
|
|
873
|
+
migrateFromIdentityAnchor
|
|
874
|
+
};
|
|
875
|
+
//# sourceMappingURL=chunk-TUFG6VXY.js.map
|