@remnic/core 9.66.0 → 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 -11
- package/dist/access-admin-ops-surface.js +22 -22
- package/dist/access-authorization-probe.d.ts +11 -11
- package/dist/access-authorization-probe.js +23 -23
- package/dist/access-boundary.d.ts +11 -11
- package/dist/access-boundary.js +22 -22
- package/dist/access-cli.js +86 -84
- package/dist/access-cli.js.map +1 -1
- package/dist/access-coding-context-resolution.d.ts +1 -1
- package/dist/access-extraction-force-flush.d.ts +11 -11
- package/dist/access-extraction-force-flush.js +22 -22
- package/dist/access-health-types.d.ts +1 -1
- package/dist/access-http-lcm-compaction.d.ts +11 -11
- package/dist/access-http-lifecycle-flush.d.ts +11 -11
- package/dist/access-http-offline-stream.d.ts +11 -11
- package/dist/access-http-query.d.ts +2 -2
- package/dist/access-http-query.js +24 -24
- package/dist/access-http.d.ts +12 -12
- package/dist/access-http.js +39 -39
- package/dist/access-identity-continuity-surface.d.ts +9 -9
- package/dist/access-identity-continuity-surface.js +22 -22
- package/dist/access-lcm-surface.d.ts +11 -11
- package/dist/access-lcm-surface.js +22 -22
- package/dist/access-mcp.d.ts +11 -11
- package/dist/access-mcp.js +29 -29
- package/dist/access-memory-search-fanout.d.ts +2 -2
- package/dist/{access-namespace-preflight-CLWUoMyW.d.ts → access-namespace-preflight-50VIkPhB.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +3 -3
- package/dist/access-namespace-preflight.js +22 -22
- package/dist/access-observe-write-surface.d.ts +11 -11
- package/dist/access-observe-write-surface.js +22 -22
- package/dist/access-offline-manifest.d.ts +9 -9
- package/dist/access-operations-batch.js +24 -24
- package/dist/access-operations.d.ts +16 -16
- package/dist/access-operations.js +28 -28
- package/dist/access-recall-concurrency.d.ts +11 -11
- package/dist/access-recall-concurrency.js +22 -22
- package/dist/access-recall-response.d.ts +11 -11
- package/dist/access-recall-response.js +22 -22
- package/dist/access-recall-surface.d.ts +11 -11
- package/dist/access-recall-surface.js +22 -22
- package/dist/access-schema.d.ts +89 -89
- package/dist/access-schema.js +3 -3
- package/dist/{access-service-CEUE1Isj.d.ts → access-service-C2tV2-uL.d.ts} +65 -65
- package/dist/access-service-helpers.d.ts +11 -11
- package/dist/access-service.d.ts +11 -11
- package/dist/access-service.js +22 -22
- package/dist/access-surface-catalog.d.ts +11 -11
- package/dist/access-surface-catalog.js +24 -24
- package/dist/access-wearables-meetings-surface.d.ts +3 -3
- package/dist/action-confidence.d.ts +1 -1
- package/dist/active-memory-bridge.d.ts +1 -1
- package/dist/active-recall.d.ts +1 -1
- package/dist/active-recall.js +2 -2
- package/dist/adapters/index.js +7 -7
- package/dist/adapters/registry.js +3 -3
- package/dist/ambient-provenance.d.ts +1 -1
- package/dist/artifact-search.d.ts +1 -1
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +9 -9
- package/dist/briefing-window.d.ts +2 -2
- package/dist/briefing.d.ts +2 -2
- package/dist/briefing.js +9 -9
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer-turn-helpers.d.ts +1 -1
- package/dist/buffer.d.ts +2 -2
- package/dist/bulk-import/index.d.ts +3 -3
- package/dist/calibration.d.ts +1 -1
- package/dist/capabilities.d.ts +1 -1
- package/dist/{catalog-D1HgugTA.d.ts → catalog-C2jA-gLm.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-consolidation.js +10 -10
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/{chunk-J3OND5QT.js → chunk-2FA7U5XY.js} +2 -2
- package/dist/{chunk-GEJKYA7D.js → chunk-2ITZ74A6.js} +9 -9
- package/dist/{chunk-2LBAFHOQ.js → chunk-2X6BGKQL.js} +8 -8
- package/dist/{chunk-KODXCHXJ.js → chunk-46XR5FNZ.js} +39 -3
- package/dist/chunk-46XR5FNZ.js.map +1 -0
- package/dist/{chunk-4STAANV7.js → chunk-4XLTUR6R.js} +3 -3
- package/dist/{chunk-FTTJRVB7.js → chunk-65JOGLIS.js} +2 -2
- package/dist/{chunk-FESUGFIL.js → chunk-7UOXCCCI.js} +2 -2
- package/dist/{chunk-PEBH5DCK.js → chunk-AF5H7TKI.js} +100 -18
- package/dist/chunk-AF5H7TKI.js.map +1 -0
- package/dist/{chunk-6CEGSTBD.js → chunk-B4AOWRYF.js} +4 -4
- package/dist/{chunk-FYWLSFFS.js → chunk-C5IUOBCN.js} +2 -2
- package/dist/{chunk-FKKGCGYL.js → chunk-CHGG74CY.js} +2 -2
- package/dist/{chunk-H7VDIF2V.js → chunk-CX4OLNIH.js} +2 -2
- package/dist/{chunk-Z3YEGSR4.js → chunk-D3UXGE5D.js} +10 -10
- package/dist/{chunk-7XOG75AU.js → chunk-D6Q5EPOV.js} +2 -2
- package/dist/{chunk-MJRGVXPQ.js → chunk-EH65UV2Z.js} +2 -2
- package/dist/{chunk-VQ4AMTGZ.js → chunk-EWKVYCFP.js} +1 -1
- package/dist/{chunk-23CVL7HS.js → chunk-FFUMTH27.js} +2 -2
- package/dist/{chunk-GX6FTSYH.js → chunk-GAJK3DQ5.js} +2 -2
- package/dist/{chunk-O57GM3FR.js → chunk-GBEOUCBB.js} +2 -2
- package/dist/{chunk-DMEHOEC7.js → chunk-H2IRSXZN.js} +3 -3
- 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-OAJMQKQR.js → chunk-IGZCAHFL.js} +2 -2
- package/dist/{chunk-CN4VKV3S.js → chunk-INUBU6I5.js} +2 -2
- package/dist/{chunk-CTCGHNWN.js → chunk-J2R275FN.js} +4 -4
- package/dist/{chunk-2QSZNTDO.js → chunk-JBPKEARU.js} +7 -7
- package/dist/{chunk-VQNRICAQ.js → chunk-JKTV3JNX.js} +3 -3
- package/dist/{chunk-33MFRY25.js → chunk-KI64TTBL.js} +2 -2
- package/dist/{chunk-VCKWULAK.js → chunk-KJXCD7VR.js} +5 -5
- package/dist/{chunk-7LCGFUMB.js → chunk-KQAFEZQX.js} +4 -4
- package/dist/{chunk-GSKINLAK.js → chunk-LJABGXC4.js} +3 -3
- package/dist/{chunk-NPIBN2VL.js → chunk-LK4TOYPU.js} +2 -2
- package/dist/{chunk-EZSCW4EM.js → chunk-LYUUA6QB.js} +2 -2
- package/dist/{chunk-I5VB44ZK.js → chunk-M5ERTI4I.js} +2 -2
- package/dist/{chunk-IHGMRDEE.js → chunk-MUEGIKKY.js} +227 -144
- package/dist/chunk-MUEGIKKY.js.map +1 -0
- package/dist/{chunk-QCRJMU5V.js → chunk-NFP4KPTA.js} +2 -2
- package/dist/{chunk-YXFCALVT.js → chunk-NSTNGMSS.js} +8 -8
- package/dist/{chunk-L4X4PJYK.js → chunk-NUF7VSEX.js} +2 -2
- package/dist/{chunk-IVIAHQBR.js → chunk-OJUEUQDJ.js} +2 -2
- package/dist/{chunk-ZW4VXELZ.js → chunk-OMX6TKXH.js} +2 -2
- package/dist/{chunk-EFQCDJZ2.js → chunk-QBNE55VA.js} +2 -2
- package/dist/{chunk-6QDXA26G.js → chunk-RPIS5FQ7.js} +47 -47
- package/dist/{chunk-HJXA6ZM7.js → chunk-S4CDUXQY.js} +2 -2
- package/dist/{chunk-72OIT7KS.js → chunk-S4Z2OBTX.js} +3 -3
- package/dist/{chunk-4FHRZD5T.js → chunk-SZMYGDSM.js} +2 -2
- package/dist/{chunk-MAH64N55.js → chunk-TBCDF556.js} +4 -4
- package/dist/{chunk-56IV4J5W.js → chunk-TCF4MU7L.js} +443 -58
- package/dist/chunk-TCF4MU7L.js.map +1 -0
- package/dist/{chunk-K66OY4EI.js → chunk-TCQRIIIN.js} +2 -2
- package/dist/{chunk-KXIXO76C.js → chunk-U65VJSCJ.js} +14 -14
- package/dist/{chunk-HNPE66LB.js → chunk-U6NGKS32.js} +7 -7
- package/dist/{chunk-WKJFIMVN.js → chunk-UW4RYPWC.js} +2 -2
- package/dist/{chunk-MN5NOOI7.js → chunk-VG4SSPAW.js} +2 -2
- package/dist/chunk-WFCWP4XU.js +17 -0
- package/dist/chunk-WFCWP4XU.js.map +1 -0
- package/dist/{chunk-UNUMFURP.js → chunk-X5PIDJ3L.js} +3 -3
- package/dist/{chunk-RZ3IZIJG.js → chunk-XOHYGIWF.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-6RUHELWR.js → chunk-YWPLOJ7T.js} +2 -2
- package/dist/{chunk-ZJPM7GZ3.js → chunk-ZPS724LT.js} +2 -2
- package/dist/{chunk-7UTDHQZ5.js → chunk-ZZZWEDF4.js} +2 -2
- package/dist/{cli-BEkm2MEf.d.ts → cli-CsfFMe6n.d.ts} +5 -5
- package/dist/cli.d.ts +13 -13
- package/dist/cli.js +63 -63
- package/dist/coding/export-okf-codegraph.d.ts +1 -1
- package/dist/coding/export-okf-codegraph.js +9 -9
- package/dist/coding/pre-action-gate.d.ts +1 -1
- package/dist/compounding/engine.d.ts +2 -2
- package/dist/compounding/engine.js +9 -9
- package/dist/compounding/preference-consolidator.d.ts +1 -1
- package/dist/compression-optimizer.d.ts +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js +2 -2
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +9 -9
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +9 -9
- package/dist/consolidation-provenance-check.d.ts +2 -2
- package/dist/consolidation-undo.d.ts +2 -2
- package/dist/contradiction/index.d.ts +3 -3
- package/dist/converge-config.d.ts +1 -1
- package/dist/convergence-refresh.d.ts +2 -2
- package/dist/convergence-refresh.js +11 -11
- package/dist/conversation-index/backend.d.ts +1 -1
- package/dist/conversation-index/chunker.d.ts +1 -1
- package/dist/conversation-index/faiss-adapter.d.ts +1 -1
- package/dist/conversation-index/indexer.d.ts +1 -1
- package/dist/conversation-index/search.d.ts +1 -1
- package/dist/corpus-watermark.d.ts +1 -1
- package/dist/corpus-watermark.js +11 -11
- package/dist/cross-lingual-recall.d.ts +1 -1
- package/dist/day-summary.d.ts +1 -1
- package/dist/delinearize.d.ts +1 -1
- package/dist/dependency-propagation-config.d.ts +1 -1
- package/dist/{dependency-propagation-delivery-BCpeo14F.d.ts → dependency-propagation-delivery-D4WMbOwA.d.ts} +1 -1
- package/dist/direct-answer-wiring.d.ts +1 -1
- package/dist/direct-answer.d.ts +1 -1
- package/dist/embedding-fallback.d.ts +1 -1
- package/dist/enrichment/index.d.ts +1 -1
- package/dist/entity-origin-fields.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +2 -2
- package/dist/entity-retrieval.js +9 -9
- package/dist/entity-schema.d.ts +1 -1
- package/dist/episodic-context.d.ts +1 -1
- package/dist/eval-trajectory-contracts.d.ts +1 -1
- package/dist/eval-trajectory-store.d.ts +1 -1
- package/dist/eval-trajectory.d.ts +1 -1
- package/dist/explicit-capture.d.ts +9 -9
- package/dist/external-wiki-access.d.ts +11 -11
- package/dist/external-wiki-access.js +23 -23
- package/dist/external-wiki-collection-registration.d.ts +1 -1
- package/dist/external-wiki-collection.d.ts +1 -1
- package/dist/external-wiki-mcp-tools.d.ts +11 -11
- package/dist/extraction-error-classification.d.ts +1 -1
- package/dist/extraction-faithfulness.d.ts +1 -1
- package/dist/extraction-judge-telemetry.d.ts +1 -1
- package/dist/extraction-judge-training.d.ts +1 -1
- package/dist/extraction-judge.d.ts +1 -1
- package/dist/extraction-liveness.d.ts +1 -1
- package/dist/extraction-normalization.d.ts +1 -1
- package/dist/extraction-prompt.d.ts +1 -1
- package/dist/extraction-source-grounding-rules.d.ts +1 -1
- package/dist/extraction-source-grounding.d.ts +1 -1
- package/dist/extraction.d.ts +1 -1
- package/dist/extraction.js +9 -9
- package/dist/fallback-llm.d.ts +1 -1
- package/dist/graph-dashboard-diff.d.ts +1 -1
- package/dist/graph-dashboard-key.d.ts +1 -1
- package/dist/graph-dashboard-parser.d.ts +1 -1
- package/dist/graph-edge-reinforcement.d.ts +1 -1
- package/dist/graph-path-reconstruction.d.ts +1 -1
- package/dist/graph-path-scoring.d.ts +1 -1
- package/dist/graph-snapshot.d.ts +1 -1
- package/dist/graph.d.ts +1 -1
- package/dist/harmonic-retrieval.js +1 -1
- package/dist/importance.d.ts +1 -1
- package/dist/importers/index.d.ts +1 -1
- package/dist/in-flight-reads.d.ts +1 -1
- package/dist/{index-D_pyMUaP.d.ts → index-DuJnzwHv.d.ts} +2 -2
- package/dist/index.d.ts +807 -698
- package/dist/index.js +130 -102
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/engine.js +4 -4
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/index.js +10 -10
- package/dist/lcm/tools.d.ts +1 -1
- package/dist/lifecycle.d.ts +1 -1
- package/dist/live-connectors-runner.d.ts +1 -1
- package/dist/local-llm.d.ts +1 -1
- package/dist/local-model-endpoint.d.ts +1 -1
- package/dist/location/index.d.ts +3 -3
- package/dist/location/index.js +11 -11
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/maintenance/memory-governance.js +9 -9
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +9 -9
- package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-projection.js +10 -10
- package/dist/{maintenance-DDUX9d6D.d.ts → maintenance-BBeaeYRR.d.ts} +3 -3
- package/dist/mcp-memory-inspector-app.d.ts +11 -11
- package/dist/memory-action-policy.d.ts +1 -1
- package/dist/memory-cache.d.ts +1 -1
- package/dist/memory-controller.d.ts +1 -1
- package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
- package/dist/memory-projection-store.d.ts +1 -1
- package/dist/memory-provenance.d.ts +1 -1
- package/dist/memory-snapshot.d.ts +1 -1
- package/dist/memory-subject-cli.d.ts +11 -11
- package/dist/memory-subject.d.ts +11 -11
- package/dist/memory-worth-outcomes.d.ts +2 -2
- package/dist/models-json.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +3 -3
- package/dist/namespaces/migrate.js +10 -10
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/search.js +5 -5
- package/dist/namespaces/storage.d.ts +3 -3
- package/dist/namespaces/storage.js +9 -9
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/offline-sync-impression-drain.d.ts +1 -1
- package/dist/operator-doctor-corpus.d.ts +1 -1
- package/dist/operator-doctor-corpus.js +12 -12
- package/dist/operator-doctor-replica.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +3 -3
- package/dist/operator-toolkit.js +19 -19
- package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
- package/dist/orchestration/maintenance.d.ts +4 -4
- package/dist/orchestration/maintenance.js +18 -18
- package/dist/{orchestrator-3F4jihCo.d.ts → orchestrator-CaqnwNwM.d.ts} +8 -8
- package/dist/orchestrator.d.ts +9 -9
- package/dist/orchestrator.js +86 -84
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/{pipeline-CB1dj6Uh.d.ts → pipeline-CrxVjlJr.d.ts} +1 -1
- package/dist/policy-runtime.d.ts +1 -1
- package/dist/proactive-contention.d.ts +1 -1
- package/dist/provenance.d.ts +1 -1
- package/dist/{public-http-34-JIAGQ.d.ts → public-http-Cwvl4QZr.d.ts} +1 -1
- package/dist/{qmd-edLLZXc5.d.ts → qmd-BZgbJm0g.d.ts} +1 -1
- package/dist/qmd-preflight.d.ts +2 -2
- package/dist/qmd-recall-cache.d.ts +1 -1
- package/dist/qmd.d.ts +2 -2
- package/dist/recall-concurrency-config.d.ts +1 -1
- 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 -1
- package/dist/recall-explain-renderer.d.ts +1 -1
- package/dist/recall-explain-renderer.js +3 -3
- package/dist/recall-memory-map.d.ts +1 -1
- 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 -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-wire.js.map +1 -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 -1
- package/dist/recall-tag-filter.d.ts +1 -1
- package/dist/recall-timings.d.ts +1 -1
- package/dist/recall-xray-cli.d.ts +1 -1
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.d.ts +1 -1
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.d.ts +1 -1
- package/dist/recall-xray.js +2 -2
- package/dist/reconcile/cursor.d.ts +1 -1
- package/dist/reconcile/manifest.d.ts +1 -1
- package/dist/reconcile/plan.d.ts +1 -1
- package/dist/replay/normalizers/chatgpt.d.ts +1 -1
- package/dist/replay/normalizers/claude.d.ts +1 -1
- package/dist/replay/normalizers/openclaw.d.ts +1 -1
- package/dist/replay/normalizers/shared.d.ts +1 -1
- package/dist/replay/runner.d.ts +1 -1
- package/dist/replay/types.d.ts +1 -1
- package/dist/replica-divergence.d.ts +1 -1
- package/dist/replica-peers-config.d.ts +1 -1
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/resume-bundles.js +3 -3
- package/dist/retrieval-agents.d.ts +2 -2
- package/dist/retrieval-tiers.d.ts +1 -1
- package/dist/routing/engine.d.ts +1 -1
- package/dist/routing/store.d.ts +1 -1
- package/dist/salvage-envelope.d.ts +1 -1
- package/dist/schemas.d.ts +152 -152
- package/dist/{scope-profiles-BF2lu81V.d.ts → scope-profiles-DFaojvoP.d.ts} +1 -1
- package/dist/search/embed-helper.d.ts +1 -1
- package/dist/search/factory.d.ts +1 -1
- package/dist/search/factory.js +4 -4
- package/dist/search/index.d.ts +1 -1
- package/dist/search/index.js +10 -10
- package/dist/search/lancedb-backend.d.ts +1 -1
- package/dist/search/meilisearch-backend.d.ts +1 -1
- package/dist/search/noop-backend.d.ts +1 -1
- package/dist/search/orama-backend.d.ts +1 -1
- package/dist/search/port.d.ts +1 -1
- package/dist/search/remote-backend.d.ts +1 -1
- package/dist/{semantic-consolidation-5OuWXBRt.d.ts → semantic-consolidation-BiX68wZA.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +10 -10
- package/dist/semantic-rule-promotion.js +9 -9
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +9 -9
- package/dist/{service-CrqEhLXD.d.ts → service-D5h2zZ0M.d.ts} +2 -2
- package/dist/session-observer-bands.d.ts +1 -1
- package/dist/session-observer-state.d.ts +1 -1
- package/dist/shared-context/manager.d.ts +7 -7
- package/dist/signal.d.ts +1 -1
- package/dist/source-agent-qualifier.d.ts +1 -1
- package/dist/source-agent-qualifier.js +9 -9
- package/dist/{storage-BQn-xnxm.d.ts → storage-CtsaojWD.d.ts} +1 -1
- package/dist/storage.d.ts +2 -2
- package/dist/storage.js +8 -8
- package/dist/subject-config.d.ts +1 -1
- package/dist/summarizer.d.ts +1 -1
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/support-passport/index.d.ts +14 -14
- package/dist/support-passport/index.js +25 -25
- package/dist/temporal-supersession.d.ts +2 -2
- package/dist/temporal-timeline-recall.d.ts +1 -1
- package/dist/temporal-validity.d.ts +1 -1
- package/dist/threading.d.ts +1 -1
- package/dist/tier-migration.d.ts +2 -2
- package/dist/tier-routing.d.ts +1 -1
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/transfer/capsule-export.js +2 -2
- package/dist/transfer/capsule-import.js +2 -2
- package/dist/transfer/export-okf.d.ts +1 -1
- package/dist/transfer/export-okf.js +10 -10
- package/dist/transfer/types.d.ts +78 -78
- package/dist/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/{types-BRpcNjHZ.d.ts → types-CIpfYz1I.d.ts} +16 -11
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/dist/utility-runtime.d.ts +1 -1
- package/dist/verified-recall.js +9 -9
- package/dist/who-knows-cli.d.ts +11 -11
- package/dist/who-knows-cli.js +10 -10
- package/dist/who-knows.d.ts +11 -11
- package/dist/who-knows.js +9 -9
- package/dist/write-envelope.d.ts +1 -1
- package/package.json +2 -2
- package/src/activity/config.test.ts +1 -1
- package/src/activity/config.ts +48 -3
- package/src/activity/index.ts +2 -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/index.ts +2 -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/weekly.test.ts +215 -0
- package/src/activity/timeline/weekly.ts +234 -0
- package/src/activity/types.ts +14 -0
- package/src/activity/vault-publish.test.ts +166 -0
- package/src/activity/vault-publish.ts +101 -0
- package/src/config.test.ts +1 -1
- 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/location/recall-exclusion.test.ts +1 -0
- package/src/orchestration/extraction-persist.ts +22 -23
- package/src/orchestration/generic-recall-paths.ts +11 -0
- 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/shared-context/governance.test.ts +53 -0
- package/src/shared-context/governance.ts +86 -0
- package/src/types.ts +3 -10
- package/dist/chunk-56IV4J5W.js.map +0 -1
- package/dist/chunk-IHGMRDEE.js.map +0 -1
- package/dist/chunk-KODXCHXJ.js.map +0 -1
- package/dist/chunk-PEBH5DCK.js.map +0 -1
- /package/dist/{chunk-J3OND5QT.js.map → chunk-2FA7U5XY.js.map} +0 -0
- /package/dist/{chunk-GEJKYA7D.js.map → chunk-2ITZ74A6.js.map} +0 -0
- /package/dist/{chunk-2LBAFHOQ.js.map → chunk-2X6BGKQL.js.map} +0 -0
- /package/dist/{chunk-4STAANV7.js.map → chunk-4XLTUR6R.js.map} +0 -0
- /package/dist/{chunk-FTTJRVB7.js.map → chunk-65JOGLIS.js.map} +0 -0
- /package/dist/{chunk-FESUGFIL.js.map → chunk-7UOXCCCI.js.map} +0 -0
- /package/dist/{chunk-6CEGSTBD.js.map → chunk-B4AOWRYF.js.map} +0 -0
- /package/dist/{chunk-FYWLSFFS.js.map → chunk-C5IUOBCN.js.map} +0 -0
- /package/dist/{chunk-FKKGCGYL.js.map → chunk-CHGG74CY.js.map} +0 -0
- /package/dist/{chunk-H7VDIF2V.js.map → chunk-CX4OLNIH.js.map} +0 -0
- /package/dist/{chunk-Z3YEGSR4.js.map → chunk-D3UXGE5D.js.map} +0 -0
- /package/dist/{chunk-7XOG75AU.js.map → chunk-D6Q5EPOV.js.map} +0 -0
- /package/dist/{chunk-MJRGVXPQ.js.map → chunk-EH65UV2Z.js.map} +0 -0
- /package/dist/{chunk-VQ4AMTGZ.js.map → chunk-EWKVYCFP.js.map} +0 -0
- /package/dist/{chunk-23CVL7HS.js.map → chunk-FFUMTH27.js.map} +0 -0
- /package/dist/{chunk-GX6FTSYH.js.map → chunk-GAJK3DQ5.js.map} +0 -0
- /package/dist/{chunk-O57GM3FR.js.map → chunk-GBEOUCBB.js.map} +0 -0
- /package/dist/{chunk-DMEHOEC7.js.map → chunk-H2IRSXZN.js.map} +0 -0
- /package/dist/{chunk-CFVTRUR3.js.map → chunk-H6RSANGQ.js.map} +0 -0
- /package/dist/{chunk-OAJMQKQR.js.map → chunk-IGZCAHFL.js.map} +0 -0
- /package/dist/{chunk-CN4VKV3S.js.map → chunk-INUBU6I5.js.map} +0 -0
- /package/dist/{chunk-CTCGHNWN.js.map → chunk-J2R275FN.js.map} +0 -0
- /package/dist/{chunk-2QSZNTDO.js.map → chunk-JBPKEARU.js.map} +0 -0
- /package/dist/{chunk-VQNRICAQ.js.map → chunk-JKTV3JNX.js.map} +0 -0
- /package/dist/{chunk-33MFRY25.js.map → chunk-KI64TTBL.js.map} +0 -0
- /package/dist/{chunk-VCKWULAK.js.map → chunk-KJXCD7VR.js.map} +0 -0
- /package/dist/{chunk-7LCGFUMB.js.map → chunk-KQAFEZQX.js.map} +0 -0
- /package/dist/{chunk-GSKINLAK.js.map → chunk-LJABGXC4.js.map} +0 -0
- /package/dist/{chunk-NPIBN2VL.js.map → chunk-LK4TOYPU.js.map} +0 -0
- /package/dist/{chunk-EZSCW4EM.js.map → chunk-LYUUA6QB.js.map} +0 -0
- /package/dist/{chunk-I5VB44ZK.js.map → chunk-M5ERTI4I.js.map} +0 -0
- /package/dist/{chunk-QCRJMU5V.js.map → chunk-NFP4KPTA.js.map} +0 -0
- /package/dist/{chunk-YXFCALVT.js.map → chunk-NSTNGMSS.js.map} +0 -0
- /package/dist/{chunk-L4X4PJYK.js.map → chunk-NUF7VSEX.js.map} +0 -0
- /package/dist/{chunk-IVIAHQBR.js.map → chunk-OJUEUQDJ.js.map} +0 -0
- /package/dist/{chunk-ZW4VXELZ.js.map → chunk-OMX6TKXH.js.map} +0 -0
- /package/dist/{chunk-EFQCDJZ2.js.map → chunk-QBNE55VA.js.map} +0 -0
- /package/dist/{chunk-6QDXA26G.js.map → chunk-RPIS5FQ7.js.map} +0 -0
- /package/dist/{chunk-HJXA6ZM7.js.map → chunk-S4CDUXQY.js.map} +0 -0
- /package/dist/{chunk-72OIT7KS.js.map → chunk-S4Z2OBTX.js.map} +0 -0
- /package/dist/{chunk-4FHRZD5T.js.map → chunk-SZMYGDSM.js.map} +0 -0
- /package/dist/{chunk-MAH64N55.js.map → chunk-TBCDF556.js.map} +0 -0
- /package/dist/{chunk-K66OY4EI.js.map → chunk-TCQRIIIN.js.map} +0 -0
- /package/dist/{chunk-KXIXO76C.js.map → chunk-U65VJSCJ.js.map} +0 -0
- /package/dist/{chunk-HNPE66LB.js.map → chunk-U6NGKS32.js.map} +0 -0
- /package/dist/{chunk-WKJFIMVN.js.map → chunk-UW4RYPWC.js.map} +0 -0
- /package/dist/{chunk-MN5NOOI7.js.map → chunk-VG4SSPAW.js.map} +0 -0
- /package/dist/{chunk-UNUMFURP.js.map → chunk-X5PIDJ3L.js.map} +0 -0
- /package/dist/{chunk-RZ3IZIJG.js.map → chunk-XOHYGIWF.js.map} +0 -0
- /package/dist/{chunk-6RUHELWR.js.map → chunk-YWPLOJ7T.js.map} +0 -0
- /package/dist/{chunk-ZJPM7GZ3.js.map → chunk-ZPS724LT.js.map} +0 -0
- /package/dist/{chunk-7UTDHQZ5.js.map → chunk-ZZZWEDF4.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,215 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import test from "node:test";
|
|
3
|
+
|
|
4
|
+
import type { TimelineCard, TimelineCategory } from "./types.js";
|
|
5
|
+
import { buildWeeklyActivitySummary } from "./weekly.js";
|
|
6
|
+
|
|
7
|
+
const HOUR = 3_600_000;
|
|
8
|
+
const DAY = 86_400_000;
|
|
9
|
+
const WEEK_START = "2026-07-13T00:00:00.000Z";
|
|
10
|
+
const WEEK_END = "2026-07-20T00:00:00.000Z";
|
|
11
|
+
const WEEK_MS = 7 * DAY;
|
|
12
|
+
|
|
13
|
+
const CATEGORIES: TimelineCategory[] = [
|
|
14
|
+
{ id: "alpha", name: "Alpha", color: "#111111", description: "a", order: 1 },
|
|
15
|
+
{ id: "beta", name: "Beta", color: "#222222", description: "b", order: 2 },
|
|
16
|
+
{ id: "development", name: "Development", color: "#333333", description: "d", order: 3 },
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
function card(
|
|
20
|
+
overrides: Partial<TimelineCard> & Pick<TimelineCard, "id" | "startUtc" | "endUtc">,
|
|
21
|
+
): TimelineCard {
|
|
22
|
+
return {
|
|
23
|
+
kind: "activity",
|
|
24
|
+
title: "Untitled",
|
|
25
|
+
summary: "none",
|
|
26
|
+
categoryId: "development",
|
|
27
|
+
confidence: 1,
|
|
28
|
+
dayKey: overrides.startUtc.slice(0, 10),
|
|
29
|
+
timezone: "UTC",
|
|
30
|
+
machine: "ws-a",
|
|
31
|
+
evidenceIds: [],
|
|
32
|
+
evidenceRange: null,
|
|
33
|
+
...overrides,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function options(overrides: Partial<Parameters<typeof buildWeeklyActivitySummary>[1]> = {}) {
|
|
38
|
+
return {
|
|
39
|
+
timezone: "UTC",
|
|
40
|
+
weekStartUtc: WEEK_START,
|
|
41
|
+
weekEndUtc: WEEK_END,
|
|
42
|
+
categories: CATEGORIES,
|
|
43
|
+
...overrides,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
test("empty week reports zeros, full gap, and previous period unavailable", () => {
|
|
48
|
+
const summary = buildWeeklyActivitySummary([], options());
|
|
49
|
+
assert.equal(summary.formatVersion, 1);
|
|
50
|
+
assert.equal(summary.activeMs, 0);
|
|
51
|
+
assert.equal(summary.idleMs, 0);
|
|
52
|
+
assert.equal(summary.pauseMs, 0);
|
|
53
|
+
assert.equal(summary.unclassifiedMs, 0);
|
|
54
|
+
assert.equal(summary.gapMs, WEEK_MS);
|
|
55
|
+
assert.deepEqual(
|
|
56
|
+
summary.categories.map((row) => row.durationMs),
|
|
57
|
+
[0, 0, 0],
|
|
58
|
+
);
|
|
59
|
+
assert.equal(summary.days.length, 7);
|
|
60
|
+
assert.ok(summary.days.every((day) => day.gapMs === DAY && day.activeMs === 0));
|
|
61
|
+
assert.deepEqual(summary.previousPeriod, { available: false });
|
|
62
|
+
assert.equal("durationMs" in summary.previousPeriod, false);
|
|
63
|
+
const blob = JSON.stringify(summary);
|
|
64
|
+
assert.equal(/productivity|mood|intent|score/i.test(blob), false);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test("exact midnight boundary is not double-counted", () => {
|
|
68
|
+
const summary = buildWeeklyActivitySummary(
|
|
69
|
+
[
|
|
70
|
+
card({
|
|
71
|
+
id: "ends-at-midnight",
|
|
72
|
+
categoryId: "alpha",
|
|
73
|
+
startUtc: "2026-07-13T23:00:00.000Z",
|
|
74
|
+
endUtc: "2026-07-14T00:00:00.000Z",
|
|
75
|
+
}),
|
|
76
|
+
card({
|
|
77
|
+
id: "starts-at-midnight",
|
|
78
|
+
categoryId: "beta",
|
|
79
|
+
startUtc: "2026-07-14T00:00:00.000Z",
|
|
80
|
+
endUtc: "2026-07-14T01:00:00.000Z",
|
|
81
|
+
}),
|
|
82
|
+
card({
|
|
83
|
+
id: "before-week",
|
|
84
|
+
categoryId: "development",
|
|
85
|
+
startUtc: "2026-07-12T23:00:00.000Z",
|
|
86
|
+
endUtc: WEEK_START,
|
|
87
|
+
}),
|
|
88
|
+
card({
|
|
89
|
+
id: "after-week",
|
|
90
|
+
categoryId: "development",
|
|
91
|
+
startUtc: WEEK_END,
|
|
92
|
+
endUtc: "2026-07-20T01:00:00.000Z",
|
|
93
|
+
}),
|
|
94
|
+
],
|
|
95
|
+
options(),
|
|
96
|
+
);
|
|
97
|
+
assert.equal(summary.categories.find((row) => row.categoryId === "alpha")?.durationMs, HOUR);
|
|
98
|
+
assert.equal(summary.categories.find((row) => row.categoryId === "beta")?.durationMs, HOUR);
|
|
99
|
+
assert.equal(summary.categories.find((row) => row.categoryId === "development")?.durationMs, 0);
|
|
100
|
+
assert.equal(summary.activeMs, 2 * HOUR);
|
|
101
|
+
|
|
102
|
+
const day13 = summary.days.find((day) => day.date === "2026-07-13");
|
|
103
|
+
const day14 = summary.days.find((day) => day.date === "2026-07-14");
|
|
104
|
+
assert.equal(day13?.categories.find((row) => row.categoryId === "alpha")?.durationMs, HOUR);
|
|
105
|
+
assert.equal(day13?.categories.find((row) => row.categoryId === "beta")?.durationMs, 0);
|
|
106
|
+
assert.equal(day14?.categories.find((row) => row.categoryId === "beta")?.durationMs, HOUR);
|
|
107
|
+
assert.equal(day14?.categories.find((row) => row.categoryId === "alpha")?.durationMs, 0);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
test("idle and pause kinds are distinct from active", () => {
|
|
111
|
+
const summary = buildWeeklyActivitySummary(
|
|
112
|
+
[
|
|
113
|
+
card({
|
|
114
|
+
id: "work",
|
|
115
|
+
startUtc: "2026-07-13T10:00:00.000Z",
|
|
116
|
+
endUtc: "2026-07-13T11:00:00.000Z",
|
|
117
|
+
}),
|
|
118
|
+
card({
|
|
119
|
+
id: "idle",
|
|
120
|
+
kind: "idle",
|
|
121
|
+
categoryId: "alpha",
|
|
122
|
+
startUtc: "2026-07-13T11:00:00.000Z",
|
|
123
|
+
endUtc: "2026-07-13T11:30:00.000Z",
|
|
124
|
+
}),
|
|
125
|
+
card({
|
|
126
|
+
id: "pause",
|
|
127
|
+
kind: "pause",
|
|
128
|
+
categoryId: "beta",
|
|
129
|
+
startUtc: "2026-07-13T11:30:00.000Z",
|
|
130
|
+
endUtc: "2026-07-13T11:45:00.000Z",
|
|
131
|
+
}),
|
|
132
|
+
],
|
|
133
|
+
options(),
|
|
134
|
+
);
|
|
135
|
+
assert.equal(summary.activeMs, HOUR);
|
|
136
|
+
assert.equal(summary.idleMs, 30 * 60_000);
|
|
137
|
+
assert.equal(summary.pauseMs, 15 * 60_000);
|
|
138
|
+
assert.equal(summary.gapMs, WEEK_MS - HOUR - 30 * 60_000 - 15 * 60_000);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
test("unknown category is unclassified, not a silent zero row", () => {
|
|
142
|
+
const summary = buildWeeklyActivitySummary(
|
|
143
|
+
[
|
|
144
|
+
card({
|
|
145
|
+
id: "mystery",
|
|
146
|
+
categoryId: "not-configured",
|
|
147
|
+
startUtc: "2026-07-15T08:00:00.000Z",
|
|
148
|
+
endUtc: "2026-07-15T09:00:00.000Z",
|
|
149
|
+
}),
|
|
150
|
+
],
|
|
151
|
+
options(),
|
|
152
|
+
);
|
|
153
|
+
assert.equal(summary.unclassifiedMs, HOUR);
|
|
154
|
+
assert.equal(summary.activeMs, HOUR);
|
|
155
|
+
assert.equal(summary.categories.some((row) => row.categoryId === "not-configured"), false);
|
|
156
|
+
assert.ok(summary.categories.every((row) => row.durationMs === 0));
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
test("configured category with no cards stays at zero", () => {
|
|
160
|
+
const summary = buildWeeklyActivitySummary(
|
|
161
|
+
[
|
|
162
|
+
card({
|
|
163
|
+
id: "only-dev",
|
|
164
|
+
categoryId: "development",
|
|
165
|
+
startUtc: "2026-07-16T12:00:00.000Z",
|
|
166
|
+
endUtc: "2026-07-16T13:00:00.000Z",
|
|
167
|
+
}),
|
|
168
|
+
],
|
|
169
|
+
options(),
|
|
170
|
+
);
|
|
171
|
+
const byId = Object.fromEntries(summary.categories.map((row) => [row.categoryId, row.durationMs]));
|
|
172
|
+
assert.equal(byId.development, HOUR);
|
|
173
|
+
assert.equal(byId.alpha, 0);
|
|
174
|
+
assert.equal(byId.beta, 0);
|
|
175
|
+
assert.equal(summary.categories.length, 3);
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
test("equal durations sort by categoryId ascending", () => {
|
|
179
|
+
const summary = buildWeeklyActivitySummary(
|
|
180
|
+
[
|
|
181
|
+
card({
|
|
182
|
+
id: "a",
|
|
183
|
+
categoryId: "alpha",
|
|
184
|
+
startUtc: "2026-07-13T09:00:00.000Z",
|
|
185
|
+
endUtc: "2026-07-13T10:00:00.000Z",
|
|
186
|
+
}),
|
|
187
|
+
card({
|
|
188
|
+
id: "b",
|
|
189
|
+
categoryId: "beta",
|
|
190
|
+
startUtc: "2026-07-13T10:00:00.000Z",
|
|
191
|
+
endUtc: "2026-07-13T12:00:00.000Z",
|
|
192
|
+
}),
|
|
193
|
+
card({
|
|
194
|
+
id: "d",
|
|
195
|
+
categoryId: "development",
|
|
196
|
+
startUtc: "2026-07-13T12:00:00.000Z",
|
|
197
|
+
endUtc: "2026-07-13T14:00:00.000Z",
|
|
198
|
+
}),
|
|
199
|
+
],
|
|
200
|
+
options(),
|
|
201
|
+
);
|
|
202
|
+
assert.deepEqual(
|
|
203
|
+
summary.categories.map((row) => row.categoryId),
|
|
204
|
+
["beta", "development", "alpha"],
|
|
205
|
+
);
|
|
206
|
+
assert.deepEqual(
|
|
207
|
+
summary.categories.map((row) => row.durationMs),
|
|
208
|
+
[2 * HOUR, 2 * HOUR, HOUR],
|
|
209
|
+
);
|
|
210
|
+
const day13 = summary.days.find((day) => day.date === "2026-07-13");
|
|
211
|
+
assert.deepEqual(
|
|
212
|
+
day13?.categories.map((row) => row.categoryId),
|
|
213
|
+
["beta", "development", "alpha"],
|
|
214
|
+
);
|
|
215
|
+
});
|