skillwiki 0.10.64 → 0.10.67

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.
@@ -5803,6 +5803,17 @@ async function runVaultSyncPullHelper(input) {
5803
5803
  }
5804
5804
 
5805
5805
  // src/commands/sync.ts
5806
+ function countAheadBehind(vault) {
5807
+ const revOutput = git(vault, ["rev-list", "--left-right", "--count", "origin/HEAD...HEAD"]);
5808
+ let ahead = 0;
5809
+ let behind = 0;
5810
+ if (revOutput) {
5811
+ const parts = revOutput.split(/\s+/);
5812
+ behind = parseInt(parts[0], 10) || 0;
5813
+ ahead = parseInt(parts[1], 10) || 0;
5814
+ }
5815
+ return { ahead, behind };
5816
+ }
5806
5817
  function parseDirtyPaths(porcelain) {
5807
5818
  if (!porcelain) return [];
5808
5819
  return porcelain.split("\n").map((line) => line.trimEnd()).filter((line) => line.length >= 4).map((line) => {
@@ -5854,14 +5865,7 @@ function runSyncStatus(input) {
5854
5865
  const dirty = porcelain ? porcelain.split("\n").filter((l) => l.trim().length > 0).length : 0;
5855
5866
  const dirtyPaths = parseDirtyPaths(porcelain);
5856
5867
  const untrackedPaths = splitNonEmptyLines(git(vault, ["ls-files", "--others", "--exclude-standard"]));
5857
- const revOutput = git(vault, ["rev-list", "--left-right", "--count", "origin/HEAD...HEAD"]);
5858
- let ahead = 0;
5859
- let behind = 0;
5860
- if (revOutput) {
5861
- const parts = revOutput.split(/\s+/);
5862
- behind = parseInt(parts[0], 10) || 0;
5863
- ahead = parseInt(parts[1], 10) || 0;
5864
- }
5868
+ const { ahead, behind } = countAheadBehind(vault);
5865
5869
  const tsRaw = git(vault, ["log", "-1", "--format=%ct"]);
5866
5870
  let last_commit;
5867
5871
  if (tsRaw) {
@@ -5961,14 +5965,91 @@ async function runSyncPush(input) {
5961
5965
  const porcelain = git(vault, ["status", "--porcelain"]);
5962
5966
  const dirtyFiles = porcelain ? porcelain.split("\n").filter((l) => l.trim().length > 0) : [];
5963
5967
  if (dirtyFiles.length === 0) {
5968
+ const { ahead } = countAheadBehind(vault);
5969
+ if (ahead === 0) {
5970
+ return {
5971
+ exitCode: ExitCode.OK,
5972
+ result: ok({
5973
+ files_committed: 0,
5974
+ commit_message: "",
5975
+ pushed: false,
5976
+ path_fixes: pathFixes,
5977
+ humanHint: "nothing to commit, working tree clean"
5978
+ })
5979
+ };
5980
+ }
5981
+ let delta2 = { full_errors: 0, base_errors: 0, new_errors: 0, resolved_errors: 0 };
5982
+ const preferredBase2 = git(vault, ["rev-parse", "--verify", "origin/main"]) ? "origin/main" : git(vault, ["rev-parse", "--verify", "origin/HEAD"]) ? "origin/HEAD" : "";
5983
+ if (preferredBase2) {
5984
+ const deltaResult = await runSyncLintDelta({ vault, baseRef: preferredBase2 });
5985
+ if (!deltaResult.result.ok) {
5986
+ return {
5987
+ exitCode: ExitCode.LINT_HAS_ERRORS,
5988
+ result: err("LINT_DELTA_UNAVAILABLE", {
5989
+ message: "lint-delta evidence missing or failed \u2014 fail closed",
5990
+ detail: deltaResult.result
5991
+ })
5992
+ };
5993
+ }
5994
+ delta2 = deltaResult.result.data;
5995
+ if (delta2.new_errors > 0) {
5996
+ return {
5997
+ exitCode: ExitCode.LINT_HAS_ERRORS,
5998
+ result: err("LINT_NEW_ERRORS_BLOCK_PUSH", {
5999
+ full_errors: delta2.full_errors,
6000
+ base_errors: delta2.base_errors,
6001
+ new_errors: delta2.new_errors,
6002
+ resolved_errors: delta2.resolved_errors,
6003
+ new_fingerprints: deltaResult.result.data.new_fingerprints
6004
+ })
6005
+ };
6006
+ }
6007
+ } else {
6008
+ const lintResult = await runLint({ vault, days: 90, lines: 200, logThreshold: 500 });
6009
+ if (lintResult.result.ok) {
6010
+ const fullErrors = lintResult.result.data.summary.errors;
6011
+ delta2 = { full_errors: fullErrors, base_errors: 0, new_errors: fullErrors, resolved_errors: 0 };
6012
+ if (fullErrors > 0) {
6013
+ const buckets = "by_severity" in lintResult.result.data ? lintResult.result.data.by_severity.error : [];
6014
+ return {
6015
+ exitCode: ExitCode.LINT_HAS_ERRORS,
6016
+ result: err("LINT_ERRORS_BLOCK_PUSH", {
6017
+ errors: fullErrors,
6018
+ buckets,
6019
+ message: "no origin base ref for delta; absolute lint errors block push"
6020
+ })
6021
+ };
6022
+ }
6023
+ } else {
6024
+ delta2 = { full_errors: 0, base_errors: 0, new_errors: 0, resolved_errors: 0 };
6025
+ }
6026
+ }
6027
+ let pushed2 = false;
6028
+ try {
6029
+ gitStrict(vault, ["push", "origin", "HEAD"]);
6030
+ pushed2 = true;
6031
+ } catch (e) {
6032
+ return {
6033
+ exitCode: ExitCode.SYNC_PUSH_FAILED,
6034
+ result: err("SYNC_PUSH_FAILED", {
6035
+ pushed: false,
6036
+ message: `push failed: ${String(e)}`
6037
+ })
6038
+ };
6039
+ }
6040
+ const inheritedNote2 = delta2.full_errors > 0 ? `; lint full=${delta2.full_errors} base=${delta2.base_errors} new=${delta2.new_errors} resolved=${delta2.resolved_errors} (inherited debt only)` : `; lint full=0 new=0`;
5964
6041
  return {
5965
6042
  exitCode: ExitCode.OK,
5966
6043
  result: ok({
5967
6044
  files_committed: 0,
5968
6045
  commit_message: "",
5969
- pushed: false,
6046
+ pushed: pushed2,
5970
6047
  path_fixes: pathFixes,
5971
- humanHint: "nothing to commit, working tree clean"
6048
+ lint_full_errors: delta2.full_errors,
6049
+ lint_base_errors: delta2.base_errors,
6050
+ lint_new_errors: delta2.new_errors,
6051
+ lint_resolved_errors: delta2.resolved_errors,
6052
+ humanHint: `pushed ${ahead} commit(s) on clean working tree${pathFixes > 0 ? ` after ${pathFixes} long-path fix(es)` : ""}${inheritedNote2}`
5972
6053
  })
5973
6054
  };
5974
6055
  }
@@ -40,7 +40,7 @@ import {
40
40
  snapshotterAliasForLocalHost,
41
41
  toUndirectedWeighted,
42
42
  writeDotenv
43
- } from "./chunk-CKDF4DWU.js";
43
+ } from "./chunk-R5SDVKHS.js";
44
44
  import {
45
45
  atomicWriteText,
46
46
  prepareTypedPage
package/dist/cli.js CHANGED
@@ -50,7 +50,7 @@ import {
50
50
  snapshotterHealthChecks,
51
51
  upsertIndexEntry,
52
52
  vectorIndexStatus
53
- } from "./chunk-SNHTWLGF.js";
53
+ } from "./chunk-YKVJ2A3O.js";
54
54
  import {
55
55
  normalizeDistTag,
56
56
  readCache,
@@ -151,7 +151,7 @@ import {
151
151
  supersedeStaleReviewRequiredJournals,
152
152
  taxonomyCommentForPage,
153
153
  writeDotenv
154
- } from "./chunk-CKDF4DWU.js";
154
+ } from "./chunk-R5SDVKHS.js";
155
155
  import {
156
156
  assertTargetInsideVault,
157
157
  atomicWriteText,
@@ -10410,7 +10410,7 @@ async function emitManagedVaultWrite(vault, command, mutate, opts) {
10410
10410
  if (dirty) {
10411
10411
  return emit(dirty, void 0, { postCommit: false });
10412
10412
  }
10413
- const { runManagedWriteTransaction: runManagedWriteTransaction2 } = await import("./managed-write-preflight-2MMVUXD3.js");
10413
+ const { runManagedWriteTransaction: runManagedWriteTransaction2 } = await import("./managed-write-preflight-PUEJOXJO.js");
10414
10414
  const run = await runManagedWriteTransaction2({
10415
10415
  vault,
10416
10416
  command,
@@ -6,7 +6,7 @@ import {
6
6
  runManagedWritePeerGate,
7
7
  runManagedWritePreflight,
8
8
  runManagedWriteTransaction
9
- } from "./chunk-CKDF4DWU.js";
9
+ } from "./chunk-R5SDVKHS.js";
10
10
  import "./chunk-BPJ5KWIT.js";
11
11
  import "./chunk-OMO45AHI.js";
12
12
  import "./chunk-HJ4ALQG6.js";
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runSkillwikiMcpStdio
4
- } from "./chunk-SNHTWLGF.js";
4
+ } from "./chunk-YKVJ2A3O.js";
5
5
  import "./chunk-7I2TPIV5.js";
6
6
  import "./chunk-KFEOMMWK.js";
7
- import "./chunk-CKDF4DWU.js";
7
+ import "./chunk-R5SDVKHS.js";
8
8
  import "./chunk-BPJ5KWIT.js";
9
9
  import "./chunk-NPTIYO2S.js";
10
10
  import "./chunk-OMO45AHI.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skillwiki",
3
- "version": "0.10.64",
3
+ "version": "0.10.67",
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.10.64",
3
+ "version": "0.10.67",
4
4
  "skills": "./",
5
5
  "description": "Project-aware Karpathy-style knowledge base for Claude Code: 20 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.10.64",
3
+ "version": "0.10.67",
4
4
  "description": "Project-aware Karpathy-style knowledge base for Codex with 20 prompt-only skills backed by the deterministic skillwiki CLI.",
5
5
  "author": {
6
6
  "name": "karlorz",
package/skills/README.md CHANGED
@@ -38,6 +38,12 @@ Each top-level skill subdirectory holds one canonical `SKILL.md`. The nested
38
38
  `skills/<skill>/SKILL.md` tree mirrors those files for Codex plugin discovery;
39
39
  keep it byte-for-byte in sync with the canonical top-level files.
40
40
 
41
+ `description` is routing metadata for every skill, not a README. Author to
42
+ 180 characters (CI fails above 220). Unique-canonical totals are capped with
43
+ agent-skills so the combined Codex catalog stays at 8,000 characters. See
44
+ vault concept `concepts/codex-skill-catalog-budget.md`. Run
45
+ `python3 scripts/lint-skill-descriptions.py --layout llm-wiki --max-total-chars 3200`.
46
+
41
47
  Codex installs through `packages/codex-skills`, a materialized plugin root that
42
48
  copies this package's `.codex-plugin/` manifest, `skills/` mirror, and
43
49
  Codex-specific hook files. That root exposes `hooks/hooks-codex.json` and
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skillwiki/skills",
3
- "version": "0.10.64",
3
+ "version": "0.10.67",
4
4
  "private": true,
5
5
  "files": [
6
6
  "wiki-*",
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: using-skillwiki
3
- description: Invoke when vault, wiki, knowledge-base, or SkillWiki setup work arises — maps skillwiki skills, dev-loop alignment, adaptive workflow profiles, and vault routing. Do not invoke for unrelated coding or creative tasks.
3
+ description: Invoke for vault, wiki, or SkillWiki setup. Maps skills, workflow profiles, and vault routing. Skip unrelated coding.
4
4
  ---
5
5
  *Note: If executing as a background subagent, skip this skill section.*
6
6
 
@@ -287,7 +287,7 @@ skillwiki has multiple distribution channels that can drift:
287
287
  | Claude plugin | `~/.claude/plugins/cache/llm-wiki/` | `claude plugin update skillwiki@llm-wiki` |
288
288
  | Codex plugin | `~/.codex/plugins/cache/llm-wiki/` | `codex plugin marketplace upgrade llm-wiki`, then reinstall or restart Codex as needed |
289
289
  | Grok plugin | `~/.grok/installed-plugins/` (marketplace cache under `~/.grok/marketplace-cache/`) | `grok plugin update skillwiki`, then start a new session or reload plugins |
290
- | Cursor / Grok Bot (Team GitHub import) | `~/.cursor/plugins/cache/llm-wiki/` and `~/.cursor/plugins/marketplaces/github.com/karlorz/llm-wiki/<sha>/` | Cursor Dashboard Plugins → **Refresh** or Enable Auto Refresh on `karlorz/llm-wiki`. Reinstall does not move a pinned snapshot. |
290
+ | Cursor / Grok Bot (user GitHub add) | `~/.cursor/plugins/cache/llm-wiki/` and `~/.cursor/plugins/marketplaces/github.com/karlorz/llm-wiki/<sha>/` | `cursor-github-marketplace-repin` (`status.sh`). Team Dashboard Refresh only for a Team admin row. Reinstall does not move a pinned snapshot. |
291
291
  | Local git dev | source repo checkout | `npm link ./packages/cli` (from repo root) |
292
292
  **Check versions:** `skillwiki doctor` reports Plugin/CLI version mismatch warnings when installed channels disagree. For Grok, also inspect `~/.grok/installed-plugins/*/.claude-plugin/plugin.json` version and agent frontmatter under `agents/*.md`.
293
293
  **Plugin channel rule:** Plugin-managed skills and agents are not refreshed with `skillwiki install`. When Claude, Codex, or Grok plugin is installed and enabled, the plugin install root is the skill/agent provider; `skillwiki install` is only a legacy/standalone copier for `~/.claude/skills/`.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: wiki-freshness-repair
3
- description: Repair stale vault sources end to end. Consumes skillwiki drift --affected-pages, re-ingests changed sources through wiki-reingest, then republishes the affected typed pages through the page publish approval flow. Attended only; never auto-repairs.
3
+ description: Repair stale vault sources via drift, reingest, and attended republish. Use when skillwiki drift lists affected pages.
4
4
  ---
5
5
 
6
6
  # wiki-freshness-repair
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: wiki-sync
3
- description: Safely sync the vault git repository multi-session safe via advisory lockfile. Handles rebase conflict storms from archive-commit × snapshot-stream patterns. Runs skillwiki sync status, then guides push or pull with lint guards and conflict resolution.
3
+ description: Safely sync vault git with a lockfile and lint guards. Use to push or pull wiki changes across sessions.
4
4
  ---
5
5
  # wiki-sync
6
6
  ## When This Skill Activates
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: using-skillwiki
3
- description: Invoke when vault, wiki, knowledge-base, or SkillWiki setup work arises — maps skillwiki skills, dev-loop alignment, adaptive workflow profiles, and vault routing. Do not invoke for unrelated coding or creative tasks.
3
+ description: Invoke for vault, wiki, or SkillWiki setup. Maps skills, workflow profiles, and vault routing. Skip unrelated coding.
4
4
  ---
5
5
  *Note: If executing as a background subagent, skip this skill section.*
6
6
 
@@ -287,7 +287,7 @@ skillwiki has multiple distribution channels that can drift:
287
287
  | Claude plugin | `~/.claude/plugins/cache/llm-wiki/` | `claude plugin update skillwiki@llm-wiki` |
288
288
  | Codex plugin | `~/.codex/plugins/cache/llm-wiki/` | `codex plugin marketplace upgrade llm-wiki`, then reinstall or restart Codex as needed |
289
289
  | Grok plugin | `~/.grok/installed-plugins/` (marketplace cache under `~/.grok/marketplace-cache/`) | `grok plugin update skillwiki`, then start a new session or reload plugins |
290
- | Cursor / Grok Bot (Team GitHub import) | `~/.cursor/plugins/cache/llm-wiki/` and `~/.cursor/plugins/marketplaces/github.com/karlorz/llm-wiki/<sha>/` | Cursor Dashboard Plugins → **Refresh** or Enable Auto Refresh on `karlorz/llm-wiki`. Reinstall does not move a pinned snapshot. |
290
+ | Cursor / Grok Bot (user GitHub add) | `~/.cursor/plugins/cache/llm-wiki/` and `~/.cursor/plugins/marketplaces/github.com/karlorz/llm-wiki/<sha>/` | `cursor-github-marketplace-repin` (`status.sh`). Team Dashboard Refresh only for a Team admin row. Reinstall does not move a pinned snapshot. |
291
291
  | Local git dev | source repo checkout | `npm link ./packages/cli` (from repo root) |
292
292
  **Check versions:** `skillwiki doctor` reports Plugin/CLI version mismatch warnings when installed channels disagree. For Grok, also inspect `~/.grok/installed-plugins/*/.claude-plugin/plugin.json` version and agent frontmatter under `agents/*.md`.
293
293
  **Plugin channel rule:** Plugin-managed skills and agents are not refreshed with `skillwiki install`. When Claude, Codex, or Grok plugin is installed and enabled, the plugin install root is the skill/agent provider; `skillwiki install` is only a legacy/standalone copier for `~/.claude/skills/`.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: wiki-freshness-repair
3
- description: Repair stale vault sources end to end. Consumes skillwiki drift --affected-pages, re-ingests changed sources through wiki-reingest, then republishes the affected typed pages through the page publish approval flow. Attended only; never auto-repairs.
3
+ description: Repair stale vault sources via drift, reingest, and attended republish. Use when skillwiki drift lists affected pages.
4
4
  ---
5
5
 
6
6
  # wiki-freshness-repair
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: wiki-sync
3
- description: Safely sync the vault git repository multi-session safe via advisory lockfile. Handles rebase conflict storms from archive-commit × snapshot-stream patterns. Runs skillwiki sync status, then guides push or pull with lint guards and conflict resolution.
3
+ description: Safely sync vault git with a lockfile and lint guards. Use to push or pull wiki changes across sessions.
4
4
  ---
5
5
  # wiki-sync
6
6
  ## When This Skill Activates