# WrongStack — Refactoring & Improvement Plan

**Generated:** 2026-06-05
**Scope:** Full monorepo — 14 packages, ~110K SLOC source
**Previous audit:** 2026-05-30 (docs/notes/refactor.md)
**Status:** Active — decomposing overgrown modules

---

## Executive Summary

The codebase has grown **significantly** in the past 6 days (May 30 → June 5):

| Metric | May 30 | June 5 | Delta |
|--------|--------|--------|-------|
| Files >1000 lines | 3 | **14** | +367% |
| Files >300 lines | 23 | **185** | +704% |
| Critical bugs | 0 ✅ | 0 ✅ | — |
| Security issues open | 0 ✅ | 0 ✅ | — |

**The good news:** All 5 critical bugs, 6 security issues, and 5 medium issues from the May 30 audit are resolved. Architecture boundary tests pass 12/12.

**The bad news:** Several core files are growing at alarming rates (+64% in one week for some). The new `tui/src/app.tsx` at **6,408 lines** is the largest single file in the project and was not tracked in the previous audit.

---

## Priority Execution Order

```
Phase 1 — Split the Big Three (tui/app.tsx, cli/sdd.ts, cli/index.ts)
Phase 2 — Split coordinator layer (director.ts, multi-agent-coordinator.ts, multi-agent.ts)
Phase 3 — Split webui layer (server/index.ts, useWebSocket.ts, stores/index.ts)
Phase 4 — Split UI components (history.tsx, MessageBubble.tsx, SettingsPanel.tsx, etc.)
Phase 5 — Medium-priority cleanups + test coverage
```

---

## Phase 1 — Critical: Split the Three Largest Files

### 1.1 `packages/tui/src/app.tsx` — 6,408 lines 🔥

**Current state:** A React component (`App`) at 4,409 lines with a 1,020-line reducer, plus types, state, and helpers. Already imports sub-components from `./components/` but the App itself contains all orchestration logic: event subscriptions, keyboard handling, paste handling, file search, queue management, history rendering, autonomy mode UI, and SDD integration.

**Decomposition plan:**

```
packages/tui/src/
  app.tsx                       →  thin: <App> shell (props → children, ~200 lines)
  app-reducer.ts                →  extracted from app.tsx (~1,020 lines)
  app-state.ts                  →  State, Action, FleetEntry, SlashCommandMatch types (~300 lines)
  hooks/
    use-event-subscriptions.ts  →  FleetBus, iteration, stage, autophase subscriptions
    use-keyboard-handling.ts    →  all keyboard event handling
    use-paste-handling.ts       →  paste buffering + clipboard image
    use-queue-manager.ts        →  /queue command + queue state
    use-file-search.ts          →  Ctrl+O file picker
    use-autonomy-ui.ts          →  autonomy mode picker + settings
    use-sdd-integration.ts      →  SDD context injection + output detection
```

**Risk:** High (touches the single largest component). Must preserve all existing behavior — exhaustive manual testing required.

### 1.2 `packages/cli/src/slash-commands/sdd.ts` — 1,809 lines 🔥

**Current state:** Single file with `buildSddCommand()` (1,096 lines) plus ~20 helper functions for spec detection, task management, rendering, and project context gathering.

**Decomposition plan:**

```
packages/cli/src/slash-commands/
  sdd.ts              →  thin: re-exports from sub-modules (~50 lines)
  sdd/
    index.ts          →  buildSddCommand() — just wiring, ~80 lines
    spec-detection.ts →  trySaveSpecFromAIOutput, isExplanatoryText, autoDetectTaskCompletion (~200 lines)
    task-manager.ts   →  trySaveTasksFromAIOutput, markTaskCompleted, advanceToNextTask,
                         getCurrentTask, getCurrentExecutingContext (~250 lines)
    project-context.ts → gatherProjectContext, findSpec, getActiveBuilder (~100 lines)
    rendering.ts      →  renderTaskListWithProgress, renderTaskGraph (wraps core), sddHelp,
                         formatElapsed, renderProgress (~300 lines)
    state.ts          →  SDDState class, getSessionState (~80 lines)
```

