skillwiki 0.9.55 → 0.9.57

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.
@@ -1,13 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- CACHE_FILENAME,
4
- CHECK_INTERVAL_MS,
5
- CLI_DISABLE_FLAG,
6
- DIST_TAG,
7
- ENV_DISABLE_KEY,
8
- normalizeDistTag,
3
+ latestFromCache,
9
4
  semverGt
10
- } from "./chunk-E6UWZ3S3.js";
5
+ } from "./chunk-7I2TPIV5.js";
11
6
 
12
7
  // ../shared/src/exit-codes.ts
13
8
  var ExitCode = {
@@ -2893,6 +2888,7 @@ function buildCliSurface() {
2893
2888
  syncCmd.command("lock").option("--summary <text>").option("--ttl-minutes <n>").option("--force").option("--wiki <name>");
2894
2889
  syncCmd.command("unlock").option("--force").option("--wiki <name>");
2895
2890
  syncCmd.command("peers").option("--wiki <name>");
2891
+ syncCmd.command("lint-delta").option("--base-ref <ref>").option("--wiki <name>");
2896
2892
  const backupCmd = program.commands.find((c) => c.name() === "backup");
2897
2893
  backupCmd.command("sync").option("--dry-run").option("--bucket <name>").option("--endpoint <url>").option("--region <region>").option("--prune").option("--wiki <name>");
2898
2894
  backupCmd.command("restore").option("--bucket <name>").option("--endpoint <url>").option("--region <region>").option("--target <dir>").option("--wiki <name>");
@@ -4255,6 +4251,159 @@ ${split.data.body}`;
4255
4251
  result: ok(input.summary ? summarizeLintOutput(output, input.examplesLimit) : output)
4256
4252
  };
4257
4253
  }
4254
+ function lintIssueFingerprint(bucket, item) {
4255
+ const page = extractIssuePage(item);
4256
+ const detail = normalizeIssueDetail(item);
4257
+ return `${bucket}\0${page}\0${detail}`;
4258
+ }
4259
+ function extractIssuePage(item) {
4260
+ if (typeof item === "string") {
4261
+ const m = item.match(/^([^:]+?)(?::\s|$)/);
4262
+ return (m?.[1] ?? item).trim();
4263
+ }
4264
+ if (item && typeof item === "object") {
4265
+ const obj = item;
4266
+ for (const key of ["path", "file", "page", "relPath"]) {
4267
+ if (typeof obj[key] === "string") return obj[key];
4268
+ }
4269
+ }
4270
+ return "";
4271
+ }
4272
+ function normalizeIssueDetail(item) {
4273
+ if (typeof item === "string") {
4274
+ return item.replace(/\s+/g, " ").trim();
4275
+ }
4276
+ try {
4277
+ return JSON.stringify(item, Object.keys(item).sort());
4278
+ } catch {
4279
+ return String(item);
4280
+ }
4281
+ }
4282
+ function collectLintErrorFingerprints(output) {
4283
+ const fps = /* @__PURE__ */ new Set();
4284
+ for (const bucket of output.by_severity.error) {
4285
+ for (const item of bucket.items) {
4286
+ fps.add(lintIssueFingerprint(bucket.kind, item));
4287
+ }
4288
+ }
4289
+ return fps;
4290
+ }
4291
+ async function runSyncLintDelta(input) {
4292
+ const { mkdtempSync, rmSync, existsSync: fsExists } = await import("fs");
4293
+ const { join: pathJoin } = await import("path");
4294
+ const { tmpdir } = await import("os");
4295
+ const { execFileSync: execFileSync2 } = await import("child_process");
4296
+ const vault = input.vault;
4297
+ const baseRef = input.baseRef ?? "origin/main";
4298
+ const days = input.days ?? 90;
4299
+ const lines = input.lines ?? 200;
4300
+ const logThreshold = input.logThreshold ?? 500;
4301
+ if (!fsExists(pathJoin(vault, ".git"))) {
4302
+ return {
4303
+ exitCode: ExitCode.VAULT_PATH_INVALID,
4304
+ result: err("NOT_A_GIT_REPO", { path: vault })
4305
+ };
4306
+ }
4307
+ try {
4308
+ execFileSync2("git", ["rev-parse", "--verify", baseRef], {
4309
+ cwd: vault,
4310
+ stdio: ["pipe", "pipe", "pipe"]
4311
+ });
4312
+ } catch {
4313
+ return {
4314
+ exitCode: ExitCode.LINT_HAS_ERRORS,
4315
+ result: err("LINT_DELTA_BASE_UNAVAILABLE", {
4316
+ baseRef,
4317
+ message: `base ref ${baseRef} does not resolve \u2014 fail closed`
4318
+ })
4319
+ };
4320
+ }
4321
+ const fullLint = await runLint({ vault, days, lines, logThreshold });
4322
+ if (!fullLint.result.ok) {
4323
+ return {
4324
+ exitCode: ExitCode.LINT_HAS_ERRORS,
4325
+ result: err("LINT_DELTA_FULL_FAILED", { detail: fullLint.result })
4326
+ };
4327
+ }
4328
+ const fullOutput = fullLint.result.data;
4329
+ if (!("by_severity" in fullOutput) || !fullOutput.by_severity) {
4330
+ return {
4331
+ exitCode: ExitCode.LINT_HAS_ERRORS,
4332
+ result: err("LINT_DELTA_MALFORMED", { message: "full lint missing by_severity" })
4333
+ };
4334
+ }
4335
+ const fullFps = collectLintErrorFingerprints(fullOutput);
4336
+ const tmpRoot = mkdtempSync(pathJoin(tmpdir(), "skillwiki-lint-delta-"));
4337
+ try {
4338
+ const archive = execFileSync2("git", ["archive", "--format=tar", baseRef], {
4339
+ cwd: vault,
4340
+ stdio: ["pipe", "pipe", "pipe"],
4341
+ maxBuffer: 256 * 1024 * 1024
4342
+ });
4343
+ execFileSync2("tar", ["-xf", "-"], {
4344
+ cwd: tmpRoot,
4345
+ input: archive,
4346
+ stdio: ["pipe", "pipe", "pipe"]
4347
+ });
4348
+ if (!fsExists(pathJoin(tmpRoot, "SCHEMA.md"))) {
4349
+ }
4350
+ const baseLint = await runLint({ vault: tmpRoot, days, lines, logThreshold });
4351
+ if (!baseLint.result.ok) {
4352
+ return {
4353
+ exitCode: ExitCode.LINT_HAS_ERRORS,
4354
+ result: err("LINT_DELTA_BASE_LINT_FAILED", {
4355
+ baseRef,
4356
+ detail: baseLint.result
4357
+ })
4358
+ };
4359
+ }
4360
+ const baseOutput = baseLint.result.data;
4361
+ if (!("by_severity" in baseOutput) || !baseOutput.by_severity) {
4362
+ return {
4363
+ exitCode: ExitCode.LINT_HAS_ERRORS,
4364
+ result: err("LINT_DELTA_MALFORMED", { message: "base lint missing by_severity" })
4365
+ };
4366
+ }
4367
+ const baseFps = collectLintErrorFingerprints(baseOutput);
4368
+ const newFps = [];
4369
+ const resolvedFps = [];
4370
+ for (const fp of fullFps) {
4371
+ if (!baseFps.has(fp)) newFps.push(fp);
4372
+ }
4373
+ for (const fp of baseFps) {
4374
+ if (!fullFps.has(fp)) resolvedFps.push(fp);
4375
+ }
4376
+ newFps.sort();
4377
+ resolvedFps.sort();
4378
+ const fullList = [...fullFps].sort();
4379
+ const output = {
4380
+ full_errors: fullFps.size,
4381
+ base_errors: baseFps.size,
4382
+ new_errors: newFps.length,
4383
+ resolved_errors: resolvedFps.length,
4384
+ full_fingerprints: fullList,
4385
+ new_fingerprints: newFps,
4386
+ resolved_fingerprints: resolvedFps,
4387
+ base_ref: baseRef,
4388
+ humanHint: newFps.length > 0 ? `lint delta: ${newFps.length} new error(s) vs ${baseRef} (full=${fullFps.size}, base=${baseFps.size}, resolved=${resolvedFps.length})` : fullFps.size > 0 ? `lint delta: 0 new errors vs ${baseRef}; inherited full_errors=${fullFps.size} (base=${baseFps.size}, resolved=${resolvedFps.length})` : `lint delta: clean (0 errors) vs ${baseRef}`
4389
+ };
4390
+ const exitCode = output.new_errors > 0 ? ExitCode.LINT_HAS_ERRORS : fullLint.exitCode === ExitCode.LINT_HAS_WARNINGS ? ExitCode.LINT_HAS_WARNINGS : ExitCode.OK;
4391
+ return { exitCode, result: ok(output) };
4392
+ } catch (e) {
4393
+ return {
4394
+ exitCode: ExitCode.LINT_HAS_ERRORS,
4395
+ result: err("LINT_DELTA_ARCHIVE_FAILED", {
4396
+ baseRef,
4397
+ message: String(e)
4398
+ })
4399
+ };
4400
+ } finally {
4401
+ try {
4402
+ rmSync(tmpRoot, { recursive: true, force: true });
4403
+ } catch {
4404
+ }
4405
+ }
4406
+ }
4258
4407
 
4259
4408
  // src/commands/config.ts
4260
4409
  import { readFile as readFile13 } from "fs/promises";
@@ -4317,71 +4466,12 @@ async function runConfigPath(input) {
4317
4466
  return { exitCode: ExitCode.OK, result: ok({ path: filePath, exists: existsSync6(filePath), humanHint: filePath }) };
4318
4467
  }
4319
4468
 
4320
- // src/utils/auto-update.ts
4321
- import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, existsSync as existsSync7, mkdirSync as mkdirSync3 } from "fs";
4322
- import { join as join17, dirname as dirname7 } from "path";
4323
- import { spawn } from "child_process";
4324
- function cachePath(home) {
4325
- return join17(home, ".skillwiki", CACHE_FILENAME);
4326
- }
4327
- function readCacheRaw(home) {
4328
- try {
4329
- const raw = readFileSync4(cachePath(home), "utf8");
4330
- return JSON.parse(raw);
4331
- } catch {
4332
- return null;
4333
- }
4334
- }
4335
- function readCache(home) {
4336
- const cache = readCacheRaw(home);
4337
- if (!cache) return { cache: null, hasUpdate: false, isStale: true };
4338
- const isStale = Date.now() - cache.lastCheck >= CHECK_INTERVAL_MS;
4339
- const hasUpdate = !!cache.latestVersion && semverGt(cache.latestVersion, cache.currentVersion);
4340
- return { cache, hasUpdate, isStale };
4341
- }
4342
- function writeCache(home, cache) {
4343
- const p = cachePath(home);
4344
- mkdirSync3(dirname7(p), { recursive: true });
4345
- writeFileSync3(p, JSON.stringify(cache, null, 2));
4346
- }
4347
- function latestFromCache(home, currentVersion) {
4348
- const { cache } = readCache(home);
4349
- if (!cache || !cache.latestVersion) return { hasUpdate: false, latest: null, distTag: DIST_TAG };
4350
- const distTag = normalizeDistTag(cache.distTag);
4351
- return {
4352
- hasUpdate: semverGt(cache.latestVersion, currentVersion),
4353
- latest: cache.latestVersion,
4354
- distTag
4355
- };
4356
- }
4357
- function distTagFromCache(home) {
4358
- return normalizeDistTag(readCacheRaw(home)?.distTag);
4359
- }
4360
- function isDisabled() {
4361
- return !!(process.env[ENV_DISABLE_KEY] || process.env.NODE_ENV === "test" || process.argv.includes(CLI_DISABLE_FLAG));
4362
- }
4363
- function triggerAutoUpdate(home, currentVersion) {
4364
- if (isDisabled()) return;
4365
- const { isStale } = readCache(home);
4366
- if (!isStale) return;
4367
- const distTag = distTagFromCache(home);
4368
- const bgScript = new URL("../auto-update-bg.js", import.meta.url).pathname;
4369
- if (!existsSync7(bgScript)) return;
4370
- const child = spawn(process.execPath, [bgScript, home, currentVersion, distTag], {
4371
- detached: true,
4372
- stdio: "ignore"
4373
- });
4374
- child.on("error", () => {
4375
- });
4376
- child.unref();
4377
- }
4378
-
4379
4469
  // src/commands/fleet.ts
4380
4470
  import { readFile as readFile14 } from "fs/promises";
4381
4471
  import { hostname as nodeHostname, userInfo } from "os";
4382
- import { join as join18 } from "path";
4472
+ import { join as join17 } from "path";
4383
4473
  import yaml3 from "js-yaml";
4384
- var FLEET_REL_PATH = join18("projects", "llm-wiki", "architecture", "fleet.yaml");
4474
+ var FLEET_REL_PATH = join17("projects", "llm-wiki", "architecture", "fleet.yaml");
4385
4475
  async function runFleetValidate(input) {
4386
4476
  const loaded = await loadFleetManifest(input.file);
4387
4477
  if (!loaded.ok) {
@@ -4412,7 +4502,7 @@ async function runFleetContext(input) {
4412
4502
  const osHostname = input.osHostname ?? safeEnvValue(env.HOSTNAME) ?? nodeHostname();
4413
4503
  const user = input.user ?? safeEnvValue(env.USER) ?? safeUserName();
4414
4504
  const vault = input.vault ?? safeEnvValue(env.WIKI_PATH);
4415
- const file = input.file ?? (vault ? join18(vault, FLEET_REL_PATH) : void 0);
4505
+ const file = input.file ?? (vault ? join17(vault, FLEET_REL_PATH) : void 0);
4416
4506
  const generatedAt = (/* @__PURE__ */ new Date()).toISOString();
4417
4507
  const loaded = file ? await loadFleetManifest(file) : { ok: false, error: "FILE_NOT_FOUND" };
4418
4508
  if (!loaded.ok) {
@@ -4532,7 +4622,7 @@ function fleetContextEnv(input) {
4532
4622
  const home = input.home ?? env.HOME ?? "";
4533
4623
  const osHostname = input.osHostname ?? safeEnvValue(env.HOSTNAME) ?? nodeHostname();
4534
4624
  const vault = input.vault ?? safeEnvValue(env.WIKI_PATH);
4535
- const file = input.file ?? (vault ? join18(vault, FLEET_REL_PATH) : void 0);
4625
+ const file = input.file ?? (vault ? join17(vault, FLEET_REL_PATH) : void 0);
4536
4626
  return { env, home, osHostname, vault, file };
4537
4627
  }
4538
4628
  async function loadFleetManifestAndHost(input) {
@@ -4666,7 +4756,7 @@ async function resolveFleetHostId(input) {
4666
4756
  }
4667
4757
  trace.push({ source: "AGENT_HOST_ID", status: "unset" });
4668
4758
  if (input.home) {
4669
- const dotenv = await parseDotenvFile(join18(input.home, ".skillwiki", ".env"));
4759
+ const dotenv = await parseDotenvFile(join17(input.home, ".skillwiki", ".env"));
4670
4760
  if (dotenv.SKILLWIKI_HOST_ID) {
4671
4761
  trace.push({ source: "~/.skillwiki/.env:SKILLWIKI_HOST_ID", status: "matched", value: dotenv.SKILLWIKI_HOST_ID });
4672
4762
  return { hostId: dotenv.SKILLWIKI_HOST_ID, source: "~/.skillwiki/.env:SKILLWIKI_HOST_ID", trace };
@@ -4839,20 +4929,20 @@ function safeUserName() {
4839
4929
  }
4840
4930
 
4841
4931
  // src/commands/doctor.ts
4842
- import { existsSync as existsSync13, lstatSync, readlinkSync, readdirSync as readdirSync3, statSync, readFileSync as readFileSync10 } from "fs";
4843
- import { join as join24, resolve as resolve5 } from "path";
4932
+ import { existsSync as existsSync12, lstatSync, readlinkSync, readdirSync as readdirSync3, statSync, readFileSync as readFileSync9 } from "fs";
4933
+ import { join as join23, resolve as resolve5 } from "path";
4844
4934
  import { execSync as execSync2 } from "child_process";
4845
4935
  import { platform as platform2 } from "os";
4846
4936
 
4847
4937
  // src/utils/plugin-registry.ts
4848
- import { existsSync as existsSync8, readdirSync, readFileSync as readFileSync5 } from "fs";
4849
- import { join as join19 } from "path";
4850
- var REGISTRY_PATH = join19(".claude", "plugins", "installed_plugins.json");
4851
- var CODEX_CONFIG_PATH = join19(".codex", "config.toml");
4938
+ import { existsSync as existsSync7, readdirSync, readFileSync as readFileSync4 } from "fs";
4939
+ import { join as join18 } from "path";
4940
+ var REGISTRY_PATH = join18(".claude", "plugins", "installed_plugins.json");
4941
+ var CODEX_CONFIG_PATH = join18(".codex", "config.toml");
4852
4942
  var PLUGIN_KEY = "skillwiki@llm-wiki";
4853
4943
  function readInstalledPlugins(home) {
4854
4944
  try {
4855
- const raw = readFileSync5(join19(home, REGISTRY_PATH), "utf8");
4945
+ const raw = readFileSync4(join18(home, REGISTRY_PATH), "utf8");
4856
4946
  return JSON.parse(raw);
4857
4947
  } catch {
4858
4948
  return null;
@@ -4888,8 +4978,8 @@ function findPluginInstallations(home, key = PLUGIN_KEY) {
4888
4978
  function findCodexPlugin(home, key, pluginName, marketplace) {
4889
4979
  const config = readCodexPluginConfig(home, key, marketplace);
4890
4980
  if (!config?.enabled) return null;
4891
- const cacheRoot = join19(home, ".codex", "plugins", "cache", marketplace, pluginName);
4892
- if (!existsSync8(cacheRoot)) return null;
4981
+ const cacheRoot = join18(home, ".codex", "plugins", "cache", marketplace, pluginName);
4982
+ if (!existsSync7(cacheRoot)) return null;
4893
4983
  let versions;
4894
4984
  try {
4895
4985
  versions = readdirSync(cacheRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
@@ -4904,7 +4994,7 @@ function findCodexPlugin(home, key, pluginName, marketplace) {
4904
4994
  key,
4905
4995
  pluginName,
4906
4996
  marketplace,
4907
- installPath: join19(cacheRoot, version),
4997
+ installPath: join18(cacheRoot, version),
4908
4998
  version,
4909
4999
  sourceType: config.sourceType,
4910
5000
  source: config.source
@@ -4921,7 +5011,7 @@ function parsePluginKey(key) {
4921
5011
  function readCodexPluginConfig(home, key, marketplace) {
4922
5012
  let raw;
4923
5013
  try {
4924
- raw = readFileSync5(join19(home, CODEX_CONFIG_PATH), "utf8");
5014
+ raw = readFileSync4(join18(home, CODEX_CONFIG_PATH), "utf8");
4925
5015
  } catch {
4926
5016
  return null;
4927
5017
  }
@@ -4963,8 +5053,8 @@ function parseTomlScalar(rawValue) {
4963
5053
  }
4964
5054
 
4965
5055
  // src/utils/conflict-markers.ts
4966
- import { existsSync as existsSync9, readdirSync as readdirSync2, readFileSync as readFileSync6 } from "fs";
4967
- import { join as join20 } from "path";
5056
+ import { existsSync as existsSync8, readdirSync as readdirSync2, readFileSync as readFileSync5 } from "fs";
5057
+ import { join as join19 } from "path";
4968
5058
  function scanConflictMarkerBlocksInText(relPath, text) {
4969
5059
  const findings = [];
4970
5060
  const lines = text.split(/\r?\n/);
@@ -5015,21 +5105,21 @@ function walkMarkdownFiles2(root, dir, rel, out) {
5015
5105
  for (const entry of entries) {
5016
5106
  if (entry.isDirectory()) {
5017
5107
  if (PRUNE_DIRS.has(entry.name)) continue;
5018
- walkMarkdownFiles2(root, join20(dir, entry.name), rel ? `${rel}/${entry.name}` : entry.name, out);
5108
+ walkMarkdownFiles2(root, join19(dir, entry.name), rel ? `${rel}/${entry.name}` : entry.name, out);
5019
5109
  } else if (entry.isFile() && entry.name.endsWith(".md")) {
5020
5110
  out.push(rel ? `${rel}/${entry.name}` : entry.name);
5021
5111
  }
5022
5112
  }
5023
5113
  }
5024
5114
  function scanVaultConflictMarkers(vaultRoot) {
5025
- if (!existsSync9(vaultRoot)) return [];
5115
+ if (!existsSync8(vaultRoot)) return [];
5026
5116
  const relPaths = [];
5027
5117
  walkMarkdownFiles2(vaultRoot, vaultRoot, "", relPaths);
5028
5118
  const all = [];
5029
5119
  for (const rel of relPaths) {
5030
5120
  let text;
5031
5121
  try {
5032
- text = readFileSync6(join20(vaultRoot, rel), "utf8");
5122
+ text = readFileSync5(join19(vaultRoot, rel), "utf8");
5033
5123
  } catch {
5034
5124
  continue;
5035
5125
  }
@@ -5039,8 +5129,8 @@ function scanVaultConflictMarkers(vaultRoot) {
5039
5129
  }
5040
5130
 
5041
5131
  // src/utils/remote-health.ts
5042
- import { existsSync as existsSync10, readFileSync as readFileSync7 } from "fs";
5043
- import { join as join21 } from "path";
5132
+ import { existsSync as existsSync9, readFileSync as readFileSync6 } from "fs";
5133
+ import { join as join20 } from "path";
5044
5134
  import { execFileSync } from "child_process";
5045
5135
  var REMOTE_PROBE_TIMEOUT_MS = 3e3;
5046
5136
  var defaultExec = (file, args, cwd) => execFileSync(file, args, {
@@ -5052,7 +5142,7 @@ var defaultExec = (file, args, cwd) => execFileSync(file, args, {
5052
5142
  var DEFAULT_WIKI_S3_REMOTE = "seaweed-wiki:cloud/wiki";
5053
5143
  function readWikiS3RemoteConfigured(home) {
5054
5144
  try {
5055
- const content = readFileSync7(join21(home, ".skillwiki", ".env"), "utf8");
5145
+ const content = readFileSync6(join20(home, ".skillwiki", ".env"), "utf8");
5056
5146
  for (const line of content.split(/\r?\n/)) {
5057
5147
  const trimmed = line.trim();
5058
5148
  if (!trimmed || trimmed.startsWith("#")) continue;
@@ -5070,7 +5160,7 @@ function readWikiS3RemoteFromEnv(home) {
5070
5160
  return readWikiS3RemoteConfigured(home) ?? DEFAULT_WIKI_S3_REMOTE;
5071
5161
  }
5072
5162
  function probeGithubReachability(vaultPath, exec = defaultExec) {
5073
- if (!existsSync10(join21(vaultPath, ".git"))) return "unknown";
5163
+ if (!existsSync9(join20(vaultPath, ".git"))) return "unknown";
5074
5164
  try {
5075
5165
  exec("git", ["remote", "get-url", "origin"], vaultPath);
5076
5166
  } catch {
@@ -5131,11 +5221,11 @@ function probeRemoteHealth(input) {
5131
5221
  }
5132
5222
 
5133
5223
  // src/utils/satellite-run-health.ts
5134
- import { existsSync as existsSync11, readFileSync as readFileSync8 } from "fs";
5135
- import { join as join22 } from "path";
5224
+ import { existsSync as existsSync10, readFileSync as readFileSync7 } from "fs";
5225
+ import { join as join21 } from "path";
5136
5226
  var SATELLITE_STALE_MS = 26 * 60 * 60 * 1e3;
5137
5227
  function satelliteLatestRunPath(vault) {
5138
- return join22(vault, ".skillwiki", "agent-memory-trends", "latest-run.json");
5228
+ return join21(vault, ".skillwiki", "agent-memory-trends", "latest-run.json");
5139
5229
  }
5140
5230
  function isFailedRunStatus(status) {
5141
5231
  return status === "fail" || status === "failure";
@@ -5157,9 +5247,9 @@ function readSatelliteLatestRunFromText(text) {
5157
5247
  }
5158
5248
  function readSatelliteLatestRun(vault) {
5159
5249
  const latestPath = satelliteLatestRunPath(vault);
5160
- if (!existsSync11(latestPath)) return null;
5250
+ if (!existsSync10(latestPath)) return null;
5161
5251
  try {
5162
- return parseLatestRunFile(readFileSync8(latestPath, "utf8"));
5252
+ return parseLatestRunFile(readFileSync7(latestPath, "utf8"));
5163
5253
  } catch {
5164
5254
  return null;
5165
5255
  }
@@ -5188,8 +5278,8 @@ function evaluateSatelliteRunHealth(vault, now) {
5188
5278
  // src/utils/s3-mount-health.ts
5189
5279
  import { execSync } from "child_process";
5190
5280
  import { platform } from "os";
5191
- import { readFileSync as readFileSync9, writeFileSync as writeFileSync4, unlinkSync as unlinkSync3, readFileSync as readFile15 } from "fs";
5192
- import { join as join23 } from "path";
5281
+ import { readFileSync as readFileSync8, writeFileSync as writeFileSync3, unlinkSync as unlinkSync3, readFileSync as readFile15 } from "fs";
5282
+ import { join as join22 } from "path";
5193
5283
  var OS = platform();
5194
5284
  function findRcloneMountPid() {
5195
5285
  try {
@@ -5273,7 +5363,7 @@ function extractRcloneFs(args) {
5273
5363
  function getRcloneArgs(pid) {
5274
5364
  try {
5275
5365
  if (OS === "linux") {
5276
- const raw = readFileSync9(`/proc/${pid}/cmdline`);
5366
+ const raw = readFileSync8(`/proc/${pid}/cmdline`);
5277
5367
  return new TextDecoder().decode(raw).split("\0").filter(Boolean);
5278
5368
  } else {
5279
5369
  const out = execSync(`ps -o args= -p ${pid}`, {
@@ -5316,7 +5406,7 @@ function queryRcloneRC(rcAddr, fs) {
5316
5406
  function detectFuseMount(vaultPath) {
5317
5407
  try {
5318
5408
  if (OS === "linux") {
5319
- const mounts = readFileSync9("/proc/mounts", "utf8");
5409
+ const mounts = readFileSync8("/proc/mounts", "utf8");
5320
5410
  let best = null;
5321
5411
  for (const line of mounts.split("\n")) {
5322
5412
  const parts = line.split(" ");
@@ -5347,11 +5437,11 @@ function detectFuseMount(vaultPath) {
5347
5437
  return null;
5348
5438
  }
5349
5439
  function writeTest(dir) {
5350
- const testFile = join23(dir, `.doctor-write-test-${process.pid}.tmp`);
5440
+ const testFile = join22(dir, `.doctor-write-test-${process.pid}.tmp`);
5351
5441
  const payload = `skillwiki doctor write test \u2014 ${Date.now()} \u2014 ${Math.random().toString(36).slice(2)}`;
5352
5442
  const start = Date.now();
5353
5443
  try {
5354
- writeFileSync4(testFile, payload, "utf8");
5444
+ writeFileSync3(testFile, payload, "utf8");
5355
5445
  } catch (e) {
5356
5446
  return { success: false, writeMs: Date.now() - start, readMs: 0, size: 0, error: `write failed: ${e.message}` };
5357
5447
  }
@@ -5447,13 +5537,13 @@ function detectCliChannels(argv, home) {
5447
5537
  }
5448
5538
  const plugin = findPlugin(home);
5449
5539
  if (plugin) {
5450
- const pluginBin = join24(plugin.installPath, "bin", "skillwiki");
5451
- if (existsSync13(pluginBin)) {
5540
+ const pluginBin = join23(plugin.installPath, "bin", "skillwiki");
5541
+ if (existsSync12(pluginBin)) {
5452
5542
  channels.push({ name: "plugin", path: pluginBin, isDevLink: false });
5453
5543
  }
5454
5544
  }
5455
- const installBin = join24(home, ".claude", "skills", "bin", "skillwiki");
5456
- if (existsSync13(installBin)) {
5545
+ const installBin = join23(home, ".claude", "skills", "bin", "skillwiki");
5546
+ if (existsSync12(installBin)) {
5457
5547
  channels.push({ name: "install", path: installBin, isDevLink: false });
5458
5548
  }
5459
5549
  return channels;
@@ -5514,7 +5604,7 @@ function isDevSourceRun(argv) {
5514
5604
  }
5515
5605
  async function checkConfigFile(home) {
5516
5606
  const cfgPath = configPath(home);
5517
- if (!existsSync13(cfgPath)) {
5607
+ if (!existsSync12(cfgPath)) {
5518
5608
  return check("warn", "config_file", "Config file exists", `${cfgPath} not found`);
5519
5609
  }
5520
5610
  try {
@@ -5529,7 +5619,7 @@ function checkWikiPathExists(resolvedPath) {
5529
5619
  if (resolvedPath === void 0) {
5530
5620
  return check("error", "wiki_path_exists", "Vault directory exists", "Cannot check \u2014 WIKI_PATH not resolved");
5531
5621
  }
5532
- if (existsSync13(resolvedPath) && statSync(resolvedPath).isDirectory()) {
5622
+ if (existsSync12(resolvedPath) && statSync(resolvedPath).isDirectory()) {
5533
5623
  return check("pass", "wiki_path_exists", "Vault directory exists", resolvedPath);
5534
5624
  }
5535
5625
  return check("error", "wiki_path_exists", "Vault directory exists", `${resolvedPath} does not exist or is not a directory`);
@@ -5538,13 +5628,13 @@ function checkVaultStructure(resolvedPath) {
5538
5628
  if (resolvedPath === void 0) {
5539
5629
  return check("error", "vault_structure", "Vault structure valid", "Cannot check \u2014 WIKI_PATH not resolved");
5540
5630
  }
5541
- if (!existsSync13(resolvedPath)) {
5631
+ if (!existsSync12(resolvedPath)) {
5542
5632
  return check("error", "vault_structure", "Vault structure valid", "Cannot check \u2014 vault directory does not exist");
5543
5633
  }
5544
5634
  const missing = [];
5545
- if (!existsSync13(join24(resolvedPath, "SCHEMA.md"))) missing.push("SCHEMA.md");
5635
+ if (!existsSync12(join23(resolvedPath, "SCHEMA.md"))) missing.push("SCHEMA.md");
5546
5636
  for (const dir of ["raw", "entities", "concepts", "meta"]) {
5547
- if (!existsSync13(join24(resolvedPath, dir))) missing.push(dir + "/");
5637
+ if (!existsSync12(join23(resolvedPath, dir))) missing.push(dir + "/");
5548
5638
  }
5549
5639
  if (missing.length === 0) {
5550
5640
  return check("pass", "vault_structure", "Vault structure valid", "All required files and directories present");
@@ -5552,8 +5642,8 @@ function checkVaultStructure(resolvedPath) {
5552
5642
  return check("warn", "vault_structure", "Vault structure valid", `Missing: ${missing.join(", ")} \u2014 run \`skillwiki init\` to add CodeWiki structure`);
5553
5643
  }
