@kurrent/kcap 0.9.1 → 0.9.2
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/bin/kcap.js +84 -56
- package/kcap/.claude-plugin/plugin.json +1 -1
- package/package.json +7 -7
package/bin/kcap.js
CHANGED
|
@@ -28,73 +28,98 @@ const PLATFORM_PACKAGES = {
|
|
|
28
28
|
"win32-x64": "@kurrent/kcap-win-x64",
|
|
29
29
|
};
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
31
|
+
// Resolves the npm dist-tag to install for `kcap update`, based on the
|
|
32
|
+
// resolved channel reported by `kcap update --check`'s `install_tag` field.
|
|
33
|
+
// Falls back to "latest" when the probe is missing, failed, or has no tag,
|
|
34
|
+
// preserving today's default behavior.
|
|
35
|
+
function resolveInstallSpec(info) {
|
|
36
|
+
const tag = info && typeof info.install_tag === "string" && info.install_tag
|
|
37
|
+
? info.install_tag
|
|
38
|
+
: "latest";
|
|
39
|
+
return `@kurrent/kcap@${tag}`;
|
|
39
40
|
}
|
|
40
41
|
|
|
41
|
-
//
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
process.exit(1);
|
|
42
|
+
// Builds the arg list for the `kcap update --check` probe, forwarding only
|
|
43
|
+
// the channel-switch flags (`--beta`/`--stable`) from the user's `kcap update`
|
|
44
|
+
// invocation. Nothing else is forwarded — the probe already supplies `--check`
|
|
45
|
+
// and `--no-update-check` itself, so this is a controlled call.
|
|
46
|
+
function probeArgs(updArgs) {
|
|
47
|
+
const channelFlags = (updArgs || []).filter((a) => a === "--beta" || a === "--stable");
|
|
48
|
+
return ["update", "--check", "--no-update-check", ...channelFlags];
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
// Everything below actually DOES something (resolves the binary, execs it,
|
|
52
|
+
// runs the update flow), so it's guarded to only run when this file is
|
|
53
|
+
// executed directly — not when `require()`d (e.g. by the test).
|
|
54
|
+
if (require.main === module) {
|
|
55
|
+
const musl = process.platform === "linux" && isMusl() ? "-musl" : "";
|
|
56
|
+
const platformKey = `${process.platform}${musl}-${process.arch}`;
|
|
57
|
+
const packageName = PLATFORM_PACKAGES[platformKey];
|
|
58
|
+
|
|
59
|
+
if (!packageName) {
|
|
60
|
+
console.error(`Unsupported platform: ${platformKey}`);
|
|
61
|
+
console.error(`Supported: ${Object.keys(PLATFORM_PACKAGES).join(", ")}`);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
53
64
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
65
|
+
// Resolve the platform package
|
|
66
|
+
let binaryDir;
|
|
67
|
+
try {
|
|
68
|
+
binaryDir = path.dirname(require.resolve(`${packageName}/package.json`));
|
|
69
|
+
} catch {
|
|
70
|
+
console.error(`Platform package ${packageName} is not installed.`);
|
|
71
|
+
console.error(`Try: npm install -g @kurrent/kcap`);
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
58
74
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
fs.accessSync(binaryPath, fs.constants.X_OK);
|
|
62
|
-
} catch {
|
|
63
|
-
try { fs.chmodSync(binaryPath, 0o755); } catch {}
|
|
64
|
-
}
|
|
75
|
+
const ext = process.platform === "win32" ? ".exe" : "";
|
|
76
|
+
const binaryPath = path.join(binaryDir, "bin", `kcap${ext}`);
|
|
65
77
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
// from this script (with the native binary not running) npm can overwrite the
|
|
70
|
-
// binary even on Windows, with no temp-file/rename/detached-helper dance.
|
|
71
|
-
// `--check` (JSON probe) and `--help` fall through to the native binary.
|
|
72
|
-
{
|
|
73
|
-
const updArgs = process.argv.slice(3);
|
|
74
|
-
const checkOnly = updArgs.includes("--check");
|
|
75
|
-
const wantsHelp = updArgs.some((a) => a === "--help" || a === "-h");
|
|
76
|
-
if (process.argv[2] === "update" && !checkOnly && !wantsHelp) {
|
|
77
|
-
runUpdate(binaryPath); // never returns
|
|
78
|
+
if (!fs.existsSync(binaryPath)) {
|
|
79
|
+
console.error(`Binary not found at ${binaryPath}`);
|
|
80
|
+
process.exit(1);
|
|
78
81
|
}
|
|
79
|
-
}
|
|
80
82
|
|
|
81
|
-
//
|
|
82
|
-
try {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
83
|
+
// Ensure the binary is executable (npm doesn't always preserve permissions)
|
|
84
|
+
try {
|
|
85
|
+
fs.accessSync(binaryPath, fs.constants.X_OK);
|
|
86
|
+
} catch {
|
|
87
|
+
try { fs.chmodSync(binaryPath, 0o755); } catch {}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// `kcap update` for npm-global installs is driven HERE, in the Node launcher,
|
|
91
|
+
// not by the native binary. The OS locks an executable image for the whole
|
|
92
|
+
// process lifetime but a script only during load — so by driving the upgrade
|
|
93
|
+
// from this script (with the native binary not running) npm can overwrite the
|
|
94
|
+
// binary even on Windows, with no temp-file/rename/detached-helper dance.
|
|
95
|
+
// `--check` (JSON probe) and `--help` fall through to the native binary.
|
|
96
|
+
{
|
|
97
|
+
const updArgs = process.argv.slice(3);
|
|
98
|
+
const checkOnly = updArgs.includes("--check");
|
|
99
|
+
const wantsHelp = updArgs.some((a) => a === "--help" || a === "-h");
|
|
100
|
+
if (process.argv[2] === "update" && !checkOnly && !wantsHelp) {
|
|
101
|
+
runUpdate(binaryPath, updArgs); // never returns
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Exec the native binary, replacing this process
|
|
106
|
+
try {
|
|
107
|
+
execFileSync(binaryPath, process.argv.slice(2), {
|
|
108
|
+
stdio: "inherit",
|
|
109
|
+
env: process.env,
|
|
110
|
+
});
|
|
111
|
+
process.exit(0);
|
|
112
|
+
} catch (e) {
|
|
113
|
+
if (e.status !== null) {
|
|
114
|
+
process.exit(e.status);
|
|
115
|
+
}
|
|
116
|
+
process.exit(1);
|
|
91
117
|
}
|
|
92
|
-
process.exit(1);
|
|
93
118
|
}
|
|
94
119
|
|
|
95
120
|
// Performs `kcap update`: upgrade the global npm package, then refresh
|
|
96
121
|
// user-scope skills/hooks. Always exits the process; never returns.
|
|
97
|
-
function runUpdate(binaryPath) {
|
|
122
|
+
function runUpdate(binaryPath, updArgs) {
|
|
98
123
|
// On Windows, `npm` is a .cmd shim; Node refuses to spawn .cmd/.bat directly
|
|
99
124
|
// (2024 command-injection fix), so route npm through a shell there. Our npm
|
|
100
125
|
// args are static, so shell use is safe.
|
|
@@ -127,12 +152,13 @@ function runUpdate(binaryPath) {
|
|
|
127
152
|
// child fully EXITS before we run npm, so the binary file is unlocked when
|
|
128
153
|
// npm overwrites it (matters on Windows). `--no-update-check` keeps the
|
|
129
154
|
// background nudge from racing onto stderr.
|
|
155
|
+
let info = null;
|
|
130
156
|
try {
|
|
131
|
-
const out = execFileSync(binaryPath,
|
|
157
|
+
const out = execFileSync(binaryPath, probeArgs(updArgs), { encoding: "utf8" });
|
|
132
158
|
// The probe prints one JSON line; take the last {...} line in case anything
|
|
133
159
|
// else (e.g. a git-remote warning) landed on stdout first.
|
|
134
160
|
const line = out.split(/\r?\n/).reverse().find((l) => l.trim().startsWith("{"));
|
|
135
|
-
|
|
161
|
+
info = JSON.parse(line);
|
|
136
162
|
// Only short-circuit when the probe is CONFIDENT we're up to date: `newer`
|
|
137
163
|
// explicitly false AND a known current version. `newer: null` (version
|
|
138
164
|
// unknown / check failed) falls through to the upgrade rather than stranding
|
|
@@ -177,7 +203,7 @@ function runUpdate(binaryPath) {
|
|
|
177
203
|
process.exit(1);
|
|
178
204
|
}
|
|
179
205
|
|
|
180
|
-
const res = spawnSync("npm", ["install", "-g",
|
|
206
|
+
const res = spawnSync("npm", ["install", "-g", resolveInstallSpec(info)], {
|
|
181
207
|
stdio: "inherit",
|
|
182
208
|
windowsHide: true,
|
|
183
209
|
...npmOpts,
|
|
@@ -211,3 +237,5 @@ function runUpdate(binaryPath) {
|
|
|
211
237
|
|
|
212
238
|
process.exit(0);
|
|
213
239
|
}
|
|
240
|
+
|
|
241
|
+
module.exports = { resolveInstallSpec, probeArgs };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kurrent/kcap",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.2",
|
|
4
4
|
"description": "CLI companion for Kurrent Capacitor — records and visualizes Claude Code sessions",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
6
6
|
"repository": {
|
|
@@ -14,12 +14,12 @@
|
|
|
14
14
|
"postinstall": "node bin/postinstall.js"
|
|
15
15
|
},
|
|
16
16
|
"optionalDependencies": {
|
|
17
|
-
"@kurrent/kcap-darwin-arm64": "0.9.
|
|
18
|
-
"@kurrent/kcap-linux-x64": "0.9.
|
|
19
|
-
"@kurrent/kcap-linux-arm64": "0.9.
|
|
20
|
-
"@kurrent/kcap-linux-musl-x64": "0.9.
|
|
21
|
-
"@kurrent/kcap-linux-musl-arm64": "0.9.
|
|
22
|
-
"@kurrent/kcap-win-x64": "0.9.
|
|
17
|
+
"@kurrent/kcap-darwin-arm64": "0.9.2",
|
|
18
|
+
"@kurrent/kcap-linux-x64": "0.9.2",
|
|
19
|
+
"@kurrent/kcap-linux-arm64": "0.9.2",
|
|
20
|
+
"@kurrent/kcap-linux-musl-x64": "0.9.2",
|
|
21
|
+
"@kurrent/kcap-linux-musl-arm64": "0.9.2",
|
|
22
|
+
"@kurrent/kcap-win-x64": "0.9.2"
|
|
23
23
|
},
|
|
24
24
|
"files": [
|
|
25
25
|
"bin/",
|