mirror of
https://github.com/hanzo-js/hanzo.git
synced 2026-10-30 18:55:09 +00:00
Four npm names published the same idea -- hanzo (a 2020 placeholder with no
main, no bin and no deps), @hanzo/cli, @hanzo/ai, hanzoai -- and a reader had
to know which. The cost is not tidiness: a wrong guess installs a client that
does not carry the surface being called.
This is a front door and nothing else. `hanzo` re-exports the generated cloud
client, `hanzo/ai` re-exports the agents library, and the `hanzo` command execs
the Rust binary @hanzo/cli fetches. Nothing is vendored, nothing reimplemented;
each piece stays in the package that owns it and depending on those directly
still works.
The launcher execs the binary rather than @hanzo/cli's own launcher, so exactly
one process sits between the terminal and an interactive program -- a wrapper
that outlives its child owns that child's signals. A signalled child re-raises
rather than collapsing to an exit code.
Measured from a packed tarball, installed clean: `import * as h from 'hanzo'`
772 exports, `require('hanzo')` 770, `import * as a from 'hanzo/ai'` 36, and
`hanzo --version` prints 1.9.57 with one bin linked.
Co-authored-by: Hanzo Dev <[email protected]>
45 lines
1.8 KiB
JavaScript
Executable File
45 lines
1.8 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
// Hand the real binary the argv it was given and get out of the way.
|
|
//
|
|
// ONE HOP, NOT TWO. @hanzo/cli ships its own launcher that finds the binary and
|
|
// execs it, and calling THAT would put a second Node process between the
|
|
// terminal and an interactive program. So this resolves the same binary and
|
|
// execs it directly: `hanzo` is interactive, and every process in front of the
|
|
// real one is a process that owns its signals instead of forwarding them.
|
|
//
|
|
// The binary itself arrives with @hanzo/cli, whose install script fetches the
|
|
// build for this platform. Nothing is vendored here — one downloader, one
|
|
// naming rule, in the package that owns it.
|
|
import { spawnSync } from "node:child_process";
|
|
import { existsSync } from "node:fs";
|
|
import { createRequire } from "node:module";
|
|
import { dirname, join } from "node:path";
|
|
|
|
const require = createRequire(import.meta.url);
|
|
|
|
let cliDir;
|
|
try {
|
|
cliDir = dirname(require.resolve("@hanzo/cli/package.json"));
|
|
} catch {
|
|
console.error(
|
|
"hanzo: @hanzo/cli is not installed. It is a dependency of this package, so\n" +
|
|
"reinstall with `npm install -g hanzo` (or `npm install hanzo` in a project)."
|
|
);
|
|
process.exit(1);
|
|
}
|
|
|
|
const bin = join(cliDir, "bin", process.platform === "win32" ? "hanzo.exe" : "hanzo");
|
|
if (!existsSync(bin)) {
|
|
console.error(
|
|
"hanzo: the binary is missing. @hanzo/cli's install script fetches it;\n" +
|
|
"if that was skipped (--ignore-scripts) run `node " + join(cliDir, "install.js") + "`."
|
|
);
|
|
process.exit(1);
|
|
}
|
|
|
|
const { status, signal } = spawnSync(bin, process.argv.slice(2), { stdio: "inherit" });
|
|
// A signalled child did not choose its exit code, so report the signal the way
|
|
// a shell does rather than collapsing it to 0.
|
|
if (signal) process.kill(process.pid, signal);
|
|
process.exit(status ?? 1);
|