Refactor: decompose god files, restructure into domains/, add typed abstractions#38
Merged
DorianZheng merged 10 commits intomainfrom Mar 22, 2026
Merged
Refactor: decompose god files, restructure into domains/, add typed abstractions#38DorianZheng merged 10 commits intomainfrom
DorianZheng merged 10 commits intomainfrom
Conversation
Split the monolithic agent-manager.ts by shared mutable state analysis: - runtime-state.ts: owns runningAgents Map, agent locks, runtime singleton - lifecycle.ts: startAgent/stopAgent orchestration - messaging.ts: sendMessage + Claude CLI command building - todo-reminder.ts: idle reminders, leader PDCA, policy detection - daemon-sync.ts: communication daemon lifecycle - settings-sync.ts: Claude settings merge + push - runtime-sandbox.ts: runtime sandbox CRUD - container-exec.ts: stateless BoxLite exec wrappers - prompt-builder.ts: system prompt assembly - host-paths.ts: host filesystem setup - skills-sync.ts: skill directory sync - nginx.ts: miniapp nginx routing - screen.ts: screenshot + screen info - constants.ts: all shared constants and types agent-manager.ts becomes a 61-line barrel re-export for backward compatibility with all existing consumers (17 test files, 7 source files).
Split the monolithic RPC handler map by domain prefix: - client-handlers/channels.ts, messages.ts, agents.ts, mounts.ts - client-handlers/memory.ts, mailbox.ts, apps.ts, host-ops.ts - client-handlers/todos.ts, settings.ts, admin.ts, sandboxes.ts - client-handlers/slack.ts, media.ts, validation.ts, index.ts client-api.ts becomes a 3-line barrel re-export. Each handler file uses registerXxxHandlers(h) pattern for clean composition.
Split by domain: lifecycle, exec, files, ACL, resource conversion, path helpers, runtime state, terminal, and shared exec helpers. sandbox-manager.ts becomes an 8-line barrel re-export.
Extract three sub-components from the monolithic chat view: - memory-editor.ts: <agent-memory-editor> with file list, editor, resize - host-settings.ts: <agent-host-settings-panel> with operator settings - stash-strip.ts: <agent-stash-strip> with offline message queue - chat-view.css.ts: extracted CSS styles Parent communicates via properties down, CustomEvents up. agent-chat-view.ts slimmed from 3351 to 852 lines.
Extract tab components from the monolithic sandbox view: - overview-tab.ts, execs-tab.ts, files-tab.ts, terminal-tab.ts - create-dialog.ts for new sandbox creation - view.css.ts for shared styles sandboxes-view.ts slimmed to ~260 lines (card grid + tab switching).
app-shell.ts (1963 -> 1282 lines): - Extract app-shell.css.ts, host-approval-modal.ts, workspace-sync.ts agent-profile-panel.ts (1656 -> 493 lines): - Extract profile-tab.ts, skills-tab.ts, logs-tab.ts, system-prompt-overlay.ts settings-view.ts (1286 -> 150 lines): - Extract settings-model-section.ts, settings-slack-section.ts
slack-connection.ts (849 -> 34 lines barrel): - connection.ts: lifecycle, start/stop - event-router.ts: message handling, send APIs - approval-notify.ts: approval request posting - agent-sync.ts: agent <-> Slack sync - channel-sync.ts: channel <-> Slack sync api/agents.ts (1184 -> 550 lines): - agents-validation.ts: shared validation helpers - agents-memory.ts: memory file CRUD routes - agents-mounts.ts: mount CRUD routes
Backend: - Group 6 domain dirs under domains/ (agents, sandboxes, slack, host, mailbox, todos) — keeps top-level scannable (8 items vs 16) - Merge host-operator/ + host-commands/ into domains/host/ (gui-service.ts, gui-provider.ts, shell-service.ts) - Delete 10 dead api/ REST route files (replaced by WS RPC gateway) - Delete 6 barrel re-export files (agent-manager.ts, index.ts, sandbox-manager.ts, slack-connection.ts, client-api.ts) - Update all 40+ consumer files to import specific sub-modules Frontend: - Remove redundant agent-/channel-/sandboxes- prefixes from 12 files (directory already provides namespace) - Keep @CustomElement tag names unchanged Research-backed decisions (20 projects analyzed): - Grouped domains pattern: Ghost (60), Twenty (20), Amplication (51) - No barrel files: VS Code, Cal.com, TkDodo consensus - No redundant prefixes: universal convention
Backend: - Merge mailbox/ and todos/ into domains/agents/ (agent sub-concerns) - Move agent-prompts/ and agent-skills/ into domains/agents/ - Move utils/host-directory-picker.ts to domains/host/ - Move utils/mentions.ts to domains/agents/ - Move api/admin.ts to domains/host/admin.ts - Delete empty api/, websocket/, mailbox/, todos/ directories Frontend: - Dissolve components/layout/ kitchen sink into proper directories: - message-area + codex-composer → components/messages/ - settings-view + sections → components/settings/ - host-approval-modal → components/modals/ - sidebar-panel → components/sidebar/ Backend top-level: 8 items (was 16). Clean domain/infra separation. Frontend components: 8 directories, each with clear purpose.
1. Typed event bus (gateway/events.ts) — discriminated union for all WS broadcast events, compile-time payload safety 2. Async lock utility (utils/async-lock.ts) — shared keyed lock pattern used by both agents and sandboxes 3. Storage helpers (storage/helpers.ts) — shared JSON parsing, bool conversion used across store files 4. Agent runtime grouping — RunningAgent fields grouped into session/execution/interrupt/daemon/ports sub-objects 5. Status transition validation — warns on invalid agent state transitions (e.g., stopped → responding) 6. Message delivery types (domains/agents/message-types.ts) — shared types as foundation for future messaging unification All changes are structural (better types, deduplication, grouping). No behavior changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Major codebase refactoring for maintainability and readability, guided by research across 20+ open-source TypeScript projects (VS Code, Outline, Cal.com, Twenty CRM, Ghost, etc.).
Phase 1: Decompose 8 god files into ~70 focused modules
agent-manager.ts(3,387 lines) → 14 modules underagents/client-api.ts(1,253 lines) → 16 domain handler files underclient-handlers/sandbox-manager.ts(1,345 lines) → 12 modules undersandboxes/agent-chat-view.ts(3,351 lines) → 5 Lit componentssandboxes-view.ts(2,520 lines) → 7 Lit componentsapp-shell.ts(1,963 → 1,282 lines),agent-profile-panel.ts(1,656 → 493 lines),settings-view.ts(1,286 → 150 lines)slack-connection.ts(849 lines) → 5 modules,api/agents.ts(1,184 → 550 lines)Phase 2: Restructure file hierarchy
domains/(agents, sandboxes, slack, host, mailbox, todos)host-operator/+host-commands/intodomains/host/agent-chat-view.ts→chat-view.tsinagents/)components/layout/kitchen sink intomessages/,settings/,modals/,sidebar/Phase 3: Final cleanup
mailbox/andtodos/intoagents/(tightly coupled)host-directory-picker.ts,mentions.ts) to their domainsagent-prompts/andagent-skills/intodomains/agents/Phase 4: Code abstraction improvements
gateway/events.ts) — discriminated union for WS broadcastsutils/async-lock.ts)storage/helpers.ts) — JSON parsing, bool conversionDesign principles applied
Test plan
make buildpasses for all packages (backend, frontend, electron)make test— no new test failures (pre-existing failures unchanged)make dev— app starts, agents can be created/started/messaged