skillwiki 0.9.36 → 0.9.38

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.
@@ -1110,7 +1110,13 @@ async function runOrphans(input) {
1110
1110
  if (input.vault) {
1111
1111
  vault = input.vault;
1112
1112
  } else {
1113
- const r = await resolveRuntimePath({ flag: void 0, envValue: input.envValue, home: input.home ?? "", wiki: input.wiki });
1113
+ const r = await resolveRuntimePath({
1114
+ flag: void 0,
1115
+ envValue: input.envValue,
1116
+ home: input.home ?? "",
1117
+ wiki: input.wiki,
1118
+ cwd: input.cwd
1119
+ });
1114
1120
  if (!r.ok) {
1115
1121
  const exitCode = r.error === "UNKNOWN_WIKI_PROFILE" ? ExitCode.UNKNOWN_WIKI_PROFILE : ExitCode.NO_VAULT_CONFIGURED;
1116
1122
  return { exitCode, result: r };
@@ -6393,7 +6399,12 @@ async function runDoctor(input) {
6393
6399
  checks.push(await checkConfigFile(input.home));
6394
6400
  checks.push(await checkProfiles(input.home));
6395
6401
  checks.push(await checkProjectLocalOverride(input.cwd));
6396
- const resolved = await resolveRuntimePath({ flag: void 0, envValue: input.envValue, home: input.home });
6402
+ const resolved = await resolveRuntimePath({
6403
+ flag: void 0,
6404
+ envValue: input.envValue,
6405
+ home: input.home,
6406
+ cwd: input.cwd
6407
+ });
6397
6408
  if (resolved.ok) {
6398
6409
  checks.push(check("pass", "wiki_path_set", "WIKI_PATH configured", `Resolved via ${resolved.data.source}: ${resolved.data.path}`));
6399
6410
  } else {
@@ -7923,7 +7934,8 @@ async function resolveMcpVault(input) {
7923
7934
  envValue: process.env.WIKI_PATH,
7924
7935
  wikiEnv: process.env.WIKI,
7925
7936
  home,
7926
- wiki: input.wiki
7937
+ wiki: input.wiki,
7938
+ cwd: input.cwd ?? process.cwd()
7927
7939
  });
7928
7940
  if (!r.ok) return r;
7929
7941
  vaultPath = resolve7(r.data.path);
package/dist/cli.js CHANGED
@@ -75,7 +75,7 @@ import {
75
75
  triggerAutoUpdate,
76
76
  writeCache,
77
77
  writeDotenv
78
- } from "./chunk-TK4ZIQNE.js";
78
+ } from "./chunk-G52HKU7I.js";
79
79
  import {
80
80
  normalizeDistTag
81
81
  } from "./chunk-E6UWZ3S3.js";
@@ -425,6 +425,7 @@ async function runPath(input) {
425
425
  flag: input.flag,
426
426
  envValue: input.envValue,
427
427
  home: input.home,
428
+ cwd: input.cwd,
428
429
  explain: input.explain
429
430
  });
430
431
  return { exitCode: ExitCode.OK, result: ok({ path: r2.path, source: r2.source, ...r2.chain ? { chain: r2.chain } : {}, humanHint: `${r2.path} (via ${r2.source})` }) };
@@ -434,6 +435,7 @@ async function runPath(input) {
434
435
  envValue: input.envValue,
435
436
  home: input.home,
436
437
  wiki: input.wiki,
438
+ cwd: input.cwd,
437
439
  explain: input.explain
438
440
  });
439
441
  if (!r.ok) {
@@ -3303,6 +3305,7 @@ ${body}`;
3303
3305
  // src/commands/sync.ts
3304
3306
  import { existsSync as existsSync7 } from "fs";
3305
3307
  import { join as join18 } from "path";
3308
+ import { execFileSync as execFileSync2 } from "child_process";
3306
3309
 
3307
3310
  // src/utils/git.ts
3308
3311
  import { execFileSync } from "child_process";
@@ -3453,6 +3456,33 @@ function stageVaultContentChanges(vault) {
3453
3456
  }
3454
3457
 
3455
3458
  // src/commands/sync.ts
3459
+ function parseDirtyPaths(porcelain) {
3460
+ if (!porcelain) return [];
3461
+ return porcelain.split("\n").map((line) => line.trimEnd()).filter((line) => line.length >= 4).map((line) => {
3462
+ const payload = line.length >= 3 && line[2] === " " ? line.slice(3) : line.length >= 2 && line[1] === " " ? line.slice(2) : line;
3463
+ const arrow = payload.lastIndexOf(" -> ");
3464
+ return arrow >= 0 ? payload.slice(arrow + 4) : payload;
3465
+ }).filter((path) => path.length > 0);
3466
+ }
3467
+ function splitNonEmptyLines(text) {
3468
+ if (!text) return [];
3469
+ return text.split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
3470
+ }
3471
+ function isTrackedNotePath(path) {
3472
+ if (!path.endsWith(".md")) return false;
3473
+ return !/^\.(skillwiki|claude|obsidian|antigravitycli|playwright-cli)\//.test(path);
3474
+ }
3475
+ function refHasPath(vault, ref, path) {
3476
+ try {
3477
+ execFileSync2("git", ["cat-file", "-e", `${ref}:${path}`], {
3478
+ cwd: vault,
3479
+ stdio: ["pipe", "pipe", "pipe"]
3480
+ });
3481
+ return true;
3482
+ } catch {
3483
+ return false;
3484
+ }
3485
+ }
3456
3486
  function runSyncStatus(input) {
3457
3487
  const vault = input.vault;
3458
3488
  const includeStashes = input.includeStashes ?? false;
@@ -3464,6 +3494,8 @@ function runSyncStatus(input) {
3464
3494
  dirty: 0,
3465
3495
  ahead: 0,
3466
3496
  behind: 0,
3497
+ unpromoted_note_paths: 0,
3498
+ unpromoted_note_examples: [],
3467
3499
  last_commit: "never",
3468
3500
  status: "not_a_repo",
3469
3501
  humanHint: "not a git repository"
@@ -3473,6 +3505,8 @@ function runSyncStatus(input) {
3473
3505
  enableGitLongPathsOnWindows(vault);
3474
3506
  const porcelain = git(vault, ["status", "--porcelain"]);
3475
3507
  const dirty = porcelain ? porcelain.split("\n").filter((l) => l.trim().length > 0).length : 0;
3508
+ const dirtyPaths = parseDirtyPaths(porcelain);
3509
+ const untrackedPaths = splitNonEmptyLines(git(vault, ["ls-files", "--others", "--exclude-standard"]));
3476
3510
  const revOutput = git(vault, ["rev-list", "--left-right", "--count", "origin/HEAD...HEAD"]);
3477
3511
  let ahead = 0;
3478
3512
  let behind = 0;
@@ -3493,6 +3527,10 @@ function runSyncStatus(input) {
3493
3527
  } else {
3494
3528
  last_commit = "never";
3495
3529
  }
3530
+ const remoteRef = git(vault, ["rev-parse", "--verify", "origin/main"]) ? "origin/main" : git(vault, ["rev-parse", "--verify", "origin/HEAD"]) ? "origin/HEAD" : "HEAD";
3531
+ const unpromotedNoteAll = Array.from(/* @__PURE__ */ new Set([...dirtyPaths, ...untrackedPaths])).filter(isTrackedNotePath).filter((path) => !refHasPath(vault, remoteRef, path));
3532
+ const unpromotedNoteExamples = unpromotedNoteAll.slice(0, 5);
3533
+ const unpromotedNotePaths = unpromotedNoteAll.length;
3496
3534
  let status;
3497
3535
  if (dirty > 0) {
3498
3536
  status = "dirty";
@@ -3508,6 +3546,7 @@ function runSyncStatus(input) {
3508
3546
  `dirty: ${dirty}`,
3509
3547
  `ahead: ${ahead}`,
3510
3548
  `behind: ${behind}`,
3549
+ `unpromoted_note_paths: ${unpromotedNotePaths}`,
3511
3550
  `last_commit: ${last_commit}`
3512
3551
  ];
3513
3552
  const exitCode = status === "clean" ? ExitCode.OK : ExitCode.LINT_HAS_WARNINGS;
@@ -3520,6 +3559,8 @@ function runSyncStatus(input) {
3520
3559
  dirty,
3521
3560
  ahead,
3522
3561
  behind,
3562
+ unpromoted_note_paths: unpromotedNotePaths,
3563
+ unpromoted_note_examples: unpromotedNoteExamples,
3523
3564
  last_commit,
3524
3565
  status,
3525
3566
  humanHint: hintLines.join("\n")
@@ -4849,7 +4890,8 @@ program.command("orphans [vault]").description("find pages not referenced by any
4849
4890
  vault,
4850
4891
  envValue: process.env.WIKI_PATH,
4851
4892
  home: process.env.HOME ?? "",
4852
- wiki: opts.wiki
4893
+ wiki: opts.wiki,
4894
+ cwd: process.cwd()
4853
4895
  })));
4854
4896
  program.command("audit <file>").description("audit citation markers and source provenance for a vault page").action(async (file) => emit(await runAudit({ file })));
4855
4897
  program.command("install").description("install skillwiki SKILL.md files into ~/.claude/skills/").option("--target <dir>", "target install directory", `${process.env.HOME ?? ""}/.claude/skills/`).option("--dry-run", "preview only", false).option("--skills-root <dir>", "source skills directory (defaults to packaged)").option("--symlink", "create symlinks instead of copies (dev mode \u2014 edits to source are immediately visible)", false).option("--force", "install CLI copies even when the skillwiki@llm-wiki plugin channel is active", false).action(async (opts) => {
@@ -4865,6 +4907,7 @@ program.command("path").description("show the resolved vault path").option("--va
4865
4907
  home: process.env.HOME ?? "",
4866
4908
  initTime,
4867
4909
  wiki: opts.wiki,
4910
+ cwd: process.cwd(),
4868
4911
  explain: !!opts.explain
4869
4912
  }));
4870
4913
  });
@@ -4899,7 +4942,8 @@ async function resolveVaultArg(arg, wiki) {
4899
4942
  envValue: process.env.WIKI_PATH,
4900
4943
  wikiEnv: process.env.WIKI,
4901
4944
  home: process.env.HOME ?? "",
4902
- wiki
4945
+ wiki,
4946
+ cwd: process.cwd()
4903
4947
  });
4904
4948
  if (!r.ok) {
4905
4949
  const exitCode = r.error === "UNKNOWN_WIKI_PROFILE" ? 35 : 25;
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runSkillwikiMcpStdio
4
- } from "./chunk-TK4ZIQNE.js";
4
+ } from "./chunk-G52HKU7I.js";
5
5
  import "./chunk-E6UWZ3S3.js";
6
6
 
7
7
  // src/mcp-entry.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skillwiki",
3
- "version": "0.9.36",
3
+ "version": "0.9.38",
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.36",
3
+ "version": "0.9.38",
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.36",
3
+ "version": "0.9.38",
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.36",
3
+ "version": "0.9.38",
4
4
  "private": true,
5
5
  "files": [
6
6
  "wiki-*",
@@ -124,7 +124,9 @@ Key CLI subcommands: `init`, `health`, `lint`, `config`, `doctor`, `path`, `lang
124
124
  Run `skillwiki health <vault> --out /tmp/skillwiki-health.json --no-fail` for a bounded whole-system report that includes doctor, lint, vault-sync, query-readiness, source-freshness, risk flags, and self-check coverage. Run `skillwiki lint <vault> --summary` for lint-only bucket counts with capped examples and details commands. Run `skillwiki doctor` to diagnose setup/runtime issues only. Run `skillwiki config list` to see current configuration.
125
125
 
126
126
  ## Runtime Host Context and Fleet Freshness
127
- The live output of `skillwiki --human fleet context <vault>` is authoritative for host identity. It overrides stale injected SessionStart context, remembered workspace context, and prior conversation summaries. `fleet context` is local and network-free; it reports `identity_status`, resolver trace, warnings, and the fact that remote freshness was not checked.
127
+ Resolve the active project vault with `skillwiki path` first. Then pass that exact path to `skillwiki --human fleet context <vault>` for host identity and safety guidance. `fleet context` is authoritative for host identity. It overrides stale injected SessionStart context, remembered workspace context, and prior conversation summaries. `fleet context` is local and network-free; it reports `identity_status`, resolver trace, warnings, and the fact that remote freshness was not checked.
128
+
129
+ Do not substitute infrastructure mirrors such as `~/wiki-git` or other snapshot worktrees for the project vault just to inspect fleet status. Those paths are snapshot infrastructure unless `skillwiki path` itself resolves there.
128
130
 
129
131
  Use the local identity check for ordinary runtime context:
130
132
  ```bash
@@ -182,6 +182,8 @@ Some deployments use a cloud-backed vault (`rclone mount`) with a separate git r
182
182
  ~/wiki-git → git repository cloned from GitHub — snapshot target
183
183
  cron hourly → rsync ~/wiki/ → ~/wiki-git/ → git commit → git push
184
184
  ```
185
+ On snapshotter hosts, `~/wiki` remains the active SkillWiki vault for path resolution unless the operator explicitly configures otherwise. `~/wiki-git` is snapshot infrastructure, not the default authoring or dev-loop vault. Do not point project work or `fleet context` at `~/wiki-git` unless `skillwiki path` intentionally resolves there.
186
+
185
187
  ### Implementation (wiki-snapshot.sh)
186
188
  ```bash
187
189
  #!/bin/bash
@@ -124,7 +124,9 @@ Key CLI subcommands: `init`, `health`, `lint`, `config`, `doctor`, `path`, `lang
124
124
  Run `skillwiki health <vault> --out /tmp/skillwiki-health.json --no-fail` for a bounded whole-system report that includes doctor, lint, vault-sync, query-readiness, source-freshness, risk flags, and self-check coverage. Run `skillwiki lint <vault> --summary` for lint-only bucket counts with capped examples and details commands. Run `skillwiki doctor` to diagnose setup/runtime issues only. Run `skillwiki config list` to see current configuration.
125
125
 
126
126
  ## Runtime Host Context and Fleet Freshness
127
- The live output of `skillwiki --human fleet context <vault>` is authoritative for host identity. It overrides stale injected SessionStart context, remembered workspace context, and prior conversation summaries. `fleet context` is local and network-free; it reports `identity_status`, resolver trace, warnings, and the fact that remote freshness was not checked.
127
+ Resolve the active project vault with `skillwiki path` first. Then pass that exact path to `skillwiki --human fleet context <vault>` for host identity and safety guidance. `fleet context` is authoritative for host identity. It overrides stale injected SessionStart context, remembered workspace context, and prior conversation summaries. `fleet context` is local and network-free; it reports `identity_status`, resolver trace, warnings, and the fact that remote freshness was not checked.
128
+
129
+ Do not substitute infrastructure mirrors such as `~/wiki-git` or other snapshot worktrees for the project vault just to inspect fleet status. Those paths are snapshot infrastructure unless `skillwiki path` itself resolves there.
128
130
 
129
131
  Use the local identity check for ordinary runtime context:
130
132
  ```bash
@@ -182,6 +182,8 @@ Some deployments use a cloud-backed vault (`rclone mount`) with a separate git r
182
182
  ~/wiki-git → git repository cloned from GitHub — snapshot target
183
183
  cron hourly → rsync ~/wiki/ → ~/wiki-git/ → git commit → git push
184
184
  ```
185
+ On snapshotter hosts, `~/wiki` remains the active SkillWiki vault for path resolution unless the operator explicitly configures otherwise. `~/wiki-git` is snapshot infrastructure, not the default authoring or dev-loop vault. Do not point project work or `fleet context` at `~/wiki-git` unless `skillwiki path` intentionally resolves there.
186
+
185
187
  ### Implementation (wiki-snapshot.sh)
186
188
  ```bash
187
189
  #!/bin/bash