skillwiki 0.9.55 → 0.9.57
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/auto-update-bg.js +28 -8
- package/dist/chunk-7I2TPIV5.js +154 -0
- package/dist/{chunk-4BT3HY4K.js → chunk-NIPZVIHT.js} +311 -222
- package/dist/cli.js +68 -16
- package/dist/skillwiki-mcp.js +2 -2
- package/package.json +1 -1
- package/skills/.claude-plugin/plugin.json +1 -1
- package/skills/.codex-plugin/plugin.json +1 -1
- package/skills/README.md +16 -2
- package/skills/package.json +1 -1
- package/skills/skills/wiki-sync/SKILL.md +20 -3
- package/skills/wiki-sync/SKILL.md +20 -3
- package/dist/chunk-E6UWZ3S3.js +0 -62
package/dist/cli.js
CHANGED
|
@@ -66,6 +66,7 @@ import {
|
|
|
66
66
|
runQuery,
|
|
67
67
|
runSkillwikiMcpStdio,
|
|
68
68
|
runStale,
|
|
69
|
+
runSyncLintDelta,
|
|
69
70
|
runTagAudit,
|
|
70
71
|
runTopicMapCheck,
|
|
71
72
|
runValidate,
|
|
@@ -75,13 +76,15 @@ import {
|
|
|
75
76
|
scanVault,
|
|
76
77
|
snapshotterAliasForLocalHost,
|
|
77
78
|
splitFrontmatter,
|
|
78
|
-
triggerAutoUpdate,
|
|
79
|
-
writeCache,
|
|
80
79
|
writeDotenv
|
|
81
|
-
} from "./chunk-
|
|
80
|
+
} from "./chunk-NIPZVIHT.js";
|
|
82
81
|
import {
|
|
83
|
-
normalizeDistTag
|
|
84
|
-
|
|
82
|
+
normalizeDistTag,
|
|
83
|
+
readCache,
|
|
84
|
+
resolveAutoApplyAt,
|
|
85
|
+
triggerAutoUpdate,
|
|
86
|
+
writeCache
|
|
87
|
+
} from "./chunk-7I2TPIV5.js";
|
|
85
88
|
|
|
86
89
|
// src/cli.ts
|
|
87
90
|
import { join as join26 } from "path";
|
|
@@ -1956,11 +1959,14 @@ async function runUpdate(input) {
|
|
|
1956
1959
|
result: err("PREFLIGHT_FAILED", { message: `Failed to query npm registry: ${String(e)}` })
|
|
1957
1960
|
};
|
|
1958
1961
|
}
|
|
1962
|
+
const { firstSeenAt, autoApplyAt } = resolveAutoApplyAt(readCache(input.home).cache, latest);
|
|
1959
1963
|
const cache = {
|
|
1960
1964
|
lastCheck: Date.now(),
|
|
1961
1965
|
latestVersion: latest,
|
|
1962
1966
|
currentVersion,
|
|
1963
|
-
distTag: tag
|
|
1967
|
+
distTag: tag,
|
|
1968
|
+
firstSeenAt,
|
|
1969
|
+
autoApplyAt
|
|
1964
1970
|
};
|
|
1965
1971
|
if (latest === currentVersion) {
|
|
1966
1972
|
writeCache(input.home, cache);
|
|
@@ -3720,15 +3726,51 @@ async function runSyncPush(input) {
|
|
|
3720
3726
|
})
|
|
3721
3727
|
};
|
|
3722
3728
|
}
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
|
|
3731
|
-
|
|
3729
|
+
let delta = { full_errors: 0, base_errors: 0, new_errors: 0, resolved_errors: 0 };
|
|
3730
|
+
const preferredBase = git(vault, ["rev-parse", "--verify", "origin/main"]) ? "origin/main" : git(vault, ["rev-parse", "--verify", "origin/HEAD"]) ? "origin/HEAD" : "";
|
|
3731
|
+
if (preferredBase) {
|
|
3732
|
+
const deltaResult = await runSyncLintDelta({ vault, baseRef: preferredBase });
|
|
3733
|
+
if (!deltaResult.result.ok) {
|
|
3734
|
+
return {
|
|
3735
|
+
exitCode: ExitCode.LINT_HAS_ERRORS,
|
|
3736
|
+
result: err("LINT_DELTA_UNAVAILABLE", {
|
|
3737
|
+
message: "lint-delta evidence missing or failed \u2014 fail closed",
|
|
3738
|
+
detail: deltaResult.result
|
|
3739
|
+
})
|
|
3740
|
+
};
|
|
3741
|
+
}
|
|
3742
|
+
delta = deltaResult.result.data;
|
|
3743
|
+
if (delta.new_errors > 0) {
|
|
3744
|
+
return {
|
|
3745
|
+
exitCode: ExitCode.LINT_HAS_ERRORS,
|
|
3746
|
+
result: err("LINT_NEW_ERRORS_BLOCK_PUSH", {
|
|
3747
|
+
full_errors: delta.full_errors,
|
|
3748
|
+
base_errors: delta.base_errors,
|
|
3749
|
+
new_errors: delta.new_errors,
|
|
3750
|
+
resolved_errors: delta.resolved_errors,
|
|
3751
|
+
new_fingerprints: deltaResult.result.data.new_fingerprints
|
|
3752
|
+
})
|
|
3753
|
+
};
|
|
3754
|
+
}
|
|
3755
|
+
} else {
|
|
3756
|
+
const lintResult = await runLint({ vault, days: 90, lines: 200, logThreshold: 500 });
|
|
3757
|
+
if (lintResult.result.ok) {
|
|
3758
|
+
const fullErrors = lintResult.result.data.summary.errors;
|
|
3759
|
+
delta = { full_errors: fullErrors, base_errors: 0, new_errors: fullErrors, resolved_errors: 0 };
|
|
3760
|
+
if (fullErrors > 0) {
|
|
3761
|
+
const buckets = "by_severity" in lintResult.result.data ? lintResult.result.data.by_severity.error : [];
|
|
3762
|
+
return {
|
|
3763
|
+
exitCode: ExitCode.LINT_HAS_ERRORS,
|
|
3764
|
+
result: err("LINT_ERRORS_BLOCK_PUSH", {
|
|
3765
|
+
errors: fullErrors,
|
|
3766
|
+
buckets,
|
|
3767
|
+
message: "no origin base ref for delta; absolute lint errors block push"
|
|
3768
|
+
})
|
|
3769
|
+
};
|
|
3770
|
+
}
|
|
3771
|
+
} else {
|
|
3772
|
+
delta = { full_errors: 0, base_errors: 0, new_errors: 0, resolved_errors: 0 };
|
|
3773
|
+
}
|
|
3732
3774
|
}
|
|
3733
3775
|
try {
|
|
3734
3776
|
stageVaultContentChanges(vault);
|
|
@@ -3771,6 +3813,7 @@ async function runSyncPush(input) {
|
|
|
3771
3813
|
})
|
|
3772
3814
|
};
|
|
3773
3815
|
}
|
|
3816
|
+
const inheritedNote = delta.full_errors > 0 ? `; lint full=${delta.full_errors} base=${delta.base_errors} new=${delta.new_errors} resolved=${delta.resolved_errors} (inherited debt only)` : `; lint full=0 new=0`;
|
|
3774
3817
|
return {
|
|
3775
3818
|
exitCode: ExitCode.OK,
|
|
3776
3819
|
result: ok({
|
|
@@ -3778,7 +3821,11 @@ async function runSyncPush(input) {
|
|
|
3778
3821
|
commit_message: commitMessage,
|
|
3779
3822
|
pushed,
|
|
3780
3823
|
path_fixes: pathFixes,
|
|
3781
|
-
|
|
3824
|
+
lint_full_errors: delta.full_errors,
|
|
3825
|
+
lint_base_errors: delta.base_errors,
|
|
3826
|
+
lint_new_errors: delta.new_errors,
|
|
3827
|
+
lint_resolved_errors: delta.resolved_errors,
|
|
3828
|
+
humanHint: `committed and pushed ${dirtyFiles.length} file(s)${pathFixes > 0 ? ` after ${pathFixes} long-path fix(es)` : ""}${inheritedNote}`
|
|
3782
3829
|
})
|
|
3783
3830
|
};
|
|
3784
3831
|
}
|
|
@@ -5493,6 +5540,11 @@ syncCmd.command("peers [vault]").description("list active locks and recent wiki-
|
|
|
5493
5540
|
if (!v.ok) emit({ exitCode: v.exitCode, result: v.payload });
|
|
5494
5541
|
else emit(runSyncPeers({ vault: v.vault, sessionId: getCliSessionId() }));
|
|
5495
5542
|
});
|
|
5543
|
+
syncCmd.command("lint-delta [vault]").description("compare lint errors against a base ref; block only on new errors").option("--base-ref <ref>", "base git ref to compare against", "origin/main").option("--wiki <name>", "wiki profile name").action(async (vault, opts) => {
|
|
5544
|
+
const v = await resolveVaultArg(vault, opts.wiki);
|
|
5545
|
+
if (!v.ok) emit({ exitCode: v.exitCode, result: v.payload });
|
|
5546
|
+
else emit(await runSyncLintDelta({ vault: v.vault, baseRef: opts.baseRef }));
|
|
5547
|
+
});
|
|
5496
5548
|
var backupCmd = program.command("backup").description("manage S3-compatible remote backup");
|
|
5497
5549
|
backupCmd.command("sync [vault]").description("sync vault to S3-compatible remote backup").option("--dry-run", "list actions without executing").option("--bucket <name>", "S3 bucket name").option("--endpoint <url>", "S3 endpoint URL").option("--region <region>", "S3 region", "us-east-1").option("--prune", "delete orphaned S3 objects not in vault", false).option("--wiki <name>", "wiki profile name").action(async (vault, opts) => {
|
|
5498
5550
|
const v = await resolveVaultArg(vault, opts.wiki);
|
package/dist/skillwiki-mcp.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skillwiki",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.57",
|
|
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": {
|
package/skills/README.md
CHANGED
|
@@ -1,11 +1,22 @@
|
|
|
1
1
|
# @skillwiki/skills
|
|
2
2
|
|
|
3
|
-
Prompt-only Markdown skills for Claude Code. Installed via `skillwiki install
|
|
3
|
+
Prompt-only Markdown skills for Claude Code. Installed via `skillwiki install`
|
|
4
|
+
or the Claude/Codex/Antigravity plugin packaging paths.
|
|
5
|
+
|
|
6
|
+
Current package inventory: **18 skills**.
|
|
4
7
|
|
|
5
8
|
| Namespace | Skills |
|
|
6
9
|
|---|---|
|
|
7
|
-
| `wiki-*` | `wiki-init`, `wiki-ingest`, `wiki-query`, `wiki-lint`, `wiki-crystallize`, `wiki-audit` |
|
|
10
|
+
| `wiki-*` | `wiki-init`, `wiki-ingest`, `wiki-query`, `wiki-lint`, `wiki-crystallize`, `wiki-audit`, `wiki-archive`, `wiki-reingest`, `wiki-adapter-prd`, `wiki-add-task`, `wiki-sync`, `wiki-canvas`, `wiki-gate-plan-mode` |
|
|
8
11
|
| `proj-*` | `proj-init`, `proj-work`, `proj-distill`, `proj-decide` |
|
|
12
|
+
| onboarding | `using-skillwiki` |
|
|
13
|
+
|
|
14
|
+
Verify the live inventory from source:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
find packages/skills -mindepth 2 -maxdepth 2 -name SKILL.md -print | sort
|
|
18
|
+
bash scripts/verify-manifests.sh
|
|
19
|
+
```
|
|
9
20
|
|
|
10
21
|
Each top-level skill subdirectory holds one canonical `SKILL.md`. The nested
|
|
11
22
|
`skills/<skill>/SKILL.md` tree mirrors those files for Codex plugin discovery;
|
|
@@ -20,3 +31,6 @@ Codex-specific hook files. That root exposes `hooks/hooks-codex.json` and
|
|
|
20
31
|
Run `npm run materialize:plugins` from the repository root after changing
|
|
21
32
|
canonical skill, agent, or hook assets. Run
|
|
22
33
|
`npm run materialize:plugins:check` for read-only drift detection.
|
|
34
|
+
|
|
35
|
+
The sibling `vault-sync` plugin ships six additional operational skills under
|
|
36
|
+
`packages/vault-sync/skills/` and is packaged separately from this skill set.
|
package/skills/package.json
CHANGED
|
@@ -44,8 +44,8 @@ On every invocation, count `wiki-sync:*` stashes older than 24 hours via `skillw
|
|
|
44
44
|
|
|
45
45
|
### Push workflow
|
|
46
46
|
4. If vault is dirty, ask the user to review uncommitted changes before proceeding.
|
|
47
|
-
5. Run `skillwiki lint <vault
|
|
48
|
-
6. If lint
|
|
47
|
+
5. Run `skillwiki sync lint-delta <vault> --base-ref origin/main`. Block only when `new_errors > 0`. Report full/base/new/resolved. Malformed delta evidence fails closed — do not push.
|
|
48
|
+
6. If lint-delta allows (new_errors = 0), stage and commit:
|
|
49
49
|
- `git -C <vault> add -A`
|
|
50
50
|
- `git -C <vault> commit -m "sync: vault update $(date -u +%Y-%m-%dT%H:%MZ)"`
|
|
51
51
|
7. Run `git -C <vault> push origin HEAD`. Report result.
|
|
@@ -62,7 +62,7 @@ On every invocation, count `wiki-sync:*` stashes older than 24 hours via `skillw
|
|
|
62
62
|
MSG="wiki-sync:${SESSION_ID}:${CWD_HASH}:${ISO_TS}:pre-pull"
|
|
63
63
|
git -C "$VAULT" stash push -m "$MSG"
|
|
64
64
|
```
|
|
65
|
-
11.
|
|
65
|
+
11. Prefer the canonical pull helper (`wiki-pull-with-auto-resolve.sh` / vault-presync `--execute`) so stale-clean rebase state uses recovery-ref + `rebase --quit`, active rebases fail closed, and only fully materialized commits are dropped. If invoking git directly: `git -C <vault> pull --rebase origin HEAD`. Report result.
|
|
66
66
|
12. If a stash was created, pop it: `git -C <vault> stash pop`.
|
|
67
67
|
13. If conflicts occur during stash pop, identify them and present to the user for resolution (see Conflict Resolution below).
|
|
68
68
|
14. Run `skillwiki lint <vault>` after pull to verify vault integrity.
|
|
@@ -240,3 +240,20 @@ bash ~/.hermes/scripts/wiki-snapshot.sh # Re-sync fresh
|
|
|
240
240
|
- Modifying files in `raw/` to resolve conflicts (N9 — archive and re-ingest instead).
|
|
241
241
|
- Stashing without the `wiki-sync:...` name format (breaks peer detection).
|
|
242
242
|
- Force-deleting a peer's lockfile (use `--force` only if peer is confirmed dead).
|
|
243
|
+
|
|
244
|
+
## Convergence safeguards (2026-07-11)
|
|
245
|
+
|
|
246
|
+
### Rebase-state classification
|
|
247
|
+
- `stale-clean`: recovery ref at tip + `git rebase --quit` (preserves advanced tip; never abort-reset to orig-head).
|
|
248
|
+
- `active` (REBASE_HEAD / UU paths): leave untouched; fail closed.
|
|
249
|
+
- Recovery refs live under `refs/vault-sync/recovery/<UTC timestamp>`.
|
|
250
|
+
|
|
251
|
+
### Materialized-commit proof
|
|
252
|
+
Drop a local commit from rebase only when every path is proven present on the target ref (exact blobs; byte-identical added `## ` log sections). Partial/raw/rename mismatches retain or stop.
|
|
253
|
+
|
|
254
|
+
### Lint-delta fail-closed
|
|
255
|
+
- Fingerprints: `<bucket>\0<page>\0<normalized-detail>`
|
|
256
|
+
- CLI: `skillwiki sync lint-delta <vault> --base-ref origin/main`
|
|
257
|
+
- Block publication only when `new_errors > 0`; inherited full debt remains visible.
|
|
258
|
+
- Missing/malformed delta evidence blocks (never silent lint skip).
|
|
259
|
+
|
|
@@ -44,8 +44,8 @@ On every invocation, count `wiki-sync:*` stashes older than 24 hours via `skillw
|
|
|
44
44
|
|
|
45
45
|
### Push workflow
|
|
46
46
|
4. If vault is dirty, ask the user to review uncommitted changes before proceeding.
|
|
47
|
-
5. Run `skillwiki lint <vault
|
|
48
|
-
6. If lint
|
|
47
|
+
5. Run `skillwiki sync lint-delta <vault> --base-ref origin/main`. Block only when `new_errors > 0`. Report full/base/new/resolved. Malformed delta evidence fails closed — do not push.
|
|
48
|
+
6. If lint-delta allows (new_errors = 0), stage and commit:
|
|
49
49
|
- `git -C <vault> add -A`
|
|
50
50
|
- `git -C <vault> commit -m "sync: vault update $(date -u +%Y-%m-%dT%H:%MZ)"`
|
|
51
51
|
7. Run `git -C <vault> push origin HEAD`. Report result.
|
|
@@ -62,7 +62,7 @@ On every invocation, count `wiki-sync:*` stashes older than 24 hours via `skillw
|
|
|
62
62
|
MSG="wiki-sync:${SESSION_ID}:${CWD_HASH}:${ISO_TS}:pre-pull"
|
|
63
63
|
git -C "$VAULT" stash push -m "$MSG"
|
|
64
64
|
```
|
|
65
|
-
11.
|
|
65
|
+
11. Prefer the canonical pull helper (`wiki-pull-with-auto-resolve.sh` / vault-presync `--execute`) so stale-clean rebase state uses recovery-ref + `rebase --quit`, active rebases fail closed, and only fully materialized commits are dropped. If invoking git directly: `git -C <vault> pull --rebase origin HEAD`. Report result.
|
|
66
66
|
12. If a stash was created, pop it: `git -C <vault> stash pop`.
|
|
67
67
|
13. If conflicts occur during stash pop, identify them and present to the user for resolution (see Conflict Resolution below).
|
|
68
68
|
14. Run `skillwiki lint <vault>` after pull to verify vault integrity.
|
|
@@ -240,3 +240,20 @@ bash ~/.hermes/scripts/wiki-snapshot.sh # Re-sync fresh
|
|
|
240
240
|
- Modifying files in `raw/` to resolve conflicts (N9 — archive and re-ingest instead).
|
|
241
241
|
- Stashing without the `wiki-sync:...` name format (breaks peer detection).
|
|
242
242
|
- Force-deleting a peer's lockfile (use `--force` only if peer is confirmed dead).
|
|
243
|
+
|
|
244
|
+
## Convergence safeguards (2026-07-11)
|
|
245
|
+
|
|
246
|
+
### Rebase-state classification
|
|
247
|
+
- `stale-clean`: recovery ref at tip + `git rebase --quit` (preserves advanced tip; never abort-reset to orig-head).
|
|
248
|
+
- `active` (REBASE_HEAD / UU paths): leave untouched; fail closed.
|
|
249
|
+
- Recovery refs live under `refs/vault-sync/recovery/<UTC timestamp>`.
|
|
250
|
+
|
|
251
|
+
### Materialized-commit proof
|
|
252
|
+
Drop a local commit from rebase only when every path is proven present on the target ref (exact blobs; byte-identical added `## ` log sections). Partial/raw/rename mismatches retain or stop.
|
|
253
|
+
|
|
254
|
+
### Lint-delta fail-closed
|
|
255
|
+
- Fingerprints: `<bucket>\0<page>\0<normalized-detail>`
|
|
256
|
+
- CLI: `skillwiki sync lint-delta <vault> --base-ref origin/main`
|
|
257
|
+
- Block publication only when `new_errors > 0`; inherited full debt remains visible.
|
|
258
|
+
- Missing/malformed delta evidence blocks (never silent lint skip).
|
|
259
|
+
|
package/dist/chunk-E6UWZ3S3.js
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// src/utils/semver.ts
|
|
4
|
-
function semverGt(a, b) {
|
|
5
|
-
const pa = parseSemver(a);
|
|
6
|
-
const pb = parseSemver(b);
|
|
7
|
-
if (!pa || !pb) return a > b;
|
|
8
|
-
if (pa.major !== pb.major) return pa.major > pb.major;
|
|
9
|
-
if (pa.minor !== pb.minor) return pa.minor > pb.minor;
|
|
10
|
-
if (pa.patch !== pb.patch) return pa.patch > pb.patch;
|
|
11
|
-
if (!pa.pre && pb.pre) return true;
|
|
12
|
-
if (pa.pre && !pb.pre) return false;
|
|
13
|
-
if (!pa.pre && !pb.pre) return false;
|
|
14
|
-
const aParts = pa.pre.split(".");
|
|
15
|
-
const bParts = pb.pre.split(".");
|
|
16
|
-
const len = Math.max(aParts.length, bParts.length);
|
|
17
|
-
for (let i = 0; i < len; i++) {
|
|
18
|
-
const ai = aParts[i];
|
|
19
|
-
const bi = bParts[i];
|
|
20
|
-
if (ai === void 0) return false;
|
|
21
|
-
if (bi === void 0) return true;
|
|
22
|
-
const aNum = parseInt(ai, 10);
|
|
23
|
-
const bNum = parseInt(bi, 10);
|
|
24
|
-
if (!isNaN(aNum) && !isNaN(bNum)) {
|
|
25
|
-
if (aNum !== bNum) return aNum > bNum;
|
|
26
|
-
} else {
|
|
27
|
-
if (ai !== bi) return ai > bi;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
return false;
|
|
31
|
-
}
|
|
32
|
-
function parseSemver(version) {
|
|
33
|
-
const match = version.match(/^(\d+)\.(\d+)\.(\d+)(?:-(.+))?$/);
|
|
34
|
-
if (!match) return null;
|
|
35
|
-
return {
|
|
36
|
-
major: parseInt(match[1], 10),
|
|
37
|
-
minor: parseInt(match[2], 10),
|
|
38
|
-
patch: parseInt(match[3], 10),
|
|
39
|
-
pre: match[4] ?? null
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// src/utils/update-consts.ts
|
|
44
|
-
var DIST_TAG = "latest";
|
|
45
|
-
var CACHE_FILENAME = ".update-cache.json";
|
|
46
|
-
var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
47
|
-
var ENV_DISABLE_KEY = "NO_UPDATE_NOTIFIER";
|
|
48
|
-
var CLI_DISABLE_FLAG = "--no-update-notifier";
|
|
49
|
-
function normalizeDistTag(tag) {
|
|
50
|
-
const value = (tag ?? DIST_TAG).trim();
|
|
51
|
-
return /^[A-Za-z0-9._-]+$/.test(value) ? value : DIST_TAG;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export {
|
|
55
|
-
semverGt,
|
|
56
|
-
DIST_TAG,
|
|
57
|
-
CACHE_FILENAME,
|
|
58
|
-
CHECK_INTERVAL_MS,
|
|
59
|
-
ENV_DISABLE_KEY,
|
|
60
|
-
CLI_DISABLE_FLAG,
|
|
61
|
-
normalizeDistTag
|
|
62
|
-
};
|