feat(cli): add Pi as AI provider option in setup wizard and doctor#1609
Conversation
The `archon setup` wizard previously hardcoded `[claude, codex]` in its AI multiselect. Pi is a registered community provider but was unreachable through the wizard, so users had to ctrl-c and hand-edit `~/.archon/.env` plus `~/.archon/config.yaml` to use it. Changes: - Add Pi (community) option to the `collectAIConfig` multiselect, with a per-backend prompt covering 9 LLM backends and an optional API key. - Write the chosen backend API key to `.env` under its canonical name (e.g. `ANTHROPIC_API_KEY`) and the model ref to `~/.archon/config.yaml` under `assistants.pi.model`. Skip the YAML write if `pi:` already exists or show a manual paste-in note when `assistants:` is present without `pi:`. - Add a Pi module-load verification spinner mirroring the Claude binary spawn-test, with a continue/abort prompt on failure. - Extend `archon doctor` with `checkPi` (skip when not configured, pass on auth.json or API key env var, fail when default but no auth). - Update default-assistant selection to handle Pi alongside Claude/Codex. - Mention the wizard path in the Pi docs page. - Tests cover Pi-only, Claude+Pi, no-API-key, `checkExistingConfig` Pi detection, all `checkPi` branches, and `checkPiModule` ok/fail. Fixes #1607
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (6)
📝 WalkthroughWalkthroughThis PR integrates Pi (community) as a first-class AI assistant option in the setup wizard and adds corresponding authentication checks to the doctor command. Users can now select Pi alongside Claude and Codex, choose a Pi backend, and provide the associated API key—all within the setup flow. The wizard writes credentials to ChangesPi Setup and Doctor Integration
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related issues
Possibly related PRs
Poem
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. 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 |
Comprehensive PR ReviewPR: #1609 — feat(cli): add Pi as AI provider option in setup wizard and doctor SummaryThe Pi provider addition to Verdict:
🟠 High IssuesH1:
|
| Issue | Location | Suggestion |
|---|---|---|
includes('pi:') false positive — 'api:'.includes('pi:') is true
|
setup.ts:1588 |
Replace with /^\s*pi\s*:/m.test(existing)
|
log.warn used once; rest of file uses log.warning
|
setup.ts:2053 |
Change to log.warning(...) for consistency |
writeHomePiModelConfig catch omits err.code (unlike the neighbor env-write catch above it) |
setup.ts:2050-2054 |
const code = e.code ? \ (${e.code})` : ''; log.warning(`...${code}: ${e.message}`)` |
Mixed Claude+Pi generateEnvContent test missing section header assertion |
setup.test.ts:375-395 |
Add expect(content).toContain('# Pi Authentication')
|
checkPiModule docstring says "mirrors the Claude binary check pattern" — they're structurally different |
setup.ts:514 |
Replace with "serves the same doctor-step role as checkClaudeBinary" |
CLAUDE.md bun run cli doctor comment omits Pi |
CLAUDE.md:260 |
Add "Pi provider" to the parenthetical |
✅ What's Good
checkPiModuleinjection pattern is excellent — theloaderdefault parameter avoidsmock.module('@archon/providers')pollution, exactly matching the codebase's Bun mock isolation constraints.- Non-fatal degradation:
writeHomePiModelConfigfailure is caught, shown to the user, and doesn't abort setup after the env write succeeded. - API keys never logged:
piApiKeycollected viapassword()(masked), written only to.env, never in any log call. - Cancellation paths are thorough — both
selectandpasswordprompts handleisCancelcorrectly. - Bidirectional "keep in sync" notes between
PI_BACKENDSandPI_API_KEY_VARSexplicitly name the other file — better than a generic pointer. continueWithoutPiconfirm defaults totrue— good UX, doesn't block setup on a non-critical check failure.docs-webaddition is accurate — no gap between feature and user-facing docs.
Reviewed by Archon comprehensive-pr-review workflow
Full artifacts: /Users/rasmus/.archon/workspaces/coleam00/Archon/artifacts/runs/3211ffc8ad767223b53d1c80f988d6db/review/
- Add `probeAuthJsonExists` wrapper to doctor.ts so the existsSync call
can be properly spied in tests (ESM named-import rebinding limitation,
consistent with `probeFileExists` pattern in setup.ts)
- Fix `checkPi` false positive: shared keys like ANTHROPIC_API_KEY no
longer count as Pi evidence unless DEFAULT_AI_ASSISTANT=pi; Claude-only
users no longer see a spurious "pass" or "Pi: Configured" status
- Fix `writeHomePiModelConfig` to use `pathsGetArchonHome` from
@archon/paths instead of the local `getArchonHome()`, so Docker
environments (/.archon) are handled correctly
- Replace `includes('pi:')` substring check with `/^\s*pi\s*:/m` regex
to prevent false positives from substrings like `api:`
- Fix `log.warn` → `log.warning` for consistency with rest of setup.ts
- Add `err.code` to the Pi model config write-failure warning message
- Update `checkPiModule` docstring to avoid "mirrors Claude binary check
pattern" phrasing that misled maintainers
- Update `writeHomePiModelConfig` branch-1 docstring from "user-edited"
to "idempotent" to accurately describe the skip condition
- Add `writeHomePiModelConfig` test suite covering all three branches,
quote escaping, and the api:/pi: regex fix
- Update checkPi tests to spy on `probeAuthJsonExists` via doctorModule
instead of fsModule.existsSync; add regression tests for M2 false positive
- Add `# Pi Authentication` section header assertion to mixed Claude+Pi
generateEnvContent test
Fix Report — automated self-review passCommit 33b0c0e7 addresses all HIGH and MEDIUM findings plus actionable LOW items from the review. H1 —
|
🔍 Comprehensive PR ReviewPR: #1609 — feat(cli): add Pi as AI provider option in setup wizard and doctor SummaryThis PR adds Pi as a first-class option in Verdict:
🟡 Medium Issues (Recommended Fixes)1.
|
| Issue | Location | Agent | Suggestion |
|---|---|---|---|
Redundant typeof apiKey === 'string' after isCancel guard |
setup.ts collectPiConfig |
code-review | Simplify to const key = apiKey.trim() — TS narrows to string after guard |
writeHomePiModelConfig catch logs string-only, no structured err |
setup.ts setupCommand catch |
error-handling | Change to log.warning({ err: e }, \Could not write...`)` |
checkExistingConfig missing OAuth-only Pi test |
setup.test.ts |
test-coverage | Add test: DEFAULT_AI_ASSISTANT=pi without API key → hasPi: false; documents detection intent |
writeHomePiModelConfig no test for writeFileSync failure |
setup.ts |
test-coverage | Low priority — caller handles gracefully |
doctorCommand Pi inclusion not verified at command-aggregate level |
doctor.ts:~278 |
test-coverage | Low priority — checkPi follows same CheckResult contract |
generateEnvContent emits # Pi not configured when Pi=false; Codex does not |
setup.ts:1425-1442 |
code-review | Leave as-is — matches Claude pattern, helpful hint |
hasPi false-positive for shared API keys |
setup.ts:408 |
code-review | Addressed by Issue 4 comment |
archon doctor cli.md omits Pi from checklist |
packages/docs-web/src/content/docs/reference/cli.md:89 |
docs-impact | Add "Pi auth (when Pi is configured as default)" to the enumeration |
collectPiConfig TTY path not unit tested |
setup.ts |
test-coverage | Out of scope per established codebase pattern |
✅ What's Good
probeAuthJsonExistsspy-wrapper pattern: Correctly applied to sidestep ESM named-import rebinding. Consistent with the existingprobeFileExistspattern.- YAML corruption guard in
writeHomePiModelConfig: The/^\s*pi\s*:/mregex correctly prevents theapi:false-positive. Explicit test guards this edge case. checkPigating onDEFAULT_AI_ASSISTANT=pi: Correctly avoids false-pass for Claude-only users who haveANTHROPIC_API_KEYset.- Cross-reference comments on
PI_BACKENDS/PI_API_KEY_VARS: Both constants carry explicit cross-reference comments naming the counterpart. Exactly right for drift-prone parallel data structures. - 19 new tests, all real assertions: Tests use actual temp dirs (no
writeFileSyncmocking), exercise real edge cases, and document design decisions inline. - Regression guard test: The "Claude-only user with
ANTHROPIC_API_KEY" test is named and commented — permanent documentation of the M2 design decision. - Type safety: No
anytypes, noeslint-disable, all new functions have explicit return types. selectedProvidersarray built after module-check: Elegantly handles the case wherehasPiis cleared mid-flow when the user selects "Continue without Pi".
📋 Suggested Follow-up Issues
| Issue Title | Priority |
|---|---|
"Wire checkPiModule into doctorCommand for binary health checks" |
P3 |
"Unify hasPi detection between setup re-run and doctor check" |
P3 |
Reviewed by Archon comprehensive-pr-review workflow · 5 specialized agents
Full artifacts: ~/.archon/workspaces/coleam00/Archon/artifacts/runs/e2ed11f61a3f2606d1acccc81e8ee9e8/review/
Fixed: - checkPiModule docstring: remove inaccurate 'doctor-step role' analogy - checkPiModule catch: use instanceof Error guard + structured Pino log - Move checkPiModule tests from doctor.test.ts to setup.test.ts (convention) - hasPi detection: add clarifying comment explaining API-key-only intent - collectPiConfig: remove redundant typeof guard after isCancel narrows to string - writeHomePiModelConfig catch: add structured err field to Pino log - cli.md: add Pi auth to archon doctor checklist description Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fix Report — Review Findings AddressedAll 4 MEDIUM and actionable LOW findings from the code review have been resolved in commit 69dec8c. Fixes Applied
Added a Pino lazy logger ( Validation
|
- Remove `rawValue`/`value` alias in serializeEnv (no transformation) - Remove `skillTarget`/`skillTargetRaw` alias (use raw directly) - Simplify single-provider default selection to use selectedProviders array Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…oleam00#1609) * Add Pi as AI provider option in setup wizard (coleam00#1607) The `archon setup` wizard previously hardcoded `[claude, codex]` in its AI multiselect. Pi is a registered community provider but was unreachable through the wizard, so users had to ctrl-c and hand-edit `~/.archon/.env` plus `~/.archon/config.yaml` to use it. Changes: - Add Pi (community) option to the `collectAIConfig` multiselect, with a per-backend prompt covering 9 LLM backends and an optional API key. - Write the chosen backend API key to `.env` under its canonical name (e.g. `ANTHROPIC_API_KEY`) and the model ref to `~/.archon/config.yaml` under `assistants.pi.model`. Skip the YAML write if `pi:` already exists or show a manual paste-in note when `assistants:` is present without `pi:`. - Add a Pi module-load verification spinner mirroring the Claude binary spawn-test, with a continue/abort prompt on failure. - Extend `archon doctor` with `checkPi` (skip when not configured, pass on auth.json or API key env var, fail when default but no auth). - Update default-assistant selection to handle Pi alongside Claude/Codex. - Mention the wizard path in the Pi docs page. - Tests cover Pi-only, Claude+Pi, no-API-key, `checkExistingConfig` Pi detection, all `checkPi` branches, and `checkPiModule` ok/fail. Fixes coleam00#1607 * fix(cli): address Pi provider review findings in doctor and setup - Add `probeAuthJsonExists` wrapper to doctor.ts so the existsSync call can be properly spied in tests (ESM named-import rebinding limitation, consistent with `probeFileExists` pattern in setup.ts) - Fix `checkPi` false positive: shared keys like ANTHROPIC_API_KEY no longer count as Pi evidence unless DEFAULT_AI_ASSISTANT=pi; Claude-only users no longer see a spurious "pass" or "Pi: Configured" status - Fix `writeHomePiModelConfig` to use `pathsGetArchonHome` from @archon/paths instead of the local `getArchonHome()`, so Docker environments (/.archon) are handled correctly - Replace `includes('pi:')` substring check with `/^\s*pi\s*:/m` regex to prevent false positives from substrings like `api:` - Fix `log.warn` → `log.warning` for consistency with rest of setup.ts - Add `err.code` to the Pi model config write-failure warning message - Update `checkPiModule` docstring to avoid "mirrors Claude binary check pattern" phrasing that misled maintainers - Update `writeHomePiModelConfig` branch-1 docstring from "user-edited" to "idempotent" to accurately describe the skip condition - Add `writeHomePiModelConfig` test suite covering all three branches, quote escaping, and the api:/pi: regex fix - Update checkPi tests to spy on `probeAuthJsonExists` via doctorModule instead of fsModule.existsSync; add regression tests for M2 false positive - Add `# Pi Authentication` section header assertion to mixed Claude+Pi generateEnvContent test * simplify: remove redundant hasApiKey in checkPi * fix: address code review findings for PR coleam00#1609 Fixed: - checkPiModule docstring: remove inaccurate 'doctor-step role' analogy - checkPiModule catch: use instanceof Error guard + structured Pino log - Move checkPiModule tests from doctor.test.ts to setup.test.ts (convention) - hasPi detection: add clarifying comment explaining API-key-only intent - collectPiConfig: remove redundant typeof guard after isCancel narrows to string - writeHomePiModelConfig catch: add structured err field to Pino log - cli.md: add Pi auth to archon doctor checklist description Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * simplify: remove redundant aliases in setup.ts - Remove `rawValue`/`value` alias in serializeEnv (no transformation) - Remove `skillTarget`/`skillTargetRaw` alias (use raw directly) - Simplify single-provider default selection to use selectedProviders array Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Cole Medin <cole@dynamous.ai> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary
archon setuponly offered Claude and Codex in its AI assistant multiselect; Pi (a registered community provider supporting ~20 LLM backends) was unreachable via the wizard.~/.archon/.envand~/.archon/config.yaml, which is error-prone and undiscoverable.archon setup— wizard collects backend choice and optional API key, writes the key to.env, and writes the model ref to~/.archon/config.yaml.archon doctorgained acheckPistep.@archon/providersPi implementation is untouched. No changes to the Pi provider registry, SDK integration, or any other provider's wizard flow.UX Journey
Before
After
Architecture Diagram
Before
After
Connection inventory:
setup.ts::collectAIConfigcollectPiConfigsetup.ts::collectAIConfigcheckPiModulesetup.ts::setupCommandwriteHomePiModelConfigsetup.ts::generateEnvContentdoctor.ts::doctorCommandcheckPiLabel Snapshot
risk: lowsize: Mclicli:setup,cli:doctorChange Metadata
featurecliLinked Issue
Validation Evidence (required)
All 6 checks passed:
check:bundledcheck:bundled-skillbun run type-checkbun run lint --max-warnings 0bun run format:checkbun --filter '*' testCLI test details:
setup.test.ts: 44 pass, 1 skip (pre-existing terminal-spawn skip), 0 fail (+6 new Pi tests)doctor.test.ts: 35 pass, 0 fail (+7 new Pi tests)Evidence provided: Full
bun run validateexit 0 on commitc161443eNo checks skipped
Security Impact (required)
generateEnvContentcan now write a Pi backend API key (e.g.ANTHROPIC_API_KEY=...) to~/.archon/.env. This matches the existing pattern for Claude API keys and Codex tokens; the file is user-owned and local-only.writeHomePiModelConfigwrites to~/.archon/config.yaml. Scope is restricted to the Archon home directory, same as existing config writes.@clack/promptspassword()(masked input), written only to the local.envfile, never logged or transmitted. Theconfig.yamlwrite is append-only and guarded by an existence check to avoid corrupting existing Pi config.Compatibility / Migration
pi: falseis the default for existing configs; no env vars written unless Pi is explicitly selectedANTHROPIC_API_KEY(or other Pi backend key) +~/.archon/config.yamlentry if Pi is selectedHuman Verification (required)
What was personally validated beyond CI:
generateEnvContentPi branches,checkExistingConfigPi detection,checkPiskip/pass/fail,checkPiModuleok/fail)assistants:in config.yaml (shows manual note instead of writing)Side Effects / Blast Radius (required)
packages/clionly (setup.ts,doctor.ts, their tests);packages/docs-web(one paragraph added to Pi docs)pi: falsefield inSetupConfig.aiis required but all callers updatedbun run validatecatches any regression; type-check enforcespi: booleanis always providedRollback Plan (required)
git revert c161443e— single atomic commitarchon setupwould not show Pi option; no other observable changeRisks and Mitigations
Risk:
PI_BACKENDSinsetup.tsandPI_API_KEY_VARSindoctor.tsdrift out of sync when new Pi backends are added.PI_BACKENDStuple shape changes.Risk:
writeHomePiModelConfigcould corrupt~/.archon/config.yamlif it already has anassistants:block with different indentation.assistants:presence and shows a manualnote()callout instead of writing, avoiding any YAML corruption risk. Only writes when the file has noassistants:section at all.Summary by CodeRabbit
New Features
Documentation