@remnic/core 10.0.83 → 10.0.85
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access-admin-ops-surface.js +67 -66
- package/dist/access-authorization-probe.js +68 -67
- package/dist/access-boundary.js +67 -66
- package/dist/access-cli.js +148 -146
- package/dist/access-cli.js.map +1 -1
- package/dist/access-extraction-force-flush.js +67 -66
- package/dist/access-http-briefing.js +68 -67
- package/dist/access-http-query.js +69 -68
- package/dist/access-http.js +91 -89
- package/dist/access-identity-continuity-surface.js +67 -66
- package/dist/access-lcm-surface.js +67 -66
- package/dist/access-mcp-frames.d.ts +29 -0
- package/dist/access-mcp-frames.d.ts.map +1 -0
- package/dist/access-mcp-frames.js +10 -0
- package/dist/access-mcp.d.ts +1 -1
- package/dist/access-mcp.d.ts.map +1 -1
- package/dist/access-mcp.js +82 -80
- package/dist/access-namespace-preflight.js +67 -66
- package/dist/access-observe-write-category.js +9 -9
- package/dist/access-observe-write-surface.d.ts.map +1 -1
- package/dist/access-observe-write-surface.js +67 -66
- package/dist/access-offline-manifest.js +3 -3
- package/dist/access-operations-batch.js +71 -70
- package/dist/access-operations.d.ts +1 -1
- package/dist/access-operations.js +78 -77
- package/dist/access-recall-concurrency.js +67 -66
- package/dist/access-recall-response.js +67 -66
- package/dist/access-recall-surface.js +67 -66
- package/dist/access-schema.js +4 -4
- package/dist/access-service.js +67 -66
- package/dist/access-surface-catalog.js +69 -68
- package/dist/access-surface-catalog.js.map +1 -1
- package/dist/active-recall.js +31 -31
- package/dist/{auto-sync-C7E6G7Y2.js → auto-sync-3AZW7MXI.js} +6 -6
- package/dist/briefing.js +25 -25
- package/dist/buffer-persistence.d.ts +8 -4
- package/dist/buffer-persistence.d.ts.map +1 -1
- package/dist/buffer-persistence.js +1 -1
- package/dist/buffer-turn-helpers.d.ts +5 -0
- package/dist/buffer-turn-helpers.d.ts.map +1 -1
- package/dist/buffer-turn-helpers.js +1 -1
- package/dist/buffer.d.ts +4 -1
- package/dist/buffer.d.ts.map +1 -1
- package/dist/buffer.js +9 -9
- package/dist/calibration.js +2 -2
- package/dist/{capsule-crypto-YO5QJ6L3.js → capsule-crypto-GWVG7LGC.js} +2 -2
- package/dist/capsule-gunzip-KGBDGF7P.js +11 -0
- package/dist/{capsule-merge-XVTQJJ6R.js → capsule-merge-2IIXFXN5.js} +5 -11
- package/dist/capsule-merge-2IIXFXN5.js.map +1 -0
- package/dist/causal-behavior.js +2 -2
- package/dist/causal-chain.js +2 -2
- package/dist/causal-consolidation.js +32 -32
- package/dist/causal-retrieval.js +2 -2
- package/dist/causal-trajectory-graph.js +2 -2
- package/dist/causal-trajectory.js +1 -1
- package/dist/{chunk-T6T2RMWW.js → chunk-23B4HLWG.js} +5 -5
- package/dist/{chunk-LECSS7EE.js → chunk-2ASEDFOA.js} +2 -2
- package/dist/{chunk-TPX7XXY4.js → chunk-2JAT4S7N.js} +2 -2
- package/dist/{chunk-XRBHIR7Q.js → chunk-2URKYLMK.js} +2 -2
- package/dist/{chunk-IN4OFAHX.js → chunk-2XYDL2FG.js} +2 -2
- package/dist/{chunk-HQGATKG2.js → chunk-3KGCHTTK.js} +2 -2
- package/dist/{chunk-YAUHSNPB.js → chunk-3LHPTBWG.js} +2 -2
- package/dist/{chunk-7PMOCQOL.js → chunk-3ODZLCHC.js} +192 -63
- package/dist/chunk-3ODZLCHC.js.map +1 -0
- package/dist/{chunk-XT45WCKX.js → chunk-3VU2FDTU.js} +8 -8
- package/dist/{chunk-CIIHIAJ2.js → chunk-433EXTC4.js} +3 -3
- package/dist/{chunk-QZSIDSB2.js → chunk-44FQCC5D.js} +2 -2
- package/dist/{chunk-YUTT4ZTI.js → chunk-45VUHDV2.js} +2 -2
- package/dist/{chunk-54FDG7K7.js → chunk-4DPLCYEK.js} +2 -2
- package/dist/{chunk-KO3YBHOV.js → chunk-4IWEPQEV.js} +2 -2
- package/dist/{chunk-H7BZBSP6.js → chunk-52II7PB6.js} +4 -4
- package/dist/{chunk-K6RTQZA4.js → chunk-6DANGCMO.js} +2 -2
- package/dist/{chunk-2IW5PT7U.js → chunk-6KFFRMPQ.js} +2 -2
- package/dist/{chunk-MSIRVXQ3.js → chunk-73YVMZ7D.js} +4 -4
- package/dist/{chunk-A7BM2JTH.js → chunk-AJHNXIQU.js} +2 -2
- package/dist/{chunk-2D7BTSDW.js → chunk-ANZZLRUX.js} +2 -2
- package/dist/{chunk-YOEYL6CH.js → chunk-AP3TSV6S.js} +2 -2
- package/dist/{chunk-GQZSGXR6.js → chunk-BATPQNRG.js} +2 -2
- package/dist/{chunk-D5SSBCYY.js → chunk-BLGQUZFB.js} +2 -2
- package/dist/{chunk-BDN3TDGV.js → chunk-BLMTOIBK.js} +2 -2
- package/dist/{chunk-B74NPUHT.js → chunk-BMIM6ESC.js} +43 -43
- package/dist/chunk-BMIM6ESC.js.map +1 -0
- package/dist/{chunk-R45L4TV6.js → chunk-BUKK5SWA.js} +6 -6
- package/dist/{chunk-TFLPDNQV.js → chunk-CCU7URRP.js} +2 -2
- package/dist/{chunk-2XJZLSXE.js → chunk-CMRHXPLQ.js} +20 -20
- package/dist/{chunk-BK4FBHZ3.js → chunk-D6THW7PA.js} +3 -3
- package/dist/{chunk-BFBS7OFQ.js → chunk-DC55RIEZ.js} +4 -4
- package/dist/{chunk-VKDAJJQP.js → chunk-DI5ET2IE.js} +5 -5
- package/dist/{chunk-QZBTIYKD.js → chunk-DM4RRTN7.js} +3 -3
- package/dist/{chunk-S57QBPTA.js → chunk-DPPLNZ3A.js} +4 -6
- package/dist/chunk-DPPLNZ3A.js.map +1 -0
- package/dist/{chunk-EBOHFZI4.js → chunk-E5QEF3JO.js} +2 -2
- package/dist/{chunk-DD6OIFDG.js → chunk-E7V5AK7I.js} +3 -3
- package/dist/{chunk-WAD32CZG.js → chunk-ELWI2R6H.js} +26 -13
- package/dist/chunk-ELWI2R6H.js.map +1 -0
- package/dist/{chunk-BV2BRHD4.js → chunk-FHGWKODN.js} +2 -2
- package/dist/{chunk-HPFVZPRH.js → chunk-FK4WC6VK.js} +3 -3
- package/dist/{chunk-VLMBSGQF.js → chunk-FRM4UTDR.js} +6 -6
- package/dist/{chunk-LTDLJCMQ.js → chunk-FZPDRCOB.js} +2 -2
- package/dist/{chunk-ZJJFUEPO.js → chunk-GBOYOL5L.js} +2 -2
- package/dist/{chunk-YUTG35M4.js → chunk-GJVGFKOU.js} +2 -2
- package/dist/{chunk-77R7BQZ2.js → chunk-GKYIRTNX.js} +33 -11
- package/dist/{chunk-77R7BQZ2.js.map → chunk-GKYIRTNX.js.map} +1 -1
- package/dist/{chunk-K36RMINQ.js → chunk-GOZXQNIM.js} +3 -3
- package/dist/{chunk-HWHNQVRV.js → chunk-GYNRNKMW.js} +2 -2
- package/dist/{chunk-LU66I56Q.js → chunk-H34INI3P.js} +29 -3
- package/dist/chunk-H34INI3P.js.map +1 -0
- package/dist/{chunk-AYTDCMEL.js → chunk-H4D5YURJ.js} +80 -94
- package/dist/chunk-H4D5YURJ.js.map +1 -0
- package/dist/{chunk-6LCWKS62.js → chunk-HVFX2N2G.js} +60 -59
- package/dist/chunk-HVFX2N2G.js.map +1 -0
- package/dist/chunk-IGLJNHOX.js +62 -0
- package/dist/chunk-IGLJNHOX.js.map +1 -0
- package/dist/{chunk-KFLD7ZZG.js → chunk-IUKYFTGW.js} +3 -3
- package/dist/{chunk-YK7GOPIE.js → chunk-JFH6JAGY.js} +6 -4
- package/dist/chunk-JFH6JAGY.js.map +1 -0
- package/dist/{chunk-BNQJKWWZ.js → chunk-K3FH3LAQ.js} +4 -4
- package/dist/{chunk-FJ2VJTGA.js → chunk-KHZVAISH.js} +2 -2
- package/dist/{chunk-WHQXWFH7.js → chunk-LT3CMO65.js} +2 -2
- package/dist/{chunk-NUSAAN75.js → chunk-MHSBOEH7.js} +2 -2
- package/dist/{chunk-KJCL2FZO.js → chunk-MNYQVYJ4.js} +2 -2
- package/dist/{chunk-RZH5RVJC.js → chunk-MTTYIXSU.js} +2 -2
- package/dist/{chunk-FVRTCYZ3.js → chunk-MVOJDLXS.js} +2 -2
- package/dist/{chunk-KESJ5XX3.js → chunk-MYCCO6AA.js} +2 -2
- package/dist/{chunk-66JOLMWS.js → chunk-MZCGHPIJ.js} +2 -2
- package/dist/{chunk-B4ZU34JQ.js → chunk-N6II66E5.js} +3 -3
- package/dist/{chunk-BK7AJUWB.js → chunk-NIV7RPWQ.js} +6 -6
- package/dist/{chunk-TLHF75OR.js → chunk-O55AGDTI.js} +10 -10
- package/dist/{chunk-GGJFRVRD.js → chunk-OMYRPMQC.js} +2 -2
- package/dist/{chunk-SVCHO337.js → chunk-ONN2E5QD.js} +32 -23
- package/dist/chunk-ONN2E5QD.js.map +1 -0
- package/dist/{chunk-XHGYZRVW.js → chunk-OSTFDWZJ.js} +4 -4
- package/dist/{chunk-BXLOS5AJ.js → chunk-OWHERGF2.js} +2 -2
- package/dist/{chunk-WC475JOG.js → chunk-P225W4RQ.js} +6 -6
- package/dist/{chunk-TFA6HPOA.js → chunk-QCP75JGO.js} +5 -5
- package/dist/{chunk-JRVMCZE3.js → chunk-QEYTRFR3.js} +2 -2
- package/dist/chunk-QV2VZKD5.js +31 -0
- package/dist/chunk-QV2VZKD5.js.map +1 -0
- package/dist/{chunk-IZJQNDGI.js → chunk-R6HMAIKM.js} +2 -2
- package/dist/{chunk-VUROWXFL.js → chunk-RNGDKFY2.js} +2 -2
- package/dist/{chunk-FF6N7BXC.js → chunk-S45INSV3.js} +4 -4
- package/dist/{chunk-2RUTN7PR.js → chunk-S7GJNA3K.js} +2 -2
- package/dist/{chunk-XYP5WBDO.js → chunk-SGHV6LZ7.js} +13 -13
- package/dist/chunk-SGHV6LZ7.js.map +1 -0
- package/dist/{chunk-RJWL3RHB.js → chunk-TFEHSPGQ.js} +2 -2
- package/dist/{chunk-T77AX6DG.js → chunk-TQVECGUQ.js} +4 -4
- package/dist/{chunk-OQSSQOKQ.js → chunk-TV65NR7L.js} +2 -2
- package/dist/{chunk-KQUSP6LB.js → chunk-UDKWFDV2.js} +1 -1
- package/dist/chunk-UDKWFDV2.js.map +1 -0
- package/dist/{chunk-HQPFACXO.js → chunk-UH3FPX3L.js} +2 -2
- package/dist/{chunk-4EACCIPO.js → chunk-UHPHH74F.js} +2 -2
- package/dist/{chunk-DQEMWVMT.js → chunk-UVYI6VIX.js} +1 -1
- package/dist/{chunk-6QYPL6NI.js → chunk-V45TEVDA.js} +3 -3
- package/dist/{chunk-GCAQ3VUJ.js → chunk-VCVEMQJK.js} +2 -2
- package/dist/{chunk-6L63IN3M.js → chunk-VEFGHRKV.js} +1 -1
- package/dist/{chunk-E33UJHY3.js → chunk-WFDWLWDK.js} +2 -2
- package/dist/{chunk-4KLQI3L2.js → chunk-WLNWFHX3.js} +1 -1
- package/dist/chunk-WLNWFHX3.js.map +1 -0
- package/dist/{chunk-KQLBXUUQ.js → chunk-WYG5UNDY.js} +2 -2
- package/dist/{chunk-MPGLM2VU.js → chunk-X7REO4CH.js} +2 -2
- package/dist/{chunk-MPDLLLOG.js → chunk-XO23OKMK.js} +9 -5
- package/dist/chunk-XO23OKMK.js.map +1 -0
- package/dist/{chunk-Z3DDQXM4.js → chunk-XSFQN7TP.js} +35 -36
- package/dist/chunk-XSFQN7TP.js.map +1 -0
- package/dist/{chunk-FZVROZKC.js → chunk-XVZA6VXC.js} +4 -4
- package/dist/{chunk-WV254W4V.js → chunk-Y3IYKNBY.js} +2 -2
- package/dist/{chunk-FUOAIJKQ.js → chunk-Y43X3E24.js} +2 -2
- package/dist/{chunk-3T3VHXUH.js → chunk-YAAKVTZA.js} +2 -2
- package/dist/{chunk-VPEIWMUT.js → chunk-YLTU2DC4.js} +2 -2
- package/dist/{chunk-65SKM4BF.js → chunk-YNBMBL4C.js} +2 -2
- package/dist/{chunk-PJYK7HH2.js → chunk-ZWTHVUT5.js} +2 -2
- package/dist/cli.js +110 -108
- package/dist/coding/export-okf-codegraph.js +25 -25
- package/dist/coding/pre-action-gate.js +2 -2
- package/dist/compounding/engine.js +27 -27
- package/dist/config.js +28 -28
- package/dist/connectors/codex-materialize-runner.js +25 -25
- package/dist/connectors/index.js +25 -25
- package/dist/contradiction/index.js +4 -4
- package/dist/convergence-refresh.js +27 -27
- package/dist/conversation-index/backend.js +2 -2
- package/dist/corpus-watermark.js +27 -27
- package/dist/deep-recall-http-glue.js +5 -5
- package/dist/entity-mention-index-cache.d.ts.map +1 -1
- package/dist/entity-mention-index-cache.js +2 -1
- package/dist/entity-retrieval.js +27 -26
- package/dist/event-order-recall.js +2 -2
- package/dist/explicit-capture.js +5 -5
- package/dist/external-wiki-access.js +68 -67
- package/dist/extraction-evidence-class.js +2 -2
- package/dist/extraction-quote-grounding.d.ts.map +1 -1
- package/dist/extraction-quote-grounding.js +1 -1
- package/dist/extraction-source-grounding-rules.js +2 -2
- package/dist/extraction-source-grounding.js +5 -5
- package/dist/extraction-span-materialize.js +2 -2
- package/dist/extraction.js +40 -40
- package/dist/{first-start-migration-QVD22WWS.js → first-start-migration-A6PHIBUQ.js} +4 -4
- package/dist/{graph-edge-decay-CXTNJ7IQ.js → graph-edge-decay-EKWXRBWF.js} +5 -5
- package/dist/graph-edge-decay-EKWXRBWF.js.map +1 -0
- package/dist/graph-jsonl.js +3 -3
- package/dist/graph-snapshot.js +3 -3
- package/dist/graph.js +2 -2
- package/dist/harmonic-retrieval.js +25 -25
- package/dist/index.js +205 -203
- package/dist/lcm/engine.js +2 -2
- package/dist/lcm/index.js +2 -2
- package/dist/local-llm.js +2 -2
- package/dist/location/index.js +28 -28
- package/dist/maintenance/memory-governance.js +25 -25
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +25 -25
- package/dist/maintenance/rebuild-memory-projection-runner.js +27 -27
- package/dist/maintenance/rebuild-memory-projection.js +26 -26
- package/dist/memory-browse-operations.js +68 -67
- package/dist/memory-subject.js +2 -2
- package/dist/namespaces/migrate.js +26 -26
- package/dist/namespaces/search.d.ts +8 -0
- package/dist/namespaces/search.d.ts.map +1 -1
- package/dist/namespaces/search.js +10 -6
- package/dist/namespaces/storage.js +25 -25
- package/dist/operator-doctor-corpus.js +28 -28
- package/dist/operator-toolkit.js +39 -39
- package/dist/orchestration/backlog-scheduler.d.ts +3 -2
- package/dist/orchestration/backlog-scheduler.d.ts.map +1 -1
- package/dist/orchestration/backlog-scheduler.js +159 -157
- package/dist/orchestration/backlog-scheduler.js.map +1 -1
- package/dist/orchestration/buffer-drain-runner.d.ts +6 -1
- package/dist/orchestration/buffer-drain-runner.d.ts.map +1 -1
- package/dist/orchestration/buffer-drain-runner.js +149 -147
- package/dist/orchestration/extraction-persist.d.ts.map +1 -1
- package/dist/orchestration/fact-dedup-window.d.ts +1 -4
- package/dist/orchestration/fact-dedup-window.d.ts.map +1 -1
- package/dist/orchestration/maintenance.js +39 -39
- package/dist/orchestrator.js +148 -146
- package/dist/provenance.js +2 -2
- package/dist/recall-navigation-operations.js +68 -67
- package/dist/recall-navigation.js +67 -66
- package/dist/reconcile/manifest.js +2 -2
- package/dist/{resolution-BNWE5Y25.js → resolution-23ZBDM6A.js} +5 -5
- package/dist/resolution-23ZBDM6A.js.map +1 -0
- package/dist/resume-bundles.js +29 -29
- package/dist/salvage-envelope.js +4 -4
- package/dist/search/factory.js +5 -5
- package/dist/search/index.js +9 -9
- package/dist/semantic-consolidation.js +26 -26
- package/dist/semantic-rule-promotion.js +25 -25
- package/dist/semantic-rule-verifier.js +25 -25
- package/dist/source-agent-qualifier.js +31 -31
- package/dist/standup/build.js +25 -25
- package/dist/storage/buffer-drain-claims.d.ts +18 -6
- package/dist/storage/buffer-drain-claims.d.ts.map +1 -1
- package/dist/storage/buffer-drain-claims.js +2 -2
- package/dist/storage/buffer-session-files.js +2 -2
- package/dist/storage/content-hash-index.d.ts +8 -0
- package/dist/storage/content-hash-index.d.ts.map +1 -1
- package/dist/storage.d.ts +10 -1
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +24 -24
- package/dist/subject-config.js +3 -3
- package/dist/summarizer.js +3 -3
- package/dist/support-passport/index.js +70 -69
- package/dist/transfer/autodetect.js +1 -1
- package/dist/transfer/backup.js +2 -2
- package/dist/transfer/capsule-export.js +3 -3
- package/dist/transfer/capsule-gunzip.d.ts +14 -0
- package/dist/transfer/capsule-gunzip.d.ts.map +1 -0
- package/dist/transfer/capsule-import.d.ts.map +1 -1
- package/dist/transfer/capsule-import.js +3 -2
- package/dist/transfer/capsule-merge.d.ts.map +1 -1
- package/dist/transfer/export-okf.js +25 -25
- package/dist/verified-recall.js +25 -25
- package/dist/who-knows-cli.js +26 -26
- package/dist/who-knows.js +25 -25
- package/dist/write-envelope.js +3 -3
- package/package.json +2 -2
- package/src/access-mcp-correction-tools.test.ts +45 -0
- package/src/access-mcp-frames.test.ts +47 -0
- package/src/access-mcp-frames.ts +74 -0
- package/src/access-mcp.test.ts +146 -0
- package/src/access-mcp.ts +30 -30
- package/src/access-observe-write-surface.ts +4 -4
- package/src/backlog-scheduler.test.ts +443 -3
- package/src/buffer-persistence.ts +15 -6
- package/src/buffer-turn-helpers.ts +6 -0
- package/src/buffer.ts +6 -6
- package/src/cli.ts +4 -4
- package/src/compounding/weekly-evidence.test.ts +237 -0
- package/src/entity-mention-index-cache.ts +1 -6
- package/src/extraction-quote-grounding.test.ts +49 -0
- package/src/extraction-quote-grounding.ts +50 -12
- package/src/fact-dedup-window.test.ts +103 -20
- package/src/maintenance/rebuild-memory-projection-runner.test.ts +90 -0
- package/src/namespaces/search.test.ts +339 -0
- package/src/namespaces/search.ts +54 -1
- package/src/orchestration/backlog-scheduler.ts +13 -12
- package/src/orchestration/buffer-drain-runner.ts +40 -16
- package/src/orchestration/extraction-persist.ts +2 -10
- package/src/orchestration/fact-dedup-window.ts +5 -12
- package/src/orchestration/full-corpus-heap-guard.test.ts +52 -0
- package/src/projection-rebuild-config.test.ts +79 -0
- package/src/storage/buffer-drain-claims.test.ts +330 -6
- package/src/storage/buffer-drain-claims.ts +226 -80
- package/src/storage/buffer-session-files.ts +2 -2
- package/src/storage/content-hash-index.ts +9 -0
- package/src/storage/entity-store-symlink.test.ts +44 -0
- package/src/storage.ts +15 -0
- package/src/transfer/capsule-gunzip.ts +39 -0
- package/src/transfer/capsule-import.test.ts +73 -0
- package/src/transfer/capsule-import.ts +2 -2
- package/src/transfer/capsule-merge.test.ts +34 -0
- package/src/transfer/capsule-merge.ts +2 -10
- package/src/utils/malformed-entity-record.test.ts +69 -0
- package/dist/capsule-merge-XVTQJJ6R.js.map +0 -1
- package/dist/chunk-4KLQI3L2.js.map +0 -1
- package/dist/chunk-6LCWKS62.js.map +0 -1
- package/dist/chunk-7PMOCQOL.js.map +0 -1
- package/dist/chunk-AYTDCMEL.js.map +0 -1
- package/dist/chunk-B74NPUHT.js.map +0 -1
- package/dist/chunk-KQUSP6LB.js.map +0 -1
- package/dist/chunk-LU66I56Q.js.map +0 -1
- package/dist/chunk-MPDLLLOG.js.map +0 -1
- package/dist/chunk-S57QBPTA.js.map +0 -1
- package/dist/chunk-SVCHO337.js.map +0 -1
- package/dist/chunk-WAD32CZG.js.map +0 -1
- package/dist/chunk-XYP5WBDO.js.map +0 -1
- package/dist/chunk-YK7GOPIE.js.map +0 -1
- package/dist/chunk-Z3DDQXM4.js.map +0 -1
- /package/dist/{capsule-crypto-YO5QJ6L3.js.map → access-mcp-frames.js.map} +0 -0
- /package/dist/{auto-sync-C7E6G7Y2.js.map → auto-sync-3AZW7MXI.js.map} +0 -0
- /package/dist/{graph-edge-decay-CXTNJ7IQ.js.map → capsule-crypto-GWVG7LGC.js.map} +0 -0
- /package/dist/{resolution-BNWE5Y25.js.map → capsule-gunzip-KGBDGF7P.js.map} +0 -0
- /package/dist/{chunk-T6T2RMWW.js.map → chunk-23B4HLWG.js.map} +0 -0
- /package/dist/{chunk-LECSS7EE.js.map → chunk-2ASEDFOA.js.map} +0 -0
- /package/dist/{chunk-TPX7XXY4.js.map → chunk-2JAT4S7N.js.map} +0 -0
- /package/dist/{chunk-XRBHIR7Q.js.map → chunk-2URKYLMK.js.map} +0 -0
- /package/dist/{chunk-IN4OFAHX.js.map → chunk-2XYDL2FG.js.map} +0 -0
- /package/dist/{chunk-HQGATKG2.js.map → chunk-3KGCHTTK.js.map} +0 -0
- /package/dist/{chunk-YAUHSNPB.js.map → chunk-3LHPTBWG.js.map} +0 -0
- /package/dist/{chunk-XT45WCKX.js.map → chunk-3VU2FDTU.js.map} +0 -0
- /package/dist/{chunk-CIIHIAJ2.js.map → chunk-433EXTC4.js.map} +0 -0
- /package/dist/{chunk-QZSIDSB2.js.map → chunk-44FQCC5D.js.map} +0 -0
- /package/dist/{chunk-YUTT4ZTI.js.map → chunk-45VUHDV2.js.map} +0 -0
- /package/dist/{chunk-54FDG7K7.js.map → chunk-4DPLCYEK.js.map} +0 -0
- /package/dist/{chunk-KO3YBHOV.js.map → chunk-4IWEPQEV.js.map} +0 -0
- /package/dist/{chunk-H7BZBSP6.js.map → chunk-52II7PB6.js.map} +0 -0
- /package/dist/{chunk-K6RTQZA4.js.map → chunk-6DANGCMO.js.map} +0 -0
- /package/dist/{chunk-2IW5PT7U.js.map → chunk-6KFFRMPQ.js.map} +0 -0
- /package/dist/{chunk-MSIRVXQ3.js.map → chunk-73YVMZ7D.js.map} +0 -0
- /package/dist/{chunk-A7BM2JTH.js.map → chunk-AJHNXIQU.js.map} +0 -0
- /package/dist/{chunk-2D7BTSDW.js.map → chunk-ANZZLRUX.js.map} +0 -0
- /package/dist/{chunk-YOEYL6CH.js.map → chunk-AP3TSV6S.js.map} +0 -0
- /package/dist/{chunk-GQZSGXR6.js.map → chunk-BATPQNRG.js.map} +0 -0
- /package/dist/{chunk-D5SSBCYY.js.map → chunk-BLGQUZFB.js.map} +0 -0
- /package/dist/{chunk-BDN3TDGV.js.map → chunk-BLMTOIBK.js.map} +0 -0
- /package/dist/{chunk-R45L4TV6.js.map → chunk-BUKK5SWA.js.map} +0 -0
- /package/dist/{chunk-TFLPDNQV.js.map → chunk-CCU7URRP.js.map} +0 -0
- /package/dist/{chunk-2XJZLSXE.js.map → chunk-CMRHXPLQ.js.map} +0 -0
- /package/dist/{chunk-BK4FBHZ3.js.map → chunk-D6THW7PA.js.map} +0 -0
- /package/dist/{chunk-BFBS7OFQ.js.map → chunk-DC55RIEZ.js.map} +0 -0
- /package/dist/{chunk-VKDAJJQP.js.map → chunk-DI5ET2IE.js.map} +0 -0
- /package/dist/{chunk-QZBTIYKD.js.map → chunk-DM4RRTN7.js.map} +0 -0
- /package/dist/{chunk-EBOHFZI4.js.map → chunk-E5QEF3JO.js.map} +0 -0
- /package/dist/{chunk-DD6OIFDG.js.map → chunk-E7V5AK7I.js.map} +0 -0
- /package/dist/{chunk-BV2BRHD4.js.map → chunk-FHGWKODN.js.map} +0 -0
- /package/dist/{chunk-HPFVZPRH.js.map → chunk-FK4WC6VK.js.map} +0 -0
- /package/dist/{chunk-VLMBSGQF.js.map → chunk-FRM4UTDR.js.map} +0 -0
- /package/dist/{chunk-LTDLJCMQ.js.map → chunk-FZPDRCOB.js.map} +0 -0
- /package/dist/{chunk-ZJJFUEPO.js.map → chunk-GBOYOL5L.js.map} +0 -0
- /package/dist/{chunk-YUTG35M4.js.map → chunk-GJVGFKOU.js.map} +0 -0
- /package/dist/{chunk-K36RMINQ.js.map → chunk-GOZXQNIM.js.map} +0 -0
- /package/dist/{chunk-HWHNQVRV.js.map → chunk-GYNRNKMW.js.map} +0 -0
- /package/dist/{chunk-KFLD7ZZG.js.map → chunk-IUKYFTGW.js.map} +0 -0
- /package/dist/{chunk-BNQJKWWZ.js.map → chunk-K3FH3LAQ.js.map} +0 -0
- /package/dist/{chunk-FJ2VJTGA.js.map → chunk-KHZVAISH.js.map} +0 -0
- /package/dist/{chunk-WHQXWFH7.js.map → chunk-LT3CMO65.js.map} +0 -0
- /package/dist/{chunk-NUSAAN75.js.map → chunk-MHSBOEH7.js.map} +0 -0
- /package/dist/{chunk-KJCL2FZO.js.map → chunk-MNYQVYJ4.js.map} +0 -0
- /package/dist/{chunk-RZH5RVJC.js.map → chunk-MTTYIXSU.js.map} +0 -0
- /package/dist/{chunk-FVRTCYZ3.js.map → chunk-MVOJDLXS.js.map} +0 -0
- /package/dist/{chunk-KESJ5XX3.js.map → chunk-MYCCO6AA.js.map} +0 -0
- /package/dist/{chunk-66JOLMWS.js.map → chunk-MZCGHPIJ.js.map} +0 -0
- /package/dist/{chunk-B4ZU34JQ.js.map → chunk-N6II66E5.js.map} +0 -0
- /package/dist/{chunk-BK7AJUWB.js.map → chunk-NIV7RPWQ.js.map} +0 -0
- /package/dist/{chunk-TLHF75OR.js.map → chunk-O55AGDTI.js.map} +0 -0
- /package/dist/{chunk-GGJFRVRD.js.map → chunk-OMYRPMQC.js.map} +0 -0
- /package/dist/{chunk-XHGYZRVW.js.map → chunk-OSTFDWZJ.js.map} +0 -0
- /package/dist/{chunk-BXLOS5AJ.js.map → chunk-OWHERGF2.js.map} +0 -0
- /package/dist/{chunk-WC475JOG.js.map → chunk-P225W4RQ.js.map} +0 -0
- /package/dist/{chunk-TFA6HPOA.js.map → chunk-QCP75JGO.js.map} +0 -0
- /package/dist/{chunk-JRVMCZE3.js.map → chunk-QEYTRFR3.js.map} +0 -0
- /package/dist/{chunk-IZJQNDGI.js.map → chunk-R6HMAIKM.js.map} +0 -0
- /package/dist/{chunk-VUROWXFL.js.map → chunk-RNGDKFY2.js.map} +0 -0
- /package/dist/{chunk-FF6N7BXC.js.map → chunk-S45INSV3.js.map} +0 -0
- /package/dist/{chunk-2RUTN7PR.js.map → chunk-S7GJNA3K.js.map} +0 -0
- /package/dist/{chunk-RJWL3RHB.js.map → chunk-TFEHSPGQ.js.map} +0 -0
- /package/dist/{chunk-T77AX6DG.js.map → chunk-TQVECGUQ.js.map} +0 -0
- /package/dist/{chunk-OQSSQOKQ.js.map → chunk-TV65NR7L.js.map} +0 -0
- /package/dist/{chunk-HQPFACXO.js.map → chunk-UH3FPX3L.js.map} +0 -0
- /package/dist/{chunk-4EACCIPO.js.map → chunk-UHPHH74F.js.map} +0 -0
- /package/dist/{chunk-DQEMWVMT.js.map → chunk-UVYI6VIX.js.map} +0 -0
- /package/dist/{chunk-6QYPL6NI.js.map → chunk-V45TEVDA.js.map} +0 -0
- /package/dist/{chunk-GCAQ3VUJ.js.map → chunk-VCVEMQJK.js.map} +0 -0
- /package/dist/{chunk-6L63IN3M.js.map → chunk-VEFGHRKV.js.map} +0 -0
- /package/dist/{chunk-E33UJHY3.js.map → chunk-WFDWLWDK.js.map} +0 -0
- /package/dist/{chunk-KQLBXUUQ.js.map → chunk-WYG5UNDY.js.map} +0 -0
- /package/dist/{chunk-MPGLM2VU.js.map → chunk-X7REO4CH.js.map} +0 -0
- /package/dist/{chunk-FZVROZKC.js.map → chunk-XVZA6VXC.js.map} +0 -0
- /package/dist/{chunk-WV254W4V.js.map → chunk-Y3IYKNBY.js.map} +0 -0
- /package/dist/{chunk-FUOAIJKQ.js.map → chunk-Y43X3E24.js.map} +0 -0
- /package/dist/{chunk-3T3VHXUH.js.map → chunk-YAAKVTZA.js.map} +0 -0
- /package/dist/{chunk-VPEIWMUT.js.map → chunk-YLTU2DC4.js.map} +0 -0
- /package/dist/{chunk-65SKM4BF.js.map → chunk-YNBMBL4C.js.map} +0 -0
- /package/dist/{chunk-PJYK7HH2.js.map → chunk-ZWTHVUT5.js.map} +0 -0
- /package/dist/{first-start-migration-QVD22WWS.js.map → first-start-migration-A6PHIBUQ.js.map} +0 -0
package/src/access-mcp.test.ts
CHANGED
|
@@ -10,12 +10,16 @@ import assert from "node:assert/strict";
|
|
|
10
10
|
import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
11
11
|
import os from "node:os";
|
|
12
12
|
import path from "node:path";
|
|
13
|
+
import { PassThrough } from "node:stream";
|
|
13
14
|
import test from "node:test";
|
|
14
15
|
|
|
15
16
|
import { EngramMcpServer } from "./access-mcp.js";
|
|
17
|
+
import { MCP_STDIO_MAX_FRAME_BYTES } from "./access-mcp-frames.js";
|
|
18
|
+
import { EngramAccessForbiddenError } from "./access-errors.js";
|
|
16
19
|
import { tokenCapabilityStore } from "./access-token-capabilities.js";
|
|
17
20
|
import { EngramAccessInputError, type EngramAccessService } from "./access-service.js";
|
|
18
21
|
import { parseConfig } from "./config.js";
|
|
22
|
+
import { initLogger, resetLogger } from "./logger.js";
|
|
19
23
|
import { readPair, writePair } from "./contradiction/contradiction-review.js";
|
|
20
24
|
import type { StorageManager } from "./storage.js";
|
|
21
25
|
|
|
@@ -1451,3 +1455,145 @@ test("MCP external_wiki_search rejects an empty query before service dispatch",
|
|
|
1451
1455
|
assert.equal(readMcpResult(response).isError, true);
|
|
1452
1456
|
assert.equal(configRead, false);
|
|
1453
1457
|
});
|
|
1458
|
+
|
|
1459
|
+
// ===========================================================================
|
|
1460
|
+
// Issue #3225 C5 — tools/call catch-all must not leak unexpected Error.message
|
|
1461
|
+
// (paths from fs/backend). Intended typed access errors stay readable.
|
|
1462
|
+
// ===========================================================================
|
|
1463
|
+
|
|
1464
|
+
function serviceWithRecallThrow(error: Error): EngramAccessService {
|
|
1465
|
+
const service = makeMockService();
|
|
1466
|
+
service.recall = async () => {
|
|
1467
|
+
throw error;
|
|
1468
|
+
};
|
|
1469
|
+
return service;
|
|
1470
|
+
}
|
|
1471
|
+
|
|
1472
|
+
test("MCP tools/call hides unexpected Error.message paths behind internal error", async () => {
|
|
1473
|
+
const secretPath = "/home/secret/vault/token.pem";
|
|
1474
|
+
const service = serviceWithRecallThrow(
|
|
1475
|
+
new Error(`ENOENT: no such file or directory, open '${secretPath}'`),
|
|
1476
|
+
);
|
|
1477
|
+
|
|
1478
|
+
const logLines: string[] = [];
|
|
1479
|
+
initLogger(
|
|
1480
|
+
{
|
|
1481
|
+
info() {},
|
|
1482
|
+
warn() {},
|
|
1483
|
+
error(msg: string) {
|
|
1484
|
+
logLines.push(msg);
|
|
1485
|
+
},
|
|
1486
|
+
},
|
|
1487
|
+
false,
|
|
1488
|
+
{ timestamps: false },
|
|
1489
|
+
);
|
|
1490
|
+
try {
|
|
1491
|
+
const server = new EngramMcpServer(service);
|
|
1492
|
+
const outcome = readCallToolOutcome(
|
|
1493
|
+
await server.handleRequest(makeToolRequest("engram.recall", { query: "anything" })),
|
|
1494
|
+
);
|
|
1495
|
+
assert.equal(outcome.isError, true);
|
|
1496
|
+
assert.equal(outcome.text, "internal error");
|
|
1497
|
+
assert.equal(outcome.text.includes(secretPath), false);
|
|
1498
|
+
assert.ok(
|
|
1499
|
+
logLines.some((line) => line.includes(secretPath)),
|
|
1500
|
+
"server log must retain the unexpected detail",
|
|
1501
|
+
);
|
|
1502
|
+
} finally {
|
|
1503
|
+
resetLogger();
|
|
1504
|
+
}
|
|
1505
|
+
});
|
|
1506
|
+
|
|
1507
|
+
test("MCP tools/call keeps intended EngramAccessInputError and ForbiddenError messages", async () => {
|
|
1508
|
+
const inputOutcome = readCallToolOutcome(
|
|
1509
|
+
await new EngramMcpServer(serviceWithRecallThrow(new EngramAccessInputError("memory not found: mem-42"))).handleRequest(
|
|
1510
|
+
makeToolRequest("engram.recall", { query: "anything" }),
|
|
1511
|
+
),
|
|
1512
|
+
);
|
|
1513
|
+
assert.equal(inputOutcome.isError, true);
|
|
1514
|
+
assert.equal(inputOutcome.text, "memory not found: mem-42");
|
|
1515
|
+
|
|
1516
|
+
const forbiddenOutcome = readCallToolOutcome(
|
|
1517
|
+
await new EngramMcpServer(
|
|
1518
|
+
serviceWithRecallThrow(new EngramAccessForbiddenError("token is not permitted to call operation: recall")),
|
|
1519
|
+
).handleRequest(makeToolRequest("engram.recall", { query: "anything" })),
|
|
1520
|
+
);
|
|
1521
|
+
assert.equal(forbiddenOutcome.isError, true);
|
|
1522
|
+
assert.equal(forbiddenOutcome.text, "token is not permitted to call operation: recall");
|
|
1523
|
+
});
|
|
1524
|
+
|
|
1525
|
+
// ===========================================================================
|
|
1526
|
+
// Issue #3225 N1 — stdio framing is bounded, refuses an oversized frame,
|
|
1527
|
+
// and keeps answering the frames that follow it.
|
|
1528
|
+
// ===========================================================================
|
|
1529
|
+
|
|
1530
|
+
type StdioMessage = { id?: number | null; result?: object; error?: { message: string } };
|
|
1531
|
+
type StdioRequest = { jsonrpc: "2.0"; id: number; method: string };
|
|
1532
|
+
|
|
1533
|
+
function stdioFrame(payload: StdioRequest): string {
|
|
1534
|
+
const body = JSON.stringify(payload);
|
|
1535
|
+
return `Content-Length: ${Buffer.byteLength(body, "utf-8")}\r\n\r\n${body}`;
|
|
1536
|
+
}
|
|
1537
|
+
|
|
1538
|
+
function readStdioMessages(raw: string): StdioMessage[] {
|
|
1539
|
+
const messages: StdioMessage[] = [];
|
|
1540
|
+
let rest = raw;
|
|
1541
|
+
while (rest.length > 0) {
|
|
1542
|
+
const headerEnd = rest.indexOf("\r\n\r\n");
|
|
1543
|
+
assert.ok(headerEnd >= 0, "server output must be Content-Length framed");
|
|
1544
|
+
const length = Number.parseInt(rest.slice(0, headerEnd).split(":")[1] ?? "", 10);
|
|
1545
|
+
const message: StdioMessage = JSON.parse(rest.slice(headerEnd + 4, headerEnd + 4 + length));
|
|
1546
|
+
messages.push(message);
|
|
1547
|
+
rest = rest.slice(headerEnd + 4 + length);
|
|
1548
|
+
}
|
|
1549
|
+
return messages;
|
|
1550
|
+
}
|
|
1551
|
+
|
|
1552
|
+
/** Feeds each chunk in its own tick so the server sees separate data events. */
|
|
1553
|
+
async function runStdioChunks(chunks: string[]): Promise<StdioMessage[]> {
|
|
1554
|
+
const input = new PassThrough();
|
|
1555
|
+
const output = new PassThrough();
|
|
1556
|
+
output.setEncoding("utf8");
|
|
1557
|
+
let raw = "";
|
|
1558
|
+
output.on("data", (chunk: string) => {
|
|
1559
|
+
raw += chunk;
|
|
1560
|
+
});
|
|
1561
|
+
const running = new EngramMcpServer(makeMockService()).runStdio(input, output);
|
|
1562
|
+
for (const chunk of chunks) {
|
|
1563
|
+
input.write(chunk);
|
|
1564
|
+
await new Promise<void>((resolve) => setImmediate(resolve));
|
|
1565
|
+
}
|
|
1566
|
+
input.end();
|
|
1567
|
+
await running;
|
|
1568
|
+
return readStdioMessages(raw);
|
|
1569
|
+
}
|
|
1570
|
+
|
|
1571
|
+
const stdioPing = (id: number) => stdioFrame({ jsonrpc: "2.0", id, method: "ping" });
|
|
1572
|
+
|
|
1573
|
+
test("MCP stdio refuses an oversized Content-Length, discards its body, and answers the next frame", async () => {
|
|
1574
|
+
const declared = MCP_STDIO_MAX_FRAME_BYTES + 1;
|
|
1575
|
+
const messages = await runStdioChunks([
|
|
1576
|
+
`Content-Length: ${declared}\r\n\r\n`,
|
|
1577
|
+
"x".repeat(1000),
|
|
1578
|
+
"x".repeat(declared - 1000),
|
|
1579
|
+
stdioPing(7),
|
|
1580
|
+
]);
|
|
1581
|
+
assert.equal(messages.length, 2);
|
|
1582
|
+
assert.match(messages[0]?.error?.message ?? "", /frame too large/);
|
|
1583
|
+
assert.equal(messages[1]?.id, 7);
|
|
1584
|
+
assert.ok(messages[1]?.result, "the frame after the refused one is answered normally");
|
|
1585
|
+
});
|
|
1586
|
+
|
|
1587
|
+
test("MCP stdio refuses a header that never terminates and answers the next frame", async () => {
|
|
1588
|
+
const messages = await runStdioChunks(["A".repeat(MCP_STDIO_MAX_FRAME_BYTES + 1), stdioPing(8)]);
|
|
1589
|
+
assert.equal(messages.length, 2);
|
|
1590
|
+
assert.match(messages[0]?.error?.message ?? "", /frame too large/);
|
|
1591
|
+
assert.equal(messages[1]?.id, 8);
|
|
1592
|
+
});
|
|
1593
|
+
|
|
1594
|
+
test("MCP stdio reassembles a frame split inside its header and inside its body", async () => {
|
|
1595
|
+
const frame = stdioPing(9);
|
|
1596
|
+
const messages = await runStdioChunks([frame.slice(0, 6), frame.slice(6, frame.length - 4), frame.slice(frame.length - 4)]);
|
|
1597
|
+
assert.equal(messages.length, 1);
|
|
1598
|
+
assert.equal(messages[0]?.id, 9);
|
|
1599
|
+
});
|
package/src/access-mcp.ts
CHANGED
|
@@ -30,7 +30,9 @@ import {
|
|
|
30
30
|
validateRequest,
|
|
31
31
|
} from "./access-schema.js";
|
|
32
32
|
import { EngramAccessInputError, type EngramAccessRecallResponse, type EngramAccessService } from "./access-service.js";
|
|
33
|
-
import { unknownToolError } from "./access-errors.js";
|
|
33
|
+
import { EngramAccessForbiddenError, unknownToolError } from "./access-errors.js";
|
|
34
|
+
import { log } from "./logger.js";
|
|
35
|
+
import { McpFrameReader } from "./access-mcp-frames.js";
|
|
34
36
|
import "./access-operations.js";
|
|
35
37
|
import { validateBriefingFormat } from "./briefing.js";
|
|
36
38
|
import { processChatMessage } from "./chat/chat-factory.js";
|
|
@@ -88,6 +90,19 @@ function throwMcpAbort(signal: AbortSignal | undefined, message: string): void {
|
|
|
88
90
|
throw abortError(message);
|
|
89
91
|
}
|
|
90
92
|
|
|
93
|
+
/**
|
|
94
|
+
* Map tools/call failures to a client-safe message. Unexpected backend/fs
|
|
95
|
+
* errors become a stable generic string; detail stays in the server log.
|
|
96
|
+
* Intended EngramAccessInputError / EngramAccessForbiddenError stay readable.
|
|
97
|
+
*/
|
|
98
|
+
function mcpToolErrorMessage(err: Error): string {
|
|
99
|
+
if (err instanceof EngramAccessInputError || err instanceof EngramAccessForbiddenError) {
|
|
100
|
+
return err.message;
|
|
101
|
+
}
|
|
102
|
+
log.error("engram MCP tools/call internal error", err);
|
|
103
|
+
return "internal error";
|
|
104
|
+
}
|
|
105
|
+
|
|
91
106
|
type McpRequestOptions = {
|
|
92
107
|
principalOverride?: string;
|
|
93
108
|
namespaceOverride?: string;
|
|
@@ -406,7 +421,7 @@ function parseMcpRequest<N extends SchemaName>(schemaName: N, args: Record<strin
|
|
|
406
421
|
function optionalNonEmptyString(value: unknown, label: string): string | undefined {
|
|
407
422
|
if (value === undefined || value === null || value === "") return undefined;
|
|
408
423
|
if (typeof value !== "string") {
|
|
409
|
-
throw new
|
|
424
|
+
throw new EngramAccessInputError(`${label} expects a string; got ${JSON.stringify(value)}`);
|
|
410
425
|
}
|
|
411
426
|
return value;
|
|
412
427
|
}
|
|
@@ -420,11 +435,11 @@ function optionalNonEmptyString(value: unknown, label: string): string | undefin
|
|
|
420
435
|
function optionalPositiveInteger(value: unknown, label: string): number | undefined {
|
|
421
436
|
if (value === undefined || value === null || value === "") return undefined;
|
|
422
437
|
if (typeof value !== "number" && typeof value !== "string") {
|
|
423
|
-
throw new
|
|
438
|
+
throw new EngramAccessInputError(`${label} expects a positive integer; got ${JSON.stringify(value)}`);
|
|
424
439
|
}
|
|
425
440
|
const parsed = typeof value === "number" ? value : Number(value);
|
|
426
441
|
if (!Number.isFinite(parsed) || parsed <= 0 || !Number.isInteger(parsed)) {
|
|
427
|
-
throw new
|
|
442
|
+
throw new EngramAccessInputError(`${label} expects a positive integer; got ${JSON.stringify(value)}`);
|
|
428
443
|
}
|
|
429
444
|
return parsed;
|
|
430
445
|
}
|
|
@@ -447,7 +462,7 @@ async function getMcpServerVersion(): Promise<string> {
|
|
|
447
462
|
}
|
|
448
463
|
|
|
449
464
|
export class EngramMcpServer {
|
|
450
|
-
private
|
|
465
|
+
private readonly frames = new McpFrameReader();
|
|
451
466
|
private flushTask: Promise<void> | null = null;
|
|
452
467
|
private readonly tools: McpTool[];
|
|
453
468
|
private readonly resources: McpResource[];
|
|
@@ -2402,7 +2417,7 @@ export class EngramMcpServer {
|
|
|
2402
2417
|
// Cancellation is transport control flow, not a JSON-RPC tool error.
|
|
2403
2418
|
// Preserve the original AbortError so HTTP can silently end a dead socket.
|
|
2404
2419
|
if (isAbortError(err)) throw err;
|
|
2405
|
-
const message = err instanceof Error ? err
|
|
2420
|
+
const message = mcpToolErrorMessage(err instanceof Error ? err : new Error(String(err)));
|
|
2406
2421
|
return {
|
|
2407
2422
|
jsonrpc: "2.0",
|
|
2408
2423
|
id,
|
|
@@ -2426,7 +2441,7 @@ export class EngramMcpServer {
|
|
|
2426
2441
|
|
|
2427
2442
|
async runStdio(input: Readable, output: Writable): Promise<void> {
|
|
2428
2443
|
input.on("data", (chunk) => {
|
|
2429
|
-
this.
|
|
2444
|
+
this.frames.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
2430
2445
|
this.scheduleFlush(output);
|
|
2431
2446
|
});
|
|
2432
2447
|
await new Promise<void>((resolve, reject) => {
|
|
@@ -2455,7 +2470,7 @@ export class EngramMcpServer {
|
|
|
2455
2470
|
if (this.flushTask === task) {
|
|
2456
2471
|
this.flushTask = null;
|
|
2457
2472
|
}
|
|
2458
|
-
if (this.
|
|
2473
|
+
if (this.frames.hasUnread()) {
|
|
2459
2474
|
this.scheduleFlush(output);
|
|
2460
2475
|
}
|
|
2461
2476
|
});
|
|
@@ -2463,30 +2478,15 @@ export class EngramMcpServer {
|
|
|
2463
2478
|
}
|
|
2464
2479
|
|
|
2465
2480
|
private async flushBuffer(output: Writable): Promise<void> {
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
const headers = headerText.split("\r\n");
|
|
2471
|
-
const contentLengthHeader = headers.find((line) => line.toLowerCase().startsWith("content-length:"));
|
|
2472
|
-
if (!contentLengthHeader) {
|
|
2473
|
-
this.buffer = Buffer.alloc(0);
|
|
2474
|
-
return;
|
|
2475
|
-
}
|
|
2476
|
-
const contentLength = Number.parseInt(contentLengthHeader.split(":")[1]?.trim() ?? "0", 10);
|
|
2477
|
-
if (!Number.isFinite(contentLength) || contentLength < 0) {
|
|
2478
|
-
this.buffer = Buffer.alloc(0);
|
|
2479
|
-
return;
|
|
2481
|
+
for (let frame = this.frames.next(); frame; frame = this.frames.next()) {
|
|
2482
|
+
if (frame.kind === "too-large") {
|
|
2483
|
+
this.writeMessage(output, { jsonrpc: "2.0", id: null, error: { code: -32600, message: "frame too large" } });
|
|
2484
|
+
continue;
|
|
2480
2485
|
}
|
|
2481
|
-
const messageStart = headerEnd + 4;
|
|
2482
|
-
const messageEnd = messageStart + contentLength;
|
|
2483
|
-
if (this.buffer.length < messageEnd) return;
|
|
2484
|
-
const body = this.buffer.slice(messageStart, messageEnd).toString("utf-8");
|
|
2485
|
-
this.buffer = this.buffer.slice(messageEnd);
|
|
2486
|
-
|
|
2487
2486
|
let parsed: JsonRpcRequest;
|
|
2488
2487
|
try {
|
|
2489
|
-
|
|
2488
|
+
// SAFETY: handleRequest defaults missing fields; a non-object body throws and scheduleFlush answers -32700.
|
|
2489
|
+
parsed = JSON.parse(frame.text) as JsonRpcRequest;
|
|
2490
2490
|
} catch {
|
|
2491
2491
|
this.writeMessage(output, {
|
|
2492
2492
|
jsonrpc: "2.0",
|
|
@@ -2620,7 +2620,7 @@ export class EngramMcpServer {
|
|
|
2620
2620
|
caps?.ops === undefined || capabilityAllowsOp(caps, MCP_MIGRATED_OPERATIONS[toLegacyToolName(t.name)] ?? "")
|
|
2621
2621
|
)
|
|
2622
2622
|
.map((t) => t.name);
|
|
2623
|
-
throw new
|
|
2623
|
+
throw new EngramAccessInputError(unknownToolError(name, visible));
|
|
2624
2624
|
}
|
|
2625
2625
|
const op = getOperation(migrated);
|
|
2626
2626
|
if (!op) {
|
|
@@ -51,6 +51,7 @@ import {
|
|
|
51
51
|
queueExplicitCaptureForReview,
|
|
52
52
|
} from "./explicit-capture.js";
|
|
53
53
|
import { log } from "./logger.js";
|
|
54
|
+
import { embeddingBacklogExceeds, isSearchHealthDegraded } from "./namespaces/search.js";
|
|
54
55
|
import { recordObjectiveStateSnapshotsFromObservedMessages } from "./objective-state-writers.js";
|
|
55
56
|
import type { Orchestrator } from "./orchestrator.js";
|
|
56
57
|
import { displayErrorDetail } from "./runtime/better-sqlite.js";
|
|
@@ -289,7 +290,7 @@ export class AccessObserveWriteSurface {
|
|
|
289
290
|
/* status probe failed — non-fatal */
|
|
290
291
|
}
|
|
291
292
|
}
|
|
292
|
-
if (
|
|
293
|
+
if (embeddingBacklogExceeds(pendingEmbeddings, threshold)) {
|
|
293
294
|
degraded = true;
|
|
294
295
|
degradedReason = `embedding-backlog: ${pendingEmbeddings} pending > threshold ${threshold}`;
|
|
295
296
|
}
|
|
@@ -355,14 +356,13 @@ export class AccessObserveWriteSurface {
|
|
|
355
356
|
const pending = health.pendingEmbeddings ?? null;
|
|
356
357
|
const oldest = health.oldestPendingAgeMs ?? null;
|
|
357
358
|
const threshold = this.deps.orchestrator.config.qmdEmbeddingBacklogThreshold;
|
|
358
|
-
const backlogDegraded =
|
|
359
|
-
const degraded = !active || health.collectionState === "unknown" || backlogDegraded;
|
|
359
|
+
const backlogDegraded = embeddingBacklogExceeds(pending, threshold);
|
|
360
360
|
const mode = !active ? "fallback" : health.daemonMode === true ? "daemon" : "cli";
|
|
361
361
|
|
|
362
362
|
return {
|
|
363
363
|
enabled: true,
|
|
364
364
|
active,
|
|
365
|
-
degraded,
|
|
365
|
+
degraded: isSearchHealthDegraded({ ...health, pendingEmbeddings: pending }, threshold),
|
|
366
366
|
mode,
|
|
367
367
|
collection: health.collection || fallbackCollection,
|
|
368
368
|
collectionState: health.collectionState,
|