skillwiki 0.10.88 → 0.10.90
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/{chunk-5QFHISNH.js → chunk-ZYVP52PM.js} +22 -2
- package/dist/cli.js +72 -35
- package/dist/skillwiki-mcp.js +1 -1
- package/dist/vault-sync/scripts/wiki-fetch-notify.sh +11 -1
- package/dist/vault-sync/scripts/wiki-snapshot.sh +33 -1
- package/package.json +1 -1
- package/skills/.claude-plugin/plugin.json +1 -1
- package/skills/.codex-plugin/plugin.json +1 -1
- package/skills/.cursor-plugin/plugin.json +1 -1
- package/skills/package.json +1 -1
|
@@ -4512,10 +4512,16 @@ function isHygieneCommand(command) {
|
|
|
4512
4512
|
}
|
|
4513
4513
|
return false;
|
|
4514
4514
|
}
|
|
4515
|
+
function isEventLedgerPath(rel) {
|
|
4516
|
+
const n = rel.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
4517
|
+
return n === "meta/log-events" || n.startsWith("meta/log-events/");
|
|
4518
|
+
}
|
|
4515
4519
|
function measureDirtyVolume(vault) {
|
|
4516
4520
|
const empty = (extra = {}) => ({
|
|
4517
4521
|
porcelain_lines: 0,
|
|
4518
4522
|
expanded_files: 0,
|
|
4523
|
+
content_files: 0,
|
|
4524
|
+
ledger_files: 0,
|
|
4519
4525
|
modified: 0,
|
|
4520
4526
|
untracked: 0,
|
|
4521
4527
|
buckets: [],
|
|
@@ -4545,7 +4551,13 @@ function measureDirtyVolume(vault) {
|
|
|
4545
4551
|
let modified = 0;
|
|
4546
4552
|
let untracked = 0;
|
|
4547
4553
|
let expanded = 0;
|
|
4554
|
+
let contentFiles = 0;
|
|
4555
|
+
let ledgerFiles = 0;
|
|
4548
4556
|
const bucketMap = /* @__PURE__ */ new Map();
|
|
4557
|
+
const classify = (rel, n) => {
|
|
4558
|
+
if (isEventLedgerPath(rel)) ledgerFiles += n;
|
|
4559
|
+
else contentFiles += n;
|
|
4560
|
+
};
|
|
4549
4561
|
const addBucket = (rel, n) => {
|
|
4550
4562
|
const top = rel.split(/[/\\]/)[0] || ".";
|
|
4551
4563
|
bucketMap.set(top, (bucketMap.get(top) ?? 0) + n);
|
|
@@ -4567,20 +4579,27 @@ function measureDirtyVolume(vault) {
|
|
|
4567
4579
|
const files = listFilesRecursive(abs);
|
|
4568
4580
|
expanded += files.length;
|
|
4569
4581
|
addBucket(rel, files.length);
|
|
4582
|
+
for (const file of files) {
|
|
4583
|
+
classify(relative2(vault, file).replace(/\\/g, "/"), 1);
|
|
4584
|
+
}
|
|
4570
4585
|
} else {
|
|
4571
4586
|
expanded += 1;
|
|
4572
4587
|
addBucket(rel, 1);
|
|
4588
|
+
classify(rel, 1);
|
|
4573
4589
|
}
|
|
4574
4590
|
} else {
|
|
4575
4591
|
modified += 1;
|
|
4576
4592
|
expanded += 1;
|
|
4577
4593
|
addBucket(rel, 1);
|
|
4594
|
+
classify(rel, 1);
|
|
4578
4595
|
}
|
|
4579
4596
|
}
|
|
4580
4597
|
const buckets = [...bucketMap.entries()].map(([bucket, count]) => ({ bucket, count })).sort((a, b) => b.count - a.count);
|
|
4581
4598
|
return {
|
|
4582
4599
|
porcelain_lines: lines.length,
|
|
4583
4600
|
expanded_files: expanded,
|
|
4601
|
+
content_files: contentFiles,
|
|
4602
|
+
ledger_files: ledgerFiles,
|
|
4584
4603
|
modified,
|
|
4585
4604
|
untracked,
|
|
4586
4605
|
buckets,
|
|
@@ -4613,7 +4632,7 @@ function evaluateDirtyVolumeGate(input) {
|
|
|
4613
4632
|
const threshold = input.threshold ?? DEFAULT_DIRTY_VOLUME_THRESHOLD;
|
|
4614
4633
|
const report = measureDirtyVolume(input.vault);
|
|
4615
4634
|
report.threshold = threshold;
|
|
4616
|
-
report.over_threshold = report.is_git_repo && report.
|
|
4635
|
+
report.over_threshold = report.is_git_repo && report.content_files > threshold;
|
|
4617
4636
|
if (input.skip) {
|
|
4618
4637
|
return { allowed: true, reason: "skipped", report };
|
|
4619
4638
|
}
|
|
@@ -4632,7 +4651,7 @@ function evaluateDirtyVolumeGate(input) {
|
|
|
4632
4651
|
reason: "over_threshold",
|
|
4633
4652
|
code: GateError.VAULT_DIRTY_BACKLOG,
|
|
4634
4653
|
report,
|
|
4635
|
-
humanHint: `Vault dirty volume ${report.
|
|
4654
|
+
humanHint: `Vault content dirty volume ${report.content_files} exceeds threshold ${threshold} (event-ledger ${report.ledger_files} excluded; porcelain ${report.porcelain_lines}; buckets: ${top || "none"}). Triage/commit keep-set before more non-hygiene writes. Do not git add meta/log-events. Hygiene commands still allowed.`
|
|
4636
4655
|
};
|
|
4637
4656
|
}
|
|
4638
4657
|
var SATURATION_PATTERNS = [
|
|
@@ -7828,6 +7847,7 @@ export {
|
|
|
7828
7847
|
DEFAULT_CAPTURE_BUDGET,
|
|
7829
7848
|
DEFAULT_NO_DECISION_STREAK,
|
|
7830
7849
|
GateError,
|
|
7850
|
+
measureDirtyVolume,
|
|
7831
7851
|
evaluateDirtyVolumeGate,
|
|
7832
7852
|
CAPTURE_HYGIENE_CONTRACT,
|
|
7833
7853
|
runWritePreflight,
|
package/dist/cli.js
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
findPlugin,
|
|
16
16
|
guardProtectedVaultWrite,
|
|
17
17
|
isFailedRunStatus,
|
|
18
|
+
measureDirtyVolume,
|
|
18
19
|
memoryAuthorityTiersRank,
|
|
19
20
|
pruneVectorIndex,
|
|
20
21
|
readCliPackageJson,
|
|
@@ -52,7 +53,7 @@ import {
|
|
|
52
53
|
snapshotterHealthChecks,
|
|
53
54
|
upsertIndexEntry,
|
|
54
55
|
vectorIndexStatus
|
|
55
|
-
} from "./chunk-
|
|
56
|
+
} from "./chunk-ZYVP52PM.js";
|
|
56
57
|
import {
|
|
57
58
|
normalizeDistTag,
|
|
58
59
|
readCache,
|
|
@@ -9348,57 +9349,83 @@ function githubRecord(p) {
|
|
|
9348
9349
|
if (p.ageHours !== void 0) rec.age_hours = p.ageHours;
|
|
9349
9350
|
return rec;
|
|
9350
9351
|
}
|
|
9352
|
+
function withDirty(rec, p) {
|
|
9353
|
+
if (p.dirty !== void 0) rec.dirty = p.dirty;
|
|
9354
|
+
if (p.untracked !== void 0) rec.untracked = p.untracked;
|
|
9355
|
+
if (p.ledger_untracked !== void 0) rec.ledger_untracked = p.ledger_untracked;
|
|
9356
|
+
if (p.content_untracked !== void 0) rec.content_untracked = p.content_untracked;
|
|
9357
|
+
return rec;
|
|
9358
|
+
}
|
|
9351
9359
|
function localRecord(p, githubOid) {
|
|
9352
9360
|
if (p.blockedReason) {
|
|
9353
|
-
return
|
|
9354
|
-
|
|
9355
|
-
|
|
9356
|
-
|
|
9357
|
-
|
|
9358
|
-
|
|
9359
|
-
|
|
9361
|
+
return withDirty(
|
|
9362
|
+
{
|
|
9363
|
+
state: "blocked",
|
|
9364
|
+
oid: p.head,
|
|
9365
|
+
behind: p.behind,
|
|
9366
|
+
blocked_reason: p.blockedReason,
|
|
9367
|
+
detail: p.detail ?? p.blockedReason
|
|
9368
|
+
},
|
|
9369
|
+
p
|
|
9370
|
+
);
|
|
9360
9371
|
}
|
|
9361
9372
|
if (p.head && githubOid && p.head === githubOid && (p.behind === void 0 || p.behind === 0)) {
|
|
9362
|
-
return
|
|
9363
|
-
|
|
9364
|
-
|
|
9365
|
-
|
|
9366
|
-
|
|
9367
|
-
|
|
9373
|
+
return withDirty(
|
|
9374
|
+
{
|
|
9375
|
+
state: "ok",
|
|
9376
|
+
oid: p.head,
|
|
9377
|
+
behind: p.behind,
|
|
9378
|
+
detail: p.detail ?? "HEAD matches GitHub"
|
|
9379
|
+
},
|
|
9380
|
+
p
|
|
9381
|
+
);
|
|
9368
9382
|
}
|
|
9369
9383
|
if (p.behind !== void 0 && p.behind > 0) {
|
|
9370
|
-
return
|
|
9371
|
-
|
|
9372
|
-
|
|
9373
|
-
|
|
9374
|
-
|
|
9375
|
-
|
|
9384
|
+
return withDirty(
|
|
9385
|
+
{
|
|
9386
|
+
state: "stale",
|
|
9387
|
+
oid: p.head,
|
|
9388
|
+
behind: p.behind,
|
|
9389
|
+
detail: p.detail ?? `behind origin/main by ${p.behind}`
|
|
9390
|
+
},
|
|
9391
|
+
p
|
|
9392
|
+
);
|
|
9376
9393
|
}
|
|
9377
9394
|
if (p.head && githubOid && p.head !== githubOid) {
|
|
9378
|
-
return
|
|
9379
|
-
|
|
9380
|
-
|
|
9381
|
-
|
|
9382
|
-
|
|
9383
|
-
|
|
9395
|
+
return withDirty(
|
|
9396
|
+
{
|
|
9397
|
+
state: "stale",
|
|
9398
|
+
oid: p.head,
|
|
9399
|
+
behind: p.behind,
|
|
9400
|
+
detail: p.detail ?? "HEAD differs from GitHub"
|
|
9401
|
+
},
|
|
9402
|
+
p
|
|
9403
|
+
);
|
|
9384
9404
|
}
|
|
9385
9405
|
if (p.head) {
|
|
9386
|
-
return
|
|
9387
|
-
|
|
9388
|
-
|
|
9389
|
-
|
|
9390
|
-
|
|
9391
|
-
|
|
9406
|
+
return withDirty(
|
|
9407
|
+
{
|
|
9408
|
+
state: "ok",
|
|
9409
|
+
oid: p.head,
|
|
9410
|
+
behind: p.behind,
|
|
9411
|
+
detail: p.detail ?? "HEAD present"
|
|
9412
|
+
},
|
|
9413
|
+
p
|
|
9414
|
+
);
|
|
9392
9415
|
}
|
|
9393
|
-
return { state: "unknown", detail: p.detail ?? "leaf clone unmeasured" };
|
|
9416
|
+
return withDirty({ state: "unknown", detail: p.detail ?? "leaf clone unmeasured" }, p);
|
|
9394
9417
|
}
|
|
9395
9418
|
function formatPlane(name, rec) {
|
|
9396
9419
|
const parts = [`${name}: ${rec.state}`];
|
|
9397
9420
|
if (rec.oid) parts.push(`oid=${rec.oid.slice(0, 12)}`);
|
|
9398
9421
|
if (rec.behind !== void 0) parts.push(`behind=${rec.behind}`);
|
|
9399
9422
|
if (rec.age_hours !== void 0) parts.push(`age_hours=${rec.age_hours}`);
|
|
9423
|
+
if (rec.ledger_untracked !== void 0) parts.push(`ledger_untracked=${rec.ledger_untracked}`);
|
|
9424
|
+
if (rec.content_untracked !== void 0) parts.push(`content_untracked=${rec.content_untracked}`);
|
|
9425
|
+
if (rec.ledger_untracked === void 0 && rec.dirty !== void 0) parts.push(`dirty=${rec.dirty}`);
|
|
9426
|
+
if (rec.ledger_untracked === void 0 && rec.untracked !== void 0) parts.push(`untracked=${rec.untracked}`);
|
|
9400
9427
|
if (rec.blocked_reason) parts.push(rec.blocked_reason);
|
|
9401
|
-
if (rec.detail) parts.push(rec.detail);
|
|
9428
|
+
if (rec.detail && rec.detail !== rec.blocked_reason) parts.push(rec.detail);
|
|
9402
9429
|
return parts.join(" ");
|
|
9403
9430
|
}
|
|
9404
9431
|
function composeCopyStatus(input) {
|
|
@@ -9466,11 +9493,21 @@ function defaultCopyStatusDeps(input) {
|
|
|
9466
9493
|
const behind = behindRaw === "" ? void 0 : Number.parseInt(behindRaw, 10);
|
|
9467
9494
|
const review = listReviewRequiredOps(input.vault)[0];
|
|
9468
9495
|
const blockedReason = review ? `review-required:${review.opId}` : void 0;
|
|
9496
|
+
const dirty = measureDirtyVolume(input.vault);
|
|
9497
|
+
const dirtyCount = dirty.is_git_repo ? dirty.expanded_files : void 0;
|
|
9498
|
+
const untrackedCount = dirty.is_git_repo ? dirty.untracked : void 0;
|
|
9499
|
+
const ledgerUntracked = dirty.is_git_repo ? dirty.ledger_files : void 0;
|
|
9500
|
+
const contentUntracked = dirty.is_git_repo ? dirty.content_files : void 0;
|
|
9501
|
+
const dirtyHint = dirtyCount && dirtyCount > 0 ? ledgerUntracked && ledgerUntracked > 0 ? `event-ledger live-ahead of GitHub; do not git add` : `live-ahead of GitHub; do not git add` : void 0;
|
|
9469
9502
|
return {
|
|
9470
9503
|
head,
|
|
9471
9504
|
behind: Number.isFinite(behind) ? behind : void 0,
|
|
9472
9505
|
blockedReason,
|
|
9473
|
-
|
|
9506
|
+
dirty: dirtyCount,
|
|
9507
|
+
untracked: untrackedCount,
|
|
9508
|
+
ledger_untracked: dirtyCount && dirtyCount > 0 ? ledgerUntracked : void 0,
|
|
9509
|
+
content_untracked: dirtyCount && dirtyCount > 0 ? contentUntracked : void 0,
|
|
9510
|
+
detail: dirtyHint ?? blockedReason
|
|
9474
9511
|
};
|
|
9475
9512
|
}
|
|
9476
9513
|
};
|
package/dist/skillwiki-mcp.js
CHANGED
|
@@ -72,7 +72,17 @@ log() {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
handle_existing_handoff() {
|
|
75
|
-
local blocker reason op identity previous_identity notified_at now
|
|
75
|
+
local blocker reason op identity previous_identity notified_at now before after
|
|
76
|
+
# Same altitude as managed-write preflight: a review-required whose target_oid
|
|
77
|
+
# is already in HEAD is obsolete. Preserve dirty live-ahead WIP; only real
|
|
78
|
+
# unresolved handoffs (target still ahead / sequencer / unmerged) skip pull.
|
|
79
|
+
before="$(vault_sync_op_find_review_required "$WIKI_DIR" 2>/dev/null || true)"
|
|
80
|
+
if vault_sync_op_supersede_stale_review_required "$WIKI_DIR" "wiki-fetch-notify" 2>/dev/null; then
|
|
81
|
+
after="$(vault_sync_op_find_review_required "$WIKI_DIR" 2>/dev/null || true)"
|
|
82
|
+
if [ -n "$before" ] && [ -z "$after" ]; then
|
|
83
|
+
log "OK superseded stale review-required handoff(s); fetch pull may proceed"
|
|
84
|
+
fi
|
|
85
|
+
fi
|
|
76
86
|
blocker="$(vault_sync_op_preflight_blocker "$WIKI_DIR" 2>/dev/null || true)"
|
|
77
87
|
[ -n "$blocker" ] || { rm -f "$HANDOFF_STATE_FILE" "$FETCH_HARD_PAUSE_COUNTER_FILE" 2>/dev/null || true; return 1; }
|
|
78
88
|
|
|
@@ -100,6 +100,26 @@ CLOUD_REMOTE="${CLOUD_REMOTE:-cloud:cloud/wiki}"
|
|
|
100
100
|
REPAIR_SCRIPT="${WIKI_GIT_REPAIR_SCRIPT:-$SCRIPT_DIR/wiki-git-repair-v3.sh}"
|
|
101
101
|
MAX_S3_ONLY_NOTES="${WIKI_SNAPSHOT_MAX_S3_ONLY_NOTES:-200}"
|
|
102
102
|
MAX_TOMBSTONE_PRUNES="${WIKI_SNAPSHOT_MAX_TOMBSTONE_PRUNES:-10}"
|
|
103
|
+
|
|
104
|
+
# Classified inventory: event ledger + local scratch are not GitHub-promotable notes.
|
|
105
|
+
# Cap and rclone must share this class. Do not raise MAX_S3_ONLY_NOTES instead.
|
|
106
|
+
# meta/log-events stay S3-authoritative; snapshot copies them separately for --events-from.
|
|
107
|
+
snapshot_non_promotable_path() {
|
|
108
|
+
local p="${1#./}"
|
|
109
|
+
case "$p" in
|
|
110
|
+
.skillwiki/*|.claude/*|.obsidian/*|.antigravitycli/*|.playwright-cli/*|.superpowers/*|.snapshots/*|.git/*|.drafts/*)
|
|
111
|
+
return 0 ;;
|
|
112
|
+
tmp/*|logs|logs/*|meta/log-events|meta/log-events/*)
|
|
113
|
+
return 0 ;;
|
|
114
|
+
raw/._.DS_Store|._.DS_Store)
|
|
115
|
+
return 0 ;;
|
|
116
|
+
._*)
|
|
117
|
+
return 0 ;;
|
|
118
|
+
.conflict*|*.conflict-*)
|
|
119
|
+
return 0 ;;
|
|
120
|
+
esac
|
|
121
|
+
return 1
|
|
122
|
+
}
|
|
103
123
|
PROJECTION_PARITY_TIMEOUT_SECONDS="${WIKI_SNAPSHOT_PROJECTION_PARITY_TIMEOUT_SECONDS:-120}"
|
|
104
124
|
PROJECTION_PARITY_POLL_SECONDS="${WIKI_SNAPSHOT_PROJECTION_PARITY_POLL_SECONDS:-2}"
|
|
105
125
|
PROJECTION_READ_TIMEOUT_SECONDS="${WIKI_SNAPSHOT_PROJECTION_READ_TIMEOUT_SECONDS:-15}"
|
|
@@ -185,7 +205,14 @@ snapshot_direct_s3_preflight() {
|
|
|
185
205
|
fi
|
|
186
206
|
SNAPSHOT_REMOTE_INVENTORY_READY=1
|
|
187
207
|
|
|
188
|
-
|
|
208
|
+
: > "$direct_notes"
|
|
209
|
+
while IFS= read -r snapshot_inv_path || [ -n "$snapshot_inv_path" ]; do
|
|
210
|
+
[ -n "$snapshot_inv_path" ] || continue
|
|
211
|
+
if snapshot_non_promotable_path "$snapshot_inv_path"; then
|
|
212
|
+
continue
|
|
213
|
+
fi
|
|
214
|
+
printf '%s\n' "$snapshot_inv_path"
|
|
215
|
+
done < "$direct_paths" | LC_ALL=C sort -u > "$direct_notes" || true
|
|
189
216
|
(
|
|
190
217
|
cd "$SNAPSHOT_WORKTREE" || exit 1
|
|
191
218
|
if git rev-parse --verify --quiet origin/main >/dev/null 2>&1; then
|
|
@@ -939,6 +966,11 @@ RCLONE_OPTS=(
|
|
|
939
966
|
--exclude ".antigravitycli/**"
|
|
940
967
|
--exclude ".playwright-cli/**"
|
|
941
968
|
--exclude ".superpowers/**"
|
|
969
|
+
--exclude ".drafts/**"
|
|
970
|
+
--exclude "tmp/**"
|
|
971
|
+
--exclude "logs"
|
|
972
|
+
--exclude "logs/**"
|
|
973
|
+
--exclude "meta/log-events/**"
|
|
942
974
|
--exclude "._*"
|
|
943
975
|
--exclude ".conflict*"
|
|
944
976
|
--exclude "*.conflict-*"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skillwiki",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.90",
|
|
4
4
|
"skills": "./",
|
|
5
5
|
"description": "Project-aware Karpathy-style knowledge base for Claude Code: 21 prompt-only skills (wiki-*, proj-*, using-skillwiki, skillwiki-mcp) backed by the deterministic `skillwiki` CLI.",
|
|
6
6
|
"author": {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skillwiki",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.90",
|
|
4
4
|
"description": "Project-aware Karpathy-style knowledge base: 21 prompt-only skills (wiki-*, proj-*, using-skillwiki, skillwiki-mcp) backed by HTTP MCP wiki_capture.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "karlorz"
|