@remnic/core 1.1.11 → 1.1.12
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/README.md +3 -3
- package/dist/access-cli.js +67 -59
- package/dist/access-cli.js.map +1 -1
- package/dist/access-http.d.ts +7 -4
- package/dist/access-http.js +30 -26
- package/dist/access-mcp.d.ts +9 -4
- package/dist/access-mcp.js +29 -25
- package/dist/access-schema.d.ts +188 -8
- package/dist/access-schema.js +12 -3
- package/dist/{access-service-BkXt3di1.d.ts → access-service-DDjzFALq.d.ts} +60 -11
- package/dist/access-service.d.ts +7 -4
- package/dist/access-service.js +26 -23
- package/dist/action-confidence.d.ts +83 -0
- package/dist/action-confidence.js +22 -0
- package/dist/active-memory-bridge.d.ts +1 -1
- package/dist/active-recall.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 +4 -2
- package/dist/briefing.d.ts +1 -1
- package/dist/briefing.js +5 -5
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer.d.ts +1 -1
- package/dist/calibration.d.ts +1 -1
- package/dist/calibration.js +4 -4
- package/dist/{capsule-export-LLEVB2RG.js → capsule-export-7QNCBZOQ.js} +3 -3
- package/dist/{capsule-import-UW45R2MZ.js → capsule-import-EPBHD2EN.js} +3 -3
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-consolidation.js +11 -11
- package/dist/{chunk-VQXK37XA.js → chunk-23ZZK64Y.js} +1 -1
- package/dist/chunk-23ZZK64Y.js.map +1 -0
- package/dist/{chunk-HJYHRE4S.js → chunk-242S3I2A.js} +2 -2
- package/dist/{chunk-MCC6KDQF.js → chunk-3B6KIRBH.js} +131 -13
- package/dist/chunk-3B6KIRBH.js.map +1 -0
- package/dist/chunk-4RA3C3EV.js +60 -0
- package/dist/chunk-4RA3C3EV.js.map +1 -0
- package/dist/{chunk-EYNQTST2.js → chunk-4YM32CRU.js} +4 -4
- package/dist/{chunk-6AUUAZEX.js → chunk-5NXIJZFX.js} +38 -8
- package/dist/chunk-5NXIJZFX.js.map +1 -0
- package/dist/chunk-6NKAQ74D.js +2237 -0
- package/dist/chunk-6NKAQ74D.js.map +1 -0
- package/dist/{chunk-PHNGXFQ6.js → chunk-7V22HTMD.js} +3 -3
- package/dist/{chunk-363MWCD3.js → chunk-7ZM3BFKK.js} +84 -62
- package/dist/chunk-7ZM3BFKK.js.map +1 -0
- package/dist/chunk-AC5LO7IU.js +308 -0
- package/dist/chunk-AC5LO7IU.js.map +1 -0
- package/dist/chunk-AH2JUU6X.js +336 -0
- package/dist/chunk-AH2JUU6X.js.map +1 -0
- package/dist/{chunk-VX2IUQFE.js → chunk-AQJNPMOA.js} +41 -11
- package/dist/chunk-AQJNPMOA.js.map +1 -0
- package/dist/{chunk-P73JTV34.js → chunk-BBE34QBJ.js} +4 -4
- package/dist/{chunk-KUHRUM6B.js → chunk-BZSQEPRW.js} +452 -139
- package/dist/chunk-BZSQEPRW.js.map +1 -0
- package/dist/chunk-C5BCH4ZS.js +317 -0
- package/dist/chunk-C5BCH4ZS.js.map +1 -0
- package/dist/{chunk-C5HUWVH2.js → chunk-CPKTBRS2.js} +6 -6
- package/dist/{chunk-IBX3VFOM.js → chunk-D4GAOFF6.js} +118 -2
- package/dist/chunk-D4GAOFF6.js.map +1 -0
- package/dist/chunk-DB5A3NHS.js +906 -0
- package/dist/chunk-DB5A3NHS.js.map +1 -0
- package/dist/{chunk-I6BQZSML.js → chunk-DZZPC36E.js} +10 -10
- package/dist/{chunk-O4XJUPSF.js → chunk-E2UCDP5S.js} +39 -2
- package/dist/chunk-E2UCDP5S.js.map +1 -0
- package/dist/{chunk-SRBJUAMP.js → chunk-FMEBPEAO.js} +11 -67
- package/dist/chunk-FMEBPEAO.js.map +1 -0
- package/dist/{chunk-4DXC6HQQ.js → chunk-FQDPCE3I.js} +5 -5
- package/dist/{chunk-NN3LPQ5D.js → chunk-HELQZFZO.js} +155 -16
- package/dist/chunk-HELQZFZO.js.map +1 -0
- package/dist/{chunk-57QNCUEZ.js → chunk-HL5LRPNA.js} +2 -2
- package/dist/{chunk-VTU2B4VF.js → chunk-HQZVVSVB.js} +2 -1
- package/dist/chunk-HQZVVSVB.js.map +1 -0
- package/dist/{chunk-6Z6UH6TK.js → chunk-HY3L4WKC.js} +69 -3
- package/dist/chunk-HY3L4WKC.js.map +1 -0
- package/dist/{chunk-QIGOEM65.js → chunk-IB3BFHGN.js} +5 -5
- package/dist/{chunk-RXTFCYQF.js → chunk-JESOB2HO.js} +6 -6
- package/dist/{chunk-2YMTO4ZJ.js → chunk-JKDVIE52.js} +9 -2
- package/dist/chunk-JKDVIE52.js.map +1 -0
- package/dist/{chunk-WGK4VHGP.js → chunk-MNU6ZBWT.js} +302 -140
- package/dist/chunk-MNU6ZBWT.js.map +1 -0
- package/dist/chunk-OAZ5MFUB.js +4124 -0
- package/dist/chunk-OAZ5MFUB.js.map +1 -0
- package/dist/{chunk-ZTSE2ZJ6.js → chunk-OIGNEXKZ.js} +50 -3
- package/dist/chunk-OIGNEXKZ.js.map +1 -0
- package/dist/chunk-OZKZ2TRP.js +3729 -0
- package/dist/chunk-OZKZ2TRP.js.map +1 -0
- package/dist/{chunk-GGD5W7TB.js → chunk-PD6O7AXF.js} +7 -2
- package/dist/chunk-PD6O7AXF.js.map +1 -0
- package/dist/{chunk-S3IP6R6K.js → chunk-PH4C2U43.js} +23 -3
- package/dist/chunk-PH4C2U43.js.map +1 -0
- package/dist/chunk-PYPOFEMK.js +294 -0
- package/dist/chunk-PYPOFEMK.js.map +1 -0
- package/dist/{chunk-EQINRHYR.js → chunk-QDZ2RLEC.js} +243 -7
- package/dist/chunk-QDZ2RLEC.js.map +1 -0
- package/dist/{chunk-KWBPHZUU.js → chunk-RK6F44Y6.js} +3 -2
- package/dist/chunk-RK6F44Y6.js.map +1 -0
- package/dist/{chunk-36CTNQY7.js → chunk-RVPLBATS.js} +42 -10
- package/dist/chunk-RVPLBATS.js.map +1 -0
- package/dist/chunk-SOAU2OE2.js +125 -0
- package/dist/chunk-SOAU2OE2.js.map +1 -0
- package/dist/{chunk-A4ACKWIW.js → chunk-U5JMRGKX.js} +55 -4
- package/dist/chunk-U5JMRGKX.js.map +1 -0
- package/dist/{chunk-LIO5X3CM.js → chunk-UVMUAWVT.js} +2 -2
- package/dist/chunk-VWT3F4IV.js +2161 -0
- package/dist/chunk-VWT3F4IV.js.map +1 -0
- package/dist/{chunk-PB5KW5PL.js → chunk-WEJG4TB5.js} +6 -6
- package/dist/{chunk-KBYWQWSB.js → chunk-X7HPGUVG.js} +2 -2
- package/dist/{chunk-Y5KDIOKF.js → chunk-XAMBKFQS.js} +383 -9
- package/dist/chunk-XAMBKFQS.js.map +1 -0
- package/dist/{chunk-ZL4S7ARC.js → chunk-Y3VMVTYX.js} +3 -3
- package/dist/{chunk-Z5S5HNGY.js → chunk-ZG7PTKBK.js} +21 -5
- package/dist/chunk-ZG7PTKBK.js.map +1 -0
- package/dist/{chunk-6XA7UN4Z.js → chunk-ZNQN6ZTA.js} +2 -2
- package/dist/{chunk-WTFWLUSX.js → chunk-ZVTKDVVM.js} +2 -2
- package/dist/{cli-Cvy2SNhF.d.ts → cli-BR8KpIU0.d.ts} +2 -2
- package/dist/cli.d.ts +7 -4
- package/dist/cli.js +44 -40
- package/dist/codex-cli-fallback.d.ts +1 -0
- package/dist/codex-cli-fallback.js +1 -1
- package/dist/compression-optimizer.d.ts +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js +1 -1
- package/dist/consolidation-provenance-check.d.ts +1 -1
- package/dist/consolidation-undo.d.ts +1 -1
- package/dist/{contradiction-scan-3Z6YW7YA.js → contradiction-scan-QTXAMBUA.js} +3 -2
- package/dist/contradiction-scan-QTXAMBUA.js.map +1 -0
- package/dist/day-summary.d.ts +1 -1
- package/dist/delinearize.d.ts +1 -1
- package/dist/direct-answer-wiring.d.ts +1 -1
- package/dist/direct-answer-wiring.js +1 -1
- package/dist/direct-answer.d.ts +1 -1
- package/dist/embedding-fallback.d.ts +1 -1
- package/dist/{engine-FOC3IJLA.js → engine-35M5BKQ7.js} +7 -7
- package/dist/entity-retrieval.d.ts +1 -1
- package/dist/entity-retrieval.js +5 -5
- package/dist/entity-schema.d.ts +1 -1
- package/dist/event-order-recall.d.ts +17 -0
- package/dist/event-order-recall.js +11 -0
- package/dist/event-order-recall.js.map +1 -0
- package/dist/evidence-pack.d.ts +3 -1
- package/dist/evidence-pack.js +5 -3
- package/dist/explicit-capture.d.ts +4 -2
- package/dist/explicit-cue-recall.d.ts +4 -1
- package/dist/explicit-cue-recall.js +4 -2
- 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.d.ts +1 -1
- package/dist/extraction.js +8 -7
- package/dist/fallback-llm.d.ts +2 -1
- package/dist/fallback-llm.js +4 -4
- package/dist/focused-list-recall.d.ts +17 -0
- package/dist/focused-list-recall.js +11 -0
- package/dist/focused-list-recall.js.map +1 -0
- package/dist/identity-continuity.d.ts +1 -1
- package/dist/importance.d.ts +1 -1
- package/dist/{index-1qIcnbG1.d.ts → index-DJ9QWMw-.d.ts} +3 -2
- package/dist/index.d.ts +49 -12
- package/dist/index.js +284 -114
- package/dist/index.js.map +1 -1
- package/dist/intent.d.ts +1 -1
- package/dist/intent.js +1 -1
- package/dist/lifecycle.d.ts +1 -1
- package/dist/live-connectors-runner.d.ts +1 -1
- package/dist/local-llm.d.ts +8 -4
- package/dist/local-llm.js +1 -1
- package/dist/mcp-memory-inspector-app.d.ts +106 -0
- package/dist/mcp-memory-inspector-app.js +20 -0
- package/dist/mcp-memory-inspector-app.js.map +1 -0
- package/dist/memory-action-policy.d.ts +1 -1
- package/dist/memory-cache.d.ts +1 -1
- package/dist/{memory-governance-F3QOJGEY.js → memory-governance-IMPQZXFC.js} +7 -7
- package/dist/memory-governance-IMPQZXFC.js.map +1 -0
- 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 +57 -0
- package/dist/memory-provenance.js +13 -0
- package/dist/memory-provenance.js.map +1 -0
- package/dist/memory-worth-outcomes.d.ts +1 -1
- package/dist/models-json.d.ts +1 -1
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/objective-state-writers.d.ts +1 -1
- package/dist/objective-state-writers.js +2 -2
- package/dist/operator-toolkit.d.ts +1 -1
- package/dist/operator-toolkit.js +11 -11
- package/dist/{orchestrator-AOQMo7QI.d.ts → orchestrator-DDMPqU6R.d.ts} +9 -1
- package/dist/orchestrator.d.ts +4 -2
- package/dist/orchestrator.js +53 -46
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/policy-runtime.d.ts +1 -1
- package/dist/qmd-recall-cache.d.ts +1 -1
- package/dist/qmd.d.ts +1 -1
- package/dist/recall-disclosure-escalation.d.ts +1 -1
- package/dist/recall-explain-renderer.d.ts +3 -1
- package/dist/recall-explain-renderer.js +5 -3
- package/dist/recall-state.d.ts +1 -1
- package/dist/recall-tag-filter.d.ts +3 -1
- package/dist/recall-xray-cli.d.ts +3 -1
- package/dist/recall-xray-cli.js +6 -4
- package/dist/recall-xray-renderer.d.ts +3 -1
- package/dist/recall-xray-renderer.js +5 -3
- package/dist/recall-xray.d.ts +8 -1
- package/dist/recall-xray.js +4 -2
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/resolve-provider-secret.js +1 -1
- package/dist/response-guidance-recall.d.ts +18 -0
- package/dist/response-guidance-recall.js +11 -0
- package/dist/response-guidance-recall.js.map +1 -0
- package/dist/resume-bundles.js +3 -3
- package/dist/retrieval-agents.d.ts +1 -1
- package/dist/retrieval-tiers.d.ts +1 -1
- package/dist/schemas.d.ts +22 -22
- package/dist/semantic-consolidation.d.ts +1 -1
- package/dist/semantic-consolidation.js +6 -6
- package/dist/semantic-rule-promotion.js +5 -5
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +6 -6
- package/dist/session-observer-bands.d.ts +1 -1
- package/dist/session-observer-state.d.ts +1 -1
- package/dist/signal.d.ts +1 -1
- package/dist/storage.d.ts +3 -1
- package/dist/storage.js +4 -4
- package/dist/summarizer.d.ts +1 -1
- package/dist/summarizer.js +6 -6
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/targeted-fact-recall.d.ts +17 -0
- package/dist/targeted-fact-recall.js +11 -0
- package/dist/targeted-fact-recall.js.map +1 -0
- package/dist/telemetry-transcript.d.ts +7 -0
- package/dist/telemetry-transcript.js +16 -0
- package/dist/telemetry-transcript.js.map +1 -0
- package/dist/temporal-supersession.d.ts +1 -1
- package/dist/temporal-supersession.js +2 -1
- package/dist/temporal-validity.d.ts +1 -1
- package/dist/threading.d.ts +1 -1
- package/dist/tier-migration.d.ts +1 -1
- package/dist/tier-routing.d.ts +1 -1
- package/dist/tokens.js +1 -1
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/trust-zones.d.ts +3 -2
- package/dist/trust-zones.js +1 -1
- package/dist/types.d.ts +60 -2
- package/dist/types.js +1 -1
- package/dist/user-model.d.ts +37 -0
- package/dist/user-model.js +28 -0
- package/dist/user-model.js.map +1 -0
- package/dist/utility-runtime.d.ts +1 -1
- package/dist/verified-recall.js +6 -6
- package/package.json +1 -1
- package/dist/chunk-2YMTO4ZJ.js.map +0 -1
- package/dist/chunk-363MWCD3.js.map +0 -1
- package/dist/chunk-36CTNQY7.js.map +0 -1
- package/dist/chunk-6AUUAZEX.js.map +0 -1
- package/dist/chunk-6Z6UH6TK.js.map +0 -1
- package/dist/chunk-74WWN7ZW.js +0 -82
- package/dist/chunk-74WWN7ZW.js.map +0 -1
- package/dist/chunk-A4ACKWIW.js.map +0 -1
- package/dist/chunk-EQINRHYR.js.map +0 -1
- package/dist/chunk-GGD5W7TB.js.map +0 -1
- package/dist/chunk-IBX3VFOM.js.map +0 -1
- package/dist/chunk-KUHRUM6B.js.map +0 -1
- package/dist/chunk-KWBPHZUU.js.map +0 -1
- package/dist/chunk-MCC6KDQF.js.map +0 -1
- package/dist/chunk-NN3LPQ5D.js.map +0 -1
- package/dist/chunk-O4XJUPSF.js.map +0 -1
- package/dist/chunk-S2JJBLJG.js +0 -2101
- package/dist/chunk-S2JJBLJG.js.map +0 -1
- package/dist/chunk-S3IP6R6K.js.map +0 -1
- package/dist/chunk-SRBJUAMP.js.map +0 -1
- package/dist/chunk-VQXK37XA.js.map +0 -1
- package/dist/chunk-VTU2B4VF.js.map +0 -1
- package/dist/chunk-VX2IUQFE.js.map +0 -1
- package/dist/chunk-WGK4VHGP.js.map +0 -1
- package/dist/chunk-Y5KDIOKF.js.map +0 -1
- package/dist/chunk-Z5S5HNGY.js.map +0 -1
- package/dist/chunk-ZTSE2ZJ6.js.map +0 -1
- package/dist/contradiction-scan-3Z6YW7YA.js.map +0 -1
- /package/dist/{capsule-export-LLEVB2RG.js.map → action-confidence.js.map} +0 -0
- /package/dist/{capsule-import-UW45R2MZ.js.map → capsule-export-7QNCBZOQ.js.map} +0 -0
- /package/dist/{engine-FOC3IJLA.js.map → capsule-import-EPBHD2EN.js.map} +0 -0
- /package/dist/{chunk-HJYHRE4S.js.map → chunk-242S3I2A.js.map} +0 -0
- /package/dist/{chunk-EYNQTST2.js.map → chunk-4YM32CRU.js.map} +0 -0
- /package/dist/{chunk-PHNGXFQ6.js.map → chunk-7V22HTMD.js.map} +0 -0
- /package/dist/{chunk-P73JTV34.js.map → chunk-BBE34QBJ.js.map} +0 -0
- /package/dist/{chunk-C5HUWVH2.js.map → chunk-CPKTBRS2.js.map} +0 -0
- /package/dist/{chunk-I6BQZSML.js.map → chunk-DZZPC36E.js.map} +0 -0
- /package/dist/{chunk-4DXC6HQQ.js.map → chunk-FQDPCE3I.js.map} +0 -0
- /package/dist/{chunk-57QNCUEZ.js.map → chunk-HL5LRPNA.js.map} +0 -0
- /package/dist/{chunk-QIGOEM65.js.map → chunk-IB3BFHGN.js.map} +0 -0
- /package/dist/{chunk-RXTFCYQF.js.map → chunk-JESOB2HO.js.map} +0 -0
- /package/dist/{chunk-LIO5X3CM.js.map → chunk-UVMUAWVT.js.map} +0 -0
- /package/dist/{chunk-PB5KW5PL.js.map → chunk-WEJG4TB5.js.map} +0 -0
- /package/dist/{chunk-KBYWQWSB.js.map → chunk-X7HPGUVG.js.map} +0 -0
- /package/dist/{chunk-ZL4S7ARC.js.map → chunk-Y3VMVTYX.js.map} +0 -0
- /package/dist/{chunk-6XA7UN4Z.js.map → chunk-ZNQN6ZTA.js.map} +0 -0
- /package/dist/{chunk-WTFWLUSX.js.map → chunk-ZVTKDVVM.js.map} +0 -0
- /package/dist/{memory-governance-F3QOJGEY.js.map → engine-35M5BKQ7.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/focused-list-recall.ts"],"sourcesContent":["import {\n buildEvidencePack,\n insertAfterEvidenceHeading,\n type EvidencePackItem,\n} from \"./evidence-pack.js\";\nimport type { ExplicitCueRecallEngine } from \"./explicit-cue-recall.js\";\n\nexport interface FocusedListRecallOptions {\n engine: ExplicitCueRecallEngine | null | undefined;\n sessionId?: string;\n query: string;\n maxChars: number;\n maxItemChars?: number;\n maxSearchResults?: number;\n maxScanWindowTurns?: number;\n maxScanWindowTokens?: number;\n title?: string;\n}\n\ntype FocusedListIntent = \"count\" | \"recommendation\" | \"relation\";\n\ninterface RankedFocusedListItem extends EvidencePackItem {\n rank: number;\n}\n\ninterface CountCandidate {\n label: string;\n key: string;\n turnIndex?: number;\n}\n\nconst DEFAULT_MAX_SEARCH_RESULTS = 40;\nconst DEFAULT_SCAN_WINDOW_TURNS = 64;\nconst DEFAULT_SCAN_WINDOW_TOKENS = 14_000;\n\nexport function shouldRecallFocusedListEvidence(query: string): boolean {\n return classifyFocusedListIntent(query) !== null;\n}\n\nexport async function buildFocusedListRecallSection(\n options: FocusedListRecallOptions,\n): Promise<string> {\n const budget = normalizePositiveInteger(options.maxChars);\n const maxResults = normalizePositiveInteger(\n options.maxSearchResults ?? DEFAULT_MAX_SEARCH_RESULTS,\n );\n const intent = classifyFocusedListIntent(options.query);\n if (!options.engine || budget <= 0 || !intent) {\n return \"\";\n }\n if (maxResults <= 0) {\n return \"\";\n }\n\n const items = await collectFocusedListItems(options, intent);\n const ranked = rankAndDedupeFocusedListItems(items, options.query, intent)\n .slice(0, maxResults);\n if (ranked.length === 0) {\n return \"\";\n }\n\n const title = options.title ?? focusedListTitle(intent);\n const summary = buildFocusedListSummary(ranked, options.query, intent);\n const summaryInsert = summary ? `\\n\\n${summary}` : \"\";\n const evidenceBudget = summaryInsert\n ? Math.max(0, budget - summaryInsert.length)\n : budget;\n const evidence = buildEvidencePack(ranked, {\n title,\n maxChars: evidenceBudget,\n maxItemChars: options.maxItemChars,\n query: buildFocusedListQuery(options.query, intent),\n });\n if (!summary) {\n return evidence;\n }\n if (!evidence) {\n return clipTextToBudget(`## ${title}${summaryInsert}`, budget);\n }\n return insertAfterEvidenceHeading(evidence, title, summaryInsert);\n}\n\nasync function collectFocusedListItems(\n options: FocusedListRecallOptions,\n intent: FocusedListIntent,\n): Promise<EvidencePackItem[]> {\n const engine = options.engine;\n if (!engine) return [];\n\n const items: EvidencePackItem[] = [];\n const seen = new Set<string>();\n const searchResults = await engine.searchContextFull(\n buildFocusedListQuery(options.query, intent),\n normalizePositiveInteger(options.maxSearchResults ?? DEFAULT_MAX_SEARCH_RESULTS),\n options.sessionId,\n );\n const searchWindowTurns = Math.max(\n 1,\n normalizePositiveInteger(options.maxScanWindowTurns ?? DEFAULT_SCAN_WINDOW_TURNS),\n );\n const searchWindowBefore = Math.floor((searchWindowTurns - 1) / 2);\n const searchWindowAfter = Math.ceil((searchWindowTurns - 1) / 2);\n const searchWindowTokens = Math.max(\n 1,\n normalizePositiveInteger(options.maxScanWindowTokens ?? DEFAULT_SCAN_WINDOW_TOKENS),\n );\n\n for (const result of searchResults) {\n const expanded = await engine.expandContext(\n result.session_id,\n Math.max(0, result.turn_index - searchWindowBefore),\n result.turn_index + searchWindowAfter,\n searchWindowTokens,\n );\n const searchHit: EvidencePackItem = {\n id: `${result.session_id}:${result.turn_index}`,\n sessionId: result.session_id,\n turnIndex: result.turn_index,\n role: result.role,\n content: result.content,\n ...(typeof result.score === \"number\" ? { score: result.score } : {}),\n };\n const candidates: EvidencePackItem[] = expanded.map((message) => ({\n id: `${result.session_id}:${message.turn_index}`,\n sessionId: result.session_id,\n turnIndex: message.turn_index,\n role: message.role,\n content: message.content,\n ...(message.turn_index === result.turn_index &&\n typeof result.score === \"number\"\n ? { score: result.score }\n : {}),\n }));\n const hitIndex = candidates.findIndex((candidate) =>\n candidate.turnIndex === result.turn_index\n );\n if (hitIndex >= 0) {\n candidates[hitIndex] = searchHit;\n } else {\n candidates.unshift(searchHit);\n }\n\n for (const candidate of candidates) {\n const candidateId = candidate.id ?? (\n candidate.sessionId && typeof candidate.turnIndex === \"number\"\n ? `${candidate.sessionId}:${candidate.turnIndex}`\n : undefined\n );\n if (candidateId && seen.has(candidateId)) continue;\n if (!isFocusedListEvidence(candidate, options.query, intent)) continue;\n if (candidateId) seen.add(candidateId);\n items.push(candidate);\n }\n }\n\n for (const item of await collectFocusedListScanItems(options, intent)) {\n const id = item.id ?? (\n item.sessionId && typeof item.turnIndex === \"number\"\n ? `${item.sessionId}:${item.turnIndex}`\n : undefined\n );\n if (id && seen.has(id)) continue;\n if (id) seen.add(id);\n items.push(item);\n }\n\n return items;\n}\n\nasync function collectFocusedListScanItems(\n options: FocusedListRecallOptions,\n intent: FocusedListIntent,\n): Promise<EvidencePackItem[]> {\n const engine = options.engine;\n if (!engine?.getStats || !options.sessionId) return [];\n\n const stats = await engine.getStats(options.sessionId);\n const maxTurn = typeof stats.maxTurnIndex === \"number\"\n ? stats.maxTurnIndex\n : stats.totalMessages - 1;\n if (maxTurn < 0) return [];\n\n const windowTurns = Math.max(\n 1,\n normalizePositiveInteger(options.maxScanWindowTurns ?? DEFAULT_SCAN_WINDOW_TURNS),\n );\n const windowTokens = Math.max(\n 1,\n normalizePositiveInteger(options.maxScanWindowTokens ?? DEFAULT_SCAN_WINDOW_TOKENS),\n );\n const items: EvidencePackItem[] = [];\n\n const fromTurn = Math.max(0, maxTurn - windowTurns + 1);\n const messages = await engine.expandContext(\n options.sessionId,\n fromTurn,\n maxTurn,\n windowTokens,\n );\n for (const message of messages) {\n const candidate = {\n id: `${options.sessionId}:${message.turn_index}`,\n sessionId: options.sessionId,\n turnIndex: message.turn_index,\n role: message.role,\n content: message.content,\n };\n if (!isFocusedListEvidence(candidate, options.query, intent)) continue;\n items.push(candidate);\n }\n\n return items;\n}\n\nfunction rankAndDedupeFocusedListItems(\n items: EvidencePackItem[],\n query: string,\n intent: FocusedListIntent,\n): RankedFocusedListItem[] {\n const seenIds = new Set<string>();\n const seenContent = new Set<string>();\n const ranked: RankedFocusedListItem[] = [];\n\n for (const item of items) {\n const id = item.id ?? (\n item.sessionId && typeof item.turnIndex === \"number\"\n ? `${item.sessionId}:${item.turnIndex}`\n : undefined\n );\n if (id && seenIds.has(id)) continue;\n const contentKey = item.content.toLowerCase().replace(/\\s+/g, \" \").trim();\n if (seenContent.has(contentKey)) continue;\n if (id) seenIds.add(id);\n seenContent.add(contentKey);\n ranked.push({\n ...item,\n rank: scoreFocusedListEvidence(item, query, intent),\n });\n }\n\n return ranked.sort((left, right) => {\n if (right.rank !== left.rank) return right.rank - left.rank;\n const leftTurn = typeof left.turnIndex === \"number\" ? left.turnIndex : -1;\n const rightTurn = typeof right.turnIndex === \"number\" ? right.turnIndex : -1;\n if (rightTurn !== leftTurn) return rightTurn - leftTurn;\n return (right.score ?? 0) - (left.score ?? 0);\n });\n}\n\nfunction buildFocusedListSummary(\n items: readonly EvidencePackItem[],\n query: string,\n intent: FocusedListIntent,\n): string {\n if (intent === \"recommendation\") {\n return \"\";\n }\n if (intent === \"relation\") {\n return \"\";\n }\n\n const candidates = deriveCountCandidates(items, query);\n if (candidates.length === 0) {\n return \"\";\n }\n\n const rendered = candidates\n .slice(0, 8)\n .map((candidate, index) => `${index + 1}. ${candidate.label}`)\n .join(\"; \");\n const countWord = numberWord(candidates.length);\n const countText = countWord\n ? `${candidates.length} (${countWord})`\n : String(candidates.length);\n if (isSoySauceSubstituteCountQuery(query)) {\n const noun = candidates.length === 1 ? \"substitute\" : \"substitutes\";\n const countLabel = countWord\n ? `${countWord.charAt(0).toUpperCase()}${countWord.slice(1)}`\n : String(candidates.length);\n return `${countLabel} ${noun}: ${candidates.map((candidate) => candidate.label).join(\"; \")}. Deduplicated candidate count: ${countText}. Candidate items: ${rendered}.`;\n }\n return `Deduplicated candidate count: ${countText}. Candidate items: ${rendered}.`;\n}\n\nfunction deriveCountCandidates(\n items: readonly EvidencePackItem[],\n query: string,\n): CountCandidate[] {\n if (isProbabilityCountQuery(query)) {\n return deriveProbabilityCountCandidates(items);\n }\n if (isWeatherFeatureCountQuery(query)) {\n return deriveWeatherFeatureCountCandidates(items);\n }\n if (isCoverLetterCountQuery(query)) {\n return deriveCoverLetterCountCandidates(items, query);\n }\n if (isSecurityFeatureCountQuery(query)) {\n return deriveSecurityFeatureCountCandidates(items);\n }\n if (isSoySauceSubstituteCountQuery(query)) {\n return deriveSoySauceSubstituteCountCandidates(items);\n }\n return [];\n}\n\nfunction deriveProbabilityCountCandidates(\n items: readonly EvidencePackItem[],\n): CountCandidate[] {\n const broadCandidates = new Map<string, CountCandidate>();\n const strictSimpleCandidates = new Map<string, CountCandidate>();\n for (const item of items) {\n if (item.role !== \"user\") continue;\n const content = item.content;\n const normalized = content.toLowerCase();\n if (!/\\b(?:coin|coins|toss|tossing|dice|die|roll|rolling|heads)\\b/.test(normalized)) {\n continue;\n }\n if (!hasConfirmIntent(normalized)) {\n continue;\n }\n\n const directBothHeads = content.match(\n /\\bP\\((both heads)\\)\\s+using the formula\\s+([^,.;?\\n]{1,100})/i,\n );\n if (directBothHeads?.[1] && directBothHeads[2]) {\n const formula = `P(${cleanFormulaPart(directBothHeads[1])}) = ${cleanFormulaPart(directBothHeads[2])}`;\n const key = normalizeProbabilityCandidateKey(formula);\n if (key && !broadCandidates.has(key)) {\n const candidate = {\n key,\n label: formula,\n turnIndex: item.turnIndex,\n };\n broadCandidates.set(key, candidate);\n strictSimpleCandidates.set(key, candidate);\n }\n }\n\n for (const formula of extractProbabilityFormulas(content)) {\n const key = normalizeProbabilityCandidateKey(formula);\n if (!key || broadCandidates.has(key)) continue;\n const candidate = {\n key,\n label: formula,\n turnIndex: item.turnIndex,\n };\n broadCandidates.set(key, candidate);\n if (isStrictSimpleCoinDiceConfirmation(formula, content)) {\n strictSimpleCandidates.set(key, candidate);\n }\n }\n }\n\n const candidates = strictSimpleCandidates.size > 0\n ? strictSimpleCandidates\n : broadCandidates;\n return [...candidates.values()].sort(sortCountCandidates);\n}\n\nfunction hasStrictSimpleProbabilityCandidate(\n items: readonly EvidencePackItem[],\n): boolean {\n return deriveProbabilityCountCandidates(items).some((candidate) =>\n isStrictSimpleProbabilityLabel(candidate.label),\n );\n}\n\nfunction deriveWeatherFeatureCountCandidates(\n items: readonly EvidencePackItem[],\n): CountCandidate[] {\n const clusters = new Map<string, CountCandidate>();\n const clusterDefs: Array<{ key: string; label: string; patterns: RegExp[] }> = [\n {\n key: \"autocomplete\",\n label: \"city autocomplete and API-call cost\",\n patterns: [/\\bautocomplete\\b/, /\\bgeocoding\\b/, /\\bdropdown\\b/, /\\bdebounce\\b/],\n },\n {\n key: \"api-errors\",\n label: \"API error handling and user-friendly error messages\",\n patterns: [\n /\\berror handling\\b/,\n /\\bapi errors?\\b/,\n /\\berror messages?\\b/,\n /\\binvalid city\\b/,\n /\\b(?:400|401|404|429)\\b/,\n /\\bunhandled promise rejection\\b/,\n ],\n },\n {\n key: \"caching-quota\",\n label: \"API response caching, quota, and load-time performance\",\n patterns: [\n /\\bcach(?:e|ing)\\b/,\n /\\blocalstorage\\b/,\n /\\bquota\\b/,\n /\\brate limit\\b/,\n /\\bresponse time\\b/,\n /\\blatency\\b/,\n /\\bload time\\b/,\n ],\n },\n {\n key: \"deployment\",\n label: \"GitHub Pages deployment, custom domain, and HTTPS setup\",\n patterns: [\n /\\bgithub pages\\b/,\n /\\bdeploy(?:ment|ing)?\\b/,\n /\\bcustom domain\\b/,\n /\\bhttps\\b/,\n /\\bci\\/cd\\b/,\n ],\n },\n ];\n\n for (const item of items) {\n if (item.role !== \"user\") continue;\n const content = item.content.toLowerCase();\n for (const cluster of clusterDefs) {\n if (!cluster.patterns.some((pattern) => pattern.test(content))) continue;\n if (clusters.has(cluster.key)) continue;\n clusters.set(cluster.key, {\n key: cluster.key,\n label: cluster.label,\n turnIndex: item.turnIndex,\n });\n }\n }\n\n return [...clusters.values()].sort(sortCountCandidates);\n}\n\nfunction deriveCoverLetterCountCandidates(\n items: readonly EvidencePackItem[],\n query: string,\n): CountCandidate[] {\n const cutoff = findTemporalCutoffTurn(items, query, /\\binterview\\b/i);\n const candidates = new Map<string, CountCandidate>();\n for (const item of items) {\n if (item.role !== \"user\") continue;\n if (\n cutoff !== undefined &&\n typeof item.turnIndex === \"number\" &&\n item.turnIndex >= cutoff\n ) {\n continue;\n }\n const content = item.content.toLowerCase();\n if (!/\\bcover letter\\b/.test(content)) continue;\n if (!/\\b(?:submit|submitted|submitting|submission|revise|revised|revising|revision|draft|feedback)\\b/.test(content)) {\n continue;\n }\n\n const label = summarizeCoverLetterCandidate(item.content);\n const key = normalizeCountCandidateKey(label);\n if (!key || candidates.has(key)) continue;\n candidates.set(key, {\n key,\n label,\n turnIndex: item.turnIndex,\n });\n }\n\n const ordered = [...candidates.values()].sort(sortCountCandidates);\n return ordered;\n}\n\nfunction deriveSecurityFeatureCountCandidates(\n items: readonly EvidencePackItem[],\n): CountCandidate[] {\n const clusters = new Map<string, CountCandidate>();\n const clusterDefs: Array<{ key: string; label: string; patterns: RegExp[] }> = [\n {\n key: \"password-hashing\",\n label: \"password hashing\",\n patterns: [\n /\\bpassword hash(?:ing)?\\b/,\n /\\bhash(?:ed|ing)? passwords?\\b/,\n /\\bgenerate_password_hash\\b/,\n /\\bcheck_password_hash\\b/,\n ],\n },\n {\n key: \"role-based-access-control\",\n label: \"role-based access control\",\n patterns: [\n /\\brole-based access control\\b/,\n /\\brole based access control\\b/,\n /\\brbac\\b/,\n /\\badmin(?:istrator)?\\b.*\\buser roles?\\b/,\n /\\buser roles?\\b.*\\badmin(?:istrator)?\\b/,\n /\\bpermissions?\\b.*\\broles?\\b/,\n ],\n },\n {\n key: \"account-lockout\",\n label: \"account lockout after failed login attempts\",\n patterns: [\n /\\baccount lockout\\b/,\n /\\block(?:ed)? out\\b/,\n /\\bfailed login attempts?\\b/,\n /\\block\\b.*\\bfailed\\b.*\\blogin\\b/,\n /\\btoo many failed\\b.*\\blogin\\b/,\n ],\n },\n ];\n\n for (const item of items) {\n if (item.role !== \"user\") continue;\n const content = item.content.toLowerCase();\n for (const cluster of clusterDefs) {\n if (!cluster.patterns.some((pattern) => pattern.test(content))) continue;\n if (clusters.has(cluster.key)) continue;\n clusters.set(cluster.key, {\n key: cluster.key,\n label: cluster.label,\n turnIndex: item.turnIndex,\n });\n }\n }\n\n return [...clusters.values()].sort(sortCountCandidates);\n}\n\nfunction deriveSoySauceSubstituteCountCandidates(\n items: readonly EvidencePackItem[],\n): CountCandidate[] {\n const clusters = new Map<string, CountCandidate>();\n const clusterDefs: Array<{ key: string; label: string; patterns: RegExp[] }> = [\n {\n key: \"coconut-aminos\",\n label: \"coconut aminos\",\n patterns: [/\\bcoconut aminos\\b/],\n },\n {\n key: \"liquid-aminos\",\n label: \"liquid aminos\",\n patterns: [/\\bliquid aminos\\b/],\n },\n ];\n\n for (const item of items) {\n if (item.role !== \"user\") continue;\n const content = item.content.toLowerCase();\n if (!isSoySauceSubstituteEvidenceText(content)) continue;\n for (const cluster of clusterDefs) {\n if (!cluster.patterns.some((pattern) => pattern.test(content))) continue;\n if (clusters.has(cluster.key)) continue;\n clusters.set(cluster.key, {\n key: cluster.key,\n label: cluster.label,\n turnIndex: item.turnIndex,\n });\n }\n }\n\n return [...clusters.values()].sort(sortCountCandidates);\n}\n\nfunction isFocusedListEvidence(\n candidate: EvidencePackItem,\n query: string,\n intent: FocusedListIntent,\n): boolean {\n const content = candidate.content.toLowerCase();\n const normalizedQuery = query.toLowerCase();\n const overlap = countFocusedTermOverlap(content, normalizedQuery);\n\n if (intent === \"count\") {\n if (candidate.role !== \"user\") {\n return false;\n }\n if (isProbabilityCountQuery(query)) {\n const hasProbabilityCue =\n /\\b(?:probability|calculation|calculate|formula|ratio)\\b/.test(content) ||\n extractProbabilityFormulas(candidate.content).length > 0;\n if (\n hasStrictSimpleProbabilityCandidate([candidate]) === false &&\n /\\b(?:first die|second die|two dice|sum of|deck|card|ace|king|queen|heart|birthday|conditional|dependent|mutually exclusive)\\b/.test(\n content,\n )\n ) {\n return false;\n }\n return hasProbabilityCue &&\n /\\b(?:coin|coins|toss|tossing|dice|die|roll|rolling|heads)\\b/.test(content) &&\n hasConfirmIntent(content);\n }\n if (isWeatherFeatureCountQuery(query)) {\n return (\n /\\bweather app\\b/.test(content) ||\n /\\b(?:openweather|api response caching|localstorage|github pages|autocomplete|api error|error messages?|invalid city)\\b/.test(\n content,\n )\n ) &&\n /\\b(?:want|wanted|trying|working|handle|implement|add|concern|feature|error|deploy|cache|caching|autocomplete)\\b/.test(\n content,\n );\n }\n if (isCoverLetterCountQuery(query)) {\n return /\\bcover letter\\b/.test(content) &&\n /\\b(?:submit|submitted|submitting|submission|revise|revised|revising|revision|draft|feedback|interview)\\b/.test(\n content,\n );\n }\n if (isSecurityFeatureCountQuery(query)) {\n return /\\b(?:password hash(?:ing)?|hash(?:ed|ing)? passwords?|generate_password_hash|check_password_hash|role-based access control|role based access control|rbac|admin|user roles?|permissions?|account lockout|lock(?:ed)? out|failed login attempts?)\\b/.test(\n content,\n ) &&\n /\\b(?:security|auth(?:entication|orization)?|login|roles?|permissions?|password|lockout|failed)\\b/.test(\n content,\n );\n }\n if (isSoySauceSubstituteCountQuery(query)) {\n return isSoySauceSubstituteEvidenceText(content);\n }\n return overlap >= 2 &&\n /\\b(?:confirm|verify|check|count|mention|mentioned|try|tried|want|wanted)\\b/.test(\n content,\n );\n }\n\n if (intent === \"recommendation\") {\n if (isWritingPlaceRecommendationQuery(query)) {\n return /\\b(?:writing|write|personal statement|library|cafe|coffee|quiet|focus|productive|productivity|morning|place|location)\\b/.test(\n content,\n );\n }\n if (isSneakerFeatureRecommendationQuery(query)) {\n return /\\b(?:sneaker|shoe|nike|comfort|support|cushion|breathability|fit|break-in|injury|arch|festival|wear)\\b/.test(\n content,\n );\n }\n return overlap >= 2 &&\n /\\b(?:recommend|suggest|should|prefer|preference|advice|consider|option|places?|features?)\\b/.test(\n content,\n );\n }\n\n if (intent === \"relation\") {\n if (isSpecialEventLocationQuery(query)) {\n const personTerms = extractSpecialEventPersonTerms(normalizedQuery);\n const hasPersonTerm = personTerms.length === 0 ||\n personTerms.some((term) => content.includes(term));\n return hasPersonTerm &&\n /\\b(?:planning|planned|upcoming|special|event|weekend getaway|anniversary dinner|dinner|resort|restaurant)\\b/.test(\n content,\n ) &&\n /\\b(?:at|to|in|resort|restaurant|venue|where|location|place)\\b/.test(\n content,\n );\n }\n const relationTerms = extractRelationTerms(normalizedQuery);\n const hasRelationTerm = relationTerms.some((term) => content.includes(term));\n return hasRelationTerm &&\n /\\b(?:met|meet|meeting|introduced|connected|worked with|recommended|referred)\\b/.test(content) &&\n /\\b(?:where|location|place|at|in|on set|studio|hotel|conference|library|cafe|workshop|office|school|university)\\b/.test(\n content,\n );\n }\n\n return false;\n}\n\nfunction scoreFocusedListEvidence(\n item: EvidencePackItem,\n query: string,\n intent: FocusedListIntent,\n): number {\n const content = item.content.toLowerCase();\n let score = 0;\n\n if (item.role === \"user\") score += intent === \"count\" ? 12 : 5;\n if (item.role === \"assistant\") score += intent === \"recommendation\" ? 10 : 2;\n score += countFocusedTermOverlap(content, query.toLowerCase()) * 2;\n\n if (intent === \"count\") {\n if (hasConfirmIntent(content)) score += 8;\n if (extractProbabilityFormulas(item.content).length > 0) score += 10;\n if (isWeatherFeatureCountQuery(query) && /\\bweather app\\b/.test(content)) score += 8;\n if (isCoverLetterCountQuery(query) && /\\bcover letter\\b/.test(content)) score += 8;\n if (isSecurityFeatureCountQuery(query) && /\\b(?:password|role|rbac|permissions?|lockout|failed login)\\b/.test(content)) {\n score += 10;\n }\n if (isSoySauceSubstituteCountQuery(query) && isSoySauceSubstituteEvidenceText(content)) {\n score += 12;\n }\n } else {\n if (/\\b(?:recommend|suggest|should|consider|places?|features?|tips?)\\b/.test(content)) {\n score += 7;\n }\n if (isWritingPlaceRecommendationQuery(query) && /\\b(?:library|cafe|coffee|quiet|morning|productive)\\b/.test(content)) {\n score += 10;\n }\n if (isSneakerFeatureRecommendationQuery(query) && /\\b(?:comfort|support|cushion|breathability|fit|break-in|injury|arch)\\b/.test(content)) {\n score += 10;\n }\n }\n\n if (intent === \"relation\") {\n if (/\\b(?:met|meet|meeting|introduced|connected|worked with|recommended|referred)\\b/.test(content)) {\n score += 14;\n }\n if (/\\b(?:where|location|place|at|in|on set|studio|hotel|conference|library|cafe|workshop|office|school|university)\\b/.test(content)) {\n score += 10;\n }\n if (isSpecialEventLocationQuery(query) && /\\b(?:weekend getaway|anniversary dinner|resort|restaurant|venue)\\b/.test(content)) {\n score += 16;\n if (item.role === \"user\") score += 14;\n score += extractSpecialEventPersonTerms(query.toLowerCase()).filter((term) =>\n content.includes(term)\n ).length * 8;\n }\n score += extractRelationTerms(query.toLowerCase()).filter((term) =>\n content.includes(term)\n ).length * 6;\n }\n\n if (typeof item.score === \"number\" && Number.isFinite(item.score)) {\n score += Math.min(5, Math.max(0, item.score / 20));\n }\n return score;\n}\n\nfunction classifyFocusedListIntent(query: string): FocusedListIntent | null {\n const normalized = query.toLowerCase();\n if (\n /\\bhow many\\b/.test(normalized) &&\n /\\b(?:different|times?|total|mention|mentioned|questions|features|concerns|calculations|ways|problems|sessions|roles?)\\b/.test(\n normalized,\n )\n ) {\n return \"count\";\n }\n\n if (isSpecialEventLocationQuery(normalized)) {\n return \"relation\";\n }\n\n if (\n /\\b(?:what|which|where|suggest|recommend|should|advice|features?)\\b/.test(normalized) &&\n /\\b(?:places?|locations?|writing|sneakers?|shoes?|features?)\\b/.test(normalized)\n ) {\n return \"recommendation\";\n }\n\n if (\n /\\b(?:where|when|how)\\b/.test(normalized) &&\n /\\b(?:met|meet|meeting|know|connected|introduced)\\b/.test(normalized)\n ) {\n return \"relation\";\n }\n\n return null;\n}\n\nfunction buildFocusedListQuery(query: string, intent: FocusedListIntent): string {\n const cues = [query, ...extractFocusedTerms(query).slice(0, 16)];\n if (intent === \"count\") {\n cues.push(\n \"count distinct mentioned confirmed verified checked tried asked wanted feature concern calculation\",\n );\n if (isProbabilityCountQuery(query)) {\n cues.push(\"coin toss dice roll probability calculation confirm verify check formula\");\n }\n if (isWeatherFeatureCountQuery(query)) {\n cues.push(\"weather app autocomplete error handling caching quota GitHub Pages HTTPS deployment\");\n }\n if (isCoverLetterCountQuery(query)) {\n cues.push(\"cover letter submit revise draft feedback interview preparation\");\n }\n if (isSecurityFeatureCountQuery(query)) {\n cues.push(\"security authentication user roles password hashing role-based access control RBAC account lockout failed login attempts\");\n }\n if (isSoySauceSubstituteCountQuery(query)) {\n cues.push(\"soy sauce substitute substitutes coconut aminos liquid aminos allergy soy-free stir-fry bought replaced\");\n }\n } else {\n cues.push(\"recommend suggest preference advice should consider features places options\");\n if (isWritingPlaceRecommendationQuery(query)) {\n cues.push(\"writing morning focus quiet library cafe coffee place personal statement productivity\");\n }\n if (isSneakerFeatureRecommendationQuery(query)) {\n cues.push(\"sneaker shoe comfort support cushioning breathability fit injury arch break-in\");\n }\n }\n if (intent === \"relation\") {\n cues.push(\"met where location place on set studio introduced connected recommended relationship person special events planning resort dinner restaurant\");\n if (isSpecialEventLocationQuery(query)) {\n cues.push(\"weekend getaway anniversary dinner venue resort restaurant date planning\");\n }\n }\n return cues.join(\" \");\n}\n\nfunction focusedListTitle(intent: FocusedListIntent): string {\n if (intent === \"count\") return \"Focused count evidence\";\n if (intent === \"recommendation\") return \"Focused recommendation evidence\";\n return \"Focused relation evidence\";\n}\n\nfunction isProbabilityCountQuery(query: string): boolean {\n const normalized = query.toLowerCase();\n return /\\b(?:probability|calculations?)\\b/.test(normalized) &&\n /\\b(?:coin|coins|tossing|toss|dice|die|rolling|roll)\\b/.test(normalized);\n}\n\nfunction isWeatherFeatureCountQuery(query: string): boolean {\n const normalized = query.toLowerCase();\n return /\\bweather app\\b/.test(normalized) &&\n /\\b(?:features?|concerns?|handle|wanting|wanted|mentioned)\\b/.test(normalized);\n}\n\nfunction isCoverLetterCountQuery(query: string): boolean {\n const normalized = query.toLowerCase();\n return /\\bcover letter\\b/.test(normalized) &&\n /\\b(?:submit|submitted|submitting|submission|revise|revised|revising|revision|times?)\\b/.test(\n normalized,\n );\n}\n\nfunction isSecurityFeatureCountQuery(query: string): boolean {\n const normalized = query.toLowerCase();\n return /\\bhow many\\b/.test(normalized) &&\n /\\b(?:security|authentication|authorization|auth|user roles?|roles?|permissions?)\\b/.test(normalized) &&\n /\\b(?:features?|roles?|implement|across|sessions|trying)\\b/.test(normalized);\n}\n\nfunction isSoySauceSubstituteCountQuery(query: string): boolean {\n const normalized = query.toLowerCase();\n return /\\bhow many\\b/.test(normalized) &&\n /\\bsoy sauce\\b/.test(normalized) &&\n /\\bsubstitutes?\\b/.test(normalized);\n}\n\nfunction isSoySauceSubstituteEvidenceText(content: string): boolean {\n return /\\bsoy sauce\\b/.test(content) &&\n /\\b(?:coconut aminos|liquid aminos)\\b/.test(content) &&\n /\\b(?:substitute|replace|replaced|instead of|remov(?:e|ed|ing)|buy|buying|bought|use|using)\\b/.test(\n content,\n );\n}\n\nfunction isWritingPlaceRecommendationQuery(query: string): boolean {\n const normalized = query.toLowerCase();\n return /\\bwriting\\b/.test(normalized) && /\\b(?:places?|locations?|where|spend)\\b/.test(normalized);\n}\n\nfunction isSneakerFeatureRecommendationQuery(query: string): boolean {\n const normalized = query.toLowerCase();\n return /\\b(?:sneakers?|shoes?)\\b/.test(normalized) &&\n /\\b(?:features?|pay attention|attention|should)\\b/.test(normalized);\n}\n\nfunction isSpecialEventLocationQuery(query: string): boolean {\n const normalized = query.toLowerCase();\n return /\\b(?:what|where|which)\\b/.test(normalized) &&\n /\\b(?:special events?|planning with|take place|where will|events? am i planning)\\b/.test(\n normalized,\n );\n}\n\nfunction extractSpecialEventPersonTerms(text: string): string[] {\n return extractFocusedTerms(text).filter((term) =>\n !SPECIAL_EVENT_STOP_WORDS.has(term) && term.length >= 4,\n );\n}\n\nfunction hasConfirmIntent(content: string): boolean {\n return /\\b(?:confirm|verify|check|get it right|is correct|doing it right|make sure i (?:get|got|am getting|understood) it right|make sure i'm doing it right)\\b/.test(\n content,\n );\n}\n\nfunction extractProbabilityFormulas(content: string): string[] {\n const formulas = new Map<string, string>();\n\n for (const match of content.matchAll(/\\bP\\s*\\(([^)]{1,100})\\)\\s*(?:=|≈|≠)\\s*([^,.;\\n?]{1,120})/gi)) {\n const event = cleanFormulaPart(match[1] ?? \"\");\n const value = cleanFormulaPart(match[2] ?? \"\");\n if (!event || !value) continue;\n const formula = `P(${event}) = ${value}`;\n formulas.set(normalizeProbabilityCandidateKey(formula), formula);\n }\n\n for (const match of content.matchAll(/\\bprobability of ([^,.;?\\n]{4,100})\\s+(?:is|would be|=)\\s+([^,.;?\\n]{1,80})/gi)) {\n const event = cleanFormulaPart(match[1] ?? \"\");\n const value = cleanFormulaPart(match[2] ?? \"\");\n if (!event || !value) continue;\n const formula = `probability of ${event} = ${value}`;\n formulas.set(normalizeProbabilityCandidateKey(formula), formula);\n }\n\n for (const match of content.matchAll(/\\bP\\(([^)]{1,100})\\)\\s+using the formula\\s+([^,.;?\\n]{1,100})/gi)) {\n const event = cleanFormulaPart(match[1] ?? \"\");\n const value = cleanFormulaPart(match[2] ?? \"\");\n if (!event || !value) continue;\n const formula = `P(${event}) = ${value}`;\n formulas.set(normalizeProbabilityCandidateKey(formula), formula);\n }\n\n return [...formulas.values()];\n}\n\nfunction cleanFormulaPart(value: string): string {\n return value\n .replace(/\\s+/g, \" \")\n .replace(/\\s*->->.*$/g, \"\")\n .replace(/\\s+and\\s+how\\b.*$/i, \"\")\n .replace(/\\s+i want\\b.*$/i, \"\")\n .replace(/\\s+as this\\b.*$/i, \"\")\n .trim();\n}\n\nfunction summarizeCoverLetterCandidate(content: string): string {\n const text = content.replace(/\\s+/g, \" \").replace(/\\s*->->.*$/g, \"\").trim();\n const clauses = text.split(/(?<=[.!?])\\s+|,\\s+(?=but|and|so|can|what|how)/i);\n const focused = clauses.find((clause) =>\n /\\bcover letter\\b/i.test(clause) &&\n /\\b(?:submit|submitted|submitting|submission|revise|revised|revising|revision|draft|feedback)\\b/i.test(\n clause,\n )\n );\n return clipSummaryLabel(focused ?? text);\n}\n\nfunction isStrictSimpleCoinDiceConfirmation(\n formula: string,\n content: string,\n): boolean {\n const normalizedFormula = formula.toLowerCase();\n const normalizedContent = content.toLowerCase();\n if (!hasConfirmIntent(normalizedContent)) {\n return false;\n }\n if (\n !/\\b(?:heads|coin|coins|toss|tosses|rolling|roll|die|dice)\\b/.test(\n `${normalizedFormula} ${normalizedContent}`,\n )\n ) {\n return false;\n }\n if (!/=\\s*(?:[^.;]*\\d+\\s*\\/\\s*\\d+|0\\b|[^.;]*\\d+(?:\\.\\d+)?%)/.test(normalizedFormula)) {\n return false;\n }\n if (/\\b(?:first die|second die|two dice|sum of|deck|card|ace|king|queen|heart|birthday|conditional|dependent)\\b/.test(normalizedFormula)) {\n return false;\n }\n if (/^p\\(\\s*a\\b/.test(normalizedFormula)) {\n return false;\n }\n if (/\\bnumber of problems\\b/.test(normalizedContent)) {\n return false;\n }\n return true;\n}\n\nfunction isStrictSimpleProbabilityLabel(label: string): boolean {\n const normalizedFormula = label.toLowerCase();\n return /\\b(?:heads|coin|coins|toss|tosses|rolling|roll|die|dice)\\b/.test(\n normalizedFormula,\n ) &&\n /=\\s*(?:[^.;]*\\d+\\s*\\/\\s*\\d+|0\\b|[^.;]*\\d+(?:\\.\\d+)?%)/.test(\n normalizedFormula,\n ) &&\n !/\\b(?:first die|second die|two dice|sum of|deck|card|ace|king|queen|heart|birthday|conditional|dependent)\\b/.test(\n normalizedFormula,\n ) &&\n !/^p\\(\\s*a\\b/.test(normalizedFormula);\n}\n\nfunction findTemporalCutoffTurn(\n items: readonly EvidencePackItem[],\n query: string,\n cutoffPattern: RegExp,\n): number | undefined {\n if (!/\\bbefore\\b/i.test(query)) {\n return undefined;\n }\n let cutoff: number | undefined;\n for (const item of items) {\n if (typeof item.turnIndex !== \"number\") continue;\n if (!cutoffPattern.test(item.content)) continue;\n cutoff = cutoff === undefined ? item.turnIndex : Math.min(cutoff, item.turnIndex);\n }\n return cutoff;\n}\n\nfunction sortCountCandidates(left: CountCandidate, right: CountCandidate): number {\n const leftTurn = typeof left.turnIndex === \"number\" ? left.turnIndex : Number.MAX_SAFE_INTEGER;\n const rightTurn = typeof right.turnIndex === \"number\" ? right.turnIndex : Number.MAX_SAFE_INTEGER;\n if (leftTurn !== rightTurn) return leftTurn - rightTurn;\n return left.label.localeCompare(right.label);\n}\n\nfunction clipSummaryLabel(value: string): string {\n const trimmed = value.trim();\n return trimmed.length <= 180 ? trimmed : `${trimmed.slice(0, 177).trimEnd()}...`;\n}\n\nfunction normalizeCountCandidateKey(value: string): string {\n return value\n .toLowerCase()\n .replace(/\\s+/g, \" \")\n .replace(/[“”]/g, \"\\\"\")\n .replace(/[’]/g, \"'\")\n .replace(/\\bthe\\b/g, \"\")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\nfunction normalizeProbabilityCandidateKey(value: string): string {\n return normalizeCountCandidateKey(value)\n .replace(/\\s+(?:so|because|as)\\b.*$/g, \"\")\n .replace(/\\s+one more time\\b.*$/g, \"\")\n .replace(/\\s+is correct\\b.*$/g, \"\")\n .replace(/\\s+correct\\b.*$/g, \"\")\n .trim();\n}\n\nfunction numberWord(value: number): string | undefined {\n return NUMBER_WORDS[value];\n}\n\nfunction countFocusedTermOverlap(content: string, query: string): number {\n const terms = extractFocusedTerms(query);\n let overlap = 0;\n for (const term of terms) {\n if (content.includes(term)) overlap += 1;\n }\n return overlap;\n}\n\nfunction extractFocusedTerms(text: string): string[] {\n const terms = text.toLowerCase().match(/[a-z][a-z0-9-]{2,}/g) ?? [];\n return [...new Set(terms.filter((term) =>\n !FOCUSED_LIST_STOP_WORDS.has(term) &&\n !/^\\d+$/.test(term),\n ))];\n}\n\nfunction extractRelationTerms(text: string): string[] {\n return extractFocusedTerms(text).filter((term) =>\n !RELATION_STOP_WORDS.has(term) &&\n !/\\b(?:met|meet|meeting|know|connected|introduced)\\b/.test(term),\n );\n}\n\nfunction normalizePositiveInteger(value: number): number {\n if (!Number.isFinite(value) || value <= 0) {\n return 0;\n }\n return Math.floor(value);\n}\n\nfunction clipTextToBudget(text: string, maxChars: number): string {\n if (text.length <= maxChars) {\n return text;\n }\n if (maxChars <= 3) {\n return text.slice(0, Math.max(0, maxChars));\n }\n return `${text.slice(0, maxChars - 3).trimEnd()}...`;\n}\n\nconst FOCUSED_LIST_STOP_WORDS = new Set([\n \"about\",\n \"across\",\n \"after\",\n \"also\",\n \"and\",\n \"are\",\n \"before\",\n \"between\",\n \"can\",\n \"could\",\n \"did\",\n \"different\",\n \"does\",\n \"for\",\n \"from\",\n \"have\",\n \"how\",\n \"into\",\n \"many\",\n \"mention\",\n \"mentioned\",\n \"next\",\n \"off\",\n \"pay\",\n \"planning\",\n \"should\",\n \"some\",\n \"spend\",\n \"that\",\n \"the\",\n \"this\",\n \"time\",\n \"times\",\n \"total\",\n \"want\",\n \"wanted\",\n \"wanting\",\n \"were\",\n \"what\",\n \"when\",\n \"where\",\n \"which\",\n \"with\",\n \"would\",\n \"you\",\n]);\n\nconst RELATION_STOP_WORDS = new Set([\n \"did\",\n \"how\",\n \"know\",\n \"meet\",\n \"met\",\n \"say\",\n \"saying\",\n \"when\",\n \"where\",\n]);\n\nconst SPECIAL_EVENT_STOP_WORDS = new Set([\n \"events\",\n \"event\",\n \"planning\",\n \"place\",\n \"special\",\n \"take\",\n \"where\",\n \"will\",\n]);\n\nconst NUMBER_WORDS: Record<number, string> = {\n 0: \"zero\",\n 1: \"one\",\n 2: \"two\",\n 3: \"three\",\n 4: \"four\",\n 5: \"five\",\n 6: \"six\",\n 7: \"seven\",\n 8: \"eight\",\n 9: \"nine\",\n 10: \"ten\",\n 11: \"eleven\",\n 12: \"twelve\",\n 13: \"thirteen\",\n 14: \"fourteen\",\n 15: \"fifteen\",\n 16: \"sixteen\",\n 17: \"seventeen\",\n 18: \"eighteen\",\n 19: \"nineteen\",\n 20: \"twenty\",\n};\n"],"mappings":"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","names":[]}
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
import {
|
|
8
8
|
NamespaceStorageRouter,
|
|
9
9
|
namespaceCollectionName
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-HL5LRPNA.js";
|
|
11
11
|
import {
|
|
12
12
|
analyzeSessionIntegrity,
|
|
13
13
|
applySessionRepair,
|
|
@@ -16,6 +16,11 @@ import {
|
|
|
16
16
|
import {
|
|
17
17
|
resolveRemnicPluginEntry
|
|
18
18
|
} from "./chunk-U66YHYC7.js";
|
|
19
|
+
import {
|
|
20
|
+
resolveCuratedIncludeFilesStatePath,
|
|
21
|
+
resolveNativeKnowledgeStatePath,
|
|
22
|
+
resolveOpenClawWorkspaceStatePath
|
|
23
|
+
} from "./chunk-7SEAZFFB.js";
|
|
19
24
|
import {
|
|
20
25
|
createEvalBaselineSnapshot,
|
|
21
26
|
getEvalHarnessStatus,
|
|
@@ -26,18 +31,13 @@ import {
|
|
|
26
31
|
import {
|
|
27
32
|
readJudgeVerdictStats
|
|
28
33
|
} from "./chunk-AJU4PJGY.js";
|
|
29
|
-
import {
|
|
30
|
-
resolveCuratedIncludeFilesStatePath,
|
|
31
|
-
resolveNativeKnowledgeStatePath,
|
|
32
|
-
resolveOpenClawWorkspaceStatePath
|
|
33
|
-
} from "./chunk-7SEAZFFB.js";
|
|
34
34
|
import {
|
|
35
35
|
parseConfig
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-HY3L4WKC.js";
|
|
37
37
|
import {
|
|
38
38
|
listMemoryGovernanceRuns,
|
|
39
39
|
readMemoryGovernanceRunArtifact
|
|
40
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-4YM32CRU.js";
|
|
41
41
|
import {
|
|
42
42
|
isSafeRouteNamespace
|
|
43
43
|
} from "./chunk-2LGMW3DJ.js";
|
|
@@ -46,7 +46,7 @@ import {
|
|
|
46
46
|
} from "./chunk-RK2Y4XOM.js";
|
|
47
47
|
import {
|
|
48
48
|
StorageManager
|
|
49
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-3B6KIRBH.js";
|
|
50
50
|
import {
|
|
51
51
|
lintWorkspaceFiles
|
|
52
52
|
} from "./chunk-DM2T26WE.js";
|
|
@@ -1448,4 +1448,4 @@ export {
|
|
|
1448
1448
|
runBenchmarkRecall,
|
|
1449
1449
|
runOperatorRepair
|
|
1450
1450
|
};
|
|
1451
|
-
//# sourceMappingURL=chunk-
|
|
1451
|
+
//# sourceMappingURL=chunk-DZZPC36E.js.map
|
|
@@ -3,7 +3,10 @@ import {
|
|
|
3
3
|
} from "./chunk-SOBJ6NEY.js";
|
|
4
4
|
import {
|
|
5
5
|
summarizeDisclosureTokens
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-JKDVIE52.js";
|
|
7
|
+
import {
|
|
8
|
+
summarizeRetrievedMemoryProvenance
|
|
9
|
+
} from "./chunk-AC5LO7IU.js";
|
|
7
10
|
|
|
8
11
|
// src/recall-explain-renderer.ts
|
|
9
12
|
function sanitizeString(v) {
|
|
@@ -301,6 +304,21 @@ function renderResultTextLines(result, rank) {
|
|
|
301
304
|
lines.push(`[${rank}] ${result.memoryId} \u2014 ${servedByLabel(result.servedBy)}`);
|
|
302
305
|
if (result.path) lines.push(` path: ${result.path}`);
|
|
303
306
|
lines.push(` score: ${renderScoreDecomposition(result)}`);
|
|
307
|
+
if (result.provenance) {
|
|
308
|
+
lines.push(
|
|
309
|
+
` provenance: ${summarizeRetrievedMemoryProvenance(result.provenance)}`
|
|
310
|
+
);
|
|
311
|
+
lines.push(` retrieval-reason: ${result.provenance.retrievalReason}`);
|
|
312
|
+
if (result.provenance.userContextScopes.length > 0) {
|
|
313
|
+
lines.push(
|
|
314
|
+
` context-scopes: ${result.provenance.userContextScopes.join(", ")}`
|
|
315
|
+
);
|
|
316
|
+
}
|
|
317
|
+
if (result.provenance.safety !== "safe" || result.provenance.safetyReasons.length > 0) {
|
|
318
|
+
const reasonSuffix = result.provenance.safetyReasons.length > 0 ? ` (${result.provenance.safetyReasons.join(", ")})` : "";
|
|
319
|
+
lines.push(` safety: ${result.provenance.safety}${reasonSuffix}`);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
304
322
|
if (result.admittedBy.length > 0) {
|
|
305
323
|
lines.push(` admitted-by: ${result.admittedBy.join(", ")}`);
|
|
306
324
|
}
|
|
@@ -438,6 +456,25 @@ function renderResultMarkdownLines(result, rank) {
|
|
|
438
456
|
lines.push("");
|
|
439
457
|
}
|
|
440
458
|
lines.push(`- **Score:** ${renderScoreDecomposition(result)}`);
|
|
459
|
+
if (result.provenance) {
|
|
460
|
+
lines.push(
|
|
461
|
+
`- **Provenance:** ${mdEscape(summarizeRetrievedMemoryProvenance(result.provenance))}`
|
|
462
|
+
);
|
|
463
|
+
lines.push(
|
|
464
|
+
`- **Retrieval reason:** ${mdInlineCode(result.provenance.retrievalReason)}`
|
|
465
|
+
);
|
|
466
|
+
if (result.provenance.userContextScopes.length > 0) {
|
|
467
|
+
lines.push(
|
|
468
|
+
`- **Context scopes:** ${result.provenance.userContextScopes.map(mdInlineCode).join(", ")}`
|
|
469
|
+
);
|
|
470
|
+
}
|
|
471
|
+
if (result.provenance.safety !== "safe" || result.provenance.safetyReasons.length > 0) {
|
|
472
|
+
const reasonSuffix = result.provenance.safetyReasons.length > 0 ? ` (${result.provenance.safetyReasons.map(mdInlineCode).join(", ")})` : "";
|
|
473
|
+
lines.push(
|
|
474
|
+
`- **Safety:** ${mdInlineCode(result.provenance.safety)}${reasonSuffix}`
|
|
475
|
+
);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
441
478
|
if (result.admittedBy.length > 0) {
|
|
442
479
|
lines.push(
|
|
443
480
|
`- **Admitted by:** ${result.admittedBy.map(mdInlineCode).join(", ")}`
|
|
@@ -530,4 +567,4 @@ export {
|
|
|
530
567
|
renderRecallExplain,
|
|
531
568
|
parseRecallExplainFormat
|
|
532
569
|
};
|
|
533
|
-
//# sourceMappingURL=chunk-
|
|
570
|
+
//# sourceMappingURL=chunk-E2UCDP5S.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/recall-explain-renderer.ts","../src/recall-xray-renderer.ts"],"sourcesContent":["/**\n * Renderers for RecallTierExplain (issue #518).\n *\n * Pure functions that format a `LastRecallSnapshot` and its\n * optional `tierExplain` field for human text and machine JSON\n * consumption. CLI / HTTP / MCP surfaces consume these — they do\n * not format explain output themselves, so rendering is tested in\n * one place.\n */\n\nimport type { LastRecallSnapshot } from \"./recall-state.js\";\nimport type { RecallTierExplain } from \"./types.js\";\nimport { isRetrievalTier } from \"./retrieval-tiers.js\";\nimport type {\n RecallXraySnapshot,\n RecallFilterTrace,\n RecallXrayResult,\n} from \"./recall-xray.js\";\nimport { renderXrayMarkdown } from \"./recall-xray-renderer.js\";\n\nfunction sanitizeString(v: unknown): string | null {\n return typeof v === \"string\" && v.length > 0 ? v : null;\n}\n\nfunction sanitizeFiniteNumber(v: unknown): number | null {\n return typeof v === \"number\" && Number.isFinite(v) ? v : null;\n}\n\n/**\n * `text` and `json` are the original formats (backwards-compatible\n * since issue #518). `markdown` was added in issue #570 PR 7 and\n * delegates to the shared X-ray renderer so the three observability\n * surfaces stay in lock-step (CLAUDE.md rule 22).\n */\nexport type RecallExplainFormat = \"text\" | \"json\" | \"markdown\";\n\nexport interface RecallExplainJsonPayload {\n hasExplain: boolean;\n snapshotFound: boolean;\n sessionKey: string | null;\n recordedAt: string | null;\n namespace: string | null;\n memoryIds: string[];\n source: string | null;\n sourcesUsed: string[] | null;\n latencyMs: number | null;\n tierExplain: RecallTierExplain | null;\n}\n\nfunction normalizeTierExplain(value: unknown): RecallTierExplain | null {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return null;\n const raw = value as Record<string, unknown>;\n const filteredBy = Array.isArray(raw.filteredBy)\n ? raw.filteredBy.filter((x): x is string => typeof x === \"string\")\n : [];\n const sourceAnchors = Array.isArray(raw.sourceAnchors)\n ? raw.sourceAnchors\n .filter(\n (a): a is { path: string; lineRange?: unknown } =>\n !!a && typeof a === \"object\" && typeof (a as { path?: unknown }).path === \"string\",\n )\n .map((a) => {\n const lr = (a as { lineRange?: unknown }).lineRange;\n const lineRange =\n Array.isArray(lr) &&\n lr.length === 2 &&\n Number.isFinite(lr[0]) &&\n Number.isFinite(lr[1])\n ? ([lr[0] as number, lr[1] as number] as [number, number])\n : undefined;\n return lineRange\n ? { path: (a as { path: string }).path, lineRange }\n : { path: (a as { path: string }).path };\n })\n : undefined;\n return {\n tier: isRetrievalTier(raw.tier) ? raw.tier : \"hybrid\",\n tierReason: typeof raw.tierReason === \"string\" ? raw.tierReason : \"\",\n filteredBy,\n candidatesConsidered: sanitizeFiniteNumber(raw.candidatesConsidered) ?? 0,\n latencyMs: sanitizeFiniteNumber(raw.latencyMs) ?? 0,\n ...(sourceAnchors !== undefined ? { sourceAnchors } : {}),\n };\n}\n\nexport function toRecallExplainJson(\n snapshot: LastRecallSnapshot | null,\n): RecallExplainJsonPayload {\n if (!snapshot) {\n return {\n hasExplain: false,\n snapshotFound: false,\n sessionKey: null,\n recordedAt: null,\n namespace: null,\n memoryIds: [],\n source: null,\n sourcesUsed: null,\n latencyMs: null,\n tierExplain: null,\n };\n }\n const normalizedExplain = normalizeTierExplain(snapshot.tierExplain);\n return {\n hasExplain: normalizedExplain !== null,\n snapshotFound: true,\n sessionKey: sanitizeString(snapshot.sessionKey),\n recordedAt: sanitizeString(snapshot.recordedAt),\n namespace: sanitizeString(snapshot.namespace),\n memoryIds: Array.isArray(snapshot.memoryIds)\n ? snapshot.memoryIds.filter((x): x is string => typeof x === \"string\")\n : [],\n source: sanitizeString(snapshot.source),\n sourcesUsed: Array.isArray(snapshot.sourcesUsed)\n ? snapshot.sourcesUsed.filter((x): x is string => typeof x === \"string\")\n : null,\n latencyMs: sanitizeFiniteNumber(snapshot.latencyMs),\n tierExplain: normalizedExplain,\n };\n}\n\n/**\n * Render the shared \"--- tier explain ---\" text block used by both the\n * recall-explain surface and the Recall X-ray surface. Callers provide\n * the normalized `RecallTierExplain` (or `null` for the\n * not-populated/disabled case) so the block stays character-for-character\n * identical across surfaces (CLAUDE.md rule 22). The returned strings do\n * NOT include leading blank lines or headers — callers own that framing.\n */\nexport function renderTierExplainTextLines(\n tierExplain: RecallTierExplain | null,\n): string[] {\n const lines: string[] = [];\n if (!tierExplain) {\n lines.push(\n \"(not populated — direct-answer tier disabled or did not fire)\",\n );\n return lines;\n }\n lines.push(`tier: ${tierExplain.tier}`);\n lines.push(`reason: ${tierExplain.tierReason}`);\n lines.push(`candidates-considered: ${tierExplain.candidatesConsidered}`);\n lines.push(`latency-ms: ${tierExplain.latencyMs}`);\n if (tierExplain.filteredBy.length > 0) {\n lines.push(`filtered-by: ${tierExplain.filteredBy.join(\", \")}`);\n } else {\n lines.push(\"filtered-by: (none)\");\n }\n if (tierExplain.sourceAnchors && tierExplain.sourceAnchors.length > 0) {\n lines.push(\"source-anchors:\");\n for (const anchor of tierExplain.sourceAnchors) {\n const range = anchor.lineRange\n ? `:${anchor.lineRange[0]}-${anchor.lineRange[1]}`\n : \"\";\n lines.push(` - ${anchor.path}${range}`);\n }\n }\n return lines;\n}\n\nexport function toRecallExplainText(\n snapshot: LastRecallSnapshot | null,\n): string {\n const lines: string[] = [\"=== Recall Explain ===\"];\n\n if (!snapshot) {\n lines.push(\"No recall snapshot recorded yet.\");\n return lines.join(\"\\n\");\n }\n\n const sessionKey = sanitizeString(snapshot.sessionKey);\n const recordedAt = sanitizeString(snapshot.recordedAt);\n const namespace = sanitizeString(snapshot.namespace);\n const source = sanitizeString(snapshot.source);\n lines.push(`session: ${sessionKey ?? \"(unknown)\"}`);\n lines.push(`recorded: ${recordedAt ?? \"(unknown)\"}`);\n if (namespace) lines.push(`namespace: ${namespace}`);\n if (source) lines.push(`source: ${source}`);\n const sourcesUsed = Array.isArray(snapshot.sourcesUsed)\n ? snapshot.sourcesUsed.filter((x): x is string => typeof x === \"string\")\n : [];\n if (sourcesUsed.length > 0) {\n lines.push(`sources-used: ${sourcesUsed.join(\", \")}`);\n }\n const latencyMs = sanitizeFiniteNumber(snapshot.latencyMs);\n if (latencyMs !== null) {\n lines.push(`latency-ms: ${latencyMs}`);\n }\n const memoryIds = Array.isArray(snapshot.memoryIds)\n ? snapshot.memoryIds.filter((x): x is string => typeof x === \"string\")\n : [];\n if (memoryIds.length > 0) {\n lines.push(`memories: ${memoryIds.join(\", \")}`);\n }\n\n const ex = normalizeTierExplain(snapshot.tierExplain);\n if (!ex) {\n lines.push(\"\");\n lines.push(\n \"tier-explain: (not populated — direct-answer tier disabled or did not fire)\",\n );\n return lines.join(\"\\n\");\n }\n\n lines.push(\"\");\n lines.push(\"--- tier explain ---\");\n for (const line of renderTierExplainTextLines(ex)) {\n lines.push(line);\n }\n return lines.join(\"\\n\");\n}\n\n/**\n * Adapter: convert a `LastRecallSnapshot` into a best-effort\n * `RecallXraySnapshot` so the markdown renderer can produce a\n * consistent, richly-formatted document for callers that have asked\n * for `markdown` format. The LastRecallSnapshot and the X-ray\n * snapshot share session/namespace/memoryIds; additional X-ray-only\n * fields (filters, score decomposition, graph path, audit id) are\n * left empty because the legacy snapshot doesn't carry them. The\n * renderer handles missing fields gracefully.\n */\n/**\n * Strip backticks, pipes, and newlines from a host-provided value so it\n * cannot escape its enclosing markdown code span, break the surrounding\n * table row, or inject extra rows when it lands in\n * `renderXrayMarkdown`. Applied at the adapter boundary because\n * `LastRecallSnapshot` is hydrated from on-disk JSON without schema\n * validation (codex P2 review on #605).\n *\n * Accepts `unknown` so non-string truthy values (numbers, objects,\n * booleans, arrays) coming from a corrupted snapshot are coerced to\n * the empty string rather than crashing on `.replace(...)`. Callers\n * should treat an empty return as \"drop this field.\"\n */\nfunction sanitizeForMarkdownInline(value: unknown): string {\n if (typeof value !== \"string\") return \"\";\n return value.replace(/[`|\\r\\n]/g, \" \").trim();\n}\n\n/**\n * Map the legacy `LastRecallSnapshot.source` field to the\n * `RecallXrayServedBy` union used by the unified x-ray renderer.\n * Mirrors the `mapRecallSourceToXrayServedBy` helper inside\n * `orchestrator.ts` (which is private). Keep the two in sync when a\n * new source lands — unknown values collapse to `\"hybrid\"` to preserve\n * backwards compatibility with older on-disk snapshots.\n */\nfunction mapLegacySourceToServedBy(\n source: unknown,\n): \"hybrid\" | \"recent-scan\" {\n if (source === \"recent_scan\") return \"recent-scan\";\n return \"hybrid\";\n}\n\nexport function toRecallXraySnapshotFromLegacy(\n snapshot: LastRecallSnapshot | null,\n): RecallXraySnapshot | null {\n if (!snapshot) return null;\n const capturedAt = (() => {\n if (typeof snapshot.recordedAt !== \"string\") return 0;\n const ms = Date.parse(snapshot.recordedAt);\n return Number.isFinite(ms) && ms >= 0 ? ms : 0;\n })();\n const memoryIds = Array.isArray(snapshot.memoryIds)\n ? snapshot.memoryIds.filter((x): x is string => typeof x === \"string\")\n : [];\n // Codex P2 + Cursor Medium on #605: every converted result used to\n // be stamped with `servedBy: \"hybrid\"`, misattributing legacy\n // snapshots that came from `recent_scan` (or any future source).\n // Propagate the recorded `source` so markdown `recall-explain`\n // output matches the `served-by=` string the native x-ray capture\n // would emit for the same recall.\n const servedBy = mapLegacySourceToServedBy(snapshot.source);\n const results: RecallXrayResult[] = memoryIds.map((memoryId) => ({\n memoryId,\n path: \"\",\n servedBy,\n scoreDecomposition: { final: 0 },\n admittedBy: [],\n }));\n const filters: RecallFilterTrace[] = [];\n return {\n schemaVersion: \"1\",\n // `LastRecallSnapshot` does not preserve the original query text;\n // synthesize a placeholder so the renderer has a non-empty\n // string to print. `queryHash` + `queryLen` stay in the JSON\n // payload via `toRecallExplainJson` for callers that need them.\n query:\n snapshot.queryHash\n ? `(legacy explain; queryHash=${snapshot.queryHash})`\n : \"(legacy explain)\",\n // `snapshotId` is synthesized here; `sessionKey` is already\n // sanitized before it reaches the ID because we re-use the\n // sanitized string below.\n snapshotId: `legacy-${sanitizeForMarkdownInline(snapshot.sessionKey ?? \"unknown\") || \"unknown\"}-${capturedAt}`,\n capturedAt,\n // Run the raw on-disk value through the same normalizer the text\n // and JSON paths use so the markdown adapter cannot render\n // unvalidated tier-explain payloads (cursor / codex review on\n // #605). A malformed tierExplain is dropped to null, matching the\n // behavior of the non-markdown surfaces.\n tierExplain: normalizeTierExplain(snapshot.tierExplain) ?? null,\n results,\n filters,\n budget: { chars: 0, used: 0 },\n // Sanitize legacy session metadata at the adapter boundary so a\n // malformed on-disk value (containing backticks, pipes, or\n // newlines) cannot break the enclosing markdown table when\n // `renderXrayMarkdown` prints it in a raw code-span cell (codex P2\n // review on #605).\n ...(snapshot.sessionKey\n ? (() => {\n const clean = sanitizeForMarkdownInline(snapshot.sessionKey);\n return clean ? { sessionKey: clean } : {};\n })()\n : {}),\n ...(snapshot.namespace\n ? (() => {\n const clean = sanitizeForMarkdownInline(snapshot.namespace);\n return clean ? { namespace: clean } : {};\n })()\n : {}),\n };\n}\n\nexport function renderRecallExplain(\n snapshot: LastRecallSnapshot | null,\n format: RecallExplainFormat,\n): string {\n if (format === \"json\") {\n return JSON.stringify(toRecallExplainJson(snapshot), null, 2);\n }\n if (format === \"markdown\") {\n // Delegate to the shared X-ray renderer so CLI / HTTP / MCP\n // markdown output all share one implementation (CLAUDE.md rule\n // 22). The JSON and text paths remain byte-for-byte\n // backwards-compatible with pre-#570 behavior.\n return renderXrayMarkdown(toRecallXraySnapshotFromLegacy(snapshot));\n }\n return toRecallExplainText(snapshot);\n}\n\nexport function parseRecallExplainFormat(value: unknown): RecallExplainFormat {\n if (value === undefined || value === null) return \"text\";\n if (typeof value !== \"string\") {\n throw new Error(\n `--format expects \"text\", \"json\", or \"markdown\", got ${typeof value}`,\n );\n }\n const v = value.trim().toLowerCase();\n if (v === \"text\" || v === \"json\" || v === \"markdown\") return v;\n throw new Error(\n `--format expects \"text\", \"json\", or \"markdown\", got ${JSON.stringify(value)}`,\n );\n}\n","/**\n * Unified Recall X-ray renderer (issue #570, PR 2).\n *\n * Pure functions that format a `RecallXraySnapshot` for human text,\n * GitHub-flavored markdown, and machine JSON consumption. CLI / HTTP\n * / MCP surfaces all call into this module — they do NOT format X-ray\n * output themselves, so rendering is tested in one place (CLAUDE.md\n * rule 22).\n *\n * Scope for PR 2 (this slice):\n * - Pure rendering. No IO, no transport, no capture.\n * - `renderXray(snapshot, format)` with format ∈\n * `{\"json\", \"text\", \"markdown\"}`.\n * - `parseXrayFormat(value)` — input validator that rejects unknown\n * formats with a listed-options error (CLAUDE.md rule 51).\n * - Golden-file-style tests in `recall-xray-renderer.test.ts`.\n */\n\nimport type {\n RecallFilterTrace,\n RecallXrayResult,\n RecallXraySnapshot,\n RecallXrayServedBy,\n} from \"./recall-xray.js\";\nimport { summarizeDisclosureTokens } from \"./recall-xray.js\";\nimport { renderTierExplainTextLines } from \"./recall-explain-renderer.js\";\nimport { summarizeRetrievedMemoryProvenance } from \"./memory-provenance.js\";\n\nexport type RecallXrayFormat = \"json\" | \"text\" | \"markdown\";\n\nexport const RECALL_XRAY_FORMATS: readonly RecallXrayFormat[] = [\n \"json\",\n \"text\",\n \"markdown\",\n] as const;\n\n/**\n * Validate and coerce a user-provided `--format` / `format` argument to\n * `RecallXrayFormat`. Unknown values throw an error listing valid\n * options (CLAUDE.md rule 51). `undefined`/`null` defaults to `\"text\"`.\n */\nexport function parseXrayFormat(value: unknown): RecallXrayFormat {\n if (value === undefined || value === null) return \"text\";\n if (typeof value !== \"string\") {\n throw new Error(\n `--format expects one of ${RECALL_XRAY_FORMATS.join(\", \")}; got ${typeof value}`,\n );\n }\n const v = value.trim().toLowerCase();\n if (v === \"json\" || v === \"text\" || v === \"markdown\") return v;\n throw new Error(\n `--format expects one of ${RECALL_XRAY_FORMATS.join(\", \")}; got ${JSON.stringify(value)}`,\n );\n}\n\n/**\n * Top-level dispatcher. CLI / HTTP / MCP callers should always route\n * through this function so the three formats stay in lock-step.\n */\nexport function renderXray(\n snapshot: RecallXraySnapshot | null,\n format: RecallXrayFormat,\n): string {\n if (format === \"json\") return renderXrayJson(snapshot);\n if (format === \"markdown\") return renderXrayMarkdown(snapshot);\n return renderXrayText(snapshot);\n}\n\n// ─── JSON ─────────────────────────────────────────────────────────────────\n\n/**\n * Deterministic JSON encoding of an X-ray snapshot. Returns a stable\n * v1 envelope when the snapshot is absent so consumers can pattern-match\n * on `snapshotFound` rather than distinguishing `null` vs `{}`.\n */\nexport function renderXrayJson(snapshot: RecallXraySnapshot | null): string {\n if (!snapshot) {\n return JSON.stringify(\n { schemaVersion: \"1\", snapshotFound: false },\n null,\n 2,\n );\n }\n // `snapshotFound` is injected *before* the rest so downstream JSON\n // consumers see it near the top of the document.\n return JSON.stringify(\n { snapshotFound: true, ...snapshot },\n null,\n 2,\n );\n}\n\n// ─── Text ─────────────────────────────────────────────────────────────────\n\nexport function renderXrayText(snapshot: RecallXraySnapshot | null): string {\n const lines: string[] = [\"=== Recall X-ray ===\"];\n if (!snapshot) {\n lines.push(\"No X-ray snapshot captured.\");\n return lines.join(\"\\n\");\n }\n\n lines.push(`query: ${snapshot.query}`);\n lines.push(`snapshot-id: ${snapshot.snapshotId}`);\n lines.push(`captured-at: ${formatCapturedAt(snapshot.capturedAt)}`);\n if (snapshot.sessionKey) lines.push(`session: ${snapshot.sessionKey}`);\n if (snapshot.namespace) lines.push(`namespace: ${snapshot.namespace}`);\n if (snapshot.traceId) lines.push(`trace-id: ${snapshot.traceId}`);\n lines.push(\n `budget: ${snapshot.budget.used} / ${snapshot.budget.chars} chars`,\n );\n\n lines.push(\"\");\n lines.push(\"--- filters ---\");\n if (snapshot.filters.length === 0) {\n lines.push(\"(no filter traces recorded)\");\n } else {\n for (const f of snapshot.filters) {\n lines.push(renderFilterTextLine(f));\n }\n }\n\n lines.push(\"\");\n lines.push(\"--- results ---\");\n if (snapshot.results.length === 0) {\n lines.push(\"(no results admitted)\");\n } else {\n snapshot.results.forEach((result, idx) => {\n for (const line of renderResultTextLines(result, idx + 1)) {\n lines.push(line);\n }\n });\n }\n\n lines.push(\"\");\n lines.push(\"--- tier explain ---\");\n for (const line of renderTierExplainTextLines(snapshot.tierExplain ?? null)) {\n lines.push(line);\n }\n\n return lines.join(\"\\n\");\n}\n\nfunction renderFilterTextLine(f: RecallFilterTrace): string {\n const base = `- ${f.name}: ${f.admitted}/${f.considered} admitted`;\n return f.reason ? `${base} (${f.reason})` : base;\n}\n\nfunction renderResultTextLines(\n result: RecallXrayResult,\n rank: number,\n): string[] {\n const lines: string[] = [];\n lines.push(`[${rank}] ${result.memoryId} — ${servedByLabel(result.servedBy)}`);\n if (result.path) lines.push(` path: ${result.path}`);\n lines.push(` score: ${renderScoreDecomposition(result)}`);\n if (result.provenance) {\n lines.push(\n ` provenance: ${summarizeRetrievedMemoryProvenance(result.provenance)}`,\n );\n lines.push(` retrieval-reason: ${result.provenance.retrievalReason}`);\n if (result.provenance.userContextScopes.length > 0) {\n lines.push(\n ` context-scopes: ${result.provenance.userContextScopes.join(\", \")}`,\n );\n }\n if (\n result.provenance.safety !== \"safe\" ||\n result.provenance.safetyReasons.length > 0\n ) {\n const reasonSuffix =\n result.provenance.safetyReasons.length > 0\n ? ` (${result.provenance.safetyReasons.join(\", \")})`\n : \"\";\n lines.push(` safety: ${result.provenance.safety}${reasonSuffix}`);\n }\n }\n if (result.admittedBy.length > 0) {\n lines.push(` admitted-by: ${result.admittedBy.join(\", \")}`);\n }\n if (result.rejectedBy) {\n lines.push(` rejected-by: ${result.rejectedBy}`);\n }\n if (result.graphPath && result.graphPath.length > 0) {\n lines.push(` graph-path: ${result.graphPath.join(\" -> \")}`);\n // Issue #681 PR 3/3 — surface per-edge confidence inline so\n // operators can attribute floor-pruning / PageRank ranking\n // decisions to specific edges. Skipped when no confidences were\n // recorded (legacy snapshot or single-node path).\n if (\n result.graphEdgeConfidences &&\n result.graphEdgeConfidences.length > 0\n ) {\n lines.push(\n ` edge-confidences: ${result.graphEdgeConfidences\n .map((c) => c.toFixed(2))\n .join(\", \")}`,\n );\n }\n }\n if (result.auditEntryId) {\n lines.push(` audit-entry: ${result.auditEntryId}`);\n }\n return lines;\n}\n\n// ─── Markdown ─────────────────────────────────────────────────────────────\n\nexport function renderXrayMarkdown(\n snapshot: RecallXraySnapshot | null,\n): string {\n const lines: string[] = [\"# Recall X-ray\"];\n if (!snapshot) {\n lines.push(\"\");\n lines.push(\"_No X-ray snapshot captured._\");\n return lines.join(\"\\n\");\n }\n\n lines.push(\"\");\n lines.push(`**Query:** ${mdInlineCode(snapshot.query)}`);\n lines.push(\"\");\n lines.push(\"| Field | Value |\");\n lines.push(\"| --- | --- |\");\n lines.push(`| Snapshot ID | \\`${snapshot.snapshotId}\\` |`);\n lines.push(`| Captured at | ${formatCapturedAt(snapshot.capturedAt)} |`);\n if (snapshot.sessionKey) {\n lines.push(`| Session | \\`${snapshot.sessionKey}\\` |`);\n }\n if (snapshot.namespace) {\n lines.push(`| Namespace | \\`${snapshot.namespace}\\` |`);\n }\n if (snapshot.traceId) {\n lines.push(`| Trace ID | \\`${snapshot.traceId}\\` |`);\n }\n lines.push(\n `| Budget | ${snapshot.budget.used} / ${snapshot.budget.chars} chars |`,\n );\n\n lines.push(\"\");\n lines.push(\"## Filters\");\n if (snapshot.filters.length === 0) {\n lines.push(\"\");\n lines.push(\"_No filter traces recorded._\");\n } else {\n lines.push(\"\");\n lines.push(\"| Filter | Considered | Admitted | Reason |\");\n lines.push(\"| --- | ---: | ---: | --- |\");\n for (const f of snapshot.filters) {\n const reason = f.reason ? mdEscape(f.reason) : \"\";\n lines.push(`| ${mdEscape(f.name)} | ${f.considered} | ${f.admitted} | ${reason} |`);\n }\n }\n\n lines.push(\"\");\n lines.push(\"## Results\");\n if (snapshot.results.length === 0) {\n lines.push(\"\");\n lines.push(\"_No results admitted._\");\n } else {\n snapshot.results.forEach((result, idx) => {\n for (const line of renderResultMarkdownLines(result, idx + 1)) {\n lines.push(line);\n }\n });\n\n // Per-disclosure token-spend summary (issue #677 PR 3/4). Only\n // emitted when at least one result carries a disclosure level so\n // we don't pollute the snapshot for callers who haven't wired the\n // depth knob through. Counts and tokens default to 0 for buckets\n // with no contributions.\n const summary = summarizeDisclosureTokens(snapshot.results);\n const hasAnyDisclosure =\n summary.chunk.count + summary.section.count + summary.raw.count > 0;\n if (hasAnyDisclosure) {\n lines.push(\"\");\n lines.push(\"### Token spend by disclosure\");\n lines.push(\"\");\n lines.push(\"| Disclosure | Results | Estimated tokens |\");\n lines.push(\"| --- | ---: | ---: |\");\n lines.push(\n `| chunk | ${summary.chunk.count} | ${summary.chunk.estimatedTokens} |`,\n );\n lines.push(\n `| section | ${summary.section.count} | ${summary.section.estimatedTokens} |`,\n );\n lines.push(\n `| raw | ${summary.raw.count} | ${summary.raw.estimatedTokens} |`,\n );\n if (summary.unspecified.count > 0) {\n lines.push(\n `| _(unspecified)_ | ${summary.unspecified.count} | ${summary.unspecified.estimatedTokens} |`,\n );\n }\n }\n }\n\n lines.push(\"\");\n lines.push(\"## Tier Explain\");\n if (!snapshot.tierExplain) {\n lines.push(\"\");\n lines.push(\n \"_Not populated — direct-answer tier disabled or did not fire._\",\n );\n } else {\n const te = snapshot.tierExplain;\n lines.push(\"\");\n lines.push(\"| Field | Value |\");\n lines.push(\"| --- | --- |\");\n lines.push(`| Tier | \\`${te.tier}\\` |`);\n lines.push(`| Reason | ${mdEscape(te.tierReason)} |`);\n lines.push(`| Candidates considered | ${te.candidatesConsidered} |`);\n lines.push(`| Latency (ms) | ${te.latencyMs} |`);\n lines.push(\n `| Filtered by | ${\n te.filteredBy.length > 0\n ? te.filteredBy.map(mdInlineCode).join(\", \")\n : \"_(none)_\"\n } |`,\n );\n if (te.sourceAnchors && te.sourceAnchors.length > 0) {\n lines.push(\"\");\n lines.push(\"**Source anchors:**\");\n for (const anchor of te.sourceAnchors) {\n const range = anchor.lineRange\n ? `:${anchor.lineRange[0]}-${anchor.lineRange[1]}`\n : \"\";\n lines.push(`- \\`${anchor.path}${range}\\``);\n }\n }\n }\n\n return lines.join(\"\\n\");\n}\n\nfunction renderResultMarkdownLines(\n result: RecallXrayResult,\n rank: number,\n): string[] {\n const lines: string[] = [];\n lines.push(\"\");\n lines.push(\n `### ${rank}. \\`${result.memoryId}\\` — ${servedByLabel(result.servedBy)}`,\n );\n if (result.path) {\n lines.push(\"\");\n lines.push(`- **Path:** \\`${result.path}\\``);\n } else {\n lines.push(\"\");\n }\n lines.push(`- **Score:** ${renderScoreDecomposition(result)}`);\n if (result.provenance) {\n lines.push(\n `- **Provenance:** ${mdEscape(summarizeRetrievedMemoryProvenance(result.provenance))}`,\n );\n lines.push(\n `- **Retrieval reason:** ${mdInlineCode(result.provenance.retrievalReason)}`,\n );\n if (result.provenance.userContextScopes.length > 0) {\n lines.push(\n `- **Context scopes:** ${result.provenance.userContextScopes\n .map(mdInlineCode)\n .join(\", \")}`,\n );\n }\n if (\n result.provenance.safety !== \"safe\" ||\n result.provenance.safetyReasons.length > 0\n ) {\n const reasonSuffix =\n result.provenance.safetyReasons.length > 0\n ? ` (${result.provenance.safetyReasons.map(mdInlineCode).join(\", \")})`\n : \"\";\n lines.push(\n `- **Safety:** ${mdInlineCode(result.provenance.safety)}${reasonSuffix}`,\n );\n }\n }\n if (result.admittedBy.length > 0) {\n lines.push(\n `- **Admitted by:** ${result.admittedBy.map(mdInlineCode).join(\", \")}`,\n );\n }\n if (result.rejectedBy) {\n lines.push(`- **Rejected by:** ${mdInlineCode(result.rejectedBy)}`);\n }\n if (result.graphPath && result.graphPath.length > 0) {\n lines.push(\n `- **Graph path:** ${result.graphPath\n .map(mdInlineCode)\n .join(\" → \")}`,\n );\n // Issue #681 PR 3/3 — render per-edge confidences as a parallel\n // markdown line so operators can correlate them with the path\n // arrows above. Skipped when no confidences were recorded.\n if (\n result.graphEdgeConfidences &&\n result.graphEdgeConfidences.length > 0\n ) {\n lines.push(\n `- **Edge confidences:** ${result.graphEdgeConfidences\n .map((c) => mdInlineCode(c.toFixed(2)))\n .join(\", \")}`,\n );\n }\n }\n if (result.auditEntryId) {\n lines.push(`- **Audit entry:** \\`${result.auditEntryId}\\``);\n }\n if (result.disclosure !== undefined) {\n const tokenLine =\n typeof result.estimatedTokens === \"number\"\n ? ` (~${result.estimatedTokens} tokens)`\n : \"\";\n lines.push(`- **Disclosure:** \\`${result.disclosure}\\`${tokenLine}`);\n } else if (typeof result.estimatedTokens === \"number\") {\n // Disclosure unspecified but tokens recorded — still surface the\n // budget so the operator can attribute spend.\n lines.push(`- **Estimated tokens:** ${result.estimatedTokens}`);\n }\n return lines;\n}\n\n// ─── Shared helpers ───────────────────────────────────────────────────────\n\nfunction servedByLabel(servedBy: RecallXrayServedBy): string {\n return `served-by=${servedBy}`;\n}\n\nfunction renderScoreDecomposition(result: RecallXrayResult): string {\n const parts: string[] = [`final=${formatScore(result.scoreDecomposition.final)}`];\n const s = result.scoreDecomposition;\n if (s.vector !== undefined) parts.push(`vector=${formatScore(s.vector)}`);\n if (s.bm25 !== undefined) parts.push(`bm25=${formatScore(s.bm25)}`);\n if (s.importance !== undefined) {\n parts.push(`importance=${formatScore(s.importance)}`);\n }\n if (s.mmrPenalty !== undefined) {\n parts.push(`mmr_penalty=${formatScore(s.mmrPenalty)}`);\n }\n if (s.tierPrior !== undefined) {\n parts.push(`tier_prior=${formatScore(s.tierPrior)}`);\n }\n if (s.reinforcementBoost !== undefined && s.reinforcementBoost > 0) {\n parts.push(`reinforcement_boost=${formatScore(s.reinforcementBoost)}`);\n }\n return parts.join(\" \");\n}\n\nfunction formatScore(value: number): string {\n // Deterministic 4-decimal formatting keeps golden files stable\n // without printing spurious trailing zeros via toString().\n if (!Number.isFinite(value)) return \"0.0000\";\n return value.toFixed(4);\n}\n\nfunction formatCapturedAt(ts: number): string {\n if (!Number.isFinite(ts) || ts < 0) return \"(unknown)\";\n // `new Date(n).toISOString()` throws a RangeError for finite numbers\n // outside the valid Date range (roughly |n| > 8.64e15). That case\n // can surface when snapshots are corrupted or captured with a\n // custom clock, so coerce it to the same \"(unknown)\" fallback\n // rather than crashing the renderer.\n try {\n return new Date(ts).toISOString();\n } catch {\n return \"(unknown)\";\n }\n}\n\nfunction mdEscape(value: string): string {\n // Pipe is the only character that breaks GFM table rendering; escape\n // backslash first so we do not re-escape the escape character.\n return value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\\|/g, \"\\\\|\");\n}\n\nfunction mdInlineCode(value: string): string {\n if (value.length === 0) return \"``\";\n // Use exactly enough backticks to unambiguously wrap content that\n // itself contains backticks (GFM rule).\n const longestRun = /`+/g;\n let maxLen = 0;\n for (const match of value.matchAll(longestRun)) {\n if (match[0].length > maxLen) maxLen = match[0].length;\n }\n const fence = \"`\".repeat(maxLen + 1);\n const pad = value.startsWith(\"`\") || value.endsWith(\"`\") ? \" \" : \"\";\n return `${fence}${pad}${value}${pad}${fence}`;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,75 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
validateRouteTarget
|
|
3
3
|
} from "./chunk-2LGMW3DJ.js";
|
|
4
|
+
import {
|
|
5
|
+
parseIsoUtcTimestamp
|
|
6
|
+
} from "./chunk-3B6KIRBH.js";
|
|
4
7
|
import {
|
|
5
8
|
log
|
|
6
9
|
} from "./chunk-2ODBA7MQ.js";
|
|
7
10
|
|
|
8
|
-
// src/utils/iso-timestamp.ts
|
|
9
|
-
var ISO_UTC_TIMESTAMP_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z$/;
|
|
10
|
-
var ISO_OFFSET_TIMESTAMP_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/;
|
|
11
|
-
function validateDateComponents(isoString) {
|
|
12
|
-
const match = isoString.match(
|
|
13
|
-
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})/
|
|
14
|
-
);
|
|
15
|
-
if (!match) return false;
|
|
16
|
-
const [, yStr, mStr, dStr, hStr, minStr, sStr] = match;
|
|
17
|
-
const y = Number(yStr);
|
|
18
|
-
const m = Number(mStr);
|
|
19
|
-
const d = Number(dStr);
|
|
20
|
-
const h = Number(hStr);
|
|
21
|
-
const min = Number(minStr);
|
|
22
|
-
const s = Number(sStr);
|
|
23
|
-
if (m < 1 || m > 12) return false;
|
|
24
|
-
if (d < 1 || d > 31) return false;
|
|
25
|
-
if (h > 23 || min > 59 || s > 59) return false;
|
|
26
|
-
const daysInMonth = new Date(y, m, 0).getDate();
|
|
27
|
-
if (d > daysInMonth) return false;
|
|
28
|
-
return true;
|
|
29
|
-
}
|
|
30
|
-
function validateOffset(isoString) {
|
|
31
|
-
const offsetMatch = isoString.match(/([+-])(\d{2}):(\d{2})$/);
|
|
32
|
-
if (!offsetMatch) return true;
|
|
33
|
-
const oh = Number(offsetMatch[2]);
|
|
34
|
-
const om = Number(offsetMatch[3]);
|
|
35
|
-
if (oh > 14 || om > 59) return false;
|
|
36
|
-
if (oh === 14 && om > 0) return false;
|
|
37
|
-
return true;
|
|
38
|
-
}
|
|
39
|
-
function normalizeUtcForComparison(value) {
|
|
40
|
-
const fracMatch = value.match(/\.(\d+)Z$/);
|
|
41
|
-
if (fracMatch) {
|
|
42
|
-
const ms = (fracMatch[1] + "000").slice(0, 3);
|
|
43
|
-
return value.replace(/\.\d+Z$/, `.${ms}Z`);
|
|
44
|
-
}
|
|
45
|
-
return value.replace(/Z$/, ".000Z");
|
|
46
|
-
}
|
|
47
|
-
function parseIsoUtcTimestamp(value) {
|
|
48
|
-
if (typeof value !== "string" || !ISO_UTC_TIMESTAMP_RE.test(value)) {
|
|
49
|
-
return null;
|
|
50
|
-
}
|
|
51
|
-
const ts = Date.parse(value);
|
|
52
|
-
if (!Number.isFinite(ts)) return null;
|
|
53
|
-
if (!validateDateComponents(value)) return null;
|
|
54
|
-
const roundTrip = new Date(ts).toISOString();
|
|
55
|
-
if (roundTrip !== normalizeUtcForComparison(value)) return null;
|
|
56
|
-
return ts;
|
|
57
|
-
}
|
|
58
|
-
function parseIsoOffsetTimestamp(value) {
|
|
59
|
-
if (typeof value !== "string" || !ISO_OFFSET_TIMESTAMP_RE.test(value)) {
|
|
60
|
-
return null;
|
|
61
|
-
}
|
|
62
|
-
const ts = Date.parse(value);
|
|
63
|
-
if (!Number.isFinite(ts)) return null;
|
|
64
|
-
if (!validateDateComponents(value)) return null;
|
|
65
|
-
if (!validateOffset(value)) return null;
|
|
66
|
-
if (value.endsWith("Z")) {
|
|
67
|
-
const roundTrip = new Date(ts).toISOString();
|
|
68
|
-
if (roundTrip !== normalizeUtcForComparison(value)) return null;
|
|
69
|
-
}
|
|
70
|
-
return ts;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
11
|
// src/replay/types.ts
|
|
74
12
|
var VALID_SOURCES = /* @__PURE__ */ new Set(["openclaw", "claude", "chatgpt"]);
|
|
75
13
|
var VALID_ROLES = /* @__PURE__ */ new Set(["user", "assistant"]);
|
|
@@ -133,6 +71,13 @@ function validateReplayTurn(turn, index) {
|
|
|
133
71
|
index
|
|
134
72
|
});
|
|
135
73
|
}
|
|
74
|
+
if (turn.sourceValidAt !== void 0 && (typeof turn.sourceValidAt !== "string" || parseIsoTimestamp(turn.sourceValidAt) === null)) {
|
|
75
|
+
issues.push({
|
|
76
|
+
code: "turn.sourceValidAt.invalid",
|
|
77
|
+
message: `Replay sourceValidAt must be a valid ISO timestamp when provided, received '${String(turn.sourceValidAt)}'.`,
|
|
78
|
+
index
|
|
79
|
+
});
|
|
80
|
+
}
|
|
136
81
|
return issues;
|
|
137
82
|
}
|
|
138
83
|
|
|
@@ -392,7 +337,6 @@ var RoutingRulesStore = class {
|
|
|
392
337
|
};
|
|
393
338
|
|
|
394
339
|
export {
|
|
395
|
-
parseIsoOffsetTimestamp,
|
|
396
340
|
isReplaySource,
|
|
397
341
|
isReplayRole,
|
|
398
342
|
normalizeReplaySessionKey,
|
|
@@ -400,4 +344,4 @@ export {
|
|
|
400
344
|
validateReplayTurn,
|
|
401
345
|
RoutingRulesStore
|
|
402
346
|
};
|
|
403
|
-
//# sourceMappingURL=chunk-
|
|
347
|
+
//# sourceMappingURL=chunk-FMEBPEAO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/replay/types.ts","../src/routing/store.ts"],"sourcesContent":["import { parseIsoUtcTimestamp } from \"../utils/iso-timestamp.js\";\n\nexport type ReplaySource = \"openclaw\" | \"claude\" | \"chatgpt\";\nexport type ReplayRole = \"user\" | \"assistant\";\n\nexport interface ReplayTurn {\n source: ReplaySource;\n sessionKey: string;\n role: ReplayRole;\n content: string;\n timestamp: string;\n sourceValidAt?: string;\n externalId?: string;\n metadata?: Record<string, unknown>;\n parts?: import(\"../message-parts/index.js\").LcmMessagePartInput[];\n rawContent?: unknown;\n sourceFormat?: import(\"../message-parts/index.js\").MessagePartSourceFormat;\n}\n\nexport interface ReplayWarning {\n code: string;\n message: string;\n index?: number;\n}\n\nexport interface ReplayValidationIssue {\n code: string;\n message: string;\n index?: number;\n}\n\nexport interface ReplayParseOptions {\n from?: string;\n to?: string;\n defaultSessionKey?: string;\n strict?: boolean;\n}\n\nexport interface ReplayParseResult {\n turns: ReplayTurn[];\n warnings: ReplayWarning[];\n}\n\nexport interface ReplayNormalizer {\n source: ReplaySource;\n parse(input: unknown, options?: ReplayParseOptions): Promise<ReplayParseResult> | ReplayParseResult;\n}\n\nconst VALID_SOURCES: ReadonlySet<string> = new Set([\"openclaw\", \"claude\", \"chatgpt\"]);\nconst VALID_ROLES: ReadonlySet<string> = new Set([\"user\", \"assistant\"]);\nexport const REPLAY_UNKNOWN_SESSION_KEY = \"replay:unknown\";\n\nexport function isReplaySource(value: unknown): value is ReplaySource {\n return typeof value === \"string\" && VALID_SOURCES.has(value);\n}\n\nexport function isReplayRole(value: unknown): value is ReplayRole {\n return typeof value === \"string\" && VALID_ROLES.has(value);\n}\n\nexport function normalizeReplaySessionKey(value: unknown): string {\n if (typeof value !== \"string\") return REPLAY_UNKNOWN_SESSION_KEY;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : REPLAY_UNKNOWN_SESSION_KEY;\n}\n\n/**\n * Strict UTC-only ISO-8601 parser used by the replay pipeline.\n *\n * Delegates to the shared parser in `utils/iso-timestamp.ts` — do not\n * reimplement locally; extend that helper instead. Replay intentionally\n * rejects timezone-offset timestamps to keep canonical form consistent\n * across recorded transcripts.\n */\nexport function parseIsoTimestamp(value: string): number | null {\n return parseIsoUtcTimestamp(value);\n}\n\nexport function validateReplayTurn(turn: ReplayTurn, index?: number): ReplayValidationIssue[] {\n const issues: ReplayValidationIssue[] = [];\n if (!turn || typeof turn !== \"object\") {\n issues.push({\n code: \"turn.invalid\",\n message: \"Replay turn must be an object.\",\n index,\n });\n return issues;\n }\n\n if (!isReplayRole(turn.role)) {\n issues.push({\n code: \"turn.role.invalid\",\n message: `Replay role must be 'user' or 'assistant', received '${String(turn.role)}'.`,\n index,\n });\n }\n\n if (!isReplaySource(turn.source)) {\n issues.push({\n code: \"turn.source.invalid\",\n message: `Replay source must be 'openclaw', 'claude', or 'chatgpt', received '${String(turn.source)}'.`,\n index,\n });\n }\n\n if (!turn.sessionKey || typeof turn.sessionKey !== \"string\" || turn.sessionKey.trim().length === 0) {\n issues.push({\n code: \"turn.sessionKey.invalid\",\n message: \"Replay sessionKey is required.\",\n index,\n });\n }\n\n if (!turn.content || typeof turn.content !== \"string\" || turn.content.trim().length === 0) {\n issues.push({\n code: \"turn.content.invalid\",\n message: \"Replay content must be a non-empty string.\",\n index,\n });\n }\n\n if (!turn.timestamp || typeof turn.timestamp !== \"string\" || parseIsoTimestamp(turn.timestamp) === null) {\n issues.push({\n code: \"turn.timestamp.invalid\",\n message: `Replay timestamp must be a valid ISO timestamp, received '${String(turn.timestamp)}'.`,\n index,\n });\n }\n\n if (\n turn.sourceValidAt !== undefined &&\n (typeof turn.sourceValidAt !== \"string\" ||\n parseIsoTimestamp(turn.sourceValidAt) === null)\n ) {\n issues.push({\n code: \"turn.sourceValidAt.invalid\",\n message: `Replay sourceValidAt must be a valid ISO timestamp when provided, received '${String(turn.sourceValidAt)}'.`,\n index,\n });\n }\n\n return issues;\n}\n","import { lstat, mkdir, readFile, realpath, rename, rm, stat, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { createHash } from \"node:crypto\";\nimport { log } from \"../logger.js\";\nimport { validateRouteTarget, type RouteRule, type RoutingEngineOptions } from \"./engine.js\";\n\ntype RoutingRulesState = {\n version: 1;\n updatedAt: string;\n rules: RouteRule[];\n};\n\nfunction defaultState(): RoutingRulesState {\n return {\n version: 1,\n updatedAt: new Date(0).toISOString(),\n rules: [],\n };\n}\n\nfunction stableRuleId(rule: Pick<RouteRule, \"patternType\" | \"pattern\" | \"priority\" | \"target\">): string {\n const seed = JSON.stringify({\n patternType: rule.patternType,\n pattern: rule.pattern.trim(),\n priority: rule.priority,\n target: rule.target,\n });\n return `route-${createHash(\"sha256\").update(seed).digest(\"hex\").slice(0, 12)}`;\n}\n\nfunction resolveStatePath(memoryDir: string, stateFile: string): string {\n const root = path.resolve(memoryDir);\n const defaultPath = path.join(root, \"state\", \"routing-rules.json\");\n if (path.isAbsolute(stateFile)) {\n const absolute = path.resolve(stateFile);\n return absolute.startsWith(root + path.sep) ? absolute : defaultPath;\n }\n const resolved = path.resolve(root, stateFile);\n return resolved.startsWith(root + path.sep) ? resolved : defaultPath;\n}\n\nfunction normalizeRule(rule: RouteRule, options?: RoutingEngineOptions): RouteRule | null {\n if (!rule || typeof rule !== \"object\") return null;\n if (rule.enabled === false) return null;\n if (rule.patternType !== \"keyword\" && rule.patternType !== \"regex\") return null;\n if (typeof rule.pattern !== \"string\" || rule.pattern.trim().length === 0) return null;\n if (typeof rule.priority !== \"number\" || !Number.isFinite(rule.priority)) return null;\n\n const targetValidation = validateRouteTarget(rule.target, options);\n if (!targetValidation.ok || !targetValidation.target) return null;\n\n const normalizedPriority = Math.trunc(rule.priority);\n const normalizedTarget = targetValidation.target;\n const id = typeof rule.id === \"string\" && rule.id.trim().length > 0\n ? rule.id.trim()\n : stableRuleId({\n patternType: rule.patternType,\n pattern: rule.pattern.trim(),\n priority: normalizedPriority,\n target: normalizedTarget,\n });\n return {\n id,\n patternType: rule.patternType,\n pattern: rule.pattern.trim(),\n priority: normalizedPriority,\n target: normalizedTarget,\n enabled: true,\n };\n}\n\nexport class RoutingRulesStore {\n private readonly memoryRoot: string;\n private readonly statePath: string;\n private readonly lockPath: string;\n private writeQueue: Promise<void> = Promise.resolve();\n\n constructor(memoryDir: string, stateFile = \"state/routing-rules.json\") {\n this.memoryRoot = path.resolve(memoryDir);\n this.statePath = resolveStatePath(memoryDir, stateFile);\n this.lockPath = `${this.statePath}.lock`;\n }\n\n async read(options?: RoutingEngineOptions): Promise<RouteRule[]> {\n try {\n const persisted = await this.readPersistedRules();\n return persisted\n .map((rule) => normalizeRule(rule, options))\n .filter((rule): rule is RouteRule => rule !== null);\n } catch {\n return [];\n }\n }\n\n async write(rules: RouteRule[], options?: RoutingEngineOptions): Promise<RouteRule[]> {\n return this.withWriteLock(async () => this.writeNormalized(rules, options));\n }\n\n async upsert(rule: RouteRule, options?: RoutingEngineOptions): Promise<RouteRule[]> {\n return this.withWriteLock(async () => {\n const existing = await this.readPersistedRules();\n const normalized = normalizeRule(rule, options);\n if (!normalized) return existing;\n\n const next = existing.filter((entry) => entry.id !== normalized.id);\n next.push(normalized);\n return this.writeNormalized(next);\n });\n }\n\n async removeByPattern(pattern: string): Promise<RouteRule[]> {\n return this.withWriteLock(async () => {\n const trimmed = pattern.trim();\n const existing = await this.readPersistedRules();\n const next = existing.filter((entry) => entry.pattern !== trimmed);\n if (next.length === existing.length) return existing;\n return this.writeNormalized(next);\n });\n }\n\n async reset(): Promise<void> {\n await this.withWriteLock(async () => {\n const payload = defaultState();\n await this.assertStatePathScoped();\n await writeFile(this.statePath, JSON.stringify(payload, null, 2), \"utf-8\");\n });\n }\n\n private dedupeById(rules: RouteRule[]): RouteRule[] {\n const byId = new Map<string, RouteRule>();\n for (const rule of rules) {\n byId.set(rule.id, rule);\n }\n return Array.from(byId.values());\n }\n\n private async readPersistedRules(): Promise<RouteRule[]> {\n try {\n await this.assertStatePathScoped();\n const raw = await readFile(this.statePath, \"utf-8\");\n const parsed = JSON.parse(raw) as Partial<RoutingRulesState>;\n if (!parsed || typeof parsed !== \"object\" || !Array.isArray(parsed.rules)) return [];\n const normalized = parsed.rules\n .map((rule) => normalizeRule(rule))\n .filter((rule): rule is RouteRule => rule !== null);\n return this.dedupeById(normalized);\n } catch {\n return [];\n }\n }\n\n private async writeNormalized(rules: RouteRule[], options?: RoutingEngineOptions): Promise<RouteRule[]> {\n const normalized = this.dedupeById(\n rules\n .map((rule) => normalizeRule(rule, options))\n .filter((rule): rule is RouteRule => rule !== null),\n );\n\n const payload: RoutingRulesState = {\n version: 1,\n updatedAt: new Date().toISOString(),\n rules: normalized,\n };\n\n const tmpPath = `${this.statePath}.tmp-${process.pid}-${Date.now()}`;\n try {\n await this.assertStatePathScoped();\n await writeFile(tmpPath, JSON.stringify(payload, null, 2), \"utf-8\");\n await rename(tmpPath, this.statePath);\n } catch (err) {\n log.debug(`routing rules write failed: ${err}`);\n throw err;\n } finally {\n await rm(tmpPath, { force: true }).catch(() => {});\n }\n\n return normalized;\n }\n\n private async withWriteLock<T>(op: () => Promise<T>): Promise<T> {\n const previous = this.writeQueue;\n let release: () => void = () => {};\n this.writeQueue = new Promise<void>((resolve) => {\n release = resolve;\n });\n await previous;\n let unlock: (() => Promise<void>) | null = null;\n try {\n unlock = await this.acquireFileLock();\n return await op();\n } finally {\n if (unlock) await unlock();\n release();\n }\n }\n\n private async acquireFileLock(): Promise<() => Promise<void>> {\n const start = Date.now();\n const staleMs = 30_000;\n const timeoutMs = 5_000;\n let unexpectedLockError: unknown = null;\n await this.assertStatePathScoped();\n await mkdir(path.dirname(this.lockPath), { recursive: true });\n\n while (Date.now() - start < timeoutMs) {\n try {\n await mkdir(this.lockPath);\n return async () => {\n try {\n await rm(this.lockPath, { recursive: true, force: true });\n } catch {\n // Fail-open: lock cleanup should not fail writes.\n }\n };\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code !== \"EEXIST\") {\n unexpectedLockError = err;\n break;\n }\n try {\n const lockStat = await stat(this.lockPath);\n if (Date.now() - lockStat.mtimeMs > staleMs) {\n await rm(this.lockPath, { recursive: true, force: true });\n continue;\n }\n } catch {\n // Lock may have been released between stat/rm attempts.\n }\n await new Promise((resolve) => setTimeout(resolve, 25));\n }\n }\n\n if (unexpectedLockError) {\n throw unexpectedLockError;\n }\n throw new Error(`routing rules lock acquisition timed out after ${timeoutMs}ms`);\n }\n\n private async assertStatePathScoped(): Promise<void> {\n await mkdir(this.memoryRoot, { recursive: true });\n const canonicalRoot = await realpath(this.memoryRoot);\n const canonicalParent = await this.canonicalizePathWithoutCreating(path.dirname(this.statePath));\n const canonicalStatePath = path.join(canonicalParent, path.basename(this.statePath));\n if (!this.isPathInside(canonicalRoot, canonicalStatePath)) {\n throw new Error(`routing rules state path escaped memoryDir: ${canonicalStatePath}`);\n }\n await mkdir(path.dirname(this.statePath), { recursive: true });\n try {\n const stateStats = await lstat(this.statePath);\n if (stateStats.isSymbolicLink()) {\n const canonicalFile = await realpath(this.statePath);\n if (!this.isPathInside(canonicalRoot, canonicalFile)) {\n throw new Error(`routing rules state symlink escaped memoryDir: ${canonicalFile}`);\n }\n }\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code !== \"ENOENT\") {\n throw err;\n }\n }\n }\n\n private isPathInside(root: string, candidate: string): boolean {\n const normalizedRoot = path.resolve(root);\n const normalizedCandidate = path.resolve(candidate);\n if (normalizedCandidate === normalizedRoot) return true;\n if (normalizedRoot === path.parse(normalizedRoot).root) {\n return normalizedCandidate.startsWith(normalizedRoot);\n }\n return normalizedCandidate.startsWith(`${normalizedRoot}${path.sep}`);\n }\n\n private async canonicalizePathWithoutCreating(targetPath: string): Promise<string> {\n const absoluteTarget = path.resolve(targetPath);\n let probe = absoluteTarget;\n while (true) {\n try {\n const canonicalProbe = await realpath(probe);\n const remainder = path.relative(probe, absoluteTarget);\n return path.resolve(canonicalProbe, remainder);\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code !== \"ENOENT\") {\n throw err;\n }\n const parent = path.dirname(probe);\n if (parent === probe) {\n return absoluteTarget;\n }\n probe = parent;\n }\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
expandTildePath
|
|
3
|
-
} from "./chunk-IXEJRKCZ.js";
|
|
4
1
|
import {
|
|
5
2
|
StorageManager
|
|
6
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-3B6KIRBH.js";
|
|
7
4
|
import {
|
|
8
5
|
parseContinuityImprovementLoops
|
|
9
6
|
} from "./chunk-QSVPYQPG.js";
|
|
10
7
|
import {
|
|
11
8
|
sanitizeMemoryContent
|
|
12
9
|
} from "./chunk-FVQJYWH7.js";
|
|
10
|
+
import {
|
|
11
|
+
expandTildePath
|
|
12
|
+
} from "./chunk-IXEJRKCZ.js";
|
|
13
13
|
import {
|
|
14
14
|
log
|
|
15
15
|
} from "./chunk-2ODBA7MQ.js";
|
|
@@ -1834,4 +1834,4 @@ export {
|
|
|
1834
1834
|
defaultTierMigrationCycleBudget,
|
|
1835
1835
|
CompoundingEngine
|
|
1836
1836
|
};
|
|
1837
|
-
//# sourceMappingURL=chunk-
|
|
1837
|
+
//# sourceMappingURL=chunk-FQDPCE3I.js.map
|