skillwiki 0.10.110 → 0.10.111

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/dist/{chunk-5MV5SSRM.js → chunk-5IBLXGLY.js} +5 -3
  2. package/dist/chunk-6OQLBNKR.js +250 -0
  3. package/dist/chunk-GQWCTJTU.js +55 -0
  4. package/dist/{chunk-QU2CKXM4.js → chunk-HBJLFPQP.js} +91 -199
  5. package/dist/chunk-I2J3IJB7.js +54 -0
  6. package/dist/{chunk-WPJHDRTP.js → chunk-I6IRJCUJ.js} +12 -57
  7. package/dist/{chunk-NA3TZ4JN.js → chunk-JQV5KNPT.js} +8 -6
  8. package/dist/chunk-KWEYA3OE.js +60 -0
  9. package/dist/{chunk-KX5Y3GSX.js → chunk-MRPJ7X7W.js} +5 -3
  10. package/dist/{chunk-6X6PPQNI.js → chunk-OJJBZDPR.js} +162 -296
  11. package/dist/chunk-OSL4J7GF.js +32 -0
  12. package/dist/chunk-PYPPG7RF.js +126 -0
  13. package/dist/chunk-QESNTTVY.js +50 -0
  14. package/dist/chunk-TDBUJUYH.js +109 -0
  15. package/dist/{chunk-R2DJ7IJ5.js → chunk-UIEQIJXP.js} +5 -336
  16. package/dist/chunk-X5GL2FCU.js +344 -0
  17. package/dist/chunk-ZRGZBAVS.js +98 -0
  18. package/dist/cli.js +308 -298
  19. package/dist/{index-projection-6XGESSHV.js → index-projection-2K672CBO.js} +5 -3
  20. package/dist/journal-QU5IDXQF.js +13 -0
  21. package/dist/{managed-write-preflight-JPOBVVSU.js → managed-write-preflight-GRSHQYKC.js} +7 -4
  22. package/dist/migrate-PIB4QA54.js +21 -0
  23. package/dist/ready-S7F53Q2D.js +9 -0
  24. package/dist/runtime-GLMI5OCT.js +15 -0
  25. package/dist/skillwiki-mcp.js +12 -7
  26. package/dist/sources-D2MGP246.js +10 -0
  27. package/dist/upload-HTE62TOV.js +14 -0
  28. package/dist/watcher-MHG46J3R.js +616 -0
  29. package/docs/clip-outbox.md +119 -0
  30. package/package.json +5 -1
  31. package/skills/.claude-plugin/plugin.json +1 -1
  32. package/skills/.codex-plugin/plugin.json +1 -1
  33. package/skills/.cursor-plugin/plugin.json +1 -1
  34. package/skills/package.json +1 -1
  35. package/templates/launchd/com.karlchow.skillwiki-clip-outbox.plist +12 -13
  36. package/dist/sources-CLOF5VAT.js +0 -9
@@ -1,4 +1,17 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ applySourceCompileClaim,
4
+ applySourceCompilePublished,
5
+ applySourceCompileRelease,
6
+ applySourceReview,
7
+ listCompileStatus,
8
+ listSourceReviews,
9
+ planSourceCompileClaim,
10
+ planSourceCompilePublished,
11
+ planSourceCompileRelease,
12
+ planSourceReview,
13
+ runSourcesPending
14
+ } from "./chunk-JQV5KNPT.js";
2
15
  import {
3
16
  latestFromCache,
4
17
  semverGt
@@ -6,9 +19,8 @@ import {
6
19
  import {
7
20
  renderRootIndex,
8
21
  writeRootIndexProjection
9
- } from "./chunk-KX5Y3GSX.js";
22
+ } from "./chunk-MRPJ7X7W.js";
10
23
  import {
11
- CONFIG_KEYS,
12
24
  VAULT_HYGIENE_GENERATED_COMMIT_PATHS,
13
25
  VAULT_HYGIENE_GITIGNORE_PATTERNS,
14
26
  VAULT_SYNC_FILTER_REQUIRED_EXCLUDES,
@@ -18,20 +30,16 @@ import {
18
30
  communityCohesion,
19
31
  git,
20
32
  hasUnmergedPaths,
21
- isValidWikiProfileKey,
22
33
  listReviewRequiredOps,
23
34
  loadFleetManifestAndHost,
24
35
  louvain,
25
36
  missingIgnorePatterns,
26
- parseDotenvFile,
27
- parseDotenvText,
28
37
  probeGithubReachability,
29
38
  probeS3Reachability,
30
39
  probeSnapshotterSsh,
31
40
  releaseOwnedSyncLock,
32
41
  resolveConfiguredSnapshotWorktree,
33
42
  resolveRuntimePath,
34
- resolveSkillwikiHome,
35
43
  resolveVaultSyncPullHelper,
36
44
  resolveWikiS3Remote,
37
45
  runLint,
@@ -39,32 +47,47 @@ import {
39
47
  runStale,
40
48
  satelliteGateFromFleetLoad,
41
49
  snapshotterAliasForLocalHost,
42
- toUndirectedWeighted,
43
- writeDotenv
44
- } from "./chunk-QU2CKXM4.js";
50
+ toUndirectedWeighted
51
+ } from "./chunk-HBJLFPQP.js";
52
+ import {
53
+ eventPathFor,
54
+ writeLogEvent
55
+ } from "./chunk-5IBLXGLY.js";
45
56
  import {
46
- atomicWriteText,
47
57
  prepareTypedPage
48
- } from "./chunk-WPJHDRTP.js";
58
+ } from "./chunk-I6IRJCUJ.js";
49
59
  import {
50
- applySourceCompileClaim,
51
- applySourceCompilePublished,
52
- applySourceCompileRelease,
53
- applySourceReview,
54
- listCompileStatus,
55
- listSourceReviews,
56
- planSourceCompileClaim,
57
- planSourceCompilePublished,
58
- planSourceCompileRelease,
59
- planSourceReview,
60
- runSourcesPending
61
- } from "./chunk-NA3TZ4JN.js";
60
+ extractFrontmatter,
61
+ readPage,
62
+ redactSensitiveContent,
63
+ resolveReadOnlyVaultRoot,
64
+ scanSensitiveContent,
65
+ scanVault,
66
+ splitFrontmatter
67
+ } from "./chunk-X5GL2FCU.js";
62
68
  import {
63
- eventPathFor,
64
- writeLogEvent
65
- } from "./chunk-5MV5SSRM.js";
69
+ xml
70
+ } from "./chunk-TDBUJUYH.js";
71
+ import {
72
+ CLIP_NOT_CONFIGURED,
73
+ PRODUCTION_WATCHER_LABEL,
74
+ RETIRED_WATCHER_LABELS,
75
+ conditionalCreateProven,
76
+ loadClipCredentials,
77
+ loadClipOutboxConfig
78
+ } from "./chunk-6OQLBNKR.js";
79
+ import {
80
+ CONFIG_KEYS,
81
+ isValidWikiProfileKey,
82
+ parseDotenvFile,
83
+ parseDotenvText,
84
+ resolveSkillwikiHome,
85
+ writeDotenv
86
+ } from "./chunk-PYPPG7RF.js";
87
+ import {
88
+ atomicWriteText
89
+ } from "./chunk-GQWCTJTU.js";
66
90
  import {
67
- CLIP_OUTBOX_DEFAULTS,
68
91
  CompoundSchema,
69
92
  ExitCode,
70
93
  MetaSchema,
@@ -73,20 +96,13 @@ import {
73
96
  WorkItemSchema,
74
97
  detectSchema,
75
98
  err,
76
- extractFrontmatter,
77
99
  isClipOutboxKey,
78
100
  isVaultSyncKey,
79
101
  ok,
80
102
  parseClipOutboxKeyValue,
81
103
  parseVaultSyncKeyValue,
82
- readPage,
83
- redactSensitiveContent,
84
- resolveReadOnlyVaultRoot,
85
- scanSensitiveContent,
86
- scanVault,
87
- splitFrontmatter,
88
104
  systemdPropertyFor
89
- } from "./chunk-R2DJ7IJ5.js";
105
+ } from "./chunk-UIEQIJXP.js";
90
106
 
