PostHog / PostHog/wizard

refactor: move settings-conflict orchestration out of the runner into a pure planner

Open
#756 0 comments 0 reactions 0 assignees View on GitHub

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 the source === 'managed' ? 'org' : source ternary),
  • logToFile narration,
  • the backupAndFixClaudeSettings call + 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: extend classifySettingsConflicts (or add planConflictResolution(conflicts) → { backup, warn, block }) — pure, no UI, trivially unit-testable.
  • bootstrap.ts keeps the imperative shell: the backupAndFixClaudeSettings call, the getUI().showSettingsOverride call, 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-backup tests pass unchanged.
  • Planner is pure (no getUI, no fs side-effects) and unit-tested.
  • claude-settings.ts gains no UI/agent-stack imports.
  • bootstrap.ts conflict 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-backup magic string,
  • share the CLAUDE_CONFIG_DIR || ~/.claude resolution (duplicated in stored-login.ts + agent-interface.ts).

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.