fix(init): --help should not mutate config or scan filesystem#762
Open
brandonlipman wants to merge 1 commit intogarrytan:masterfrom
Open
fix(init): --help should not mutate config or scan filesystem#762brandonlipman wants to merge 1 commit intogarrytan:masterfrom
brandonlipman wants to merge 1 commit intogarrytan:masterfrom
Conversation
`gbrain init --help` (and `-h`) currently fall through to the smart-detection branch in runInit(), which scans cwd for .md files and on a directory with 1000+ files prints "Found ~1500 .md files. For a brain this size, Supabase gives faster search..." then defaults to PGLite — calling saveConfig() and overwriting any existing Postgres config with `engine: 'pglite' + database_path: ~/.gbrain/brain.pglite`. Confirmed in the wild: ran `gbrain init --help` from $HOME on a machine where ~/.gbrain/config.json pointed at a Supabase Postgres brain with 10K+ pages. The config was silently flipped to PGLite. The Supabase data was intact, but gbrain stopped pointing at it until the config was manually restored. Root cause: cli.ts:62-69 only routes --help → printOpHelp() for shared-op commands; CLI_ONLY commands (init, embed, etc.) fall through to their handler with --help still in argv. None of them check for it. Fix: add a --help/-h guard at the top of runInit() that prints help text and returns. Help should never mutate state — Postel's robustness principle for CLI tools. Help text covers all flags (engine selection, AI provider options, thin-client mode) so users running `--help` get the canonical list rather than having to read the source. A wider architectural fix — adding --help routing for all CLI_ONLY commands in cli.ts — is plausible follow-up, but each CLI_ONLY command would still need its own help text. This per-command pattern matches how shared ops handle it via printOpHelp(). Init is the highest-stakes case because it's the only CLI_ONLY command that calls saveConfig(). Smoke test: from a directory with 1500 .md files, with GBRAIN_HOME pointed at a fresh tempdir: - Before fix: ~/.gbrain/config.json materialized with engine: 'pglite' - After fix: help text printed, no config dir created `bun run typecheck` clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
gbrain init --helpcurrently falls through to the smart-detection branch inrunInit()instead of printing help. From a directory with 1000+.mdfiles, that path scans cwd, prints "Found ~N .md files. For a brain this size, Supabase gives faster search...", and then defaults to PGLite — callingsaveConfig()and overwriting any existing Postgres config.Repro
Confirmed on a real install:
The Supabase data was intact, but gbrain stopped pointing at it until config was manually restored from a backup. On a 10K+ page brain that's a several-minute incident at best, a data-loss-shaped scare at worst ("did
gbrain initjust nuke my brain?").Root cause
cli.ts:62-69only routes--help→printOpHelp()for shared-op commands:CLI_ONLY commands (
init,embed,serve, etc.) skip this branch — they fall through tohandleCliOnlywith--helpstill in argv. None of the CLI_ONLY handlers check for it.Fix
Add a
--help/-hguard at the top ofrunInit()that prints help text and returns. Help should never mutate state — Postel's robustness principle for CLI tools.Help text covers all flags (engine selection, AI provider options, thin-client mode) so users running
--helpget the canonical list rather than reading the source.Why per-command, not cli.ts-level
A wider architectural fix — adding
--helprouting for all CLI_ONLY commands incli.ts— is plausible follow-up, but each CLI_ONLY command would still need its own help text. This per-command pattern matches how shared ops do it viaprintOpHelp(). Init is the highest-stakes case because it's the only CLI_ONLY command that callssaveConfig().If the maintainer prefers the wider fix, happy to extend; flagging here as the local-minimum patch.
Smoke test
From a directory with 1500
.mdfiles, withGBRAIN_HOMEpointed at a fresh tempdir:~/.gbrain/config.jsonmaterialized withengine: 'pglite'Test plan
bun run typecheckcleangbrain init --helpfrom a 1500-file directory — no config mutationtest/init-help-guard.test.tsif desired)🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmithwith what you need.