91
107
  // src/commands/log-append.ts
92
108
  import { readFile, stat } from "fs/promises";
@@ -1139,7 +1155,7 @@ function isMcpOnlyLeaf(input) {
1139
1155
  }
1140
1156
 
1141
1157
  // src/doctor/runner.ts
1142
- import { existsSync as existsSync20 } from "fs";
1158
+ import { existsSync as existsSync19 } from "fs";
1143
1159
 
1144
1160
  // src/doctor/probes/environment.ts
1145
1161
  import { existsSync as existsSync4, lstatSync, readlinkSync } from "fs";
@@ -4443,182 +4459,10 @@ var mcpHandshakeProbe = {
4443
4459
  };
4444
4460
 
4445
4461
  // src/doctor/probes/clip-outbox.ts
4446
- import { existsSync as existsSync19 } from "fs";
4462
+ import { existsSync as existsSync18, readFileSync as readFileSync12 } from "fs";
4447
4463
  import { execSync as execSync7 } from "child_process";
4448
4464
  import { platform as platform6 } from "os";
4449
- import { join as join23 } from "path";
4450
-
4451
- // src/utils/clip-outbox-config.ts
4452
- import { realpathSync, statSync as statSync3, existsSync as existsSync18, accessSync, constants } from "fs";
4453
- import { homedir } from "os";
4454
- import { isAbsolute, join as join22, resolve as resolve3, sep as sep2 } from "path";
4455
- var CLIP_NOT_CONFIGURED = "clip channel not configured";
4456
- var PRODUCTION_WATCHER_LABEL = CLIP_OUTBOX_DEFAULTS.watcher_label;
4457
- var RETIRED_WATCHER_LABELS = [
4458
- "com.karlchow.wiki-dev-outbox",
4459
- "com.karlchow.wiki-dev-sse",
4460
- "com.karlchow.wiki-dev-hourly",
4461
- "com.karlchow.skillwiki-note-outbox"
4462
- ];
4463
- function expandUserPath(raw, home) {
4464
- if (raw === "~") return home;
4465
- if (raw.startsWith("~/")) return resolve3(home, raw.slice(2));
4466
- return raw;
4467
- }
4468
- function canonicalPath(raw, home) {
4469
- const expanded = expandUserPath(raw.trim(), home);
4470
- if (expanded.includes("\0")) return { ok: false, message: "path contains NUL" };
4471
- if (expanded.includes("://") || expanded.includes("@")) {
4472
- return { ok: false, message: "path must not include URL credentials" };
4473
- }
4474
- if (!isAbsolute(expanded)) return { ok: false, message: "must be an absolute path" };
4475
- try {
4476
- const real = existsSync18(expanded) ? realpathSync(expanded) : resolve3(expanded);
4477
- if (real.split(sep2).some((seg) => seg === "..")) {
4478
- return { ok: false, message: "path must not contain traversal" };
4479
- }
4480
- return { ok: true, path: real };
4481
- } catch (error) {
4482
- return { ok: false, message: error instanceof Error ? error.message : "invalid path" };
4483
- }
4484
- }
4485
- function nestedOrEqual(a, b) {
4486
- if (a === b) return true;
4487
- const prefixA = a.endsWith(sep2) ? a : a + sep2;
4488
- const prefixB = b.endsWith(sep2) ? b : b + sep2;
4489
- return prefixA.startsWith(prefixB) || prefixB.startsWith(prefixA);
4490
- }
4491
- function intField(value, fallback) {
4492
- return Number(value && value.length > 0 ? value : fallback);
4493
- }
4494
- function requireWritableDir(path, label) {
4495
- try {
4496
- const st = statSync3(path);
4497
- if (!st.isDirectory()) return `${label} is not a directory`;
4498
- accessSync(path, constants.W_OK);
4499
- return void 0;
4500
- } catch {
4501
- return `${label} is missing or not writable`;
4502
- }
4503
- }
4504
- function resolveClipOutboxConfig(map, home) {
4505
- const present = Object.keys(map).filter(isClipOutboxKey);
4506
- for (const key of present) {
4507
- const parsed = parseClipOutboxKeyValue(key, map[key] ?? "");
4508
- if (!parsed.ok) return { ok: false, message: `${key}: ${parsed.message}` };
4509
- }
4510
- const enabled = (map["clip_outbox.enabled"] ?? CLIP_OUTBOX_DEFAULTS.enabled) === "true";
4511
- if (!enabled) {
4512
- return { ok: true, enabled: false };
4513
- }
4514
- const required = [
4515
- "clip_outbox.root",
4516
- "clip_outbox.state_root",
4517
- "clip_outbox.mirror_root",
4518
- "clip_outbox.ready_url",
4519
- "clip_outbox.s3_credential_ref",
4520
- "clip_outbox.ready_credential_ref"
4521
- ];
4522
- for (const key of required) {
4523
- if (!map[key]) return { ok: false, message: `${key} is required when clip_outbox.enabled=true` };
4524
- }
4525
- const d8Absent = map["clip_outbox.d8_note_absent"] === "true";
4526
- const d8RootRaw = map["clip_outbox.d8_note_root"];
4527
- if (d8Absent && d8RootRaw) {
4528
- return { ok: false, message: "clip_outbox.d8_note_root and clip_outbox.d8_note_absent cannot both be set" };
4529
- }
4530
- if (!d8Absent && !d8RootRaw) {
4531
- return { ok: false, message: "clip_outbox.d8_note_root or clip_outbox.d8_note_absent=true is required when enabled" };
4532
- }
4533
- const root = canonicalPath(map["clip_outbox.root"], home);
4534
- const stateRoot = canonicalPath(map["clip_outbox.state_root"], home);
4535
- const mirrorRoot = canonicalPath(map["clip_outbox.mirror_root"], home);
4536
- if (!root.ok) return { ok: false, message: `clip_outbox.root: ${root.message}` };
4537
- if (!stateRoot.ok) return { ok: false, message: `clip_outbox.state_root: ${stateRoot.message}` };
4538
- if (!mirrorRoot.ok) return { ok: false, message: `clip_outbox.mirror_root: ${mirrorRoot.message}` };
4539
- let d8NoteRoot = null;
4540
- if (d8RootRaw) {
4541
- const d8 = canonicalPath(d8RootRaw, home);
4542
- if (!d8.ok) return { ok: false, message: `clip_outbox.d8_note_root: ${d8.message}` };
4543
- d8NoteRoot = d8.path;
4544
- }
4545
- if (nestedOrEqual(root.path, mirrorRoot.path)) {
4546
- return { ok: false, message: "clip_outbox.root must be outside the frozen mirror" };
4547
- }
4548
- if (nestedOrEqual(root.path, stateRoot.path) || nestedOrEqual(stateRoot.path, mirrorRoot.path)) {
4549
- return { ok: false, message: "clip_outbox.state_root must be disjoint from outbox and mirror" };
4550
- }
4551
- if (d8NoteRoot && (nestedOrEqual(root.path, d8NoteRoot) || nestedOrEqual(stateRoot.path, d8NoteRoot))) {
4552
- return { ok: false, message: "clip outbox must not equal or nest the D8 note outbox" };
4553
- }
4554
- const rootErr = requireWritableDir(root.path, "clip_outbox.root");
4555
- if (rootErr) return { ok: false, message: rootErr };
4556
- const stateErr = requireWritableDir(stateRoot.path, "clip_outbox.state_root");
4557
- if (stateErr) {
4558
- if (existsSync18(stateRoot.path)) return { ok: false, message: stateErr };
4559
- const parentErr = requireWritableDir(resolve3(stateRoot.path, ".."), "clip_outbox.state_root parent");
4560
- if (parentErr) return { ok: false, message: stateErr };
4561
- }
4562
- if (!existsSync18(mirrorRoot.path)) {
4563
- return { ok: false, message: "clip_outbox.mirror_root does not exist" };
4564
- }
4565
- const vaultId = map["clip_outbox.vault_id"] ?? CLIP_OUTBOX_DEFAULTS.vault_id;
4566
- if (vaultId !== "central") return { ok: false, message: "clip_outbox.vault_id must be central" };
4567
- const destination = map["clip_outbox.destination"] ?? CLIP_OUTBOX_DEFAULTS.destination;
4568
- if (destination !== CLIP_OUTBOX_DEFAULTS.destination) {
4569
- return { ok: false, message: "clip_outbox.destination must be seaweed-wiki:cloud/wiki" };
4570
- }
4571
- const mode = map["clip_outbox.mode"] ?? CLIP_OUTBOX_DEFAULTS.mode;
4572
- if (mode !== "event-watch") return { ok: false, message: "clip_outbox.mode must be event-watch" };
4573
- const watcherLabel = map["clip_outbox.watcher_label"] ?? CLIP_OUTBOX_DEFAULTS.watcher_label;
4574
- if (watcherLabel !== PRODUCTION_WATCHER_LABEL) {
4575
- return { ok: false, message: "clip_outbox.watcher_label must be the production clip watcher" };
4576
- }
4577
- const imageTypes = (map["clip_outbox.image_types"] ?? CLIP_OUTBOX_DEFAULTS.image_types).split(",").map((p) => p.trim()).filter(Boolean);
4578
- return {
4579
- ok: true,
4580
- enabled: true,
4581
- config: {
4582
- enabled: true,
4583
- root: root.path,
4584
- stateRoot: stateRoot.path,
4585
- mirrorRoot: mirrorRoot.path,
4586
- d8NoteRoot,
4587
- d8NoteAbsent: d8Absent,
4588
- vaultId: "central",
4589
- allowedPrefixes: ["raw/articles", "raw/assets"],
4590
- destination: "seaweed-wiki:cloud/wiki",
4591
- mode: "event-watch",
4592
- pollFallbackEnabled: (map["clip_outbox.poll_fallback_enabled"] ?? CLIP_OUTBOX_DEFAULTS.poll_fallback_enabled) === "true",
4593
- reconcileSeconds: intField(map["clip_outbox.reconcile_seconds"], CLIP_OUTBOX_DEFAULTS.reconcile_seconds),
4594
- debounceMs: intField(map["clip_outbox.debounce_ms"], CLIP_OUTBOX_DEFAULTS.debounce_ms),
4595
- stableHashMs: intField(map["clip_outbox.stable_hash_ms"], CLIP_OUTBOX_DEFAULTS.stable_hash_ms),
4596
- maxArticleBytes: intField(map["clip_outbox.max_article_bytes"], CLIP_OUTBOX_DEFAULTS.max_article_bytes),
4597
- maxImages: intField(map["clip_outbox.max_images"], CLIP_OUTBOX_DEFAULTS.max_images),
4598
- maxImageBytes: intField(map["clip_outbox.max_image_bytes"], CLIP_OUTBOX_DEFAULTS.max_image_bytes),
4599
- maxBundleBytes: intField(map["clip_outbox.max_bundle_bytes"], CLIP_OUTBOX_DEFAULTS.max_bundle_bytes),
4600
- maxPixels: intField(map["clip_outbox.max_pixels"], CLIP_OUTBOX_DEFAULTS.max_pixels),
4601
- downloadConcurrency: intField(map["clip_outbox.download_concurrency"], CLIP_OUTBOX_DEFAULTS.download_concurrency),
4602
- imageTypes,
4603
- maxRedirects: intField(map["clip_outbox.max_redirects"], CLIP_OUTBOX_DEFAULTS.max_redirects),
4604
- requestTimeoutMs: intField(map["clip_outbox.request_timeout_ms"], CLIP_OUTBOX_DEFAULTS.request_timeout_ms),
4605
- localizeTimeoutMs: intField(map["clip_outbox.localize_timeout_ms"], CLIP_OUTBOX_DEFAULTS.localize_timeout_ms),
4606
- readyUrl: map["clip_outbox.ready_url"],
4607
- s3CredentialRef: map["clip_outbox.s3_credential_ref"],
4608
- readyCredentialRef: map["clip_outbox.ready_credential_ref"],
4609
- watcherLabel: PRODUCTION_WATCHER_LABEL
4610
- }
4611
- };
4612
- }
4613
- function clipOutboxConfigPath(home) {
4614
- return join22(resolveSkillwikiHome(home), ".skillwiki", ".env");
4615
- }
4616
- async function loadClipOutboxConfig(home) {
4617
- const map = await parseDotenvFile(clipOutboxConfigPath(home));
4618
- return resolveClipOutboxConfig(map, home || homedir());
4619
- }
4620
-
4621
- // src/doctor/probes/clip-outbox.ts
4465
+ import { join as join22 } from "path";
4622
4466
  var CLIP_CHECK_IDS = [
4623
4467
  "clip_config",
4624
4468
  "clip_frozen_mirror",
@@ -4669,7 +4513,7 @@ function launchdLoaded(label) {
4669
4513
  return false;
4670
4514
  }
4671
4515
  }
