mirror of
https://github.com/different-ai/openwork
synced 2026-04-25 17:15:34 +02:00
7.6 KiB
7.6 KiB
PRD - Refactor App.tsx (50 percent size reduction)
Summary
Create a low-risk refactor plan that cuts src/App.tsx from ~2000 lines to ~1000 lines by extracting cohesive state modules and view-prop builders. The work is purely structural and must preserve all behavior. Every extraction step has explicit checks so a simple agent can execute it safely.
Goals
- Reduce
src/App.tsxline count by about 50 percent without changing runtime behavior. - Keep all signals scoped to the App reactive root by using factory functions.
- Ensure each extraction step is reversible and validated by a consistent test gate.
- Produce a repeatable plan that any agent can follow with minimal judgment calls.
Non-Goals
- No UI changes or copy changes.
- No data model or storage changes.
- No SDK or API updates.
- No new abstractions that change how state is consumed.
Definitions
- Extraction: Moving related state and helpers into a new module while keeping logic the same.
- Factory module: A
createXState(...)orbuildXProps(...)function called inside App to keep signals scoped. - Test gate: A single command that must pass after each extraction step.
Guiding Principles
- Small, reversible moves over large rewrites.
- Preserve function names and signal behavior.
- Avoid new shared global state.
- Keep all props to views identical.
Current State
src/App.tsxcontains routing, state, effects, preference storage, template logic, update flow, and view prop builders.- There is no single place to see what belongs to which feature.
- Refactors are risky because many flows are coupled in one file.
Proposal
- Create small modules under
src/app/that own one domain each. - Keep App.tsx as wiring only: create signals, instantiate factories, render views and modals.
- Use one test gate after every change and a heavier check every few steps.
Required Test Gate
Add a single script so every step runs the same command.
package.jsonscript:"test:refactor": "pnpm typecheck && pnpm test:health && pnpm test:sessions"
Implementation Plan (step-by-step)
Each step ends with the same two actions:
- Run
pnpm -C vendor/openwork test:refactor - If it fails, stop and fix or revert the last step.
Step 0 - Baseline and guardrails
- Action:
- Record baseline line count:
wc -l src/App.tsx. - Add
test:refactorscript.
- Record baseline line count:
- Pay attention:
- Do not change any runtime logic while adding the script.
- Check:
- Run
pnpm -C vendor/openwork test:refactor.
- Run
Step 1 - Demo mode state
- Move to:
src/app/demo-state.ts. - Move these items:
demoMode,demoSequence,setDemoSequenceState.- Demo signals: sessions, statuses, messages, todos, artifacts, working files, authorized dirs, active workspace display.
isDemoModememo and allactive*memos.selectDemoSessionhelper.
- Inputs required:
deriveArtifacts,deriveWorkingFiles, and typesMessageWithParts,TodoItem,WorkspaceDisplay.- Live session data accessors for real mode.
- Pay attention:
- Ensure demo state is reset when sequence changes.
- All
active*memos must still switch between demo and real state.
- Check:
- Run
pnpm -C vendor/openwork test:refactor.
- Run
Step 2 - Template management
- Move to:
src/app/template-state.ts. - Move these items:
- Template lists and load flags.
- Template modal state and draft signals.
openTemplateModal,saveTemplate,deleteTemplate,runTemplate.loadWorkspaceTemplatesandworkspaceTemplates/globalTemplatesmemos.
- Inputs required:
client,workspaceStore.activeWorkspaceRoot,loadSessions,selectSession.defaultModel,modelVariant,setBusy,setBusyLabel,setBusyStartedAt,setError.- Tauri commands:
workspaceTemplateWrite,workspaceTemplateDelete.
- Pay attention:
- Preserve busy label values and error messages.
loadWorkspaceTemplatesis used bycreateWorkspaceStoreand must keep its signature.
- Check:
- Run
pnpm -C vendor/openwork test:refactor.
- Run
Step 3 - Update, reload, reset, cache repair
- Move to:
src/app/system-state.ts. - Move these items:
- Reload state,
reloadCopy,canReloadEngine,reloadEngineInstance. - Cache repair state and
repairOpencodeCache. - Update flow: check, download, install, auto-check state.
- Reset modal state and
confirmResetflow.
- Reload state,
- Inputs required:
client,mode,anyActiveRuns,refreshPlugins,refreshSkills.- Provider setters,
setError,safeStringify. - Tauri commands:
resetOpenworkState,resetOpencodeCache,updaterEnvironment.
- Pay attention:
- Reload gating must still block during active runs and non-host mode.
- Reset must still clear local storage before relaunch/reload.
- Check:
- Run
pnpm -C vendor/openwork test:refactor.
- Run
Step 4 - Provider and model selection
- Move to:
src/app/model-state.ts. - Move these items:
- Provider signals, default model, picker state.
modelOptions,filteredModelOptions, and picker helpers.
- Inputs required:
DEFAULT_MODEL,formatModelLabel,formatModelRef.sessionModelOverrideById,selectedSessionId,setSessionModelOverrideById.
- Pay attention:
- Keep sorting logic identical (connected and free first).
- Preserve default model fallback behavior when no providers are loaded.
- Check:
- Run
pnpm -C vendor/openwork test:refactor.
- Run
Step 5 - Preferences and local storage
- Move to:
src/app/preferences.ts. - Move these items:
onMountpreference hydration.- All
createEffectlocalStorage writes.
- Inputs required:
- Preference signals and setters (baseUrl, clientDirectory, engineSource, demo settings, model settings, update auto-check).
- Helpers and constants:
readModePreference,writeModePreference,parseModelRef,formatModelRef, preference keys.
- Pay attention:
- Keep legacy keys for compatibility (e.g.
openwork_mode_pref,openwork.projectDir). - Do not change any localStorage key names or value formats.
- Keep legacy keys for compatibility (e.g.
- Check:
- Run
pnpm -C vendor/openwork test:refactor.
- Run
Step 6 - View prop builders
- Move to:
src/app/view-props.ts. - Move these items:
headerStatus,busyHint,localHostLabelmemos.onboardingProps,dashboardPropsbuilders.
- Inputs required:
- Pass a single dependency object into
buildOnboardingPropsandbuildDashboardPropsto reduce imports.
- Pass a single dependency object into
- Pay attention:
- Every prop name must match the current view usage.
- Do not remove any callbacks or rename handlers.
- Check:
- Run
pnpm -C vendor/openwork test:refactor.
- Run
Step 7 - App.tsx cleanup
- Remove unused imports and reorder remaining imports.
- App.tsx should only create signals, wire factories, and render views/modals.
- Check:
- Run
pnpm -C vendor/openwork test:refactor. - Run
pnpm -C vendor/openwork test:e2e.
- Run
Attention Checklist (every step)
- Do not change view prop names or shapes.
- Keep all async flows, busy labels, and error messages identical.
- Keep all signals and memos created inside the App reactive scope.
- Avoid circular imports between new modules.
- If a move changes import order, re-run the test gate immediately.
Regression Checks (every step)
pnpm -C vendor/openwork test:refactor- Manual smoke (optional):
pnpm -C vendor/openwork dev:weband verify onboarding and dashboard render.
Acceptance Criteria
src/App.tsx<= 1100 lines.- All test gates pass after each step.
- Final
pnpm -C vendor/openwork test:e2epasses. - No UI or behavior changes.
Open Questions
- Should
test:refactorincludepnpm build:webfor extra safety? - Should the plan enforce a maximum module size to avoid new files getting too large?