skillwiki 0.8.5-beta.1 → 0.8.5-beta.3
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
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
#!/usr/bin/env node
|
|
3
3
|
import {
|
|
4
|
+
normalizeDistTag,
|
|
4
5
|
semverGt
|
|
5
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-E6UWZ3S3.js";
|
|
6
7
|
|
|
7
8
|
// src/auto-update-bg.ts
|
|
8
9
|
import { execSync } from "child_process";
|
|
@@ -10,11 +11,12 @@ import { writeFileSync, mkdirSync } from "fs";
|
|
|
10
11
|
import { join, dirname } from "path";
|
|
11
12
|
var home = process.argv[2];
|
|
12
13
|
var currentVersion = process.argv[3];
|
|
14
|
+
var distTag = normalizeDistTag(process.argv[4]);
|
|
13
15
|
if (!home || !currentVersion) process.exit(0);
|
|
14
16
|
var cacheFile = join(home, ".skillwiki", ".update-cache.json");
|
|
15
17
|
setTimeout(() => process.exit(0), 3e4);
|
|
16
18
|
try {
|
|
17
|
-
const latest = execSync(
|
|
19
|
+
const latest = execSync(`npm view skillwiki@${distTag} version`, {
|
|
18
20
|
encoding: "utf8",
|
|
19
21
|
timeout: 15e3
|
|
20
22
|
}).trim();
|
|
@@ -22,10 +24,11 @@ try {
|
|
|
22
24
|
const cache = {
|
|
23
25
|
lastCheck: Date.now(),
|
|
24
26
|
latestVersion: latest,
|
|
25
|
-
currentVersion
|
|
27
|
+
currentVersion,
|
|
28
|
+
distTag
|
|
26
29
|
};
|
|
27
30
|
if (semverGt(latest, currentVersion)) {
|
|
28
|
-
execSync(
|
|
31
|
+
execSync(`npm install -g skillwiki@${distTag}`, {
|
|
29
32
|
stdio: "ignore",
|
|
30
33
|
timeout: 6e4
|
|
31
34
|
});
|
|
@@ -36,7 +39,7 @@ try {
|
|
|
36
39
|
} catch {
|
|
37
40
|
try {
|
|
38
41
|
mkdirSync(dirname(cacheFile), { recursive: true });
|
|
39
|
-
writeFileSync(cacheFile, JSON.stringify({ lastCheck: Date.now(), latestVersion: "", currentVersion }, null, 2));
|
|
42
|
+
writeFileSync(cacheFile, JSON.stringify({ lastCheck: Date.now(), latestVersion: "", currentVersion, distTag }, null, 2));
|
|
40
43
|
} catch {
|
|
41
44
|
}
|
|
42
45
|
}
|
|
@@ -40,6 +40,23 @@ function parseSemver(version) {
|
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
// src/utils/update-consts.ts
|
|
44
|
+
var DIST_TAG = "latest";
|
|
45
|
+
var CACHE_FILENAME = ".update-cache.json";
|
|
46
|
+
var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
47
|
+
var ENV_DISABLE_KEY = "NO_UPDATE_NOTIFIER";
|
|
48
|
+
var CLI_DISABLE_FLAG = "--no-update-notifier";
|
|
49
|
+
function normalizeDistTag(tag) {
|
|
50
|
+
const value = (tag ?? DIST_TAG).trim();
|
|
51
|
+
return /^[A-Za-z0-9._-]+$/.test(value) ? value : DIST_TAG;
|
|
52
|
+
}
|
|
53
|
+
|
|
43
54
|
export {
|
|
44
|
-
semverGt
|
|
55
|
+
semverGt,
|
|
56
|
+
DIST_TAG,
|
|
57
|
+
CACHE_FILENAME,
|
|
58
|
+
CHECK_INTERVAL_MS,
|
|
59
|
+
ENV_DISABLE_KEY,
|
|
60
|
+
CLI_DISABLE_FLAG,
|
|
61
|
+
normalizeDistTag
|
|
45
62
|
};
|
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
+
CACHE_FILENAME,
|
|
4
|
+
CHECK_INTERVAL_MS,
|
|
5
|
+
CLI_DISABLE_FLAG,
|
|
6
|
+
DIST_TAG,
|
|
7
|
+
ENV_DISABLE_KEY,
|
|
8
|
+
normalizeDistTag,
|
|
3
9
|
semverGt
|
|
4
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-E6UWZ3S3.js";
|
|
5
11
|
import {
|
|
6
12
|
git,
|
|
7
13
|
gitStrict
|
|
@@ -4011,7 +4017,7 @@ async function runConfigPath(input) {
|
|
|
4011
4017
|
}
|
|
4012
4018
|
|
|
4013
4019
|
// src/commands/doctor.ts
|
|
4014
|
-
import { existsSync as
|
|
4020
|
+
import { existsSync as existsSync10, lstatSync, readlinkSync, readdirSync as readdirSync2, statSync as statSync3, readFileSync as readFileSync7 } from "fs";
|
|
4015
4021
|
import { join as join27, resolve as resolve5 } from "path";
|
|
4016
4022
|
import { execSync as execSync2 } from "child_process";
|
|
4017
4023
|
import { platform as platform2 } from "os";
|
|
@@ -4020,14 +4026,6 @@ import { platform as platform2 } from "os";
|
|
|
4020
4026
|
import { readFileSync as readFileSync4, writeFileSync as writeFileSync4, existsSync as existsSync7, mkdirSync as mkdirSync3 } from "fs";
|
|
4021
4027
|
import { join as join24, dirname as dirname9 } from "path";
|
|
4022
4028
|
import { spawn } from "child_process";
|
|
4023
|
-
|
|
4024
|
-
// src/utils/update-consts.ts
|
|
4025
|
-
var CACHE_FILENAME = ".update-cache.json";
|
|
4026
|
-
var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
4027
|
-
var ENV_DISABLE_KEY = "NO_UPDATE_NOTIFIER";
|
|
4028
|
-
var CLI_DISABLE_FLAG = "--no-update-notifier";
|
|
4029
|
-
|
|
4030
|
-
// src/utils/auto-update.ts
|
|
4031
4029
|
function cachePath(home) {
|
|
4032
4030
|
return join24(home, ".skillwiki", CACHE_FILENAME);
|
|
4033
4031
|
}
|
|
@@ -4053,12 +4051,17 @@ function writeCache(home, cache) {
|
|
|
4053
4051
|
}
|
|
4054
4052
|
function latestFromCache(home, currentVersion) {
|
|
4055
4053
|
const { cache } = readCache(home);
|
|
4056
|
-
if (!cache || !cache.latestVersion) return { hasUpdate: false, latest: null };
|
|
4054
|
+
if (!cache || !cache.latestVersion) return { hasUpdate: false, latest: null, distTag: DIST_TAG };
|
|
4055
|
+
const distTag = normalizeDistTag(cache.distTag);
|
|
4057
4056
|
return {
|
|
4058
4057
|
hasUpdate: semverGt(cache.latestVersion, currentVersion),
|
|
4059
|
-
latest: cache.latestVersion
|
|
4058
|
+
latest: cache.latestVersion,
|
|
4059
|
+
distTag
|
|
4060
4060
|
};
|
|
4061
4061
|
}
|
|
4062
|
+
function distTagFromCache(home) {
|
|
4063
|
+
return normalizeDistTag(readCacheRaw(home)?.distTag);
|
|
4064
|
+
}
|
|
4062
4065
|
function isDisabled() {
|
|
4063
4066
|
return !!(process.env[ENV_DISABLE_KEY] || process.env.NODE_ENV === "test" || process.argv.includes(CLI_DISABLE_FLAG));
|
|
4064
4067
|
}
|
|
@@ -4066,9 +4069,10 @@ function triggerAutoUpdate(home, currentVersion) {
|
|
|
4066
4069
|
if (isDisabled()) return;
|
|
4067
4070
|
const { isStale: isStale2 } = readCache(home);
|
|
4068
4071
|
if (!isStale2) return;
|
|
4072
|
+
const distTag = distTagFromCache(home);
|
|
4069
4073
|
const bgScript = new URL("../auto-update-bg.js", import.meta.url).pathname;
|
|
4070
4074
|
if (!existsSync7(bgScript)) return;
|
|
4071
|
-
const child = spawn(process.execPath, [bgScript, home, currentVersion], {
|
|
4075
|
+
const child = spawn(process.execPath, [bgScript, home, currentVersion, distTag], {
|
|
4072
4076
|
detached: true,
|
|
4073
4077
|
stdio: "ignore"
|
|
4074
4078
|
});
|
|
@@ -4078,9 +4082,10 @@ function triggerAutoUpdate(home, currentVersion) {
|
|
|
4078
4082
|
}
|
|
4079
4083
|
|
|
4080
4084
|
// src/utils/plugin-registry.ts
|
|
4081
|
-
import { readFileSync as readFileSync5 } from "fs";
|
|
4085
|
+
import { existsSync as existsSync8, readdirSync, readFileSync as readFileSync5 } from "fs";
|
|
4082
4086
|
import { join as join25 } from "path";
|
|
4083
4087
|
var REGISTRY_PATH = join25(".claude", "plugins", "installed_plugins.json");
|
|
4088
|
+
var CODEX_CONFIG_PATH = join25(".codex", "config.toml");
|
|
4084
4089
|
var PLUGIN_KEY = "skillwiki@llm-wiki";
|
|
4085
4090
|
function readInstalledPlugins(home) {
|
|
4086
4091
|
try {
|
|
@@ -4097,6 +4102,102 @@ function findPlugin(home, key = PLUGIN_KEY) {
|
|
|
4097
4102
|
if (!entries || entries.length === 0) return null;
|
|
4098
4103
|
return entries[0];
|
|
4099
4104
|
}
|
|
4105
|
+
function findPluginInstallations(home, key = PLUGIN_KEY) {
|
|
4106
|
+
const parsed = parsePluginKey(key);
|
|
4107
|
+
if (!parsed) return [];
|
|
4108
|
+
const installs = [];
|
|
4109
|
+
const claudePlugin = findPlugin(home, key);
|
|
4110
|
+
if (claudePlugin) {
|
|
4111
|
+
installs.push({
|
|
4112
|
+
channel: "claude",
|
|
4113
|
+
label: "Claude",
|
|
4114
|
+
key,
|
|
4115
|
+
pluginName: parsed.pluginName,
|
|
4116
|
+
marketplace: parsed.marketplace,
|
|
4117
|
+
installPath: claudePlugin.installPath,
|
|
4118
|
+
version: claudePlugin.version
|
|
4119
|
+
});
|
|
4120
|
+
}
|
|
4121
|
+
const codexPlugin = findCodexPlugin(home, key, parsed.pluginName, parsed.marketplace);
|
|
4122
|
+
if (codexPlugin) installs.push(codexPlugin);
|
|
4123
|
+
return installs;
|
|
4124
|
+
}
|
|
4125
|
+
function findCodexPlugin(home, key, pluginName, marketplace) {
|
|
4126
|
+
const config = readCodexPluginConfig(home, key, marketplace);
|
|
4127
|
+
if (!config?.enabled) return null;
|
|
4128
|
+
const cacheRoot = join25(home, ".codex", "plugins", "cache", marketplace, pluginName);
|
|
4129
|
+
if (!existsSync8(cacheRoot)) return null;
|
|
4130
|
+
let versions;
|
|
4131
|
+
try {
|
|
4132
|
+
versions = readdirSync(cacheRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
|
|
4133
|
+
} catch {
|
|
4134
|
+
return null;
|
|
4135
|
+
}
|
|
4136
|
+
if (versions.length === 0) return null;
|
|
4137
|
+
const version = versions.reduce((latest, candidate) => semverGt(candidate, latest) ? candidate : latest);
|
|
4138
|
+
return {
|
|
4139
|
+
channel: "codex",
|
|
4140
|
+
label: "Codex",
|
|
4141
|
+
key,
|
|
4142
|
+
pluginName,
|
|
4143
|
+
marketplace,
|
|
4144
|
+
installPath: join25(cacheRoot, version),
|
|
4145
|
+
version,
|
|
4146
|
+
sourceType: config.sourceType,
|
|
4147
|
+
source: config.source
|
|
4148
|
+
};
|
|
4149
|
+
}
|
|
4150
|
+
function parsePluginKey(key) {
|
|
4151
|
+
const at = key.lastIndexOf("@");
|
|
4152
|
+
if (at <= 0 || at === key.length - 1) return null;
|
|
4153
|
+
return {
|
|
4154
|
+
pluginName: key.slice(0, at),
|
|
4155
|
+
marketplace: key.slice(at + 1)
|
|
4156
|
+
};
|
|
4157
|
+
}
|
|
4158
|
+
function readCodexPluginConfig(home, key, marketplace) {
|
|
4159
|
+
let raw;
|
|
4160
|
+
try {
|
|
4161
|
+
raw = readFileSync5(join25(home, CODEX_CONFIG_PATH), "utf8");
|
|
4162
|
+
} catch {
|
|
4163
|
+
return null;
|
|
4164
|
+
}
|
|
4165
|
+
const pluginSections = /* @__PURE__ */ new Set([`plugins."${key}"`, `plugins.${key}`]);
|
|
4166
|
+
const marketplaceSections = /* @__PURE__ */ new Set([`marketplaces.${marketplace}`, `marketplaces."${marketplace}"`]);
|
|
4167
|
+
let section = "";
|
|
4168
|
+
let sawPlugin = false;
|
|
4169
|
+
const config = { enabled: false };
|
|
4170
|
+
for (const line of raw.split(/\r?\n/)) {
|
|
4171
|
+
const trimmed = line.trim();
|
|
4172
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
4173
|
+
const sectionMatch = trimmed.match(/^\[([^\]]+)\]$/);
|
|
4174
|
+
if (sectionMatch) {
|
|
4175
|
+
section = sectionMatch[1];
|
|
4176
|
+
continue;
|
|
4177
|
+
}
|
|
4178
|
+
const kv = trimmed.match(/^([A-Za-z0-9_.-]+)\s*=\s*(.+)$/);
|
|
4179
|
+
if (!kv) continue;
|
|
4180
|
+
const name = kv[1];
|
|
4181
|
+
const value = parseTomlScalar(kv[2]);
|
|
4182
|
+
if (pluginSections.has(section) && name === "enabled") {
|
|
4183
|
+
sawPlugin = true;
|
|
4184
|
+
config.enabled = value === true;
|
|
4185
|
+
} else if (marketplaceSections.has(section) && name === "source_type" && typeof value === "string") {
|
|
4186
|
+
config.sourceType = value;
|
|
4187
|
+
} else if (marketplaceSections.has(section) && name === "source" && typeof value === "string") {
|
|
4188
|
+
config.source = value;
|
|
4189
|
+
}
|
|
4190
|
+
}
|
|
4191
|
+
return sawPlugin ? config : null;
|
|
4192
|
+
}
|
|
4193
|
+
function parseTomlScalar(rawValue) {
|
|
4194
|
+
const value = rawValue.replace(/\s+#.*$/, "").trim();
|
|
4195
|
+
if (value === "true") return true;
|
|
4196
|
+
if (value === "false") return false;
|
|
4197
|
+
const quoted = value.match(/^"((?:\\"|[^"])*)"$/);
|
|
4198
|
+
if (quoted) return quoted[1].replace(/\\"/g, '"');
|
|
4199
|
+
return value;
|
|
4200
|
+
}
|
|
4100
4201
|
|
|
4101
4202
|
// src/utils/s3-mount-health.ts
|
|
4102
4203
|
import { execSync } from "child_process";
|
|
@@ -4361,12 +4462,12 @@ function detectCliChannels(argv, home) {
|
|
|
4361
4462
|
const plugin = findPlugin(home);
|
|
4362
4463
|
if (plugin) {
|
|
4363
4464
|
const pluginBin = join27(plugin.installPath, "bin", "skillwiki");
|
|
4364
|
-
if (
|
|
4465
|
+
if (existsSync10(pluginBin)) {
|
|
4365
4466
|
channels.push({ name: "plugin", path: pluginBin, isDevLink: false });
|
|
4366
4467
|
}
|
|
4367
4468
|
}
|
|
4368
4469
|
const installBin = join27(home, ".claude", "skills", "bin", "skillwiki");
|
|
4369
|
-
if (
|
|
4470
|
+
if (existsSync10(installBin)) {
|
|
4370
4471
|
channels.push({ name: "install", path: installBin, isDevLink: false });
|
|
4371
4472
|
}
|
|
4372
4473
|
return channels;
|
|
@@ -4418,7 +4519,7 @@ function checkCliChannels(argv, home) {
|
|
|
4418
4519
|
}
|
|
4419
4520
|
async function checkConfigFile(home) {
|
|
4420
4521
|
const cfgPath = configPath(home);
|
|
4421
|
-
if (!
|
|
4522
|
+
if (!existsSync10(cfgPath)) {
|
|
4422
4523
|
return check("warn", "config_file", "Config file exists", `${cfgPath} not found`);
|
|
4423
4524
|
}
|
|
4424
4525
|
try {
|
|
@@ -4433,7 +4534,7 @@ function checkWikiPathExists(resolvedPath) {
|
|
|
4433
4534
|
if (resolvedPath === void 0) {
|
|
4434
4535
|
return check("error", "wiki_path_exists", "Vault directory exists", "Cannot check \u2014 WIKI_PATH not resolved");
|
|
4435
4536
|
}
|
|
4436
|
-
if (
|
|
4537
|
+
if (existsSync10(resolvedPath) && statSync3(resolvedPath).isDirectory()) {
|
|
4437
4538
|
return check("pass", "wiki_path_exists", "Vault directory exists", resolvedPath);
|
|
4438
4539
|
}
|
|
4439
4540
|
return check("error", "wiki_path_exists", "Vault directory exists", `${resolvedPath} does not exist or is not a directory`);
|
|
@@ -4442,13 +4543,13 @@ function checkVaultStructure(resolvedPath) {
|
|
|
4442
4543
|
if (resolvedPath === void 0) {
|
|
4443
4544
|
return check("error", "vault_structure", "Vault structure valid", "Cannot check \u2014 WIKI_PATH not resolved");
|
|
4444
4545
|
}
|
|
4445
|
-
if (!
|
|
4546
|
+
if (!existsSync10(resolvedPath)) {
|
|
4446
4547
|
return check("error", "vault_structure", "Vault structure valid", "Cannot check \u2014 vault directory does not exist");
|
|
4447
4548
|
}
|
|
4448
4549
|
const missing = [];
|
|
4449
|
-
if (!
|
|
4550
|
+
if (!existsSync10(join27(resolvedPath, "SCHEMA.md"))) missing.push("SCHEMA.md");
|
|
4450
4551
|
for (const dir of ["raw", "entities", "concepts", "meta"]) {
|
|
4451
|
-
if (!
|
|
4552
|
+
if (!existsSync10(join27(resolvedPath, dir))) missing.push(dir + "/");
|
|
4452
4553
|
}
|
|
4453
4554
|
if (missing.length === 0) {
|
|
4454
4555
|
return check("pass", "vault_structure", "Vault structure valid", "All required files and directories present");
|
|
@@ -4457,7 +4558,7 @@ function checkVaultStructure(resolvedPath) {
|
|
|
4457
4558
|
}
|
|
4458
4559
|
function checkSkillsInstalled(home, cwd) {
|
|
4459
4560
|
const srcDir = cwd ? join27(cwd, "packages", "skills") : void 0;
|
|
4460
|
-
if (srcDir &&
|
|
4561
|
+
if (srcDir && existsSync10(srcDir)) {
|
|
4461
4562
|
const found = findInstalledSkillMd(srcDir);
|
|
4462
4563
|
if (found.length > 0) {
|
|
4463
4564
|
return check("pass", "skills_installed", "Skills installed", `${found.length} SKILL.md file(s) found (source)`);
|
|
@@ -4471,7 +4572,7 @@ function checkSkillsInstalled(home, cwd) {
|
|
|
4471
4572
|
}
|
|
4472
4573
|
}
|
|
4473
4574
|
const skillsDir = join27(home, ".claude", "skills");
|
|
4474
|
-
if (
|
|
4575
|
+
if (existsSync10(skillsDir)) {
|
|
4475
4576
|
const found = findInstalledSkillMd(skillsDir);
|
|
4476
4577
|
if (found.length > 0) {
|
|
4477
4578
|
return check("pass", "skills_installed", "Skills installed", `${found.length} SKILL.md file(s) found (CLI install)`);
|
|
@@ -4513,32 +4614,54 @@ function checkDuplicateSkills(home) {
|
|
|
4513
4614
|
return check(status, "skills_duplicate", "Skills not duplicated", parts.join("; "));
|
|
4514
4615
|
}
|
|
4515
4616
|
function checkNpmUpdate(home, currentVersion) {
|
|
4516
|
-
const { hasUpdate, latest } = latestFromCache(home, currentVersion);
|
|
4617
|
+
const { hasUpdate, latest, distTag } = latestFromCache(home, currentVersion);
|
|
4517
4618
|
if (!latest) {
|
|
4518
|
-
return check("pass", "npm_update", "npm CLI version", `v${currentVersion} (no cache yet)`);
|
|
4619
|
+
return check("pass", "npm_update", "npm CLI version", `v${currentVersion} (${distTag}: no cache yet)`);
|
|
4519
4620
|
}
|
|
4520
4621
|
if (hasUpdate) {
|
|
4521
|
-
return check("warn", "npm_update", "npm CLI version", `v${currentVersion} \u2014 update available: v${latest}. Run \`skillwiki update\`.`);
|
|
4622
|
+
return check("warn", "npm_update", "npm CLI version", `v${currentVersion} \u2014 ${distTag} update available: v${latest}. Run \`skillwiki update --tag ${distTag}\`.`);
|
|
4522
4623
|
}
|
|
4523
|
-
return check("pass", "npm_update", "npm CLI version", `v${currentVersion} (
|
|
4624
|
+
return check("pass", "npm_update", "npm CLI version", `v${currentVersion} (${distTag}: v${latest})`);
|
|
4524
4625
|
}
|
|
4525
4626
|
function checkPluginVersionDrift(home, currentVersion) {
|
|
4526
|
-
const
|
|
4527
|
-
if (
|
|
4627
|
+
const plugins = findPluginInstallations(home);
|
|
4628
|
+
if (plugins.length === 0) {
|
|
4528
4629
|
return check("pass", "plugin_version_drift", "Plugin/CLI version", "Plugin not installed \u2014 CLI only");
|
|
4529
4630
|
}
|
|
4530
|
-
const
|
|
4531
|
-
if (
|
|
4532
|
-
|
|
4631
|
+
const drifted = plugins.filter((plugin) => plugin.version !== currentVersion);
|
|
4632
|
+
if (drifted.length === 0) {
|
|
4633
|
+
if (plugins.length === 1 && plugins[0].channel === "claude") {
|
|
4634
|
+
return check("pass", "plugin_version_drift", "Plugin/CLI version", `Both at v${currentVersion}`);
|
|
4635
|
+
}
|
|
4636
|
+
if (plugins.length === 1) {
|
|
4637
|
+
return check("pass", "plugin_version_drift", "Plugin/CLI version", `${plugins[0].label} plugin and CLI both at v${currentVersion}`);
|
|
4638
|
+
}
|
|
4639
|
+
const labels = plugins.map((plugin) => `${plugin.label} plugin`).join(", ");
|
|
4640
|
+
return check("pass", "plugin_version_drift", "Plugin/CLI version", `${labels}, and CLI all at v${currentVersion}`);
|
|
4533
4641
|
}
|
|
4534
|
-
const
|
|
4642
|
+
const details = drifted.map((plugin) => {
|
|
4643
|
+
const updateCmd = pluginUpdateCommand(plugin, currentVersion);
|
|
4644
|
+
return `${plugin.label} plugin v${plugin.version} \u2260 CLI v${currentVersion} \u2014 run \`${updateCmd}\``;
|
|
4645
|
+
});
|
|
4535
4646
|
return check(
|
|
4536
4647
|
"warn",
|
|
4537
4648
|
"plugin_version_drift",
|
|
4538
4649
|
"Plugin/CLI version",
|
|
4539
|
-
|
|
4650
|
+
details.join("; ")
|
|
4540
4651
|
);
|
|
4541
4652
|
}
|
|
4653
|
+
function pluginUpdateCommand(plugin, currentVersion) {
|
|
4654
|
+
if (semverGt(plugin.version, currentVersion)) {
|
|
4655
|
+
return "npm install -g skillwiki@latest";
|
|
4656
|
+
}
|
|
4657
|
+
if (plugin.channel === "claude") {
|
|
4658
|
+
return "claude plugin update skillwiki@llm-wiki";
|
|
4659
|
+
}
|
|
4660
|
+
if (plugin.sourceType === "git") {
|
|
4661
|
+
return "codex plugin marketplace upgrade llm-wiki && codex plugin remove skillwiki@llm-wiki && codex plugin add skillwiki@llm-wiki";
|
|
4662
|
+
}
|
|
4663
|
+
return "codex plugin remove skillwiki@llm-wiki && codex plugin add skillwiki@llm-wiki";
|
|
4664
|
+
}
|
|
4542
4665
|
async function checkProfiles(home) {
|
|
4543
4666
|
const map = await parseDotenvFile(configPath(home));
|
|
4544
4667
|
const profiles = [];
|
|
@@ -4562,7 +4685,7 @@ async function checkProfiles(home) {
|
|
|
4562
4685
|
async function checkProjectLocalOverride(cwd) {
|
|
4563
4686
|
const dir = cwd ?? process.cwd();
|
|
4564
4687
|
const envPath = join27(dir, ".skillwiki", ".env");
|
|
4565
|
-
if (
|
|
4688
|
+
if (existsSync10(envPath)) {
|
|
4566
4689
|
return check("pass", "project_local", "Project-local config", `Found: ${envPath}`);
|
|
4567
4690
|
}
|
|
4568
4691
|
return check("pass", "project_local", "Project-local config", "None");
|
|
@@ -4571,7 +4694,7 @@ function checkVaultGitRemote(resolvedPath) {
|
|
|
4571
4694
|
if (resolvedPath === void 0) {
|
|
4572
4695
|
return check("error", "vault_git_remote", "Vault git remote", "Cannot check \u2014 WIKI_PATH not resolved");
|
|
4573
4696
|
}
|
|
4574
|
-
if (!
|
|
4697
|
+
if (!existsSync10(join27(resolvedPath, ".git"))) {
|
|
4575
4698
|
return check("warn", "vault_git_remote", "Vault git remote", "Vault is not a git repository \u2014 sync features unavailable");
|
|
4576
4699
|
}
|
|
4577
4700
|
try {
|
|
@@ -4594,9 +4717,9 @@ function checkObsidianTemplates(resolvedPath) {
|
|
|
4594
4717
|
return check("error", "obsidian_templates", "Obsidian templates", "Cannot check \u2014 WIKI_PATH not resolved");
|
|
4595
4718
|
}
|
|
4596
4719
|
const missing = [];
|
|
4597
|
-
if (!
|
|
4598
|
-
if (!
|
|
4599
|
-
if (!
|
|
4720
|
+
if (!existsSync10(join27(resolvedPath, "_Templates"))) missing.push("_Templates/");
|
|
4721
|
+
if (!existsSync10(join27(resolvedPath, ".obsidian", "templates.json"))) missing.push(".obsidian/templates.json");
|
|
4722
|
+
if (!existsSync10(join27(resolvedPath, ".obsidian", "app.json"))) missing.push(".obsidian/app.json");
|
|
4600
4723
|
if (missing.length === 0) {
|
|
4601
4724
|
return check("pass", "obsidian_templates", "Obsidian templates", "Template folder and config present");
|
|
4602
4725
|
}
|
|
@@ -4607,14 +4730,14 @@ function checkDotStoreClean(resolvedPath) {
|
|
|
4607
4730
|
return check("error", "dsstore_clean", "No .DS_Store in raw/", "Cannot check \u2014 WIKI_PATH not resolved");
|
|
4608
4731
|
}
|
|
4609
4732
|
const rawDir = join27(resolvedPath, "raw");
|
|
4610
|
-
if (!
|
|
4733
|
+
if (!existsSync10(rawDir)) {
|
|
4611
4734
|
return check("pass", "dsstore_clean", "No .DS_Store in raw/", "raw/ directory not found \u2014 check skipped");
|
|
4612
4735
|
}
|
|
4613
4736
|
const found = [];
|
|
4614
4737
|
(function walk2(dir, rel) {
|
|
4615
4738
|
let entries;
|
|
4616
4739
|
try {
|
|
4617
|
-
entries =
|
|
4740
|
+
entries = readdirSync2(dir, { withFileTypes: true });
|
|
4618
4741
|
} catch {
|
|
4619
4742
|
return;
|
|
4620
4743
|
}
|
|
@@ -4635,7 +4758,7 @@ function checkSyncLastPush(resolvedPath) {
|
|
|
4635
4758
|
if (resolvedPath === void 0) {
|
|
4636
4759
|
return check("error", "sync_last_push", "Vault sync recency", "Cannot check \u2014 WIKI_PATH not resolved");
|
|
4637
4760
|
}
|
|
4638
|
-
if (!
|
|
4761
|
+
if (!existsSync10(join27(resolvedPath, ".git"))) {
|
|
4639
4762
|
return check("pass", "sync_last_push", "Vault sync recency", "No git repo \u2014 sync check skipped");
|
|
4640
4763
|
}
|
|
4641
4764
|
let timestamp;
|
|
@@ -4683,7 +4806,7 @@ function checkVaultGitDirty(resolvedPath) {
|
|
|
4683
4806
|
if (resolvedPath === void 0) {
|
|
4684
4807
|
return check("pass", "vault_git_dirty", "Vault git dirty state", "No vault path \u2014 check skipped");
|
|
4685
4808
|
}
|
|
4686
|
-
if (!
|
|
4809
|
+
if (!existsSync10(join27(resolvedPath, ".git"))) {
|
|
4687
4810
|
return check("pass", "vault_git_dirty", "Vault git dirty state", "No git repo \u2014 check skipped");
|
|
4688
4811
|
}
|
|
4689
4812
|
try {
|
|
@@ -4724,7 +4847,7 @@ function checkVaultGitComparison(resolvedPath, id, label, range, nonZeroSuffix,
|
|
|
4724
4847
|
if (resolvedPath === void 0) {
|
|
4725
4848
|
return check("pass", id, label, "No vault path \u2014 check skipped");
|
|
4726
4849
|
}
|
|
4727
|
-
if (!
|
|
4850
|
+
if (!existsSync10(join27(resolvedPath, ".git"))) {
|
|
4728
4851
|
return check("pass", id, label, "No git repo \u2014 check skipped");
|
|
4729
4852
|
}
|
|
4730
4853
|
if (!hasOriginMain(resolvedPath)) {
|
|
@@ -4762,7 +4885,7 @@ function isRecentLogLine(line, nowMs) {
|
|
|
4762
4885
|
return nowMs - ts <= 24 * 60 * 60 * 1e3;
|
|
4763
4886
|
}
|
|
4764
4887
|
function checkVaultGitPullFailures(home) {
|
|
4765
|
-
const path = pullLogPaths(home).find((p) =>
|
|
4888
|
+
const path = pullLogPaths(home).find((p) => existsSync10(p));
|
|
4766
4889
|
if (!path) {
|
|
4767
4890
|
return check("pass", "vault_git_pull_failures", "Vault pull failures", "No wiki-pull.log found \u2014 check skipped");
|
|
4768
4891
|
}
|
|
@@ -4791,7 +4914,7 @@ function checkS3MountPerf(resolvedPath) {
|
|
|
4791
4914
|
}
|
|
4792
4915
|
const mountPoint = fuse.mountPoint;
|
|
4793
4916
|
const conceptsDir = join27(resolvedPath, "concepts");
|
|
4794
|
-
if (!
|
|
4917
|
+
if (!existsSync10(conceptsDir)) {
|
|
4795
4918
|
return check("pass", "s3_mount_perf", "S3 mount performance", `S3 FUSE mount (${mountPoint}), no concepts/ to benchmark`);
|
|
4796
4919
|
}
|
|
4797
4920
|
const start = Date.now();
|
|
@@ -4974,7 +5097,7 @@ function checkWriteTest(resolvedPath) {
|
|
|
4974
5097
|
return check("pass", "s3_write_test", "S3 write test", "local disk \u2014 check skipped");
|
|
4975
5098
|
}
|
|
4976
5099
|
const conceptsDir = join27(resolvedPath, "concepts");
|
|
4977
|
-
if (!
|
|
5100
|
+
if (!existsSync10(conceptsDir)) {
|
|
4978
5101
|
return check("pass", "s3_write_test", "S3 write test", "no concepts/ dir to test \u2014 check skipped");
|
|
4979
5102
|
}
|
|
4980
5103
|
const result = writeTest(conceptsDir);
|
|
@@ -5099,7 +5222,7 @@ function vaultSyncChecks(input) {
|
|
|
5099
5222
|
const filterPath = input.filterPath ?? join27(home, ".config", "rclone", "wiki-push-filters.txt");
|
|
5100
5223
|
const snapshotPath = input.snapshotScriptPath ?? "/root/.hermes/scripts/wiki-snapshot-v3.sh";
|
|
5101
5224
|
const pushScriptPath = join27(shareDir, "wiki-push.sh");
|
|
5102
|
-
const c1 =
|
|
5225
|
+
const c1 = existsSync10(pushScriptPath) ? check("pass", "vault_sync_installed", "Vault sync installed", `Found: ${pushScriptPath}`) : check("error", "vault_sync_installed", "Vault sync installed", `Script not found at ${pushScriptPath} \u2014 run vault-sync-install`);
|
|
5103
5226
|
let c2;
|
|
5104
5227
|
try {
|
|
5105
5228
|
if (isMac) {
|
|
@@ -5209,7 +5332,7 @@ function vaultSyncChecks(input) {
|
|
|
5209
5332
|
}
|
|
5210
5333
|
}
|
|
5211
5334
|
} catch {
|
|
5212
|
-
c3 =
|
|
5335
|
+
c3 = existsSync10(logDir) ? check(
|
|
5213
5336
|
"warn",
|
|
5214
5337
|
"vault_sync_last_push_age",
|
|
5215
5338
|
"Vault sync last push recency",
|
|
@@ -5268,7 +5391,7 @@ function vaultSyncChecks(input) {
|
|
|
5268
5391
|
}
|
|
5269
5392
|
let c4;
|
|
5270
5393
|
try {
|
|
5271
|
-
if (!
|
|
5394
|
+
if (!existsSync10(filterPath)) {
|
|
5272
5395
|
c4 = check(
|
|
5273
5396
|
"error",
|
|
5274
5397
|
"vault_sync_filter_present",
|
|
@@ -5317,7 +5440,7 @@ function vaultSyncChecks(input) {
|
|
|
5317
5440
|
);
|
|
5318
5441
|
} else {
|
|
5319
5442
|
try {
|
|
5320
|
-
if (!
|
|
5443
|
+
if (!existsSync10(snapshotPath)) {
|
|
5321
5444
|
c5 = check(
|
|
5322
5445
|
"error",
|
|
5323
5446
|
"vault_sync_snapshot_guard",
|
|
@@ -5357,7 +5480,7 @@ function findSkillMd(dir) {
|
|
|
5357
5480
|
const results = [];
|
|
5358
5481
|
let entries;
|
|
5359
5482
|
try {
|
|
5360
|
-
entries =
|
|
5483
|
+
entries = readdirSync2(dir, { withFileTypes: true });
|
|
5361
5484
|
} catch {
|
|
5362
5485
|
return results;
|
|
5363
5486
|
}
|
|
@@ -5378,12 +5501,12 @@ function findSkillNames(dir) {
|
|
|
5378
5501
|
const results = [];
|
|
5379
5502
|
let entries;
|
|
5380
5503
|
try {
|
|
5381
|
-
entries =
|
|
5504
|
+
entries = readdirSync2(dir, { withFileTypes: true });
|
|
5382
5505
|
} catch {
|
|
5383
5506
|
return results;
|
|
5384
5507
|
}
|
|
5385
5508
|
for (const entry of entries) {
|
|
5386
|
-
if (entry.isDirectory() &&
|
|
5509
|
+
if (entry.isDirectory() && existsSync10(join27(dir, entry.name, "SKILL.md"))) {
|
|
5387
5510
|
results.push(entry.name);
|
|
5388
5511
|
}
|
|
5389
5512
|
}
|
|
@@ -6057,7 +6180,7 @@ async function runUpdate(input) {
|
|
|
6057
6180
|
readFileSync8(new URL("../../package.json", import.meta.url), "utf8")
|
|
6058
6181
|
);
|
|
6059
6182
|
const currentVersion = pkg2.version;
|
|
6060
|
-
const tag = input.distTag
|
|
6183
|
+
const tag = normalizeDistTag(input.distTag);
|
|
6061
6184
|
const target = join29(input.home, ".claude", "skills");
|
|
6062
6185
|
let latest;
|
|
6063
6186
|
try {
|
|
@@ -6074,7 +6197,8 @@ async function runUpdate(input) {
|
|
|
6074
6197
|
const cache = {
|
|
6075
6198
|
lastCheck: Date.now(),
|
|
6076
6199
|
latestVersion: latest,
|
|
6077
|
-
currentVersion
|
|
6200
|
+
currentVersion,
|
|
6201
|
+
distTag: tag
|
|
6078
6202
|
};
|
|
6079
6203
|
if (latest === currentVersion) {
|
|
6080
6204
|
writeCache(input.home, cache);
|
|
@@ -6086,7 +6210,7 @@ async function runUpdate(input) {
|
|
|
6086
6210
|
wasAlreadyLatest: true,
|
|
6087
6211
|
version_warnings: [],
|
|
6088
6212
|
skills_refreshed: false,
|
|
6089
|
-
humanHint: `Already on
|
|
6213
|
+
humanHint: `Already on npm@${tag}: v${currentVersion}`
|
|
6090
6214
|
})
|
|
6091
6215
|
};
|
|
6092
6216
|
}
|
|
@@ -6106,7 +6230,7 @@ async function runUpdate(input) {
|
|
|
6106
6230
|
const version_warnings = installResult.warnings;
|
|
6107
6231
|
const skills_refreshed = installResult.refreshed;
|
|
6108
6232
|
const hintLines = [
|
|
6109
|
-
`Updated skillwiki ${currentVersion} \u2192 ${latest}`,
|
|
6233
|
+
`Updated skillwiki ${currentVersion} \u2192 ${latest} via npm@${tag}`,
|
|
6110
6234
|
`skills refreshed: ${skills_refreshed}`
|
|
6111
6235
|
];
|
|
6112
6236
|
if (version_warnings.length > 0) {
|
|
@@ -6128,7 +6252,7 @@ async function runUpdate(input) {
|
|
|
6128
6252
|
|
|
6129
6253
|
// src/commands/self-update.ts
|
|
6130
6254
|
import { execSync as execSync4 } from "child_process";
|
|
6131
|
-
import { existsSync as
|
|
6255
|
+
import { existsSync as existsSync11, readFileSync as readFileSync9 } from "fs";
|
|
6132
6256
|
import { join as join30 } from "path";
|
|
6133
6257
|
var DEFAULT_SOURCE_ROOT_SUFFIX = "/Desktop/code/llm-wiki";
|
|
6134
6258
|
async function runSelfUpdate(input) {
|
|
@@ -6136,8 +6260,9 @@ async function runSelfUpdate(input) {
|
|
|
6136
6260
|
readFileSync9(new URL("../../package.json", import.meta.url), "utf8")
|
|
6137
6261
|
).version;
|
|
6138
6262
|
const sourceRoot = input.sourceRoot ?? `${input.home}${DEFAULT_SOURCE_ROOT_SUFFIX}`;
|
|
6263
|
+
const distTag = normalizeDistTag(input.distTag);
|
|
6139
6264
|
const localPkgPath = join30(sourceRoot, "packages", "cli", "package.json");
|
|
6140
|
-
const hasLocalSource =
|
|
6265
|
+
const hasLocalSource = existsSync11(localPkgPath);
|
|
6141
6266
|
if (input.check) {
|
|
6142
6267
|
let availableVersion = null;
|
|
6143
6268
|
let source;
|
|
@@ -6151,7 +6276,7 @@ async function runSelfUpdate(input) {
|
|
|
6151
6276
|
} else {
|
|
6152
6277
|
source = "npm";
|
|
6153
6278
|
try {
|
|
6154
|
-
availableVersion = execSync4(
|
|
6279
|
+
availableVersion = execSync4(`npm view skillwiki@${distTag} version`, {
|
|
6155
6280
|
encoding: "utf8",
|
|
6156
6281
|
timeout: 15e3
|
|
6157
6282
|
}).trim();
|
|
@@ -6221,7 +6346,7 @@ async function runSelfUpdate(input) {
|
|
|
6221
6346
|
}
|
|
6222
6347
|
let latestVersion;
|
|
6223
6348
|
try {
|
|
6224
|
-
latestVersion = execSync4(
|
|
6349
|
+
latestVersion = execSync4(`npm view skillwiki@${distTag} version`, {
|
|
6225
6350
|
encoding: "utf8",
|
|
6226
6351
|
timeout: 15e3
|
|
6227
6352
|
}).trim();
|
|
@@ -6239,12 +6364,12 @@ async function runSelfUpdate(input) {
|
|
|
6239
6364
|
currentVersion,
|
|
6240
6365
|
availableVersion: latestVersion,
|
|
6241
6366
|
updateAvailable: false,
|
|
6242
|
-
humanHint: `Already on
|
|
6367
|
+
humanHint: `Already on ${distTag}: v${currentVersion}`
|
|
6243
6368
|
})
|
|
6244
6369
|
};
|
|
6245
6370
|
}
|
|
6246
6371
|
try {
|
|
6247
|
-
execSync4(
|
|
6372
|
+
execSync4(`npm install -g skillwiki@${distTag}`, {
|
|
6248
6373
|
stdio: "pipe",
|
|
6249
6374
|
timeout: 6e4
|
|
6250
6375
|
});
|
|
@@ -6262,7 +6387,7 @@ async function runSelfUpdate(input) {
|
|
|
6262
6387
|
availableVersion: latestVersion,
|
|
6263
6388
|
updateAvailable: true,
|
|
6264
6389
|
newVersion: latestVersion,
|
|
6265
|
-
humanHint: `Updated skillwiki ${currentVersion} \u2192 ${latestVersion} via npm
|
|
6390
|
+
humanHint: `Updated skillwiki ${currentVersion} \u2192 ${latestVersion} via npm@${distTag}`
|
|
6266
6391
|
})
|
|
6267
6392
|
};
|
|
6268
6393
|
}
|
|
@@ -6445,7 +6570,7 @@ ${entries.map((e) => ` ${e.type}: [[${e.page.replace(/\.md$/, "")}]] \u2014 ${e
|
|
|
6445
6570
|
// src/commands/compound.ts
|
|
6446
6571
|
import { writeFile as writeFile12, mkdir as mkdir11, readdir as readdir7, unlink as unlink4 } from "fs/promises";
|
|
6447
6572
|
import { join as join33 } from "path";
|
|
6448
|
-
import { existsSync as
|
|
6573
|
+
import { existsSync as existsSync12 } from "fs";
|
|
6449
6574
|
import { readFile as readFile23 } from "fs/promises";
|
|
6450
6575
|
var RETRO_HEADING_RE = /^## \[(\d{4}-\d{2}-\d{2})(?:\s+[^\]]+)?\] retro \| loop cycle(?: (\d+))?: (.+)$/;
|
|
6451
6576
|
var FIELD_RE = {
|
|
@@ -6563,7 +6688,7 @@ async function runCompound(input) {
|
|
|
6563
6688
|
}
|
|
6564
6689
|
const slug = slugify(entry.cycleName);
|
|
6565
6690
|
const compoundPath = join33(compoundDir, `${slug}.md`);
|
|
6566
|
-
if (
|
|
6691
|
+
if (existsSync12(compoundPath)) {
|
|
6567
6692
|
skipped.push(entry.date);
|
|
6568
6693
|
continue;
|
|
6569
6694
|
}
|
|
@@ -6601,7 +6726,7 @@ async function runCompound(input) {
|
|
|
6601
6726
|
].join("\n");
|
|
6602
6727
|
const content = frontmatter + "\n" + body;
|
|
6603
6728
|
if (!input.dryRun) {
|
|
6604
|
-
if (!
|
|
6729
|
+
if (!existsSync12(compoundDir)) {
|
|
6605
6730
|
await mkdir11(compoundDir, { recursive: true });
|
|
6606
6731
|
}
|
|
6607
6732
|
await writeFile12(compoundPath, content, "utf8");
|
|
@@ -6624,7 +6749,7 @@ async function runCompound(input) {
|
|
|
6624
6749
|
}
|
|
6625
6750
|
async function runCompoundDelete(input) {
|
|
6626
6751
|
const projectDir = join33(input.vault, "projects", input.project);
|
|
6627
|
-
if (!
|
|
6752
|
+
if (!existsSync12(projectDir)) {
|
|
6628
6753
|
return {
|
|
6629
6754
|
exitCode: ExitCode.PROJECT_NOT_FOUND,
|
|
6630
6755
|
result: err("PROJECT_NOT_FOUND", { slug: input.project, path: projectDir })
|
|
@@ -6632,7 +6757,7 @@ async function runCompoundDelete(input) {
|
|
|
6632
6757
|
}
|
|
6633
6758
|
const entryName = input.entry.replace(/\.md$/, "");
|
|
6634
6759
|
const compoundPath = join33(projectDir, "compound", `${entryName}.md`);
|
|
6635
|
-
if (!
|
|
6760
|
+
if (!existsSync12(compoundPath)) {
|
|
6636
6761
|
return {
|
|
6637
6762
|
exitCode: ExitCode.FILE_NOT_FOUND,
|
|
6638
6763
|
result: err("FILE_NOT_FOUND", { path: compoundPath })
|
|
@@ -6666,7 +6791,7 @@ knowledge.md regenerated`
|
|
|
6666
6791
|
}
|
|
6667
6792
|
async function runCompoundList(input) {
|
|
6668
6793
|
const compoundDir = join33(input.vault, "projects", input.project, "compound");
|
|
6669
|
-
if (!
|
|
6794
|
+
if (!existsSync12(compoundDir)) {
|
|
6670
6795
|
return {
|
|
6671
6796
|
exitCode: ExitCode.OK,
|
|
6672
6797
|
result: ok({
|
|
@@ -6729,7 +6854,7 @@ no compound entries found`;
|
|
|
6729
6854
|
|
|
6730
6855
|
// src/commands/observe.ts
|
|
6731
6856
|
import { mkdir as mkdir12, writeFile as writeFile13 } from "fs/promises";
|
|
6732
|
-
import { existsSync as
|
|
6857
|
+
import { existsSync as existsSync13, statSync as statSync4 } from "fs";
|
|
6733
6858
|
import { join as join34 } from "path";
|
|
6734
6859
|
import { createHash as createHash4 } from "crypto";
|
|
6735
6860
|
var ALLOWED_KINDS = /* @__PURE__ */ new Set(["note", "bug", "task", "idea", "session-log"]);
|
|
@@ -6753,7 +6878,7 @@ async function runObserve(input) {
|
|
|
6753
6878
|
result: err("SCHEME_REJECTED", { message: "Text must not be empty" })
|
|
6754
6879
|
};
|
|
6755
6880
|
}
|
|
6756
|
-
if (!
|
|
6881
|
+
if (!existsSync13(input.vault) || !statSync4(input.vault).isDirectory()) {
|
|
6757
6882
|
return {
|
|
6758
6883
|
exitCode: ExitCode.VAULT_PATH_INVALID,
|
|
6759
6884
|
result: err("VAULT_PATH_INVALID", { path: input.vault })
|
|
@@ -7257,11 +7382,11 @@ ${body}`;
|
|
|
7257
7382
|
}
|
|
7258
7383
|
|
|
7259
7384
|
// src/commands/sync.ts
|
|
7260
|
-
import { existsSync as
|
|
7385
|
+
import { existsSync as existsSync15 } from "fs";
|
|
7261
7386
|
import { join as join37 } from "path";
|
|
7262
7387
|
|
|
7263
7388
|
// src/utils/sync-lock.ts
|
|
7264
|
-
import { existsSync as
|
|
7389
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync4, readFileSync as readFileSync10, renameSync, unlinkSync as unlinkSync5, writeFileSync as writeFileSync6 } from "fs";
|
|
7265
7390
|
import { join as join36 } from "path";
|
|
7266
7391
|
import { createHash as createHash6 } from "crypto";
|
|
7267
7392
|
function getSessionId() {
|
|
@@ -7274,7 +7399,7 @@ function lockPath(vault) {
|
|
|
7274
7399
|
}
|
|
7275
7400
|
function readLock(vault) {
|
|
7276
7401
|
const path = lockPath(vault);
|
|
7277
|
-
if (!
|
|
7402
|
+
if (!existsSync14(path)) return null;
|
|
7278
7403
|
try {
|
|
7279
7404
|
const raw = readFileSync10(path, "utf8");
|
|
7280
7405
|
return JSON.parse(raw);
|
|
@@ -7290,7 +7415,7 @@ function isStale(lock, now) {
|
|
|
7290
7415
|
function acquireLock(vault, opts = {}) {
|
|
7291
7416
|
const path = lockPath(vault);
|
|
7292
7417
|
const dir = join36(vault, ".skillwiki");
|
|
7293
|
-
if (!
|
|
7418
|
+
if (!existsSync14(dir)) {
|
|
7294
7419
|
mkdirSync4(dir, { recursive: true });
|
|
7295
7420
|
}
|
|
7296
7421
|
const sessionId = opts.sessionId ?? getSessionId();
|
|
@@ -7335,7 +7460,7 @@ function writeLockedFile(path, lock) {
|
|
|
7335
7460
|
}
|
|
7336
7461
|
function releaseLock(vault, opts = {}) {
|
|
7337
7462
|
const path = lockPath(vault);
|
|
7338
|
-
if (!
|
|
7463
|
+
if (!existsSync14(path)) {
|
|
7339
7464
|
return { released: false };
|
|
7340
7465
|
}
|
|
7341
7466
|
const sessionId = opts.sessionId ?? getSessionId();
|
|
@@ -7364,7 +7489,7 @@ function releaseLock(vault, opts = {}) {
|
|
|
7364
7489
|
function runSyncStatus(input) {
|
|
7365
7490
|
const vault = input.vault;
|
|
7366
7491
|
const includeStashes = input.includeStashes ?? false;
|
|
7367
|
-
if (!
|
|
7492
|
+
if (!existsSync15(join37(vault, ".git"))) {
|
|
7368
7493
|
return {
|
|
7369
7494
|
exitCode: ExitCode.VAULT_PATH_INVALID,
|
|
7370
7495
|
result: ok({
|
|
@@ -7442,7 +7567,7 @@ function runSyncStatus(input) {
|
|
|
7442
7567
|
}
|
|
7443
7568
|
async function runSyncPush(input) {
|
|
7444
7569
|
const vault = input.vault;
|
|
7445
|
-
if (!
|
|
7570
|
+
if (!existsSync15(join37(vault, ".git"))) {
|
|
7446
7571
|
return {
|
|
7447
7572
|
exitCode: ExitCode.VAULT_PATH_INVALID,
|
|
7448
7573
|
result: err("NOT_A_GIT_REPO", { path: vault })
|
|
@@ -7565,7 +7690,7 @@ function enableGitLongPathsOnWindows(vault) {
|
|
|
7565
7690
|
}
|
|
7566
7691
|
async function runSyncPull(input) {
|
|
7567
7692
|
const vault = input.vault;
|
|
7568
|
-
if (!
|
|
7693
|
+
if (!existsSync15(join37(vault, ".git"))) {
|
|
7569
7694
|
return {
|
|
7570
7695
|
exitCode: ExitCode.VAULT_PATH_INVALID,
|
|
7571
7696
|
result: err("NOT_A_GIT_REPO", { path: vault })
|
|
@@ -7737,7 +7862,7 @@ function runSyncPeers(input) {
|
|
|
7737
7862
|
}
|
|
7738
7863
|
function runSyncLock(input) {
|
|
7739
7864
|
const vault = input.vault;
|
|
7740
|
-
if (!
|
|
7865
|
+
if (!existsSync15(vault)) {
|
|
7741
7866
|
return {
|
|
7742
7867
|
exitCode: ExitCode.VAULT_PATH_INVALID,
|
|
7743
7868
|
result: err("VAULT_PATH_INVALID", { path: vault })
|
|
@@ -7772,7 +7897,7 @@ function runSyncLock(input) {
|
|
|
7772
7897
|
}
|
|
7773
7898
|
function runSyncUnlock(input) {
|
|
7774
7899
|
const vault = input.vault;
|
|
7775
|
-
if (!
|
|
7900
|
+
if (!existsSync15(vault)) {
|
|
7776
7901
|
return {
|
|
7777
7902
|
exitCode: ExitCode.VAULT_PATH_INVALID,
|
|
7778
7903
|
result: err("VAULT_PATH_INVALID", { path: vault })
|
|
@@ -7805,7 +7930,7 @@ function runSyncUnlock(input) {
|
|
|
7805
7930
|
}
|
|
7806
7931
|
|
|
7807
7932
|
// src/commands/backup.ts
|
|
7808
|
-
import { statSync as statSync5, readdirSync as
|
|
7933
|
+
import { statSync as statSync5, readdirSync as readdirSync3, readFileSync as readFileSync11, mkdirSync as mkdirSync5, writeFileSync as writeFileSync7 } from "fs";
|
|
7809
7934
|
import { join as join38, relative as relative3, dirname as dirname12 } from "path";
|
|
7810
7935
|
import { PutObjectCommand, HeadObjectCommand, ListObjectsV2Command, GetObjectCommand, DeleteObjectsCommand } from "@aws-sdk/client-s3";
|
|
7811
7936
|
|
|
@@ -7828,7 +7953,7 @@ function createS3Client(config) {
|
|
|
7828
7953
|
// src/commands/backup.ts
|
|
7829
7954
|
var SKIP_DIRS2 = /* @__PURE__ */ new Set([".git", ".obsidian", "_archive", "node_modules", ".skillwiki"]);
|
|
7830
7955
|
function* walkMarkdown(dir, base) {
|
|
7831
|
-
for (const entry of
|
|
7956
|
+
for (const entry of readdirSync3(dir, { withFileTypes: true })) {
|
|
7832
7957
|
if (SKIP_DIRS2.has(entry.name)) continue;
|
|
7833
7958
|
const full = join38(dir, entry.name);
|
|
7834
7959
|
if (entry.isDirectory()) {
|
|
@@ -7975,11 +8100,11 @@ async function runBackupRestore(input) {
|
|
|
7975
8100
|
}
|
|
7976
8101
|
|
|
7977
8102
|
// src/commands/status.ts
|
|
7978
|
-
import { existsSync as
|
|
8103
|
+
import { existsSync as existsSync16, statSync as statSync6 } from "fs";
|
|
7979
8104
|
import { readFile as readFile25 } from "fs/promises";
|
|
7980
8105
|
import { join as join39 } from "path";
|
|
7981
8106
|
async function runStatus(input) {
|
|
7982
|
-
if (!
|
|
8107
|
+
if (!existsSync16(input.vault)) {
|
|
7983
8108
|
return { exitCode: ExitCode.VAULT_PATH_INVALID, result: err("VAULT_PATH_INVALID", { vault: input.vault }) };
|
|
7984
8109
|
}
|
|
7985
8110
|
const scan = await scanVault(input.vault);
|
|
@@ -8180,7 +8305,7 @@ async function runSeed(input) {
|
|
|
8180
8305
|
|
|
8181
8306
|
// src/commands/canvas.ts
|
|
8182
8307
|
import { readFile as readFile26, writeFile as writeFile16 } from "fs/promises";
|
|
8183
|
-
import { existsSync as
|
|
8308
|
+
import { existsSync as existsSync17 } from "fs";
|
|
8184
8309
|
import { join as join41 } from "path";
|
|
8185
8310
|
var NODE_WIDTH = 240;
|
|
8186
8311
|
var NODE_HEIGHT = 60;
|
|
@@ -8260,7 +8385,7 @@ function buildCanvasEdges(adjacency) {
|
|
|
8260
8385
|
}
|
|
8261
8386
|
async function runCanvasGenerate(input) {
|
|
8262
8387
|
const graphPath = input.graphPath ?? join41(input.vault, ".skillwiki", "graph.json");
|
|
8263
|
-
if (!
|
|
8388
|
+
if (!existsSync17(graphPath)) {
|
|
8264
8389
|
return {
|
|
8265
8390
|
exitCode: ExitCode.FILE_NOT_FOUND,
|
|
8266
8391
|
result: err("FILE_NOT_FOUND", {
|
|
@@ -8463,14 +8588,14 @@ async function loadOrBuildGraph(vault) {
|
|
|
8463
8588
|
}
|
|
8464
8589
|
|
|
8465
8590
|
// src/utils/auto-commit.ts
|
|
8466
|
-
import { existsSync as
|
|
8591
|
+
import { existsSync as existsSync18 } from "fs";
|
|
8467
8592
|
import { join as join43 } from "path";
|
|
8468
8593
|
async function postCommit(vault, exitCode) {
|
|
8469
8594
|
if (exitCode !== 0) return;
|
|
8470
8595
|
const home = process.env.HOME ?? "";
|
|
8471
8596
|
const dotenv = await parseDotenvFile(configPath(home));
|
|
8472
8597
|
if (dotenv["AUTO_COMMIT"] === "false") return;
|
|
8473
|
-
if (!
|
|
8598
|
+
if (!existsSync18(join43(vault, ".git"))) return;
|
|
8474
8599
|
const lastOps = readLastOp(vault);
|
|
8475
8600
|
if (lastOps.length === 0) return;
|
|
8476
8601
|
const porcelain = git(vault, ["status", "--porcelain"]);
|
|
@@ -8711,13 +8836,14 @@ program.command("frontmatter-fix [vault]").description("fix common frontmatter i
|
|
|
8711
8836
|
if (!v.ok) emit({ exitCode: v.exitCode, result: v.payload });
|
|
8712
8837
|
else emit(await runFrontmatterFix({ vault: v.vault, dryRun: !!opts.dryRun }), v.vault);
|
|
8713
8838
|
});
|
|
8714
|
-
program.command("update").description("update skillwiki CLI
|
|
8839
|
+
program.command("update").description("update skillwiki CLI from npm dist-tag").option("--tag <tag>", "npm dist-tag", "latest").action(async (opts) => emit(await runUpdate({
|
|
8715
8840
|
home: process.env.HOME ?? "",
|
|
8716
8841
|
distTag: opts.tag
|
|
8717
8842
|
})));
|
|
8718
|
-
program.command("self-update").description("update skillwiki CLI from local source or npm
|
|
8843
|
+
program.command("self-update").description("update skillwiki CLI from local source or npm dist-tag").option("--check", "check for updates without installing", false).option("--tag <tag>", "npm dist-tag", "latest").action(async (opts) => emit(await runSelfUpdate({
|
|
8719
8844
|
home: process.env.HOME ?? "",
|
|
8720
|
-
check: !!opts.check
|
|
8845
|
+
check: !!opts.check,
|
|
8846
|
+
distTag: opts.tag
|
|
8721
8847
|
})));
|
|
8722
8848
|
program.command("transcripts [vault]").description("list transcript files in raw/transcripts/").option("--since <date>", "only files ingested on or after this date (YYYY-MM-DD)").option("--wiki <name>", "wiki profile name").action(async (vault, opts) => {
|
|
8723
8849
|
const v = await resolveVaultArg(vault, opts.wiki);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skillwiki",
|
|
3
|
-
"version": "0.8.5-beta.
|
|
3
|
+
"version": "0.8.5-beta.3",
|
|
4
4
|
"skills": "./",
|
|
5
5
|
"description": "Project-aware Karpathy-style knowledge base for Claude Code: 18 prompt-only skills (wiki-*, proj-*, using-skillwiki) backed by the deterministic `skillwiki` CLI.",
|
|
6
6
|
"author": {
|