fabro/docs/superpowers/plans
Bryan Helmkamp 32f100cbe7
Some checks failed
Rust / Clippy (push) Waiting to run
Rust / Format (push) Waiting to run
Rust / Generated Docs (push) Waiting to run
Rust / Test (Linux) (push) Waiting to run
Rust / Test (macOS) (push) Waiting to run
TypeScript / Typecheck (push) Has been cancelled
TypeScript / Test (push) Has been cancelled
TypeScript / Build (push) Has been cancelled
feat(install): make LLM setup optional in web installer and CLI (#265)
## Summary

Makes LLM setup explicitly skippable in both the web installer and
`fabro install`, without making omission accidental. A skipped LLM step
lets install complete with zero LLM credentials; later LLM-dependent
workflows keep using the existing provider-not-configured behavior.
`fabro doctor` is intentionally unchanged.

Plan: `docs/superpowers/plans/2026-05-14-optional-llm-install.md`

## Key changes

**Server + API**
- `PUT /install/llm` now accepts `{"providers":[]}` as "LLM step
completed, skipped" — the empty-list rejection is removed; per-provider
validation for non-empty lists is retained.
- OpenAPI: dropped `minItems: 1` from
`InstallLlmProvidersInput.providers`, updated schema descriptions so
empty = skipped and `llm: null` = incomplete. TypeScript client
regenerated.
- `/install/finish` still requires the LLM step to be present, but
tolerates zero credentials — it writes settings, runtime auth secrets,
and GitHub secrets normally and writes no LLM vault entries.

**Web installer**
- New "Skip LLM setup" secondary action on the LLM step (via a
`secondaryAction` prop on `StepPanel`) that records an empty provider
list and advances to GitHub.
- Review screen shows `LLM providers: Skipped` (step completed, empty)
vs `Not configured` (step never completed), via a new
`describeLlmSummary` helper.
- Continue with no API keys still shows the existing validation error —
skipping is only reachable through the explicit skip action.

**CLI**
- Interactive `fabro install` asks "Configure LLM providers now?"
(default yes) before provider selection; declining returns an empty
selection and continues to GitHub.
- Hidden non-interactive `--skip-llm` flag, mutually exclusive with
`--llm-provider` / `--llm-api-key-stdin` / `--llm-api-key-env` via clap
`conflicts_with_all`. Missing LLM flags are still validation errors
unless `--skip-llm` is present. Non-interactive usage text updated with
a skip example.

## Code review

Ran a 12-reviewer `ce:review` pass (correctness, testing,
maintainability, project-standards, agent-native, learnings, security,
api-contract, reliability, adversarial, cli-readiness,
kieran-typescript). No P0/P1 findings; agent-native parity PASS. Applied
fixes in `40a29c591`:
- Re-entrancy guard on `runStepSubmit` so a fast double-click on "Skip
LLM setup" can't fire two requests.
- `validate()` only suggests `--skip-llm` in the missing-provider error
when no credential flag is set (it conflicts with those flags).
- Added tests: all three `--skip-llm` conflict arms, the review screen's
"Not configured" branch, and the skip-button failure path.

One advisory finding left as report-only: an empty `PUT /install/llm`
overwrites previously-saved credentials if a user navigates Back and
clicks Skip — judged acceptable since the button is explicitly labeled
and clicking it is deliberate.

## Testing

- `cargo nextest run -p fabro-server -p fabro-cli -p fabro-install` —
1521 passed
- `cargo build -p fabro-api`, `cargo fmt --check`, `cargo clippy`
(changed crates) — clean
- `bun test` (install-app) — 14 passed; `bun run typecheck` — clean
- New coverage: server accepts empty providers + session shows `llm`
complete with `providers:[]`; finish with skipped LLM persists no LLM
vault credentials but keeps GitHub secrets; web skip button PUTs
`providers:[]` and navigates to GitHub; review renders Skipped / Not
configured; CLI `--skip-llm` requires `--non-interactive`, conflicts
with all credential flags, `validate()` succeeds with `--skip-llm`,
usage text documents `--skip-llm`.

Not added (out of plan scope): an automated test for the interactive
`InstallInputSource` skip branch — `InteractiveInstallInputSource` is
TTY-coupled and has no existing tests; the non-interactive `--skip-llm`
path is fully covered.

## Post-Deploy Monitoring & Validation

This change is install-time only; there is no continuous runtime impact.
Validate during the next install/release smoke:

- **Web installer:** run a fresh browser install, click "Skip LLM setup"
on the LLM step, confirm it advances to GitHub and the review screen
reads `LLM providers: Skipped`. Finish the install and confirm the
server restarts into normal mode with no LLM credentials in the vault
(`secrets.json` has no credential entries) and
GitHub/server/object-store/sandbox settings written normally.
- **CLI:** run `fabro install --non-interactive --skip-llm
--github-strategy token --github-username <user>` and confirm it
completes; run interactive `fabro install` and confirm declining
"Configure LLM providers now?" continues to GitHub.
- **Healthy signals:** install completes (web `/install/finish` → 202;
CLI exits 0), server boots in normal mode, `fabro doctor` runs and
reports no LLM providers configured (expected, unchanged behavior).
- **Failure signals / rollback trigger:** install fails to finish,
server fails to boot after a skipped install, or `/install/finish`
rejects a completed-but-empty LLM step. Rollback = revert this PR;
install behavior returns to requiring at least one LLM provider.
- **Validation window/owner:** next install smoke / release
verification, owned by whoever runs the release.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 22:34:39 -04:00
..
2026-04-29-metadata-snapshot-events.md feat(workflow): emit metadata snapshot events 2026-04-29 19:31:13 -04:00
2026-04-30-duplicate-type-unification.md docs(plans): add command output streaming and type unification plans 2026-04-30 08:36:00 -04:00
2026-04-30-preserve-exec-failure-diagnostics.md fix(workflow): preserve exec failure diagnostics 2026-05-01 08:45:50 -04:00
2026-05-02-event-module-split.md refactor(workflow): split event module by responsibility 2026-05-02 14:52:10 -04:00
2026-05-02-server-readiness-timeouts.md fix(cli): bound server readiness probes 2026-05-02 20:13:18 -04:00
2026-05-02-settings-driven-llm-providers-models.md docs(llm): finish configurable provider cleanup (#260) 2026-05-13 17:17:54 -04:00
2026-05-04-cross-tab-sse-coordination.md chore: add plan 2026-05-04 16:09:12 -04:00
2026-05-04-model-test-bounded-concurrency.md chore: update plan 2026-05-04 12:55:19 -04:00
2026-05-04-unique-git-checkpoint-commit-message-path.md chore: add plan 2026-05-04 11:12:40 -04:00
2026-05-05-clean-pierre-virtualizer-integration.md chore: plan 2026-05-06 07:15:18 -04:00
2026-05-05-decouple-interrupts-from-steering.md Wire end-to-end steering for running agents (#209) 2026-05-05 15:34:16 -04:00
2026-05-06-cli-input-overrides.md feat(cli): support sparse input overrides (#222) 2026-05-09 10:00:35 -04:00
2026-05-06-improve-cli-api-error-display.md fix(cli): preserve API error details 2026-05-06 14:03:12 -04:00
2026-05-06-polished-foreground-tty-logging.md feat(cli): polish foreground TTY logs 2026-05-06 15:31:25 -04:00
2026-05-08-generated-typescript-api-client-migration.md feat(web): migrate to generated API client 2026-05-08 07:44:33 -07:00
2026-05-08-run-owned-sandbox-lifecycle.md chore: plan run-owned sandbox lifecycle 2026-05-08 14:45:56 -07:00
2026-05-09-daytona-run-terminal.md chore: plan 2026-05-09 19:02:03 -04:00
2026-05-09-fixed-project-workflow-directory.md fix(workflow): ignore deprecated project directory 2026-05-09 10:55:56 -04:00
2026-05-09-inline-markdown-run-titles.md chore: plans 2026-05-08 18:59:49 -07:00
2026-05-09-live-stage-token-projection.md feat(billing): project live stage token usage 2026-05-09 15:25:51 -04:00
2026-05-09-remove-local-worktree-mode.md refactor(workflow): remove local worktree mode 2026-05-09 11:04:23 -04:00
2026-05-09-run-files-diff-scope-picker.md feat(run-files): add sandbox diff scopes 2026-05-09 13:00:14 -04:00
2026-05-10-auth-sessions-backend.md feat(auth): add unified session API 2026-05-10 14:16:23 -04:00
2026-05-10-auth-sessions-frontend.md chore: plans 2026-05-10 23:40:02 -04:00
2026-05-10-live-events-page.md feat(web): build live events page in settings 2026-05-10 14:05:10 -04:00
2026-05-10-sandbox-services-backend.md feat(server): list sandbox services 2026-05-10 11:24:39 -04:00
2026-05-10-sandbox-services-frontend.md feat(web): add Services tab to sandbox page 2026-05-10 11:56:05 -04:00
2026-05-11-automations-end-to-end.md chore: plans 2026-05-10 23:40:02 -04:00
2026-05-13-path-based-daytona-dockerfiles.md feat(manifest): support path-based Daytona Dockerfiles (#258) 2026-05-13 12:32:15 -04:00
2026-05-13-sandbox-repo-layout-plan.md feat(sandbox): prepare clone layout for multi-repo runs (#250) 2026-05-14 09:38:20 -04:00
2026-05-14-optional-llm-install.md feat(install): make LLM setup optional in web installer and CLI (#265) 2026-05-14 22:34:39 -04:00