skillwiki 0.10.20 → 0.10.21
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-QJPCCW4N.js → chunk-65Q5UGND.js} +38 -12
- package/dist/cli.js +2 -2
- package/dist/{managed-write-preflight-LO4LZ6OQ.js → managed-write-preflight-CTXX2MHQ.js} +1 -1
- package/dist/vault-sync/scripts/lib/managed-write-lock.sh +4 -3
- 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
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
|
|
19
19
|
// src/utils/managed-write-preflight.ts
|
|
20
20
|
import { existsSync as existsSync2 } from "fs";
|
|
21
|
-
import { join as join2, resolve } from "path";
|
|
21
|
+
import { join as join2, resolve as resolve2 } from "path";
|
|
22
22
|
|
|
23
23
|
// src/utils/managed-write-lock.ts
|
|
24
24
|
import { randomBytes } from "crypto";
|
|
@@ -29,7 +29,8 @@ import {
|
|
|
29
29
|
unlinkSync,
|
|
30
30
|
writeFileSync
|
|
31
31
|
} from "fs";
|
|
32
|
-
import {
|
|
32
|
+
import { hostname } from "os";
|
|
33
|
+
import { dirname, join, resolve } from "path";
|
|
33
34
|
function managedWriteLockPath(vault) {
|
|
34
35
|
const gitPath = git(vault, ["rev-parse", "--git-path", "vault-sync/managed-write.lock"]);
|
|
35
36
|
if (gitPath) return gitPath.startsWith("/") ? gitPath : join(vault, gitPath);
|
|
@@ -65,19 +66,35 @@ function hasUnsafeGitState(vault) {
|
|
|
65
66
|
const unmerged = git(vault, ["ls-files", "-u"]);
|
|
66
67
|
return Boolean(unmerged && unmerged.trim().length > 0);
|
|
67
68
|
}
|
|
68
|
-
function
|
|
69
|
+
function isGitBackedVault(vault) {
|
|
70
|
+
return Boolean(git(vault, ["rev-parse", "--absolute-git-dir"]));
|
|
71
|
+
}
|
|
72
|
+
function hasLocalOwnerProof(vault, record) {
|
|
73
|
+
return isGitBackedVault(vault) || typeof record.owner_hostname === "string" && record.owner_hostname === hostname();
|
|
74
|
+
}
|
|
75
|
+
function reclaimDeadManagedWriteLockOwner(vault, options = {}) {
|
|
69
76
|
const path = managedWriteLockPath(vault);
|
|
77
|
+
const gitStateVault = resolve(options.gitStateVault ?? vault);
|
|
70
78
|
if (!existsSync(path)) return ok({ reclaimed: false });
|
|
71
79
|
const record = readLockRecord(path);
|
|
72
80
|
if (!record) {
|
|
73
81
|
return err("SYNC_LOCK_HELD", { path, message: "managed-write lock unreadable" });
|
|
74
82
|
}
|
|
83
|
+
if (!hasLocalOwnerProof(vault, record)) {
|
|
84
|
+
return err("SYNC_LOCK_HELD", {
|
|
85
|
+
path,
|
|
86
|
+
owner_hostname: record.owner_hostname,
|
|
87
|
+
current_hostname: hostname(),
|
|
88
|
+
message: "managed-write lock origin is foreign or unknown"
|
|
89
|
+
});
|
|
90
|
+
}
|
|
75
91
|
if (isManagedWriteLockOwnerAlive(record.pid)) {
|
|
76
92
|
return err("SYNC_LOCK_HELD", { path, message: "managed-write lock owner is alive" });
|
|
77
93
|
}
|
|
78
|
-
if (hasUnsafeGitState(
|
|
94
|
+
if (hasUnsafeGitState(gitStateVault)) {
|
|
79
95
|
return err("SYNC_LOCK_HELD", {
|
|
80
96
|
path,
|
|
97
|
+
git_state_vault: gitStateVault,
|
|
81
98
|
message: "managed-write lock not reclaimed: unsafe git state"
|
|
82
99
|
});
|
|
83
100
|
}
|
|
@@ -90,6 +107,7 @@ function reclaimDeadManagedWriteLockOwner(vault) {
|
|
|
90
107
|
recovered_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
91
108
|
recovery_reason: "owner_pid_dead",
|
|
92
109
|
owner_pid_alive: false,
|
|
110
|
+
git_state_vault: gitStateVault,
|
|
93
111
|
lock: record
|
|
94
112
|
};
|
|
95
113
|
writeFileSync(recoveryPath, `${JSON.stringify(meta, null, 2)}
|
|
@@ -107,7 +125,13 @@ function tryCreateLock(path, command) {
|
|
|
107
125
|
mkdirSync(dirname(path), { recursive: true });
|
|
108
126
|
writeFileSync(
|
|
109
127
|
path,
|
|
110
|
-
`${JSON.stringify({
|
|
128
|
+
`${JSON.stringify({
|
|
129
|
+
pid: process.pid,
|
|
130
|
+
owner_hostname: hostname(),
|
|
131
|
+
owner_token: ownerToken,
|
|
132
|
+
acquired,
|
|
133
|
+
command
|
|
134
|
+
})}
|
|
111
135
|
`,
|
|
112
136
|
{ flag: "wx" }
|
|
113
137
|
);
|
|
@@ -117,14 +141,14 @@ function tryCreateLock(path, command) {
|
|
|
117
141
|
return err("WRITE_FAILED", { path, message: String(error) });
|
|
118
142
|
}
|
|
119
143
|
}
|
|
120
|
-
function acquireManagedWriteLock(vault, command) {
|
|
144
|
+
function acquireManagedWriteLock(vault, command, options = {}) {
|
|
121
145
|
const path = managedWriteLockPath(vault);
|
|
122
146
|
const first = tryCreateLock(path, command);
|
|
123
147
|
if (first.ok) {
|
|
124
148
|
return ok({ ...first.data, vault });
|
|
125
149
|
}
|
|
126
150
|
if (first.error !== "SYNC_LOCK_HELD") return first;
|
|
127
|
-
const reclaimed = reclaimDeadManagedWriteLockOwner(vault);
|
|
151
|
+
const reclaimed = reclaimDeadManagedWriteLockOwner(vault, options);
|
|
128
152
|
if (!reclaimed.ok || !reclaimed.data.reclaimed) {
|
|
129
153
|
return err("SYNC_LOCK_HELD", { path });
|
|
130
154
|
}
|
|
@@ -180,8 +204,8 @@ function isGitVault(vault) {
|
|
|
180
204
|
return Boolean(git(vault, ["rev-parse", "--absolute-git-dir"]));
|
|
181
205
|
}
|
|
182
206
|
async function runManagedWritePreflight(input, deps = DEFAULT_DEPS) {
|
|
183
|
-
const mutationVault =
|
|
184
|
-
let convergenceVault = input.convergenceVault &&
|
|
207
|
+
const mutationVault = resolve2(input.vault);
|
|
208
|
+
let convergenceVault = input.convergenceVault && resolve2(input.convergenceVault) !== mutationVault ? resolve2(input.convergenceVault) : void 0;
|
|
185
209
|
let convergenceSource = convergenceVault ? "explicit" : "single-path";
|
|
186
210
|
const mutationBlocker = preflightBlocker(mutationVault);
|
|
187
211
|
if (mutationBlocker) {
|
|
@@ -264,7 +288,7 @@ async function runManagedWritePreflight(input, deps = DEFAULT_DEPS) {
|
|
|
264
288
|
})
|
|
265
289
|
};
|
|
266
290
|
}
|
|
267
|
-
convergenceVault =
|
|
291
|
+
convergenceVault = resolve2(configured);
|
|
268
292
|
convergenceSource = "configured";
|
|
269
293
|
if (convergenceVault === mutationVault) {
|
|
270
294
|
return {
|
|
@@ -373,8 +397,10 @@ async function runManagedWritePreflight(input, deps = DEFAULT_DEPS) {
|
|
|
373
397
|
};
|
|
374
398
|
}
|
|
375
399
|
async function runManagedWriteTransaction(input, deps = DEFAULT_DEPS) {
|
|
376
|
-
const mutationVault =
|
|
377
|
-
const lock = acquireManagedWriteLock(mutationVault, input.command
|
|
400
|
+
const mutationVault = resolve2(input.vault);
|
|
401
|
+
const lock = acquireManagedWriteLock(mutationVault, input.command, {
|
|
402
|
+
gitStateVault: input.convergenceVault ? resolve2(input.convergenceVault) : mutationVault
|
|
403
|
+
});
|
|
378
404
|
if (!lock.ok) {
|
|
379
405
|
return { exitCode: ExitCode.SYNC_LOCK_HELD, result: lock };
|
|
380
406
|
}
|
package/dist/cli.js
CHANGED
|
@@ -109,7 +109,7 @@ import {
|
|
|
109
109
|
import {
|
|
110
110
|
runManagedWritePreflight,
|
|
111
111
|
runManagedWriteTransaction
|
|
112
|
-
} from "./chunk-
|
|
112
|
+
} from "./chunk-65Q5UGND.js";
|
|
113
113
|
import {
|
|
114
114
|
FLEET_REL_PATH,
|
|
115
115
|
canSupersedeJournal,
|
|
@@ -7862,7 +7862,7 @@ async function emitManagedVaultWrite(vault, command, mutate, opts) {
|
|
|
7862
7862
|
if (dirty) {
|
|
7863
7863
|
return emit(dirty, void 0, { postCommit: false });
|
|
7864
7864
|
}
|
|
7865
|
-
const { runManagedWriteTransaction: runManagedWriteTransaction2 } = await import("./managed-write-preflight-
|
|
7865
|
+
const { runManagedWriteTransaction: runManagedWriteTransaction2 } = await import("./managed-write-preflight-CTXX2MHQ.js");
|
|
7866
7866
|
const run = await runManagedWriteTransaction2({
|
|
7867
7867
|
vault,
|
|
7868
7868
|
command,
|
|
@@ -159,7 +159,7 @@ vault_sync_managed_lock_reclaim_dead_owner() {
|
|
|
159
159
|
vault_sync_managed_lock_acquire() {
|
|
160
160
|
local repo="${1:-.}"
|
|
161
161
|
local command="${2:-wiki-pull}"
|
|
162
|
-
local path token now inherited attempt
|
|
162
|
+
local path token now owner_hostname inherited attempt
|
|
163
163
|
|
|
164
164
|
path="$(vault_sync_managed_lock_path "$repo")" || return 1
|
|
165
165
|
VAULT_SYNC_MANAGED_LOCK_PATH="$path"
|
|
@@ -185,8 +185,9 @@ vault_sync_managed_lock_acquire() {
|
|
|
185
185
|
token="$(od -An -N16 -tx1 /dev/urandom 2>/dev/null | tr -d ' \n')"
|
|
186
186
|
[ -n "$token" ] || token="$$-$(date +%s)"
|
|
187
187
|
now="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
188
|
-
|
|
189
|
-
|
|
188
|
+
owner_hostname="$(hostname 2>/dev/null || printf unknown)"
|
|
189
|
+
if ( set -o noclobber; printf '{"pid":%s,"owner_hostname":"%s","owner_token":"%s","acquired":"%s","command":"%s"}\n' \
|
|
190
|
+
"$$" "$owner_hostname" "$token" "$now" "$command" >"$path" ) 2>/dev/null; then
|
|
190
191
|
VAULT_SYNC_MANAGED_LOCK_TOKEN_OWNED="$token"
|
|
191
192
|
VAULT_SYNC_MANAGED_LOCK_ACQUIRED="$now"
|
|
192
193
|
VAULT_SYNC_MANAGED_LOCK_OWNS_RELEASE=1
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skillwiki",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.21",
|
|
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": {
|