Hmbown / Hmbown/Codewhale

EPIC-005: CodeWhale TUI Crate Decomposition (Umbrella)

Open
#5,316 29 comments 1 reaction 0 assignees View on GitHub
Dominant language
Rust
Stars
41k
Forks
3.6k
Avg merge
13h 59m
Merged PRs (30d)
299

Description

## Current Core execution — September 9, 2026

Follow the [Codewhale Core execution plan]() for C03–C10, ownership, dependency order and completion evidence. Linear is the current execution authority; local checklists are supporting snapshots.

C03 is active with the existing Kimi worker. Local commits 2be4359f5 migrate AppMode/ApprovalMode consumers and durable context records; 798d3d664 moves worker roster records; 76f8d0044 moves reasoning preferences and removes the UI re-export. The last commit records 229 passing reasoning tests and a warning-free all-target cargo check. Final C03 boundary/approval-policy reconciliation remains open; C04–C10 are not complete.

Preserve the contributor provenance below and credit merged command-contract Stage A and Stage B FEAT-018 through FEAT-024. Current direction supersedes older fleet-stays-in-TUI, engine-last, mandatory staged-shim and fixed-size assumptions. Converge parent/child execution before extracting one runtime; migrate every consumer and measure the headless build boundary. C06 gives the model discretion over useful goals and supported effort, with runtime-owned limits and receipts. Do not impose explicit-goal-request-only semantics.

The whole extraction is active project scope; C20 separately decides which source is required for 0.9.13. These local commits do not establish hosted CI, installed acceptance or publication.

---

## Original umbrella and delivery history

## EPIC-005: CodeWhale TUI Crate Decomposition — Umbrella EPIC

This issue is the **EpicStyle tracking issue** for the CodeWhale TUI crate decomposition. It represents the entire structure below: every sub-EPIC and every FEAT reports here when done, and every PR created under this work is logged here.

