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