refactor(hooks): dissolve src/hooks/workStation into owning modules - #821
Merged
Conversation
Delete hooks with zero consumers: workStation/indexing (2 hooks), workStation/search (useCodeSearch + duplicate latestRequestGuard), usePanelResize, useTabSwitchVerification, benchmark/useBenchmarkRun, and src/hooks/index.ts (unreferenced barrel re-exporting engines/).
UseOutputChannelsReturn and UseTaskOutputIntegrationReturn now live in types/workstation/output.ts; useGitOutputIntegration/types.ts moves to types/workstation/gitOutputIntegration.ts. store/ atoms and services/guiAgent no longer import from src/hooks (inverted edges), and the hooks import their own return contracts from types/.
hooks/workStation was a module-named subtree in the global hooks layer;
~60 of its files had exactly one consumer area. Files now live next to
their consumers:
- hooks/tabHost/ cross-cutting tab-host contract hooks (tabs,
header publish, panels, shortcut bridge)
- modules/WorkStation/CodeEditor/hooks/ editor, fileContent, diagnostics,
output, gitOutputIntegration, useCodeEditor
- modules/WorkStation/Browser/hooks/ browser pane/session hooks
- modules/ useNarrowChatFocus, useOpenUrlInBrowser
- features/SessionSetup/hooks/ session capture / OAuth capture
- scaffold/ContextMenu/ useContextMenu + search handlers/roots
- engines/GitWorkflow/GitHubDiff/useDiff.ts
- util/core/latestRequestGuard.ts
- DbPreviewView/ useDbPreview + utils next to sole consumer
All per-group barrels removed; consumers import files directly.
- hooks/dependencies -> modules/MainApp/Integrations/hooks (useSystemDependencies,
usePrerequisiteCheck) and app/root/usePostPaintGitProbe.ts
- hooks/git/sourceControl -> modules/WorkStation/CodeEditor/hooks/sourceControl;
generateCommitMessage (a bare invoke wrapper) -> api/tauri/git/commitMessage.ts
so the ChatPanel test does not import from modules/
- hooks/testRunner -> modules/WorkStation/CodeEditor/hooks/useTestRunner.ts
- hooks/benchmark -> features/BenchmarkPanel/hooks (WorkStation sidebar imports the feature)
Group barrels removed; consumers import files directly.
no-restricted-imports blocks @src/hooks/{workStation,dependencies,
git/sourceControl,testRunner,benchmark} with messages naming the new
homes, so in-flight branches get a pointer on rebase. util-organization.md
gains the hooks placement rules and drops its dead hooks-organization link.
10 tasks
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
src/hooks/workStation/(78 files, the largest subtree in the global hooks layer) into the modules that own each hook; same treatment forhooks/dependencies,hooks/git/sourceControl,hooks/testRunner,hooks/benchmark.src/hooks/tabHost/for the workstation tab-host contract (useWorkStationTabs,usePublishWorkstationTabHeader,useWorkStationPanels, shortcut bridge, …) — the only part of the old dir that is genuinely consumed by WorkStation, ProjectManager, MainApp, features and engines.store/andservices/depend on move tosrc/types/workstation/{output,gitOutputIntegration}.ts.no-restricted-importstripwire on the old paths, with messages pointing at the new homes.Problem
A static import-graph pass over
src/showedsrc/hooks/— nominally the global hooks dir — had drifted into a dumping ground:hooks/workStation/was a module named aftermodules/WorkStationliving in the global layer. ~60 of its 78 files had exactly one consuming area; the top-level barrel hid this (40 files imported through it, and the barrel itself carried a "DO NOT re-export browser — circular deps" warning).indexing/,search/useCodeSearch,usePanelResize,useTabSwitchVerification, a duplicatedlatestRequestGuard), plus an orphansrc/hooks/index.tsre-exporting fromengines/.hooks → modules/WorkStation/Browser,hooks → scaffold/ContextMenu,hooks → CodeEditor/…/ProblemsContent, andstore → hooks/services → hooksvia hook return types.hooks/dependencies(MainApp),hooks/git/sourceControl+hooks/testRunner(CodeEditor),hooks/benchmark(BenchmarkPanel).Solution
Five commits, each independently typechecking, reviewable in order:
Dead code — delete the zero-consumer hooks and the orphan
hooks/index.ts.Contracts out of hooks —
UseOutputChannelsReturn/UseTaskOutputIntegrationReturn→types/workstation/output.ts;useGitOutputIntegration/types.ts→types/workstation/gitOutputIntegration.ts.store/…/{gitOutputAtom,taskOutputAtom}andservices/guiAgentnow import types, not hooks.Dissolve
hooks/workStation—git mvper this map, then a codemod that splits barrel imports per symbol and recomputes relative imports in moved files:src/hooks/workStation/…)tabs/*,useWorkstationTabHeader,useWorkStationTabShortcutBridge,panels/useWorkStationPanelssrc/hooks/tabHost/editor/*,useCodeEditor/,fileContent/,diagnostics/,output/,useGitOutputIntegration/,git/useGitDiffStatemodules/WorkStation/CodeEditor/hooks/browser/useBrowserPaneState,useBrowserSessions,browserDiagnosticsPolicymodules/WorkStation/Browser/hooks/database/*…/FilePreviewContent/DbPreviewView/(sole consumer)sessionCapture/*features/SessionSetup/hooks/panels/useContextMenu,contextMenuSearch{Handlers,Roots}scaffold/ContextMenu/git/useDiffengines/GitWorkflow/GitHubDiff/(sole consumer)useNarrowChatFocus,browser/useOpenUrlInBrowsersrc/modules/(sole consumermodules/index.tsx)latestRequestGuardutil/core/Wave 2 —
dependencies→modules/MainApp/Integrations/hooks/(+usePostPaintGitProbe→app/root/);git/sourceControl+testRunner→CodeEditor/hooks/;benchmark→features/BenchmarkPanel/hooks/;generateCommitMessage(a bareinvokewrapper) →api/tauri/git/commitMessage.tsso the ChatPanel test that exercises it does not import frommodules/.Guard + docs —
no-restricted-importsentry in.eslintrc.js; hooks placement rules added tosrc/util/util-organization.md(deadhooks-organization.mdlink fixed).Placement rules applied uniformly: single consumer area → colocate; cohesive family over one store stays together (
useFocusTab/usePinnedTabs/useSelectedFilego totabHostwithuseWorkStationTabs); generic primitive →util/; no new barrels; never create an upward edge (extract the type/API wrapper instead).hooks/fileReviewwas considered and kept — it is consumed byengines/ChatPanel/ChatView.tsxplus two modules, so it is genuinely cross-cutting.Potential risks
@src/hooks/workStation…,@src/hooks/dependencies…,@src/hooks/git/sourceControl…,@src/hooks/testRunner…or@src/hooks/benchmark…will fail lint/typecheck on rebase. The newno-restricted-importsmessage names the replacement path for each group. Bulk of the churn is a mechanical import rewrite; no runtime logic changed.vi.mocksites that mocked the barrel now mock the specific file (CanvasApp*.test.ts,GitHistoryContent.remount.test.ts).useFileContent.tsnow underCodeEditor/hooks/{fileContent,useCodeEditor}/; duplicateOutputChannelinterface intypes/workstation/gitOutputIntegration.tsvsoutput.ts; three loose hooks still atCodeEditor/root;gitDiffActions.test.tsassertinggenerateCommitMessage.Test plan
pnpm typecheck— 0 errors (also gated per commit by the pre-commit hook)pnpm lintoversrc/— 0 errors, including the newno-restricted-importsrulepnpm test— 1099 test files / 8680 tests pass; the 31 relocated test files are discovered at their new pathssrc/hooks/328 → 238 files, single-consumer 91 → 59, orphans 14 → 6; layer-inverted edges 111 → 101 (10 removed, 0 added — diffed edge by edge); zero remainingstore/services → hooksedges from the moved setrgfor the old paths acrosssrc/**→ only the eslint tripwire and the doc mention themSubmit checklist
feat(scope): summaryorfix(scope): summary.