refactor(studio): decompose App.tsx non-React corpus into feature modules and shared utilities#1608
Merged
Merged
Conversation
This was referenced Jun 12, 2026
Owner
Author
|
Railway preview (MapGen Studio): not provisioned for this PR. Policy (Graphite stacks): previews are created only for the top-of-stack PR by default.
Debug: |
This was referenced Jun 12, 2026
Merged
This was referenced Jun 12, 2026
Merged
mateicanavra
force-pushed
the
design/app-decompose
branch
from
June 12, 2026 20:44
62008f3 to
5af226e
Compare
Owner
Author
Merge activity
|
mateicanavra
changed the base branch from
design/shell-reskin
to
graphite-base/1608
June 12, 2026 20:55
…g extraction Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… feature modules
Behavior-preserving MOVE of the ~535 LoC of non-React helpers from the top of
App.tsx into focused feature modules. No logic changes: every helper is byte-for-
byte identical, only relocated, and App.tsx re-imports them.
- features/mapConfigSave/api.ts: toConfigId, saveRepoBackedConfig,
fetchMapConfigSaveDeployStatus, MAP_CONFIG_SAVE_LAST_REQUEST_KEY
- features/runInGame/{api,sourceSnapshotStorage,liveSource}.ts
- features/civ7Setup/{api,setupOptions,livePreset}.ts
- features/configOverrides/configBuilders.ts (merge/path/config builders)
- features/presets/{repoBacked,dialogState}.ts
- shared/{async,number}.ts
localStorage key strings preserved verbatim (persistence contract). tsc clean;
prod build + worker-bundle check pass.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ever hand-roll fetch User directive 2026-06-09. Studio talks to CIV through the control-oRPC client + contract behind one typed LiveControlPort (oRPC-native TanStack Query; studio-server proxies control-oRPC, never re-implements CIV API calls). No new manual /api fetch; existing /api/civ7/* middleware wrapped behind the port then deleted when the client lands. No FireTuner. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…C too, server un-deferred User reaffirmed: no manual fetch of our own /api either. Studio exposes its own effect-orpc contract+server (contracts already scaffolded), client consumes via oRPC client + oRPC-native TanStack Query. Server NOT deferred (uses direct-control, on main). Existing /api lifted verbatim into effect-orpc procedures (parity); Bun topology + prod parity = later supervised step. Data layer precedes decomposition. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
mateicanavra
force-pushed
the
design/app-decompose
branch
from
June 12, 2026 20:57
5af226e to
e4e7c87
Compare
This was referenced Jun 12, 2026
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.

This PR performs a behavior-preserving structural extraction of the non-React helper corpus from
App.tsxinto focused feature modules, reducing the file from a 3,000+ line god-module to a leaner authoring closure.The ~535 lines of inline helpers — fetch wrappers, config builders, deterministic merge/path utilities, preset adapters, Civ7 setup option helpers, localStorage key constants, and shared predicates — are moved verbatim into named modules under
features/*andshared/:features/mapConfigSave/api.ts—toConfigId,saveRepoBackedConfig,fetchMapConfigSaveDeployStatus,MAP_CONFIG_SAVE_LAST_REQUEST_KEYfeatures/runInGame/api.ts—runCurrentConfigInGame,fetchRunInGameStatusfeatures/runInGame/sourceSnapshotStorage.ts—readStoredRunInGameSourceSnapshotand theRUN_IN_GAME_LAST_*localStorage keysfeatures/runInGame/liveSource.ts—liveSourceMatchesStudio,LastRunSnapshotfeatures/civ7Setup/api.ts—fetchCiv7SetupConfig,fetchCiv7SavedSetupConfigs,fetchCiv7SetupCatalog,requestCiv7Autoplay, and theCiv7SetupCatalogtypesfeatures/civ7Setup/setupOptions.ts—findSetupParameterLike,ensureSelectOption,mergeSelectOptions,setupCatalogOptionsfeatures/civ7Setup/livePreset.ts—LIVE_GAME_PRESET_ID,LIVE_GAME_PRESET_KEYfeatures/configOverrides/configBuilders.ts—isPlainObject,mergeDeterministic,setAtPath,buildConfigSkeleton,buildDefaultConfig,applyPresetConfig,formatPresetErrors, and related typesfeatures/presets/repoBacked.ts—mergeBuiltInPresets,toRepoBackedPresetfeatures/presets/dialogState.ts—PresetErrorStateshared/async.ts—delay,isAbortLikeErrorshared/number.ts—clampNumberApp.tsxreplaces all inline definitions with imports. No logic is rewritten; theAppContentclosure is unchanged except at import sites. localStorage key strings are preserved verbatim to maintain the persistence contract across dev-server reloads.An accompanying OpenSpec change set documents the decomposition design, requirements, and task checklist. The FRAME constraint document is updated to record the directive that all API communication must go through oRPC rather than hand-rolled
fetch, with the existing/api/*middleware to be lifted into effect-orpc procedures in a later supervised step.The container/presentational store-reading split for
RecipeConfigPanel,ExploreController, andAppFooteris explicitly deferred to the post-stores decomposition slice, as it depends on the not-yet-landed Zustand/TanStack Query client-data layer.