Files
bot/test/entry-wrapper-pairs.test.ts
zeekay f105ffff17 fix: make the published package installable and the CLI actually run
The public repo could not be installed or run, and the two defects share a
cause: a rename left constants pointing at names that do not exist.

Install: @hanzo/iam was pinned to github:hanzo-js/iam#main, a private repo, so
pnpm install failed with ERR_PNPM_FETCH_404 for anyone without access to it —
including CI, which passes no token, so the image install could not have
resolved it either. The package is published, so depend on it from npm. That
leaves no dependency needing credentials, so the Dockerfile's GIT_TOKEN plumbing
goes too; it wrote the token into .npmrc and took it on a build arg, which
docker history keeps.

The SDK names its server-side types Config/AuthResult/JwtClaims, so alias them
to the Iam* names the gateway wrapper exposes. Config is what validateToken and
IamClient accept; IAMConfig is the browser entrypoint's config and does not
belong here.

CLI: package.json declares hanzo-bot.mjs as its bin, but ENTRY_WRAPPER_PAIRS
listed bot.mjs twice and hanzo-bot.mjs never, so isMainModule() saw no pair,
entry.ts skipped its body, and every invocation exited 0 with no output — a
gateway that starts, registers nothing and stops. Derive the pairs from the
bin wrappers and the entry files hanzo-bot.mjs imports, as a cross product, so
a row cannot be duplicated or dropped.

Version: resolveBinaryVersion() skips any package.json whose name is not
CORE_PACKAGE_NAME, which read "bot" while the package ships as @hanzo/bot, so
the package.json path resolved nothing and the version came from build-info.json
alone — absent from a bundle-only build, which then reported 0.0.0.

Both new tests fail when their defect is reintroduced: they assert against the
bins package.json declares and against the real package.json, rather than
restating the value under test.

Also from hanzobot/core: cloud-node detection behind one helper, node-host
reusing startPlaygroundRegistration instead of a second hand-rolled copy, the
playground node API on /v1, and the install smoke tests naming the package
@hanzo/bot rather than the bin name.
2026-07-15 23:25:40 -07:00

55 lines
2.0 KiB
TypeScript

import { readFileSync } from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { describe, expect, it } from "vitest";
import { ENTRY_WRAPPER_PAIRS } from "../src/infra/entry-wrappers.js";
import { isMainModule } from "../src/infra/is-main.js";
// The bins package.json declares are wrappers that import the built entry out of
// dist/. entry.ts only runs when isMainModule() recognises that pairing; miss it
// and the CLI exits 0 with no output — silently dead for `bot`, `hanzo-bot`, and
// every cloud-bot pod whose gateway then never starts.
//
// This asserts the pairing the shipped binary actually uses (ENTRY_WRAPPER_PAIRS),
// against the bins package.json actually declares. Restating the list here instead
// would pass even with entry.ts broken.
const repoRoot = fileURLToPath(new URL("..", import.meta.url));
const pkg = JSON.parse(readFileSync(path.join(repoRoot, "package.json"), "utf8")) as {
bin: Record<string, string>;
};
const declaredWrappers = [
...new Set(Object.values(pkg.bin).map((target) => path.basename(target))),
];
describe("entry wrapper pairing", () => {
it("declares at least one bin", () => {
expect(declaredWrappers.length).toBeGreaterThan(0);
});
it.each(declaredWrappers)("%s is recognised as main for dist/entry.js", (wrapper) => {
const isMain = isMainModule({
currentFile: "/app/dist/entry.js",
argv: ["/usr/bin/node", `/app/${wrapper}`],
env: {},
cwd: "/app",
wrapperEntryPairs: [...ENTRY_WRAPPER_PAIRS],
});
expect(isMain).toBe(true);
});
it("pairs every declared bin wrapper", () => {
const paired = new Set(ENTRY_WRAPPER_PAIRS.map((pair) => pair.wrapperBasename));
for (const wrapper of declaredWrappers) {
expect(paired).toContain(wrapper);
}
});
it("has no duplicate pairs", () => {
const keys = ENTRY_WRAPPER_PAIRS.map(
(pair) => `${pair.wrapperBasename}->${pair.entryBasename}`,
);
expect(keys).toHaveLength(new Set(keys).size);
});
});