skillwiki 0.10.109 → 0.10.111

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.
Files changed (42) hide show
  1. package/dist/{chunk-JCDAEZVD.js → chunk-5IBLXGLY.js} +5 -3
  2. package/dist/chunk-6OQLBNKR.js +250 -0
  3. package/dist/chunk-GQWCTJTU.js +55 -0
  4. package/dist/{chunk-FYAKMULW.js → chunk-HBJLFPQP.js} +91 -198
  5. package/dist/chunk-I2J3IJB7.js +54 -0
  6. package/dist/{chunk-HMHMCPCE.js → chunk-I6IRJCUJ.js} +12 -57
  7. package/dist/{chunk-QU2IXZRN.js → chunk-JQV5KNPT.js} +8 -6
  8. package/dist/chunk-KWEYA3OE.js +60 -0
  9. package/dist/{chunk-DTTKCCQ4.js → chunk-MRPJ7X7W.js} +5 -3
  10. package/dist/{chunk-LDEZQXH6.js → chunk-OJJBZDPR.js} +306 -116
  11. package/dist/chunk-OSL4J7GF.js +32 -0
  12. package/dist/chunk-PYPPG7RF.js +126 -0
  13. package/dist/chunk-QESNTTVY.js +50 -0
  14. package/dist/chunk-TDBUJUYH.js +109 -0
  15. package/dist/{chunk-GJC2CI3W.js → chunk-UIEQIJXP.js} +108 -336
  16. package/dist/chunk-X5GL2FCU.js +344 -0
  17. package/dist/chunk-ZRGZBAVS.js +98 -0
  18. package/dist/cli.js +352 -297
  19. package/dist/{index-projection-ESBJOBS7.js → index-projection-2K672CBO.js} +5 -3
  20. package/dist/journal-QU5IDXQF.js +13 -0
  21. package/dist/{managed-write-preflight-MAIGWFQJ.js → managed-write-preflight-GRSHQYKC.js} +7 -4
  22. package/dist/migrate-PIB4QA54.js +21 -0
  23. package/dist/ready-S7F53Q2D.js +9 -0
  24. package/dist/runtime-GLMI5OCT.js +15 -0
  25. package/dist/skillwiki-mcp.js +12 -7
  26. package/dist/sources-D2MGP246.js +10 -0
  27. package/dist/upload-HTE62TOV.js +14 -0
  28. package/dist/watcher-MHG46J3R.js +616 -0
  29. package/docs/clip-outbox.md +119 -0
  30. package/package.json +5 -1
  31. package/skills/.claude-plugin/plugin.json +1 -1
  32. package/skills/.codex-plugin/plugin.json +1 -1
  33. package/skills/.cursor-plugin/plugin.json +1 -1
  34. package/skills/package.json +1 -1
  35. package/skills/skills/using-skillwiki/SKILL.md +1 -1
  36. package/skills/skills/wiki-init/SKILL.md +12 -11
  37. package/skills/using-skillwiki/SKILL.md +1 -1
  38. package/skills/wiki-init/SKILL.md +12 -11
  39. package/templates/launchd/com.karlchow.skillwiki-clip-outbox.plist +21 -0
  40. package/templates/web-clipper/llm-wiki-clippings.json +1 -1
  41. package/templates/web-clipper/readme.txt +13 -13
  42. package/dist/sources-QTQSZMST.js +0 -9
@@ -1,8 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- atomicWriteText,
4
- buildRootIndexUniverse
5
- } from "./chunk-HMHMCPCE.js";
6
2
  import {
7
3
  authorizeRawOperation,
8
4
  buildSourceReferenceIndex,
@@ -22,17 +18,14 @@ import {
22
18
  resolveExistingRegularFileInsideVault,
23
19
  stripFencedBlocks,
24
20
  writeLogEvent
25
- } from "./chunk-JCDAEZVD.js";
21
+ } from "./chunk-5IBLXGLY.js";
22
+ import {
23
+ buildRootIndexUniverse
24
+ } from "./chunk-I6IRJCUJ.js";
26
25
  import {
27
- ExitCode,
28
- FleetManifestSchema,
29
- err,
30
26
  extractFrontmatter,
31
27
  filterGitIgnoredRelativePaths,
32
- getErrorMessage,
33
- isVaultSyncKey,
34
28
  mapWithConcurrency,
35
- ok,
36
29
  readPage,
37
30
  readPageCached,
38
31
  redactSensitiveContent,
@@ -41,130 +34,33 @@ import {
41
34
  scanVault,
42
35
  splitFrontmatter,
43
36
  vaultIoConcurrency
44
- } from "./chunk-GJC2CI3W.js";
45
-
46
- // src/utils/home.ts
47
- import { homedir } from "os";
48
- import { resolve } from "path";
49
- function resolveSkillwikiHome(home, env = process.env) {
50
- for (const candidate of [home, env.HOME, env.USERPROFILE]) {
51
- if (candidate?.trim()) return resolve(candidate);
52
- }
53
- try {
54
- const fallback = homedir();
55
- if (fallback?.trim()) return resolve(fallback);
56
- } catch {
57
- throw new Error("Could not resolve SkillWiki home directory");
58
- }
59
- throw new Error("Could not resolve SkillWiki home directory");
60
- }
37
+ } from "./chunk-X5GL2FCU.js";
38
+ import {
39
+ parseDotenvFile,
40
+ parseDotenvText,
41
+ profileKey,
42
+ resolveSkillwikiHome
43
+ } from "./chunk-PYPPG7RF.js";
44
+ import {
45
+ atomicWriteText
46
+ } from "./chunk-GQWCTJTU.js";
47
+ import {
48
+ ExitCode,
49
+ FleetManifestSchema,
50
+ err,
51
+ getErrorMessage,
52
+ ok
53
+ } from "./chunk-UIEQIJXP.js";
61
54
 
