Skip to content

Isolate balade's Pi credentials and model preference from a user's own Pi installation #27

Description

@PhilDL

Problem

balade generate currently shares state with a user's own Pi installation:

  • CredentialsModelRuntime.create() uses Pi's default auth store, ~/.pi/agent/auth.json. Logins made through balade land in the user's Pi credential file, and balade reuses logins the user made with the pi CLI.
  • Default model — every explicit or confirmed selection calls setDefaultModelAndProvider, which Pi writes to the global ~/.pi/agent/settings.json. A balade run therefore silently changes the default provider/model of someone's own pi CLI.

The authoring session itself is already isolated (SessionManager.inMemory, SettingsManager.inMemory, no extensions/skills/themes) — this issue is only about the outer account/preference layer in src/generate/pi.ts.

This revisits a recorded trade-off: DECISIONS.md ("Provider/model defaults use Pi's global SettingsManager rather than a second balade preference file"). The decision entry must be updated with the outcome.

What to build

Stop mutating a Pi user's configuration. Decide and implement one of:

  1. Fully separate agent dir — point Pi at a balade-owned directory (SettingsManager.create(cwd, agentDir), ModelRuntime.create({ authPath }); Pi also honors PI_CODING_AGENT_DIR). Cleanest isolation; the cost is that a user already logged into Pi must authenticate again for balade.
  2. Shared auth, own preferences — keep reading/writing ~/.pi/agent/auth.json so existing Pi logins keep working, but store balade's remembered model in a balade-owned settings location instead of Pi's global settings.json. Preserves login reuse; balade never rewrites Pi defaults.

Either way, balade's own state should live in a predictable, documented location.

Acceptance criteria

  • Running balade generate and picking a model never changes the default provider/model of a standalone pi CLI installation.
  • The chosen credential-storage behavior (shared vs. separate) is deliberate, documented in the README, and recorded in DECISIONS.md as the revision of the existing entry.
  • Preference read/write failures remain typed warnings that do not block a generation run.
  • Adapter tests cover the storage seam through injected stores, per the testing rules.

Blocked by

None — can start immediately.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions