@remnic/core 9.69.23 → 9.69.24
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/abstraction-nodes.js +3 -2
- package/dist/access-admin-ops-surface.d.ts +1 -1
- package/dist/access-admin-ops-surface.js +53 -53
- package/dist/access-authorization-probe.d.ts +1 -1
- package/dist/access-authorization-probe.js +54 -54
- package/dist/access-boundary.d.ts +1 -1
- package/dist/access-boundary.js +53 -53
- package/dist/access-citation-namespace.js +3 -3
- package/dist/access-cli.js +112 -112
- package/dist/access-extraction-force-flush.d.ts +1 -1
- package/dist/access-extraction-force-flush.js +53 -53
- package/dist/access-http-briefing.d.ts +1 -1
- package/dist/access-http-briefing.js +54 -54
- package/dist/access-http-lcm-compaction.d.ts +1 -1
- package/dist/access-http-lifecycle-flush.d.ts +1 -1
- package/dist/access-http-offline-stream.d.ts +1 -1
- package/dist/access-http-query.js +55 -55
- package/dist/access-http.d.ts +2 -2
- package/dist/access-http.js +72 -72
- package/dist/access-identity-continuity-surface.js +53 -53
- package/dist/access-lcm-surface.d.ts +1 -1
- package/dist/access-lcm-surface.js +53 -53
- package/dist/access-mcp.d.ts +1 -1
- package/dist/access-mcp.js +64 -64
- package/dist/access-namespace-preflight.js +53 -53
- package/dist/access-observe-write-surface.d.ts +1 -1
- package/dist/access-observe-write-surface.js +53 -53
- package/dist/access-offline-manifest.js +10 -10
- package/dist/access-operations-batch.js +58 -58
- package/dist/access-operations.d.ts +6 -6
- package/dist/access-operations.js +63 -63
- package/dist/access-recall-concurrency.d.ts +1 -1
- package/dist/access-recall-concurrency.js +53 -53
- package/dist/access-recall-response.d.ts +1 -1
- package/dist/access-recall-response.js +53 -53
- package/dist/access-recall-surface.d.ts +1 -1
- package/dist/access-recall-surface.js +53 -53
- package/dist/access-schema.d.ts +91 -91
- package/dist/access-schema.js +6 -5
- package/dist/access-service-helpers.d.ts +1 -1
- package/dist/access-service.d.ts +1 -1
- package/dist/access-service.js +53 -53
- package/dist/access-surface-catalog.d.ts +1 -1
- package/dist/access-surface-catalog.js +55 -55
- package/dist/active-recall.js +12 -11
- package/dist/active-recall.js.map +1 -1
- package/dist/{auto-sync-TTIEWJ5X.js → auto-sync-WNGG2GC2.js} +7 -7
- package/dist/briefing.js +20 -20
- package/dist/buffer.js +9 -9
- package/dist/calibration.js +2 -1
- package/dist/calibration.js.map +1 -1
- package/dist/{capsule-merge-CU6QJBSV.js → capsule-merge-IPG4IOFP.js} +4 -4
- package/dist/causal-behavior.js +4 -3
- package/dist/causal-behavior.js.map +1 -1
- package/dist/causal-chain.js +4 -3
- package/dist/causal-consolidation.js +25 -25
- package/dist/causal-retrieval.js +4 -3
- package/dist/causal-retrieval.js.map +1 -1
- package/dist/causal-trajectory-graph.js +2 -1
- package/dist/causal-trajectory-graph.js.map +1 -1
- package/dist/causal-trajectory.js +3 -2
- package/dist/{chunk-5RWHODVF.js → chunk-27QVNSQ3.js} +2 -2
- package/dist/{chunk-2MX7RU7B.js → chunk-2EKJDQZB.js} +2 -2
- package/dist/{chunk-XLRM6PPI.js → chunk-2IOHTUP3.js} +4 -4
- package/dist/{chunk-ZGQDTD5T.js → chunk-2ITE4C2Z.js} +2 -2
- package/dist/{chunk-O5ZR7SXV.js → chunk-2SGLMP2E.js} +2 -2
- package/dist/{chunk-FYWLSFFS.js → chunk-2Z4GS5E6.js} +2 -2
- package/dist/{chunk-WELP4CG6.js → chunk-37KUQPX4.js} +6 -6
- package/dist/{chunk-DDQQY2E3.js → chunk-3BTFBQLO.js} +7 -7
- package/dist/chunk-3BTFBQLO.js.map +1 -0
- package/dist/{chunk-UR6PBX2J.js → chunk-3K7V3HE6.js} +35 -60
- package/dist/chunk-3K7V3HE6.js.map +1 -0
- package/dist/{chunk-MRSLR6TB.js → chunk-3QQTXYZ6.js} +2 -2
- package/dist/{chunk-DJUKBGAD.js → chunk-46EST7JO.js} +5 -5
- package/dist/chunk-46EST7JO.js.map +1 -0
- package/dist/{chunk-CI6C33EO.js → chunk-46ZPIGWI.js} +3 -3
- package/dist/{chunk-HTIIXNJQ.js → chunk-4FIH6MPS.js} +6 -3
- package/dist/chunk-4FIH6MPS.js.map +1 -0
- package/dist/{chunk-MCA2X4WH.js → chunk-4IHBN6WU.js} +2 -2
- package/dist/{chunk-W7IGLX4G.js → chunk-4O6WRBGE.js} +7 -7
- package/dist/chunk-4O6WRBGE.js.map +1 -0
- package/dist/{chunk-TOZCM7WN.js → chunk-4TKJGOCJ.js} +2 -2
- package/dist/{chunk-3ADRFFRO.js → chunk-54WHLA65.js} +4 -4
- package/dist/{chunk-Z2N2AHEM.js → chunk-56Y6EKZN.js} +2 -2
- package/dist/{chunk-2H2N5UQW.js → chunk-5ATKSPEQ.js} +2 -2
- package/dist/{chunk-MSOXFXCA.js → chunk-5FAGCOZD.js} +5 -5
- package/dist/chunk-5FAGCOZD.js.map +1 -0
- package/dist/{chunk-ZVZHG7AI.js → chunk-5UBH37SL.js} +3 -3
- package/dist/{chunk-YZYZ2BEU.js → chunk-66OJSCI6.js} +2 -2
- package/dist/{chunk-HNPE66LB.js → chunk-6CVNSDCZ.js} +4 -4
- package/dist/{chunk-ERVJFFTR.js → chunk-6NXSYYGP.js} +2 -2
- package/dist/{chunk-2HIJHXB3.js → chunk-6WHJ2EAB.js} +2 -2
- package/dist/{chunk-34VTBPNE.js → chunk-6XL73HQ4.js} +4 -4
- package/dist/{chunk-YK3UIF7X.js → chunk-AQ7SYDVO.js} +2 -2
- package/dist/{chunk-DSCCM66R.js → chunk-B3O3IRZN.js} +2 -2
- package/dist/{chunk-P77QX3ID.js → chunk-B6O2YLUR.js} +21 -20
- package/dist/chunk-B6O2YLUR.js.map +1 -0
- package/dist/{chunk-N37X5RU7.js → chunk-BD7JTBYP.js} +2 -2
- package/dist/{chunk-VO43BJ2F.js → chunk-BLJWYCNO.js} +5 -5
- package/dist/{chunk-ACPCA4NO.js → chunk-BMWN7B3Y.js} +6 -6
- package/dist/chunk-BMWN7B3Y.js.map +1 -0
- package/dist/{chunk-HSKSVY3Q.js → chunk-C553ZTLF.js} +15 -15
- package/dist/{chunk-GCASGYIO.js → chunk-C7HJ3NEI.js} +2 -2
- package/dist/{chunk-WVGXCBOC.js → chunk-D5F7TKMH.js} +2 -2
- package/dist/{chunk-UFT2XNBW.js → chunk-DGS34QSY.js} +2 -2
- package/dist/{chunk-VAOL3SOT.js → chunk-DZD3WGCD.js} +4 -4
- package/dist/{chunk-KHMS2FQS.js → chunk-E2P7TZTF.js} +2 -2
- package/dist/{chunk-6FC3IZ26.js → chunk-EBA5DA77.js} +2 -2
- package/dist/{chunk-E6EANYLD.js → chunk-EOQ6FSQP.js} +2 -2
- package/dist/{chunk-7RPPCA26.js → chunk-FVOP3NT7.js} +2 -2
- package/dist/{chunk-NRLELHAY.js → chunk-G7NYVKD6.js} +2 -2
- package/dist/{chunk-QY34X2QJ.js → chunk-GHTSNGBZ.js} +2 -2
- package/dist/{chunk-SLIOMMPF.js → chunk-H272ZPQ3.js} +5 -5
- package/dist/{chunk-ZZBQNQS6.js → chunk-H3TKENU4.js} +2 -2
- package/dist/{chunk-5OPNUUBX.js → chunk-H4SEGIZY.js} +2 -2
- package/dist/{chunk-F2HMDGLC.js → chunk-H54VWRPS.js} +13 -13
- package/dist/{chunk-HTP6XRUI.js → chunk-HM7RHKS4.js} +2 -2
- package/dist/{chunk-O7H3P2SJ.js → chunk-HWLIMQE2.js} +2 -2
- package/dist/{chunk-62WZDHTW.js → chunk-ICKJ52PE.js} +33 -33
- package/dist/chunk-ICKJ52PE.js.map +1 -0
- package/dist/{chunk-I3FDDCY3.js → chunk-JEC4DVM3.js} +8 -8
- package/dist/chunk-JEC4DVM3.js.map +1 -0
- package/dist/{chunk-ET2CNMLD.js → chunk-JN72EPOE.js} +2 -2
- package/dist/{chunk-E7UQOS4C.js → chunk-JPKK466T.js} +2 -2
- package/dist/{chunk-JCCWJHOP.js → chunk-JYZSRNR7.js} +2 -2
- package/dist/{chunk-7IUESBLV.js → chunk-K7724CH2.js} +2 -2
- package/dist/{chunk-UK7HXNNJ.js → chunk-KAXCYM66.js} +3 -3
- package/dist/{chunk-7XVP4P4O.js → chunk-KB2G2I6Q.js} +3 -3
- package/dist/{chunk-K7LTRJZU.js → chunk-KEF46KL2.js} +2 -2
- package/dist/{chunk-5UZXUTVO.js → chunk-KNA3BXXL.js} +6 -2
- package/dist/chunk-KNA3BXXL.js.map +1 -0
- package/dist/{chunk-JYYTWCPU.js → chunk-KTWG7CNY.js} +6 -6
- package/dist/{chunk-XTYDEO7M.js → chunk-L7Z57SID.js} +2 -2
- package/dist/{chunk-EYMPUXAN.js → chunk-LO4UKPKX.js} +3 -3
- package/dist/{chunk-LDWIPYJ6.js → chunk-LS2FHUML.js} +3 -3
- package/dist/{chunk-GDB4J2H3.js → chunk-MPC7TYTZ.js} +2 -2
- package/dist/{chunk-2GF27PGH.js → chunk-MRPOZBJC.js} +3 -3
- package/dist/{chunk-7OLKAQMG.js → chunk-MWN6QEI2.js} +2 -2
- package/dist/{chunk-J62HG52Z.js → chunk-MY5EDR46.js} +4 -4
- package/dist/{chunk-IZRMWPGS.js → chunk-N3ZOP7KC.js} +2 -2
- package/dist/{chunk-N6A2RP5S.js → chunk-NB3LRY4T.js} +3 -3
- package/dist/{chunk-4N5BIR2U.js → chunk-ND6IQGSZ.js} +2 -2
- package/dist/{chunk-NOB2T2FC.js → chunk-NHLLKEKK.js} +2 -2
- package/dist/{chunk-WW6B7NQJ.js → chunk-NLYVH66G.js} +6 -6
- package/dist/chunk-NLYVH66G.js.map +1 -0
- package/dist/{chunk-M5CQNOQN.js → chunk-O6ZNNVSP.js} +2 -2
- package/dist/{chunk-NNBZS3DY.js → chunk-OB3XMWX5.js} +2 -2
- package/dist/{chunk-TXJNRGMI.js → chunk-OEYZXDQI.js} +6 -6
- package/dist/chunk-OEYZXDQI.js.map +1 -0
- package/dist/{chunk-SIBVIP2Y.js → chunk-PAZY2ZKP.js} +2 -2
- package/dist/{chunk-LXESHEBP.js → chunk-PX4UMA5Z.js} +2 -2
- package/dist/{chunk-4KNRKJXQ.js → chunk-QOOBICJF.js} +5 -5
- package/dist/chunk-QOOBICJF.js.map +1 -0
- package/dist/{chunk-NNZFPYYX.js → chunk-R7QY5ZVB.js} +2 -2
- package/dist/{chunk-WTRTFIIN.js → chunk-R7RTXEYG.js} +2 -2
- package/dist/{chunk-XRBJ5R3P.js → chunk-RBCQVOVJ.js} +3 -3
- package/dist/{chunk-WFZNT4KB.js → chunk-RC5DXXWC.js} +2 -2
- package/dist/{chunk-OH7LZHGJ.js → chunk-RJYJ7KR7.js} +52 -52
- package/dist/{chunk-OH7LZHGJ.js.map → chunk-RJYJ7KR7.js.map} +1 -1
- package/dist/{chunk-5QZR2RA3.js → chunk-ROBHL3GL.js} +2 -2
- package/dist/{chunk-6PST2SFW.js → chunk-SCXURCVT.js} +3 -3
- package/dist/{chunk-AYG7ML7O.js → chunk-SJDQ5RSN.js} +3 -3
- package/dist/{chunk-3ZBLKIHJ.js → chunk-SMWTZLHE.js} +51 -41
- package/dist/{chunk-3ZBLKIHJ.js.map → chunk-SMWTZLHE.js.map} +1 -1
- package/dist/{chunk-IQXDSKTL.js → chunk-SVXJLDDC.js} +6 -6
- package/dist/{chunk-SEF4IOFE.js → chunk-SWIKABKI.js} +2 -2
- package/dist/{chunk-ZJABRLCZ.js → chunk-TBXAY2SS.js} +4 -4
- package/dist/{chunk-GIC6BASP.js → chunk-TNSCIPBQ.js} +2 -2
- package/dist/{chunk-ZMDMHSV2.js → chunk-TVEONGBU.js} +2 -2
- package/dist/{chunk-4FSEZRGK.js → chunk-TWF35IC6.js} +2 -2
- package/dist/{chunk-LS2SGMQE.js → chunk-U6N5IBVY.js} +2 -2
- package/dist/{chunk-62YW6OYI.js → chunk-UCKYTA2T.js} +3 -3
- package/dist/{chunk-YFCHNOGJ.js → chunk-UNNPNBR2.js} +9 -9
- package/dist/{chunk-Z2M7F4QM.js → chunk-VVX5PZFS.js} +3 -3
- package/dist/{chunk-NTYLZXDX.js → chunk-VYCOJKSX.js} +2 -2
- package/dist/{chunk-UICSQESY.js → chunk-W24T5YMW.js} +2 -2
- package/dist/{chunk-HDQUQBPW.js → chunk-W3K3HITK.js} +2 -2
- package/dist/{chunk-GDASG7NC.js → chunk-W4F3C7N7.js} +2 -2
- package/dist/{chunk-YBLZFNIQ.js → chunk-WJHGDE7X.js} +2 -2
- package/dist/{chunk-ZBPXG5PJ.js → chunk-WMLEPWMO.js} +9 -9
- package/dist/chunk-WMLEPWMO.js.map +1 -0
- package/dist/{chunk-4F24PHNX.js → chunk-WQZZDN5M.js} +2 -2
- package/dist/{chunk-CDZEUCV7.js → chunk-X5K5TAQZ.js} +4 -4
- package/dist/{chunk-5AUODSOQ.js → chunk-XM24CDZX.js} +3 -3
- package/dist/{chunk-6VML2LII.js → chunk-XOVKXJEP.js} +3 -3
- package/dist/{chunk-OU5TIWDQ.js → chunk-XSGUMQQQ.js} +12 -12
- package/dist/{chunk-7CFVBWDC.js → chunk-XUE46UYW.js} +3 -3
- package/dist/{chunk-DJORULH3.js → chunk-YRLHEEQT.js} +2 -2
- package/dist/{chunk-YRWDPE32.js → chunk-Z3O53WZR.js} +2 -2
- package/dist/{chunk-CSY5DA7O.js → chunk-Z6COGHHN.js} +2 -2
- package/dist/{chunk-OYR3IPHD.js → chunk-ZIW5JVRM.js} +2 -2
- package/dist/{cli-B_YwqoIr.d.ts → cli-DD0P-lu8.d.ts} +1 -1
- package/dist/cli.d.ts +2 -2
- package/dist/cli.js +94 -94
- package/dist/coding/export-okf-codegraph.js +21 -21
- package/dist/coding/pre-action-gate.js +4 -3
- package/dist/commitment-ledger.js +3 -2
- package/dist/compounding/engine.js +21 -21
- package/dist/config.js +12 -11
- package/dist/connectors/codex-materialize-runner.js +21 -21
- package/dist/connectors/codex-materialize.js +3 -3
- package/dist/connectors/index.js +21 -21
- package/dist/consolidation-provenance-check.js +4 -4
- package/dist/consolidation-undo.js +3 -3
- package/dist/contradiction/index.js +7 -7
- package/dist/convergence-refresh.js +22 -22
- package/dist/corpus-watermark.js +22 -22
- package/dist/cue-anchors.js +4 -3
- package/dist/deep-recall-http-glue.d.ts +1 -1
- package/dist/deep-recall-http-glue.js +7 -6
- package/dist/deep-recall-mcp-tools.d.ts +1 -1
- package/dist/entity-retrieval.js +20 -20
- package/dist/eval-trajectory-store.js +4 -3
- package/dist/eval-trajectory.js +4 -3
- package/dist/evals.js +3 -2
- package/dist/explicit-capture.js +8 -8
- package/dist/external-wiki-access.d.ts +1 -1
- package/dist/external-wiki-access.js +54 -54
- package/dist/external-wiki-mcp-tools.d.ts +1 -1
- package/dist/extraction.js +25 -25
- package/dist/{first-start-migration-KHIMCBIC.js → first-start-migration-RC345GPL.js} +6 -5
- package/dist/{first-start-migration-KHIMCBIC.js.map → first-start-migration-RC345GPL.js.map} +1 -1
- package/dist/{graph-edge-decay-CJW4OT2X.js → graph-edge-decay-MKIRZ762.js} +5 -4
- package/dist/graph-jsonl.js +3 -2
- package/dist/graph-snapshot.js +3 -2
- package/dist/graph.js +2 -1
- package/dist/harmonic-construction.js +5 -4
- package/dist/harmonic-retrieval.js +5 -4
- package/dist/index.d.ts +693 -681
- package/dist/index.js +114 -112
- package/dist/json-store.js +2 -1
- package/dist/live-connectors-runner.js +3 -2
- package/dist/location/index.js +23 -23
- package/dist/maintenance/memory-governance.js +20 -20
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +20 -20
- package/dist/maintenance/rebuild-memory-projection.js +21 -21
- package/dist/mcp-memory-inspector-app.d.ts +1 -1
- package/dist/memory-projection-mutations.js +3 -3
- package/dist/memory-subject-cli.d.ts +1 -1
- package/dist/memory-subject.d.ts +1 -1
- package/dist/memory-subject.js +4 -4
- package/dist/namespaces/migrate.js +21 -21
- package/dist/namespaces/search.js +8 -8
- package/dist/namespaces/storage.js +20 -20
- package/dist/objective-state-writers.js +4 -3
- package/dist/objective-state.js +3 -2
- package/dist/offline-sync-file-io.js +4 -3
- package/dist/offline-sync-impression-drain.js +5 -5
- package/dist/offline-sync.js +5 -4
- package/dist/operator-doctor-corpus.js +23 -23
- package/dist/operator-toolkit.js +38 -38
- package/dist/orchestration/maintenance.js +29 -29
- package/dist/orchestrator.js +112 -112
- package/dist/page-versioning.js +3 -3
- package/dist/{public-http-D6d4W8x-.d.ts → public-http-C4i8Opxc.d.ts} +1 -1
- package/dist/{purge-OP6BEDFY.js → purge-TZKRE6ZQ.js} +5 -5
- package/dist/purge-TZKRE6ZQ.js.map +1 -0
- package/dist/recall-state.js +3 -3
- package/dist/reconcile/manifest.js +4 -4
- package/dist/{resolution-U5O4QANY.js → resolution-VKATP2HT.js} +8 -8
- package/dist/resume-bundles.js +16 -15
- package/dist/salvage-envelope.js +6 -6
- package/dist/schemas.d.ts +176 -176
- package/dist/search/document-scanner.js +3 -3
- package/dist/search/factory.js +7 -7
- package/dist/search/index.js +7 -7
- package/dist/search/lancedb-backend.js +4 -4
- package/dist/search/meilisearch-backend.js +4 -4
- package/dist/search/orama-backend.js +4 -4
- package/dist/secure-store/index.js +3 -3
- package/dist/semantic-consolidation.js +22 -22
- package/dist/semantic-rule-promotion.js +20 -20
- package/dist/semantic-rule-verifier.js +20 -20
- package/dist/shared-context/manager.d.ts +6 -6
- package/dist/source-agent-qualifier.js +24 -24
- package/dist/standup/build.js +20 -20
- package/dist/storage.js +19 -19
- package/dist/subject-config.js +5 -5
- package/dist/support-passport/index.d.ts +4 -4
- package/dist/support-passport/index.js +56 -56
- package/dist/{tier-stats-2TOW3QNL.js → tier-stats-KA6OZX2C.js} +6 -5
- package/dist/{tier-stats-2TOW3QNL.js.map → tier-stats-KA6OZX2C.js.map} +1 -1
- package/dist/transfer/capsule-import.js +4 -4
- package/dist/transfer/export-okf.js +21 -21
- package/dist/transfer/types.d.ts +78 -78
- package/dist/trust-zones.js +3 -2
- package/dist/utility-learner.js +4 -3
- package/dist/utility-runtime.js +5 -4
- package/dist/utility-telemetry.js +3 -2
- package/dist/verified-recall.js +20 -20
- package/dist/who-knows-cli.d.ts +1 -1
- package/dist/who-knows-cli.js +21 -21
- package/dist/who-knows.d.ts +1 -1
- package/dist/who-knows.js +20 -20
- package/dist/work/board.js +3 -3
- package/dist/work/storage.js +2 -2
- package/dist/work-product-ledger.js +3 -2
- package/dist/write-envelope.js +5 -5
- package/package.json +2 -2
- package/src/abstraction-nodes.ts +1 -4
- package/src/binary-lifecycle/backend.ts +2 -1
- package/src/connectors/live/github.ts +10 -17
- package/src/connectors/live/gmail.ts +8 -19
- package/src/connectors/live/google-drive.ts +6 -13
- package/src/connectors/live/notion.ts +11 -21
- package/src/cue-anchors.ts +1 -6
- package/src/graph.ts +2 -4
- package/src/json-store.ts +17 -20
- package/src/live-connectors-runner.ts +2 -1
- package/src/location/store.ts +1 -4
- package/src/maintenance/purge.ts +2 -5
- package/src/maintenance/rebuild-memory-lifecycle-ledger.ts +3 -6
- package/src/maintenance/rebuild-memory-projection.ts +2 -5
- package/src/namespaces/catalog.ts +1 -9
- package/src/offline-sync-file-io.test.ts +39 -0
- package/src/offline-sync-file-io.ts +3 -7
- package/src/procedural/procedure-miner.ts +1 -9
- package/src/search/document-scanner.ts +3 -6
- package/src/semantic-rule-promotion.ts +1 -4
- package/src/utils/errno.test.ts +31 -0
- package/src/utils/errno.ts +5 -0
- package/src/wearables/index.ts +1 -0
- package/src/wearables/registry.ts +23 -0
- package/dist/chunk-4KNRKJXQ.js.map +0 -1
- package/dist/chunk-5UZXUTVO.js.map +0 -1
- package/dist/chunk-62WZDHTW.js.map +0 -1
- package/dist/chunk-ACPCA4NO.js.map +0 -1
- package/dist/chunk-DDQQY2E3.js.map +0 -1
- package/dist/chunk-DJUKBGAD.js.map +0 -1
- package/dist/chunk-HTIIXNJQ.js.map +0 -1
- package/dist/chunk-I3FDDCY3.js.map +0 -1
- package/dist/chunk-MSOXFXCA.js.map +0 -1
- package/dist/chunk-P77QX3ID.js.map +0 -1
- package/dist/chunk-TXJNRGMI.js.map +0 -1
- package/dist/chunk-UR6PBX2J.js.map +0 -1
- package/dist/chunk-W7IGLX4G.js.map +0 -1
- package/dist/chunk-WW6B7NQJ.js.map +0 -1
- package/dist/chunk-ZBPXG5PJ.js.map +0 -1
- package/dist/purge-OP6BEDFY.js.map +0 -1
- package/dist/{access-service-Cv8Rizo0.d.ts → access-service-DWdY9Mlk.d.ts} +64 -64
- /package/dist/{auto-sync-TTIEWJ5X.js.map → auto-sync-WNGG2GC2.js.map} +0 -0
- /package/dist/{capsule-merge-CU6QJBSV.js.map → capsule-merge-IPG4IOFP.js.map} +0 -0
- /package/dist/{chunk-5RWHODVF.js.map → chunk-27QVNSQ3.js.map} +0 -0
- /package/dist/{chunk-2MX7RU7B.js.map → chunk-2EKJDQZB.js.map} +0 -0
- /package/dist/{chunk-XLRM6PPI.js.map → chunk-2IOHTUP3.js.map} +0 -0
- /package/dist/{chunk-ZGQDTD5T.js.map → chunk-2ITE4C2Z.js.map} +0 -0
- /package/dist/{chunk-O5ZR7SXV.js.map → chunk-2SGLMP2E.js.map} +0 -0
- /package/dist/{chunk-FYWLSFFS.js.map → chunk-2Z4GS5E6.js.map} +0 -0
- /package/dist/{chunk-WELP4CG6.js.map → chunk-37KUQPX4.js.map} +0 -0
- /package/dist/{chunk-MRSLR6TB.js.map → chunk-3QQTXYZ6.js.map} +0 -0
- /package/dist/{chunk-CI6C33EO.js.map → chunk-46ZPIGWI.js.map} +0 -0
- /package/dist/{chunk-MCA2X4WH.js.map → chunk-4IHBN6WU.js.map} +0 -0
- /package/dist/{chunk-TOZCM7WN.js.map → chunk-4TKJGOCJ.js.map} +0 -0
- /package/dist/{chunk-3ADRFFRO.js.map → chunk-54WHLA65.js.map} +0 -0
- /package/dist/{chunk-Z2N2AHEM.js.map → chunk-56Y6EKZN.js.map} +0 -0
- /package/dist/{chunk-2H2N5UQW.js.map → chunk-5ATKSPEQ.js.map} +0 -0
- /package/dist/{chunk-ZVZHG7AI.js.map → chunk-5UBH37SL.js.map} +0 -0
- /package/dist/{chunk-YZYZ2BEU.js.map → chunk-66OJSCI6.js.map} +0 -0
- /package/dist/{chunk-HNPE66LB.js.map → chunk-6CVNSDCZ.js.map} +0 -0
- /package/dist/{chunk-ERVJFFTR.js.map → chunk-6NXSYYGP.js.map} +0 -0
- /package/dist/{chunk-2HIJHXB3.js.map → chunk-6WHJ2EAB.js.map} +0 -0
- /package/dist/{chunk-34VTBPNE.js.map → chunk-6XL73HQ4.js.map} +0 -0
- /package/dist/{chunk-YK3UIF7X.js.map → chunk-AQ7SYDVO.js.map} +0 -0
- /package/dist/{chunk-DSCCM66R.js.map → chunk-B3O3IRZN.js.map} +0 -0
- /package/dist/{chunk-N37X5RU7.js.map → chunk-BD7JTBYP.js.map} +0 -0
- /package/dist/{chunk-VO43BJ2F.js.map → chunk-BLJWYCNO.js.map} +0 -0
- /package/dist/{chunk-HSKSVY3Q.js.map → chunk-C553ZTLF.js.map} +0 -0
- /package/dist/{chunk-GCASGYIO.js.map → chunk-C7HJ3NEI.js.map} +0 -0
- /package/dist/{chunk-WVGXCBOC.js.map → chunk-D5F7TKMH.js.map} +0 -0
- /package/dist/{chunk-UFT2XNBW.js.map → chunk-DGS34QSY.js.map} +0 -0
- /package/dist/{chunk-VAOL3SOT.js.map → chunk-DZD3WGCD.js.map} +0 -0
- /package/dist/{chunk-KHMS2FQS.js.map → chunk-E2P7TZTF.js.map} +0 -0
- /package/dist/{chunk-6FC3IZ26.js.map → chunk-EBA5DA77.js.map} +0 -0
- /package/dist/{chunk-E6EANYLD.js.map → chunk-EOQ6FSQP.js.map} +0 -0
- /package/dist/{chunk-7RPPCA26.js.map → chunk-FVOP3NT7.js.map} +0 -0
- /package/dist/{chunk-NRLELHAY.js.map → chunk-G7NYVKD6.js.map} +0 -0
- /package/dist/{chunk-QY34X2QJ.js.map → chunk-GHTSNGBZ.js.map} +0 -0
- /package/dist/{chunk-SLIOMMPF.js.map → chunk-H272ZPQ3.js.map} +0 -0
- /package/dist/{chunk-ZZBQNQS6.js.map → chunk-H3TKENU4.js.map} +0 -0
- /package/dist/{chunk-5OPNUUBX.js.map → chunk-H4SEGIZY.js.map} +0 -0
- /package/dist/{chunk-F2HMDGLC.js.map → chunk-H54VWRPS.js.map} +0 -0
- /package/dist/{chunk-HTP6XRUI.js.map → chunk-HM7RHKS4.js.map} +0 -0
- /package/dist/{chunk-O7H3P2SJ.js.map → chunk-HWLIMQE2.js.map} +0 -0
- /package/dist/{chunk-ET2CNMLD.js.map → chunk-JN72EPOE.js.map} +0 -0
- /package/dist/{chunk-E7UQOS4C.js.map → chunk-JPKK466T.js.map} +0 -0
- /package/dist/{chunk-JCCWJHOP.js.map → chunk-JYZSRNR7.js.map} +0 -0
- /package/dist/{chunk-7IUESBLV.js.map → chunk-K7724CH2.js.map} +0 -0
- /package/dist/{chunk-UK7HXNNJ.js.map → chunk-KAXCYM66.js.map} +0 -0
- /package/dist/{chunk-7XVP4P4O.js.map → chunk-KB2G2I6Q.js.map} +0 -0
- /package/dist/{chunk-K7LTRJZU.js.map → chunk-KEF46KL2.js.map} +0 -0
- /package/dist/{chunk-JYYTWCPU.js.map → chunk-KTWG7CNY.js.map} +0 -0
- /package/dist/{chunk-XTYDEO7M.js.map → chunk-L7Z57SID.js.map} +0 -0
- /package/dist/{chunk-EYMPUXAN.js.map → chunk-LO4UKPKX.js.map} +0 -0
- /package/dist/{chunk-LDWIPYJ6.js.map → chunk-LS2FHUML.js.map} +0 -0
- /package/dist/{chunk-GDB4J2H3.js.map → chunk-MPC7TYTZ.js.map} +0 -0
- /package/dist/{chunk-2GF27PGH.js.map → chunk-MRPOZBJC.js.map} +0 -0
- /package/dist/{chunk-7OLKAQMG.js.map → chunk-MWN6QEI2.js.map} +0 -0
- /package/dist/{chunk-J62HG52Z.js.map → chunk-MY5EDR46.js.map} +0 -0
- /package/dist/{chunk-IZRMWPGS.js.map → chunk-N3ZOP7KC.js.map} +0 -0
- /package/dist/{chunk-N6A2RP5S.js.map → chunk-NB3LRY4T.js.map} +0 -0
- /package/dist/{chunk-4N5BIR2U.js.map → chunk-ND6IQGSZ.js.map} +0 -0
- /package/dist/{chunk-NOB2T2FC.js.map → chunk-NHLLKEKK.js.map} +0 -0
- /package/dist/{chunk-M5CQNOQN.js.map → chunk-O6ZNNVSP.js.map} +0 -0
- /package/dist/{chunk-NNBZS3DY.js.map → chunk-OB3XMWX5.js.map} +0 -0
- /package/dist/{chunk-SIBVIP2Y.js.map → chunk-PAZY2ZKP.js.map} +0 -0
- /package/dist/{chunk-LXESHEBP.js.map → chunk-PX4UMA5Z.js.map} +0 -0
- /package/dist/{chunk-NNZFPYYX.js.map → chunk-R7QY5ZVB.js.map} +0 -0
- /package/dist/{chunk-WTRTFIIN.js.map → chunk-R7RTXEYG.js.map} +0 -0
- /package/dist/{chunk-XRBJ5R3P.js.map → chunk-RBCQVOVJ.js.map} +0 -0
- /package/dist/{chunk-WFZNT4KB.js.map → chunk-RC5DXXWC.js.map} +0 -0
- /package/dist/{chunk-5QZR2RA3.js.map → chunk-ROBHL3GL.js.map} +0 -0
- /package/dist/{chunk-6PST2SFW.js.map → chunk-SCXURCVT.js.map} +0 -0
- /package/dist/{chunk-AYG7ML7O.js.map → chunk-SJDQ5RSN.js.map} +0 -0
- /package/dist/{chunk-IQXDSKTL.js.map → chunk-SVXJLDDC.js.map} +0 -0
- /package/dist/{chunk-SEF4IOFE.js.map → chunk-SWIKABKI.js.map} +0 -0
- /package/dist/{chunk-ZJABRLCZ.js.map → chunk-TBXAY2SS.js.map} +0 -0
- /package/dist/{chunk-GIC6BASP.js.map → chunk-TNSCIPBQ.js.map} +0 -0
- /package/dist/{chunk-ZMDMHSV2.js.map → chunk-TVEONGBU.js.map} +0 -0
- /package/dist/{chunk-4FSEZRGK.js.map → chunk-TWF35IC6.js.map} +0 -0
- /package/dist/{chunk-LS2SGMQE.js.map → chunk-U6N5IBVY.js.map} +0 -0
- /package/dist/{chunk-62YW6OYI.js.map → chunk-UCKYTA2T.js.map} +0 -0
- /package/dist/{chunk-YFCHNOGJ.js.map → chunk-UNNPNBR2.js.map} +0 -0
- /package/dist/{chunk-Z2M7F4QM.js.map → chunk-VVX5PZFS.js.map} +0 -0
- /package/dist/{chunk-NTYLZXDX.js.map → chunk-VYCOJKSX.js.map} +0 -0
- /package/dist/{chunk-UICSQESY.js.map → chunk-W24T5YMW.js.map} +0 -0
- /package/dist/{chunk-HDQUQBPW.js.map → chunk-W3K3HITK.js.map} +0 -0
- /package/dist/{chunk-GDASG7NC.js.map → chunk-W4F3C7N7.js.map} +0 -0
- /package/dist/{chunk-YBLZFNIQ.js.map → chunk-WJHGDE7X.js.map} +0 -0
- /package/dist/{chunk-4F24PHNX.js.map → chunk-WQZZDN5M.js.map} +0 -0
- /package/dist/{chunk-CDZEUCV7.js.map → chunk-X5K5TAQZ.js.map} +0 -0
- /package/dist/{chunk-5AUODSOQ.js.map → chunk-XM24CDZX.js.map} +0 -0
- /package/dist/{chunk-6VML2LII.js.map → chunk-XOVKXJEP.js.map} +0 -0
- /package/dist/{chunk-OU5TIWDQ.js.map → chunk-XSGUMQQQ.js.map} +0 -0
- /package/dist/{chunk-7CFVBWDC.js.map → chunk-XUE46UYW.js.map} +0 -0
- /package/dist/{chunk-DJORULH3.js.map → chunk-YRLHEEQT.js.map} +0 -0
- /package/dist/{chunk-YRWDPE32.js.map → chunk-Z3O53WZR.js.map} +0 -0
- /package/dist/{chunk-CSY5DA7O.js.map → chunk-Z6COGHHN.js.map} +0 -0
- /package/dist/{chunk-OYR3IPHD.js.map → chunk-ZIW5JVRM.js.map} +0 -0
- /package/dist/{graph-edge-decay-CJW4OT2X.js.map → graph-edge-decay-MKIRZ762.js.map} +0 -0
- /package/dist/{resolution-U5O4QANY.js.map → resolution-VKATP2HT.js.map} +0 -0
|
@@ -64,6 +64,7 @@ import type {
|
|
|
64
64
|
SyncIncrementalResult,
|
|
65
65
|
} from "./framework.js";
|
|
66
66
|
import { isTransientHttpError } from "./transient-errors.js";
|
|
67
|
+
import { throwIfAborted } from "../../abort-error.js";
|
|
67
68
|
|
|
68
69
|
/**
|
|
69
70
|
* Stable connector id. Lives in the registry under this exact string.
|
|
@@ -414,10 +415,10 @@ export function createGoogleDriveConnector(
|
|
|
414
415
|
async syncIncremental(args: SyncIncrementalArgs): Promise<SyncIncrementalResult> {
|
|
415
416
|
// Re-validate on every pass: a JS caller could mutate it between passes.
|
|
416
417
|
const config = validateGoogleDriveConfig(args.config);
|
|
417
|
-
throwIfAborted(args.abortSignal);
|
|
418
|
+
throwIfAborted(args.abortSignal, "googleDrive: sync aborted");
|
|
418
419
|
|
|
419
420
|
const client = await clientFactory(config);
|
|
420
|
-
throwIfAborted(args.abortSignal);
|
|
421
|
+
throwIfAborted(args.abortSignal, "googleDrive: sync aborted");
|
|
421
422
|
|
|
422
423
|
// Cursor bootstrap. On the very first pass (cursor=null) we ask Drive
|
|
423
424
|
// for a page token but DO NOT consume any changes — this aligns with
|
|
@@ -455,7 +456,7 @@ export function createGoogleDriveConnector(
|
|
|
455
456
|
// Page through `changes.list` until we run out, hit the per-pass cap,
|
|
456
457
|
// or get aborted.
|
|
457
458
|
while (true) {
|
|
458
|
-
throwIfAborted(args.abortSignal);
|
|
459
|
+
throwIfAborted(args.abortSignal, "googleDrive: sync aborted");
|
|
459
460
|
const remaining = MAX_CHANGES_PER_PASS - consumed;
|
|
460
461
|
if (remaining <= 0) {
|
|
461
462
|
// Hit the cap — persist whatever we have. The next pass resumes
|
|
@@ -467,7 +468,7 @@ export function createGoogleDriveConnector(
|
|
|
467
468
|
const page = await client.listChanges({ pageToken, pageSize });
|
|
468
469
|
|
|
469
470
|
for (const change of page.changes) {
|
|
470
|
-
throwIfAborted(args.abortSignal);
|
|
471
|
+
throwIfAborted(args.abortSignal, "googleDrive: sync aborted");
|
|
471
472
|
consumed++;
|
|
472
473
|
const decision = decideChange(change, folderScope);
|
|
473
474
|
switch (decision.kind) {
|
|
@@ -538,7 +539,7 @@ async function fetchDocument(
|
|
|
538
539
|
fetchedAt: string,
|
|
539
540
|
abortSignal: AbortSignal | undefined,
|
|
540
541
|
): Promise<ConnectorDocument | null> {
|
|
541
|
-
throwIfAborted(abortSignal);
|
|
542
|
+
throwIfAborted(abortSignal, "googleDrive: sync aborted");
|
|
542
543
|
const file = decision.file;
|
|
543
544
|
let body: string;
|
|
544
545
|
try {
|
|
@@ -581,14 +582,6 @@ async function fetchDocument(
|
|
|
581
582
|
};
|
|
582
583
|
}
|
|
583
584
|
|
|
584
|
-
function throwIfAborted(signal: AbortSignal | undefined): void {
|
|
585
|
-
if (signal?.aborted) {
|
|
586
|
-
const err = new Error("googleDrive: sync aborted");
|
|
587
|
-
err.name = "AbortError";
|
|
588
|
-
throw err;
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
|
|
592
585
|
/**
|
|
593
586
|
* Classify a per-file fetch error as "transient" (re-throw to caller so
|
|
594
587
|
* the sync stops without advancing the cursor and the next poll retries)
|
|
@@ -60,6 +60,7 @@ import type {
|
|
|
60
60
|
SyncIncrementalResult,
|
|
61
61
|
} from "./framework.js";
|
|
62
62
|
import { isTransientHttpError } from "./transient-errors.js";
|
|
63
|
+
import { throwIfAborted } from "../../abort-error.js";
|
|
63
64
|
|
|
64
65
|
// ---------------------------------------------------------------------------
|
|
65
66
|
// Public constants
|
|
@@ -362,17 +363,6 @@ export function isTransientNotionError(err: unknown): boolean {
|
|
|
362
363
|
const NOTION_BASE_URL = "https://api.notion.com/v1";
|
|
363
364
|
const NOTION_API_VERSION = "2022-06-28";
|
|
364
365
|
|
|
365
|
-
/**
|
|
366
|
-
* Throw if aborted (cooperative cancellation).
|
|
367
|
-
*/
|
|
368
|
-
function throwIfAborted(signal: AbortSignal | undefined): void {
|
|
369
|
-
if (signal?.aborted) {
|
|
370
|
-
const err = new Error("notion: sync aborted");
|
|
371
|
-
err.name = "AbortError";
|
|
372
|
-
throw err;
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
|
|
376
366
|
/**
|
|
377
367
|
* Build a Notion API error with the HTTP status attached for classification.
|
|
378
368
|
*/
|
|
@@ -531,14 +521,14 @@ async function fetchPageText(
|
|
|
531
521
|
signal: AbortSignal | undefined,
|
|
532
522
|
): Promise<string> {
|
|
533
523
|
if (depth > MAX_BLOCK_DEPTH) return "";
|
|
534
|
-
throwIfAborted(signal);
|
|
524
|
+
throwIfAborted(signal, "notion: sync aborted");
|
|
535
525
|
|
|
536
526
|
const lines: string[] = [];
|
|
537
527
|
let cursor: string | undefined = undefined;
|
|
538
528
|
|
|
539
529
|
// Page through block children.
|
|
540
530
|
while (true) {
|
|
541
|
-
throwIfAborted(signal);
|
|
531
|
+
throwIfAborted(signal, "notion: sync aborted");
|
|
542
532
|
const pathQuery = cursor
|
|
543
533
|
? `/blocks/${blockId}/children?page_size=100&start_cursor=${encodeURIComponent(cursor)}`
|
|
544
534
|
: `/blocks/${blockId}/children?page_size=100`;
|
|
@@ -552,7 +542,7 @@ async function fetchPageText(
|
|
|
552
542
|
};
|
|
553
543
|
|
|
554
544
|
for (const block of page.results ?? []) {
|
|
555
|
-
throwIfAborted(signal);
|
|
545
|
+
throwIfAborted(signal, "notion: sync aborted");
|
|
556
546
|
const text = extractBlockText(block);
|
|
557
547
|
if (text.length > 0) lines.push(text);
|
|
558
548
|
|
|
@@ -653,7 +643,7 @@ export function createNotionConnector(
|
|
|
653
643
|
|
|
654
644
|
async syncIncremental(args: SyncIncrementalArgs): Promise<SyncIncrementalResult> {
|
|
655
645
|
const config = validateNotionConfig(args.config);
|
|
656
|
-
throwIfAborted(args.abortSignal);
|
|
646
|
+
throwIfAborted(args.abortSignal, "notion: sync aborted");
|
|
657
647
|
|
|
658
648
|
// Short-circuit: if no databases are configured, there is nothing to do.
|
|
659
649
|
// We still return a valid cursor so the framework has something to
|
|
@@ -719,12 +709,12 @@ async function seedWatermark(
|
|
|
719
709
|
const databases = { ...payload.databases };
|
|
720
710
|
|
|
721
711
|
for (const dbId of config.databaseIds) {
|
|
722
|
-
throwIfAborted(signal);
|
|
712
|
+
throwIfAborted(signal, "notion: sync aborted");
|
|
723
713
|
let notionCursor: string | undefined = undefined;
|
|
724
714
|
let latestInDb = "";
|
|
725
715
|
|
|
726
716
|
while (true) {
|
|
727
|
-
throwIfAborted(signal);
|
|
717
|
+
throwIfAborted(signal, "notion: sync aborted");
|
|
728
718
|
const body: Record<string, unknown> = { page_size: 100, sorts: [] };
|
|
729
719
|
if (notionCursor) body.start_cursor = notionCursor;
|
|
730
720
|
|
|
@@ -784,7 +774,7 @@ async function incrementalSync(
|
|
|
784
774
|
let totalConsumed = 0;
|
|
785
775
|
|
|
786
776
|
for (const dbId of config.databaseIds) {
|
|
787
|
-
throwIfAborted(signal);
|
|
777
|
+
throwIfAborted(signal, "notion: sync aborted");
|
|
788
778
|
if (totalConsumed >= MAX_PAGES_PER_PASS) break;
|
|
789
779
|
|
|
790
780
|
const dbWatermark = payload.databases[dbId];
|
|
@@ -807,7 +797,7 @@ async function incrementalSync(
|
|
|
807
797
|
let databaseFullyDrained = false;
|
|
808
798
|
|
|
809
799
|
while (true) {
|
|
810
|
-
throwIfAborted(signal);
|
|
800
|
+
throwIfAborted(signal, "notion: sync aborted");
|
|
811
801
|
if (totalConsumed >= MAX_PAGES_PER_PASS) break;
|
|
812
802
|
|
|
813
803
|
const body: Record<string, unknown> = {
|
|
@@ -845,7 +835,7 @@ async function incrementalSync(
|
|
|
845
835
|
|
|
846
836
|
let cutoffMidPage = false;
|
|
847
837
|
for (const notionPage of pageResp.results ?? []) {
|
|
848
|
-
throwIfAborted(signal);
|
|
838
|
+
throwIfAborted(signal, "notion: sync aborted");
|
|
849
839
|
|
|
850
840
|
const pageId = notionPage.id;
|
|
851
841
|
const lastEdited = notionPage.last_edited_time;
|
|
@@ -970,7 +960,7 @@ async function fetchPageDocument(
|
|
|
970
960
|
fetchedAt: string,
|
|
971
961
|
signal: AbortSignal | undefined,
|
|
972
962
|
): Promise<ConnectorDocument | "too-large" | "empty" | null> {
|
|
973
|
-
throwIfAborted(signal);
|
|
963
|
+
throwIfAborted(signal, "notion: sync aborted");
|
|
974
964
|
|
|
975
965
|
let text: string;
|
|
976
966
|
try {
|
package/src/cue-anchors.ts
CHANGED
|
@@ -3,6 +3,7 @@ import path from "node:path";
|
|
|
3
3
|
import { resolveAbstractionNodeStoreDir, validateAbstractionNode, type AbstractionNode } from "./abstraction-nodes.js";
|
|
4
4
|
import { listJsonFilesStrict, readJsonFile, withJsonStoreMutationLock, writeJsonFileAtomic } from "./json-store.js";
|
|
5
5
|
import { compareDeterministicStrings, mergeSortedUniqueStrings } from "./deterministic-order.js";
|
|
6
|
+
import { isNotFoundError } from "./utils/errno.js";
|
|
6
7
|
import {
|
|
7
8
|
assertIsoRecordedAt,
|
|
8
9
|
assertSafePathSegment,
|
|
@@ -170,12 +171,6 @@ function mergeSortedValues(existing: string[] | undefined, incoming: string[] |
|
|
|
170
171
|
return mergeSortedUniqueStrings(existing, incoming);
|
|
171
172
|
}
|
|
172
173
|
|
|
173
|
-
function isNotFoundError(error: unknown): boolean {
|
|
174
|
-
return (
|
|
175
|
-
typeof error === "object" && error !== null && "code" in error && (error as { code?: unknown }).code === "ENOENT"
|
|
176
|
-
);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
174
|
function boundNodeRefs(nodeRefs: string[], liveNodes?: Map<string, AbstractionNode>): string[] {
|
|
180
175
|
const uniqueRefs = mergeSortedUniqueStrings(nodeRefs);
|
|
181
176
|
if (!liveNodes) return uniqueRefs.slice(0, 50);
|
package/src/graph.ts
CHANGED
|
@@ -30,6 +30,7 @@ import {
|
|
|
30
30
|
withGraphWriteLock,
|
|
31
31
|
yieldForLockHeartbeat,
|
|
32
32
|
} from "./graph-write-lock.js";
|
|
33
|
+
import { isErrnoCode } from "./utils/errno.js";
|
|
33
34
|
|
|
34
35
|
export type GraphType = "entity" | "time" | "causal";
|
|
35
36
|
|
|
@@ -143,9 +144,6 @@ export async function appendEdge(memoryDir: string, edge: GraphEdge): Promise<vo
|
|
|
143
144
|
confidence: typeof edge.confidence === "number" ? edge.confidence : 1.0,
|
|
144
145
|
});
|
|
145
146
|
}
|
|
146
|
-
function isNodeError(err: unknown): err is NodeJS.ErrnoException {
|
|
147
|
-
return typeof err === "object" && err !== null && "code" in err;
|
|
148
|
-
}
|
|
149
147
|
|
|
150
148
|
function parseEdgesJsonl(raw: string, expectedType: GraphType): GraphEdge[] {
|
|
151
149
|
const edges: GraphEdge[] = [];
|
|
@@ -213,7 +211,7 @@ export async function readEdgesStrict(memoryDir: string, type: GraphType): Promi
|
|
|
213
211
|
const raw = await readFile(filePath, "utf8");
|
|
214
212
|
return await parseEdgesJsonlYielding(raw, type);
|
|
215
213
|
} catch (err) {
|
|
216
|
-
if (
|
|
214
|
+
if (isErrnoCode(err, "ENOENT")) {
|
|
217
215
|
return [];
|
|
218
216
|
}
|
|
219
217
|
throw err;
|
package/src/json-store.ts
CHANGED
|
@@ -13,17 +13,14 @@ import {
|
|
|
13
13
|
type FileHandle,
|
|
14
14
|
} from "node:fs/promises";
|
|
15
15
|
import path from "node:path";
|
|
16
|
-
|
|
17
|
-
function hasErrorCode(error: unknown, code: string): boolean {
|
|
18
|
-
return typeof error === "object" && error !== null && "code" in error && (error as { code?: unknown }).code === code;
|
|
19
|
-
}
|
|
16
|
+
import { isErrnoCode } from "./utils/errno.js";
|
|
20
17
|
|
|
21
18
|
async function listJsonFilesStrictInner(dir: string, allowMissingDirectory: boolean): Promise<string[]> {
|
|
22
19
|
let entries: Dirent[];
|
|
23
20
|
try {
|
|
24
21
|
entries = await readdir(dir, { withFileTypes: true });
|
|
25
22
|
} catch (error) {
|
|
26
|
-
if (allowMissingDirectory &&
|
|
23
|
+
if (allowMissingDirectory && isErrnoCode(error, "ENOENT")) return [];
|
|
27
24
|
throw error;
|
|
28
25
|
}
|
|
29
26
|
const out: string[] = [];
|
|
@@ -107,7 +104,7 @@ function jsonStoreLockTimeoutMs(): number {
|
|
|
107
104
|
async function closeAndRemoveJsonStoreReclaimGuard(reclaimPath: string, reclaimHandle: FileHandle): Promise<void> {
|
|
108
105
|
await reclaimHandle.close().catch(() => undefined);
|
|
109
106
|
await unlink(reclaimPath).catch((error) => {
|
|
110
|
-
if (!
|
|
107
|
+
if (!isErrnoCode(error, "ENOENT")) throw error;
|
|
111
108
|
});
|
|
112
109
|
}
|
|
113
110
|
|
|
@@ -116,7 +113,7 @@ async function removeStaleJsonStoreReclaimGuard(reclaimPath: string): Promise<vo
|
|
|
116
113
|
try {
|
|
117
114
|
initial = await readJsonStoreLockState(reclaimPath);
|
|
118
115
|
} catch (error) {
|
|
119
|
-
if (
|
|
116
|
+
if (isErrnoCode(error, "ENOENT")) return;
|
|
120
117
|
throw error;
|
|
121
118
|
}
|
|
122
119
|
if (Date.now() - initial.mtimeMs <= jsonStoreLockStaleMs()) return;
|
|
@@ -134,12 +131,12 @@ async function removeStaleJsonStoreReclaimGuard(reclaimPath: string): Promise<vo
|
|
|
134
131
|
try {
|
|
135
132
|
confirmed = await readJsonStoreLockState(reclaimPath);
|
|
136
133
|
} catch (error) {
|
|
137
|
-
if (
|
|
134
|
+
if (isErrnoCode(error, "ENOENT")) return;
|
|
138
135
|
throw error;
|
|
139
136
|
}
|
|
140
137
|
if (!sameJsonStoreLockState(initial, confirmed)) return;
|
|
141
138
|
await unlink(reclaimPath).catch((error) => {
|
|
142
|
-
if (!
|
|
139
|
+
if (!isErrnoCode(error, "ENOENT")) throw error;
|
|
143
140
|
});
|
|
144
141
|
}
|
|
145
142
|
|
|
@@ -147,12 +144,12 @@ async function acquireJsonStoreReclaimGuard(reclaimPath: string): Promise<FileHa
|
|
|
147
144
|
try {
|
|
148
145
|
return await open(reclaimPath, "wx", 0o600);
|
|
149
146
|
} catch (error) {
|
|
150
|
-
if (!
|
|
147
|
+
if (!isErrnoCode(error, "EEXIST")) throw error;
|
|
151
148
|
await removeStaleJsonStoreReclaimGuard(reclaimPath);
|
|
152
149
|
try {
|
|
153
150
|
return await open(reclaimPath, "wx", 0o600);
|
|
154
151
|
} catch (retryError) {
|
|
155
|
-
if (
|
|
152
|
+
if (isErrnoCode(retryError, "EEXIST")) return undefined;
|
|
156
153
|
throw retryError;
|
|
157
154
|
}
|
|
158
155
|
}
|
|
@@ -169,7 +166,7 @@ function processIsRunning(pid: number): boolean {
|
|
|
169
166
|
process.kill(pid, 0);
|
|
170
167
|
return true;
|
|
171
168
|
} catch (error) {
|
|
172
|
-
return !
|
|
169
|
+
return !isErrnoCode(error, "ESRCH");
|
|
173
170
|
}
|
|
174
171
|
}
|
|
175
172
|
|
|
@@ -208,7 +205,7 @@ async function removeJsonStoreMutationLockIfOwned(lockPath: string, token: strin
|
|
|
208
205
|
const metadata = JSON.parse(state.content) as { token?: unknown };
|
|
209
206
|
if (metadata.token === token) await unlink(lockPath);
|
|
210
207
|
} catch (error) {
|
|
211
|
-
if (!
|
|
208
|
+
if (!isErrnoCode(error, "ENOENT") && !(error instanceof SyntaxError)) throw error;
|
|
212
209
|
}
|
|
213
210
|
}
|
|
214
211
|
|
|
@@ -224,7 +221,7 @@ async function removeStaleJsonStoreLock(lockPath: string): Promise<void> {
|
|
|
224
221
|
try {
|
|
225
222
|
initial = await readJsonStoreLockState(lockPath);
|
|
226
223
|
} catch (error) {
|
|
227
|
-
if (
|
|
224
|
+
if (isErrnoCode(error, "ENOENT")) return;
|
|
228
225
|
throw error;
|
|
229
226
|
}
|
|
230
227
|
if (Date.now() - initial.mtimeMs <= jsonStoreLockStaleMs()) return;
|
|
@@ -241,12 +238,12 @@ async function removeStaleJsonStoreLock(lockPath: string): Promise<void> {
|
|
|
241
238
|
try {
|
|
242
239
|
confirmed = await readJsonStoreLockState(lockPath);
|
|
243
240
|
} catch (error) {
|
|
244
|
-
if (
|
|
241
|
+
if (isErrnoCode(error, "ENOENT")) return;
|
|
245
242
|
throw error;
|
|
246
243
|
}
|
|
247
244
|
if (!sameJsonStoreLockState(initial, confirmed)) return;
|
|
248
245
|
await unlink(lockPath).catch((error) => {
|
|
249
|
-
if (!
|
|
246
|
+
if (!isErrnoCode(error, "ENOENT")) throw error;
|
|
250
247
|
});
|
|
251
248
|
} finally {
|
|
252
249
|
await closeAndRemoveJsonStoreReclaimGuard(reclaimPath, reclaimHandle);
|
|
@@ -272,7 +269,7 @@ async function confirmJsonStoreMutationLockOwnership(
|
|
|
272
269
|
const metadata = JSON.parse(state.content) as { token?: unknown };
|
|
273
270
|
return metadata.token === token;
|
|
274
271
|
} catch (error) {
|
|
275
|
-
if (
|
|
272
|
+
if (isErrnoCode(error, "ENOENT") || error instanceof SyntaxError) return false;
|
|
276
273
|
throw error;
|
|
277
274
|
}
|
|
278
275
|
} finally {
|
|
@@ -291,9 +288,9 @@ async function acquireJsonStoreMutationFileLock(key: string): Promise<() => Prom
|
|
|
291
288
|
try {
|
|
292
289
|
handle = await open(lockPath, "wx", 0o600);
|
|
293
290
|
} catch (error) {
|
|
294
|
-
if (!
|
|
291
|
+
if (!isErrnoCode(error, "EEXIST")) throw error;
|
|
295
292
|
await removeStaleJsonStoreLock(lockPath).catch((staleError) => {
|
|
296
|
-
if (!
|
|
293
|
+
if (!isErrnoCode(staleError, "ENOENT")) throw staleError;
|
|
297
294
|
});
|
|
298
295
|
if (Date.now() >= deadline) {
|
|
299
296
|
throw new Error(`Timed out acquiring JSON store mutation lock: ${lockPath}`);
|
|
@@ -338,7 +335,7 @@ async function acquireJsonStoreMutationFileLock(key: string): Promise<() => Prom
|
|
|
338
335
|
const metadata = JSON.parse(await readFile(lockPath, "utf8")) as { token?: unknown };
|
|
339
336
|
if (metadata.token === token) await unlink(lockPath);
|
|
340
337
|
} catch (error) {
|
|
341
|
-
if (!
|
|
338
|
+
if (!isErrnoCode(error, "ENOENT")) throw error;
|
|
342
339
|
}
|
|
343
340
|
};
|
|
344
341
|
}
|
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
type ConnectorState,
|
|
30
30
|
type LiveConnector,
|
|
31
31
|
} from "./connectors/live/index.js";
|
|
32
|
+
import { abortError } from "./abort-error.js";
|
|
32
33
|
import type { LiveConnectorsConfig } from "./types.js";
|
|
33
34
|
|
|
34
35
|
export type LiveConnectorSkipReason =
|
|
@@ -428,7 +429,7 @@ function throwIfAborted(signal: AbortSignal | undefined): void {
|
|
|
428
429
|
if (reason instanceof Error) {
|
|
429
430
|
throw reason;
|
|
430
431
|
}
|
|
431
|
-
throw
|
|
432
|
+
throw abortError(reason === undefined ? "operation aborted" : String(reason));
|
|
432
433
|
}
|
|
433
434
|
|
|
434
435
|
async function writeConnectorErrorState(options: {
|
package/src/location/store.ts
CHANGED
|
@@ -21,6 +21,7 @@ import path from "node:path";
|
|
|
21
21
|
|
|
22
22
|
import { writeFileAtomically } from "../maintenance/atomic-file.js";
|
|
23
23
|
import { pathIsInside } from "../utils/path-containment.js";
|
|
24
|
+
import { isErrnoCode } from "../utils/errno.js";
|
|
24
25
|
import { isValidLocationDate, placeDurations } from "./intervals.js";
|
|
25
26
|
import type { LocationSegment } from "./types.js";
|
|
26
27
|
|
|
@@ -376,10 +377,6 @@ export function parseLocationDaySummary(raw: string): LocationDaySummary | null
|
|
|
376
377
|
|
|
377
378
|
// ── Containment-checked day-file IO ─────────────────────────────────────────
|
|
378
379
|
|
|
379
|
-
function isErrnoCode(err: unknown, code: string): boolean {
|
|
380
|
-
return err instanceof Error && (err as NodeJS.ErrnoException).code === code;
|
|
381
|
-
}
|
|
382
|
-
|
|
383
380
|
async function assertNotSymlink(target: string, kind: "directory" | "day file"): Promise<void> {
|
|
384
381
|
let stat: { isSymbolicLink(): boolean };
|
|
385
382
|
try {
|
package/src/maintenance/purge.ts
CHANGED
|
@@ -25,6 +25,7 @@ import type { StorageManager } from "../storage.js";
|
|
|
25
25
|
import type { MemoryFile } from "../types.js";
|
|
26
26
|
import { markProjectedMemoryPathInvalid } from "../memory-projection-store.js";
|
|
27
27
|
import type { SearchBackend } from "../search/port.js";
|
|
28
|
+
import { isErrnoCode } from "../utils/errno.js";
|
|
28
29
|
|
|
29
30
|
export type PurgeTierFilter = "cold" | "all";
|
|
30
31
|
|
|
@@ -87,10 +88,6 @@ export interface PurgeMemoriesResult {
|
|
|
87
88
|
errors: Array<{ id: string; path: string; error: string }>;
|
|
88
89
|
}
|
|
89
90
|
|
|
90
|
-
function hasErrorCode(err: unknown, code: string): boolean {
|
|
91
|
-
return typeof err === "object" && err !== null && "code" in err && (err as { code?: unknown }).code === code;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
91
|
function resolveTimestamp(memory: MemoryFile): string {
|
|
95
92
|
const fm = memory.frontmatter as unknown as Record<string, unknown>;
|
|
96
93
|
const updated = typeof fm.updated === "string" ? (fm.updated as string) : "";
|
|
@@ -247,7 +244,7 @@ export async function purgeMemories(
|
|
|
247
244
|
}
|
|
248
245
|
} catch (err) {
|
|
249
246
|
const message = err instanceof Error ? err.message : String(err);
|
|
250
|
-
if (
|
|
247
|
+
if (isErrnoCode(err, "ENOENT")) {
|
|
251
248
|
alreadyAbsent.push(candidate);
|
|
252
249
|
addCollectionForCandidate(candidate);
|
|
253
250
|
markProjectedMemoryPathInvalid(storage.dir, candidate.id);
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
} from "../memory-lifecycle-ledger-utils.js";
|
|
19
19
|
import { withHeldFileLock, type HeldFileLockOptions, type HeldFileLockController } from "../utils/serialize-mutations.js";
|
|
20
20
|
import { probeEncryptedRegularFileHeader } from "../secure-store/secure-fs.js";
|
|
21
|
+
import { isErrnoCode } from "../utils/errno.js";
|
|
21
22
|
|
|
22
23
|
|
|
23
24
|
export interface RebuildMemoryLifecycleLedgerOptions {
|
|
@@ -115,10 +116,6 @@ export interface RebuildMemoryLifecycleLedgerResult {
|
|
|
115
116
|
rewritten?: boolean;
|
|
116
117
|
}
|
|
117
118
|
|
|
118
|
-
function isNodeError(err: unknown): err is NodeJS.ErrnoException {
|
|
119
|
-
return typeof err === "object" && err !== null && "code" in err;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
119
|
/** Serialized on-disk size (bytes, incl. trailing newline) of one ledger row. */
|
|
123
120
|
function lifecycleRowBytes(event: MemoryLifecycleEvent): number {
|
|
124
121
|
return Buffer.byteLength(`${JSON.stringify(event)}\n`, "utf8");
|
|
@@ -174,7 +171,7 @@ export async function backupExistingLedger(
|
|
|
174
171
|
try {
|
|
175
172
|
await stat(outputPath);
|
|
176
173
|
} catch (err) {
|
|
177
|
-
if (
|
|
174
|
+
if (isErrnoCode(err, "ENOENT")) {
|
|
178
175
|
return undefined;
|
|
179
176
|
}
|
|
180
177
|
throw err;
|
|
@@ -397,7 +394,7 @@ export async function rebuildMemoryLifecycleLedger(
|
|
|
397
394
|
currentEncrypted = await probeEncryptedRegularFileHeader(outputPath);
|
|
398
395
|
priorRawBuffer = await storage.readMemoryLifecycleLedgerRawBufferForCompaction();
|
|
399
396
|
} catch (err) {
|
|
400
|
-
if (!
|
|
397
|
+
if (!isErrnoCode(err, "ENOENT")) throw err;
|
|
401
398
|
}
|
|
402
399
|
// Preserve encryption at rest (#2033). An already-encrypted ledger (or its
|
|
403
400
|
// encrypted backup) MUST be rewritten encrypted even when the
|
|
@@ -76,6 +76,7 @@ import type {
|
|
|
76
76
|
SkippedDuplicateMemory,
|
|
77
77
|
SkippedDuplicateTimelineEvent,
|
|
78
78
|
} from "./projection-support.js";
|
|
79
|
+
import { isErrnoCode } from "../utils/errno.js";
|
|
79
80
|
|
|
80
81
|
|
|
81
82
|
export interface RebuildMemoryProjectionResult {
|
|
@@ -150,10 +151,6 @@ export interface RepairMemoryProjectionResult {
|
|
|
150
151
|
rebuild?: RebuildMemoryProjectionResult;
|
|
151
152
|
}
|
|
152
153
|
|
|
153
|
-
function isNodeError(err: unknown): err is NodeJS.ErrnoException {
|
|
154
|
-
return typeof err === "object" && err !== null && "code" in err;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
154
|
export async function backupExistingProjection(
|
|
158
155
|
memoryDir: string,
|
|
159
156
|
outputPath: string,
|
|
@@ -162,7 +159,7 @@ export async function backupExistingProjection(
|
|
|
162
159
|
try {
|
|
163
160
|
await stat(outputPath);
|
|
164
161
|
} catch (err) {
|
|
165
|
-
if (
|
|
162
|
+
if (isErrnoCode(err, "ENOENT")) {
|
|
166
163
|
return undefined;
|
|
167
164
|
}
|
|
168
165
|
throw err;
|
|
@@ -22,6 +22,7 @@ import { isSafeRouteNamespace } from "../routing/engine.js";
|
|
|
22
22
|
import { namespaceIdentityFromToken, namespaceIdentityLegacyToken, namespaceIdentityToken, normalizeNamespaceIdentity } from "./identity.js";
|
|
23
23
|
import { resolveDefaultNamespaceRoot, resolveNamespaceStorageRoot } from "./storage.js";
|
|
24
24
|
import { ALL_CATEGORY_DIRS } from "../utils/category-dir.js";
|
|
25
|
+
import { isNotFoundError } from "../utils/errno.js";
|
|
25
26
|
|
|
26
27
|
/**
|
|
27
28
|
* Rebuildable namespace catalog (issue #1499).
|
|
@@ -191,15 +192,6 @@ type MemoryDataRootStatus = {
|
|
|
191
192
|
invalidMarker?: string;
|
|
192
193
|
};
|
|
193
194
|
|
|
194
|
-
function isNotFoundError(err: unknown): boolean {
|
|
195
|
-
return (
|
|
196
|
-
typeof err === "object" &&
|
|
197
|
-
err !== null &&
|
|
198
|
-
"code" in err &&
|
|
199
|
-
(err as { code?: string }).code === "ENOENT"
|
|
200
|
-
);
|
|
201
|
-
}
|
|
202
|
-
|
|
203
195
|
/**
|
|
204
196
|
* Inspect `child` under `rootDir` as a memory-data marker (NIw0F / PR #1506).
|
|
205
197
|
* Existence alone is not enough: a bogus marker — e.g. `facts` as a symlink or a
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { mkdtemp, writeFile } from "node:fs/promises";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import test from "node:test";
|
|
6
|
+
|
|
7
|
+
import { sha256OfflineSyncFile } from "./offline-sync-file-io.js";
|
|
8
|
+
|
|
9
|
+
async function tempFile(name: string, content: string): Promise<string> {
|
|
10
|
+
const dir = await mkdtemp(path.join(os.tmpdir(), `${name}-`));
|
|
11
|
+
const filePath = path.join(dir, `${name}.txt`);
|
|
12
|
+
await writeFile(filePath, content);
|
|
13
|
+
return filePath;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** The abort guards must surface `name === "AbortError"`, not a plain Error (issue #2795). */
|
|
17
|
+
async function assertRejectsWithAbortError(promise: Promise<unknown>): Promise<void> {
|
|
18
|
+
await assert.rejects(promise, (err: unknown) => {
|
|
19
|
+
assert.ok(err instanceof Error, "abort must surface an Error");
|
|
20
|
+
assert.equal(err.name, "AbortError", "abort must preserve the AbortError name");
|
|
21
|
+
return true;
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
test("sha256OfflineSyncFile rejects with AbortError name via the per-chunk guard", async () => {
|
|
26
|
+
const filePath = await tempFile("offline-sync-abort", "chunk-of-bytes");
|
|
27
|
+
const controller = new AbortController();
|
|
28
|
+
controller.abort();
|
|
29
|
+
// A non-empty file yields at least one chunk, so the in-loop guard fires first.
|
|
30
|
+
await assertRejectsWithAbortError(sha256OfflineSyncFile(filePath, controller.signal));
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test("sha256OfflineSyncFile rejects with AbortError name via the post-loop guard", async () => {
|
|
34
|
+
const filePath = await tempFile("offline-sync-abort-empty", "");
|
|
35
|
+
const controller = new AbortController();
|
|
36
|
+
controller.abort();
|
|
37
|
+
// An empty file yields no chunks, so only the trailing guard runs.
|
|
38
|
+
await assertRejectsWithAbortError(sha256OfflineSyncFile(filePath, controller.signal));
|
|
39
|
+
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { createReadStream } from "node:fs";
|
|
3
3
|
import { open } from "node:fs/promises";
|
|
4
|
+
import { throwIfAborted } from "./abort-error.js";
|
|
4
5
|
import { MAGIC_HEADER_SIZE, isEncryptedFile } from "./secure-store/secure-fs.js";
|
|
5
6
|
|
|
6
7
|
export interface OfflineSyncFileTarget {
|
|
@@ -10,11 +11,6 @@ export interface OfflineSyncFileTarget {
|
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
export type OfflineSyncExcludeFile = (target: OfflineSyncFileTarget) => boolean | Promise<boolean>;
|
|
13
|
-
|
|
14
|
-
function throwIfAborted(signal: AbortSignal | undefined): void {
|
|
15
|
-
if (signal?.aborted) throw new Error("offline sync request aborted");
|
|
16
|
-
}
|
|
17
|
-
|
|
18
14
|
export async function shouldExcludeOfflineSyncFile(
|
|
19
15
|
excludeFile: OfflineSyncExcludeFile | undefined,
|
|
20
16
|
target: OfflineSyncFileTarget
|
|
@@ -29,12 +25,12 @@ export async function sha256OfflineSyncFile(
|
|
|
29
25
|
const hash = createHash("sha256");
|
|
30
26
|
let bytes = 0;
|
|
31
27
|
for await (const chunk of createReadStream(filePath)) {
|
|
32
|
-
throwIfAborted(signal);
|
|
28
|
+
throwIfAborted(signal, "offline sync request aborted");
|
|
33
29
|
const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
34
30
|
hash.update(buffer);
|
|
35
31
|
bytes += buffer.length;
|
|
36
32
|
}
|
|
37
|
-
throwIfAborted(signal);
|
|
33
|
+
throwIfAborted(signal, "offline sync request aborted");
|
|
38
34
|
return { sha256: hash.digest("hex"), bytes };
|
|
39
35
|
}
|
|
40
36
|
|
|
@@ -16,6 +16,7 @@ import { buildProcedurePersistBody, normalizeProcedureSteps, type ProcedureStep
|
|
|
16
16
|
import { clusterByKey } from "./reinforcement-core.js";
|
|
17
17
|
import { log } from "../logger.js";
|
|
18
18
|
import { composeMemoryEnvelope, STRUCTURED_ATTRIBUTE_LIMITS } from "../write-envelope.js";
|
|
19
|
+
import { isErrnoCode } from "../utils/errno.js";
|
|
19
20
|
|
|
20
21
|
/** Must match truncation on `procedure_cluster` structured attribute (dedupe + storage). */
|
|
21
22
|
const PROCEDURE_CLUSTER_ATTR_MAX = 500;
|
|
@@ -53,15 +54,6 @@ function clusterKeyHash(cluster: string): string {
|
|
|
53
54
|
return createHash("sha256").update(cluster).digest("hex");
|
|
54
55
|
}
|
|
55
56
|
|
|
56
|
-
function isErrnoCode(error: unknown, code: string): boolean {
|
|
57
|
-
return (
|
|
58
|
-
typeof error === "object" &&
|
|
59
|
-
error !== null &&
|
|
60
|
-
"code" in error &&
|
|
61
|
-
(error as { code?: unknown }).code === code
|
|
62
|
-
);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
57
|
function sleep(ms: number): Promise<void> {
|
|
66
58
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
67
59
|
}
|
|
@@ -2,6 +2,7 @@ import path from "node:path";
|
|
|
2
2
|
import { lstat, readdir, readFile, realpath } from "node:fs/promises";
|
|
3
3
|
import { RECALL_FALLBACK_DIRS } from "../utils/category-dir.js";
|
|
4
4
|
import { assertPathInsideRoot } from "../utils/path-containment.js";
|
|
5
|
+
import { isErrnoCode } from "../utils/errno.js";
|
|
5
6
|
|
|
6
7
|
export interface IndexableDocument {
|
|
7
8
|
/** Memory ID from frontmatter or filename stem */
|
|
@@ -83,7 +84,7 @@ async function scanDir(dir: string, memoryRootReal: string): Promise<IndexableDo
|
|
|
83
84
|
}
|
|
84
85
|
}
|
|
85
86
|
} catch (err) {
|
|
86
|
-
if (
|
|
87
|
+
if (isErrnoCode(err, "ENOENT")) {
|
|
87
88
|
// Optional category directories may not exist yet.
|
|
88
89
|
return docs;
|
|
89
90
|
}
|
|
@@ -92,10 +93,6 @@ async function scanDir(dir: string, memoryRootReal: string): Promise<IndexableDo
|
|
|
92
93
|
return docs;
|
|
93
94
|
}
|
|
94
95
|
|
|
95
|
-
function isNodeError(err: unknown): err is NodeJS.ErrnoException {
|
|
96
|
-
return typeof err === "object" && err !== null && "code" in err;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
96
|
/**
|
|
100
97
|
* Scan every recall category subdir of memoryDir for indexable markdown
|
|
101
98
|
* documents. The directory set is derived from `RECALL_FALLBACK_DIRS`
|
|
@@ -114,7 +111,7 @@ export async function scanMemoryDir(memoryDir: string): Promise<IndexableDocumen
|
|
|
114
111
|
try {
|
|
115
112
|
memoryRootReal = await realpath(memoryDir);
|
|
116
113
|
} catch (err) {
|
|
117
|
-
if (
|
|
114
|
+
if (isErrnoCode(err, "ENOENT")) {
|
|
118
115
|
return [];
|
|
119
116
|
}
|
|
120
117
|
throw err;
|
|
@@ -6,6 +6,7 @@ import path from "node:path";
|
|
|
6
6
|
import { setTimeout as sleep } from "node:timers/promises";
|
|
7
7
|
import { StorageManager } from "./storage.js";
|
|
8
8
|
import type { MemoryFile, MemoryLink } from "./types.js";
|
|
9
|
+
import { isErrnoCode } from "./utils/errno.js";
|
|
9
10
|
|
|
10
11
|
export interface SemanticRulePromotionCandidate {
|
|
11
12
|
id: string;
|
|
@@ -79,10 +80,6 @@ function promotionLockHeartbeatMs(): number {
|
|
|
79
80
|
return testHooks?.heartbeatMs ?? PROMOTION_LOCK_HEARTBEAT_MS;
|
|
80
81
|
}
|
|
81
82
|
|
|
82
|
-
function isErrnoCode(err: unknown, code: string): boolean {
|
|
83
|
-
return typeof err === "object" && err !== null && "code" in err && (err as { code?: unknown }).code === code;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
83
|
function promotionLockDir(memoryDir: string, ruleKey: string): string {
|
|
87
84
|
const digest = createHash("sha256").update(ruleKey).digest("hex");
|
|
88
85
|
return path.join(path.resolve(memoryDir), "state", "semantic-rule-promotion-locks", `${digest}.lock`);
|