@monoes/monomindcli 2.14.0 → 2.15.0
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/.claude/helpers/control-start.cjs +10 -13
- package/.claude/skills/monodesign/scripts/context.mjs +5 -5
- package/.claude/skills/monodesign/scripts/critique-storage.mjs +1 -1
- package/.claude/skills/monodesign/scripts/detect-csp.mjs +1 -6
- package/.claude/skills/monodesign/scripts/detector/browser/injected/index.mjs +16 -18
- package/.claude/skills/monodesign/scripts/detector/cli/main.mjs +3 -3
- package/.claude/skills/monodesign/scripts/detector/detect-antipatterns-browser.js +69 -49
- package/.claude/skills/monodesign/scripts/detector/engines/regex/detect-text.mjs +6 -6
- package/.claude/skills/monodesign/scripts/detector/engines/static-html/css-cascade.mjs +6 -5
- package/.claude/skills/monodesign/scripts/detector/engines/static-html/detect-html.mjs +6 -6
- package/.claude/skills/monodesign/scripts/detector/fix/index.mjs +3 -3
- package/.claude/skills/monodesign/scripts/detector/node/file-system.mjs +1 -1
- package/.claude/skills/monodesign/scripts/detector/registry/antipatterns.mjs +1 -1
- package/.claude/skills/monodesign/scripts/detector/rules/checks.mjs +26 -27
- package/.claude/skills/monodesign/scripts/detector/shared/color.mjs +2 -2
- package/.claude/skills/monodesign/scripts/detector/shared/constants.mjs +1 -1
- package/.claude/skills/monodesign/scripts/detector/shared/inline-ignores.mjs +2 -2
- package/.claude/skills/monodesign/scripts/hook-admin.mjs +6 -6
- package/.claude/skills/monodesign/scripts/hook-before-edit.mjs +4 -4
- package/.claude/skills/monodesign/scripts/hook-lib.mjs +20 -11
- package/.claude/skills/monodesign/scripts/hook.mjs +1 -1
- package/.claude/skills/monodesign/scripts/lib/design-parser.mjs +9 -42
- package/.claude/skills/monodesign/scripts/lib/is-generated.mjs +1 -1
- package/.claude/skills/monodesign/scripts/lib/monodesign-config.mjs +5 -5
- package/.claude/skills/monodesign/scripts/lib/monodesign-paths.mjs +1 -1
- package/.claude/skills/monodesign/scripts/live/event-validation.mjs +13 -13
- package/.claude/skills/monodesign/scripts/live/manual-apply.mjs +4 -4
- package/.claude/skills/monodesign/scripts/live/manual-edits-buffer.mjs +1 -1
- package/.claude/skills/monodesign/scripts/live/session-store.mjs +5 -5
- package/.claude/skills/monodesign/scripts/live/svelte-component.mjs +13 -13
- package/.claude/skills/monodesign/scripts/live/sveltekit-adapter.mjs +4 -4
- package/.claude/skills/monodesign/scripts/live/ui-core.mjs +1 -1
- package/.claude/skills/monodesign/scripts/live-accept.mjs +24 -24
- package/.claude/skills/monodesign/scripts/live-browser-dom.js +8 -7
- package/.claude/skills/monodesign/scripts/live-browser-session.js +8 -7
- package/.claude/skills/monodesign/scripts/live-browser.js +406 -433
- package/.claude/skills/monodesign/scripts/live-commit-manual-edits.mjs +6 -6
- package/.claude/skills/monodesign/scripts/live-copy-edit-agent.mjs +2 -2
- package/.claude/skills/monodesign/scripts/live-discard-manual-edits.mjs +1 -1
- package/.claude/skills/monodesign/scripts/live-inject.mjs +7 -7
- package/.claude/skills/monodesign/scripts/live-insert.mjs +11 -11
- package/.claude/skills/monodesign/scripts/live-manual-edit-evidence.mjs +4 -4
- package/.claude/skills/monodesign/scripts/live-poll.mjs +5 -5
- package/.claude/skills/monodesign/scripts/live-server.mjs +10 -10
- package/.claude/skills/monodesign/scripts/live-wrap.mjs +31 -41
- package/.claude/skills/monodesign/scripts/live.mjs +5 -5
- package/.claude/skills/monodesign/scripts/palette.mjs +3 -1
- package/.claude/skills/monodesign/scripts/pin.mjs +1 -1
- package/bin/cli.js +21 -1
- package/bin/mcp-server.js +21 -1
- package/dist/src/capabilities/cap-documents.d.ts.map +1 -1
- package/dist/src/capabilities/cap-documents.js +23 -0
- package/dist/src/capabilities/cap-documents.js.map +1 -1
- package/dist/src/commands/doc-filters.d.ts +19 -0
- package/dist/src/commands/doc-filters.d.ts.map +1 -0
- package/dist/src/commands/doc-filters.js +64 -0
- package/dist/src/commands/doc-filters.js.map +1 -0
- package/dist/src/commands/doc-library.d.ts +22 -0
- package/dist/src/commands/doc-library.d.ts.map +1 -0
- package/dist/src/commands/doc-library.js +454 -0
- package/dist/src/commands/doc-library.js.map +1 -0
- package/dist/src/commands/doc-list.d.ts +9 -0
- package/dist/src/commands/doc-list.d.ts.map +1 -0
- package/dist/src/commands/doc-list.js +99 -0
- package/dist/src/commands/doc-list.js.map +1 -0
- package/dist/src/commands/doc.d.ts.map +1 -1
- package/dist/src/commands/doc.js +51 -37
- package/dist/src/commands/doc.js.map +1 -1
- package/dist/src/commands/ui.d.ts.map +1 -1
- package/dist/src/commands/ui.js +60 -0
- package/dist/src/commands/ui.js.map +1 -1
- package/dist/src/knowledge/capture-envelope.d.ts +85 -0
- package/dist/src/knowledge/capture-envelope.d.ts.map +1 -0
- package/dist/src/knowledge/capture-envelope.js +167 -0
- package/dist/src/knowledge/capture-envelope.js.map +1 -0
- package/dist/src/knowledge/capture-text.d.ts +23 -0
- package/dist/src/knowledge/capture-text.d.ts.map +1 -0
- package/dist/src/knowledge/capture-text.js +49 -0
- package/dist/src/knowledge/capture-text.js.map +1 -0
- package/dist/src/knowledge/citation.d.ts +121 -0
- package/dist/src/knowledge/citation.d.ts.map +1 -0
- package/dist/src/knowledge/citation.js +252 -0
- package/dist/src/knowledge/citation.js.map +1 -0
- package/dist/src/knowledge/document-chunking.d.ts +42 -0
- package/dist/src/knowledge/document-chunking.d.ts.map +1 -0
- package/dist/src/knowledge/document-chunking.js +288 -0
- package/dist/src/knowledge/document-chunking.js.map +1 -0
- package/dist/src/knowledge/document-index.d.ts +124 -0
- package/dist/src/knowledge/document-index.d.ts.map +1 -0
- package/dist/src/knowledge/document-index.js +314 -0
- package/dist/src/knowledge/document-index.js.map +1 -0
- package/dist/src/knowledge/document-ingest.d.ts +23 -0
- package/dist/src/knowledge/document-ingest.d.ts.map +1 -0
- package/dist/src/knowledge/document-ingest.js +368 -0
- package/dist/src/knowledge/document-ingest.js.map +1 -0
- package/dist/src/knowledge/document-pipeline.d.ts +26 -148
- package/dist/src/knowledge/document-pipeline.d.ts.map +1 -1
- package/dist/src/knowledge/document-pipeline.js +25 -920
- package/dist/src/knowledge/document-pipeline.js.map +1 -1
- package/dist/src/knowledge/document-search.d.ts +27 -0
- package/dist/src/knowledge/document-search.d.ts.map +1 -0
- package/dist/src/knowledge/document-search.js +138 -0
- package/dist/src/knowledge/document-search.js.map +1 -0
- package/dist/src/knowledge/document-store.d.ts +28 -0
- package/dist/src/knowledge/document-store.d.ts.map +1 -0
- package/dist/src/knowledge/document-store.js +61 -0
- package/dist/src/knowledge/document-store.js.map +1 -0
- package/dist/src/knowledge/document-types.d.ts +103 -0
- package/dist/src/knowledge/document-types.d.ts.map +1 -0
- package/dist/src/knowledge/document-types.js +12 -0
- package/dist/src/knowledge/document-types.js.map +1 -0
- package/dist/src/knowledge/highlights.d.ts +168 -0
- package/dist/src/knowledge/highlights.d.ts.map +1 -0
- package/dist/src/knowledge/highlights.js +311 -0
- package/dist/src/knowledge/highlights.js.map +1 -0
- package/dist/src/knowledge/html-extract.d.ts +43 -0
- package/dist/src/knowledge/html-extract.d.ts.map +1 -0
- package/dist/src/knowledge/html-extract.js +286 -0
- package/dist/src/knowledge/html-extract.js.map +1 -0
- package/dist/src/knowledge/html-tags.d.ts +30 -0
- package/dist/src/knowledge/html-tags.d.ts.map +1 -0
- package/dist/src/knowledge/html-tags.js +229 -0
- package/dist/src/knowledge/html-tags.js.map +1 -0
- package/dist/src/knowledge/library.d.ts +106 -0
- package/dist/src/knowledge/library.d.ts.map +1 -0
- package/dist/src/knowledge/library.js +195 -0
- package/dist/src/knowledge/library.js.map +1 -0
- package/dist/src/knowledge/lookup.d.ts +80 -0
- package/dist/src/knowledge/lookup.d.ts.map +1 -0
- package/dist/src/knowledge/lookup.js +156 -0
- package/dist/src/knowledge/lookup.js.map +1 -0
- package/dist/src/knowledge/mhtml.d.ts +60 -0
- package/dist/src/knowledge/mhtml.d.ts.map +1 -0
- package/dist/src/knowledge/mhtml.js +154 -0
- package/dist/src/knowledge/mhtml.js.map +1 -0
- package/dist/src/knowledge/okf-bundle.d.ts +19 -0
- package/dist/src/knowledge/okf-bundle.d.ts.map +1 -0
- package/dist/src/knowledge/okf-bundle.js +106 -0
- package/dist/src/knowledge/okf-bundle.js.map +1 -0
- package/dist/src/knowledge/profile-store.d.ts +134 -0
- package/dist/src/knowledge/profile-store.d.ts.map +1 -0
- package/dist/src/knowledge/profile-store.js +237 -0
- package/dist/src/knowledge/profile-store.js.map +1 -0
- package/dist/src/knowledge/related.d.ts +58 -0
- package/dist/src/knowledge/related.d.ts.map +1 -0
- package/dist/src/knowledge/related.js +222 -0
- package/dist/src/knowledge/related.js.map +1 -0
- package/dist/src/knowledge/section-diff.d.ts +48 -0
- package/dist/src/knowledge/section-diff.d.ts.map +1 -0
- package/dist/src/knowledge/section-diff.js +151 -0
- package/dist/src/knowledge/section-diff.js.map +1 -0
- package/dist/src/knowledge/watch.d.ts +92 -0
- package/dist/src/knowledge/watch.d.ts.map +1 -0
- package/dist/src/knowledge/watch.js +221 -0
- package/dist/src/knowledge/watch.js.map +1 -0
- package/dist/src/mcp-server.d.ts.map +1 -1
- package/dist/src/mcp-server.js +44 -87
- package/dist/src/mcp-server.js.map +1 -1
- package/dist/src/mcp-tools/browser-instrument-tools.d.ts +35 -0
- package/dist/src/mcp-tools/browser-instrument-tools.d.ts.map +1 -0
- package/dist/src/mcp-tools/browser-instrument-tools.js +359 -0
- package/dist/src/mcp-tools/browser-instrument-tools.js.map +1 -0
- package/dist/src/mcp-tools/browser-metrics.d.ts +42 -0
- package/dist/src/mcp-tools/browser-metrics.d.ts.map +1 -0
- package/dist/src/mcp-tools/browser-metrics.js +91 -0
- package/dist/src/mcp-tools/browser-metrics.js.map +1 -0
- package/dist/src/mcp-tools/browser-profile-tools.d.ts +16 -0
- package/dist/src/mcp-tools/browser-profile-tools.d.ts.map +1 -0
- package/dist/src/mcp-tools/browser-profile-tools.js +324 -0
- package/dist/src/mcp-tools/browser-profile-tools.js.map +1 -0
- package/dist/src/mcp-tools/browser-session.d.ts +68 -0
- package/dist/src/mcp-tools/browser-session.d.ts.map +1 -0
- package/dist/src/mcp-tools/browser-session.js +224 -0
- package/dist/src/mcp-tools/browser-session.js.map +1 -0
- package/dist/src/mcp-tools/browser-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/browser-tools.js +10 -176
- package/dist/src/mcp-tools/browser-tools.js.map +1 -1
- package/dist/src/mcp-tools/capture-resource-read.d.ts +115 -0
- package/dist/src/mcp-tools/capture-resource-read.d.ts.map +1 -0
- package/dist/src/mcp-tools/capture-resource-read.js +296 -0
- package/dist/src/mcp-tools/capture-resource-read.js.map +1 -0
- package/dist/src/mcp-tools/capture-resource-tools.d.ts +22 -0
- package/dist/src/mcp-tools/capture-resource-tools.d.ts.map +1 -0
- package/dist/src/mcp-tools/capture-resource-tools.js +182 -0
- package/dist/src/mcp-tools/capture-resource-tools.js.map +1 -0
- package/dist/src/mcp-tools/capture-resources.d.ts +142 -0
- package/dist/src/mcp-tools/capture-resources.d.ts.map +1 -0
- package/dist/src/mcp-tools/capture-resources.js +289 -0
- package/dist/src/mcp-tools/capture-resources.js.map +1 -0
- package/dist/src/mcp-tools/index.d.ts +3 -0
- package/dist/src/mcp-tools/index.d.ts.map +1 -1
- package/dist/src/mcp-tools/index.js +6 -0
- package/dist/src/mcp-tools/index.js.map +1 -1
- package/dist/src/mcp-tools/knowledge-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/knowledge-tools.js +9 -1
- package/dist/src/mcp-tools/knowledge-tools.js.map +1 -1
- package/dist/src/mcp-tools/resource-router.d.ts +86 -0
- package/dist/src/mcp-tools/resource-router.d.ts.map +1 -0
- package/dist/src/mcp-tools/resource-router.js +181 -0
- package/dist/src/mcp-tools/resource-router.js.map +1 -0
- package/dist/src/memory/memory-bridge.js +1 -1
- package/dist/src/memory/memory-bridge.js.map +1 -1
- package/dist/src/orgrt/agent-runner.d.ts +4 -0
- package/dist/src/orgrt/agent-runner.d.ts.map +1 -1
- package/dist/src/orgrt/agent-runner.js +22 -0
- package/dist/src/orgrt/agent-runner.js.map +1 -1
- package/dist/src/orgrt/antigravity-runner.d.ts.map +1 -1
- package/dist/src/orgrt/antigravity-runner.js +2 -1
- package/dist/src/orgrt/antigravity-runner.js.map +1 -1
- package/dist/src/orgrt/authority-mask.d.ts +32 -0
- package/dist/src/orgrt/authority-mask.d.ts.map +1 -0
- package/dist/src/orgrt/authority-mask.js +135 -0
- package/dist/src/orgrt/authority-mask.js.map +1 -0
- package/dist/src/orgrt/codex-runner.d.ts.map +1 -1
- package/dist/src/orgrt/codex-runner.js +2 -1
- package/dist/src/orgrt/codex-runner.js.map +1 -1
- package/dist/src/orgrt/copilot-runner.d.ts.map +1 -1
- package/dist/src/orgrt/copilot-runner.js +2 -1
- package/dist/src/orgrt/copilot-runner.js.map +1 -1
- package/dist/src/orgrt/crush-runner.d.ts.map +1 -1
- package/dist/src/orgrt/crush-runner.js +6 -1
- package/dist/src/orgrt/crush-runner.js.map +1 -1
- package/dist/src/orgrt/daemon.d.ts +4 -0
- package/dist/src/orgrt/daemon.d.ts.map +1 -1
- package/dist/src/orgrt/daemon.js +13 -2
- package/dist/src/orgrt/daemon.js.map +1 -1
- package/dist/src/orgrt/decisions.d.ts +9 -0
- package/dist/src/orgrt/decisions.d.ts.map +1 -1
- package/dist/src/orgrt/decisions.js +32 -5
- package/dist/src/orgrt/decisions.js.map +1 -1
- package/dist/src/orgrt/file-roots.d.ts +2 -1
- package/dist/src/orgrt/file-roots.d.ts.map +1 -1
- package/dist/src/orgrt/file-roots.js +7 -3
- package/dist/src/orgrt/file-roots.js.map +1 -1
- package/dist/src/orgrt/grok-runner.d.ts.map +1 -1
- package/dist/src/orgrt/grok-runner.js +2 -1
- package/dist/src/orgrt/grok-runner.js.map +1 -1
- package/dist/src/orgrt/hermes-runner.d.ts.map +1 -1
- package/dist/src/orgrt/hermes-runner.js +2 -1
- package/dist/src/orgrt/hermes-runner.js.map +1 -1
- package/dist/src/orgrt/inbox.d.ts.map +1 -1
- package/dist/src/orgrt/inbox.js +70 -4
- package/dist/src/orgrt/inbox.js.map +1 -1
- package/dist/src/orgrt/kimicode-runner.d.ts.map +1 -1
- package/dist/src/orgrt/kimicode-runner.js +2 -1
- package/dist/src/orgrt/kimicode-runner.js.map +1 -1
- package/dist/src/orgrt/opencode-runner.d.ts.map +1 -1
- package/dist/src/orgrt/opencode-runner.js +3 -2
- package/dist/src/orgrt/opencode-runner.js.map +1 -1
- package/dist/src/orgrt/pi-rpc-runner.d.ts.map +1 -1
- package/dist/src/orgrt/pi-rpc-runner.js +3 -2
- package/dist/src/orgrt/pi-rpc-runner.js.map +1 -1
- package/dist/src/orgrt/pi-runner.d.ts.map +1 -1
- package/dist/src/orgrt/pi-runner.js +2 -1
- package/dist/src/orgrt/pi-runner.js.map +1 -1
- package/dist/src/orgrt/policy.d.ts.map +1 -1
- package/dist/src/orgrt/policy.js +3 -0
- package/dist/src/orgrt/policy.js.map +1 -1
- package/dist/src/orgrt/qwen-rpc-runner.d.ts.map +1 -1
- package/dist/src/orgrt/qwen-rpc-runner.js +3 -2
- package/dist/src/orgrt/qwen-rpc-runner.js.map +1 -1
- package/dist/src/orgrt/qwen-runner.d.ts.map +1 -1
- package/dist/src/orgrt/qwen-runner.js +2 -1
- package/dist/src/orgrt/qwen-runner.js.map +1 -1
- package/dist/src/orgrt/role-sandbox.d.ts +21 -0
- package/dist/src/orgrt/role-sandbox.d.ts.map +1 -1
- package/dist/src/orgrt/role-sandbox.js +31 -6
- package/dist/src/orgrt/role-sandbox.js.map +1 -1
- package/dist/src/orgrt/session-ledger.d.ts +7 -0
- package/dist/src/orgrt/session-ledger.d.ts.map +1 -1
- package/dist/src/orgrt/session-ledger.js +15 -0
- package/dist/src/orgrt/session-ledger.js.map +1 -1
- package/dist/src/orgrt/session.d.ts.map +1 -1
- package/dist/src/orgrt/session.js +42 -10
- package/dist/src/orgrt/session.js.map +1 -1
- package/dist/src/orgrt/task-dag.d.ts +3 -0
- package/dist/src/orgrt/task-dag.d.ts.map +1 -1
- package/dist/src/orgrt/task-dag.js +1 -0
- package/dist/src/orgrt/task-dag.js.map +1 -1
- package/dist/src/orgrt/types.d.ts +5 -0
- package/dist/src/orgrt/types.d.ts.map +1 -1
- package/dist/src/orgrt/types.js +23 -1
- package/dist/src/orgrt/types.js.map +1 -1
- package/dist/src/ui/dashboard.html +28 -848
- package/dist/src/ui/human-auth.mjs +103 -0
- package/dist/src/ui/org-hil.mjs +86 -37
- package/dist/src/ui/org-runtime.mjs +21 -13
- package/dist/src/ui/routes-org.mjs +49 -445
- package/dist/src/ui/server.mjs +90 -2
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -9
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capture-envelope.js","sourceRoot":"","sources":["../../../src/knowledge/capture-envelope.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text extraction for web captures (RCL-01) — the HTML/MHTML arm of
|
|
3
|
+
* `extractText`, kept here so `cap-documents.ts` stays a dispatch table.
|
|
4
|
+
*
|
|
5
|
+
* @module v1/cli/knowledge/capture-text
|
|
6
|
+
*/
|
|
7
|
+
export declare const HTML_EXTENSIONS: Set<string>;
|
|
8
|
+
export declare const MHTML_EXTENSIONS: Set<string>;
|
|
9
|
+
export declare function isCaptureExtension(ext: string): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Clean text for an archived page.
|
|
12
|
+
*
|
|
13
|
+
* PRECEDENCE — when the file sits in a capture envelope, the sibling
|
|
14
|
+
* `readable.md` wins. It was produced by Readability against the LIVE DOM,
|
|
15
|
+
* with lazy images resolved, the consent modal dismissed and the site's own JS
|
|
16
|
+
* finished; nothing derived from the archived markup can beat that. Our own
|
|
17
|
+
* extractor is the fallback for archives nobody cleaned.
|
|
18
|
+
*
|
|
19
|
+
* Returns '' rather than throwing — an unreadable capture is a document with
|
|
20
|
+
* no text, not a failed ingest.
|
|
21
|
+
*/
|
|
22
|
+
export declare function extractCaptureText(absolutePath: string, ext: string): string;
|
|
23
|
+
//# sourceMappingURL=capture-text.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capture-text.d.ts","sourceRoot":"","sources":["../../../src/knowledge/capture-text.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,eAAO,MAAM,eAAe,aAAuC,CAAC;AACpE,eAAO,MAAM,gBAAgB,aAA8B,CAAC;AAE5D,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAiB5E"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text extraction for web captures (RCL-01) — the HTML/MHTML arm of
|
|
3
|
+
* `extractText`, kept here so `cap-documents.ts` stays a dispatch table.
|
|
4
|
+
*
|
|
5
|
+
* @module v1/cli/knowledge/capture-text
|
|
6
|
+
*/
|
|
7
|
+
import * as fs from 'node:fs';
|
|
8
|
+
import { readableSiblingFor } from './capture-envelope.js';
|
|
9
|
+
import { htmlToMarkdown } from './html-extract.js';
|
|
10
|
+
import { mhtmlToHtml } from './mhtml.js';
|
|
11
|
+
export const HTML_EXTENSIONS = new Set(['.html', '.htm', '.xhtml']);
|
|
12
|
+
export const MHTML_EXTENSIONS = new Set(['.mhtml', '.mht']);
|
|
13
|
+
export function isCaptureExtension(ext) {
|
|
14
|
+
return HTML_EXTENSIONS.has(ext) || MHTML_EXTENSIONS.has(ext);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Clean text for an archived page.
|
|
18
|
+
*
|
|
19
|
+
* PRECEDENCE — when the file sits in a capture envelope, the sibling
|
|
20
|
+
* `readable.md` wins. It was produced by Readability against the LIVE DOM,
|
|
21
|
+
* with lazy images resolved, the consent modal dismissed and the site's own JS
|
|
22
|
+
* finished; nothing derived from the archived markup can beat that. Our own
|
|
23
|
+
* extractor is the fallback for archives nobody cleaned.
|
|
24
|
+
*
|
|
25
|
+
* Returns '' rather than throwing — an unreadable capture is a document with
|
|
26
|
+
* no text, not a failed ingest.
|
|
27
|
+
*/
|
|
28
|
+
export function extractCaptureText(absolutePath, ext) {
|
|
29
|
+
try {
|
|
30
|
+
const readable = readableSiblingFor(absolutePath);
|
|
31
|
+
if (readable)
|
|
32
|
+
return fs.readFileSync(readable, 'utf-8');
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
/* no envelope, or an unreadable one — extract from the file itself */
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
if (MHTML_EXTENSIONS.has(ext)) {
|
|
39
|
+
// latin1 preserves the raw bytes: transfer encoding comes off first, and
|
|
40
|
+
// the real charset is only known per MIME part.
|
|
41
|
+
return htmlToMarkdown(mhtmlToHtml(fs.readFileSync(absolutePath, 'latin1')).html);
|
|
42
|
+
}
|
|
43
|
+
return htmlToMarkdown(fs.readFileSync(absolutePath, 'utf-8'));
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return '';
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=capture-text.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capture-text.js","sourceRoot":"","sources":["../../../src/knowledge/capture-text.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;AACpE,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;AAE5D,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC5C,OAAO,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAC/D,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,kBAAkB,CAAC,YAAoB,EAAE,GAAW;IAClE,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,kBAAkB,CAAC,YAAY,CAAC,CAAC;QAClD,IAAI,QAAQ;YAAE,OAAO,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC1D,CAAC;IAAC,MAAM,CAAC;QACP,sEAAsE;IACxE,CAAC;IACD,IAAI,CAAC;QACH,IAAI,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC9B,yEAAyE;YACzE,gDAAgD;YAChD,OAAO,cAAc,CAAC,WAAW,CAAC,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACnF,CAAC;QACD,OAAO,cAAc,CAAC,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC;IAChE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Paragraph-level citation (RCL-10).
|
|
3
|
+
*
|
|
4
|
+
* A search hit already knows WHICH document it came from. A citation has to
|
|
5
|
+
* know WHERE IN IT: the character span of the chunk against the extracted
|
|
6
|
+
* text, an anchor that survives being written down, and a way back to the
|
|
7
|
+
* live page at that passage.
|
|
8
|
+
*
|
|
9
|
+
* Three pieces, deliberately separate:
|
|
10
|
+
*
|
|
11
|
+
* - `span:<start>-<end>` — a tag written next to every chunk at ingest, so a
|
|
12
|
+
* search result carries offsets without re-reading the document.
|
|
13
|
+
* - the ANCHOR `<hash12>#<start>-<end>` — offsets bound to the content hash
|
|
14
|
+
* of the exact version they were measured against. Quoting an offset range
|
|
15
|
+
* without the version it belongs to is how citations rot: the document is
|
|
16
|
+
* re-captured, the text shifts, and the quote silently points at other
|
|
17
|
+
* words. A stale anchor here is DETECTED (`stale: true`), never served as
|
|
18
|
+
* if it were still true.
|
|
19
|
+
* - a W3C text fragment (`#:~:text=`) — the link a human clicks, which lands
|
|
20
|
+
* on the sentence even though the site never had an id there.
|
|
21
|
+
*
|
|
22
|
+
* Everything above `resolveCitation` is pure and synchronous so the pipeline
|
|
23
|
+
* can use it while ingesting. `resolveCitation` reaches back into the
|
|
24
|
+
* document-pipeline through a DYNAMIC import: the pipeline imports this
|
|
25
|
+
* module statically, and a static import back would close the cycle.
|
|
26
|
+
*
|
|
27
|
+
* @module v1/cli/knowledge/citation
|
|
28
|
+
*/
|
|
29
|
+
import type { CaptureProvenance } from './capture-envelope.js';
|
|
30
|
+
export declare const SPAN_TAG_PREFIX = "span:";
|
|
31
|
+
export interface ChunkSpan {
|
|
32
|
+
chunkIndex: number;
|
|
33
|
+
startChar: number;
|
|
34
|
+
endChar: number;
|
|
35
|
+
}
|
|
36
|
+
/** The tag written beside a chunk at ingest: `span:<start>-<end>`. */
|
|
37
|
+
export declare function spanTag(startChar: number, endChar: number): string;
|
|
38
|
+
/** Offsets from a chunk's tag list, or null when it predates span tags. */
|
|
39
|
+
export declare function parseSpanTag(tags: readonly string[] | undefined): {
|
|
40
|
+
startChar: number;
|
|
41
|
+
endChar: number;
|
|
42
|
+
} | null;
|
|
43
|
+
/** `<hash12>#<start>-<end>` — offsets bound to the version they were measured against. */
|
|
44
|
+
export declare function citationAnchor(contentHash: string, startChar: number, endChar: number): string;
|
|
45
|
+
export declare function parseCitationAnchor(anchor: string): {
|
|
46
|
+
hashPrefix: string;
|
|
47
|
+
startChar: number;
|
|
48
|
+
endChar: number;
|
|
49
|
+
} | null;
|
|
50
|
+
/** True when the anchor was cut against this document version. */
|
|
51
|
+
export declare function anchorMatchesHash(anchor: string, contentHash: string): boolean;
|
|
52
|
+
/**
|
|
53
|
+
* The prose of a passage: § context prefixes gone, markdown syntax gone,
|
|
54
|
+
* whitespace collapsed.
|
|
55
|
+
*
|
|
56
|
+
* `skipHeadings` drops heading lines as well, which is what a text fragment
|
|
57
|
+
* wants — a heading is usually its own element on the page, so starting a
|
|
58
|
+
* range there matches less reliably than starting at the paragraph. It falls
|
|
59
|
+
* back to including them when the passage is nothing but headings.
|
|
60
|
+
*/
|
|
61
|
+
export declare function passageProse(passage: string, skipHeadings?: boolean): string;
|
|
62
|
+
/** The head of a passage as a quotable sentence or two — the words a reader
|
|
63
|
+
* would see on the page, not the markdown we stored. */
|
|
64
|
+
export declare function passageQuote(passage: string, maxChars?: number): string;
|
|
65
|
+
/**
|
|
66
|
+
* A W3C scroll-to-text fragment for this passage.
|
|
67
|
+
*
|
|
68
|
+
* Long passages use the `textStart,textEnd` form rather than the whole
|
|
69
|
+
* paragraph: the spec matches across the range, and a shorter pair survives
|
|
70
|
+
* the site re-flowing its markup between capture and click.
|
|
71
|
+
*/
|
|
72
|
+
export declare function textFragment(passage: string): string;
|
|
73
|
+
/** The captured page's URL, pointed at the passage. Returns undefined when
|
|
74
|
+
* there is no URL — a citation into a local file has no link to give. */
|
|
75
|
+
export declare function citationUrl(url: string | undefined, passage: string): string | undefined;
|
|
76
|
+
export interface Citation {
|
|
77
|
+
/** `<scope>:<filePath>` — the pipeline's own document id. */
|
|
78
|
+
docId: string;
|
|
79
|
+
filePath: string;
|
|
80
|
+
scope: string;
|
|
81
|
+
chunkIndex: number;
|
|
82
|
+
startChar: number;
|
|
83
|
+
endChar: number;
|
|
84
|
+
/** Hash of the text the offsets were cut against, i.e. the file as it is NOW. */
|
|
85
|
+
contentHash: string;
|
|
86
|
+
anchor: string;
|
|
87
|
+
/** The cited text itself, straight out of the extracted document. */
|
|
88
|
+
passage: string;
|
|
89
|
+
/** The head of the passage, collapsed — what an agent puts in quotes. */
|
|
90
|
+
quote: string;
|
|
91
|
+
/** Present only when the anchor asked for a version this file no longer is. */
|
|
92
|
+
stale?: boolean;
|
|
93
|
+
version?: number;
|
|
94
|
+
title?: string;
|
|
95
|
+
url?: string;
|
|
96
|
+
/** `url` with a text fragment appended: the link that lands on the passage. */
|
|
97
|
+
citeUrl?: string;
|
|
98
|
+
capturedAt?: string;
|
|
99
|
+
source?: string;
|
|
100
|
+
provenance?: CaptureProvenance;
|
|
101
|
+
}
|
|
102
|
+
export interface ResolveCitationOptions {
|
|
103
|
+
rootDir?: string;
|
|
104
|
+
scope?: string;
|
|
105
|
+
/** Chunk index, as reported on a search hit. */
|
|
106
|
+
chunkIndex?: number;
|
|
107
|
+
/** An anchor string from a previous citation — resolved by offsets, and
|
|
108
|
+
* flagged `stale` when it names a version this document no longer is. */
|
|
109
|
+
anchor?: string;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Resolve a citation back to the passage it came from.
|
|
113
|
+
*
|
|
114
|
+
* `target` is whatever the caller has written down: an indexed file path, a
|
|
115
|
+
* capture's `canonicalUrl`, or the `<scope>:<path>` docId. Throws with a
|
|
116
|
+
* message meant for a human when the document is not indexed, its file is
|
|
117
|
+
* gone, or the chunk does not exist — a citation that cannot be checked must
|
|
118
|
+
* fail loudly, not resolve to an empty string.
|
|
119
|
+
*/
|
|
120
|
+
export declare function resolveCitation(target: string, opts?: ResolveCitationOptions): Promise<Citation>;
|
|
121
|
+
//# sourceMappingURL=citation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"citation.d.ts","sourceRoot":"","sources":["../../../src/knowledge/citation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Paragraph-level citation (RCL-10).
|
|
3
|
+
*
|
|
4
|
+
* A search hit already knows WHICH document it came from. A citation has to
|
|
5
|
+
* know WHERE IN IT: the character span of the chunk against the extracted
|
|
6
|
+
* text, an anchor that survives being written down, and a way back to the
|
|
7
|
+
* live page at that passage.
|
|
8
|
+
*
|
|
9
|
+
* Three pieces, deliberately separate:
|
|
10
|
+
*
|
|
11
|
+
* - `span:<start>-<end>` — a tag written next to every chunk at ingest, so a
|
|
12
|
+
* search result carries offsets without re-reading the document.
|
|
13
|
+
* - the ANCHOR `<hash12>#<start>-<end>` — offsets bound to the content hash
|
|
14
|
+
* of the exact version they were measured against. Quoting an offset range
|
|
15
|
+
* without the version it belongs to is how citations rot: the document is
|
|
16
|
+
* re-captured, the text shifts, and the quote silently points at other
|
|
17
|
+
* words. A stale anchor here is DETECTED (`stale: true`), never served as
|
|
18
|
+
* if it were still true.
|
|
19
|
+
* - a W3C text fragment (`#:~:text=`) — the link a human clicks, which lands
|
|
20
|
+
* on the sentence even though the site never had an id there.
|
|
21
|
+
*
|
|
22
|
+
* Everything above `resolveCitation` is pure and synchronous so the pipeline
|
|
23
|
+
* can use it while ingesting. `resolveCitation` reaches back into the
|
|
24
|
+
* document-pipeline through a DYNAMIC import: the pipeline imports this
|
|
25
|
+
* module statically, and a static import back would close the cycle.
|
|
26
|
+
*
|
|
27
|
+
* @module v1/cli/knowledge/citation
|
|
28
|
+
*/
|
|
29
|
+
import * as crypto from 'node:crypto';
|
|
30
|
+
import * as fs from 'node:fs';
|
|
31
|
+
import * as path from 'node:path';
|
|
32
|
+
export const SPAN_TAG_PREFIX = 'span:';
|
|
33
|
+
/** The tag written beside a chunk at ingest: `span:<start>-<end>`. */
|
|
34
|
+
export function spanTag(startChar, endChar) {
|
|
35
|
+
return `${SPAN_TAG_PREFIX}${startChar}-${endChar}`;
|
|
36
|
+
}
|
|
37
|
+
/** Offsets from a chunk's tag list, or null when it predates span tags. */
|
|
38
|
+
export function parseSpanTag(tags) {
|
|
39
|
+
for (const tag of tags ?? []) {
|
|
40
|
+
if (typeof tag !== 'string' || !tag.startsWith(SPAN_TAG_PREFIX))
|
|
41
|
+
continue;
|
|
42
|
+
const m = /^span:(\d+)-(\d+)$/.exec(tag);
|
|
43
|
+
if (!m)
|
|
44
|
+
continue;
|
|
45
|
+
const startChar = Number(m[1]);
|
|
46
|
+
const endChar = Number(m[2]);
|
|
47
|
+
if (endChar < startChar)
|
|
48
|
+
continue;
|
|
49
|
+
return { startChar, endChar };
|
|
50
|
+
}
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
const ANCHOR_HASH_CHARS = 12;
|
|
54
|
+
/** `<hash12>#<start>-<end>` — offsets bound to the version they were measured against. */
|
|
55
|
+
export function citationAnchor(contentHash, startChar, endChar) {
|
|
56
|
+
return `${(contentHash || '').slice(0, ANCHOR_HASH_CHARS)}#${startChar}-${endChar}`;
|
|
57
|
+
}
|
|
58
|
+
export function parseCitationAnchor(anchor) {
|
|
59
|
+
const m = /^([0-9a-f]{4,64})#(\d+)-(\d+)$/.exec((anchor || '').trim());
|
|
60
|
+
if (!m)
|
|
61
|
+
return null;
|
|
62
|
+
const startChar = Number(m[2]);
|
|
63
|
+
const endChar = Number(m[3]);
|
|
64
|
+
if (endChar < startChar)
|
|
65
|
+
return null;
|
|
66
|
+
return { hashPrefix: m[1], startChar, endChar };
|
|
67
|
+
}
|
|
68
|
+
/** True when the anchor was cut against this document version. */
|
|
69
|
+
export function anchorMatchesHash(anchor, contentHash) {
|
|
70
|
+
const parsed = parseCitationAnchor(anchor);
|
|
71
|
+
if (!parsed)
|
|
72
|
+
return false;
|
|
73
|
+
return (contentHash || '').startsWith(parsed.hashPrefix);
|
|
74
|
+
}
|
|
75
|
+
// ── Quotes and links ───────────────────────────────────────────────
|
|
76
|
+
const QUOTE_MAX_CHARS = 320;
|
|
77
|
+
const CONTEXT_PREFIX_RE = /^(§ [^\n]*\n)+/;
|
|
78
|
+
const HEADING_LINE_RE = /^\s{0,3}#{1,6}\s+/;
|
|
79
|
+
/**
|
|
80
|
+
* One line of markdown as the words a reader sees.
|
|
81
|
+
*
|
|
82
|
+
* This matters more than it looks: a text fragment built from `# Pricing ##
|
|
83
|
+
* Starter Nine dollars` matches NOTHING on the live page, because the page
|
|
84
|
+
* never contained a `#`. The link is only worth having if it is made of the
|
|
85
|
+
* prose the site actually renders.
|
|
86
|
+
*/
|
|
87
|
+
function stripMarkdown(line) {
|
|
88
|
+
return line
|
|
89
|
+
.replace(HEADING_LINE_RE, '')
|
|
90
|
+
.replace(/^\s{0,3}>\s?/, '')
|
|
91
|
+
.replace(/^\s{0,3}([-*+]|\d+\.)\s+/, '')
|
|
92
|
+
.replace(/!\[([^\]]*)\]\([^)]*\)/g, '$1')
|
|
93
|
+
.replace(/\[([^\]]+)\]\([^)]*\)/g, '$1')
|
|
94
|
+
.replace(/`{1,3}([^`]*)`{1,3}/g, '$1')
|
|
95
|
+
.replace(/(\*\*|__)(.*?)\1/g, '$2')
|
|
96
|
+
.replace(/(\*|_)(?=\S)(.*?)(?<=\S)\1/g, '$2')
|
|
97
|
+
.trim();
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* The prose of a passage: § context prefixes gone, markdown syntax gone,
|
|
101
|
+
* whitespace collapsed.
|
|
102
|
+
*
|
|
103
|
+
* `skipHeadings` drops heading lines as well, which is what a text fragment
|
|
104
|
+
* wants — a heading is usually its own element on the page, so starting a
|
|
105
|
+
* range there matches less reliably than starting at the paragraph. It falls
|
|
106
|
+
* back to including them when the passage is nothing but headings.
|
|
107
|
+
*/
|
|
108
|
+
export function passageProse(passage, skipHeadings = false) {
|
|
109
|
+
const lines = String(passage ?? '')
|
|
110
|
+
.replace(CONTEXT_PREFIX_RE, '')
|
|
111
|
+
.split('\n');
|
|
112
|
+
const keep = (only) => lines
|
|
113
|
+
.filter((l) => !only || !HEADING_LINE_RE.test(l))
|
|
114
|
+
.map(stripMarkdown)
|
|
115
|
+
.filter(Boolean)
|
|
116
|
+
.join(' ')
|
|
117
|
+
.replace(/\s+/g, ' ')
|
|
118
|
+
.trim();
|
|
119
|
+
const body = keep(skipHeadings);
|
|
120
|
+
return body || keep(false);
|
|
121
|
+
}
|
|
122
|
+
/** The head of a passage as a quotable sentence or two — the words a reader
|
|
123
|
+
* would see on the page, not the markdown we stored. */
|
|
124
|
+
export function passageQuote(passage, maxChars = QUOTE_MAX_CHARS) {
|
|
125
|
+
const text = passageProse(passage);
|
|
126
|
+
if (text.length <= maxChars)
|
|
127
|
+
return text;
|
|
128
|
+
const window = text.slice(0, maxChars);
|
|
129
|
+
const stop = Math.max(window.lastIndexOf('. '), window.lastIndexOf('? '), window.lastIndexOf('! '));
|
|
130
|
+
return stop > maxChars * 0.4 ? window.slice(0, stop + 1) : `${window.trimEnd()}…`;
|
|
131
|
+
}
|
|
132
|
+
/** `,` and `-` are syntax inside a text fragment, so they cannot be left raw. */
|
|
133
|
+
function encodeFragmentPart(text) {
|
|
134
|
+
return encodeURIComponent(text).replace(/-/g, '%2D').replace(/,/g, '%2C');
|
|
135
|
+
}
|
|
136
|
+
const FRAGMENT_WORDS = 8;
|
|
137
|
+
/**
|
|
138
|
+
* A W3C scroll-to-text fragment for this passage.
|
|
139
|
+
*
|
|
140
|
+
* Long passages use the `textStart,textEnd` form rather than the whole
|
|
141
|
+
* paragraph: the spec matches across the range, and a shorter pair survives
|
|
142
|
+
* the site re-flowing its markup between capture and click.
|
|
143
|
+
*/
|
|
144
|
+
export function textFragment(passage) {
|
|
145
|
+
const text = passageProse(passage, true).slice(0, 2000);
|
|
146
|
+
if (!text)
|
|
147
|
+
return '';
|
|
148
|
+
const words = text.split(' ').filter(Boolean);
|
|
149
|
+
if (words.length <= FRAGMENT_WORDS * 2)
|
|
150
|
+
return `:~:text=${encodeFragmentPart(text)}`;
|
|
151
|
+
const start = words.slice(0, FRAGMENT_WORDS).join(' ');
|
|
152
|
+
const end = words.slice(-FRAGMENT_WORDS).join(' ');
|
|
153
|
+
return `:~:text=${encodeFragmentPart(start)},${encodeFragmentPart(end)}`;
|
|
154
|
+
}
|
|
155
|
+
/** The captured page's URL, pointed at the passage. Returns undefined when
|
|
156
|
+
* there is no URL — a citation into a local file has no link to give. */
|
|
157
|
+
export function citationUrl(url, passage) {
|
|
158
|
+
if (!url)
|
|
159
|
+
return undefined;
|
|
160
|
+
const fragment = textFragment(passage);
|
|
161
|
+
if (!fragment)
|
|
162
|
+
return url;
|
|
163
|
+
const hash = url.indexOf('#');
|
|
164
|
+
const base = hash === -1 ? url : url.slice(0, hash);
|
|
165
|
+
return `${base}#${fragment}`;
|
|
166
|
+
}
|
|
167
|
+
function fileEntry(absolutePath) {
|
|
168
|
+
const stat = fs.statSync(absolutePath);
|
|
169
|
+
return {
|
|
170
|
+
path: absolutePath,
|
|
171
|
+
absolutePath,
|
|
172
|
+
extension: path.extname(absolutePath).toLowerCase(),
|
|
173
|
+
size: stat.size,
|
|
174
|
+
modified: stat.mtime,
|
|
175
|
+
created: stat.birthtime,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Resolve a citation back to the passage it came from.
|
|
180
|
+
*
|
|
181
|
+
* `target` is whatever the caller has written down: an indexed file path, a
|
|
182
|
+
* capture's `canonicalUrl`, or the `<scope>:<path>` docId. Throws with a
|
|
183
|
+
* message meant for a human when the document is not indexed, its file is
|
|
184
|
+
* gone, or the chunk does not exist — a citation that cannot be checked must
|
|
185
|
+
* fail loudly, not resolve to an empty string.
|
|
186
|
+
*/
|
|
187
|
+
export async function resolveCitation(target, opts = {}) {
|
|
188
|
+
const pipeline = await import('./document-pipeline.js');
|
|
189
|
+
const { extractText } = await import('../capabilities/cap-documents.js');
|
|
190
|
+
const rootDir = opts.rootDir ?? pipeline.getKnowledgeRoot(opts.scope);
|
|
191
|
+
const scope = opts.scope;
|
|
192
|
+
const record = pipeline.findDocumentRecord(rootDir, target, scope);
|
|
193
|
+
if (!record)
|
|
194
|
+
throw new Error(`not indexed: ${target}`);
|
|
195
|
+
if (!fs.existsSync(record.filePath)) {
|
|
196
|
+
throw new Error(`source file is gone: ${record.filePath} (re-ingest the capture to cite it)`);
|
|
197
|
+
}
|
|
198
|
+
const text = await extractText(fileEntry(record.filePath));
|
|
199
|
+
if (!text)
|
|
200
|
+
throw new Error(`no text could be extracted from ${record.filePath}`);
|
|
201
|
+
const hash = crypto.createHash('sha256').update(text).digest('hex');
|
|
202
|
+
let startChar;
|
|
203
|
+
let endChar;
|
|
204
|
+
let chunkIndex;
|
|
205
|
+
const parsedAnchor = opts.anchor ? parseCitationAnchor(opts.anchor) : null;
|
|
206
|
+
if (opts.anchor && !parsedAnchor)
|
|
207
|
+
throw new Error(`malformed citation anchor: ${opts.anchor}`);
|
|
208
|
+
if (parsedAnchor) {
|
|
209
|
+
startChar = Math.min(parsedAnchor.startChar, text.length);
|
|
210
|
+
endChar = Math.min(parsedAnchor.endChar, text.length);
|
|
211
|
+
const spans = await pipeline.chunkSpans(text);
|
|
212
|
+
chunkIndex = spans.findIndex((s) => s.startChar === startChar);
|
|
213
|
+
if (chunkIndex === -1) {
|
|
214
|
+
chunkIndex = spans.findIndex((s) => s.startChar <= startChar && startChar < s.endChar);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
chunkIndex = opts.chunkIndex ?? 0;
|
|
219
|
+
const spans = await pipeline.chunkSpans(text);
|
|
220
|
+
const span = spans[chunkIndex];
|
|
221
|
+
if (!span) {
|
|
222
|
+
throw new Error(`chunk ${chunkIndex} is out of range: ${path.basename(record.filePath)} has ${spans.length} chunk(s)`);
|
|
223
|
+
}
|
|
224
|
+
startChar = span.startChar;
|
|
225
|
+
endChar = span.endChar;
|
|
226
|
+
}
|
|
227
|
+
const passage = text.slice(startChar, endChar);
|
|
228
|
+
const url = record.canonicalUrl ?? record.provenance?.canonicalUrl ?? record.provenance?.url;
|
|
229
|
+
const stale = parsedAnchor
|
|
230
|
+
? !anchorMatchesHash(opts.anchor, hash)
|
|
231
|
+
: hash !== record.contentHash;
|
|
232
|
+
return {
|
|
233
|
+
docId: `${record.scope}:${record.filePath}`,
|
|
234
|
+
filePath: record.filePath,
|
|
235
|
+
scope: record.scope,
|
|
236
|
+
chunkIndex: chunkIndex === -1 ? 0 : chunkIndex,
|
|
237
|
+
startChar,
|
|
238
|
+
endChar,
|
|
239
|
+
contentHash: hash,
|
|
240
|
+
anchor: citationAnchor(hash, startChar, endChar),
|
|
241
|
+
passage,
|
|
242
|
+
quote: passageQuote(passage),
|
|
243
|
+
...(stale ? { stale: true } : {}),
|
|
244
|
+
...(record.version ? { version: record.version } : {}),
|
|
245
|
+
...(record.provenance?.title ? { title: record.provenance.title } : {}),
|
|
246
|
+
...(url ? { url, citeUrl: citationUrl(url, passage) } : {}),
|
|
247
|
+
...(record.provenance?.capturedAt ? { capturedAt: record.provenance.capturedAt } : {}),
|
|
248
|
+
...(record.provenance?.source ? { source: record.provenance.source } : {}),
|
|
249
|
+
...(record.provenance ? { provenance: record.provenance } : {}),
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
//# sourceMappingURL=citation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"citation.js","sourceRoot":"","sources":["../../../src/knowledge/citation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Document chunking — turning a document's extracted text into the enriched
|
|
3
|
+
* chunks that get embedded and stored.
|
|
4
|
+
*
|
|
5
|
+
* Two passes, in this order:
|
|
6
|
+
* 1. CHUNK — split on heading/paragraph boundaries (shared `@monoes/memory`
|
|
7
|
+
* chunker, with an inline fallback kept byte-identical to it).
|
|
8
|
+
* 2. ENRICH — replace each chunk's leaf-heading prefix with a situating blurb
|
|
9
|
+
* (doc title + full heading path + summary) so the embedding model can tell
|
|
10
|
+
* two identically-titled sections of different documents apart.
|
|
11
|
+
*
|
|
12
|
+
* Split out of document-pipeline.ts. Pure string work: no fs, no network, no
|
|
13
|
+
* store access — which is what makes chunk spans reproducible at citation time
|
|
14
|
+
* (`chunkSpans`) without re-reading anything.
|
|
15
|
+
*
|
|
16
|
+
* @module v1/cli/knowledge/document-chunking
|
|
17
|
+
*/
|
|
18
|
+
import type { ChunkSpan } from './citation.js';
|
|
19
|
+
export interface TextChunk {
|
|
20
|
+
chunkId: string;
|
|
21
|
+
docId: string;
|
|
22
|
+
text: string;
|
|
23
|
+
startChar: number;
|
|
24
|
+
endChar: number;
|
|
25
|
+
chunkIndex: number;
|
|
26
|
+
}
|
|
27
|
+
export declare function chunkDocument(docId: string, text: string): Promise<TextChunk[]>;
|
|
28
|
+
/**
|
|
29
|
+
* Replace each chunk's `§ heading` prefix with a richer situating blurb:
|
|
30
|
+
* § <doc title> · <full heading path>
|
|
31
|
+
* <doc summary for non-first chunks>
|
|
32
|
+
*
|
|
33
|
+
* First chunks that start with their own heading are left untouched (the
|
|
34
|
+
* heading IS the context). The summary line is omitted for the first
|
|
35
|
+
* chunk since it is adjacent to the summary text anyway.
|
|
36
|
+
*/
|
|
37
|
+
export declare function enrichChunks(chunks: TextChunk[], fullText: string, filePath: string): TextChunk[];
|
|
38
|
+
/** Chunk spans for a text, using the SAME chunker the ingest used — this is
|
|
39
|
+
* what makes a chunk index resolvable back to a character range without
|
|
40
|
+
* storing the text twice. */
|
|
41
|
+
export declare function chunkSpans(text: string): Promise<ChunkSpan[]>;
|
|
42
|
+
//# sourceMappingURL=document-chunking.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-chunking.d.ts","sourceRoot":"","sources":["../../../src/knowledge/document-chunking.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE/C,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AA6GD,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAOrF;AAwGD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,CAoCjG;AAED;;8BAE8B;AAC9B,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAOnE"}
|