ReviewOS

craft-native/craft

craft <url> fails with "Unknown option --url": resolveCraftBinary() resolves to the CLI shim via PATH

#26
Closed glennmichael123 opened this 9 days ago ·
9 days ago

Summary

craft <url> — the primary documented usage, and the first example in craft --help — always fails with Unknown option --url. The CLI re-invokes itself instead of the native binary.

Reproduction

$ craft http://localhost:3000
ClappError: Unknown option `--url`

Run `craft [url] --help` to see available options.
   exitCode: 2,
 isUsageError: true,

      at checkUnknownOptions (@stacksjs/clapp/dist/index.js:740:17)
      at runMatchedCommand (@stacksjs/clapp/dist/index.js:1336:13)
      at parse (@stacksjs/clapp/dist/index.js:1252:18)
      at packages/typescript/bin/cli.ts:937:5
Error: Craft exited with code 1

No flags are needed to trigger it — the bare form is enough. --url is never typed by the user; the CLI adds it.

Cause

bin/cli.ts builds native-binary args and pushes --url:

if (url) {
  args.push('--url', validateUrl(url))
}
...
await runCraftBinary(args)

runCraftBinary spawns whatever resolveCraftBinary() returns, and with no CRAFT_BIN set that is the bare string 'craft' (packages/typescript/src/binary-resolver.ts:50):

// PATH lookup. The OS resolves `'craft'` to whatever pantry installed.
return 'craft'

On a machine where the CLI shim is what's on PATH — e.g. ~/.bun/bin/craft, a #!/usr/bin/env bun script — spawn('craft', ['--url', …]) re-enters the TypeScript CLI, whose own parser has no --url option. The recursion is cut short by the arg check, which is why it surfaces as a usage error rather than a fork bomb.

Workarounds

Both bypass PATH:

CRAFT_BIN=/path/to/craft/packages/zig/zig-out/bin/craft craft http://localhost:3000
/path/to/craft/packages/zig/zig-out/bin/craft --url http://localhost:3000

@stacksjs/desktop is unaffected because it resolves zig-out/bin/craft directly rather than going through PATH.

Expected

resolveCraftBinary() should resolve to the native binary, not to whatever craft happens to mean on PATH. Resolving relative to the package (as bin/craft already does via $ROOT_DIR/packages/zig/zig-out/bin/craft) would avoid it; at minimum the resolver should reject a candidate that is the CLI shim itself.

Environment

craft 0.0.66, macOS (arm64), Bun 1.3.14. PATH entry is ~/.bun/bin/craft.

Sign in to comment on this issue.