@monoes/monomindcli 2.14.1 → 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 +4 -4
- 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 +67 -47
- 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 +24 -25
- 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 +405 -432
- 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/dist/src/commands/doc-filters.d.ts.map +1 -1
- package/dist/src/commands/doc-filters.js +6 -0
- package/dist/src/commands/doc-filters.js.map +1 -1
- package/dist/src/commands/doc-library.d.ts +2 -1
- package/dist/src/commands/doc-library.d.ts.map +1 -1
- package/dist/src/commands/doc-library.js +66 -2
- package/dist/src/commands/doc-library.js.map +1 -1
- package/dist/src/commands/doc.d.ts.map +1 -1
- package/dist/src/commands/doc.js +2 -0
- 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 +5 -0
- package/dist/src/knowledge/capture-envelope.d.ts.map +1 -1
- package/dist/src/knowledge/capture-envelope.js +2 -0
- package/dist/src/knowledge/capture-envelope.js.map +1 -1
- 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 -208
- package/dist/src/knowledge/document-pipeline.d.ts.map +1 -1
- package/dist/src/knowledge/document-pipeline.js +25 -1104
- 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/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/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/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.d.ts.map +1 -1
- package/dist/src/orgrt/session.js +21 -2
- 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 +6 -6
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The document index — the append-only metadata log that records which
|
|
3
|
+
* documents are indexed, at which version, and whether that is still true.
|
|
4
|
+
*
|
|
5
|
+
* The log (`.monomind/knowledge/doc-metadata.jsonl`) is the pipeline's source
|
|
6
|
+
* of truth. Everything here reads or writes it:
|
|
7
|
+
*
|
|
8
|
+
* - WRITE: append a version record, tombstone a removed one.
|
|
9
|
+
* - READ: the last-wins live view, the full history, and lookups by path,
|
|
10
|
+
* canonical URL or `<scope>:<path>` docId.
|
|
11
|
+
* - JUDGE: which content hashes are current, which chunk keys are therefore
|
|
12
|
+
* superseded, and which indexed files no longer exist on disk.
|
|
13
|
+
*
|
|
14
|
+
* Nothing here touches the vector store. Removal tombstones metadata and lets
|
|
15
|
+
* the superseded filter hide the chunks — mark, don't destroy.
|
|
16
|
+
*
|
|
17
|
+
* Split out of document-pipeline.ts.
|
|
18
|
+
*
|
|
19
|
+
* @module v1/cli/knowledge/document-index
|
|
20
|
+
*/
|
|
21
|
+
import * as fs from 'node:fs';
|
|
22
|
+
import * as path from 'node:path';
|
|
23
|
+
// Static import is safe and deliberate: memory-bridge imports only node builtins
|
|
24
|
+
// at module scope (everything heavy is lazy), and the project-root rule must not
|
|
25
|
+
// be duplicated — two copies of "which directory is this project" is exactly the
|
|
26
|
+
// bug this default exists to fix.
|
|
27
|
+
import { getProjectRoot } from '../memory/memory-bridge.js';
|
|
28
|
+
export const METADATA_FILE = 'doc-metadata.jsonl';
|
|
29
|
+
// ── Metadata log ───────────────────────────────────────────────────
|
|
30
|
+
export function metadataPath(rootDir) {
|
|
31
|
+
const dir = path.join(rootDir, '.monomind', 'knowledge');
|
|
32
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
33
|
+
return path.join(dir, METADATA_FILE);
|
|
34
|
+
}
|
|
35
|
+
/** Every record ever appended, in order, including superseded versions and
|
|
36
|
+
* removal tombstones. Reads the path directly instead of via `metadataPath`,
|
|
37
|
+
* which mkdir's. */
|
|
38
|
+
export function readMetadataLog(rootDir) {
|
|
39
|
+
const file = path.join(rootDir, '.monomind', 'knowledge', METADATA_FILE);
|
|
40
|
+
if (!fs.existsSync(file))
|
|
41
|
+
return [];
|
|
42
|
+
const out = [];
|
|
43
|
+
for (const line of fs.readFileSync(file, 'utf-8').split('\n')) {
|
|
44
|
+
if (!line.trim())
|
|
45
|
+
continue;
|
|
46
|
+
try {
|
|
47
|
+
out.push(JSON.parse(line));
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
/* torn line */
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return out;
|
|
54
|
+
}
|
|
55
|
+
export function readMetadata(rootDir) {
|
|
56
|
+
const file = metadataPath(rootDir);
|
|
57
|
+
if (!fs.existsSync(file))
|
|
58
|
+
return [];
|
|
59
|
+
// Last-wins per (filePath, scope): the file is append-only under concurrent
|
|
60
|
+
// ingests (session-start detached reindex + a manual `doc ingest` can
|
|
61
|
+
// overlap), so duplicates are expected and the newest record is truth.
|
|
62
|
+
// Corrupt lines (torn concurrent writes) are skipped, not fatal.
|
|
63
|
+
const latest = new Map();
|
|
64
|
+
for (const l of fs.readFileSync(file, 'utf-8').split('\n')) {
|
|
65
|
+
if (!l.trim())
|
|
66
|
+
continue;
|
|
67
|
+
try {
|
|
68
|
+
const m = JSON.parse(l);
|
|
69
|
+
latest.set(`${m.filePath} ${m.scope}`, m);
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
/* torn line */
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// chunkCount -1 records are removal tombstones (see removeMetadataEntry)
|
|
76
|
+
const live = [...latest.values()].filter((m) => m.chunkCount >= 0);
|
|
77
|
+
// Occasional compaction: append-only + tombstones grow without bound; when
|
|
78
|
+
// the log gets big, rewrite it deduped (atomic rename — a concurrent append
|
|
79
|
+
// in the tiny window loses only its own record and self-heals on re-ingest).
|
|
80
|
+
try {
|
|
81
|
+
if (fs.statSync(file).size > 1024 * 1024) {
|
|
82
|
+
const tmp = `${file}.${process.pid}.compact`;
|
|
83
|
+
fs.writeFileSync(tmp, live.map((r) => JSON.stringify(r)).join('\n') + (live.length ? '\n' : ''), 'utf-8');
|
|
84
|
+
fs.renameSync(tmp, file);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
/* compaction is best-effort */
|
|
89
|
+
}
|
|
90
|
+
return live;
|
|
91
|
+
}
|
|
92
|
+
export function appendMetadata(rootDir, meta) {
|
|
93
|
+
fs.appendFileSync(metadataPath(rootDir), `${JSON.stringify(meta)}\n`, 'utf-8');
|
|
94
|
+
}
|
|
95
|
+
export function removeMetadataEntry(rootDir, filePath, scope) {
|
|
96
|
+
const file = metadataPath(rootDir);
|
|
97
|
+
if (!fs.existsSync(file))
|
|
98
|
+
return;
|
|
99
|
+
// Tombstone by APPEND (chunkCount -1) instead of read-filter-rewrite — the
|
|
100
|
+
// rewrite raced concurrent appends and silently dropped them.
|
|
101
|
+
appendMetadata(rootDir, {
|
|
102
|
+
filePath,
|
|
103
|
+
scope,
|
|
104
|
+
contentHash: '',
|
|
105
|
+
chunkCount: -1,
|
|
106
|
+
indexedAt: new Date().toISOString(),
|
|
107
|
+
size: 0,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
// ── Superseded-version filtering ───────────────────────────────────
|
|
111
|
+
//
|
|
112
|
+
// Chunk keys are `doc:<contentHash>:<chunkIndex>`. Re-ingesting a changed file
|
|
113
|
+
// produces a NEW contentHash, so its chunks land under new keys — the previous
|
|
114
|
+
// version's rows are never touched (`removeDocument` only tombstones metadata;
|
|
115
|
+
// the bridge exposes no delete-by-prefix). The store therefore accumulates every
|
|
116
|
+
// version a document has ever had, and all of them stay searchable.
|
|
117
|
+
//
|
|
118
|
+
// Measured on this repo's own store (2026-07-26): 9,067 `doc:`-keyed rows in
|
|
119
|
+
// `knowledge:shared` spanning 798 distinct content hashes, of which only 139
|
|
120
|
+
// are current — 8,542 rows (94.2%) are orphaned older versions.
|
|
121
|
+
//
|
|
122
|
+
// Nothing is deleted here. The current-hash set from doc-metadata.jsonl is used
|
|
123
|
+
// to decide what search RETURNS; `includeSuperseded` puts the old versions back
|
|
124
|
+
// (flagged `superseded: true`) for anyone who wants document history.
|
|
125
|
+
/** Content hashes of the documents currently indexed under `rootDir`. */
|
|
126
|
+
export function liveContentHashes(rootDir) {
|
|
127
|
+
const live = new Set();
|
|
128
|
+
for (const m of readMetadata(rootDir))
|
|
129
|
+
if (m.contentHash)
|
|
130
|
+
live.add(m.contentHash);
|
|
131
|
+
return live;
|
|
132
|
+
}
|
|
133
|
+
/** True when a metadata log exists under `rootDir`.
|
|
134
|
+
*
|
|
135
|
+
* An empty live-hash set has two very different causes: the log is missing (we
|
|
136
|
+
* cannot judge what is current) or the log exists and every document has been
|
|
137
|
+
* removed (nothing is current). Collapsing them made `doc remove` of the LAST
|
|
138
|
+
* document a no-op — the tombstoned chunks came straight back in search.
|
|
139
|
+
*
|
|
140
|
+
* Reads the path directly instead of via `metadataPath`, which mkdir's. */
|
|
141
|
+
export function hasKnowledgeMetadata(rootDir) {
|
|
142
|
+
return fs.existsSync(path.join(rootDir, '.monomind', 'knowledge', METADATA_FILE));
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* True when `key` is a document chunk whose version is no longer current.
|
|
146
|
+
* Non-`doc:` keys are never superseded. When no metadata is available nothing
|
|
147
|
+
* is filtered, because "no metadata" must not read as "everything is stale".
|
|
148
|
+
*
|
|
149
|
+
* `metadataPresent` defaults to the old `live.size > 0` heuristic so existing
|
|
150
|
+
* two-argument callers keep their exact behaviour; pass `hasKnowledgeMetadata`
|
|
151
|
+
* to also filter correctly once the last document has been removed.
|
|
152
|
+
*/
|
|
153
|
+
export function isSupersededKey(key, live, metadataPresent = live.size > 0) {
|
|
154
|
+
if (!key?.startsWith('doc:'))
|
|
155
|
+
return false;
|
|
156
|
+
if (!metadataPresent)
|
|
157
|
+
return false;
|
|
158
|
+
return !live.has(key.split(':')[1] ?? '');
|
|
159
|
+
}
|
|
160
|
+
/** How many rows to ask the backend for per requested result when superseded
|
|
161
|
+
* filtering is active — most rows in a long-lived store are old versions, so
|
|
162
|
+
* a 1:1 fetch would return an almost-empty page. */
|
|
163
|
+
const SUPERSEDED_OVERFETCH = 20;
|
|
164
|
+
const SUPERSEDED_OVERFETCH_CAP = 300;
|
|
165
|
+
export function supersededOverfetchLimit(limit, live) {
|
|
166
|
+
if (live.size === 0)
|
|
167
|
+
return limit;
|
|
168
|
+
return Math.min(Math.max(limit * SUPERSEDED_OVERFETCH, limit), SUPERSEDED_OVERFETCH_CAP);
|
|
169
|
+
}
|
|
170
|
+
// ── List / lookup ──────────────────────────────────────────────────
|
|
171
|
+
export function listDocuments(rootDir = getProjectRoot(), scope) {
|
|
172
|
+
const all = readMetadata(rootDir);
|
|
173
|
+
return scope ? all.filter((m) => m.scope === scope) : all;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Every recorded version of one document, oldest first (RCL-06).
|
|
177
|
+
*
|
|
178
|
+
* `target` is either an indexed file path or a capture's `canonicalUrl`. Read
|
|
179
|
+
* from the append-only log rather than the last-wins view, which is how a
|
|
180
|
+
* superseded version stays addressable after its record has been replaced or
|
|
181
|
+
* tombstoned.
|
|
182
|
+
*
|
|
183
|
+
* Best-effort by design: `readMetadata` compacts the log once it passes 1MB
|
|
184
|
+
* and keeps only live records, so history older than a compaction is gone.
|
|
185
|
+
* The `supersedes` pointer on each record is the durable part.
|
|
186
|
+
*/
|
|
187
|
+
export function listDocumentVersions(rootDir = getProjectRoot(), target, scope) {
|
|
188
|
+
const resolved = target ? path.resolve(target) : undefined;
|
|
189
|
+
return readMetadataLog(rootDir)
|
|
190
|
+
.filter((m) => m.chunkCount >= 0)
|
|
191
|
+
.filter((m) => !scope || m.scope === scope)
|
|
192
|
+
.filter((m) => !target || m.filePath === resolved || m.filePath === target || m.canonicalUrl === target)
|
|
193
|
+
.sort((a, b) => (a.version ?? 0) - (b.version ?? 0) || a.indexedAt.localeCompare(b.indexedAt));
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* The indexed record for whatever a caller wrote down: a file path, a
|
|
197
|
+
* capture's `canonicalUrl` (fragment ignored), or the `<scope>:<path>` docId.
|
|
198
|
+
*
|
|
199
|
+
* Live records win. A superseded version is only reached through the
|
|
200
|
+
* append-only log, and only when nothing live matches — otherwise citing a
|
|
201
|
+
* re-captured page would resolve against the version it replaced.
|
|
202
|
+
*/
|
|
203
|
+
export function findDocumentRecord(rootDir = getProjectRoot(), target = '', scope) {
|
|
204
|
+
const raw = target.trim();
|
|
205
|
+
if (!raw)
|
|
206
|
+
return undefined;
|
|
207
|
+
// `<scope>:<path>` — but not `https://…`, whose colon is a URL scheme.
|
|
208
|
+
const scoped = /^([a-z][a-z0-9_-]*):(?!\/\/)(.+)$/i.exec(raw);
|
|
209
|
+
const candidates = scoped ? [raw, scoped[2]] : [raw];
|
|
210
|
+
const hash = raw.indexOf('#');
|
|
211
|
+
if (hash > 0)
|
|
212
|
+
candidates.push(raw.slice(0, hash));
|
|
213
|
+
const resolvedPaths = new Set(candidates.map((c) => path.resolve(c)));
|
|
214
|
+
const wanted = new Set(candidates);
|
|
215
|
+
const scopeFilter = scope ?? (scoped ? scoped[1] : undefined);
|
|
216
|
+
const matches = (m) => {
|
|
217
|
+
if (scopeFilter && m.scope !== scopeFilter && !wanted.has(m.filePath))
|
|
218
|
+
return false;
|
|
219
|
+
if (wanted.has(m.filePath) || resolvedPaths.has(path.resolve(m.filePath)))
|
|
220
|
+
return true;
|
|
221
|
+
return !!m.canonicalUrl && wanted.has(m.canonicalUrl);
|
|
222
|
+
};
|
|
223
|
+
const live = readMetadata(rootDir).filter(matches);
|
|
224
|
+
if (live.length) {
|
|
225
|
+
return live.sort((a, b) => (b.version ?? 0) - (a.version ?? 0))[0];
|
|
226
|
+
}
|
|
227
|
+
const historical = readMetadataLog(rootDir)
|
|
228
|
+
.filter((m) => m.chunkCount >= 0)
|
|
229
|
+
.filter(matches);
|
|
230
|
+
return historical.sort((a, b) => (b.version ?? 0) - (a.version ?? 0))[0];
|
|
231
|
+
}
|
|
232
|
+
export async function removeDocument(filePath, scope = 'shared', rootDir = getProjectRoot()) {
|
|
233
|
+
removeMetadataEntry(rootDir, path.resolve(filePath), scope);
|
|
234
|
+
// SQLite cleanup: bridge doesn't expose delete-by-key, so metadata removal is sufficient.
|
|
235
|
+
// Orphaned SQLite entries get swept on next full re-index or TTL expiry.
|
|
236
|
+
}
|
|
237
|
+
// ── Filesystem reconciliation (item 4b-i) ──────────────────────────
|
|
238
|
+
/**
|
|
239
|
+
* True for macOS AppleDouble sidecars (`._name`).
|
|
240
|
+
*
|
|
241
|
+
* Matches on the BASENAME PREFIX only. A legitimate document may contain `._`
|
|
242
|
+
* elsewhere in its name (`v1._2-release.md`), or live under a dot-directory
|
|
243
|
+
* that is deliberately indexed (`.monodesign/` critique snapshots), and
|
|
244
|
+
* neither may be rejected.
|
|
245
|
+
*/
|
|
246
|
+
export function isResourceFork(filePath) {
|
|
247
|
+
return path.basename(filePath).startsWith('._');
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Reconcile the document index against the filesystem: find index entries whose
|
|
251
|
+
* source file no longer exists and, only when explicitly asked, tombstone them.
|
|
252
|
+
*
|
|
253
|
+
* WHY — `removeDocument` only ever tombstoned metadata, and nothing has ever
|
|
254
|
+
* compared the index against the disk, so a deleted file stayed searchable
|
|
255
|
+
* forever. Measured 2026-07-28: 109 of 257 live entries (42.4%) had no file
|
|
256
|
+
* behind them, including `docs/concepts/memory.md`. The Second Brain was
|
|
257
|
+
* answering questions from documents the user had deleted.
|
|
258
|
+
*
|
|
259
|
+
* WHY IT IS THIS CAUTIOUS — "drop the index entry when the file is missing" is
|
|
260
|
+
* a rule with a known catastrophic reading. A missing file is also an unmounted
|
|
261
|
+
* volume, a checked-out branch, a partial clone, or a permissions failure. Two
|
|
262
|
+
* guards were tried against real data and REJECTED; they are recorded here so
|
|
263
|
+
* they are not re-proposed:
|
|
264
|
+
*
|
|
265
|
+
* - "abort if >50% of entries are missing" — the real, legitimate missing
|
|
266
|
+
* fraction was 42.4%, so the threshold never fires in the one case we have.
|
|
267
|
+
* Any threshold that would have blocked this reconcile is fitted to nothing.
|
|
268
|
+
* - "only reconcile when the parent directory still exists" — 26 of the 109
|
|
269
|
+
* missing files had no parent directory, because `docs/concepts`,
|
|
270
|
+
* `docs/adrs` and `docs/commands` were legitimately deleted wholesale. A
|
|
271
|
+
* deleted directory and an unmounted volume are indistinguishable there.
|
|
272
|
+
*
|
|
273
|
+
* What does discriminate is the ROOT. An intact, readable root carrying a
|
|
274
|
+
* metadata log means the tree is genuinely present, so a missing file is
|
|
275
|
+
* genuinely gone. A missing root means nothing beneath it is knowable and
|
|
276
|
+
* nothing may be removed — hence throw rather than reconcile.
|
|
277
|
+
*
|
|
278
|
+
* Removal tombstones metadata; it does not delete store rows. Chunks stay on
|
|
279
|
+
* disk and fall out of search through the existing superseded filter, which
|
|
280
|
+
* keeps this consistent with the mark-don't-destroy rule and leaves the whole
|
|
281
|
+
* operation reversible from the archive.
|
|
282
|
+
*/
|
|
283
|
+
export async function reconcileIndex(rootDir = getProjectRoot(), opts) {
|
|
284
|
+
const apply = opts?.apply === true;
|
|
285
|
+
// Root guard — the unmounted-volume case. Every file below a missing root
|
|
286
|
+
// looks deleted, so this must abort rather than reconcile.
|
|
287
|
+
if (!rootDir || !fs.existsSync(rootDir)) {
|
|
288
|
+
throw new Error(`reconcileIndex: project root does not exist: ${rootDir} — refusing to reconcile ` +
|
|
289
|
+
`(an unmounted volume makes every indexed file look deleted)`);
|
|
290
|
+
}
|
|
291
|
+
if (!hasKnowledgeMetadata(rootDir)) {
|
|
292
|
+
throw new Error(`reconcileIndex: no knowledge metadata log under ${rootDir} — refusing to reconcile ` +
|
|
293
|
+
`("no metadata" must not read as "everything is stale")`);
|
|
294
|
+
}
|
|
295
|
+
const records = readMetadata(rootDir).filter((m) => !opts?.scope || m.scope === opts.scope);
|
|
296
|
+
const missing = records.filter((m) => !fs.existsSync(m.filePath));
|
|
297
|
+
if (!apply || missing.length === 0) {
|
|
298
|
+
return { missing, scanned: records.length, applied: apply, removed: 0 };
|
|
299
|
+
}
|
|
300
|
+
// Archive BEFORE removing, inside the operation so no caller can bypass it
|
|
301
|
+
// by forgetting — the same precondition rule the delete path uses.
|
|
302
|
+
const dir = path.join(rootDir, '.monomind', 'knowledge', 'archive');
|
|
303
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
304
|
+
const stamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
305
|
+
const archivePath = path.join(dir, `reconcile-${stamp}.jsonl`);
|
|
306
|
+
fs.writeFileSync(archivePath, `${missing.map((m) => JSON.stringify(m)).join('\n')}\n`, 'utf-8');
|
|
307
|
+
let removed = 0;
|
|
308
|
+
for (const m of missing) {
|
|
309
|
+
removeMetadataEntry(rootDir, m.filePath, m.scope);
|
|
310
|
+
removed++;
|
|
311
|
+
}
|
|
312
|
+
return { missing, scanned: records.length, applied: true, removed, archivePath };
|
|
313
|
+
}
|
|
314
|
+
//# sourceMappingURL=document-index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-index.js","sourceRoot":"","sources":["../../../src/knowledge/document-index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,iFAAiF;AACjF,iFAAiF;AACjF,iFAAiF;AACjF,kCAAkC;AAClC,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAG5D,MAAM,CAAC,MAAM,aAAa,GAAG,oBAAoB,CAAC;AAElD,sEAAsE;AAEtE,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;IACzD,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvC,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;AACvC,CAAC;AAED;;qBAEqB;AACrB,MAAM,UAAU,eAAe,CAAC,OAAe;IAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC;IACzE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IACpC,MAAM,GAAG,GAAmB,EAAE,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9D,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YAAE,SAAS;QAC3B,IAAI,CAAC;YACH,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAiB,CAAC,CAAC;QAC7C,CAAC;QAAC,MAAM,CAAC;YACP,eAAe;QACjB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,MAAM,IAAI,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IACnC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IACpC,4EAA4E;IAC5E,sEAAsE;IACtE,uEAAuE;IACvE,iEAAiE;IACjE,MAAM,MAAM,GAAG,IAAI,GAAG,EAAwB,CAAC;IAC/C,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3D,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE;YAAE,SAAS;QACxB,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAiB,CAAC;YACxC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC;QAC5C,CAAC;QAAC,MAAM,CAAC;YACP,eAAe;QACjB,CAAC;IACH,CAAC;IACD,yEAAyE;IACzE,MAAM,IAAI,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC;IACnE,2EAA2E;IAC3E,4EAA4E;IAC5E,6EAA6E;IAC7E,IAAI,CAAC;QACH,IAAI,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC;YACzC,MAAM,GAAG,GAAG,GAAG,IAAI,IAAI,OAAO,CAAC,GAAG,UAAU,CAAC;YAC7C,EAAE,CAAC,aAAa,CACd,GAAG,EACH,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EACzE,OAAO,CACR,CAAC;YACF,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,+BAA+B;IACjC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAAe,EAAE,IAAkB;IAChE,EAAE,CAAC,cAAc,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AACjF,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,OAAe,EAAE,QAAgB,EAAE,KAAa;IAClF,MAAM,IAAI,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IACnC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO;IACjC,2EAA2E;IAC3E,8DAA8D;IAC9D,cAAc,CAAC,OAAO,EAAE;QACtB,QAAQ;QACR,KAAK;QACL,WAAW,EAAE,EAAE;QACf,UAAU,EAAE,CAAC,CAAC;QACd,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,IAAI,EAAE,CAAC;KACR,CAAC,CAAC;AACL,CAAC;AAED,sEAAsE;AACtE,EAAE;AACF,+EAA+E;AAC/E,+EAA+E;AAC/E,+EAA+E;AAC/E,iFAAiF;AACjF,oEAAoE;AACpE,EAAE;AACF,6EAA6E;AAC7E,6EAA6E;AAC7E,gEAAgE;AAChE,EAAE;AACF,gFAAgF;AAChF,gFAAgF;AAChF,sEAAsE;AAEtE,yEAAyE;AACzE,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAC/C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,CAAC,IAAI,YAAY,CAAC,OAAO,CAAC;QAAE,IAAI,CAAC,CAAC,WAAW;YAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IAClF,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;2EAO2E;AAC3E,MAAM,UAAU,oBAAoB,CAAC,OAAe;IAClD,OAAO,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC,CAAC;AACpF,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAC7B,GAAW,EACX,IAAiB,EACjB,eAAe,GAAG,IAAI,CAAC,IAAI,GAAG,CAAC;IAE/B,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IAC3C,IAAI,CAAC,eAAe;QAAE,OAAO,KAAK,CAAC;IACnC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;AAC5C,CAAC;AAED;;qDAEqD;AACrD,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAChC,MAAM,wBAAwB,GAAG,GAAG,CAAC;AAErC,MAAM,UAAU,wBAAwB,CAAC,KAAa,EAAE,IAAiB;IACvE,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAClC,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,oBAAoB,EAAE,KAAK,CAAC,EAAE,wBAAwB,CAAC,CAAC;AAC3F,CAAC;AAED,sEAAsE;AAEtE,MAAM,UAAU,aAAa,CAAC,OAAO,GAAG,cAAc,EAAE,EAAE,KAAc;IACtE,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IAClC,OAAO,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AAC5D,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,oBAAoB,CAClC,OAAO,GAAG,cAAc,EAAE,EAC1B,MAAe,EACf,KAAc;IAEd,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC3D,OAAO,eAAe,CAAC,OAAO,CAAC;SAC5B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC;SAChC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC;SAC1C,MAAM,CACL,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,MAAM,IAAI,CAAC,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,CAAC,QAAQ,KAAK,MAAM,IAAI,CAAC,CAAC,YAAY,KAAK,MAAM,CAC3F;SACA,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;AACnG,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAAO,GAAG,cAAc,EAAE,EAC1B,MAAM,GAAG,EAAE,EACX,KAAc;IAEd,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IAC1B,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAC3B,uEAAuE;IACvE,MAAM,MAAM,GAAG,oCAAoC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC9D,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACrD,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC9B,IAAI,IAAI,GAAG,CAAC;QAAE,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;IAClD,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACtE,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;IACnC,MAAM,WAAW,GAAG,KAAK,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAE9D,MAAM,OAAO,GAAG,CAAC,CAAe,EAAW,EAAE;QAC3C,IAAI,WAAW,IAAI,CAAC,CAAC,KAAK,KAAK,WAAW,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC;YAAE,OAAO,KAAK,CAAC;QACpF,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QACvF,OAAO,CAAC,CAAC,CAAC,CAAC,YAAY,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;IACxD,CAAC,CAAC;IAEF,MAAM,IAAI,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACnD,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACrE,CAAC;IACD,MAAM,UAAU,GAAG,eAAe,CAAC,OAAO,CAAC;SACxC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC;SAChC,MAAM,CAAC,OAAO,CAAC,CAAC;IACnB,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3E,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,QAAgB,EAChB,KAAK,GAAG,QAAQ,EAChB,OAAO,GAAG,cAAc,EAAE;IAE1B,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,CAAC;IAC5D,0FAA0F;IAC1F,yEAAyE;AAC3E,CAAC;AAED,sEAAsE;AAEtE;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AAClD,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,OAAO,GAAG,cAAc,EAAE,EAC1B,IAA0C;IAE1C,MAAM,KAAK,GAAG,IAAI,EAAE,KAAK,KAAK,IAAI,CAAC;IAEnC,0EAA0E;IAC1E,2DAA2D;IAC3D,IAAI,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CACb,gDAAgD,OAAO,2BAA2B;YAChF,6DAA6D,CAChE,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CACb,mDAAmD,OAAO,2BAA2B;YACnF,wDAAwD,CAC3D,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,IAAI,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC;IAC5F,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IAElE,IAAI,CAAC,KAAK,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;IAC1E,CAAC;IAED,2EAA2E;IAC3E,mEAAmE;IACnE,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;IACpE,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvC,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAC7D,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,KAAK,QAAQ,CAAC,CAAC;IAC/D,EAAE,CAAC,aAAa,CAAC,WAAW,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAEhG,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,mBAAmB,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;QAClD,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;AACnF,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Document ingest — the write side of the pipeline: a file on disk (or a
|
|
3
|
+
* capture envelope) becomes an indexed, versioned, searchable document.
|
|
4
|
+
*
|
|
5
|
+
* One pass per document: guard the input, resolve the capture envelope's
|
|
6
|
+
* identity, extract and hash the text, chunk and enrich it, store every chunk,
|
|
7
|
+
* and only then commit the version record. An incomplete store commits
|
|
8
|
+
* nothing, which is what makes a re-ingest repair it.
|
|
9
|
+
*
|
|
10
|
+
* Split out of document-pipeline.ts.
|
|
11
|
+
*
|
|
12
|
+
* @module v1/cli/knowledge/document-ingest
|
|
13
|
+
*/
|
|
14
|
+
import type { FileEntry } from '../capabilities/types.js';
|
|
15
|
+
import type { BatchIngestResult, DocumentMeta, IngestResult } from './document-types.js';
|
|
16
|
+
/** @internal — shared with okf-bundle, which extracts text the same way. */
|
|
17
|
+
export declare function toFileEntry(filePath: string): FileEntry;
|
|
18
|
+
export declare function ingestDocument(filePath: string, scope?: string, rootDir?: string, _metadataCache?: DocumentMeta[]): Promise<IngestResult>;
|
|
19
|
+
export declare function ingestDirectory(dirPath: string, scope?: string, opts?: {
|
|
20
|
+
rootDir?: string;
|
|
21
|
+
onProgress?: (file: string, done: number, total: number) => void;
|
|
22
|
+
}): Promise<BatchIngestResult>;
|
|
23
|
+
//# sourceMappingURL=document-ingest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-ingest.d.ts","sourceRoot":"","sources":["../../../src/knowledge/document-ingest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAsB1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAgBzF,4EAA4E;AAC5E,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAUvD;AAED,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,KAAK,SAAW,EAChB,OAAO,SAAmB,EAC1B,cAAc,CAAC,EAAE,YAAY,EAAE,GAC9B,OAAO,CAAC,YAAY,CAAC,CA0RvB;AAED,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,KAAK,SAAW,EAChB,IAAI,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,GAC5F,OAAO,CAAC,iBAAiB,CAAC,CAyD5B"}
|