refactor: move settings-conflict orchestration out of the runner into a pure planner
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 197
- Forks
- 51
- Avg merge
- 1d 23h
- Merged PRs (30d)
- 94
Description
Summary
Extract the settings-conflict orchestration out of the runner (bootstrap.ts) into a pure, testable planner, leaving bootstrap a thin imperative shell. Behavior-preserving refactor — no functional change.
Spun out of #744 (agent credential isolation), where the conflict-resolution logic landed.
Problem
src/lib/agent/runner/shared/bootstrap.ts (~lines 150–210, ~60 lines) currently mixes, inline in the runner:
- classification of detected conflicts,
- three near-identical
analytics.wizardCapture('settings conflict …', { level, keys })calls (each repeating thesource === 'managed' ? 'org' : sourceternary), logToFilenarration,- the
backupAndFixClaudeSettingscall + the "backup failed → fall back to fail-closed" re-assignment, - the
getUI().showSettingsOverride(...)call.
The repo's own wizard-development skill names "the runner is getting longer" as a design smell, and says infra concerns should route to the narrowest surface. This block is the most tiring part of the credential path to read.
Constraint (important)
src/lib/agent/claude-settings.ts is intentionally UI-free and dependency-light — its header documents that it lives apart from the agent stack so bin.ts can run orphan recovery at process start without pulling in getUI()/the SDK. Do not move the UI/analytics calls into it.
Proposed approach — split decision from I/O
- Pure planner in
claude-settings.ts: extendclassifySettingsConflicts(or addplanConflictResolution(conflicts) → { backup, warn, block }) — pure, no UI, trivially unit-testable. bootstrap.tskeeps the imperative shell: thebackupAndFixClaudeSettingscall, thegetUI().showSettingsOverridecall, analytics — but collapse the repeated capture into one local helper, e.g.const report = (event: string, c: SettingsConflict) => analytics.wizardCapture(event, { level: c.source === 'managed' ? 'org' : c.source, keys: c.keys });
Acceptance criteria
- No behavior change; existing
settings-conflicts+claude-settings-backuptests pass unchanged. - Planner is pure (no
getUI, no fs side-effects) and unit-tested. -
claude-settings.tsgains no UI/agent-stack imports. -
bootstrap.tsconflict block is materially shorter and reads as "classify → act".
Out of scope (separate, optional)
Adjacent cleanups identified in the same review, not blocking this:
- delete dead
@deprecated checkClaudeSettingsOverrides(no callers), - dedupe the 3×
['settings.json','settings']backup/restore/recover loop +.wizard-backupmagic string, - share the
CLAUDE_CONFIG_DIR || ~/.clauderesolution (duplicated instored-login.ts+agent-interface.ts).
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with src/lib/agent/runner/shared/bootstrap.ts around lines 150–210 and src/lib/agent/claude-settings.ts, then read the existing settings-conflicts and claude-settings-backup tests. Extract the conflict decision into a pure planner while keeping UI, analytics, backup, and filesystem work in bootstrap.ts. Done means the conflict block is shorter, the planner is unit-tested and UI-free, and the existing tests pass unchanged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- tooling
- Issue type
- Refactor
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100