skillwiki 0.2.0-beta.25 → 0.2.0-beta.27

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
@@ -796,6 +796,9 @@ var MARKER_RE = /\^\[(raw\/[^\]]+)\]/g;
796
796
  function stripFences(body) {
797
797
  return body.replace(FENCE2, "").replace(INLINE_CODE, "");
798
798
  }
799
+ function stripFencedBlocks(body) {
800
+ return body.replace(FENCE2, "");
801
+ }
799
802
  function extractCitationMarkers(body) {
800
803
  const stripped = stripFences(body);
801
804
  const out = [];
@@ -806,7 +809,7 @@ function extractCitationMarkers(body) {
806
809
  return out;
807
810
  }
808
811
  function hasSourcesFooter(body) {
809
- return /^## Sources\s*$/m.test(stripFences(body));
812
+ return /^## Sources\s*$/m.test(stripFencedBlocks(body));
810
813
  }
811
814
  function isLegacyCitationStyle(body) {
812
815
  const markers = extractCitationMarkers(body);
@@ -2337,6 +2340,71 @@ ${migratedBody}${newFooter}`;
2337
2340
  };
2338
2341
  }
2339
2342
 
2343
+ // src/commands/frontmatter-fix.ts
2344
+ import { writeFile as writeFile8 } from "fs/promises";
2345
+ function isoToday() {
2346
+ return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
2347
+ }
2348
+ function fixFrontmatter(rawFm) {
2349
+ const additions = [];
2350
+ if (!/^created:/m.test(rawFm)) additions.push(`created: ${isoToday()}`);
2351
+ if (!/^updated:/m.test(rawFm)) additions.push(`updated: ${isoToday()}`);
2352
+ if (!/^tags:/m.test(rawFm)) additions.push("tags: []");
2353
+ if (!/^sources:/m.test(rawFm)) additions.push("sources: []");
2354
+ if (!/^provenance:/m.test(rawFm)) additions.push("provenance: research");
2355
+ if (additions.length === 0) return rawFm;
2356
+ return rawFm.trimEnd() + "\n" + additions.join("\n") + "\n";
2357
+ }
2358
+ function removeOrphanTagsLines(body) {
2359
+ return body.split("\n").filter((line) => !/^tags:\s*\[/.test(line.trim())).join("\n");
2360
+ }
2361
+ async function runFrontmatterFix(input) {
2362
+ const scan = await scanVault(input.vault);
2363
+ if (!scan.ok) return { exitCode: ExitCode.VAULT_PATH_INVALID, result: scan };
2364
+ const fixed = [];
2365
+ const skipped = [];
2366
+ let unchanged = 0;
2367
+ for (const page of scan.data.typedKnowledge) {
2368
+ const text = await readPage(page);
2369
+ const split = splitFrontmatter(text);
2370
+ if (!split.ok) {
2371
+ skipped.push(page.relPath);
2372
+ continue;
2373
+ }
2374
+ const { rawFrontmatter, body } = split.data;
2375
+ const newFm = fixFrontmatter(rawFrontmatter);
2376
+ const newBody = removeOrphanTagsLines(body);
2377
+ const newText = `---
2378
+ ${newFm}
2379
+ ---
2380
+ ${newBody}`;
2381
+ if (newText === text) {
2382
+ unchanged++;
2383
+ continue;
2384
+ }
2385
+ if (!input.dryRun) {
2386
+ await writeFile8(page.absPath, newText, "utf8");
2387
+ }
2388
+ fixed.push(page.relPath);
2389
+ }
2390
+ const exitCode = fixed.length > 0 ? ExitCode.MIGRATION_APPLIED : ExitCode.OK;
2391
+ const hintLines = [`scanned: ${fixed.length + skipped.length + unchanged}`];
2392
+ if (fixed.length > 0) hintLines.push(`fixed: ${fixed.length}`);
2393
+ if (skipped.length > 0) hintLines.push(`skipped (parse error): ${skipped.length}`);
2394
+ if (unchanged > 0) hintLines.push(`unchanged: ${unchanged}`);
2395
+ if (input.dryRun && fixed.length > 0) hintLines.push("(dry run \u2014 no files written)");
2396
+ return {
2397
+ exitCode,
2398
+ result: ok({
2399
+ scanned: fixed.length + skipped.length + unchanged,
2400
+ fixed,
2401
+ skipped,
2402
+ unchanged,
2403
+ humanHint: hintLines.join("\n")
2404
+ })
2405
+ };
2406
+ }
2407
+
2340
2408
  // src/commands/update.ts
2341
2409
  import { execSync as execSync2 } from "child_process";
2342
2410
  import { readFileSync as readFileSync3 } from "fs";
@@ -2548,6 +2616,11 @@ program.command("migrate-citations [vault]").description("migrate ^[raw/...] mar
2548
2616
  if (!v.ok) emit({ exitCode: v.exitCode, result: v.payload });
2549
2617
  else emit(await runMigrateCitations({ vault: v.vault, dryRun: !!opts.dryRun }));
2550
2618
  });
2619
+ program.command("frontmatter-fix [vault]").description("fix common frontmatter issues on typed-knowledge pages").option("--dry-run", "preview changes without writing", false).option("--wiki <name>", "wiki profile name").action(async (vault, opts) => {
2620
+ const v = await resolveVaultArg(vault, opts.wiki);
2621
+ if (!v.ok) emit({ exitCode: v.exitCode, result: v.payload });
2622
+ else emit(await runFrontmatterFix({ vault: v.vault, dryRun: !!opts.dryRun }));
2623
+ });
2551
2624
  program.command("update").description("update skillwiki CLI to the latest version").option("--tag <tag>", "npm dist-tag", "beta").action(async (opts) => emit(await runUpdate({
2552
2625
  home: process.env.HOME ?? "",
2553
2626
  distTag: opts.tag
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skillwiki",
3
- "version": "0.2.0-beta.25",
3
+ "version": "0.2.0-beta.27",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "skillwiki": "dist/cli.js"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skillwiki",
3
- "version": "0.2.0-beta.25",
3
+ "version": "0.2.0-beta.27",
4
4
  "skills": "./",
5
5
  "description": "Project-aware Karpathy-style knowledge base for Claude Code: 11 prompt-only skills (wiki-*, proj-*, using-skillwiki) backed by the deterministic `skillwiki` CLI (8 subcommands, JSON-by-default).",
6
6
  "author": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skillwiki/skills",
3
- "version": "0.2.0-beta.25",
3
+ "version": "0.2.0-beta.27",
4
4
  "private": true,
5
5
  "files": [
6
6
  "wiki-*",