**Risk:** Medium. Helpers are already well-separated functions — mostly moving code between files.

### 1.3 `packages/cli/src/index.ts` — 1,786 lines 🔥

**Current state:** `main()` at 1,696 lines. Handles: subcommand dispatch, REPL setup, TUI launch, WebUI launch, autophase, eternal autonomy, config management, model selection, and session initialization.

**Decomposition plan:**

```
packages/cli/src/
  index.ts                →  thin: parse argv → dispatch (~100 lines)
  cli-main.ts             →  main() extracted, ~400 lines
  wiring/
    dispatcher.ts         →  subcommand routing (init, auth, mcp, plugin, export, update, etc.)
    session-init.ts       →  session creation or resume logic
    agent-init.ts         →  Agent construction with all wiring
    repl-launcher.ts      →  REPL vs TUI vs WebUI decision
    eternal-launcher.ts   →  eternal/autophase mode boot
```

**Risk:** High. `main()` is the CLI entry point. Must test all subcommand paths, both TTY and non-TTY, and both REPL and WebUI modes.

---

## Phase 2 — Split Coordinator Layer

### 2.1 `packages/core/src/coordination/director.ts` — 1,743 lines 🔥

**Current state:** `Director` class at 1,405 lines. Grew 64% in one week (1,067 → 1,743). Already has `director-tools.ts` (547 lines) and `director-prompts.ts` extracted. The Director class handles: spawn, assign, awaitTasks, terminate, status, usage, collab debug sessions, checkpoint persistence, fleet manifest writing, subagent nickname generation, model matrix resolution, and budget enforcement.

**Decomposition plan:**

```
packages/core/src/coordination/
  director.ts              →  thin orchestrator (~300 lines)
  director/
    spawn-pipeline.ts      →  spawn() with validation, budget check, nickname, runner
    task-management.ts     →  assign(), awaitTasks() with timeout + result collection
    fleet-state.ts         →  status(), usage(), FleetUsageAggregator integration
    collab-sessions.ts     →  collabDebug(), collabBus — already in collab-debug.ts but
                              the Director wraps it; extract the wrapper
    checkpoint.ts          →  saveCheckpoint(), loadCheckpoint(), fleet.json manifest
    shorthands.ts          →  terminateAll(), workComplete() shorthands
```

**Risk:** Medium. The class is well-documented (37% comment ratio). The split is mostly extracting private methods into helper modules.

### 2.2 `packages/core/src/coordination/multi-agent-coordinator.ts` — 1,098 lines

**Current state:** `DefaultMultiAgentCoordinator` at 921 lines. Grew 64% (669 → 1,098).

**Decomposition plan:**

```
packages/core/src/coordination/
  multi-agent-coordinator.ts  → thin, ~200 lines
  coordinator/
    subagent-lifecycle.ts     → spawn, stop, health monitoring, AbortController recycling
    task-queue.ts             → enqueue, dequeue, concurrency control, priority
    budget-enforcement.ts     → SubagentBudget validation, auto-extend, exceeded errors
    error-classifier.ts       → classifySubagentError, providerErrorToSubagentError
```

**Risk:** Low-Medium. Clear separation of concerns already visible in the code.

### 2.3 `packages/cli/src/multi-agent.ts` — 1,033 lines

**Current state:** `MultiAgentHost` class at 832 lines. Grew 44% (717 → 1,033).

**Decomposition plan:**

```
packages/cli/src/
  multi-agent.ts          → thin, ~150 lines
  fleet/
    host.ts               → MultiAgentHost class — fleet lifecycle
    ui.ts                  → status line rendering, task formatting
    routing.ts             → buildRoutingRunner — model routing logic
```

**Risk:** Low. Host and UI concerns are mostly separable.

---

## Phase 3 — Split WebUI Layer

### 3.1 `packages/webui/src/server/index.ts` — 1,961 lines

