15 KiB
| id | ticket | title | status | created | completed | tags | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| PLN-0037 | studio-project-local-studio-state-under-dot-studio | Project-local Studio state store and restoration | done | 2026-04-04 | 2026-04-04 |
|
Objective
Implement the first accepted wave of project-local Studio state persistence under .studio/, using a single-file project-session-owned store that restores setup, shell organization, and editor tabs for a project.
Background
DEC-0016 normatively locks the following:
- project-local Studio state must live under
.studio/in the project root; - the main store must be owned by
StudioProjectSession; - the main store must start as a single file;
- wave 1 must include project-local setup, shell layout, open shell/workspace state, and editor restoration;
- project-local activity must remain outside the main store;
- the policy is read on project-session open, restore on shell mount, and save on shell/project close;
- missing or invalid persisted state must fall back to safe defaults without blocking project open.
The current codebase already has a StudioProjectSession boundary plus a MainView shell and an EditorWorkspace with in-memory tab/session state, but it has no project-local persistence contract for those concerns.
Scope
Included
- Propagate DEC-0016 into Studio specifications.
- Introduce a project-session-owned single-file state store under
.studio/. - Load project-local setup when a project session opens.
- Restore shell layout and open shell/workspace state when the project shell mounts.
- Restore editor open tabs and active tab from project-local persisted state.
- Save the main project-session store when the shell or project session closes.
- Fall back to default values when persisted state is absent, unknown, or invalid.
- Add tests for store parsing, fallback behavior, session ownership, shell restoration, and editor tab restoration.
Excluded
- Project-local activity persistence changes.
- General autosave or global incremental persistence for the main store.
- Multi-file store layout under
.studio/. - New settings UI for project-local setup editing.
- Persistence of ephemeral hover state, derived cache, heavy logs, or recomputable operational output.
Execution Steps
Step 1 - Propagate DEC-0016 into Studio specs
What: Add normative spec coverage for the project-local Studio state store and its wave-1 boundaries.
How: Update the existing shell and editor specs, and add a dedicated Studio persistence spec if needed, so the repository explicitly states:
.studio/is the project-local root for the main Studio state store;StudioProjectSessionowns load/save lifecycle for the store;- the store begins as a single file;
- wave-1 categories are
projectLocalSetup,shellLayout,openShellState, andeditorRestoration; project-local activityis excluded from the main store;- read/restore/save policy and default fallback behavior are normative.
The preferred propagation shape is:
- update
docs/specs/studio/1. Studio Shell and Workspace Layout Specification.mdfor shell/session ownership and restore/save timing; - update
docs/specs/studio/5. Code Editor Workspace Specification.mdto replace the current “no cross-session tab restoration” rule with the accepted wave-1 restoration contract; - add a new dedicated spec such as
docs/specs/studio/8. Project-Local Studio State Specification.mdto hold the store schema boundary and exclusions.
File(s):
/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/studio/docs/specs/studio/1. Studio Shell and Workspace Layout Specification.md/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/studio/docs/specs/studio/5. Code Editor Workspace Specification.md/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/studio/docs/specs/studio/8. Project-Local Studio State Specification.md/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/studio/docs/specs/studio/README.mdif the new spec must be indexed
Step 2 - Define the project-session state store contract and single-file codec
What: Create the main persisted-state model and the single-file read/write boundary used by StudioProjectSession.
How: Introduce a small persistence module or package in prometeu-studio that defines:
- a versioned root DTO for the main state file;
- wave-1 category DTOs for
projectLocalSetup,shellLayout,openShellState, andeditorRestoration; - a file path convention under
.studio/; - loader/writer logic that returns safe defaults when the file is absent, unreadable, schema-incompatible, or invalid.
The implementation must keep project-local activity out of this file and must not broaden the schema to cache-like or transient UI data.
File(s):
/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/studio/prometeu-studio/src/main/java/p/studio/projectsessions/- a new package for state persistence such as
/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/studio/prometeu-studio/src/main/java/p/studio/projectstate/ - corresponding test files under
/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/studio/prometeu-studio/src/test/java/p/studio/
Step 3 - Extend StudioProjectSession to load setup and expose restorable state
What: Move the main store lifecycle into the project-session boundary.
How: Update StudioProjectSession and StudioProjectSessionFactory so opening a project session:
- loads the main store from
.studio/; - exposes the loaded state to shell/workspace consumers through explicit accessors or a dedicated session-owned state service;
- makes project-local setup available before workspace-specific UI mounts.
The session boundary must remain the owner of the persistence lifecycle; MainView and workspaces may consume the state but must not redefine load semantics.
File(s):
/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/studio/prometeu-studio/src/main/java/p/studio/projectsessions/StudioProjectSession.java/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/studio/prometeu-studio/src/main/java/p/studio/projectsessions/StudioProjectSessionFactory.java- any new project-session-owned state service under
/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/studio/prometeu-studio/src/main/java/p/studio/projectsessions/or/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/studio/prometeu-studio/src/main/java/p/studio/projectstate/
Step 4 - Restore shell layout and open shell/workspace state from the session store
What: Apply persisted shell organization when the project shell mounts and capture it again when the shell closes.
How: Update MainView and any shell controls it owns so they can:
- restore the selected/open workspace state from the session store instead of hardcoding the default assets workspace when persisted state exists;
- restore accepted shell layout properties such as splitter positions or equivalent shell-level geometry once the relevant shell surfaces are mounted;
- collect the latest shell state before the shell or project session closes so
save on closepersists the canonical snapshot.
If a specific shell surface does not yet expose restorable layout state, introduce the minimal shell-owned API needed to read/write that state without making the shell controls own persistence themselves.
File(s):
/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/studio/prometeu-studio/src/main/java/p/studio/window/MainView.java- shell controls under
/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/studio/prometeu-studio/src/main/java/p/studio/controls/shell/ - application/window close wiring where the current Studio shell lifecycle is finalized
Step 5 - Restore editor open tabs and active tab through an editor-owned snapshot contract
What: Persist and restore the editor workspace’s accepted wave-1 restoration state.
How: Refactor the editor workspace so it can:
- export a pure restoration snapshot containing open tab paths and active tab path;
- accept a restoration snapshot when the workspace mounts under a project session;
- reopen supported files through
prometeu-vfsusing those persisted paths; - fall back safely when a previously open file no longer exists or is no longer supported;
- preserve the active-tab choice when restoration succeeds.
This step must not broaden into persistence of editor-local transient data beyond what DEC-0016 accepts.
File(s):
/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/studio/prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorWorkspace.java/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/studio/prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorOpenFileSession.java/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/studio/prometeu-studio/src/main/java/p/studio/workspaces/editor/EditorTabStrip.javaif small UI adjustments are needed for restore-first behavior
Step 6 - Wire save-on-close and category-scoped checkpoints if any are required
What: Make the accepted save policy real in the application lifecycle.
How: Ensure the main store is serialized:
- when the project shell closes;
- and when the project session closes through its normal lifecycle.
Do not introduce general autosave for the main store. Only add checkpoint saves if a specific accepted category proves it cannot safely rely on close-time persistence alone, and keep that logic isolated to that category.
File(s):
/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/studio/prometeu-studio/src/main/java/p/studio/window/MainView.java/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/studio/prometeu-studio/src/main/java/p/studio/projectsessions/StudioProjectSession.java- any shell/window lifecycle integration surface that currently owns project-window close behavior
Step 7 - Add tests for defaults, restoration, and persistence boundaries
What: Lock the decision through automated tests.
How: Add tests that verify:
- missing
.studio/falls back to defaults; - invalid or schema-incompatible persisted content falls back to defaults;
- project-local setup is loaded at project-session open;
- shell/workspace state is restored from persisted state when present;
- editor open tabs and active tab restore correctly;
project-local activityis not part of the main store contract;- saving the main store happens on the accepted close boundary.
File(s):
/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/studio/prometeu-studio/src/test/java/p/studio/projectsessions//Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/studio/prometeu-studio/src/test/java/p/studio/window//Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/studio/prometeu-studio/src/test/java/p/studio/workspaces/editor/- tests for the new persistence package under
/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/studio/prometeu-studio/src/test/java/p/studio/projectstate/
Test Requirements
Unit Tests
- Persisted-state codec tests for versioned single-file read/write behavior.
- Fallback tests for absent, invalid, and schema-incompatible state files.
- Session-service tests proving default values are exposed when persisted state is unusable.
- Editor snapshot tests proving only open-tab paths and active-tab identity are persisted.
Integration Tests
StudioProjectSessionFactorytests that verify setup is loaded during session open.- Shell or window tests that verify persisted workspace selection and shell state are applied on mount.
- Editor workspace tests that reopen tabs from persisted paths and preserve the active tab when possible.
- Close-lifecycle tests that verify the main store is written when the shell or session closes.
Manual Verification
- Open a project with no
.studio/state and confirm the Studio boots with defaults. - Configure project-local setup such as a Prometeu runtime path, close the shell, reopen the project, and confirm the setup is restored.
- Open multiple editor tabs, switch the active tab, close the project, reopen it, and confirm the same tabs and active tab are restored.
- Change shell/workspace organization that is in scope for wave 1, close the project, reopen it, and confirm that layout/workspace state is restored.
- Corrupt or remove the persisted state file and confirm the project still opens with defaults instead of failing.
Acceptance Criteria
- Studio specs normatively describe the
.studio/single-file project-session store and its exclusions. StudioProjectSessionowns loading of project-local setup and access to the main state store.- The main store is persisted as a single file under
.studio/. - Wave-1 categories are implemented without admitting excluded categories such as activity history or derived cache.
- Shell/workspace state restores on shell mount and saves on shell/project close.
- Editor open tabs and active tab restore from persisted project-local state.
- Missing or invalid persisted state falls back to safe defaults without blocking project open.
Dependencies
- Accepted decision
DEC-0016-project-local-studio-state-under-dot-studio.md - Existing project-session boundary in
/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/studio/prometeu-studio/src/main/java/p/studio/projectsessions/ - Existing editor tab/session behavior in
/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/studio/prometeu-studio/src/main/java/p/studio/workspaces/editor/
Risks
- The current shell controls may not yet expose enough structured state to restore all accepted wave-1 layout fields cleanly.
- Editor restoration may need a small refactor to separate pure restore snapshots from current UI-driven open-file behavior.
- A new persistence spec may overlap with current shell/editor specs unless propagation boundaries are written carefully.
- Save-on-close behavior may depend on application/window lifecycle code not yet centralized in one obvious surface.