Extract GlobalConfig store from WorktreeApi.fs#88
Open
0101 wants to merge 8 commits into
Open
Conversation
Planning spec for code-improvement candidate #7: lift the ~250-line machine-level config.json read/modify/write block out of WorktreeApi.fs into a dedicated Server.GlobalConfig module. Behavior-preserving; atomic move with all consumers retargeted (no compat shims).
…retarget all consumers Extract machine-level config.json I/O from WorktreeApi.fs into new Server.GlobalConfig module (263 lines); retarget all consumers (Program.fs 3 refs, 4 test files) in one atomic change with no compat shims. WorktreeApi.fs 870->614 lines.
…tion Docs-only spec hygiene after the GlobalConfig extraction: - worktree-monitor.md Key Files: add GlobalConfig.fs row (config.json store + typed accessors), retarget WorktreeApi.fs row to IWorktreeApi wiring + DashboardResponse assembly. - code-improvements.md: move candidate #7 to Done with one-line summary + spec link; fix the now-dangling row-5 cross-reference; keep #8's stable ID.
…-monitor parent spec (spec-hygiene) Folded the durable config-store invariants (single serialized writer + atomic temp-file replace, never-destroy-data/corrupt-backup, typed accessors over one store) into worktree-monitor.md Expected Behavior and added a GlobalConfig vs TreemonConfig Decisions bullet. Deleted the stale extraction-plan spec global-config-store.md and repointed the code-improvements.md Done entry. Sibling task Spec: pointers retargeted in beads.
…path with no parent directory (defensive, Low) Added a ot (String.IsNullOrEmpty dir) guard so directory creation is skipped (rather than attempted-and-caught) when the config path has no parent directory. Trigger is unreachable for current callers; defensive hardening only per focused-review finding 2.
There was a problem hiding this comment.
Pull request overview
This PR extracts the machine-level configuration store (~/.treemon/config.json read/modify/write) out of the oversized WorktreeApi.fs into a new dedicated src/Server/GlobalConfig.fs module. It is a behavior-preserving refactor — the config format, locking, atomic-write semantics, missing-vs-empty worktreeRoots distinction, and IWorktreeApi responses are unchanged. It fits the codebase's ongoing "view/state extraction" effort (candidate #7 from the code-improvement survey) by separating config persistence from IWorktreeApi wiring and DashboardResponse assembly.
Changes:
- New
GlobalConfig.fsowningconfig.json(single-writer lock, atomic temp-file replace, typed accessors); moved symbols widened fromprivatetointernalso cross-module call sites resolve. WorktreeApi.fsslimmed (~870 → 605 lines) to API wiring +DashboardResponse, nowopen Server.GlobalConfig;Server.fsprojcompilesGlobalConfig.fsbeforeWorktreeApi.fs.- Consumers retargeted with no compat shims:
Program.fsplus tests (ConfigWriterTests,WorktreeRootsConfigTests,ServerStartupResolutionTests,SmokeTests); a smallupdateConfigAtPathhardening (skip dir creation when the path has no parent); docs updated.
Show a summary per file
| File | Description |
|---|---|
src/Server/GlobalConfig.fs |
New module owning config.json; moved accessors/writers, now internal; adds empty-dir guard in updateConfigAtPath |
src/Server/WorktreeApi.fs |
Removes the config block, adds open Server.GlobalConfig; call sites use unqualified moved functions |
src/Server/Server.fsproj |
Adds GlobalConfig.fs to compile order before WorktreeApi.fs |
src/Server/Program.fs |
Retargets globalConfigDir/tryReadWorktreeRootsConfig/writeWorktreeRoots to GlobalConfig |
src/Tests/ConfigWriterTests.fs |
open switched to Server.GlobalConfig |
src/Tests/WorktreeRootsConfigTests.fs |
open switched to Server.GlobalConfig |
src/Tests/ServerStartupResolutionTests.fs |
Qualified refs switched to Server.GlobalConfig |
src/Tests/SmokeTests.fs |
Comment updated to reference GlobalConfig.globalConfigDir |
docs/spec/worktree-monitor.md |
Adds Configuration Store section, Key Files rows, and GlobalConfig vs TreemonConfig decision |
docs/spec/future/code-improvements.md |
Records survey findings; moves #7 to Done (one inaccurate line count) |
Review details
- Files reviewed: 10/10 changed files
- Comments generated: 1
- Review effort level: Medium
| - **`GlobalConfig` store extraction** — lifted the machine-level `~/.treemon/config.json` | ||
| read/modify/write (single-writer lock, atomic temp-file replace, missing-vs-empty | ||
| `worktreeRoots` semantics, plus the canvas / collapsed-repos / last-viewed-hashes / editor | ||
| accessors) out of `WorktreeApi.fs` (870 → 614 L) into `src/Server/GlobalConfig.fs`, leaving the |
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.
Problem
src/Server/WorktreeApi.fswas the largest production module (870 lines) and mixed four concerns: machine-level config persistence,DashboardResponseprojection, worktree actions, andIWorktreeApiwiring. Roughly 250 of those lines were the machine-level~/.treemon/config.jsonread/modify/write store — and that concern already had its own test suites (ConfigWriterTests.fs,WorktreeRootsConfigTests.fs), so the boundary existed; the code just lived in the wrong module.This is candidate #7 from the code-improvement survey on this branch (the same view/state extraction lens that drove the earlier
App.fswork).Changes
Behavior-preserving extraction — no config format, key semantics, locking, atomic-write, or
IWorktreeApiresponse changes.src/Server/GlobalConfig.fs(263 L,module Server.GlobalConfig) — ownsconfig.json: the single-serialized-writer lock + atomic temp-file-then-replace (updateConfigAtPath), the missing-vs-emptyworktreeRootssemantics the startup resolver depends on, and the typed accessors (watched roots, canvas pane open/position, collapsed repos, last-viewed hashes, editor command/name). Module-private helpers stayprivate; the externally-consumed surface isinternal.src/Server/WorktreeApi.fs870 → 605 lines — left with justIWorktreeApiwiring +DashboardResponseassembly, calling the moved functions viaopen Server.GlobalConfig.src/Server/Server.fsproj—GlobalConfig.fscompiles beforeWorktreeApi.fs.Program.fs(startup roots resolver) and the test filesConfigWriterTests.fs,WorktreeRootsConfigTests.fs,ServerStartupResolutionTests.fs,SmokeTests.fs.updateConfigAtPathskips directory creation when the config path has no parent dir, rather than attempting-and-catching.worktree-monitor.mdgains aConfiguration Storesubsection + aGlobalConfigvsTreemonConfigdecision and an updated Key Files table;code-improvements.mdrecords the survey findings and moves Parallel startup burst + fix branch event key mismatch #7 to Done.Tests
Full suite green on the final commit (independently re-run by the verification reviewer):
GlobalConfig.fsholds the moved symbols; the moved definitions are gone fromWorktreeApi.fs(proving a move, not a copy); line count dropped ~265.A focused-review quality gate ran over the branch diff (19 rules + 3 concern models) — 2 actionable findings, both fixed in this PR; the rest were verbatim-move/pre-existing false-positives.