**Current state:** `startWebUI()` at 1,824 lines. Already has several sub-modules extracted (http-server.ts, ws-auth.ts, autophase-ws-handler.ts, collaboration-ws-handler.ts, worktree-ws-handler.ts, lifecycle.ts, port-utils.ts, boot.ts). But the main startWebUI still handles: WebSocket message routing, API handlers (config, session, providers, models, context, files, prompts), SSE streaming, static file serving, and tool execution coordination.

**Decomposition plan:**

```
packages/webui/src/server/
  index.ts                  → thin bootstrap, ~150 lines
  server/
    ws-message-router.ts    → WebSocket message dispatch to handlers
    api/
      config-api.ts         → config get/set, providers CRUD, keys management
      session-api.ts        → session list/get/resume/delete, session reader integration
      context-api.ts        → context mode switch, repair, compact, prune, summary
      file-api.ts           → file read/write/list, path traversal guards
      prompt-api.ts         → prompt list/get/set/delete
      model-api.ts          → model switch, provider list, cost rates
      usage-api.ts          → usage cost computation
    sse-coordinator.ts      → SSE streaming manager
    tool-coordinator.ts     → tool execution + permission flow over WS
```

**Risk:** Medium-High. The startWebUI function touches every WebUI feature. Must test every API endpoint and WS message type.

### 3.2 `packages/webui/src/hooks/useWebSocket.ts` — 1,040 lines

**Current state:** `installHandlers` at 784 lines + `useWebSocket` at 178 lines.

**Decomposition plan:**

```
packages/webui/src/hooks/
  useWebSocket.ts            → thin, ~100 lines (connection lifecycle only)
  ws-handlers/
    auth-handlers.ts         → auth challenge/response, token refresh
    session-handlers.ts      → session.start, session.resume, session.list
    agent-handlers.ts        → agent response, text delta, tool calls
    config-handlers.ts       → config update, provider sync
    fleet-handlers.ts        → fleet status, subagent events
    collab-handlers.ts       → collaboration events
```

**Risk:** Medium. Handlers are isolated per message type — the split is natural.

### 3.3 `packages/webui/src/stores/index.ts` — 928 lines

**Current state:** 7 stores mixed in one file. Already separate functions — just need file splits.

**Decomposition plan:**

```
packages/webui/src/stores/
  index.ts              → barrel re-exports
  chat-store.ts         → useChatStore, ChatState, ChatMessage
  session-store.ts      → useSessionStore, SessionState
  ui-store.ts           → useUIStore, UIState
  fleet-store.ts        → useFleetStore
  config-store.ts       → useConfigStore, ConfigState
```

**Risk:** Very low. Pure file split — no logic changes.

---

## Phase 4 — Split UI Components

### 4.1 `packages/tui/src/components/history.tsx` — 1,632 lines

Split into:
- `history/index.tsx` — History, HistoryEntry types
- `history/banner.tsx` — Banner component
- `history/code-block.tsx` — CodeBlock, DiffBlock
- `history/tool-output.tsx` — formatToolOutput, formatToolArgs, summarizeJsonObject, ToolStreamBox
- `history/entry.tsx` — Entry component

### 4.2 `packages/webui/src/components/MessageBubble.tsx` — 922 lines

Split into:
- `MessageBubble/index.tsx` — main component
- `MessageBubble/ToolInputView.tsx`
- `MessageBubble/CopyButton.tsx`
- `MessageBubble/ErrorBody.tsx`
- `MessageBubble/utils.ts` — copyToClipboard, downloadTextFile, detectStackBoundary, fileExtensionFor

### 4.3 `packages/webui/src/components/SettingsPanel.tsx` — 886 lines

Split into:
- `SettingsPanel/index.tsx` — main component
- `SettingsPanel/PreferenceToggle.tsx`
- `SettingsPanel/ProviderSection.tsx`
- `SettingsPanel/ModelSection.tsx`

### 4.4 `packages/webui/src/components/ChatInput.tsx` — 874 lines

