skillwiki 0.2.1-beta.4 → 0.2.1-beta.6
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 +54 -3
- package/package.json +1 -1
- package/skills/.claude-plugin/plugin.json +1 -1
- package/skills/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -2248,11 +2248,25 @@ async function runDrift(input) {
|
|
|
2248
2248
|
const scan = await scanVault(input.vault);
|
|
2249
2249
|
if (!scan.ok) return { exitCode: ExitCode.VAULT_PATH_INVALID, result: scan };
|
|
2250
2250
|
const results = [];
|
|
2251
|
+
const newResults = [];
|
|
2251
2252
|
for (const raw of scan.data.raw) {
|
|
2252
2253
|
const text = await readPage(raw);
|
|
2253
2254
|
const split = splitFrontmatter(text);
|
|
2254
2255
|
if (!split.ok) continue;
|
|
2255
2256
|
const { rawFrontmatter, body } = split.data;
|
|
2257
|
+
const ingestedMatch = rawFrontmatter.match(/^ingested:\s*(.+)$/m);
|
|
2258
|
+
const ingestedRaw = ingestedMatch?.[1]?.trim() ?? "";
|
|
2259
|
+
const ingested = ingestedRaw.replace(/^["']|["']$/g, "");
|
|
2260
|
+
if (input.newSince && ingested && ingested >= input.newSince) {
|
|
2261
|
+
newResults.push({
|
|
2262
|
+
raw_path: raw.relPath,
|
|
2263
|
+
source_url: "",
|
|
2264
|
+
stored_sha256: "",
|
|
2265
|
+
current_sha256: null,
|
|
2266
|
+
status: "new",
|
|
2267
|
+
ingested
|
|
2268
|
+
});
|
|
2269
|
+
}
|
|
2256
2270
|
const sourceUrlMatch = rawFrontmatter.match(/^source_url:\s*(.+)$/m);
|
|
2257
2271
|
const storedHashMatch = rawFrontmatter.match(/^sha256:\s*([a-f0-9]+)$/m);
|
|
2258
2272
|
if (!sourceUrlMatch || !storedHashMatch) continue;
|
|
@@ -2302,12 +2316,13 @@ ${body}`;
|
|
|
2302
2316
|
const unchanged = results.filter((r) => r.status === "unchanged").length;
|
|
2303
2317
|
const exitCode = drifted.length > 0 ? ExitCode.DRIFT_DETECTED : ExitCode.OK;
|
|
2304
2318
|
const hintLines = [`scanned: ${results.length}, unchanged: ${unchanged}`];
|
|
2319
|
+
if (newResults.length > 0) hintLines.push(`new: ${newResults.length}`, ...newResults.map((n) => ` ${n.raw_path} (ingested: ${n.ingested})`));
|
|
2305
2320
|
if (drifted.length > 0) hintLines.push(`drifted: ${drifted.length}`, ...drifted.map((d) => ` ${d.raw_path}`));
|
|
2306
2321
|
if (fetchFailed.length > 0) hintLines.push(`fetch_failed: ${fetchFailed.length}`, ...fetchFailed.map((f) => ` ${f.raw_path}: ${f.fetch_error}`));
|
|
2307
2322
|
if (updated.length > 0) hintLines.push(`updated: ${updated.length}`, ...updated.map((u) => ` ${u.raw_path}`));
|
|
2308
2323
|
return {
|
|
2309
2324
|
exitCode,
|
|
2310
|
-
result: ok({ scanned: results.length, drifted, fetch_failed: fetchFailed, updated, unchanged, humanHint: hintLines.join("\n") })
|
|
2325
|
+
result: ok({ scanned: results.length, drifted, fetch_failed: fetchFailed, updated, newFiles: newResults, unchanged, humanHint: hintLines.join("\n") })
|
|
2311
2326
|
};
|
|
2312
2327
|
}
|
|
2313
2328
|
|
|
@@ -2582,6 +2597,37 @@ async function runUpdate(input) {
|
|
|
2582
2597
|
};
|
|
2583
2598
|
}
|
|
2584
2599
|
|
|
2600
|
+
// src/commands/transcripts.ts
|
|
2601
|
+
import { readdir as readdir4, stat as stat6, readFile as readFile14 } from "fs/promises";
|
|
2602
|
+
import { join as join19 } from "path";
|
|
2603
|
+
async function runTranscripts(input) {
|
|
2604
|
+
const dir = join19(input.vault, "raw", "transcripts");
|
|
2605
|
+
let entries;
|
|
2606
|
+
try {
|
|
2607
|
+
entries = await readdir4(dir, { withFileTypes: true });
|
|
2608
|
+
} catch {
|
|
2609
|
+
return { exitCode: ExitCode.VAULT_PATH_INVALID, result: { ok: false, error: "VAULT_PATH_INVALID", detail: `raw/transcripts/ not found: ${dir}` } };
|
|
2610
|
+
}
|
|
2611
|
+
const transcripts = [];
|
|
2612
|
+
for (const entry of entries) {
|
|
2613
|
+
if (!entry.isFile() || !entry.name.endsWith(".md")) continue;
|
|
2614
|
+
const filePath = join19(dir, entry.name);
|
|
2615
|
+
const content = await readFile14(filePath, "utf8");
|
|
2616
|
+
const fm = extractFrontmatter(content);
|
|
2617
|
+
if (!fm.ok) continue;
|
|
2618
|
+
const ingested = typeof fm.data.ingested === "string" ? fm.data.ingested : "";
|
|
2619
|
+
if (input.since && ingested && ingested < input.since) continue;
|
|
2620
|
+
const s = await stat6(filePath);
|
|
2621
|
+
transcripts.push({
|
|
2622
|
+
file: `raw/transcripts/${entry.name}`,
|
|
2623
|
+
ingested,
|
|
2624
|
+
size: s.size
|
|
2625
|
+
});
|
|
2626
|
+
}
|
|
2627
|
+
const hint = transcripts.length > 0 ? transcripts.map((t) => `${t.file} (ingested: ${t.ingested || "unknown"}, ${t.size}B)`).join("\n") : "no transcript files found";
|
|
2628
|
+
return { exitCode: ExitCode.OK, result: ok({ transcripts, humanHint: hint }) };
|
|
2629
|
+
}
|
|
2630
|
+
|
|
2585
2631
|
// src/cli.ts
|
|
2586
2632
|
var pkg = JSON.parse(readFileSync5(new URL("../package.json", import.meta.url), "utf8"));
|
|
2587
2633
|
var program = new Command();
|
|
@@ -2717,10 +2763,10 @@ program.command("archive <page> [vault]").description("archive a typed-knowledge
|
|
|
2717
2763
|
if (!v.ok) emit({ exitCode: v.exitCode, result: v.payload });
|
|
2718
2764
|
else emit(await runArchive({ vault: v.vault, page }));
|
|
2719
2765
|
});
|
|
2720
|
-
program.command("drift [vault]").description("detect content drift in raw sources").option("--apply", "update sha256 in drifted sources").option("--wiki <name>", "wiki profile name").action(async (vault, opts) => {
|
|
2766
|
+
program.command("drift [vault]").description("detect content drift in raw sources").option("--apply", "update sha256 in drifted sources").option("--new <date>", "list raw files ingested on/after this date (YYYY-MM-DD)").option("--wiki <name>", "wiki profile name").action(async (vault, opts) => {
|
|
2721
2767
|
const v = await resolveVaultArg(vault, opts.wiki);
|
|
2722
2768
|
if (!v.ok) emit({ exitCode: v.exitCode, result: v.payload });
|
|
2723
|
-
else emit(await runDrift({ vault: v.vault, apply: opts.apply }));
|
|
2769
|
+
else emit(await runDrift({ vault: v.vault, apply: opts.apply, newSince: opts.new }));
|
|
2724
2770
|
});
|
|
2725
2771
|
program.command("dedup [vault]").description("detect duplicate raw sources by sha256").option("--apply", "rewire citations and remove duplicate raw files", false).option("--wiki <name>", "wiki profile name").action(async (vault, opts) => {
|
|
2726
2772
|
const v = await resolveVaultArg(vault, opts.wiki);
|
|
@@ -2741,6 +2787,11 @@ program.command("update").description("update skillwiki CLI to the latest versio
|
|
|
2741
2787
|
home: process.env.HOME ?? "",
|
|
2742
2788
|
distTag: opts.tag
|
|
2743
2789
|
})));
|
|
2790
|
+
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) => {
|
|
2791
|
+
const v = await resolveVaultArg(vault, opts.wiki);
|
|
2792
|
+
if (!v.ok) emit({ exitCode: v.exitCode, result: v.payload });
|
|
2793
|
+
else emit(await runTranscripts({ vault: v.vault, since: opts.since }));
|
|
2794
|
+
});
|
|
2744
2795
|
triggerAutoUpdate(process.env.HOME ?? "", pkg.version);
|
|
2745
2796
|
program.parseAsync(process.argv).catch((e) => {
|
|
2746
2797
|
process.stdout.write(JSON.stringify({ ok: false, error: "INTERNAL", detail: { message: String(e) } }) + "\n");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skillwiki",
|
|
3
|
-
"version": "0.2.1-beta.
|
|
3
|
+
"version": "0.2.1-beta.6",
|
|
4
4
|
"skills": "./",
|
|
5
5
|
"description": "Project-aware Karpathy-style knowledge base for Claude Code: 15 prompt-only skills (wiki-*, proj-*, using-skillwiki) backed by the deterministic `skillwiki` CLI.",
|
|
6
6
|
"author": {
|