skillwiki 0.9.19 → 0.9.20

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
@@ -2866,9 +2866,9 @@ ${content}
2866
2866
 
2867
2867
  // src/commands/lint.ts
2868
2868
  import { existsSync as existsSync6 } from "fs";
2869
- import { readFile as readFile17 } from "fs/promises";
2869
+ import { readFile as readFile17, readdir as readdir5 } from "fs/promises";
2870
2870
  import { createHash as createHash5 } from "crypto";
2871
- import { join as join23 } from "path";
2871
+ import { join as join23, relative as relative3, sep as sep3 } from "path";
2872
2872
 
2873
2873
  // src/commands/sparse-community.ts
2874
2874
  async function runSparseCommunity(input) {
@@ -3714,6 +3714,7 @@ var ERROR_ORDER = ["sensitive_content", "broken_wikilinks", "invalid_frontmatter
3714
3714
  var WARNING_ORDER = ["raw_body_duplicate", "raw_subdirectory_duplicate", "file_source_url", "index_incomplete", "index_link_format", "stale_page", "page_too_large", "log_rotate_needed", "orphans", "compound_refs", "legacy_citation_style", "orphaned_citations", "duplicate_frontmatter", "work_item_health", "orphaned_project_pages", "missing_overview", "missing_diagram"];
3715
3715
  var INFO_ORDER = ["bridges", "sparse_community", "page_structure", "topic_map_recommended", "frontmatter_wikilink", "wikilink_citation", "missing_tldr", "stale_sections", "cli_refs"];
3716
3716
  var KNOWN_BUCKETS = [...ERROR_ORDER, ...WARNING_ORDER, ...INFO_ORDER];
3717
+ var CLI_REFS_TYPED_DIRS = ["entities", "concepts", "comparisons", "queries", "meta"];
3717
3718
  function shellQuote(value) {
3718
3719
  return `'${value.replace(/'/g, `'\\''`)}'`;
3719
3720
  }
@@ -3786,6 +3787,63 @@ function summarizeLintOutput(output, examplesLimit = 3) {
3786
3787
  humanHint: lines.join("\n")
3787
3788
  };
3788
3789
  }
3790
+ async function walkMarkdownFiles(absDir, vaultRoot) {
3791
+ const entries = await readdir5(absDir, { withFileTypes: true });
3792
+ const pages = [];
3793
+ for (const entry of entries) {
3794
+ const absPath = join23(absDir, entry.name);
3795
+ if (entry.isDirectory()) {
3796
+ if (entry.name === ".git" || entry.name === "node_modules") continue;
3797
+ pages.push(...await walkMarkdownFiles(absPath, vaultRoot));
3798
+ } else if (entry.isFile() && entry.name.endsWith(".md")) {
3799
+ pages.push({ absPath, relPath: relative3(vaultRoot, absPath).split(sep3).join("/") });
3800
+ }
3801
+ }
3802
+ return pages;
3803
+ }
3804
+ async function collectCliRefsPages(vault) {
3805
+ if (!existsSync6(join23(vault, "SCHEMA.md"))) {
3806
+ return err("VAULT_PATH_INVALID", { root: vault, reason: "SCHEMA.md missing" });
3807
+ }
3808
+ const pages = [];
3809
+ for (const dir of CLI_REFS_TYPED_DIRS) {
3810
+ const absDir = join23(vault, dir);
3811
+ if (!existsSync6(absDir)) continue;
3812
+ pages.push(...await walkMarkdownFiles(absDir, vault));
3813
+ }
3814
+ return ok(pages);
3815
+ }
3816
+ async function runCliRefsOnly(input) {
3817
+ const pages = await collectCliRefsPages(input.vault);
3818
+ if (!pages.ok) {
3819
+ return { exitCode: ExitCode.VAULT_PATH_INVALID, result: pages };
3820
+ }
3821
+ const cliRefFlags = [];
3822
+ const cliSurface = buildCliSurface();
3823
+ for (const page of pages.data) {
3824
+ const text = await readPage(page);
3825
+ const violations = validateCliRefs(text, page.relPath, cliSurface);
3826
+ for (const v of violations) {
3827
+ cliRefFlags.push(`${v.page}: ${v.ref} (${v.reason})`);
3828
+ }
3829
+ }
3830
+ const infoOut = cliRefFlags.length > 0 ? [{ kind: "cli_refs", items: cliRefFlags }] : [];
3831
+ const summary = { errors: 0, warnings: 0, info: cliRefFlags.length };
3832
+ const exitCode = cliRefFlags.length > 0 ? ExitCode.LINT_HAS_WARNINGS : ExitCode.OK;
3833
+ const output = {
3834
+ vault: { path: input.vault, source: input.source ?? "resolved" },
3835
+ summary,
3836
+ by_severity: { error: [], warning: [], info: infoOut },
3837
+ fixed: [],
3838
+ unresolved: [],
3839
+ humanHint: `--only cli_refs
3840
+ ${cliRefFlags.length === 0 ? "0 violations" : ` cli_refs: ${cliRefFlags.length}`}`
3841
+ };
3842
+ return {
3843
+ exitCode,
3844
+ result: ok(input.summary ? summarizeLintOutput(output, input.examplesLimit) : output)
3845
+ };
3846
+ }
3789
3847
  async function runLint(input) {
3790
3848
  if (input.only && !KNOWN_BUCKETS.includes(input.only)) {
3791
3849
  return {
@@ -3793,6 +3851,9 @@ async function runLint(input) {
3793
3851
  result: { ok: false, error: "UNKNOWN_BUCKET", detail: `Unknown bucket "${input.only}". Valid: ${KNOWN_BUCKETS.join(", ")}` }
3794
3852
  };
3795
3853
  }
3854
+ if (input.only === "cli_refs") {
3855
+ return runCliRefsOnly(input);
3856
+ }
3796
3857
  const shouldFix = (bucket) => !!input.fix && (!input.only || input.only === bucket);
3797
3858
  const buckets = {};
3798
3859
  const fixed = [];
@@ -8001,13 +8062,13 @@ async function runSelfUpdate(input) {
8001
8062
  }
8002
8063
 
8003
8064
  // src/commands/transcripts.ts
8004
- import { readdir as readdir5, stat as stat8, readFile as readFile22 } from "fs/promises";
8065
+ import { readdir as readdir6, stat as stat8, readFile as readFile22 } from "fs/promises";
8005
8066
  import { join as join34 } from "path";
8006
8067
  async function runTranscripts(input) {
8007
8068
  const dir = join34(input.vault, "raw", "transcripts");
8008
8069
  let entries;
8009
8070
  try {
8010
- entries = await readdir5(dir, { withFileTypes: true });
8071
+ entries = await readdir6(dir, { withFileTypes: true });
8011
8072
  } catch {
8012
8073
  return { exitCode: ExitCode.VAULT_PATH_INVALID, result: { ok: false, error: "VAULT_PATH_INVALID", detail: `raw/transcripts/ not found: ${dir}` } };
8013
8074
  }
@@ -8032,14 +8093,14 @@ async function runTranscripts(input) {
8032
8093
  }
8033
8094
 
8034
8095
  // src/commands/project-index.ts
8035
- import { readdir as readdir6, readFile as readFile23, writeFile as writeFile11, mkdir as mkdir10 } from "fs/promises";
8096
+ import { readdir as readdir7, readFile as readFile23, writeFile as writeFile11, mkdir as mkdir10 } from "fs/promises";
8036
8097
  import { join as join35, dirname as dirname13 } from "path";
8037
8098
  var LAYER2_DIRS = ["entities", "concepts", "comparisons", "queries", "meta"];
8038
8099
  async function runProjectIndex(input) {
8039
8100
  const slug = input.slug;
8040
8101
  const projectDir = join35(input.vault, "projects", slug);
8041
8102
  try {
8042
- await readdir6(projectDir);
8103
+ await readdir7(projectDir);
8043
8104
  } catch {
8044
8105
  return {
8045
8106
  exitCode: ExitCode.PROJECT_NOT_FOUND,
@@ -8050,7 +8111,7 @@ async function runProjectIndex(input) {
8050
8111
  const entries = [];
8051
8112
  const compoundDir = join35(input.vault, "projects", slug, "compound");
8052
8113
  try {
8053
- const compoundFiles = await readdir6(compoundDir, { withFileTypes: true });
8114
+ const compoundFiles = await readdir7(compoundDir, { withFileTypes: true });
8054
8115
  for (const entry of compoundFiles) {
8055
8116
  if (!entry.isFile() || !entry.name.endsWith(".md")) continue;
8056
8117
  const filePath = join35(compoundDir, entry.name);
@@ -8073,7 +8134,7 @@ async function runProjectIndex(input) {
8073
8134
  for (const dir of LAYER2_DIRS) {
8074
8135
  let files;
8075
8136
  try {
8076
- files = await readdir6(join35(input.vault, dir), { withFileTypes: true });
8137
+ files = await readdir7(join35(input.vault, dir), { withFileTypes: true });
8077
8138
  } catch {
8078
8139
  continue;
8079
8140
  }
@@ -8176,7 +8237,7 @@ ${entries.map((e) => ` ${e.type}: [[${e.page.replace(/\.md$/, "")}]] \u2014 ${e
8176
8237
  }
8177
8238
 
8178
8239
  // src/commands/compound.ts
8179
- import { writeFile as writeFile12, mkdir as mkdir11, readdir as readdir7, unlink as unlink4 } from "fs/promises";
8240
+ import { writeFile as writeFile12, mkdir as mkdir11, readdir as readdir8, unlink as unlink4 } from "fs/promises";
8180
8241
  import { join as join36 } from "path";
8181
8242
  import { existsSync as existsSync14 } from "fs";
8182
8243
  import { readFile as readFile24 } from "fs/promises";
@@ -8413,7 +8474,7 @@ no compound directory found`
8413
8474
  }
8414
8475
  let dirents;
8415
8476
  try {
8416
- dirents = await readdir7(compoundDir, { withFileTypes: true });
8477
+ dirents = await readdir8(compoundDir, { withFileTypes: true });
8417
8478
  } catch {
8418
8479
  return {
8419
8480
  exitCode: ExitCode.OK,
@@ -8545,7 +8606,7 @@ ${input.text.trim()}
8545
8606
 
8546
8607
  // src/commands/session-brief.ts
8547
8608
  import { mkdir as mkdir13, readFile as readFile25, writeFile as writeFile14 } from "fs/promises";
8548
- import { join as join38, relative as relative3, sep as sep3 } from "path";
8609
+ import { join as join38, relative as relative4, sep as sep4 } from "path";
8549
8610
  var MAX_WORDS = 900;
8550
8611
  async function runSessionBrief(input) {
8551
8612
  const scan = await scanVault(input.vault);
@@ -8649,7 +8710,7 @@ async function readProjectSlug(file) {
8649
8710
  return void 0;
8650
8711
  }
8651
8712
  function inferProjectFromPath(vault, cwd) {
8652
- const rel = relative3(vault, cwd).split(sep3).join("/");
8713
+ const rel = relative4(vault, cwd).split(sep4).join("/");
8653
8714
  const match = rel.match(/^projects\/([^/]+)(?:\/|$)/);
8654
8715
  return match?.[1];
8655
8716
  }
@@ -8938,8 +8999,8 @@ function dateFromPath(path) {
8938
8999
 
8939
9000
  // src/commands/memory.ts
8940
9001
  import { createHash as createHash8 } from "crypto";
8941
- import { mkdir as mkdir14, readFile as readFile26, readdir as readdir8, stat as stat9, writeFile as writeFile15 } from "fs/promises";
8942
- import { basename as basename2, extname, join as join39, relative as relative4, sep as sep4 } from "path";
9002
+ import { mkdir as mkdir14, readFile as readFile26, readdir as readdir9, stat as stat9, writeFile as writeFile15 } from "fs/promises";
9003
+ import { basename as basename2, extname, join as join39, relative as relative5, sep as sep5 } from "path";
8943
9004
  async function runMemoryTopics(input) {
8944
9005
  const scan = await scanVault(input.vault);
8945
9006
  if (!scan.ok) return { exitCode: ExitCode.VAULT_PATH_INVALID, result: scan };
@@ -9126,7 +9187,7 @@ async function collectImportFiles(source) {
9126
9187
  return files.sort((a, b) => a.localeCompare(b));
9127
9188
  }
9128
9189
  async function walkImportFiles(dir, out) {
9129
- const entries = await readdir8(dir, { withFileTypes: true });
9190
+ const entries = await readdir9(dir, { withFileTypes: true });
9130
9191
  for (const entry of entries) {
9131
9192
  if (entry.name === ".git" || entry.name === "node_modules") continue;
9132
9193
  const path = join39(dir, entry.name);
@@ -9179,7 +9240,7 @@ async function buildImportEntry(file, sourceRoot, project, today, maxBytes) {
9179
9240
  const redacted = redactSensitiveContent(extracted, { file });
9180
9241
  const privacy = redacted.findings.length > 0 ? "sensitive" : "local";
9181
9242
  const sourceSlug = slugify3(basename2(file, extname(file)));
9182
- const relSource = relative4(sourceRoot, file).split(sep4).join("/");
9243
+ const relSource = relative5(sourceRoot, file).split(sep5).join("/");
9183
9244
  const entry = {
9184
9245
  ...baseEntry,
9185
9246
  status: "ready",
@@ -9251,7 +9312,7 @@ function hiddenString(entry, key) {
9251
9312
  return entry[key] ?? "";
9252
9313
  }
9253
9314
  function classifyImportSource(file) {
9254
- const rel = file.split(sep4).join("/");
9315
+ const rel = file.split(sep5).join("/");
9255
9316
  const name = basename2(file);
9256
9317
  if (rel.includes("/.codex/memories/")) return "codex-memory";
9257
9318
  if (rel.includes("/.codex/rules/")) return "codex-rule";
@@ -10498,7 +10559,7 @@ function runSyncUnlock(input) {
10498
10559
 
10499
10560
  // src/commands/backup.ts
10500
10561
  import { statSync as statSync5, readdirSync as readdirSync3, readFileSync as readFileSync12, mkdirSync as mkdirSync7, writeFileSync as writeFileSync8 } from "fs";
10501
- import { join as join43, relative as relative5, dirname as dirname14 } from "path";
10562
+ import { join as join43, relative as relative6, dirname as dirname14 } from "path";
10502
10563
  import { PutObjectCommand, HeadObjectCommand, ListObjectsV2Command, GetObjectCommand, DeleteObjectsCommand } from "@aws-sdk/client-s3";
10503
10564
 
10504
10565
  // src/utils/s3-client.ts
@@ -10526,7 +10587,7 @@ function* walkMarkdown(dir, base) {
10526
10587
  if (entry.isDirectory()) {
10527
10588
  yield* walkMarkdown(full, base);
10528
10589
  } else if (entry.name.endsWith(".md")) {
10529
- yield relative5(base, full).replace(/\\/g, "/");
10590
+ yield relative6(base, full).replace(/\\/g, "/");
10530
10591
  }
10531
10592
  }
10532
10593
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skillwiki",
3
- "version": "0.9.19",
3
+ "version": "0.9.20",
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.9.19",
3
+ "version": "0.9.20",
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": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skillwiki",
3
- "version": "0.9.19",
3
+ "version": "0.9.20",
4
4
  "description": "Project-aware Karpathy-style knowledge base for Codex with 18 prompt-only skills backed by the deterministic skillwiki CLI.",
5
5
  "author": {
6
6
  "name": "karlorz",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skillwiki/skills",
3
- "version": "0.9.19",
3
+ "version": "0.9.20",
4
4
  "private": true,
5
5
  "files": [
6
6
  "wiki-*",