62
55
  // src/utils/managed-write-preflight.ts
63
56
  import { existsSync as existsSync11 } from "fs";
64
- import { join as join21, resolve as resolve7 } from "path";
57
+ import { join as join21, resolve as resolve6 } from "path";
65
58
 
66
59
  // src/commands/fleet.ts
67
- import { readFile as readFile2 } from "fs/promises";
60
+ import { readFile } from "fs/promises";
68
61
  import { hostname as nodeHostname, userInfo } from "os";
69
62
  import { join } from "path";
70
63
  import yaml from "js-yaml";
71
-
72
- // src/utils/dotenv.ts
73
- import { readFile, writeFile, mkdir } from "fs/promises";
74
- import { dirname } from "path";
75
- var CONFIG_KEYS = [
76
- "WIKI_PATH",
77
- "WIKI_LANG",
78
- "SKILLWIKI_HOST_ID",
79
- "AUTO_COMMIT",
80
- "BACKUP_ENDPOINT",
81
- "BACKUP_BUCKET",
82
- "BACKUP_REGION",
83
- "BACKUP_ACCESS_KEY_ID",
84
- "BACKUP_SECRET_ACCESS_KEY"
85
- ];
86
- var MCP_AUTH_KEYS = ["SKILLWIKI_MCP_TOKEN", "SKILLWIKI_MCP_URL"];
87
- var _whitelist = /* @__PURE__ */ new Set([...CONFIG_KEYS, ...MCP_AUTH_KEYS]);
88
- var PROFILE_PATH_RE = /^WIKI_([A-Z][A-Z0-9_]{0,31})_PATH$/;
89
- var PROFILE_LANG_RE = /^WIKI_([A-Z][A-Z0-9_]{0,31})_LANG$/;
90
- var PROFILE_DEFAULT_RE = /^WIKI_DEFAULT$/;
91
- function isValidWikiProfileKey(key) {
92
- if (key === "WIKI_PATH" || key === "WIKI_LANG") return false;
93
- return PROFILE_PATH_RE.test(key) || PROFILE_LANG_RE.test(key) || PROFILE_DEFAULT_RE.test(key);
94
- }
95
- function profileKey(name, suffix) {
96
- return `WIKI_${name.toUpperCase().replace(/-/g, "_").replace(/[^A-Z0-9_]/g, "")}_${suffix}`;
97
- }
98
- function parseDotenvText(text) {
99
- const out = {};
100
- for (const rawLine of text.split(/\r?\n/)) {
101
- const line = rawLine.trim();
102
- if (line.length === 0 || line.startsWith("#")) continue;
103
- const eq = line.indexOf("=");
104
- if (eq <= 0) continue;
105
- const key = line.slice(0, eq).trim();
106
- const value = line.slice(eq + 1).trim();
107
- if (!_whitelist.has(key) && !isValidWikiProfileKey(key) && !isVaultSyncKey(key)) continue;
108
- if (value.length === 0) continue;
109
- out[key] = value;
110
- }
111
- return out;
112
- }
113
- async function parseDotenvFile(path) {
114
- let text;
115
- try {
116
- text = await readFile(path, "utf8");
117
- } catch {
118
- return {};
119
- }
120
- return parseDotenvText(text);
121
- }
122
- async function writeDotenv(filePath, entries, originalContent) {
123
- const lines = originalContent !== void 0 ? updateLines(originalContent, entries) : freshLines(entries);
124
- await mkdir(dirname(filePath), { recursive: true });
125
- await writeFile(filePath, lines.join("\n") + "\n", "utf8");
126
- }
127
- function freshLines(entries) {
128
- const out = [];
129
- for (const [key, value] of Object.entries(entries)) {
130
- if (value !== void 0) out.push(`${key}=${value}`);
131
- }
132
- return out;
133
- }
134
- function updateLines(originalContent, entries) {
135
- let rawLines = originalContent.split(/\r?\n/);
136
- if (rawLines.length > 0 && rawLines[rawLines.length - 1] === "") {
137
- rawLines = rawLines.slice(0, -1);
138
- }
139
- const keysToWrite = new Set(Object.keys(entries));
140
- const out = [];
141
- for (const line of rawLines) {
142
- const trimmed = line.trim();
143
- if (trimmed.length === 0 || trimmed.startsWith("#")) {
144
- out.push(line);
145
- continue;
146
- }
147
- const eq = trimmed.indexOf("=");
148
- if (eq <= 0) {
149
- out.push(line);
150
- continue;
151
- }
152
- const key = trimmed.slice(0, eq).trim();
153
- if (keysToWrite.has(key)) {
154
- out.push(`${key}=${entries[key]}`);
155
- keysToWrite.delete(key);
156
- } else {
157
- out.push(line);
158
- }
159
- }
160
- for (const key of keysToWrite) {
161
- const value = entries[key];
162
- if (value !== void 0) out.push(`${key}=${value}`);
163
- }
164
- return out;
165
- }
166
-
167
- // src/commands/fleet.ts
168
64
  var FLEET_REL_PATH = join("projects", "llm-wiki", "architecture", "fleet.yaml");
