skillwiki 0.9.47 → 0.9.48

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.
@@ -659,6 +659,7 @@ import { writeFile as writeFile2, mkdir } from "fs/promises";
659
659
  import { dirname } from "path";
660
660
 
661
661
  // src/utils/vault.ts
662
+ import { existsSync, readFileSync } from "fs";
662
663
  import { readFile as readFile2, readdir, stat } from "fs/promises";
663
664
  import { join as join2, relative as relative2, sep as sep2 } from "path";
664
665
  var TYPED_DIRS = ["entities", "concepts", "comparisons", "queries", "meta"];
@@ -668,6 +669,38 @@ function vaultIoConcurrency() {
668
669
  const raw = Number.parseInt(process.env.SKILLWIKI_VAULT_IO_CONCURRENCY ?? "", 10);
669
670
  return Number.isFinite(raw) && raw > 0 ? Math.min(raw, 64) : DEFAULT_IO_CONCURRENCY;
670
671
  }
672
+ function decodeProcMountPath(value) {
673
+ return value.replace(/\\040/g, " ");
674
+ }
675
+ function isRcloneFuseVault(root) {
676
+ let mounts;
677
+ try {
678
+ mounts = readFileSync("/proc/mounts", "utf8");
679
+ } catch {
680
+ return false;
681
+ }
682
+ return mounts.split(/\r?\n/).some((line) => {
683
+ const parts = line.split(" ");
684
+ if (parts.length < 3) return false;
685
+ const mountPoint = decodeProcMountPath(parts[1]);
686
+ const fsType = parts[2];
687
+ return fsType === "fuse.rclone" && (root === mountPoint || root.startsWith(`${mountPoint}/`));
688
+ });
689
+ }
690
+ function resolveReadOnlyVaultRoot(root) {
691
+ if (/^(1|true|yes)$/i.test(process.env.SKILLWIKI_DISABLE_VAULT_READ_MIRROR ?? "")) {
692
+ return { root, mirrored: false };
693
+ }
694
+ const explicitMirror = process.env.SKILLWIKI_VAULT_READ_MIRROR;
695
+ if (explicitMirror && existsSync(join2(explicitMirror, "SCHEMA.md"))) {
696
+ return { root: explicitMirror, mirrored: explicitMirror !== root };
697
+ }
698
+ const siblingMirror = `${root}-git`;
699
+ if (isRcloneFuseVault(root) && existsSync(join2(siblingMirror, "SCHEMA.md"))) {
700
+ return { root: siblingMirror, mirrored: true };
701
+ }
702
+ return { root, mirrored: false };
703
+ }
671
704
  async function mapWithConcurrency(items, limit, mapper) {
672
705
  const out = new Array(items.length);
673
706
  let next = 0;
@@ -1334,7 +1367,7 @@ function hasWikilinkCitations(body) {
1334
1367
  }
1335
1368
 
1336
1369
  // src/utils/raw-source.ts
1337
- import { existsSync } from "fs";
1370
+ import { existsSync as existsSync2 } from "fs";
1338
1371
  import { stat as stat2 } from "fs/promises";
1339
1372
  import { join as join4 } from "path";
1340
1373
  function normalizeRawSourceTarget(entry) {
@@ -1355,7 +1388,7 @@ function rawSourceTargetCandidates(vault, target) {
1355
1388
  return [...new Set(candidates)];
1356
1389
  }
1357
1390
  function rawSourceTargetExistsSync(vault, target) {
1358
- return rawSourceTargetCandidates(vault, target).some((candidate) => existsSync(candidate));
1391
+ return rawSourceTargetCandidates(vault, target).some((candidate) => existsSync2(candidate));
1359
1392
  }
1360
1393
  async function rawSourceTargetExists(vault, target) {
1361
1394
  for (const candidate of rawSourceTargetCandidates(vault, target)) {
@@ -1666,7 +1699,7 @@ function parseExpiryAnnotations(content, pagePath) {
1666
1699
  }
1667
1700
 
1668
1701
  // src/utils/last-op.ts
1669
- import { readFileSync, writeFileSync, mkdirSync, unlinkSync, existsSync as existsSync2 } from "fs";
1702
+ import { readFileSync as readFileSync2, writeFileSync, mkdirSync, unlinkSync, existsSync as existsSync3 } from "fs";
1670
1703
  import { join as join8 } from "path";
1671
1704
  var LAST_OP_DIR = ".skillwiki";
1672
1705
  var LAST_OP_FILE = "last-op.json";
@@ -1675,9 +1708,9 @@ function lastOpPath(vault) {
1675
1708
  }
1676
1709
  function readLastOp(vault) {
1677
1710
  const p = lastOpPath(vault);
1678
- if (!existsSync2(p)) return [];
1711
+ if (!existsSync3(p)) return [];
1679
1712
  try {
1680
- const raw = readFileSync(p, "utf8");
1713
+ const raw = readFileSync2(p, "utf8");
1681
1714
  const parsed = JSON.parse(raw);
1682
1715
  if (!Array.isArray(parsed)) {
1683
1716
  unlinkSync(p);
@@ -1696,7 +1729,7 @@ function appendLastOp(vault, entry) {
1696
1729
  const existing = readLastOp(vault);
1697
1730
  existing.push(entry);
1698
1731
  const dir = join8(vault, LAST_OP_DIR);
1699
- if (!existsSync2(dir)) mkdirSync(dir, { recursive: true });
1732
+ if (!existsSync3(dir)) mkdirSync(dir, { recursive: true });
1700
1733
  writeFileSync(lastOpPath(vault), JSON.stringify(existing, null, 2), "utf8");
1701
1734
  }
1702
1735
  function clearLastOp(vault) {
@@ -2142,7 +2175,7 @@ ${markdown_links.map((l) => ` line ${l.line}: ${l.text}`).join("\n")}`;
2142
2175
 
2143
2176
  // src/commands/dedup.ts
2144
2177
  import { createHash as createHash2 } from "crypto";
2145
- import { mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, unlinkSync as unlinkSync2 } from "fs";
2178
+ import { mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2, unlinkSync as unlinkSync2 } from "fs";
2146
2179
  import { dirname as dirname4, join as join12, resolve as resolve3 } from "path";
2147
2180
 
2148
2181
  // src/utils/rclone.ts
@@ -2262,7 +2295,7 @@ async function runDedup(input) {
2262
2295
  }
2263
2296
  }
2264
2297
  for (const page of scan.allMarkdown.filter((p) => !p.relPath.startsWith("raw/"))) {
2265
- const text = readFileSync2(join12(input.vault, page.relPath), "utf-8");
2298
+ const text = readFileSync3(join12(input.vault, page.relPath), "utf-8");
2266
2299
  let updated = text;
2267
2300
  let changed = false;
2268
2301
  for (const [oldPath, newPath] of replacements) {
@@ -2379,14 +2412,14 @@ function buildSafeEntries(vault, duplicates, unsafe) {
2379
2412
  return entries;
2380
2413
  }
2381
2414
  function hashRawBody(vault, relPath) {
2382
- const text = readFileSync2(join12(vault, relPath), "utf-8");
2415
+ const text = readFileSync3(join12(vault, relPath), "utf-8");
2383
2416
  const split = splitFrontmatter(text);
2384
2417
  const body = split.ok ? split.data.body : text;
2385
2418
  return createHash2("sha256").update(body).digest("hex");
2386
2419
  }
2387
2420
  function readManifest(path) {
2388
2421
  try {
2389
- const parsed = JSON.parse(readFileSync2(path, "utf-8"));
2422
+ const parsed = JSON.parse(readFileSync3(path, "utf-8"));
2390
2423
  if (parsed.version !== 1 || !Array.isArray(parsed.entries)) {
2391
2424
  return err("INVALID_FRONTMATTER", { message: "dedup manifest must have version 1 and entries[]" });
2392
2425
  }
@@ -2553,7 +2586,7 @@ ${newBody}`;
2553
2586
  }
2554
2587
 
2555
2588
  // src/commands/lint.ts
2556
- import { existsSync as existsSync4 } from "fs";
2589
+ import { existsSync as existsSync5 } from "fs";
2557
2590
  import { readFile as readFile12, readdir as readdir3 } from "fs/promises";
2558
2591
  import { createHash as createHash4 } from "crypto";
2559
2592
  import { join as join15, relative as relative3, sep as sep3 } from "path";
@@ -2613,7 +2646,7 @@ async function runRawBodyDedup(vault, scan, pageTextCache) {
2613
2646
  }
2614
2647
 
2615
2648
  // src/commands/path-too-long.ts
2616
- import { existsSync as existsSync3 } from "fs";
2649
+ import { existsSync as existsSync4 } from "fs";
2617
2650
  import { mkdir as mkdir4, readFile as readFile11, rename as rename4, unlink as unlink2 } from "fs/promises";
2618
2651
  import { dirname as dirname6, join as join14, posix, resolve as resolve4 } from "path";
2619
2652
  var MAX_PATH_LENGTH = 240;
@@ -2729,7 +2762,7 @@ async function resolveFixTarget(vault, original, preferred, maxLength) {
2729
2762
  for (const candidate of candidateRelPaths(preferred, maxLength)) {
2730
2763
  if (candidate === original || candidate.length > maxLength) continue;
2731
2764
  const candidatePath = join14(vault, candidate);
2732
- if (!existsSync3(candidatePath)) return { relPath: candidate, mode: "rename" };
2765
+ if (!existsSync4(candidatePath)) return { relPath: candidate, mode: "rename" };
2733
2766
  if (await hasSameContent(join14(vault, original), candidatePath)) {
2734
2767
  return { relPath: candidate, mode: "dedupe" };
2735
2768
  }
@@ -3126,6 +3159,9 @@ ${match.length === 0 ? "0 violations" : match.map((b) => ` ${b.kind}: ${b.items
3126
3159
  result: ok(input.summary ? summarizeLintOutput(output, input.examplesLimit) : output)
3127
3160
  };
3128
3161
  }
3162
+ function lintReadVault(input) {
3163
+ return input.fix ? input.vault : resolveReadOnlyVaultRoot(input.vault).root;
3164
+ }
3129
3165
  function recomputeRawSha256IfPresent(content) {
3130
3166
  const split = splitFrontmatter(content);
3131
3167
  if (!split.ok) return content;
@@ -3188,19 +3224,20 @@ async function walkMarkdownFiles(absDir, vaultRoot) {
3188
3224
  return pages;
3189
3225
  }
3190
3226
  async function collectCliRefsPages(vault) {
3191
- if (!existsSync4(join15(vault, "SCHEMA.md"))) {
3227
+ if (!existsSync5(join15(vault, "SCHEMA.md"))) {
3192
3228
  return err("VAULT_PATH_INVALID", { root: vault, reason: "SCHEMA.md missing" });
3193
3229
  }
3194
3230
  const pages = [];
3195
3231
  for (const dir of CLI_REFS_TYPED_DIRS) {
3196
3232
  const absDir = join15(vault, dir);
3197
- if (!existsSync4(absDir)) continue;
3233
+ if (!existsSync5(absDir)) continue;
3198
3234
  pages.push(...await walkMarkdownFiles(absDir, vault));
3199
3235
  }
3200
3236
  return ok(pages);
3201
3237
  }
3202
3238
  async function runCliRefsOnly(input) {
3203
- const pages = await collectCliRefsPages(input.vault);
3239
+ const lintVault = lintReadVault(input);
3240
+ const pages = await collectCliRefsPages(lintVault);
3204
3241
  if (!pages.ok) {
3205
3242
  return { exitCode: ExitCode.VAULT_PATH_INVALID, result: pages };
3206
3243
  }
@@ -3358,7 +3395,8 @@ async function applyFileSourceUrlFix(input, scan, fileSourceUrlFlags, fileSource
3358
3395
  return remaining;
3359
3396
  }
3360
3397
  async function runFileSourceUrlOnly(input) {
3361
- const scanResult = await scanVault(input.vault);
3398
+ const lintVault = lintReadVault(input);
3399
+ const scanResult = await scanVault(lintVault);
3362
3400
  if (!scanResult.ok) return { exitCode: ExitCode.VAULT_PATH_INVALID, result: scanResult };
3363
3401
  const pageTextCache = /* @__PURE__ */ new Map();
3364
3402
  const fixed = [];
@@ -3389,10 +3427,11 @@ async function runLint(input) {
3389
3427
  return runFileSourceUrlOnly(input);
3390
3428
  }
3391
3429
  const shouldFix = (bucket) => !!input.fix && (!input.only || input.only === bucket);
3430
+ const lintVault = lintReadVault(input);
3392
3431
  const buckets = {};
3393
3432
  const fixed = [];
3394
3433
  const unresolved = [];
3395
- const scanResult = await scanVault(input.vault);
3434
+ const scanResult = await scanVault(lintVault);
3396
3435
  if (!scanResult.ok) {
3397
3436
  return { exitCode: ExitCode.VAULT_PATH_INVALID, result: scanResult };
3398
3437
  }
@@ -3406,64 +3445,64 @@ async function runLint(input) {
3406
3445
  }
3407
3446
  });
3408
3447
  }
3409
- const links = await runLinks({ vault: input.vault, scan, pageTextCache });
3448
+ const links = await runLinks({ vault: lintVault, scan, pageTextCache });
3410
3449
  if (links.result.ok && links.result.data.broken.length > 0) buckets.broken_wikilinks = links.result.data.broken;
3411
3450
  if (!links.result.ok && links.result.error === "INVALID_FRONTMATTER") {
3412
3451
  buckets.invalid_frontmatter = [links.result.detail ?? {}];
3413
3452
  }
3414
- const tags = await runTagAudit({ vault: input.vault, scan, pageTextCache });
3453
+ const tags = await runTagAudit({ vault: lintVault, scan, pageTextCache });
3415
3454
  if (tags.result.ok && tags.result.data.violations.length > 0) buckets.tag_not_in_taxonomy = tags.result.data.violations;
3416
3455
  if (!tags.result.ok && tags.result.error === "INVALID_FRONTMATTER") {
3417
3456
  buckets.invalid_frontmatter = [...buckets.invalid_frontmatter ?? [], tags.result.detail ?? {}];
3418
3457
  }
3419
- const idx = await runIndexCheck({ vault: input.vault, scan });
3458
+ const idx = await runIndexCheck({ vault: lintVault, scan });
3420
3459
  if (idx.result.ok && (idx.result.data.missing_from_index.length > 0 || idx.result.data.ghost_entries.length > 0)) {
3421
3460
  buckets.index_incomplete = [{
3422
3461
  missing_from_index: idx.result.data.missing_from_index,
3423
3462
  ghost_entries: idx.result.data.ghost_entries
3424
3463
  }];
3425
3464
  }
3426
- const linkFmt = await runIndexLinkFormat({ vault: input.vault });
3465
+ const linkFmt = await runIndexLinkFormat({ vault: lintVault });
3427
3466
  if (linkFmt.result.ok && linkFmt.result.data.markdown_links.length > 0) {
3428
3467
  buckets.index_link_format = linkFmt.result.data.markdown_links;
3429
3468
  }
3430
- const staleResult = await runStale({ vault: input.vault, days: input.days, scan, pageTextCache });
3469
+ const staleResult = await runStale({ vault: lintVault, days: input.days, scan, pageTextCache });
3431
3470
  if (staleResult.result.ok) {
3432
3471
  const st = staleResult.result.data;
3433
3472
  const staleList = [...st.stale_transcripts.map((t) => t.path), ...(st.unclaimed_transcripts ?? []).map((t) => t.path), ...st.incomplete_work_items.map((w) => w.path), ...(st.done_work_items ?? []).map((w) => w.path)];
3434
3473
  if (staleList.length > 0) buckets.stale_page = staleList;
3435
3474
  }
3436
- const pagesize = await runPagesize({ vault: input.vault, lines: input.lines, scan, pageTextCache });
3475
+ const pagesize = await runPagesize({ vault: lintVault, lines: input.lines, scan, pageTextCache });
3437
3476
  if (pagesize.result.ok && pagesize.result.data.oversized.length > 0) buckets.page_too_large = pagesize.result.data.oversized;
3438
- const rotate = await runLogRotate({ vault: input.vault, threshold: input.logThreshold, apply: false });
3477
+ const rotate = await runLogRotate({ vault: lintVault, threshold: input.logThreshold, apply: false });
3439
3478
  if (rotate.result.ok && rotate.exitCode === ExitCode.LOG_ROTATE_NEEDED) {
3440
3479
  buckets.log_rotate_needed = [{ entries: rotate.result.data.entries, threshold: rotate.result.data.threshold }];
3441
3480
  }
3442
- const orphans = await runOrphans({ vault: input.vault, scan, pageTextCache });
3481
+ const orphans = await runOrphans({ vault: lintVault, scan, pageTextCache });
3443
3482
  if (orphans.result.ok) {
3444
3483
  if (orphans.result.data.orphans.length > 0) buckets.orphans = orphans.result.data.orphans;
3445
3484
  if (orphans.result.data.bridges.length > 0) buckets.bridges = orphans.result.data.bridges;
3446
3485
  }
3447
- const sparse = await runSparseCommunity({ vault: input.vault, scan, pageTextCache });
3486
+ const sparse = await runSparseCommunity({ vault: lintVault, scan, pageTextCache });
3448
3487
  if (sparse.result.ok && sparse.result.data.communities.length > 0) {
3449
3488
  buckets.sparse_community = sparse.result.data.communities;
3450
3489
  }
3451
- const topicMap = await runTopicMapCheck({ vault: input.vault, scan });
3490
+ const topicMap = await runTopicMapCheck({ vault: lintVault, scan });
3452
3491
  if (topicMap.result.ok && topicMap.result.data.recommended) {
3453
3492
  buckets.topic_map_recommended = [{ page_count: topicMap.result.data.page_count, threshold: topicMap.result.data.threshold }];
3454
3493
  }
3455
- const dedup = await runDedup({ vault: input.vault, scan, pageTextCache });
3494
+ const dedup = await runDedup({ vault: lintVault, scan, pageTextCache });
3456
3495
  if (dedup.result.ok && dedup.result.data.duplicates.length > 0) buckets.raw_dedup = dedup.result.data.duplicates;
3457
- const bodyDedup = await runRawBodyDedup(input.vault, scan, pageTextCache);
3496
+ const bodyDedup = await runRawBodyDedup(lintVault, scan, pageTextCache);
3458
3497
  if (bodyDedup.result.ok && bodyDedup.result.data.duplicates.length > 0) {
3459
3498
  buckets.raw_body_duplicate = bodyDedup.result.data.duplicates.map((d) => ({
3460
3499
  body_hash: d.bodyHash.slice(0, 12),
3461
3500
  files: d.files.map((f) => `${f.relPath} (sha256: ${f.sha256 ?? "none"})`)
3462
3501
  }));
3463
3502
  }
3464
- const compoundRefs = await validateCompoundReferences(input.vault, scan, pageTextCache);
3503
+ const compoundRefs = await validateCompoundReferences(lintVault, scan, pageTextCache);
3465
3504
  if (compoundRefs.ok && compoundRefs.data.length > 0) buckets.compound_refs = compoundRefs.data;
3466
- const pathCheck = await runPathTooLong({ vault: input.vault, scan });
3505
+ const pathCheck = await runPathTooLong({ vault: lintVault, scan });
3467
3506
  if (pathCheck.result.ok && pathCheck.result.data.violations.length > 0) buckets.path_too_long = pathCheck.result.data.violations;
3468
3507
  const allPages = [...scan.typedKnowledge, ...scan.raw, ...scan.workItems, ...scan.compound];
3469
3508
  const slugs = buildSlugMap(allPages);
@@ -3553,12 +3592,12 @@ async function runLint(input) {
3553
3592
  for (const entry of sourcesEntries) {
3554
3593
  const rawPath = normalizeRawSourceTarget(entry);
3555
3594
  if (!rawPath) continue;
3556
- if (!rawSourceTargetExistsSync(input.vault, rawPath)) {
3595
+ if (!rawSourceTargetExistsSync(lintVault, rawPath)) {
3557
3596
  result.brokenSourceFlags.push(`${page.relPath}: ${rawPath}`);
3558
3597
  }
3559
3598
  }
3560
3599
  for (const marker of extractCitationMarkers(body)) {
3561
- if (!rawSourceTargetExistsSync(input.vault, marker.target)) {
3600
+ if (!rawSourceTargetExistsSync(lintVault, marker.target)) {
3562
3601
  result.brokenSourceFlags.push(`${page.relPath}: ${marker.target}`);
3563
3602
  }
3564
3603
  }
@@ -3661,8 +3700,8 @@ async function runLint(input) {
3661
3700
  const readKnowledgeContent = (slug) => {
3662
3701
  const existing = knowledgeContentCache.get(slug);
3663
3702
  if (existing) return existing;
3664
- const knowledgePath = join15(input.vault, "projects", slug, "knowledge.md");
3665
- const pending = existsSync4(knowledgePath) ? readFile12(knowledgePath, "utf8").catch(() => null) : Promise.resolve(null);
3703
+ const knowledgePath = join15(lintVault, "projects", slug, "knowledge.md");
3704
+ const pending = existsSync5(knowledgePath) ? readFile12(knowledgePath, "utf8").catch(() => null) : Promise.resolve(null);
3666
3705
  knowledgeContentCache.set(slug, pending);
3667
3706
  return pending;
3668
3707
  };
@@ -4145,7 +4184,7 @@ ${split.data.body}`;
4145
4184
 
4146
4185
  // src/commands/config.ts
4147
4186
  import { readFile as readFile13 } from "fs/promises";
4148
- import { existsSync as existsSync5 } from "fs";
4187
+ import { existsSync as existsSync6 } from "fs";
4149
4188
  import { join as join16 } from "path";
4150
4189
  function validateKey(key) {
4151
4190
  return CONFIG_KEYS.includes(key) || isValidWikiProfileKey(key);
@@ -4201,11 +4240,11 @@ async function runConfigList(input) {
4201
4240
  }
4202
4241
  async function runConfigPath(input) {
4203
4242
  const filePath = configPath(input.home);
4204
- return { exitCode: ExitCode.OK, result: ok({ path: filePath, exists: existsSync5(filePath), humanHint: filePath }) };
4243
+ return { exitCode: ExitCode.OK, result: ok({ path: filePath, exists: existsSync6(filePath), humanHint: filePath }) };
4205
4244
  }
4206
4245
 
4207
4246
  // src/utils/auto-update.ts
4208
- import { readFileSync as readFileSync3, writeFileSync as writeFileSync3, existsSync as existsSync6, mkdirSync as mkdirSync3 } from "fs";
4247
+ import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, existsSync as existsSync7, mkdirSync as mkdirSync3 } from "fs";
4209
4248
  import { join as join17, dirname as dirname7 } from "path";
4210
4249
  import { spawn } from "child_process";
4211
4250
  function cachePath(home) {
@@ -4213,7 +4252,7 @@ function cachePath(home) {
4213
4252
  }
4214
4253
  function readCacheRaw(home) {
4215
4254
  try {
4216
- const raw = readFileSync3(cachePath(home), "utf8");
4255
+ const raw = readFileSync4(cachePath(home), "utf8");
4217
4256
  return JSON.parse(raw);
4218
4257
  } catch {
4219
4258
  return null;
@@ -4253,7 +4292,7 @@ function triggerAutoUpdate(home, currentVersion) {
4253
4292
  if (!isStale) return;
4254
4293
  const distTag = distTagFromCache(home);
4255
4294
  const bgScript = new URL("../auto-update-bg.js", import.meta.url).pathname;
4256
- if (!existsSync6(bgScript)) return;
4295
+ if (!existsSync7(bgScript)) return;
4257
4296
  const child = spawn(process.execPath, [bgScript, home, currentVersion, distTag], {
4258
4297
  detached: true,
4259
4298
  stdio: "ignore"
@@ -4717,20 +4756,20 @@ function safeUserName() {
4717
4756
  }
4718
4757
 
4719
4758
  // src/commands/doctor.ts
4720
- import { existsSync as existsSync10, lstatSync, readlinkSync, readdirSync as readdirSync2, statSync, readFileSync as readFileSync7 } from "fs";
4759
+ import { existsSync as existsSync11, lstatSync, readlinkSync, readdirSync as readdirSync2, statSync, readFileSync as readFileSync8 } from "fs";
4721
4760
  import { join as join22, resolve as resolve5 } from "path";
4722
4761
  import { execSync as execSync2 } from "child_process";
4723
4762
  import { platform as platform2 } from "os";
4724
4763
 
4725
4764
  // src/utils/plugin-registry.ts
4726
- import { existsSync as existsSync7, readdirSync, readFileSync as readFileSync4 } from "fs";
4765
+ import { existsSync as existsSync8, readdirSync, readFileSync as readFileSync5 } from "fs";
4727
4766
  import { join as join19 } from "path";
4728
4767
  var REGISTRY_PATH = join19(".claude", "plugins", "installed_plugins.json");
4729
4768
  var CODEX_CONFIG_PATH = join19(".codex", "config.toml");
4730
4769
  var PLUGIN_KEY = "skillwiki@llm-wiki";
4731
4770
  function readInstalledPlugins(home) {
4732
4771
  try {
4733
- const raw = readFileSync4(join19(home, REGISTRY_PATH), "utf8");
4772
+ const raw = readFileSync5(join19(home, REGISTRY_PATH), "utf8");
4734
4773
  return JSON.parse(raw);
4735
4774
  } catch {
4736
4775
  return null;
@@ -4767,7 +4806,7 @@ function findCodexPlugin(home, key, pluginName, marketplace) {
4767
4806
  const config = readCodexPluginConfig(home, key, marketplace);
4768
4807
  if (!config?.enabled) return null;
4769
4808
  const cacheRoot = join19(home, ".codex", "plugins", "cache", marketplace, pluginName);
4770
- if (!existsSync7(cacheRoot)) return null;
4809
+ if (!existsSync8(cacheRoot)) return null;
4771
4810
  let versions;
4772
4811
  try {
4773
4812
  versions = readdirSync(cacheRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
@@ -4799,7 +4838,7 @@ function parsePluginKey(key) {
4799
4838
  function readCodexPluginConfig(home, key, marketplace) {
4800
4839
  let raw;
4801
4840
  try {
4802
- raw = readFileSync4(join19(home, CODEX_CONFIG_PATH), "utf8");
4841
+ raw = readFileSync5(join19(home, CODEX_CONFIG_PATH), "utf8");
4803
4842
  } catch {
4804
4843
  return null;
4805
4844
  }
@@ -4841,7 +4880,7 @@ function parseTomlScalar(rawValue) {
4841
4880
  }
4842
4881
 
4843
4882
  // src/utils/satellite-run-health.ts
4844
- import { existsSync as existsSync8, readFileSync as readFileSync5 } from "fs";
4883
+ import { existsSync as existsSync9, readFileSync as readFileSync6 } from "fs";
4845
4884
  import { join as join20 } from "path";
4846
4885
  var SATELLITE_STALE_MS = 26 * 60 * 60 * 1e3;
4847
4886
  function satelliteLatestRunPath(vault) {
@@ -4867,9 +4906,9 @@ function readSatelliteLatestRunFromText(text) {
4867
4906
  }
4868
4907
  function readSatelliteLatestRun(vault) {
4869
4908
  const latestPath = satelliteLatestRunPath(vault);
4870
- if (!existsSync8(latestPath)) return null;
4909
+ if (!existsSync9(latestPath)) return null;
4871
4910
  try {
4872
- return parseLatestRunFile(readFileSync5(latestPath, "utf8"));
4911
+ return parseLatestRunFile(readFileSync6(latestPath, "utf8"));
4873
4912
  } catch {
4874
4913
  return null;
4875
4914
  }
@@ -4898,7 +4937,7 @@ function evaluateSatelliteRunHealth(vault, now) {
4898
4937
  // src/utils/s3-mount-health.ts
4899
4938
  import { execSync } from "child_process";
4900
4939
  import { platform } from "os";
4901
- import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, unlinkSync as unlinkSync3, readFileSync as readFile15 } from "fs";
4940
+ import { readFileSync as readFileSync7, writeFileSync as writeFileSync4, unlinkSync as unlinkSync3, readFileSync as readFile15 } from "fs";
4902
4941
  import { join as join21 } from "path";
4903
4942
  var OS = platform();
4904
4943
  function findRcloneMountPid() {
@@ -4983,7 +5022,7 @@ function extractRcloneFs(args) {
4983
5022
  function getRcloneArgs(pid) {
4984
5023
  try {
4985
5024
  if (OS === "linux") {
4986
- const raw = readFileSync6(`/proc/${pid}/cmdline`);
5025
+ const raw = readFileSync7(`/proc/${pid}/cmdline`);
4987
5026
  return new TextDecoder().decode(raw).split("\0").filter(Boolean);
4988
5027
  } else {
4989
5028
  const out = execSync(`ps -o args= -p ${pid}`, {
@@ -5026,7 +5065,7 @@ function queryRcloneRC(rcAddr, fs) {
5026
5065
  function detectFuseMount(vaultPath) {
5027
5066
  try {
5028
5067
  if (OS === "linux") {
5029
- const mounts = readFileSync6("/proc/mounts", "utf8");
5068
+ const mounts = readFileSync7("/proc/mounts", "utf8");
5030
5069
  let best = null;
5031
5070
  for (const line of mounts.split("\n")) {
5032
5071
  const parts = line.split(" ");
@@ -5158,12 +5197,12 @@ function detectCliChannels(argv, home) {
5158
5197
  const plugin = findPlugin(home);
5159
5198
  if (plugin) {
5160
5199
  const pluginBin = join22(plugin.installPath, "bin", "skillwiki");
5161
- if (existsSync10(pluginBin)) {
5200
+ if (existsSync11(pluginBin)) {
5162
5201
  channels.push({ name: "plugin", path: pluginBin, isDevLink: false });
5163
5202
  }
5164
5203
  }
5165
5204
  const installBin = join22(home, ".claude", "skills", "bin", "skillwiki");
5166
- if (existsSync10(installBin)) {
5205
+ if (existsSync11(installBin)) {
5167
5206
  channels.push({ name: "install", path: installBin, isDevLink: false });
5168
5207
  }
5169
5208
  return channels;
@@ -5224,7 +5263,7 @@ function isDevSourceRun(argv) {
5224
5263
  }
5225
5264
  async function checkConfigFile(home) {
5226
5265
  const cfgPath = configPath(home);
5227
- if (!existsSync10(cfgPath)) {
5266
+ if (!existsSync11(cfgPath)) {
5228
5267
  return check("warn", "config_file", "Config file exists", `${cfgPath} not found`);
5229
5268
  }
5230
5269
  try {
@@ -5239,7 +5278,7 @@ function checkWikiPathExists(resolvedPath) {
5239
5278
  if (resolvedPath === void 0) {
5240
5279
  return check("error", "wiki_path_exists", "Vault directory exists", "Cannot check \u2014 WIKI_PATH not resolved");
5241
5280
  }
5242
- if (existsSync10(resolvedPath) && statSync(resolvedPath).isDirectory()) {
5281
+ if (existsSync11(resolvedPath) && statSync(resolvedPath).isDirectory()) {
5243
5282
  return check("pass", "wiki_path_exists", "Vault directory exists", resolvedPath);
5244
5283
  }
5245
5284
  return check("error", "wiki_path_exists", "Vault directory exists", `${resolvedPath} does not exist or is not a directory`);
@@ -5248,13 +5287,13 @@ function checkVaultStructure(resolvedPath) {
5248
5287
  if (resolvedPath === void 0) {
5249
5288
  return check("error", "vault_structure", "Vault structure valid", "Cannot check \u2014 WIKI_PATH not resolved");
5250
5289
  }
5251
- if (!existsSync10(resolvedPath)) {
5290
+ if (!existsSync11(resolvedPath)) {
5252
5291
  return check("error", "vault_structure", "Vault structure valid", "Cannot check \u2014 vault directory does not exist");
5253
5292
  }
5254
5293
  const missing = [];
5255
- if (!existsSync10(join22(resolvedPath, "SCHEMA.md"))) missing.push("SCHEMA.md");
5294
+ if (!existsSync11(join22(resolvedPath, "SCHEMA.md"))) missing.push("SCHEMA.md");
5256
5295
  for (const dir of ["raw", "entities", "concepts", "meta"]) {
5257
- if (!existsSync10(join22(resolvedPath, dir))) missing.push(dir + "/");
5296
+ if (!existsSync11(join22(resolvedPath, dir))) missing.push(dir + "/");
5258
5297
  }
5259
5298
  if (missing.length === 0) {
5260
5299
  return check("pass", "vault_structure", "Vault structure valid", "All required files and directories present");
@@ -5263,7 +5302,7 @@ function checkVaultStructure(resolvedPath) {
5263
5302
  }
5264
5303
  function checkSkillsInstalled(home, cwd) {
5265
5304
  const srcDir = cwd ? join22(cwd, "packages", "skills") : void 0;
5266
- if (srcDir && existsSync10(srcDir)) {
5305
+ if (srcDir && existsSync11(srcDir)) {
5267
5306
  const found = findInstalledSkillMd(srcDir);
5268
5307
  if (found.length > 0) {
5269
5308
  return check("pass", "skills_installed", "Skills installed", `${found.length} SKILL.md file(s) found (source)`);
@@ -5277,7 +5316,7 @@ function checkSkillsInstalled(home, cwd) {
5277
5316
  }
5278
5317
  }
5279
5318
  const skillsDir = join22(home, ".claude", "skills");
5280
- if (existsSync10(skillsDir)) {
5319
+ if (existsSync11(skillsDir)) {
5281
5320
  const found = findInstalledSkillMd(skillsDir);
5282
5321
  if (found.length > 0) {
5283
5322
  return check("pass", "skills_installed", "Skills installed", `${found.length} SKILL.md file(s) found (CLI install)`);
@@ -5394,7 +5433,7 @@ async function checkProfiles(home) {
5394
5433
  async function checkProjectLocalOverride(cwd) {
5395
5434
  const dir = cwd ?? process.cwd();
5396
5435
  const envPath = join22(dir, ".skillwiki", ".env");
5397
- if (existsSync10(envPath)) {
5436
+ if (existsSync11(envPath)) {
5398
5437
  return check("pass", "project_local", "Project-local config", `Found: ${envPath}`);
5399
5438
  }
5400
5439
  return check("pass", "project_local", "Project-local config", "None");
@@ -5403,7 +5442,7 @@ function checkVaultGitRemote(resolvedPath) {
5403
5442
  if (resolvedPath === void 0) {
5404
5443
  return check("error", "vault_git_remote", "Vault git remote", "Cannot check \u2014 WIKI_PATH not resolved");
5405
5444
  }
5406
- if (!existsSync10(join22(resolvedPath, ".git"))) {
5445
+ if (!existsSync11(join22(resolvedPath, ".git"))) {
5407
5446
  return check("warn", "vault_git_remote", "Vault git remote", "Vault is not a git repository \u2014 sync features unavailable");
5408
5447
  }
5409
5448
  try {
@@ -5426,9 +5465,9 @@ function checkObsidianTemplates(resolvedPath) {
5426
5465
  return check("error", "obsidian_templates", "Obsidian templates", "Cannot check \u2014 WIKI_PATH not resolved");
5427
5466
  }
5428
5467
  const missing = [];
5429
- if (!existsSync10(join22(resolvedPath, "_Templates"))) missing.push("_Templates/");
5430
- if (!existsSync10(join22(resolvedPath, ".obsidian", "templates.json"))) missing.push(".obsidian/templates.json");
5431
- if (!existsSync10(join22(resolvedPath, ".obsidian", "app.json"))) missing.push(".obsidian/app.json");
5468
+ if (!existsSync11(join22(resolvedPath, "_Templates"))) missing.push("_Templates/");
5469
+ if (!existsSync11(join22(resolvedPath, ".obsidian", "templates.json"))) missing.push(".obsidian/templates.json");
5470
+ if (!existsSync11(join22(resolvedPath, ".obsidian", "app.json"))) missing.push(".obsidian/app.json");
5432
5471
  if (missing.length === 0) {
5433
5472
  return check("pass", "obsidian_templates", "Obsidian templates", "Template folder and config present");
5434
5473
  }
@@ -5439,7 +5478,7 @@ function checkDotStoreClean(resolvedPath) {
5439
5478
  return check("error", "dsstore_clean", "No .DS_Store in raw/", "Cannot check \u2014 WIKI_PATH not resolved");
5440
5479
  }
5441
5480
  const rawDir = join22(resolvedPath, "raw");
5442
- if (!existsSync10(rawDir)) {
5481
+ if (!existsSync11(rawDir)) {
5443
5482
  return check("pass", "dsstore_clean", "No .DS_Store in raw/", "raw/ directory not found \u2014 check skipped");
5444
5483
  }
5445
5484
  const found = [];
@@ -5467,7 +5506,7 @@ function checkSyncLastPush(resolvedPath) {
5467
5506
  if (resolvedPath === void 0) {
5468
5507
  return check("error", "sync_last_push", "Vault sync recency", "Cannot check \u2014 WIKI_PATH not resolved");
5469
5508
  }
5470
- if (!existsSync10(join22(resolvedPath, ".git"))) {
5509
+ if (!existsSync11(join22(resolvedPath, ".git"))) {
5471
5510
  return check("pass", "sync_last_push", "Vault sync recency", "No git repo \u2014 sync check skipped");
5472
5511
  }
5473
5512
  let timestamp;
@@ -5515,7 +5554,7 @@ function checkVaultGitDirty(resolvedPath) {
5515
5554
  if (resolvedPath === void 0) {
5516
5555
  return check("pass", "vault_git_dirty", "Vault git dirty state", "No vault path \u2014 check skipped");
5517
5556
  }
5518
- if (!existsSync10(join22(resolvedPath, ".git"))) {
5557
+ if (!existsSync11(join22(resolvedPath, ".git"))) {
5519
5558
  return check("pass", "vault_git_dirty", "Vault git dirty state", "No git repo \u2014 check skipped");
5520
5559
  }
5521
5560
  try {
@@ -5583,7 +5622,7 @@ function remoteMainHash(resolvedPath) {
5583
5622
  }
5584
5623
  function checkStaleRemoteMain(resolvedPath) {
5585
5624
  if (resolvedPath === void 0) return void 0;
5586
- if (!existsSync10(join22(resolvedPath, ".git"))) return void 0;
5625
+ if (!existsSync11(join22(resolvedPath, ".git"))) return void 0;
5587
5626
  const localOrigin = gitRefHash(resolvedPath, "origin/main");
5588
5627
  if (!localOrigin) return void 0;
5589
5628
  const remoteMain = remoteMainHash(resolvedPath);
@@ -5599,7 +5638,7 @@ function checkVaultGitComparison(resolvedPath, id, label, range, nonZeroSuffix,
5599
5638
  if (resolvedPath === void 0) {
5600
5639
  return check("pass", id, label, "No vault path \u2014 check skipped");
5601
5640
  }
5602
- if (!existsSync10(join22(resolvedPath, ".git"))) {
5641
+ if (!existsSync11(join22(resolvedPath, ".git"))) {
5603
5642
  return check("pass", id, label, "No git repo \u2014 check skipped");
5604
5643
  }
5605
5644
  if (!hasOriginMain(resolvedPath)) {
@@ -5627,7 +5666,7 @@ function checkSatelliteLastRun(vaultPath, satelliteExpected) {
5627
5666
  return check("pass", "satellite_job_last_run", "Satellite job last run", "No vault path \u2014 check skipped");
5628
5667
  }
5629
5668
  const latestPath = satelliteLatestRunPath(vaultPath);
5630
- if (!existsSync10(latestPath)) {
5669
+ if (!existsSync11(latestPath)) {
5631
5670
  return check("pass", "satellite_job_last_run", "Satellite job last run", "No latest-run.json \u2014 satellite has not run yet");
5632
5671
  }
5633
5672
  try {
@@ -5731,12 +5770,12 @@ function isRecentLogLine(line, nowMs) {
5731
5770
  return nowMs - ts <= 24 * 60 * 60 * 1e3;
5732
5771
  }
5733
5772
  function checkVaultGitPullFailures(home) {
5734
- const path = pullLogPaths(home).find((p) => existsSync10(p));
5773
+ const path = pullLogPaths(home).find((p) => existsSync11(p));
5735
5774
  if (!path) {
5736
5775
  return check("pass", "vault_git_pull_failures", "Vault pull failures", "No wiki-pull.log found \u2014 check skipped");
5737
5776
  }
5738
5777
  try {
5739
- const lines = readFileSync7(path, "utf8").split(/\r?\n/).filter(Boolean);
5778
+ const lines = readFileSync8(path, "utf8").split(/\r?\n/).filter(Boolean);
5740
5779
  const now = Date.now();
5741
5780
  const failures = lines.filter(
5742
5781
  (line) => isRecentLogLine(line, now) && /(pre-push pull failed|FAIL .*pull|FAIL .*rebase|cannot pull with rebase|unstaged changes)/i.test(line)
@@ -5760,7 +5799,7 @@ function checkS3MountPerf(resolvedPath) {
5760
5799
  }
5761
5800
  const mountPoint = fuse.mountPoint;
5762
5801
  const conceptsDir = join22(resolvedPath, "concepts");
5763
- if (!existsSync10(conceptsDir)) {
5802
+ if (!existsSync11(conceptsDir)) {
5764
5803
  return check("pass", "s3_mount_perf", "S3 mount performance", `S3 FUSE mount (${mountPoint}), no concepts/ to benchmark`);
5765
5804
  }
5766
5805
  const start = Date.now();
@@ -5943,7 +5982,7 @@ function checkWriteTest(resolvedPath) {
5943
5982
  return check("pass", "s3_write_test", "S3 write test", "local disk \u2014 check skipped");
5944
5983
  }
5945
5984
  const conceptsDir = join22(resolvedPath, "concepts");
5946
- if (!existsSync10(conceptsDir)) {
5985
+ if (!existsSync11(conceptsDir)) {
5947
5986
  return check("pass", "s3_write_test", "S3 write test", "no concepts/ dir to test \u2014 check skipped");
5948
5987
  }
5949
5988
  const result = writeTest(conceptsDir);
@@ -6029,7 +6068,7 @@ function checkVfsCacheHealth(resolvedPath) {
6029
6068
  }
6030
6069
  function readVaultSyncConfig(home) {
6031
6070
  try {
6032
- const content = readFileSync7(join22(home, ".skillwiki", ".env"), "utf8");
6071
+ const content = readFileSync8(join22(home, ".skillwiki", ".env"), "utf8");
6033
6072
  let installed = false;
6034
6073
  let role;
6035
6074
  let serviceScope;
@@ -6058,7 +6097,7 @@ function readVaultSyncConfig(home) {
6058
6097
  }
6059
6098
  function readKeyFromEnvFile(path, keys) {
6060
6099
  try {
6061
- const content = readFileSync7(path, "utf8");
6100
+ const content = readFileSync8(path, "utf8");
6062
6101
  for (const line of content.split(/\r?\n/)) {
6063
6102
  const trimmed = line.trim();
6064
6103
  if (trimmed.length === 0 || trimmed.startsWith("#")) continue;
@@ -6080,7 +6119,7 @@ function resolveSnapshotGitWorktree(config) {
6080
6119
  if (fromProfile) return fromProfile;
6081
6120
  }
6082
6121
  const defaultPath = "/root/wiki-git";
6083
- return existsSync10(defaultPath) ? defaultPath : void 0;
6122
+ return existsSync11(defaultPath) ? defaultPath : void 0;
6084
6123
  }
6085
6124
  function vaultSyncChecks(input) {
6086
6125
  const os = input.os ?? platform2();
@@ -6102,11 +6141,11 @@ function vaultSyncChecks(input) {
6102
6141
  const filterPath = input.filterPath ?? join22(home, ".config", "rclone", "wiki-push-filters.txt");
6103
6142
  const packagedSnapshotPath = join22(shareDir, "wiki-snapshot.sh");
6104
6143
  const legacySnapshotPath = "/root/.hermes/scripts/wiki-snapshot-v3.sh";
6105
- const snapshotPath = input.snapshotScriptPath ?? (existsSync10(packagedSnapshotPath) ? packagedSnapshotPath : legacySnapshotPath);
6144
+ const snapshotPath = input.snapshotScriptPath ?? (existsSync11(packagedSnapshotPath) ? packagedSnapshotPath : legacySnapshotPath);
6106
6145
  function snapshotLastStatusCheck() {
6107
6146
  const snapshotLog = join22(logDir, "wiki-snapshot.log");
6108
6147
  try {
6109
- const logContent = readFileSync7(snapshotLog, "utf8");
6148
+ const logContent = readFileSync8(snapshotLog, "utf8");
6110
6149
  const lines = logContent.trim().split("\n").filter(Boolean);
6111
6150
  if (lines.length === 0) {
6112
6151
  return check(
@@ -6151,14 +6190,14 @@ function vaultSyncChecks(input) {
6151
6190
  }
6152
6191
  }
6153
6192
  if (input.vaultSyncRole === "snapshotter") {
6154
- const c12 = existsSync10(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}`);
6193
+ const c12 = existsSync11(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}`);
6155
6194
  const serviceScope = input.vaultSyncServiceScope ?? "user";
6156
6195
  const userTimerPath = join22(home, ".config", "systemd", "user", "wiki-snapshot.timer");
6157
6196
  const systemTimerPath = "/etc/systemd/system/wiki-snapshot.timer";
6158
6197
  let c22;
6159
- if (serviceScope === "user" && existsSync10(userTimerPath)) {
6198
+ if (serviceScope === "user" && existsSync11(userTimerPath)) {
6160
6199
  c22 = check("pass", "vault_sync_jobs_enabled", "Vault sync jobs enabled", `Found: ${userTimerPath}`);
6161
- } else if (serviceScope === "system" && existsSync10(systemTimerPath)) {
6200
+ } else if (serviceScope === "system" && existsSync11(systemTimerPath)) {
6162
6201
  c22 = check("pass", "vault_sync_jobs_enabled", "Vault sync jobs enabled", `Found: ${systemTimerPath}`);
6163
6202
  } else if (os !== "linux") {
6164
6203
  c22 = check("warn", "vault_sync_jobs_enabled", "Vault sync jobs enabled", "Snapshotter scheduler is Linux-only and no wiki-snapshot.timer file was found");
@@ -6190,7 +6229,7 @@ function vaultSyncChecks(input) {
6190
6229
  );
6191
6230
  let c52;
6192
6231
  try {
6193
- if (!existsSync10(snapshotPath)) {
6232
+ if (!existsSync11(snapshotPath)) {
6194
6233
  c52 = check(
6195
6234
  "error",
6196
6235
  "vault_sync_snapshot_guard",
@@ -6198,7 +6237,7 @@ function vaultSyncChecks(input) {
6198
6237
  `Snapshot script not found at ${snapshotPath}`
6199
6238
  );
6200
6239
  } else {
6201
- const content = readFileSync7(snapshotPath, "utf8");
6240
+ const content = readFileSync8(snapshotPath, "utf8");
6202
6241
  if (!content.includes("--max-delete")) {
6203
6242
  c52 = check(
6204
6243
  "error",
@@ -6226,7 +6265,7 @@ function vaultSyncChecks(input) {
6226
6265
  return [c12, c22, c32, cFetch2, c42, c52];
6227
6266
  }
6228
6267
  const pushScriptPath = join22(shareDir, "wiki-push.sh");
6229
- const c1 = existsSync10(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`);
6268
+ const c1 = existsSync11(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`);
6230
6269
  let c2;
6231
6270
  try {
6232
6271
  if (isMac) {
@@ -6280,7 +6319,7 @@ function vaultSyncChecks(input) {
6280
6319
  const logFile = join22(logDir, "wiki-push.log");
6281
6320
  let c3;
6282
6321
  try {
6283
- const logContent = readFileSync7(logFile, "utf8");
6322
+ const logContent = readFileSync8(logFile, "utf8");
6284
6323
  const lines = logContent.trim().split("\n").filter(Boolean);
6285
6324
  if (lines.length === 0) {
6286
6325
  c3 = check(
@@ -6336,7 +6375,7 @@ function vaultSyncChecks(input) {
6336
6375
  }
6337
6376
  }
6338
6377
  } catch {
6339
- c3 = existsSync10(logDir) ? check(
6378
+ c3 = existsSync11(logDir) ? check(
6340
6379
  "warn",
6341
6380
  "vault_sync_last_push_age",
6342
6381
  "Vault sync last push recency",
@@ -6351,7 +6390,7 @@ function vaultSyncChecks(input) {
6351
6390
  const fetchLogFile = join22(logDir, "wiki-fetch.log");
6352
6391
  let cFetch;
6353
6392
  try {
6354
- const logContent = readFileSync7(fetchLogFile, "utf8");
6393
+ const logContent = readFileSync8(fetchLogFile, "utf8");
6355
6394
  const lines = logContent.trim().split("\n").filter(Boolean);
6356
6395
  if (lines.length === 0) {
6357
6396
  cFetch = check(
@@ -6395,7 +6434,7 @@ function vaultSyncChecks(input) {
6395
6434
  }
6396
6435
  let c4;
6397
6436
  try {
6398
- if (!existsSync10(filterPath)) {
6437
+ if (!existsSync11(filterPath)) {
6399
6438
  c4 = check(
6400
6439
  "error",
6401
6440
  "vault_sync_filter_present",
@@ -6403,7 +6442,7 @@ function vaultSyncChecks(input) {
6403
6442
  `Filter file not found at ${filterPath}`
6404
6443
  );
6405
6444
  } else {
6406
- const content = readFileSync7(filterPath, "utf8");
6445
+ const content = readFileSync8(filterPath, "utf8");
6407
6446
  const requiredExcludes = [
6408
6447
  "remotely-save/data.json",
6409
6448
  ".skillwiki/sync.lock",
@@ -6446,7 +6485,7 @@ function vaultSyncChecks(input) {
6446
6485
  );
6447
6486
  } else {
6448
6487
  try {
6449
- if (!existsSync10(snapshotPath)) {
6488
+ if (!existsSync11(snapshotPath)) {
6450
6489
  c5 = check(
6451
6490
  "error",
6452
6491
  "vault_sync_snapshot_guard",
@@ -6454,7 +6493,7 @@ function vaultSyncChecks(input) {
6454
6493
  `Snapshot script not found at ${snapshotPath}`
6455
6494
  );
6456
6495
  } else {
6457
- const content = readFileSync7(snapshotPath, "utf8");
6496
+ const content = readFileSync8(snapshotPath, "utf8");
6458
6497
  if (!content.includes("--max-delete")) {
6459
6498
  c5 = check(
6460
6499
  "error",
@@ -6512,7 +6551,7 @@ function findSkillNames(dir) {
6512
6551
  return results;
6513
6552
  }
6514
6553
  for (const entry of entries) {
6515
- if (entry.isDirectory() && existsSync10(join22(dir, entry.name, "SKILL.md"))) {
6554
+ if (entry.isDirectory() && existsSync11(join22(dir, entry.name, "SKILL.md"))) {
6516
6555
  results.push(entry.name);
6517
6556
  }
6518
6557
  }
@@ -6556,7 +6595,7 @@ async function vaultMetrics(resolvedPath) {
6556
6595
  }
6557
6596
  let logLines = 0;
6558
6597
  try {
6559
- logLines = readFileSync7(join22(resolvedPath, "log.md"), "utf8").split("\n").length;
6598
+ logLines = readFileSync8(join22(resolvedPath, "log.md"), "utf8").split("\n").length;
6560
6599
  } catch {
6561
6600
  }
6562
6601
  return [
@@ -6658,7 +6697,7 @@ async function runDoctor(input) {
6658
6697
  }
6659
6698
 
6660
6699
  // src/utils/package-info.ts
6661
- import { readFileSync as readFileSync8 } from "fs";
6700
+ import { readFileSync as readFileSync9 } from "fs";
6662
6701
  function packageJsonCandidateUrls(baseUrl = import.meta.url) {
6663
6702
  return [
6664
6703
  new URL("../package.json", baseUrl),
@@ -6668,7 +6707,7 @@ function packageJsonCandidateUrls(baseUrl = import.meta.url) {
6668
6707
  function readCliPackageJson(baseUrl = import.meta.url) {
6669
6708
  for (const url of packageJsonCandidateUrls(baseUrl)) {
6670
6709
  try {
6671
- const pkg = JSON.parse(readFileSync8(url, "utf8"));
6710
+ const pkg = JSON.parse(readFileSync9(url, "utf8"));
6672
6711
  if (typeof pkg.version === "string") {
6673
6712
  return { ...pkg, version: pkg.version };
6674
6713
  }
@@ -6824,7 +6863,7 @@ ${entries.map((e) => ` ${e.type}: [[${e.page.replace(/\.md$/, "")}]] \u2014 ${e
6824
6863
 
6825
6864
  // src/commands/observe.ts
6826
6865
  import { mkdir as mkdir6, writeFile as writeFile7 } from "fs/promises";
6827
- import { existsSync as existsSync11, statSync as statSync2 } from "fs";
6866
+ import { existsSync as existsSync12, statSync as statSync2 } from "fs";
6828
6867
  import { join as join24 } from "path";
6829
6868
  import { createHash as createHash5 } from "crypto";
6830
6869
  var ALLOWED_KINDS = /* @__PURE__ */ new Set(["note", "bug", "task", "idea", "session-log"]);
@@ -6848,7 +6887,7 @@ async function runObserve(input) {
6848
6887
  result: err("SCHEME_REJECTED", { message: "Text must not be empty" })
6849
6888
  };
6850
6889
  }
6851
- if (!existsSync11(input.vault) || !statSync2(input.vault).isDirectory()) {
6890
+ if (!existsSync12(input.vault) || !statSync2(input.vault).isDirectory()) {
6852
6891
  return {
6853
6892
  exitCode: ExitCode.VAULT_PATH_INVALID,
6854
6893
  result: err("VAULT_PATH_INVALID", { path: input.vault })
@@ -8522,7 +8561,7 @@ async function fetchQueryPreview(input) {
8522
8561
  // src/mcp/graph-html.ts
8523
8562
  import { readFile as readFile19 } from "fs/promises";
8524
8563
  import { join as join29 } from "path";
8525
- import { existsSync as existsSync12 } from "fs";
8564
+ import { existsSync as existsSync13 } from "fs";
8526
8565
  var TYPE_COLORS = {
8527
8566
  entities: "#e74c3c",
8528
8567
  concepts: "#27ae60",
@@ -8592,7 +8631,7 @@ ${nodeSvg}
8592
8631
  async function fetchGraphHtmlReport(input) {
8593
8632
  const graphPath = input.graphPath ?? join29(input.vault, ".skillwiki", "graph.json");
8594
8633
  const maxNodes = Math.min(Math.max(10, input.maxNodes ?? 120), 500);
8595
- if (!existsSync12(graphPath)) {
8634
+ if (!existsSync13(graphPath)) {
8596
8635
  return {
8597
8636
  exitCode: ExitCode.FILE_NOT_FOUND,
8598
8637
  result: err("GRAPH_MISSING", { path: graphPath, hint: "Run skillwiki.graph_build first." })
package/dist/cli.js CHANGED
@@ -75,7 +75,7 @@ import {
75
75
  triggerAutoUpdate,
76
76
  writeCache,
77
77
  writeDotenv
78
- } from "./chunk-MI4BZI7Q.js";
78
+ } from "./chunk-UCTLPX3M.js";
79
79
  import {
80
80
  normalizeDistTag
81
81
  } from "./chunk-E6UWZ3S3.js";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runSkillwikiMcpStdio
4
- } from "./chunk-MI4BZI7Q.js";
4
+ } from "./chunk-UCTLPX3M.js";
5
5
  import "./chunk-E6UWZ3S3.js";
6
6
 
7
7
  // src/mcp-entry.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skillwiki",
3
- "version": "0.9.47",
3
+ "version": "0.9.48",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "skillwiki": "dist/cli.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skillwiki",
3
- "version": "0.9.47",
3
+ "version": "0.9.48",
4
4
  "skills": "./",
5
5
  "description": "Project-aware Karpathy-style knowledge base for Claude Code: 18 prompt-only skills (wiki-*, proj-*, using-skillwiki) backed by the deterministic `skillwiki` CLI.",
6
6
  "author": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skillwiki",
3
- "version": "0.9.47",
3
+ "version": "0.9.48",
4
4
  "description": "Project-aware Karpathy-style knowledge base for Codex with 18 prompt-only skills backed by the deterministic skillwiki CLI.",
5
5
  "author": {
6
6
  "name": "karlorz",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skillwiki/skills",
3
- "version": "0.9.47",
3
+ "version": "0.9.48",
4
4
  "private": true,
5
5
  "files": [
6
6
  "wiki-*",