skillwiki 0.10.110 → 0.10.112

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 (45) hide show
  1. package/dist/chunk-25OXNFDV.js +133 -0
  2. package/dist/{chunk-R2DJ7IJ5.js → chunk-7POLZOFY.js} +44 -375
  3. package/dist/chunk-ABRYBO4T.js +275 -0
  4. package/dist/{chunk-6X6PPQNI.js → chunk-APKDTEVV.js} +280 -446
  5. package/dist/{chunk-5MV5SSRM.js → chunk-CKQPUHM2.js} +5 -3
  6. package/dist/chunk-DOHWNPAZ.js +60 -0
  7. package/dist/chunk-EE7W3GLA.js +55 -0
  8. package/dist/chunk-FCA3RRNF.js +60 -0
  9. package/dist/{chunk-KX5Y3GSX.js → chunk-IR2DI4Y5.js} +5 -3
  10. package/dist/chunk-K3M6OSUW.js +77 -0
  11. package/dist/{chunk-WPJHDRTP.js → chunk-KJG2CSYD.js} +12 -57
  12. package/dist/chunk-LOVLZNLX.js +111 -0
  13. package/dist/chunk-OSL4J7GF.js +32 -0
  14. package/dist/{chunk-QU2CKXM4.js → chunk-Q6EZF37H.js} +91 -199
  15. package/dist/chunk-QESNTTVY.js +50 -0
  16. package/dist/{chunk-NA3TZ4JN.js → chunk-RR6VDWSI.js} +8 -6
  17. package/dist/chunk-SKOLE6US.js +126 -0
  18. package/dist/chunk-TKX6PSWZ.js +344 -0
  19. package/dist/chunk-ZRGZBAVS.js +98 -0
  20. package/dist/cli.js +359 -305
  21. package/dist/{index-projection-6XGESSHV.js → index-projection-UNZG5UJZ.js} +5 -3
  22. package/dist/journal-5IW3TZ5F.js +13 -0
  23. package/dist/{managed-write-preflight-JPOBVVSU.js → managed-write-preflight-L7IRQ76C.js} +7 -4
  24. package/dist/mcp-auth-env-X5MI5IX6.js +25 -0
  25. package/dist/migrate-RO4BJP5T.js +22 -0
  26. package/dist/mirror-H5BTBAON.js +151 -0
  27. package/dist/ready-S7F53Q2D.js +9 -0
  28. package/dist/runtime-VMFYW2K3.js +20 -0
  29. package/dist/skillwiki-mcp.js +14 -7
  30. package/dist/sources-AOYP6ROO.js +10 -0
  31. package/dist/upload-HTE62TOV.js +14 -0
  32. package/dist/watcher-MGHQD3UI.js +526 -0
  33. package/docs/clip-outbox.md +119 -0
  34. package/package.json +5 -1
  35. package/skills/.claude-plugin/plugin.json +1 -1
  36. package/skills/.codex-plugin/plugin.json +1 -1
  37. package/skills/.cursor-plugin/plugin.json +1 -1
  38. package/skills/package.json +1 -1
  39. package/skills/skills/using-skillwiki/SKILL.md +1 -1
  40. package/skills/skills/wiki-init/SKILL.md +3 -0
  41. package/skills/using-skillwiki/SKILL.md +1 -1
  42. package/skills/wiki-init/SKILL.md +3 -0
  43. package/templates/launchd/com.karlchow.skillwiki-clip-outbox.plist +12 -13
  44. package/templates/launchd/com.karlchow.skillwiki-mirror-sse.plist +20 -0
  45. package/dist/sources-CLOF5VAT.js +0 -9
@@ -1,4 +1,17 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ applySourceCompileClaim,
4
+ applySourceCompilePublished,
5
+ applySourceCompileRelease,
6
+ applySourceReview,
7
+ listCompileStatus,
8
+ listSourceReviews,
9
+ planSourceCompileClaim,
10
+ planSourceCompilePublished,
11
+ planSourceCompileRelease,
12
+ planSourceReview,
13
+ runSourcesPending
14
+ } from "./chunk-RR6VDWSI.js";
2
15
  import {
3
16
  latestFromCache,
4
17
  semverGt
@@ -6,9 +19,8 @@ import {
6
19
  import {
7
20
  renderRootIndex,
8
21
  writeRootIndexProjection
9
- } from "./chunk-KX5Y3GSX.js";
22
+ } from "./chunk-IR2DI4Y5.js";
10
23
  import {
11
- CONFIG_KEYS,
12
24
  VAULT_HYGIENE_GENERATED_COMMIT_PATHS,
13
25
  VAULT_HYGIENE_GITIGNORE_PATTERNS,
14
26
  VAULT_SYNC_FILTER_REQUIRED_EXCLUDES,
@@ -18,20 +30,16 @@ import {
18
30
  communityCohesion,
19
31
  git,
20
32
  hasUnmergedPaths,
21
- isValidWikiProfileKey,
22
33
  listReviewRequiredOps,
23
34
  loadFleetManifestAndHost,
24
35
  louvain,
25
36
  missingIgnorePatterns,
26
- parseDotenvFile,
27
- parseDotenvText,
28
37
  probeGithubReachability,
29
38
  probeS3Reachability,
30
39
  probeSnapshotterSsh,
31
40
  releaseOwnedSyncLock,
32
41
  resolveConfiguredSnapshotWorktree,
33
42
  resolveRuntimePath,
34
- resolveSkillwikiHome,
35
43
  resolveVaultSyncPullHelper,
36
44
  resolveWikiS3Remote,
37
45
  runLint,
@@ -39,32 +47,54 @@ import {
39
47
  runStale,
40
48
  satelliteGateFromFleetLoad,
41
49
  snapshotterAliasForLocalHost,
42
- toUndirectedWeighted,
43
- writeDotenv
44
- } from "./chunk-QU2CKXM4.js";
50
+ toUndirectedWeighted
51
+ } from "./chunk-Q6EZF37H.js";
52
+ import {
53
+ eventPathFor,
54
+ writeLogEvent
55
+ } from "./chunk-CKQPUHM2.js";
45
56
  import {
46
- atomicWriteText,
47
57
  prepareTypedPage
48
- } from "./chunk-WPJHDRTP.js";
58
+ } from "./chunk-KJG2CSYD.js";
49
59
  import {
50
- applySourceCompileClaim,
51
- applySourceCompilePublished,
52
- applySourceCompileRelease,
53
- applySourceReview,
54
- listCompileStatus,
55
- listSourceReviews,
56
- planSourceCompileClaim,
57
- planSourceCompilePublished,
58
- planSourceCompileRelease,
59
- planSourceReview,
60
- runSourcesPending
61
- } from "./chunk-NA3TZ4JN.js";
60
+ extractFrontmatter,
61
+ readPage,
62
+ redactSensitiveContent,
63
+ resolveReadOnlyVaultRoot,
64
+ scanSensitiveContent,
65
+ scanVault,
66
+ splitFrontmatter
67
+ } from "./chunk-TKX6PSWZ.js";
62
68
  import {
63
- eventPathFor,
64
- writeLogEvent
65
- } from "./chunk-5MV5SSRM.js";
69
+ isMcpOnlyLeaf,
70
+ mcpAuthFromEnv,
71
+ mergeMcpAuthIntoEnv,
72
+ redactMcpSecret
73
+ } from "./chunk-DOHWNPAZ.js";
74
+ import {
75
+ xml
76
+ } from "./chunk-25OXNFDV.js";
77
+ import {
78
+ atomicWriteText
79
+ } from "./chunk-EE7W3GLA.js";
80
+ import {
81
+ CLIP_NOT_CONFIGURED,
82
+ PRODUCTION_MIRROR_LABEL,
83
+ PRODUCTION_WATCHER_LABEL,
84
+ RETIRED_WATCHER_LABELS,
85
+ conditionalCreateProven,
86
+ loadClipCredentials,
87
+ loadClipOutboxConfig
88
+ } from "./chunk-ABRYBO4T.js";
89
+ import {
90
+ CONFIG_KEYS,
91
+ isValidWikiProfileKey,
92
+ parseDotenvFile,
93
+ parseDotenvText,
94
+ resolveSkillwikiHome,
95
+ writeDotenv
96
+ } from "./chunk-SKOLE6US.js";
66
97
  import {
67
- CLIP_OUTBOX_DEFAULTS,
68
98
  CompoundSchema,
69
99
  ExitCode,
70
100
  MetaSchema,
@@ -73,20 +103,13 @@ import {
73
103
  WorkItemSchema,
74
104
  detectSchema,
75
105
  err,
76
- extractFrontmatter,
77
106
  isClipOutboxKey,
78
107
  isVaultSyncKey,
79
108
  ok,
80
109
  parseClipOutboxKeyValue,
81
110
  parseVaultSyncKeyValue,
82
- readPage,
83
- redactSensitiveContent,
84
- resolveReadOnlyVaultRoot,
85
- scanSensitiveContent,
86
- scanVault,
87
- splitFrontmatter,
88
111
  systemdPropertyFor
89
- } from "./chunk-R2DJ7IJ5.js";
112
+ } from "./chunk-7POLZOFY.js";
90
113
 
91
114
  // src/commands/log-append.ts
92
115
  import { readFile, stat } from "fs/promises";
@@ -1095,66 +1118,23 @@ async function runConfigPath(input) {
1095
1118
  return { exitCode: ExitCode.OK, result: ok({ path: filePath, exists: existsSync2(filePath), humanHint: filePath }) };
1096
1119
  }
1097
1120
 
1098
- // src/utils/mcp-auth-env.ts
1099
- import { join as join6 } from "path";
1100
- var MCP_URL_ENV = "SKILLWIKI_MCP_URL";
1101
- var MCP_TOKEN_ENV = "SKILLWIKI_MCP_TOKEN";
1102
- var MCP_HOST_ID_ENV = "SKILLWIKI_HOST_ID";
1103
- function nonEmptyEnvValue(value) {
1104
- if (typeof value !== "string") return void 0;
1105
- const trimmed = value.trim();
1106
- return trimmed.length > 0 ? trimmed : void 0;
1107
- }
1108
- function mcpAuthFromEnv(env) {
1109
- return {
1110
- url: nonEmptyEnvValue(env[MCP_URL_ENV]),
1111
- token: nonEmptyEnvValue(env[MCP_TOKEN_ENV]),
1112
- hostId: nonEmptyEnvValue(env[MCP_HOST_ID_ENV])
1113
- };
1114
- }
1115
- async function resolveMcpAuthEnv(input) {
1116
- const processAuth = mcpAuthFromEnv(input.env ?? process.env);
1117
- const dotenv = await parseDotenvFile(join6(resolveSkillwikiHome(input.home, input.env), ".skillwiki", ".env"));
1118
- const fileAuth = mcpAuthFromEnv(dotenv);
1119
- return {
1120
- url: processAuth.url ?? fileAuth.url,
1121
- token: processAuth.token ?? fileAuth.token,
1122
- hostId: processAuth.hostId ?? fileAuth.hostId
1123
- };
1124
- }
1125
- async function mergeMcpAuthIntoEnv(home, env) {
1126
- const auth = await resolveMcpAuthEnv({ home, env });
1127
- const merged = { ...env };
1128
- if (auth.url && !nonEmptyEnvValue(env[MCP_URL_ENV])) merged[MCP_URL_ENV] = auth.url;
1129
- if (auth.token && !nonEmptyEnvValue(env[MCP_TOKEN_ENV])) merged[MCP_TOKEN_ENV] = auth.token;
1130
- if (auth.hostId && !nonEmptyEnvValue(env[MCP_HOST_ID_ENV])) merged[MCP_HOST_ID_ENV] = auth.hostId;
1131
- return merged;
1132
- }
1133
- function redactMcpSecret(text, secret) {
1134
- if (!secret || secret.length === 0 || !text.includes(secret)) return text;
1135
- return text.split(secret).join("[REDACTED]");
1136
- }
1137
- function isMcpOnlyLeaf(input) {
1138
- return !input.resolvedPath && Boolean(input.token) && !input.vaultSyncInstalled;
1139
- }
1140
-
1141
1121
  // src/doctor/runner.ts
1142
- import { existsSync as existsSync20 } from "fs";
1122
+ import { existsSync as existsSync19 } from "fs";
1143
1123
 
1144
1124
  // src/doctor/probes/environment.ts
1145
1125
  import { existsSync as existsSync4, lstatSync, readlinkSync } from "fs";
1146
- import { resolve as resolve2, join as join8 } from "path";
1126
+ import { resolve as resolve2, join as join7 } from "path";
1147
1127
  import { execSync } from "child_process";
1148
1128
 
1149
1129
  // src/utils/plugin-registry.ts
1150
1130
  import { existsSync as existsSync3, readdirSync, readFileSync as readFileSync2 } from "fs";
1151
- import { join as join7 } from "path";
1152
- var REGISTRY_PATH = join7(".claude", "plugins", "installed_plugins.json");
1153
- var CODEX_CONFIG_PATH = join7(".codex", "config.toml");
1131
+ import { join as join6 } from "path";
1132
+ var REGISTRY_PATH = join6(".claude", "plugins", "installed_plugins.json");
1133
+ var CODEX_CONFIG_PATH = join6(".codex", "config.toml");
1154
1134
  var PLUGIN_KEY = "skillwiki@llm-wiki";
