@bartolli/kmd 0.2.0 → 0.3.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/dist/kmd.mjs +48 -39
- package/dist/kmd.mjs.map +3 -3
- package/package.json +1 -1
package/dist/kmd.mjs
CHANGED
|
@@ -115,7 +115,9 @@ var init_config = __esm({
|
|
|
115
115
|
tags: z.object({
|
|
116
116
|
canonical: z.array(z.string()),
|
|
117
117
|
aliases: z.record(z.string(), z.string())
|
|
118
|
-
})
|
|
118
|
+
}),
|
|
119
|
+
authoring_rules: z.string().optional(),
|
|
120
|
+
sync_protocol: z.string().optional()
|
|
119
121
|
});
|
|
120
122
|
}
|
|
121
123
|
});
|
|
@@ -923,19 +925,11 @@ var init_logger = __esm({
|
|
|
923
925
|
});
|
|
924
926
|
|
|
925
927
|
// ../mcp/src/resources/authoring.ts
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
const start = raw.indexOf("## Authoring rules");
|
|
932
|
-
if (start === -1) return "";
|
|
933
|
-
const after = raw.indexOf("\n## ", start + 1);
|
|
934
|
-
const section = after === -1 ? raw.slice(start) : raw.slice(start, after);
|
|
935
|
-
return section.trim();
|
|
936
|
-
} catch {
|
|
937
|
-
return "";
|
|
938
|
-
}
|
|
928
|
+
function buildAuthoringRules(config) {
|
|
929
|
+
return ["## Authoring rules", "", config.authoring_rules ?? DEFAULT_AUTHORING_RULES].join("\n");
|
|
930
|
+
}
|
|
931
|
+
function buildSyncProtocol(config) {
|
|
932
|
+
return ["## Resync protocol", "", config.sync_protocol ?? DEFAULT_SYNC_PROTOCOL].join("\n");
|
|
939
933
|
}
|
|
940
934
|
function buildKindSelector(kinds) {
|
|
941
935
|
const lines = ["## Kind selector", "", "| Signal | Kind | Where |", "|---|---|---|"];
|
|
@@ -974,16 +968,15 @@ function buildVocabulary(config) {
|
|
|
974
968
|
}
|
|
975
969
|
return lines.join("\n");
|
|
976
970
|
}
|
|
977
|
-
function registerAuthoringResource(mcp,
|
|
971
|
+
function registerAuthoringResource(mcp, _vaultRoot, vaultConfig) {
|
|
978
972
|
mcp.registerResource(
|
|
979
973
|
"Authoring guide",
|
|
980
974
|
"wiki://authoring",
|
|
981
975
|
{
|
|
982
|
-
description: "Wiki authoring pedagogy: kind selector, controlled vocabulary, authoring rules, and template URIs. Read before creating or editing wiki pages.",
|
|
976
|
+
description: "Wiki authoring pedagogy: kind selector, controlled vocabulary, authoring rules, resync protocol, and template URIs. Read before creating or editing wiki pages.",
|
|
983
977
|
mimeType: "text/markdown"
|
|
984
978
|
},
|
|
985
979
|
async (uri) => {
|
|
986
|
-
const rules = await readAuthoringRules(vaultRoot2);
|
|
987
980
|
const sections = [
|
|
988
981
|
"# Wiki authoring guide",
|
|
989
982
|
"",
|
|
@@ -993,11 +986,12 @@ function registerAuthoringResource(mcp, vaultRoot2, vaultConfig) {
|
|
|
993
986
|
"",
|
|
994
987
|
"## Templates",
|
|
995
988
|
"",
|
|
996
|
-
"Full index with URIs and descriptions: `wiki://templates`"
|
|
989
|
+
"Full index with URIs and descriptions: `wiki://templates`",
|
|
990
|
+
"",
|
|
991
|
+
buildAuthoringRules(vaultConfig),
|
|
992
|
+
"",
|
|
993
|
+
buildSyncProtocol(vaultConfig)
|
|
997
994
|
];
|
|
998
|
-
if (rules) {
|
|
999
|
-
sections.push("", rules);
|
|
1000
|
-
}
|
|
1001
995
|
return {
|
|
1002
996
|
contents: [
|
|
1003
997
|
{
|
|
@@ -1010,7 +1004,7 @@ function registerAuthoringResource(mcp, vaultRoot2, vaultConfig) {
|
|
|
1010
1004
|
}
|
|
1011
1005
|
);
|
|
1012
1006
|
}
|
|
1013
|
-
var KIND_PEDAGOGY;
|
|
1007
|
+
var KIND_PEDAGOGY, DEFAULT_AUTHORING_RULES, DEFAULT_SYNC_PROTOCOL;
|
|
1014
1008
|
var init_authoring = __esm({
|
|
1015
1009
|
"../mcp/src/resources/authoring.ts"() {
|
|
1016
1010
|
"use strict";
|
|
@@ -1094,21 +1088,34 @@ var init_authoring = __esm({
|
|
|
1094
1088
|
}
|
|
1095
1089
|
]
|
|
1096
1090
|
]);
|
|
1091
|
+
DEFAULT_AUTHORING_RULES = [
|
|
1092
|
+
"- **Use the matching template** via `wiki://template/{domain}/{kind}` (MCP) or from `templates/` (filesystem). Don't hand-roll frontmatter.",
|
|
1093
|
+
'- **Quote prose-bearing frontmatter scalars.** `summary: "..."` \u2014 unquoted `Word: phrase` patterns break the YAML parser.',
|
|
1094
|
+
"- **On any edit, update the frontmatter `updated` field.**",
|
|
1095
|
+
"- **Folder name = slug prefix in `projects/`.** `spec/spec-x.md`, `adr/adr-y.md`, `plan/plan-z.md`, `ops/ops-w.md`. Stories use `story-` prefix under `plan/{plan-name}/`.",
|
|
1096
|
+
"- **Research is flat.** Articles are `{subject}.md`; sources are `src-{slug}.md`. Avoid generic slugs (`architecture.md`, `notes.md`).",
|
|
1097
|
+
"- **Notes have no `kind` field** \u2014 implied by location. Sync sets `kind: note`.",
|
|
1098
|
+
"- **Reuse existing tags** (visible in `prime` response `top_tags`). No synonyms.",
|
|
1099
|
+
"- **ADR supersession is bidirectional**: `superseded_by` on the old ADR + `supersedes` on the new one.",
|
|
1100
|
+
"- **Sources convention**: external paths/URLs go inline in body text. Vault-internal `raw/` paths go in frontmatter `sources:` array. Don't mix the two surfaces.",
|
|
1101
|
+
"- **Spec / ADR edits land inline with the slice that surfaces them.** Don't queue corrections in plans. The spec must reflect current code at every commit."
|
|
1102
|
+
].join("\n");
|
|
1103
|
+
DEFAULT_SYNC_PROTOCOL = "Edit the smallest set of files that reflects the change. A milestone tick is plan-only; don't cascade to index.md unless phase or status changed. Controlled-vocabulary edits need explicit user approval.";
|
|
1097
1104
|
}
|
|
1098
1105
|
});
|
|
1099
1106
|
|
|
1100
1107
|
// ../mcp/src/resources/templates.ts
|
|
1101
|
-
import { readFile as
|
|
1102
|
-
import { join as
|
|
1108
|
+
import { readFile as readFile4 } from "node:fs/promises";
|
|
1109
|
+
import { join as join5 } from "node:path";
|
|
1103
1110
|
function registerTemplateResources(mcp, vaultRoot2) {
|
|
1104
|
-
const dir =
|
|
1111
|
+
const dir = join5(vaultRoot2, "templates");
|
|
1105
1112
|
for (const tmpl of TEMPLATES) {
|
|
1106
1113
|
mcp.registerResource(
|
|
1107
1114
|
tmpl.name,
|
|
1108
1115
|
tmpl.uri,
|
|
1109
1116
|
{ description: tmpl.description, mimeType: "text/markdown" },
|
|
1110
1117
|
async (uri) => {
|
|
1111
|
-
const text = await
|
|
1118
|
+
const text = await readFile4(join5(dir, tmpl.file), "utf8");
|
|
1112
1119
|
return {
|
|
1113
1120
|
contents: [
|
|
1114
1121
|
{
|
|
@@ -1282,15 +1289,15 @@ var init_toolResponse = __esm({
|
|
|
1282
1289
|
});
|
|
1283
1290
|
|
|
1284
1291
|
// ../mcp/src/tools/prime.ts
|
|
1285
|
-
import { readFile as
|
|
1286
|
-
import { basename as basename2, join as
|
|
1292
|
+
import { readFile as readFile5 } from "node:fs/promises";
|
|
1293
|
+
import { basename as basename2, join as join6 } from "node:path";
|
|
1287
1294
|
import { z as z4 } from "zod";
|
|
1288
1295
|
function pathSlug(p) {
|
|
1289
1296
|
return basename2(p).replace(/\.md$/, "");
|
|
1290
1297
|
}
|
|
1291
1298
|
async function readIndexFm(vaultRoot2, scope) {
|
|
1292
1299
|
try {
|
|
1293
|
-
const raw = await
|
|
1300
|
+
const raw = await readFile5(join6(vaultRoot2, "projects", scope, "index.md"), "utf8");
|
|
1294
1301
|
return parseFrontmatter2(raw).data;
|
|
1295
1302
|
} catch {
|
|
1296
1303
|
return {};
|
|
@@ -1298,7 +1305,7 @@ async function readIndexFm(vaultRoot2, scope) {
|
|
|
1298
1305
|
}
|
|
1299
1306
|
async function readPrimer(vaultRoot2, scope) {
|
|
1300
1307
|
try {
|
|
1301
|
-
const raw = await
|
|
1308
|
+
const raw = await readFile5(join6(vaultRoot2, "projects", scope, "primer.md"), "utf8");
|
|
1302
1309
|
return parseFrontmatter2(raw).content.trim().replace(/^#\s+[^\n]+\n+/, "");
|
|
1303
1310
|
} catch {
|
|
1304
1311
|
return "";
|
|
@@ -1594,15 +1601,15 @@ var init_server = __esm({
|
|
|
1594
1601
|
});
|
|
1595
1602
|
|
|
1596
1603
|
// ../mcp/src/vault-config.ts
|
|
1597
|
-
import { readFile as
|
|
1598
|
-
import { join as
|
|
1604
|
+
import { readFile as readFile6 } from "node:fs/promises";
|
|
1605
|
+
import { join as join7 } from "node:path";
|
|
1599
1606
|
import { parse as parse2 } from "yaml";
|
|
1600
1607
|
import { z as z6 } from "zod";
|
|
1601
1608
|
async function loadVaultConfig2(vaultRoot2) {
|
|
1602
|
-
const path =
|
|
1609
|
+
const path = join7(vaultRoot2, "vault.yaml");
|
|
1603
1610
|
let raw;
|
|
1604
1611
|
try {
|
|
1605
|
-
raw = await
|
|
1612
|
+
raw = await readFile6(path, "utf8");
|
|
1606
1613
|
} catch (err) {
|
|
1607
1614
|
throw new Error(`vault.yaml not found at ${path}`, { cause: err });
|
|
1608
1615
|
}
|
|
@@ -1631,7 +1638,9 @@ var init_vault_config = __esm({
|
|
|
1631
1638
|
tags: z6.object({
|
|
1632
1639
|
canonical: z6.array(z6.string()),
|
|
1633
1640
|
aliases: z6.record(z6.string(), z6.string())
|
|
1634
|
-
})
|
|
1641
|
+
}),
|
|
1642
|
+
authoring_rules: z6.string().optional(),
|
|
1643
|
+
sync_protocol: z6.string().optional()
|
|
1635
1644
|
});
|
|
1636
1645
|
}
|
|
1637
1646
|
});
|
|
@@ -1750,9 +1759,9 @@ async function run() {
|
|
|
1750
1759
|
const sub = positionals[1];
|
|
1751
1760
|
if (sub === "reset") {
|
|
1752
1761
|
const { homedir: homedir4 } = await import("node:os");
|
|
1753
|
-
const { join:
|
|
1762
|
+
const { join: join8 } = await import("node:path");
|
|
1754
1763
|
const { unlinkSync } = await import("node:fs");
|
|
1755
|
-
const dbPath =
|
|
1764
|
+
const dbPath = join8(homedir4(), ".kmd", "db", "index.db");
|
|
1756
1765
|
let deleted = false;
|
|
1757
1766
|
for (const suffix of ["", "-wal", "-shm"]) {
|
|
1758
1767
|
try {
|
|
@@ -1772,10 +1781,10 @@ async function run() {
|
|
|
1772
1781
|
case "--version":
|
|
1773
1782
|
case "-v": {
|
|
1774
1783
|
const { readFileSync } = await import("node:fs");
|
|
1775
|
-
const { join:
|
|
1784
|
+
const { join: join8, dirname } = await import("node:path");
|
|
1776
1785
|
const { fileURLToPath } = await import("node:url");
|
|
1777
1786
|
const pkgDir = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
1778
|
-
const pkg = JSON.parse(readFileSync(
|
|
1787
|
+
const pkg = JSON.parse(readFileSync(join8(pkgDir, "package.json"), "utf8"));
|
|
1779
1788
|
console.log(pkg.version);
|
|
1780
1789
|
break;
|
|
1781
1790
|
}
|
package/dist/kmd.mjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../db/src/database.ts", "../../cli/src/config.ts", "../../cli/src/frontmatter.ts", "../../cli/src/sync.ts", "../../cli/src/validate.ts", "../../cli/src/cli.ts", "../../mcp/src/config.ts", "../../mcp/src/db.ts", "../../mcp/src/lib/diag.ts", "../../mcp/src/lib/logger.ts", "../../mcp/src/resources/authoring.ts", "../../mcp/src/resources/templates.ts", "../../mcp/src/frontmatter.ts", "../../mcp/src/lib/fts.ts", "../../mcp/src/lib/toolResponse.ts", "../../mcp/src/tools/prime.ts", "../../mcp/src/tools/search.ts", "../../mcp/src/server.ts", "../../mcp/src/vault-config.ts", "../../mcp/src/start.ts", "../bin/kmd.ts"],
|
|
4
|
-
"sourcesContent": ["import { DatabaseSync } from 'node:sqlite';\n\nconst SCHEMA = `\nCREATE TABLE IF NOT EXISTS pages (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n path TEXT UNIQUE NOT NULL,\n title TEXT NOT NULL,\n kind TEXT NOT NULL,\n scope TEXT,\n topic TEXT,\n status TEXT NOT NULL DEFAULT 'draft',\n summary TEXT,\n tags TEXT,\n updated TEXT,\n body TEXT,\n content_hash TEXT,\n meta TEXT\n);\n\nCREATE INDEX IF NOT EXISTS pages_scope_kind ON pages(scope, kind, status);\nCREATE INDEX IF NOT EXISTS pages_topic_kind ON pages(topic, kind, status);\n\nCREATE VIRTUAL TABLE IF NOT EXISTS pages_fts USING fts5(\n title, summary, body,\n content='pages',\n content_rowid='id'\n);\n\nCREATE TABLE IF NOT EXISTS links (\n source_path TEXT NOT NULL,\n target_path TEXT NOT NULL,\n link_text TEXT,\n PRIMARY KEY (source_path, target_path)\n);\n\nCREATE INDEX IF NOT EXISTS links_source ON links(source_path);\nCREATE INDEX IF NOT EXISTS links_target ON links(target_path);\n\nCREATE TABLE IF NOT EXISTS events (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n ts TEXT DEFAULT (datetime('now')),\n scope TEXT,\n operation TEXT NOT NULL,\n path TEXT,\n note TEXT\n);\n\nCREATE INDEX IF NOT EXISTS events_scope_ts ON events(scope, ts DESC);\n`;\n\nexport function openDatabase(dbPath: string): DatabaseSync {\n const db = new DatabaseSync(dbPath);\n db.exec('PRAGMA journal_mode = WAL');\n db.exec('PRAGMA foreign_keys = ON');\n db.exec(SCHEMA);\n return db;\n}\n", "import { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { parse } from 'yaml';\nimport { z } from 'zod';\n\nconst ScopeSchema = z.object({\n repo: z.string().optional(),\n methodology: z.enum(['sdd', 'tdd', 'hybrid']).optional(),\n status: z.string()\n});\n\nconst VaultConfigSchema = z.object({\n scopes: z.record(z.string(), ScopeSchema),\n kinds: z.array(z.string()),\n statuses: z.array(z.string()),\n methodologies: z.array(z.string()),\n tags: z.object({\n canonical: z.array(z.string()),\n aliases: z.record(z.string(), z.string())\n })\n});\n\nexport type VaultConfig = z.infer<typeof VaultConfigSchema>;\n\n/**\n * Load and validate `$vaultRoot/vault.yaml` \u2014 the single source of truth for\n * the controlled vocabulary. Throws (fail-loud) when the file is missing or\n * the contents don't satisfy the schema; sync must not run on partial\n * vocabulary.\n */\nexport async function loadVaultConfig(vaultRoot: string): Promise<VaultConfig> {\n const path = join(vaultRoot, 'vault.yaml');\n let raw: string;\n try {\n raw = await readFile(path, 'utf8');\n } catch (err) {\n throw new Error(`vault.yaml not found at ${path}`, { cause: err });\n }\n const parsed = VaultConfigSchema.safeParse(parse(raw));\n if (!parsed.success) {\n const issues = parsed.error.issues\n .map((i) => ` - ${i.path.join('.') || '(root)'}: ${i.message}`)\n .join('\\n');\n throw new Error(`Invalid vault.yaml at ${path}:\\n${issues}`);\n }\n return parsed.data;\n}\n", "import { parse as parseYaml } from 'yaml';\n\nexport interface ParsedFrontmatter {\n data: Record<string, unknown>;\n content: string;\n}\n\n// Leading `---` block, YAML, closing `---`, then one consumed newline. Matches\n// gray-matter's delimiter handling; the closing `---` must be on its own line so\n// `---` rules inside the body are left intact.\nconst FRONTMATTER_RE = /^---\\r?\\n([\\s\\S]*?)\\r?\\n?---\\r?\\n?/;\n\n/**\n * Split a page's frontmatter from its body using the `yaml` parser. Throws\n * (deterministically, no cache) when the frontmatter is not valid YAML \u2014 this is\n * the failure mode `wiki validate` exists to catch. A page with no leading\n * delimiter parses to empty data and the whole input as body.\n */\nexport function parseFrontmatter(raw: string): ParsedFrontmatter {\n const match = FRONTMATTER_RE.exec(raw);\n if (!match) {\n return { data: {}, content: raw };\n }\n const yamlText = match[1] ?? '';\n const content = raw.slice(match[0].length);\n if (yamlText.trim() === '') {\n return { data: {}, content };\n }\n const parsed = parseYaml(yamlText);\n const data =\n parsed !== null && typeof parsed === 'object' ? (parsed as Record<string, unknown>) : {};\n return { data, content };\n}\n", "import { createHash } from 'node:crypto';\nimport { mkdirSync } from 'node:fs';\nimport { readdir, readFile } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { join, relative, sep } from 'node:path';\nimport type { DatabaseSync } from 'node:sqlite';\nimport { openDatabase } from '@llm-wiki/db/database';\nimport { z } from 'zod';\nimport { loadVaultConfig } from './config.js';\nimport { type ParsedFrontmatter, parseFrontmatter } from './frontmatter.js';\n\nconst EnvSchema = z.object({\n WIKI_VAULT: z.string().min(1)\n});\n\n// Scan only the three content domains. raw/, templates/, .obsidian/, .git/\n// are intentionally excluded by the design.\nexport const SCAN_DOMAINS = ['projects', 'research', 'notes'] as const;\n\n// [[target]], [[target|display]], [[target#heading]], [[target^block]]\nconst WIKILINK_RE = /\\[\\[([^\\]|#^]+)(?:[#^][^\\]|]*)?(?:\\|([^\\]]+))?\\]\\]/g;\n\ninterface Frontmatter {\n title?: string;\n kind?: string;\n status?: string;\n summary?: string;\n tags?: string[];\n updated?: string | Date;\n}\n\n// Frontmatter keys that already map to first-class indexed columns. Anything\n// outside this set flows into the `meta` JSONB column verbatim, so future\n// vocabulary extensions (e.g. story.triage_state, story.category) become\n// queryable without further schema changes.\nconst INDEXED_FRONTMATTER_KEYS = new Set<string>([\n 'title',\n 'kind',\n 'status',\n 'summary',\n 'tags',\n 'updated',\n 'scope',\n 'topic'\n]);\n\ninterface WikiLink {\n target: string;\n text: string | null;\n}\n\ninterface PageFields {\n path: string;\n title: string;\n kind: string;\n scope: string | null;\n topic: string | null;\n status: string;\n summary: string | null;\n tags: string[] | null;\n updated: string | null;\n body: string;\n hash: string;\n meta: Record<string, unknown> | null;\n}\n\ntype SyncResult = 'changed' | 'unchanged' | 'skipped';\n\nfunction loadEnv(): { WIKI_VAULT: string } {\n const parsed = EnvSchema.safeParse({\n WIKI_VAULT: process.env.WIKI_VAULT\n });\n if (!parsed.success) {\n console.error('invalid env:');\n console.error(parsed.error.format());\n process.exit(1);\n }\n return parsed.data;\n}\n\nexport async function walkMarkdown(root: string, domain: string): Promise<string[]> {\n const out: string[] = [];\n async function recurse(dir: string): Promise<void> {\n // null when the domain dir doesn't exist yet \u2014 fine, nothing to walk.\n const entries = await readdir(dir, { withFileTypes: true }).catch(() => null);\n if (!entries) return;\n for (const entry of entries) {\n if (entry.name.startsWith('.')) continue;\n if (entry.isDirectory()) {\n await recurse(join(dir, entry.name));\n } else if (entry.isFile() && entry.name.endsWith('.md')) {\n out.push(join(dir, entry.name));\n }\n }\n }\n await recurse(join(root, domain));\n return out;\n}\n\nexport function toRelativePath(root: string, absolute: string): string {\n return relative(root, absolute).split(sep).join('/');\n}\n\nfunction sha256(content: string): string {\n return createHash('sha256').update(content).digest('hex');\n}\n\nexport function extractWikilinks(body: string): WikiLink[] {\n const links: WikiLink[] = [];\n const seen = new Set<string>();\n for (const match of body.matchAll(WIKILINK_RE)) {\n const rawTarget = match[1]?.trim() ?? '';\n if (!rawTarget) continue;\n // Treat any existing extension as authoritative (handles embeds of\n // `.base`, `.png`, `.pdf`, etc.); only append `.md` when the target\n // is bare.\n const hasExt = /\\.[a-zA-Z0-9]+$/.test(rawTarget);\n const target = hasExt ? rawTarget : `${rawTarget}.md`;\n const text = match[2]?.trim() ?? null;\n const key = `${target}|${text ?? ''}`;\n if (seen.has(key)) continue;\n seen.add(key);\n links.push({ target, text });\n }\n return links;\n}\n\n/**\n * Path is authoritative for scope/topic. Frontmatter may also carry these\n * (for human readability) but sync trusts the filesystem.\n *\n * projects/{scope}/... \u2192 scope = first segment\n * research/{topic}/... \u2192 topic = first segment\n * notes/... \u2192 both null\n */\nexport function deriveLocation(relPath: string): { scope: string | null; topic: string | null } {\n const segments = relPath.split('/');\n const domain = segments[0];\n if (domain === 'projects' && segments.length >= 2 && segments[1]) {\n return { scope: segments[1], topic: null };\n }\n if (domain === 'research' && segments.length >= 2 && segments[1]) {\n return { scope: null, topic: segments[1] };\n }\n return { scope: null, topic: null };\n}\n\n/**\n * Build the page row from frontmatter + path. Returns `null` to signal\n * \"skip this file\" (intentionally not indexed).\n *\n * Skip rules:\n * - No `title` in frontmatter \u2192 narrative-only page (e.g., primer.md).\n * - No `kind` AND not under notes/ \u2192 authoring incomplete; warn.\n *\n * Notes are the one place where `kind` is implied by location.\n */\nexport function buildPageFields(\n relPath: string,\n raw: string,\n parsed: ParsedFrontmatter,\n knownScopes: ReadonlySet<string>\n): PageFields | null {\n const fm = parsed.data as Frontmatter;\n if (!fm.title) {\n return null;\n }\n\n let kind = fm.kind;\n if (!kind) {\n if (relPath.startsWith('notes/')) {\n kind = 'note';\n } else {\n console.warn(` skip: ${relPath} \u2014 has title but missing kind`);\n return null;\n }\n }\n\n const { scope, topic } = deriveLocation(relPath);\n if (scope !== null && !knownScopes.has(scope)) {\n throw new Error(\n `unknown scope \"${scope}\" for ${relPath} \u2014 add it to vault.yaml or remove the page`\n );\n }\n const updated =\n fm.updated instanceof Date\n ? fm.updated.toISOString().slice(0, 10)\n : typeof fm.updated === 'string'\n ? fm.updated.slice(0, 10)\n : null;\n\n const metaEntries = Object.entries(parsed.data as Record<string, unknown>).filter(\n ([k]) => !INDEXED_FRONTMATTER_KEYS.has(k)\n );\n const meta = metaEntries.length > 0 ? Object.fromEntries(metaEntries) : null;\n\n return {\n path: relPath,\n title: fm.title,\n kind,\n scope,\n topic,\n status: fm.status ?? (kind === 'note' ? 'active' : 'draft'),\n summary: fm.summary ?? null,\n tags: Array.isArray(fm.tags) ? fm.tags : null,\n updated,\n body: parsed.content,\n hash: sha256(raw),\n meta\n };\n}\n\nexport function syncPage(db: DatabaseSync, fields: PageFields): SyncResult {\n const existing = db.prepare('SELECT content_hash FROM pages WHERE path = ?').get(fields.path) as\n | { content_hash: string | null }\n | undefined;\n if (existing?.content_hash === fields.hash) {\n return 'unchanged';\n }\n\n const upsert = db.prepare(\n `INSERT INTO pages (path, title, kind, scope, topic, status, summary, tags, updated, body, content_hash, meta)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT (path) DO UPDATE SET\n title = EXCLUDED.title,\n kind = EXCLUDED.kind,\n scope = EXCLUDED.scope,\n topic = EXCLUDED.topic,\n status = EXCLUDED.status,\n summary = EXCLUDED.summary,\n tags = EXCLUDED.tags,\n updated = EXCLUDED.updated,\n body = EXCLUDED.body,\n content_hash = EXCLUDED.content_hash,\n meta = EXCLUDED.meta`\n );\n\n upsert.run(\n fields.path,\n fields.title,\n fields.kind,\n fields.scope,\n fields.topic,\n fields.status,\n fields.summary,\n fields.tags ? JSON.stringify(fields.tags) : null,\n fields.updated,\n fields.body,\n fields.hash,\n fields.meta ? JSON.stringify(fields.meta) : null\n );\n\n db.prepare('DELETE FROM links WHERE source_path = ?').run(fields.path);\n const insertLink = db.prepare(\n `INSERT INTO links (source_path, target_path, link_text)\n VALUES (?, ?, ?)\n ON CONFLICT (source_path, target_path) DO NOTHING`\n );\n for (const link of extractWikilinks(fields.body)) {\n insertLink.run(fields.path, link.target, link.text);\n }\n\n return 'changed';\n}\n\nexport async function runSync(): Promise<void> {\n const env = loadEnv();\n const dbDir = join(homedir(), '.kmd', 'db');\n const dbPath = join(dbDir, 'index.db');\n console.log(`sync: ${env.WIKI_VAULT} \u2192 ${dbPath}`);\n\n const vaultConfig = await loadVaultConfig(env.WIKI_VAULT);\n const scopes = new Set(Object.keys(vaultConfig.scopes));\n\n mkdirSync(dbDir, { recursive: true });\n const db = openDatabase(dbPath);\n\n try {\n const files: string[] = [];\n for (const domain of SCAN_DOMAINS) {\n files.push(...(await walkMarkdown(env.WIKI_VAULT, domain)));\n }\n\n const indexedPaths: string[] = [];\n let changed = 0;\n let unchanged = 0;\n let skipped = 0;\n\n for (const file of files) {\n const path = toRelativePath(env.WIKI_VAULT, file);\n const raw = await readFile(file, 'utf8');\n const parsed = parseFrontmatter(raw);\n const fields = buildPageFields(path, raw, parsed, scopes);\n if (!fields) {\n skipped++;\n continue;\n }\n\n const result = syncPage(db, fields);\n if (result === 'changed') {\n changed++;\n } else {\n unchanged++;\n }\n indexedPaths.push(path);\n }\n\n let pagesDeleted = 0;\n let linksDeleted = 0;\n if (indexedPaths.length > 0) {\n const placeholders = indexedPaths.map(() => '?').join(', ');\n const pageResult = db\n .prepare(`DELETE FROM pages WHERE path NOT IN (${placeholders})`)\n .run(...indexedPaths);\n pagesDeleted = Number(pageResult.changes);\n const linkResult = db\n .prepare('DELETE FROM links WHERE source_path NOT IN (SELECT path FROM pages)')\n .run();\n linksDeleted = Number(linkResult.changes);\n } else {\n console.warn('no indexable pages found; skipping orphan deletion (safety)');\n }\n\n db.exec(\"INSERT INTO pages_fts(pages_fts) VALUES('rebuild')\");\n\n console.log(\n `done: ${changed} changed, ${unchanged} unchanged, ${skipped} skipped, ${pagesDeleted} pages deleted, ${linksDeleted} link orphans cleared`\n );\n } finally {\n db.close();\n }\n}\n", "import { readFile } from 'node:fs/promises';\nimport { loadVaultConfig, type VaultConfig } from './config.js';\nimport { parseFrontmatter } from './frontmatter.js';\nimport {\n deriveLocation,\n extractWikilinks,\n SCAN_DOMAINS,\n toRelativePath,\n walkMarkdown\n} from './sync.js';\n\nexport type Severity = 'error' | 'warning';\n\nexport interface Finding {\n path: string;\n rule: string;\n severity: Severity;\n message: string;\n}\n\n/**\n * A page sync would index: it has a `title` and either a `kind` or lives under\n * notes/ (notes imply kind=note). Title-less narrative/reserved pages (primers,\n * the title-less ontology/alayacare pages) are skipped by sync, so every check\n * except frontmatter-parse is gated on this \u2014 validate governs what sync governs.\n */\nfunction isIndexed(relPath: string, data: Record<string, unknown>): boolean {\n if (typeof data.title !== 'string' || data.title.trim() === '') return false;\n if (typeof data.kind === 'string' && data.kind !== '') return true;\n return relPath.startsWith('notes/');\n}\n\n/**\n * A reserved `primer.md` (at any level). Title-less, so it is skipped by the\n * indexed-page checks \u2014 but it is the agent's first-read surface, so a stale\n * `[[link]]` there must not silently pass the gate. Its body links are checked.\n */\nfunction isPrimer(relPath: string): boolean {\n return relPath === 'primer.md' || relPath.endsWith('/primer.md');\n}\n\n// Required-field floor per kind \u2014 the set of keys present on 100% of existing\n// pages of that kind (corpus-scanned; spec-wiki-validate \u00A7 Required fields per\n// kind). Key-presence, not non-emptiness. Kinds absent here (artifact, prompt,\n// glossary-entry, pso-roster) carry no required-field contract. `tags` is\n// governed separately by the `tags-required` rule (non-empty), not this floor.\nconst REQUIRED_FIELDS: Record<string, readonly string[]> = {\n project: [\n 'title',\n 'kind',\n 'scope',\n 'status',\n 'summary',\n 'updated',\n 'methodology',\n 'phase',\n 'repo'\n ],\n spec: ['title', 'kind', 'scope', 'status', 'summary', 'updated', 'sources'],\n adr: ['title', 'kind', 'scope', 'status', 'updated'],\n plan: ['title', 'kind', 'scope', 'status', 'summary', 'updated'],\n ops: ['title', 'kind', 'scope', 'status', 'summary', 'updated'],\n story: [\n 'title',\n 'kind',\n 'scope',\n 'status',\n 'updated',\n 'parent',\n 'triage_state',\n 'category',\n 'blocked_by',\n 'sources'\n ],\n topic: ['title', 'kind', 'status', 'summary', 'updated', 'confidence'],\n article: ['title', 'kind', 'status', 'updated'],\n src: ['title', 'kind', 'topic', 'status', 'summary', 'updated'],\n note: ['title', 'updated']\n};\n\n// Kinds exempt from the tags-required floor: deliverable/package internals\n// (artifact, prompt) and registry stubs (glossary-entry, pso-roster), not\n// discoverable content pages. Mirrors the required-fields floor exemption.\nconst TAG_OPTIONAL_KINDS = new Set(['artifact', 'prompt', 'glossary-entry', 'pso-roster']);\n\n// Per-kind path patterns (spec-wiki-validate \u00A7 Folder and slug patterns). Kinds\n// absent here have no documented pattern and are exempt (article free naming,\n// notes, and the registered-but-undocumented ontology/alayacare kinds).\nconst FOLDER_PATTERNS: Record<string, RegExp> = {\n spec: /^projects\\/[^/]+\\/spec\\/spec-[^/]+\\.md$/,\n adr: /^projects\\/[^/]+\\/adr\\/adr-[^/]+\\.md$/,\n ops: /^projects\\/[^/]+\\/ops\\/ops-[^/]+\\.md$/,\n plan: /^projects\\/[^/]+\\/plan\\/plan-[^/]+\\.md$/,\n story: /^projects\\/[^/]+\\/plan\\/[^/]+\\/story-[^/]+\\.md$/,\n project: /^projects\\/[^/]+\\/index\\.md$/,\n topic: /^research\\/[^/]+\\/index\\.md$/,\n src: /^research\\/[^/]+\\/src-[^/]+\\.md$/\n};\n\nfunction checkRequiredFields(relPath: string, data: Record<string, unknown>): Finding[] {\n // Notes carry no `kind` key \u2014 sync infers `note` from location; mirror that so\n // the note floor is reachable rather than dead.\n const kind =\n typeof data.kind === 'string' && data.kind !== ''\n ? data.kind\n : relPath.startsWith('notes/')\n ? 'note'\n : undefined;\n const required = kind ? REQUIRED_FIELDS[kind] : undefined;\n if (!required) return [];\n const findings: Finding[] = [];\n for (const field of required) {\n if (!Object.hasOwn(data, field)) {\n findings.push({\n path: relPath,\n rule: 'required-fields',\n severity: 'error',\n message: `missing required field \"${field}\" for kind \"${kind}\"`\n });\n }\n }\n return findings;\n}\n\n/**\n * Tags are an open dimension \u2014 any value, no controlled vocabulary \u2014 but every\n * content page must carry at least one. Indexed pages whose kind is not\n * tag-optional require a non-empty `tags` list.\n */\nfunction checkTagsRequired(relPath: string, data: Record<string, unknown>): Finding[] {\n const kind =\n typeof data.kind === 'string' && data.kind !== ''\n ? data.kind\n : relPath.startsWith('notes/')\n ? 'note'\n : undefined;\n if (kind && TAG_OPTIONAL_KINDS.has(kind)) return [];\n if (Array.isArray(data.tags) && data.tags.length > 0) return [];\n return [\n {\n path: relPath,\n rule: 'tags-required',\n severity: 'error',\n message:\n 'tags must be present and non-empty (tags are open \u2014 any values, every content page tagged)'\n }\n ];\n}\n\nfunction checkFolderSlug(relPath: string, data: Record<string, unknown>): Finding[] {\n const kind = data.kind;\n const pattern = typeof kind === 'string' ? FOLDER_PATTERNS[kind] : undefined;\n if (!pattern || pattern.test(relPath)) return [];\n return [\n {\n path: relPath,\n rule: 'folder-slug',\n severity: 'error',\n message: `path does not match the \"${kind}\" slug pattern ${pattern.source}`\n }\n ];\n}\n\nfunction checkVocabulary(\n relPath: string,\n data: Record<string, unknown>,\n cfg: VaultConfig\n): Finding[] {\n const findings: Finding[] = [];\n const kind = data.kind;\n if (typeof kind === 'string' && !cfg.kinds.includes(kind)) {\n findings.push({\n path: relPath,\n rule: 'kind-vocabulary',\n severity: 'error',\n message: `kind \"${kind}\" is not in vault.yaml`\n });\n }\n const status = data.status;\n if (typeof status === 'string' && !cfg.statuses.includes(status)) {\n findings.push({\n path: relPath,\n rule: 'status-vocabulary',\n severity: 'error',\n message: `status \"${status}\" is not in vault.yaml`\n });\n }\n const { scope } = deriveLocation(relPath);\n if (scope !== null && !Object.hasOwn(cfg.scopes, scope)) {\n findings.push({\n path: relPath,\n rule: 'scope-vocabulary',\n severity: 'error',\n message: `scope \"${scope}\" is not in vault.yaml`\n });\n }\n const methodology = data.methodology;\n if (typeof methodology === 'string' && !cfg.methodologies.includes(methodology)) {\n findings.push({\n path: relPath,\n rule: 'methodology-vocabulary',\n severity: 'error',\n message: `methodology \"${methodology}\" is not in vault.yaml`\n });\n }\n return findings;\n}\n\n/**\n * Path is authoritative for `scope`/`topic`: sync derives them from the path and\n * ignores frontmatter. A frontmatter copy is allowed for readability but must not\n * lie \u2014 a mismatch means the label disagrees with where the file actually lives.\n * Fires only where the path defines the value (projects \u2192 scope, research \u2192 topic)\n * and the frontmatter carries it.\n */\nfunction checkScopePath(relPath: string, data: Record<string, unknown>): Finding[] {\n const { scope, topic } = deriveLocation(relPath);\n const findings: Finding[] = [];\n if (\n scope !== null &&\n typeof data.scope === 'string' &&\n data.scope !== '' &&\n data.scope !== scope\n ) {\n findings.push({\n path: relPath,\n rule: 'path-authority',\n severity: 'error',\n message: `frontmatter scope \"${data.scope}\" disagrees with path scope \"${scope}\"`\n });\n }\n if (\n topic !== null &&\n typeof data.topic === 'string' &&\n data.topic !== '' &&\n data.topic !== topic\n ) {\n findings.push({\n path: relPath,\n rule: 'path-authority',\n severity: 'error',\n message: `frontmatter topic \"${data.topic}\" disagrees with path topic \"${topic}\"`\n });\n }\n return findings;\n}\n\n/** A reference's basename target, or null if absent/empty/non-string. */\nfunction refTarget(value: unknown): string | null {\n if (typeof value !== 'string') return null;\n const trimmed = value.trim();\n return trimmed === '' ? null : basename(trimmed);\n}\n\n/**\n * Basename targets of a reference field that may be scalar or array. `supersedes`\n * and `superseded_by` are list-valued in the wild (one ADR can supersede several),\n * so a scalar-only read would miss them and falsely fail reciprocity.\n */\nfunction refTargets(value: unknown): string[] {\n if (Array.isArray(value)) {\n return value.map(refTarget).filter((t): t is string => t !== null);\n }\n const single = refTarget(value);\n return single === null ? [] : [single];\n}\n\n/**\n * Strip code regions so `[[...]]`-shaped syntax inside them is not mistaken for a\n * wikilink: fenced ``` blocks (e.g. a bash `if [[ x == y ]]` test) and inline\n * `code` spans (e.g. a `[[wikilink]]` documentation example). Sync's own link\n * extraction is unaffected \u2014 its pseudo-links are a separate, pre-existing concern.\n */\nfunction stripCode(body: string): string {\n return body.replace(/```[\\s\\S]*?```/g, '').replace(/`[^`]*`/g, '');\n}\n\n/**\n * Body `[[wikilink]]` dangling check against the basename `refIndex`. Code\n * regions are stripped first (see `stripCode`) so `[[...]]`-shaped syntax inside\n * fences/inline-code is not mistaken for a link. Shared by the indexed-page\n * reference checks and the title-less primer carve-in.\n */\nfunction checkBodyLinks(relPath: string, body: string, refIndex: ReadonlySet<string>): Finding[] {\n const findings: Finding[] = [];\n for (const link of extractWikilinks(stripCode(body))) {\n if (!link.target.endsWith('.md')) continue;\n if (!refIndex.has(basename(link.target))) {\n findings.push({\n path: relPath,\n rule: 'dangling-link',\n severity: 'error',\n message: `wikilink target \"${link.target}\" does not resolve`\n });\n }\n }\n return findings;\n}\n\n/**\n * Reference resolution against the basename index: body `[[wikilinks]]` to `.md`\n * targets, plus the frontmatter reference fields. Empty values never fire (the\n * empty `supersedes:`/`superseded_by:` template keys are the 52/57). Non-`.md`\n * wikilink targets (images, `.base`, external) are not policed.\n */\nfunction checkReferences(\n relPath: string,\n data: Record<string, unknown>,\n body: string,\n refIndex: ReadonlySet<string>\n): Finding[] {\n const findings: Finding[] = checkBodyLinks(relPath, body, refIndex);\n const fieldRefs: string[] = [];\n const parent = refTarget(data.parent);\n if (parent !== null) fieldRefs.push(parent);\n for (const field of ['supersedes', 'superseded_by', 'blocked_by'] as const) {\n fieldRefs.push(...refTargets(data[field]));\n }\n for (const target of fieldRefs) {\n if (!refIndex.has(target)) {\n findings.push({\n path: relPath,\n rule: 'ref-resolves',\n severity: 'error',\n message: `frontmatter reference \"${target}\" does not resolve`\n });\n }\n }\n return findings;\n}\n\n/**\n * Tag policy: only the alias case is enforced, as a non-fatal warning. A full\n * canonical-membership check is deferred \u2014 the corpus carries ~211 distinct tags\n * against an 11-entry canonical list, so flagging non-canonical tags would fire\n * on nearly every page (spec-wiki-validate \u00A7 Tag policy).\n */\nfunction checkTags(relPath: string, data: Record<string, unknown>, cfg: VaultConfig): Finding[] {\n if (!Array.isArray(data.tags)) return [];\n const findings: Finding[] = [];\n for (const tag of data.tags) {\n if (typeof tag === 'string' && Object.hasOwn(cfg.tags.aliases, tag)) {\n findings.push({\n path: relPath,\n rule: 'tag-alias',\n severity: 'warning',\n message: `tag \"${tag}\" is an alias; use canonical \"${cfg.tags.aliases[tag]}\"`\n });\n }\n }\n return findings;\n}\n\n/** `status: superseded` requires a non-empty `superseded_by` (README \u00A76). */\nfunction checkSupersededLink(relPath: string, data: Record<string, unknown>): Finding[] {\n if (data.status === 'superseded' && refTargets(data.superseded_by).length === 0) {\n return [\n {\n path: relPath,\n rule: 'superseded-needs-link',\n severity: 'error',\n message: 'status is \"superseded\" but superseded_by is empty'\n }\n ];\n }\n return [];\n}\n\n/** Indexed-page checks on already-parsed frontmatter. Pure. */\nfunction checkIndexedPage(\n relPath: string,\n data: Record<string, unknown>,\n body: string,\n cfg: VaultConfig,\n refIndex: ReadonlySet<string>\n): Finding[] {\n if (!isIndexed(relPath, data)) return [];\n return [\n ...checkRequiredFields(relPath, data),\n ...checkTagsRequired(relPath, data),\n ...checkFolderSlug(relPath, data),\n ...checkVocabulary(relPath, data, cfg),\n ...checkScopePath(relPath, data),\n ...checkReferences(relPath, data, body, refIndex),\n ...checkSupersededLink(relPath, data),\n ...checkTags(relPath, data, cfg)\n ];\n}\n\n/**\n * Deterministic checks on a single page's raw content. Pure \u2014 no IO. Parses the\n * frontmatter first: a parse failure is the live bug that silently halts sync\n * mid-walk, reported regardless of the page's other fields. Well-formed pages\n * are then subjected to the indexed-page checks (vocabulary, \u2026) against the\n * controlled vocabulary `cfg` and the basename `refIndex` of valid link targets.\n */\nexport function validatePage(\n relPath: string,\n raw: string,\n cfg: VaultConfig,\n refIndex: ReadonlySet<string>\n): Finding[] {\n let parsed: ReturnType<typeof parseFrontmatter>;\n try {\n parsed = parseFrontmatter(raw);\n } catch (err) {\n return [\n {\n path: relPath,\n rule: 'frontmatter-parse',\n severity: 'error',\n message: err instanceof Error ? err.message : String(err)\n }\n ];\n }\n if (isPrimer(relPath)) {\n return checkBodyLinks(relPath, parsed.content, refIndex);\n }\n return checkIndexedPage(relPath, parsed.data, parsed.content, cfg, refIndex);\n}\n\n/** Exit-code decision: any error-severity finding fails the run. */\nexport function hasErrors(findings: Finding[]): boolean {\n return findings.some((f) => f.severity === 'error');\n}\n\n/** Basename (no extension) of a vault-relative path. */\nfunction basename(relPath: string): string {\n const last = relPath.split('/').pop() ?? relPath;\n return last.replace(/\\.md$/, '');\n}\n\nexport interface PageData {\n path: string;\n data: Record<string, unknown>;\n}\n\n/**\n * Cross-page ADR supersession reciprocity: a non-empty `superseded_by: B` on\n * ADR A requires `supersedes: A` on B, and vice-versa. Fires only on non-empty\n * values; a value pointing at a non-existent ADR is a `ref-resolves` error\n * (checked per-page), not a reciprocity error, so unresolved targets are skipped\n * here. (spec-wiki-validate \u00A7 Supersession.)\n */\nexport function validateSupersession(pages: PageData[]): Finding[] {\n const adrs = new Map<string, { path: string; supersedes: string[]; supersededBy: string[] }>();\n for (const { path, data } of pages) {\n if (data.kind !== 'adr') continue;\n adrs.set(basename(path), {\n path,\n supersedes: refTargets(data.supersedes),\n supersededBy: refTargets(data.superseded_by)\n });\n }\n const findings: Finding[] = [];\n for (const [name, adr] of adrs) {\n for (const target of adr.supersededBy) {\n const other = adrs.get(target);\n if (other && !other.supersedes.includes(name)) {\n findings.push({\n path: adr.path,\n rule: 'supersession-reciprocal',\n severity: 'error',\n message: `superseded_by \"${target}\" which does not declare supersedes \"${name}\"`\n });\n }\n }\n for (const target of adr.supersedes) {\n const other = adrs.get(target);\n if (other && !other.supersededBy.includes(name)) {\n findings.push({\n path: adr.path,\n rule: 'supersession-reciprocal',\n severity: 'error',\n message: `supersedes \"${target}\" which does not declare superseded_by \"${name}\"`\n });\n }\n }\n }\n return findings;\n}\n\n/** Top-level scope/topic key of a path (`projects/{scope}` or `research/{topic}`), or\n * null for notes/root pages. Two pages \"share a scope\" iff their keys are equal. */\nfunction locationKey(relPath: string): string | null {\n const seg = relPath.split('/');\n if ((seg[0] === 'projects' || seg[0] === 'research') && seg[1]) {\n return `${seg[0]}/${seg[1]}`;\n }\n return null;\n}\n\nexport interface LinkPage {\n path: string;\n body: string;\n}\n\n/**\n * Cross-page ambiguity warning. A **bare** `[[wikilink]]` whose basename is owned by\n * more than one file is ambiguous only when none of those owners shares the linking\n * page's scope: a same-scope copy resolves it locally (the per-scope `spec-context`/\n * `primer`/`index` pattern), and a path-qualified link (`[[a/b/c]]`) is already\n * disambiguated. Warning, not error \u2014 the link resolves, just not uniquely.\n */\nexport function validateAmbiguousLinks(\n pages: LinkPage[],\n basenameToPaths: ReadonlyMap<string, string[]>\n): Finding[] {\n const findings: Finding[] = [];\n for (const { path, body } of pages) {\n const here = locationKey(path);\n for (const link of extractWikilinks(stripCode(body))) {\n if (!link.target.endsWith('.md') || link.target.includes('/')) continue;\n const base = basename(link.target);\n const owners = basenameToPaths.get(base);\n if (!owners || owners.length < 2) continue;\n if (here !== null && owners.some((p) => locationKey(p) === here)) continue;\n findings.push({\n path,\n rule: 'ambiguous-link',\n severity: 'warning',\n message: `bare link \"[[${base}]]\" is ambiguous \u2014 basename owned by ${owners.length} files, none in this scope`\n });\n }\n }\n return findings;\n}\n\n/**\n * Walk the vault's content domains (reusing the sync walker), build the basename\n * index of valid reference targets (all on-disk pages, including title-less ones),\n * then aggregate findings across all pages. No database \u2014 validation is a\n * pre-sync, read-only pass over the filesystem.\n */\nexport async function validateVault(root: string): Promise<Finding[]> {\n const cfg = await loadVaultConfig(root);\n\n // Reference target universe = every on-disk page, including title-less ones and\n // pages outside the scanned domains (raw/, templates/) that are legitimate link\n // targets. Walking from '.' covers the whole vault; dotdirs (.git, .obsidian)\n // are skipped by the walker.\n const all = (await walkMarkdown(root, '.')).map((abs) => ({\n relPath: toRelativePath(root, abs),\n abs\n }));\n // basename \u2192 [paths] (the spec's reference-resolution model). `refIndex` (dangling\n // checks: does the basename exist) is its key set; the multimap also backs the\n // cross-page ambiguity warning (does a basename have more than one owner).\n const basenameToPaths = new Map<string, string[]>();\n for (const f of all) {\n const b = basename(f.relPath);\n const owners = basenameToPaths.get(b);\n if (owners) owners.push(f.relPath);\n else basenameToPaths.set(b, [f.relPath]);\n }\n const refIndex = new Set<string>(basenameToPaths.keys());\n\n // Applicability = only the indexed content domains.\n const files = all.filter((f) => SCAN_DOMAINS.some((d) => f.relPath.startsWith(`${d}/`)));\n\n const findings: Finding[] = [];\n const pages: PageData[] = [];\n const linkPages: LinkPage[] = [];\n for (const { relPath, abs } of files) {\n const raw = await readFile(abs, 'utf8');\n findings.push(...validatePage(relPath, raw, cfg, refIndex));\n try {\n const parsed = parseFrontmatter(raw);\n pages.push({ path: relPath, data: parsed.data });\n linkPages.push({ path: relPath, body: parsed.content });\n } catch {\n // Parse failure already reported by validatePage; skip in the graph pass.\n }\n }\n findings.push(...validateSupersession(pages));\n findings.push(...validateAmbiguousLinks(linkPages, basenameToPaths));\n return findings;\n}\n", "import { parseArgs } from 'node:util';\nimport { runSync } from './sync.js';\nimport { type Finding, hasErrors, validateVault } from './validate.js';\n\nexport type Command = 'sync' | 'validate';\n\nexport type CliResolution = { kind: 'run'; command: Command } | { kind: 'error'; message: string };\n\n/**\n * Resolve a `wiki <command>` invocation to the command to run, or a usage\n * error. Pure \u2014 no side effects \u2014 so the routing is testable without executing\n * the (index-touching) command. `argv` is `process.argv.slice(2)`.\n */\nexport function resolveCli(argv: string[]): CliResolution {\n const { positionals } = parseArgs({ args: argv, allowPositionals: true, strict: false });\n const command = positionals[0];\n if (command === 'sync') {\n return { kind: 'run', command: 'sync' };\n }\n if (command === 'validate') {\n return { kind: 'run', command: 'validate' };\n }\n if (command === undefined) {\n return { kind: 'error', message: 'usage: wiki <sync|validate>' };\n }\n return { kind: 'error', message: `unknown command: ${command}` };\n}\n\nexport function vaultRoot(): string {\n const root = process.env.WIKI_VAULT;\n if (!root) {\n console.error('WIKI_VAULT is not set');\n process.exit(1);\n }\n return root;\n}\n\nfunction reportFindings(findings: Finding[]): void {\n for (const f of findings) {\n console.error(`${f.severity}: ${f.path} [${f.rule}] ${f.message}`);\n }\n}\n\nexport async function runValidate(): Promise<void> {\n const findings = await validateVault(vaultRoot());\n reportFindings(findings);\n console.log(`validate: ${findings.length} finding(s)`);\n process.exit(hasErrors(findings) ? 1 : 0);\n}\n\nexport async function runSyncCommand(): Promise<void> {\n const findings = await validateVault(vaultRoot());\n reportFindings(findings);\n if (hasErrors(findings)) {\n const errors = findings.filter((f) => f.severity === 'error').length;\n console.error(`sync aborted: ${errors} validation error(s); no database writes`);\n process.exit(1);\n }\n await runSync();\n}\n\nexport async function main(): Promise<void> {\n const resolution = resolveCli(process.argv.slice(2));\n if (resolution.kind === 'error') {\n console.error(resolution.message);\n process.exit(1);\n }\n if (resolution.command === 'sync') {\n await runSyncCommand();\n } else {\n await runValidate();\n }\n}\n", "import { z } from 'zod';\n\nconst EnvSchema = z.object({\n WIKI_VAULT: z.string().min(1).describe('Absolute path to the Obsidian vault root'),\n LOG_LEVEL: z\n .enum(['trace', 'debug', 'info', 'warn', 'error', 'fatal', 'silent'])\n .default('info')\n .describe('Pino log level. Logs go to stderr to keep the stdio JSON-RPC stream clean.'),\n SERVER_NAME: z.string().default('wiki-mcp'),\n SERVER_VERSION: z.string().default('0.0.0')\n});\n\nexport interface Config {\n readonly wikiVault: string;\n readonly logLevel: z.infer<typeof EnvSchema>['LOG_LEVEL'];\n readonly serverName: string;\n readonly serverVersion: string;\n}\n\nexport function loadConfig(env: NodeJS.ProcessEnv = process.env): Config {\n const parsed = EnvSchema.safeParse(env);\n if (!parsed.success) {\n const issues = parsed.error.issues\n .map((i) => ` - ${i.path.join('.') || '(root)'}: ${i.message}`)\n .join('\\n');\n throw new Error(`Invalid environment configuration:\\n${issues}`);\n }\n return {\n wikiVault: parsed.data.WIKI_VAULT,\n logLevel: parsed.data.LOG_LEVEL,\n serverName: parsed.data.SERVER_NAME,\n serverVersion: parsed.data.SERVER_VERSION\n };\n}\n", "import { mkdirSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport type { DatabaseSync } from 'node:sqlite';\nimport { openDatabase } from '@llm-wiki/db/database';\n\nexport function createDatabase(): DatabaseSync {\n const dbDir = join(homedir(), '.kmd', 'db');\n const dbPath = join(dbDir, 'index.db');\n mkdirSync(dbDir, { recursive: true });\n return openDatabase(dbPath);\n}\n", "import { appendFileSync, mkdirSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\nconst DIAG_DIR = join(homedir(), '.local', 'state', 'wiki-mcp');\nexport const DIAG_LOG_PATH = join(DIAG_DIR, 'server.log');\n\ntry {\n mkdirSync(DIAG_DIR, { recursive: true });\n} catch {\n // best-effort; do not block startup on log dir creation\n}\n\n/**\n * Synchronous file logger that survives even when pino, the MCP SDK, or any\n * import down the chain fails to load. Writes to ~/.local/state/wiki-mcp/server.log\n * regardless of stdio/stderr capture by the parent process. Use to trace\n * spawn-time failures that never reach pino.\n */\nexport function diag(msg: string, data?: Record<string, unknown>): void {\n try {\n const line = data\n ? `${new Date().toISOString()} pid=${process.pid} ${msg} ${JSON.stringify(data)}\\n`\n : `${new Date().toISOString()} pid=${process.pid} ${msg}\\n`;\n appendFileSync(DIAG_LOG_PATH, line);\n } catch {\n // best-effort; never crash the server on log write failure\n }\n}\n", "import pino from 'pino';\nimport { DIAG_LOG_PATH } from './diag.js';\n\n/**\n * Pino logger that fans out to BOTH stderr (fd 2, captured by Claude Code)\n * AND ~/.local/state/wiki-mcp/server.log (so logs survive when stderr capture\n * doesn't make it into the JSONL connection log). The file destination shares\n * the path with diag.ts so a single `tail -f` follows the entire startup +\n * runtime stream.\n */\nexport function createLogger(level: string, name: string): pino.Logger {\n const streams: pino.StreamEntry[] = [\n { level: level as pino.Level, stream: pino.destination(2) },\n {\n level: level as pino.Level,\n stream: pino.destination({ dest: DIAG_LOG_PATH, sync: false, mkdir: true })\n }\n ];\n return pino({ name, level, base: { pid: process.pid } }, pino.multistream(streams));\n}\n\nexport type Logger = pino.Logger;\n", "import { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { VaultConfig } from '../vault-config.js';\n\ninterface KindPedagogy {\n readonly signal: string;\n readonly where: string;\n}\n\nconst KIND_PEDAGOGY: ReadonlyMap<string, KindPedagogy> = new Map([\n [\n 'project',\n {\n signal: 'Identity card for a project scope',\n where: '`projects/{scope}/index.md`'\n }\n ],\n [\n 'spec',\n {\n signal: 'How a system works (state of world, not decision)',\n where: '`projects/{scope}/spec/spec-{slug}.md`'\n }\n ],\n [\n 'adr',\n {\n signal: 'Decision between alternatives, commits direction',\n where: '`projects/{scope}/adr/adr-{slug}.md`'\n }\n ],\n [\n 'plan',\n {\n signal: 'Phase/initiative with milestones and stories',\n where: '`projects/{scope}/plan/plan-{slug}.md`'\n }\n ],\n [\n 'story',\n {\n signal: 'User story with Gherkin + slices (child of plan)',\n where: '`projects/{scope}/plan/{plan}/story-N-{slug}.md`'\n }\n ],\n [\n 'ops',\n {\n signal: 'Operational runbook, how to run/deploy',\n where: '`projects/{scope}/ops/ops-{slug}.md`'\n }\n ],\n [\n 'topic',\n {\n signal: 'Identity card for a research area',\n where: '`research/{topic}/index.md`'\n }\n ],\n [\n 'article',\n {\n signal: 'Original synthesis about a concept/entity',\n where: '`research/{topic}/{slug}.md`'\n }\n ],\n [\n 'src',\n {\n signal: 'Summary of external source with citation',\n where: '`research/{topic}/src-{slug}.md`'\n }\n ],\n ['note', { signal: 'Low-ceremony capture, sort later', where: '`notes/{slug}.md`' }],\n [\n 'artifact',\n {\n signal: 'Deployable configuration (scope-specific, versioned)',\n where: '`projects/{scope}/ops/{deployment}/{slug}.md`'\n }\n ],\n [\n 'prompt',\n {\n signal: 'LLM prompt template (scope-specific, versioned)',\n where: '`projects/{scope}/ops/{deployment}/prompts/{role}/{slug}.md`'\n }\n ]\n]);\n\nasync function readAuthoringRules(vaultRoot: string): Promise<string> {\n try {\n const raw = await readFile(join(vaultRoot, 'CLAUDE.md'), 'utf8');\n const start = raw.indexOf('## Authoring rules');\n if (start === -1) return '';\n const after = raw.indexOf('\\n## ', start + 1);\n const section = after === -1 ? raw.slice(start) : raw.slice(start, after);\n return section.trim();\n } catch {\n return '';\n }\n}\n\nfunction buildKindSelector(kinds: ReadonlyArray<string>): string {\n const lines: string[] = ['## Kind selector', '', '| Signal | Kind | Where |', '|---|---|---|'];\n for (const kind of kinds) {\n const pedagogy = KIND_PEDAGOGY.get(kind);\n const signal = pedagogy?.signal ?? '\u2014';\n const where = pedagogy?.where ?? '\u2014';\n lines.push(`| ${signal} | **${kind}** | ${where} |`);\n }\n const hasNote = kinds.includes('note');\n const hasAdrAndSpec = kinds.includes('adr') && kinds.includes('spec');\n if (hasNote || hasAdrAndSpec) {\n const hints: string[] = [];\n if (hasNote) hints.push('If none fits \u2192 note.');\n if (hasAdrAndSpec) {\n hints.push(\n 'If torn between adr and spec \u2192 does it record a choice? adr. Does it describe how things work? spec.'\n );\n }\n lines.push('', hints.join(' '));\n }\n return lines.join('\\n');\n}\n\nfunction buildVocabulary(config: VaultConfig): string {\n const lines: string[] = [\n '## Controlled vocabulary',\n '',\n `**Kinds:** ${config.kinds.join(', ')}`,\n `**Statuses:** ${config.statuses.join(' \u2192 ')} (one-directional; superseded requires superseded_by link)`,\n `**Methodologies:** ${config.methodologies.join(', ')}`,\n `**Canonical tags:** ${config.tags.canonical.join(', ')}`\n ];\n const aliases = Object.entries(config.tags.aliases);\n if (aliases.length > 0) {\n lines.push(`**Tag aliases:** ${aliases.map(([a, c]) => `${a} \u2192 ${c}`).join(', ')}`);\n }\n return lines.join('\\n');\n}\n\nexport function registerAuthoringResource(\n mcp: McpServer,\n vaultRoot: string,\n vaultConfig: VaultConfig\n): void {\n mcp.registerResource(\n 'Authoring guide',\n 'wiki://authoring',\n {\n description:\n 'Wiki authoring pedagogy: kind selector, controlled vocabulary, authoring rules, and template URIs. Read before creating or editing wiki pages.',\n mimeType: 'text/markdown'\n },\n async (uri) => {\n const rules = await readAuthoringRules(vaultRoot);\n const sections = [\n '# Wiki authoring guide',\n '',\n buildKindSelector(vaultConfig.kinds),\n '',\n buildVocabulary(vaultConfig),\n '',\n '## Templates',\n '',\n 'Full index with URIs and descriptions: `wiki://templates`'\n ];\n if (rules) {\n sections.push('', rules);\n }\n return {\n contents: [\n {\n uri: uri.toString(),\n mimeType: 'text/markdown' as const,\n text: sections.join('\\n')\n }\n ]\n };\n }\n );\n}\n", "import { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\n\ninterface TemplateSpec {\n /** wiki://template/{domain}/{kind} \u2014 `note` collapses to single segment. */\n readonly uri: string;\n /** Human-readable name shown in resources/list. */\n readonly name: string;\n /** Filename in vault/templates/. */\n readonly file: string;\n /** Description shown in resources/list. */\n readonly description: string;\n}\n\n/**\n * The vault has 11 fixed templates, mirroring the v2 frontmatter schemas\n * (extended with `story` per adr-story-vocabulary-and-triage-fields).\n * URI scheme: `wiki://template/{domain}/{kind}` \u2014 the agent thinks\n * \"I'm authoring a {kind} in the {domain} domain\" and the URI matches\n * that mental model. `note` collapses to a single segment because the\n * notes domain has only one kind.\n */\nexport const TEMPLATES: ReadonlyArray<TemplateSpec> = [\n {\n uri: 'wiki://template/project/index',\n name: 'Project index',\n file: 'project-index.md',\n description:\n 'Identity card for a project. Frontmatter-heavy: methodology, phase, repo, scope, summary, tags. Short body.'\n },\n {\n uri: 'wiki://template/project/primer',\n name: 'Project primer',\n file: 'project-primer.md',\n description:\n 'Human-authored narrative context for a project. Free-form body. Inlined into the prime tool response.'\n },\n {\n uri: 'wiki://template/project/spec',\n name: 'Project spec',\n file: 'project-spec.md',\n description:\n 'Specification page \u2014 how a system or feature works (state of the world, not decision).'\n },\n {\n uri: 'wiki://template/project/adr',\n name: 'Project ADR',\n file: 'project-adr.md',\n description:\n 'Architecture Decision Record \u2014 pinned moment of choice. Sections: Status, Context, Decision, Rationale, Consequences.'\n },\n {\n uri: 'wiki://template/project/plan',\n name: 'Project plan',\n file: 'project-plan.md',\n description:\n 'Plan for a phase or initiative. Sections: Goal, Scope, Milestones, Dependencies, Status Log.'\n },\n {\n uri: 'wiki://template/project/ops',\n name: 'Project ops',\n file: 'project-ops.md',\n description: 'Operational runbook \u2014 how to run or operate a system. Procedural.'\n },\n {\n uri: 'wiki://template/project/story',\n name: 'Project story',\n file: 'project-story.md',\n description:\n 'User story with Gherkin scenarios and inline implementation slices. Lives at plan/{plan-name}/story-N-{slug}.md. Frontmatter carries triage_state, category, blocked_by, parent.'\n },\n {\n uri: 'wiki://template/research/index',\n name: 'Research index',\n file: 'research-index.md',\n description:\n 'Topic identity card for a research area. Frontmatter: confidence, source_count, summary, tags.'\n },\n {\n uri: 'wiki://template/research/article',\n name: 'Research article',\n file: 'research-article.md',\n description:\n 'Wikipedia-style article about a concept, entity, or system. Original synthesis with sources.'\n },\n {\n uri: 'wiki://template/research/src',\n name: 'Research source',\n file: 'research-src.md',\n description:\n 'Summary of an external source (paper, talk, doc) with citation. The only `src-` prefix in research.'\n },\n {\n uri: 'wiki://template/note',\n name: 'Note',\n file: 'note.md',\n description: 'Low-ceremony everyday note. Capture fast, sort later.'\n }\n];\n\n/**\n * Register all template resources with the MCP server. Each template is a\n * fixed URI; `resources/read` re-reads the file on every call, so edits to\n * vault/templates/*.md are picked up without restarting the server.\n */\nexport function registerTemplateResources(mcp: McpServer, vaultRoot: string): void {\n const dir = join(vaultRoot, 'templates');\n for (const tmpl of TEMPLATES) {\n mcp.registerResource(\n tmpl.name,\n tmpl.uri,\n { description: tmpl.description, mimeType: 'text/markdown' },\n async (uri) => {\n const text = await readFile(join(dir, tmpl.file), 'utf8');\n return {\n contents: [\n {\n uri: uri.toString(),\n mimeType: 'text/markdown' as const,\n text\n }\n ]\n };\n }\n );\n }\n\n const indexLines = ['# Wiki Templates', ''];\n for (const tmpl of TEMPLATES) {\n indexLines.push(`- **${tmpl.name}** \u2014 \\`${tmpl.uri}\\` `);\n indexLines.push(` ${tmpl.description}`);\n }\n const indexText = indexLines.join('\\n');\n\n mcp.registerResource(\n 'Template index',\n 'wiki://templates',\n {\n description:\n 'Index of all wiki templates with URIs and descriptions. Read a specific template via its URI.',\n mimeType: 'text/markdown'\n },\n async (uri) => ({\n contents: [{ uri: uri.toString(), mimeType: 'text/markdown' as const, text: indexText }]\n })\n );\n}\n", "import { parse as parseYaml } from 'yaml';\n\n// Verbatim mirror of @llm-wiki/cli's src/frontmatter.ts. Kept byte-identical so\n// mcp parses frontmatter the same way sync/validate do. Collapse into a shared\n// package only when a third separate consumer appears (CLAUDE.md YAGNI rule).\n\nexport interface ParsedFrontmatter {\n data: Record<string, unknown>;\n content: string;\n}\n\n// Leading `---` block, YAML, closing `---`, then one consumed newline. Matches\n// gray-matter's delimiter handling; the closing `---` must be on its own line so\n// `---` rules inside the body are left intact.\nconst FRONTMATTER_RE = /^---\\r?\\n([\\s\\S]*?)\\r?\\n?---\\r?\\n?/;\n\n/**\n * Split a page's frontmatter from its body using the `yaml` parser. Throws\n * (deterministically, no cache) when the frontmatter is not valid YAML. A page\n * with no leading delimiter parses to empty data and the whole input as body.\n */\nexport function parseFrontmatter(raw: string): ParsedFrontmatter {\n const match = FRONTMATTER_RE.exec(raw);\n if (!match) {\n return { data: {}, content: raw };\n }\n const yamlText = match[1] ?? '';\n const content = raw.slice(match[0].length);\n if (yamlText.trim() === '') {\n return { data: {}, content };\n }\n const parsed = parseYaml(yamlText);\n const data =\n parsed !== null && typeof parsed === 'object' ? (parsed as Record<string, unknown>) : {};\n return { data, content };\n}\n", "const FTS5_KEYWORDS = new Set(['AND', 'OR', 'NOT', 'NEAR']);\n\nexport function sanitizeFtsQuery(raw: string): string {\n return raw\n .replace(/[^\\p{L}\\p{N}\\s]/gu, ' ')\n .split(/\\s+/)\n .filter((t) => t.length > 0 && !FTS5_KEYWORDS.has(t))\n .join(' ');\n}\n", "/**\n * MCP CallToolResult helpers. `content[0].text` carries pretty-printed JSON\n * for LLM-facing clients; `structuredContent` carries the same payload as\n * raw JSON for clients that parse directly. Both fields kept in sync so\n * callers never choose one over the other.\n */\n\nexport function textJson(data: object) {\n return {\n content: [{ type: 'text' as const, text: JSON.stringify(data, null, 2) }],\n structuredContent: data as Record<string, unknown>\n };\n}\n\n/**\n * Variant for tools whose model-facing surface is denser as markdown than as\n * pretty-printed JSON (~20% token savings on prose-heavy payloads). The\n * markdown goes to `content[0].text`; `structuredContent` keeps the machine\n * fields so a non-LLM client still gets a parseable shape.\n */\nexport function textWithStruct(markdown: string, data: object) {\n return {\n content: [{ type: 'text' as const, text: markdown }],\n structuredContent: data as Record<string, unknown>\n };\n}\n\nexport interface ToolErrorPayload {\n readonly code: string;\n readonly message: string;\n readonly details?: Record<string, unknown>;\n}\n\nexport function textError(error: ToolErrorPayload) {\n const payload = {\n code: error.code,\n message: error.message,\n details: error.details ?? {}\n };\n return {\n isError: true as const,\n content: [{ type: 'text' as const, text: JSON.stringify(payload) }],\n structuredContent: payload as Record<string, unknown>\n };\n}\n", "import { readFile } from 'node:fs/promises';\nimport { basename, join } from 'node:path';\nimport type { DatabaseSync } from 'node:sqlite';\nimport { z } from 'zod';\nimport { parseFrontmatter } from '../frontmatter.js';\nimport { sanitizeFtsQuery } from '../lib/fts.js';\nimport { textError, textWithStruct } from '../lib/toolResponse.js';\nimport type { VaultConfig } from '../vault-config.js';\n\nexport const PrimeInputSchema = z.object({\n scope: z\n .string()\n .min(1)\n .describe('Project scope to prime (matches projects/{scope}/ in the vault).'),\n task: z\n .string()\n .optional()\n .describe('Optional task description; surfaces top-3 tsvector-ranked relevant pages.')\n});\n\nexport type PrimeInput = z.infer<typeof PrimeInputSchema>;\n\ninterface ProjectIndexFm {\n title?: string;\n methodology?: string;\n phase?: number;\n summary?: string;\n}\n\nexport interface PrimeData {\n scope: string;\n title: string | null;\n methodology: string | null;\n phase: number | null;\n summary: string;\n primer: string;\n counts: Record<string, number>;\n active_adrs: Array<{ path: string; slug: string; title: string; summary: string | null }>;\n current_plan: { path: string; slug: string; title: string } | null;\n top_tags: string[];\n hub_pages: Array<{ path: string; title: string; inbound: number }>;\n recent: Array<{ path: string; operation: string; date: string }>;\n relevant: Array<{ path: string; title: string; score: number }>;\n cross_scope: Array<{ from_scope: string; from_path: string; to_path: string }>;\n}\n\nexport interface PrimeDeps {\n readonly db: DatabaseSync;\n readonly vaultRoot: string;\n readonly vaultConfig: VaultConfig;\n}\n\nfunction pathSlug(p: string): string {\n return basename(p).replace(/\\.md$/, '');\n}\n\nasync function readIndexFm(vaultRoot: string, scope: string): Promise<ProjectIndexFm> {\n try {\n const raw = await readFile(join(vaultRoot, 'projects', scope, 'index.md'), 'utf8');\n return parseFrontmatter(raw).data as ProjectIndexFm;\n } catch {\n return {};\n }\n}\n\nasync function readPrimer(vaultRoot: string, scope: string): Promise<string> {\n try {\n const raw = await readFile(join(vaultRoot, 'projects', scope, 'primer.md'), 'utf8');\n return parseFrontmatter(raw)\n .content.trim()\n .replace(/^#\\s+[^\\n]+\\n+/, '');\n } catch {\n return '';\n }\n}\n\nexport async function prime(\n deps: PrimeDeps,\n input: PrimeInput\n): Promise<{ markdown: string; data: PrimeData }> {\n const { db, vaultRoot, vaultConfig } = deps;\n const { scope, task } = input;\n\n const [fm, primer] = await Promise.all([\n readIndexFm(vaultRoot, scope),\n readPrimer(vaultRoot, scope)\n ]);\n\n const counts = db\n .prepare('SELECT kind, count(*) AS count FROM pages WHERE scope = ? GROUP BY kind')\n .all(scope) as Array<{ kind: string; count: number | bigint }>;\n\n const adrs = db\n .prepare(\n \"SELECT path, title, summary FROM pages WHERE scope = ? AND kind = 'adr' AND status = 'active' ORDER BY updated DESC\"\n )\n .all(scope) as Array<{ path: string; title: string; summary: string | null }>;\n\n const planRow = db\n .prepare(\n \"SELECT path, title FROM pages WHERE scope = ? AND kind = 'plan' AND status = 'active' ORDER BY updated DESC LIMIT 1\"\n )\n .get(scope) as { path: string; title: string } | undefined;\n\n const tags = db\n .prepare(\n `SELECT j.value AS tag, count(*) AS cnt\n FROM pages, json_each(pages.tags) AS j\n WHERE scope = ?\n GROUP BY j.value\n ORDER BY cnt DESC\n LIMIT 10`\n )\n .all(scope) as Array<{ tag: string }>;\n\n const hubs = db\n .prepare(\n `SELECT p.path, p.title, count(*) AS inbound\n FROM links l JOIN pages p ON p.path = l.target_path\n WHERE p.scope = ?\n GROUP BY p.path, p.title\n ORDER BY inbound DESC LIMIT 5`\n )\n .all(scope) as Array<{ path: string; title: string; inbound: number | bigint }>;\n\n const events = db\n .prepare('SELECT path, operation, ts FROM events WHERE scope = ? ORDER BY ts DESC LIMIT 5')\n .all(scope) as Array<{ path: string; operation: string; ts: string }>;\n\n const crossScope = db\n .prepare(\n `SELECT pf.scope AS from_scope, l.source_path AS from_path, l.target_path AS to_path\n FROM links l\n JOIN pages pt ON pt.path = l.target_path\n JOIN pages pf ON pf.path = l.source_path\n WHERE pt.scope = ? AND pf.scope IS NOT NULL AND pf.scope != ?\n LIMIT 10`\n )\n .all(scope, scope) as Array<{ from_scope: string; from_path: string; to_path: string }>;\n\n let relevant: Array<{ path: string; title: string; score: number }> = [];\n if (task) {\n const ftsQuery = sanitizeFtsQuery(task);\n if (ftsQuery) {\n relevant = (\n db\n .prepare(\n `SELECT p.path, p.title, bm25(pages_fts) AS score\n FROM pages_fts\n JOIN pages p ON p.id = pages_fts.rowid\n WHERE pages_fts MATCH ? AND p.scope = ?\n ORDER BY bm25(pages_fts) LIMIT 3`\n )\n .all(ftsQuery, scope) as Array<{ path: string; title: string; score: number }>\n ).map((row) => ({\n path: row.path,\n title: row.title,\n score: row.score\n }));\n }\n }\n\n const countsRecord: Record<string, number> = {};\n for (const row of counts) countsRecord[row.kind] = Number(row.count);\n\n const data: PrimeData = {\n scope,\n title: fm.title ?? null,\n methodology: fm.methodology ?? null,\n phase: typeof fm.phase === 'number' ? fm.phase : null,\n summary: fm.summary ?? '',\n primer,\n counts: countsRecord,\n active_adrs: adrs.map((r) => ({\n path: r.path,\n slug: pathSlug(r.path),\n title: r.title,\n summary: r.summary\n })),\n current_plan: planRow\n ? {\n path: planRow.path,\n slug: pathSlug(planRow.path),\n title: planRow.title\n }\n : null,\n top_tags: tags.map((r) => r.tag),\n hub_pages: hubs.map((r) => ({\n path: r.path,\n title: r.title,\n inbound: Number(r.inbound)\n })),\n recent: events.map((r) => ({\n path: r.path,\n operation: r.operation,\n date: r.ts.slice(0, 10)\n })),\n relevant,\n cross_scope: crossScope.map((r) => ({\n from_scope: r.from_scope,\n from_path: r.from_path,\n to_path: r.to_path\n }))\n };\n\n return { markdown: renderMarkdown(data, vaultConfig, task), data };\n}\n\nexport function renderMarkdown(\n d: PrimeData,\n config: VaultConfig,\n task: string | undefined\n): string {\n const lines: string[] = [];\n\n const phaseLabel =\n d.phase !== null\n ? d.methodology\n ? `Phase ${d.phase} (${d.methodology})`\n : `Phase ${d.phase}`\n : '';\n const header = phaseLabel ? `${d.scope} \u2014 ${phaseLabel}` : d.scope;\n lines.push(`# ${header}`);\n if (d.summary) lines.push(d.summary);\n\n if (d.primer) {\n lines.push('', '## Primer', d.primer);\n }\n\n if (d.active_adrs.length > 0) {\n lines.push('', '## Active Decisions');\n for (const a of d.active_adrs) {\n lines.push(`- ${a.slug}: ${a.summary ?? a.title}`);\n }\n }\n\n if (d.current_plan) {\n lines.push('', '## Current Plan');\n lines.push(`${d.current_plan.slug}: ${d.current_plan.title}`);\n }\n\n const countEntries = Object.entries(d.counts);\n if (countEntries.length > 0) {\n lines.push('', '## Pages');\n lines.push(countEntries.map(([k, n]) => `${k}: ${n}`).join(' | '));\n }\n\n lines.push('', '## Vocabulary');\n lines.push(`kinds: ${config.kinds.join(', ')}`);\n lines.push(`statuses: ${config.statuses.join(', ')}`);\n lines.push(`tags: ${config.tags.canonical.join(', ')}`);\n\n if (d.top_tags.length > 0) {\n lines.push('', '## Tags');\n lines.push(d.top_tags.join(', '));\n }\n\n if (d.hub_pages.length > 0) {\n lines.push('', '## Hubs');\n for (const h of d.hub_pages) {\n lines.push(`- ${pathSlug(h.path)} (${h.inbound} inbound)`);\n }\n }\n\n if (d.recent.length > 0) {\n lines.push('', '## Recent');\n for (const r of d.recent) {\n lines.push(`- [${r.date}] ${pathSlug(r.path)} ${r.operation}`);\n }\n }\n\n if (d.relevant.length > 0) {\n lines.push('', `## Relevant (task: \"${task}\")`);\n for (const r of d.relevant) {\n lines.push(`- ${pathSlug(r.path)} (${r.score.toFixed(2)})`);\n }\n }\n\n if (d.cross_scope.length > 0) {\n lines.push('', '## Cross-scope');\n for (const c of d.cross_scope) {\n lines.push(`- ${c.from_scope}/${pathSlug(c.from_path)} \u2192 ${pathSlug(c.to_path)}`);\n }\n }\n\n lines.push(\n '',\n '---',\n 'Authoring wiki content? Read `wiki://authoring` for kind selector, rules, and templates.'\n );\n\n return lines.join('\\n');\n}\n\nexport async function handlePrime(deps: PrimeDeps, input: PrimeInput) {\n if (!Object.hasOwn(deps.vaultConfig.scopes, input.scope)) {\n const valid = Object.keys(deps.vaultConfig.scopes).sort().join(', ');\n return textError({\n code: 'UNKNOWN_SCOPE',\n message: `unknown scope \"${input.scope}\"; valid scopes: ${valid}`\n });\n }\n try {\n const { markdown, data } = await prime(deps, input);\n return textWithStruct(markdown, data as unknown as Record<string, unknown>);\n } catch (err) {\n return textError({\n code: 'PRIME_FAILED',\n message: err instanceof Error ? err.message : String(err)\n });\n }\n}\n", "import type { DatabaseSync } from 'node:sqlite';\nimport { z } from 'zod';\nimport { sanitizeFtsQuery } from '../lib/fts.js';\nimport { textError, textJson } from '../lib/toolResponse.js';\n\nexport const SearchInputSchema = z.object({\n query: z\n .string()\n .min(1)\n .describe(\n 'Natural-language search query. Matched against title, summary, and body via SQLite FTS5.'\n ),\n scope: z\n .string()\n .optional()\n .describe('Optional: restrict to a project scope (e.g. \"ontology\", \"sotto\").'),\n kind: z\n .string()\n .optional()\n .describe(\n 'Optional: restrict to a kind. Project kinds: spec, adr, plan, ops. Research kinds: article, src. Misc: note.'\n ),\n limit: z\n .number()\n .int()\n .min(1)\n .max(50)\n .default(5)\n .describe('Maximum number of ranked results to return. Default 5.')\n});\n\nexport type SearchInput = z.infer<typeof SearchInputSchema>;\n\nexport interface SearchResult {\n readonly path: string;\n readonly title: string;\n readonly kind: string;\n readonly summary: string | null;\n readonly score: number;\n readonly scope?: string | null;\n}\n\nexport interface SearchDeps {\n readonly db: DatabaseSync;\n}\n\nexport function search(deps: SearchDeps, input: SearchInput): { results: SearchResult[] } {\n const ftsQuery = sanitizeFtsQuery(input.query);\n if (!ftsQuery) return { results: [] };\n\n let sql = `SELECT p.path, p.title, p.kind, p.summary, p.scope, bm25(pages_fts) AS score\n FROM pages_fts\n JOIN pages p ON p.id = pages_fts.rowid\n WHERE pages_fts MATCH ?`;\n const params: Array<string | number> = [ftsQuery];\n\n if (input.scope) {\n sql += ' AND p.scope = ?';\n params.push(input.scope);\n }\n if (input.kind) {\n sql += ' AND p.kind = ?';\n params.push(input.kind);\n }\n sql += ' ORDER BY bm25(pages_fts) LIMIT ?';\n params.push(input.limit);\n\n const rows = deps.db.prepare(sql).all(...params) as Array<{\n path: string;\n title: string;\n kind: string;\n summary: string | null;\n scope: string | null;\n score: number;\n }>;\n\n return {\n results: rows.map((r) => ({\n path: r.path,\n title: r.title,\n kind: r.kind,\n summary: r.summary,\n scope: r.scope,\n score: r.score\n }))\n };\n}\n\nexport function handleSearch(deps: SearchDeps, input: SearchInput) {\n try {\n return textJson(search(deps, input));\n } catch (err) {\n return textError({\n code: 'SEARCH_FAILED',\n message: err instanceof Error ? err.message : String(err)\n });\n }\n}\n", "import type { DatabaseSync } from 'node:sqlite';\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { Logger } from './lib/logger.js';\nimport { registerAuthoringResource } from './resources/authoring.js';\nimport { registerTemplateResources } from './resources/templates.js';\nimport { handlePrime, PrimeInputSchema } from './tools/prime.js';\nimport { handleSearch, SearchInputSchema } from './tools/search.js';\nimport type { VaultConfig } from './vault-config.js';\n\nexport interface BuildServerArgs {\n readonly name: string;\n readonly version: string;\n readonly vaultRoot: string;\n readonly db: DatabaseSync;\n readonly logger: Logger;\n readonly vaultConfig: VaultConfig;\n}\n\nexport function buildServer(args: BuildServerArgs): McpServer {\n const { name, version, vaultRoot, db, logger, vaultConfig } = args;\n\n const mcp = new McpServer({ name, version }, { capabilities: { tools: {}, resources: {} } });\n\n mcp.tool(\n 'prime',\n 'Orient on a project. Returns a markdown briefing with: identity (scope, phase, methodology, summary), the human-authored primer.md inlined, active ADRs, current plan, page counts, top tags, hub pages (most-linked-to), recent events, cross-scope references, and \u2014 when `task` is provided \u2014 the top 3 tsvector-ranked relevant pages. Call once at session start. Empty sections are omitted to keep the surface lean.',\n PrimeInputSchema.shape,\n async (input) => {\n logger.debug({ tool: 'prime', input }, 'tool call');\n return handlePrime({ db, vaultRoot, vaultConfig }, input);\n }\n );\n\n mcp.tool(\n 'search',\n 'Full-text search across wiki pages via SQLite FTS5. Returns ranked candidates {path, title, kind, summary, score} \u2014 never page bodies. The agent reads the returned paths directly from the filesystem.',\n SearchInputSchema.shape,\n async (input) => {\n logger.debug({ tool: 'search', input }, 'tool call');\n return handleSearch({ db }, input);\n }\n );\n\n registerTemplateResources(mcp, vaultRoot);\n registerAuthoringResource(mcp, vaultRoot, vaultConfig);\n\n return mcp;\n}\n", "import { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { parse } from 'yaml';\nimport { z } from 'zod';\n\n// Verbatim mirror of @llm-wiki/cli's src/config.ts \u2014 the single definition of a\n// valid vault.yaml. Kept byte-identical (schema + error strings) so mcp and\n// sync/validate never disagree on what is valid. Collapse both into a shared\n// package only when a third separate consumer appears (CLAUDE.md YAGNI rule).\n\nconst ScopeSchema = z.object({\n repo: z.string().optional(),\n methodology: z.enum(['sdd', 'tdd', 'hybrid']).optional(),\n status: z.string()\n});\n\nconst VaultConfigSchema = z.object({\n scopes: z.record(z.string(), ScopeSchema),\n kinds: z.array(z.string()),\n statuses: z.array(z.string()),\n methodologies: z.array(z.string()),\n tags: z.object({\n canonical: z.array(z.string()),\n aliases: z.record(z.string(), z.string())\n })\n});\n\nexport type VaultConfig = z.infer<typeof VaultConfigSchema>;\n\n/**\n * Load and validate `$vaultRoot/vault.yaml` \u2014 the single source of truth for\n * the controlled vocabulary. Throws (fail-loud) when the file is missing or\n * the contents don't satisfy the schema; the server must not start on partial\n * vocabulary.\n */\nexport async function loadVaultConfig(vaultRoot: string): Promise<VaultConfig> {\n const path = join(vaultRoot, 'vault.yaml');\n let raw: string;\n try {\n raw = await readFile(path, 'utf8');\n } catch (err) {\n throw new Error(`vault.yaml not found at ${path}`, { cause: err });\n }\n const parsed = VaultConfigSchema.safeParse(parse(raw));\n if (!parsed.success) {\n const issues = parsed.error.issues\n .map((i) => ` - ${i.path.join('.') || '(root)'}: ${i.message}`)\n .join('\\n');\n throw new Error(`Invalid vault.yaml at ${path}:\\n${issues}`);\n }\n return parsed.data;\n}\n", "import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { loadConfig } from './config.js';\nimport { createDatabase } from './db.js';\nimport { diag } from './lib/diag.js';\nimport { createLogger } from './lib/logger.js';\nimport { buildServer } from './server.js';\nimport { loadVaultConfig } from './vault-config.js';\n\nexport async function startMcpServer(): Promise<void> {\n diag('main entered');\n\n const config = loadConfig();\n diag('config loaded', { vault: config.wikiVault, level: config.logLevel });\n\n const vaultConfig = await loadVaultConfig(config.wikiVault);\n diag('vault config loaded', {\n scopes: Object.keys(vaultConfig.scopes).length,\n kinds: vaultConfig.kinds.length,\n statuses: vaultConfig.statuses.length\n });\n\n const logger = createLogger(config.logLevel, config.serverName);\n logger.info(\n { vault: config.wikiVault, serverName: config.serverName, serverVersion: config.serverVersion },\n 'starting wiki-mcp on stdio'\n );\n\n const db = createDatabase();\n diag('database opened');\n\n const mcp = buildServer({\n name: config.serverName,\n version: config.serverVersion,\n vaultRoot: config.wikiVault,\n db,\n logger,\n vaultConfig\n });\n diag('server built');\n\n const shutdown = async (signal: NodeJS.Signals) => {\n logger.info({ signal }, 'shutting down');\n diag('shutting down', { signal });\n try {\n await mcp.close();\n db.close();\n } catch (err) {\n logger.error({ err }, 'error during shutdown');\n }\n process.exit(0);\n };\n process.once('SIGINT', (s) => void shutdown(s));\n process.once('SIGTERM', (s) => void shutdown(s));\n\n const transport = new StdioServerTransport();\n await mcp.connect(transport);\n logger.info('wiki-mcp ready');\n diag('ready and connected to transport');\n}\n", "#!/usr/bin/env node\nimport { parseArgs } from 'node:util';\n\nconst USAGE = `usage: kmd <command> [options]\n\ncommands:\n sync vault \u2192 index sync (runs validate first)\n validate [<path>] deterministic vault checker (default: $WIKI_VAULT)\n mcp [<vault-root>] start the stdio MCP server (default: $WIKI_VAULT)\n db reset delete and recreate the index\n\noptions:\n --version print version\n --help show this help`;\n\nconst { positionals, values } = parseArgs({\n args: process.argv.slice(2),\n allowPositionals: true,\n strict: false,\n options: {\n version: { type: 'boolean', short: 'v' },\n help: { type: 'boolean', short: 'h' }\n }\n});\n\nconst command = values.version ? '--version' : values.help ? '--help' : positionals[0];\n\nfunction applyVaultRoot(positionalIndex: number): void {\n const arg = positionals[positionalIndex];\n if (arg) {\n process.env.WIKI_VAULT = arg;\n }\n}\n\nasync function run(): Promise<void> {\n switch (command) {\n case 'sync': {\n const { runSyncCommand } = await import('@llm-wiki/cli/cli');\n await runSyncCommand();\n break;\n }\n case 'validate': {\n applyVaultRoot(1);\n const { runValidate } = await import('@llm-wiki/cli/cli');\n await runValidate();\n break;\n }\n case 'mcp': {\n applyVaultRoot(1);\n const { startMcpServer } = await import('@llm-wiki/mcp/start');\n await startMcpServer();\n break;\n }\n case 'db': {\n const sub = positionals[1];\n if (sub === 'reset') {\n const { homedir } = await import('node:os');\n const { join } = await import('node:path');\n const { unlinkSync } = await import('node:fs');\n const dbPath = join(homedir(), '.kmd', 'db', 'index.db');\n let deleted = false;\n for (const suffix of ['', '-wal', '-shm']) {\n try {\n unlinkSync(dbPath + suffix);\n deleted = true;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') throw err;\n }\n }\n console.log(deleted ? `deleted ${dbPath}` : `${dbPath} does not exist \u2014 nothing to reset`);\n } else {\n console.error(sub ? `unknown db subcommand: ${sub}` : 'usage: kmd db reset');\n process.exit(2);\n }\n break;\n }\n case '--version':\n case '-v': {\n const { readFileSync } = await import('node:fs');\n const { join, dirname } = await import('node:path');\n const { fileURLToPath } = await import('node:url');\n const pkgDir = dirname(dirname(fileURLToPath(import.meta.url)));\n const pkg = JSON.parse(readFileSync(join(pkgDir, 'package.json'), 'utf8')) as {\n version: string;\n };\n console.log(pkg.version);\n break;\n }\n case '--help':\n case '-h':\n case undefined: {\n console.log(USAGE);\n if (command === undefined) process.exit(2);\n break;\n }\n default: {\n console.error(`unknown command: ${command}\\n\\n${USAGE}`);\n process.exit(2);\n }\n }\n}\n\nrun().catch((err) => {\n console.error('kmd failed:', err instanceof Error ? (err.stack ?? err.message) : err);\n process.exit(1);\n});\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["vaultRoot", "readFile", "join", "z", "readFile", "positionals", "command", "z", "EnvSchema", "init_config", "mkdirSync", "homedir", "join", "mkdirSync", "homedir", "join", "readFile", "join", "vaultRoot", "
|
|
4
|
+
"sourcesContent": ["import { DatabaseSync } from 'node:sqlite';\n\nconst SCHEMA = `\nCREATE TABLE IF NOT EXISTS pages (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n path TEXT UNIQUE NOT NULL,\n title TEXT NOT NULL,\n kind TEXT NOT NULL,\n scope TEXT,\n topic TEXT,\n status TEXT NOT NULL DEFAULT 'draft',\n summary TEXT,\n tags TEXT,\n updated TEXT,\n body TEXT,\n content_hash TEXT,\n meta TEXT\n);\n\nCREATE INDEX IF NOT EXISTS pages_scope_kind ON pages(scope, kind, status);\nCREATE INDEX IF NOT EXISTS pages_topic_kind ON pages(topic, kind, status);\n\nCREATE VIRTUAL TABLE IF NOT EXISTS pages_fts USING fts5(\n title, summary, body,\n content='pages',\n content_rowid='id'\n);\n\nCREATE TABLE IF NOT EXISTS links (\n source_path TEXT NOT NULL,\n target_path TEXT NOT NULL,\n link_text TEXT,\n PRIMARY KEY (source_path, target_path)\n);\n\nCREATE INDEX IF NOT EXISTS links_source ON links(source_path);\nCREATE INDEX IF NOT EXISTS links_target ON links(target_path);\n\nCREATE TABLE IF NOT EXISTS events (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n ts TEXT DEFAULT (datetime('now')),\n scope TEXT,\n operation TEXT NOT NULL,\n path TEXT,\n note TEXT\n);\n\nCREATE INDEX IF NOT EXISTS events_scope_ts ON events(scope, ts DESC);\n`;\n\nexport function openDatabase(dbPath: string): DatabaseSync {\n const db = new DatabaseSync(dbPath);\n db.exec('PRAGMA journal_mode = WAL');\n db.exec('PRAGMA foreign_keys = ON');\n db.exec(SCHEMA);\n return db;\n}\n", "import { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { parse } from 'yaml';\nimport { z } from 'zod';\n\nconst ScopeSchema = z.object({\n repo: z.string().optional(),\n methodology: z.enum(['sdd', 'tdd', 'hybrid']).optional(),\n status: z.string()\n});\n\nconst VaultConfigSchema = z.object({\n scopes: z.record(z.string(), ScopeSchema),\n kinds: z.array(z.string()),\n statuses: z.array(z.string()),\n methodologies: z.array(z.string()),\n tags: z.object({\n canonical: z.array(z.string()),\n aliases: z.record(z.string(), z.string())\n }),\n authoring_rules: z.string().optional(),\n sync_protocol: z.string().optional()\n});\n\nexport type VaultConfig = z.infer<typeof VaultConfigSchema>;\n\n/**\n * Load and validate `$vaultRoot/vault.yaml` \u2014 the single source of truth for\n * the controlled vocabulary. Throws (fail-loud) when the file is missing or\n * the contents don't satisfy the schema; sync must not run on partial\n * vocabulary.\n */\nexport async function loadVaultConfig(vaultRoot: string): Promise<VaultConfig> {\n const path = join(vaultRoot, 'vault.yaml');\n let raw: string;\n try {\n raw = await readFile(path, 'utf8');\n } catch (err) {\n throw new Error(`vault.yaml not found at ${path}`, { cause: err });\n }\n const parsed = VaultConfigSchema.safeParse(parse(raw));\n if (!parsed.success) {\n const issues = parsed.error.issues\n .map((i) => ` - ${i.path.join('.') || '(root)'}: ${i.message}`)\n .join('\\n');\n throw new Error(`Invalid vault.yaml at ${path}:\\n${issues}`);\n }\n return parsed.data;\n}\n", "import { parse as parseYaml } from 'yaml';\n\nexport interface ParsedFrontmatter {\n data: Record<string, unknown>;\n content: string;\n}\n\n// Leading `---` block, YAML, closing `---`, then one consumed newline. Matches\n// gray-matter's delimiter handling; the closing `---` must be on its own line so\n// `---` rules inside the body are left intact.\nconst FRONTMATTER_RE = /^---\\r?\\n([\\s\\S]*?)\\r?\\n?---\\r?\\n?/;\n\n/**\n * Split a page's frontmatter from its body using the `yaml` parser. Throws\n * (deterministically, no cache) when the frontmatter is not valid YAML \u2014 this is\n * the failure mode `wiki validate` exists to catch. A page with no leading\n * delimiter parses to empty data and the whole input as body.\n */\nexport function parseFrontmatter(raw: string): ParsedFrontmatter {\n const match = FRONTMATTER_RE.exec(raw);\n if (!match) {\n return { data: {}, content: raw };\n }\n const yamlText = match[1] ?? '';\n const content = raw.slice(match[0].length);\n if (yamlText.trim() === '') {\n return { data: {}, content };\n }\n const parsed = parseYaml(yamlText);\n const data =\n parsed !== null && typeof parsed === 'object' ? (parsed as Record<string, unknown>) : {};\n return { data, content };\n}\n", "import { createHash } from 'node:crypto';\nimport { mkdirSync } from 'node:fs';\nimport { readdir, readFile } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { join, relative, sep } from 'node:path';\nimport type { DatabaseSync } from 'node:sqlite';\nimport { openDatabase } from '@llm-wiki/db/database';\nimport { z } from 'zod';\nimport { loadVaultConfig } from './config.js';\nimport { type ParsedFrontmatter, parseFrontmatter } from './frontmatter.js';\n\nconst EnvSchema = z.object({\n WIKI_VAULT: z.string().min(1)\n});\n\n// Scan only the three content domains. raw/, templates/, .obsidian/, .git/\n// are intentionally excluded by the design.\nexport const SCAN_DOMAINS = ['projects', 'research', 'notes'] as const;\n\n// [[target]], [[target|display]], [[target#heading]], [[target^block]]\nconst WIKILINK_RE = /\\[\\[([^\\]|#^]+)(?:[#^][^\\]|]*)?(?:\\|([^\\]]+))?\\]\\]/g;\n\ninterface Frontmatter {\n title?: string;\n kind?: string;\n status?: string;\n summary?: string;\n tags?: string[];\n updated?: string | Date;\n}\n\n// Frontmatter keys that already map to first-class indexed columns. Anything\n// outside this set flows into the `meta` JSONB column verbatim, so future\n// vocabulary extensions (e.g. story.triage_state, story.category) become\n// queryable without further schema changes.\nconst INDEXED_FRONTMATTER_KEYS = new Set<string>([\n 'title',\n 'kind',\n 'status',\n 'summary',\n 'tags',\n 'updated',\n 'scope',\n 'topic'\n]);\n\ninterface WikiLink {\n target: string;\n text: string | null;\n}\n\ninterface PageFields {\n path: string;\n title: string;\n kind: string;\n scope: string | null;\n topic: string | null;\n status: string;\n summary: string | null;\n tags: string[] | null;\n updated: string | null;\n body: string;\n hash: string;\n meta: Record<string, unknown> | null;\n}\n\ntype SyncResult = 'changed' | 'unchanged' | 'skipped';\n\nfunction loadEnv(): { WIKI_VAULT: string } {\n const parsed = EnvSchema.safeParse({\n WIKI_VAULT: process.env.WIKI_VAULT\n });\n if (!parsed.success) {\n console.error('invalid env:');\n console.error(parsed.error.format());\n process.exit(1);\n }\n return parsed.data;\n}\n\nexport async function walkMarkdown(root: string, domain: string): Promise<string[]> {\n const out: string[] = [];\n async function recurse(dir: string): Promise<void> {\n // null when the domain dir doesn't exist yet \u2014 fine, nothing to walk.\n const entries = await readdir(dir, { withFileTypes: true }).catch(() => null);\n if (!entries) return;\n for (const entry of entries) {\n if (entry.name.startsWith('.')) continue;\n if (entry.isDirectory()) {\n await recurse(join(dir, entry.name));\n } else if (entry.isFile() && entry.name.endsWith('.md')) {\n out.push(join(dir, entry.name));\n }\n }\n }\n await recurse(join(root, domain));\n return out;\n}\n\nexport function toRelativePath(root: string, absolute: string): string {\n return relative(root, absolute).split(sep).join('/');\n}\n\nfunction sha256(content: string): string {\n return createHash('sha256').update(content).digest('hex');\n}\n\nexport function extractWikilinks(body: string): WikiLink[] {\n const links: WikiLink[] = [];\n const seen = new Set<string>();\n for (const match of body.matchAll(WIKILINK_RE)) {\n const rawTarget = match[1]?.trim() ?? '';\n if (!rawTarget) continue;\n // Treat any existing extension as authoritative (handles embeds of\n // `.base`, `.png`, `.pdf`, etc.); only append `.md` when the target\n // is bare.\n const hasExt = /\\.[a-zA-Z0-9]+$/.test(rawTarget);\n const target = hasExt ? rawTarget : `${rawTarget}.md`;\n const text = match[2]?.trim() ?? null;\n const key = `${target}|${text ?? ''}`;\n if (seen.has(key)) continue;\n seen.add(key);\n links.push({ target, text });\n }\n return links;\n}\n\n/**\n * Path is authoritative for scope/topic. Frontmatter may also carry these\n * (for human readability) but sync trusts the filesystem.\n *\n * projects/{scope}/... \u2192 scope = first segment\n * research/{topic}/... \u2192 topic = first segment\n * notes/... \u2192 both null\n */\nexport function deriveLocation(relPath: string): { scope: string | null; topic: string | null } {\n const segments = relPath.split('/');\n const domain = segments[0];\n if (domain === 'projects' && segments.length >= 2 && segments[1]) {\n return { scope: segments[1], topic: null };\n }\n if (domain === 'research' && segments.length >= 2 && segments[1]) {\n return { scope: null, topic: segments[1] };\n }\n return { scope: null, topic: null };\n}\n\n/**\n * Build the page row from frontmatter + path. Returns `null` to signal\n * \"skip this file\" (intentionally not indexed).\n *\n * Skip rules:\n * - No `title` in frontmatter \u2192 narrative-only page (e.g., primer.md).\n * - No `kind` AND not under notes/ \u2192 authoring incomplete; warn.\n *\n * Notes are the one place where `kind` is implied by location.\n */\nexport function buildPageFields(\n relPath: string,\n raw: string,\n parsed: ParsedFrontmatter,\n knownScopes: ReadonlySet<string>\n): PageFields | null {\n const fm = parsed.data as Frontmatter;\n if (!fm.title) {\n return null;\n }\n\n let kind = fm.kind;\n if (!kind) {\n if (relPath.startsWith('notes/')) {\n kind = 'note';\n } else {\n console.warn(` skip: ${relPath} \u2014 has title but missing kind`);\n return null;\n }\n }\n\n const { scope, topic } = deriveLocation(relPath);\n if (scope !== null && !knownScopes.has(scope)) {\n throw new Error(\n `unknown scope \"${scope}\" for ${relPath} \u2014 add it to vault.yaml or remove the page`\n );\n }\n const updated =\n fm.updated instanceof Date\n ? fm.updated.toISOString().slice(0, 10)\n : typeof fm.updated === 'string'\n ? fm.updated.slice(0, 10)\n : null;\n\n const metaEntries = Object.entries(parsed.data as Record<string, unknown>).filter(\n ([k]) => !INDEXED_FRONTMATTER_KEYS.has(k)\n );\n const meta = metaEntries.length > 0 ? Object.fromEntries(metaEntries) : null;\n\n return {\n path: relPath,\n title: fm.title,\n kind,\n scope,\n topic,\n status: fm.status ?? (kind === 'note' ? 'active' : 'draft'),\n summary: fm.summary ?? null,\n tags: Array.isArray(fm.tags) ? fm.tags : null,\n updated,\n body: parsed.content,\n hash: sha256(raw),\n meta\n };\n}\n\nexport function syncPage(db: DatabaseSync, fields: PageFields): SyncResult {\n const existing = db.prepare('SELECT content_hash FROM pages WHERE path = ?').get(fields.path) as\n | { content_hash: string | null }\n | undefined;\n if (existing?.content_hash === fields.hash) {\n return 'unchanged';\n }\n\n const upsert = db.prepare(\n `INSERT INTO pages (path, title, kind, scope, topic, status, summary, tags, updated, body, content_hash, meta)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT (path) DO UPDATE SET\n title = EXCLUDED.title,\n kind = EXCLUDED.kind,\n scope = EXCLUDED.scope,\n topic = EXCLUDED.topic,\n status = EXCLUDED.status,\n summary = EXCLUDED.summary,\n tags = EXCLUDED.tags,\n updated = EXCLUDED.updated,\n body = EXCLUDED.body,\n content_hash = EXCLUDED.content_hash,\n meta = EXCLUDED.meta`\n );\n\n upsert.run(\n fields.path,\n fields.title,\n fields.kind,\n fields.scope,\n fields.topic,\n fields.status,\n fields.summary,\n fields.tags ? JSON.stringify(fields.tags) : null,\n fields.updated,\n fields.body,\n fields.hash,\n fields.meta ? JSON.stringify(fields.meta) : null\n );\n\n db.prepare('DELETE FROM links WHERE source_path = ?').run(fields.path);\n const insertLink = db.prepare(\n `INSERT INTO links (source_path, target_path, link_text)\n VALUES (?, ?, ?)\n ON CONFLICT (source_path, target_path) DO NOTHING`\n );\n for (const link of extractWikilinks(fields.body)) {\n insertLink.run(fields.path, link.target, link.text);\n }\n\n return 'changed';\n}\n\nexport async function runSync(): Promise<void> {\n const env = loadEnv();\n const dbDir = join(homedir(), '.kmd', 'db');\n const dbPath = join(dbDir, 'index.db');\n console.log(`sync: ${env.WIKI_VAULT} \u2192 ${dbPath}`);\n\n const vaultConfig = await loadVaultConfig(env.WIKI_VAULT);\n const scopes = new Set(Object.keys(vaultConfig.scopes));\n\n mkdirSync(dbDir, { recursive: true });\n const db = openDatabase(dbPath);\n\n try {\n const files: string[] = [];\n for (const domain of SCAN_DOMAINS) {\n files.push(...(await walkMarkdown(env.WIKI_VAULT, domain)));\n }\n\n const indexedPaths: string[] = [];\n let changed = 0;\n let unchanged = 0;\n let skipped = 0;\n\n for (const file of files) {\n const path = toRelativePath(env.WIKI_VAULT, file);\n const raw = await readFile(file, 'utf8');\n const parsed = parseFrontmatter(raw);\n const fields = buildPageFields(path, raw, parsed, scopes);\n if (!fields) {\n skipped++;\n continue;\n }\n\n const result = syncPage(db, fields);\n if (result === 'changed') {\n changed++;\n } else {\n unchanged++;\n }\n indexedPaths.push(path);\n }\n\n let pagesDeleted = 0;\n let linksDeleted = 0;\n if (indexedPaths.length > 0) {\n const placeholders = indexedPaths.map(() => '?').join(', ');\n const pageResult = db\n .prepare(`DELETE FROM pages WHERE path NOT IN (${placeholders})`)\n .run(...indexedPaths);\n pagesDeleted = Number(pageResult.changes);\n const linkResult = db\n .prepare('DELETE FROM links WHERE source_path NOT IN (SELECT path FROM pages)')\n .run();\n linksDeleted = Number(linkResult.changes);\n } else {\n console.warn('no indexable pages found; skipping orphan deletion (safety)');\n }\n\n db.exec(\"INSERT INTO pages_fts(pages_fts) VALUES('rebuild')\");\n\n console.log(\n `done: ${changed} changed, ${unchanged} unchanged, ${skipped} skipped, ${pagesDeleted} pages deleted, ${linksDeleted} link orphans cleared`\n );\n } finally {\n db.close();\n }\n}\n", "import { readFile } from 'node:fs/promises';\nimport { loadVaultConfig, type VaultConfig } from './config.js';\nimport { parseFrontmatter } from './frontmatter.js';\nimport {\n deriveLocation,\n extractWikilinks,\n SCAN_DOMAINS,\n toRelativePath,\n walkMarkdown\n} from './sync.js';\n\nexport type Severity = 'error' | 'warning';\n\nexport interface Finding {\n path: string;\n rule: string;\n severity: Severity;\n message: string;\n}\n\n/**\n * A page sync would index: it has a `title` and either a `kind` or lives under\n * notes/ (notes imply kind=note). Title-less narrative/reserved pages (primers,\n * the title-less ontology/alayacare pages) are skipped by sync, so every check\n * except frontmatter-parse is gated on this \u2014 validate governs what sync governs.\n */\nfunction isIndexed(relPath: string, data: Record<string, unknown>): boolean {\n if (typeof data.title !== 'string' || data.title.trim() === '') return false;\n if (typeof data.kind === 'string' && data.kind !== '') return true;\n return relPath.startsWith('notes/');\n}\n\n/**\n * A reserved `primer.md` (at any level). Title-less, so it is skipped by the\n * indexed-page checks \u2014 but it is the agent's first-read surface, so a stale\n * `[[link]]` there must not silently pass the gate. Its body links are checked.\n */\nfunction isPrimer(relPath: string): boolean {\n return relPath === 'primer.md' || relPath.endsWith('/primer.md');\n}\n\n// Required-field floor per kind \u2014 the set of keys present on 100% of existing\n// pages of that kind (corpus-scanned; spec-wiki-validate \u00A7 Required fields per\n// kind). Key-presence, not non-emptiness. Kinds absent here (artifact, prompt,\n// glossary-entry, pso-roster) carry no required-field contract. `tags` is\n// governed separately by the `tags-required` rule (non-empty), not this floor.\nconst REQUIRED_FIELDS: Record<string, readonly string[]> = {\n project: [\n 'title',\n 'kind',\n 'scope',\n 'status',\n 'summary',\n 'updated',\n 'methodology',\n 'phase',\n 'repo'\n ],\n spec: ['title', 'kind', 'scope', 'status', 'summary', 'updated', 'sources'],\n adr: ['title', 'kind', 'scope', 'status', 'updated'],\n plan: ['title', 'kind', 'scope', 'status', 'summary', 'updated'],\n ops: ['title', 'kind', 'scope', 'status', 'summary', 'updated'],\n story: [\n 'title',\n 'kind',\n 'scope',\n 'status',\n 'updated',\n 'parent',\n 'triage_state',\n 'category',\n 'blocked_by',\n 'sources'\n ],\n topic: ['title', 'kind', 'status', 'summary', 'updated', 'confidence'],\n article: ['title', 'kind', 'status', 'updated'],\n src: ['title', 'kind', 'topic', 'status', 'summary', 'updated'],\n note: ['title', 'updated']\n};\n\n// Kinds exempt from the tags-required floor: deliverable/package internals\n// (artifact, prompt) and registry stubs (glossary-entry, pso-roster), not\n// discoverable content pages. Mirrors the required-fields floor exemption.\nconst TAG_OPTIONAL_KINDS = new Set(['artifact', 'prompt', 'glossary-entry', 'pso-roster']);\n\n// Per-kind path patterns (spec-wiki-validate \u00A7 Folder and slug patterns). Kinds\n// absent here have no documented pattern and are exempt (article free naming,\n// notes, and the registered-but-undocumented ontology/alayacare kinds).\nconst FOLDER_PATTERNS: Record<string, RegExp> = {\n spec: /^projects\\/[^/]+\\/spec\\/spec-[^/]+\\.md$/,\n adr: /^projects\\/[^/]+\\/adr\\/adr-[^/]+\\.md$/,\n ops: /^projects\\/[^/]+\\/ops\\/ops-[^/]+\\.md$/,\n plan: /^projects\\/[^/]+\\/plan\\/plan-[^/]+\\.md$/,\n story: /^projects\\/[^/]+\\/plan\\/[^/]+\\/story-[^/]+\\.md$/,\n project: /^projects\\/[^/]+\\/index\\.md$/,\n topic: /^research\\/[^/]+\\/index\\.md$/,\n src: /^research\\/[^/]+\\/src-[^/]+\\.md$/\n};\n\nfunction checkRequiredFields(relPath: string, data: Record<string, unknown>): Finding[] {\n // Notes carry no `kind` key \u2014 sync infers `note` from location; mirror that so\n // the note floor is reachable rather than dead.\n const kind =\n typeof data.kind === 'string' && data.kind !== ''\n ? data.kind\n : relPath.startsWith('notes/')\n ? 'note'\n : undefined;\n const required = kind ? REQUIRED_FIELDS[kind] : undefined;\n if (!required) return [];\n const findings: Finding[] = [];\n for (const field of required) {\n if (!Object.hasOwn(data, field)) {\n findings.push({\n path: relPath,\n rule: 'required-fields',\n severity: 'error',\n message: `missing required field \"${field}\" for kind \"${kind}\"`\n });\n }\n }\n return findings;\n}\n\n/**\n * Tags are an open dimension \u2014 any value, no controlled vocabulary \u2014 but every\n * content page must carry at least one. Indexed pages whose kind is not\n * tag-optional require a non-empty `tags` list.\n */\nfunction checkTagsRequired(relPath: string, data: Record<string, unknown>): Finding[] {\n const kind =\n typeof data.kind === 'string' && data.kind !== ''\n ? data.kind\n : relPath.startsWith('notes/')\n ? 'note'\n : undefined;\n if (kind && TAG_OPTIONAL_KINDS.has(kind)) return [];\n if (Array.isArray(data.tags) && data.tags.length > 0) return [];\n return [\n {\n path: relPath,\n rule: 'tags-required',\n severity: 'error',\n message:\n 'tags must be present and non-empty (tags are open \u2014 any values, every content page tagged)'\n }\n ];\n}\n\nfunction checkFolderSlug(relPath: string, data: Record<string, unknown>): Finding[] {\n const kind = data.kind;\n const pattern = typeof kind === 'string' ? FOLDER_PATTERNS[kind] : undefined;\n if (!pattern || pattern.test(relPath)) return [];\n return [\n {\n path: relPath,\n rule: 'folder-slug',\n severity: 'error',\n message: `path does not match the \"${kind}\" slug pattern ${pattern.source}`\n }\n ];\n}\n\nfunction checkVocabulary(\n relPath: string,\n data: Record<string, unknown>,\n cfg: VaultConfig\n): Finding[] {\n const findings: Finding[] = [];\n const kind = data.kind;\n if (typeof kind === 'string' && !cfg.kinds.includes(kind)) {\n findings.push({\n path: relPath,\n rule: 'kind-vocabulary',\n severity: 'error',\n message: `kind \"${kind}\" is not in vault.yaml`\n });\n }\n const status = data.status;\n if (typeof status === 'string' && !cfg.statuses.includes(status)) {\n findings.push({\n path: relPath,\n rule: 'status-vocabulary',\n severity: 'error',\n message: `status \"${status}\" is not in vault.yaml`\n });\n }\n const { scope } = deriveLocation(relPath);\n if (scope !== null && !Object.hasOwn(cfg.scopes, scope)) {\n findings.push({\n path: relPath,\n rule: 'scope-vocabulary',\n severity: 'error',\n message: `scope \"${scope}\" is not in vault.yaml`\n });\n }\n const methodology = data.methodology;\n if (typeof methodology === 'string' && !cfg.methodologies.includes(methodology)) {\n findings.push({\n path: relPath,\n rule: 'methodology-vocabulary',\n severity: 'error',\n message: `methodology \"${methodology}\" is not in vault.yaml`\n });\n }\n return findings;\n}\n\n/**\n * Path is authoritative for `scope`/`topic`: sync derives them from the path and\n * ignores frontmatter. A frontmatter copy is allowed for readability but must not\n * lie \u2014 a mismatch means the label disagrees with where the file actually lives.\n * Fires only where the path defines the value (projects \u2192 scope, research \u2192 topic)\n * and the frontmatter carries it.\n */\nfunction checkScopePath(relPath: string, data: Record<string, unknown>): Finding[] {\n const { scope, topic } = deriveLocation(relPath);\n const findings: Finding[] = [];\n if (\n scope !== null &&\n typeof data.scope === 'string' &&\n data.scope !== '' &&\n data.scope !== scope\n ) {\n findings.push({\n path: relPath,\n rule: 'path-authority',\n severity: 'error',\n message: `frontmatter scope \"${data.scope}\" disagrees with path scope \"${scope}\"`\n });\n }\n if (\n topic !== null &&\n typeof data.topic === 'string' &&\n data.topic !== '' &&\n data.topic !== topic\n ) {\n findings.push({\n path: relPath,\n rule: 'path-authority',\n severity: 'error',\n message: `frontmatter topic \"${data.topic}\" disagrees with path topic \"${topic}\"`\n });\n }\n return findings;\n}\n\n/** A reference's basename target, or null if absent/empty/non-string. */\nfunction refTarget(value: unknown): string | null {\n if (typeof value !== 'string') return null;\n const trimmed = value.trim();\n return trimmed === '' ? null : basename(trimmed);\n}\n\n/**\n * Basename targets of a reference field that may be scalar or array. `supersedes`\n * and `superseded_by` are list-valued in the wild (one ADR can supersede several),\n * so a scalar-only read would miss them and falsely fail reciprocity.\n */\nfunction refTargets(value: unknown): string[] {\n if (Array.isArray(value)) {\n return value.map(refTarget).filter((t): t is string => t !== null);\n }\n const single = refTarget(value);\n return single === null ? [] : [single];\n}\n\n/**\n * Strip code regions so `[[...]]`-shaped syntax inside them is not mistaken for a\n * wikilink: fenced ``` blocks (e.g. a bash `if [[ x == y ]]` test) and inline\n * `code` spans (e.g. a `[[wikilink]]` documentation example). Sync's own link\n * extraction is unaffected \u2014 its pseudo-links are a separate, pre-existing concern.\n */\nfunction stripCode(body: string): string {\n return body.replace(/```[\\s\\S]*?```/g, '').replace(/`[^`]*`/g, '');\n}\n\n/**\n * Body `[[wikilink]]` dangling check against the basename `refIndex`. Code\n * regions are stripped first (see `stripCode`) so `[[...]]`-shaped syntax inside\n * fences/inline-code is not mistaken for a link. Shared by the indexed-page\n * reference checks and the title-less primer carve-in.\n */\nfunction checkBodyLinks(relPath: string, body: string, refIndex: ReadonlySet<string>): Finding[] {\n const findings: Finding[] = [];\n for (const link of extractWikilinks(stripCode(body))) {\n if (!link.target.endsWith('.md')) continue;\n if (!refIndex.has(basename(link.target))) {\n findings.push({\n path: relPath,\n rule: 'dangling-link',\n severity: 'error',\n message: `wikilink target \"${link.target}\" does not resolve`\n });\n }\n }\n return findings;\n}\n\n/**\n * Reference resolution against the basename index: body `[[wikilinks]]` to `.md`\n * targets, plus the frontmatter reference fields. Empty values never fire (the\n * empty `supersedes:`/`superseded_by:` template keys are the 52/57). Non-`.md`\n * wikilink targets (images, `.base`, external) are not policed.\n */\nfunction checkReferences(\n relPath: string,\n data: Record<string, unknown>,\n body: string,\n refIndex: ReadonlySet<string>\n): Finding[] {\n const findings: Finding[] = checkBodyLinks(relPath, body, refIndex);\n const fieldRefs: string[] = [];\n const parent = refTarget(data.parent);\n if (parent !== null) fieldRefs.push(parent);\n for (const field of ['supersedes', 'superseded_by', 'blocked_by'] as const) {\n fieldRefs.push(...refTargets(data[field]));\n }\n for (const target of fieldRefs) {\n if (!refIndex.has(target)) {\n findings.push({\n path: relPath,\n rule: 'ref-resolves',\n severity: 'error',\n message: `frontmatter reference \"${target}\" does not resolve`\n });\n }\n }\n return findings;\n}\n\n/**\n * Tag policy: only the alias case is enforced, as a non-fatal warning. A full\n * canonical-membership check is deferred \u2014 the corpus carries ~211 distinct tags\n * against an 11-entry canonical list, so flagging non-canonical tags would fire\n * on nearly every page (spec-wiki-validate \u00A7 Tag policy).\n */\nfunction checkTags(relPath: string, data: Record<string, unknown>, cfg: VaultConfig): Finding[] {\n if (!Array.isArray(data.tags)) return [];\n const findings: Finding[] = [];\n for (const tag of data.tags) {\n if (typeof tag === 'string' && Object.hasOwn(cfg.tags.aliases, tag)) {\n findings.push({\n path: relPath,\n rule: 'tag-alias',\n severity: 'warning',\n message: `tag \"${tag}\" is an alias; use canonical \"${cfg.tags.aliases[tag]}\"`\n });\n }\n }\n return findings;\n}\n\n/** `status: superseded` requires a non-empty `superseded_by` (README \u00A76). */\nfunction checkSupersededLink(relPath: string, data: Record<string, unknown>): Finding[] {\n if (data.status === 'superseded' && refTargets(data.superseded_by).length === 0) {\n return [\n {\n path: relPath,\n rule: 'superseded-needs-link',\n severity: 'error',\n message: 'status is \"superseded\" but superseded_by is empty'\n }\n ];\n }\n return [];\n}\n\n/** Indexed-page checks on already-parsed frontmatter. Pure. */\nfunction checkIndexedPage(\n relPath: string,\n data: Record<string, unknown>,\n body: string,\n cfg: VaultConfig,\n refIndex: ReadonlySet<string>\n): Finding[] {\n if (!isIndexed(relPath, data)) return [];\n return [\n ...checkRequiredFields(relPath, data),\n ...checkTagsRequired(relPath, data),\n ...checkFolderSlug(relPath, data),\n ...checkVocabulary(relPath, data, cfg),\n ...checkScopePath(relPath, data),\n ...checkReferences(relPath, data, body, refIndex),\n ...checkSupersededLink(relPath, data),\n ...checkTags(relPath, data, cfg)\n ];\n}\n\n/**\n * Deterministic checks on a single page's raw content. Pure \u2014 no IO. Parses the\n * frontmatter first: a parse failure is the live bug that silently halts sync\n * mid-walk, reported regardless of the page's other fields. Well-formed pages\n * are then subjected to the indexed-page checks (vocabulary, \u2026) against the\n * controlled vocabulary `cfg` and the basename `refIndex` of valid link targets.\n */\nexport function validatePage(\n relPath: string,\n raw: string,\n cfg: VaultConfig,\n refIndex: ReadonlySet<string>\n): Finding[] {\n let parsed: ReturnType<typeof parseFrontmatter>;\n try {\n parsed = parseFrontmatter(raw);\n } catch (err) {\n return [\n {\n path: relPath,\n rule: 'frontmatter-parse',\n severity: 'error',\n message: err instanceof Error ? err.message : String(err)\n }\n ];\n }\n if (isPrimer(relPath)) {\n return checkBodyLinks(relPath, parsed.content, refIndex);\n }\n return checkIndexedPage(relPath, parsed.data, parsed.content, cfg, refIndex);\n}\n\n/** Exit-code decision: any error-severity finding fails the run. */\nexport function hasErrors(findings: Finding[]): boolean {\n return findings.some((f) => f.severity === 'error');\n}\n\n/** Basename (no extension) of a vault-relative path. */\nfunction basename(relPath: string): string {\n const last = relPath.split('/').pop() ?? relPath;\n return last.replace(/\\.md$/, '');\n}\n\nexport interface PageData {\n path: string;\n data: Record<string, unknown>;\n}\n\n/**\n * Cross-page ADR supersession reciprocity: a non-empty `superseded_by: B` on\n * ADR A requires `supersedes: A` on B, and vice-versa. Fires only on non-empty\n * values; a value pointing at a non-existent ADR is a `ref-resolves` error\n * (checked per-page), not a reciprocity error, so unresolved targets are skipped\n * here. (spec-wiki-validate \u00A7 Supersession.)\n */\nexport function validateSupersession(pages: PageData[]): Finding[] {\n const adrs = new Map<string, { path: string; supersedes: string[]; supersededBy: string[] }>();\n for (const { path, data } of pages) {\n if (data.kind !== 'adr') continue;\n adrs.set(basename(path), {\n path,\n supersedes: refTargets(data.supersedes),\n supersededBy: refTargets(data.superseded_by)\n });\n }\n const findings: Finding[] = [];\n for (const [name, adr] of adrs) {\n for (const target of adr.supersededBy) {\n const other = adrs.get(target);\n if (other && !other.supersedes.includes(name)) {\n findings.push({\n path: adr.path,\n rule: 'supersession-reciprocal',\n severity: 'error',\n message: `superseded_by \"${target}\" which does not declare supersedes \"${name}\"`\n });\n }\n }\n for (const target of adr.supersedes) {\n const other = adrs.get(target);\n if (other && !other.supersededBy.includes(name)) {\n findings.push({\n path: adr.path,\n rule: 'supersession-reciprocal',\n severity: 'error',\n message: `supersedes \"${target}\" which does not declare superseded_by \"${name}\"`\n });\n }\n }\n }\n return findings;\n}\n\n/** Top-level scope/topic key of a path (`projects/{scope}` or `research/{topic}`), or\n * null for notes/root pages. Two pages \"share a scope\" iff their keys are equal. */\nfunction locationKey(relPath: string): string | null {\n const seg = relPath.split('/');\n if ((seg[0] === 'projects' || seg[0] === 'research') && seg[1]) {\n return `${seg[0]}/${seg[1]}`;\n }\n return null;\n}\n\nexport interface LinkPage {\n path: string;\n body: string;\n}\n\n/**\n * Cross-page ambiguity warning. A **bare** `[[wikilink]]` whose basename is owned by\n * more than one file is ambiguous only when none of those owners shares the linking\n * page's scope: a same-scope copy resolves it locally (the per-scope `spec-context`/\n * `primer`/`index` pattern), and a path-qualified link (`[[a/b/c]]`) is already\n * disambiguated. Warning, not error \u2014 the link resolves, just not uniquely.\n */\nexport function validateAmbiguousLinks(\n pages: LinkPage[],\n basenameToPaths: ReadonlyMap<string, string[]>\n): Finding[] {\n const findings: Finding[] = [];\n for (const { path, body } of pages) {\n const here = locationKey(path);\n for (const link of extractWikilinks(stripCode(body))) {\n if (!link.target.endsWith('.md') || link.target.includes('/')) continue;\n const base = basename(link.target);\n const owners = basenameToPaths.get(base);\n if (!owners || owners.length < 2) continue;\n if (here !== null && owners.some((p) => locationKey(p) === here)) continue;\n findings.push({\n path,\n rule: 'ambiguous-link',\n severity: 'warning',\n message: `bare link \"[[${base}]]\" is ambiguous \u2014 basename owned by ${owners.length} files, none in this scope`\n });\n }\n }\n return findings;\n}\n\n/**\n * Walk the vault's content domains (reusing the sync walker), build the basename\n * index of valid reference targets (all on-disk pages, including title-less ones),\n * then aggregate findings across all pages. No database \u2014 validation is a\n * pre-sync, read-only pass over the filesystem.\n */\nexport async function validateVault(root: string): Promise<Finding[]> {\n const cfg = await loadVaultConfig(root);\n\n // Reference target universe = every on-disk page, including title-less ones and\n // pages outside the scanned domains (raw/, templates/) that are legitimate link\n // targets. Walking from '.' covers the whole vault; dotdirs (.git, .obsidian)\n // are skipped by the walker.\n const all = (await walkMarkdown(root, '.')).map((abs) => ({\n relPath: toRelativePath(root, abs),\n abs\n }));\n // basename \u2192 [paths] (the spec's reference-resolution model). `refIndex` (dangling\n // checks: does the basename exist) is its key set; the multimap also backs the\n // cross-page ambiguity warning (does a basename have more than one owner).\n const basenameToPaths = new Map<string, string[]>();\n for (const f of all) {\n const b = basename(f.relPath);\n const owners = basenameToPaths.get(b);\n if (owners) owners.push(f.relPath);\n else basenameToPaths.set(b, [f.relPath]);\n }\n const refIndex = new Set<string>(basenameToPaths.keys());\n\n // Applicability = only the indexed content domains.\n const files = all.filter((f) => SCAN_DOMAINS.some((d) => f.relPath.startsWith(`${d}/`)));\n\n const findings: Finding[] = [];\n const pages: PageData[] = [];\n const linkPages: LinkPage[] = [];\n for (const { relPath, abs } of files) {\n const raw = await readFile(abs, 'utf8');\n findings.push(...validatePage(relPath, raw, cfg, refIndex));\n try {\n const parsed = parseFrontmatter(raw);\n pages.push({ path: relPath, data: parsed.data });\n linkPages.push({ path: relPath, body: parsed.content });\n } catch {\n // Parse failure already reported by validatePage; skip in the graph pass.\n }\n }\n findings.push(...validateSupersession(pages));\n findings.push(...validateAmbiguousLinks(linkPages, basenameToPaths));\n return findings;\n}\n", "import { parseArgs } from 'node:util';\nimport { runSync } from './sync.js';\nimport { type Finding, hasErrors, validateVault } from './validate.js';\n\nexport type Command = 'sync' | 'validate';\n\nexport type CliResolution = { kind: 'run'; command: Command } | { kind: 'error'; message: string };\n\n/**\n * Resolve a `wiki <command>` invocation to the command to run, or a usage\n * error. Pure \u2014 no side effects \u2014 so the routing is testable without executing\n * the (index-touching) command. `argv` is `process.argv.slice(2)`.\n */\nexport function resolveCli(argv: string[]): CliResolution {\n const { positionals } = parseArgs({ args: argv, allowPositionals: true, strict: false });\n const command = positionals[0];\n if (command === 'sync') {\n return { kind: 'run', command: 'sync' };\n }\n if (command === 'validate') {\n return { kind: 'run', command: 'validate' };\n }\n if (command === undefined) {\n return { kind: 'error', message: 'usage: wiki <sync|validate>' };\n }\n return { kind: 'error', message: `unknown command: ${command}` };\n}\n\nexport function vaultRoot(): string {\n const root = process.env.WIKI_VAULT;\n if (!root) {\n console.error('WIKI_VAULT is not set');\n process.exit(1);\n }\n return root;\n}\n\nfunction reportFindings(findings: Finding[]): void {\n for (const f of findings) {\n console.error(`${f.severity}: ${f.path} [${f.rule}] ${f.message}`);\n }\n}\n\nexport async function runValidate(): Promise<void> {\n const findings = await validateVault(vaultRoot());\n reportFindings(findings);\n console.log(`validate: ${findings.length} finding(s)`);\n process.exit(hasErrors(findings) ? 1 : 0);\n}\n\nexport async function runSyncCommand(): Promise<void> {\n const findings = await validateVault(vaultRoot());\n reportFindings(findings);\n if (hasErrors(findings)) {\n const errors = findings.filter((f) => f.severity === 'error').length;\n console.error(`sync aborted: ${errors} validation error(s); no database writes`);\n process.exit(1);\n }\n await runSync();\n}\n\nexport async function main(): Promise<void> {\n const resolution = resolveCli(process.argv.slice(2));\n if (resolution.kind === 'error') {\n console.error(resolution.message);\n process.exit(1);\n }\n if (resolution.command === 'sync') {\n await runSyncCommand();\n } else {\n await runValidate();\n }\n}\n", "import { z } from 'zod';\n\nconst EnvSchema = z.object({\n WIKI_VAULT: z.string().min(1).describe('Absolute path to the Obsidian vault root'),\n LOG_LEVEL: z\n .enum(['trace', 'debug', 'info', 'warn', 'error', 'fatal', 'silent'])\n .default('info')\n .describe('Pino log level. Logs go to stderr to keep the stdio JSON-RPC stream clean.'),\n SERVER_NAME: z.string().default('wiki-mcp'),\n SERVER_VERSION: z.string().default('0.0.0')\n});\n\nexport interface Config {\n readonly wikiVault: string;\n readonly logLevel: z.infer<typeof EnvSchema>['LOG_LEVEL'];\n readonly serverName: string;\n readonly serverVersion: string;\n}\n\nexport function loadConfig(env: NodeJS.ProcessEnv = process.env): Config {\n const parsed = EnvSchema.safeParse(env);\n if (!parsed.success) {\n const issues = parsed.error.issues\n .map((i) => ` - ${i.path.join('.') || '(root)'}: ${i.message}`)\n .join('\\n');\n throw new Error(`Invalid environment configuration:\\n${issues}`);\n }\n return {\n wikiVault: parsed.data.WIKI_VAULT,\n logLevel: parsed.data.LOG_LEVEL,\n serverName: parsed.data.SERVER_NAME,\n serverVersion: parsed.data.SERVER_VERSION\n };\n}\n", "import { mkdirSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport type { DatabaseSync } from 'node:sqlite';\nimport { openDatabase } from '@llm-wiki/db/database';\n\nexport function createDatabase(): DatabaseSync {\n const dbDir = join(homedir(), '.kmd', 'db');\n const dbPath = join(dbDir, 'index.db');\n mkdirSync(dbDir, { recursive: true });\n return openDatabase(dbPath);\n}\n", "import { appendFileSync, mkdirSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\nconst DIAG_DIR = join(homedir(), '.local', 'state', 'wiki-mcp');\nexport const DIAG_LOG_PATH = join(DIAG_DIR, 'server.log');\n\ntry {\n mkdirSync(DIAG_DIR, { recursive: true });\n} catch {\n // best-effort; do not block startup on log dir creation\n}\n\n/**\n * Synchronous file logger that survives even when pino, the MCP SDK, or any\n * import down the chain fails to load. Writes to ~/.local/state/wiki-mcp/server.log\n * regardless of stdio/stderr capture by the parent process. Use to trace\n * spawn-time failures that never reach pino.\n */\nexport function diag(msg: string, data?: Record<string, unknown>): void {\n try {\n const line = data\n ? `${new Date().toISOString()} pid=${process.pid} ${msg} ${JSON.stringify(data)}\\n`\n : `${new Date().toISOString()} pid=${process.pid} ${msg}\\n`;\n appendFileSync(DIAG_LOG_PATH, line);\n } catch {\n // best-effort; never crash the server on log write failure\n }\n}\n", "import pino from 'pino';\nimport { DIAG_LOG_PATH } from './diag.js';\n\n/**\n * Pino logger that fans out to BOTH stderr (fd 2, captured by Claude Code)\n * AND ~/.local/state/wiki-mcp/server.log (so logs survive when stderr capture\n * doesn't make it into the JSONL connection log). The file destination shares\n * the path with diag.ts so a single `tail -f` follows the entire startup +\n * runtime stream.\n */\nexport function createLogger(level: string, name: string): pino.Logger {\n const streams: pino.StreamEntry[] = [\n { level: level as pino.Level, stream: pino.destination(2) },\n {\n level: level as pino.Level,\n stream: pino.destination({ dest: DIAG_LOG_PATH, sync: false, mkdir: true })\n }\n ];\n return pino({ name, level, base: { pid: process.pid } }, pino.multistream(streams));\n}\n\nexport type Logger = pino.Logger;\n", "import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { VaultConfig } from '../vault-config.js';\n\ninterface KindPedagogy {\n readonly signal: string;\n readonly where: string;\n}\n\nconst KIND_PEDAGOGY: ReadonlyMap<string, KindPedagogy> = new Map([\n [\n 'project',\n {\n signal: 'Identity card for a project scope',\n where: '`projects/{scope}/index.md`'\n }\n ],\n [\n 'spec',\n {\n signal: 'How a system works (state of world, not decision)',\n where: '`projects/{scope}/spec/spec-{slug}.md`'\n }\n ],\n [\n 'adr',\n {\n signal: 'Decision between alternatives, commits direction',\n where: '`projects/{scope}/adr/adr-{slug}.md`'\n }\n ],\n [\n 'plan',\n {\n signal: 'Phase/initiative with milestones and stories',\n where: '`projects/{scope}/plan/plan-{slug}.md`'\n }\n ],\n [\n 'story',\n {\n signal: 'User story with Gherkin + slices (child of plan)',\n where: '`projects/{scope}/plan/{plan}/story-N-{slug}.md`'\n }\n ],\n [\n 'ops',\n {\n signal: 'Operational runbook, how to run/deploy',\n where: '`projects/{scope}/ops/ops-{slug}.md`'\n }\n ],\n [\n 'topic',\n {\n signal: 'Identity card for a research area',\n where: '`research/{topic}/index.md`'\n }\n ],\n [\n 'article',\n {\n signal: 'Original synthesis about a concept/entity',\n where: '`research/{topic}/{slug}.md`'\n }\n ],\n [\n 'src',\n {\n signal: 'Summary of external source with citation',\n where: '`research/{topic}/src-{slug}.md`'\n }\n ],\n ['note', { signal: 'Low-ceremony capture, sort later', where: '`notes/{slug}.md`' }],\n [\n 'artifact',\n {\n signal: 'Deployable configuration (scope-specific, versioned)',\n where: '`projects/{scope}/ops/{deployment}/{slug}.md`'\n }\n ],\n [\n 'prompt',\n {\n signal: 'LLM prompt template (scope-specific, versioned)',\n where: '`projects/{scope}/ops/{deployment}/prompts/{role}/{slug}.md`'\n }\n ]\n]);\n\nconst DEFAULT_AUTHORING_RULES = [\n \"- **Use the matching template** via `wiki://template/{domain}/{kind}` (MCP) or from `templates/` (filesystem). Don't hand-roll frontmatter.\",\n '- **Quote prose-bearing frontmatter scalars.** `summary: \"...\"` \u2014 unquoted `Word: phrase` patterns break the YAML parser.',\n '- **On any edit, update the frontmatter `updated` field.**',\n '- **Folder name = slug prefix in `projects/`.** `spec/spec-x.md`, `adr/adr-y.md`, `plan/plan-z.md`, `ops/ops-w.md`. Stories use `story-` prefix under `plan/{plan-name}/`.',\n '- **Research is flat.** Articles are `{subject}.md`; sources are `src-{slug}.md`. Avoid generic slugs (`architecture.md`, `notes.md`).',\n '- **Notes have no `kind` field** \u2014 implied by location. Sync sets `kind: note`.',\n '- **Reuse existing tags** (visible in `prime` response `top_tags`). No synonyms.',\n '- **ADR supersession is bidirectional**: `superseded_by` on the old ADR + `supersedes` on the new one.',\n \"- **Sources convention**: external paths/URLs go inline in body text. Vault-internal `raw/` paths go in frontmatter `sources:` array. Don't mix the two surfaces.\",\n \"- **Spec / ADR edits land inline with the slice that surfaces them.** Don't queue corrections in plans. The spec must reflect current code at every commit.\"\n].join('\\n');\n\nfunction buildAuthoringRules(config: VaultConfig): string {\n return ['## Authoring rules', '', config.authoring_rules ?? DEFAULT_AUTHORING_RULES].join('\\n');\n}\n\nconst DEFAULT_SYNC_PROTOCOL =\n 'Edit the smallest set of files that reflects the change. ' +\n \"A milestone tick is plan-only; don't cascade to index.md unless phase or status changed. \" +\n 'Controlled-vocabulary edits need explicit user approval.';\n\nfunction buildSyncProtocol(config: VaultConfig): string {\n return ['## Resync protocol', '', config.sync_protocol ?? DEFAULT_SYNC_PROTOCOL].join('\\n');\n}\n\nfunction buildKindSelector(kinds: ReadonlyArray<string>): string {\n const lines: string[] = ['## Kind selector', '', '| Signal | Kind | Where |', '|---|---|---|'];\n for (const kind of kinds) {\n const pedagogy = KIND_PEDAGOGY.get(kind);\n const signal = pedagogy?.signal ?? '\u2014';\n const where = pedagogy?.where ?? '\u2014';\n lines.push(`| ${signal} | **${kind}** | ${where} |`);\n }\n const hasNote = kinds.includes('note');\n const hasAdrAndSpec = kinds.includes('adr') && kinds.includes('spec');\n if (hasNote || hasAdrAndSpec) {\n const hints: string[] = [];\n if (hasNote) hints.push('If none fits \u2192 note.');\n if (hasAdrAndSpec) {\n hints.push(\n 'If torn between adr and spec \u2192 does it record a choice? adr. Does it describe how things work? spec.'\n );\n }\n lines.push('', hints.join(' '));\n }\n return lines.join('\\n');\n}\n\nfunction buildVocabulary(config: VaultConfig): string {\n const lines: string[] = [\n '## Controlled vocabulary',\n '',\n `**Kinds:** ${config.kinds.join(', ')}`,\n `**Statuses:** ${config.statuses.join(' \u2192 ')} (one-directional; superseded requires superseded_by link)`,\n `**Methodologies:** ${config.methodologies.join(', ')}`,\n `**Canonical tags:** ${config.tags.canonical.join(', ')}`\n ];\n const aliases = Object.entries(config.tags.aliases);\n if (aliases.length > 0) {\n lines.push(`**Tag aliases:** ${aliases.map(([a, c]) => `${a} \u2192 ${c}`).join(', ')}`);\n }\n return lines.join('\\n');\n}\n\nexport function registerAuthoringResource(\n mcp: McpServer,\n _vaultRoot: string,\n vaultConfig: VaultConfig\n): void {\n mcp.registerResource(\n 'Authoring guide',\n 'wiki://authoring',\n {\n description:\n 'Wiki authoring pedagogy: kind selector, controlled vocabulary, authoring rules, resync protocol, and template URIs. Read before creating or editing wiki pages.',\n mimeType: 'text/markdown'\n },\n async (uri) => {\n const sections = [\n '# Wiki authoring guide',\n '',\n buildKindSelector(vaultConfig.kinds),\n '',\n buildVocabulary(vaultConfig),\n '',\n '## Templates',\n '',\n 'Full index with URIs and descriptions: `wiki://templates`',\n '',\n buildAuthoringRules(vaultConfig),\n '',\n buildSyncProtocol(vaultConfig)\n ];\n return {\n contents: [\n {\n uri: uri.toString(),\n mimeType: 'text/markdown' as const,\n text: sections.join('\\n')\n }\n ]\n };\n }\n );\n}\n", "import { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\n\ninterface TemplateSpec {\n /** wiki://template/{domain}/{kind} \u2014 `note` collapses to single segment. */\n readonly uri: string;\n /** Human-readable name shown in resources/list. */\n readonly name: string;\n /** Filename in vault/templates/. */\n readonly file: string;\n /** Description shown in resources/list. */\n readonly description: string;\n}\n\n/**\n * The vault has 11 fixed templates, mirroring the v2 frontmatter schemas\n * (extended with `story` per adr-story-vocabulary-and-triage-fields).\n * URI scheme: `wiki://template/{domain}/{kind}` \u2014 the agent thinks\n * \"I'm authoring a {kind} in the {domain} domain\" and the URI matches\n * that mental model. `note` collapses to a single segment because the\n * notes domain has only one kind.\n */\nexport const TEMPLATES: ReadonlyArray<TemplateSpec> = [\n {\n uri: 'wiki://template/project/index',\n name: 'Project index',\n file: 'project-index.md',\n description:\n 'Identity card for a project. Frontmatter-heavy: methodology, phase, repo, scope, summary, tags. Short body.'\n },\n {\n uri: 'wiki://template/project/primer',\n name: 'Project primer',\n file: 'project-primer.md',\n description:\n 'Human-authored narrative context for a project. Free-form body. Inlined into the prime tool response.'\n },\n {\n uri: 'wiki://template/project/spec',\n name: 'Project spec',\n file: 'project-spec.md',\n description:\n 'Specification page \u2014 how a system or feature works (state of the world, not decision).'\n },\n {\n uri: 'wiki://template/project/adr',\n name: 'Project ADR',\n file: 'project-adr.md',\n description:\n 'Architecture Decision Record \u2014 pinned moment of choice. Sections: Status, Context, Decision, Rationale, Consequences.'\n },\n {\n uri: 'wiki://template/project/plan',\n name: 'Project plan',\n file: 'project-plan.md',\n description:\n 'Plan for a phase or initiative. Sections: Goal, Scope, Milestones, Dependencies, Status Log.'\n },\n {\n uri: 'wiki://template/project/ops',\n name: 'Project ops',\n file: 'project-ops.md',\n description: 'Operational runbook \u2014 how to run or operate a system. Procedural.'\n },\n {\n uri: 'wiki://template/project/story',\n name: 'Project story',\n file: 'project-story.md',\n description:\n 'User story with Gherkin scenarios and inline implementation slices. Lives at plan/{plan-name}/story-N-{slug}.md. Frontmatter carries triage_state, category, blocked_by, parent.'\n },\n {\n uri: 'wiki://template/research/index',\n name: 'Research index',\n file: 'research-index.md',\n description:\n 'Topic identity card for a research area. Frontmatter: confidence, source_count, summary, tags.'\n },\n {\n uri: 'wiki://template/research/article',\n name: 'Research article',\n file: 'research-article.md',\n description:\n 'Wikipedia-style article about a concept, entity, or system. Original synthesis with sources.'\n },\n {\n uri: 'wiki://template/research/src',\n name: 'Research source',\n file: 'research-src.md',\n description:\n 'Summary of an external source (paper, talk, doc) with citation. The only `src-` prefix in research.'\n },\n {\n uri: 'wiki://template/note',\n name: 'Note',\n file: 'note.md',\n description: 'Low-ceremony everyday note. Capture fast, sort later.'\n }\n];\n\n/**\n * Register all template resources with the MCP server. Each template is a\n * fixed URI; `resources/read` re-reads the file on every call, so edits to\n * vault/templates/*.md are picked up without restarting the server.\n */\nexport function registerTemplateResources(mcp: McpServer, vaultRoot: string): void {\n const dir = join(vaultRoot, 'templates');\n for (const tmpl of TEMPLATES) {\n mcp.registerResource(\n tmpl.name,\n tmpl.uri,\n { description: tmpl.description, mimeType: 'text/markdown' },\n async (uri) => {\n const text = await readFile(join(dir, tmpl.file), 'utf8');\n return {\n contents: [\n {\n uri: uri.toString(),\n mimeType: 'text/markdown' as const,\n text\n }\n ]\n };\n }\n );\n }\n\n const indexLines = ['# Wiki Templates', ''];\n for (const tmpl of TEMPLATES) {\n indexLines.push(`- **${tmpl.name}** \u2014 \\`${tmpl.uri}\\` `);\n indexLines.push(` ${tmpl.description}`);\n }\n const indexText = indexLines.join('\\n');\n\n mcp.registerResource(\n 'Template index',\n 'wiki://templates',\n {\n description:\n 'Index of all wiki templates with URIs and descriptions. Read a specific template via its URI.',\n mimeType: 'text/markdown'\n },\n async (uri) => ({\n contents: [{ uri: uri.toString(), mimeType: 'text/markdown' as const, text: indexText }]\n })\n );\n}\n", "import { parse as parseYaml } from 'yaml';\n\n// Verbatim mirror of @llm-wiki/cli's src/frontmatter.ts. Kept byte-identical so\n// mcp parses frontmatter the same way sync/validate do. Collapse into a shared\n// package only when a third separate consumer appears (CLAUDE.md YAGNI rule).\n\nexport interface ParsedFrontmatter {\n data: Record<string, unknown>;\n content: string;\n}\n\n// Leading `---` block, YAML, closing `---`, then one consumed newline. Matches\n// gray-matter's delimiter handling; the closing `---` must be on its own line so\n// `---` rules inside the body are left intact.\nconst FRONTMATTER_RE = /^---\\r?\\n([\\s\\S]*?)\\r?\\n?---\\r?\\n?/;\n\n/**\n * Split a page's frontmatter from its body using the `yaml` parser. Throws\n * (deterministically, no cache) when the frontmatter is not valid YAML. A page\n * with no leading delimiter parses to empty data and the whole input as body.\n */\nexport function parseFrontmatter(raw: string): ParsedFrontmatter {\n const match = FRONTMATTER_RE.exec(raw);\n if (!match) {\n return { data: {}, content: raw };\n }\n const yamlText = match[1] ?? '';\n const content = raw.slice(match[0].length);\n if (yamlText.trim() === '') {\n return { data: {}, content };\n }\n const parsed = parseYaml(yamlText);\n const data =\n parsed !== null && typeof parsed === 'object' ? (parsed as Record<string, unknown>) : {};\n return { data, content };\n}\n", "const FTS5_KEYWORDS = new Set(['AND', 'OR', 'NOT', 'NEAR']);\n\nexport function sanitizeFtsQuery(raw: string): string {\n return raw\n .replace(/[^\\p{L}\\p{N}\\s]/gu, ' ')\n .split(/\\s+/)\n .filter((t) => t.length > 0 && !FTS5_KEYWORDS.has(t))\n .join(' ');\n}\n", "/**\n * MCP CallToolResult helpers. `content[0].text` carries pretty-printed JSON\n * for LLM-facing clients; `structuredContent` carries the same payload as\n * raw JSON for clients that parse directly. Both fields kept in sync so\n * callers never choose one over the other.\n */\n\nexport function textJson(data: object) {\n return {\n content: [{ type: 'text' as const, text: JSON.stringify(data, null, 2) }],\n structuredContent: data as Record<string, unknown>\n };\n}\n\n/**\n * Variant for tools whose model-facing surface is denser as markdown than as\n * pretty-printed JSON (~20% token savings on prose-heavy payloads). The\n * markdown goes to `content[0].text`; `structuredContent` keeps the machine\n * fields so a non-LLM client still gets a parseable shape.\n */\nexport function textWithStruct(markdown: string, data: object) {\n return {\n content: [{ type: 'text' as const, text: markdown }],\n structuredContent: data as Record<string, unknown>\n };\n}\n\nexport interface ToolErrorPayload {\n readonly code: string;\n readonly message: string;\n readonly details?: Record<string, unknown>;\n}\n\nexport function textError(error: ToolErrorPayload) {\n const payload = {\n code: error.code,\n message: error.message,\n details: error.details ?? {}\n };\n return {\n isError: true as const,\n content: [{ type: 'text' as const, text: JSON.stringify(payload) }],\n structuredContent: payload as Record<string, unknown>\n };\n}\n", "import { readFile } from 'node:fs/promises';\nimport { basename, join } from 'node:path';\nimport type { DatabaseSync } from 'node:sqlite';\nimport { z } from 'zod';\nimport { parseFrontmatter } from '../frontmatter.js';\nimport { sanitizeFtsQuery } from '../lib/fts.js';\nimport { textError, textWithStruct } from '../lib/toolResponse.js';\nimport type { VaultConfig } from '../vault-config.js';\n\nexport const PrimeInputSchema = z.object({\n scope: z\n .string()\n .min(1)\n .describe('Project scope to prime (matches projects/{scope}/ in the vault).'),\n task: z\n .string()\n .optional()\n .describe('Optional task description; surfaces top-3 tsvector-ranked relevant pages.')\n});\n\nexport type PrimeInput = z.infer<typeof PrimeInputSchema>;\n\ninterface ProjectIndexFm {\n title?: string;\n methodology?: string;\n phase?: number;\n summary?: string;\n}\n\nexport interface PrimeData {\n scope: string;\n title: string | null;\n methodology: string | null;\n phase: number | null;\n summary: string;\n primer: string;\n counts: Record<string, number>;\n active_adrs: Array<{ path: string; slug: string; title: string; summary: string | null }>;\n current_plan: { path: string; slug: string; title: string } | null;\n top_tags: string[];\n hub_pages: Array<{ path: string; title: string; inbound: number }>;\n recent: Array<{ path: string; operation: string; date: string }>;\n relevant: Array<{ path: string; title: string; score: number }>;\n cross_scope: Array<{ from_scope: string; from_path: string; to_path: string }>;\n}\n\nexport interface PrimeDeps {\n readonly db: DatabaseSync;\n readonly vaultRoot: string;\n readonly vaultConfig: VaultConfig;\n}\n\nfunction pathSlug(p: string): string {\n return basename(p).replace(/\\.md$/, '');\n}\n\nasync function readIndexFm(vaultRoot: string, scope: string): Promise<ProjectIndexFm> {\n try {\n const raw = await readFile(join(vaultRoot, 'projects', scope, 'index.md'), 'utf8');\n return parseFrontmatter(raw).data as ProjectIndexFm;\n } catch {\n return {};\n }\n}\n\nasync function readPrimer(vaultRoot: string, scope: string): Promise<string> {\n try {\n const raw = await readFile(join(vaultRoot, 'projects', scope, 'primer.md'), 'utf8');\n return parseFrontmatter(raw)\n .content.trim()\n .replace(/^#\\s+[^\\n]+\\n+/, '');\n } catch {\n return '';\n }\n}\n\nexport async function prime(\n deps: PrimeDeps,\n input: PrimeInput\n): Promise<{ markdown: string; data: PrimeData }> {\n const { db, vaultRoot, vaultConfig } = deps;\n const { scope, task } = input;\n\n const [fm, primer] = await Promise.all([\n readIndexFm(vaultRoot, scope),\n readPrimer(vaultRoot, scope)\n ]);\n\n const counts = db\n .prepare('SELECT kind, count(*) AS count FROM pages WHERE scope = ? GROUP BY kind')\n .all(scope) as Array<{ kind: string; count: number | bigint }>;\n\n const adrs = db\n .prepare(\n \"SELECT path, title, summary FROM pages WHERE scope = ? AND kind = 'adr' AND status = 'active' ORDER BY updated DESC\"\n )\n .all(scope) as Array<{ path: string; title: string; summary: string | null }>;\n\n const planRow = db\n .prepare(\n \"SELECT path, title FROM pages WHERE scope = ? AND kind = 'plan' AND status = 'active' ORDER BY updated DESC LIMIT 1\"\n )\n .get(scope) as { path: string; title: string } | undefined;\n\n const tags = db\n .prepare(\n `SELECT j.value AS tag, count(*) AS cnt\n FROM pages, json_each(pages.tags) AS j\n WHERE scope = ?\n GROUP BY j.value\n ORDER BY cnt DESC\n LIMIT 10`\n )\n .all(scope) as Array<{ tag: string }>;\n\n const hubs = db\n .prepare(\n `SELECT p.path, p.title, count(*) AS inbound\n FROM links l JOIN pages p ON p.path = l.target_path\n WHERE p.scope = ?\n GROUP BY p.path, p.title\n ORDER BY inbound DESC LIMIT 5`\n )\n .all(scope) as Array<{ path: string; title: string; inbound: number | bigint }>;\n\n const events = db\n .prepare('SELECT path, operation, ts FROM events WHERE scope = ? ORDER BY ts DESC LIMIT 5')\n .all(scope) as Array<{ path: string; operation: string; ts: string }>;\n\n const crossScope = db\n .prepare(\n `SELECT pf.scope AS from_scope, l.source_path AS from_path, l.target_path AS to_path\n FROM links l\n JOIN pages pt ON pt.path = l.target_path\n JOIN pages pf ON pf.path = l.source_path\n WHERE pt.scope = ? AND pf.scope IS NOT NULL AND pf.scope != ?\n LIMIT 10`\n )\n .all(scope, scope) as Array<{ from_scope: string; from_path: string; to_path: string }>;\n\n let relevant: Array<{ path: string; title: string; score: number }> = [];\n if (task) {\n const ftsQuery = sanitizeFtsQuery(task);\n if (ftsQuery) {\n relevant = (\n db\n .prepare(\n `SELECT p.path, p.title, bm25(pages_fts) AS score\n FROM pages_fts\n JOIN pages p ON p.id = pages_fts.rowid\n WHERE pages_fts MATCH ? AND p.scope = ?\n ORDER BY bm25(pages_fts) LIMIT 3`\n )\n .all(ftsQuery, scope) as Array<{ path: string; title: string; score: number }>\n ).map((row) => ({\n path: row.path,\n title: row.title,\n score: row.score\n }));\n }\n }\n\n const countsRecord: Record<string, number> = {};\n for (const row of counts) countsRecord[row.kind] = Number(row.count);\n\n const data: PrimeData = {\n scope,\n title: fm.title ?? null,\n methodology: fm.methodology ?? null,\n phase: typeof fm.phase === 'number' ? fm.phase : null,\n summary: fm.summary ?? '',\n primer,\n counts: countsRecord,\n active_adrs: adrs.map((r) => ({\n path: r.path,\n slug: pathSlug(r.path),\n title: r.title,\n summary: r.summary\n })),\n current_plan: planRow\n ? {\n path: planRow.path,\n slug: pathSlug(planRow.path),\n title: planRow.title\n }\n : null,\n top_tags: tags.map((r) => r.tag),\n hub_pages: hubs.map((r) => ({\n path: r.path,\n title: r.title,\n inbound: Number(r.inbound)\n })),\n recent: events.map((r) => ({\n path: r.path,\n operation: r.operation,\n date: r.ts.slice(0, 10)\n })),\n relevant,\n cross_scope: crossScope.map((r) => ({\n from_scope: r.from_scope,\n from_path: r.from_path,\n to_path: r.to_path\n }))\n };\n\n return { markdown: renderMarkdown(data, vaultConfig, task), data };\n}\n\nexport function renderMarkdown(\n d: PrimeData,\n config: VaultConfig,\n task: string | undefined\n): string {\n const lines: string[] = [];\n\n const phaseLabel =\n d.phase !== null\n ? d.methodology\n ? `Phase ${d.phase} (${d.methodology})`\n : `Phase ${d.phase}`\n : '';\n const header = phaseLabel ? `${d.scope} \u2014 ${phaseLabel}` : d.scope;\n lines.push(`# ${header}`);\n if (d.summary) lines.push(d.summary);\n\n if (d.primer) {\n lines.push('', '## Primer', d.primer);\n }\n\n if (d.active_adrs.length > 0) {\n lines.push('', '## Active Decisions');\n for (const a of d.active_adrs) {\n lines.push(`- ${a.slug}: ${a.summary ?? a.title}`);\n }\n }\n\n if (d.current_plan) {\n lines.push('', '## Current Plan');\n lines.push(`${d.current_plan.slug}: ${d.current_plan.title}`);\n }\n\n const countEntries = Object.entries(d.counts);\n if (countEntries.length > 0) {\n lines.push('', '## Pages');\n lines.push(countEntries.map(([k, n]) => `${k}: ${n}`).join(' | '));\n }\n\n lines.push('', '## Vocabulary');\n lines.push(`kinds: ${config.kinds.join(', ')}`);\n lines.push(`statuses: ${config.statuses.join(', ')}`);\n lines.push(`tags: ${config.tags.canonical.join(', ')}`);\n\n if (d.top_tags.length > 0) {\n lines.push('', '## Tags');\n lines.push(d.top_tags.join(', '));\n }\n\n if (d.hub_pages.length > 0) {\n lines.push('', '## Hubs');\n for (const h of d.hub_pages) {\n lines.push(`- ${pathSlug(h.path)} (${h.inbound} inbound)`);\n }\n }\n\n if (d.recent.length > 0) {\n lines.push('', '## Recent');\n for (const r of d.recent) {\n lines.push(`- [${r.date}] ${pathSlug(r.path)} ${r.operation}`);\n }\n }\n\n if (d.relevant.length > 0) {\n lines.push('', `## Relevant (task: \"${task}\")`);\n for (const r of d.relevant) {\n lines.push(`- ${pathSlug(r.path)} (${r.score.toFixed(2)})`);\n }\n }\n\n if (d.cross_scope.length > 0) {\n lines.push('', '## Cross-scope');\n for (const c of d.cross_scope) {\n lines.push(`- ${c.from_scope}/${pathSlug(c.from_path)} \u2192 ${pathSlug(c.to_path)}`);\n }\n }\n\n lines.push(\n '',\n '---',\n 'Authoring wiki content? Read `wiki://authoring` for kind selector, rules, and templates.'\n );\n\n return lines.join('\\n');\n}\n\nexport async function handlePrime(deps: PrimeDeps, input: PrimeInput) {\n if (!Object.hasOwn(deps.vaultConfig.scopes, input.scope)) {\n const valid = Object.keys(deps.vaultConfig.scopes).sort().join(', ');\n return textError({\n code: 'UNKNOWN_SCOPE',\n message: `unknown scope \"${input.scope}\"; valid scopes: ${valid}`\n });\n }\n try {\n const { markdown, data } = await prime(deps, input);\n return textWithStruct(markdown, data as unknown as Record<string, unknown>);\n } catch (err) {\n return textError({\n code: 'PRIME_FAILED',\n message: err instanceof Error ? err.message : String(err)\n });\n }\n}\n", "import type { DatabaseSync } from 'node:sqlite';\nimport { z } from 'zod';\nimport { sanitizeFtsQuery } from '../lib/fts.js';\nimport { textError, textJson } from '../lib/toolResponse.js';\n\nexport const SearchInputSchema = z.object({\n query: z\n .string()\n .min(1)\n .describe(\n 'Natural-language search query. Matched against title, summary, and body via SQLite FTS5.'\n ),\n scope: z\n .string()\n .optional()\n .describe('Optional: restrict to a project scope (e.g. \"ontology\", \"sotto\").'),\n kind: z\n .string()\n .optional()\n .describe(\n 'Optional: restrict to a kind. Project kinds: spec, adr, plan, ops. Research kinds: article, src. Misc: note.'\n ),\n limit: z\n .number()\n .int()\n .min(1)\n .max(50)\n .default(5)\n .describe('Maximum number of ranked results to return. Default 5.')\n});\n\nexport type SearchInput = z.infer<typeof SearchInputSchema>;\n\nexport interface SearchResult {\n readonly path: string;\n readonly title: string;\n readonly kind: string;\n readonly summary: string | null;\n readonly score: number;\n readonly scope?: string | null;\n}\n\nexport interface SearchDeps {\n readonly db: DatabaseSync;\n}\n\nexport function search(deps: SearchDeps, input: SearchInput): { results: SearchResult[] } {\n const ftsQuery = sanitizeFtsQuery(input.query);\n if (!ftsQuery) return { results: [] };\n\n let sql = `SELECT p.path, p.title, p.kind, p.summary, p.scope, bm25(pages_fts) AS score\n FROM pages_fts\n JOIN pages p ON p.id = pages_fts.rowid\n WHERE pages_fts MATCH ?`;\n const params: Array<string | number> = [ftsQuery];\n\n if (input.scope) {\n sql += ' AND p.scope = ?';\n params.push(input.scope);\n }\n if (input.kind) {\n sql += ' AND p.kind = ?';\n params.push(input.kind);\n }\n sql += ' ORDER BY bm25(pages_fts) LIMIT ?';\n params.push(input.limit);\n\n const rows = deps.db.prepare(sql).all(...params) as Array<{\n path: string;\n title: string;\n kind: string;\n summary: string | null;\n scope: string | null;\n score: number;\n }>;\n\n return {\n results: rows.map((r) => ({\n path: r.path,\n title: r.title,\n kind: r.kind,\n summary: r.summary,\n scope: r.scope,\n score: r.score\n }))\n };\n}\n\nexport function handleSearch(deps: SearchDeps, input: SearchInput) {\n try {\n return textJson(search(deps, input));\n } catch (err) {\n return textError({\n code: 'SEARCH_FAILED',\n message: err instanceof Error ? err.message : String(err)\n });\n }\n}\n", "import type { DatabaseSync } from 'node:sqlite';\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { Logger } from './lib/logger.js';\nimport { registerAuthoringResource } from './resources/authoring.js';\nimport { registerTemplateResources } from './resources/templates.js';\nimport { handlePrime, PrimeInputSchema } from './tools/prime.js';\nimport { handleSearch, SearchInputSchema } from './tools/search.js';\nimport type { VaultConfig } from './vault-config.js';\n\nexport interface BuildServerArgs {\n readonly name: string;\n readonly version: string;\n readonly vaultRoot: string;\n readonly db: DatabaseSync;\n readonly logger: Logger;\n readonly vaultConfig: VaultConfig;\n}\n\nexport function buildServer(args: BuildServerArgs): McpServer {\n const { name, version, vaultRoot, db, logger, vaultConfig } = args;\n\n const mcp = new McpServer({ name, version }, { capabilities: { tools: {}, resources: {} } });\n\n mcp.tool(\n 'prime',\n 'Orient on a project. Returns a markdown briefing with: identity (scope, phase, methodology, summary), the human-authored primer.md inlined, active ADRs, current plan, page counts, top tags, hub pages (most-linked-to), recent events, cross-scope references, and \u2014 when `task` is provided \u2014 the top 3 tsvector-ranked relevant pages. Call once at session start. Empty sections are omitted to keep the surface lean.',\n PrimeInputSchema.shape,\n async (input) => {\n logger.debug({ tool: 'prime', input }, 'tool call');\n return handlePrime({ db, vaultRoot, vaultConfig }, input);\n }\n );\n\n mcp.tool(\n 'search',\n 'Full-text search across wiki pages via SQLite FTS5. Returns ranked candidates {path, title, kind, summary, score} \u2014 never page bodies. The agent reads the returned paths directly from the filesystem.',\n SearchInputSchema.shape,\n async (input) => {\n logger.debug({ tool: 'search', input }, 'tool call');\n return handleSearch({ db }, input);\n }\n );\n\n registerTemplateResources(mcp, vaultRoot);\n registerAuthoringResource(mcp, vaultRoot, vaultConfig);\n\n return mcp;\n}\n", "import { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { parse } from 'yaml';\nimport { z } from 'zod';\n\n// Verbatim mirror of @llm-wiki/cli's src/config.ts \u2014 the single definition of a\n// valid vault.yaml. Kept byte-identical (schema + error strings) so mcp and\n// sync/validate never disagree on what is valid. Collapse both into a shared\n// package only when a third separate consumer appears (CLAUDE.md YAGNI rule).\n\nconst ScopeSchema = z.object({\n repo: z.string().optional(),\n methodology: z.enum(['sdd', 'tdd', 'hybrid']).optional(),\n status: z.string()\n});\n\nconst VaultConfigSchema = z.object({\n scopes: z.record(z.string(), ScopeSchema),\n kinds: z.array(z.string()),\n statuses: z.array(z.string()),\n methodologies: z.array(z.string()),\n tags: z.object({\n canonical: z.array(z.string()),\n aliases: z.record(z.string(), z.string())\n }),\n authoring_rules: z.string().optional(),\n sync_protocol: z.string().optional()\n});\n\nexport type VaultConfig = z.infer<typeof VaultConfigSchema>;\n\n/**\n * Load and validate `$vaultRoot/vault.yaml` \u2014 the single source of truth for\n * the controlled vocabulary. Throws (fail-loud) when the file is missing or\n * the contents don't satisfy the schema; the server must not start on partial\n * vocabulary.\n */\nexport async function loadVaultConfig(vaultRoot: string): Promise<VaultConfig> {\n const path = join(vaultRoot, 'vault.yaml');\n let raw: string;\n try {\n raw = await readFile(path, 'utf8');\n } catch (err) {\n throw new Error(`vault.yaml not found at ${path}`, { cause: err });\n }\n const parsed = VaultConfigSchema.safeParse(parse(raw));\n if (!parsed.success) {\n const issues = parsed.error.issues\n .map((i) => ` - ${i.path.join('.') || '(root)'}: ${i.message}`)\n .join('\\n');\n throw new Error(`Invalid vault.yaml at ${path}:\\n${issues}`);\n }\n return parsed.data;\n}\n", "import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { loadConfig } from './config.js';\nimport { createDatabase } from './db.js';\nimport { diag } from './lib/diag.js';\nimport { createLogger } from './lib/logger.js';\nimport { buildServer } from './server.js';\nimport { loadVaultConfig } from './vault-config.js';\n\nexport async function startMcpServer(): Promise<void> {\n diag('main entered');\n\n const config = loadConfig();\n diag('config loaded', { vault: config.wikiVault, level: config.logLevel });\n\n const vaultConfig = await loadVaultConfig(config.wikiVault);\n diag('vault config loaded', {\n scopes: Object.keys(vaultConfig.scopes).length,\n kinds: vaultConfig.kinds.length,\n statuses: vaultConfig.statuses.length\n });\n\n const logger = createLogger(config.logLevel, config.serverName);\n logger.info(\n { vault: config.wikiVault, serverName: config.serverName, serverVersion: config.serverVersion },\n 'starting wiki-mcp on stdio'\n );\n\n const db = createDatabase();\n diag('database opened');\n\n const mcp = buildServer({\n name: config.serverName,\n version: config.serverVersion,\n vaultRoot: config.wikiVault,\n db,\n logger,\n vaultConfig\n });\n diag('server built');\n\n const shutdown = async (signal: NodeJS.Signals) => {\n logger.info({ signal }, 'shutting down');\n diag('shutting down', { signal });\n try {\n await mcp.close();\n db.close();\n } catch (err) {\n logger.error({ err }, 'error during shutdown');\n }\n process.exit(0);\n };\n process.once('SIGINT', (s) => void shutdown(s));\n process.once('SIGTERM', (s) => void shutdown(s));\n\n const transport = new StdioServerTransport();\n await mcp.connect(transport);\n logger.info('wiki-mcp ready');\n diag('ready and connected to transport');\n}\n", "#!/usr/bin/env node\nimport { parseArgs } from 'node:util';\n\nconst USAGE = `usage: kmd <command> [options]\n\ncommands:\n sync vault \u2192 index sync (runs validate first)\n validate [<path>] deterministic vault checker (default: $WIKI_VAULT)\n mcp [<vault-root>] start the stdio MCP server (default: $WIKI_VAULT)\n db reset delete and recreate the index\n\noptions:\n --version print version\n --help show this help`;\n\nconst { positionals, values } = parseArgs({\n args: process.argv.slice(2),\n allowPositionals: true,\n strict: false,\n options: {\n version: { type: 'boolean', short: 'v' },\n help: { type: 'boolean', short: 'h' }\n }\n});\n\nconst command = values.version ? '--version' : values.help ? '--help' : positionals[0];\n\nfunction applyVaultRoot(positionalIndex: number): void {\n const arg = positionals[positionalIndex];\n if (arg) {\n process.env.WIKI_VAULT = arg;\n }\n}\n\nasync function run(): Promise<void> {\n switch (command) {\n case 'sync': {\n const { runSyncCommand } = await import('@llm-wiki/cli/cli');\n await runSyncCommand();\n break;\n }\n case 'validate': {\n applyVaultRoot(1);\n const { runValidate } = await import('@llm-wiki/cli/cli');\n await runValidate();\n break;\n }\n case 'mcp': {\n applyVaultRoot(1);\n const { startMcpServer } = await import('@llm-wiki/mcp/start');\n await startMcpServer();\n break;\n }\n case 'db': {\n const sub = positionals[1];\n if (sub === 'reset') {\n const { homedir } = await import('node:os');\n const { join } = await import('node:path');\n const { unlinkSync } = await import('node:fs');\n const dbPath = join(homedir(), '.kmd', 'db', 'index.db');\n let deleted = false;\n for (const suffix of ['', '-wal', '-shm']) {\n try {\n unlinkSync(dbPath + suffix);\n deleted = true;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') throw err;\n }\n }\n console.log(deleted ? `deleted ${dbPath}` : `${dbPath} does not exist \u2014 nothing to reset`);\n } else {\n console.error(sub ? `unknown db subcommand: ${sub}` : 'usage: kmd db reset');\n process.exit(2);\n }\n break;\n }\n case '--version':\n case '-v': {\n const { readFileSync } = await import('node:fs');\n const { join, dirname } = await import('node:path');\n const { fileURLToPath } = await import('node:url');\n const pkgDir = dirname(dirname(fileURLToPath(import.meta.url)));\n const pkg = JSON.parse(readFileSync(join(pkgDir, 'package.json'), 'utf8')) as {\n version: string;\n };\n console.log(pkg.version);\n break;\n }\n case '--help':\n case '-h':\n case undefined: {\n console.log(USAGE);\n if (command === undefined) process.exit(2);\n break;\n }\n default: {\n console.error(`unknown command: ${command}\\n\\n${USAGE}`);\n process.exit(2);\n }\n }\n}\n\nrun().catch((err) => {\n console.error('kmd failed:', err instanceof Error ? (err.stack ?? err.message) : err);\n process.exit(1);\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["vaultRoot", "readFile", "join", "z", "readFile", "positionals", "command", "z", "EnvSchema", "init_config", "mkdirSync", "homedir", "join", "mkdirSync", "homedir", "join", "readFile", "join", "vaultRoot", "parseYaml", "parseFrontmatter", "FRONTMATTER_RE", "init_frontmatter", "readFile", "basename", "join", "z", "vaultRoot", "parseFrontmatter", "init_frontmatter", "z", "vaultRoot", "readFile", "join", "parse", "z", "loadVaultConfig", "vaultRoot", "VaultConfigSchema", "ScopeSchema", "loadVaultConfig", "init_config", "parseArgs", "runSyncCommand", "runValidate", "startMcpServer", "homedir", "join"]
|
|
7
7
|
}
|
package/package.json
CHANGED