skillwiki 0.9.55 → 0.9.56

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 = {
@@ -4317,71 +4312,12 @@ async function runConfigPath(input) {
4317
4312
  return { exitCode: ExitCode.OK, result: ok({ path: filePath, exists: existsSync6(filePath), humanHint: filePath }) };
4318
4313
  }
4319
4314
 
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
4315
  // src/commands/fleet.ts
4380
4316
  import { readFile as readFile14 } from "fs/promises";
4381
4317
  import { hostname as nodeHostname, userInfo } from "os";
4382
- import { join as join18 } from "path";
4318
+ import { join as join17 } from "path";
4383
4319
  import yaml3 from "js-yaml";
4384
- var FLEET_REL_PATH = join18("projects", "llm-wiki", "architecture", "fleet.yaml");
4320
+ var FLEET_REL_PATH = join17("projects", "llm-wiki", "architecture", "fleet.yaml");
4385
4321
  async function runFleetValidate(input) {
4386
4322
  const loaded = await loadFleetManifest(input.file);
4387
4323
  if (!loaded.ok) {
@@ -4412,7 +4348,7 @@ async function runFleetContext(input) {
4412
4348
  const osHostname = input.osHostname ?? safeEnvValue(env.HOSTNAME) ?? nodeHostname();
4413
4349
  const user = input.user ?? safeEnvValue(env.USER) ?? safeUserName();
4414
4350
  const vault = input.vault ?? safeEnvValue(env.WIKI_PATH);
4415
- const file = input.file ?? (vault ? join18(vault, FLEET_REL_PATH) : void 0);
4351
+ const file = input.file ?? (vault ? join17(vault, FLEET_REL_PATH) : void 0);
4416
4352
  const generatedAt = (/* @__PURE__ */ new Date()).toISOString();
4417
4353
  const loaded = file ? await loadFleetManifest(file) : { ok: false, error: "FILE_NOT_FOUND" };
4418
4354
  if (!loaded.ok) {
@@ -4532,7 +4468,7 @@ function fleetContextEnv(input) {
4532
4468
  const home = input.home ?? env.HOME ?? "";
4533
4469
  const osHostname = input.osHostname ?? safeEnvValue(env.HOSTNAME) ?? nodeHostname();
4534
4470
  const vault = input.vault ?? safeEnvValue(env.WIKI_PATH);
4535
- const file = input.file ?? (vault ? join18(vault, FLEET_REL_PATH) : void 0);
4471
+ const file = input.file ?? (vault ? join17(vault, FLEET_REL_PATH) : void 0);
4536
4472
  return { env, home, osHostname, vault, file };
4537
4473
  }
4538
4474
  async function loadFleetManifestAndHost(input) {
@@ -4666,7 +4602,7 @@ async function resolveFleetHostId(input) {
4666
4602
  }
4667
4603
  trace.push({ source: "AGENT_HOST_ID", status: "unset" });
4668
4604
  if (input.home) {
4669
- const dotenv = await parseDotenvFile(join18(input.home, ".skillwiki", ".env"));
4605
+ const dotenv = await parseDotenvFile(join17(input.home, ".skillwiki", ".env"));
4670
4606
  if (dotenv.SKILLWIKI_HOST_ID) {
4671
4607
  trace.push({ source: "~/.skillwiki/.env:SKILLWIKI_HOST_ID", status: "matched", value: dotenv.SKILLWIKI_HOST_ID });
4672
4608
  return { hostId: dotenv.SKILLWIKI_HOST_ID, source: "~/.skillwiki/.env:SKILLWIKI_HOST_ID", trace };
@@ -4839,20 +4775,20 @@ function safeUserName() {
4839
4775
  }
4840
4776
 
4841
4777
  // 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";
4778
+ import { existsSync as existsSync12, lstatSync, readlinkSync, readdirSync as readdirSync3, statSync, readFileSync as readFileSync9 } from "fs";
4779
+ import { join as join23, resolve as resolve5 } from "path";
4844
4780
  import { execSync as execSync2 } from "child_process";
4845
4781
  import { platform as platform2 } from "os";
4846
4782
 
4847
4783
  // 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");
4784
+ import { existsSync as existsSync7, readdirSync, readFileSync as readFileSync4 } from "fs";
4785
+ import { join as join18 } from "path";
4786
+ var REGISTRY_PATH = join18(".claude", "plugins", "installed_plugins.json");
4787
+ var CODEX_CONFIG_PATH = join18(".codex", "config.toml");
4852
4788
  var PLUGIN_KEY = "skillwiki@llm-wiki";
4853
4789
  function readInstalledPlugins(home) {
4854
4790
  try {
4855
- const raw = readFileSync5(join19(home, REGISTRY_PATH), "utf8");
4791
+ const raw = readFileSync4(join18(home, REGISTRY_PATH), "utf8");
4856
4792
  return JSON.parse(raw);
4857
4793
  } catch {
4858
4794
  return null;
@@ -4888,8 +4824,8 @@ function findPluginInstallations(home, key = PLUGIN_KEY) {
4888
4824
  function findCodexPlugin(home, key, pluginName, marketplace) {
4889
4825
  const config = readCodexPluginConfig(home, key, marketplace);
4890
4826
  if (!config?.enabled) return null;
4891
- const cacheRoot = join19(home, ".codex", "plugins", "cache", marketplace, pluginName);
4892
- if (!existsSync8(cacheRoot)) return null;
4827
+ const cacheRoot = join18(home, ".codex", "plugins", "cache", marketplace, pluginName);
4828
+ if (!existsSync7(cacheRoot)) return null;
4893
4829
  let versions;
4894
4830
  try {
4895
4831
  versions = readdirSync(cacheRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
@@ -4904,7 +4840,7 @@ function findCodexPlugin(home, key, pluginName, marketplace) {
4904
4840
  key,
4905
4841
  pluginName,
4906
4842
  marketplace,
4907
- installPath: join19(cacheRoot, version),
4843
+ installPath: join18(cacheRoot, version),
4908
4844
  version,
4909
4845
  sourceType: config.sourceType,
4910
4846
  source: config.source
@@ -4921,7 +4857,7 @@ function parsePluginKey(key) {
4921
4857
  function readCodexPluginConfig(home, key, marketplace) {
4922
4858
  let raw;
4923
4859
  try {
4924
- raw = readFileSync5(join19(home, CODEX_CONFIG_PATH), "utf8");
4860
+ raw = readFileSync4(join18(home, CODEX_CONFIG_PATH), "utf8");
4925
4861
  } catch {
4926
4862
  return null;
4927
4863
  }
@@ -4963,8 +4899,8 @@ function parseTomlScalar(rawValue) {
4963
4899
  }
4964
4900
 
4965
4901
  // 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";
4902
+ import { existsSync as existsSync8, readdirSync as readdirSync2, readFileSync as readFileSync5 } from "fs";
4903
+ import { join as join19 } from "path";
4968
4904
  function scanConflictMarkerBlocksInText(relPath, text) {
4969
4905
  const findings = [];
4970
4906
  const lines = text.split(/\r?\n/);
@@ -5015,21 +4951,21 @@ function walkMarkdownFiles2(root, dir, rel, out) {
5015
4951
  for (const entry of entries) {
5016
4952
  if (entry.isDirectory()) {
5017
4953
  if (PRUNE_DIRS.has(entry.name)) continue;
5018
- walkMarkdownFiles2(root, join20(dir, entry.name), rel ? `${rel}/${entry.name}` : entry.name, out);
4954
+ walkMarkdownFiles2(root, join19(dir, entry.name), rel ? `${rel}/${entry.name}` : entry.name, out);
5019
4955
  } else if (entry.isFile() && entry.name.endsWith(".md")) {
5020
4956
  out.push(rel ? `${rel}/${entry.name}` : entry.name);
5021
4957
  }
5022
4958
  }
5023
4959
  }
5024
4960
  function scanVaultConflictMarkers(vaultRoot) {
5025
- if (!existsSync9(vaultRoot)) return [];
4961
+ if (!existsSync8(vaultRoot)) return [];
5026
4962
  const relPaths = [];
5027
4963
  walkMarkdownFiles2(vaultRoot, vaultRoot, "", relPaths);
5028
4964
  const all = [];
5029
4965
  for (const rel of relPaths) {
5030
4966
  let text;
5031
4967
  try {
5032
- text = readFileSync6(join20(vaultRoot, rel), "utf8");
4968
+ text = readFileSync5(join19(vaultRoot, rel), "utf8");
5033
4969
  } catch {
5034
4970
  continue;
5035
4971
  }
@@ -5039,8 +4975,8 @@ function scanVaultConflictMarkers(vaultRoot) {
5039
4975
  }
5040
4976
 
5041
4977
  // src/utils/remote-health.ts
5042
- import { existsSync as existsSync10, readFileSync as readFileSync7 } from "fs";
5043
- import { join as join21 } from "path";
4978
+ import { existsSync as existsSync9, readFileSync as readFileSync6 } from "fs";
4979
+ import { join as join20 } from "path";
5044
4980
  import { execFileSync } from "child_process";
5045
4981
  var REMOTE_PROBE_TIMEOUT_MS = 3e3;
5046
4982
  var defaultExec = (file, args, cwd) => execFileSync(file, args, {
@@ -5052,7 +4988,7 @@ var defaultExec = (file, args, cwd) => execFileSync(file, args, {
5052
4988
  var DEFAULT_WIKI_S3_REMOTE = "seaweed-wiki:cloud/wiki";
5053
4989
  function readWikiS3RemoteConfigured(home) {
5054
4990
  try {
5055
- const content = readFileSync7(join21(home, ".skillwiki", ".env"), "utf8");
4991
+ const content = readFileSync6(join20(home, ".skillwiki", ".env"), "utf8");
5056
4992
  for (const line of content.split(/\r?\n/)) {
5057
4993
  const trimmed = line.trim();
5058
4994
  if (!trimmed || trimmed.startsWith("#")) continue;
@@ -5070,7 +5006,7 @@ function readWikiS3RemoteFromEnv(home) {
5070
5006
  return readWikiS3RemoteConfigured(home) ?? DEFAULT_WIKI_S3_REMOTE;
5071
5007
  }
5072
5008
  function probeGithubReachability(vaultPath, exec = defaultExec) {
5073
- if (!existsSync10(join21(vaultPath, ".git"))) return "unknown";
5009
+ if (!existsSync9(join20(vaultPath, ".git"))) return "unknown";
5074
5010
  try {
5075
5011
  exec("git", ["remote", "get-url", "origin"], vaultPath);
5076
5012
  } catch {
@@ -5131,11 +5067,11 @@ function probeRemoteHealth(input) {
5131
5067
  }
5132
5068
 
5133
5069
  // src/utils/satellite-run-health.ts
5134
- import { existsSync as existsSync11, readFileSync as readFileSync8 } from "fs";
5135
- import { join as join22 } from "path";
5070
+ import { existsSync as existsSync10, readFileSync as readFileSync7 } from "fs";
5071
+ import { join as join21 } from "path";
5136
5072
  var SATELLITE_STALE_MS = 26 * 60 * 60 * 1e3;
5137
5073
  function satelliteLatestRunPath(vault) {
5138
- return join22(vault, ".skillwiki", "agent-memory-trends", "latest-run.json");
5074
+ return join21(vault, ".skillwiki", "agent-memory-trends", "latest-run.json");
5139
5075
  }
5140
5076
  function isFailedRunStatus(status) {
5141
5077
  return status === "fail" || status === "failure";
@@ -5157,9 +5093,9 @@ function readSatelliteLatestRunFromText(text) {
5157
5093
  }
5158
5094
  function readSatelliteLatestRun(vault) {
5159
5095
  const latestPath = satelliteLatestRunPath(vault);
5160
- if (!existsSync11(latestPath)) return null;
5096
+ if (!existsSync10(latestPath)) return null;
5161
5097
  try {
5162
- return parseLatestRunFile(readFileSync8(latestPath, "utf8"));
5098
+ return parseLatestRunFile(readFileSync7(latestPath, "utf8"));
5163
5099
  } catch {
5164
5100
  return null;
5165
5101
  }
@@ -5188,8 +5124,8 @@ function evaluateSatelliteRunHealth(vault, now) {
5188
5124
  // src/utils/s3-mount-health.ts
5189
5125
  import { execSync } from "child_process";
5190
5126
  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";
5127
+ import { readFileSync as readFileSync8, writeFileSync as writeFileSync3, unlinkSync as unlinkSync3, readFileSync as readFile15 } from "fs";
5128
+ import { join as join22 } from "path";
5193
5129
  var OS = platform();
5194
5130
  function findRcloneMountPid() {
5195
5131
  try {
@@ -5273,7 +5209,7 @@ function extractRcloneFs(args) {
5273
5209
  function getRcloneArgs(pid) {
5274
5210
  try {
5275
5211
  if (OS === "linux") {
5276
- const raw = readFileSync9(`/proc/${pid}/cmdline`);
5212
+ const raw = readFileSync8(`/proc/${pid}/cmdline`);
5277
5213
  return new TextDecoder().decode(raw).split("\0").filter(Boolean);
5278
5214
  } else {
5279
5215
  const out = execSync(`ps -o args= -p ${pid}`, {
@@ -5316,7 +5252,7 @@ function queryRcloneRC(rcAddr, fs) {
5316
5252
  function detectFuseMount(vaultPath) {
5317
5253
  try {
5318
5254
  if (OS === "linux") {
5319
- const mounts = readFileSync9("/proc/mounts", "utf8");
5255
+ const mounts = readFileSync8("/proc/mounts", "utf8");
5320
5256
  let best = null;
5321
5257
  for (const line of mounts.split("\n")) {
5322
5258
  const parts = line.split(" ");
@@ -5347,11 +5283,11 @@ function detectFuseMount(vaultPath) {
5347
5283
  return null;
5348
5284
  }
5349
5285
  function writeTest(dir) {
5350
- const testFile = join23(dir, `.doctor-write-test-${process.pid}.tmp`);
5286
+ const testFile = join22(dir, `.doctor-write-test-${process.pid}.tmp`);
5351
5287
  const payload = `skillwiki doctor write test \u2014 ${Date.now()} \u2014 ${Math.random().toString(36).slice(2)}`;
5352
5288
  const start = Date.now();
5353
5289
  try {
5354
- writeFileSync4(testFile, payload, "utf8");
5290
+ writeFileSync3(testFile, payload, "utf8");
5355
5291
  } catch (e) {
5356
5292
  return { success: false, writeMs: Date.now() - start, readMs: 0, size: 0, error: `write failed: ${e.message}` };
5357
5293
  }
@@ -5447,13 +5383,13 @@ function detectCliChannels(argv, home) {
5447
5383
  }
5448
5384
  const plugin = findPlugin(home);
5449
5385
  if (plugin) {
5450
- const pluginBin = join24(plugin.installPath, "bin", "skillwiki");
5451
- if (existsSync13(pluginBin)) {
5386
+ const pluginBin = join23(plugin.installPath, "bin", "skillwiki");
5387
+ if (existsSync12(pluginBin)) {
5452
5388
  channels.push({ name: "plugin", path: pluginBin, isDevLink: false });
5453
5389
  }
5454
5390
  }
5455
- const installBin = join24(home, ".claude", "skills", "bin", "skillwiki");
5456
- if (existsSync13(installBin)) {
5391
+ const installBin = join23(home, ".claude", "skills", "bin", "skillwiki");
5392
+ if (existsSync12(installBin)) {
5457
5393
  channels.push({ name: "install", path: installBin, isDevLink: false });
5458
5394
  }
5459
5395
  return channels;
@@ -5514,7 +5450,7 @@ function isDevSourceRun(argv) {
5514
5450
  }
5515
5451
  async function checkConfigFile(home) {
5516
5452
  const cfgPath = configPath(home);
5517
- if (!existsSync13(cfgPath)) {
5453
+ if (!existsSync12(cfgPath)) {
5518
5454
  return check("warn", "config_file", "Config file exists", `${cfgPath} not found`);
5519
5455
  }
5520
5456
  try {
@@ -5529,7 +5465,7 @@ function checkWikiPathExists(resolvedPath) {
5529
5465
  if (resolvedPath === void 0) {
5530
5466
  return check("error", "wiki_path_exists", "Vault directory exists", "Cannot check \u2014 WIKI_PATH not resolved");
5531
5467
  }
5532
- if (existsSync13(resolvedPath) && statSync(resolvedPath).isDirectory()) {
5468
+ if (existsSync12(resolvedPath) && statSync(resolvedPath).isDirectory()) {
5533
5469
  return check("pass", "wiki_path_exists", "Vault directory exists", resolvedPath);
5534
5470
  }
5535
5471
  return check("error", "wiki_path_exists", "Vault directory exists", `${resolvedPath} does not exist or is not a directory`);
@@ -5538,13 +5474,13 @@ function checkVaultStructure(resolvedPath) {
5538
5474
  if (resolvedPath === void 0) {
5539
5475
  return check("error", "vault_structure", "Vault structure valid", "Cannot check \u2014 WIKI_PATH not resolved");
5540
5476
  }
5541
- if (!existsSync13(resolvedPath)) {
5477
+ if (!existsSync12(resolvedPath)) {
5542
5478
  return check("error", "vault_structure", "Vault structure valid", "Cannot check \u2014 vault directory does not exist");
5543
5479
  }
5544
5480
  const missing = [];
5545
- if (!existsSync13(join24(resolvedPath, "SCHEMA.md"))) missing.push("SCHEMA.md");
5481
+ if (!existsSync12(join23(resolvedPath, "SCHEMA.md"))) missing.push("SCHEMA.md");
5546
5482
  for (const dir of ["raw", "entities", "concepts", "meta"]) {
5547
- if (!existsSync13(join24(resolvedPath, dir))) missing.push(dir + "/");
5483
+ if (!existsSync12(join23(resolvedPath, dir))) missing.push(dir + "/");
5548
5484
  }
5549
5485
  if (missing.length === 0) {
5550
5486
  return check("pass", "vault_structure", "Vault structure valid", "All required files and directories present");
@@ -5552,8 +5488,8 @@ function checkVaultStructure(resolvedPath) {
5552
5488
  return check("warn", "vault_structure", "Vault structure valid", `Missing: ${missing.join(", ")} \u2014 run \`skillwiki init\` to add CodeWiki structure`);
5553
5489
  }
5554
5490
  function checkSkillsInstalled(home, cwd) {
5555
- const srcDir = cwd ? join24(cwd, "packages", "skills") : void 0;
5556
- if (srcDir && existsSync13(srcDir)) {
5491
+ const srcDir = cwd ? join23(cwd, "packages", "skills") : void 0;
5492
+ if (srcDir && existsSync12(srcDir)) {
5557
5493
  const found = findInstalledSkillMd(srcDir);
5558
5494
  if (found.length > 0) {
5559
5495
  return check("pass", "skills_installed", "Skills installed", `${found.length} SKILL.md file(s) found (source)`);
@@ -5566,8 +5502,8 @@ function checkSkillsInstalled(home, cwd) {
5566
5502
  return check("pass", "skills_installed", "Skills installed", `${found.length} SKILL.md file(s) found (plugin v${plugin.version})`);
5567
5503
  }
5568
5504
  }
5569
- const skillsDir = join24(home, ".claude", "skills");
5570
- if (existsSync13(skillsDir)) {
5505
+ const skillsDir = join23(home, ".claude", "skills");
5506
+ if (existsSync12(skillsDir)) {
5571
5507
  const found = findInstalledSkillMd(skillsDir);
5572
5508
  if (found.length > 0) {
5573
5509
  return check("pass", "skills_installed", "Skills installed", `${found.length} SKILL.md file(s) found (CLI install)`);
@@ -5577,10 +5513,10 @@ function checkSkillsInstalled(home, cwd) {
5577
5513
  }
5578
5514
  function checkDuplicateSkills(home) {
5579
5515
  const plugin = findPlugin(home);
5580
- const skillsDir = join24(home, ".claude", "skills");
5516
+ const skillsDir = join23(home, ".claude", "skills");
5581
5517
  const agentSkillDirs = [
5582
- { label: "~/.codex/skills/", path: join24(home, ".codex", "skills") },
5583
- { label: "~/.agents/skills/", path: join24(home, ".agents", "skills") }
5518
+ { label: "~/.codex/skills/", path: join23(home, ".codex", "skills") },
5519
+ { label: "~/.agents/skills/", path: join23(home, ".agents", "skills") }
5584
5520
  ];
5585
5521
  if (!plugin) {
5586
5522
  return check("pass", "skills_duplicate", "Skills not duplicated", "Single install channel");
@@ -5683,8 +5619,8 @@ async function checkProfiles(home) {
5683
5619
  }
5684
5620
  async function checkProjectLocalOverride(cwd) {
5685
5621
  const dir = cwd ?? process.cwd();
5686
- const envPath = join24(dir, ".skillwiki", ".env");
5687
- if (existsSync13(envPath)) {
5622
+ const envPath = join23(dir, ".skillwiki", ".env");
5623
+ if (existsSync12(envPath)) {
5688
5624
  return check("pass", "project_local", "Project-local config", `Found: ${envPath}`);
5689
5625
  }
5690
5626
  return check("pass", "project_local", "Project-local config", "None");
@@ -5693,7 +5629,7 @@ function checkVaultGitRemote(resolvedPath) {
5693
5629
  if (resolvedPath === void 0) {
5694
5630
  return check("error", "vault_git_remote", "Vault git remote", "Cannot check \u2014 WIKI_PATH not resolved");
5695
5631
  }
5696
- if (!existsSync13(join24(resolvedPath, ".git"))) {
5632
+ if (!existsSync12(join23(resolvedPath, ".git"))) {
5697
5633
  return check("warn", "vault_git_remote", "Vault git remote", "Vault is not a git repository \u2014 sync features unavailable");
5698
5634
  }
5699
5635
  try {
@@ -5716,9 +5652,9 @@ function checkObsidianTemplates(resolvedPath) {
5716
5652
  return check("error", "obsidian_templates", "Obsidian templates", "Cannot check \u2014 WIKI_PATH not resolved");
5717
5653
  }
5718
5654
  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");
5655
+ if (!existsSync12(join23(resolvedPath, "_Templates"))) missing.push("_Templates/");
5656
+ if (!existsSync12(join23(resolvedPath, ".obsidian", "templates.json"))) missing.push(".obsidian/templates.json");
5657
+ if (!existsSync12(join23(resolvedPath, ".obsidian", "app.json"))) missing.push(".obsidian/app.json");
5722
5658
  if (missing.length === 0) {
5723
5659
  return check("pass", "obsidian_templates", "Obsidian templates", "Template folder and config present");
5724
5660
  }
@@ -5728,8 +5664,8 @@ function checkDotStoreClean(resolvedPath) {
5728
5664
  if (resolvedPath === void 0) {
5729
5665
  return check("error", "dsstore_clean", "No .DS_Store in raw/", "Cannot check \u2014 WIKI_PATH not resolved");
5730
5666
  }
5731
- const rawDir = join24(resolvedPath, "raw");
5732
- if (!existsSync13(rawDir)) {
5667
+ const rawDir = join23(resolvedPath, "raw");
5668
+ if (!existsSync12(rawDir)) {
5733
5669
  return check("pass", "dsstore_clean", "No .DS_Store in raw/", "raw/ directory not found \u2014 check skipped");
5734
5670
  }
5735
5671
  const found = [];
@@ -5744,7 +5680,7 @@ function checkDotStoreClean(resolvedPath) {
5744
5680
  if (entry.name === ".DS_Store") {
5745
5681
  found.push(rel ? `${rel}/.DS_Store` : ".DS_Store");
5746
5682
  } else if (entry.isDirectory()) {
5747
- walk2(join24(dir, entry.name), rel ? `${rel}/${entry.name}` : entry.name);
5683
+ walk2(join23(dir, entry.name), rel ? `${rel}/${entry.name}` : entry.name);
5748
5684
  }
5749
5685
  }
5750
5686
  })(rawDir, "");
@@ -5775,7 +5711,7 @@ function checkSyncLastPush(resolvedPath) {
5775
5711
  if (resolvedPath === void 0) {
5776
5712
  return check("error", "sync_last_push", "Vault sync recency", "Cannot check \u2014 WIKI_PATH not resolved");
5777
5713
  }
5778
- if (!existsSync13(join24(resolvedPath, ".git"))) {
5714
+ if (!existsSync12(join23(resolvedPath, ".git"))) {
5779
5715
  return check("pass", "sync_last_push", "Vault sync recency", "No git repo \u2014 sync check skipped");
5780
5716
  }
5781
5717
  let timestamp;
@@ -5823,7 +5759,7 @@ function checkVaultGitDirty(resolvedPath) {
5823
5759
  if (resolvedPath === void 0) {
5824
5760
  return check("pass", "vault_git_dirty", "Vault git dirty state", "No vault path \u2014 check skipped");
5825
5761
  }
5826
- if (!existsSync13(join24(resolvedPath, ".git"))) {
5762
+ if (!existsSync12(join23(resolvedPath, ".git"))) {
5827
5763
  return check("pass", "vault_git_dirty", "Vault git dirty state", "No git repo \u2014 check skipped");
5828
5764
  }
5829
5765
  try {
@@ -5891,7 +5827,7 @@ function remoteMainHash(resolvedPath) {
5891
5827
  }
5892
5828
  function checkStaleRemoteMain(resolvedPath) {
5893
5829
  if (resolvedPath === void 0) return void 0;
5894
- if (!existsSync13(join24(resolvedPath, ".git"))) return void 0;
5830
+ if (!existsSync12(join23(resolvedPath, ".git"))) return void 0;
5895
5831
  const localOrigin = gitRefHash(resolvedPath, "origin/main");
5896
5832
  if (!localOrigin) return void 0;
5897
5833
  const remoteMain = remoteMainHash(resolvedPath);
@@ -5907,7 +5843,7 @@ function checkVaultLocalGit(resolvedPath) {
5907
5843
  if (resolvedPath === void 0) {
5908
5844
  return check("warn", "vault_local_git", "Vault local git", "Cannot check \u2014 WIKI_PATH not resolved");
5909
5845
  }
5910
- if (!existsSync13(join24(resolvedPath, ".git"))) {
5846
+ if (!existsSync12(join23(resolvedPath, ".git"))) {
5911
5847
  return check("warn", "vault_local_git", "Vault local git", "Not a git repository - sync features unavailable");
5912
5848
  }
5913
5849
  try {
@@ -5926,7 +5862,7 @@ function checkVaultGithubRemote(resolvedPath, exec) {
5926
5862
  if (resolvedPath === void 0) {
5927
5863
  return check("pass", "vault_github_remote", "Vault GitHub remote", "No vault path \u2014 check skipped");
5928
5864
  }
5929
- if (!existsSync13(join24(resolvedPath, ".git"))) {
5865
+ if (!existsSync12(join23(resolvedPath, ".git"))) {
5930
5866
  return check("pass", "vault_github_remote", "Vault GitHub remote", "No git repo \u2014 check skipped");
5931
5867
  }
5932
5868
  const state = probeGithubReachability(resolvedPath, exec);
@@ -5970,7 +5906,7 @@ function checkVaultPromotionLag(resolvedPath) {
5970
5906
  if (resolvedPath === void 0) {
5971
5907
  return check("pass", "vault_promotion_lag", "Vault promotion lag", "No vault path \u2014 check skipped");
5972
5908
  }
5973
- if (!existsSync13(join24(resolvedPath, ".git"))) {
5909
+ if (!existsSync12(join23(resolvedPath, ".git"))) {
5974
5910
  return check("pass", "vault_promotion_lag", "Vault promotion lag", "No git repo \u2014 check skipped");
5975
5911
  }
5976
5912
  try {
@@ -5997,7 +5933,7 @@ function checkVaultGitComparison(resolvedPath, id, label, range, nonZeroSuffix,
5997
5933
  if (resolvedPath === void 0) {
5998
5934
  return check("pass", id, label, "No vault path \u2014 check skipped");
5999
5935
  }
6000
- if (!existsSync13(join24(resolvedPath, ".git"))) {
5936
+ if (!existsSync12(join23(resolvedPath, ".git"))) {
6001
5937
  return check("pass", id, label, "No git repo \u2014 check skipped");
6002
5938
  }
6003
5939
  if (!hasOriginMain(resolvedPath)) {
@@ -6025,7 +5961,7 @@ function checkSatelliteLastRun(vaultPath, satelliteExpected) {
6025
5961
  return check("pass", "satellite_job_last_run", "Satellite job last run", "No vault path \u2014 check skipped");
6026
5962
  }
6027
5963
  const latestPath = satelliteLatestRunPath(vaultPath);
6028
- if (!existsSync13(latestPath)) {
5964
+ if (!existsSync12(latestPath)) {
6029
5965
  return check("pass", "satellite_job_last_run", "Satellite job last run", "No latest-run.json \u2014 satellite has not run yet");
6030
5966
  }
6031
5967
  try {
@@ -6113,11 +6049,11 @@ async function checkFleetIdentity(input) {
6113
6049
  }
6114
6050
  function pullLogPaths(home) {
6115
6051
  const paths = platform2() === "darwin" ? [
6116
- join24(home, "Library", "Logs", "wiki-pull.log"),
6117
- join24(home, ".local", "state", "vault-sync", "log", "wiki-pull.log")
6052
+ join23(home, "Library", "Logs", "wiki-pull.log"),
6053
+ join23(home, ".local", "state", "vault-sync", "log", "wiki-pull.log")
6118
6054
  ] : [
6119
- join24(home, ".local", "state", "vault-sync", "log", "wiki-pull.log"),
6120
- join24(home, "Library", "Logs", "wiki-pull.log")
6055
+ join23(home, ".local", "state", "vault-sync", "log", "wiki-pull.log"),
6056
+ join23(home, "Library", "Logs", "wiki-pull.log")
6121
6057
  ];
6122
6058
  return [...new Set(paths)];
6123
6059
  }
@@ -6129,12 +6065,12 @@ function isRecentLogLine(line, nowMs) {
6129
6065
  return nowMs - ts <= 24 * 60 * 60 * 1e3;
6130
6066
  }
6131
6067
  function checkVaultGitPullFailures(home) {
6132
- const path = pullLogPaths(home).find((p) => existsSync13(p));
6068
+ const path = pullLogPaths(home).find((p) => existsSync12(p));
6133
6069
  if (!path) {
6134
6070
  return check("pass", "vault_git_pull_failures", "Vault pull failures", "No wiki-pull.log found \u2014 check skipped");
6135
6071
  }
6136
6072
  try {
6137
- const lines = readFileSync10(path, "utf8").split(/\r?\n/).filter(Boolean);
6073
+ const lines = readFileSync9(path, "utf8").split(/\r?\n/).filter(Boolean);
6138
6074
  const now = Date.now();
6139
6075
  const failures = lines.filter(
6140
6076
  (line) => isRecentLogLine(line, now) && /(pre-push pull failed|FAIL .*pull|FAIL .*rebase|cannot pull with rebase|unstaged changes)/i.test(line)
@@ -6157,8 +6093,8 @@ function checkS3MountPerf(resolvedPath) {
6157
6093
  return check("pass", "s3_mount_perf", "S3 mount performance", "local disk");
6158
6094
  }
6159
6095
  const mountPoint = fuse.mountPoint;
6160
- const conceptsDir = join24(resolvedPath, "concepts");
6161
- if (!existsSync13(conceptsDir)) {
6096
+ const conceptsDir = join23(resolvedPath, "concepts");
6097
+ if (!existsSync12(conceptsDir)) {
6162
6098
  return check("pass", "s3_mount_perf", "S3 mount performance", `S3 FUSE mount (${mountPoint}), no concepts/ to benchmark`);
6163
6099
  }
6164
6100
  const start = Date.now();
@@ -6340,8 +6276,8 @@ function checkWriteTest(resolvedPath) {
6340
6276
  if (!fuse) {
6341
6277
  return check("pass", "s3_write_test", "S3 write test", "local disk \u2014 check skipped");
6342
6278
  }
6343
- const conceptsDir = join24(resolvedPath, "concepts");
6344
- if (!existsSync13(conceptsDir)) {
6279
+ const conceptsDir = join23(resolvedPath, "concepts");
6280
+ if (!existsSync12(conceptsDir)) {
6345
6281
  return check("pass", "s3_write_test", "S3 write test", "no concepts/ dir to test \u2014 check skipped");
6346
6282
  }
6347
6283
  const result = writeTest(conceptsDir);
@@ -6427,7 +6363,7 @@ function checkVfsCacheHealth(resolvedPath) {
6427
6363
  }
6428
6364
  function readVaultSyncConfig(home) {
6429
6365
  try {
6430
- const content = readFileSync10(join24(home, ".skillwiki", ".env"), "utf8");
6366
+ const content = readFileSync9(join23(home, ".skillwiki", ".env"), "utf8");
6431
6367
  let installed = false;
6432
6368
  let role;
6433
6369
  let serviceScope;
@@ -6456,7 +6392,7 @@ function readVaultSyncConfig(home) {
6456
6392
  }
6457
6393
  function readKeyFromEnvFile(path, keys) {
6458
6394
  try {
6459
- const content = readFileSync10(path, "utf8");
6395
+ const content = readFileSync9(path, "utf8");
6460
6396
  for (const line of content.split(/\r?\n/)) {
6461
6397
  const trimmed = line.trim();
6462
6398
  if (trimmed.length === 0 || trimmed.startsWith("#")) continue;
@@ -6478,7 +6414,7 @@ function resolveSnapshotGitWorktree(config) {
6478
6414
  if (fromProfile) return fromProfile;
6479
6415
  }
6480
6416
  const defaultPath = "/root/wiki-git";
6481
- return existsSync13(defaultPath) ? defaultPath : void 0;
6417
+ return existsSync12(defaultPath) ? defaultPath : void 0;
6482
6418
  }
6483
6419
  function vaultSyncChecks(input) {
6484
6420
  const os = input.os ?? platform2();
@@ -6495,16 +6431,16 @@ function vaultSyncChecks(input) {
6495
6431
  ];
6496
6432
  }
6497
6433
  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");
6434
+ const logDir = input.logDir ?? (isMac ? join23(home, "Library", "Logs") : join23(home, ".local", "state", "vault-sync", "log"));
6435
+ const shareDir = input.shareDir ?? (isMac ? join23(home, "Library", "Application Support", "vault-sync", "bin") : join23(home, ".local", "share", "vault-sync", "bin"));
6436
+ const filterPath = input.filterPath ?? join23(home, ".config", "rclone", "wiki-push-filters.txt");
6437
+ const packagedSnapshotPath = join23(shareDir, "wiki-snapshot.sh");
6502
6438
  const legacySnapshotPath = "/root/.hermes/scripts/wiki-snapshot-v3.sh";
6503
- const snapshotPath = input.snapshotScriptPath ?? (existsSync13(packagedSnapshotPath) ? packagedSnapshotPath : legacySnapshotPath);
6439
+ const snapshotPath = input.snapshotScriptPath ?? (existsSync12(packagedSnapshotPath) ? packagedSnapshotPath : legacySnapshotPath);
6504
6440
  function snapshotLastStatusCheck() {
6505
- const snapshotLog = join24(logDir, "wiki-snapshot.log");
6441
+ const snapshotLog = join23(logDir, "wiki-snapshot.log");
6506
6442
  try {
6507
- const logContent = readFileSync10(snapshotLog, "utf8");
6443
+ const logContent = readFileSync9(snapshotLog, "utf8");
6508
6444
  const lines = logContent.trim().split("\n").filter(Boolean);
6509
6445
  if (lines.length === 0) {
6510
6446
  return check(
@@ -6549,14 +6485,14 @@ function vaultSyncChecks(input) {
6549
6485
  }
6550
6486
  }
6551
6487
  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}`);
6488
+ 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
6489
  const serviceScope = input.vaultSyncServiceScope ?? "user";
6554
- const userTimerPath = join24(home, ".config", "systemd", "user", "wiki-snapshot.timer");
6490
+ const userTimerPath = join23(home, ".config", "systemd", "user", "wiki-snapshot.timer");
6555
6491
  const systemTimerPath = "/etc/systemd/system/wiki-snapshot.timer";
6556
6492
  let c22;
6557
- if (serviceScope === "user" && existsSync13(userTimerPath)) {
6493
+ if (serviceScope === "user" && existsSync12(userTimerPath)) {
6558
6494
  c22 = check("pass", "vault_sync_jobs_enabled", "Vault sync jobs enabled", `Found: ${userTimerPath}`);
6559
- } else if (serviceScope === "system" && existsSync13(systemTimerPath)) {
6495
+ } else if (serviceScope === "system" && existsSync12(systemTimerPath)) {
6560
6496
  c22 = check("pass", "vault_sync_jobs_enabled", "Vault sync jobs enabled", `Found: ${systemTimerPath}`);
6561
6497
  } else if (os !== "linux") {
6562
6498
  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 +6524,7 @@ function vaultSyncChecks(input) {
6588
6524
  );
6589
6525
  let c52;
6590
6526
  try {
6591
- if (!existsSync13(snapshotPath)) {
6527
+ if (!existsSync12(snapshotPath)) {
6592
6528
  c52 = check(
6593
6529
  "error",
6594
6530
  "vault_sync_snapshot_guard",
@@ -6596,7 +6532,7 @@ function vaultSyncChecks(input) {
6596
6532
  `Snapshot script not found at ${snapshotPath}`
6597
6533
  );
6598
6534
  } else {
6599
- const content = readFileSync10(snapshotPath, "utf8");
6535
+ const content = readFileSync9(snapshotPath, "utf8");
6600
6536
  if (!content.includes("--max-delete")) {
6601
6537
  c52 = check(
6602
6538
  "error",
@@ -6623,8 +6559,8 @@ function vaultSyncChecks(input) {
6623
6559
  }
6624
6560
  return [c12, c22, c32, cFetch2, c42, c52];
6625
6561
  }
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`);
6562
+ const pushScriptPath = join23(shareDir, "wiki-push.sh");
6563
+ 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
6564
  let c2;
6629
6565
  try {
6630
6566
  if (isMac) {
@@ -6675,10 +6611,10 @@ function vaultSyncChecks(input) {
6675
6611
  "Scheduler check failed \u2014 run vault-sync-install"
6676
6612
  );
6677
6613
  }
6678
- const logFile = join24(logDir, "wiki-push.log");
6614
+ const logFile = join23(logDir, "wiki-push.log");
6679
6615
  let c3;
6680
6616
  try {
6681
- const logContent = readFileSync10(logFile, "utf8");
6617
+ const logContent = readFileSync9(logFile, "utf8");
6682
6618
  const lines = logContent.trim().split("\n").filter(Boolean);
6683
6619
  if (lines.length === 0) {
6684
6620
  c3 = check(
@@ -6734,7 +6670,7 @@ function vaultSyncChecks(input) {
6734
6670
  }
6735
6671
  }
6736
6672
  } catch {
6737
- c3 = existsSync13(logDir) ? check(
6673
+ c3 = existsSync12(logDir) ? check(
6738
6674
  "warn",
6739
6675
  "vault_sync_last_push_age",
6740
6676
  "Vault sync last push recency",
@@ -6746,10 +6682,10 @@ function vaultSyncChecks(input) {
6746
6682
  `Log directory not found at ${logDir}`
6747
6683
  );
6748
6684
  }
6749
- const fetchLogFile = join24(logDir, "wiki-fetch.log");
6685
+ const fetchLogFile = join23(logDir, "wiki-fetch.log");
6750
6686
  let cFetch;
6751
6687
  try {
6752
- const logContent = readFileSync10(fetchLogFile, "utf8");
6688
+ const logContent = readFileSync9(fetchLogFile, "utf8");
6753
6689
  const lines = logContent.trim().split("\n").filter(Boolean);
6754
6690
  if (lines.length === 0) {
6755
6691
  cFetch = check(
@@ -6793,7 +6729,7 @@ function vaultSyncChecks(input) {
6793
6729
  }
6794
6730
  let c4;
6795
6731
  try {
6796
- if (!existsSync13(filterPath)) {
6732
+ if (!existsSync12(filterPath)) {
6797
6733
  c4 = check(
6798
6734
  "error",
6799
6735
  "vault_sync_filter_present",
@@ -6801,7 +6737,7 @@ function vaultSyncChecks(input) {
6801
6737
  `Filter file not found at ${filterPath}`
6802
6738
  );
6803
6739
  } else {
6804
- const content = readFileSync10(filterPath, "utf8");
6740
+ const content = readFileSync9(filterPath, "utf8");
6805
6741
  const requiredExcludes = [
6806
6742
  "remotely-save/data.json",
6807
6743
  ".skillwiki/sync.lock",
@@ -6844,7 +6780,7 @@ function vaultSyncChecks(input) {
6844
6780
  );
6845
6781
  } else {
6846
6782
  try {
6847
- if (!existsSync13(snapshotPath)) {
6783
+ if (!existsSync12(snapshotPath)) {
6848
6784
  c5 = check(
6849
6785
  "error",
6850
6786
  "vault_sync_snapshot_guard",
@@ -6852,7 +6788,7 @@ function vaultSyncChecks(input) {
6852
6788
  `Snapshot script not found at ${snapshotPath}`
6853
6789
  );
6854
6790
  } else {
6855
- const content = readFileSync10(snapshotPath, "utf8");
6791
+ const content = readFileSync9(snapshotPath, "utf8");
6856
6792
  if (!content.includes("--max-delete")) {
6857
6793
  c5 = check(
6858
6794
  "error",
@@ -6890,15 +6826,15 @@ function findSkillMd(dir) {
6890
6826
  }
6891
6827
  for (const entry of entries) {
6892
6828
  if (entry.isFile() && entry.name === "SKILL.md") {
6893
- results.push(join24(dir, entry.name));
6829
+ results.push(join23(dir, entry.name));
6894
6830
  } else if (entry.isDirectory()) {
6895
- results.push(...findSkillMd(join24(dir, entry.name)));
6831
+ results.push(...findSkillMd(join23(dir, entry.name)));
6896
6832
  }
6897
6833
  }
6898
6834
  return results;
6899
6835
  }
6900
6836
  function findInstalledSkillMd(dir) {
6901
- const directSkills = findSkillNames(dir).map((name) => join24(dir, name, "SKILL.md"));
6837
+ const directSkills = findSkillNames(dir).map((name) => join23(dir, name, "SKILL.md"));
6902
6838
  return directSkills.length > 0 ? directSkills : findSkillMd(dir);
6903
6839
  }
6904
6840
  function findSkillNames(dir) {
@@ -6910,7 +6846,7 @@ function findSkillNames(dir) {
6910
6846
  return results;
6911
6847
  }
6912
6848
  for (const entry of entries) {
6913
- if (entry.isDirectory() && existsSync13(join24(dir, entry.name, "SKILL.md"))) {
6849
+ if (entry.isDirectory() && existsSync12(join23(dir, entry.name, "SKILL.md"))) {
6914
6850
  results.push(entry.name);
6915
6851
  }
6916
6852
  }
@@ -6954,7 +6890,7 @@ async function vaultMetrics(resolvedPath) {
6954
6890
  }
6955
6891
  let logLines = 0;
6956
6892
  try {
6957
- logLines = readFileSync10(join24(resolvedPath, "log.md"), "utf8").split("\n").length;
6893
+ logLines = readFileSync9(join23(resolvedPath, "log.md"), "utf8").split("\n").length;
6958
6894
  } catch {
6959
6895
  }
6960
6896
  return [
@@ -7062,7 +6998,7 @@ async function runDoctor(input) {
7062
6998
  }
7063
6999
 
7064
7000
  // src/utils/package-info.ts
7065
- import { readFileSync as readFileSync11 } from "fs";
7001
+ import { readFileSync as readFileSync10 } from "fs";
7066
7002
  function packageJsonCandidateUrls(baseUrl = import.meta.url) {
7067
7003
  return [
7068
7004
  new URL("../package.json", baseUrl),
@@ -7072,7 +7008,7 @@ function packageJsonCandidateUrls(baseUrl = import.meta.url) {
7072
7008
  function readCliPackageJson(baseUrl = import.meta.url) {
7073
7009
  for (const url of packageJsonCandidateUrls(baseUrl)) {
7074
7010
  try {
7075
- const pkg = JSON.parse(readFileSync11(url, "utf8"));
7011
+ const pkg = JSON.parse(readFileSync10(url, "utf8"));
7076
7012
  if (typeof pkg.version === "string") {
7077
7013
  return { ...pkg, version: pkg.version };
7078
7014
  }
@@ -7084,7 +7020,7 @@ function readCliPackageJson(baseUrl = import.meta.url) {
7084
7020
 
7085
7021
  // src/commands/project-index.ts
7086
7022
  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";
7023
+ import { join as join24, dirname as dirname7, basename as basename2 } from "path";
7088
7024
  var LAYER2_DIRS = ["entities", "concepts", "comparisons", "queries", "meta"];
7089
7025
  var PROJECT_LOCAL_DIRS = ["requirements", "work", "architecture", "history"];
7090
7026
  async function scanMarkdownTree(rootAbs, rootRel) {
@@ -7096,7 +7032,7 @@ async function scanMarkdownTree(rootAbs, rootRel) {
7096
7032
  return found;
7097
7033
  }
7098
7034
  for (const entry of entries) {
7099
- const abs = join25(rootAbs, entry.name);
7035
+ const abs = join24(rootAbs, entry.name);
7100
7036
  const rel = `${rootRel}/${entry.name}`;
7101
7037
  if (entry.isDirectory()) {
7102
7038
  found.push(...await scanMarkdownTree(abs, rel));
@@ -7126,7 +7062,7 @@ function projectLocalType(slug, page, data) {
7126
7062
  }
7127
7063
  async function runProjectIndex(input) {
7128
7064
  const slug = input.slug;
7129
- const projectDir = join25(input.vault, "projects", slug);
7065
+ const projectDir = join24(input.vault, "projects", slug);
7130
7066
  try {
7131
7067
  await readdir4(projectDir);
7132
7068
  } catch {
@@ -7137,12 +7073,12 @@ async function runProjectIndex(input) {
7137
7073
  }
7138
7074
  const wikilinkPattern = `[[${slug}]]`;
7139
7075
  const entries = [];
7140
- const compoundDir = join25(input.vault, "projects", slug, "compound");
7076
+ const compoundDir = join24(input.vault, "projects", slug, "compound");
7141
7077
  try {
7142
7078
  const compoundFiles = await readdir4(compoundDir, { withFileTypes: true });
7143
7079
  for (const entry of compoundFiles) {
7144
7080
  if (!entry.isFile() || !entry.name.endsWith(".md")) continue;
7145
- const filePath = join25(compoundDir, entry.name);
7081
+ const filePath = join24(compoundDir, entry.name);
7146
7082
  let text;
7147
7083
  try {
7148
7084
  text = await readFile16(filePath, "utf8");
@@ -7162,13 +7098,13 @@ async function runProjectIndex(input) {
7162
7098
  for (const dir of LAYER2_DIRS) {
7163
7099
  let files;
7164
7100
  try {
7165
- files = await readdir4(join25(input.vault, dir), { withFileTypes: true });
7101
+ files = await readdir4(join24(input.vault, dir), { withFileTypes: true });
7166
7102
  } catch {
7167
7103
  continue;
7168
7104
  }
7169
7105
  for (const entry of files) {
7170
7106
  if (!entry.isFile() || !entry.name.endsWith(".md")) continue;
7171
- const filePath = join25(input.vault, dir, entry.name);
7107
+ const filePath = join24(input.vault, dir, entry.name);
7172
7108
  let text;
7173
7109
  try {
7174
7110
  text = await readFile16(filePath, "utf8");
@@ -7187,11 +7123,11 @@ async function runProjectIndex(input) {
7187
7123
  }
7188
7124
  }
7189
7125
  for (const dir of PROJECT_LOCAL_DIRS) {
7190
- const rootAbs = join25(projectDir, dir);
7126
+ const rootAbs = join24(projectDir, dir);
7191
7127
  const rootRel = `projects/${slug}/${dir}`;
7192
7128
  const pages = await scanMarkdownTree(rootAbs, rootRel);
7193
7129
  for (const page of pages) {
7194
- const filePath = join25(input.vault, page);
7130
+ const filePath = join24(input.vault, page);
7195
7131
  let text;
7196
7132
  try {
7197
7133
  text = await readFile16(filePath, "utf8");
@@ -7213,7 +7149,7 @@ async function runProjectIndex(input) {
7213
7149
  const tb = typeOrder[b.type] ?? 99;
7214
7150
  return ta !== tb ? ta - tb : a.title.localeCompare(b.title);
7215
7151
  });
7216
- const indexPath = join25(projectDir, "knowledge.md");
7152
+ const indexPath = join24(projectDir, "knowledge.md");
7217
7153
  let existing = false;
7218
7154
  let stale = false;
7219
7155
  try {
@@ -7257,7 +7193,7 @@ Autogenerated by \`skillwiki project-index\` on ${today}.
7257
7193
  }
7258
7194
  if (input.apply) {
7259
7195
  try {
7260
- await mkdir5(dirname8(indexPath), { recursive: true });
7196
+ await mkdir5(dirname7(indexPath), { recursive: true });
7261
7197
  await writeFile6(indexPath, body, "utf8");
7262
7198
  } catch (e) {
7263
7199
  return {
@@ -7287,8 +7223,8 @@ ${entries.map((e) => ` ${e.type}: [[${e.page.replace(/\.md$/, "")}]] \u2014 ${e
7287
7223
 
7288
7224
  // src/commands/observe.ts
7289
7225
  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";
7226
+ import { existsSync as existsSync13, statSync as statSync2 } from "fs";
7227
+ import { join as join25 } from "path";
7292
7228
  import { createHash as createHash5 } from "crypto";
7293
7229
  var ALLOWED_KINDS = /* @__PURE__ */ new Set(["note", "bug", "task", "idea", "session-log"]);
7294
7230
  function slugify(text) {
@@ -7311,13 +7247,13 @@ async function runObserve(input) {
7311
7247
  result: err("SCHEME_REJECTED", { message: "Text must not be empty" })
7312
7248
  };
7313
7249
  }
7314
- if (!existsSync14(input.vault) || !statSync2(input.vault).isDirectory()) {
7250
+ if (!existsSync13(input.vault) || !statSync2(input.vault).isDirectory()) {
7315
7251
  return {
7316
7252
  exitCode: ExitCode.VAULT_PATH_INVALID,
7317
7253
  result: err("VAULT_PATH_INVALID", { path: input.vault })
7318
7254
  };
7319
7255
  }
7320
- const transcriptsDir = join26(input.vault, "raw", "transcripts");
7256
+ const transcriptsDir = join25(input.vault, "raw", "transcripts");
7321
7257
  try {
7322
7258
  await mkdir6(transcriptsDir, { recursive: true });
7323
7259
  } catch {
@@ -7329,7 +7265,7 @@ async function runObserve(input) {
7329
7265
  const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
7330
7266
  const slug = slugify(input.text);
7331
7267
  const fileName = `${today}-observation-${slug}.md`;
7332
- const filePath = join26(transcriptsDir, fileName);
7268
+ const filePath = join25(transcriptsDir, fileName);
7333
7269
  const body = `
7334
7270
  ${input.text.trim()}
7335
7271
  `;
@@ -7371,7 +7307,7 @@ ${input.text.trim()}
7371
7307
  // src/commands/memory.ts
7372
7308
  import { createHash as createHash6 } from "crypto";
7373
7309
  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";
7310
+ import { basename as basename3, extname, join as join26, relative as relative4, sep as sep4 } from "path";
7375
7311
  async function runMemoryTopics(input) {
7376
7312
  const scan = await scanVault(input.vault);
7377
7313
  if (!scan.ok) return { exitCode: ExitCode.VAULT_PATH_INVALID, result: scan };
@@ -7435,8 +7371,8 @@ async function runMemoryIndex(input) {
7435
7371
  }
7436
7372
  const generatedAt = (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
7437
7373
  const relCachePath = memoryCacheRelPath(input.project);
7438
- const absCachePath = join27(input.vault, relCachePath);
7439
- await mkdir7(join27(input.vault, ".skillwiki", "memory", input.project), { recursive: true });
7374
+ const absCachePath = join26(input.vault, relCachePath);
7375
+ await mkdir7(join26(input.vault, ".skillwiki", "memory", input.project), { recursive: true });
7440
7376
  await writeFile8(absCachePath, `${JSON.stringify({
7441
7377
  generated_at: generatedAt,
7442
7378
  project: input.project,
@@ -7628,7 +7564,7 @@ async function buildMemoryIndexState(pages, project) {
7628
7564
  }
7629
7565
  async function checkMemoryIndex(vault, project, current) {
7630
7566
  const relCachePath = memoryCacheRelPath(project);
7631
- const cacheText = await readIfExists2(join27(vault, relCachePath));
7567
+ const cacheText = await readIfExists2(join26(vault, relCachePath));
7632
7568
  if (!cacheText) {
7633
7569
  return {
7634
7570
  ok: true,
@@ -8037,7 +7973,7 @@ async function walkImportFiles(dir, out) {
8037
7973
  const entries = await readdir5(dir, { withFileTypes: true });
8038
7974
  for (const entry of entries) {
8039
7975
  if (entry.name === ".git" || entry.name === "node_modules") continue;
8040
- const path = join27(dir, entry.name);
7976
+ const path = join26(dir, entry.name);
8041
7977
  if (entry.isDirectory()) {
8042
7978
  await walkImportFiles(path, out);
8043
7979
  } else if (entry.isFile() && isImportCandidate(path)) {
@@ -8104,8 +8040,8 @@ async function writeImportCapture(vault, entry, today) {
8104
8040
  const content = hiddenString(entry, "__content");
8105
8041
  const project = hiddenString(entry, "__project");
8106
8042
  const relPath = await availableImportPath(vault, entry.proposed_path);
8107
- const absPath = join27(vault, relPath);
8108
- await mkdir7(join27(vault, "raw", "transcripts"), { recursive: true });
8043
+ const absPath = join26(vault, relPath);
8044
+ await mkdir7(join26(vault, "raw", "transcripts"), { recursive: true });
8109
8045
  await writeFile8(absPath, renderImportCapture(entry, content, project, today), "utf8");
8110
8046
  const validation = await runValidate({ file: absPath });
8111
8047
  return {
@@ -8121,7 +8057,7 @@ async function availableImportPath(vault, proposed) {
8121
8057
  const stem = proposed.slice(0, -ext.length);
8122
8058
  let candidate = proposed;
8123
8059
  let i = 2;
8124
- while (await readIfExists2(join27(vault, candidate))) {
8060
+ while (await readIfExists2(join26(vault, candidate))) {
8125
8061
  candidate = `${stem}-${i}${ext}`;
8126
8062
  i++;
8127
8063
  }
@@ -8293,10 +8229,10 @@ function memoryCacheRelPath(project) {
8293
8229
  }
8294
8230
  async function readMemoryCache(vault, project) {
8295
8231
  if (project) {
8296
- const projectCache = await readIfExists2(join27(vault, memoryCacheRelPath(project)));
8232
+ const projectCache = await readIfExists2(join26(vault, memoryCacheRelPath(project)));
8297
8233
  if (projectCache) return projectCache;
8298
8234
  }
8299
- return readIfExists2(join27(vault, ".skillwiki", "memory-topics.json"));
8235
+ return readIfExists2(join26(vault, ".skillwiki", "memory-topics.json"));
8300
8236
  }
8301
8237
  function dedupePages(pages) {
8302
8238
  const seen = /* @__PURE__ */ new Set();
@@ -8383,7 +8319,7 @@ function slugify2(value) {
8383
8319
 
8384
8320
  // src/commands/query.ts
8385
8321
  import { readFile as readFile18, stat as stat6 } from "fs/promises";
8386
- import { join as join28 } from "path";
8322
+ import { join as join27 } from "path";
8387
8323
  var W_KEYWORD = 2;
8388
8324
  var W_SOURCE_OVERLAP = 4;
8389
8325
  var W_WIKILINK = 3;
@@ -8504,7 +8440,7 @@ function computeKeywordScore(terms, title, tags, body) {
8504
8440
  return score;
8505
8441
  }
8506
8442
  async function loadOrBuildGraph(vault) {
8507
- const graphPath = join28(vault, ".skillwiki", "graph.json");
8443
+ const graphPath = join27(vault, ".skillwiki", "graph.json");
8508
8444
  let needsBuild = false;
8509
8445
  try {
8510
8446
  const fileStat = await stat6(graphPath);
@@ -8533,7 +8469,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
8533
8469
  import { z as z2 } from "zod";
8534
8470
 
8535
8471
  // src/mcp/vault-resolve.ts
8536
- import { join as join29, resolve as resolve7 } from "path";
8472
+ import { join as join28, resolve as resolve7 } from "path";
8537
8473
 
8538
8474
  // src/mcp/allowlist.ts
8539
8475
  import { resolve as resolve6, sep as sep5 } from "path";
@@ -8595,7 +8531,7 @@ async function resolveMcpVault(input) {
8595
8531
  return ok({ vault: vaultPath, source });
8596
8532
  }
8597
8533
  function defaultGraphOut(vault) {
8598
- return join29(vault, ".skillwiki", "graph.json");
8534
+ return join28(vault, ".skillwiki", "graph.json");
8599
8535
  }
8600
8536
 
8601
8537
  // src/mcp/result-format.ts
@@ -8610,9 +8546,9 @@ function formatToolResult(payload) {
8610
8546
  }
8611
8547
 
8612
8548
  // src/mcp/audit-log.ts
8613
- import { appendFileSync, mkdirSync as mkdirSync4 } from "fs";
8549
+ import { appendFileSync, mkdirSync as mkdirSync3 } from "fs";
8614
8550
  import { homedir } from "os";
8615
- import { join as join30 } from "path";
8551
+ import { join as join29 } from "path";
8616
8552
  function auditEnabled() {
8617
8553
  const v = process.env.SKILLWIKI_MCP_AUDIT;
8618
8554
  if (v === "0" || v === "false") return false;
@@ -8624,7 +8560,7 @@ function auditSink() {
8624
8560
  function auditFilePath() {
8625
8561
  const custom = process.env.SKILLWIKI_MCP_AUDIT_FILE;
8626
8562
  if (custom && custom.length > 0) return custom;
8627
- return join30(homedir(), ".skillwiki", "mcp-audit.jsonl");
8563
+ return join29(homedir(), ".skillwiki", "mcp-audit.jsonl");
8628
8564
  }
8629
8565
  function auditMcpToolCall(entry) {
8630
8566
  if (!auditEnabled()) return;
@@ -8634,7 +8570,7 @@ function auditMcpToolCall(entry) {
8634
8570
  return;
8635
8571
  }
8636
8572
  const path = auditFilePath();
8637
- mkdirSync4(join30(path, ".."), { recursive: true });
8573
+ mkdirSync3(join29(path, ".."), { recursive: true });
8638
8574
  appendFileSync(path, line, "utf8");
8639
8575
  }
8640
8576
  async function runMcpToolHandler(tool, input, fn) {
@@ -8855,7 +8791,7 @@ function registerMcpMutatingTools(server) {
8855
8791
 
8856
8792
  // src/mcp/resources.ts
8857
8793
  import { readFile as readFile20 } from "fs/promises";
8858
- import { join as join32 } from "path";
8794
+ import { join as join31 } from "path";
8859
8795
  import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
8860
8796
 
8861
8797
  // src/mcp/lint-bucket.ts
@@ -8984,8 +8920,8 @@ async function fetchQueryPreview(input) {
8984
8920
 
8985
8921
  // src/mcp/graph-html.ts
8986
8922
  import { readFile as readFile19 } from "fs/promises";
8987
- import { join as join31 } from "path";
8988
- import { existsSync as existsSync15 } from "fs";
8923
+ import { join as join30 } from "path";
8924
+ import { existsSync as existsSync14 } from "fs";
8989
8925
  var TYPE_COLORS = {
8990
8926
  entities: "#e74c3c",
8991
8927
  concepts: "#27ae60",
@@ -9053,9 +8989,9 @@ ${nodeSvg}
9053
8989
  return { html, node_count: nodes.length, edge_count: edges.length, truncated };
9054
8990
  }
9055
8991
  async function fetchGraphHtmlReport(input) {
9056
- const graphPath = input.graphPath ?? join31(input.vault, ".skillwiki", "graph.json");
8992
+ const graphPath = input.graphPath ?? join30(input.vault, ".skillwiki", "graph.json");
9057
8993
  const maxNodes = Math.min(Math.max(10, input.maxNodes ?? 120), 500);
9058
- if (!existsSync15(graphPath)) {
8994
+ if (!existsSync14(graphPath)) {
9059
8995
  return {
9060
8996
  exitCode: ExitCode.FILE_NOT_FOUND,
9061
8997
  result: err("GRAPH_MISSING", { path: graphPath, hint: "Run skillwiki.graph_build first." })
@@ -9127,7 +9063,7 @@ async function fetchStaleSummary(input) {
9127
9063
 
9128
9064
  // src/mcp/resources.ts
9129
9065
  async function readVaultFile(vault, rel) {
9130
- return readFile20(join32(vault, rel), "utf8");
9066
+ return readFile20(join31(vault, rel), "utf8");
9131
9067
  }
9132
9068
  async function tailLines(text, lines) {
9133
9069
  const parts = text.split(/\r?\n/);
@@ -9213,7 +9149,7 @@ function registerMcpResources(server) {
9213
9149
  if (!v.ok) {
9214
9150
  return { contents: [{ uri: uri.href, mimeType: "text/plain", text: JSON.stringify(v) }] };
9215
9151
  }
9216
- const path = join32(v.data.vault, ".skillwiki", "graph.json");
9152
+ const path = join31(v.data.vault, ".skillwiki", "graph.json");
9217
9153
  try {
9218
9154
  const raw = await readFile20(path, "utf8");
9219
9155
  const graph = JSON.parse(raw);
@@ -9576,8 +9512,6 @@ export {
9576
9512
  runConfigSet,
9577
9513
  runConfigList,
9578
9514
  runConfigPath,
9579
- writeCache,
9580
- triggerAutoUpdate,
9581
9515
  buildDegradedReasons,
9582
9516
  probeRemoteHealth,
9583
9517
  FLEET_REL_PATH,