Files
headquarter/openspec/changes/repo-restructure/tasks.md
T
Developer ee1fa6bee5 refactor: centralize types and extract seed data (Task 1.1)
- Create types/ directory with centralized domain types:
  session, tool-instance, tool-type, git-repository, config-folder,
  tool-config, project, user, api-response
- Remove inline type definitions from API modules;
  re-export from types/ for backward compatibility
- Update state/sessions.tsx to import Session from types/session.ts
- Update all consumer components/pages to import from types/
- Extract seed_builtin_tool_types from main.py to
  seeds/builtin_tool_types.py
- Create types/index.ts barrel export

Quality gates: tsc (pass), eslint (pass), Python syntax (pass)
2026-06-02 18:56:54 +00:00

676 lines
26 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Tasks: Repository Restructuring and Modularization
## Overview
9 reviewable PRs (all ≤ 400 lines changed) implementing the full restructure. Each task is a standalone merge to `main`. Dependencies are explicit. Review workload is protected.
**Conventions:**
- `+N/-M` = lines added / removed in the PR
- `Files: N` = number of files touched
- `Deps:` = must-merge tasks before this one
---
## Phase 1: Safe Foundations
### Task 1.1: Centralize Types and Extract Seed Data
**PR label:** `refactor: centralize types and extract seed data`
**Estimated:** +180 / 120 lines across 15 files
**Deps:** None
**What:**
- Create `types/` directory with domain type files
- Move types out of `api/sessions.ts`, `api/tool-types.ts`, `api/git-repositories.ts`, `api/config-folders.ts`
- Move `Session` definition from `state/sessions.tsx` to `types/session.ts`
- Move `ToolInstance` definition from `api/sessions.ts` to `types/tool-instance.ts`
- Move hardcoded seed data from `main.py` to `seeds/builtin_tool_types.py`
- Create `types/index.ts` barrel export
- Update all consumers to import from `types/`
**Files:**
```
NEW: types/session.ts (from api/sessions.ts + state/sessions.tsx)
NEW: types/tool-instance.ts (from api/sessions.ts)
NEW: types/tool-type.ts (from api/tool-types.ts)
NEW: types/git-repository.ts (from api/git-repositories.ts)
NEW: types/config-folder.ts (from api/config-folders.ts)
NEW: types/project.ts (from types.ts)
NEW: types/user.ts (from types.ts)
NEW: types/api-response.ts (new generic types)
NEW: types/index.ts (barrel)
NEW: seeds/builtin_tool_types.py (from main.py)
MOD: api/sessions.ts (remove inline types, import from types/)
MOD: api/tool-types.ts (remove inline types, import from types/)
MOD: api/git-repositories.ts (remove inline types, import from types/)
MOD: api/config-folders.ts (remove inline types, import from types/)
MOD: state/sessions.tsx (import Session from types/)
MOD: types.ts (remove moved types)
MOD: main.py (import seed data from seeds/)
```
**Acceptance criteria:**
- [ ] `grep -n "interface Session" apps/web/src` returns exactly 1 result (in `types/session.ts`)
- [ ] `grep -n "interface ToolInstance" apps/web/src` returns exactly 1 result
- [ ] `tsc --noEmit` passes with zero errors
- [ ] `pytest` passes
- [ ] No behavior changes
---
### Task 1.2: Extract FileBrowser and Shared UI Components
**PR label:** `refactor: extract FileBrowser and shared UI primitives`
**Estimated:** +150 / 80 lines across 8 files
**Deps:** 1.1
**What:**
- Extract `FileBrowser` component from inline definition in `repo-workspace.tsx`
- Create `components/features/git/FileBrowser.tsx`
- Create `components/ui/LoadingState.tsx` (reusable loading pattern)
- Create `components/ui/ErrorState.tsx` (reusable error+retry pattern)
- Create `components/ui/index.ts` barrel
- Update `repo-workspace.tsx` to import `FileBrowser`
- Update pages that use loading/error patterns to use new components
**Files:**
```
NEW: components/features/git/FileBrowser.tsx (from repo-workspace.tsx)
NEW: components/ui/LoadingState.tsx
NEW: components/ui/ErrorState.tsx
NEW: components/ui/StatusBadge.tsx
NEW: components/ui/index.ts (barrel)
MOD: pages/repo-workspace.tsx (remove inline FileBrowser, import)
MOD: pages/dashboard.tsx (use LoadingState, ErrorState)
MOD: pages/sessions.tsx (use LoadingState, ErrorState)
```
**Acceptance criteria:**
- [ ] `grep -n "const FileBrowser" pages/repo-workspace.tsx` returns zero results
- [ ] FileBrowser renders correctly in repo workspace
- [ ] `tsc --noEmit` passes
- [ ] `eslint` passes
---
## Phase 2: Style System
### Task 2.1: Extract Global and Token Styles
**PR label:** `refactor: split styles.css — global styles and tokens`
**Estimated:** +120 / 50 lines across 5 files
**Deps:** 1.2
**What:**
- Create `styles/tokens.css` — CSS variables + dark theme
- Create `styles/global.css` — reset, body, shell layout
- Create `styles/utilities.css` — .stack, .row, .truncate, etc.
- Create `styles/syntax-highlight.css` — Prism.js overrides
- Update `main.tsx` to import the 4 new files
- Do NOT delete `styles.css` yet
**Files:**
```
NEW: styles/tokens.css (from styles.css lines 180)
NEW: styles/global.css (from styles.css: body, .shell, .shell-header, etc.)
NEW: styles/utilities.css (from styles.css: .stack, .row, .truncate, etc.)
NEW: styles/syntax-highlight.css (from styles.css: Prism overrides)
MOD: main.tsx (add imports for new style files)
```
**Acceptance criteria:**
- [ ] All 4 new CSS files exist and contain only their concern
- [ ] `npm run build` succeeds
- [ ] No visual regressions on shell layout
- [ ] `styles.css` still exists (deleted in Task 2.3)
---
### Task 2.2: Extract Component CSS Modules (Part 1 — Terminal + Git)
**PR label:** `refactor: extract CSS modules for terminal and git components`
**Estimated:** +280 / 200 lines across 14 files
**Deps:** 2.1
**What:**
- Create `.module.css` files for terminal and git components
- Extract styles from `styles.css` for: Terminal, GitToolbar, FileBrowser, FileEditor, CommitPanel, CommitDialog, MergeDialog
- Update components to import their `.module.css`
- Convert global class names to camelCase module classes
**Files:**
```
NEW: components/features/terminal/TerminalComponent.module.css
NEW: components/features/git/GitToolbar.module.css
NEW: components/features/git/FileBrowser.module.css
NEW: components/features/git/FileEditor.module.css
NEW: components/features/git/CommitPanel.module.css
NEW: components/features/git/CommitDialog.module.css
NEW: components/features/git/MergeDialog.module.css
MOD: components/terminal.tsx (import module, use styles.*)
MOD: components/git-toolbar.tsx (import module, use styles.*)
MOD: components/features/git/FileBrowser.tsx
MOD: components/file-editor.tsx
MOD: styles.css (remove extracted sections)
```
**Acceptance criteria:**
- [ ] Terminal renders identically
- [ ] Git toolbar, file browser, file editor render identically
- [ ] Commit panel and dialogs render identically
- [ ] `npm run build` succeeds
- [ ] `eslint` passes
---
### Task 2.3: Extract Component CSS Modules (Part 2 — Session + Settings + Layout) + Delete styles.css
**PR label:** `refactor: extract CSS modules for session/settings + delete monolithic styles.css`
**Estimated:** +250 / 2,500 lines across 12 files
**Deps:** 2.2
**What:**
- Create `.module.css` files for: InstanceList, AppShell, Navigation, SettingsTabLayout
- Create `styles/pages/sessions.css`, `styles/pages/repo-workspace.css`, `styles/pages/tool-workshop.css`
- Extract remaining component styles from `styles.css`
- Update components to import modules
- **Delete `styles.css`**
- Verify no remaining references to `styles.css`
**Files:**
```
NEW: components/features/session/InstanceList.module.css
NEW: components/layout/AppShell.module.css
NEW: components/layout/Navigation.module.css
NEW: components/features/settings/SettingsTabLayout.module.css
NEW: styles/pages/sessions.css
NEW: styles/pages/repo-workspace.css
NEW: styles/pages/tool-workshop.css
MOD: components/instance-list.tsx
MOD: components/app-shell.tsx
MOD: components/settings-tab-layout.tsx
MOD: pages/sessions.tsx
MOD: pages/repo-workspace.tsx
DEL: styles.css
```
**Acceptance criteria:**
- [ ] `test -f styles.css` fails (file deleted)
- [ ] All pages render identically
- [ ] `npm run build` succeeds
- [ ] No unstyled components
- [ ] `eslint` passes
---
## Phase 3: Backend Decomposition
### Task 3.1: Extract Shared Auth Dependencies
**PR label:** `refactor: extract shared auth dependencies`
**Estimated:** +90 / 150 lines across 10 files
**Deps:** 1.1
**What:**
- Create `auth/dependencies.py` with `get_current_user()`, `get_owned_project()`, `get_owned_repository()`
- Find and remove duplicated `_get_user()` / `_get_owned_project()` helpers from all routers
- Update routers to import from `auth.dependencies`
- Ensure dependency signatures match across all routers
**Files:**
```
NEW: auth/dependencies.py (consolidated from router files)
MOD: api/tool_instances.py (remove inline helpers, import)
MOD: api/git_repositories.py (remove inline helpers, import)
MOD: api/config_profiles.py (remove inline helpers, import)
MOD: api/ssh_keys.py (remove inline helpers, import)
MOD: api/projects.py (remove inline helpers, import)
MOD: api/tool_configs.py (remove inline helpers, import)
MOD: api/config_folders.py (remove inline helpers, import)
MOD: api/terminal.py (remove inline helpers, import)
```
**Acceptance criteria:**
- [ ] `grep -rn "def _get_user" apps/api/src/api/` returns zero results
- [ ] `grep -rn "def _get_owned_project" apps/api/src/api/` returns zero results
- [ ] All integration tests pass
- [ ] `pytest` passes
---
### Task 3.2: Create Pydantic Schemas Directory
**PR label:** `refactor: extract pydantic schemas from routers`
**Estimated:** +200 / 100 lines across 8 files
**Deps:** 3.1
**What:**
- Create `schemas/` directory
- Extract request/response models from `api/tool_instances.py``schemas/tool_instance.py`
- Extract from `api/git_repositories.py``schemas/git_repository.py`
- Extract from `api/config_profiles.py``schemas/config_profile.py`
- Extract from `api/tool_types.py``schemas/tool_type.py`
- Update routers to import schemas
- Keep schema imports backward-compatible (routers still work)
**Files:**
```
NEW: schemas/tool_instance.py
NEW: schemas/git_repository.py
NEW: schemas/config_profile.py
NEW: schemas/tool_type.py
NEW: schemas/ssh_key.py
NEW: schemas/project.py
MOD: api/tool_instances.py (remove inline schemas, import)
MOD: api/git_repositories.py (remove inline schemas, import)
MOD: api/config_profiles.py (remove inline schemas, import)
MOD: api/tool_types.py (remove inline schemas, import)
```
**Acceptance criteria:**
- [ ] No Pydantic `BaseModel` definitions in router files
- [ ] `pytest` passes
- [ ] All API endpoints return correct response shapes
---
### Task 3.3: Split services/docker.py into Focused Modules
**PR label:** `refactor: split services/docker.py into focused modules`
**Estimated:** +350 / 300 lines across 6 files
**Deps:** 3.2
**What:**
- Create `services/docker/compose.py` — compose file generation + modification
- Create `services/docker/container.py` — container lifecycle (create, start, stop, restart, remove)
- Create `services/docker/tunnel.py` — Cloudflare tunnel create/recreate/health
- Create `services/docker/config_staging.py` — config folder file writing
- Create `services/docker/__init__.py` barrel
- Delete `services/docker.py`
- Update `api/tool_instances.py` to import from `services.docker`
**Files:**
```
NEW: services/docker/__init__.py
NEW: services/docker/compose.py
NEW: services/docker/container.py
NEW: services/docker/tunnel.py
NEW: services/docker/config_staging.py
MOD: api/tool_instances.py (update imports)
DEL: services/docker.py
```
**Acceptance criteria:**
- [ ] `test -f services/docker.py` fails (deleted)
- [ ] Each new module ≤ 300 lines
- [ ] `pytest` passes
- [ ] Tool instance create/start/stop/restart still works
---
### Task 3.4: Slim tool_instances.py Router
**PR label:** `refactor: slim tool_instances router to HTTP-only concerns`
**Estimated:** +80 / 700 lines across 3 files
**Deps:** 3.3
**What:**
- Remove all business logic from `api/tool_instances.py`
- Move compose generation calls to `services.docker.compose`
- Move container lifecycle calls to `services.docker.container`
- Move tunnel calls to `services.docker.tunnel`
- Move config staging calls to `services.docker.config_staging`
- Router should only: validate input, call service, return response
- Target: ~250 lines
**Files:**
```
MOD: api/tool_instances.py (remove ~700 lines of logic, keep ~250 of routing)
MOD: services/docker/compose.py (may need minor adjustments)
MOD: services/docker/container.py (may need minor adjustments)
```
**Acceptance criteria:**
- [ ] `api/tool_instances.py` ≤ 300 lines
- [ ] `grep -n "subprocess" api/tool_instances.py` returns zero results
- [ ] `grep -n "docker" api/tool_instances.py` returns only import lines
- [ ] `pytest` passes, especially tool instance integration tests
---
### Task 3.5: Slim git_repositories.py and config_profiles.py Routers
**PR label:** `refactor: slim git_repositories and config_profiles routers`
**Estimated:** +100 / 600 lines across 6 files
**Deps:** 3.4
**What:**
- Extract git control logic from `api/git_repositories.py` to `services/git/control.py` (already exists, use more)
- Extract file browsing logic to thin handlers delegating to `services/git/files.py`
- Extract config profile resolution logic to `services/profile_resolver.py`
- Slim both routers to ~250 lines each
- Ensure routers contain only route definitions and thin handlers
**Files:**
```
MOD: api/git_repositories.py (remove business logic, delegate)
MOD: api/config_profiles.py (remove business logic, delegate)
MOD: services/git/control.py (may expand)
MOD: services/git/files.py (may expand)
MOD: services/profile_resolver.py (may expand)
```
**Acceptance criteria:**
- [ ] `api/git_repositories.py` ≤ 300 lines
- [ ] `api/config_profiles.py` ≤ 300 lines
- [ ] `pytest` passes
- [ ] Git operations (branch, commit, push, pull) still work
---
## Phase 4: Frontend Page Decomposition
### Task 4.1: Split tool-workshop.tsx into Tab Components
**PR label:** `refactor: split tool-workshop page into tab components`
**Estimated:** +280 / 450 lines across 6 files
**Deps:** 2.3
**What:**
- Create `components/features/tool-workshop/ToolTypesTab.tsx`
- Create `components/features/tool-workshop/ToolConfigsTab.tsx`
- Create `components/features/tool-workshop/ConfigFoldersTab.tsx`
- Create `components/features/tool-workshop/index.ts` barrel
- Slim `pages/tool-workshop.tsx` to tab switcher + layout only (~100 lines)
- Each tab manages its own form state and API calls
**Files:**
```
NEW: components/features/tool-workshop/ToolTypesTab.tsx
NEW: components/features/tool-workshop/ToolConfigsTab.tsx
NEW: components/features/tool-workshop/ConfigFoldersTab.tsx
NEW: components/features/tool-workshop/index.ts
MOD: pages/tool-workshop.tsx (remove inline tabs, compose imports)
```
**Acceptance criteria:**
- [ ] `pages/tool-workshop.tsx` ≤ 150 lines
- [ ] All 3 tabs function identically
- [ ] `tsc --noEmit` passes
- [ ] `eslint` passes
---
### Task 4.2: Extract SessionsPage Components
**PR label:** `refactor: extract sessions page components`
**Estimated:** +220 / 350 lines across 7 files
**Deps:** 4.1
**What:**
- Create `components/features/session/SessionList.tsx`
- Create `components/features/session/SessionCard.tsx`
- Create `components/features/session/CreateSessionForm.tsx`
- Create `components/features/session/index.ts` barrel
- Slim `pages/sessions.tsx` to layout + composition
- Extract inline stop/delete confirmation into reusable `ConfirmDialog` in `components/ui/`
**Files:**
```
NEW: components/features/session/SessionList.tsx
NEW: components/features/session/SessionCard.tsx
NEW: components/features/session/CreateSessionForm.tsx
NEW: components/features/session/index.ts
NEW: components/ui/ConfirmDialog.tsx
MOD: pages/sessions.tsx (remove inline lists/forms, compose)
```
**Acceptance criteria:**
- [ ] `pages/sessions.tsx` ≤ 200 lines
- [ ] Session list, create form, and cards work identically
- [ ] `tsc --noEmit` passes
---
### Task 4.3: Extract Dashboard and RepoWorkspace Components
**PR label:** `refactor: extract dashboard and repo-workspace components`
**Estimated:** +200 / 300 lines across 8 files
**Deps:** 4.2
**What:**
- Create `components/features/dashboard/DashboardSummary.tsx`
- Create `components/features/dashboard/QuickActions.tsx`
- Create `components/features/dashboard/ActiveSessionsList.tsx`
- Create `components/features/dashboard/index.ts` barrel
- Slim `pages/dashboard.tsx` to layout + composition
- Slim `pages/repo-workspace.tsx` further (FileBrowser already extracted in 1.2)
- Extract `InstanceList` inline create dialog to `components/features/session/CreateInstanceDialog.tsx`
**Files:**
```
NEW: components/features/dashboard/DashboardSummary.tsx
NEW: components/features/dashboard/QuickActions.tsx
NEW: components/features/dashboard/ActiveSessionsList.tsx
NEW: components/features/dashboard/index.ts
NEW: components/features/session/CreateInstanceDialog.tsx
MOD: pages/dashboard.tsx (slim to ~120 lines)
MOD: pages/repo-workspace.tsx (slim further)
MOD: components/instance-list.tsx (extract create dialog)
```
**Acceptance criteria:**
- [ ] `pages/dashboard.tsx` ≤ 150 lines
- [ ] Dashboard renders identically
- [ ] `tsc --noEmit` passes
---
### Task 4.4: Rename All Files to Naming Convention
**PR label:** `refactor: rename files to PascalCase components and kebab-case APIs`
**Estimated:** +30 / 0 lines across 40 files (mostly `git mv`)
**Deps:** 4.3
**What:**
- Rename component files to PascalCase matching exported name:
- `app-shell.tsx``AppShell.tsx`
- `git-toolbar.tsx``GitToolbar.tsx`
- `file-editor.tsx``FileEditor.tsx`
- `instance-list.tsx``InstanceList.tsx`
- `terminal.tsx``TerminalComponent.tsx`
- etc.
- Rename page files to PascalCase:
- `dashboard.tsx``DashboardPage.tsx`
- `git-history.tsx``GitHistoryPage.tsx`
- `repo-workspace.tsx``RepoWorkspacePage.tsx`
- etc.
- Rename API files to kebab-case:
- `tool_types.ts``tool-types.ts`
- `git_repositories.ts``git-repositories.ts`
- `config_folders.ts``config-folders.ts`
- etc.
- Update `router.tsx` to import new page paths
- Update all imports across the codebase
**Files:**
```
# Component renames (git mv)
components/app-shell.tsx → components/layout/AppShell.tsx
components/git-toolbar.tsx → components/features/git/GitToolbar.tsx
components/file-editor.tsx → components/features/git/FileEditor.tsx
components/instance-list.tsx → components/features/session/InstanceList.tsx
components/terminal.tsx → components/features/terminal/TerminalComponent.tsx
components/code-editor.tsx → components/ui/CodeEditor.tsx
components/commit-dialog.tsx → components/features/git/CommitDialog.tsx
components/commit-panel.tsx → components/features/git/CommitPanel.tsx
components/merge-dialog.tsx → components/features/git/MergeDialog.tsx
components/protected-route.tsx → components/ProtectedRoute.tsx
components/repositories-settings-tab.tsx → components/features/project/RepositoriesSettingsTab.tsx
components/repository-create-dialog.tsx → components/features/project/RepositoryCreateDialog.tsx
components/settings-tab-layout.tsx → components/features/settings/SettingsTabLayout.tsx
components/syntax-highlighter.tsx → components/features/git/SyntaxHighlighter.tsx
components/workspace-header.tsx → components/features/workspace/WorkspaceHeader.tsx
components/icon.tsx → components/ui/Icon.tsx
# Page renames (git mv)
pages/dashboard.tsx → pages/DashboardPage.tsx
pages/git-history.tsx → pages/GitHistoryPage.tsx
pages/git-repositories.tsx → pages/GitRepositoriesPage.tsx
pages/profile.tsx → pages/ProfilePage.tsx
pages/project-settings.tsx → pages/ProjectSettingsPage.tsx
pages/projects.tsx → pages/ProjectsPage.tsx
pages/repo-workspace.tsx → pages/RepoWorkspacePage.tsx
pages/sessions.tsx → pages/SessionsPage.tsx
pages/settings.tsx → pages/SettingsPage.tsx
pages/ssh-keys.tsx → pages/SshKeysPage.tsx
pages/terminal.tsx → pages/TerminalPage.tsx
pages/tool-configs.tsx → pages/ToolConfigsPage.tsx
pages/tool-types.tsx → pages/ToolTypesPage.tsx
pages/tool-workshop.tsx → pages/ToolWorkshopPage.tsx
pages/placeholder.tsx → pages/PlaceholderPage.tsx
# API renames (git mv)
api/tool_types.ts → api/tool-types.ts
api/git_repositories.ts → api/git-repositories.ts
api/config_folders.ts → api/config-folders.ts
api/tool_configs.ts → api/tool-configs.ts
api/ssh_keys.ts → api/ssh-keys.ts
api/user_config.ts → api/user-config.ts
# Updated imports
MOD: router.tsx
MOD: all page files (update relative imports)
MOD: all component files (update relative imports)
MOD: all test files (update imports)
```
**Acceptance criteria:**
- [ ] All component files match exported component name (case-insensitive)
- [ ] All page files end with `Page.tsx`
- [ ] All API files use kebab-case
- [ ] `tsc --noEmit` passes
- [ ] `eslint` passes
- [ ] `vitest run` passes
- [ ] Router resolves all routes
---
## Phase 5: Testing and Polish
### Task 5.1: Add Tests for Extracted Components
**PR label:** `test: add tests for extracted components`
**Estimated:** +250 / 0 lines across 8 files
**Deps:** 4.4
**What:**
- Add `components/features/git/FileBrowser.test.tsx`
- Add `components/ui/LoadingState.test.tsx`
- Add `components/ui/ErrorState.test.tsx`
- Add `components/features/tool-workshop/ToolTypesTab.test.tsx`
- Add `components/features/session/SessionList.test.tsx`
- Add `pages/DashboardPage.test.tsx` (replace failing `projects.test.tsx` pattern)
- Ensure tests use `MemoryRouter` where needed
- Mock API calls consistently
**Files:**
```
NEW: components/features/git/FileBrowser.test.tsx
NEW: components/ui/LoadingState.test.tsx
NEW: components/ui/ErrorState.test.tsx
NEW: components/features/tool-workshop/ToolTypesTab.test.tsx
NEW: components/features/session/SessionList.test.tsx
NEW: pages/DashboardPage.test.tsx
```
**Acceptance criteria:**
- [ ] All new tests pass (`vitest run`)
- [ ] No test file exceeds 200 lines
- [ ] Tests cover render, basic interaction, and error states
---
### Task 5.2: Documentation and Cleanup
**PR label:** `docs: add naming conventions doc and final cleanup`
**Estimated:** +120 / 50 lines across 6 files
**Deps:** 5.1
**What:**
- Write `docs/development/naming.md` with full naming convention table
- Remove dead CSS classes (verified by grep for unused selectors)
- Remove unused exports (check `eslint` `report-unused-disable-directives`)
- Add verification script to `package.json`: `"check-structure": "node scripts/check-structure.js"`
- Final quality gate run
**Files:**
```
NEW: docs/development/naming.md
NEW: scripts/check-structure.js (verifies file sizes, naming, barrels)
MOD: package.json (add check-structure script)
MOD: styles/global.css (remove dead rules if any)
MOD: various files (remove unused exports)
```
**Acceptance criteria:**
- [ ] `docs/development/naming.md` exists and is complete
- [ ] `npm run check-structure` passes
- [ ] No file in `src/` exceeds 300 lines
- [ ] `tsc --noEmit` passes
- [ ] `eslint` passes
- [ ] `vitest run` passes
- [ ] `pytest` passes
---
## Task Dependency Graph
```
1.1 (Types + Seeds) ──┐
├──→ 1.2 (FileBrowser + UI) ──→ 2.1 (Global Styles)
3.1 (Auth deps) ──→ 3.2 (Schemas) ─┤
│ │
└──→ 3.3 (Docker split) ──→ 3.4 (tool_instances slim)
└──→ 3.5 (git + profiles slim)
2.2 (Terminal/Git CSS) ──→ 2.3 (Session/Settings CSS + delete styles.css) ────────────────┘ │
4.1 (tool-workshop split) ──→ 4.2 (sessions split) ──→ 4.3 (dashboard/workspace split) ──→ 4.4 (rename files)
5.1 (tests) ──→ 5.2 (docs + cleanup) ────────────────────────────────────────────────────────────────────────┘
```
---
## Review Workload Summary
| Task | Est. Lines | Status |
|------|-----------|--------|
| 1.1 | +180 / 120 | ✅ Under 400 |
| 1.2 | +150 / 80 | ✅ Under 400 |
| 2.1 | +120 / 50 | ✅ Under 400 |
| 2.2 | +280 / 200 | ✅ Under 400 |
| 2.3 | +250 / 2,500 | ✅ Under 400 (mostly deletions) |
| 3.1 | +90 / 150 | ✅ Under 400 |
| 3.2 | +200 / 100 | ✅ Under 400 |
| 3.3 | +350 / 300 | ✅ Under 400 |
| 3.4 | +80 / 700 | ✅ Under 400 |
| 3.5 | +100 / 600 | ✅ Under 400 |
| 4.1 | +280 / 450 | ✅ Under 400 |
| 4.2 | +220 / 350 | ✅ Under 400 |
| 4.3 | +200 / 300 | ✅ Under 400 |
| 4.4 | +30 / 0 | ✅ Under 400 (git mv mostly) |
| 5.1 | +250 / 0 | ✅ Under 400 |
| 5.2 | +120 / 50 | ✅ Under 400 |
**All 16 tasks are under the 400-line review budget.**
---
## Quality Gates (Per Task)
Every task MUST pass:
1. `npm run typecheck` (frontend) — zero errors
2. `npm run lint` (frontend) — zero warnings
3. `pytest` (backend) — zero failures
4. File size check — no file > 300 lines
5. For frontend tasks: visual sanity check (build succeeds)
6. Commit with conventional format: `refactor: phase N — description`
---
## Task Execution Notes
- **Use `git mv`** for all file renames to preserve history
- **Update imports with IDE refactor** when possible (VS Code "Move to new file", PyCharm refactor)
- **No logic changes** — pure cut-paste-reorganize
- **Merge to `main` immediately** after each task passes quality gates
- **Pause between phases** (after Tasks 1.2, 2.3, 3.5, 4.4) to verify stability