169
65
  async function runFleetValidate(input) {
170
66
  const loaded = await loadFleetManifest(input.file);
@@ -376,7 +272,7 @@ function satelliteGateFromFleetLoad(load) {
376
272
  async function loadFleetManifest(file) {
377
273
  let text;
378
274
  try {
379
- text = await readFile2(file, "utf8");
275
+ text = await readFile(file, "utf8");
380
276
  } catch {
381
277
  return { ok: false, error: "FILE_NOT_FOUND" };
382
278
  }
@@ -954,7 +850,7 @@ function collectLintErrorFingerprints(output) {
954
850
 
955
851
  // src/lint/rules.ts
956
852
  import { existsSync as existsSync4 } from "fs";
957
- import { readFile as readFile13 } from "fs/promises";
853
+ import { readFile as readFile12 } from "fs/promises";
958
854
  import { join as join13 } from "path";
959
855
 
960
856
  // src/parsers/wikilinks.ts
@@ -1062,7 +958,7 @@ ${broken.map((b) => ` ${b.page}:[[${b.slug}]] (line ${b.line})`).join("\n")}` }
1062
958
  }
1063
959
 
1064
960
  // src/commands/tag-audit.ts
1065
- import { readFile as readFile3 } from "fs/promises";
961
+ import { readFile as readFile2 } from "fs/promises";
1066
962
  import { join as join4 } from "path";
1067
963
 
1068
964
  // src/parsers/taxonomy.ts
@@ -1216,7 +1112,7 @@ async function runTagAudit(input) {
1216
1112
  const scanResult = input.scan ? ok(input.scan) : await scanVault(input.vault);
1217
1113
  if (!scanResult.ok) return { exitCode: ExitCode.VAULT_PATH_INVALID, result: scanResult };
1218
1114
  const scan = scanResult.data;
1219
- const schemaText = await readFile3(join4(input.vault, "SCHEMA.md"), "utf8");
1115
+ const schemaText = await readFile2(join4(input.vault, "SCHEMA.md"), "utf8");
1220
1116
  const tax = extractTaxonomy(schemaText);
1221
1117
  if (!tax.ok) return { exitCode: ExitCode.INVALID_FRONTMATTER, result: tax };
1222
1118
  const allowed = new Set(tax.data);
@@ -1248,7 +1144,7 @@ async function runTagAudit(input) {
1248
1144
  }
1249
1145
 
1250
1146
  // src/commands/index-check.ts
1251
- import { readFile as readFile4 } from "fs/promises";
1147
+ import { readFile as readFile3 } from "fs/promises";
1252
1148
  import { join as join5 } from "path";
1253
1149
  function normalizeIndexTarget(raw) {
1254
1150
  return raw.replace(/\.md$/, "").replace(/^\.?\//, "");
@@ -1261,7 +1157,7 @@ async function runIndexCheck(input) {
1261
1157
  }
1262
1158
  let indexText = "";
1263
1159
  try {
1264
- indexText = await readFile4(join5(input.vault, "index.md"), "utf8");
1160
+ indexText = await readFile3(join5(input.vault, "index.md"), "utf8");
1265
1161
  } catch {
1266
1162
  }
1267
1163
  const indexTargets = /* @__PURE__ */ new Set();
@@ -1315,13 +1211,13 @@ async function runIndexCheck(input) {
1315
1211
  }
1316
1212
 
1317
1213
  // src/commands/index-link-format.ts
1318
- import { readFile as readFile5 } from "fs/promises";
1214
+ import { readFile as readFile4 } from "fs/promises";
1319
1215
  import { join as join6 } from "path";
1320
1216
  var MD_LINK_RE = /\[[^\[\]]+\]\([^)]+\.md\)/;
1321
1217
  async function runIndexLinkFormat(input) {
1322
1218
  let text = "";
1323
1219
  try {
1324
- text = await readFile5(join6(input.vault, "index.md"), "utf8");
1220
+ text = await readFile4(join6(input.vault, "index.md"), "utf8");
1325
1221
  } catch {
1326
1222
  }
1327
1223
  const markdown_links = [];
@@ -1334,7 +1230,7 @@ ${markdown_links.map((l) => ` line ${l.line}: ${l.text}`).join("\n")}`;
1334
1230
  }
1335
1231
 
1336
1232
  // src/commands/stale.ts
1337
- import { readdir as readdir2, rename, mkdir as mkdir3, readFile as readFile7 } from "fs/promises";
1233
+ import { readdir as readdir2, rename, mkdir as mkdir2, readFile as readFile6 } from "fs/promises";
1338
1234
  import { join as join7 } from "path";
1339
1235
 
1340
1236
  // src/parsers/expiry-annotations.ts
@@ -1373,9 +1269,9 @@ function parseExpiryAnnotations(content, pagePath) {
1373
1269
 
1374
1270
  // src/utils/raw-structural-transaction.ts
1375
1271
  import { createHash } from "crypto";
1376
- import { copyFile, mkdir as mkdir2, readFile as readFile6, unlink } from "fs/promises";
1272
+ import { copyFile, mkdir, readFile as readFile5, unlink } from "fs/promises";
1377
1273
  import { constants } from "fs";
1378
- import { dirname as dirname2 } from "path";
1274
+ import { dirname } from "path";
1379
1275
  function sha256(bytes) {
1380
1276
  return createHash("sha256").update(bytes).digest("hex");
1381
1277
  }
@@ -1429,7 +1325,7 @@ async function planRawStructuralMove(input) {
1429
1325
  if (!destinationResolved.ok) {
1430
1326
  return destinationResolved.error === "RAW_DESTINATION_EXISTS" ? destinationResolved : err("RAW_DESTINATION_UNSAFE", { path: input.destination, cause: destinationResolved });
1431
1327
  }
1432
- const sourceBytes = await readFile6(sourceResolved.data);
1328
+ const sourceBytes = await readFile5(sourceResolved.data);
1433
1329
  const sourceSha = sha256(sourceBytes);
1434
1330
  const operation_id = operationId("raw-structural", [input.operation, input.source, input.destination, sourceSha]);
1435
1331
  const base = {
@@ -1456,13 +1352,13 @@ async function applyRawStructuralMove(input) {
1456
1352
  }
1457
1353
  const sourceAbs = sourceResolved.data;
1458
1354
  const destinationAbs = destinationResolved.data;
1459
- await mkdir2(dirname2(destinationAbs), { recursive: true });
1355
+ await mkdir(dirname(destinationAbs), { recursive: true });
1460
1356
  try {
1461
1357
  await copyFile(sourceAbs, destinationAbs, constants.COPYFILE_EXCL);
1462
1358
  } catch (error) {
1463
1359
  return err("RAW_MOVE_COPY_FAILED", { source: input.source, destination: input.destination, message: String(error) });
1464
1360
  }
1465
- const destinationBytes = await readFile6(destinationAbs);
1361
+ const destinationBytes = await readFile5(destinationAbs);
1466
1362
  const destinationSha = sha256(destinationBytes);
1467
1363
  if (destinationSha !== planned.data.source_sha256) {
1468
1364
  return err("RAW_MOVE_HASH_MISMATCH", { source: input.source, destination: input.destination, source_sha256: planned.data.source_sha256, destination_sha256: destinationSha });
@@ -1643,7 +1539,7 @@ async function runStale(input) {
1643
1539
  for (const f of files) {
1644
1540
  if (!f.endsWith(".md")) continue;
1645
1541
  try {
1646
- const fm = extractFrontmatter(await readFile7(join7(absDir, f), "utf8"));
1542
+ const fm = extractFrontmatter(await readFile6(join7(absDir, f), "utf8"));
1647
1543
  if (fm.ok && typeof fm.data.status === "string") {
1648
1544
  status = fm.data.status;
1649
1545
  break;
@@ -1705,7 +1601,7 @@ async function runStale(input) {
1705
1601
  const claimSources = await mapWithConcurrency([...workDirs.keys()], vaultIoConcurrency(), async (relDir) => {
1706
1602
  const specPath = join7(input.vault, relDir, "spec.md");
1707
1603
  try {
1708
- const specContent = await readFile7(specPath, "utf8");
1604
+ const specContent = await readFile6(specPath, "utf8");
1709
1605
  const specFm = extractFrontmatter(specContent);
1710
1606
  if (!specFm.ok) return null;
1711
1607
  return {
@@ -1869,7 +1765,7 @@ async function runStale(input) {
1869
1765
  if (input.approve !== approvalToken) {
1870
1766
  return { exitCode: ExitCode.USAGE, result: { ok: false, error: "APPROVAL_INVALID", detail: { message: "stale archive approval does not match live state", approval_token: approvalToken } } };
1871
1767
  }
1872
- await mkdir3(archiveDir, { recursive: true });
1768
+ await mkdir2(archiveDir, { recursive: true });
1873
1769
  for (const plan of rawPlans) {
1874
1770
  const moved = await applyRawStructuralMove({
1875
1771
  vault: input.vault,
@@ -1887,7 +1783,7 @@ async function runStale(input) {
1887
1783
  if (active) {
1888
1784
  const { project: slug, item: itemName } = active;
1889
1785
  const histDir = join7(input.vault, "projects", slug, "history", "archived-work");
1890
- await mkdir3(histDir, { recursive: true });
1786
+ await mkdir2(histDir, { recursive: true });
1891
1787
  const dest = join7(histDir, itemName);
1892
1788
  try {
1893
1789
  await rename(join7(input.vault, w.path), dest);
@@ -1954,7 +1850,7 @@ async function runPagesize(input) {
1954
1850
  }
1955
1851
 
1956
1852
  // src/commands/log-rotate.ts
1957
- import { access, readFile as readFile8, rename as rename2, writeFile as writeFile2, stat } from "fs/promises";
1853
+ import { access, readFile as readFile7, rename as rename2, writeFile, stat } from "fs/promises";
1958
1854
  import { join as join8 } from "path";
1959
1855
  var ENTRY_RE = /^## \[(\d{4})-\d{2}-\d{2}\]/gm;
1960
1856
  var FULL_DATE_RE = /^## \[(\d{4}-\d{2}-\d{2})\]/gm;
@@ -1978,7 +1874,7 @@ function archiveNameForExistingYearLog(existingText, fallbackYear) {
1978
1874
  }
1979
1875
  async function sidelineExistingYearLog(vault, rotatedPath, fallbackYear) {
1980
1876
  if (!await pathExists(rotatedPath)) return void 0;
1981
- const existingText = await readFile8(rotatedPath, "utf8");
1877
+ const existingText = await readFile7(rotatedPath, "utf8");
1982
1878
  let archiveName = archiveNameForExistingYearLog(existingText, fallbackYear);
1983
1879
  let archivePath = join8(vault, archiveName);
1984
1880
  if (await pathExists(archivePath)) {
@@ -1998,7 +1894,7 @@ async function runLogRotate(input) {
1998
1894
  const logPath = join8(input.vault, "log.md");
1999
1895
  let logText;
2000
1896
  try {
2001
- logText = await readFile8(logPath, "utf8");
1897
+ logText = await readFile7(logPath, "utf8");
2002
1898
  } catch {
2003
1899
  return { exitCode: ExitCode.FILE_NOT_FOUND, result: err("FILE_NOT_FOUND", { path: logPath }) };
2004
1900
  }
@@ -2033,7 +1929,7 @@ Chronological action log. Newest entries last. Skill writes append entries; lint
2033
1929
  ## [${today}] rotate | Log rotated from ${entries} entries
2034
1930
 
2035
1931
  - Previous log moved to ${rotatedName}${sidelineNote}`;
2036
- await writeFile2(logPath, fresh, "utf8");
1932
+ await writeFile(logPath, fresh, "utf8");
2037
1933
  } catch (e) {
2038
1934
  return { exitCode: ExitCode.WRITE_FAILED, result: err("WRITE_FAILED", { message: String(e) }) };
2039
1935
  }
@@ -2430,7 +2326,7 @@ async function runTopicMapCheck(input) {
2430
2326
  // src/commands/dedup.ts
2431
2327
  import { createHash as createHash3 } from "crypto";
2432
2328
  import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
2433
- import { dirname as dirname3, join as join10, posix, resolve as resolve2 } from "path";
2329
+ import { dirname as dirname2, join as join10, posix, resolve } from "path";
2434
2330
 
2435
2331
  // src/utils/rclone.ts
2436
2332
  import { execFile } from "child_process";
@@ -2480,7 +2376,7 @@ async function defaultRcloneRunner(args) {
2480
2376
  }
2481
2377
 
2482
2378
  // src/utils/safe-write.ts
2483
- import { readFile as readFile9, writeFile as writeFile3 } from "fs/promises";
2379
+ import { readFile as readFile8, writeFile as writeFile2 } from "fs/promises";
2484
2380
  var DEFAULT_MIN_BODY_RATIO = 0.5;
2485
2381
  var DEFAULT_MIN_OLD_BODY_BYTES = 200;
2486
2382
  function bodyBytes(text) {
@@ -2490,7 +2386,7 @@ function bodyBytes(text) {
2490
2386
  }
2491
2387
  async function readIfExists(absPath) {
2492
2388
  try {
2493
- return await readFile9(absPath, "utf8");
2389
+ return await readFile8(absPath, "utf8");
2494
2390
  } catch (e) {
2495
2391
  if (e.code === "ENOENT") return null;
2496
2392
  throw e;
@@ -2602,11 +2498,11 @@ ${rewrittenFrontmatter}
2602
2498
 
2603
2499
  // src/utils/maintained-page-state.ts
2604
2500
  import { createHash as createHash2 } from "crypto";
2605
- import { readFile as readFile10 } from "fs/promises";
2501
+ import { readFile as readFile9 } from "fs/promises";
2606
2502
  async function snapshotMaintainedPageState(pages) {
2607
2503
  const entries = await Promise.all(
2608
2504
  pages.filter((page) => !page.relPath.startsWith("raw/")).map(async (page) => {
2609
- const bytes = await readFile10(page.absPath);
2505
+ const bytes = await readFile9(page.absPath);
2610
2506
  return `${page.relPath}:${createHash2("sha256").update(bytes).digest("hex")}`;
2611
2507
  })
2612
2508
  );
@@ -2665,7 +2561,7 @@ async function runDedup(input) {
2665
2561
  const manifest = safeEntries.length > 0 ? {
2666
2562
  version: 1,
2667
2563
  created_at: (/* @__PURE__ */ new Date()).toISOString(),
2668
- vault: resolve2(input.vault),
2564
+ vault: resolve(input.vault),
2669
2565
  entries: safeEntries
2670
2566
  } : void 0;
2671
2567
  const remoteDeleteCount = safeEntries.reduce((count, entry) => count + entry.duplicates.length, 0);
@@ -2692,7 +2588,7 @@ async function runDedup(input) {
2692
2588
  }
2693
2589
  if (input.manifestOut && manifest) {
2694
2590
  try {
2695
- mkdirSync2(dirname3(input.manifestOut), { recursive: true });
2591
+ mkdirSync2(dirname2(input.manifestOut), { recursive: true });
2696
2592
  writeFileSync2(input.manifestOut, `${JSON.stringify(manifest, null, 2)}
2697
2593
  `, "utf-8");
2698
2594
  } catch (e) {
@@ -2859,11 +2755,11 @@ function readManifest(path) {
2859
2755
  }
2860
2756
  }
2861
2757
  function validateManifestLocalState(vault, manifest) {
2862
- if (resolve2(manifest.vault) !== resolve2(vault)) {
2758
+ if (resolve(manifest.vault) !== resolve(vault)) {
2863
2759
  return err("APPROVAL_INVALID", {
2864
2760
  message: "dedup manifest belongs to a different vault",
2865
2761
  manifest_vault: manifest.vault,
2866
- vault: resolve2(vault)
2762
+ vault: resolve(vault)
2867
2763
  });
2868
2764
  }
2869
2765
  for (const entry of manifest.entries) {
@@ -2944,12 +2840,12 @@ async function runRawBodyDedup(vault, scan, pageTextCache) {
2944
2840
  }
2945
2841
 
2946
2842
  // src/commands/audit.ts
2947
- import { readFile as readFile11, stat as stat2 } from "fs/promises";
2948
- import { dirname as dirname4, resolve as resolve3, join as join11 } from "path";
2843
+ import { readFile as readFile10, stat as stat2 } from "fs/promises";
2844
+ import { dirname as dirname3, resolve as resolve2, join as join11 } from "path";
2949
2845
  async function runAudit(input) {
2950
2846
  let text;
2951
2847
  try {
2952
- text = await readFile11(input.file, "utf8");
2848
+ text = await readFile10(input.file, "utf8");
2953
2849
  } catch {
2954
2850
  return { exitCode: ExitCode.FILE_NOT_FOUND, result: err("FILE_NOT_FOUND", { path: input.file }) };
2955
2851
  }
@@ -2957,7 +2853,7 @@ async function runAudit(input) {
2957
2853
  if (!fm.ok) return { exitCode: ExitCode.INVALID_FRONTMATTER, result: fm };
2958
2854
  const split = splitFrontmatter(text);
2959
2855
  const body = split.ok ? split.data.body : text;
2960
- const vault = await findVaultRoot(dirname4(resolve3(input.file)));
2856
+ const vault = await findVaultRoot(dirname3(resolve2(input.file)));
2961
2857
  if (!vault) return { exitCode: ExitCode.VAULT_PATH_INVALID, result: err("VAULT_PATH_INVALID") };
2962
2858
  const markers = extractCitationMarkers(body);
2963
2859
  const resolved = await Promise.all(markers.map(async (m) => {
@@ -3009,7 +2905,7 @@ async function findVaultRoot(start) {
3009
2905
  return cur;
3010
2906
  } catch {
3011
2907
  }
3012
- const parent = dirname4(cur);
2908
+ const parent = dirname3(cur);
3013
2909
  if (parent === cur) return null;
3014
2910
  cur = parent;
3015
2911
  }
@@ -3058,8 +2954,8 @@ async function validateCompoundReferences(vault, existingScan, pageTextCache) {
3058
2954
 
3059
2955
  // src/commands/path-too-long.ts
3060
2956
  import { existsSync as existsSync3 } from "fs";
3061
- import { mkdir as mkdir4, readFile as readFile12, rename as rename3, unlink as unlink2 } from "fs/promises";
3062
- import { dirname as dirname5, join as join12, posix as posix2, resolve as resolve4 } from "path";
2957
+ import { mkdir as mkdir3, readFile as readFile11, rename as rename3, unlink as unlink2 } from "fs/promises";
2958
+ import { dirname as dirname4, join as join12, posix as posix2, resolve as resolve3 } from "path";
3063
2959
  var MAX_PATH_LENGTH = 240;
3064
2960
  var WINDOWS_ABSOLUTE_PATH_LIMIT = 259;
3065
2961
  async function runPathTooLong(input) {
@@ -3098,7 +2994,7 @@ async function fixPathTooLong(input) {
3098
2994
  if (target.mode === "dedupe") {
3099
2995
  await unlink2(join12(input.vault, violation.relPath));
3100
2996
  } else {
3101
- await mkdir4(dirname5(join12(input.vault, target.relPath)), { recursive: true });
2997
+ await mkdir3(dirname4(join12(input.vault, target.relPath)), { recursive: true });
3102
2998
  await rename3(join12(input.vault, violation.relPath), join12(input.vault, target.relPath));
3103
2999
  }
3104
3000
  fixed.push({ from: violation.relPath, to: target.relPath });
@@ -3113,7 +3009,7 @@ async function fixPathTooLong(input) {
3113
3009
  for (const page of afterScan.data.allMarkdown) {
3114
3010
  if (!shouldRewriteReferences(page.relPath)) continue;
3115
3011
  try {
3116
- const original = await readFile12(page.absPath, "utf8");
3012
+ const original = await readFile11(page.absPath, "utf8");
3117
3013
  let updated = original;
3118
3014
  for (const fix of fixed) {
3119
3015
  updated = replacePathReferences(updated, fix.from, fix.to);
@@ -3152,7 +3048,7 @@ function findPathTooLongViolations(pages, maxLength) {
3152
3048
  }
3153
3049
  function maxFixPathLength(vault) {
3154
3050
  if (process.platform !== "win32") return MAX_PATH_LENGTH;
3155
- const root = resolve4(vault);
3051
+ const root = resolve3(vault);
3156
3052
  const separatorBudget = root.endsWith("\\") || root.endsWith("/") ? 0 : 1;
3157
3053
  const absoluteSafeRelLength = WINDOWS_ABSOLUTE_PATH_LIMIT - root.length - separatorBudget;
3158
3054
  return Math.max(1, Math.min(MAX_PATH_LENGTH, absoluteSafeRelLength));
@@ -3204,7 +3100,7 @@ function candidateRelPaths(preferred, maxLength) {
3204
3100
  }
3205
3101
  async function hasSameContent(a, b) {
3206
3102
  try {
3207
- const [left, right] = await Promise.all([readFile12(a), readFile12(b)]);
3103
+ const [left, right] = await Promise.all([readFile11(a), readFile11(b)]);
3208
3104
  return left.equals(right);
3209
3105
  } catch {
3210
3106
  return false;
@@ -3352,6 +3248,10 @@ function buildCliSurface() {
3352
3248
  program.command("config");
3353
3249
  program.command("health").option("--wiki <name>").option("--sync <mode>").option("--no-fail").option("--out <path>").option("--examples <n>");
3354
3250
  program.command("doctor").option("--check-snapshotter").option("--check-mcp");
3251
+ const clipOutbox = program.command("clip-outbox");
3252
+ clipOutbox.command("status");
3253
+ clipOutbox.command("watch");
3254
+ clipOutbox.command("install-or-migrate").option("--load").option("--conditional-create-proven");
3355
3255
  program.command("connect").option("--from-file <path>").option("--from-stdin").option("--dry-run").option("--force");
3356
3256
  program.command("status").option("--wiki <name>");
3357
3257
  program.command("copy-status").option("--wiki <name>");
@@ -3706,7 +3606,7 @@ async function applyFileSourceUrlFix(input, scan, fileSourceUrlFlags, fileSource
3706
3606
  }
3707
3607
  try {
3708
3608
  const absPath = `${input.vault}/${relPath}`;
3709
- const raw = await readFile13(absPath, "utf8");
3609
+ const raw = await readFile12(absPath, "utf8");
3710
3610
  const parts = raw.split("---", 3);
3711
3611
  if (parts.length < 3) {
3712
3612
  unresolved.push(relPath);
@@ -4321,7 +4221,7 @@ var legacyCitationStyleRule = {
4321
4221
  for (const relPath of legacyPages) {
4322
4222
  try {
4323
4223
  const absPath = `${ctx.input.vault}/${relPath}`;
4324
- const raw = await readFile13(absPath, "utf8");
4224
+ const raw = await readFile12(absPath, "utf8");
4325
4225
  const split = splitFrontmatter(raw);
4326
4226
  if (!split.ok) {
4327
4227
  ctx.unresolved.push(relPath);
@@ -4509,7 +4409,7 @@ var missingOverviewRule = {
4509
4409
  for (const relPath of noOverview) {
4510
4410
  try {
4511
4411
  const absPath = `${ctx.input.vault}/${relPath}`;
4512
- const raw = await readFile13(absPath, "utf8");
4412
+ const raw = await readFile12(absPath, "utf8");
4513
4413
  const split = splitFrontmatter(raw);
4514
4414
  if (!split.ok) {
4515
4415
  ctx.unresolved.push(relPath);
@@ -4601,7 +4501,7 @@ var wikilinkCitationRule = {
4601
4501
  for (const relPath of wikilinkCitationFlags) {
4602
4502
  try {
4603
4503
  const absPath = `${ctx.input.vault}/${relPath}`;
4604
- const raw = await readFile13(absPath, "utf8");
4504
+ const raw = await readFile12(absPath, "utf8");
4605
4505
  const split = splitFrontmatter(raw);
4606
4506
  if (!split.ok) {
4607
4507
  ctx.unresolved.push(relPath);
@@ -4746,7 +4646,7 @@ var missingTldrRule = {
4746
4646
  for (const relPath of missingTldrFlags) {
4747
4647
  try {
4748
4648
  const absPath = `${ctx.input.vault}/${relPath}`;
4749
- const raw = await readFile13(absPath, "utf8");
4649
+ const raw = await readFile12(absPath, "utf8");
4750
4650
  const split = splitFrontmatter(raw);
4751
4651
  if (!split.ok) {
4752
4652
  ctx.unresolved.push(relPath);
@@ -4876,7 +4776,7 @@ var orphanedProjectPagesRule = {
4876
4776
  const existing = knowledgeContentCache.get(slug);
4877
4777
  if (existing) return existing;
4878
4778
  const knowledgePath = join13(ctx.vault, "projects", slug, "knowledge.md");
4879
- const pending = existsSync4(knowledgePath) ? readFile13(knowledgePath, "utf8").catch(() => null) : Promise.resolve(null);
4779
+ const pending = existsSync4(knowledgePath) ? readFile12(knowledgePath, "utf8").catch(() => null) : Promise.resolve(null);
4880
4780
  knowledgeContentCache.set(slug, pending);
4881
4781
  return pending;
4882
4782
  };
@@ -5740,7 +5640,7 @@ function probeRemoteHealth(input) {
5740
5640
  import { spawnSync } from "child_process";
5741
5641
  import { existsSync as existsSync7 } from "fs";
5742
5642
  import { platform } from "os";
5743
- import { dirname as dirname6, join as join16 } from "path";
5643
+ import { dirname as dirname5, join as join16 } from "path";
5744
5644
  import { fileURLToPath } from "url";
5745
5645
  var HELPER_NAME = "wiki-pull-with-auto-resolve.sh";
5746
5646
  function candidateHelperPaths(input = { vault: "" }) {
@@ -5751,7 +5651,7 @@ function candidateHelperPaths(input = { vault: "" }) {
5751
5651
  let here = input.moduleDir;
5752
5652
  if (!here) {
5753
5653
  try {
5754
- here = dirname6(fileURLToPath(import.meta.url));
5654
+ here = dirname5(fileURLToPath(import.meta.url));
5755
5655
  } catch {
5756
5656
  here = void 0;
5757
5657
  }
@@ -6537,7 +6437,7 @@ import {
6537
6437
  writeFileSync as writeFileSync4
6538
6438
  } from "fs";
6539
6439
  import { hostname } from "os";
6540
- import { dirname as dirname7, join as join18, resolve as resolve5 } from "path";
6440
+ import { dirname as dirname6, join as join18, resolve as resolve4 } from "path";
6541
6441
  function managedWriteLockPath(vault) {
6542
6442
  const gitPath = git(vault, ["rev-parse", "--git-path", "vault-sync/managed-write.lock"]);
6543
6443
  if (gitPath) return gitPath.startsWith("/") ? gitPath : join18(vault, gitPath);
@@ -6582,7 +6482,7 @@ function hasLocalOwnerProof(vault, record) {
6582
6482
  }
6583
6483
  function reclaimDeadManagedWriteLockOwner(vault, options = {}) {
6584
6484
  const path = managedWriteLockPath(vault);
6585
- const gitStateVault = resolve5(options.gitStateVault ?? vault);
6485
+ const gitStateVault = resolve4(options.gitStateVault ?? vault);
6586
6486
  if (!existsSync9(path)) return ok({ reclaimed: false });
6587
6487
  const record = readLockRecord(path);
6588
6488
  if (!record) {
@@ -6607,7 +6507,7 @@ function reclaimDeadManagedWriteLockOwner(vault, options = {}) {
6607
6507
  });
6608
6508
  }
6609
6509
  try {
6610
- const recoveryDir = join18(dirname7(path), "recovery");
6510
+ const recoveryDir = join18(dirname6(path), "recovery");
6611
6511
  mkdirSync4(recoveryDir, { recursive: true });
6612
6512
  const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[-:]/g, "").replace(/\.\d+Z$/, "Z");
6613
6513
  const recoveryPath = join18(recoveryDir, `stale-managed-write-lock-${stamp}-${process.pid}.json`);
@@ -6630,7 +6530,7 @@ function tryCreateLock(path, command) {
6630
6530
  const ownerToken = randomBytes2(16).toString("hex");
6631
6531
  const acquired = (/* @__PURE__ */ new Date()).toISOString();
6632
6532
  try {
6633
- mkdirSync4(dirname7(path), { recursive: true });
6533
+ mkdirSync4(dirname6(path), { recursive: true });
6634
6534
  writeFileSync4(
6635
6535
  path,
6636
6536
  `${JSON.stringify({
@@ -6869,7 +6769,7 @@ function supersedeStaleReviewRequiredJournals(vault, opts = {}) {
6869
6769
 
6870
6770
  // src/utils/snapshot-worktree.ts
6871
6771
  import { readFileSync as readFileSync8 } from "fs";
6872
- import { join as join20, resolve as resolve6 } from "path";
6772
+ import { join as join20, resolve as resolve5 } from "path";
6873
6773
  function readSkillWikiConfig(path) {
6874
6774
  try {
6875
6775
  return parseDotenvText(readFileSync8(path, "utf8"));
@@ -6898,12 +6798,12 @@ function resolveConfiguredSnapshotWorktree(home) {
6898
6798
  if (!home) return void 0;
6899
6799
  const config = readSkillWikiConfig(join20(home, ".skillwiki", ".env"));
6900
6800
  const explicit = config["vault_sync.snapshot_worktree"];
6901
- if (explicit) return resolve6(explicit);
6801
+ if (explicit) return resolve5(explicit);
6902
6802
  const snapshotProfile = config["vault_sync.snapshot_profile"];
6903
6803
  if (!snapshotProfile) return void 0;
6904
- const profile = readSnapshotProfile(resolve6(snapshotProfile));
6804
+ const profile = readSnapshotProfile(resolve5(snapshotProfile));
6905
6805
  const fromProfile = profile.WIKI_GIT_WORKTREE ?? profile.SNAPSHOT_WORKTREE ?? profile.GIT_DIR;
6906
- return fromProfile ? resolve6(fromProfile) : void 0;
6806
+ return fromProfile ? resolve5(fromProfile) : void 0;
6907
6807
  }
6908
6808
 
6909
6809
  // src/utils/managed-write-preflight.ts
@@ -6920,7 +6820,7 @@ var DEFAULT_DEPS = {
6920
6820
  converge: (input) => runVaultSyncPullHelper(input),
6921
6821
  resolveConfiguredSnapshotWorktree,
6922
6822
  syncPeers: runSyncPeers,
6923
- sleepMs: (ms) => new Promise((resolve8) => setTimeout(resolve8, ms)),
6823
+ sleepMs: (ms) => new Promise((resolve7) => setTimeout(resolve7, ms)),
6924
6824
  nowMs: () => Date.now(),
6925
6825
  logHeartbeat: (message) => {
6926
6826
  process.stderr.write(`${message}
@@ -7112,8 +7012,8 @@ function isGitVault(vault) {
7112
7012
  return Boolean(git(vault, ["rev-parse", "--absolute-git-dir"]));
7113
7013
  }
7114
7014
  async function runManagedWritePreflight(input, deps = DEFAULT_DEPS) {
7115
- const mutationVault = resolve7(input.vault);
7116
- let convergenceVault = input.convergenceVault && resolve7(input.convergenceVault) !== mutationVault ? resolve7(input.convergenceVault) : void 0;
7015
+ const mutationVault = resolve6(input.vault);
7016
+ let convergenceVault = input.convergenceVault && resolve6(input.convergenceVault) !== mutationVault ? resolve6(input.convergenceVault) : void 0;
7117
7017
  let convergenceSource = convergenceVault ? "explicit" : "single-path";
7118
7018
  const mutationBlocker = preflightBlocker(mutationVault);
7119
7019
  if (mutationBlocker) {
@@ -7203,7 +7103,7 @@ async function runManagedWritePreflight(input, deps = DEFAULT_DEPS) {
7203
7103
  })
7204
7104
  };
7205
7105
  }
7206
- convergenceVault = resolve7(configured);
7106
+ convergenceVault = resolve6(configured);
7207
7107
  convergenceSource = "configured";
7208
7108
  if (convergenceVault === mutationVault) {
7209
7109
  return {
@@ -7312,9 +7212,9 @@ async function runManagedWritePreflight(input, deps = DEFAULT_DEPS) {
7312
7212
  };
7313
7213
  }
7314
7214
  async function runManagedWriteTransaction(input, deps = DEFAULT_DEPS) {
7315
- const mutationVault = resolve7(input.vault);
7215
+ const mutationVault = resolve6(input.vault);
7316
7216
  const lock = acquireManagedWriteLock(mutationVault, input.command, {
7317
- gitStateVault: input.convergenceVault ? resolve7(input.convergenceVault) : mutationVault
7217
+ gitStateVault: input.convergenceVault ? resolve6(input.convergenceVault) : mutationVault
7318
7218
  });
7319
7219
  if (!lock.ok) {
7320
7220
  return { exitCode: ExitCode.SYNC_LOCK_HELD, result: lock };
@@ -7367,7 +7267,6 @@ async function runManagedWriteTransaction(input, deps = DEFAULT_DEPS) {
7367
7267
  }
7368
7268
 
7369
7269
  export {
7370
- resolveSkillwikiHome,
7371
7270
  readLastOp,
7372
7271
  appendLastOp,
7373
7272
  clearLastOp,
@@ -7400,12 +7299,6 @@ export {
7400
7299
  runStale,
7401
7300
  runPagesize,
7402
7301
  runLogRotate,
7403
- CONFIG_KEYS,
7404
- isValidWikiProfileKey,
7405
- profileKey,
7406
- parseDotenvText,
7407
- parseDotenvFile,
7408
- writeDotenv,
7409
7302
  resolveInitTimePath,
7410
7303
  resolveRuntimePath,
7411
7304
  runOrphans,