Skip to content

fix(cli): only run init when it is the first operand, not when an option value reads "init" - #9

Open
eastagiletracker wants to merge 1 commit into
bitrefill:masterfrom
eastagiletracker:agile-board/fix-init-dispatch
Open

fix(cli): only run init when it is the first operand, not when an option value reads "init"#9
eastagiletracker wants to merge 1 commit into
bitrefill:masterfrom
eastagiletracker:agile-board/fix-init-dispatch

Conversation

@eastagiletracker

Copy link
Copy Markdown

This PR proposes a fix so that bitrefill only runs the init flow when init is the first operand, instead of whenever any argument happens to read init. We include this PR work along with a full history of your repo at https://eastagiletracker.com/projects/496. You can sign in with your GitHub ID to claim ownership of the project.

What is wrong

The pre-connect dispatch in src/index.ts decides whether the invocation is init by scanning the whole of process.argv:

const isInit = process.argv.some((arg, i) => arg === 'init' && i >= 2);

Any token that reads init matches, including an option value. Two ordinary invocations therefore run setup instead of the command that was typed, and since handleInit() finishes with clearOAuthStore(), both of them delete ~/.config/bitrefill-cli/<host>.v1.json — the signed-in session is gone, and ~/.openclaw/openclaw.json is rewritten on the way:

  • bitrefill help init — the help [command] form that bitrefill --help itself advertises
  • bitrefill search-products --query init — a catalog search whose query happens to be that word

Reproducing it on master (635c341)

Both paths short-circuit before the MCP connection, so this needs no network and no account — only a scratch HOME so your real state is untouched:

export HOME=$(mktemp -d)
mkdir -p "$HOME/.config/bitrefill-cli"
printf '{"version":1,"email":"you@example.com","tokens":{"access_token":"tok"}}' \
  > "$HOME/.config/bitrefill-cli/api.bitrefill.com.v1.json"

npx tsx src/index.ts help init
ls "$HOME/.config/bitrefill-cli"

Observed at 635c341:

$ npx tsx src/index.ts help init

Bitrefill initialized.

  Tools:      0 available

Try it:
  CLI:       bitrefill search-products --query "Netflix"

$ ls "$HOME/.config/bitrefill-cli"
$            # empty — the saved session was deleted

npx tsx src/index.ts search-products --query init prints the same banner, performs no search, and deletes the session file the same way.

The change

detectInitInvocation now resolves the subcommand the way commander does — the first token that is not an option — so an option value can never be mistaken for it. The helper moves into a new src/argv.ts because src/index.ts executes main() on import and so cannot be pulled into a test; that matches how tools.ts, output.ts and manifest.ts already keep testable logic beside a colocated *.test.ts. Nothing about init itself changes: init, init --openclaw, --json init and init --help all take exactly the path they took before, and help init now falls through to commander, which prints the help for that command.

Verifying it

src/argv.test.ts covers both directions, and its two regression cases fail against the previous scan and pass with this change:

$ npx vitest run src/argv.test.ts        # with the old whole-argv scan restored
 FAIL  src/argv.test.ts > detectInitInvocation > does not treat an option value of "init" as the subcommand
 FAIL  src/argv.test.ts > detectInitInvocation > leaves `help init` to the help command
      Tests  2 failed | 5 passed (7)

Full checks before and after, on the same machine: pnpm test 38 passed → 45 passed, pnpm build clean, pnpm format reports All matched files use Prettier code style!. Nothing was failing before this change and nothing fails after it.

End to end against a local MCP server standing in for api.bitrefill.com/mcp, with a session file seeded as above: help init prints the help for init and leaves the session in place, search-products --query init returns the search result for the query init, and init, --json init and init --help behave exactly as they do on master.

How this was managed

We tracked this work on a board built from your own issues and pull requests — 8 stories and 2 labels imported from bitrefill/cli. The story behind this PR is bitrefill help init runs the init flow instead of showing help, on the board at https://eastagiletracker.com/projects/496.

board

If you'd rather not receive contributions like this, reply no-more-prs on this pull request and we won't open any further ones on your repositories.


Lawrence W. Sinclair
CEO / East Agile
linkedin.com/in/lwsinclair/
eastagile.com

The pre-connect dispatch scanned all of process.argv for the token
"init", so any option value spelled that way was mistaken for the
subcommand: `bitrefill help init` and `bitrefill search-products --query
init` both ran the init flow, which rewrites ~/.openclaw/openclaw.json
and clears the saved session via clearOAuthStore().

Resolve the subcommand as the first non-option operand instead, in a new
src/argv.ts so it can be unit tested without importing the entry point.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant