skillwiki 0.9.55 → 0.9.56
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-SE5URAJR.js} +156 -222
- package/dist/cli.js +11 -6
- 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/package.json +1 -1
- package/dist/chunk-E6UWZ3S3.js +0 -62
package/dist/auto-update-bg.js
CHANGED
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
#!/usr/bin/env node
|
|
3
3
|
import {
|
|
4
|
+
cachePath,
|
|
4
5
|
normalizeDistTag,
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
readCacheRaw,
|
|
7
|
+
resolveAutoApplyAt,
|
|
8
|
+
semverGt,
|
|
9
|
+
writeCache
|
|
10
|
+
} from "./chunk-7I2TPIV5.js";
|
|
7
11
|
|
|
8
12
|
// src/auto-update-bg.ts
|
|
9
13
|
import { execSync } from "child_process";
|
|
10
14
|
import { writeFileSync, mkdirSync } from "fs";
|
|
11
|
-
import {
|
|
15
|
+
import { dirname } from "path";
|
|
12
16
|
var home = process.argv[2];
|
|
13
17
|
var currentVersion = process.argv[3];
|
|
14
18
|
var distTag = normalizeDistTag(process.argv[4]);
|
|
15
19
|
if (!home || !currentVersion) process.exit(0);
|
|
16
|
-
var cacheFile =
|
|
20
|
+
var cacheFile = cachePath(home);
|
|
17
21
|
setTimeout(() => process.exit(0), 3e4);
|
|
18
22
|
try {
|
|
19
23
|
const latest = execSync(`npm view skillwiki@${distTag} version`, {
|
|
@@ -21,25 +25,41 @@ try {
|
|
|
21
25
|
timeout: 15e3
|
|
22
26
|
}).trim();
|
|
23
27
|
mkdirSync(dirname(cacheFile), { recursive: true });
|
|
28
|
+
const prior = readCacheRaw(home);
|
|
29
|
+
const { firstSeenAt, autoApplyAt } = resolveAutoApplyAt(prior, latest);
|
|
24
30
|
const cache = {
|
|
25
31
|
lastCheck: Date.now(),
|
|
26
32
|
latestVersion: latest,
|
|
27
33
|
currentVersion,
|
|
28
|
-
distTag
|
|
34
|
+
distTag,
|
|
35
|
+
firstSeenAt,
|
|
36
|
+
autoApplyAt
|
|
29
37
|
};
|
|
30
38
|
if (semverGt(latest, currentVersion)) {
|
|
39
|
+
if (Date.now() < autoApplyAt) {
|
|
40
|
+
writeFileSync(cacheFile, JSON.stringify(cache, null, 2));
|
|
41
|
+
process.exit(0);
|
|
42
|
+
}
|
|
31
43
|
execSync(`npm install -g skillwiki@${distTag}`, {
|
|
32
44
|
stdio: "ignore",
|
|
33
45
|
timeout: 6e4
|
|
34
46
|
});
|
|
35
|
-
|
|
47
|
+
writeCache(home, { ...cache, updateAppliedAt: Date.now() });
|
|
36
48
|
} else {
|
|
37
49
|
writeFileSync(cacheFile, JSON.stringify(cache, null, 2));
|
|
38
50
|
}
|
|
39
51
|
} catch {
|
|
40
52
|
try {
|
|
41
|
-
|
|
42
|
-
|
|
53
|
+
const prior = readCacheRaw(home);
|
|
54
|
+
const staleCache = {
|
|
55
|
+
lastCheck: Date.now(),
|
|
56
|
+
latestVersion: "",
|
|
57
|
+
currentVersion,
|
|
58
|
+
distTag,
|
|
59
|
+
...prior?.firstSeenAt ? { firstSeenAt: prior.firstSeenAt } : {},
|
|
60
|
+
...prior?.autoApplyAt ? { autoApplyAt: prior.autoApplyAt } : {}
|
|
61
|
+
};
|
|
62
|
+
writeCache(home, staleCache);
|
|
43
63
|
} catch {
|
|
44
64
|
}
|
|
45
65
|
}
|
|
@@ -0,0 +1,154 @@
|
|
|
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 AUTO_APPLY_DELAY_MS = 6 * 60 * 60 * 1e3;
|
|
48
|
+
var ENV_DISABLE_KEY = "NO_UPDATE_NOTIFIER";
|
|
49
|
+
var CLI_DISABLE_FLAG = "--no-update-notifier";
|
|
50
|
+
function normalizeDistTag(tag) {
|
|
51
|
+
const value = (tag ?? DIST_TAG).trim();
|
|
52
|
+
return /^[A-Za-z0-9._-]+$/.test(value) ? value : DIST_TAG;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// src/utils/auto-update.ts
|
|
56
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
|
|
57
|
+
import { join, dirname } from "path";
|
|
58
|
+
import { spawn } from "child_process";
|
|
59
|
+
import { fileURLToPath } from "url";
|
|
60
|
+
function cachePath(home) {
|
|
61
|
+
return join(home, ".skillwiki", CACHE_FILENAME);
|
|
62
|
+
}
|
|
63
|
+
function readCacheRaw(home) {
|
|
64
|
+
try {
|
|
65
|
+
const raw = readFileSync(cachePath(home), "utf8");
|
|
66
|
+
return JSON.parse(raw);
|
|
67
|
+
} catch {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function readCache(home) {
|
|
72
|
+
const cache = readCacheRaw(home);
|
|
73
|
+
if (!cache) return { cache: null, hasUpdate: false, isStale: true };
|
|
74
|
+
const isStale = Date.now() - cache.lastCheck >= CHECK_INTERVAL_MS;
|
|
75
|
+
const hasUpdate = !!cache.latestVersion && semverGt(cache.latestVersion, cache.currentVersion);
|
|
76
|
+
return { cache, hasUpdate, isStale };
|
|
77
|
+
}
|
|
78
|
+
function writeCache(home, cache) {
|
|
79
|
+
const p = cachePath(home);
|
|
80
|
+
mkdirSync(dirname(p), { recursive: true });
|
|
81
|
+
writeFileSync(p, JSON.stringify(cache, null, 2));
|
|
82
|
+
}
|
|
83
|
+
function resolveAutoApplyAt(cache, latestVersion, now = Date.now()) {
|
|
84
|
+
if (cache && cache.firstSeenAt && cache.latestVersion === latestVersion && cache.autoApplyAt) {
|
|
85
|
+
return { firstSeenAt: cache.firstSeenAt, autoApplyAt: cache.autoApplyAt };
|
|
86
|
+
}
|
|
87
|
+
const firstSeenAt = now;
|
|
88
|
+
return { firstSeenAt, autoApplyAt: firstSeenAt + AUTO_APPLY_DELAY_MS };
|
|
89
|
+
}
|
|
90
|
+
function formatCountdown(autoApplyAt, now = Date.now()) {
|
|
91
|
+
if (!autoApplyAt) return null;
|
|
92
|
+
const remainingMs = autoApplyAt - now;
|
|
93
|
+
if (remainingMs <= 0) return null;
|
|
94
|
+
const totalMin = Math.ceil(remainingMs / 6e4);
|
|
95
|
+
const hours = Math.floor(totalMin / 60);
|
|
96
|
+
const mins = totalMin % 60;
|
|
97
|
+
return hours > 0 ? `${hours}h ${mins}m` : `${mins}m`;
|
|
98
|
+
}
|
|
99
|
+
function latestFromCache(home, currentVersion) {
|
|
100
|
+
const { cache } = readCache(home);
|
|
101
|
+
if (!cache || !cache.latestVersion) return { hasUpdate: false, latest: null, distTag: DIST_TAG };
|
|
102
|
+
const distTag = normalizeDistTag(cache.distTag);
|
|
103
|
+
return {
|
|
104
|
+
hasUpdate: semverGt(cache.latestVersion, currentVersion),
|
|
105
|
+
latest: cache.latestVersion,
|
|
106
|
+
distTag
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function isDisabled() {
|
|
110
|
+
return !!(process.env[ENV_DISABLE_KEY] || process.env.NODE_ENV === "test" || process.argv.includes(CLI_DISABLE_FLAG));
|
|
111
|
+
}
|
|
112
|
+
function triggerAutoUpdate(home, currentVersion) {
|
|
113
|
+
if (isDisabled()) return;
|
|
114
|
+
const { cache, isStale } = readCache(home);
|
|
115
|
+
if (isStale) {
|
|
116
|
+
const distTag = normalizeDistTag(cache?.distTag);
|
|
117
|
+
const bgScript = fileURLToPath(new URL("./auto-update-bg.js", import.meta.url));
|
|
118
|
+
if (existsSync(bgScript)) {
|
|
119
|
+
const child = spawn(process.execPath, [bgScript, home, currentVersion, distTag], {
|
|
120
|
+
detached: true,
|
|
121
|
+
stdio: "ignore"
|
|
122
|
+
});
|
|
123
|
+
child.on("error", () => {
|
|
124
|
+
});
|
|
125
|
+
child.unref();
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
notifyPendingUpdate(cache, currentVersion);
|
|
129
|
+
}
|
|
130
|
+
function notifyPendingUpdate(cache, currentVersion) {
|
|
131
|
+
if (isDisabled()) return;
|
|
132
|
+
if (!cache || !cache.latestVersion) return;
|
|
133
|
+
if (!semverGt(cache.latestVersion, currentVersion)) return;
|
|
134
|
+
const { autoApplyAt } = resolveAutoApplyAt(cache, cache.latestVersion);
|
|
135
|
+
const remaining = formatCountdown(autoApplyAt);
|
|
136
|
+
if (remaining === null) return;
|
|
137
|
+
const distTag = normalizeDistTag(cache.distTag);
|
|
138
|
+
process.stderr.write(
|
|
139
|
+
`Update available: ${currentVersion} -> ${cache.latestVersion} (${distTag}). Auto-applying in ${remaining}. Run \`skillwiki update --tag ${distTag}\` now, or set NO_UPDATE_NOTIFIER=1 to opt out.
|
|
140
|
+
`
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export {
|
|
145
|
+
semverGt,
|
|
146
|
+
normalizeDistTag,
|
|
147
|
+
cachePath,
|
|
148
|
+
readCacheRaw,
|
|
149
|
+
readCache,
|
|
150
|
+
writeCache,
|
|
151
|
+
resolveAutoApplyAt,
|
|
152
|
+
latestFromCache,
|
|
153
|
+
triggerAutoUpdate
|
|
154
|
+
};
|