Split into:
- `ChatInput/index.tsx` — main component
- `ChatInput/slash-commands.ts` — SlashCommandDef, matchSlash
- `ChatInput/mention-detection.ts` — detectAtMention

### 4.5 `packages/webui/src/components/Sidebar.tsx` — 744 lines

Split into:
- `Sidebar/index.tsx` — main component
- `Sidebar/SessionList.tsx`
- `Sidebar/SessionActions.tsx`
- `Sidebar/ConfigSection.tsx`

### 4.6 `packages/webui/src/components/ChatView.tsx` — 710 lines

Split into:
- `ChatView/index.tsx` — main component
- `ChatView/ThinkingBubble.tsx`
- `ChatView/utils.ts` — fmtTok

### 4.7 `packages/webui/src/components/CommandPalette.tsx` — 591 lines

Split into:
- `CommandPalette/index.tsx` — main component
- `CommandPalette/export-utils.ts` — downloadChatAsHtml, downloadChatAsMarkdown

---

## Phase 5 — Medium Priority

### 5.1 ACP Integration — Incomplete

**File:** `packages/acp/src/agent/wrongstack-acp-agent.ts`

```typescript
/* TODO: load WrongStack Context */ {},
```

The ACP agent is stubbed. Either complete it or add to the roadmap with an ETA.

### 5.2 pnpm Not in PATH

The system `pnpm` is not globally available. Some tools (`outdated`, `audit`, `typecheck`) fail with `spawn pnpm ENOENT`. Fix with `corepack enable pnpm` or ensure `pnpm` is in the CI/PATH.

### 5.3 Test Coverage

| Package | Coverage | Target |
|---------|----------|--------|
| `webui` | **0%** | 60% |
| `cli` | **21%** | 60% |
| `plug-lsp` | 27% | 50% |
| `core` | 40% | 70% |
| `providers` | 43% | 65% |
| `mcp` | 45% | 65% |
| `tools` | 50% | 65% |
| `tui` | 71% | 75% |

Priority: webui and cli. The file splits in Phases 1-4 will make these packages more testable by isolating concerns into smaller, mockable units.

### 5.4 Architecture — Internal Layering Healthy

The dependency direction check found no cross-package violations. All 12 architecture boundary tests pass. The internal core layering (kernel → infrastructure → domain → execution → storage → coordination → UI) is well-maintained. The only "upward deps" detected are subpath imports within `@wrongstack/core` (e.g., `@wrongstack/core/security`, `@wrongstack/core/execution`) which are the documented intended API surface.

The `aepp.tsx` (6,408L) and `sdd.ts` (1,809L) files represent the biggest architecture concern — they concentrate too much responsibility in single files.

### 5.5 Already Completed (from May 30 audit)

**Critical Bugs:** C1-C5 ✅ All fixed
**Security:** S1-S6 ✅ All fixed (S3 HttpOnly cookie, S4 CSP, S6 prototype pollution)
**Medium:** M1-M5 ✅ All fixed (MCP close race, session TOCTOU, auto-permission, type coercion, recovery lock)
**Low:** L1-L15 ✅ All fixed or acknowledged

---

## Estimated Effort

| Phase | Items | Est. Days | Risk |
|-------|-------|-----------|------|
| 1 — Big Three | app.tsx, sdd.ts, cli/index.ts | 3-4 days | High |
| 2 — Coordinator | director, multi-agent-coordinator, multi-agent | 2 days | Medium |
| 3 — WebUI Layer | server/index, useWebSocket, stores | 2 days | Medium |
| 4 — UI Components | history, MessageBubble, SettingsPanel, etc. | 2 days | Low |
| 5 — Cleanup | ACP, pnpm, tests | 2-3 days | Low |
| **Total** | | **11-13 days** | |

---

## Notes

- Each phase is independent and can be parallelized across developers
- Within each phase, split one file at a time and run the full test suite
- The tui/app.tsx split is the highest risk — consider doing it as the very first item with extra QA
- After Phase 1, update the `docs/notes/refactor.md` baseline for the next audit cycle

---

*Last updated: 2026-06-05*
