@omgbase/core 0.1.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/LICENSE +21 -0
- package/dist/src/cli/eval-matcher.d.ts +13 -0
- package/dist/src/cli/eval-matcher.js +36 -0
- package/dist/src/core/attach.d.ts +5 -0
- package/dist/src/core/attach.js +38 -0
- package/dist/src/core/cursor.d.ts +11 -0
- package/dist/src/core/cursor.js +35 -0
- package/dist/src/core/hash.d.ts +23 -0
- package/dist/src/core/hash.js +82 -0
- package/dist/src/core/ids.d.ts +6 -0
- package/dist/src/core/ids.js +26 -0
- package/dist/src/core/index.d.ts +1 -0
- package/dist/src/core/index.js +2 -0
- package/dist/src/core/ingest.d.ts +43 -0
- package/dist/src/core/ingest.js +287 -0
- package/dist/src/core/order-key.d.ts +8 -0
- package/dist/src/core/order-key.js +72 -0
- package/dist/src/core/parse/parse.d.ts +3 -0
- package/dist/src/core/parse/parse.js +104 -0
- package/dist/src/core/parse/render.d.ts +3 -0
- package/dist/src/core/parse/render.js +20 -0
- package/dist/src/core/parse/tree.d.ts +8 -0
- package/dist/src/core/parse/tree.js +43 -0
- package/dist/src/core/parse/types.d.ts +52 -0
- package/dist/src/core/parse/types.js +9 -0
- package/dist/src/core/read/document.d.ts +107 -0
- package/dist/src/core/read/document.js +191 -0
- package/dist/src/core/read/nodes.d.ts +47 -0
- package/dist/src/core/read/nodes.js +102 -0
- package/dist/src/core/read/outline.d.ts +12 -0
- package/dist/src/core/read/outline.js +76 -0
- package/dist/src/core/read/reader.d.ts +125 -0
- package/dist/src/core/read/reader.js +206 -0
- package/dist/src/core/read/refs.d.ts +15 -0
- package/dist/src/core/read/refs.js +51 -0
- package/dist/src/core/store/edges.d.ts +26 -0
- package/dist/src/core/store/edges.js +101 -0
- package/dist/src/core/store/fts.d.ts +10 -0
- package/dist/src/core/store/fts.js +22 -0
- package/dist/src/core/store/gc.d.ts +18 -0
- package/dist/src/core/store/gc.js +69 -0
- package/dist/src/core/store/nodes.d.ts +5 -0
- package/dist/src/core/store/nodes.js +57 -0
- package/dist/src/core/store/properties.d.ts +38 -0
- package/dist/src/core/store/properties.js +177 -0
- package/dist/src/core/store/rebuild.d.ts +3 -0
- package/dist/src/core/store/rebuild.js +29 -0
- package/dist/src/core/store/schema.d.ts +9 -0
- package/dist/src/core/store/schema.js +386 -0
- package/dist/src/core/store/sections.d.ts +2 -0
- package/dist/src/core/store/sections.js +29 -0
- package/dist/src/core/store/store.d.ts +24 -0
- package/dist/src/core/store/store.js +164 -0
- package/dist/src/core/store/writers.d.ts +52 -0
- package/dist/src/core/store/writers.js +89 -0
- package/dist/src/core/vec.d.ts +10 -0
- package/dist/src/core/vec.js +33 -0
- package/dist/src/format/adapter.d.ts +97 -0
- package/dist/src/format/adapter.js +14 -0
- package/dist/src/format/index.d.ts +6 -0
- package/dist/src/format/index.js +15 -0
- package/dist/src/format/json.d.ts +3 -0
- package/dist/src/format/json.js +324 -0
- package/dist/src/format/markdown.d.ts +5 -0
- package/dist/src/format/markdown.js +217 -0
- package/dist/src/format/registry.d.ts +6 -0
- package/dist/src/format/registry.js +24 -0
- package/dist/src/format/yaml.d.ts +5 -0
- package/dist/src/format/yaml.js +413 -0
- package/dist/src/graph/extract.d.ts +38 -0
- package/dist/src/graph/extract.js +242 -0
- package/dist/src/graph/history.d.ts +103 -0
- package/dist/src/graph/history.js +210 -0
- package/dist/src/graph/inbound-links.d.ts +33 -0
- package/dist/src/graph/inbound-links.js +130 -0
- package/dist/src/graph/link-destinations.d.ts +22 -0
- package/dist/src/graph/link-destinations.js +84 -0
- package/dist/src/graph/link-health.d.ts +79 -0
- package/dist/src/graph/link-health.js +146 -0
- package/dist/src/graph/links.d.ts +23 -0
- package/dist/src/graph/links.js +42 -0
- package/dist/src/index.d.ts +60 -0
- package/dist/src/index.js +70 -0
- package/dist/src/mcp/errors.d.ts +17 -0
- package/dist/src/mcp/errors.js +18 -0
- package/dist/src/mcp/graph.d.ts +63 -0
- package/dist/src/mcp/graph.js +212 -0
- package/dist/src/mcp/reference.d.ts +1 -0
- package/dist/src/mcp/reference.js +227 -0
- package/dist/src/mcp/server.d.ts +30 -0
- package/dist/src/mcp/server.js +1076 -0
- package/dist/src/mcp/stdio.d.ts +13 -0
- package/dist/src/mcp/stdio.js +24 -0
- package/dist/src/migrate/mrplex.d.ts +27 -0
- package/dist/src/migrate/mrplex.js +29 -0
- package/dist/src/mutate/apply.d.ts +83 -0
- package/dist/src/mutate/apply.js +302 -0
- package/dist/src/mutate/doc-store.d.ts +49 -0
- package/dist/src/mutate/doc-store.js +71 -0
- package/dist/src/mutate/docs.d.ts +60 -0
- package/dist/src/mutate/docs.js +232 -0
- package/dist/src/mutate/known-ids.d.ts +12 -0
- package/dist/src/mutate/known-ids.js +154 -0
- package/dist/src/mutate/load.d.ts +3 -0
- package/dist/src/mutate/load.js +66 -0
- package/dist/src/mutate/lower.d.ts +32 -0
- package/dist/src/mutate/lower.js +232 -0
- package/dist/src/mutate/macros.d.ts +91 -0
- package/dist/src/mutate/macros.js +230 -0
- package/dist/src/mutate/ops.d.ts +40 -0
- package/dist/src/mutate/ops.js +513 -0
- package/dist/src/mutate/opset.d.ts +92 -0
- package/dist/src/mutate/opset.js +79 -0
- package/dist/src/mutate/plan-update.d.ts +51 -0
- package/dist/src/mutate/plan-update.js +187 -0
- package/dist/src/mutate/tree.d.ts +46 -0
- package/dist/src/mutate/tree.js +167 -0
- package/dist/src/oqx/run.d.ts +1 -0
- package/dist/src/oqx/run.js +6 -0
- package/dist/src/oqx-js/context.d.ts +23 -0
- package/dist/src/oqx-js/context.js +564 -0
- package/dist/src/oqx-js/planner.d.ts +10 -0
- package/dist/src/oqx-js/planner.js +91 -0
- package/dist/src/oqx-js/run.d.ts +41 -0
- package/dist/src/oqx-js/run.js +332 -0
- package/dist/src/oqx-js/sql/translate.d.ts +27 -0
- package/dist/src/oqx-js/sql/translate.js +290 -0
- package/dist/src/reconcile/crossdoc.d.ts +34 -0
- package/dist/src/reconcile/crossdoc.js +76 -0
- package/dist/src/reconcile/eval/generator.d.ts +21 -0
- package/dist/src/reconcile/eval/generator.js +129 -0
- package/dist/src/reconcile/eval/metrics.d.ts +32 -0
- package/dist/src/reconcile/eval/metrics.js +74 -0
- package/dist/src/reconcile/flatten.d.ts +12 -0
- package/dist/src/reconcile/flatten.js +37 -0
- package/dist/src/reconcile/phase5.d.ts +8 -0
- package/dist/src/reconcile/phase5.js +167 -0
- package/dist/src/reconcile/phase6a.d.ts +2 -0
- package/dist/src/reconcile/phase6a.js +159 -0
- package/dist/src/reconcile/phases.d.ts +28 -0
- package/dist/src/reconcile/phases.js +0 -0
- package/dist/src/reconcile/reconcile.d.ts +21 -0
- package/dist/src/reconcile/reconcile.js +115 -0
- package/dist/src/reconcile/similarity.d.ts +7 -0
- package/dist/src/reconcile/similarity.js +41 -0
- package/dist/src/reconcile/types.d.ts +46 -0
- package/dist/src/reconcile/types.js +19 -0
- package/dist/src/search/cel/ast.d.ts +74 -0
- package/dist/src/search/cel/ast.js +3 -0
- package/dist/src/search/cel/compile.d.ts +60 -0
- package/dist/src/search/cel/compile.js +836 -0
- package/dist/src/search/cel/lexer.d.ts +9 -0
- package/dist/src/search/cel/lexer.js +139 -0
- package/dist/src/search/cel/parser.d.ts +7 -0
- package/dist/src/search/cel/parser.js +219 -0
- package/dist/src/search/drain.d.ts +39 -0
- package/dist/src/search/drain.js +97 -0
- package/dist/src/search/embeddings.d.ts +131 -0
- package/dist/src/search/embeddings.js +263 -0
- package/dist/src/search/external.d.ts +13 -0
- package/dist/src/search/external.js +177 -0
- package/dist/src/search/fts-query.d.ts +1 -0
- package/dist/src/search/fts-query.js +64 -0
- package/dist/src/search/provider.d.ts +17 -0
- package/dist/src/search/provider.js +13 -0
- package/dist/src/search/resolve.d.ts +18 -0
- package/dist/src/search/resolve.js +23 -0
- package/dist/src/search/rrf.d.ts +36 -0
- package/dist/src/search/rrf.js +84 -0
- package/dist/src/search/tasks.d.ts +12 -0
- package/dist/src/search/tasks.js +131 -0
- package/dist/src/search/text.d.ts +16 -0
- package/dist/src/search/text.js +21 -0
- package/dist/src/search/vector.d.ts +18 -0
- package/dist/src/search/vector.js +49 -0
- package/dist/src/sync/admin.d.ts +59 -0
- package/dist/src/sync/admin.js +53 -0
- package/dist/src/sync/attach.d.ts +13 -0
- package/dist/src/sync/attach.js +29 -0
- package/dist/src/sync/checkpoint.d.ts +21 -0
- package/dist/src/sync/checkpoint.js +52 -0
- package/dist/src/sync/driver.d.ts +25 -0
- package/dist/src/sync/driver.js +80 -0
- package/dist/src/sync/external-source.d.ts +14 -0
- package/dist/src/sync/external-source.js +137 -0
- package/dist/src/sync/freshness.d.ts +42 -0
- package/dist/src/sync/freshness.js +152 -0
- package/dist/src/sync/fs-util.d.ts +12 -0
- package/dist/src/sync/fs-util.js +55 -0
- package/dist/src/sync/git-heuristics.d.ts +6 -0
- package/dist/src/sync/git-heuristics.js +16 -0
- package/dist/src/sync/observe.d.ts +63 -0
- package/dist/src/sync/observe.js +84 -0
- package/dist/src/sync/plugin.d.ts +54 -0
- package/dist/src/sync/plugin.js +12 -0
- package/dist/src/sync/reconciling-ingest.d.ts +12 -0
- package/dist/src/sync/reconciling-ingest.js +209 -0
- package/dist/src/sync/recovery.d.ts +6 -0
- package/dist/src/sync/recovery.js +34 -0
- package/dist/src/sync/settings.d.ts +18 -0
- package/dist/src/sync/settings.js +58 -0
- package/dist/src/sync/sources.d.ts +37 -0
- package/dist/src/sync/sources.js +75 -0
- package/dist/src/sync/tombstone.d.ts +9 -0
- package/dist/src/sync/tombstone.js +55 -0
- package/dist/src/sync/watch-lease.d.ts +14 -0
- package/dist/src/sync/watch-lease.js +91 -0
- package/dist/src/sync/watcher.d.ts +19 -0
- package/dist/src/sync/watcher.js +34 -0
- package/dist/src/sync/workspace.d.ts +34 -0
- package/dist/src/sync/workspace.js +120 -0
- package/dist/src/sync/writer-lock.d.ts +16 -0
- package/dist/src/sync/writer-lock.js +121 -0
- package/package.json +80 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { extractFromBlock, maskCode, resolveRelativePath } from "./extract.js";
|
|
2
|
+
function canonical(path) {
|
|
3
|
+
return path.replace(/^\/+/, "");
|
|
4
|
+
}
|
|
5
|
+
function dirOf(path) {
|
|
6
|
+
return path.replace(/[^/]*$/, "");
|
|
7
|
+
}
|
|
8
|
+
/** Does a destination written in a doc under `srcDir` resolve to `docPath`? */
|
|
9
|
+
function resolvesTo(dest, srcDir, docPath) {
|
|
10
|
+
if (dest === "" || /^[a-z][a-z0-9+.-]*:/i.test(dest))
|
|
11
|
+
return false;
|
|
12
|
+
return canonical(resolveRelativePath(dest, srcDir)) === docPath;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Every link occurrence in the repo whose destination resolves to `docPath`,
|
|
16
|
+
* found via the open edges that point at `docId`. Block-level edges are
|
|
17
|
+
* re-scanned from the block raw so `target`/`anchor` are as written (and so a
|
|
18
|
+
* self-doc pure-fragment link `#H`, which also has dst_node == docId, is NOT
|
|
19
|
+
* reported — it does not depend on the path). Frontmatter edges are reported
|
|
20
|
+
* with `block: null`, `target: docPath`, and their `field`.
|
|
21
|
+
*/
|
|
22
|
+
export function inboundLinksTo(store, repoId, docId, docPath) {
|
|
23
|
+
const rows = store.db
|
|
24
|
+
.prepare(`SELECT DISTINCT e.src_doc AS srcDoc, d.path AS srcPath, e.src_block AS srcBlock, e.src_field AS srcField
|
|
25
|
+
FROM edges e JOIN docs d ON d.doc_id = e.src_doc
|
|
26
|
+
WHERE e.repo_id = ? AND e.dst_node = ? AND e.to_commit IS NULL AND d.deleted_commit IS NULL
|
|
27
|
+
ORDER BY d.path, e.src_block`)
|
|
28
|
+
.all(repoId, docId);
|
|
29
|
+
const out = [];
|
|
30
|
+
const seenBlocks = new Set();
|
|
31
|
+
for (const r of rows) {
|
|
32
|
+
if (r.srcBlock === null) {
|
|
33
|
+
out.push({ doc: r.srcDoc, path: r.srcPath, block: null, target: docPath, anchor: null, ...(r.srcField ? { field: r.srcField } : {}) });
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
if (seenBlocks.has(r.srcBlock))
|
|
37
|
+
continue;
|
|
38
|
+
seenBlocks.add(r.srcBlock);
|
|
39
|
+
const blk = store.db
|
|
40
|
+
.prepare("SELECT bl.type, b.bytes FROM blocks bl JOIN blobs b ON b.hash = bl.raw_hash WHERE bl.block_id = ? AND bl.deleted_commit IS NULL")
|
|
41
|
+
.get(r.srcBlock);
|
|
42
|
+
if (!blk)
|
|
43
|
+
continue;
|
|
44
|
+
const srcDir = dirOf(r.srcPath);
|
|
45
|
+
for (const e of extractFromBlock(r.srcBlock, blk.type, blk.bytes.toString("utf8"))) {
|
|
46
|
+
if (e.dstKind === "external" || !resolvesTo(e.target, srcDir, docPath))
|
|
47
|
+
continue;
|
|
48
|
+
out.push({
|
|
49
|
+
doc: r.srcDoc,
|
|
50
|
+
path: r.srcPath,
|
|
51
|
+
block: r.srcBlock,
|
|
52
|
+
target: e.target,
|
|
53
|
+
anchor: e.anchor,
|
|
54
|
+
...(e.srcField ? { field: e.srcField } : {}),
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
60
|
+
// Relative path from directory `fromDir` ("a/b/" or "") to file `to`.
|
|
61
|
+
function relativePath(fromDir, to) {
|
|
62
|
+
const from = fromDir.split("/").filter(Boolean);
|
|
63
|
+
const target = to.split("/").filter(Boolean);
|
|
64
|
+
let i = 0;
|
|
65
|
+
while (i < from.length && i < target.length && from[i] === target[i])
|
|
66
|
+
i++;
|
|
67
|
+
const ups = from.length - i;
|
|
68
|
+
const rest = target.slice(i).join("/");
|
|
69
|
+
return ups === 0 ? `./${rest}` : `${"../".repeat(ups)}${rest}`;
|
|
70
|
+
}
|
|
71
|
+
// Rewrite one destination (path + optional fragment) if its path resolves to
|
|
72
|
+
// `fromPath`, keeping the author's style: absolute stays absolute, `./`/`../`
|
|
73
|
+
// stays relative (recomputed from `writeDir`), bare root-relative stays bare.
|
|
74
|
+
function rewriteDest(dest, matchDir, writeDir, fromPath, toPath) {
|
|
75
|
+
const hashIdx = dest.indexOf("#");
|
|
76
|
+
const caretIdx = dest.indexOf("^");
|
|
77
|
+
let cut = dest.length;
|
|
78
|
+
if (caretIdx >= 0 && (hashIdx < 0 || caretIdx < hashIdx))
|
|
79
|
+
cut = caretIdx;
|
|
80
|
+
else if (hashIdx >= 0)
|
|
81
|
+
cut = hashIdx;
|
|
82
|
+
const pathPart = dest.slice(0, cut);
|
|
83
|
+
const fragment = dest.slice(cut);
|
|
84
|
+
if (!resolvesTo(pathPart, matchDir, fromPath))
|
|
85
|
+
return null;
|
|
86
|
+
let newPath;
|
|
87
|
+
if (pathPart.startsWith("/"))
|
|
88
|
+
newPath = "/" + toPath;
|
|
89
|
+
else if (pathPart.startsWith("./") || pathPart.startsWith("../"))
|
|
90
|
+
newPath = relativePath(writeDir, toPath);
|
|
91
|
+
else
|
|
92
|
+
newPath = toPath;
|
|
93
|
+
return newPath + fragment;
|
|
94
|
+
}
|
|
95
|
+
// Destination-bearing syntaxes, with the destination isolated in group 2 so we
|
|
96
|
+
// can splice it in place. Scanned over the code-MASKED raw (positions carry
|
|
97
|
+
// over 1:1 to the original), so links inside code are never touched.
|
|
98
|
+
const MD_LINK_DEST = /(!?\[[^\]]*\]\()([^)\s]+)((?:\s+"[^"]*")?\))/g;
|
|
99
|
+
const WIKILINK_DEST = /(!?\[\[)([^\]]+)(\]\])/g;
|
|
100
|
+
const INLINE_FIELD_PATH = /((?:^|\s)[a-z][a-z0-9_]*::\s*)(\/[^\s]+)/gi;
|
|
101
|
+
/**
|
|
102
|
+
* Rewrite every link destination in `raw` that resolves (relative to `matchDir`,
|
|
103
|
+
* the source doc's directory at extraction time) to `fromPath` so it points at
|
|
104
|
+
* `toPath`, writing relative forms against `writeDir` (the source doc's current
|
|
105
|
+
* directory — differs from `matchDir` only for links inside the moved doc
|
|
106
|
+
* itself). Anchors, link text, titles, and code spans are preserved. Returns
|
|
107
|
+
* null when nothing changed.
|
|
108
|
+
*/
|
|
109
|
+
export function retargetLinksInRaw(raw, matchDir, writeDir, fromPath, toPath) {
|
|
110
|
+
const masked = maskCode(raw);
|
|
111
|
+
const edits = [];
|
|
112
|
+
for (const re of [MD_LINK_DEST, WIKILINK_DEST, INLINE_FIELD_PATH]) {
|
|
113
|
+
for (const m of masked.matchAll(re)) {
|
|
114
|
+
const dest = m[2];
|
|
115
|
+
const replaced = rewriteDest(dest, matchDir, writeDir, fromPath, toPath);
|
|
116
|
+
if (replaced === null)
|
|
117
|
+
continue;
|
|
118
|
+
const start = (m.index ?? 0) + m[1].length;
|
|
119
|
+
edits.push({ start, end: start + dest.length, text: replaced });
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (edits.length === 0)
|
|
123
|
+
return null;
|
|
124
|
+
edits.sort((a, b) => b.start - a.start);
|
|
125
|
+
let out = raw;
|
|
126
|
+
for (const e of edits)
|
|
127
|
+
out = out.slice(0, e.start) + e.text + out.slice(e.end);
|
|
128
|
+
return out === raw ? null : out;
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=inbound-links.js.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** Split an authored destination into its path part and its trailing fragment
|
|
2
|
+
* (`#Heading` / `^ref`, fragment includes the marker). Mirrors extract.ts
|
|
3
|
+
* splitAnchor: a `^` ref wins over a `#` heading when both appear. */
|
|
4
|
+
export declare function splitDestination(dest: string): {
|
|
5
|
+
path: string;
|
|
6
|
+
fragment: string;
|
|
7
|
+
};
|
|
8
|
+
/** Canonical repo-relative path for a link path as authored in a doc living in
|
|
9
|
+
* `docDir` ("" for the root, else "dir/sub/"): `./`/`../` resolve against the
|
|
10
|
+
* doc's directory (mirroring sync/reconciling-ingest resolveRelativePath), and
|
|
11
|
+
* the leading `/` (repo-root anchor) is dropped — this is the path the edge
|
|
12
|
+
* index keys phantoms by. */
|
|
13
|
+
export declare function canonicalLinkPath(path: string, docDir?: string): string;
|
|
14
|
+
/** Directory prefix ("" or "a/b/") of a repo-relative doc path. */
|
|
15
|
+
export declare function docDirOf(docPath: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Rewrite link destinations in a block's raw markdown. `replace(dest)` is called
|
|
18
|
+
* once per link feature found outside inline code; it returns the new
|
|
19
|
+
* destination text, or null to leave that link untouched. Bytes outside link
|
|
20
|
+
* destinations are never changed.
|
|
21
|
+
*/
|
|
22
|
+
export declare function rewriteLinkDestinations(raw: string, replace: (dest: string) => string | null): string;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// Link-destination awareness shared by the stale detector (link-health.ts) and
|
|
2
|
+
// the repair macro (mutate/macros.ts linksRepair). A "destination" is the exact
|
|
3
|
+
// authored target text of a link feature in a block's raw markdown:
|
|
4
|
+
//
|
|
5
|
+
// [text](dest)  Markdown link / image → `dest`
|
|
6
|
+
// [[dest]] [[dest|alias]] wikilink → `dest` (alias kept aside)
|
|
7
|
+
// key:: /dest inline field, bare repo path → `/dest`
|
|
8
|
+
//
|
|
9
|
+
// Inline code spans (`…`) are opaque: a link-shaped string inside backticks is
|
|
10
|
+
// prose about a link, not a link, so scanners skip them. Whole `code_fence`
|
|
11
|
+
// blocks are the caller's job to exclude (they are their own block type).
|
|
12
|
+
//
|
|
13
|
+
// The same regexes the edge extractor (extract.ts) and node projector
|
|
14
|
+
// (format/markdown.ts) use, so what this module rewrites is exactly what the
|
|
15
|
+
// edge index reports as a link.
|
|
16
|
+
/** Split an authored destination into its path part and its trailing fragment
|
|
17
|
+
* (`#Heading` / `^ref`, fragment includes the marker). Mirrors extract.ts
|
|
18
|
+
* splitAnchor: a `^` ref wins over a `#` heading when both appear. */
|
|
19
|
+
export function splitDestination(dest) {
|
|
20
|
+
const caret = dest.indexOf("^");
|
|
21
|
+
if (caret >= 0)
|
|
22
|
+
return { path: dest.slice(0, caret), fragment: dest.slice(caret) };
|
|
23
|
+
const hash = dest.indexOf("#");
|
|
24
|
+
if (hash >= 0)
|
|
25
|
+
return { path: dest.slice(0, hash), fragment: dest.slice(hash) };
|
|
26
|
+
return { path: dest, fragment: "" };
|
|
27
|
+
}
|
|
28
|
+
/** Canonical repo-relative path for a link path as authored in a doc living in
|
|
29
|
+
* `docDir` ("" for the root, else "dir/sub/"): `./`/`../` resolve against the
|
|
30
|
+
* doc's directory (mirroring sync/reconciling-ingest resolveRelativePath), and
|
|
31
|
+
* the leading `/` (repo-root anchor) is dropped — this is the path the edge
|
|
32
|
+
* index keys phantoms by. */
|
|
33
|
+
export function canonicalLinkPath(path, docDir = "") {
|
|
34
|
+
if (path.startsWith("./") || path.startsWith("../")) {
|
|
35
|
+
const out = [];
|
|
36
|
+
for (const p of (docDir + path).split("/")) {
|
|
37
|
+
if (p === "." || p === "")
|
|
38
|
+
continue;
|
|
39
|
+
if (p === "..") {
|
|
40
|
+
out.pop();
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
out.push(p);
|
|
44
|
+
}
|
|
45
|
+
return out.join("/");
|
|
46
|
+
}
|
|
47
|
+
return path.replace(/^\//, "");
|
|
48
|
+
}
|
|
49
|
+
/** Directory prefix ("" or "a/b/") of a repo-relative doc path. */
|
|
50
|
+
export function docDirOf(docPath) {
|
|
51
|
+
const i = docPath.lastIndexOf("/");
|
|
52
|
+
return i < 0 ? "" : docPath.slice(0, i + 1);
|
|
53
|
+
}
|
|
54
|
+
// Link-feature scanners. Each captures (prefix, dest, suffix) so a rewrite can
|
|
55
|
+
// splice a new destination in place and leave everything else byte-identical.
|
|
56
|
+
const MD_LINK = /(!?\[[^\]]*\]\()([^)\s]+)((?:\s+"[^"]*")?\))/g;
|
|
57
|
+
const WIKILINK = /(!?\[\[)([^\]|]+)((?:\|[^\]]*)?\]\])/g;
|
|
58
|
+
const INLINE_FIELD_PATH = /((?:^|\s)[a-z][a-z0-9_]*::[ \t]*)(\/[^\s]+)()/gi;
|
|
59
|
+
// Inline code: a backtick run closed by an identical run (CommonMark code span).
|
|
60
|
+
const CODE_SPAN = /(`+)[^`][\s\S]*?\1/g;
|
|
61
|
+
/**
|
|
62
|
+
* Rewrite link destinations in a block's raw markdown. `replace(dest)` is called
|
|
63
|
+
* once per link feature found outside inline code; it returns the new
|
|
64
|
+
* destination text, or null to leave that link untouched. Bytes outside link
|
|
65
|
+
* destinations are never changed.
|
|
66
|
+
*/
|
|
67
|
+
export function rewriteLinkDestinations(raw, replace) {
|
|
68
|
+
const rewriteSegment = (seg) => {
|
|
69
|
+
const sub = (re) => (s) => s.replace(re, (whole, pre, dest, post) => {
|
|
70
|
+
const next = replace(dest);
|
|
71
|
+
return next === null ? whole : pre + next + post;
|
|
72
|
+
});
|
|
73
|
+
return sub(INLINE_FIELD_PATH)(sub(WIKILINK)(sub(MD_LINK)(seg)));
|
|
74
|
+
};
|
|
75
|
+
let out = "";
|
|
76
|
+
let last = 0;
|
|
77
|
+
for (const m of raw.matchAll(CODE_SPAN)) {
|
|
78
|
+
const start = m.index ?? 0;
|
|
79
|
+
out += rewriteSegment(raw.slice(last, start)) + m[0];
|
|
80
|
+
last = start + m[0].length;
|
|
81
|
+
}
|
|
82
|
+
return out + rewriteSegment(raw.slice(last));
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=link-destinations.js.map
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { Store } from "../core/store/store.js";
|
|
2
|
+
export type StaleReason = "dangling_doc" | "dangling_block" | "broken_anchor";
|
|
3
|
+
export interface StaleLink {
|
|
4
|
+
/** source document id */
|
|
5
|
+
srcDoc: string;
|
|
6
|
+
/** source document repo-relative path */
|
|
7
|
+
srcPath: string;
|
|
8
|
+
/** source block id (null for frontmatter-level edges) */
|
|
9
|
+
srcBlock: string | null;
|
|
10
|
+
predicate: string;
|
|
11
|
+
provenance: string;
|
|
12
|
+
dstKind: string;
|
|
13
|
+
/** canonical target PATH (phantom prefix stripped, no leading `/`), e.g. "guides/old.md" */
|
|
14
|
+
target: string;
|
|
15
|
+
/** the destination exactly as authored in the source block, e.g. "/guides/old.md#Setup"
|
|
16
|
+
* — paste-ready as `links_repair.from`. null when it can't be recovered (frontmatter
|
|
17
|
+
* edges have no block; a projected node no longer matches). */
|
|
18
|
+
authored: string | null;
|
|
19
|
+
anchor: string | null;
|
|
20
|
+
reason: StaleReason;
|
|
21
|
+
}
|
|
22
|
+
/** links_stale summary mode: counts only, no per-row output. */
|
|
23
|
+
export interface LinkHealthSummary {
|
|
24
|
+
/** number of dangling internal links (rows `linksStale` would return, uncapped) */
|
|
25
|
+
staleCount: number;
|
|
26
|
+
/** distinct missing targets, most-referenced first (ties by target) */
|
|
27
|
+
byTarget: {
|
|
28
|
+
target: string;
|
|
29
|
+
count: number;
|
|
30
|
+
}[];
|
|
31
|
+
/** source documents carrying dangling links, most first (ties by path) */
|
|
32
|
+
bySource: {
|
|
33
|
+
srcPath: string;
|
|
34
|
+
count: number;
|
|
35
|
+
}[];
|
|
36
|
+
externalCount: number;
|
|
37
|
+
totalOpenEdges: number;
|
|
38
|
+
}
|
|
39
|
+
export interface LinkHealth {
|
|
40
|
+
/** dangling internal links, ordered by srcPath then target */
|
|
41
|
+
stale: StaleLink[];
|
|
42
|
+
/** open external (http(s)) edges — unverifiable, not counted as stale */
|
|
43
|
+
externalCount: number;
|
|
44
|
+
/** total open edges scanned (after src-doc glob scoping) */
|
|
45
|
+
totalOpenEdges: number;
|
|
46
|
+
/** true when `stale` was capped by `limit` */
|
|
47
|
+
truncated: boolean;
|
|
48
|
+
}
|
|
49
|
+
export interface LinkHealthOptions {
|
|
50
|
+
/** scope the SOURCE docs by a path glob (`journal/*`); `*` maps to SQL `%`. */
|
|
51
|
+
pathGlob?: string;
|
|
52
|
+
/** cap the number of stale links returned (default 500). */
|
|
53
|
+
limit?: number;
|
|
54
|
+
}
|
|
55
|
+
export declare function globClause(column: string, glob: string): {
|
|
56
|
+
clause: string;
|
|
57
|
+
param: string;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* linksStale: scan open edges repo-wide and return the dangling internal ones,
|
|
61
|
+
* plus a count of unverifiable external links. Read-only; pure DB read over the
|
|
62
|
+
* edge index (no FS/network).
|
|
63
|
+
*
|
|
64
|
+
* Dangling detection: an open edge whose `dst_node LIKE 'phantom:%'` points at a
|
|
65
|
+
* path with no live doc. `target` is the path with the `phantom:` prefix
|
|
66
|
+
* stripped so callers see `guides/old.md`, not the internal id.
|
|
67
|
+
*
|
|
68
|
+
* Scoping: `pathGlob` filters the SOURCE docs (joined edges.src_doc → docs).
|
|
69
|
+
* Edges whose src_doc is tombstoned (docs.deleted_commit IS NOT NULL) are
|
|
70
|
+
* skipped — a deleted doc's dangling links are not actionable.
|
|
71
|
+
*/
|
|
72
|
+
export declare function linksStale(store: Store, repoId: string, opts?: LinkHealthOptions): LinkHealth;
|
|
73
|
+
/**
|
|
74
|
+
* linksStaleSummary: the same scan as linksStale, reduced to counts grouped by
|
|
75
|
+
* missing target and by source document — a repo-wide audit in one small call
|
|
76
|
+
* (no per-row output, no limit). Scoping (`pathGlob` over SOURCE docs) and the
|
|
77
|
+
* tombstone rule match linksStale exactly, so the totals agree.
|
|
78
|
+
*/
|
|
79
|
+
export declare function linksStaleSummary(store: Store, repoId: string, opts?: Pick<LinkHealthOptions, "pathGlob">): LinkHealthSummary;
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { canonicalLinkPath, docDirOf, splitDestination } from "./link-destinations.js";
|
|
2
|
+
// Convert a path glob to a SQL LIKE clause + param, mirroring compileWithin
|
|
3
|
+
// (search/cel/compile.ts) and docHistory (graph/history.ts): escape %/_ then
|
|
4
|
+
// map `*`→`%`. A glob without `*` is an exact-path match.
|
|
5
|
+
export function globClause(column, glob) {
|
|
6
|
+
if (glob.includes("*")) {
|
|
7
|
+
const like = glob.replace(/[%_]/g, "\\$&").replace(/\*/g, "%");
|
|
8
|
+
return { clause: `${column} LIKE ? ESCAPE '\\'`, param: like };
|
|
9
|
+
}
|
|
10
|
+
return { clause: `${column} = ?`, param: glob };
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* linksStale: scan open edges repo-wide and return the dangling internal ones,
|
|
14
|
+
* plus a count of unverifiable external links. Read-only; pure DB read over the
|
|
15
|
+
* edge index (no FS/network).
|
|
16
|
+
*
|
|
17
|
+
* Dangling detection: an open edge whose `dst_node LIKE 'phantom:%'` points at a
|
|
18
|
+
* path with no live doc. `target` is the path with the `phantom:` prefix
|
|
19
|
+
* stripped so callers see `guides/old.md`, not the internal id.
|
|
20
|
+
*
|
|
21
|
+
* Scoping: `pathGlob` filters the SOURCE docs (joined edges.src_doc → docs).
|
|
22
|
+
* Edges whose src_doc is tombstoned (docs.deleted_commit IS NOT NULL) are
|
|
23
|
+
* skipped — a deleted doc's dangling links are not actionable.
|
|
24
|
+
*/
|
|
25
|
+
export function linksStale(store, repoId, opts = {}) {
|
|
26
|
+
const limit = opts.limit ?? 500;
|
|
27
|
+
const params = [repoId];
|
|
28
|
+
let globSql = "";
|
|
29
|
+
if (opts.pathGlob) {
|
|
30
|
+
const { clause, param } = globClause("d.path", opts.pathGlob);
|
|
31
|
+
globSql = `AND ${clause}`;
|
|
32
|
+
params.push(param);
|
|
33
|
+
}
|
|
34
|
+
// Total open edges (scoped) and external count in one pass over the join.
|
|
35
|
+
const totals = store.db
|
|
36
|
+
.prepare(`SELECT count(*) AS total,
|
|
37
|
+
sum(CASE WHEN e.dst_kind = 'external' THEN 1 ELSE 0 END) AS external
|
|
38
|
+
FROM edges e
|
|
39
|
+
JOIN docs d ON d.doc_id = e.src_doc
|
|
40
|
+
WHERE e.repo_id = ? AND e.to_commit IS NULL AND d.deleted_commit IS NULL ${globSql}`)
|
|
41
|
+
.get(...params);
|
|
42
|
+
// Dangling internal links: open, source not tombstoned, dst is a phantom.
|
|
43
|
+
const rows = store.db
|
|
44
|
+
.prepare(`SELECT e.src_doc AS srcDoc, d.path AS srcPath, e.src_block AS srcBlock,
|
|
45
|
+
e.predicate AS predicate, e.provenance AS provenance, e.dst_kind AS dstKind,
|
|
46
|
+
e.dst_node AS dstNode, e.anchor AS anchor
|
|
47
|
+
FROM edges e
|
|
48
|
+
JOIN docs d ON d.doc_id = e.src_doc
|
|
49
|
+
WHERE e.repo_id = ? AND e.to_commit IS NULL AND d.deleted_commit IS NULL
|
|
50
|
+
AND e.dst_node LIKE 'phantom:%' ${globSql}
|
|
51
|
+
ORDER BY d.path, e.dst_node, e.src_block
|
|
52
|
+
LIMIT ?`)
|
|
53
|
+
.all(...params, limit + 1);
|
|
54
|
+
const truncated = rows.length > limit;
|
|
55
|
+
const page = rows.slice(0, limit);
|
|
56
|
+
// Recover the destination AS AUTHORED from the block's projected link nodes:
|
|
57
|
+
// the edge index keeps only the canonical target, but md:link / md:wikilink /
|
|
58
|
+
// md:inline_field nodes carry the exact destination text. Pick the node whose
|
|
59
|
+
// canonical (path, fragment) equals this edge's (target, anchor).
|
|
60
|
+
const nodeStmt = store.db.prepare("SELECT kind, value FROM nodes WHERE block_id = ? AND kind IN ('md:link','md:wikilink','md:inline_field') AND value IS NOT NULL");
|
|
61
|
+
const authoredFor = (srcBlock, srcPath, target, anchor) => {
|
|
62
|
+
if (srcBlock === null)
|
|
63
|
+
return null;
|
|
64
|
+
const docDir = docDirOf(srcPath);
|
|
65
|
+
for (const n of nodeStmt.all(srcBlock)) {
|
|
66
|
+
let dest = n.value;
|
|
67
|
+
if (n.kind === "md:inline_field") {
|
|
68
|
+
const wl = /^\[\[([^\]]+)\]\]$/.exec(dest);
|
|
69
|
+
if (wl)
|
|
70
|
+
dest = wl[1];
|
|
71
|
+
else if (!dest.startsWith("/"))
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (n.kind === "md:wikilink")
|
|
75
|
+
dest = dest.split("|")[0];
|
|
76
|
+
const { path, fragment } = splitDestination(dest);
|
|
77
|
+
if (canonicalLinkPath(path, docDir) !== target)
|
|
78
|
+
continue;
|
|
79
|
+
if ((fragment === "" ? null : fragment.slice(1)) !== anchor)
|
|
80
|
+
continue;
|
|
81
|
+
return dest;
|
|
82
|
+
}
|
|
83
|
+
return null;
|
|
84
|
+
};
|
|
85
|
+
const stale = page.map((r) => {
|
|
86
|
+
// Strip the "phantom:" prefix to expose the canonical path.
|
|
87
|
+
const target = r.dstNode.slice("phantom:".length);
|
|
88
|
+
return {
|
|
89
|
+
srcDoc: r.srcDoc,
|
|
90
|
+
srcPath: r.srcPath,
|
|
91
|
+
srcBlock: r.srcBlock,
|
|
92
|
+
predicate: r.predicate,
|
|
93
|
+
provenance: r.provenance,
|
|
94
|
+
dstKind: r.dstKind,
|
|
95
|
+
target,
|
|
96
|
+
authored: authoredFor(r.srcBlock, r.srcPath, target, r.anchor),
|
|
97
|
+
anchor: r.anchor,
|
|
98
|
+
// All phantom targets are dangling DOCUMENTS in this data model (cross-doc
|
|
99
|
+
// block refs collapse to document phantoms carrying an anchor). We tag rows
|
|
100
|
+
// that also carry an anchor as such, but the miss is still a missing doc.
|
|
101
|
+
reason: "dangling_doc",
|
|
102
|
+
};
|
|
103
|
+
});
|
|
104
|
+
return {
|
|
105
|
+
stale,
|
|
106
|
+
externalCount: totals.external ?? 0,
|
|
107
|
+
totalOpenEdges: totals.total,
|
|
108
|
+
truncated,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* linksStaleSummary: the same scan as linksStale, reduced to counts grouped by
|
|
113
|
+
* missing target and by source document — a repo-wide audit in one small call
|
|
114
|
+
* (no per-row output, no limit). Scoping (`pathGlob` over SOURCE docs) and the
|
|
115
|
+
* tombstone rule match linksStale exactly, so the totals agree.
|
|
116
|
+
*/
|
|
117
|
+
export function linksStaleSummary(store, repoId, opts = {}) {
|
|
118
|
+
const params = [repoId];
|
|
119
|
+
let globSql = "";
|
|
120
|
+
if (opts.pathGlob) {
|
|
121
|
+
const { clause, param } = globClause("d.path", opts.pathGlob);
|
|
122
|
+
globSql = `AND ${clause}`;
|
|
123
|
+
params.push(param);
|
|
124
|
+
}
|
|
125
|
+
const base = `FROM edges e JOIN docs d ON d.doc_id = e.src_doc
|
|
126
|
+
WHERE e.repo_id = ? AND e.to_commit IS NULL AND d.deleted_commit IS NULL ${globSql}`;
|
|
127
|
+
const totals = store.db
|
|
128
|
+
.prepare(`SELECT count(*) AS total, sum(CASE WHEN e.dst_kind = 'external' THEN 1 ELSE 0 END) AS external ${base}`)
|
|
129
|
+
.get(...params);
|
|
130
|
+
const phantom = `${base} AND e.dst_node LIKE 'phantom:%'`;
|
|
131
|
+
const byTarget = store.db
|
|
132
|
+
.prepare(`SELECT e.dst_node AS dstNode, count(*) AS count ${phantom} GROUP BY e.dst_node ORDER BY count DESC, e.dst_node`)
|
|
133
|
+
.all(...params)
|
|
134
|
+
.map((r) => ({ target: r.dstNode.slice("phantom:".length), count: r.count }));
|
|
135
|
+
const bySource = store.db
|
|
136
|
+
.prepare(`SELECT d.path AS srcPath, count(*) AS count ${phantom} GROUP BY d.path ORDER BY count DESC, d.path`)
|
|
137
|
+
.all(...params);
|
|
138
|
+
return {
|
|
139
|
+
staleCount: byTarget.reduce((n, t) => n + t.count, 0),
|
|
140
|
+
byTarget,
|
|
141
|
+
bySource,
|
|
142
|
+
externalCount: totals.external ?? 0,
|
|
143
|
+
totalOpenEdges: totals.total,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=link-health.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Store } from "../core/store/store.js";
|
|
2
|
+
export interface LinkEdge {
|
|
3
|
+
predicate: string;
|
|
4
|
+
/** the other endpoint (dst for out-edges, src for in-edges) */
|
|
5
|
+
node: string;
|
|
6
|
+
kind: string;
|
|
7
|
+
/** how many underlying block-grain edges this doc-grain row rolls up */
|
|
8
|
+
count: number;
|
|
9
|
+
/** sample source block ids (out-edges only) */
|
|
10
|
+
samples?: string[];
|
|
11
|
+
}
|
|
12
|
+
export interface LinksResult {
|
|
13
|
+
out: LinkEdge[];
|
|
14
|
+
in: LinkEdge[];
|
|
15
|
+
}
|
|
16
|
+
export interface LinksOptions {
|
|
17
|
+
direction?: "out" | "in" | "both";
|
|
18
|
+
predicates?: string[];
|
|
19
|
+
/** block-grain instead of the doc_edges rollup */
|
|
20
|
+
blocks?: boolean;
|
|
21
|
+
}
|
|
22
|
+
/** Open edges touching a document, grouped by direction (11 §5.4). */
|
|
23
|
+
export declare function docLinks(store: Store, docId: string, opts?: LinksOptions): LinksResult;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/** Open edges touching a document, grouped by direction (11 §5.4). */
|
|
2
|
+
export function docLinks(store, docId, opts = {}) {
|
|
3
|
+
const dir = opts.direction ?? "both";
|
|
4
|
+
const predFilter = opts.predicates && opts.predicates.length > 0 ? opts.predicates : null;
|
|
5
|
+
const inPred = (p) => !predFilter || predFilter.includes(p);
|
|
6
|
+
const out = [];
|
|
7
|
+
const inbound = [];
|
|
8
|
+
if (dir === "out" || dir === "both") {
|
|
9
|
+
if (opts.blocks) {
|
|
10
|
+
const rows = store.db
|
|
11
|
+
.prepare(`SELECT predicate, dst_node, dst_kind FROM edges
|
|
12
|
+
WHERE src_doc = ? AND to_commit IS NULL ORDER BY predicate, dst_node`)
|
|
13
|
+
.all(docId);
|
|
14
|
+
for (const r of rows)
|
|
15
|
+
if (inPred(r.predicate))
|
|
16
|
+
out.push({ predicate: r.predicate, node: r.dst_node, kind: r.dst_kind, count: 1 });
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
const rows = store.db
|
|
20
|
+
.prepare(`SELECT predicate, dst_node, dst_kind, count, samples FROM doc_edges
|
|
21
|
+
WHERE src_doc = ? ORDER BY predicate, dst_node`)
|
|
22
|
+
.all(docId);
|
|
23
|
+
for (const r of rows) {
|
|
24
|
+
if (!inPred(r.predicate))
|
|
25
|
+
continue;
|
|
26
|
+
out.push({ predicate: r.predicate, node: r.dst_node, kind: r.dst_kind, count: r.count, samples: JSON.parse(r.samples) });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (dir === "in" || dir === "both") {
|
|
31
|
+
const rows = store.db
|
|
32
|
+
.prepare(`SELECT predicate, src_doc, count(*) AS cnt FROM edges
|
|
33
|
+
WHERE dst_node = ? AND to_commit IS NULL
|
|
34
|
+
GROUP BY predicate, src_doc ORDER BY predicate, src_doc`)
|
|
35
|
+
.all(docId);
|
|
36
|
+
for (const r of rows)
|
|
37
|
+
if (inPred(r.predicate))
|
|
38
|
+
inbound.push({ predicate: r.predicate, node: r.src_doc, kind: "document", count: r.cnt });
|
|
39
|
+
}
|
|
40
|
+
return { out, in: inbound };
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=links.js.map
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export { VERSION } from "./core/index.js";
|
|
2
|
+
export type { FormatAdapter, AdapterEdge, ProjectedNode, EmbeddingChunk, ReconcileHints } from "./format/adapter.js";
|
|
3
|
+
export { AdapterCapability } from "./format/adapter.js";
|
|
4
|
+
export { registerAdapter, adapterForFormat, adapterForPath, registeredFormats, detectFormat } from "./format/registry.js";
|
|
5
|
+
export { markdownAdapter, MARKDOWN_FORMAT } from "./format/markdown.js";
|
|
6
|
+
export { yamlAdapter, YAML_FORMAT } from "./format/yaml.js";
|
|
7
|
+
export { jsonAdapter, JSON_FORMAT } from "./format/json.js";
|
|
8
|
+
export { writeDocNodes, deleteDocNodes } from "./core/store/nodes.js";
|
|
9
|
+
export { docPropertiesMerged, docPropertiesGrouped, writeDocProperties, flattenFrontmatter } from "./core/store/properties.js";
|
|
10
|
+
import "./format/index.js";
|
|
11
|
+
export { Store, type StoreOptions } from "./core/store/store.js";
|
|
12
|
+
export { Workspace, RepoSelectionError, type RepoRow } from "./sync/workspace.js";
|
|
13
|
+
export { resolveSettings, workspaceSettings, repoOwnSettings, writeWorkspaceSettings, writeRepoSettings, deepMerge, type Settings, } from "./sync/settings.js";
|
|
14
|
+
export { freshnessSweep, rebuildFileStats, recordFileStat, detectDiskDrift, type SweepResult, type DiskDrift } from "./sync/freshness.js";
|
|
15
|
+
export { withWriterLock, writerLockFree, WriterLockTimeout } from "./sync/writer-lock.js";
|
|
16
|
+
export { WatchLease, watchLeaseLive } from "./sync/watch-lease.js";
|
|
17
|
+
export { ingestDirectory, type IngestDirResult } from "./sync/attach.js";
|
|
18
|
+
export { ensureRepo } from "./core/attach.js";
|
|
19
|
+
export { walkMarkdown, walkMarkdownAsync } from "./sync/fs-util.js";
|
|
20
|
+
export { Watcher, type WatcherOptions } from "./sync/watcher.js";
|
|
21
|
+
export type { SyncSource, SourceCapabilities, SourceIdentity, SourceEntry, SourceItem, SourceWatch, WatchListener, } from "./sync/plugin.js";
|
|
22
|
+
export { createExternalSource, type ExternalSourceSpec } from "./sync/external-source.js";
|
|
23
|
+
export { ensureAdapter, listAdapters, createSource, deleteSource, listSources, getSourceByName, attachSourceToRepo, detachSourceFromRepo, sourcesForRepo, renderConfigFlags, type AdapterRow, type SourceRow, } from "./sync/sources.js";
|
|
24
|
+
export { reconcileChanges, attachSource } from "./sync/driver.js";
|
|
25
|
+
export { observeFile, observeMany, observeOne, observeDelete, type ObserveResult, type ObserveOneResult, type ObserveDeleteResult } from "./sync/observe.js";
|
|
26
|
+
export { buildServer, type ServerContext } from "./mcp/server.js";
|
|
27
|
+
export { serveStdio, type ServeStdioHandle } from "./mcp/stdio.js";
|
|
28
|
+
export { processCheckpoint, type CheckpointResult } from "./sync/checkpoint.js";
|
|
29
|
+
export { reposStatus, syncStatus, type RepoStatus, type SyncStatus, type DiskStatus } from "./sync/admin.js";
|
|
30
|
+
export { docsOutline, type OutlineResult, type OutlineOptions } from "./core/read/outline.js";
|
|
31
|
+
export { docsRead, reconstructContent, type DocsReadResult, type DocsReadOptions } from "./core/read/document.js";
|
|
32
|
+
export { nodesGet, nodesGetMany, type GetNode, type Resolution } from "./core/read/nodes.js";
|
|
33
|
+
export { findDoc, loadDocBlocks, blockRaw, docsList, docsTree, normalizeTreePrefix, DOCS_LIST_DEFAULT_LIMIT, DOCS_TREE_DEFAULT_LIMIT, type DocInfo, type BlockNode, type DocListRow, type DocListPage, type DocListOptions, type DocTreeEntry, type DocTreePage, type DocTreeOptions, } from "./core/read/reader.js";
|
|
34
|
+
export { CursorInvalid, encodeCursor, decodeCursor } from "./core/cursor.js";
|
|
35
|
+
export { resolveRef, type ResolvedRef } from "./core/read/refs.js";
|
|
36
|
+
export { resolve, type ResolveHit, type ResolveInput } from "./search/resolve.js";
|
|
37
|
+
export { oqxRun, oqxRunAsync, collectSemanticPhrases, parseOqx, type OqxResult, type OqxHit, type OqxOptions, type EmbedQuery } from "./oqx/run.js";
|
|
38
|
+
export { EmbeddingWorker, SemanticUnavailable, contextPrefix, shouldEmbed, estimateTokens, type EmbeddingProvider, type EmbedTask, type DocEmbedTask, type DocEmbedBlockRef, type DocEmbedMethod, type DocVectorRow, } from "./search/embeddings.js";
|
|
39
|
+
export { buildEmbedTasks, buildDocEmbedTasks } from "./search/tasks.js";
|
|
40
|
+
export { EmbedDrainer, type DrainerOptions } from "./search/drain.js";
|
|
41
|
+
export { embeddingSettings, type EmbeddingSettings } from "./search/provider.js";
|
|
42
|
+
export { createExternalProvider, type ExternalProvider } from "./search/external.js";
|
|
43
|
+
export { hybridSearch, type HybridHit, type HybridInput } from "./search/rrf.js";
|
|
44
|
+
export { vectorSearch, docVectorSearch, type VectorHit, type DocVectorHit } from "./search/vector.js";
|
|
45
|
+
export { historyNode, diffUnified, changesSince, type NodeChange, type CommitDigest } from "./graph/history.js";
|
|
46
|
+
export { docLinks, type LinksResult, type LinkEdge, type LinksOptions } from "./graph/links.js";
|
|
47
|
+
export { FilterInvalid } from "./search/cel/parser.js";
|
|
48
|
+
export { EngineError, type ErrorCode } from "./mcp/errors.js";
|
|
49
|
+
export { MutationError } from "./mutate/tree.js";
|
|
50
|
+
export { isValidId, prefixOf } from "./core/ids.js";
|
|
51
|
+
export { apply, type ApplyRequest, type ApplyResult, type Op } from "./mutate/apply.js";
|
|
52
|
+
export { type DocStore, FsDocStore, NullDocStore, resolveDocStore } from "./mutate/doc-store.js";
|
|
53
|
+
export { type To, type At, type Expect } from "./mutate/ops.js";
|
|
54
|
+
export { tasksComplete, sectionsAppend, sectionsRename, sectionsMove, listsInsertItem, linksRetarget, nodeSet, editablePropsFor, type RetargetHit, } from "./mutate/macros.js";
|
|
55
|
+
export { docsCreate, docsMove, docsDelete, docsSetMeta, type DocOpContext, type DocOpResult, type DocMoveOptions, type DocMoveResult, } from "./mutate/docs.js";
|
|
56
|
+
export { inboundLinksTo, retargetLinksInRaw, type InboundLink } from "./graph/inbound-links.js";
|
|
57
|
+
export { planUpdate, applyOpset, docsUpdate, type PlanUpdateOptions, type ApplyOpsetRequest, type DocsUpdateContext, type DocsUpdateResult, } from "./mutate/plan-update.js";
|
|
58
|
+
export { opsetKernelOps, renderOpsetPlan, serializeOpset, parseOpset, type Opset, type PlanOp, type OpsetSummary, type OpsetPrecondition, type PlanDisposition, } from "./mutate/opset.js";
|
|
59
|
+
export { rebuildIndex, type RebuildTarget } from "./core/store/rebuild.js";
|
|
60
|
+
export { runGc, type GcResult } from "./core/store/gc.js";
|