The decomposition is the direct answer to the compilation-time discussion in [#4991]() — see the Developer fast loop section below.

## Structure

EPIC-005 is the **umbrella EPIC**. It does not contain FEATs directly — it holds the map of **sub-EPICs**, each of which contains its own FEATs.

```mermaid
flowchart TD
U["EPIC-005: TUI Crate Decomposition (umbrella)"]
U --> E6["EPIC-006: Commands -> codewhale-commands (P1)"]
U --> E7["EPIC-007: Tools consolidation -> crates/tools (P1)"]
U --> E8["EPIC-008: Config consolidation -> crates/config (P2)"]
U --> E9["EPIC-009: Hooks + Execpolicy + MCP (P2)"]
U --> E10["EPIC-010: Core extraction -> crates/core (P3)"]
```

| ID | Sub-EPIC | Scope | Status |
| -- | -- | -- | -- |
| EPIC-006 | Commands → `codewhale-commands` | `crates/tui/src/commands/` (\~42k lines incl. tests; 9 groups, registry, discovery) | IN PROGRESS — Stage A complete (2/2); first seven Stage B group/slice migrations merged (7/18). All nine merged delivery FEATs (FEAT-014/015/018–024) are verified in current `origin/main` (`3f3aa9ed7`). FEAT-024 merged through [#5951]() as `a58e96d40`; FEAT-025 is next. |
| EPIC-007 | Tools consolidation | `crates/tui/src/tools/` (\~117k lines) → `crates/tools` (currently 1.3k) | NotStarted |
| EPIC-008 | Config consolidation | `crates/tui/src/config/` (\~13k lines) → `crates/config` (currently 33k) | NotStarted |
| EPIC-009 | Hooks + Execpolicy + MCP | `hooks/` (7k), `execpolicy/` (0.5k), `mcp/` (8k) → `crates/hooks`, `crates/execpolicy`, `crates/mcp` | NotStarted |
| EPIC-010 | Core extraction | `crates/tui/src/core/` (\~42k lines) → `crates/core` (currently 3.4k); tightly coupled, P3 follow-up | NotStarted |

Stays in `codewhale-tui`: `tui/` rendering (\~205k lines), `fleet/` (\~27k lines), and the TUI-specific long tail.

## Rules (applied to every sub-EPIC)

1. Behavior-preserving — extraction only, no command/UX behavior changes.
2. Trait-first — define the boundary interface before moving code (pattern: EPIC-006 `CommandContext`).
3. Compiles at every step — bottom-up extraction, workspace stays green at each commit.
4. CI gate — extracted crate must never depend on `codewhale-tui` (e.g. `cargo check -p codewhale-commands` pulls no TUI).
5. Fork-local until complete — rebase onto upstream main frequently; no upstream PR until the sub-EPIC is done.
6. Sequencing — EPIC-006 first, then 007/008, then 009, then 010.

## Work summary (to be done)

Estimated FEATs under each EPIC. Check a FEAT off and append its PR link when the PR lands; parent EPICs auto-complete when all their FEATs are done. This section is the visual tracker — the Features Breakdown tables in the MemoryBank EPIC documents are the static FEAT-creation source and are not updated per PR.

- [ ] EPIC-006: Commands extraction — staged, **one FEAT = one independently green PR**
- [X] **Stage A — shapes + infrastructure (COMPLETE 2026-08-19)**
- [X] FEAT-014: Prototype command capability/handler/registration shapes only — **merged** in [#5328]() (2026-08-13, merge commit `3b41d0ee`); no TUI production rewiring
- [X] FEAT-015: Add TUI adapters, dual-path dispatch seam, and shrinking migration gate; convert no group — **merged** in [#5506]() (2026-08-19, merge commit `ae56154c`); complete required check matrix green
- [ ] **Stage B — adopt shapes inside TUI (files do not move)**
* **Least-capability invariant:** every contextual registration declares its exact minimum external facet set; the TUI exposes only those facets; pure handlers construct no host bundle; missing required facets fail safely. FEAT-019 through FEAT-035 inherit this pattern, and FEAT-035 enforces it repository-wide.

> [!NOTE]
> **Current-main verification (2026-09-07): all completed delivery FEATs are present.** PR merge commits for FEAT-014, FEAT-015, and FEAT-018 through FEAT-024 are ancestors of current `origin/main` (`3f3aa9ed7`). FEAT-024 landed through [#5951]() (`a58e96d40`) after owner feedback was addressed in final contributor head `d4b68963d`; the complete GitHub and Buildkite matrix was green on that exact head before merge. The migration frontier remains `config`, `core`, `debug`, and `session` because FEAT-025 and FEAT-026 still own the remaining session slices.
>
> **EPIC-006 current state:** Stage A is complete (2/2); Stage B has 7/18 FEATs merged; 9/33 EPIC-006 FEATs are merged overall; FEAT-025 (session export) is implementation-complete with PR [#6096]() **ready for review with all checks green**; FEAT-026 (session structcopy) is the next milestone and must begin by widening `CommandCapabilities` to `u32`.
- [X] **FEAT-018: Utility group** — **shipped** in [#5525]() via v0.9.11 (2026-08-23); complete utility group adopted external command shapes in place
- [X] FEAT-019: Memory group — merged to `main` via maintainer re-land [#5833]() (`ad813cda6`) after review fixes/current-main reconciliation through [#5839](); original [#5609]() retained as harvested provenance
- [X] FEAT-020: Plugins group — **merged into** `main` via current-main re-land [#5865]() (2026-09-05, `dcd4c200f`), preserving original [#5657]() authored history, reconciling FEAT-019/021/022 plus current plugin/marketplace behavior, and restoring three current-main CI blockers with a fully green final matrix
- [X] FEAT-021: Project group — **merged into** `main` in [#5717]() (2026-08-30, merge commit `2f200ee`) — first Stage B FEAT to land directly on `main`; exact least-authority facets (`/init`=workspace, `/lsp` and `/share`=project, `/goal`=project+presentation). Subsequent FEAT-019/020/022 reconciliation preserves these declarations; current frontier has four groups
- [X] FEAT-022: Skills group — **merged into** `main` via maintainer replacement [#5829]() (2026-09-02, `84b3dd694`); contributor PR [#5825]() closed as superseded after its work was harvested and co-author credited
- [X] FEAT-023: Session lifecycle leaves — **merged into** `main` in [#5902]() (2026-09-06, merge commit `41fecf8a4`); nine handlers migrated with a dedicated least-authority facet, `/compact` and `/purge` remain pure, concrete lifecycle machinery remains TUI-owned, and TUI-only acceptance/regression tests stay outside the movable group; final maintainer nit kept `CommandCapabilities` at `u16` with bit 13 assigned to `SESSION_LIFECYCLE`
- [X] FEAT-024: Session control / remote paths — **merged into** `main` in [#5951]() (2026-09-06, merge commit `a58e96d40`); six handlers use `CommandSessionControlContext` with exact least-authority declarations; owner feedback was addressed in `d4b68963d`, and the complete GitHub/Buildkite matrix was green before merge
- [ ] FEAT-025: Session export — **ready for review** in [#6096]() (`54d9261d8`), all checks green. `/export` and `/daochu` adopt `CommandSessionExportContext` with exact `SESSION_EXPORT` authority; concrete metadata, snapshot, clipboard, filesystem and turn-handoff access stays TUI-owned behind the adapter; four baseline-captured goldens prove byte-identical output; and the portable slice was compiled and its 21 tests run outside the TUI with no `codewhale-tui` in the dependency graph. It also consumes the last free `u16` capability bit, so FEAT-026 must widen the backing storage to `u32` before adding its own facet. Root `session` frontier remains pending for FEAT-026.
- [ ] FEAT-026: Session structcopy
- [ ] FEAT-027: Config policy/status
- [ ] FEAT-028: Main config module
- [ ] FEAT-029: Debug diagnostics
- [ ] FEAT-030: Debug mutation paths
- [ ] FEAT-031: Core navigation/display leaves
- [ ] FEAT-032: Core model/provider/setup
- [ ] FEAT-033: Core coordination/workflow
- [ ] FEAT-034: Remaining core policy/interaction
- [ ] FEAT-035: Registry/discovery completion + enforce zero direct concrete-`App` handlers
- [ ] **Stage C — focused prerequisites after in-place decoupling**
- [ ] FEAT-036: Extract localization behind the existing compatibility path
- [ ] FEAT-037: Move only shared command outcome/action data proven necessary
- [ ] **Stage D — bootstrap then move one already-decoupled group per PR**
- [ ] FEAT-016: Bootstrap `codewhale-commands` + shared registry/discovery boundary; move no group
- [ ] FEAT-038: Move utility
- [ ] FEAT-039: Move memory
- [ ] FEAT-040: Move plugins
- [ ] FEAT-041: Move project
- [ ] FEAT-042: Move skills
- [ ] FEAT-043: Move session
- [ ] FEAT-044: Move config
- [ ] FEAT-045: Move debug
- [ ] FEAT-046: Move core
- [ ] **Stage E — final validation**
- [ ] FEAT-017: Acceptance-test boundary, compatibility-shim removal, and EPIC validation
- [ ] EPIC-007: Tools consolidation
- [ ] FEAT: Audit `tools/` vs `crates/tools` and define the shared boundary
- [ ] FEAT: Move shared tool code into `crates/tools`
- [ ] FEAT: Wire TUI to the consolidated crate; keep tool UI code in TUI
- [ ] FEAT: Tests, CI gate, and re-export shim
- [ ] EPIC-008: Config consolidation
- [ ] FEAT: Audit TUI `config/` vs `crates/config` (overlap, extensions, UI views)
- [ ] FEAT: Extract non-UI config logic to `crates/config` (or adopt it)
- [ ] FEAT: Wire TUI to `codewhale-config`; keep UI views in TUI
- [ ] FEAT: Tests, CI gate, and re-export shim
- [ ] EPIC-009: Hooks/Execpolicy/MCP consolidation
- [ ] FEAT: Consolidate `hooks/` with `crates/hooks`
- [ ] FEAT: Consolidate `execpolicy/` with `crates/execpolicy`
- [ ] FEAT: Consolidate `mcp/` with `crates/mcp`
- [ ] FEAT: Tests, CI gates, and cleanup
- [ ] EPIC-010: Core extraction (follow-up)
- [ ] FEAT: Core audit and coupling map (36 files, \~42k lines)
- [ ] FEAT: Extract decoupled core leaves to `crates/core` (phase 1)
- [ ] FEAT: Extract remaining core logic (phase 2, after boundary interfaces)
- [ ] FEAT: Wire TUI to `codewhale-core`; tests and CI gate
- [ ] Final: codewhale-tui reduced from \~700k to \~300k lines focused on UI rendering

## Developer fast loop

The whole point of this decomposition: once a sub-EPIC's crate exists (EPIC-006 Feature 3 and later), day-to-day development happens **entirely outside the TUI monolith** (\~700k lines). The TUI is only compiled when you explicitly need it — TUI integration tests, `cargo test --workspace`, or the final pre-PR validation.

```bash
cargo check -p codewhale-commands # production change check — seconds, not minutes
cargo test -p codewhale-commands # test loop — compiles only the commands crate + thin test binaries, never the TUI
cargo watch -x "check -p codewhale-commands" # continuous check while editing (cargo-watch)
cargo nextest run -p codewhale-commands # optional: parallel test runner, faster startup
```

Why this stays fast:

* `cargo build` / `cargo check` never compiles `#[cfg(test)]` code, so production iteration is bounded to the small crate.
* `cargo test` compiles each `tests/` file as its **own small binary crate** depending only on the public API — a production change recompiles/relinks only those thin binaries, in parallel.
* The Gherkin acceptance harnesses live in separate test binaries (or a dedicated acceptance crate), so thousands of acceptance-test lines are **never part of the production crate compile**.
* Small white-box unit tests that need private access stay inline — they are cheap and cannot live outside the crate.

**Acceptance criterion for every extracted crate:** `cargo test -p ` must compile only that crate and its test binaries — if it pulls in `codewhale-tui`, the boundary was cut wrong.

The numbers and impact motivating this are documented in [#4991]() (Discussion: Compilation times and the TUI crate monolith): 476k lines / 82% of the workspace in one crate, 8–16 min release builds, 30+ min test suite, 2–3 iterations per hour.

## PR log (updated as work lands)

| Date | EPIC / FEAT | PR | Status | Summary |
| -- | -- | -- | -- | -- |
| 2026-08-13 | EPIC-006 / FEAT-014 | [#5328]() | MERGED | Scope-corrected after owner review: small `codewhale-command-contract` prototype only (7 facets, generic handler/registration shapes, tests, CI guard); no TUI production changes, localization extraction, shared-type move, or command migration. Merged 2026-08-13 (`3b41d0ee`) after two conflict-resolution merges against main (generated-file regen: source budget 688916, facts v0.9.7; codewhale-core pin 0.9.7). |
| 2026-08-19 | EPIC-006 / FEAT-015 | [#5506]() | MERGED | TUI-owned implementations of all seven command capability facets, authoritative `App` delegation, portable registration/localization bridge, dual-path registry dispatch, and baseline-aware shrink-or-documented-split migration gate; no production command group converted or moved. |

| 2026-08-23 | EPIC-006 / FEAT-018 | [#5525]() | MERGED (shipped v0.9.11) | Complete utility group adopted external command shapes in place: seven portable registrations, zero concrete-`App` handlers, exact least-capability declarations with restricted facet exposure, and `utility` removed from the migration frontier. Temporary result/action data references remain intentionally assigned to FEAT-037; physical movement remains FEAT-038. |
| 2026-09-03 | EPIC-006 / FEAT-019 | [#5833]() + fix [#5839]() (harvests [#5609]()) | **MERGED —** `ad813cda6` | Maintainer re-land Hmbown/Codewhale#5833 restored the memory capability/facet/portable handlers to `main` after Hmbown/Codewhale#5839 resolved the migration blocker, least-authority/safe-failure review findings, and current-main/FEAT-022 reconciliation. Full updated-head matrix passed, including Linux/macOS/Windows, lint, Safety gate, Buildkite, CodeQL, and OHOS cargo check. |
| 2026-08-30 | EPIC-006 / FEAT-021 | [#5717]() | **MERGED** (into `main`, merge commit `2f200ee`) | Project group adopted external command shapes in place on main's no-bitmask model: new `CommandProjectContext` facet, `/init`=`WORKSPACE`/`/lsp`=project/`/share`=project/`/goal`=project+presentation via exact facet destructuring + safe missing-facet errors, `/lsp` config bridge routed through the TUI adapter, `project` removed from both frontiers; FEAT-037/FEAT-041 dependency-removal obligations enumerated. Rebased onto `main` per maintainer request (integration branch will not land); full matrix green after the maintainer's sandbox fix [#5724](); owner APPROVED with both nits fixed. |
| 2026-09-05 | EPIC-006 / FEAT-020 | current-main re-land [#5865](), preserving original [#5657]() | **MERGED INTO** `main` **—** `dcd4c200f` | Forward-port retained original authored commits, appended `PLUGIN` after published project/skill identities, preserved marketplace suggestions/reload nudge/shared Runtime API loader/canonical tokens, and did not resurrect the retired computer-use catalog. Three current-main CI blockers were repaired; the final Linux/macOS/Windows and supporting matrix was green. Verified in current `origin/main` (`82b2efaef`). |
| 2026-09-02 | EPIC-006 / FEAT-022 | [#5829]() (supersedes [#5825]()) | **MERGED INTO** `main` (`84b3dd694`) | Maintainer rebased/harvested FEAT-022 after Hmbown/Codewhale#5826, credited @aboimpinto as co-author, and merged the skills command shapes through replacement PR Hmbown/Codewhale#5829. Original contributor PR Hmbown/Codewhale#5825 is closed as superseded, not rejected. |
| 2026-09-06 | EPIC-006 / FEAT-023 | [#5902]() | **MERGED —** `41fecf8a4` | Nine session lifecycle handlers adopt a dedicated portable facet with exact capability declarations; pure `/compact` and `/purge` build no host bundle; concrete lifecycle machinery remains in the TUI adapter; TUI acceptance/regression fixtures stay outside the future movable group. The final maintainer nit was addressed in `52a53ce3a`: `CommandCapabilities` remains `u16`, with `SESSION_LIFECYCLE` on available bit 13. Full CI passed before merge. |
| 2026-09-06 | EPIC-006 / FEAT-024 | [#5951]() | **MERGED —** `a58e96d40` | Six session-control handlers adopt `CommandSessionControlContext`; exact declarations are `SESSION_CONTROL` for five handlers and `SESSION_CONTROL | PRESENTATION` only for `/remote-env`. Concrete session, persistence, picker, Git, browser, and remote-service behavior remains TUI-owned; the full host regression surface remains outside the movable group. Owner feedback was addressed in final contributor head `d4b68963d`; the complete GitHub/Buildkite matrix and Devin review were green before owner merge. |
| 2026-09-11 | EPIC-006 / FEAT-025 | [#6096]() | **OPEN — ready for review** — `54d9261d8` | Session export (`/export`, alias `/daochu`) adopts a dedicated `CommandSessionExportContext` facet declared with exactly `SESSION_EXPORT`; the documented command surface (name, alias, usage, discovery, description bridge) is unchanged. The portable handler owns parsing, document rendering, redaction, restore-point correlation, operation sequencing and result composition, while metadata projection, the shared turn-handoff renderer, clipboard/recovery delivery and protected destination writing remain TUI-owned behind the adapter. Four goldens captured from the pre-change implementation (authoritative transcript, visible-history fallback, recorded restore points with correlation, and the turn handoff) prove byte-identical output with only wall-clock fields normalised, each pinned by a unit-tested normaliser. Least authority is enforced structurally: a shared helper destructures all sixteen envelope slots, so an unrelated facet cannot join the registration unnoticed. Extraction readiness is proven by compilation — the slice and its 21 portable tests build and pass outside the TUI against a stand-in for the temporary FEAT-037 outcome type, with no `codewhale-tui` in the dependency graph. Supporting relocations: the pure ANSI/URL/text/secret sanitizer moves to `codewhale-secrets` (shared with the still-legacy `/structcopy`) and the shared `last-copy.md` recovery writer moves outside the movable group (shared with `/copy`). Rebased onto `main` `447223554`; fmt, Clippy (CI lint set), nextest 15408/15408, doctests, release build, and the migration/boundary/CI-wiring/locale gates are green. Three CI-only findings were fixed before hand-off, each carried by repository configuration or platform behaviour that a Linux-only local gate cannot observe: a moved test dropped the secret-scanner avoidance idiom (GitGuardian), the new `include_str!()` goldens were not declared `text eol=lf` (Windows CRLF), and two relocated adapter tests passed raw `TempDir` paths to the symlink-checked writer (macOS `/var`). Root `session` frontier remains pending for FEAT-026. |

## Reporting contract

* Every FEAT completion updates this issue with its PR link and a one-line summary.
* Every sub-EPIC completion updates the sub-EPIC row above (status + PR links).
* EPIC-005 is closed only when all sub-EPICs above are complete.

Paulo Aboim Pinto

Contributor guide

Open the contributing guide

Research direction

Start with the linked Codewhale Core execution plan and the EPIC-006 through EPIC-010 structure, then inspect the relevant paths under crates/tui/src/commands, tools, config, and core. This umbrella is already being executed through specific FEATs and pull requests, including #6096; completion requires all planned extraction stages and validation, so choose an unclaimed child issue instead.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
cli, tooling
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
15/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.