skillwiki 0.10.37 → 0.10.40
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-WJVG3DD5.js → chunk-NDR2OY4K.js} +1 -0
- package/dist/cli.js +29 -7
- package/dist/skillwiki-mcp.js +1 -1
- package/dist/vault-sync/scripts/wiki-fetch-notify.sh +51 -1
- package/dist/vault-sync/scripts/wiki-push.sh +109 -2
- package/package.json +1 -1
- package/skills/.claude-plugin/plugin.json +1 -1
- package/skills/.codex-plugin/plugin.json +1 -1
- package/skills/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
GateError,
|
|
8
8
|
SATELLITE_STALE_MS,
|
|
9
9
|
configPath,
|
|
10
|
+
detectFuseMount,
|
|
10
11
|
evaluateDirtyVolumeGate,
|
|
11
12
|
evaluateSatelliteRunHealth,
|
|
12
13
|
findPlugin,
|
|
@@ -38,7 +39,7 @@ import {
|
|
|
38
39
|
scanConflictMarkerBlocksInText,
|
|
39
40
|
snapshotterHealthChecks,
|
|
40
41
|
upsertIndexEntry
|
|
41
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-NDR2OY4K.js";
|
|
42
43
|
import {
|
|
43
44
|
normalizeDistTag,
|
|
44
45
|
readCache,
|
|
@@ -168,6 +169,7 @@ import {
|
|
|
168
169
|
ok,
|
|
169
170
|
readPage,
|
|
170
171
|
redactSensitiveContent,
|
|
172
|
+
resolveReadOnlyVaultRoot,
|
|
171
173
|
scanSensitiveContent,
|
|
172
174
|
scanVault,
|
|
173
175
|
splitFrontmatter
|
|
@@ -4471,7 +4473,8 @@ import { mkdir as mkdir8, readFile as readFile11, writeFile as writeFile7 } from
|
|
|
4471
4473
|
import { join as join24, relative, sep } from "path";
|
|
4472
4474
|
var MAX_WORDS = 900;
|
|
4473
4475
|
async function runSessionBrief(input) {
|
|
4474
|
-
const
|
|
4476
|
+
const { root: scanRoot } = resolveReadOnlyVaultRoot(input.vault);
|
|
4477
|
+
const scan = await scanVault(scanRoot);
|
|
4475
4478
|
if (!scan.ok) {
|
|
4476
4479
|
return { exitCode: ExitCode.VAULT_PATH_INVALID, result: scan };
|
|
4477
4480
|
}
|
|
@@ -4497,7 +4500,7 @@ async function runSessionBrief(input) {
|
|
|
4497
4500
|
loadSatelliteHealth(input.vault),
|
|
4498
4501
|
loadSessionPins(input.vault, project),
|
|
4499
4502
|
project ? loadMemoryTopics(input.vault, project) : Promise.resolve([]),
|
|
4500
|
-
loadPendingSources(
|
|
4503
|
+
loadPendingSources(scanRoot, today)
|
|
4501
4504
|
]);
|
|
4502
4505
|
const healthWarnings = [
|
|
4503
4506
|
...baseHealthWarnings,
|
|
@@ -8404,11 +8407,23 @@ async function runBackupRestore(input) {
|
|
|
8404
8407
|
import { existsSync as existsSync10, statSync as statSync4 } from "fs";
|
|
8405
8408
|
import { readFile as readFile16 } from "fs/promises";
|
|
8406
8409
|
import { join as join32 } from "path";
|
|
8410
|
+
var FUSE_NO_MIRROR_NOTE = "FUSE vault with no read mirror - status scan may be slow";
|
|
8407
8411
|
async function runStatus(input) {
|
|
8408
8412
|
if (!existsSync10(input.vault)) {
|
|
8409
8413
|
return { exitCode: ExitCode.VAULT_PATH_INVALID, result: err("VAULT_PATH_INVALID", { vault: input.vault }) };
|
|
8410
8414
|
}
|
|
8411
|
-
const
|
|
8415
|
+
const { root: scanRoot, mirrored } = resolveReadOnlyVaultRoot(input.vault);
|
|
8416
|
+
let readSource = "live";
|
|
8417
|
+
if (mirrored) {
|
|
8418
|
+
readSource = "mirror";
|
|
8419
|
+
} else if (detectFuseMount(input.vault)) {
|
|
8420
|
+
readSource = "fuse-no-mirror";
|
|
8421
|
+
}
|
|
8422
|
+
if (readSource === "fuse-no-mirror") {
|
|
8423
|
+
process.stderr.write(`warning: ${FUSE_NO_MIRROR_NOTE}
|
|
8424
|
+
`);
|
|
8425
|
+
}
|
|
8426
|
+
const scan = await scanVault(scanRoot);
|
|
8412
8427
|
if (!scan.ok) {
|
|
8413
8428
|
return { exitCode: ExitCode.VAULT_PATH_INVALID, result: scan };
|
|
8414
8429
|
}
|
|
@@ -8430,7 +8445,7 @@ async function runStatus(input) {
|
|
|
8430
8445
|
const compound = scan.data.compound.length;
|
|
8431
8446
|
let schemaVersion = "v1";
|
|
8432
8447
|
try {
|
|
8433
|
-
const schemaContent = await readFile16(join32(
|
|
8448
|
+
const schemaContent = await readFile16(join32(scanRoot, "SCHEMA.md"), "utf8");
|
|
8434
8449
|
const versionMatch = schemaContent.match(/version:\s*["']?([^"'\s\n]+)/i);
|
|
8435
8450
|
if (versionMatch) schemaVersion = versionMatch[1];
|
|
8436
8451
|
} catch {
|
|
@@ -8467,14 +8482,20 @@ async function runStatus(input) {
|
|
|
8467
8482
|
};
|
|
8468
8483
|
const totalPages = Object.values(pageCounts).reduce((a, b) => a + b, 0);
|
|
8469
8484
|
const rawTotal = rawArticles + rawTranscripts;
|
|
8470
|
-
const
|
|
8485
|
+
const hintLines = [
|
|
8471
8486
|
`vault: ${input.vault}`,
|
|
8472
8487
|
`lang: ${langResult.value}`,
|
|
8473
8488
|
`total: ${totalPages} pages`,
|
|
8474
8489
|
` entities: ${pageCounts.entities} concepts: ${pageCounts.concepts} comparisons: ${pageCounts.comparisons} queries: ${pageCounts.queries} meta: ${pageCounts.meta}`,
|
|
8475
8490
|
` raw: ${rawTotal} work_items: ${workItems} compound: ${compound}`,
|
|
8476
8491
|
`last modified: ${lastModified.slice(0, 10)}`
|
|
8477
|
-
]
|
|
8492
|
+
];
|
|
8493
|
+
if (readSource === "mirror") {
|
|
8494
|
+
hintLines.push(`read source: mirror (${scanRoot}) - page counts may lag up to 30m`);
|
|
8495
|
+
} else if (readSource === "fuse-no-mirror") {
|
|
8496
|
+
hintLines.push(FUSE_NO_MIRROR_NOTE);
|
|
8497
|
+
}
|
|
8498
|
+
const humanHint = hintLines.join("\n");
|
|
8478
8499
|
return {
|
|
8479
8500
|
exitCode: ExitCode.OK,
|
|
8480
8501
|
result: ok({
|
|
@@ -8484,6 +8505,7 @@ async function runStatus(input) {
|
|
|
8484
8505
|
page_counts: pageCounts,
|
|
8485
8506
|
total_pages: totalPages,
|
|
8486
8507
|
last_modified: lastModified,
|
|
8508
|
+
read_source: readSource,
|
|
8487
8509
|
humanHint
|
|
8488
8510
|
})
|
|
8489
8511
|
};
|
package/dist/skillwiki-mcp.js
CHANGED
|
@@ -32,6 +32,21 @@ HANDOFF_NOTIFY_AFTER_SECONDS="${WIKI_FETCH_HANDOFF_NOTIFY_AFTER_SECONDS:-3600}"
|
|
|
32
32
|
case "$HANDOFF_NOTIFY_AFTER_SECONDS" in
|
|
33
33
|
''|*[!0-9]*) HANDOFF_NOTIFY_AFTER_SECONDS=3600 ;;
|
|
34
34
|
esac
|
|
35
|
+
# P2 handoff hard-pause (2026-08-12 design, see projects/llm-wiki/architecture/2026-08-12-wiki-push-fail-dedup-design.md)
|
|
36
|
+
# WIKI_FETCH_HANDOFF_HARD_PAUSE=1 enables the hard pause; default is 0 (opt-in
|
|
37
|
+
# per design Q3) so the legacy reminder-backoff behavior is preserved.
|
|
38
|
+
# WIKI_FETCH_HANDOFF_HARD_PAUSE_CYCLES controls the threshold of consecutive
|
|
39
|
+
# 5-min cycles of the same handoff identity before pausing the fetch job
|
|
40
|
+
# (default 13 cycles — one past the 1h HANDOFF_NOTIFY_AFTER_SECONDS mark at
|
|
41
|
+
# StartInterval=300, so the counter can reach the threshold before the
|
|
42
|
+
# notify resets it; the design's "1-hour hard pause" intent is preserved).
|
|
43
|
+
FETCH_HARD_PAUSE="${WIKI_FETCH_HANDOFF_HARD_PAUSE:-0}"
|
|
44
|
+
FETCH_HARD_PAUSE_CYCLES="${WIKI_FETCH_HANDOFF_HARD_PAUSE_CYCLES:-13}"
|
|
45
|
+
case "$FETCH_HARD_PAUSE_CYCLES" in
|
|
46
|
+
''|*[!0-9]*) FETCH_HARD_PAUSE_CYCLES=13 ;;
|
|
47
|
+
esac
|
|
48
|
+
FETCH_HARD_PAUSE_COUNTER_FILE="$STATE_DIR/handoff-cycle-counter"
|
|
49
|
+
FETCH_HARD_PAUSE_MARKER="$STATE_DIR/wiki-fetch.paused"
|
|
35
50
|
# Opt-in: when enabled, a positive delta triggers `git pull --rebase` so the
|
|
36
51
|
# local working tree consumes sg01 Snapshot commits automatically. This
|
|
37
52
|
# replaces the git pull that was previously bundled inside wiki-push.sh's
|
|
@@ -43,6 +58,15 @@ LOG_FILE="$(platform_log_dir)/wiki-fetch.log"
|
|
|
43
58
|
|
|
44
59
|
mkdir -p "$STATE_DIR" "$(dirname "$LOG_FILE")"
|
|
45
60
|
|
|
61
|
+
# Terminal-state check: if the pause marker exists from a prior incident,
|
|
62
|
+
# the launchd job is already unloaded. Honor the pause — log once and exit
|
|
63
|
+
# without re-fetching or re-notifying. The user clears this by removing
|
|
64
|
+
# the marker and re-loading the plist (per design Q1, B).
|
|
65
|
+
if [ -f "$FETCH_HARD_PAUSE_MARKER" ]; then
|
|
66
|
+
log "PAUSED fetch job is paused; marker present at $FETCH_HARD_PAUSE_MARKER — exiting"
|
|
67
|
+
exit 0
|
|
68
|
+
fi
|
|
69
|
+
|
|
46
70
|
log() {
|
|
47
71
|
printf '%s %s\n' "$(date -u +%FT%TZ)" "$*" >>"$LOG_FILE"
|
|
48
72
|
}
|
|
@@ -50,7 +74,7 @@ log() {
|
|
|
50
74
|
handle_existing_handoff() {
|
|
51
75
|
local blocker reason op identity previous_identity notified_at now
|
|
52
76
|
blocker="$(vault_sync_op_preflight_blocker "$WIKI_DIR" 2>/dev/null || true)"
|
|
53
|
-
[ -n "$blocker" ] || { rm -f "$HANDOFF_STATE_FILE" 2>/dev/null || true; return 1; }
|
|
77
|
+
[ -n "$blocker" ] || { rm -f "$HANDOFF_STATE_FILE" "$FETCH_HARD_PAUSE_COUNTER_FILE" 2>/dev/null || true; return 1; }
|
|
54
78
|
|
|
55
79
|
reason="${blocker%% *}"
|
|
56
80
|
op="${blocker#* }"
|
|
@@ -69,8 +93,34 @@ handle_existing_handoff() {
|
|
|
69
93
|
platform_notify "wiki" "review-required handoff ${op:-none} still blocks sync"
|
|
70
94
|
printf 'identity=%s\nnotified_at=%s\n' "$identity" "$now" > "$HANDOFF_STATE_FILE"
|
|
71
95
|
log "NOTIFY handoff identity=$identity"
|
|
96
|
+
# P2: a new handoff identity (or a fresh notify) resets the cycle counter.
|
|
97
|
+
if [ "$FETCH_HARD_PAUSE" = "1" ]; then
|
|
98
|
+
printf '0\n' > "$FETCH_HARD_PAUSE_COUNTER_FILE" 2>/dev/null || true
|
|
99
|
+
fi
|
|
72
100
|
else
|
|
73
101
|
log "SKIP PULL handoff identity=$identity reminder-backoff"
|
|
102
|
+
# P2: increment the cycle counter for this identity. When the counter
|
|
103
|
+
# reaches FETCH_HARD_PAUSE_CYCLES, write the persistent-handoff log line
|
|
104
|
+
# and unload the launchd job (with marker-file fallback for non-macOS).
|
|
105
|
+
if [ "$FETCH_HARD_PAUSE" = "1" ]; then
|
|
106
|
+
local cycle_count
|
|
107
|
+
cycle_count=0
|
|
108
|
+
if [ -f "$FETCH_HARD_PAUSE_COUNTER_FILE" ]; then
|
|
109
|
+
cycle_count="$(cat "$FETCH_HARD_PAUSE_COUNTER_FILE" 2>/dev/null || echo 0)"
|
|
110
|
+
case "$cycle_count" in ''|*[!0-9]*) cycle_count=0 ;; esac
|
|
111
|
+
fi
|
|
112
|
+
cycle_count=$((cycle_count + 1))
|
|
113
|
+
printf '%s\n' "$cycle_count" > "$FETCH_HARD_PAUSE_COUNTER_FILE" 2>/dev/null || true
|
|
114
|
+
if [ "$cycle_count" -ge "$FETCH_HARD_PAUSE_CYCLES" ]; then
|
|
115
|
+
log "handoff persistent — pausing fetch (identity=$identity cycles=$cycle_count threshold=$FETCH_HARD_PAUSE_CYCLES)"
|
|
116
|
+
printf 'paused_at=%s\nidentity=%s\ncycles=%s\nthreshold=%s\nreason=handoff-persistent-past-threshold\n' \
|
|
117
|
+
"$(date -u +%FT%TZ)" "$identity" "$cycle_count" "$FETCH_HARD_PAUSE_CYCLES" \
|
|
118
|
+
> "$FETCH_HARD_PAUSE_MARKER" 2>/dev/null || true
|
|
119
|
+
if [ "$(platform_scheduler)" = "launchd" ]; then
|
|
120
|
+
launchctl unload "$HOME/Library/LaunchAgents/com.karlchow.wiki-fetch.plist" 2>/dev/null || true
|
|
121
|
+
fi
|
|
122
|
+
fi
|
|
123
|
+
fi
|
|
74
124
|
fi
|
|
75
125
|
return 0
|
|
76
126
|
}
|
|
@@ -37,20 +37,122 @@ LOCK_FILE="$(platform_cache_dir)/wiki-push.lock"
|
|
|
37
37
|
LOG_FILE="$(platform_log_dir)/wiki-push.log"
|
|
38
38
|
LOG_MAX_SIZE=1048576 # 1 MB
|
|
39
39
|
LOG_KEEP=5
|
|
40
|
+
# P1 conflict-marker dedup (2026-08-12 design, see projects/llm-wiki/architecture/2026-08-12-wiki-push-fail-dedup-design.md)
|
|
41
|
+
# WIKI_PUSH_FAIL_DEDUP_DISABLE=1 disables the dedup entirely (rollback to legacy behavior).
|
|
42
|
+
# WIKI_PUSH_FAIL_DEDUP_COOLDOWN_SECONDS controls the per-incident cooldown window (default 900s = 15min).
|
|
43
|
+
PUSH_DEDUP_DISABLE="${WIKI_PUSH_FAIL_DEDUP_DISABLE:-0}"
|
|
44
|
+
PUSH_DEDUP_COOLDOWN_SECONDS="${WIKI_PUSH_FAIL_DEDUP_COOLDOWN_SECONDS:-900}"
|
|
45
|
+
PUSH_DEDUP_STATE_FILE="$(platform_cache_dir)/wiki-push-fail-dedup.state"
|
|
46
|
+
PUSH_DEDUP_PAUSE_MARKER="$(platform_cache_dir)/wiki-push.paused"
|
|
40
47
|
|
|
41
48
|
mkdir -p "$(dirname "$LOCK_FILE")" "$(dirname "$LOG_FILE")"
|
|
42
49
|
|
|
43
50
|
log() { printf '%s %s\n' "$(date -u +%FT%TZ)" "$*" >>"$LOG_FILE"; }
|
|
44
51
|
|
|
52
|
+
# Terminal-state check: if the pause marker exists from a prior incident,
|
|
53
|
+
# the launchd job is already unloaded. Honor the pause — log once and exit
|
|
54
|
+
# without re-scanning or re-attempting the push. The user clears this by
|
|
55
|
+
# removing the marker and re-loading the plist (per design Q1, B).
|
|
56
|
+
if [ "$PUSH_DEDUP_DISABLE" != "1" ] && [ -f "$PUSH_DEDUP_PAUSE_MARKER" ]; then
|
|
57
|
+
log "PAUSED push job is paused; marker present at $PUSH_DEDUP_PAUSE_MARKER — exiting"
|
|
58
|
+
exit 0
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
# P1 dedup state check: read the dedup state file's mtime and compare against
|
|
62
|
+
# the cooldown window. Echoes one of: "disabled" (dedup turned off, caller
|
|
63
|
+
# must not touch state), "first" (no prior incident, standard guard should
|
|
64
|
+
# run), "cooldown" (within window, suppress duplicate FAIL line + skip the
|
|
65
|
+
# new FAIL log), "expired" (past window, escalate to pause).
|
|
66
|
+
push_dedup_cooldown_check() {
|
|
67
|
+
if [ "$PUSH_DEDUP_DISABLE" = "1" ]; then
|
|
68
|
+
printf '%s\n' "disabled"
|
|
69
|
+
return 0
|
|
70
|
+
fi
|
|
71
|
+
if [ ! -f "$PUSH_DEDUP_STATE_FILE" ]; then
|
|
72
|
+
printf '%s\n' "first"
|
|
73
|
+
return 0
|
|
74
|
+
fi
|
|
75
|
+
local state_ctime now elapsed
|
|
76
|
+
state_ctime="$(platform_stat_ctime "$PUSH_DEDUP_STATE_FILE" 2>/dev/null || echo 0)"
|
|
77
|
+
now="$(date +%s)"
|
|
78
|
+
elapsed=$((now - state_ctime))
|
|
79
|
+
if [ "$elapsed" -lt "$PUSH_DEDUP_COOLDOWN_SECONDS" ]; then
|
|
80
|
+
printf '%s\n' "cooldown"
|
|
81
|
+
return 0
|
|
82
|
+
fi
|
|
83
|
+
printf '%s\n' "expired"
|
|
84
|
+
return 0
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
# Touch (or create) the dedup state file so subsequent invocations see the
|
|
88
|
+
# incident's first-detection timestamp. Uses a single `touch` to avoid races
|
|
89
|
+
# with parallel invocations (which are guarded by the lockfile above).
|
|
90
|
+
push_dedup_touch_state() {
|
|
91
|
+
touch "$PUSH_DEDUP_STATE_FILE" 2>/dev/null || true
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
# Clear the dedup state file (used on a successful push, when markers are gone).
|
|
95
|
+
push_dedup_clear_state() {
|
|
96
|
+
rm -f "$PUSH_DEDUP_STATE_FILE" 2>/dev/null || true
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
# Write a pause marker file as a portable stand-in for `launchctl unload`.
|
|
100
|
+
# On a real macOS host, the launchd plist is the actual unpause target; this
|
|
101
|
+
# marker is a portable test surface and a cross-platform indicator.
|
|
102
|
+
push_dedup_write_pause_marker() {
|
|
103
|
+
local now
|
|
104
|
+
now="$(date -u +%FT%TZ)"
|
|
105
|
+
printf 'paused_at=%s reason=conflict-markers-persist-past-cooldown cooldown_seconds=%s\n' \
|
|
106
|
+
"$now" "$PUSH_DEDUP_COOLDOWN_SECONDS" > "$PUSH_DEDUP_PAUSE_MARKER" 2>/dev/null || true
|
|
107
|
+
if [ "$(platform_scheduler)" = "launchd" ]; then
|
|
108
|
+
# Best-effort launchd unload. Failure is non-fatal — the marker file is
|
|
109
|
+
# the canonical pause signal. This matches the design doc's rollback
|
|
110
|
+
# semantics: the marker is the test surface, launchctl is the production
|
|
111
|
+
# surface, both can be present.
|
|
112
|
+
launchctl unload "$HOME/Library/LaunchAgents/com.karlchow.wiki-push.plist" 2>/dev/null || true
|
|
113
|
+
fi
|
|
114
|
+
}
|
|
115
|
+
|
|
45
116
|
conflict_marker_guard() {
|
|
46
117
|
local findings
|
|
47
118
|
findings="$(mktemp)" || { log "FAIL could not create conflict-marker scan temp file"; return 1; }
|
|
48
119
|
if ! vault_sync_scan_conflict_markers "$WIKI_DIR" "$findings"; then
|
|
49
|
-
|
|
50
|
-
|
|
120
|
+
local dedup_state
|
|
121
|
+
dedup_state="$(push_dedup_cooldown_check)"
|
|
122
|
+
case "$dedup_state" in
|
|
123
|
+
first)
|
|
124
|
+
# First detection: log the FAIL line, mark the state file so
|
|
125
|
+
# subsequent invocations within the cooldown window are silent.
|
|
126
|
+
log "FAIL conflict marker blocks present; refusing S3 push"
|
|
127
|
+
vault_sync_log_conflict_marker_findings "$findings" "$LOG_FILE"
|
|
128
|
+
push_dedup_touch_state
|
|
129
|
+
;;
|
|
130
|
+
expired)
|
|
131
|
+
# Past the cooldown: log the FAIL line + escalation notice,
|
|
132
|
+
# write the pause marker, refresh the state file so the next
|
|
133
|
+
# cooldown starts from this moment.
|
|
134
|
+
log "FAIL conflict marker blocks present; refusing S3 push"
|
|
135
|
+
vault_sync_log_conflict_marker_findings "$findings" "$LOG_FILE"
|
|
136
|
+
log "cooldown expired — pausing push (markers persist past ${PUSH_DEDUP_COOLDOWN_SECONDS}s)"
|
|
137
|
+
push_dedup_write_pause_marker
|
|
138
|
+
push_dedup_touch_state
|
|
139
|
+
;;
|
|
140
|
+
cooldown)
|
|
141
|
+
# Within cooldown: suppress the duplicate FAIL line. The first
|
|
142
|
+
# FAIL line in the incident (state=first) is already logged;
|
|
143
|
+
# subsequent invocations within the cooldown are silent.
|
|
144
|
+
;;
|
|
145
|
+
disabled)
|
|
146
|
+
# Dedup is off: log the FAIL line (legacy behavior), do not
|
|
147
|
+
# touch any state file or pause marker.
|
|
148
|
+
log "FAIL conflict marker blocks present; refusing S3 push"
|
|
149
|
+
vault_sync_log_conflict_marker_findings "$findings" "$LOG_FILE"
|
|
150
|
+
;;
|
|
151
|
+
esac
|
|
51
152
|
rm -f "$findings"
|
|
52
153
|
return 1
|
|
53
154
|
fi
|
|
155
|
+
push_dedup_clear_state
|
|
54
156
|
rm -f "$findings"
|
|
55
157
|
return 0
|
|
56
158
|
}
|
|
@@ -359,6 +461,11 @@ if [ "$RC" -eq 0 ]; then
|
|
|
359
461
|
if ! remote_prune_tombstoned_paths; then
|
|
360
462
|
log "FAIL tombstone prune failed after rclone copy"
|
|
361
463
|
fi
|
|
464
|
+
# P1: a successful push proves markers are gone. conflict_marker_guard
|
|
465
|
+
# already cleared the dedup state on the scan-success path. The pause
|
|
466
|
+
# marker rm is defensive: it covers the case where the user manually
|
|
467
|
+
# unpaused the launchd job without removing the marker file.
|
|
468
|
+
rm -f "$PUSH_DEDUP_PAUSE_MARKER" 2>/dev/null || true
|
|
362
469
|
fi
|
|
363
470
|
|
|
364
471
|
exit 0
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skillwiki",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.40",
|
|
4
4
|
"skills": "./",
|
|
5
5
|
"description": "Project-aware Karpathy-style knowledge base for Claude Code: 19 prompt-only skills (wiki-*, proj-*, using-skillwiki) backed by the deterministic `skillwiki` CLI.",
|
|
6
6
|
"author": {
|