@remnic/core 9.65.8 → 9.66.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access-admin-ops-surface.d.ts +11 -12
- package/dist/access-admin-ops-surface.js +54 -51
- package/dist/access-authorization-probe.d.ts +11 -12
- package/dist/access-authorization-probe.js +55 -52
- package/dist/access-boundary.d.ts +11 -12
- package/dist/access-boundary.js +54 -51
- package/dist/access-citation-namespace.js +3 -3
- package/dist/access-cli.js +132 -125
- package/dist/access-cli.js.map +1 -1
- package/dist/access-coding-context-resolution.d.ts +1 -2
- package/dist/access-coding-context-resolution.js +2 -2
- package/dist/access-extraction-force-flush.d.ts +11 -12
- package/dist/access-extraction-force-flush.js +54 -51
- package/dist/access-health-types.d.ts +1 -2
- package/dist/access-http-lcm-compaction.d.ts +11 -12
- package/dist/access-http-lifecycle-flush.d.ts +11 -12
- package/dist/access-http-offline-stream.d.ts +11 -12
- package/dist/access-http-query.d.ts +2 -3
- package/dist/access-http-query.js +56 -53
- package/dist/access-http.d.ts +12 -13
- package/dist/access-http.js +77 -74
- package/dist/access-identity-continuity-surface.d.ts +9 -10
- package/dist/access-identity-continuity-surface.js +54 -51
- package/dist/access-lcm-surface.d.ts +11 -12
- package/dist/access-lcm-surface.js +54 -51
- package/dist/access-mcp-output-schemas.js +1 -1
- package/dist/access-mcp.d.ts +11 -12
- package/dist/access-mcp.js +67 -64
- package/dist/access-memory-search-fanout.d.ts +2 -3
- package/dist/{access-namespace-preflight-CpAOrS-9.d.ts → access-namespace-preflight-50VIkPhB.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +3 -4
- package/dist/access-namespace-preflight.js +54 -51
- package/dist/access-observe-write-surface.d.ts +11 -12
- package/dist/access-observe-write-surface.js +54 -51
- package/dist/access-offline-manifest.d.ts +9 -10
- package/dist/access-offline-manifest.js +15 -15
- package/dist/access-operations-batch.js +59 -56
- package/dist/access-operations.d.ts +12 -13
- package/dist/access-operations.js +64 -61
- package/dist/access-recall-concurrency.d.ts +11 -12
- package/dist/access-recall-concurrency.js +54 -51
- package/dist/access-recall-response.d.ts +11 -12
- package/dist/access-recall-response.js +54 -51
- package/dist/access-recall-surface.d.ts +11 -12
- package/dist/access-recall-surface.js +54 -51
- package/dist/access-schema.d.ts +12 -12
- package/dist/access-schema.js +5 -5
- package/dist/{access-service-Diu61Cfv.d.ts → access-service-C2tV2-uL.d.ts} +8 -8
- package/dist/access-service-helpers.d.ts +11 -12
- package/dist/access-service.d.ts +11 -12
- package/dist/access-service.js +54 -51
- package/dist/access-surface-catalog.d.ts +11 -12
- package/dist/access-surface-catalog.js +58 -53
- package/dist/access-surface-catalog.js.map +1 -1
- package/dist/access-wearables-meetings-surface.d.ts +3 -4
- package/dist/action-confidence.d.ts +1 -2
- package/dist/active-memory-bridge.d.ts +1 -2
- package/dist/active-memory-bridge.js +2 -2
- package/dist/active-recall.d.ts +1 -2
- package/dist/active-recall.js +11 -11
- package/dist/adapters/index.js +7 -7
- package/dist/adapters/registry.js +3 -3
- package/dist/ambient-provenance.d.ts +1 -2
- package/dist/artifact-search.d.ts +1 -2
- package/dist/{auto-sync-2YPITIWN.js → auto-sync-Q6Q2FVSC.js} +9 -9
- package/dist/behavior-learner.d.ts +1 -2
- package/dist/behavior-signals.d.ts +1 -2
- package/dist/bootstrap.d.ts +9 -10
- package/dist/briefing-window.d.ts +2 -3
- package/dist/briefing.d.ts +2 -3
- package/dist/briefing.js +28 -28
- package/dist/buffer-surprise-report.d.ts +1 -2
- package/dist/buffer-turn-helpers.d.ts +1 -2
- package/dist/buffer.d.ts +2 -3
- package/dist/buffer.js +20 -4
- package/dist/bulk-import/index.d.ts +3 -4
- package/dist/calibration.d.ts +1 -2
- package/dist/calibration.js +1 -1
- package/dist/capabilities.d.ts +1 -2
- package/dist/{capsule-merge-SGIVB3WA.js → capsule-merge-SEHERWWP.js} +4 -4
- package/dist/{catalog-9f-vEQLS.d.ts → catalog-C2jA-gLm.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +1 -2
- package/dist/causal-consolidation.d.ts +1 -2
- package/dist/causal-consolidation.js +29 -29
- package/dist/causal-trajectory-graph.d.ts +1 -2
- package/dist/{chunk-LEPOP46W.js → chunk-227UFSEQ.js} +4 -4
- package/dist/{chunk-TFR3HG4K.js → chunk-2FA7U5XY.js} +4 -4
- package/dist/{chunk-PO7NXBG2.js → chunk-2GF27PGH.js} +5 -5
- package/dist/{chunk-W2BAGGEW.js → chunk-2ITZ74A6.js} +40 -31
- package/dist/{chunk-W2BAGGEW.js.map → chunk-2ITZ74A6.js.map} +1 -1
- package/dist/{chunk-MY2BC6UE.js → chunk-2X6BGKQL.js} +11 -11
- package/dist/{chunk-UEBDCMOO.js → chunk-3TSU662L.js} +3 -3
- package/dist/{chunk-XAB6STPO.js → chunk-46XR5FNZ.js} +53 -3
- package/dist/chunk-46XR5FNZ.js.map +1 -0
- package/dist/{chunk-FP7YTTVO.js → chunk-4OFKZAJG.js} +2 -1
- package/dist/chunk-4OFKZAJG.js.map +1 -0
- package/dist/{chunk-S5XOSTYM.js → chunk-4XLTUR6R.js} +3 -3
- package/dist/{chunk-BWGCOLEL.js → chunk-65JOGLIS.js} +2 -2
- package/dist/{chunk-HMZKGHMD.js → chunk-7UOXCCCI.js} +3 -3
- package/dist/{chunk-7WOWGRAU.js → chunk-AF5H7TKI.js} +108 -23
- package/dist/chunk-AF5H7TKI.js.map +1 -0
- package/dist/{chunk-7BDZTALN.js → chunk-AJTG3CP7.js} +12 -2
- package/dist/chunk-AJTG3CP7.js.map +1 -0
- package/dist/{chunk-2LWQSV6A.js → chunk-AL3UYZ5N.js} +3 -2
- package/dist/chunk-AL3UYZ5N.js.map +1 -0
- package/dist/{chunk-4F4AQFWL.js → chunk-B4AOWRYF.js} +10 -10
- package/dist/{chunk-ODU2CNNX.js → chunk-C5IUOBCN.js} +2 -2
- package/dist/{chunk-3A2NJP2U.js → chunk-CHGG74CY.js} +3 -3
- package/dist/{chunk-76DIF5KT.js → chunk-CX4OLNIH.js} +2 -2
- package/dist/{chunk-Z3YEGSR4.js → chunk-D3UXGE5D.js} +10 -10
- package/dist/{chunk-5HK3CJAR.js → chunk-D6Q5EPOV.js} +2 -2
- package/dist/{chunk-EGBDFJ36.js → chunk-DD5JFCWM.js} +2 -2
- package/dist/{chunk-XBGHAAKR.js → chunk-DDX6KIXF.js} +2 -2
- package/dist/{chunk-JIYDRBVZ.js → chunk-DJORULH3.js} +2 -2
- package/dist/{chunk-7KQB4EBS.js → chunk-DUAJKRR2.js} +2 -2
- package/dist/{chunk-XDL5CYZN.js → chunk-EEOUMG3J.js} +2 -1
- package/dist/{chunk-XDL5CYZN.js.map → chunk-EEOUMG3J.js.map} +1 -1
- package/dist/{chunk-Q57GOHLF.js → chunk-EGALNSZ4.js} +3 -3
- package/dist/{chunk-DPCXDG7G.js → chunk-EH65UV2Z.js} +2 -2
- package/dist/{chunk-KCT36JAW.js → chunk-ESNFSSO4.js} +2 -2
- package/dist/{chunk-XQ3HXAQH.js → chunk-ET2CNMLD.js} +4 -4
- package/dist/{chunk-TUHBYJXL.js → chunk-EWKVYCFP.js} +1 -1
- package/dist/{chunk-NPFUNWNX.js → chunk-FFUMTH27.js} +2 -2
- package/dist/{chunk-3PKAS6VL.js → chunk-GAJK3DQ5.js} +2 -2
- package/dist/{chunk-DA7ITC5Z.js → chunk-GBEOUCBB.js} +2 -2
- package/dist/{chunk-UENKPWCS.js → chunk-H2IRSXZN.js} +6 -6
- package/dist/{chunk-CFVTRUR3.js → chunk-H6RSANGQ.js} +2 -2
- package/dist/chunk-HVAEXYPL.js +98 -0
- package/dist/chunk-HVAEXYPL.js.map +1 -0
- package/dist/{chunk-EUYWQ7TS.js → chunk-IEZ6CGTW.js} +2 -2
- package/dist/{chunk-3SZD4CYO.js → chunk-IGZCAHFL.js} +3 -3
- package/dist/{chunk-UPFNQJC7.js → chunk-INUBU6I5.js} +2 -2
- package/dist/{chunk-PMVPCZJZ.js → chunk-J2R275FN.js} +3 -3
- package/dist/{chunk-UW5NPZJ2.js → chunk-JALOAKSZ.js} +59 -7
- package/dist/chunk-JALOAKSZ.js.map +1 -0
- package/dist/{chunk-2QSZNTDO.js → chunk-JBPKEARU.js} +7 -7
- package/dist/{chunk-3BCULS4U.js → chunk-JKTV3JNX.js} +145 -507
- package/dist/chunk-JKTV3JNX.js.map +1 -0
- package/dist/{chunk-5ACCD4L7.js → chunk-JRRQ747T.js} +7 -7
- package/dist/{chunk-V4IDF3EZ.js → chunk-JTWZKNUH.js} +5 -5
- package/dist/{chunk-AZMLH5UT.js → chunk-KI64TTBL.js} +2 -2
- package/dist/{chunk-DEACDKE3.js → chunk-KJXCD7VR.js} +112 -87
- package/dist/chunk-KJXCD7VR.js.map +1 -0
- package/dist/chunk-LJABGXC4.js +267 -0
- package/dist/chunk-LJABGXC4.js.map +1 -0
- package/dist/{chunk-NPIBN2VL.js → chunk-LK4TOYPU.js} +2 -2
- package/dist/{chunk-UTQUEHC7.js → chunk-LUDBXTBJ.js} +8 -8
- package/dist/{chunk-PU56CXZA.js → chunk-LYUUA6QB.js} +2 -2
- package/dist/{chunk-P36Z4JRA.js → chunk-M5ERTI4I.js} +2 -2
- package/dist/{chunk-LDKPDODJ.js → chunk-ME35HVDJ.js} +2 -2
- package/dist/{chunk-773TRRGT.js → chunk-MJUCDM3C.js} +2 -2
- package/dist/{chunk-OXRRJXPR.js → chunk-MUEGIKKY.js} +476 -1796
- package/dist/chunk-MUEGIKKY.js.map +1 -0
- package/dist/{chunk-AHPIFKNG.js → chunk-N4F7ZSSG.js} +2 -2
- package/dist/{chunk-JOZUBF4A.js → chunk-NACLNNFQ.js} +2 -2
- package/dist/{chunk-LC2BDILZ.js → chunk-NBP4EX5N.js} +2 -2
- package/dist/{chunk-T7XP6IZE.js → chunk-NFP4KPTA.js} +2 -2
- package/dist/{chunk-ZVPVTPGI.js → chunk-NNZFPYYX.js} +4 -4
- package/dist/{chunk-LPNCR4QK.js → chunk-NSTNGMSS.js} +14 -14
- package/dist/{chunk-5RWZH6PH.js → chunk-NUF7VSEX.js} +2 -2
- package/dist/{chunk-7VZFRUQU.js → chunk-O7ERGZDA.js} +5 -5
- package/dist/{chunk-HSZMX3ZJ.js → chunk-ODW5GDFE.js} +2 -2
- package/dist/{chunk-5DHKCO52.js → chunk-OJUEUQDJ.js} +2 -2
- package/dist/{chunk-LOXHYCVS.js → chunk-OMX6TKXH.js} +2 -2
- package/dist/{chunk-J2WC5LF4.js → chunk-QBC33MPY.js} +2 -1
- package/dist/{chunk-SEEJOGQX.js → chunk-QBNE55VA.js} +4 -4
- package/dist/chunk-QJCWK2A7.js +1466 -0
- package/dist/chunk-QJCWK2A7.js.map +1 -0
- package/dist/{chunk-YEUXERJ6.js → chunk-RDGKVH6T.js} +7 -3
- package/dist/{chunk-YEUXERJ6.js.map → chunk-RDGKVH6T.js.map} +1 -1
- package/dist/{chunk-JYSN42VN.js → chunk-RPIS5FQ7.js} +237 -183
- package/dist/chunk-RPIS5FQ7.js.map +1 -0
- package/dist/{chunk-F7XUD3PL.js → chunk-S4CDUXQY.js} +2 -2
- package/dist/{chunk-WNXYT4MK.js → chunk-S4Z2OBTX.js} +4 -4
- package/dist/{chunk-UL4MKZHI.js → chunk-SN4JXNLL.js} +2 -2
- package/dist/{chunk-CAMNRAJF.js → chunk-SZMYGDSM.js} +2 -2
- package/dist/chunk-TB2MJRI6.js +866 -0
- package/dist/chunk-TB2MJRI6.js.map +1 -0
- package/dist/{chunk-XNWXSGHS.js → chunk-TBCDF556.js} +28 -10
- package/dist/chunk-TBCDF556.js.map +1 -0
- package/dist/{chunk-LKYIOCWL.js → chunk-TCF4MU7L.js} +967 -132
- package/dist/chunk-TCF4MU7L.js.map +1 -0
- package/dist/chunk-TCQRIIIN.js +202 -0
- package/dist/chunk-TCQRIIIN.js.map +1 -0
- package/dist/{chunk-7PHI6GUI.js → chunk-TEZ2HTC7.js} +42 -2
- package/dist/chunk-TEZ2HTC7.js.map +1 -0
- package/dist/{chunk-CPA5NBHN.js → chunk-TNGH4ZYI.js} +2 -2
- package/dist/{chunk-F3NVYTTA.js → chunk-TNXNECAN.js} +6 -6
- package/dist/{chunk-BEC4YBNA.js → chunk-TVW4C7PV.js} +2 -2
- package/dist/{chunk-UFKPQBXH.js → chunk-U62OK7BB.js} +2 -2
- package/dist/{chunk-KZIF6XHX.js → chunk-U65VJSCJ.js} +32 -19
- package/dist/chunk-U65VJSCJ.js.map +1 -0
- package/dist/{chunk-4QEYREAV.js → chunk-U6NGKS32.js} +8 -8
- package/dist/{chunk-HRHO3ZNG.js → chunk-UW4RYPWC.js} +2 -2
- package/dist/{chunk-AX7UXCHJ.js → chunk-UYA36DQ7.js} +2 -1
- package/dist/chunk-UYA36DQ7.js.map +1 -0
- package/dist/{chunk-T6ILXUAH.js → chunk-VG4SSPAW.js} +2 -2
- package/dist/chunk-VOSWUO3K.js +100 -0
- package/dist/chunk-VOSWUO3K.js.map +1 -0
- package/dist/chunk-WFCWP4XU.js +17 -0
- package/dist/chunk-WFCWP4XU.js.map +1 -0
- package/dist/{chunk-H2YSH3DG.js → chunk-WKAXBXVA.js} +2 -2
- package/dist/{chunk-SXIMQLGV.js → chunk-WVGXCBOC.js} +2 -2
- package/dist/{chunk-UNUMFURP.js → chunk-X5PIDJ3L.js} +3 -3
- package/dist/{chunk-CRML27CO.js → chunk-X5YYSAZX.js} +4 -4
- package/dist/{chunk-FZEEWOI2.js → chunk-XJJYSX6F.js} +2 -2
- package/dist/{chunk-U7EW2W4W.js → chunk-XKNHFDTT.js} +26 -6
- package/dist/chunk-XKNHFDTT.js.map +1 -0
- package/dist/{chunk-OA2O2GJ4.js → chunk-XOHYGIWF.js} +3 -3
- package/dist/{chunk-UG6VXIOK.js → chunk-XSTNGNJP.js} +2 -2
- package/dist/{chunk-MINHJ55X.js → chunk-XXW32OL7.js} +1 -1
- package/dist/{chunk-MINHJ55X.js.map → chunk-XXW32OL7.js.map} +1 -1
- package/dist/{chunk-YDPAE2RD.js → chunk-YFLLGRXO.js} +2 -2
- package/dist/{chunk-MDD2RINF.js → chunk-YWPLOJ7T.js} +3 -3
- package/dist/{chunk-Q4WONDMJ.js → chunk-YYGZJPOK.js} +2 -2
- package/dist/{chunk-GTO56JY5.js → chunk-ZPS724LT.js} +2 -2
- package/dist/{chunk-SNOIKAHM.js → chunk-ZZZWEDF4.js} +3 -3
- package/dist/{cli-O3F-ht3i.d.ts → cli-CsfFMe6n.d.ts} +5 -5
- package/dist/cli.d.ts +13 -14
- package/dist/cli.js +101 -96
- package/dist/coding/export-okf-codegraph.d.ts +56 -0
- package/dist/coding/export-okf-codegraph.js +526 -0
- package/dist/coding/export-okf-codegraph.js.map +1 -0
- package/dist/coding/pre-action-gate.d.ts +1 -2
- package/dist/compounding/engine.d.ts +2 -3
- package/dist/compounding/engine.js +29 -29
- package/dist/compounding/preference-consolidator.d.ts +1 -2
- package/dist/compression-optimizer.d.ts +1 -2
- package/dist/config.d.ts +1 -2
- package/dist/config.js +11 -11
- package/dist/connectors/codex-materialize-runner.d.ts +1 -2
- package/dist/connectors/codex-materialize-runner.js +28 -28
- package/dist/connectors/codex-materialize.d.ts +1 -2
- package/dist/connectors/index.d.ts +1 -2
- package/dist/connectors/index.js +28 -28
- package/dist/consolidation-provenance-check.d.ts +2 -3
- package/dist/consolidation-provenance-check.js +4 -4
- package/dist/consolidation-undo.d.ts +2 -3
- package/dist/consolidation-undo.js +3 -3
- package/dist/contradiction/index.d.ts +3 -4
- package/dist/contradiction/index.js +9 -9
- package/dist/{contradiction-scan-AKUWPX5N.js → contradiction-scan-NOYMFG66.js} +3 -3
- package/dist/converge-config.d.ts +1 -2
- package/dist/convergence-refresh.d.ts +2 -3
- package/dist/convergence-refresh.js +30 -30
- package/dist/conversation-index/backend.d.ts +1 -2
- package/dist/conversation-index/backend.js +2 -2
- package/dist/conversation-index/chunker.d.ts +1 -2
- package/dist/conversation-index/faiss-adapter.d.ts +1 -2
- package/dist/conversation-index/indexer.d.ts +1 -2
- package/dist/conversation-index/search.d.ts +1 -2
- package/dist/corpus-watermark.d.ts +1 -2
- package/dist/corpus-watermark.js +30 -30
- package/dist/cross-lingual-recall.d.ts +1 -2
- package/dist/day-summary.d.ts +1 -2
- package/dist/delinearize.d.ts +1 -2
- package/dist/dependency-propagation-config.d.ts +1 -2
- package/dist/{dependency-propagation-delivery-CL6RWXTA.d.ts → dependency-propagation-delivery-D4WMbOwA.d.ts} +1 -1
- package/dist/direct-answer-wiring.d.ts +1 -2
- package/dist/direct-answer.d.ts +1 -2
- package/dist/embedding-fallback.d.ts +1 -2
- package/dist/enrichment/index.d.ts +1 -2
- package/dist/entity-origin-fields.d.ts +1 -2
- package/dist/entity-retrieval.d.ts +2 -3
- package/dist/entity-retrieval.js +28 -28
- package/dist/entity-schema.d.ts +1 -2
- package/dist/episodic-context.d.ts +1 -2
- package/dist/eval-trajectory-contracts.d.ts +1 -2
- package/dist/eval-trajectory-store.d.ts +1 -2
- package/dist/eval-trajectory.d.ts +1 -2
- package/dist/explicit-capture.d.ts +9 -10
- package/dist/explicit-capture.js +11 -11
- package/dist/external-wiki-access.d.ts +11 -12
- package/dist/external-wiki-access.js +55 -52
- package/dist/external-wiki-collection-registration.d.ts +1 -2
- package/dist/external-wiki-collection.d.ts +1 -2
- package/dist/external-wiki-mcp-tools.d.ts +11 -12
- package/dist/extraction-error-classification.d.ts +1 -2
- package/dist/extraction-faithfulness.d.ts +1 -2
- package/dist/extraction-faithfulness.js +2 -2
- package/dist/extraction-judge-telemetry.d.ts +1 -2
- package/dist/extraction-judge-training.d.ts +1 -2
- package/dist/extraction-judge.d.ts +1 -2
- package/dist/extraction-judge.js +2 -2
- package/dist/extraction-liveness.d.ts +1 -2
- package/dist/extraction-normalization.d.ts +1 -2
- package/dist/extraction-prompt.d.ts +1 -2
- package/dist/extraction-source-grounding-rules.d.ts +1 -2
- package/dist/extraction-source-grounding.d.ts +1 -2
- package/dist/extraction.d.ts +1 -2
- package/dist/extraction.js +37 -34
- package/dist/fallback-llm.d.ts +7 -2
- package/dist/fallback-llm.js +1 -1
- package/dist/{first-start-migration-4NETATFF.js → first-start-migration-KHIMCBIC.js} +3 -3
- package/dist/graph-dashboard-diff.d.ts +1 -2
- package/dist/graph-dashboard-key.d.ts +1 -2
- package/dist/graph-dashboard-parser.d.ts +1 -2
- package/dist/graph-edge-reinforcement.d.ts +1 -2
- package/dist/graph-path-reconstruction.d.ts +1 -2
- package/dist/graph-path-scoring.d.ts +1 -2
- package/dist/graph-snapshot.d.ts +1 -2
- package/dist/graph.d.ts +1 -2
- package/dist/harmonic-retrieval.js +1 -1
- package/dist/importance.d.ts +1 -2
- package/dist/importers/index.d.ts +1 -2
- package/dist/in-flight-reads.d.ts +1 -2
- package/dist/{index-C7Xep6S9.d.ts → index-DuJnzwHv.d.ts} +2 -2
- package/dist/index.d.ts +364 -26
- package/dist/index.js +232 -169
- package/dist/intent.d.ts +1 -2
- package/dist/lcm/engine.d.ts +1 -2
- package/dist/lcm/engine.js +4 -4
- package/dist/lcm/index.d.ts +1 -2
- package/dist/lcm/index.js +10 -10
- package/dist/lcm/tools.d.ts +1 -2
- package/dist/lifecycle.d.ts +1 -2
- package/dist/live-connectors-runner.d.ts +1 -2
- package/dist/local-llm.d.ts +1 -2
- package/dist/local-model-endpoint.d.ts +1 -2
- package/dist/location/index.d.ts +315 -6
- package/dist/location/index.js +151 -19
- package/dist/maintenance/memory-governance.d.ts +1 -2
- package/dist/maintenance/memory-governance.js +28 -28
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -3
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +28 -28
- package/dist/maintenance/rebuild-memory-projection.d.ts +2 -3
- package/dist/maintenance/rebuild-memory-projection.js +29 -29
- package/dist/{maintenance-CJ-xqFp0.d.ts → maintenance-BBeaeYRR.d.ts} +3 -3
- package/dist/mcp-memory-inspector-app.d.ts +11 -12
- package/dist/mcp-read-only-tools.js +1 -1
- package/dist/memory-action-policy.d.ts +1 -2
- package/dist/memory-cache.d.ts +1 -2
- package/dist/memory-controller.d.ts +1 -2
- package/dist/memory-lifecycle-ledger-utils.d.ts +1 -2
- package/dist/memory-projection-mutations.js +3 -3
- package/dist/memory-projection-store.d.ts +1 -2
- package/dist/memory-projection-store.js +1 -1
- package/dist/memory-provenance.d.ts +1 -2
- package/dist/memory-snapshot.d.ts +1 -2
- package/dist/memory-subject-cli.d.ts +11 -12
- package/dist/memory-subject.d.ts +11 -12
- package/dist/memory-subject.js +4 -4
- package/dist/memory-worth-outcomes.d.ts +2 -3
- package/dist/models-json.d.ts +1 -2
- package/dist/namespaces/migrate.d.ts +3 -4
- package/dist/namespaces/migrate.js +29 -29
- package/dist/namespaces/principal.d.ts +1 -2
- package/dist/namespaces/search.d.ts +1 -2
- package/dist/namespaces/search.js +8 -8
- package/dist/namespaces/storage.d.ts +3 -4
- package/dist/namespaces/storage.js +28 -28
- package/dist/native-knowledge.d.ts +1 -2
- package/dist/offline-sync-file-io.js +3 -3
- package/dist/offline-sync-impression-drain.d.ts +1 -2
- package/dist/offline-sync-impression-drain.js +9 -9
- package/dist/offline-sync.js +4 -4
- package/dist/operator-doctor-corpus.d.ts +1 -2
- package/dist/operator-doctor-corpus.js +31 -31
- package/dist/operator-doctor-replica.d.ts +1 -2
- package/dist/operator-toolkit.d.ts +3 -4
- package/dist/operator-toolkit.js +47 -47
- package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -3
- package/dist/orchestration/maintenance.d.ts +4 -5
- package/dist/orchestration/maintenance.js +42 -41
- package/dist/{orchestrator-BsntWxLy.d.ts → orchestrator-CaqnwNwM.d.ts} +8 -8
- package/dist/orchestrator.d.ts +9 -10
- package/dist/orchestrator.js +132 -125
- package/dist/page-versioning.js +3 -3
- package/dist/patterns-cli.d.ts +1 -2
- package/dist/{pipeline-CVoysPm2.d.ts → pipeline-CrxVjlJr.d.ts} +1 -1
- package/dist/policy-runtime.d.ts +1 -2
- package/dist/proactive-contention.d.ts +1 -2
- package/dist/provenance.d.ts +1 -2
- package/dist/{public-http-CuOxlTC2.d.ts → public-http-Cwvl4QZr.d.ts} +1 -1
- package/dist/{purge-GB7PZHT2.js → purge-OP6BEDFY.js} +2 -2
- package/dist/{qmd-DWMAGA5l.d.ts → qmd-BZgbJm0g.d.ts} +1 -1
- package/dist/qmd-preflight.d.ts +2 -3
- package/dist/qmd-recall-cache.d.ts +1 -2
- package/dist/qmd.d.ts +2 -3
- package/dist/recall-concurrency-config.d.ts +1 -2
- package/dist/recall-deep.d.ts +37 -0
- package/dist/recall-deep.js +81 -0
- package/dist/recall-deep.js.map +1 -0
- package/dist/recall-disclosure-escalation.d.ts +1 -2
- package/dist/recall-explain-renderer.d.ts +1 -2
- package/dist/recall-explain-renderer.js +3 -3
- package/dist/recall-memory-map.d.ts +1 -2
- package/dist/recall-navigate.d.ts +70 -0
- package/dist/recall-navigate.js +51 -0
- package/dist/recall-navigate.js.map +1 -0
- package/dist/recall-planner-llm.d.ts +1 -2
- package/dist/recall-planner-llm.js +1 -1
- package/dist/recall-state-view-wire.d.ts +14 -0
- package/dist/recall-state-view-wire.js +11 -0
- package/dist/recall-state-view.d.ts +25 -0
- package/dist/recall-state-view.js +22 -0
- package/dist/recall-state-view.js.map +1 -0
- package/dist/recall-state.d.ts +1 -2
- package/dist/recall-tag-filter.d.ts +1 -2
- package/dist/recall-timings.d.ts +1 -2
- package/dist/recall-xray-cli.d.ts +1 -2
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.d.ts +1 -2
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.d.ts +1 -2
- package/dist/recall-xray.js +2 -2
- package/dist/reconcile/cursor.d.ts +1 -2
- package/dist/reconcile/manifest.d.ts +1 -2
- package/dist/reconcile/manifest.js +4 -4
- package/dist/reconcile/plan.d.ts +1 -2
- package/dist/replay/normalizers/chatgpt.d.ts +1 -2
- package/dist/replay/normalizers/claude.d.ts +1 -2
- package/dist/replay/normalizers/openclaw.d.ts +1 -2
- package/dist/replay/normalizers/shared.d.ts +1 -2
- package/dist/replay/runner.d.ts +1 -2
- package/dist/replay/types.d.ts +1 -2
- package/dist/replica-divergence.d.ts +1 -2
- package/dist/replica-peers-config.d.ts +1 -2
- package/dist/{resolution-XWBPKYFB.js → resolution-4DLI3IOR.js} +10 -10
- package/dist/resolution-4DLI3IOR.js.map +1 -0
- package/dist/resolve-auth-token.d.ts +1 -2
- package/dist/resume-bundles.js +12 -12
- package/dist/retrieval-agents.d.ts +2 -3
- package/dist/retrieval-tiers.d.ts +1 -2
- package/dist/routing/engine.d.ts +1 -2
- package/dist/routing/store.d.ts +1 -2
- package/dist/salvage-envelope.d.ts +1 -2
- package/dist/salvage-envelope.js +6 -6
- package/dist/schemas.d.ts +570 -105
- package/dist/schemas.js +3 -1
- package/dist/{scope-profiles-CPWkW_dI.d.ts → scope-profiles-DFaojvoP.d.ts} +1 -1
- package/dist/search/document-scanner.js +1 -1
- package/dist/search/embed-helper.d.ts +1 -2
- package/dist/search/factory.d.ts +1 -2
- package/dist/search/factory.js +7 -7
- package/dist/search/index.d.ts +1 -2
- package/dist/search/index.js +13 -13
- package/dist/search/lancedb-backend.d.ts +1 -2
- package/dist/search/lancedb-backend.js +1 -1
- package/dist/search/meilisearch-backend.d.ts +1 -2
- package/dist/search/meilisearch-backend.js +1 -1
- package/dist/search/noop-backend.d.ts +1 -2
- package/dist/search/orama-backend.d.ts +1 -2
- package/dist/search/orama-backend.js +1 -1
- package/dist/search/port.d.ts +1 -2
- package/dist/search/remote-backend.d.ts +1 -2
- package/dist/secure-store/index.js +3 -3
- package/dist/{semantic-consolidation-CNFVBXFc.d.ts → semantic-consolidation-BiX68wZA.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -3
- package/dist/semantic-consolidation.js +29 -29
- package/dist/semantic-rule-promotion.js +28 -28
- package/dist/semantic-rule-verifier.d.ts +1 -2
- package/dist/semantic-rule-verifier.js +28 -28
- package/dist/{service-Bb-JIdQ0.d.ts → service-D5h2zZ0M.d.ts} +2 -2
- package/dist/session-observer-bands.d.ts +1 -2
- package/dist/session-observer-state.d.ts +1 -2
- package/dist/shared-context/manager.d.ts +1 -2
- package/dist/signal.d.ts +1 -2
- package/dist/source-agent-qualifier.d.ts +1 -2
- package/dist/source-agent-qualifier.js +35 -32
- package/dist/standup/build.d.ts +16 -0
- package/dist/standup/build.js +17 -0
- package/dist/standup/build.js.map +1 -0
- package/dist/{storage-CukrlNKk.d.ts → storage-CtsaojWD.d.ts} +1 -1
- package/dist/storage.d.ts +2 -3
- package/dist/storage.js +27 -27
- package/dist/subject-config.d.ts +1 -2
- package/dist/subject-config.js +5 -5
- package/dist/summarizer.d.ts +1 -2
- package/dist/summarizer.js +2 -2
- package/dist/summary-snapshot.d.ts +1 -2
- package/dist/support-passport/index.d.ts +16 -17
- package/dist/support-passport/index.js +57 -54
- package/dist/temporal-supersession.d.ts +2 -3
- package/dist/temporal-timeline-recall.d.ts +1 -2
- package/dist/temporal-validity.d.ts +1 -2
- package/dist/threading.d.ts +1 -2
- package/dist/tier-migration.d.ts +2 -3
- package/dist/tier-routing.d.ts +1 -2
- package/dist/tier-routing.js +2 -2
- package/dist/{tier-stats-4B5IJ3NE.js → tier-stats-2TOW3QNL.js} +3 -3
- package/dist/topics.d.ts +1 -2
- package/dist/transcript.d.ts +1 -2
- package/dist/transfer/capsule-import.js +4 -4
- package/dist/transfer/export-okf.d.ts +39 -0
- package/dist/transfer/export-okf.js +112 -0
- package/dist/transfer/export-okf.js.map +1 -0
- package/dist/trust-score-stage.d.ts +1 -2
- package/dist/trust-score.d.ts +1 -2
- package/dist/{types-djxQlxJ7.d.ts → types-CIpfYz1I.d.ts} +132 -12
- package/dist/types.d.ts +1 -2
- package/dist/types.js +1 -1
- package/dist/utility-runtime.d.ts +1 -2
- package/dist/verified-recall.js +28 -28
- package/dist/who-knows-cli.d.ts +11 -12
- package/dist/who-knows-cli.js +29 -29
- package/dist/who-knows.d.ts +11 -12
- package/dist/who-knows.js +28 -28
- package/dist/write-envelope.d.ts +1 -2
- package/dist/write-envelope.js +5 -5
- package/package.json +34 -3
- package/src/access-admin-ops-surface.ts +6 -1
- package/src/access-boundary.ts +1 -0
- package/src/access-http.ts +3 -1
- package/src/access-mcp-output-schemas.ts +1 -0
- package/src/access-mcp.ts +3 -3
- package/src/access-operations.ts +1 -0
- package/src/access-service-offline-file-content.test.ts +63 -0
- package/src/access-surface-catalog.ts +2 -0
- package/src/activity/config.test.ts +1 -0
- package/src/activity/config.ts +66 -1
- package/src/activity/index.ts +3 -0
- package/src/activity/journal.test.ts +97 -0
- package/src/activity/journal.ts +113 -0
- package/src/activity/privacy.test.ts +53 -0
- package/src/activity/privacy.ts +80 -0
- package/src/activity/timeline/build.ts +279 -0
- package/src/activity/timeline/categories.ts +111 -0
- package/src/activity/timeline/classify.ts +110 -0
- package/src/activity/timeline/corrections.ts +145 -0
- package/src/activity/timeline/index.ts +8 -0
- package/src/activity/timeline/journal-recap.test.ts +113 -0
- package/src/activity/timeline/journal-recap.ts +130 -0
- package/src/activity/timeline/query.test.ts +198 -0
- package/src/activity/timeline/query.ts +313 -0
- package/src/activity/timeline/timeline.test.ts +277 -0
- package/src/activity/timeline/types.ts +106 -0
- package/src/activity/timeline/weekly.test.ts +215 -0
- package/src/activity/timeline/weekly.ts +234 -0
- package/src/activity/types.ts +20 -0
- package/src/activity/vault-publish.test.ts +166 -0
- package/src/activity/vault-publish.ts +101 -0
- package/src/cli/okf-commands.ts +45 -0
- package/src/cli.ts +2 -2
- package/src/coding/export-okf-codegraph.test.ts +381 -0
- package/src/coding/export-okf-codegraph.ts +565 -0
- package/src/config.test.ts +1 -0
- package/src/config.ts +2 -22
- package/src/dedup/merge-on-write.test.ts +91 -0
- package/src/dedup/merge-on-write.ts +75 -0
- package/src/dedup/novelty-gate.test.ts +143 -0
- package/src/dedup/novelty-gate.ts +163 -0
- package/src/extraction-prompt-safety.test.ts +14 -2
- package/src/extraction.ts +21 -1
- package/src/fallback-llm.test.ts +134 -0
- package/src/fallback-llm.ts +77 -5
- package/src/location/access-operations.ts +17 -8
- package/src/location/backfill.ts +137 -0
- package/src/location/config.test.ts +3 -0
- package/src/location/config.ts +46 -2
- package/src/location/http-glue.ts +1 -1
- package/src/location/index.ts +3 -0
- package/src/location/intervals.ts +1 -0
- package/src/location/matching.test.ts +65 -0
- package/src/location/matching.ts +354 -0
- package/src/location/mcp-tools.ts +2 -1
- package/src/location/recall-exclusion.test.ts +1 -0
- package/src/location/surfaces.test.ts +15 -2
- package/src/location/surfaces.ts +95 -18
- package/src/location/tagging.test.ts +119 -0
- package/src/location/tagging.ts +277 -0
- package/src/location/types.ts +23 -1
- package/src/mcp-read-only-tools.ts +1 -0
- package/src/memory-projection-store.ts +3 -1
- package/src/okf/cli.ts +18 -5
- package/src/okf/config.ts +5 -0
- package/src/okf/index-files.test.ts +60 -0
- package/src/okf/index-files.ts +114 -0
- package/src/okf/render.ts +133 -0
- package/src/okf/type-mapping.test.ts +3 -0
- package/src/okf/type-mapping.ts +2 -0
- package/src/orchestration/extraction-persist.ts +22 -23
- package/src/orchestration/extraction-run.ts +2 -1
- package/src/orchestration/generic-recall-paths.ts +15 -3
- package/src/orchestration/recall-entry.ts +8 -3
- package/src/recall-deep.test.ts +72 -0
- package/src/recall-deep.ts +113 -0
- package/src/recall-navigate.test.ts +84 -0
- package/src/recall-navigate.ts +100 -0
- package/src/recall-state-view-wire.test.ts +35 -0
- package/src/recall-state-view-wire.ts +28 -0
- package/src/recall-state-view.test.ts +131 -0
- package/src/recall-state-view.ts +138 -0
- package/src/schemas.ts +17 -1
- package/src/shared-context/governance.test.ts +53 -0
- package/src/shared-context/governance.ts +86 -0
- package/src/standup/access-operations.ts +14 -0
- package/src/standup/build.test.ts +34 -0
- package/src/standup/build.ts +115 -0
- package/src/standup/http-glue.ts +15 -0
- package/src/standup/mcp-tools.ts +16 -0
- package/src/support-passport/card-projection.ts +1 -0
- package/src/support-passport/card-service-commit-forwarding.test.ts +1 -0
- package/src/support-passport/card-service.test.ts +75 -1
- package/src/support-passport/card-service.ts +6 -3
- package/src/support-passport/card-state.ts +5 -1
- package/src/support-passport/offline-sync-guard.ts +14 -1
- package/src/transfer/export-okf.test.ts +164 -0
- package/src/transfer/export-okf.ts +286 -0
- package/src/types.ts +3 -10
- package/dist/chunk-2LWQSV6A.js.map +0 -1
- package/dist/chunk-3BCULS4U.js.map +0 -1
- package/dist/chunk-7BDZTALN.js.map +0 -1
- package/dist/chunk-7PHI6GUI.js.map +0 -1
- package/dist/chunk-7WOWGRAU.js.map +0 -1
- package/dist/chunk-AX7UXCHJ.js.map +0 -1
- package/dist/chunk-DEACDKE3.js.map +0 -1
- package/dist/chunk-FP7YTTVO.js.map +0 -1
- package/dist/chunk-JYSN42VN.js.map +0 -1
- package/dist/chunk-KZIF6XHX.js.map +0 -1
- package/dist/chunk-LKYIOCWL.js.map +0 -1
- package/dist/chunk-OXRRJXPR.js.map +0 -1
- package/dist/chunk-U7EW2W4W.js.map +0 -1
- package/dist/chunk-UW5NPZJ2.js.map +0 -1
- package/dist/chunk-XAB6STPO.js.map +0 -1
- package/dist/chunk-XNWXSGHS.js.map +0 -1
- package/dist/types-CM86alG1.d.ts +0 -89
- /package/dist/{auto-sync-2YPITIWN.js.map → auto-sync-Q6Q2FVSC.js.map} +0 -0
- /package/dist/{capsule-merge-SGIVB3WA.js.map → capsule-merge-SEHERWWP.js.map} +0 -0
- /package/dist/{chunk-LEPOP46W.js.map → chunk-227UFSEQ.js.map} +0 -0
- /package/dist/{chunk-TFR3HG4K.js.map → chunk-2FA7U5XY.js.map} +0 -0
- /package/dist/{chunk-PO7NXBG2.js.map → chunk-2GF27PGH.js.map} +0 -0
- /package/dist/{chunk-MY2BC6UE.js.map → chunk-2X6BGKQL.js.map} +0 -0
- /package/dist/{chunk-UEBDCMOO.js.map → chunk-3TSU662L.js.map} +0 -0
- /package/dist/{chunk-S5XOSTYM.js.map → chunk-4XLTUR6R.js.map} +0 -0
- /package/dist/{chunk-BWGCOLEL.js.map → chunk-65JOGLIS.js.map} +0 -0
- /package/dist/{chunk-HMZKGHMD.js.map → chunk-7UOXCCCI.js.map} +0 -0
- /package/dist/{chunk-4F4AQFWL.js.map → chunk-B4AOWRYF.js.map} +0 -0
- /package/dist/{chunk-ODU2CNNX.js.map → chunk-C5IUOBCN.js.map} +0 -0
- /package/dist/{chunk-3A2NJP2U.js.map → chunk-CHGG74CY.js.map} +0 -0
- /package/dist/{chunk-76DIF5KT.js.map → chunk-CX4OLNIH.js.map} +0 -0
- /package/dist/{chunk-Z3YEGSR4.js.map → chunk-D3UXGE5D.js.map} +0 -0
- /package/dist/{chunk-5HK3CJAR.js.map → chunk-D6Q5EPOV.js.map} +0 -0
- /package/dist/{chunk-EGBDFJ36.js.map → chunk-DD5JFCWM.js.map} +0 -0
- /package/dist/{chunk-XBGHAAKR.js.map → chunk-DDX6KIXF.js.map} +0 -0
- /package/dist/{chunk-JIYDRBVZ.js.map → chunk-DJORULH3.js.map} +0 -0
- /package/dist/{chunk-7KQB4EBS.js.map → chunk-DUAJKRR2.js.map} +0 -0
- /package/dist/{chunk-Q57GOHLF.js.map → chunk-EGALNSZ4.js.map} +0 -0
- /package/dist/{chunk-DPCXDG7G.js.map → chunk-EH65UV2Z.js.map} +0 -0
- /package/dist/{chunk-KCT36JAW.js.map → chunk-ESNFSSO4.js.map} +0 -0
- /package/dist/{chunk-XQ3HXAQH.js.map → chunk-ET2CNMLD.js.map} +0 -0
- /package/dist/{chunk-TUHBYJXL.js.map → chunk-EWKVYCFP.js.map} +0 -0
- /package/dist/{chunk-NPFUNWNX.js.map → chunk-FFUMTH27.js.map} +0 -0
- /package/dist/{chunk-3PKAS6VL.js.map → chunk-GAJK3DQ5.js.map} +0 -0
- /package/dist/{chunk-DA7ITC5Z.js.map → chunk-GBEOUCBB.js.map} +0 -0
- /package/dist/{chunk-UENKPWCS.js.map → chunk-H2IRSXZN.js.map} +0 -0
- /package/dist/{chunk-CFVTRUR3.js.map → chunk-H6RSANGQ.js.map} +0 -0
- /package/dist/{chunk-EUYWQ7TS.js.map → chunk-IEZ6CGTW.js.map} +0 -0
- /package/dist/{chunk-3SZD4CYO.js.map → chunk-IGZCAHFL.js.map} +0 -0
- /package/dist/{chunk-UPFNQJC7.js.map → chunk-INUBU6I5.js.map} +0 -0
- /package/dist/{chunk-PMVPCZJZ.js.map → chunk-J2R275FN.js.map} +0 -0
- /package/dist/{chunk-2QSZNTDO.js.map → chunk-JBPKEARU.js.map} +0 -0
- /package/dist/{chunk-5ACCD4L7.js.map → chunk-JRRQ747T.js.map} +0 -0
- /package/dist/{chunk-V4IDF3EZ.js.map → chunk-JTWZKNUH.js.map} +0 -0
- /package/dist/{chunk-AZMLH5UT.js.map → chunk-KI64TTBL.js.map} +0 -0
- /package/dist/{chunk-NPIBN2VL.js.map → chunk-LK4TOYPU.js.map} +0 -0
- /package/dist/{chunk-UTQUEHC7.js.map → chunk-LUDBXTBJ.js.map} +0 -0
- /package/dist/{chunk-PU56CXZA.js.map → chunk-LYUUA6QB.js.map} +0 -0
- /package/dist/{chunk-P36Z4JRA.js.map → chunk-M5ERTI4I.js.map} +0 -0
- /package/dist/{chunk-LDKPDODJ.js.map → chunk-ME35HVDJ.js.map} +0 -0
- /package/dist/{chunk-773TRRGT.js.map → chunk-MJUCDM3C.js.map} +0 -0
- /package/dist/{chunk-AHPIFKNG.js.map → chunk-N4F7ZSSG.js.map} +0 -0
- /package/dist/{chunk-JOZUBF4A.js.map → chunk-NACLNNFQ.js.map} +0 -0
- /package/dist/{chunk-LC2BDILZ.js.map → chunk-NBP4EX5N.js.map} +0 -0
- /package/dist/{chunk-T7XP6IZE.js.map → chunk-NFP4KPTA.js.map} +0 -0
- /package/dist/{chunk-ZVPVTPGI.js.map → chunk-NNZFPYYX.js.map} +0 -0
- /package/dist/{chunk-LPNCR4QK.js.map → chunk-NSTNGMSS.js.map} +0 -0
- /package/dist/{chunk-5RWZH6PH.js.map → chunk-NUF7VSEX.js.map} +0 -0
- /package/dist/{chunk-7VZFRUQU.js.map → chunk-O7ERGZDA.js.map} +0 -0
- /package/dist/{chunk-HSZMX3ZJ.js.map → chunk-ODW5GDFE.js.map} +0 -0
- /package/dist/{chunk-5DHKCO52.js.map → chunk-OJUEUQDJ.js.map} +0 -0
- /package/dist/{chunk-LOXHYCVS.js.map → chunk-OMX6TKXH.js.map} +0 -0
- /package/dist/{chunk-J2WC5LF4.js.map → chunk-QBC33MPY.js.map} +0 -0
- /package/dist/{chunk-SEEJOGQX.js.map → chunk-QBNE55VA.js.map} +0 -0
- /package/dist/{chunk-F7XUD3PL.js.map → chunk-S4CDUXQY.js.map} +0 -0
- /package/dist/{chunk-WNXYT4MK.js.map → chunk-S4Z2OBTX.js.map} +0 -0
- /package/dist/{chunk-UL4MKZHI.js.map → chunk-SN4JXNLL.js.map} +0 -0
- /package/dist/{chunk-CAMNRAJF.js.map → chunk-SZMYGDSM.js.map} +0 -0
- /package/dist/{chunk-CPA5NBHN.js.map → chunk-TNGH4ZYI.js.map} +0 -0
- /package/dist/{chunk-F3NVYTTA.js.map → chunk-TNXNECAN.js.map} +0 -0
- /package/dist/{chunk-BEC4YBNA.js.map → chunk-TVW4C7PV.js.map} +0 -0
- /package/dist/{chunk-UFKPQBXH.js.map → chunk-U62OK7BB.js.map} +0 -0
- /package/dist/{chunk-4QEYREAV.js.map → chunk-U6NGKS32.js.map} +0 -0
- /package/dist/{chunk-HRHO3ZNG.js.map → chunk-UW4RYPWC.js.map} +0 -0
- /package/dist/{chunk-T6ILXUAH.js.map → chunk-VG4SSPAW.js.map} +0 -0
- /package/dist/{chunk-H2YSH3DG.js.map → chunk-WKAXBXVA.js.map} +0 -0
- /package/dist/{chunk-SXIMQLGV.js.map → chunk-WVGXCBOC.js.map} +0 -0
- /package/dist/{chunk-UNUMFURP.js.map → chunk-X5PIDJ3L.js.map} +0 -0
- /package/dist/{chunk-CRML27CO.js.map → chunk-X5YYSAZX.js.map} +0 -0
- /package/dist/{chunk-FZEEWOI2.js.map → chunk-XJJYSX6F.js.map} +0 -0
- /package/dist/{chunk-OA2O2GJ4.js.map → chunk-XOHYGIWF.js.map} +0 -0
- /package/dist/{chunk-UG6VXIOK.js.map → chunk-XSTNGNJP.js.map} +0 -0
- /package/dist/{chunk-YDPAE2RD.js.map → chunk-YFLLGRXO.js.map} +0 -0
- /package/dist/{chunk-MDD2RINF.js.map → chunk-YWPLOJ7T.js.map} +0 -0
- /package/dist/{chunk-Q4WONDMJ.js.map → chunk-YYGZJPOK.js.map} +0 -0
- /package/dist/{chunk-GTO56JY5.js.map → chunk-ZPS724LT.js.map} +0 -0
- /package/dist/{chunk-SNOIKAHM.js.map → chunk-ZZZWEDF4.js.map} +0 -0
- /package/dist/{contradiction-scan-AKUWPX5N.js.map → contradiction-scan-NOYMFG66.js.map} +0 -0
- /package/dist/{first-start-migration-4NETATFF.js.map → first-start-migration-KHIMCBIC.js.map} +0 -0
- /package/dist/{purge-GB7PZHT2.js.map → purge-OP6BEDFY.js.map} +0 -0
- /package/dist/{resolution-XWBPKYFB.js.map → recall-state-view-wire.js.map} +0 -0
- /package/dist/{tier-stats-4B5IJ3NE.js.map → tier-stats-2TOW3QNL.js.map} +0 -0
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Timeline range/search query (issue #1983 PR1).
|
|
3
|
+
*
|
|
4
|
+
* Pure functions over an in-memory card list. Half-open UTC [from, to).
|
|
5
|
+
* A zero-length range is an instant: include the card whose [start, end)
|
|
6
|
+
* contains it. Search returns distinct empty vs store_unreadable shapes.
|
|
7
|
+
*
|
|
8
|
+
* Config: activity.timeline.qa.{enabled, maxRangeDays}.
|
|
9
|
+
* MCP/HTTP and recall injection are later PRs.
|
|
10
|
+
*/
|
|
11
|
+
import { parseFlexibleIsoTimestamp } from "../../utils/iso-timestamp.js";
|
|
12
|
+
import type { ActivityTimelineQaConfig } from "../types.js";
|
|
13
|
+
import type { TimelineCard } from "./types.js";
|
|
14
|
+
|
|
15
|
+
const RANGE_FORMATS = ["cards", "compact"] as const;
|
|
16
|
+
const MS_PER_DAY = 86_400_000;
|
|
17
|
+
const DEFAULT_MAX_RANGE_DAYS = 31;
|
|
18
|
+
const DEFAULT_SEARCH_LIMIT = 10;
|
|
19
|
+
const MIN_SEARCH_LIMIT = 1;
|
|
20
|
+
const MAX_SEARCH_LIMIT = 50;
|
|
21
|
+
|
|
22
|
+
export type TimelineRangeFormat = (typeof RANGE_FORMATS)[number];
|
|
23
|
+
|
|
24
|
+
/** Card fields the query layer reads; later slices may add optional extras. */
|
|
25
|
+
export type TimelineQueryCard = TimelineCard & {
|
|
26
|
+
detailedSummary?: string;
|
|
27
|
+
distraction?: boolean;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export interface TimelineRangeQuery {
|
|
31
|
+
from: string;
|
|
32
|
+
to: string;
|
|
33
|
+
categories?: readonly string[];
|
|
34
|
+
includeDistractions?: boolean;
|
|
35
|
+
format: TimelineRangeFormat;
|
|
36
|
+
maxRangeDays?: number;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface TimelineCompactCard {
|
|
40
|
+
start: string;
|
|
41
|
+
end: string;
|
|
42
|
+
category: string;
|
|
43
|
+
title: string;
|
|
44
|
+
summary: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface TimelineCompactRange {
|
|
48
|
+
day: string;
|
|
49
|
+
cards: TimelineCompactCard[];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface TimelineSearchQuery {
|
|
53
|
+
query: string;
|
|
54
|
+
from?: string;
|
|
55
|
+
to?: string;
|
|
56
|
+
limit?: number;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export type TimelineSearchResult =
|
|
60
|
+
| { ok: true; results: TimelineQueryCard[] }
|
|
61
|
+
| { ok: false; error: "store_unreadable" };
|
|
62
|
+
|
|
63
|
+
export interface TimelineCliIo {
|
|
64
|
+
stdout: { write(chunk: string): unknown };
|
|
65
|
+
stderr: { write(chunk: string): unknown };
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Inject cards so CLI tests never need ActivityStore. */
|
|
69
|
+
export interface TimelineCliDeps {
|
|
70
|
+
cards: readonly TimelineQueryCard[] | null;
|
|
71
|
+
qa: ActivityTimelineQaConfig;
|
|
72
|
+
timelineEnabled?: boolean;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const USAGE = `Usage: timeline <command> [options]
|
|
76
|
+
|
|
77
|
+
Commands:
|
|
78
|
+
range --from <ISO> --to <ISO> [--format cards|compact] [--categories id,id] [--include-distractions]
|
|
79
|
+
search --query <text> [--from <ISO>] [--to <ISO>] [--limit N]
|
|
80
|
+
`;
|
|
81
|
+
|
|
82
|
+
const VALUE_FLAGS: Record<string, true> = {
|
|
83
|
+
"--from": true,
|
|
84
|
+
"--to": true,
|
|
85
|
+
"--format": true,
|
|
86
|
+
"--categories": true,
|
|
87
|
+
"--query": true,
|
|
88
|
+
"--limit": true,
|
|
89
|
+
};
|
|
90
|
+
const BOOLEAN_FLAGS: Record<string, true> = { "--include-distractions": true };
|
|
91
|
+
|
|
92
|
+
function parseInstant(value: string, label: string): number {
|
|
93
|
+
const ms = parseFlexibleIsoTimestamp(value);
|
|
94
|
+
if (ms === null) {
|
|
95
|
+
throw new TypeError(`${label} must be an ISO date or datetime`);
|
|
96
|
+
}
|
|
97
|
+
return ms;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function assertRange(fromMs: number, toMs: number, maxRangeDays: number): void {
|
|
101
|
+
if (fromMs > toMs) {
|
|
102
|
+
throw new RangeError("reversed range: from must be <= to");
|
|
103
|
+
}
|
|
104
|
+
if (fromMs === toMs) return;
|
|
105
|
+
if (toMs - fromMs > maxRangeDays * MS_PER_DAY) {
|
|
106
|
+
throw new RangeError(`range exceeds timeline.qa.maxRangeDays (${maxRangeDays})`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function cardOverlaps(card: TimelineQueryCard, fromMs: number, toMs: number): boolean {
|
|
111
|
+
const start = Date.parse(card.startUtc);
|
|
112
|
+
const end = Date.parse(card.endUtc);
|
|
113
|
+
if (fromMs === toMs) return start <= fromMs && fromMs < end;
|
|
114
|
+
return start < toMs && end > fromMs;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function passesFilters(
|
|
118
|
+
card: TimelineQueryCard,
|
|
119
|
+
categories: ReadonlySet<string> | undefined,
|
|
120
|
+
includeDistractions: boolean,
|
|
121
|
+
): boolean {
|
|
122
|
+
if (!includeDistractions && card.distraction === true) return false;
|
|
123
|
+
if (categories && !categories.has(card.categoryId)) return false;
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function filterRange(
|
|
128
|
+
cards: readonly TimelineQueryCard[],
|
|
129
|
+
fromMs: number,
|
|
130
|
+
toMs: number,
|
|
131
|
+
categories: ReadonlySet<string> | undefined,
|
|
132
|
+
includeDistractions: boolean,
|
|
133
|
+
): TimelineQueryCard[] {
|
|
134
|
+
return cards.filter(
|
|
135
|
+
(card) => cardOverlaps(card, fromMs, toMs) && passesFilters(card, categories, includeDistractions),
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function toCompact(cards: readonly TimelineQueryCard[], from: string): TimelineCompactRange {
|
|
140
|
+
const day = from.length >= 10 ? from.slice(0, 10) : cards[0]?.dayKey ?? from;
|
|
141
|
+
return {
|
|
142
|
+
day,
|
|
143
|
+
cards: cards.map((card) => ({
|
|
144
|
+
start: card.startUtc,
|
|
145
|
+
end: card.endUtc,
|
|
146
|
+
category: card.categoryId,
|
|
147
|
+
title: card.title,
|
|
148
|
+
summary: card.summary,
|
|
149
|
+
})),
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export function queryTimelineRange(
|
|
154
|
+
cards: readonly TimelineQueryCard[],
|
|
155
|
+
query: TimelineRangeQuery,
|
|
156
|
+
): TimelineCard[] | TimelineCompactRange {
|
|
157
|
+
if (!RANGE_FORMATS.includes(query.format)) {
|
|
158
|
+
throw new TypeError(`format must be one of: ${RANGE_FORMATS.join(", ")}`);
|
|
159
|
+
}
|
|
160
|
+
const maxRangeDays = query.maxRangeDays ?? DEFAULT_MAX_RANGE_DAYS;
|
|
161
|
+
const fromMs = parseInstant(query.from, "from");
|
|
162
|
+
const toMs = parseInstant(query.to, "to");
|
|
163
|
+
assertRange(fromMs, toMs, maxRangeDays);
|
|
164
|
+
const categories = query.categories ? new Set(query.categories) : undefined;
|
|
165
|
+
const matched = filterRange(cards, fromMs, toMs, categories, query.includeDistractions === true);
|
|
166
|
+
if (query.format === "compact") return toCompact(matched, query.from);
|
|
167
|
+
return matched;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function haystack(card: TimelineQueryCard): string {
|
|
171
|
+
const parts = [card.title, card.summary];
|
|
172
|
+
if (card.detailedSummary) parts.push(card.detailedSummary);
|
|
173
|
+
return parts.join(" ").toLowerCase();
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function tokenMatchCount(card: TimelineQueryCard, tokens: readonly string[]): number {
|
|
177
|
+
const text = haystack(card);
|
|
178
|
+
let count = 0;
|
|
179
|
+
for (const token of tokens) {
|
|
180
|
+
if (text.includes(token)) count += 1;
|
|
181
|
+
}
|
|
182
|
+
return count;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export function queryTimelineSearch(
|
|
186
|
+
cards: readonly TimelineQueryCard[] | null | undefined,
|
|
187
|
+
query: TimelineSearchQuery,
|
|
188
|
+
): TimelineSearchResult {
|
|
189
|
+
if (!Array.isArray(cards)) return { ok: false, error: "store_unreadable" };
|
|
190
|
+
const tokens = query.query.trim().toLowerCase().split(/\s+/).filter(Boolean);
|
|
191
|
+
const limit = query.limit ?? DEFAULT_SEARCH_LIMIT;
|
|
192
|
+
if (!Number.isInteger(limit) || limit < MIN_SEARCH_LIMIT || limit > MAX_SEARCH_LIMIT) {
|
|
193
|
+
throw new RangeError(`limit must be an integer from ${MIN_SEARCH_LIMIT} to ${MAX_SEARCH_LIMIT}`);
|
|
194
|
+
}
|
|
195
|
+
let pool = cards;
|
|
196
|
+
if (query.from !== undefined || query.to !== undefined) {
|
|
197
|
+
const fromMs = parseInstant(query.from ?? query.to!, "from");
|
|
198
|
+
const toMs = parseInstant(query.to ?? query.from!, "to");
|
|
199
|
+
assertRange(fromMs, toMs, DEFAULT_MAX_RANGE_DAYS);
|
|
200
|
+
pool = filterRange(cards, fromMs, toMs, undefined, true);
|
|
201
|
+
}
|
|
202
|
+
if (tokens.length === 0) return { ok: true, results: [] };
|
|
203
|
+
const ranked = pool
|
|
204
|
+
.map((card) => ({ card, matches: tokenMatchCount(card, tokens) }))
|
|
205
|
+
.filter((row) => row.matches > 0)
|
|
206
|
+
.sort((a, b) => {
|
|
207
|
+
if (a.matches !== b.matches) return b.matches - a.matches;
|
|
208
|
+
const recency = Date.parse(b.card.endUtc) - Date.parse(a.card.endUtc);
|
|
209
|
+
if (recency !== 0) return recency;
|
|
210
|
+
return a.card.id < b.card.id ? -1 : a.card.id > b.card.id ? 1 : 0;
|
|
211
|
+
})
|
|
212
|
+
.slice(0, limit)
|
|
213
|
+
.map((row) => row.card);
|
|
214
|
+
return { ok: true, results: ranked };
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function parseFlags(args: string[]): { flags: Map<string, string | true>; positional: string[] } {
|
|
218
|
+
const flags = new Map<string, string | true>();
|
|
219
|
+
const positional: string[] = [];
|
|
220
|
+
for (let i = 0; i < args.length; i++) {
|
|
221
|
+
const arg = args[i]!;
|
|
222
|
+
if (!arg.startsWith("--")) {
|
|
223
|
+
positional.push(arg);
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
if (VALUE_FLAGS[arg] === true) {
|
|
227
|
+
const value = args[i + 1];
|
|
228
|
+
if (value === undefined || value.startsWith("--")) {
|
|
229
|
+
throw new TypeError(`flag ${arg} requires a value`);
|
|
230
|
+
}
|
|
231
|
+
flags.set(arg, value);
|
|
232
|
+
i += 1;
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
if (BOOLEAN_FLAGS[arg] === true) {
|
|
236
|
+
flags.set(arg, true);
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
const known = [...Object.keys(VALUE_FLAGS), ...Object.keys(BOOLEAN_FLAGS)].sort().join(", ");
|
|
240
|
+
throw new TypeError(`unknown flag ${arg} (valid: ${known})`);
|
|
241
|
+
}
|
|
242
|
+
return { flags, positional };
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function flagString(flags: Map<string, string | true>, name: string): string | undefined {
|
|
246
|
+
const value = flags.get(name);
|
|
247
|
+
return typeof value === "string" ? value : undefined;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/** Shared CLI runner. `deps.cards` may be an in-memory fixture. */
|
|
251
|
+
export async function runTimelineCliCommand(
|
|
252
|
+
deps: TimelineCliDeps,
|
|
253
|
+
args: string[],
|
|
254
|
+
io: TimelineCliIo,
|
|
255
|
+
): Promise<number> {
|
|
256
|
+
const [command, ...rest] = args;
|
|
257
|
+
try {
|
|
258
|
+
if (command === undefined || command === "help" || command === "--help") {
|
|
259
|
+
io.stdout.write(USAGE);
|
|
260
|
+
return command === undefined ? 1 : 0;
|
|
261
|
+
}
|
|
262
|
+
if (deps.timelineEnabled === false || !deps.qa.enabled) {
|
|
263
|
+
io.stderr.write("timeline qa disabled — set activity.timeline.qa.enabled=true\n");
|
|
264
|
+
return 1;
|
|
265
|
+
}
|
|
266
|
+
const { flags } = parseFlags(rest);
|
|
267
|
+
if (command === "range") {
|
|
268
|
+
const from = flagString(flags, "--from");
|
|
269
|
+
const to = flagString(flags, "--to");
|
|
270
|
+
if (!from || !to) throw new TypeError("range requires --from and --to");
|
|
271
|
+
if (!Array.isArray(deps.cards)) {
|
|
272
|
+
io.stderr.write("store_unreadable\n");
|
|
273
|
+
return 1;
|
|
274
|
+
}
|
|
275
|
+
const formatRaw = flagString(flags, "--format") ?? "compact";
|
|
276
|
+
if (formatRaw !== "cards" && formatRaw !== "compact") {
|
|
277
|
+
throw new TypeError("format must be one of: cards, compact");
|
|
278
|
+
}
|
|
279
|
+
const categoriesRaw = flagString(flags, "--categories");
|
|
280
|
+
const result = queryTimelineRange(deps.cards, {
|
|
281
|
+
from,
|
|
282
|
+
to,
|
|
283
|
+
format: formatRaw,
|
|
284
|
+
categories: categoriesRaw ? categoriesRaw.split(",").filter(Boolean) : undefined,
|
|
285
|
+
includeDistractions: flags.get("--include-distractions") === true,
|
|
286
|
+
maxRangeDays: deps.qa.maxRangeDays,
|
|
287
|
+
});
|
|
288
|
+
io.stdout.write(`${JSON.stringify(result)}\n`);
|
|
289
|
+
return 0;
|
|
290
|
+
}
|
|
291
|
+
if (command === "search") {
|
|
292
|
+
const q = flagString(flags, "--query");
|
|
293
|
+
if (q === undefined) throw new TypeError("search requires --query");
|
|
294
|
+
const limitRaw = flagString(flags, "--limit");
|
|
295
|
+
const limit = limitRaw === undefined ? undefined : Number(limitRaw);
|
|
296
|
+
if (limitRaw !== undefined && !Number.isInteger(limit)) {
|
|
297
|
+
throw new RangeError("limit must be an integer from 1 to 50");
|
|
298
|
+
}
|
|
299
|
+
const result = queryTimelineSearch(deps.cards, {
|
|
300
|
+
query: q,
|
|
301
|
+
from: flagString(flags, "--from"),
|
|
302
|
+
to: flagString(flags, "--to"),
|
|
303
|
+
limit,
|
|
304
|
+
});
|
|
305
|
+
io.stdout.write(`${JSON.stringify(result)}\n`);
|
|
306
|
+
return result.ok ? 0 : 1;
|
|
307
|
+
}
|
|
308
|
+
throw new TypeError(`unknown command ${command} (valid: range, search)`);
|
|
309
|
+
} catch (err) {
|
|
310
|
+
io.stderr.write(`${err instanceof Error ? err.message : String(err)}\n`);
|
|
311
|
+
return 1;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { mkdtempSync, rmSync } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import test from "node:test";
|
|
6
|
+
|
|
7
|
+
import { activityDayWindow } from "../digest.js";
|
|
8
|
+
import { parseActivityConfig } from "../config.js";
|
|
9
|
+
import {
|
|
10
|
+
DEFAULT_TIMELINE_CATEGORIES,
|
|
11
|
+
TIMELINE_RESERVED_IDLE,
|
|
12
|
+
TIMELINE_RESERVED_PAUSE,
|
|
13
|
+
TIMELINE_RESERVED_UNKNOWN,
|
|
14
|
+
sortTimelineCategories,
|
|
15
|
+
validateTimelineCategories,
|
|
16
|
+
} from "./categories.js";
|
|
17
|
+
import { classifyTimelineObservation } from "./classify.js";
|
|
18
|
+
import { buildTimelineDay, serializeTimelineDay, TIMELINE_MERGE_GAP_MS } from "./build.js";
|
|
19
|
+
import { applyTimelineCorrections, TimelineCorrectionStore } from "./corrections.js";
|
|
20
|
+
import type { TimelineCategory, TimelineObservation } from "./types.js";
|
|
21
|
+
|
|
22
|
+
function obs(overrides: Partial<TimelineObservation> & { id: number; capturedAtUtc: string }): TimelineObservation {
|
|
23
|
+
return {
|
|
24
|
+
machine: "workstation-a",
|
|
25
|
+
app: "Code",
|
|
26
|
+
windowTitle: "main.ts — editor",
|
|
27
|
+
contentHash: `hash-${overrides.id}`,
|
|
28
|
+
...overrides,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const BASE_INPUT = {
|
|
33
|
+
date: "2026-06-01",
|
|
34
|
+
timezone: "UTC",
|
|
35
|
+
observations: [
|
|
36
|
+
obs({ id: 1, capturedAtUtc: "2026-06-01T09:00:00.000Z" }),
|
|
37
|
+
obs({ id: 2, capturedAtUtc: "2026-06-01T09:01:00.000Z" }),
|
|
38
|
+
obs({ id: 3, capturedAtUtc: "2026-06-01T09:02:00.000Z" }),
|
|
39
|
+
obs({ id: 4, capturedAtUtc: "2026-06-01T09:40:00.000Z" }),
|
|
40
|
+
],
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
test("synthetic observations replay into byte-stable cards regardless of input order", () => {
|
|
44
|
+
const first = buildTimelineDay(BASE_INPUT);
|
|
45
|
+
const second = buildTimelineDay({ ...BASE_INPUT, observations: [...BASE_INPUT.observations].reverse() });
|
|
46
|
+
assert.equal(serializeTimelineDay(second), serializeTimelineDay(first));
|
|
47
|
+
// "Restart" isolation: a completely fresh call over equal content matches.
|
|
48
|
+
const third = buildTimelineDay(JSON.parse(JSON.stringify(BASE_INPUT)));
|
|
49
|
+
assert.equal(serializeTimelineDay(third), serializeTimelineDay(first));
|
|
50
|
+
assert.ok(first.cards.every((card) => card.id.startsWith("tlc_")));
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test("adjacent compatible observations merge; key changes and long gaps split cards", () => {
|
|
54
|
+
const day = buildTimelineDay(BASE_INPUT);
|
|
55
|
+
const activity = day.cards.filter((card) => card.kind === "activity");
|
|
56
|
+
assert.equal(activity.length, 2, "2-min gaps merge, a 38-min gap splits");
|
|
57
|
+
assert.deepEqual(activity[0].evidenceIds, [1, 2, 3]);
|
|
58
|
+
// Dwell caps at 15 min past the LAST observation: [09:00, 09:17), [09:40, 09:55).
|
|
59
|
+
assert.equal(activity[0].startUtc, "2026-06-01T09:00:00.000Z");
|
|
60
|
+
assert.equal(activity[0].endUtc, "2026-06-01T09:17:00.000Z");
|
|
61
|
+
assert.equal(activity[1].startUtc, "2026-06-01T09:40:00.000Z");
|
|
62
|
+
assert.equal(activity[1].endUtc, "2026-06-01T09:55:00.000Z");
|
|
63
|
+
// The >15-min remainder is a derived idle card with no evidence.
|
|
64
|
+
const idle = day.cards.filter((card) => card.kind === "idle");
|
|
65
|
+
assert.equal(idle.length, 1);
|
|
66
|
+
assert.equal(idle[0].categoryId, TIMELINE_RESERVED_IDLE);
|
|
67
|
+
assert.deepEqual(idle[0].evidenceIds, []);
|
|
68
|
+
assert.equal(idle[0].startUtc, "2026-06-01T09:17:00.000Z");
|
|
69
|
+
assert.equal(idle[0].endUtc, "2026-06-01T09:40:00.000Z");
|
|
70
|
+
|
|
71
|
+
// Same cadence but a different window title: two cards, contiguous, no idle.
|
|
72
|
+
const keyed = buildTimelineDay({
|
|
73
|
+
...BASE_INPUT,
|
|
74
|
+
observations: [
|
|
75
|
+
obs({ id: 1, capturedAtUtc: "2026-06-01T09:00:00.000Z" }),
|
|
76
|
+
obs({ id: 2, capturedAtUtc: "2026-06-01T09:01:00.000Z", windowTitle: "other.ts — editor" }),
|
|
77
|
+
],
|
|
78
|
+
});
|
|
79
|
+
const cards = keyed.cards.filter((card) => card.kind === "activity");
|
|
80
|
+
assert.equal(cards.length, 2);
|
|
81
|
+
assert.equal(cards[0].endUtc, cards[1].startUtc, "dwell stops at the next observation");
|
|
82
|
+
assert.equal(keyed.cards.filter((card) => card.kind === "idle").length, 0);
|
|
83
|
+
assert.equal(TIMELINE_MERGE_GAP_MS, 120_000, "merge gap contract");
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test("card dwell is clipped at the local day end (midnight)", () => {
|
|
87
|
+
const day = buildTimelineDay({
|
|
88
|
+
date: "2026-06-01",
|
|
89
|
+
timezone: "UTC",
|
|
90
|
+
observations: [obs({ id: 7, capturedAtUtc: "2026-06-01T23:59:00.000Z" })],
|
|
91
|
+
});
|
|
92
|
+
const card = day.cards[0];
|
|
93
|
+
assert.equal(card.startUtc, "2026-06-01T23:59:00.000Z");
|
|
94
|
+
assert.equal(card.endUtc, "2026-06-02T00:00:00.000Z", "15-min dwell must not cross midnight");
|
|
95
|
+
assert.equal(card.dayKey, "2026-06-01");
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
test("DST transition days bucket observations through the shifted window", () => {
|
|
99
|
+
// America/New_York springs forward 2026-03-08: the local day is 23 hours.
|
|
100
|
+
const window = activityDayWindow("2026-03-08", "America/New_York");
|
|
101
|
+
assert.equal(Date.parse(window.endUtc) - Date.parse(window.startUtc), 23 * 3_600_000);
|
|
102
|
+
const day = buildTimelineDay({
|
|
103
|
+
date: "2026-03-08",
|
|
104
|
+
timezone: "America/New_York",
|
|
105
|
+
observations: [
|
|
106
|
+
obs({ id: 11, capturedAtUtc: "2026-03-08T06:30:00.000Z" }),
|
|
107
|
+
obs({ id: 12, capturedAtUtc: "2026-03-08T06:31:00.000Z" }),
|
|
108
|
+
],
|
|
109
|
+
});
|
|
110
|
+
assert.equal(day.cards.length, 1);
|
|
111
|
+
assert.equal(day.cards[0].dayKey, "2026-03-08");
|
|
112
|
+
assert.equal(day.startUtc, window.startUtc);
|
|
113
|
+
// Fall-back day is 25 hours.
|
|
114
|
+
const fallWindow = activityDayWindow("2026-11-01", "America/New_York");
|
|
115
|
+
assert.equal(Date.parse(fallWindow.endUtc) - Date.parse(fallWindow.startUtc), 25 * 3_600_000);
|
|
116
|
+
});
|
|
117
|
+
test("user pause closes cards, is emitted as its own kind, and wins over idle", () => {
|
|
118
|
+
const day = buildTimelineDay({
|
|
119
|
+
...BASE_INPUT,
|
|
120
|
+
observations: [
|
|
121
|
+
obs({ id: 1, capturedAtUtc: "2026-06-01T10:00:00.000Z" }),
|
|
122
|
+
obs({ id: 2, capturedAtUtc: "2026-06-01T10:01:30.000Z" }),
|
|
123
|
+
obs({ id: 3, capturedAtUtc: "2026-06-01T11:00:00.000Z" }),
|
|
124
|
+
],
|
|
125
|
+
pauses: [{ startUtc: "2026-06-01T10:30:00.000Z", endUtc: "2026-06-01T11:00:00.000Z", reason: "lunch" }],
|
|
126
|
+
});
|
|
127
|
+
const pause = day.cards.filter((card) => card.kind === "pause");
|
|
128
|
+
assert.equal(pause.length, 1);
|
|
129
|
+
assert.equal(pause[0].categoryId, TIMELINE_RESERVED_PAUSE);
|
|
130
|
+
assert.deepEqual(pause[0].evidenceIds, []);
|
|
131
|
+
assert.ok(pause[0].summary.includes("lunch"));
|
|
132
|
+
const before = day.cards.find((card) => card.kind === "activity" && card.evidenceIds.includes(1));
|
|
133
|
+
assert.equal(before?.endUtc, "2026-06-01T10:16:30.000Z", "dwell (15m from last obs) ends before the pause");
|
|
134
|
+
// Dwell stops short of the pause, so the 13.5-min remainder is one idle
|
|
135
|
+
// card; the pause wins over idle covering the same minutes.
|
|
136
|
+
const idle = day.cards.filter((card) => card.kind === "idle");
|
|
137
|
+
assert.equal(idle.length, 1);
|
|
138
|
+
assert.equal(idle[0].startUtc, "2026-06-01T10:16:30.000Z");
|
|
139
|
+
assert.equal(idle[0].endUtc, "2026-06-01T10:30:00.000Z");
|
|
140
|
+
// No idle overlaps the pause interval itself.
|
|
141
|
+
assert.ok(idle.every((card) => card.endUtc <= pause[0].startUtc || card.startUtc >= pause[0].endUtc));
|
|
142
|
+
// Overlapping pauses union into one interval.
|
|
143
|
+
const unioned = buildTimelineDay({
|
|
144
|
+
date: "2026-06-01",
|
|
145
|
+
timezone: "UTC",
|
|
146
|
+
pauses: [
|
|
147
|
+
{ startUtc: "2026-06-01T10:00:00.000Z", endUtc: "2026-06-01T10:30:00.000Z" },
|
|
148
|
+
{ startUtc: "2026-06-01T10:20:00.000Z", endUtc: "2026-06-01T11:00:00.000Z" },
|
|
149
|
+
],
|
|
150
|
+
observations: [],
|
|
151
|
+
});
|
|
152
|
+
assert.equal(unioned.cards.length, 1);
|
|
153
|
+
assert.equal(unioned.cards[0].endUtc, "2026-06-01T11:00:00.000Z");
|
|
154
|
+
// A pause between two compatible observations still closes the card.
|
|
155
|
+
const split = buildTimelineDay({
|
|
156
|
+
date: "2026-06-01",
|
|
157
|
+
timezone: "UTC",
|
|
158
|
+
observations: [
|
|
159
|
+
obs({ id: 1, capturedAtUtc: "2026-06-01T09:00:00.000Z" }),
|
|
160
|
+
obs({ id: 2, capturedAtUtc: "2026-06-01T09:00:30.000Z" }),
|
|
161
|
+
],
|
|
162
|
+
pauses: [{ startUtc: "2026-06-01T09:00:10.000Z", endUtc: "2026-06-01T09:00:20.000Z" }],
|
|
163
|
+
});
|
|
164
|
+
assert.equal(split.cards.filter((card) => card.kind === "activity").length, 2);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
test("overlapping multi-machine tracks never merge across machines", () => {
|
|
168
|
+
const day = buildTimelineDay({
|
|
169
|
+
...BASE_INPUT,
|
|
170
|
+
observations: [
|
|
171
|
+
obs({ id: 1, machine: "ws-a", capturedAtUtc: "2026-06-01T09:00:00.000Z", app: "Chrome", windowTitle: "Docs" }),
|
|
172
|
+
obs({ id: 2, machine: "ws-b", capturedAtUtc: "2026-06-01T09:00:30.000Z", app: "Chrome", windowTitle: "Docs" }),
|
|
173
|
+
obs({ id: 3, machine: "ws-a", capturedAtUtc: "2026-06-01T09:01:00.000Z", app: "Chrome", windowTitle: "Docs" }),
|
|
174
|
+
],
|
|
175
|
+
});
|
|
176
|
+
const activity = day.cards.filter((card) => card.kind === "activity");
|
|
177
|
+
assert.equal(activity.length, 2);
|
|
178
|
+
assert.deepEqual(new Set(activity.map((card) => card.machine)), new Set(["ws-a", "ws-b"]));
|
|
179
|
+
// Global order is start-time first with a stable machine tie-break.
|
|
180
|
+
assert.ok(activity[0].startUtc <= activity[1].startUtc);
|
|
181
|
+
assert.equal(activity.find((card) => card.machine === "ws-a")?.evidenceIds.length, 2);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
test("unclassified activity stays visible in system.unknown; domains outrank app names", () => {
|
|
185
|
+
const unknown = classifyTimelineObservation({ app: "MysteryTool", windowTitle: "untitled" }, DEFAULT_TIMELINE_CATEGORIES);
|
|
186
|
+
assert.deepEqual(unknown, { categoryId: TIMELINE_RESERVED_UNKNOWN, confidence: 0 });
|
|
187
|
+
const day = buildTimelineDay({
|
|
188
|
+
date: "2026-06-01",
|
|
189
|
+
timezone: "UTC",
|
|
190
|
+
observations: [obs({ id: 1, capturedAtUtc: "2026-06-01T09:00:00.000Z", app: "MysteryTool", windowTitle: "untitled" })],
|
|
191
|
+
});
|
|
192
|
+
assert.equal(day.cards[0].categoryId, TIMELINE_RESERVED_UNKNOWN);
|
|
193
|
+
assert.equal(day.cards[0].confidence, 0);
|
|
194
|
+
// A browser on github.com is development (domain signal) even though the
|
|
195
|
+
// app rule alone would say browsing.
|
|
196
|
+
const classified = classifyTimelineObservation(
|
|
197
|
+
{ app: "Chrome", windowTitle: "feat: timeline", browserUrl: "https://github.com/org/repo" },
|
|
198
|
+
DEFAULT_TIMELINE_CATEGORIES,
|
|
199
|
+
);
|
|
200
|
+
assert.equal(classified.categoryId, "development");
|
|
201
|
+
assert.equal(classified.confidence, 0.85);
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
test("categories validate reserved/system rules and sort with equal-order tie-breaks", () => {
|
|
205
|
+
assert.throws(
|
|
206
|
+
() => validateTimelineCategories([{ id: "development", name: "x", color: "#3b82f6", description: "d", order: 1 }]),
|
|
207
|
+
/system\.unknown/,
|
|
208
|
+
);
|
|
209
|
+
assert.throws(
|
|
210
|
+
() =>
|
|
211
|
+
validateTimelineCategories([
|
|
212
|
+
...DEFAULT_TIMELINE_CATEGORIES,
|
|
213
|
+
{ id: "development", name: "dup", color: "#000000", description: "d", order: 5 },
|
|
214
|
+
]),
|
|
215
|
+
/unique/,
|
|
216
|
+
);
|
|
217
|
+
assert.throws(
|
|
218
|
+
() => validateTimelineCategories(DEFAULT_TIMELINE_CATEGORIES.map((c) => (c.id === "development" ? { ...c, color: "blue" } : c))),
|
|
219
|
+
/#RRGGBB/,
|
|
220
|
+
);
|
|
221
|
+
assert.throws(
|
|
222
|
+
() => validateTimelineCategories(DEFAULT_TIMELINE_CATEGORIES.map((c) => (c.id === "development" ? { ...c, system: true } : c))),
|
|
223
|
+
/only reserved categories/,
|
|
224
|
+
);
|
|
225
|
+
const equalOrder: TimelineCategory[] = [
|
|
226
|
+
{ id: "beta", name: "B", color: "#000001", description: "d", order: 50 },
|
|
227
|
+
{ id: "alpha", name: "A", color: "#000002", description: "d", order: 50 },
|
|
228
|
+
...DEFAULT_TIMELINE_CATEGORIES,
|
|
229
|
+
];
|
|
230
|
+
validateTimelineCategories(equalOrder);
|
|
231
|
+
const sorted = sortTimelineCategories(equalOrder);
|
|
232
|
+
assert.ok(sorted.findIndex((c) => c.id === "alpha") < sorted.findIndex((c) => c.id === "beta"), "equal order tie-breaks by id");
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
test("manual corrections survive a rebuild and reset reverts the card", () => {
|
|
236
|
+
const memoryDir = mkdtempSync(path.join(tmpdir(), "remnic-timeline-test-"));
|
|
237
|
+
try {
|
|
238
|
+
const store = TimelineCorrectionStore.open(memoryDir);
|
|
239
|
+
const day = buildTimelineDay(BASE_INPUT);
|
|
240
|
+
const target = day.cards[0];
|
|
241
|
+
store.upsert({ cardId: target.id, categoryId: "communication", title: "Morning standup", editedAtUtc: "2026-06-01T12:00:00.000Z" });
|
|
242
|
+
assert.throws(() => store.upsert({ cardId: target.id, categoryId: "nope", editedAtUtc: "2026-06-01T12:00:00.000Z" }), /unknown category/);
|
|
243
|
+
|
|
244
|
+
// "Rebuild" — same evidence, fresh build call, corrections reapplied.
|
|
245
|
+
const rebuiltDay = buildTimelineDay(BASE_INPUT);
|
|
246
|
+
const rebuilt = applyTimelineCorrections(rebuiltDay.cards, store.list());
|
|
247
|
+
const corrected = rebuilt.find((card) => card.id === target.id);
|
|
248
|
+
assert.equal(corrected?.title, "Morning standup");
|
|
249
|
+
assert.equal(corrected?.categoryId, "communication");
|
|
250
|
+
assert.equal(corrected?.confidence, 1);
|
|
251
|
+
assert.equal(corrected?.manualEdit?.editedAtUtc, "2026-06-01T12:00:00.000Z");
|
|
252
|
+
const untouched = rebuilt.find((card) => card.id !== target.id);
|
|
253
|
+
assert.deepEqual(untouched, rebuiltDay.cards.find((card) => card.id === untouched?.id));
|
|
254
|
+
|
|
255
|
+
// Explicit reset restores the derived card byte-for-byte.
|
|
256
|
+
assert.equal(store.reset(target.id), true);
|
|
257
|
+
assert.equal(store.reset(target.id), false);
|
|
258
|
+
const afterReset = applyTimelineCorrections(buildTimelineDay(BASE_INPUT).cards, store.list());
|
|
259
|
+
assert.deepEqual(afterReset.find((card) => card.id === target.id), target);
|
|
260
|
+
|
|
261
|
+
// Corrections persist across close/reopen (process restart).
|
|
262
|
+
store.close();
|
|
263
|
+
const reopened = TimelineCorrectionStore.open(memoryDir);
|
|
264
|
+
assert.equal(reopened.list().length, 0);
|
|
265
|
+
reopened.close();
|
|
266
|
+
} finally {
|
|
267
|
+
rmSync(memoryDir, { recursive: true, force: true });
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
test("activity.timeline config gate defaults off and parses explicitly", () => {
|
|
272
|
+
assert.equal(parseActivityConfig(undefined).timeline.enabled, false);
|
|
273
|
+
assert.equal(parseActivityConfig({ timeline: { enabled: true } }).timeline.enabled, true);
|
|
274
|
+
assert.equal(parseActivityConfig({ timeline: { enabled: "false" } }).timeline.enabled, false);
|
|
275
|
+
assert.throws(() => parseActivityConfig({ timeline: "on" }), /activity\.timeline must be an object/);
|
|
276
|
+
assert.throws(() => parseActivityConfig({ timeline: { enabled: "maybe" } }), /activity\.timeline\.enabled must be a boolean/);
|
|
277
|
+
});
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Timeline-card layer over the #1899 activity store (issue #2049).
|
|
3
|
+
*
|
|
4
|
+
* A card is a deterministic, replayable *derived view*: it references snapshot
|
|
5
|
+
* evidence by store row id and content identity, never copying or re-storing
|
|
6
|
+
* it. All intervals are half-open [start, end) UTC; day bucketing reuses the
|
|
7
|
+
* DST-aware `activityDayWindow` from the digest layer, so timeline days and
|
|
8
|
+
* digests always agree on day bounds.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/** Reference to one stored observation (subset of ActivitySnapshot; no text). */
|
|
12
|
+
export interface TimelineObservation {
|
|
13
|
+
/** Store row id of the referenced snapshot. */
|
|
14
|
+
id: number;
|
|
15
|
+
machine: string;
|
|
16
|
+
/** UTC ISO-8601 capture instant. */
|
|
17
|
+
capturedAtUtc: string;
|
|
18
|
+
app: string;
|
|
19
|
+
windowTitle: string;
|
|
20
|
+
/** Browser tab URL, when the frontmost window is a known browser. */
|
|
21
|
+
browserUrl?: string;
|
|
22
|
+
/** Content hash of the referenced snapshot (identity, not re-stored text). */
|
|
23
|
+
contentHash: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** User-declared pause, half-open [startUtc, endUtc) in UTC. Not idle. */
|
|
27
|
+
export interface TimelinePause {
|
|
28
|
+
startUtc: string;
|
|
29
|
+
endUtc: string;
|
|
30
|
+
/** Free-form reason, kept verbatim on the derived pause card. */
|
|
31
|
+
reason?: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** One category definition in the registry. */
|
|
35
|
+
export interface TimelineCategory {
|
|
36
|
+
/** Stable ID (`system.*` is the reserved namespace). */
|
|
37
|
+
id: string;
|
|
38
|
+
name: string;
|
|
39
|
+
/** Hex color, `#RRGGBB`. */
|
|
40
|
+
color: string;
|
|
41
|
+
description: string;
|
|
42
|
+
/** Presentation order; equal orders tie-break by id. */
|
|
43
|
+
order: number;
|
|
44
|
+
/** Reserved system category (idle / pause / unknown). */
|
|
45
|
+
system?: boolean;
|
|
46
|
+
/** Marks the reserved idle category. */
|
|
47
|
+
idle?: boolean;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export type TimelineCardKind = "activity" | "idle" | "pause";
|
|
51
|
+
|
|
52
|
+
/** Provenance stamped on a card when a manual correction was applied. */
|
|
53
|
+
export interface TimelineManualEdit {
|
|
54
|
+
categoryId?: string;
|
|
55
|
+
title?: string;
|
|
56
|
+
editedAtUtc: string;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** A persisted manual correction; keyed by stable card id, survives rebuilds. */
|
|
60
|
+
export interface TimelineCorrection {
|
|
61
|
+
cardId: string;
|
|
62
|
+
categoryId?: string;
|
|
63
|
+
title?: string;
|
|
64
|
+
editedAtUtc: string;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Stable first/last evidence identity keys bracketing a card's sources. */
|
|
68
|
+
export interface TimelineEvidenceRange {
|
|
69
|
+
firstKey: string;
|
|
70
|
+
lastKey: string;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export interface TimelineCard {
|
|
74
|
+
/** Stable content-derived id (never array position or wall-clock). */
|
|
75
|
+
id: string;
|
|
76
|
+
kind: TimelineCardKind;
|
|
77
|
+
title: string;
|
|
78
|
+
summary: string;
|
|
79
|
+
categoryId: string;
|
|
80
|
+
/** Classification confidence; manual corrections set it to 1. */
|
|
81
|
+
confidence: number;
|
|
82
|
+
/** Half-open [startUtc, endUtc) UTC bounds. */
|
|
83
|
+
startUtc: string;
|
|
84
|
+
endUtc: string;
|
|
85
|
+
/** Local day key (YYYY-MM-DD) this card belongs to. */
|
|
86
|
+
dayKey: string;
|
|
87
|
+
timezone: string;
|
|
88
|
+
/** Track the card was built on; null for machine-less pause cards. */
|
|
89
|
+
machine: string | null;
|
|
90
|
+
/** Store row ids of the source snapshots (empty for idle/pause). */
|
|
91
|
+
evidenceIds: number[];
|
|
92
|
+
/** First/last evidence identity keys (null for idle/pause). */
|
|
93
|
+
evidenceRange: TimelineEvidenceRange | null;
|
|
94
|
+
/** Present only when a manual correction was applied. */
|
|
95
|
+
manualEdit?: TimelineManualEdit;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** One replayable local day of cards. */
|
|
99
|
+
export interface TimelineDay {
|
|
100
|
+
formatVersion: number;
|
|
101
|
+
date: string;
|
|
102
|
+
timezone: string;
|
|
103
|
+
startUtc: string;
|
|
104
|
+
endUtc: string;
|
|
105
|
+
cards: TimelineCard[];
|
|
106
|
+
}
|