@hanzo/dev 0.6.73 → 0.6.74
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/README.md +254 -365
- package/bin/{coder.js → dev.js} +38 -95
- package/package.json +11 -11
- package/postinstall.js +442 -501
- package/scripts/preinstall.js +5 -5
- package/scripts/windows-cleanup.ps1 +6 -7
- package/bin/codex.js +0 -197
package/bin/{coder.js → dev.js}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// Unified entry point for the
|
|
2
|
+
// Unified entry point for the Hanzo Dev CLI.
|
|
3
3
|
|
|
4
4
|
import path from "path";
|
|
5
5
|
import { fileURLToPath } from "url";
|
|
@@ -14,10 +14,6 @@ const __dirname = path.dirname(__filename);
|
|
|
14
14
|
|
|
15
15
|
const { platform, arch } = process;
|
|
16
16
|
|
|
17
|
-
// Important: Never delegate to another system's `code` binary (e.g., VS Code).
|
|
18
|
-
// When users run via `npx @just-every/code`, we must always execute our
|
|
19
|
-
// packaged native binary by absolute path to avoid PATH collisions.
|
|
20
|
-
|
|
21
17
|
function isWSL() {
|
|
22
18
|
if (platform !== "linux") return false;
|
|
23
19
|
try {
|
|
@@ -74,11 +70,10 @@ if (!targetTriple) {
|
|
|
74
70
|
throw new Error(`Unsupported platform: ${platform} (${arch})`);
|
|
75
71
|
}
|
|
76
72
|
|
|
77
|
-
//
|
|
78
|
-
let binaryPath = path.join(__dirname, "..", "bin", `
|
|
79
|
-
let legacyBinaryPath = path.join(__dirname, "..", "bin", `
|
|
73
|
+
// Binary names for Hanzo dev
|
|
74
|
+
let binaryPath = path.join(__dirname, "..", "bin", `dev-${targetTriple}`);
|
|
75
|
+
let legacyBinaryPath = path.join(__dirname, "..", "bin", `code-${targetTriple}`);
|
|
80
76
|
|
|
81
|
-
// --- Bootstrap helper (runs if the binary is missing, e.g. Bun blocked postinstall) ---
|
|
82
77
|
import { existsSync, chmodSync, statSync, openSync, readSync, closeSync, mkdirSync, copyFileSync, readFileSync, unlinkSync, createWriteStream } from "fs";
|
|
83
78
|
|
|
84
79
|
const validateBinary = (p) => {
|
|
@@ -121,16 +116,14 @@ const getCacheDir = (version) => {
|
|
|
121
116
|
} else {
|
|
122
117
|
base = process.env.XDG_CACHE_HOME || path.join(home, ".cache");
|
|
123
118
|
}
|
|
124
|
-
const dir = path.join(base, "
|
|
119
|
+
const dir = path.join(base, "hanzo", "dev", version);
|
|
125
120
|
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
126
121
|
return dir;
|
|
127
122
|
};
|
|
128
123
|
|
|
129
124
|
const getCachedBinaryPath = (version) => {
|
|
130
|
-
// targetTriple already includes the proper extension on Windows ("...msvc.exe").
|
|
131
|
-
// Do not append another suffix; just use the exact targetTriple-derived name.
|
|
132
125
|
const cacheDir = getCacheDir(version);
|
|
133
|
-
return path.join(cacheDir, `
|
|
126
|
+
return path.join(cacheDir, `dev-${targetTriple}`);
|
|
134
127
|
};
|
|
135
128
|
|
|
136
129
|
let lastBootstrapError = null;
|
|
@@ -139,7 +132,6 @@ const httpsDownload = (url, dest) => new Promise((resolve, reject) => {
|
|
|
139
132
|
const req = httpsGet(url, (res) => {
|
|
140
133
|
const status = res.statusCode || 0;
|
|
141
134
|
if (status >= 300 && status < 400 && res.headers.location) {
|
|
142
|
-
// follow one redirect recursively
|
|
143
135
|
return resolve(httpsDownload(res.headers.location, dest));
|
|
144
136
|
}
|
|
145
137
|
if (status !== 200) {
|
|
@@ -164,19 +156,17 @@ const httpsDownload = (url, dest) => new Promise((resolve, reject) => {
|
|
|
164
156
|
|
|
165
157
|
const tryBootstrapBinary = async () => {
|
|
166
158
|
try {
|
|
167
|
-
// 1) Read our published version
|
|
168
159
|
const pkg = JSON.parse(readFileSync(path.join(__dirname, "..", "package.json"), "utf8"));
|
|
169
160
|
const version = pkg.version;
|
|
170
161
|
|
|
171
162
|
const binDir = path.join(__dirname, "..", "bin");
|
|
172
163
|
if (!existsSync(binDir)) mkdirSync(binDir, { recursive: true });
|
|
173
164
|
|
|
174
|
-
//
|
|
165
|
+
// Fast path: user cache
|
|
175
166
|
const cachePath = getCachedBinaryPath(version);
|
|
176
167
|
if (existsSync(cachePath)) {
|
|
177
168
|
const v = validateBinary(cachePath);
|
|
178
169
|
if (v.ok) {
|
|
179
|
-
// Prefer running directly from cache; mirror into node_modules on Unix
|
|
180
170
|
if (platform !== "win32") {
|
|
181
171
|
copyFileSync(cachePath, binaryPath);
|
|
182
172
|
try { chmodSync(binaryPath, 0o755); } catch {}
|
|
@@ -185,26 +175,25 @@ const tryBootstrapBinary = async () => {
|
|
|
185
175
|
}
|
|
186
176
|
}
|
|
187
177
|
|
|
188
|
-
//
|
|
178
|
+
// Try platform package (if present)
|
|
189
179
|
try {
|
|
190
180
|
const req = (await import("module")).createRequire(import.meta.url);
|
|
191
181
|
const name = (() => {
|
|
192
|
-
if (platform === "win32") return "@
|
|
182
|
+
if (platform === "win32") return "@hanzo/dev-win32-x64";
|
|
193
183
|
const plt = nodePlatform();
|
|
194
184
|
const cpu = nodeArch();
|
|
195
|
-
if (plt === "darwin" && cpu === "arm64") return "@
|
|
196
|
-
if (plt === "darwin" && cpu === "x64") return "@
|
|
197
|
-
if (plt === "linux" && cpu === "x64") return "@
|
|
198
|
-
if (plt === "linux" && cpu === "arm64") return "@
|
|
185
|
+
if (plt === "darwin" && cpu === "arm64") return "@hanzo/dev-darwin-arm64";
|
|
186
|
+
if (plt === "darwin" && cpu === "x64") return "@hanzo/dev-darwin-x64";
|
|
187
|
+
if (plt === "linux" && cpu === "x64") return "@hanzo/dev-linux-x64-musl";
|
|
188
|
+
if (plt === "linux" && cpu === "arm64") return "@hanzo/dev-linux-arm64-musl";
|
|
199
189
|
return null;
|
|
200
190
|
})();
|
|
201
191
|
if (name) {
|
|
202
192
|
try {
|
|
203
193
|
const pkgJson = req.resolve(`${name}/package.json`);
|
|
204
194
|
const pkgDir = path.dirname(pkgJson);
|
|
205
|
-
const src = path.join(pkgDir, "bin", `
|
|
195
|
+
const src = path.join(pkgDir, "bin", `dev-${targetTriple}`);
|
|
206
196
|
if (existsSync(src)) {
|
|
207
|
-
// Always ensure cache has the binary; on Unix mirror into node_modules
|
|
208
197
|
copyFileSync(src, cachePath);
|
|
209
198
|
if (platform !== "win32") {
|
|
210
199
|
copyFileSync(cachePath, binaryPath);
|
|
@@ -216,21 +205,22 @@ const tryBootstrapBinary = async () => {
|
|
|
216
205
|
}
|
|
217
206
|
} catch { /* ignore */ }
|
|
218
207
|
|
|
219
|
-
//
|
|
208
|
+
// Download from GitHub release
|
|
220
209
|
const isWin = platform === "win32";
|
|
210
|
+
// Use 'code-*' binary names since that's what the release produces
|
|
211
|
+
const binaryName = `code-${targetTriple}`;
|
|
221
212
|
const archiveName = isWin
|
|
222
|
-
?
|
|
223
|
-
: (() => { try { execSync("zstd --version", { stdio: "ignore", shell: true }); return
|
|
224
|
-
const url = `https://github.com/
|
|
213
|
+
? `${binaryName}.zip`
|
|
214
|
+
: (() => { try { execSync("zstd --version", { stdio: "ignore", shell: true }); return `${binaryName}.zst`; } catch { return `${binaryName}.tar.gz`; } })();
|
|
215
|
+
const url = `https://github.com/hanzoai/dev/releases/download/v${version}/${archiveName}`;
|
|
225
216
|
const tmp = path.join(binDir, `.${archiveName}.part`);
|
|
226
217
|
return httpsDownload(url, tmp)
|
|
227
218
|
.then(() => {
|
|
228
219
|
if (isWin) {
|
|
229
|
-
// Extract zip with robust fallbacks and use a safe temp dir, then move to cache
|
|
230
220
|
try {
|
|
231
|
-
const sysRoot = process.env.SystemRoot || process.env.windir || 'C
|
|
221
|
+
const sysRoot = process.env.SystemRoot || process.env.windir || 'C:\\Windows';
|
|
232
222
|
const psFull = path.join(sysRoot, 'System32', 'WindowsPowerShell', 'v1.0', 'powershell.exe');
|
|
233
|
-
const unzipDest = getCacheDir(version);
|
|
223
|
+
const unzipDest = getCacheDir(version);
|
|
234
224
|
const psCmd = `Expand-Archive -Path '${tmp}' -DestinationPath '${unzipDest}' -Force`;
|
|
235
225
|
let ok = false;
|
|
236
226
|
try { execSync(`"${psFull}" -NoProfile -NonInteractive -Command "${psCmd}"`, { stdio: 'ignore' }); ok = true; } catch {}
|
|
@@ -251,11 +241,7 @@ const tryBootstrapBinary = async () => {
|
|
|
251
241
|
try { unlinkSync(tmp); } catch {}
|
|
252
242
|
}
|
|
253
243
|
}
|
|
254
|
-
|
|
255
|
-
if (platform === "win32") {
|
|
256
|
-
// Ensure the expected filename exists in cache; Expand-Archive extracts exact name
|
|
257
|
-
// No action required here; validation occurs below against cachePath
|
|
258
|
-
} else {
|
|
244
|
+
if (platform !== "win32") {
|
|
259
245
|
try { copyFileSync(binaryPath, cachePath); } catch {}
|
|
260
246
|
}
|
|
261
247
|
|
|
@@ -270,7 +256,7 @@ const tryBootstrapBinary = async () => {
|
|
|
270
256
|
}
|
|
271
257
|
};
|
|
272
258
|
|
|
273
|
-
// If missing, attempt to bootstrap into place
|
|
259
|
+
// If missing, attempt to bootstrap into place
|
|
274
260
|
let binaryReady = existsSync(binaryPath) || existsSync(legacyBinaryPath);
|
|
275
261
|
if (!binaryReady) {
|
|
276
262
|
let runtimePostinstallError = null;
|
|
@@ -287,7 +273,6 @@ if (!binaryReady) {
|
|
|
287
273
|
if (runtimePostinstallError && !lastBootstrapError) {
|
|
288
274
|
lastBootstrapError = runtimePostinstallError;
|
|
289
275
|
}
|
|
290
|
-
// retry legacy name in case archive provided coder-*
|
|
291
276
|
if (existsSync(legacyBinaryPath) && !existsSync(binaryPath)) {
|
|
292
277
|
binaryPath = legacyBinaryPath;
|
|
293
278
|
}
|
|
@@ -310,17 +295,14 @@ try {
|
|
|
310
295
|
// ignore
|
|
311
296
|
}
|
|
312
297
|
|
|
313
|
-
// Check if binary exists and try to fix permissions if needed
|
|
314
|
-
// fs imports are above; keep for readability if tree-shaken by bundlers
|
|
315
298
|
import { spawnSync } from "child_process";
|
|
316
299
|
if (existsSync(binaryPath)) {
|
|
317
300
|
try {
|
|
318
|
-
// Ensure binary is executable on Unix-like systems
|
|
319
301
|
if (platform !== "win32") {
|
|
320
302
|
chmodSync(binaryPath, 0o755);
|
|
321
303
|
}
|
|
322
304
|
} catch (e) {
|
|
323
|
-
// Ignore permission errors
|
|
305
|
+
// Ignore permission errors
|
|
324
306
|
}
|
|
325
307
|
} else {
|
|
326
308
|
console.error(`Binary not found: ${binaryPath}`);
|
|
@@ -329,97 +311,69 @@ if (existsSync(binaryPath)) {
|
|
|
329
311
|
console.error(`Bootstrap error: ${msg}`);
|
|
330
312
|
}
|
|
331
313
|
console.error(`Please try reinstalling the package:`);
|
|
332
|
-
console.error(` npm uninstall -g @
|
|
333
|
-
console.error(` npm install -g @
|
|
314
|
+
console.error(` npm uninstall -g @hanzo/dev`);
|
|
315
|
+
console.error(` npm install -g @hanzo/dev`);
|
|
334
316
|
if (isWSL()) {
|
|
335
317
|
console.error("Detected WSL. Install inside WSL (Ubuntu) separately:");
|
|
336
|
-
console.error(" npx -y @
|
|
318
|
+
console.error(" npx -y @hanzo/dev@latest (run inside WSL)");
|
|
337
319
|
console.error("If installed globally on Windows, those binaries are not usable from WSL.");
|
|
338
320
|
}
|
|
339
321
|
process.exit(1);
|
|
340
322
|
}
|
|
341
323
|
|
|
342
|
-
// Lightweight header validation to provide clearer errors before spawn
|
|
343
|
-
// Reuse the validateBinary helper defined above in the bootstrap section.
|
|
344
|
-
|
|
345
324
|
const validation = validateBinary(binaryPath);
|
|
346
325
|
if (!validation.ok) {
|
|
347
326
|
console.error(`The native binary at ${binaryPath} appears invalid: ${validation.reason}`);
|
|
348
327
|
console.error("This can happen if the download failed or was modified by antivirus/proxy.");
|
|
349
328
|
console.error("Please try reinstalling:");
|
|
350
|
-
console.error(" npm uninstall -g @
|
|
351
|
-
console.error(" npm install -g @
|
|
329
|
+
console.error(" npm uninstall -g @hanzo/dev");
|
|
330
|
+
console.error(" npm install -g @hanzo/dev");
|
|
352
331
|
if (platform === "win32") {
|
|
353
332
|
console.error("If the issue persists, clear npm cache and disable antivirus temporarily:");
|
|
354
333
|
console.error(" npm cache clean --force");
|
|
355
334
|
}
|
|
356
335
|
if (isWSL()) {
|
|
357
336
|
console.error("Detected WSL. Ensure you install/run inside WSL, not Windows:");
|
|
358
|
-
console.error(" npx -y @
|
|
337
|
+
console.error(" npx -y @hanzo/dev@latest (inside WSL)");
|
|
359
338
|
}
|
|
360
339
|
process.exit(1);
|
|
361
340
|
}
|
|
362
341
|
|
|
363
|
-
// If running under npx/npm, emit a concise notice
|
|
342
|
+
// If running under npx/npm, emit a concise notice
|
|
364
343
|
try {
|
|
365
344
|
const ua = process.env.npm_config_user_agent || "";
|
|
366
345
|
const isNpx = ua.includes("npx");
|
|
367
346
|
if (isNpx && process.stderr && process.stderr.isTTY) {
|
|
368
|
-
|
|
369
|
-
let otherCode = "";
|
|
370
|
-
try {
|
|
371
|
-
const cmd = process.platform === "win32" ? "where code" : "command -v code || which code || true";
|
|
372
|
-
const out = spawnSync(process.platform === "win32" ? "cmd" : "bash", [
|
|
373
|
-
process.platform === "win32" ? "/c" : "-lc",
|
|
374
|
-
cmd,
|
|
375
|
-
], { encoding: "utf8" });
|
|
376
|
-
const line = (out.stdout || "").split(/\r?\n/).map((s) => s.trim()).filter(Boolean)[0];
|
|
377
|
-
if (line && !line.includes("@just-every/code")) {
|
|
378
|
-
otherCode = line;
|
|
379
|
-
}
|
|
380
|
-
} catch {}
|
|
381
|
-
if (otherCode) {
|
|
382
|
-
console.error(`@just-every/code: running bundled binary -> ${binaryPath}`);
|
|
383
|
-
console.error(`Note: a different 'code' exists at ${otherCode}; not delegating.`);
|
|
384
|
-
} else {
|
|
385
|
-
console.error(`@just-every/code: running bundled binary -> ${binaryPath}`);
|
|
386
|
-
}
|
|
347
|
+
console.error(`@hanzo/dev: running bundled binary -> ${binaryPath}`);
|
|
387
348
|
}
|
|
388
349
|
} catch {}
|
|
389
350
|
|
|
390
|
-
// Use an asynchronous spawn instead of spawnSync so that Node is able to
|
|
391
|
-
// respond to signals (e.g. Ctrl-C / SIGINT) while the native binary is
|
|
392
|
-
// executing. This allows us to forward those signals to the child process
|
|
393
|
-
// and guarantees that when either the child terminates or the parent
|
|
394
|
-
// receives a fatal signal, both processes exit in a predictable manner.
|
|
395
351
|
const { spawn } = await import("child_process");
|
|
396
352
|
|
|
397
|
-
|
|
398
|
-
process.env.CODE_BINARY_PATH = binaryPath;
|
|
353
|
+
process.env.DEV_BINARY_PATH = binaryPath;
|
|
399
354
|
|
|
400
355
|
const child = spawn(binaryPath, process.argv.slice(2), {
|
|
401
356
|
stdio: "inherit",
|
|
402
|
-
env: { ...process.env,
|
|
357
|
+
env: { ...process.env, DEV_MANAGED_BY_NPM: "1", DEV_BINARY_PATH: binaryPath },
|
|
403
358
|
});
|
|
404
359
|
|
|
405
360
|
child.on("error", (err) => {
|
|
406
|
-
// Typically triggered when the binary is missing or not executable.
|
|
407
361
|
const code = err && err.code;
|
|
408
362
|
if (code === 'EACCES') {
|
|
409
363
|
console.error(`Permission denied: ${binaryPath}`);
|
|
410
364
|
console.error(`Try running: chmod +x "${binaryPath}"`);
|
|
411
|
-
console.error(`Or reinstall the package with: npm install -g @
|
|
365
|
+
console.error(`Or reinstall the package with: npm install -g @hanzo/dev`);
|
|
412
366
|
} else if (code === 'EFTYPE' || code === 'ENOEXEC') {
|
|
413
367
|
console.error(`Failed to execute native binary: ${binaryPath}`);
|
|
414
368
|
console.error("The file may be corrupt or of the wrong type. Reinstall usually fixes this:");
|
|
415
|
-
console.error(" npm uninstall -g @
|
|
369
|
+
console.error(" npm uninstall -g @hanzo/dev && npm install -g @hanzo/dev");
|
|
416
370
|
if (platform === 'win32') {
|
|
417
371
|
console.error("On Windows, ensure the .exe downloaded correctly (proxy/AV can interfere).");
|
|
418
372
|
console.error("Try clearing cache: npm cache clean --force");
|
|
419
373
|
}
|
|
420
374
|
if (isWSL()) {
|
|
421
375
|
console.error("Detected WSL. Windows binaries cannot be executed from WSL.");
|
|
422
|
-
console.error("Install inside WSL and run there: npx -y @
|
|
376
|
+
console.error("Install inside WSL and run there: npx -y @hanzo/dev@latest");
|
|
423
377
|
}
|
|
424
378
|
} else {
|
|
425
379
|
console.error(err);
|
|
@@ -427,10 +381,6 @@ child.on("error", (err) => {
|
|
|
427
381
|
process.exit(1);
|
|
428
382
|
});
|
|
429
383
|
|
|
430
|
-
// Forward common termination signals to the child so that it shuts down
|
|
431
|
-
// gracefully. In the handler we temporarily disable the default behavior of
|
|
432
|
-
// exiting immediately; once the child has been signaled we simply wait for
|
|
433
|
-
// its exit event which will in turn terminate the parent (see below).
|
|
434
384
|
const forwardSignal = (signal) => {
|
|
435
385
|
if (child.killed) {
|
|
436
386
|
return;
|
|
@@ -446,11 +396,6 @@ const forwardSignal = (signal) => {
|
|
|
446
396
|
process.on(sig, () => forwardSignal(sig));
|
|
447
397
|
});
|
|
448
398
|
|
|
449
|
-
// When the child exits, mirror its termination reason in the parent so that
|
|
450
|
-
// shell scripts and other tooling observe the correct exit status.
|
|
451
|
-
// Wrap the lifetime of the child process in a Promise so that we can await
|
|
452
|
-
// its termination in a structured way. The Promise resolves with an object
|
|
453
|
-
// describing how the child exited: either via exit code or due to a signal.
|
|
454
399
|
const childResult = await new Promise((resolve) => {
|
|
455
400
|
child.on("exit", (code, signal) => {
|
|
456
401
|
if (signal) {
|
|
@@ -462,8 +407,6 @@ const childResult = await new Promise((resolve) => {
|
|
|
462
407
|
});
|
|
463
408
|
|
|
464
409
|
if (childResult.type === "signal") {
|
|
465
|
-
// Re-emit the same signal so that the parent terminates with the expected
|
|
466
|
-
// semantics (this also sets the correct exit code of 128 + n).
|
|
467
410
|
process.kill(process.pid, childResult.signal);
|
|
468
411
|
} else {
|
|
469
412
|
process.exit(childResult.exitCode);
|
package/package.json
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hanzo/dev",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.74",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
|
-
"description": "
|
|
5
|
+
"description": "Hanzo AI coding assistant - intelligent CLI for developers",
|
|
6
6
|
"bin": {
|
|
7
|
-
"
|
|
7
|
+
"dev": "bin/dev.js",
|
|
8
|
+
"hanzo": "bin/dev.js"
|
|
8
9
|
},
|
|
9
10
|
"type": "module",
|
|
10
11
|
"engines": {
|
|
11
12
|
"node": ">=16"
|
|
12
13
|
},
|
|
13
14
|
"files": [
|
|
14
|
-
"bin/
|
|
15
|
-
"bin/codex.js",
|
|
15
|
+
"bin/dev.js",
|
|
16
16
|
"postinstall.js",
|
|
17
17
|
"scripts/preinstall.js",
|
|
18
18
|
"scripts/windows-cleanup.ps1",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"scripts": {
|
|
22
22
|
"preinstall": "node scripts/preinstall.js",
|
|
23
23
|
"postinstall": "node postinstall.js",
|
|
24
|
-
"prepublishOnly": "node -e \"const fs=require('fs'),path=require('path'); const repoGit=path.join(__dirname,'..','.git'); const inCi=process.env.GITHUB_ACTIONS==='true'||process.env.CI==='true'; if(fs.existsSync(repoGit) && !inCi){ console.error('Refusing to publish from
|
|
24
|
+
"prepublishOnly": "node -e \"const fs=require('fs'),path=require('path'); const repoGit=path.join(__dirname,'..','.git'); const inCi=process.env.GITHUB_ACTIONS==='true'||process.env.CI==='true'; if(fs.existsSync(repoGit) && !inCi){ console.error('Refusing to publish from dev-cli. Publishing happens via release.yml.'); process.exit(1);} else { console.log(inCi ? 'CI publish detected.' : 'Publishing staged package...'); }\""
|
|
25
25
|
},
|
|
26
26
|
"repository": {
|
|
27
27
|
"type": "git",
|
|
@@ -35,10 +35,10 @@
|
|
|
35
35
|
"prettier": "^3.3.3"
|
|
36
36
|
},
|
|
37
37
|
"optionalDependencies": {
|
|
38
|
-
"@hanzo/dev-darwin-arm64": "0.6.
|
|
39
|
-
"@hanzo/dev-darwin-x64": "0.6.
|
|
40
|
-
"@hanzo/dev-linux-x64-musl": "0.6.
|
|
41
|
-
"@hanzo/dev-linux-arm64-musl": "0.6.
|
|
42
|
-
"@hanzo/dev-win32-x64": "0.6.
|
|
38
|
+
"@hanzo/dev-darwin-arm64": "0.6.74",
|
|
39
|
+
"@hanzo/dev-darwin-x64": "0.6.74",
|
|
40
|
+
"@hanzo/dev-linux-x64-musl": "0.6.74",
|
|
41
|
+
"@hanzo/dev-linux-arm64-musl": "0.6.74",
|
|
42
|
+
"@hanzo/dev-win32-x64": "0.6.74"
|
|
43
43
|
}
|
|
44
44
|
}
|