openkrew 0.1.3 → 0.1.5
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/core-bootstrap.mjs +1 -1
- package/openkrew.mjs +12 -188
- package/package.json +1 -1
package/core-bootstrap.mjs
CHANGED
|
@@ -65,7 +65,7 @@ function getRuntimeId() {
|
|
|
65
65
|
* Returns the expected binary name for the current platform.
|
|
66
66
|
*/
|
|
67
67
|
function getBinaryName() {
|
|
68
|
-
return platform() === "win32" ? "
|
|
68
|
+
return platform() === "win32" ? "openkrew.exe" : "openkrew";
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
/**
|
package/openkrew.mjs
CHANGED
|
@@ -1,204 +1,28 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { readFileSync } from "node:fs";
|
|
4
|
-
import { access } from "node:fs/promises";
|
|
5
3
|
import module from "node:module";
|
|
6
|
-
import { fileURLToPath } from "node:url";
|
|
7
4
|
|
|
8
|
-
const MIN_NODE_MAJOR =
|
|
9
|
-
const MIN_NODE_MINOR = 12;
|
|
10
|
-
const MIN_NODE_VERSION = `${MIN_NODE_MAJOR}.${MIN_NODE_MINOR}`;
|
|
11
|
-
|
|
12
|
-
const parseNodeVersion = (rawVersion) => {
|
|
13
|
-
const [majorRaw = "0", minorRaw = "0"] = rawVersion.split(".");
|
|
14
|
-
return {
|
|
15
|
-
major: Number(majorRaw),
|
|
16
|
-
minor: Number(minorRaw),
|
|
17
|
-
};
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
const isSupportedNodeVersion = (version) =>
|
|
21
|
-
version.major > MIN_NODE_MAJOR ||
|
|
22
|
-
(version.major === MIN_NODE_MAJOR && version.minor >= MIN_NODE_MINOR);
|
|
23
|
-
|
|
24
|
-
const ensureSupportedNodeVersion = () => {
|
|
25
|
-
if (isSupportedNodeVersion(parseNodeVersion(process.versions.node))) {
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
5
|
+
const MIN_NODE_MAJOR = 18;
|
|
28
6
|
|
|
7
|
+
const nodeVersion = Number(process.versions.node.split(".")[0]);
|
|
8
|
+
if (nodeVersion < MIN_NODE_MAJOR) {
|
|
29
9
|
process.stderr.write(
|
|
30
|
-
`openkrew: Node.js v${
|
|
31
|
-
"If you use nvm, run:\n" +
|
|
32
|
-
` nvm install ${MIN_NODE_MAJOR}\n` +
|
|
33
|
-
` nvm use ${MIN_NODE_MAJOR}\n` +
|
|
34
|
-
` nvm alias default ${MIN_NODE_MAJOR}\n`,
|
|
10
|
+
`openkrew: Node.js v${MIN_NODE_MAJOR}+ is required (current: v${process.versions.node}).\n`,
|
|
35
11
|
);
|
|
36
12
|
process.exit(1);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
ensureSupportedNodeVersion();
|
|
13
|
+
}
|
|
40
14
|
|
|
41
15
|
// https://nodejs.org/api/module.html#module-compile-cache
|
|
42
16
|
if (module.enableCompileCache && !process.env.NODE_DISABLE_COMPILE_CACHE) {
|
|
43
17
|
try {
|
|
44
18
|
module.enableCompileCache();
|
|
45
|
-
} catch {
|
|
46
|
-
// Ignore errors
|
|
47
|
-
}
|
|
19
|
+
} catch {}
|
|
48
20
|
}
|
|
49
21
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
if (!isLegacyMode) {
|
|
58
|
-
try {
|
|
59
|
-
const { bootstrap } = await import("./core-bootstrap.mjs");
|
|
60
|
-
await bootstrap();
|
|
61
|
-
// bootstrap() calls process.exit() via the spawned child, so we
|
|
62
|
-
// only reach here if something went wrong.
|
|
63
|
-
} catch (err) {
|
|
64
|
-
// If the .NET bootstrapper fails (no release, no SDK, etc.),
|
|
65
|
-
// fall through to the legacy TypeScript gateway with a warning.
|
|
66
|
-
process.stderr.write(
|
|
67
|
-
`\x1b[33mOpenKrew .NET core unavailable: ${err.message}\x1b[0m\n` +
|
|
68
|
-
"Falling back to legacy TypeScript gateway.\n" +
|
|
69
|
-
"Run with OPENKREW_LEGACY=1 to skip this check.\n\n",
|
|
70
|
-
);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// ── Legacy TypeScript Gateway (OpenClaw fork) ─────────────────────────
|
|
75
|
-
|
|
76
|
-
const isModuleNotFoundError = (err) =>
|
|
77
|
-
err && typeof err === "object" && "code" in err && err.code === "ERR_MODULE_NOT_FOUND";
|
|
78
|
-
|
|
79
|
-
const isDirectModuleNotFoundError = (err, specifier) => {
|
|
80
|
-
if (!isModuleNotFoundError(err)) {
|
|
81
|
-
return false;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const expectedUrl = new URL(specifier, import.meta.url);
|
|
85
|
-
if ("url" in err && err.url === expectedUrl.href) {
|
|
86
|
-
return true;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const message = "message" in err && typeof err.message === "string" ? err.message : "";
|
|
90
|
-
const expectedPath = fileURLToPath(expectedUrl);
|
|
91
|
-
return (
|
|
92
|
-
message.includes(`Cannot find module '${expectedPath}'`) ||
|
|
93
|
-
message.includes(`Cannot find module "${expectedPath}"`)
|
|
94
|
-
);
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
const installProcessWarningFilter = async () => {
|
|
98
|
-
for (const specifier of ["./dist/warning-filter.js", "./dist/warning-filter.mjs"]) {
|
|
99
|
-
try {
|
|
100
|
-
const mod = await import(specifier);
|
|
101
|
-
if (typeof mod.installProcessWarningFilter === "function") {
|
|
102
|
-
mod.installProcessWarningFilter();
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
} catch (err) {
|
|
106
|
-
if (isDirectModuleNotFoundError(err, specifier)) {
|
|
107
|
-
continue;
|
|
108
|
-
}
|
|
109
|
-
throw err;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
const tryImport = async (specifier) => {
|
|
115
|
-
try {
|
|
116
|
-
await import(specifier);
|
|
117
|
-
return true;
|
|
118
|
-
} catch (err) {
|
|
119
|
-
if (isDirectModuleNotFoundError(err, specifier)) {
|
|
120
|
-
return false;
|
|
121
|
-
}
|
|
122
|
-
throw err;
|
|
123
|
-
}
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
const exists = async (specifier) => {
|
|
127
|
-
try {
|
|
128
|
-
await access(new URL(specifier, import.meta.url));
|
|
129
|
-
return true;
|
|
130
|
-
} catch {
|
|
131
|
-
return false;
|
|
132
|
-
}
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
const buildMissingEntryErrorMessage = async () => {
|
|
136
|
-
const lines = ["openkrew: missing dist/entry.(m)js (build output)."];
|
|
137
|
-
if (!(await exists("./src/entry.ts"))) {
|
|
138
|
-
return lines.join("\n");
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
lines.push("This install looks like an unbuilt source tree or GitHub source archive.");
|
|
142
|
-
lines.push(
|
|
143
|
-
"Build locally with `pnpm install && pnpm build`, or install a built package instead.",
|
|
144
|
-
);
|
|
145
|
-
lines.push(
|
|
146
|
-
"For pinned GitHub installs, use `npm install -g github:openkrew/openkrew#<ref>` instead of a raw `/archive/<ref>.tar.gz` URL.",
|
|
147
|
-
);
|
|
148
|
-
lines.push("For releases, use `npm install -g openkrew@latest`.");
|
|
149
|
-
return lines.join("\n");
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
const isBareRootHelpInvocation = (argv) =>
|
|
153
|
-
argv.length === 3 && (argv[2] === "--help" || argv[2] === "-h");
|
|
154
|
-
|
|
155
|
-
const loadPrecomputedRootHelpText = () => {
|
|
156
|
-
try {
|
|
157
|
-
const raw = readFileSync(new URL("./dist/cli-startup-metadata.json", import.meta.url), "utf8");
|
|
158
|
-
const parsed = JSON.parse(raw);
|
|
159
|
-
return typeof parsed?.rootHelpText === "string" && parsed.rootHelpText.length > 0
|
|
160
|
-
? parsed.rootHelpText
|
|
161
|
-
: null;
|
|
162
|
-
} catch {
|
|
163
|
-
return null;
|
|
164
|
-
}
|
|
165
|
-
};
|
|
166
|
-
|
|
167
|
-
const tryOutputBareRootHelp = async () => {
|
|
168
|
-
if (!isBareRootHelpInvocation(process.argv)) {
|
|
169
|
-
return false;
|
|
170
|
-
}
|
|
171
|
-
const precomputed = loadPrecomputedRootHelpText();
|
|
172
|
-
if (precomputed) {
|
|
173
|
-
process.stdout.write(precomputed);
|
|
174
|
-
return true;
|
|
175
|
-
}
|
|
176
|
-
for (const specifier of ["./dist/cli/program/root-help.js", "./dist/cli/program/root-help.mjs"]) {
|
|
177
|
-
try {
|
|
178
|
-
const mod = await import(specifier);
|
|
179
|
-
if (typeof mod.outputRootHelp === "function") {
|
|
180
|
-
mod.outputRootHelp();
|
|
181
|
-
return true;
|
|
182
|
-
}
|
|
183
|
-
} catch (err) {
|
|
184
|
-
if (isDirectModuleNotFoundError(err, specifier)) {
|
|
185
|
-
continue;
|
|
186
|
-
}
|
|
187
|
-
throw err;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
return false;
|
|
191
|
-
};
|
|
192
|
-
|
|
193
|
-
if (await tryOutputBareRootHelp()) {
|
|
194
|
-
// OK
|
|
195
|
-
} else {
|
|
196
|
-
await installProcessWarningFilter();
|
|
197
|
-
if (await tryImport("./dist/entry.js")) {
|
|
198
|
-
// OK
|
|
199
|
-
} else if (await tryImport("./dist/entry.mjs")) {
|
|
200
|
-
// OK
|
|
201
|
-
} else {
|
|
202
|
-
throw new Error(await buildMissingEntryErrorMessage());
|
|
203
|
-
}
|
|
22
|
+
try {
|
|
23
|
+
const { bootstrap } = await import("./core-bootstrap.mjs");
|
|
24
|
+
await bootstrap();
|
|
25
|
+
} catch (err) {
|
|
26
|
+
process.stderr.write(`\x1b[31mOpenKrew failed to start: ${err.message}\x1b[0m\n`);
|
|
27
|
+
process.exit(1);
|
|
204
28
|
}
|