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