5554
5644
  function checkSkillsInstalled(home, cwd) {
5555
- const srcDir = cwd ? join24(cwd, "packages", "skills") : void 0;
5556
- if (srcDir && existsSync13(srcDir)) {
5645
+ const srcDir = cwd ? join23(cwd, "packages", "skills") : void 0;
5646
+ if (srcDir && existsSync12(srcDir)) {
5557
5647
  const found = findInstalledSkillMd(srcDir);
5558
5648
  if (found.length > 0) {
5559
5649
  return check("pass", "skills_installed", "Skills installed", `${found.length} SKILL.md file(s) found (source)`);
@@ -5566,8 +5656,8 @@ function checkSkillsInstalled(home, cwd) {
5566
5656
  return check("pass", "skills_installed", "Skills installed", `${found.length} SKILL.md file(s) found (plugin v${plugin.version})`);
5567
5657
  }
5568
5658
  }
5569
- const skillsDir = join24(home, ".claude", "skills");
5570
- if (existsSync13(skillsDir)) {
5659
+ const skillsDir = join23(home, ".claude", "skills");
5660
+ if (existsSync12(skillsDir)) {
5571
5661
  const found = findInstalledSkillMd(skillsDir);
5572
5662
  if (found.length > 0) {
5573
5663
  return check("pass", "skills_installed", "Skills installed", `${found.length} SKILL.md file(s) found (CLI install)`);
@@ -5577,10 +5667,10 @@ function checkSkillsInstalled(home, cwd) {
5577
5667
  }
5578
5668
  function checkDuplicateSkills(home) {
5579
5669
  const plugin = findPlugin(home);
5580
- const skillsDir = join24(home, ".claude", "skills");
5670
+ const skillsDir = join23(home, ".claude", "skills");
5581
5671
  const agentSkillDirs = [
5582
- { label: "~/.codex/skills/", path: join24(home, ".codex", "skills") },
5583
- { label: "~/.agents/skills/", path: join24(home, ".agents", "skills") }
5672
+ { label: "~/.codex/skills/", path: join23(home, ".codex", "skills") },
5673
+ { label: "~/.agents/skills/", path: join23(home, ".agents", "skills") }
5584
5674
  ];
5585
5675
  if (!plugin) {
5586
5676
  return check("pass", "skills_duplicate", "Skills not duplicated", "Single install channel");
@@ -5683,8 +5773,8 @@ async function checkProfiles(home) {
5683
5773
  }
5684
5774
  async function checkProjectLocalOverride(cwd) {
5685
5775
  const dir = cwd ?? process.cwd();
5686
- const envPath = join24(dir, ".skillwiki", ".env");
5687
- if (existsSync13(envPath)) {
5776
+ const envPath = join23(dir, ".skillwiki", ".env");
5777
+ if (existsSync12(envPath)) {
5688
5778
  return check("pass", "project_local", "Project-local config", `Found: ${envPath}`);
5689
5779
  }
5690
5780
  return check("pass", "project_local", "Project-local config", "None");
@@ -5693,7 +5783,7 @@ function checkVaultGitRemote(resolvedPath) {
5693
5783
  if (resolvedPath === void 0) {
5694
5784
  return check("error", "vault_git_remote", "Vault git remote", "Cannot check \u2014 WIKI_PATH not resolved");
5695
5785
  }
5696
- if (!existsSync13(join24(resolvedPath, ".git"))) {
5786
+ if (!existsSync12(join23(resolvedPath, ".git"))) {
5697
5787
  return check("warn", "vault_git_remote", "Vault git remote", "Vault is not a git repository \u2014 sync features unavailable");
5698
5788
  }
5699
5789
  try {
@@ -5716,9 +5806,9 @@ function checkObsidianTemplates(resolvedPath) {
5716
5806
  return check("error", "obsidian_templates", "Obsidian templates", "Cannot check \u2014 WIKI_PATH not resolved");
5717
5807
  }
5718
5808
  const missing = [];
5719
- if (!existsSync13(join24(resolvedPath, "_Templates"))) missing.push("_Templates/");
5720
- if (!existsSync13(join24(resolvedPath, ".obsidian", "templates.json"))) missing.push(".obsidian/templates.json");
5721
- if (!existsSync13(join24(resolvedPath, ".obsidian", "app.json"))) missing.push(".obsidian/app.json");
5809
+ if (!existsSync12(join23(resolvedPath, "_Templates"))) missing.push("_Templates/");
5810
+ if (!existsSync12(join23(resolvedPath, ".obsidian", "templates.json"))) missing.push(".obsidian/templates.json");
5811
+ if (!existsSync12(join23(resolvedPath, ".obsidian", "app.json"))) missing.push(".obsidian/app.json");
5722
5812
  if (missing.length === 0) {
5723
5813
  return check("pass", "obsidian_templates", "Obsidian templates", "Template folder and config present");
5724
5814
  }
@@ -5728,8 +5818,8 @@ function checkDotStoreClean(resolvedPath) {
5728
5818
  if (resolvedPath === void 0) {
5729
5819
  return check("error", "dsstore_clean", "No .DS_Store in raw/", "Cannot check \u2014 WIKI_PATH not resolved");
5730
5820
  }
5731
- const rawDir = join24(resolvedPath, "raw");
5732
- if (!existsSync13(rawDir)) {
5821
+ const rawDir = join23(resolvedPath, "raw");
5822
+ if (!existsSync12(rawDir)) {
5733
5823
  return check("pass", "dsstore_clean", "No .DS_Store in raw/", "raw/ directory not found \u2014 check skipped");
5734
5824
  }
5735
5825
  const found = [];
@@ -5744,7 +5834,7 @@ function checkDotStoreClean(resolvedPath) {
5744
5834
  if (entry.name === ".DS_Store") {
5745
5835
  found.push(rel ? `${rel}/.DS_Store` : ".DS_Store");
5746
5836
  } else if (entry.isDirectory()) {
5747
- walk2(join24(dir, entry.name), rel ? `${rel}/${entry.name}` : entry.name);
5837
+ walk2(join23(dir, entry.name), rel ? `${rel}/${entry.name}` : entry.name);
5748
5838
  }
5749
5839
  }
5750
5840
  })(rawDir, "");
@@ -5775,7 +5865,7 @@ function checkSyncLastPush(resolvedPath) {
5775
5865
  if (resolvedPath === void 0) {
5776
5866
  return check("error", "sync_last_push", "Vault sync recency", "Cannot check \u2014 WIKI_PATH not resolved");
5777
5867
  }
5778
- if (!existsSync13(join24(resolvedPath, ".git"))) {
5868
+ if (!existsSync12(join23(resolvedPath, ".git"))) {
5779
5869
  return check("pass", "sync_last_push", "Vault sync recency", "No git repo \u2014 sync check skipped");
5780
5870
  }
5781
5871
  let timestamp;
@@ -5823,7 +5913,7 @@ function checkVaultGitDirty(resolvedPath) {
5823
5913
  if (resolvedPath === void 0) {
5824
5914
  return check("pass", "vault_git_dirty", "Vault git dirty state", "No vault path \u2014 check skipped");
5825
5915
  }
5826
- if (!existsSync13(join24(resolvedPath, ".git"))) {
5916
+ if (!existsSync12(join23(resolvedPath, ".git"))) {
5827
5917
  return check("pass", "vault_git_dirty", "Vault git dirty state", "No git repo \u2014 check skipped");
5828
5918
  }
5829
5919
  try {
@@ -5891,7 +5981,7 @@ function remoteMainHash(resolvedPath) {
5891
5981
  }
5892
5982
  function checkStaleRemoteMain(resolvedPath) {
5893
5983
  if (resolvedPath === void 0) return void 0;
5894
- if (!existsSync13(join24(resolvedPath, ".git"))) return void 0;
5984
+ if (!existsSync12(join23(resolvedPath, ".git"))) return void 0;
5895
5985
  const localOrigin = gitRefHash(resolvedPath, "origin/main");
5896
5986
  if (!localOrigin) return void 0;
5897
5987
  const remoteMain = remoteMainHash(resolvedPath);
@@ -5907,7 +5997,7 @@ function checkVaultLocalGit(resolvedPath) {
5907
5997
  if (resolvedPath === void 0) {
5908
5998
  return check("warn", "vault_local_git", "Vault local git", "Cannot check \u2014 WIKI_PATH not resolved");
5909
5999
  }
5910
- if (!existsSync13(join24(resolvedPath, ".git"))) {
6000
+ if (!existsSync12(join23(resolvedPath, ".git"))) {
5911
6001
  return check("warn", "vault_local_git", "Vault local git", "Not a git repository - sync features unavailable");
5912
6002
  }
5913
6003
  try {
@@ -5926,7 +6016,7 @@ function checkVaultGithubRemote(resolvedPath, exec) {
5926
6016
  if (resolvedPath === void 0) {
5927
6017
  return check("pass", "vault_github_remote", "Vault GitHub remote", "No vault path \u2014 check skipped");
5928
6018
  }
5929
- if (!existsSync13(join24(resolvedPath, ".git"))) {
6019
+ if (!existsSync12(join23(resolvedPath, ".git"))) {
5930
6020
  return check("pass", "vault_github_remote", "Vault GitHub remote", "No git repo \u2014 check skipped");
5931
6021
  }
5932
6022
  const state = probeGithubReachability(resolvedPath, exec);
@@ -5970,7 +6060,7 @@ function checkVaultPromotionLag(resolvedPath) {
5970
6060
  if (resolvedPath === void 0) {
5971
6061
  return check("pass", "vault_promotion_lag", "Vault promotion lag", "No vault path \u2014 check skipped");
5972
6062
  }
5973
- if (!existsSync13(join24(resolvedPath, ".git"))) {
6063
+ if (!existsSync12(join23(resolvedPath, ".git"))) {
5974
6064
  return check("pass", "vault_promotion_lag", "Vault promotion lag", "No git repo \u2014 check skipped");
5975
6065
  }
5976
6066
  try {
@@ -5997,7 +6087,7 @@ function checkVaultGitComparison(resolvedPath, id, label, range, nonZeroSuffix,
5997
6087
  if (resolvedPath === void 0) {
5998
6088
  return check("pass", id, label, "No vault path \u2014 check skipped");
5999
6089
  }
6000
- if (!existsSync13(join24(resolvedPath, ".git"))) {
6090
+ if (!existsSync12(join23(resolvedPath, ".git"))) {
6001
6091
  return check("pass", id, label, "No git repo \u2014 check skipped");
6002
6092
  }
6003
6093
  if (!hasOriginMain(resolvedPath)) {
@@ -6025,7 +6115,7 @@ function checkSatelliteLastRun(vaultPath, satelliteExpected) {
6025
6115
  return check("pass", "satellite_job_last_run", "Satellite job last run", "No vault path \u2014 check skipped");
6026
6116
  }
6027
6117
  const latestPath = satelliteLatestRunPath(vaultPath);
6028
- if (!existsSync13(latestPath)) {
6118
+ if (!existsSync12(latestPath)) {
6029
6119
  return check("pass", "satellite_job_last_run", "Satellite job last run", "No latest-run.json \u2014 satellite has not run yet");
6030
6120
  }
6031
6121
  try {
@@ -6113,11 +6203,11 @@ async function checkFleetIdentity(input) {
6113
6203
  }
6114
6204
  function pullLogPaths(home) {
6115
6205
  const paths = platform2() === "darwin" ? [
6116
- join24(home, "Library", "Logs", "wiki-pull.log"),
6117
- join24(home, ".local", "state", "vault-sync", "log", "wiki-pull.log")
6206
+ join23(home, "Library", "Logs", "wiki-pull.log"),
6207
+ join23(home, ".local", "state", "vault-sync", "log", "wiki-pull.log")
6118
6208
  ] : [
6119
- join24(home, ".local", "state", "vault-sync", "log", "wiki-pull.log"),
6120
- join24(home, "Library", "Logs", "wiki-pull.log")
6209
+ join23(home, ".local", "state", "vault-sync", "log", "wiki-pull.log"),
6210
+ join23(home, "Library", "Logs", "wiki-pull.log")
6121
6211
  ];
6122
6212
  return [...new Set(paths)];
6123
6213
  }
@@ -6129,12 +6219,12 @@ function isRecentLogLine(line, nowMs) {
6129
6219
  return nowMs - ts <= 24 * 60 * 60 * 1e3;
6130
6220
  }
6131
6221
  function checkVaultGitPullFailures(home) {
6132
- const path = pullLogPaths(home).find((p) => existsSync13(p));
6222
+ const path = pullLogPaths(home).find((p) => existsSync12(p));
6133
6223
  if (!path) {
6134
6224
  return check("pass", "vault_git_pull_failures", "Vault pull failures", "No wiki-pull.log found \u2014 check skipped");
6135
6225
  }
6136
6226
  try {
6137
- const lines = readFileSync10(path, "utf8").split(/\r?\n/).filter(Boolean);
6227
+ const lines = readFileSync9(path, "utf8").split(/\r?\n/).filter(Boolean);
6138
6228
  const now = Date.now();
6139
6229
  const failures = lines.filter(
6140
6230
  (line) => isRecentLogLine(line, now) && /(pre-push pull failed|FAIL .*pull|FAIL .*rebase|cannot pull with rebase|unstaged changes)/i.test(line)
@@ -6157,8 +6247,8 @@ function checkS3MountPerf(resolvedPath) {
6157
6247
  return check("pass", "s3_mount_perf", "S3 mount performance", "local disk");
6158
6248
  }
6159
6249
  const mountPoint = fuse.mountPoint;
6160
- const conceptsDir = join24(resolvedPath, "concepts");
6161
- if (!existsSync13(conceptsDir)) {
6250
+ const conceptsDir = join23(resolvedPath, "concepts");
6251
+ if (!existsSync12(conceptsDir)) {
6162
6252
  return check("pass", "s3_mount_perf", "S3 mount performance", `S3 FUSE mount (${mountPoint}), no concepts/ to benchmark`);
6163
6253
  }
6164
6254
  const start = Date.now();
@@ -6340,8 +6430,8 @@ function checkWriteTest(resolvedPath) {
6340
6430
  if (!fuse) {
6341
6431
  return check("pass", "s3_write_test", "S3 write test", "local disk \u2014 check skipped");
6342
6432
  }
6343
- const conceptsDir = join24(resolvedPath, "concepts");
6344
- if (!existsSync13(conceptsDir)) {
6433
+ const conceptsDir = join23(resolvedPath, "concepts");
6434
+ if (!existsSync12(conceptsDir)) {
6345
6435
  return check("pass", "s3_write_test", "S3 write test", "no concepts/ dir to test \u2014 check skipped");
6346
6436
  }
6347
6437
  const result = writeTest(conceptsDir);
@@ -6427,7 +6517,7 @@ function checkVfsCacheHealth(resolvedPath) {
6427
6517
  }
6428
6518
  function readVaultSyncConfig(home) {
6429
6519
  try {
6430
- const content = readFileSync10(join24(home, ".skillwiki", ".env"), "utf8");
6520
+ const content = readFileSync9(join23(home, ".skillwiki", ".env"), "utf8");
6431
6521
  let installed = false;
6432
6522
  let role;
6433
6523
  let serviceScope;
@@ -6456,7 +6546,7 @@ function readVaultSyncConfig(home) {
6456
6546
  }
6457
6547
  function readKeyFromEnvFile(path, keys) {
6458
6548
  try {
6459
- const content = readFileSync10(path, "utf8");
6549
+ const content = readFileSync9(path, "utf8");
6460
6550
  for (const line of content.split(/\r?\n/)) {
6461
6551
  const trimmed = line.trim();
6462
6552
  if (trimmed.length === 0 || trimmed.startsWith("#")) continue;
@@ -6478,7 +6568,7 @@ function resolveSnapshotGitWorktree(config) {
6478
6568
  if (fromProfile) return fromProfile;
6479
6569
  }
6480
6570
  const defaultPath = "/root/wiki-git";
6481
- return existsSync13(defaultPath) ? defaultPath : void 0;
6571
+ return existsSync12(defaultPath) ? defaultPath : void 0;
6482
6572
  }
6483
6573
  function vaultSyncChecks(input) {
6484
6574
  const os = input.os ?? platform2();
@@ -6495,16 +6585,16 @@ function vaultSyncChecks(input) {
6495
6585
  ];
6496
6586
  }
6497
6587
  const isMac = os === "darwin";
6498
- const logDir = input.logDir ?? (isMac ? join24(home, "Library", "Logs") : join24(home, ".local", "state", "vault-sync", "log"));
6499
- const shareDir = input.shareDir ?? (isMac ? join24(home, "Library", "Application Support", "vault-sync", "bin") : join24(home, ".local", "share", "vault-sync", "bin"));
6500
- const filterPath = input.filterPath ?? join24(home, ".config", "rclone", "wiki-push-filters.txt");
6501
- const packagedSnapshotPath = join24(shareDir, "wiki-snapshot.sh");
6588
+ const logDir = input.logDir ?? (isMac ? join23(home, "Library", "Logs") : join23(home, ".local", "state", "vault-sync", "log"));
6589
+ const shareDir = input.shareDir ?? (isMac ? join23(home, "Library", "Application Support", "vault-sync", "bin") : join23(home, ".local", "share", "vault-sync", "bin"));
6590
+ const filterPath = input.filterPath ?? join23(home, ".config", "rclone", "wiki-push-filters.txt");
6591
+ const packagedSnapshotPath = join23(shareDir, "wiki-snapshot.sh");
6502
6592
  const legacySnapshotPath = "/root/.hermes/scripts/wiki-snapshot-v3.sh";
6503
- const snapshotPath = input.snapshotScriptPath ?? (existsSync13(packagedSnapshotPath) ? packagedSnapshotPath : legacySnapshotPath);
6593
+ const snapshotPath = input.snapshotScriptPath ?? (existsSync12(packagedSnapshotPath) ? packagedSnapshotPath : legacySnapshotPath);
6504
6594
  function snapshotLastStatusCheck() {
6505
- const snapshotLog = join24(logDir, "wiki-snapshot.log");
6595
+ const snapshotLog = join23(logDir, "wiki-snapshot.log");
6506
6596
  try {
6507
- const logContent = readFileSync10(snapshotLog, "utf8");
6597
+ const logContent = readFileSync9(snapshotLog, "utf8");
6508
6598
  const lines = logContent.trim().split("\n").filter(Boolean);
6509
6599
  if (lines.length === 0) {
6510
6600
  return check(
@@ -6549,14 +6639,14 @@ function vaultSyncChecks(input) {
6549
6639
  }
6550
6640
  }
6551
6641
  if (input.vaultSyncRole === "snapshotter") {
6552
- const c12 = existsSync13(snapshotPath) ? check("pass", "vault_sync_installed", "Vault sync installed", `Found snapshot script: ${snapshotPath}`) : check("error", "vault_sync_installed", "Vault sync installed", `Snapshot script not found at ${snapshotPath}`);
6642
+ const c12 = existsSync12(snapshotPath) ? check("pass", "vault_sync_installed", "Vault sync installed", `Found snapshot script: ${snapshotPath}`) : check("error", "vault_sync_installed", "Vault sync installed", `Snapshot script not found at ${snapshotPath}`);
6553
6643
  const serviceScope = input.vaultSyncServiceScope ?? "user";
6554
- const userTimerPath = join24(home, ".config", "systemd", "user", "wiki-snapshot.timer");
6644
+ const userTimerPath = join23(home, ".config", "systemd", "user", "wiki-snapshot.timer");
6555
6645
  const systemTimerPath = "/etc/systemd/system/wiki-snapshot.timer";
6556
6646
  let c22;
6557
- if (serviceScope === "user" && existsSync13(userTimerPath)) {
6647
+ if (serviceScope === "user" && existsSync12(userTimerPath)) {
6558
6648
  c22 = check("pass", "vault_sync_jobs_enabled", "Vault sync jobs enabled", `Found: ${userTimerPath}`);
6559
- } else if (serviceScope === "system" && existsSync13(systemTimerPath)) {
6649
+ } else if (serviceScope === "system" && existsSync12(systemTimerPath)) {
6560
6650
  c22 = check("pass", "vault_sync_jobs_enabled", "Vault sync jobs enabled", `Found: ${systemTimerPath}`);
6561
6651
  } else if (os !== "linux") {
6562
6652
  c22 = check("warn", "vault_sync_jobs_enabled", "Vault sync jobs enabled", "Snapshotter scheduler is Linux-only and no wiki-snapshot.timer file was found");
@@ -6588,7 +6678,7 @@ function vaultSyncChecks(input) {
6588
6678
  );
6589
6679
  let c52;
6590
6680
  try {
6591
- if (!existsSync13(snapshotPath)) {
6681
+ if (!existsSync12(snapshotPath)) {
6592
6682
  c52 = check(
6593
6683
  "error",
6594
6684
  "vault_sync_snapshot_guard",
@@ -6596,7 +6686,7 @@ function vaultSyncChecks(input) {
6596
6686
  `Snapshot script not found at ${snapshotPath}`
6597
6687
  );
6598
6688
  } else {
6599
- const content = readFileSync10(snapshotPath, "utf8");
6689
+ const content = readFileSync9(snapshotPath, "utf8");
6600
6690
  if (!content.includes("--max-delete")) {
6601
6691
  c52 = check(
6602
6692
  "error",
@@ -6623,8 +6713,8 @@ function vaultSyncChecks(input) {
6623
6713
  }
6624
6714
  return [c12, c22, c32, cFetch2, c42, c52];
6625
6715
  }
6626
- const pushScriptPath = join24(shareDir, "wiki-push.sh");
6627
- const c1 = existsSync13(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`);
6716
+ const pushScriptPath = join23(shareDir, "wiki-push.sh");
6717
+ 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`);
6628
6718
  let c2;
6629
6719
  try {
6630
6720
  if (isMac) {
@@ -6675,10 +6765,10 @@ function vaultSyncChecks(input) {
6675
6765
  "Scheduler check failed \u2014 run vault-sync-install"
6676
6766
  );
6677
6767
  }
6678
- const logFile = join24(logDir, "wiki-push.log");
6768
+ const logFile = join23(logDir, "wiki-push.log");
6679
6769
  let c3;
6680
6770
  try {
6681
- const logContent = readFileSync10(logFile, "utf8");
6771
+ const logContent = readFileSync9(logFile, "utf8");
6682
6772
  const lines = logContent.trim().split("\n").filter(Boolean);
6683
6773
  if (lines.length === 0) {
6684
6774
  c3 = check(
@@ -6734,7 +6824,7 @@ function vaultSyncChecks(input) {
6734
6824
  }
6735
6825
  }
6736
6826
  } catch {
6737
- c3 = existsSync13(logDir) ? check(
6827
+ c3 = existsSync12(logDir) ? check(
6738
6828
  "warn",
6739
6829
  "vault_sync_last_push_age",
6740
6830
  "Vault sync last push recency",
@@ -6746,10 +6836,10 @@ function vaultSyncChecks(input) {
6746
6836
  `Log directory not found at ${logDir}`
6747
6837
  );
6748
6838
  }
6749
- const fetchLogFile = join24(logDir, "wiki-fetch.log");
6839
+ const fetchLogFile = join23(logDir, "wiki-fetch.log");
6750
6840
  let cFetch;
6751
6841
  try {
6752
- const logContent = readFileSync10(fetchLogFile, "utf8");
6842
+ const logContent = readFileSync9(fetchLogFile, "utf8");
6753
6843
  const lines = logContent.trim().split("\n").filter(Boolean);
6754
6844
  if (lines.length === 0) {
6755
6845
  cFetch = check(
@@ -6793,7 +6883,7 @@ function vaultSyncChecks(input) {
6793
6883
  }
6794
6884
  let c4;
6795
6885
  try {
6796
- if (!existsSync13(filterPath)) {
6886
+ if (!existsSync12(filterPath)) {
6797
6887
  c4 = check(
6798
6888
  "error",
6799
6889
  "vault_sync_filter_present",
@@ -6801,7 +6891,7 @@ function vaultSyncChecks(input) {
6801
6891
  `Filter file not found at ${filterPath}`
6802
6892
  );
6803
6893
  } else {
6804
- const content = readFileSync10(filterPath, "utf8");
6894
+ const content = readFileSync9(filterPath, "utf8");
6805
6895
  const requiredExcludes = [
6806
6896
  "remotely-save/data.json",
6807
6897
  ".skillwiki/sync.lock",
@@ -6844,7 +6934,7 @@ function vaultSyncChecks(input) {
6844
6934
  );
6845
6935
  } else {
6846
6936
  try {
6847
- if (!existsSync13(snapshotPath)) {
6937
+ if (!existsSync12(snapshotPath)) {
6848
6938
  c5 = check(
6849
6939
  "error",
6850
6940
  "vault_sync_snapshot_guard",
@@ -6852,7 +6942,7 @@ function vaultSyncChecks(input) {
6852
6942
  `Snapshot script not found at ${snapshotPath}`
6853
6943
  );
6854
6944
  } else {
6855
- const content = readFileSync10(snapshotPath, "utf8");
6945
+ const content = readFileSync9(snapshotPath, "utf8");
6856
6946
  if (!content.includes("--max-delete")) {
6857
6947
  c5 = check(
6858
6948
  "error",
@@ -6890,15 +6980,15 @@ function findSkillMd(dir) {
6890
6980
  }
6891
6981
  for (const entry of entries) {
6892
6982
  if (entry.isFile() && entry.name === "SKILL.md") {
6893
- results.push(join24(dir, entry.name));
6983
+ results.push(join23(dir, entry.name));
6894
6984
  } else if (entry.isDirectory()) {
6895
- results.push(...findSkillMd(join24(dir, entry.name)));
6985
+ results.push(...findSkillMd(join23(dir, entry.name)));
6896
6986
  }
6897
6987
  }
6898
6988
  return results;
6899
6989
  }
6900
6990
  function findInstalledSkillMd(dir) {
6901
- const directSkills = findSkillNames(dir).map((name) => join24(dir, name, "SKILL.md"));
6991
+ const directSkills = findSkillNames(dir).map((name) => join23(dir, name, "SKILL.md"));
6902
6992
  return directSkills.length > 0 ? directSkills : findSkillMd(dir);
6903
6993
  }
6904
6994
  function findSkillNames(dir) {
@@ -6910,7 +7000,7 @@ function findSkillNames(dir) {
6910
7000
  return results;
6911
7001
  }
6912
7002
  for (const entry of entries) {
6913
- if (entry.isDirectory() && existsSync13(join24(dir, entry.name, "SKILL.md"))) {
7003
+ if (entry.isDirectory() && existsSync12(join23(dir, entry.name, "SKILL.md"))) {
6914
7004
  results.push(entry.name);
6915
7005
  }
6916
7006
  }
@@ -6954,7 +7044,7 @@ async function vaultMetrics(resolvedPath) {
6954
7044
  }
6955
7045
  let logLines = 0;
6956
7046
  try {
6957
- logLines = readFileSync10(join24(resolvedPath, "log.md"), "utf8").split("\n").length;
7047
+ logLines = readFileSync9(join23(resolvedPath, "log.md"), "utf8").split("\n").length;
6958
7048
  } catch {
6959
7049
  }
6960
7050
  return [
@@ -7062,7 +7152,7 @@ async function runDoctor(input) {
7062
7152
  }
7063
7153
 
7064
7154
  // src/utils/package-info.ts
7065
- import { readFileSync as readFileSync11 } from "fs";
7155
+ import { readFileSync as readFileSync10 } from "fs";
7066
7156
  function packageJsonCandidateUrls(baseUrl = import.meta.url) {
7067
7157
  return [
7068
7158
  new URL("../package.json", baseUrl),
@@ -7072,7 +7162,7 @@ function packageJsonCandidateUrls(baseUrl = import.meta.url) {
7072
7162
  function readCliPackageJson(baseUrl = import.meta.url) {
7073
7163
  for (const url of packageJsonCandidateUrls(baseUrl)) {
7074
7164
  try {
7075
- const pkg = JSON.parse(readFileSync11(url, "utf8"));
7165
+ const pkg = JSON.parse(readFileSync10(url, "utf8"));
7076
7166
  if (typeof pkg.version === "string") {
7077
7167
  return { ...pkg, version: pkg.version };
7078
7168
  }
@@ -7084,7 +7174,7 @@ function readCliPackageJson(baseUrl = import.meta.url) {
7084
7174
 
7085
7175
  // src/commands/project-index.ts
7086
7176
  import { readdir as readdir4, readFile as readFile16, writeFile as writeFile6, mkdir as mkdir5 } from "fs/promises";
7087
- import { join as join25, dirname as dirname8, basename as basename2 } from "path";
7177
+ import { join as join24, dirname as dirname7, basename as basename2 } from "path";
7088
7178
  var LAYER2_DIRS = ["entities", "concepts", "comparisons", "queries", "meta"];
7089
7179
  var PROJECT_LOCAL_DIRS = ["requirements", "work", "architecture", "history"];
7090
7180
  async function scanMarkdownTree(rootAbs, rootRel) {
@@ -7096,7 +7186,7 @@ async function scanMarkdownTree(rootAbs, rootRel) {
7096
7186
  return found;
7097
7187
  }
7098
7188
  for (const entry of entries) {
7099
- const abs = join25(rootAbs, entry.name);
7189
+ const abs = join24(rootAbs, entry.name);
7100
7190
  const rel = `${rootRel}/${entry.name}`;
7101
7191
  if (entry.isDirectory()) {
7102
7192
  found.push(...await scanMarkdownTree(abs, rel));
@@ -7126,7 +7216,7 @@ function projectLocalType(slug, page, data) {
7126
7216
  }
7127
7217
  async function runProjectIndex(input) {
7128
7218
  const slug = input.slug;
7129
- const projectDir = join25(input.vault, "projects", slug);
7219
+ const projectDir = join24(input.vault, "projects", slug);
7130
7220
  try {
7131
7221
  await readdir4(projectDir);
7132
7222
  } catch {
@@ -7137,12 +7227,12 @@ async function runProjectIndex(input) {
7137
7227
  }
7138
7228
  const wikilinkPattern = `[[${slug}]]`;
7139
7229
  const entries = [];
7140
- const compoundDir = join25(input.vault, "projects", slug, "compound");
7230
+ const compoundDir = join24(input.vault, "projects", slug, "compound");
7141
7231
  try {
7142
7232
  const compoundFiles = await readdir4(compoundDir, { withFileTypes: true });
7143
7233
  for (const entry of compoundFiles) {
7144
7234
  if (!entry.isFile() || !entry.name.endsWith(".md")) continue;
7145
- const filePath = join25(compoundDir, entry.name);
7235
+ const filePath = join24(compoundDir, entry.name);
7146
7236
  let text;
7147
7237
  try {
7148
7238
  text = await readFile16(filePath, "utf8");
@@ -7162,13 +7252,13 @@ async function runProjectIndex(input) {
7162
7252
  for (const dir of LAYER2_DIRS) {
7163
7253
  let files;
7164
7254
  try {
7165
- files = await readdir4(join25(input.vault, dir), { withFileTypes: true });
7255
+ files = await readdir4(join24(input.vault, dir), { withFileTypes: true });
7166
7256
  } catch {
7167
7257
  continue;
7168
7258
  }
7169
7259
  for (const entry of files) {
7170
7260
  if (!entry.isFile() || !entry.name.endsWith(".md")) continue;
7171
- const filePath = join25(input.vault, dir, entry.name);
7261
+ const filePath = join24(input.vault, dir, entry.name);
7172
7262
  let text;
7173
7263
  try {
7174
7264
  text = await readFile16(filePath, "utf8");
@@ -7187,11 +7277,11 @@ async function runProjectIndex(input) {
7187
7277
  }
7188
7278
  }
7189
7279
  for (const dir of PROJECT_LOCAL_DIRS) {
7190
- const rootAbs = join25(projectDir, dir);
7280
+ const rootAbs = join24(projectDir, dir);
7191
7281
  const rootRel = `projects/${slug}/${dir}`;
7192
7282
  const pages = await scanMarkdownTree(rootAbs, rootRel);
7193
7283
  for (const page of pages) {
7194
- const filePath = join25(input.vault, page);
7284
+ const filePath = join24(input.vault, page);
7195
7285
  let text;
7196
7286
  try {
7197
7287
  text = await readFile16(filePath, "utf8");
@@ -7213,7 +7303,7 @@ async function runProjectIndex(input) {
7213
7303
  const tb = typeOrder[b.type] ?? 99;
7214
7304
  return ta !== tb ? ta - tb : a.title.localeCompare(b.title);
7215
7305
  });
7216
- const indexPath = join25(projectDir, "knowledge.md");
7306
+ const indexPath = join24(projectDir, "knowledge.md");
7217
7307
  let existing = false;
7218
7308
  let stale = false;
7219
7309
  try {
@@ -7257,7 +7347,7 @@ Autogenerated by \`skillwiki project-index\` on ${today}.
7257
7347
  }
7258
7348
  if (input.apply) {
7259
7349
  try {
7260
- await mkdir5(dirname8(indexPath), { recursive: true });
7350
+ await mkdir5(dirname7(indexPath), { recursive: true });
7261
7351
  await writeFile6(indexPath, body, "utf8");
7262
7352
  } catch (e) {
7263
7353
  return {
@@ -7287,8 +7377,8 @@ ${entries.map((e) => ` ${e.type}: [[${e.page.replace(/\.md$/, "")}]] \u2014 ${e
7287
7377
 
7288
7378
  // src/commands/observe.ts
7289
7379
  import { mkdir as mkdir6, writeFile as writeFile7 } from "fs/promises";
7290
- import { existsSync as existsSync14, statSync as statSync2 } from "fs";
7291
- import { join as join26 } from "path";
7380
+ import { existsSync as existsSync13, statSync as statSync2 } from "fs";
7381
+ import { join as join25 } from "path";
7292
7382
  import { createHash as createHash5 } from "crypto";
7293
7383
  var ALLOWED_KINDS = /* @__PURE__ */ new Set(["note", "bug", "task", "idea", "session-log"]);
7294
7384
  function slugify(text) {
@@ -7311,13 +7401,13 @@ async function runObserve(input) {
7311
7401
  result: err("SCHEME_REJECTED", { message: "Text must not be empty" })
7312
7402
  };
7313
7403
  }
7314
- if (!existsSync14(input.vault) || !statSync2(input.vault).isDirectory()) {
7404
+ if (!existsSync13(input.vault) || !statSync2(input.vault).isDirectory()) {
7315
7405
  return {
7316
7406
  exitCode: ExitCode.VAULT_PATH_INVALID,
7317
7407
  result: err("VAULT_PATH_INVALID", { path: input.vault })
7318
7408
  };
7319
7409
  }
7320
- const transcriptsDir = join26(input.vault, "raw", "transcripts");
7410
+ const transcriptsDir = join25(input.vault, "raw", "transcripts");
7321
7411
  try {
7322
7412
  await mkdir6(transcriptsDir, { recursive: true });
7323
7413
  } catch {
@@ -7329,7 +7419,7 @@ async function runObserve(input) {
7329
7419
  const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
7330
7420
  const slug = slugify(input.text);
7331
7421
  const fileName = `${today}-observation-${slug}.md`;
7332
- const filePath = join26(transcriptsDir, fileName);
7422
+ const filePath = join25(transcriptsDir, fileName);
7333
7423
  const body = `
7334
7424
  ${input.text.trim()}
7335
7425
  `;
@@ -7371,7 +7461,7 @@ ${input.text.trim()}
7371
7461
  // src/commands/memory.ts
7372
7462
  import { createHash as createHash6 } from "crypto";
7373
7463
  import { mkdir as mkdir7, readFile as readFile17, readdir as readdir5, stat as stat5, writeFile as writeFile8 } from "fs/promises";
7374
- import { basename as basename3, extname, join as join27, relative as relative4, sep as sep4 } from "path";
7464
+ import { basename as basename3, extname, join as join26, relative as relative4, sep as sep4 } from "path";
7375
7465
  async function runMemoryTopics(input) {
7376
7466
  const scan = await scanVault(input.vault);
7377
7467
  if (!scan.ok) return { exitCode: ExitCode.VAULT_PATH_INVALID, result: scan };
@@ -7435,8 +7525,8 @@ async function runMemoryIndex(input) {
7435
7525
  }
7436
7526
  const generatedAt = (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
7437
7527
  const relCachePath = memoryCacheRelPath(input.project);
7438
- const absCachePath = join27(input.vault, relCachePath);
7439
- await mkdir7(join27(input.vault, ".skillwiki", "memory", input.project), { recursive: true });
7528
+ const absCachePath = join26(input.vault, relCachePath);
7529
+ await mkdir7(join26(input.vault, ".skillwiki", "memory", input.project), { recursive: true });
7440
7530
  await writeFile8(absCachePath, `${JSON.stringify({
7441
7531
  generated_at: generatedAt,
7442
7532
  project: input.project,
@@ -7628,7 +7718,7 @@ async function buildMemoryIndexState(pages, project) {
7628
7718
  }
7629
7719
  async function checkMemoryIndex(vault, project, current) {
7630
7720
  const relCachePath = memoryCacheRelPath(project);
7631
- const cacheText = await readIfExists2(join27(vault, relCachePath));
7721
+ const cacheText = await readIfExists2(join26(vault, relCachePath));
7632
7722
  if (!cacheText) {
7633
7723
  return {
7634
7724
  ok: true,
@@ -8037,7 +8127,7 @@ async function walkImportFiles(dir, out) {
8037
8127
  const entries = await readdir5(dir, { withFileTypes: true });
8038
8128
  for (const entry of entries) {
8039
8129
  if (entry.name === ".git" || entry.name === "node_modules") continue;
8040
- const path = join27(dir, entry.name);
8130
+ const path = join26(dir, entry.name);
8041
8131
  if (entry.isDirectory()) {
8042
8132
  await walkImportFiles(path, out);
8043
8133
  } else if (entry.isFile() && isImportCandidate(path)) {
@@ -8104,8 +8194,8 @@ async function writeImportCapture(vault, entry, today) {
8104
8194
  const content = hiddenString(entry, "__content");
8105
8195
  const project = hiddenString(entry, "__project");
8106
8196
  const relPath = await availableImportPath(vault, entry.proposed_path);
8107
- const absPath = join27(vault, relPath);
8108
- await mkdir7(join27(vault, "raw", "transcripts"), { recursive: true });
8197
+ const absPath = join26(vault, relPath);
8198
+ await mkdir7(join26(vault, "raw", "transcripts"), { recursive: true });
8109
8199
  await writeFile8(absPath, renderImportCapture(entry, content, project, today), "utf8");
8110
8200
  const validation = await runValidate({ file: absPath });
8111
8201
  return {
@@ -8121,7 +8211,7 @@ async function availableImportPath(vault, proposed) {
8121
8211
  const stem = proposed.slice(0, -ext.length);
8122
8212
  let candidate = proposed;
8123
8213
  let i = 2;
8124
- while (await readIfExists2(join27(vault, candidate))) {
8214
+ while (await readIfExists2(join26(vault, candidate))) {
8125
8215
  candidate = `${stem}-${i}${ext}`;
8126
8216
  i++;
8127
8217
  }
@@ -8293,10 +8383,10 @@ function memoryCacheRelPath(project) {
8293
8383
  }
8294
8384
  async function readMemoryCache(vault, project) {
8295
8385
  if (project) {
8296
- const projectCache = await readIfExists2(join27(vault, memoryCacheRelPath(project)));
8386
+ const projectCache = await readIfExists2(join26(vault, memoryCacheRelPath(project)));
8297
8387
  if (projectCache) return projectCache;
8298
8388
  }
8299
- return readIfExists2(join27(vault, ".skillwiki", "memory-topics.json"));
8389
+ return readIfExists2(join26(vault, ".skillwiki", "memory-topics.json"));
8300
8390
  }
8301
8391
  function dedupePages(pages) {
8302
8392
  const seen = /* @__PURE__ */ new Set();
@@ -8383,7 +8473,7 @@ function slugify2(value) {
8383
8473
 
8384
8474
  // src/commands/query.ts
8385
8475
  import { readFile as readFile18, stat as stat6 } from "fs/promises";
8386
- import { join as join28 } from "path";
8476
+ import { join as join27 } from "path";
8387
8477
  var W_KEYWORD = 2;
8388
8478
  var W_SOURCE_OVERLAP = 4;
8389
8479
  var W_WIKILINK = 3;
@@ -8504,7 +8594,7 @@ function computeKeywordScore(terms, title, tags, body) {
8504
8594
  return score;
8505
8595
  }
8506
8596
  async function loadOrBuildGraph(vault) {
8507
- const graphPath = join28(vault, ".skillwiki", "graph.json");
8597
+ const graphPath = join27(vault, ".skillwiki", "graph.json");
8508
8598
  let needsBuild = false;
8509
8599
  try {
8510
8600
  const fileStat = await stat6(graphPath);
@@ -8533,7 +8623,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
8533
8623
  import { z as z2 } from "zod";
8534
8624
 
8535
8625
  // src/mcp/vault-resolve.ts
8536
- import { join as join29, resolve as resolve7 } from "path";
8626
+ import { join as join28, resolve as resolve7 } from "path";
8537
8627
 
8538
8628
  // src/mcp/allowlist.ts
8539
8629
  import { resolve as resolve6, sep as sep5 } from "path";
@@ -8595,7 +8685,7 @@ async function resolveMcpVault(input) {
8595
8685
  return ok({ vault: vaultPath, source });
8596
8686
  }
8597
8687
  function defaultGraphOut(vault) {
8598
- return join29(vault, ".skillwiki", "graph.json");
8688
+ return join28(vault, ".skillwiki", "graph.json");
8599
8689
  }
8600
8690
 
8601
8691
  // src/mcp/result-format.ts
@@ -8610,9 +8700,9 @@ function formatToolResult(payload) {
8610
8700
  }
8611
8701
 
8612
8702
  // src/mcp/audit-log.ts
8613
- import { appendFileSync, mkdirSync as mkdirSync4 } from "fs";
8703
+ import { appendFileSync, mkdirSync as mkdirSync3 } from "fs";
8614
8704
  import { homedir } from "os";
8615
- import { join as join30 } from "path";
8705
+ import { join as join29 } from "path";
8616
8706
  function auditEnabled() {
8617
8707
  const v = process.env.SKILLWIKI_MCP_AUDIT;
8618
8708
  if (v === "0" || v === "false") return false;
@@ -8624,7 +8714,7 @@ function auditSink() {
8624
8714
  function auditFilePath() {
8625
8715
  const custom = process.env.SKILLWIKI_MCP_AUDIT_FILE;
8626
8716
  if (custom && custom.length > 0) return custom;
8627
- return join30(homedir(), ".skillwiki", "mcp-audit.jsonl");
8717
+ return join29(homedir(), ".skillwiki", "mcp-audit.jsonl");
8628
8718
  }
8629
8719
  function auditMcpToolCall(entry) {
8630
8720
  if (!auditEnabled()) return;
@@ -8634,7 +8724,7 @@ function auditMcpToolCall(entry) {
8634
8724
  return;
8635
8725
  }
8636
8726
  const path = auditFilePath();
8637
- mkdirSync4(join30(path, ".."), { recursive: true });
8727
+ mkdirSync3(join29(path, ".."), { recursive: true });
8638
8728
  appendFileSync(path, line, "utf8");
8639
8729
  }
8640
8730
  async function runMcpToolHandler(tool, input, fn) {
@@ -8855,7 +8945,7 @@ function registerMcpMutatingTools(server) {
8855
8945
 
8856
8946
  // src/mcp/resources.ts
8857
8947
  import { readFile as readFile20 } from "fs/promises";
8858
- import { join as join32 } from "path";
8948
+ import { join as join31 } from "path";
8859
8949
  import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
8860
8950
 
8861
8951
  // src/mcp/lint-bucket.ts
@@ -8984,8 +9074,8 @@ async function fetchQueryPreview(input) {
8984
9074
 
8985
9075
  // src/mcp/graph-html.ts
8986
9076
  import { readFile as readFile19 } from "fs/promises";
8987
- import { join as join31 } from "path";
8988
- import { existsSync as existsSync15 } from "fs";
9077
+ import { join as join30 } from "path";
9078
+ import { existsSync as existsSync14 } from "fs";
8989
9079
  var TYPE_COLORS = {
8990
9080
  entities: "#e74c3c",
8991
9081
  concepts: "#27ae60",
@@ -9053,9 +9143,9 @@ ${nodeSvg}
9053
9143
  return { html, node_count: nodes.length, edge_count: edges.length, truncated };
9054
9144
  }
9055
9145
  async function fetchGraphHtmlReport(input) {
9056
- const graphPath = input.graphPath ?? join31(input.vault, ".skillwiki", "graph.json");
9146
+ const graphPath = input.graphPath ?? join30(input.vault, ".skillwiki", "graph.json");
9057
9147
  const maxNodes = Math.min(Math.max(10, input.maxNodes ?? 120), 500);
9058
- if (!existsSync15(graphPath)) {
9148
+ if (!existsSync14(graphPath)) {
9059
9149
  return {
9060
9150
  exitCode: ExitCode.FILE_NOT_FOUND,
9061
9151
  result: err("GRAPH_MISSING", { path: graphPath, hint: "Run skillwiki.graph_build first." })
@@ -9127,7 +9217,7 @@ async function fetchStaleSummary(input) {
9127
9217
 
9128
9218
  // src/mcp/resources.ts
9129
9219
  async function readVaultFile(vault, rel) {
9130
- return readFile20(join32(vault, rel), "utf8");
9220
+ return readFile20(join31(vault, rel), "utf8");
9131
9221
  }
9132
9222
  async function tailLines(text, lines) {
9133
9223
  const parts = text.split(/\r?\n/);
@@ -9213,7 +9303,7 @@ function registerMcpResources(server) {
9213
9303
  if (!v.ok) {
9214
9304
  return { contents: [{ uri: uri.href, mimeType: "text/plain", text: JSON.stringify(v) }] };
9215
9305
  }
9216
- const path = join32(v.data.vault, ".skillwiki", "graph.json");
9306
+ const path = join31(v.data.vault, ".skillwiki", "graph.json");
9217
9307
  try {
9218
9308
  const raw = await readFile20(path, "utf8");
9219
9309
  const graph = JSON.parse(raw);
@@ -9571,13 +9661,12 @@ export {
9571
9661
  fixPathTooLong,
9572
9662
  assessSourceIdentity,
9573
9663
  runLint,
9664
+ runSyncLintDelta,
9574
9665
  configPath,
9575
9666
  runConfigGet,
9576
9667
  runConfigSet,
9577
9668
  runConfigList,
9578
9669
  runConfigPath,
9579
- writeCache,
9580
- triggerAutoUpdate,
9581
9670
  buildDegradedReasons,
9582
9671
  probeRemoteHealth,
9583
9672
  FLEET_REL_PATH,