fix(web): persist the default CLI at any installed count, not only a sole one - #4151
fix(web): persist the default CLI at any installed count, not only a sole one#4151jsmith7735 wants to merge 1 commit into
Conversation
…sole one
The sole-install persistence added in config-form.tsx fixed the one-CLI case
but left the multi-CLI case in exactly the state its own comment warns about:
const only = list.filter((c) => c.installed);
if (only.length !== 1) return list.find((c) => c.installed)?.id || "";
if (!readSavedCliId()) persistCliId(only[0].id);
With two or more CLIs installed the early return highlights the first one and
persists nothing. Every AI surface reads `career-ops:config` directly and sends
it as `cliId`, so on a machine with claude + codex (or, here, claude, codex,
gemini and opencode) Config shows a selected CLI over empty localStorage and
every AI feature silently does nothing -- /api/explore/ai answers
{"error":"query and cliId required"} and the console shows "no CLI configured".
Nothing prompts a Save, because nothing looks unset. Reproduced on a clean
browser profile against 1.32.0: localStorage is empty after visiting /config.
Whatever Config renders as selected is what it must persist, so the pick is now
pickDefaultInstalled() -- first installed, any count -- while pickSoleInstalled
keeps its narrower meaning for resolveCliId().
Both live in src/lib/cli-pick.mjs, and saved-cli.ts re-exports them. That is
what lets tests/lib/saved-cli-pick.test.mjs import the REAL functions: the suite
previously held a hand-copied mirror of pickSoleInstalled, which by
construction cannot fail when the real function changes. Reverting
pickDefaultInstalled to the sole-install behaviour now turns 2 tests red.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Yafkyw2o71V3kyMu4QRbqB
|
Welcome to career-ops, @jsmith7735! Thanks for your first PR. A few things to know:
We review every PR by hand. Join our Discord if anything blocks you. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Advanced Run ID: 📒 Files selected for processing (4)
🔗 Linked repositories identifiedCodeRabbit considers these linked repositories for cross-repo context during reviews:
Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review. 📝 WalkthroughWalkthrough
ChangesCLI selection behavior
Priority: ➖ Normal Estimated code review effort: 3 (Moderate) | ~20 minutes Change: Bug fix Suggested labels: Merge Risk: ⚪ Minimal · up to The CLI selection persistence change is covered by the supplied tests and is ready to merge. 🚥 Pre-merge checks | ✅ 8 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (8 passed)
Full details: Agent-Operated Pr DisclosureExplanation The description does not contain Resolution Provide the PR source branch, author identity, and labels. If the source branch matches ✨ Finishing Touches🧪 Generate unit tests (beta)
🚀 Post-Merge Actions
Warning Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
What does this PR do?
Persists the default CLI on machines with two or more AI CLIs installed. Today only a sole install is persisted, so every multi-CLI machine gets a Config page that looks configured while every AI feature silently does nothing.
Related issue
None — bug fix, which CONTRIBUTING.md exempts from issue-first. Happy to open one if you'd prefer it tracked.
Type of change
The bug
config-form.tsxcurrently persists the auto-selection only when exactly one CLI is installed. The multi-CLI path falls through into precisely the state the code's own comment warns about:With two or more installed, the early return highlights the first CLI and writes nothing.
Every AI surface reads
career-ops:configdirectly and sends it ascliId. So Config displays a selected CLI over an emptylocalStorage,/api/explore/aianswers{"error":"query and cliId required"}, and the assistant shows "no CLI configured" next to a Config page that looks configured.Nothing prompts a Save, because nothing looks unset. The workaround a user lands on by accident: select a different CLI → Save → reload → select the original → Save → reload.
Reproduction
mainat 1.32.0, clean browser profile, four CLIs installed (claude,codex,gemini,opencode):With this change:
The fix
Whatever Config renders as selected is what it must persist, so the pick becomes
pickDefaultInstalled()— first installed, any count.pickSoleInstalled()keeps its narrower meaning forresolveCliId(), which answers a different question ("can I choose for the user unambiguously?") and is deliberately left alone.On the test move
Both helpers now live in
src/lib/cli-pick.mjs, re-exported fromsaved-cli.ts.That is what lets
tests/lib/saved-cli-pick.test.mjsimport the real functions. The suite previously carried a hand-copied mirror ofpickSoleInstalled:A mirrored test cannot fail when the real function changes — plausibly why this gap went unnoticed. The extraction follows the
.mjspatternweb/README.mdprescribes for exactly this reason.Mutation-checked: reverting
pickDefaultInstalledto the sole-install behavior turns 2 tests red.Tests
web/suite: 502 pass / 0 fail (was 497).npx tsc --noEmitclean.npm run buildclean.Checklist
node test-all.mjsand all tests pass — see noteweb/system-layer files touched)On the test box:
node test-all.mjsreports 2 failures on this branch. Both are pre-existing and environmental — verified by stashing the changes and re-running on a pristine tree, which fails identically:live archive: no PDF written to jds/(fetches a live posting over the network), andtests/mjs-files.test.mjsflagging a gitignored file in my own checkout that won't exist in CI. Flagging rather than ticking a box that isn't strictly true.Summary
Users with multiple installed AI CLIs now get the first installed CLI saved to
localStorage. AI features no longer treat the Config page as unconfigured.Changes
web/src/components/config-form.tsx:72-83: Select and persist the first installed CLI when no saved selection exists.web/src/lib/cli-pick.mjs:5-21: Add shared helpers for sole-CLI resolution and default selection.web/src/lib/saved-cli.ts:28-39: Re-export the helpers and retain sole-CLI behavior for unambiguous resolution.web/tests/lib/saved-cli-pick.test.mjs:38-75: Test single-, multi-, zero-, sparse-, and undefined-CLI cases against the real helpers.Validation
System files
No changes affect
AGENTS.md,modes/,update-system.mjs,DATA_CONTRACT.md,providers/, or.github/.