1155
1135
  function readInstalledPlugins(home) {
1156
1136
  try {
1157
- const raw = readFileSync2(join7(home, REGISTRY_PATH), "utf8");
1137
+ const raw = readFileSync2(join6(home, REGISTRY_PATH), "utf8");
1158
1138
  return JSON.parse(raw);
1159
1139
  } catch {
1160
1140
  return null;
@@ -1190,7 +1170,7 @@ function findPluginInstallations(home, key = PLUGIN_KEY) {
1190
1170
  return installs;
1191
1171
  }
1192
1172
  function findGrokPlugin(home, key, pluginName, marketplace) {
1193
- const pluginsRoot = join7(home, ".grok", "installed-plugins");
1173
+ const pluginsRoot = join6(home, ".grok", "installed-plugins");
1194
1174
  if (!existsSync3(pluginsRoot)) return null;
1195
1175
  let entries;
1196
1176
  try {
@@ -1201,10 +1181,10 @@ function findGrokPlugin(home, key, pluginName, marketplace) {
1201
1181
  let best = null;
1202
1182
  for (const entry of entries) {
1203
1183
  if (!entry.isDirectory()) continue;
1204
- const installPath = join7(pluginsRoot, entry.name);
1184
+ const installPath = join6(pluginsRoot, entry.name);
1205
1185
  let manifest;
1206
1186
  try {
1207
- manifest = JSON.parse(readFileSync2(join7(installPath, ".claude-plugin", "plugin.json"), "utf8"));
1187
+ manifest = JSON.parse(readFileSync2(join6(installPath, ".claude-plugin", "plugin.json"), "utf8"));
1208
1188
  } catch {
1209
1189
  continue;
1210
1190
  }
@@ -1228,7 +1208,7 @@ function findGrokPlugin(home, key, pluginName, marketplace) {
1228
1208
  function findCodexPlugin(home, key, pluginName, marketplace) {
1229
1209
  const config = readCodexPluginConfig(home, key, marketplace);
1230
1210
  if (!config?.enabled) return null;
1231
- const cacheRoot = join7(home, ".codex", "plugins", "cache", marketplace, pluginName);
1211
+ const cacheRoot = join6(home, ".codex", "plugins", "cache", marketplace, pluginName);
1232
1212
  if (!existsSync3(cacheRoot)) return null;
1233
1213
  let versions;
1234
1214
  try {
@@ -1244,7 +1224,7 @@ function findCodexPlugin(home, key, pluginName, marketplace) {
1244
1224
  key,
1245
1225
  pluginName,
1246
1226
  marketplace,
1247
- installPath: join7(cacheRoot, version),
1227
+ installPath: join6(cacheRoot, version),
1248
1228
  version,
1249
1229
  sourceType: config.sourceType,
1250
1230
  source: config.source
@@ -1261,7 +1241,7 @@ function parsePluginKey(key) {
1261
1241
  function readCodexPluginConfig(home, key, marketplace) {
1262
1242
  let raw;
1263
1243
  try {
1264
- raw = readFileSync2(join7(home, CODEX_CONFIG_PATH), "utf8");
1244
+ raw = readFileSync2(join6(home, CODEX_CONFIG_PATH), "utf8");
1265
1245
  } catch {
1266
1246
  return null;
1267
1247
  }
@@ -1338,12 +1318,12 @@ function detectCliChannels(argv, home) {
1338
1318
  }
1339
1319
  const plugin = findPlugin(home);
1340
1320
  if (plugin) {
1341
- const pluginBin = join8(plugin.installPath, "bin", "skillwiki");
1321
+ const pluginBin = join7(plugin.installPath, "bin", "skillwiki");
1342
1322
  if (existsSync4(pluginBin)) {
1343
1323
  channels.push({ name: "plugin", path: pluginBin, isDevLink: false });
1344
1324
  }
1345
1325
  }
1346
- const installBin = join8(home, ".claude", "skills", "bin", "skillwiki");
1326
+ const installBin = join7(home, ".claude", "skills", "bin", "skillwiki");
1347
1327
  if (existsSync4(installBin)) {
1348
1328
  channels.push({ name: "install", path: installBin, isDevLink: false });
1349
1329
  }
@@ -1435,7 +1415,7 @@ async function checkProfiles(home) {
1435
1415
  }
1436
1416
  async function checkProjectLocalOverride(cwd) {
1437
1417
  const dir = cwd ?? process.cwd();
1438
- const envPath = join8(dir, ".skillwiki", ".env");
1418
+ const envPath = join7(dir, ".skillwiki", ".env");
1439
1419
  if (existsSync4(envPath)) {
1440
1420
  return check("pass", "project_local", "Project-local config", `Found: ${envPath}`);
1441
1421
  }
@@ -1471,7 +1451,7 @@ var environmentProbe = {
1471
1451
 
1472
1452
  // src/doctor/probes/vault-structure.ts
1473
1453
  import { existsSync as existsSync5, statSync as statSync2 } from "fs";
1474
- import { join as join9 } from "path";
1454
+ import { join as join8 } from "path";
1475
1455
  function checkWikiPathExists(resolvedPath, mcpOnlyLeaf) {
1476
1456
  if (resolvedPath === void 0) {
1477
1457
  return mcpOnlyOr(
@@ -1499,9 +1479,9 @@ function checkVaultStructure(resolvedPath, mcpOnlyLeaf) {
1499
1479
  return check("error", "vault_structure", "Vault structure valid", "Cannot check \u2014 vault directory does not exist");
1500
1480
  }
1501
1481
  const missing = [];
1502
- if (!existsSync5(join9(resolvedPath, "SCHEMA.md"))) missing.push("SCHEMA.md");
1482
+ if (!existsSync5(join8(resolvedPath, "SCHEMA.md"))) missing.push("SCHEMA.md");
1503
1483
  for (const dir of ["raw", "entities", "concepts", "meta"]) {
1504
- if (!existsSync5(join9(resolvedPath, dir))) missing.push(dir + "/");
1484
+ if (!existsSync5(join8(resolvedPath, dir))) missing.push(dir + "/");
1505
1485
  }
1506
1486
  if (missing.length === 0) {
1507
1487
  return check("pass", "vault_structure", "Vault structure valid", "All required files and directories present");
@@ -1518,9 +1498,9 @@ function checkObsidianTemplates(resolvedPath, mcpOnlyLeaf) {
1518
1498
  );
1519
1499
  }
1520
1500
  const missing = [];
1521
- if (!existsSync5(join9(resolvedPath, "_Templates"))) missing.push("_Templates/");
1522
- if (!existsSync5(join9(resolvedPath, ".obsidian", "templates.json"))) missing.push(".obsidian/templates.json");
1523
- if (!existsSync5(join9(resolvedPath, ".obsidian", "app.json"))) missing.push(".obsidian/app.json");
1501
+ if (!existsSync5(join8(resolvedPath, "_Templates"))) missing.push("_Templates/");
1502
+ if (!existsSync5(join8(resolvedPath, ".obsidian", "templates.json"))) missing.push(".obsidian/templates.json");
1503
+ if (!existsSync5(join8(resolvedPath, ".obsidian", "app.json"))) missing.push(".obsidian/app.json");
1524
1504
  if (missing.length === 0) {
1525
1505
  return check("pass", "obsidian_templates", "Obsidian templates", "Template folder and config present");
1526
1506
  }
@@ -1539,7 +1519,7 @@ var vaultStructureProbe = {
1539
1519
 
1540
1520
  // src/doctor/probes/git-fleet.ts
1541
1521
  import { existsSync as existsSync6, readFileSync as readFileSync3 } from "fs";
1542
- import { join as join10 } from "path";
1522
+ import { join as join9 } from "path";
1543
1523
  import { execSync as execSync2 } from "child_process";
1544
1524
  import { platform } from "os";
1545
1525
  function checkVaultGitRemote(resolvedPath, mcpOnlyLeaf = false) {
@@ -1551,7 +1531,7 @@ function checkVaultGitRemote(resolvedPath, mcpOnlyLeaf = false) {
1551
1531
  check("error", "vault_git_remote", "Vault git remote", "Cannot check \u2014 WIKI_PATH not resolved")
1552
1532
  );
1553
1533
  }
1554
- if (!existsSync6(join10(resolvedPath, ".git"))) {
1534
+ if (!existsSync6(join9(resolvedPath, ".git"))) {
1555
1535
  return check("warn", "vault_git_remote", "Vault git remote", "Vault is not a git repository \u2014 sync features unavailable");
1556
1536
  }
1557
1537
  try {
@@ -1599,7 +1579,7 @@ function checkSyncLastPush(resolvedPath, mcpOnlyLeaf = false) {
1599
1579
  check("error", "sync_last_push", "Vault sync recency", "Cannot check \u2014 WIKI_PATH not resolved")
1600
1580
  );
1601
1581
  }
1602
- if (!existsSync6(join10(resolvedPath, ".git"))) {
1582
+ if (!existsSync6(join9(resolvedPath, ".git"))) {
1603
1583
  return check("pass", "sync_last_push", "Vault sync recency", "No git repo \u2014 sync check skipped");
1604
1584
  }
1605
1585
  let timestamp;
@@ -1648,7 +1628,7 @@ function checkVaultGitDirty(resolvedPath) {
1648
1628
  if (resolvedPath === void 0) {
1649
1629
  return check("pass", "vault_git_dirty", "Vault git dirty state", "No vault path \u2014 check skipped");
1650
1630
  }
1651
- if (!existsSync6(join10(resolvedPath, ".git"))) {
1631
+ if (!existsSync6(join9(resolvedPath, ".git"))) {
1652
1632
  return check("pass", "vault_git_dirty", "Vault git dirty state", "No git repo \u2014 check skipped");
1653
1633
  }
1654
1634
  try {
@@ -1695,7 +1675,7 @@ function remoteMainHash(resolvedPath) {
1695
1675
  }
1696
1676
  function checkStaleRemoteMain(resolvedPath) {
1697
1677
  if (resolvedPath === void 0) return void 0;
1698
- if (!existsSync6(join10(resolvedPath, ".git"))) return void 0;
1678
+ if (!existsSync6(join9(resolvedPath, ".git"))) return void 0;
1699
1679
  const localOrigin = gitRefHash(resolvedPath, "origin/main");
1700
1680
  if (!localOrigin) return void 0;
1701
1681
  const remoteMain = remoteMainHash(resolvedPath);
@@ -1711,7 +1691,7 @@ function checkVaultGitComparison(resolvedPath, id, label, range, nonZeroSuffix,
1711
1691
  if (resolvedPath === void 0) {
1712
1692
  return check("pass", id, label, "No vault path \u2014 check skipped");
1713
1693
  }
1714
- if (!existsSync6(join10(resolvedPath, ".git"))) {
1694
+ if (!existsSync6(join9(resolvedPath, ".git"))) {
1715
1695
  return check("pass", id, label, "No git repo \u2014 check skipped");
1716
1696
  }
1717
1697
  if (!hasOriginMain(resolvedPath)) {
@@ -1756,11 +1736,11 @@ function checkVaultGitBehind(resolvedPath) {
1756
1736
  }
1757
1737
  function pullLogPaths(home) {
1758
1738
  const paths = platform() === "darwin" ? [
1759
- join10(home, "Library", "Logs", "wiki-pull.log"),
1760
- join10(home, ".local", "state", "vault-sync", "log", "wiki-pull.log")
1739
+ join9(home, "Library", "Logs", "wiki-pull.log"),
1740
+ join9(home, ".local", "state", "vault-sync", "log", "wiki-pull.log")
1761
1741
  ] : [
1762
- join10(home, ".local", "state", "vault-sync", "log", "wiki-pull.log"),
1763
- join10(home, "Library", "Logs", "wiki-pull.log")
1742
+ join9(home, ".local", "state", "vault-sync", "log", "wiki-pull.log"),
1743
+ join9(home, "Library", "Logs", "wiki-pull.log")
1764
1744
  ];
1765
1745
  return [...new Set(paths)];
1766
1746
  }
@@ -1800,7 +1780,7 @@ function checkVaultLocalGit(resolvedPath, mcpOnlyLeaf = false) {
1800
1780
  check("warn", "vault_local_git", "Vault local git", "Cannot check \u2014 WIKI_PATH not resolved")
1801
1781
  );
1802
1782
  }
1803
- if (!existsSync6(join10(resolvedPath, ".git"))) {
1783
+ if (!existsSync6(join9(resolvedPath, ".git"))) {
1804
1784
  return check("warn", "vault_local_git", "Vault local git", "Not a git repository - sync features unavailable");
1805
1785
  }
1806
1786
  try {
@@ -1819,7 +1799,7 @@ function checkVaultGithubRemote(resolvedPath, exec) {
1819
1799
  if (resolvedPath === void 0) {
1820
1800
  return check("pass", "vault_github_remote", "Vault GitHub remote", "No vault path \u2014 check skipped");
1821
1801
  }
1822
- if (!existsSync6(join10(resolvedPath, ".git"))) {
1802
+ if (!existsSync6(join9(resolvedPath, ".git"))) {
1823
1803
  return check("pass", "vault_github_remote", "Vault GitHub remote", "No git repo \u2014 check skipped");
1824
1804
  }
1825
1805
  const state = probeGithubReachability(resolvedPath, exec);
@@ -1863,7 +1843,7 @@ function checkVaultPromotionLag(resolvedPath) {
1863
1843
  if (resolvedPath === void 0) {
1864
1844
  return check("pass", "vault_promotion_lag", "Vault promotion lag", "No vault path \u2014 check skipped");
1865
1845
  }
1866
- if (!existsSync6(join10(resolvedPath, ".git"))) {
1846
+ if (!existsSync6(join9(resolvedPath, ".git"))) {
1867
1847
  return check("pass", "vault_promotion_lag", "Vault promotion lag", "No git repo \u2014 check skipped");
1868
1848
  }
1869
1849
  try {
@@ -1914,11 +1894,11 @@ var gitFleetProbe = {
1914
1894
 
1915
1895
  // src/doctor/probes/hygiene.ts
1916
1896
  import { existsSync as existsSync8, readdirSync as readdirSync3, readFileSync as readFileSync5 } from "fs";
1917
- import { join as join12 } from "path";
1897
+ import { join as join11 } from "path";
1918
1898
 
1919
1899
  // src/utils/conflict-markers.ts
1920
1900
  import { existsSync as existsSync7, readdirSync as readdirSync2, readFileSync as readFileSync4 } from "fs";
1921
- import { join as join11 } from "path";
1901
+ import { join as join10 } from "path";
1922
1902
  function scanConflictMarkerBlocksInText(relPath, text) {
1923
1903
  const findings = [];
1924
1904
  const lines = text.split(/\r?\n/);
@@ -1969,7 +1949,7 @@ function walkMarkdownFiles(root, dir, rel, out) {
1969
1949
  for (const entry of entries) {
1970
1950
  if (entry.isDirectory()) {
1971
1951
  if (PRUNE_DIRS.has(entry.name)) continue;
1972
- walkMarkdownFiles(root, join11(dir, entry.name), rel ? `${rel}/${entry.name}` : entry.name, out);
1952
+ walkMarkdownFiles(root, join10(dir, entry.name), rel ? `${rel}/${entry.name}` : entry.name, out);
1973
1953
  } else if (entry.isFile() && entry.name.endsWith(".md")) {
1974
1954
  out.push(rel ? `${rel}/${entry.name}` : entry.name);
1975
1955
  }
@@ -1983,7 +1963,7 @@ function scanVaultConflictMarkers(vaultRoot) {
1983
1963
  for (const rel of relPaths) {
1984
1964
  let text;
1985
1965
  try {
1986
- text = readFileSync4(join11(vaultRoot, rel), "utf8");
1966
+ text = readFileSync4(join10(vaultRoot, rel), "utf8");
1987
1967
  } catch {
1988
1968
  continue;
1989
1969
  }
@@ -2002,7 +1982,7 @@ function checkDotStoreClean(resolvedPath, mcpOnlyLeaf = false) {
2002
1982
  check("error", "dsstore_clean", "No .DS_Store in raw/", "Cannot check \u2014 WIKI_PATH not resolved")
2003
1983
  );
2004
1984
  }
2005
- const rawDir = join12(resolvedPath, "raw");
1985
+ const rawDir = join11(resolvedPath, "raw");
2006
1986
  if (!existsSync8(rawDir)) {
2007
1987
  return check("pass", "dsstore_clean", "No .DS_Store in raw/", "raw/ directory not found \u2014 check skipped");
2008
1988
  }
@@ -2018,7 +1998,7 @@ function checkDotStoreClean(resolvedPath, mcpOnlyLeaf = false) {
2018
1998
  if (entry.name === ".DS_Store") {
2019
1999
  found.push(rel ? `${rel}/.DS_Store` : ".DS_Store");
2020
2000
  } else if (entry.isDirectory()) {
2021
- walk(join12(dir, entry.name), rel ? `${rel}/${entry.name}` : entry.name);
2001
+ walk(join11(dir, entry.name), rel ? `${rel}/${entry.name}` : entry.name);
2022
2002
  }
2023
2003
  }
2024
2004
  })(rawDir, "");
@@ -2047,7 +2027,7 @@ function checkVaultConflictMarkers(resolvedPath) {
2047
2027
  }
2048
2028
  function githubSyncedGitRoot(gitRoot) {
2049
2029
  if (gitRoot === void 0) return { ok: false, reason: "No vault path \u2014 check skipped" };
2050
- if (!existsSync8(join12(gitRoot, ".git"))) return { ok: false, reason: "Not a git repository \u2014 check skipped" };
2030
+ if (!existsSync8(join11(gitRoot, ".git"))) return { ok: false, reason: "Not a git repository \u2014 check skipped" };
2051
2031
  if (!git(gitRoot, ["remote"])) return { ok: false, reason: "No git remote \u2014 not GitHub-synced, check skipped" };
2052
2032
  return { ok: true, gitRoot };
2053
2033
  }
@@ -2057,7 +2037,7 @@ function checkVaultGitignoreHygiene(synced) {
2057
2037
  }
2058
2038
  let content = "";
2059
2039
  try {
2060
- content = readFileSync5(join12(synced.gitRoot, ".gitignore"), "utf8");
2040
+ content = readFileSync5(join11(synced.gitRoot, ".gitignore"), "utf8");
2061
2041
  } catch {
2062
2042
  content = "";
2063
2043
  }
@@ -2105,7 +2085,7 @@ var hygieneProbe = {
2105
2085
 
2106
2086
  // src/doctor/probes/s3-mount-health.ts
2107
2087
  import { existsSync as existsSync10 } from "fs";
2108
- import { join as join14 } from "path";
2088
+ import { join as join13 } from "path";
2109
2089
  import { execSync as execSync4 } from "child_process";
2110
2090
 
2111
2091
  // src/utils/s3-mount-health.ts
@@ -2114,7 +2094,7 @@ import { platform as platform2 } from "os";
2114
2094
  import { readFileSync as readFileSync6 } from "fs";
2115
2095
  import { readFile as readFile6, writeFile as writeFile2, unlink } from "fs/promises";
2116
2096
  import { randomUUID } from "crypto";
2117
- import { join as join13 } from "path";
2097
+ import { join as join12 } from "path";
2118
2098
  var OS = platform2();
2119
2099
  function findRcloneMountPid() {
2120
2100
  try {
@@ -2272,7 +2252,7 @@ function detectFuseMount(vaultPath) {
2272
2252
  return null;
2273
2253
  }
2274
2254
  async function writeTest(dir, options = {}) {
2275
- const testFile = join13(dir, options.fileName ?? `.doctor-write-test-${process.pid}.tmp`);
2255
+ const testFile = join12(dir, options.fileName ?? `.doctor-write-test-${process.pid}.tmp`);
2276
2256
  const io = options.io ?? {
2277
2257
  write: (path, payload2) => writeFile2(path, payload2, "utf8"),
2278
2258
  read: (path) => readFile6(path, "utf8"),
@@ -2362,7 +2342,7 @@ function checkS3MountPerf(resolvedPath) {
2362
2342
  return check("pass", "s3_mount_perf", "S3 mount performance", "local disk");
2363
2343
  }
2364
2344
  const mountPoint = fuse.mountPoint;
2365
- const conceptsDir = join14(resolvedPath, "concepts");
2345
+ const conceptsDir = join13(resolvedPath, "concepts");
2366
2346
  if (!existsSync10(conceptsDir)) {
2367
2347
  return check("pass", "s3_mount_perf", "S3 mount performance", `S3 FUSE mount (${mountPoint}), no concepts/ to benchmark`);
2368
2348
  }
@@ -2551,7 +2531,7 @@ async function checkWriteTest(resolvedPath) {
2551
2531
  if (!fuse) {
2552
2532
  return check("pass", "s3_write_test", "S3 write test", "local disk \u2014 check skipped");
2553
2533
  }
2554
- const conceptsDir = join14(resolvedPath, "concepts");
2534
+ const conceptsDir = join13(resolvedPath, "concepts");
2555
2535
  if (!existsSync10(conceptsDir)) {
2556
2536
  return check("pass", "s3_write_test", "S3 write test", "no concepts/ dir to test \u2014 check skipped");
2557
2537
  }
@@ -2652,7 +2632,7 @@ var s3MountHealthProbe = {
2652
2632
 
2653
2633
  // src/doctor/probes/skills-plugins.ts
2654
2634
  import { existsSync as existsSync11, readdirSync as readdirSync4, readFileSync as readFileSync7 } from "fs";
2655
- import { join as join15 } from "path";
2635
+ import { join as join14 } from "path";
2656
2636
  function findSkillMd(dir) {
2657
2637
  const results = [];
2658
2638
  let entries;
@@ -2663,9 +2643,9 @@ function findSkillMd(dir) {
2663
2643
  }
2664
2644
  for (const entry of entries) {
2665
2645
  if (entry.isFile() && entry.name === "SKILL.md") {
2666
- results.push(join15(dir, entry.name));
2646
+ results.push(join14(dir, entry.name));
2667
2647
  } else if (entry.isDirectory()) {
2668
- results.push(...findSkillMd(join15(dir, entry.name)));
2648
+ results.push(...findSkillMd(join14(dir, entry.name)));
2669
2649
  }
2670
2650
  }
2671
2651
  return results;
@@ -2679,18 +2659,18 @@ function findSkillNames(dir) {
2679
2659
  return results;
2680
2660
  }
2681
2661
  for (const entry of entries) {
2682
- if (entry.isDirectory() && existsSync11(join15(dir, entry.name, "SKILL.md"))) {
2662
+ if (entry.isDirectory() && existsSync11(join14(dir, entry.name, "SKILL.md"))) {
2683
2663
  results.push(entry.name);
2684
2664
  }
2685
2665
  }
2686
2666
  return results;
2687
2667
  }
2688
2668
  function findInstalledSkillMd(dir) {
2689
- const directSkills = findSkillNames(dir).map((name) => join15(dir, name, "SKILL.md"));
2669
+ const directSkills = findSkillNames(dir).map((name) => join14(dir, name, "SKILL.md"));
2690
2670
  return directSkills.length > 0 ? directSkills : findSkillMd(dir);
2691
2671
  }
2692
2672
  function checkSkillsInstalled(home, cwd) {
2693
- const srcDir = cwd ? join15(cwd, "packages", "skills") : void 0;
2673
+ const srcDir = cwd ? join14(cwd, "packages", "skills") : void 0;
2694
2674
  if (srcDir && existsSync11(srcDir)) {
2695
2675
  const found = findInstalledSkillMd(srcDir);
2696
2676
  if (found.length > 0) {
@@ -2704,7 +2684,7 @@ function checkSkillsInstalled(home, cwd) {
2704
2684
  return check("pass", "skills_installed", "Skills installed", `${found.length} SKILL.md file(s) found (plugin v${plugin.version})`);
2705
2685
  }
2706
2686
  }
2707
- const skillsDir = join15(home, ".claude", "skills");
2687
+ const skillsDir = join14(home, ".claude", "skills");
2708
2688
  if (existsSync11(skillsDir)) {
2709
2689
  const found = findInstalledSkillMd(skillsDir);
2710
2690
  if (found.length > 0) {
@@ -2715,10 +2695,10 @@ function checkSkillsInstalled(home, cwd) {
2715
2695
  }
2716
2696
  function checkDuplicateSkills(home) {
2717
2697
  const plugin = findPlugin(home);
2718
- const skillsDir = join15(home, ".claude", "skills");
2698
+ const skillsDir = join14(home, ".claude", "skills");
2719
2699
  const agentSkillDirs = [
2720
- { label: "~/.codex/skills/", path: join15(home, ".codex", "skills") },
2721
- { label: "~/.agents/skills/", path: join15(home, ".agents", "skills") }
2700
+ { label: "~/.codex/skills/", path: join14(home, ".codex", "skills") },
2701
+ { label: "~/.agents/skills/", path: join14(home, ".agents", "skills") }
2722
2702
  ];
2723
2703
  if (!plugin) {
2724
2704
  return check("pass", "skills_duplicate", "Skills not duplicated", "Single install channel");
@@ -2751,10 +2731,10 @@ var STALE_GROK_ACTIVATION_REFERENCE = "Read @skillwiki.md";
2751
2731
  var ACTIVATION_FIX_HINT = "run `npm run install:activation` from the llm-wiki repo";
2752
2732
  function findGrokActivationTemplate(home, cwd) {
2753
2733
  if (cwd) {
2754
- const src = join15(cwd, "packages", "skills", "using-skillwiki", "activation.md");
2734
+ const src = join14(cwd, "packages", "skills", "using-skillwiki", "activation.md");
2755
2735
  if (existsSync11(src)) return src;
2756
2736
  }
2757
- const pluginsRoot = join15(home, ".grok", "installed-plugins");
2737
+ const pluginsRoot = join14(home, ".grok", "installed-plugins");
2758
2738
  if (!existsSync11(pluginsRoot)) return void 0;
2759
2739
  let entries;
2760
2740
  try {
@@ -2764,21 +2744,21 @@ function findGrokActivationTemplate(home, cwd) {
2764
2744
  }
2765
2745
  for (const entry of entries) {
2766
2746
  if (!entry.isDirectory()) continue;
2767
- const root = join15(pluginsRoot, entry.name);
2747
+ const root = join14(pluginsRoot, entry.name);
2768
2748
  for (const rel of ["using-skillwiki/activation.md", "skills/using-skillwiki/activation.md"]) {
2769
- const candidate = join15(root, rel);
2749
+ const candidate = join14(root, rel);
2770
2750
  if (existsSync11(candidate)) return candidate;
2771
2751
  }
2772
2752
  }
2773
2753
  return void 0;
2774
2754
  }
2775
2755
  function checkGrokActivation(home, cwd) {
2776
- const grokDir = join15(home, ".grok");
2756
+ const grokDir = join14(home, ".grok");
2777
2757
  if (!existsSync11(grokDir)) {
2778
2758
  return check("pass", "activation_grok", "Grok activation", "Not a Grok host");
2779
2759
  }
2780
- const activationPath = join15(grokDir, "skillwiki.md");
2781
- const agentsPath = join15(grokDir, "AGENTS.md");
2760
+ const activationPath = join14(grokDir, "skillwiki.md");
2761
+ const agentsPath = join14(grokDir, "AGENTS.md");
2782
2762
  const hasActivation = existsSync11(activationPath);
2783
2763
  const issues = [];
2784
2764
  if (!hasActivation) {
@@ -2893,7 +2873,7 @@ var skillsPluginsProbe = {
2893
2873
 
2894
2874
  // src/doctor/probes/vault-sync.ts
2895
2875
  import { existsSync as existsSync12, readFileSync as readFileSync8 } from "fs";
2896
- import { join as join16 } from "path";
2876
+ import { join as join15 } from "path";
2897
2877
  import { execSync as execSync5 } from "child_process";
2898
2878
  import { platform as platform3 } from "os";
2899
2879
  function readPushResultState(stateFile) {
@@ -2922,7 +2902,7 @@ function readPushResultState(stateFile) {
2922
2902
  }
2923
2903
  function readVaultSyncConfig(home) {
2924
2904
  try {
2925
- const content = readFileSync8(join16(home, ".skillwiki", ".env"), "utf8");
2905
+ const content = readFileSync8(join15(home, ".skillwiki", ".env"), "utf8");
2926
2906
  let installed = false;
2927
2907
  let role;
2928
2908
  let serviceScope;
@@ -3225,7 +3205,7 @@ function snapshotterHealthChecks(scope, logDir, env) {
3225
3205
  let completionOutcome = "unknown";
3226
3206
  const logRecords = fixture ? fixture.log_records : (() => {
3227
3207
  try {
3228
- const content = readFileSync8(join16(logDir, "wiki-snapshot.log"), "utf8");
3208
+ const content = readFileSync8(join15(logDir, "wiki-snapshot.log"), "utf8");
3229
3209
  return content.split(/\r?\n/).filter(Boolean);
3230
3210
  } catch {
3231
3211
  return [];
@@ -3403,11 +3383,11 @@ function vaultSyncChecks(input) {
3403
3383
  ];
3404
3384
  }
3405
3385
  const isMac = os === "darwin";
3406
- const logDir = input.logDir ?? (isMac ? join16(home, "Library", "Logs") : join16(home, ".local", "state", "vault-sync", "log"));
3407
- const cacheDir = input.cacheDir ?? (isMac ? join16(home, "Library", "Caches", "vault-sync") : join16(home, ".cache", "vault-sync"));
3408
- const shareDir = input.shareDir ?? (isMac ? join16(home, "Library", "Application Support", "vault-sync", "bin") : join16(home, ".local", "share", "vault-sync", "bin"));
3409
- const filterPath = input.filterPath ?? join16(home, ".config", "rclone", "wiki-push-filters.txt");
3410
- const packagedSnapshotPath = join16(shareDir, "wiki-snapshot.sh");
3386
+ const logDir = input.logDir ?? (isMac ? join15(home, "Library", "Logs") : join15(home, ".local", "state", "vault-sync", "log"));
3387
+ const cacheDir = input.cacheDir ?? (isMac ? join15(home, "Library", "Caches", "vault-sync") : join15(home, ".cache", "vault-sync"));
3388
+ const shareDir = input.shareDir ?? (isMac ? join15(home, "Library", "Application Support", "vault-sync", "bin") : join15(home, ".local", "share", "vault-sync", "bin"));
3389
+ const filterPath = input.filterPath ?? join15(home, ".config", "rclone", "wiki-push-filters.txt");
3390
+ const packagedSnapshotPath = join15(shareDir, "wiki-snapshot.sh");
3411
3391
  const legacySnapshotPath = "/root/.hermes/scripts/wiki-snapshot-v3.sh";
3412
3392
  const snapshotPath = input.snapshotScriptPath ?? (existsSync12(packagedSnapshotPath) ? packagedSnapshotPath : legacySnapshotPath);
3413
3393
  if (input.vaultSyncRole === "snapshotter") {
@@ -3464,9 +3444,9 @@ function vaultSyncChecks(input) {
3464
3444
  return [c12, ...healthChecks, cFetch2, c42, c52];
3465
3445
  }
3466
3446
  const env = input.env ?? process.env;
3467
- const fetchLogFile = join16(logDir, "wiki-fetch.log");
3447
+ const fetchLogFile = join15(logDir, "wiki-fetch.log");
3468
3448
  if (input.pushEnabled === false) {
3469
- const fetchHelperPath = join16(shareDir, "wiki-fetch-notify.sh");
3449
+ const fetchHelperPath = join15(shareDir, "wiki-fetch-notify.sh");
3470
3450
  const c12 = existsSync12(fetchHelperPath) ? check("pass", "vault_sync_installed", "Vault sync installed", `Found: ${fetchHelperPath}`) : check(
3471
3451
  "error",
3472
3452
  "vault_sync_installed",
@@ -3501,7 +3481,7 @@ function vaultSyncChecks(input) {
3501
3481
  );
3502
3482
  return [c12, c22, c32, cPushResult2, cFetch2, c42, c52];
3503
3483
  }
3504
- const pushScriptPath = join16(shareDir, "wiki-push.sh");
3484
+ const pushScriptPath = join15(shareDir, "wiki-push.sh");
3505
3485
  const c1 = existsSync12(pushScriptPath) ? check("pass", "vault_sync_installed", "Vault sync installed", `Found: ${pushScriptPath}`) : check("error", "vault_sync_installed", "Vault sync installed", `Script not found at ${pushScriptPath} \u2014 run vault-sync-install`);
3506
3486
  let c2;
3507
3487
  try {
@@ -3553,9 +3533,9 @@ function vaultSyncChecks(input) {
3553
3533
  "Scheduler check failed \u2014 run vault-sync-install"
3554
3534
  );
3555
3535
  }
3556
- const stateFile = join16(cacheDir, "wiki-push-result.state");
3536
+ const stateFile = join15(cacheDir, "wiki-push-result.state");
3557
3537
  const pushState = readPushResultState(stateFile);
3558
- const logFile = join16(logDir, "wiki-push.log");
3538
+ const logFile = join15(logDir, "wiki-push.log");
3559
3539
  let c3;
3560
3540
  if (pushState.exists && !pushState.malformed && pushState.result === "refused") {
3561
3541
  const reasonSuffix = pushState.reason ? `: ${pushState.reason}` : "";
@@ -3705,7 +3685,7 @@ function checkVaultSyncPullHelper(home, env) {
3705
3685
  );
3706
3686
  }
3707
3687
  function isGitDir(path) {
3708
- return Boolean(path && existsSync12(join16(path, ".git")));
3688
+ return Boolean(path && existsSync12(join15(path, ".git")));
3709
3689
  }
3710
3690
  function checkVaultSyncReviewRequiredJournals(ctx) {
3711
3691
  const live = ctx.resolvedPath;
@@ -3800,10 +3780,10 @@ import { platform as platform4 } from "os";
3800
3780
 
3801
3781
  // src/utils/satellite-run-health.ts
3802
3782
  import { existsSync as existsSync13, readFileSync as readFileSync9 } from "fs";
3803
- import { join as join17 } from "path";
3783
+ import { join as join16 } from "path";
3804
3784
  var SATELLITE_STALE_MS = 26 * 60 * 60 * 1e3;
3805
3785
  function satelliteLatestRunPath(vault) {
3806
- return join17(vault, ".skillwiki", "agent-memory-trends", "latest-run.json");
3786
+ return join16(vault, ".skillwiki", "agent-memory-trends", "latest-run.json");
3807
3787
  }
3808
3788
  function isFailedRunStatus(status) {
3809
3789
  return status === "fail" || status === "failure";
@@ -3945,7 +3925,7 @@ var satelliteProbe = {
3945
3925
 
3946
3926
  // src/doctor/probes/metrics.ts
3947
3927
  import { readFileSync as readFileSync10 } from "fs";
3948
- import { join as join18 } from "path";
3928
+ import { join as join17 } from "path";
3949
3929
  var METRIC_TYPES = ["entities", "concepts", "comparisons", "queries", "meta"];
3950
3930
  function doctorReadOnlyScanRoot(resolvedPath) {
3951
3931
  return resolveReadOnlyVaultRoot(resolvedPath).root;
@@ -3989,7 +3969,7 @@ async function vaultMetrics(resolvedPath) {
3989
3969
  }
3990
3970
  let logLines = 0;
3991
3971
  try {
3992
- logLines = readFileSync10(join18(scanRoot, "log.md"), "utf8").split("\n").length;
3972
+ logLines = readFileSync10(join17(scanRoot, "log.md"), "utf8").split("\n").length;
3993
3973
  } catch {
3994
3974
  }
3995
3975
  return [
@@ -4125,18 +4105,18 @@ var fuseStalenessProbe = {
4125
4105
 
4126
4106
  // src/doctor/probes/activation-marker.ts
4127
4107
  import { existsSync as existsSync15, readFileSync as readFileSync11, readdirSync as readdirSync5 } from "fs";
4128
- import { join as join19 } from "path";
4108
+ import { join as join18 } from "path";
4129
4109
  var GROK_ACTIVATION_REFERENCE2 = "Read @~/.grok/skillwiki.md for SkillWiki activation context.";
4130
4110
  var STALE_GROK_ACTIVATION_REFERENCE2 = "Read @skillwiki.md";
4131
4111
  var ACTIVATION_FIX_HINT2 = "run `npm run install:activation` from the llm-wiki repo";
4132
4112
  function findGrokActivationTemplate2(home, cwd) {
4133
4113
  if (cwd) {
4134
- const src = join19(cwd, "packages", "skills", "using-skillwiki", "activation.md");
4114
+ const src = join18(cwd, "packages", "skills", "using-skillwiki", "activation.md");
4135
4115
  if (existsSync15(src)) return src;
4136
- const directSrc = join19(cwd, "skills", "using-skillwiki", "activation.md");
4116
+ const directSrc = join18(cwd, "skills", "using-skillwiki", "activation.md");
4137
4117
  if (existsSync15(directSrc)) return directSrc;
4138
4118
  }
4139
- const pluginsRoot = join19(home, ".grok", "installed-plugins");
4119
+ const pluginsRoot = join18(home, ".grok", "installed-plugins");
4140
4120
  if (!existsSync15(pluginsRoot)) return void 0;
4141
4121
  let entries;
4142
4122
  try {
@@ -4146,21 +4126,21 @@ function findGrokActivationTemplate2(home, cwd) {
4146
4126
  }
4147
4127
  for (const entry of entries) {
4148
4128
  if (!entry.isDirectory()) continue;
4149
- const root = join19(pluginsRoot, entry.name);
4129
+ const root = join18(pluginsRoot, entry.name);
4150
4130
  for (const rel of ["using-skillwiki/activation.md", "skills/using-skillwiki/activation.md"]) {
4151
- const candidate = join19(root, rel);
4131
+ const candidate = join18(root, rel);
4152
4132
  if (existsSync15(candidate)) return candidate;
4153
4133
  }
4154
4134
  }
4155
4135
  return void 0;
4156
4136
  }
4157
4137
  function checkActivationMarker(home, cwd) {
4158
- const grokDir = join19(home, ".grok");
4138
+ const grokDir = join18(home, ".grok");
4159
4139
  if (!existsSync15(grokDir)) {
4160
4140
  return check("pass", "activation_marker", "Activation marker", "Not a Grok host \u2014 check skipped");
4161
4141
  }
4162
- const activationPath = join19(grokDir, "skillwiki.md");
4163
- const agentsPath = join19(grokDir, "AGENTS.md");
4142
+ const activationPath = join18(grokDir, "skillwiki.md");
4143
+ const agentsPath = join18(grokDir, "AGENTS.md");
4164
4144
  const hasActivation = existsSync15(activationPath);
4165
4145
  const issues = [];
4166
4146
  if (!hasActivation) {
@@ -4217,7 +4197,7 @@ var activationMarkerProbe = {
4217
4197
 
4218
4198
  // src/doctor/probes/ds-store-noise.ts
4219
4199
  import { existsSync as existsSync16, readdirSync as readdirSync6 } from "fs";
4220
- import { join as join20 } from "path";
4200
+ import { join as join19 } from "path";
4221
4201
  var VAULT_TRACKED_DIRS = ["raw", "entities", "concepts", "comparisons", "queries", "meta", "_archive", "_Templates"];
4222
4202
  function checkDsStoreNoise(resolvedPath) {
4223
4203
  if (resolvedPath === void 0) {
@@ -4239,13 +4219,13 @@ function checkDsStoreNoise(resolvedPath) {
4239
4219
  found.push(rel ? `${rel}/.DS_Store` : ".DS_Store");
4240
4220
  } else if (entry.isDirectory()) {
4241
4221
  if (entry.name === ".git" || entry.name === "node_modules") continue;
4242
- walk(join20(dir, entry.name), rel ? `${rel}/${entry.name}` : entry.name);
4222
+ walk(join19(dir, entry.name), rel ? `${rel}/${entry.name}` : entry.name);
4243
4223
  }
4244
4224
  }
4245
4225
  }
4246
4226
  let scannedAny = false;
4247
4227
  for (const sub of VAULT_TRACKED_DIRS) {
4248
- const subDir = join20(resolvedPath, sub);
4228
+ const subDir = join19(resolvedPath, sub);
4249
4229
  if (existsSync16(subDir)) {
4250
4230
  scannedAny = true;
4251
4231
  walk(subDir, sub);
@@ -4275,7 +4255,7 @@ var dsStoreNoiseProbe = {
4275
4255
 
4276
4256
  // src/doctor/probes/mcp-handshake.ts
4277
4257
  import { existsSync as existsSync17 } from "fs";
4278
- import { join as join21 } from "path";
4258
+ import { join as join20 } from "path";
4279
4259
 
4280
4260
  // src/utils/mcp-client.ts
4281
4261
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
@@ -4346,7 +4326,7 @@ function checkMcpCredential(ctx) {
4346
4326
  }
4347
4327
  function checkFrozenLeafWritePath(ctx) {
4348
4328
  const vault = ctx.resolvedPath;
4349
- if (!vault || !existsSync17(join21(vault, ".WIKI_GIT_FROZEN"))) {
4329
+ if (!vault || !existsSync17(join20(vault, ".WIKI_GIT_FROZEN"))) {
4350
4330
  return check(
4351
4331
  "pass",
4352
4332
  "mcp_frozen_leaf_write_path",
@@ -4407,7 +4387,7 @@ async function checkMcpHandshake(ctx) {
4407
4387
  if (!advertised) {
4408
4388
  return handshakeRow("error", "handshake failed \u2014 missing serverInfo.version", token);
4409
4389
  }
4410
- const frozen = Boolean(ctx.resolvedPath && existsSync17(join21(ctx.resolvedPath, ".WIKI_GIT_FROZEN")));
4390
+ const frozen = Boolean(ctx.resolvedPath && existsSync17(join20(ctx.resolvedPath, ".WIKI_GIT_FROZEN")));
4411
4391
  if (frozen && !tools.includes(WORKITEM_TOOL)) {
4412
4392
  return handshakeRow(
4413
4393
  "error",
@@ -4443,182 +4423,10 @@ var mcpHandshakeProbe = {
4443
4423
  };
4444
4424
 
4445
4425
  // src/doctor/probes/clip-outbox.ts
4446
- import { existsSync as existsSync19 } from "fs";
4426
+ import { existsSync as existsSync18, readFileSync as readFileSync12 } from "fs";
4447
4427
  import { execSync as execSync7 } from "child_process";
4448
4428
  import { platform as platform6 } from "os";
4449
- import { join as join23 } from "path";
4450
-
4451
- // src/utils/clip-outbox-config.ts
4452
- import { realpathSync, statSync as statSync3, existsSync as existsSync18, accessSync, constants } from "fs";
4453
- import { homedir } from "os";
4454
- import { isAbsolute, join as join22, resolve as resolve3, sep as sep2 } from "path";
4455
- var CLIP_NOT_CONFIGURED = "clip channel not configured";
4456
- var PRODUCTION_WATCHER_LABEL = CLIP_OUTBOX_DEFAULTS.watcher_label;
4457
- var RETIRED_WATCHER_LABELS = [
4458
- "com.karlchow.wiki-dev-outbox",
4459
- "com.karlchow.wiki-dev-sse",
4460
- "com.karlchow.wiki-dev-hourly",
4461
- "com.karlchow.skillwiki-note-outbox"
4462
- ];
4463
- function expandUserPath(raw, home) {
4464
- if (raw === "~") return home;
4465
- if (raw.startsWith("~/")) return resolve3(home, raw.slice(2));
4466
- return raw;
4467
- }
4468
- function canonicalPath(raw, home) {
4469
- const expanded = expandUserPath(raw.trim(), home);
4470
- if (expanded.includes("\0")) return { ok: false, message: "path contains NUL" };
4471
- if (expanded.includes("://") || expanded.includes("@")) {
4472
- return { ok: false, message: "path must not include URL credentials" };
4473
- }
4474
- if (!isAbsolute(expanded)) return { ok: false, message: "must be an absolute path" };
4475
- try {
4476
- const real = existsSync18(expanded) ? realpathSync(expanded) : resolve3(expanded);
4477
- if (real.split(sep2).some((seg) => seg === "..")) {
4478
- return { ok: false, message: "path must not contain traversal" };
4479
- }
4480
- return { ok: true, path: real };
4481
- } catch (error) {
4482
- return { ok: false, message: error instanceof Error ? error.message : "invalid path" };
4483
- }
4484
- }
4485
- function nestedOrEqual(a, b) {
4486
- if (a === b) return true;
4487
- const prefixA = a.endsWith(sep2) ? a : a + sep2;
4488
- const prefixB = b.endsWith(sep2) ? b : b + sep2;
4489
- return prefixA.startsWith(prefixB) || prefixB.startsWith(prefixA);
4490
- }
4491
- function intField(value, fallback) {
4492
- return Number(value && value.length > 0 ? value : fallback);
4493
- }
4494
- function requireWritableDir(path, label) {
4495
- try {
4496
- const st = statSync3(path);
4497
- if (!st.isDirectory()) return `${label} is not a directory`;
4498
- accessSync(path, constants.W_OK);
4499
- return void 0;
4500
- } catch {
4501
- return `${label} is missing or not writable`;
4502
- }
4503
- }
4504
- function resolveClipOutboxConfig(map, home) {
4505
- const present = Object.keys(map).filter(isClipOutboxKey);
4506
- for (const key of present) {
4507
- const parsed = parseClipOutboxKeyValue(key, map[key] ?? "");
4508
- if (!parsed.ok) return { ok: false, message: `${key}: ${parsed.message}` };
4509
- }
4510
- const enabled = (map["clip_outbox.enabled"] ?? CLIP_OUTBOX_DEFAULTS.enabled) === "true";
4511
- if (!enabled) {
4512
- return { ok: true, enabled: false };
4513
- }
4514
- const required = [
4515
- "clip_outbox.root",
4516
- "clip_outbox.state_root",
4517
- "clip_outbox.mirror_root",
4518
- "clip_outbox.ready_url",
4519
- "clip_outbox.s3_credential_ref",
4520
- "clip_outbox.ready_credential_ref"
4521
- ];
4522
- for (const key of required) {
4523
- if (!map[key]) return { ok: false, message: `${key} is required when clip_outbox.enabled=true` };
4524
- }
4525
- const d8Absent = map["clip_outbox.d8_note_absent"] === "true";
4526
- const d8RootRaw = map["clip_outbox.d8_note_root"];
4527
- if (d8Absent && d8RootRaw) {
4528
- return { ok: false, message: "clip_outbox.d8_note_root and clip_outbox.d8_note_absent cannot both be set" };
4529
- }
4530
- if (!d8Absent && !d8RootRaw) {
4531
- return { ok: false, message: "clip_outbox.d8_note_root or clip_outbox.d8_note_absent=true is required when enabled" };
4532
- }
4533
- const root = canonicalPath(map["clip_outbox.root"], home);
4534
- const stateRoot = canonicalPath(map["clip_outbox.state_root"], home);
4535
- const mirrorRoot = canonicalPath(map["clip_outbox.mirror_root"], home);
4536
- if (!root.ok) return { ok: false, message: `clip_outbox.root: ${root.message}` };
4537
- if (!stateRoot.ok) return { ok: false, message: `clip_outbox.state_root: ${stateRoot.message}` };
4538
- if (!mirrorRoot.ok) return { ok: false, message: `clip_outbox.mirror_root: ${mirrorRoot.message}` };
4539
- let d8NoteRoot = null;
4540
- if (d8RootRaw) {
4541
- const d8 = canonicalPath(d8RootRaw, home);
4542
- if (!d8.ok) return { ok: false, message: `clip_outbox.d8_note_root: ${d8.message}` };
4543
- d8NoteRoot = d8.path;
4544
- }
4545
- if (nestedOrEqual(root.path, mirrorRoot.path)) {
4546
- return { ok: false, message: "clip_outbox.root must be outside the frozen mirror" };
4547
- }
4548
- if (nestedOrEqual(root.path, stateRoot.path) || nestedOrEqual(stateRoot.path, mirrorRoot.path)) {
4549
- return { ok: false, message: "clip_outbox.state_root must be disjoint from outbox and mirror" };
4550
- }
4551
- if (d8NoteRoot && (nestedOrEqual(root.path, d8NoteRoot) || nestedOrEqual(stateRoot.path, d8NoteRoot))) {
4552
- return { ok: false, message: "clip outbox must not equal or nest the D8 note outbox" };
4553
- }
4554
- const rootErr = requireWritableDir(root.path, "clip_outbox.root");
4555
- if (rootErr) return { ok: false, message: rootErr };
4556
- const stateErr = requireWritableDir(stateRoot.path, "clip_outbox.state_root");
4557
- if (stateErr) {
4558
- if (existsSync18(stateRoot.path)) return { ok: false, message: stateErr };
4559
- const parentErr = requireWritableDir(resolve3(stateRoot.path, ".."), "clip_outbox.state_root parent");
4560
- if (parentErr) return { ok: false, message: stateErr };
4561
- }
4562
- if (!existsSync18(mirrorRoot.path)) {
4563
- return { ok: false, message: "clip_outbox.mirror_root does not exist" };
4564
- }
4565
- const vaultId = map["clip_outbox.vault_id"] ?? CLIP_OUTBOX_DEFAULTS.vault_id;
4566
- if (vaultId !== "central") return { ok: false, message: "clip_outbox.vault_id must be central" };
4567
- const destination = map["clip_outbox.destination"] ?? CLIP_OUTBOX_DEFAULTS.destination;
4568
- if (destination !== CLIP_OUTBOX_DEFAULTS.destination) {
4569
- return { ok: false, message: "clip_outbox.destination must be seaweed-wiki:cloud/wiki" };
4570
- }
4571
- const mode = map["clip_outbox.mode"] ?? CLIP_OUTBOX_DEFAULTS.mode;
4572
- if (mode !== "event-watch") return { ok: false, message: "clip_outbox.mode must be event-watch" };
4573
- const watcherLabel = map["clip_outbox.watcher_label"] ?? CLIP_OUTBOX_DEFAULTS.watcher_label;
4574
- if (watcherLabel !== PRODUCTION_WATCHER_LABEL) {
4575
- return { ok: false, message: "clip_outbox.watcher_label must be the production clip watcher" };
4576
- }
4577
- const imageTypes = (map["clip_outbox.image_types"] ?? CLIP_OUTBOX_DEFAULTS.image_types).split(",").map((p) => p.trim()).filter(Boolean);
4578
- return {
4579
- ok: true,
4580
- enabled: true,
4581
- config: {
4582
- enabled: true,
4583
- root: root.path,
4584
- stateRoot: stateRoot.path,
4585
- mirrorRoot: mirrorRoot.path,
4586
- d8NoteRoot,
4587
- d8NoteAbsent: d8Absent,
4588
- vaultId: "central",
4589
- allowedPrefixes: ["raw/articles", "raw/assets"],
4590
- destination: "seaweed-wiki:cloud/wiki",
4591
- mode: "event-watch",
4592
- pollFallbackEnabled: (map["clip_outbox.poll_fallback_enabled"] ?? CLIP_OUTBOX_DEFAULTS.poll_fallback_enabled) === "true",
4593
- reconcileSeconds: intField(map["clip_outbox.reconcile_seconds"], CLIP_OUTBOX_DEFAULTS.reconcile_seconds),
4594
- debounceMs: intField(map["clip_outbox.debounce_ms"], CLIP_OUTBOX_DEFAULTS.debounce_ms),
4595
- stableHashMs: intField(map["clip_outbox.stable_hash_ms"], CLIP_OUTBOX_DEFAULTS.stable_hash_ms),
4596
- maxArticleBytes: intField(map["clip_outbox.max_article_bytes"], CLIP_OUTBOX_DEFAULTS.max_article_bytes),
4597
- maxImages: intField(map["clip_outbox.max_images"], CLIP_OUTBOX_DEFAULTS.max_images),
4598
- maxImageBytes: intField(map["clip_outbox.max_image_bytes"], CLIP_OUTBOX_DEFAULTS.max_image_bytes),
4599
- maxBundleBytes: intField(map["clip_outbox.max_bundle_bytes"], CLIP_OUTBOX_DEFAULTS.max_bundle_bytes),
4600
- maxPixels: intField(map["clip_outbox.max_pixels"], CLIP_OUTBOX_DEFAULTS.max_pixels),
4601
- downloadConcurrency: intField(map["clip_outbox.download_concurrency"], CLIP_OUTBOX_DEFAULTS.download_concurrency),
4602
- imageTypes,
4603
- maxRedirects: intField(map["clip_outbox.max_redirects"], CLIP_OUTBOX_DEFAULTS.max_redirects),
4604
- requestTimeoutMs: intField(map["clip_outbox.request_timeout_ms"], CLIP_OUTBOX_DEFAULTS.request_timeout_ms),
4605
- localizeTimeoutMs: intField(map["clip_outbox.localize_timeout_ms"], CLIP_OUTBOX_DEFAULTS.localize_timeout_ms),
4606
- readyUrl: map["clip_outbox.ready_url"],
4607
- s3CredentialRef: map["clip_outbox.s3_credential_ref"],
4608
- readyCredentialRef: map["clip_outbox.ready_credential_ref"],
4609
- watcherLabel: PRODUCTION_WATCHER_LABEL
4610
- }
4611
- };
4612
- }
4613
- function clipOutboxConfigPath(home) {
4614
- return join22(resolveSkillwikiHome(home), ".skillwiki", ".env");
4615
- }
4616
- async function loadClipOutboxConfig(home) {
4617
- const map = await parseDotenvFile(clipOutboxConfigPath(home));
4618
- return resolveClipOutboxConfig(map, home || homedir());
4619
- }
4620
-
4621
- // src/doctor/probes/clip-outbox.ts
4429
+ import { join as join21 } from "path";
4622
4430
  var CLIP_CHECK_IDS = [
4623
4431
  "clip_config",
4624
4432
  "clip_frozen_mirror",
@@ -4669,7 +4477,7 @@ function launchdLoaded(label) {
4669
4477
  return false;
4670
4478
  }
4671
4479
  }
4672
- function watcherStatus(env, label) {
4480
+ function watcherStatus(env, label, home, root) {
4673
4481
  const fixture = env.CLIP_WATCHER_FIXTURE;
4674
4482
  if (fixture === "loaded-enabled") return { loaded: true, enabled: true, kind: "production" };
4675
4483
  if (fixture === "stopped") return { loaded: false, enabled: false, kind: "production" };
@@ -4681,8 +4489,17 @@ function watcherStatus(env, label) {
4681
4489
  if (!launchdLoaded(label)) {
4682
4490
  return { loaded: false, enabled: false, kind: "unknown" };
4683
4491
  }
4684
- const plist = join23(process.env.HOME ?? "", "Library", "LaunchAgents", `${label}.plist`);
4685
- return { loaded: true, enabled: existsSync19(plist), kind: "production" };
4492
+ const plist = join21(home, "Library", "LaunchAgents", `${label}.plist`);
4493
+ try {
4494
+ const text = readFileSync12(plist, "utf8");
4495
+ const xmlRoot = xml(root);
4496
+ const matchesRoot = text.includes(`<key>WatchPaths</key><array><string>${xmlRoot}</string></array>`);
4497
+ const disabled = execSync7(`launchctl print-disabled gui/${process.getuid()}`, { encoding: "utf8", timeout: 2e3, stdio: ["ignore", "pipe", "ignore"] });
4498
+ const explicitlyDisabled = disabled.split("\n").some((line) => line.includes(`"${label}"`) && line.includes("true"));
4499
+ return { loaded: true, enabled: matchesRoot && !explicitlyDisabled, kind: "production" };
4500
+ } catch {
4501
+ return { loaded: true, enabled: false, kind: "unknown" };
4502
+ }
4686
4503
  }
4687
4504
  function pushLoaded(env) {
4688
4505
  if (env.CLIP_PUSH_FIXTURE === "loaded") return true;
@@ -4695,9 +4512,20 @@ function credentialPresent(env, ref) {
4695
4512
  const value = env[ref];
4696
4513
  return typeof value === "string" && value.length > 0;
4697
4514
  }
4698
- function listenerOk(env) {
4515
+ function listenerOk(env, home) {
4699
4516
  if (env.CLIP_LISTENER_FIXTURE === "ok") return true;
4700
- return false;
4517
+ if (env.CLIP_LISTENER_FIXTURE === "missing" || env.CLIP_LISTENER_FIXTURE === "disabled") return false;
4518
+ if (!launchdLoaded(PRODUCTION_MIRROR_LABEL)) return false;
4519
+ const plist = join21(home, "Library", "LaunchAgents", `${PRODUCTION_MIRROR_LABEL}.plist`);
4520
+ try {
4521
+ const text = readFileSync12(plist, "utf8");
4522
+ if (text.includes("<key>WatchPaths</key>")) return false;
4523
+ const disabled = execSync7(`launchctl print-disabled gui/${process.getuid()}`, { encoding: "utf8", timeout: 2e3, stdio: ["ignore", "pipe", "ignore"] });
4524
+ const explicitlyDisabled = disabled.split("\n").some((line) => line.includes(`"${PRODUCTION_MIRROR_LABEL}"`) && line.includes("true"));
4525
+ return text.includes("mirror-watch") && text.includes(PRODUCTION_MIRROR_LABEL) && !explicitlyDisabled;
4526
+ } catch {
4527
+ return false;
4528
+ }
4701
4529
  }
4702
4530
  function conditionalCreateEvidence(env) {
4703
4531
  return env.CLIP_CONDITIONAL_CREATE_FIXTURE === "ok";
@@ -4722,14 +4550,26 @@ var clipOutboxProbe = {
4722
4550
  return notConfigured();
4723
4551
  }
4724
4552
  const cfg = resolved.config;
4725
- const frozen = existsSync19(join23(cfg.mirrorRoot, ".WIKI_GIT_FROZEN"));
4553
+ const frozen = existsSync18(join21(cfg.mirrorRoot, ".WIKI_GIT_FROZEN"));
4726
4554
  const pushOn = ctx.vsConfig.pushEnabled !== false;
4727
4555
  const pushIsLoaded = pushLoaded(env);
4728
- const watch = watcherStatus(env, cfg.watcherLabel);
4729
- const s3Creds = credentialPresent(env, cfg.s3CredentialRef);
4730
- const readyCreds = credentialPresent(env, cfg.readyCredentialRef);
4731
- const condCreate = conditionalCreateEvidence(env);
4732
- const listener = listenerOk(env);
4556
+ const watch = watcherStatus(env, cfg.watcherLabel, ctx.input.home, cfg.root);
4557
+ let s3Creds = credentialPresent(env, cfg.s3CredentialRef);
4558
+ let readyCreds = credentialPresent(env, cfg.readyCredentialRef);
4559
+ let condCreate = conditionalCreateEvidence(env);
4560
+ if (!env.CLIP_CREDENTIAL_FIXTURE) {
4561
+ try {
4562
+ const credentials = await loadClipCredentials(ctx.input.home, cfg, env);
4563
+ s3Creds = true;
4564
+ readyCreds = true;
4565
+ condCreate = await conditionalCreateProven(cfg, credentials.s3.endpoint);
4566
+ } catch {
4567
+ s3Creds = false;
4568
+ readyCreds = false;
4569
+ condCreate = false;
4570
+ }
4571
+ }
4572
+ const listener = listenerOk(env, ctx.input.home);
4733
4573
  return [
4734
4574
  check("pass", "clip_config", clipLabel("clip_config"), "clip_outbox.enabled=true; schema valid"),
4735
4575
  frozen ? check("pass", "clip_frozen_mirror", clipLabel("clip_frozen_mirror"), "frozen marker present") : check("error", "clip_frozen_mirror", clipLabel("clip_frozen_mirror"), "frozen marker missing; do not unfreeze"),
@@ -4738,7 +4578,7 @@ var clipOutboxProbe = {
4738
4578
  watch.kind === "retired" ? check("error", "clip_watcher", clipLabel("clip_watcher"), "retired wiki-dev or D8 job does not satisfy the clip watcher") : watch.loaded && watch.enabled && watch.kind === "production" ? check("pass", "clip_watcher", clipLabel("clip_watcher"), `loaded and enabled: ${PRODUCTION_WATCHER_LABEL}`) : check("error", "clip_watcher", clipLabel("clip_watcher"), "production clip watcher not loaded and enabled"),
4739
4579
  s3Creds && readyCreds && condCreate ? check("pass", "clip_storage_credentials", clipLabel("clip_storage_credentials"), "credential references present; conditional-create evidence available") : check("error", "clip_storage_credentials", clipLabel("clip_storage_credentials"), "missing credential reference or conditional-create evidence"),
4740
4580
  readyCreds ? check("pass", "clip_ready_channel", clipLabel("clip_ready_channel"), "ready URL and credential reference present") : check("error", "clip_ready_channel", clipLabel("clip_ready_channel"), "ready credential missing"),
4741
- listener ? check("pass", "clip_mirror_listener", clipLabel("clip_mirror_listener"), "inbound production SSE listener configured") : check("error", "clip_mirror_listener", clipLabel("clip_mirror_listener"), "inbound SSE listener disabled or missing")
4581
+ listener ? check("pass", "clip_mirror_listener", clipLabel("clip_mirror_listener"), `loaded and enabled: ${PRODUCTION_MIRROR_LABEL}`) : check("error", "clip_mirror_listener", clipLabel("clip_mirror_listener"), "inbound SSE listener disabled or missing")
4742
4582
  ];
4743
4583
  }
4744
4584
  };
@@ -4769,7 +4609,7 @@ function resolveSnapshotGitWorktree(home) {
4769
4609
  const configured = resolveConfiguredSnapshotWorktree(home);
4770
4610
  if (configured) return configured;
4771
4611
  const defaultPath = "/root/wiki-git";
4772
- return existsSync20(defaultPath) ? defaultPath : void 0;
4612
+ return existsSync19(defaultPath) ? defaultPath : void 0;
4773
4613
  }
4774
4614
  var DoctorRunner = class {
4775
4615
  probes;
@@ -4849,6 +4689,9 @@ var DoctorRunner = class {
4849
4689
  if (summary.info > 0) summaryParts.push(`${summary.info} info`);
4850
4690
  summaryParts.push(`${summary.warn} warn`, `${summary.error} error`);
4851
4691
  lines.push(summaryParts.join(" \xB7 "));
4692
+ if (checks.some((c) => c.id === "clip_config" && c.detail === "clip channel not configured")) {
4693
+ lines.push("Clip setup is attended: skillwiki clip-outbox install-or-migrate refreshes the packaged plist; prove SeaweedFS conditional-create before enabling/loading the channel.");
4694
+ }
4852
4695
  const humanHint = redactMcpSecret(lines.join("\n"), auth.token);
4853
4696
  return { exitCode, result: ok({ checks, summary, humanHint }) };
4854
4697
  }
@@ -4858,7 +4701,7 @@ async function runDoctor(input) {
4858
4701
  }
4859
4702
 
4860
4703
  // src/utils/package-info.ts
4861
- import { readFileSync as readFileSync12 } from "fs";
4704
+ import { readFileSync as readFileSync13 } from "fs";
4862
4705
  function packageJsonCandidateUrls(baseUrl = import.meta.url) {
4863
4706
  return [
4864
4707
  new URL("../package.json", baseUrl),
@@ -4868,7 +4711,7 @@ function packageJsonCandidateUrls(baseUrl = import.meta.url) {
4868
4711
  function readCliPackageJson(baseUrl = import.meta.url) {
4869
4712
  for (const url of packageJsonCandidateUrls(baseUrl)) {
4870
4713
  try {
4871
- const pkg = JSON.parse(readFileSync12(url, "utf8"));
4714
+ const pkg = JSON.parse(readFileSync13(url, "utf8"));
4872
4715
  if (typeof pkg.version === "string") {
4873
4716
  return { ...pkg, version: pkg.version };
4874
4717
  }
@@ -4880,8 +4723,8 @@ function readCliPackageJson(baseUrl = import.meta.url) {
4880
4723
 
4881
4724
  // src/utils/vault-write-gates.ts
4882
4725
  import { execFileSync } from "child_process";
4883
- import { existsSync as existsSync21, readdirSync as readdirSync7, readFileSync as readFileSync13, statSync as statSync4 } from "fs";
4884
- import { join as join24, relative as relative2 } from "path";
4726
+ import { existsSync as existsSync20, readdirSync as readdirSync7, readFileSync as readFileSync14, statSync as statSync3 } from "fs";
4727
+ import { join as join22, relative as relative2 } from "path";
4885
4728
  var DEFAULT_DIRTY_VOLUME_THRESHOLD = 50;
4886
4729
  var DEFAULT_CAPTURE_BUDGET = 20;
4887
4730
  var DEFAULT_NO_DECISION_STREAK = 3;
@@ -4937,7 +4780,7 @@ function isEventLedgerPath(rel) {
4937
4780
  return n === "meta/log-events" || n.startsWith("meta/log-events/");
4938
4781
  }
4939
4782
  function countEventLedgerFiles(vault) {
4940
- return listFilesRecursive(join24(vault, "meta", "log-events")).length;
4783
+ return listFilesRecursive(join22(vault, "meta", "log-events")).length;
4941
4784
  }
4942
4785
  function measureDirtyVolume(vault) {
4943
4786
  const empty = (extra = {}) => ({
@@ -4953,7 +4796,7 @@ function measureDirtyVolume(vault) {
4953
4796
  is_git_repo: false,
4954
4797
  ...extra
4955
4798
  });
4956
- if (!existsSync21(vault) || !statSync4(vault).isDirectory()) {
4799
+ if (!existsSync20(vault) || !statSync3(vault).isDirectory()) {
4957
4800
  return empty();
4958
4801
  }
4959
4802
  const gitDir = git(vault, ["rev-parse", "--absolute-git-dir"]);
@@ -4997,8 +4840,8 @@ function measureDirtyVolume(vault) {
4997
4840
  if (!rel) continue;
4998
4841
  if (code === "??") {
4999
4842
  untracked += 1;
5000
- const abs = join24(vault, rel);
5001
- if (existsSync21(abs) && statSync4(abs).isDirectory()) {
4843
+ const abs = join22(vault, rel);
4844
+ if (existsSync20(abs) && statSync3(abs).isDirectory()) {
5002
4845
  const files = listFilesRecursive(abs);
5003
4846
  expanded += files.length;
5004
4847
  addBucket(rel, files.length);
@@ -5041,9 +4884,9 @@ function listFilesRecursive(dir) {
5041
4884
  }
5042
4885
  for (const name of entries) {
5043
4886
  if (name === ".git") continue;
5044
- const p = join24(dir, name);
4887
+ const p = join22(dir, name);
5045
4888
  try {
5046
- const st = statSync4(p);
4889
+ const st = statSync3(p);
5047
4890
  if (st.isDirectory()) out.push(...listFilesRecursive(p));
5048
4891
  else if (st.isFile()) out.push(p);
5049
4892
  } catch {
@@ -5136,7 +4979,7 @@ var CAPTURE_HYGIENE_CONTRACT = `After each productive cycle (or when daily captu
5136
4979
  function listProjectDayCaptures(vault, project, day) {
5137
4980
  const found = [];
5138
4981
  const slug = project.replace(/^\[\[/, "").replace(/\]\]$/, "").trim();
5139
- if (!slug || !existsSync21(vault)) return found;
4982
+ if (!slug || !existsSync20(vault)) return found;
5140
4983
  const consider = (abs, rel) => {
5141
4984
  if (!rel.endsWith(".md")) return;
5142
4985
  const base = rel.split(/[/\\]/).pop() ?? "";
@@ -5153,7 +4996,7 @@ function listProjectDayCaptures(vault, project, day) {
5153
4996
  }
5154
4997
  if (norm.startsWith("raw/transcripts/")) {
5155
4998
  try {
5156
- const body = readFileSync13(abs, "utf8");
4999
+ const body = readFileSync14(abs, "utf8");
5157
5000
  if (body.includes(`project: ${slug}`) || body.includes(`project: "[[${slug}]]"`) || body.includes(`project: [[${slug}]]`)) {
5158
5001
  found.push(norm);
5159
5002
  } else if (base.includes(slug)) {
@@ -5164,7 +5007,7 @@ function listProjectDayCaptures(vault, project, day) {
5164
5007
  }
5165
5008
  };
5166
5009
  const walk = (dir, relBase) => {
5167
- if (!existsSync21(dir)) return;
5010
+ if (!existsSync20(dir)) return;
5168
5011
  let entries;
5169
5012
  try {
5170
5013
  entries = readdirSync7(dir);
@@ -5172,27 +5015,27 @@ function listProjectDayCaptures(vault, project, day) {
5172
5015
  return;
5173
5016
  }
5174
5017
  for (const name of entries) {
5175
- const abs = join24(dir, name);
5018
+ const abs = join22(dir, name);
5176
5019
  const rel = relBase ? `${relBase}/${name}` : name;
5177
5020
  try {
5178
- const st = statSync4(abs);
5021
+ const st = statSync3(abs);
5179
5022
  if (st.isDirectory()) walk(abs, rel);
5180
5023
  else if (st.isFile()) consider(abs, rel);
5181
5024
  } catch {
5182
5025
  }
5183
5026
  }
5184
5027
  };
5185
- walk(join24(vault, "raw", "transcripts"), "raw/transcripts");
5186
- walk(join24(vault, "projects", slug, "raw", "transcripts"), `projects/${slug}/raw/transcripts`);
5187
- walk(join24(vault, "projects", slug, "requirements"), `projects/${slug}/requirements`);
5188
- const workRoot = join24(vault, "projects", slug, "work");
5189
- if (existsSync21(workRoot)) {
5028
+ walk(join22(vault, "raw", "transcripts"), "raw/transcripts");
5029
+ walk(join22(vault, "projects", slug, "raw", "transcripts"), `projects/${slug}/raw/transcripts`);
5030
+ walk(join22(vault, "projects", slug, "requirements"), `projects/${slug}/requirements`);
5031
+ const workRoot = join22(vault, "projects", slug, "work");
5032
+ if (existsSync20(workRoot)) {
5190
5033
  try {
5191
5034
  for (const name of readdirSync7(workRoot)) {
5192
5035
  if (!name.startsWith(day)) continue;
5193
5036
  if (!/investigate|pilot-q|research|cycle|dev-loop/.test(name)) continue;
5194
- const abs = join24(workRoot, name);
5195
- if (statSync4(abs).isDirectory()) {
5037
+ const abs = join22(workRoot, name);
5038
+ if (statSync3(abs).isDirectory()) {
5196
5039
  for (const f of listFilesRecursive(abs)) {
5197
5040
  const rel = relative2(vault, f).replace(/\\/g, "/");
5198
5041
  if (rel.endsWith(".md")) found.push(rel);
@@ -5236,7 +5079,7 @@ function evaluateCaptureBudget(input) {
5236
5079
  return { allowed: true, reason: "under_budget", report };
5237
5080
  }
5238
5081
  function runWritePreflight(input) {
5239
- if (!input.vault || !existsSync21(input.vault)) {
5082
+ if (!input.vault || !existsSync20(input.vault)) {
5240
5083
  return err(GateError.VAULT_PATH_INVALID, { path: input.vault });
5241
5084
  }
5242
5085
  const want = new Set(input.checks ?? ["all"]);
@@ -5296,8 +5139,8 @@ function runWritePreflight(input) {
5296
5139
 
5297
5140
  // src/commands/observe.ts
5298
5141
  import { mkdir as mkdir3, writeFile as writeFile3 } from "fs/promises";
5299
- import { existsSync as existsSync22, statSync as statSync5 } from "fs";
5300
- import { join as join25 } from "path";
5142
+ import { existsSync as existsSync21, statSync as statSync4 } from "fs";
5143
+ import { join as join23 } from "path";
5301
5144
  import { createHash as createHash2 } from "crypto";
5302
5145
  var ALLOWED_KINDS = /* @__PURE__ */ new Set(["note", "bug", "task", "idea", "session-log"]);
5303
5146
  function slugify(text) {
@@ -5320,7 +5163,7 @@ async function runObserve(input) {
5320
5163
  result: err("SCHEME_REJECTED", { message: "Text must not be empty" })
5321
5164
  };
5322
5165
  }
5323
- if (!existsSync22(input.vault) || !statSync5(input.vault).isDirectory()) {
5166
+ if (!existsSync21(input.vault) || !statSync4(input.vault).isDirectory()) {
5324
5167
  return {
5325
5168
  exitCode: ExitCode.VAULT_PATH_INVALID,
5326
5169
  result: err("VAULT_PATH_INVALID", { path: input.vault })
@@ -5346,7 +5189,7 @@ async function runObserve(input) {
5346
5189
  };
5347
5190
  }
5348
5191
  }
5349
- const transcriptsDir = join25(input.vault, "raw", "transcripts");
5192
+ const transcriptsDir = join23(input.vault, "raw", "transcripts");
5350
5193
  try {
5351
5194
  await mkdir3(transcriptsDir, { recursive: true });
5352
5195
  } catch {
@@ -5358,7 +5201,7 @@ async function runObserve(input) {
5358
5201
  const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
5359
5202
  const slug = slugify(input.text);
5360
5203
  const fileName = `${today}-observation-${slug}.md`;
5361
- const filePath = join25(transcriptsDir, fileName);
5204
+ const filePath = join23(transcriptsDir, fileName);
5362
5205
  const body = `
5363
5206
  ${input.text.trim()}
5364
5207
  `;
@@ -5400,7 +5243,7 @@ ${input.text.trim()}
5400
5243
  // src/commands/memory.ts
5401
5244
  import { createHash as createHash3 } from "crypto";
5402
5245
  import { mkdir as mkdir4, readFile as readFile7, readdir as readdir2, stat as stat2, writeFile as writeFile4 } from "fs/promises";
5403
- import { basename as basename2, extname, join as join26, relative as relative3, sep as sep3 } from "path";
5246
+ import { basename as basename2, extname, join as join24, relative as relative3, sep as sep2 } from "path";
5404
5247
 
5405
5248
  // src/utils/memory-authority.ts
5406
5249
  var TIER_RANK = {
@@ -5519,8 +5362,8 @@ async function runMemoryIndex(input) {
5519
5362
  }
5520
5363
  const generatedAt = (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
5521
5364
  const relCachePath = memoryCacheRelPath(input.project);
5522
- const absCachePath = join26(input.vault, relCachePath);
5523
- await mkdir4(join26(input.vault, ".skillwiki", "memory", input.project), { recursive: true });
5365
+ const absCachePath = join24(input.vault, relCachePath);
5366
+ await mkdir4(join24(input.vault, ".skillwiki", "memory", input.project), { recursive: true });
5524
5367
  await writeFile4(absCachePath, `${JSON.stringify({
5525
5368
  generated_at: generatedAt,
5526
5369
  project: input.project,
@@ -5712,7 +5555,7 @@ async function buildMemoryIndexState(pages, project) {
5712
5555
  }
5713
5556
  async function checkMemoryIndex(vault, project, current) {
5714
5557
  const relCachePath = memoryCacheRelPath(project);
5715
- const cacheText = await readIfExists(join26(vault, relCachePath));
5558
+ const cacheText = await readIfExists(join24(vault, relCachePath));
5716
5559
  if (!cacheText) {
5717
5560
  return {
5718
5561
  ok: true,
@@ -6121,7 +5964,7 @@ async function walkImportFiles(dir, out) {
6121
5964
  const entries = await readdir2(dir, { withFileTypes: true });
6122
5965
  for (const entry of entries) {
6123
5966
  if (entry.name === ".git" || entry.name === "node_modules") continue;
6124
- const path = join26(dir, entry.name);
5967
+ const path = join24(dir, entry.name);
6125
5968
  if (entry.isDirectory()) {
6126
5969
  await walkImportFiles(path, out);
6127
5970
  } else if (entry.isFile() && isImportCandidate(path)) {
@@ -6171,7 +6014,7 @@ async function buildImportEntry(file, sourceRoot, project, today, maxBytes) {
6171
6014
  const redacted = redactSensitiveContent(extracted, { file });
6172
6015
  const privacy = redacted.findings.length > 0 ? "sensitive" : "local";
6173
6016
  const sourceSlug = slugify2(basename2(file, extname(file)));
6174
- const relSource = relative3(sourceRoot, file).split(sep3).join("/");
6017
+ const relSource = relative3(sourceRoot, file).split(sep2).join("/");
6175
6018
  const entry = {
6176
6019
  ...baseEntry,
6177
6020
  status: "ready",
@@ -6188,8 +6031,8 @@ async function writeImportCapture(vault, entry, today) {
6188
6031
  const content = hiddenString(entry, "__content");
6189
6032
  const project = hiddenString(entry, "__project");
6190
6033
  const relPath = await availableImportPath(vault, entry.proposed_path);
6191
- const absPath = join26(vault, relPath);
6192
- await mkdir4(join26(vault, "raw", "transcripts"), { recursive: true });
6034
+ const absPath = join24(vault, relPath);
6035
+ await mkdir4(join24(vault, "raw", "transcripts"), { recursive: true });
6193
6036
  await writeFile4(absPath, renderImportCapture(entry, content, project, today), "utf8");
6194
6037
  const validation = await runValidate({ file: absPath });
6195
6038
  return {
@@ -6205,7 +6048,7 @@ async function availableImportPath(vault, proposed) {
6205
6048
  const stem = proposed.slice(0, -ext.length);
6206
6049
  let candidate = proposed;
6207
6050
  let i = 2;
6208
- while (await readIfExists(join26(vault, candidate))) {
6051
+ while (await readIfExists(join24(vault, candidate))) {
6209
6052
  candidate = `${stem}-${i}${ext}`;
6210
6053
  i++;
6211
6054
  }
@@ -6243,7 +6086,7 @@ function hiddenString(entry, key) {
6243
6086
  return entry[key] ?? "";
6244
6087
  }
6245
6088
  function classifyImportSource(file) {
6246
- const rel = file.split(sep3).join("/");
6089
+ const rel = file.split(sep2).join("/");
6247
6090
  const name = basename2(file);
6248
6091
  if (rel.includes("/.codex/memories/")) return "codex-memory";
6249
6092
  if (rel.includes("/.codex/rules/")) return "codex-rule";
@@ -6390,10 +6233,10 @@ function memoryCacheRelPath(project) {
6390
6233
  }
6391
6234
  async function readMemoryCache(vault, project) {
6392
6235
  if (project) {
6393
- const projectCache = await readIfExists(join26(vault, memoryCacheRelPath(project)));
6236
+ const projectCache = await readIfExists(join24(vault, memoryCacheRelPath(project)));
6394
6237
  if (projectCache) return projectCache;
6395
6238
  }
6396
- return readIfExists(join26(vault, ".skillwiki", "memory-topics.json"));
6239
+ return readIfExists(join24(vault, ".skillwiki", "memory-topics.json"));
6397
6240
  }
6398
6241
  function dedupePages(pages) {
6399
6242
  const seen = /* @__PURE__ */ new Set();
@@ -6485,7 +6328,7 @@ function slugify2(value) {
6485
6328
 
6486
6329
  // src/commands/query.ts
6487
6330
  import { readFile as readFile9, stat as stat4 } from "fs/promises";
6488
- import { join as join28 } from "path";
6331
+ import { join as join26 } from "path";
6489
6332
 
6490
6333
  // src/utils/rrf.ts
6491
6334
  var RRF_K = 60;
@@ -6501,8 +6344,8 @@ function fuseRankings(lists, k = RRF_K) {
6501
6344
 
6502
6345
  // src/utils/vector-index.ts
6503
6346
  import { mkdir as mkdir5, readFile as readFile8, stat as stat3 } from "fs/promises";
6504
- import { join as join27 } from "path";
6505
- import { existsSync as existsSync23 } from "fs";
6347
+ import { join as join25 } from "path";
6348
+ import { existsSync as existsSync22 } from "fs";
6506
6349
  var VECTOR_INDEX_REL = ".skillwiki/vectors/index.json";
6507
6350
  var VECTOR_INDEX_SCHEMA = "skillwiki-tfidf-index/v1";
6508
6351
  function tokenize(text) {
@@ -6516,7 +6359,7 @@ function extractPageTokens(text) {
6516
6359
  return tokenize(`${title} ${body}`);
6517
6360
  }
6518
6361
  function vectorIndexPath(vault) {
6519
- return join27(vault, ...VECTOR_INDEX_REL.split("/"));
6362
+ return join25(vault, ...VECTOR_INDEX_REL.split("/"));
6520
6363
  }
6521
6364
  function termFreq(tokens) {
6522
6365
  const tf = /* @__PURE__ */ new Map();
@@ -6571,7 +6414,7 @@ async function buildVectorIndex(vault, now = (/* @__PURE__ */ new Date()).toISOS
6571
6414
  docs
6572
6415
  };
6573
6416
  const dest = vectorIndexPath(vault);
6574
- await mkdir5(join27(vault, ".skillwiki", "vectors"), { recursive: true });
6417
+ await mkdir5(join25(vault, ".skillwiki", "vectors"), { recursive: true });
6575
6418
  await atomicWriteText(dest, `${JSON.stringify(index)}
6576
6419
  `);
6577
6420
  return ok(index);
@@ -6614,7 +6457,7 @@ async function reindexPageInVectorIndex(vault, pageRelPath, now = (/* @__PURE__
6614
6457
  if (!normalizedPage.endsWith(".md")) {
6615
6458
  return err("USAGE", { message: `Page must be a .md file: ${pageRelPath}` });
6616
6459
  }
6617
- const absPath = join27(vault, ...normalizedPage.split("/"));
6460
+ const absPath = join25(vault, ...normalizedPage.split("/"));
6618
6461
  let text;
6619
6462
  try {
6620
6463
  text = await readFile8(absPath, "utf8");
@@ -6699,7 +6542,7 @@ async function reindexPageInVectorIndex(vault, pageRelPath, now = (/* @__PURE__
6699
6542
  }
6700
6543
  }
6701
6544
  const dest = vectorIndexPath(vault);
6702
- await mkdir5(join27(vault, ".skillwiki", "vectors"), { recursive: true });
6545
+ await mkdir5(join25(vault, ".skillwiki", "vectors"), { recursive: true });
6703
6546
  await atomicWriteText(dest, `${JSON.stringify(index)}
6704
6547
  `);
6705
6548
  return ok({
@@ -6717,8 +6560,8 @@ async function pruneVectorIndex(vault, opts) {
6717
6560
  const orphans = [];
6718
6561
  for (const docKey of Object.keys(index.docs)) {
6719
6562
  const normalizedKey = docKey.split(/\\|\//).join("/");
6720
- const absPath = join27(vault, ...normalizedKey.split("/"));
6721
- if (!existsSync23(absPath)) {
6563
+ const absPath = join25(vault, ...normalizedKey.split("/"));
6564
+ if (!existsSync22(absPath)) {
6722
6565
  orphans.push(normalizedKey);
6723
6566
  }
6724
6567
  }
@@ -6764,7 +6607,7 @@ async function pruneVectorIndex(vault, opts) {
6764
6607
  index.docs[docKey] = toTfIdf(termFreq(tokens), index.df, newPageCount);
6765
6608
  } else {
6766
6609
  try {
6767
- const text = await readFile8(join27(vault, ...docKey.split("/")), "utf8");
6610
+ const text = await readFile8(join25(vault, ...docKey.split("/")), "utf8");
6768
6611
  const tokens = extractPageTokens(text);
6769
6612
  index.docs[docKey] = toTfIdf(termFreq(tokens), index.df, newPageCount);
6770
6613
  } catch {
@@ -6774,7 +6617,7 @@ async function pruneVectorIndex(vault, opts) {
6774
6617
  }
6775
6618
  if (!opts?.dryRun) {
6776
6619
  const dest = vectorIndexPath(vault);
6777
- await mkdir5(join27(vault, ".skillwiki", "vectors"), { recursive: true });
6620
+ await mkdir5(join25(vault, ".skillwiki", "vectors"), { recursive: true });
6778
6621
  await atomicWriteText(dest, `${JSON.stringify(index)}
6779
6622
  `);
6780
6623
  }
@@ -6905,7 +6748,7 @@ async function runQuery(input) {
6905
6748
  }
6906
6749
  let pendingSources;
6907
6750
  if (input.includePending) {
6908
- const { runSourcesPending: runSourcesPending2 } = await import("./sources-CLOF5VAT.js");
6751
+ const { runSourcesPending: runSourcesPending2 } = await import("./sources-AOYP6ROO.js");
6909
6752
  const pending = await runSourcesPending2({
6910
6753
  vault: input.vault,
6911
6754
  match: input.text,
@@ -7075,7 +6918,7 @@ function computeKeywordScore(terms, title, tags, body, relPath) {
7075
6918
  return score;
7076
6919
  }
7077
6920
  async function loadOrBuildGraph(vault) {
7078
- const graphPath = join28(vault, ".skillwiki", "graph.json");
6921
+ const graphPath = join26(vault, ".skillwiki", "graph.json");
7079
6922
  let needsBuild = false;
7080
6923
  try {
7081
6924
  const fileStat = await stat4(graphPath);
@@ -7164,27 +7007,27 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
7164
7007
  import { z } from "zod";
7165
7008
 
7166
7009
  // src/mcp/vault-resolve.ts
7167
- import { join as join29, resolve as resolve5 } from "path";
7010
+ import { join as join27, resolve as resolve4 } from "path";
7168
7011
 
7169
7012
  // src/mcp/allowlist.ts
7170
- import { resolve as resolve4, sep as sep4 } from "path";
7171
- import { realpathSync as realpathSync2 } from "fs";
7013
+ import { resolve as resolve3, sep as sep3 } from "path";
7014
+ import { realpathSync } from "fs";
7172
7015
  function parseVaultAllowlist(envValue) {
7173
7016
  if (envValue === void 0 || envValue.trim() === "") return null;
7174
- return envValue.split(",").map((s) => s.trim()).filter((s) => s.length > 0).map((p) => resolve4(p));
7017
+ return envValue.split(",").map((s) => s.trim()).filter((s) => s.length > 0).map((p) => resolve3(p));
7175
7018
  }
7176
7019
  function vaultAllowedByList(vaultPath, allowlist) {
7177
7020
  if (!allowlist || allowlist.length === 0) return true;
7178
7021
  let canonical = vaultPath;
7179
7022
  try {
7180
- canonical = realpathSync2(vaultPath);
7023
+ canonical = realpathSync(vaultPath);
7181
7024
  } catch {
7182
- canonical = resolve4(vaultPath);
7025
+ canonical = resolve3(vaultPath);
7183
7026
  }
7184
- const resolved = resolve4(canonical);
7027
+ const resolved = resolve3(canonical);
7185
7028
  return allowlist.some((root) => {
7186
- const r = resolve4(root);
7187
- return resolved === r || resolved.startsWith(r + sep4);
7029
+ const r = resolve3(root);
7030
+ return resolved === r || resolved.startsWith(r + sep3);
7188
7031
  });
7189
7032
  }
7190
7033
  function getVaultAllowlistFromEnv() {
@@ -7197,7 +7040,7 @@ async function resolveMcpVault(input) {
7197
7040
  let vaultPath;
7198
7041
  let source = "resolved";
7199
7042
  if (input.vault !== void 0 && input.vault.length > 0) {
7200
- vaultPath = resolve5(input.vault);
7043
+ vaultPath = resolve4(input.vault);
7201
7044
  source = "flag";
7202
7045
  } else {
7203
7046
  const r = await resolveRuntimePath({
@@ -7209,7 +7052,7 @@ async function resolveMcpVault(input) {
7209
7052
  cwd: input.cwd ?? process.cwd()
7210
7053
  });
7211
7054
  if (!r.ok) return r;
7212
- vaultPath = resolve5(r.data.path);
7055
+ vaultPath = resolve4(r.data.path);
7213
7056
  source = r.data.source;
7214
7057
  }
7215
7058
  const scan = await scanVault(vaultPath);
@@ -7226,7 +7069,7 @@ async function resolveMcpVault(input) {
7226
7069
  return ok({ vault: vaultPath, source });
7227
7070
  }
7228
7071
  function defaultGraphOut(vault) {
7229
- return join29(vault, ".skillwiki", "graph.json");
7072
+ return join27(vault, ".skillwiki", "graph.json");
7230
7073
  }
7231
7074
 
7232
7075
  // src/mcp/result-format.ts
@@ -7242,7 +7085,7 @@ function formatToolResult(payload) {
7242
7085
 
7243
7086
  // src/mcp/audit-log.ts
7244
7087
  import { appendFileSync, mkdirSync as mkdirSync2 } from "fs";
7245
- import { join as join30 } from "path";
7088
+ import { join as join28 } from "path";
7246
7089
  function auditEnabled() {
7247
7090
  const v = process.env.SKILLWIKI_MCP_AUDIT;
7248
7091
  if (v === "0" || v === "false") return false;
@@ -7254,7 +7097,7 @@ function auditSink() {
7254
7097
  function auditFilePath() {
7255
7098
  const custom = process.env.SKILLWIKI_MCP_AUDIT_FILE;
7256
7099
  if (custom && custom.length > 0) return custom;
7257
- return join30(resolveSkillwikiHome(), ".skillwiki", "mcp-audit.jsonl");
7100
+ return join28(resolveSkillwikiHome(), ".skillwiki", "mcp-audit.jsonl");
7258
7101
  }
7259
7102
  function auditMcpToolCall(entry) {
7260
7103
  if (!auditEnabled()) return;
@@ -7264,7 +7107,7 @@ function auditMcpToolCall(entry) {
7264
7107
  return;
7265
7108
  }
7266
7109
  const path = auditFilePath();
7267
- mkdirSync2(join30(path, ".."), { recursive: true });
7110
+ mkdirSync2(join28(path, ".."), { recursive: true });
7268
7111
  appendFileSync(path, line, "utf8");
7269
7112
  }
7270
7113
  async function runMcpToolHandler(tool, input, fn) {
@@ -7539,7 +7382,7 @@ function registerMcpMutatingTools(server) {
7539
7382
 
7540
7383
  // src/mcp/resources.ts
7541
7384
  import { readFile as readFile11 } from "fs/promises";
7542
- import { join as join32 } from "path";
7385
+ import { join as join30 } from "path";
7543
7386
  import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
7544
7387
 
7545
7388
  // src/mcp/lint-bucket.ts
@@ -7669,8 +7512,8 @@ async function fetchQueryPreview(input) {
7669
7512
 
7670
7513
  // src/mcp/graph-html.ts
7671
7514
  import { readFile as readFile10 } from "fs/promises";
7672
- import { join as join31 } from "path";
7673
- import { existsSync as existsSync24 } from "fs";
7515
+ import { join as join29 } from "path";
7516
+ import { existsSync as existsSync23 } from "fs";
7674
7517
  var TYPE_COLORS = {
7675
7518
  entities: "#e74c3c",
7676
7519
  concepts: "#27ae60",
@@ -7738,9 +7581,9 @@ ${nodeSvg}
7738
7581
  return { html, node_count: nodes.length, edge_count: edges.length, truncated };
7739
7582
  }
7740
7583
  async function fetchGraphHtmlReport(input) {
7741
- const graphPath = input.graphPath ?? join31(input.vault, ".skillwiki", "graph.json");
7584
+ const graphPath = input.graphPath ?? join29(input.vault, ".skillwiki", "graph.json");
7742
7585
  const maxNodes = Math.min(Math.max(10, input.maxNodes ?? 120), 500);
7743
- if (!existsSync24(graphPath)) {
7586
+ if (!existsSync23(graphPath)) {
7744
7587
  return {
7745
7588
  exitCode: ExitCode.FILE_NOT_FOUND,
7746
7589
  result: err("GRAPH_MISSING", { path: graphPath, hint: "Run skillwiki.graph_build first." })
@@ -7812,7 +7655,7 @@ async function fetchStaleSummary(input) {
7812
7655
 
7813
7656
  // src/mcp/resources.ts
7814
7657
  async function readVaultFile(vault, rel) {
7815
- return readFile11(join32(vault, rel), "utf8");
7658
+ return readFile11(join30(vault, rel), "utf8");
7816
7659
  }
7817
7660
  async function tailLines(text, lines) {
7818
7661
  const parts = text.split(/\r?\n/);
@@ -7898,7 +7741,7 @@ function registerMcpResources(server) {
7898
7741
  if (!v.ok) {
7899
7742
  return { contents: [{ uri: uri.href, mimeType: "text/plain", text: JSON.stringify(v) }] };
7900
7743
  }
7901
- const path = join32(v.data.vault, ".skillwiki", "graph.json");
7744
+ const path = join30(v.data.vault, ".skillwiki", "graph.json");
7902
7745
  try {
7903
7746
  const raw = await readFile11(path, "utf8");
7904
7747
  const graph = JSON.parse(raw);
@@ -8249,13 +8092,6 @@ export {
8249
8092
  renderProjectIndex,
8250
8093
  runProjectIndex,
8251
8094
  scanConflictMarkerBlocksInText,
8252
- MCP_URL_ENV,
8253
- MCP_TOKEN_ENV,
8254
- MCP_HOST_ID_ENV,
8255
- nonEmptyEnvValue,
8256
- mcpAuthFromEnv,
8257
- mergeMcpAuthIntoEnv,
8258
- redactMcpSecret,
8259
8095
  configPath,
8260
8096
  runConfigGet,
8261
8097
  runConfigSet,
@@ -8273,8 +8109,6 @@ export {
8273
8109
  evaluateSatelliteRunHealthState,
8274
8110
  withMcpClient,
8275
8111
  DEFAULT_MCP_URL,
8276
- CLIP_NOT_CONFIGURED,
8277
- loadClipOutboxConfig,
8278
8112
  runDoctor,
8279
8113
  readCliPackageJson,
8280
8114
  DEFAULT_DIRTY_VOLUME_THRESHOLD,