skillwiki 0.10.36 → 0.10.39
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/cli.js
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
GateError,
|
|
8
8
|
SATELLITE_STALE_MS,
|
|
9
9
|
configPath,
|
|
10
|
+
detectFuseMount,
|
|
10
11
|
evaluateDirtyVolumeGate,
|
|
11
12
|
evaluateSatelliteRunHealth,
|
|
12
13
|
findPlugin,
|
|
@@ -38,7 +39,7 @@ import {
|
|
|
38
39
|
scanConflictMarkerBlocksInText,
|
|
39
40
|
snapshotterHealthChecks,
|
|
40
41
|
upsertIndexEntry
|
|
41
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-NDR2OY4K.js";
|
|
42
43
|
import {
|
|
43
44
|
normalizeDistTag,
|
|
44
45
|
readCache,
|
|
@@ -168,6 +169,7 @@ import {
|
|
|
168
169
|
ok,
|
|
169
170
|
readPage,
|
|
170
171
|
redactSensitiveContent,
|
|
172
|
+
resolveReadOnlyVaultRoot,
|
|
171
173
|
scanSensitiveContent,
|
|
172
174
|
scanVault,
|
|
173
175
|
splitFrontmatter
|
|
@@ -181,11 +183,19 @@ import { Command } from "commander";
|
|
|
181
183
|
function printJson(r) {
|
|
182
184
|
process.stdout.write(JSON.stringify(r) + "\n");
|
|
183
185
|
}
|
|
184
|
-
function printHuman(r) {
|
|
186
|
+
function printHuman(r, opts = {}) {
|
|
185
187
|
if (r.ok) {
|
|
186
188
|
if (typeof r.data === "object" && r.data !== null && "humanHint" in r.data) {
|
|
187
|
-
|
|
189
|
+
const humanHint = r.data.humanHint;
|
|
190
|
+
if (!opts.detailHints?.length) {
|
|
191
|
+
process.stdout.write(`${humanHint}
|
|
188
192
|
`);
|
|
193
|
+
} else {
|
|
194
|
+
const existingLines = new Set(humanHint.split("\n"));
|
|
195
|
+
const detailLines2 = opts.detailHints.filter((line) => !existingLines.has(line));
|
|
196
|
+
process.stdout.write(`${[humanHint, ...detailLines2].join("\n")}
|
|
197
|
+
`);
|
|
198
|
+
}
|
|
189
199
|
} else {
|
|
190
200
|
process.stdout.write(`OK
|
|
191
201
|
${formatData(r.data)}
|
|
@@ -202,6 +212,45 @@ function formatData(d) {
|
|
|
202
212
|
return JSON.stringify(d, null, 2);
|
|
203
213
|
}
|
|
204
214
|
|
|
215
|
+
// src/utils/lint-detail-hints.ts
|
|
216
|
+
function lintDetailHints(data) {
|
|
217
|
+
const record = asRecord(data);
|
|
218
|
+
if (!record) return [];
|
|
219
|
+
const bySeverity = asRecord(record.by_severity);
|
|
220
|
+
if (bySeverity && Array.isArray(bySeverity.error)) {
|
|
221
|
+
return detailLines(bySeverity.error, false);
|
|
222
|
+
}
|
|
223
|
+
return Array.isArray(record.buckets) ? detailLines(record.buckets, true) : [];
|
|
224
|
+
}
|
|
225
|
+
function healthLintDetailHints(data) {
|
|
226
|
+
const record = asRecord(data);
|
|
227
|
+
const components = asRecord(record?.components);
|
|
228
|
+
const lint = asRecord(components?.lint);
|
|
229
|
+
return Array.isArray(lint?.buckets) ? detailLines(lint.buckets, true) : [];
|
|
230
|
+
}
|
|
231
|
+
function detailLines(buckets, requireErrorSeverity) {
|
|
232
|
+
const seen = /* @__PURE__ */ new Set();
|
|
233
|
+
const lines = [];
|
|
234
|
+
for (const bucket of buckets) {
|
|
235
|
+
const record = asRecord(bucket);
|
|
236
|
+
if (!record || requireErrorSeverity && record.severity !== "error") continue;
|
|
237
|
+
const name = nonEmptyBucketName(record);
|
|
238
|
+
if (!name || seen.has(name)) continue;
|
|
239
|
+
seen.add(name);
|
|
240
|
+
lines.push(`detail: skillwiki lint --only ${name} --examples 3`);
|
|
241
|
+
}
|
|
242
|
+
return lines;
|
|
243
|
+
}
|
|
244
|
+
function nonEmptyBucketName(bucket) {
|
|
245
|
+
if (typeof bucket.kind !== "string" || !/^[a-z0-9_]+$/.test(bucket.kind)) return null;
|
|
246
|
+
if (typeof bucket.count === "number") return bucket.count > 0 ? bucket.kind : null;
|
|
247
|
+
if (Array.isArray(bucket.items)) return bucket.items.length > 0 ? bucket.kind : null;
|
|
248
|
+
return null;
|
|
249
|
+
}
|
|
250
|
+
function asRecord(value) {
|
|
251
|
+
return typeof value === "object" && value !== null ? value : null;
|
|
252
|
+
}
|
|
253
|
+
|
|
205
254
|
// src/utils/deprecation.ts
|
|
206
255
|
import { readFileSync } from "fs";
|
|
207
256
|
import { join } from "path";
|
|
@@ -4424,7 +4473,8 @@ import { mkdir as mkdir8, readFile as readFile11, writeFile as writeFile7 } from
|
|
|
4424
4473
|
import { join as join24, relative, sep } from "path";
|
|
4425
4474
|
var MAX_WORDS = 900;
|
|
4426
4475
|
async function runSessionBrief(input) {
|
|
4427
|
-
const
|
|
4476
|
+
const { root: scanRoot } = resolveReadOnlyVaultRoot(input.vault);
|
|
4477
|
+
const scan = await scanVault(scanRoot);
|
|
4428
4478
|
if (!scan.ok) {
|
|
4429
4479
|
return { exitCode: ExitCode.VAULT_PATH_INVALID, result: scan };
|
|
4430
4480
|
}
|
|
@@ -4450,7 +4500,7 @@ async function runSessionBrief(input) {
|
|
|
4450
4500
|
loadSatelliteHealth(input.vault),
|
|
4451
4501
|
loadSessionPins(input.vault, project),
|
|
4452
4502
|
project ? loadMemoryTopics(input.vault, project) : Promise.resolve([]),
|
|
4453
|
-
loadPendingSources(
|
|
4503
|
+
loadPendingSources(scanRoot, today)
|
|
4454
4504
|
]);
|
|
4455
4505
|
const healthWarnings = [
|
|
4456
4506
|
...baseHealthWarnings,
|
|
@@ -8357,11 +8407,23 @@ async function runBackupRestore(input) {
|
|
|
8357
8407
|
import { existsSync as existsSync10, statSync as statSync4 } from "fs";
|
|
8358
8408
|
import { readFile as readFile16 } from "fs/promises";
|
|
8359
8409
|
import { join as join32 } from "path";
|
|
8410
|
+
var FUSE_NO_MIRROR_NOTE = "FUSE vault with no read mirror - status scan may be slow";
|
|
8360
8411
|
async function runStatus(input) {
|
|
8361
8412
|
if (!existsSync10(input.vault)) {
|
|
8362
8413
|
return { exitCode: ExitCode.VAULT_PATH_INVALID, result: err("VAULT_PATH_INVALID", { vault: input.vault }) };
|
|
8363
8414
|
}
|
|
8364
|
-
const
|
|
8415
|
+
const { root: scanRoot, mirrored } = resolveReadOnlyVaultRoot(input.vault);
|
|
8416
|
+
let readSource = "live";
|
|
8417
|
+
if (mirrored) {
|
|
8418
|
+
readSource = "mirror";
|
|
8419
|
+
} else if (detectFuseMount(input.vault)) {
|
|
8420
|
+
readSource = "fuse-no-mirror";
|
|
8421
|
+
}
|
|
8422
|
+
if (readSource === "fuse-no-mirror") {
|
|
8423
|
+
process.stderr.write(`warning: ${FUSE_NO_MIRROR_NOTE}
|
|
8424
|
+
`);
|
|
8425
|
+
}
|
|
8426
|
+
const scan = await scanVault(scanRoot);
|
|
8365
8427
|
if (!scan.ok) {
|
|
8366
8428
|
return { exitCode: ExitCode.VAULT_PATH_INVALID, result: scan };
|
|
8367
8429
|
}
|
|
@@ -8383,7 +8445,7 @@ async function runStatus(input) {
|
|
|
8383
8445
|
const compound = scan.data.compound.length;
|
|
8384
8446
|
let schemaVersion = "v1";
|
|
8385
8447
|
try {
|
|
8386
|
-
const schemaContent = await readFile16(join32(
|
|
8448
|
+
const schemaContent = await readFile16(join32(scanRoot, "SCHEMA.md"), "utf8");
|
|
8387
8449
|
const versionMatch = schemaContent.match(/version:\s*["']?([^"'\s\n]+)/i);
|
|
8388
8450
|
if (versionMatch) schemaVersion = versionMatch[1];
|
|
8389
8451
|
} catch {
|
|
@@ -8420,14 +8482,20 @@ async function runStatus(input) {
|
|
|
8420
8482
|
};
|
|
8421
8483
|
const totalPages = Object.values(pageCounts).reduce((a, b) => a + b, 0);
|
|
8422
8484
|
const rawTotal = rawArticles + rawTranscripts;
|
|
8423
|
-
const
|
|
8485
|
+
const hintLines = [
|
|
8424
8486
|
`vault: ${input.vault}`,
|
|
8425
8487
|
`lang: ${langResult.value}`,
|
|
8426
8488
|
`total: ${totalPages} pages`,
|
|
8427
8489
|
` entities: ${pageCounts.entities} concepts: ${pageCounts.concepts} comparisons: ${pageCounts.comparisons} queries: ${pageCounts.queries} meta: ${pageCounts.meta}`,
|
|
8428
8490
|
` raw: ${rawTotal} work_items: ${workItems} compound: ${compound}`,
|
|
8429
8491
|
`last modified: ${lastModified.slice(0, 10)}`
|
|
8430
|
-
]
|
|
8492
|
+
];
|
|
8493
|
+
if (readSource === "mirror") {
|
|
8494
|
+
hintLines.push(`read source: mirror (${scanRoot}) - page counts may lag up to 30m`);
|
|
8495
|
+
} else if (readSource === "fuse-no-mirror") {
|
|
8496
|
+
hintLines.push(FUSE_NO_MIRROR_NOTE);
|
|
8497
|
+
}
|
|
8498
|
+
const humanHint = hintLines.join("\n");
|
|
8431
8499
|
return {
|
|
8432
8500
|
exitCode: ExitCode.OK,
|
|
8433
8501
|
result: ok({
|
|
@@ -8437,6 +8505,7 @@ async function runStatus(input) {
|
|
|
8437
8505
|
page_counts: pageCounts,
|
|
8438
8506
|
total_pages: totalPages,
|
|
8439
8507
|
last_modified: lastModified,
|
|
8508
|
+
read_source: readSource,
|
|
8440
8509
|
humanHint
|
|
8441
8510
|
})
|
|
8442
8511
|
};
|
|
@@ -9354,9 +9423,16 @@ var program = new Command();
|
|
|
9354
9423
|
program.name("skillwiki").description("Deterministic helpers for CodeWiki skills").version(pkg.version);
|
|
9355
9424
|
program.option("--human", "render terminal-readable output instead of JSON");
|
|
9356
9425
|
async function emit(r, vault, opts) {
|
|
9357
|
-
if (program.opts().human)
|
|
9358
|
-
|
|
9426
|
+
if (program.opts().human) {
|
|
9427
|
+
const detailHints = r.result.ok ? opts?.humanDetailHints?.(r.result.data) : void 0;
|
|
9428
|
+
printHuman(r.result, { detailHints });
|
|
9429
|
+
} else {
|
|
9430
|
+
printJson(r.result);
|
|
9431
|
+
}
|
|
9359
9432
|
if (vault && opts?.postCommit !== false) await postCommit(vault, r.exitCode);
|
|
9433
|
+
await new Promise((resolve6, reject) => {
|
|
9434
|
+
process.stdout.write("", (error) => error ? reject(error) : resolve6());
|
|
9435
|
+
});
|
|
9360
9436
|
process.exit(r.exitCode);
|
|
9361
9437
|
}
|
|
9362
9438
|
function dirtyVolumeBlock(vault, command) {
|
|
@@ -9835,6 +9911,7 @@ projectionsCmd.command("repair-legacy [vault]").description("repair one supporte
|
|
|
9835
9911
|
});
|
|
9836
9912
|
program.command("lint [vault]").description("run all vault health checks").option("--days <n>", "stale threshold", (s) => parseInt(s, 10), 90).option("--lines <n>", "pagesize threshold", (s) => parseInt(s, 10), 200).option("--log-threshold <n>", "log rotation threshold", (s) => parseInt(s, 10), 500).option("--fix", "auto-fix supported lint violations").option("--only <bucket>", "run only the specified lint bucket").option("--summary", "emit bounded bucket counts instead of full item arrays", false).option("--examples <n>", "example count per bucket in summary mode", (s) => parseInt(s, 10), 3).option("--wiki <name>", "wiki profile name").action(async (vault, opts) => {
|
|
9837
9913
|
const v = await resolveVaultArg(vault, opts.wiki);
|
|
9914
|
+
const humanDetailHints = opts.only ? void 0 : lintDetailHints;
|
|
9838
9915
|
if (!v.ok) emit({ exitCode: v.exitCode, result: v.payload });
|
|
9839
9916
|
else if (opts.fix && opts.summary) return emitGuardedVaultWrite(
|
|
9840
9917
|
v.vault,
|
|
@@ -9849,7 +9926,8 @@ program.command("lint [vault]").description("run all vault health checks").optio
|
|
|
9849
9926
|
only: opts.only,
|
|
9850
9927
|
summary: true,
|
|
9851
9928
|
examplesLimit: opts.examples
|
|
9852
|
-
})
|
|
9929
|
+
}),
|
|
9930
|
+
{ humanDetailHints }
|
|
9853
9931
|
);
|
|
9854
9932
|
else if (opts.fix) return emitGuardedVaultWrite(
|
|
9855
9933
|
v.vault,
|
|
@@ -9863,7 +9941,8 @@ program.command("lint [vault]").description("run all vault health checks").optio
|
|
|
9863
9941
|
fix: true,
|
|
9864
9942
|
only: opts.only,
|
|
9865
9943
|
summary: false
|
|
9866
|
-
})
|
|
9944
|
+
}),
|
|
9945
|
+
{ humanDetailHints }
|
|
9867
9946
|
);
|
|
9868
9947
|
else if (opts.summary) emit(await runLint({
|
|
9869
9948
|
vault: v.vault,
|
|
@@ -9875,7 +9954,7 @@ program.command("lint [vault]").description("run all vault health checks").optio
|
|
|
9875
9954
|
only: opts.only,
|
|
9876
9955
|
summary: true,
|
|
9877
9956
|
examplesLimit: opts.examples
|
|
9878
|
-
}), v.vault);
|
|
9957
|
+
}), v.vault, { humanDetailHints });
|
|
9879
9958
|
else emit(await runLint({
|
|
9880
9959
|
vault: v.vault,
|
|
9881
9960
|
source: vault ? "flag" : void 0,
|
|
@@ -9884,7 +9963,7 @@ program.command("lint [vault]").description("run all vault health checks").optio
|
|
|
9884
9963
|
logThreshold: opts.logThreshold,
|
|
9885
9964
|
fix: false,
|
|
9886
9965
|
only: opts.only
|
|
9887
|
-
}), v.vault);
|
|
9966
|
+
}), v.vault, { humanDetailHints });
|
|
9888
9967
|
});
|
|
9889
9968
|
program.command("health [vault]").description("bounded whole-system wiki health report").option("--wiki <name>", "wiki profile name").option("--sync <mode>", "vault-sync policy: optional|required|off", "optional").option("--no-fail", "always exit 0 while reporting status in JSON").option("--out <path>", "write JSON result envelope to this path").option("--examples <n>", "example count per lint bucket", (s) => parseInt(s, 10), 3).action(async (vault, opts) => {
|
|
9890
9969
|
const sync = String(opts.sync ?? "optional");
|
|
@@ -9905,7 +9984,7 @@ program.command("health [vault]").description("bounded whole-system wiki health
|
|
|
9905
9984
|
noFail: opts.fail === false,
|
|
9906
9985
|
out: opts.out,
|
|
9907
9986
|
examplesLimit: opts.examples
|
|
9908
|
-
}), void 0, { postCommit: false });
|
|
9987
|
+
}), void 0, { postCommit: false, humanDetailHints: healthLintDetailHints });
|
|
9909
9988
|
});
|
|
9910
9989
|
var configCmd = program.command("config").description("manage skillwiki configuration");
|
|
9911
9990
|
configCmd.command("get <key>").description("print the value of a config key").action(async (key) => emit(await runConfigGet({ key, home: process.env.HOME ?? "" })));
|
package/dist/skillwiki-mcp.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skillwiki",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.39",
|
|
4
4
|
"skills": "./",
|
|
5
5
|
"description": "Project-aware Karpathy-style knowledge base for Claude Code: 19 prompt-only skills (wiki-*, proj-*, using-skillwiki) backed by the deterministic `skillwiki` CLI.",
|
|
6
6
|
"author": {
|