4672
- function watcherStatus(env, label) {
4516
+ function watcherStatus(env, label, home, root) {
4673
4517
  const fixture = env.CLIP_WATCHER_FIXTURE;
4674
4518
  if (fixture === "loaded-enabled") return { loaded: true, enabled: true, kind: "production" };
4675
4519
  if (fixture === "stopped") return { loaded: false, enabled: false, kind: "production" };
@@ -4681,8 +4525,17 @@ function watcherStatus(env, label) {
4681
4525
  if (!launchdLoaded(label)) {
4682
4526
  return { loaded: false, enabled: false, kind: "unknown" };
4683
4527
  }
4684
- const plist = join23(process.env.HOME ?? "", "Library", "LaunchAgents", `${label}.plist`);
4685
- return { loaded: true, enabled: existsSync19(plist), kind: "production" };
4528
+ const plist = join22(home, "Library", "LaunchAgents", `${label}.plist`);
4529
+ try {
4530
+ const text = readFileSync12(plist, "utf8");
4531
+ const xmlRoot = xml(root);
4532
+ const matchesRoot = text.includes(`<key>WatchPaths</key><array><string>${xmlRoot}</string></array>`);
4533
+ const disabled = execSync7(`launchctl print-disabled gui/${process.getuid()}`, { encoding: "utf8", timeout: 2e3, stdio: ["ignore", "pipe", "ignore"] });
4534
+ const explicitlyDisabled = disabled.split("\n").some((line) => line.includes(`"${label}"`) && line.includes("true"));
4535
+ return { loaded: true, enabled: matchesRoot && !explicitlyDisabled, kind: "production" };
4536
+ } catch {
4537
+ return { loaded: true, enabled: false, kind: "unknown" };
4538
+ }
4686
4539
  }
4687
4540
  function pushLoaded(env) {
4688
4541
  if (env.CLIP_PUSH_FIXTURE === "loaded") return true;
@@ -4722,13 +4575,25 @@ var clipOutboxProbe = {
4722
4575
  return notConfigured();
4723
4576
  }
4724
4577
  const cfg = resolved.config;
4725
- const frozen = existsSync19(join23(cfg.mirrorRoot, ".WIKI_GIT_FROZEN"));
4578
+ const frozen = existsSync18(join22(cfg.mirrorRoot, ".WIKI_GIT_FROZEN"));
4726
4579
  const pushOn = ctx.vsConfig.pushEnabled !== false;
4727
4580
  const pushIsLoaded = pushLoaded(env);
4728
- const watch = watcherStatus(env, cfg.watcherLabel);
4729
- const s3Creds = credentialPresent(env, cfg.s3CredentialRef);
4730
- const readyCreds = credentialPresent(env, cfg.readyCredentialRef);
4731
- const condCreate = conditionalCreateEvidence(env);
4581
+ const watch = watcherStatus(env, cfg.watcherLabel, ctx.input.home, cfg.root);
4582
+ let s3Creds = credentialPresent(env, cfg.s3CredentialRef);
4583
+ let readyCreds = credentialPresent(env, cfg.readyCredentialRef);
4584
+ let condCreate = conditionalCreateEvidence(env);
4585
+ if (!env.CLIP_CREDENTIAL_FIXTURE) {
4586
+ try {
4587
+ const credentials = await loadClipCredentials(ctx.input.home, cfg, env);
4588
+ s3Creds = true;
4589
+ readyCreds = true;
4590
+ condCreate = await conditionalCreateProven(cfg, credentials.s3.endpoint);
4591
+ } catch {
4592
+ s3Creds = false;
4593
+ readyCreds = false;
4594
+ condCreate = false;
4595
+ }
4596
+ }
4732
4597
  const listener = listenerOk(env);
4733
4598
  return [
4734
4599
  check("pass", "clip_config", clipLabel("clip_config"), "clip_outbox.enabled=true; schema valid"),
@@ -4769,7 +4634,7 @@ function resolveSnapshotGitWorktree(home) {
4769
4634
  const configured = resolveConfiguredSnapshotWorktree(home);
4770
4635
  if (configured) return configured;
4771
4636
  const defaultPath = "/root/wiki-git";
4772
- return existsSync20(defaultPath) ? defaultPath : void 0;
4637
+ return existsSync19(defaultPath) ? defaultPath : void 0;
4773
4638
  }
4774
4639
  var DoctorRunner = class {
4775
4640
  probes;
@@ -4849,6 +4714,9 @@ var DoctorRunner = class {
4849
4714
  if (summary.info > 0) summaryParts.push(`${summary.info} info`);
4850
4715
  summaryParts.push(`${summary.warn} warn`, `${summary.error} error`);
4851
4716
  lines.push(summaryParts.join(" \xB7 "));
4717
+ if (checks.some((c) => c.id === "clip_config" && c.detail === "clip channel not configured")) {
4718
+ lines.push("Clip setup is attended: skillwiki clip-outbox install-or-migrate refreshes the packaged plist; prove SeaweedFS conditional-create before enabling/loading the channel.");
4719
+ }
4852
4720
  const humanHint = redactMcpSecret(lines.join("\n"), auth.token);
4853
4721
  return { exitCode, result: ok({ checks, summary, humanHint }) };
4854
4722
  }
@@ -4858,7 +4726,7 @@ async function runDoctor(input) {
4858
4726
  }
4859
4727
 
4860
4728
  // src/utils/package-info.ts
4861
- import { readFileSync as readFileSync12 } from "fs";
4729
+ import { readFileSync as readFileSync13 } from "fs";
4862
4730
  function packageJsonCandidateUrls(baseUrl = import.meta.url) {
4863
4731
  return [
4864
4732
  new URL("../package.json", baseUrl),
@@ -4868,7 +4736,7 @@ function packageJsonCandidateUrls(baseUrl = import.meta.url) {
4868
4736
  function readCliPackageJson(baseUrl = import.meta.url) {
4869
4737
  for (const url of packageJsonCandidateUrls(baseUrl)) {
4870
4738
  try {
4871
- const pkg = JSON.parse(readFileSync12(url, "utf8"));
4739
+ const pkg = JSON.parse(readFileSync13(url, "utf8"));
4872
4740
  if (typeof pkg.version === "string") {
4873
4741
  return { ...pkg, version: pkg.version };
4874
4742
  }
@@ -4880,8 +4748,8 @@ function readCliPackageJson(baseUrl = import.meta.url) {
4880
4748
 
4881
4749
  // src/utils/vault-write-gates.ts
4882
4750
  import { execFileSync } from "child_process";
4883
- import { existsSync as existsSync21, readdirSync as readdirSync7, readFileSync as readFileSync13, statSync as statSync4 } from "fs";
4884
- import { join as join24, relative as relative2 } from "path";
4751
+ import { existsSync as existsSync20, readdirSync as readdirSync7, readFileSync as readFileSync14, statSync as statSync3 } from "fs";
4752
+ import { join as join23, relative as relative2 } from "path";
4885
4753
  var DEFAULT_DIRTY_VOLUME_THRESHOLD = 50;
4886
4754
  var DEFAULT_CAPTURE_BUDGET = 20;
4887
4755
  var DEFAULT_NO_DECISION_STREAK = 3;
@@ -4937,7 +4805,7 @@ function isEventLedgerPath(rel) {
4937
4805
  return n === "meta/log-events" || n.startsWith("meta/log-events/");
4938
4806
  }
4939
4807
  function countEventLedgerFiles(vault) {
4940
- return listFilesRecursive(join24(vault, "meta", "log-events")).length;
4808
+ return listFilesRecursive(join23(vault, "meta", "log-events")).length;
4941
4809
  }
4942
4810
  function measureDirtyVolume(vault) {
4943
4811
  const empty = (extra = {}) => ({
@@ -4953,7 +4821,7 @@ function measureDirtyVolume(vault) {
4953
4821
  is_git_repo: false,
4954
4822
  ...extra
4955
4823
  });
4956
- if (!existsSync21(vault) || !statSync4(vault).isDirectory()) {
4824
+ if (!existsSync20(vault) || !statSync3(vault).isDirectory()) {
4957
4825
  return empty();
4958
4826
  }
4959
4827
  const gitDir = git(vault, ["rev-parse", "--absolute-git-dir"]);
@@ -4997,8 +4865,8 @@ function measureDirtyVolume(vault) {
4997
4865
  if (!rel) continue;
4998
4866
  if (code === "??") {
4999
4867
  untracked += 1;
5000
- const abs = join24(vault, rel);
5001
- if (existsSync21(abs) && statSync4(abs).isDirectory()) {
4868
+ const abs = join23(vault, rel);
4869
+ if (existsSync20(abs) && statSync3(abs).isDirectory()) {
5002
4870
  const files = listFilesRecursive(abs);
5003
4871
  expanded += files.length;
5004
4872
  addBucket(rel, files.length);
@@ -5041,9 +4909,9 @@ function listFilesRecursive(dir) {
5041
4909
  }
5042
4910
  for (const name of entries) {
5043
4911
  if (name === ".git") continue;
5044
- const p = join24(dir, name);
4912
+ const p = join23(dir, name);
5045
4913
  try {
5046
- const st = statSync4(p);
4914
+ const st = statSync3(p);
5047
4915
  if (st.isDirectory()) out.push(...listFilesRecursive(p));
5048
4916
  else if (st.isFile()) out.push(p);
5049
4917
  } catch {
@@ -5136,7 +5004,7 @@ var CAPTURE_HYGIENE_CONTRACT = `After each productive cycle (or when daily captu
5136
5004
  function listProjectDayCaptures(vault, project, day) {
5137
5005
  const found = [];
5138
5006
  const slug = project.replace(/^\[\[/, "").replace(/\]\]$/, "").trim();
5139
- if (!slug || !existsSync21(vault)) return found;
5007
+ if (!slug || !existsSync20(vault)) return found;
5140
5008
  const consider = (abs, rel) => {
5141
5009
  if (!rel.endsWith(".md")) return;
5142
5010
  const base = rel.split(/[/\\]/).pop() ?? "";
@@ -5153,7 +5021,7 @@ function listProjectDayCaptures(vault, project, day) {
5153
5021
  }
5154
5022
  if (norm.startsWith("raw/transcripts/")) {
5155
5023
  try {
5156
- const body = readFileSync13(abs, "utf8");
5024
+ const body = readFileSync14(abs, "utf8");
5157
5025
  if (body.includes(`project: ${slug}`) || body.includes(`project: "[[${slug}]]"`) || body.includes(`project: [[${slug}]]`)) {
5158
5026
  found.push(norm);
5159
5027
  } else if (base.includes(slug)) {
@@ -5164,7 +5032,7 @@ function listProjectDayCaptures(vault, project, day) {
5164
5032
  }
5165
5033
  };
5166
5034
  const walk = (dir, relBase) => {
5167
- if (!existsSync21(dir)) return;
5035
+ if (!existsSync20(dir)) return;
5168
5036
  let entries;
5169
5037
  try {
5170
5038
  entries = readdirSync7(dir);
@@ -5172,27 +5040,27 @@ function listProjectDayCaptures(vault, project, day) {
5172
5040
  return;
5173
5041
  }
5174
5042
  for (const name of entries) {
5175
- const abs = join24(dir, name);
5043
+ const abs = join23(dir, name);
5176
5044
  const rel = relBase ? `${relBase}/${name}` : name;
5177
5045
  try {
5178
- const st = statSync4(abs);
5046
+ const st = statSync3(abs);
5179
5047
  if (st.isDirectory()) walk(abs, rel);
5180
5048
  else if (st.isFile()) consider(abs, rel);
5181
5049
  } catch {
5182
5050
  }
5183
5051
  }
5184
5052
  };
5185
- walk(join24(vault, "raw", "transcripts"), "raw/transcripts");
5186
- walk(join24(vault, "projects", slug, "raw", "transcripts"), `projects/${slug}/raw/transcripts`);
5187
- walk(join24(vault, "projects", slug, "requirements"), `projects/${slug}/requirements`);
5188
- const workRoot = join24(vault, "projects", slug, "work");
5189
- if (existsSync21(workRoot)) {
5053
+ walk(join23(vault, "raw", "transcripts"), "raw/transcripts");
5054
+ walk(join23(vault, "projects", slug, "raw", "transcripts"), `projects/${slug}/raw/transcripts`);
5055
+ walk(join23(vault, "projects", slug, "requirements"), `projects/${slug}/requirements`);
5056
+ const workRoot = join23(vault, "projects", slug, "work");
5057
+ if (existsSync20(workRoot)) {
5190
5058
  try {
5191
5059
  for (const name of readdirSync7(workRoot)) {
5192
5060
  if (!name.startsWith(day)) continue;
5193
5061
  if (!/investigate|pilot-q|research|cycle|dev-loop/.test(name)) continue;
5194
- const abs = join24(workRoot, name);
5195
- if (statSync4(abs).isDirectory()) {
5062
+ const abs = join23(workRoot, name);
5063
+ if (statSync3(abs).isDirectory()) {
5196
5064
  for (const f of listFilesRecursive(abs)) {
5197
5065
  const rel = relative2(vault, f).replace(/\\/g, "/");
5198
5066
  if (rel.endsWith(".md")) found.push(rel);
@@ -5236,7 +5104,7 @@ function evaluateCaptureBudget(input) {
5236
5104
  return { allowed: true, reason: "under_budget", report };
5237
5105
  }
5238
5106
  function runWritePreflight(input) {
5239
- if (!input.vault || !existsSync21(input.vault)) {
5107
+ if (!input.vault || !existsSync20(input.vault)) {
5240
5108
  return err(GateError.VAULT_PATH_INVALID, { path: input.vault });
5241
5109
  }
5242
5110
  const want = new Set(input.checks ?? ["all"]);
@@ -5296,8 +5164,8 @@ function runWritePreflight(input) {
5296
5164
 
5297
5165
  // src/commands/observe.ts
5298
5166
  import { mkdir as mkdir3, writeFile as writeFile3 } from "fs/promises";
5299
- import { existsSync as existsSync22, statSync as statSync5 } from "fs";
5300
- import { join as join25 } from "path";
5167
+ import { existsSync as existsSync21, statSync as statSync4 } from "fs";
5168
+ import { join as join24 } from "path";
5301
5169
  import { createHash as createHash2 } from "crypto";
5302
5170
  var ALLOWED_KINDS = /* @__PURE__ */ new Set(["note", "bug", "task", "idea", "session-log"]);
5303
5171
  function slugify(text) {
@@ -5320,7 +5188,7 @@ async function runObserve(input) {
5320
5188
  result: err("SCHEME_REJECTED", { message: "Text must not be empty" })
5321
5189
  };
5322
5190
  }
5323
- if (!existsSync22(input.vault) || !statSync5(input.vault).isDirectory()) {
5191
+ if (!existsSync21(input.vault) || !statSync4(input.vault).isDirectory()) {
5324
5192
  return {
5325
5193
  exitCode: ExitCode.VAULT_PATH_INVALID,
5326
5194
  result: err("VAULT_PATH_INVALID", { path: input.vault })
@@ -5346,7 +5214,7 @@ async function runObserve(input) {
5346
5214
  };
5347
5215
  }
5348
5216
  }
5349
- const transcriptsDir = join25(input.vault, "raw", "transcripts");
5217
+ const transcriptsDir = join24(input.vault, "raw", "transcripts");
5350
5218
  try {
5351
5219
  await mkdir3(transcriptsDir, { recursive: true });
5352
5220
  } catch {
@@ -5358,7 +5226,7 @@ async function runObserve(input) {
5358
5226
  const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
5359
5227
  const slug = slugify(input.text);
5360
5228
  const fileName = `${today}-observation-${slug}.md`;
5361
- const filePath = join25(transcriptsDir, fileName);
5229
+ const filePath = join24(transcriptsDir, fileName);
5362
5230
  const body = `
5363
5231
  ${input.text.trim()}
5364
5232
  `;
@@ -5400,7 +5268,7 @@ ${input.text.trim()}
5400
5268
  // src/commands/memory.ts
5401
5269
  import { createHash as createHash3 } from "crypto";
5402
5270
  import { mkdir as mkdir4, readFile as readFile7, readdir as readdir2, stat as stat2, writeFile as writeFile4 } from "fs/promises";
5403
- import { basename as basename2, extname, join as join26, relative as relative3, sep as sep3 } from "path";
5271
+ import { basename as basename2, extname, join as join25, relative as relative3, sep as sep2 } from "path";
5404
5272
 
5405
5273
  // src/utils/memory-authority.ts
5406
5274
  var TIER_RANK = {
@@ -5519,8 +5387,8 @@ async function runMemoryIndex(input) {
5519
5387
  }
5520
5388
  const generatedAt = (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
5521
5389
  const relCachePath = memoryCacheRelPath(input.project);
5522
- const absCachePath = join26(input.vault, relCachePath);
5523
- await mkdir4(join26(input.vault, ".skillwiki", "memory", input.project), { recursive: true });
5390
+ const absCachePath = join25(input.vault, relCachePath);
5391
+ await mkdir4(join25(input.vault, ".skillwiki", "memory", input.project), { recursive: true });
5524
5392
  await writeFile4(absCachePath, `${JSON.stringify({
5525
5393
  generated_at: generatedAt,
5526
5394
  project: input.project,
@@ -5712,7 +5580,7 @@ async function buildMemoryIndexState(pages, project) {
5712
5580
  }
5713
5581
  async function checkMemoryIndex(vault, project, current) {
5714
5582
  const relCachePath = memoryCacheRelPath(project);
5715
- const cacheText = await readIfExists(join26(vault, relCachePath));
5583
+ const cacheText = await readIfExists(join25(vault, relCachePath));
5716
5584
  if (!cacheText) {
5717
5585
  return {
5718
5586
  ok: true,
@@ -6121,7 +5989,7 @@ async function walkImportFiles(dir, out) {
6121
5989
  const entries = await readdir2(dir, { withFileTypes: true });
6122
5990
  for (const entry of entries) {
6123
5991
  if (entry.name === ".git" || entry.name === "node_modules") continue;
6124
- const path = join26(dir, entry.name);
5992
+ const path = join25(dir, entry.name);
6125
5993
  if (entry.isDirectory()) {
6126
5994
  await walkImportFiles(path, out);
6127
5995
  } else if (entry.isFile() && isImportCandidate(path)) {
@@ -6171,7 +6039,7 @@ async function buildImportEntry(file, sourceRoot, project, today, maxBytes) {
6171
6039
  const redacted = redactSensitiveContent(extracted, { file });
6172
6040
  const privacy = redacted.findings.length > 0 ? "sensitive" : "local";
6173
6041
  const sourceSlug = slugify2(basename2(file, extname(file)));
6174
- const relSource = relative3(sourceRoot, file).split(sep3).join("/");
6042
+ const relSource = relative3(sourceRoot, file).split(sep2).join("/");
6175
6043
  const entry = {
6176
6044
  ...baseEntry,
6177
6045
  status: "ready",
@@ -6188,8 +6056,8 @@ async function writeImportCapture(vault, entry, today) {
6188
6056
  const content = hiddenString(entry, "__content");
6189
6057
  const project = hiddenString(entry, "__project");
6190
6058
  const relPath = await availableImportPath(vault, entry.proposed_path);
6191
- const absPath = join26(vault, relPath);
6192
- await mkdir4(join26(vault, "raw", "transcripts"), { recursive: true });
6059
+ const absPath = join25(vault, relPath);
6060
+ await mkdir4(join25(vault, "raw", "transcripts"), { recursive: true });
6193
6061
  await writeFile4(absPath, renderImportCapture(entry, content, project, today), "utf8");
6194
6062
  const validation = await runValidate({ file: absPath });
6195
6063
  return {
@@ -6205,7 +6073,7 @@ async function availableImportPath(vault, proposed) {
6205
6073
  const stem = proposed.slice(0, -ext.length);
6206
6074
  let candidate = proposed;
6207
6075
  let i = 2;
6208
- while (await readIfExists(join26(vault, candidate))) {
6076
+ while (await readIfExists(join25(vault, candidate))) {
6209
6077
  candidate = `${stem}-${i}${ext}`;
6210
6078
  i++;
6211
6079
  }
@@ -6243,7 +6111,7 @@ function hiddenString(entry, key) {
6243
6111
  return entry[key] ?? "";
6244
6112
  }
6245
6113
  function classifyImportSource(file) {
6246
- const rel = file.split(sep3).join("/");
6114
+ const rel = file.split(sep2).join("/");
6247
6115
  const name = basename2(file);
6248
6116
  if (rel.includes("/.codex/memories/")) return "codex-memory";
6249
6117
  if (rel.includes("/.codex/rules/")) return "codex-rule";
@@ -6390,10 +6258,10 @@ function memoryCacheRelPath(project) {
6390
6258
  }
6391
6259
  async function readMemoryCache(vault, project) {
6392
6260
  if (project) {
6393
- const projectCache = await readIfExists(join26(vault, memoryCacheRelPath(project)));
6261
+ const projectCache = await readIfExists(join25(vault, memoryCacheRelPath(project)));
6394
6262
  if (projectCache) return projectCache;
6395
6263
  }
6396
- return readIfExists(join26(vault, ".skillwiki", "memory-topics.json"));
6264
+ return readIfExists(join25(vault, ".skillwiki", "memory-topics.json"));
6397
6265
  }
6398
6266
  function dedupePages(pages) {
6399
6267
  const seen = /* @__PURE__ */ new Set();
@@ -6485,7 +6353,7 @@ function slugify2(value) {
6485
6353
 
6486
6354
  // src/commands/query.ts
6487
6355
  import { readFile as readFile9, stat as stat4 } from "fs/promises";
6488
- import { join as join28 } from "path";
6356
+ import { join as join27 } from "path";
6489
6357
 
6490
6358
  // src/utils/rrf.ts
6491
6359
  var RRF_K = 60;
@@ -6501,8 +6369,8 @@ function fuseRankings(lists, k = RRF_K) {
6501
6369
 
6502
6370
  // src/utils/vector-index.ts
6503
6371
  import { mkdir as mkdir5, readFile as readFile8, stat as stat3 } from "fs/promises";
6504
- import { join as join27 } from "path";
6505
- import { existsSync as existsSync23 } from "fs";
6372
+ import { join as join26 } from "path";
6373
+ import { existsSync as existsSync22 } from "fs";
6506
6374
  var VECTOR_INDEX_REL = ".skillwiki/vectors/index.json";
6507
6375
  var VECTOR_INDEX_SCHEMA = "skillwiki-tfidf-index/v1";
6508
6376
  function tokenize(text) {
@@ -6516,7 +6384,7 @@ function extractPageTokens(text) {
6516
6384
  return tokenize(`${title} ${body}`);
6517
6385
  }
6518
6386
  function vectorIndexPath(vault) {
6519
- return join27(vault, ...VECTOR_INDEX_REL.split("/"));
6387
+ return join26(vault, ...VECTOR_INDEX_REL.split("/"));
6520
6388
  }
6521
6389
  function termFreq(tokens) {
6522
6390
  const tf = /* @__PURE__ */ new Map();
@@ -6571,7 +6439,7 @@ async function buildVectorIndex(vault, now = (/* @__PURE__ */ new Date()).toISOS
6571
6439
  docs
6572
6440
  };
6573
6441
  const dest = vectorIndexPath(vault);
6574
- await mkdir5(join27(vault, ".skillwiki", "vectors"), { recursive: true });
6442
+ await mkdir5(join26(vault, ".skillwiki", "vectors"), { recursive: true });
6575
6443
  await atomicWriteText(dest, `${JSON.stringify(index)}
6576
6444
  `);
6577
6445
  return ok(index);
@@ -6614,7 +6482,7 @@ async function reindexPageInVectorIndex(vault, pageRelPath, now = (/* @__PURE__
6614
6482
  if (!normalizedPage.endsWith(".md")) {
6615
6483
  return err("USAGE", { message: `Page must be a .md file: ${pageRelPath}` });
6616
6484
  }
6617
- const absPath = join27(vault, ...normalizedPage.split("/"));
6485
+ const absPath = join26(vault, ...normalizedPage.split("/"));
6618
6486
  let text;
6619
6487
  try {
6620
6488
  text = await readFile8(absPath, "utf8");
@@ -6699,7 +6567,7 @@ async function reindexPageInVectorIndex(vault, pageRelPath, now = (/* @__PURE__
6699
6567
  }
6700
6568
  }
6701
6569
  const dest = vectorIndexPath(vault);
6702
- await mkdir5(join27(vault, ".skillwiki", "vectors"), { recursive: true });
6570
+ await mkdir5(join26(vault, ".skillwiki", "vectors"), { recursive: true });
6703
6571
  await atomicWriteText(dest, `${JSON.stringify(index)}
6704
6572
  `);
6705
6573
  return ok({
@@ -6717,8 +6585,8 @@ async function pruneVectorIndex(vault, opts) {
6717
6585
  const orphans = [];
6718
6586
  for (const docKey of Object.keys(index.docs)) {
6719
6587
  const normalizedKey = docKey.split(/\\|\//).join("/");
6720
- const absPath = join27(vault, ...normalizedKey.split("/"));
6721
- if (!existsSync23(absPath)) {
6588
+ const absPath = join26(vault, ...normalizedKey.split("/"));
6589
+ if (!existsSync22(absPath)) {
6722
6590
  orphans.push(normalizedKey);
6723
6591
  }
6724
6592
  }
@@ -6764,7 +6632,7 @@ async function pruneVectorIndex(vault, opts) {
6764
6632
  index.docs[docKey] = toTfIdf(termFreq(tokens), index.df, newPageCount);
6765
6633
  } else {
6766
6634
  try {
6767
- const text = await readFile8(join27(vault, ...docKey.split("/")), "utf8");
6635
+ const text = await readFile8(join26(vault, ...docKey.split("/")), "utf8");
6768
6636
  const tokens = extractPageTokens(text);
6769
6637
  index.docs[docKey] = toTfIdf(termFreq(tokens), index.df, newPageCount);
6770
6638
  } catch {
@@ -6774,7 +6642,7 @@ async function pruneVectorIndex(vault, opts) {
6774
6642
  }
6775
6643
  if (!opts?.dryRun) {
6776
6644
  const dest = vectorIndexPath(vault);
6777
- await mkdir5(join27(vault, ".skillwiki", "vectors"), { recursive: true });
6645
+ await mkdir5(join26(vault, ".skillwiki", "vectors"), { recursive: true });
6778
6646
  await atomicWriteText(dest, `${JSON.stringify(index)}
6779
6647
  `);
6780
6648
  }
@@ -6905,7 +6773,7 @@ async function runQuery(input) {
6905
6773
  }
6906
6774
  let pendingSources;
6907
6775
  if (input.includePending) {
6908
- const { runSourcesPending: runSourcesPending2 } = await import("./sources-CLOF5VAT.js");
6776
+ const { runSourcesPending: runSourcesPending2 } = await import("./sources-D2MGP246.js");
6909
6777
  const pending = await runSourcesPending2({
6910
6778
  vault: input.vault,
6911
6779
  match: input.text,
@@ -7075,7 +6943,7 @@ function computeKeywordScore(terms, title, tags, body, relPath) {
7075
6943
  return score;
7076
6944
  }
7077
6945
  async function loadOrBuildGraph(vault) {
7078
- const graphPath = join28(vault, ".skillwiki", "graph.json");
6946
+ const graphPath = join27(vault, ".skillwiki", "graph.json");
7079
6947
  let needsBuild = false;
7080
6948
  try {
7081
6949
  const fileStat = await stat4(graphPath);
@@ -7164,27 +7032,27 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
7164
7032
  import { z } from "zod";
7165
7033
 
7166
7034
  // src/mcp/vault-resolve.ts
7167
- import { join as join29, resolve as resolve5 } from "path";
7035
+ import { join as join28, resolve as resolve4 } from "path";
7168
7036
 
7169
7037
  // src/mcp/allowlist.ts
7170
- import { resolve as resolve4, sep as sep4 } from "path";
7171
- import { realpathSync as realpathSync2 } from "fs";
7038
+ import { resolve as resolve3, sep as sep3 } from "path";
7039
+ import { realpathSync } from "fs";
7172
7040
  function parseVaultAllowlist(envValue) {
7173
7041
  if (envValue === void 0 || envValue.trim() === "") return null;
7174
- return envValue.split(",").map((s) => s.trim()).filter((s) => s.length > 0).map((p) => resolve4(p));
7042
+ return envValue.split(",").map((s) => s.trim()).filter((s) => s.length > 0).map((p) => resolve3(p));
7175
7043
  }
7176
7044
  function vaultAllowedByList(vaultPath, allowlist) {
7177
7045
  if (!allowlist || allowlist.length === 0) return true;
7178
7046
  let canonical = vaultPath;
7179
7047
  try {
7180
- canonical = realpathSync2(vaultPath);
7048
+ canonical = realpathSync(vaultPath);
7181
7049
  } catch {
7182
- canonical = resolve4(vaultPath);
7050
+ canonical = resolve3(vaultPath);
7183
7051
  }
7184
- const resolved = resolve4(canonical);
7052
+ const resolved = resolve3(canonical);
7185
7053
  return allowlist.some((root) => {
7186
- const r = resolve4(root);
7187
- return resolved === r || resolved.startsWith(r + sep4);
7054
+ const r = resolve3(root);
7055
+ return resolved === r || resolved.startsWith(r + sep3);
7188
7056
  });
7189
7057
  }
7190
7058
  function getVaultAllowlistFromEnv() {
@@ -7197,7 +7065,7 @@ async function resolveMcpVault(input) {
7197
7065
  let vaultPath;
7198
7066
  let source = "resolved";
7199
7067
  if (input.vault !== void 0 && input.vault.length > 0) {
7200
- vaultPath = resolve5(input.vault);
7068
+ vaultPath = resolve4(input.vault);
7201
7069
  source = "flag";
7202
7070
  } else {
7203
7071
  const r = await resolveRuntimePath({
@@ -7209,7 +7077,7 @@ async function resolveMcpVault(input) {
7209
7077
  cwd: input.cwd ?? process.cwd()
7210
7078
  });
7211
7079
  if (!r.ok) return r;
7212
- vaultPath = resolve5(r.data.path);
7080
+ vaultPath = resolve4(r.data.path);
7213
7081
  source = r.data.source;
7214
7082
  }
7215
7083
  const scan = await scanVault(vaultPath);
@@ -7226,7 +7094,7 @@ async function resolveMcpVault(input) {
7226
7094
  return ok({ vault: vaultPath, source });
7227
7095
  }
7228
7096
  function defaultGraphOut(vault) {
7229
- return join29(vault, ".skillwiki", "graph.json");
7097
+ return join28(vault, ".skillwiki", "graph.json");
7230
7098
  }
7231
7099
 
7232
7100
  // src/mcp/result-format.ts
@@ -7242,7 +7110,7 @@ function formatToolResult(payload) {
7242
7110
 
7243
7111
  // src/mcp/audit-log.ts
7244
7112
  import { appendFileSync, mkdirSync as mkdirSync2 } from "fs";
7245
- import { join as join30 } from "path";
7113
+ import { join as join29 } from "path";
7246
7114
  function auditEnabled() {
7247
7115
  const v = process.env.SKILLWIKI_MCP_AUDIT;
7248
7116
  if (v === "0" || v === "false") return false;
@@ -7254,7 +7122,7 @@ function auditSink() {
7254
7122
  function auditFilePath() {
7255
7123
  const custom = process.env.SKILLWIKI_MCP_AUDIT_FILE;
7256
7124
  if (custom && custom.length > 0) return custom;
7257
- return join30(resolveSkillwikiHome(), ".skillwiki", "mcp-audit.jsonl");
7125
+ return join29(resolveSkillwikiHome(), ".skillwiki", "mcp-audit.jsonl");
7258
7126
  }
7259
7127
  function auditMcpToolCall(entry) {
7260
7128
  if (!auditEnabled()) return;
@@ -7264,7 +7132,7 @@ function auditMcpToolCall(entry) {
7264
7132
  return;
7265
7133
  }
7266
7134
  const path = auditFilePath();
7267
- mkdirSync2(join30(path, ".."), { recursive: true });
7135
+ mkdirSync2(join29(path, ".."), { recursive: true });
7268
7136
  appendFileSync(path, line, "utf8");
7269
7137
  }
7270
7138
  async function runMcpToolHandler(tool, input, fn) {
@@ -7539,7 +7407,7 @@ function registerMcpMutatingTools(server) {
7539
7407
 
7540
7408
  // src/mcp/resources.ts
7541
7409
  import { readFile as readFile11 } from "fs/promises";
7542
- import { join as join32 } from "path";
7410
+ import { join as join31 } from "path";
7543
7411
  import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
7544
7412
 
7545
7413
  // src/mcp/lint-bucket.ts
@@ -7669,8 +7537,8 @@ async function fetchQueryPreview(input) {
7669
7537
 
7670
7538
  // src/mcp/graph-html.ts
7671
7539
  import { readFile as readFile10 } from "fs/promises";
7672
- import { join as join31 } from "path";
7673
- import { existsSync as existsSync24 } from "fs";
7540
+ import { join as join30 } from "path";
7541
+ import { existsSync as existsSync23 } from "fs";
7674
7542
  var TYPE_COLORS = {
7675
7543
  entities: "#e74c3c",
7676
7544
  concepts: "#27ae60",
@@ -7738,9 +7606,9 @@ ${nodeSvg}
7738
7606
  return { html, node_count: nodes.length, edge_count: edges.length, truncated };
7739
7607
  }
7740
7608
  async function fetchGraphHtmlReport(input) {
7741
- const graphPath = input.graphPath ?? join31(input.vault, ".skillwiki", "graph.json");
7609
+ const graphPath = input.graphPath ?? join30(input.vault, ".skillwiki", "graph.json");
7742
7610
  const maxNodes = Math.min(Math.max(10, input.maxNodes ?? 120), 500);
7743
- if (!existsSync24(graphPath)) {
7611
+ if (!existsSync23(graphPath)) {
7744
7612
  return {
7745
7613
  exitCode: ExitCode.FILE_NOT_FOUND,
7746
7614
  result: err("GRAPH_MISSING", { path: graphPath, hint: "Run skillwiki.graph_build first." })
@@ -7812,7 +7680,7 @@ async function fetchStaleSummary(input) {
7812
7680
 
7813
7681
  // src/mcp/resources.ts
7814
7682
  async function readVaultFile(vault, rel) {
7815
- return readFile11(join32(vault, rel), "utf8");
7683
+ return readFile11(join31(vault, rel), "utf8");
7816
7684
  }
7817
7685
  async function tailLines(text, lines) {
7818
7686
  const parts = text.split(/\r?\n/);
@@ -7898,7 +7766,7 @@ function registerMcpResources(server) {
7898
7766
  if (!v.ok) {
7899
7767
  return { contents: [{ uri: uri.href, mimeType: "text/plain", text: JSON.stringify(v) }] };
7900
7768
  }
7901
- const path = join32(v.data.vault, ".skillwiki", "graph.json");
7769
+ const path = join31(v.data.vault, ".skillwiki", "graph.json");
7902
7770
  try {
7903
7771
  const raw = await readFile11(path, "utf8");
7904
7772
  const graph = JSON.parse(raw);
@@ -8273,8 +8141,6 @@ export {
8273
8141
  evaluateSatelliteRunHealthState,
8274
8142
  withMcpClient,
8275
8143
  DEFAULT_MCP_URL,
8276
- CLIP_NOT_CONFIGURED,
8277
- loadClipOutboxConfig,
8278
8144
  runDoctor,
8279
8145
  readCliPackageJson,
8280
8146
  DEFAULT_DIRTY_VOLUME_THRESHOLD,