Promote §6.4 from three loose rules to the full barrel contract (re-export-only, enforced-sole-entry-or-no-barrel, no nesting, one-cohesive-unit) and point shared §3.1 / main §2.1 / renderer §5 at it, fixing main's stale pointer to shared. Reserve the index filename for barrels — always index.ts, never .tsx outside routes/ — with implementations in named files; add the renderer component-directory form and align §4.2's component test. Note what the contract does not remove: dev builds load a barrel's full graph (rule 4 is the bound), and dynamic import() crosses a boundary through the barrel, with the React.lazy form in renderer §5. Docs only; lint enforcement and call-site fixes follow.
Replace the fuzzy business-orchestration routing criterion with an outward-side-effects test: stateless shared modules default to utils/ and promote to services/ only for a stated reason (side effects, or a forced services import).
Rekey the Service/Manager suffix from stateful classes to stateful singleton capabilities, mechanism-independent: module-scope mutable state must take the class + singleton form, multi-instance helper classes take no suffix, and what counts as state is defined.
Codify renderer services/<topic>/ topic directories (single barrel entry, private topic-specific satellites exempt from shape routing, no UI) mirroring the existing main-process rule, and add the middle growth step to Naming 4.10.
Align residual wording across the three docs: same-kind peering edges in the renderer dependency table, the section-6 corollary vs its own worked example, quick-reference suffix note, utils charter and examples.
Re-sync the "Target vs Current State" section with the code after the
dependency-cleanup landed. §8 now tracks only what is still unfinished:
- Drop the "Already aligned" list and the six resolved deviations
(config/, queue/, components/app/Navbar, the utils/ root barrel, and
the "Boundary enforcement: none" row) -- once resolved they no longer
violate the target, so they need not appear.
- Correct the components/app/Sidebar row: it is not dead code. It is
rendered by components/layout/AppShell.tsx (main-window shell), so it
folds into the App-shell row and moves to windows/main with that shell.
- Sync the enforcement status in §5 and §8: the import/no-restricted-paths
gate is live -- shared-layer edges at error, pages -> pages at warn -- and
the remaining pages -> pages coupling is ~13, not ~35.
- Keep only the still-open half of the barrel item: utils/message/ still
needs a curated index.ts.
Add a maintenance note so resolved deviations are dropped, not recorded
as done -- the "already aligned" list is what rots.
Record the placement rule settled during the renderer cleanup: utils/ is
stateless and domain-agnostic and MAY import downward infra
(data/ipc/workers), while services/ owns state/lifecycle or performs
business/domain orchestration. A helper touching infra is still a helper;
the decisive test is role, not purity.
- renderer-architecture.md: co-equal utils/data/ipc/workers foundation
(§2); positive service identity and the revised utils row (§3).
- naming-conventions.md §5.2: add the stateless-orchestration -> services
routing row; note utils may call downward infra.
- main-process-architecture.md: Pure -> Stateless; route by role.
Move the renderer-side AI-streaming runtime (IpcChatTransport,
TopicStreamSubscription, streamDispatchCoordinator) out of the top-level
src/renderer/transport/ directory into the shared services/aiTransport/
bucket. By shape these are stateful runtime singletons/classes, and the
runtime is cross-surface (consumed by chat, quick-assistant, selection),
so per the renderer architecture it routes into services/, not its own
top-level directory.
- Add a curated index.ts barrel exposing only the externally consumed
symbols (ipcChatTransport, TopicStreamSubscription, ExecutionTerminal);
the class, dispatch coordinator and helpers stay private.
- Update the 6 consumer sites (5 imports + 1 vi.mock) to the barrel.
- Sync architecture and AI docs to the new path; drop the now-resolved
transport/ deviation from the renderer-architecture pending table.
Eliminate src/renderer/config entirely, completing the §8 dissolution
started in 1065cd4dfd. The two remaining files held a mix of genuinely
app-global constants, domain-owned constants, and v1 dead code.
- Add utils/platform.ts for the platform predicates (platform/isMac/
isWin/isLinux/isDev/isProd) and repoint ~60 cross-domain consumers.
- Relocate domain constants to their owners: LONG_TEXT_PASTE_THRESHOLD
-> composer/composerPaste; knowledge defaults -> knowledge/rag;
THEME_COLOR_PRESETS + defaultByPassRules -> CommonSettings;
MAX_COLLAPSED_CODE_HEIGHT -> CodeBlockView/constants;
API_SERVER_DEFAULTS -> ApiGatewaySettings; SiliconFlow/PPIO client ids
+ TOKENFLUX_HOST -> utils/oauth (kept below the consuming pages layer);
occupiedDirs -> BasicDataSettings (still @deprecated v1).
- Dissolve env.ts: inline the APP_NAME literal at AboutSettings and
import the avatar/logo PNGs directly at each consumer; drop the now
obsolete config/env test mocks (Vite resolves the assets natively).
- Delete v1 dead constants with no consumers (DEFAULT_TEMPERATURE,
DEFAULT_CONTEXTCOUNT, SYSTEM_PROMPT_THRESHOLD, message-count caps,
context caps, DEFAULT_STREAM_OPTIONS_INCLUDE_USAGE).
- Update renderer-architecture (§3/target layout/§8) and the preboot
doc/comment references that pointed at the old occupiedDirs location.
State the previously-implicit rules that produced "features is an isolated
island" misreadings, then tighten the result for concision:
- Make explicit that the app layer (windows/routes/pages) is a feature's
only legal consumer (window/page -> feature are legal downward edges); a
feature is isolated only horizontally, from sibling features.
- Add the same-kind-peering vs same-slice-isolation distinction
(component -> component allowed; feature -> feature not) and note that a
feature-internal piece follows identical type-axis rules as its top-level
counterpart.
- Add a 4.1 Promotion Rule with an operational trigger and a
chat -> features/chat worked example; fix the dangling 4.4 references.
- Add the DAG rationale for the two banned edges (shared -> feature,
feature -> feature).
- Fix small inconsistencies: pages/ may depend on primitives; shared-layer
order includes workers; disambiguate bare (4.8) -> (Naming Conventions
4.8); reclassify transport/ as a cross-surface ai runtime (not
chat-exclusive) bound for the shared services/ bucket.
Also clean up two dead command mocks targeting the non-existent
@renderer/features/command path: fix the stale path in TopicBranchPanel's
test so the mock intercepts the real @renderer/components/command import,
and drop the unused mock in GlobalSearchPanel's test.
The context/ directory was a by-kind bucket: React providers are
components, not their own layer. Dissolve it per renderer-architecture
section 8 by splitting each provider into its component (-> components/)
and its context object + accessor hooks (-> hooks/), mirroring the
existing command decomposition.
- ThemeProvider -> components/ThemeProvider.tsx + hooks/useTheme.ts
- CodeStyleProvider -> components/CodeStyleProvider.tsx + hooks/useCodeStyle.ts
- Tab behavior layer -> hooks/tab/ (useTabsContext, useCurrentTab,
useTabSelfMetadata, useTabs, index); TabsProvider/TabIdProvider ->
components/layout/
- Extract pure emoji-icon logic to utils/tabIcons.ts
- Remove dead TabsContextValue ops (hibernateTab/wakeTab/setTabs) and a
stale ThemeProvider comment
- Repoint ~90 import sites and test mocks; migrate provider/hook tests
- Update routes README and renderer-architecture section 8
With ImportService migrated to DataApi (#16415), the v1 Redux store at
src/renderer/store/ has zero runtime consumers. Delete the directory (30
files) along with the already-stubbed main-process ReduxService bridge.
Clean up the now-stale residue:
- Remove dead vi.mock('@renderer/store') factories from 14 test files
whose code under test no longer imports the store.
- Drop Redux from the CLAUDE.md "Removing" enumerations and refresh the
renderer-architecture / knowledge-service / v2-todo docs.
- Fix dangling store/ references in the MiniAppMigrator and
builtinMcpServers comments.
The v2 migration's Redux Persist readers (ReduxStateReader etc.) are left
untouched: they read serialized on-disk data, not this store.
Dissolve the renderer types/index.ts re-export barrel (Phase 2):
- Repoint 252 consumers to @renderer/types/<topic> (intra-types files use
relative ./topic); covers @renderer/types, @types, and the equivalent
'./', './index', '@renderer/types/index' specifier forms.
- Delete src/renderer/types/index.ts.
- Remove the @types alias from tsconfig.web.json, electron.vite.config.ts,
and the eslint main/preload boundary guard.
- Retire the resolved types-barrel and @types deviations from the renderer
and main architecture docs.
main-process-architecture.md §3: state the no-renderer-imports rule (src/main + src/preload must not import renderer code; cross-process types → @shared, main-only → src/main), now enforced by the ESLint no-restricted-imports rule; clarify that the existing 'no automated enforcement yet' note refers to the internal direction edges. §7: track the lone remaining exception — main/utils/language.ts's relative renderer i18n import, deferred to the i18n migration PR.
renderer-architecture.md §7: add the anti-pattern of importing a shared bucket root (@renderer/utils, @renderer/types) instead of the specific file/topic, or giving types/ or utils/ a re-export root index.ts.
Mirror Shared Layer Architecture §3.1 onto the renderer top-level type buckets: types/ and utils/ are categories, not modules, so they carry no root index.ts. Consumers import @renderer/<bucket>/<topic>; a multi-file topic exposes a single curated index.ts with named exports and no wildcard re-export (export *).
Record the current deviations as §8 migration items: the types/ and utils/ root barrels, and the redundant @types alias (dissolve in favor of @renderer/types/<topic>).
Move the four ad-hoc top-level @shared dirs into the closed top-level set, routed by shape: pure logic + class blueprints to utils/, type/contract declarations to types/.
command -> utils/command + types/command; file -> utils/file + types/file; shortcuts -> utils/shortcut + types/shortcut; externalApp -> utils/externalApp + types/externalApp.
Replace the exported menuRegistry singleton with a pure resolveMenu over a frozen contribution set (Invariant 1.2: no exported instance); keep MenuRegistry as a per-process blueprint sharing the same resolve algorithm.
Rewrite all consumer imports per symbol origin and align shared-layer-architecture and renderer-architecture docs.
Add docs/references/shared-layer-architecture.md as the authoritative reference for src/shared: two invariants (cross-process; no mutable runtime state), the closed top-level set {ai, data, ipc, types, utils} by category, types/utils shape rules (single-file vs subdirectory, barrels, constants guardrail), the placement decision, anti-patterns, and a deferred migration section (config dissolution with constant.ts itemized).
Relocate @shared-internal rules out of renderer-architecture.md and architecture-overview.md into the new doc (leaving pointers); repoint command's cross-process cell to @shared/utils/command + @shared/types/command in renderer-architecture sections 6 and 8; link the per-root applications of the closed-top-level rule from naming-conventions section 4.8.
- Emphasize cross-process as the entry gate for @shared; single-process logic stays in its own layer (plain shared types excepted). Mirror as a summary in architecture-overview.
- Refine the command-capability example to decompose by shape across @shared/command, utils/command, hooks/command, and components/command; update the §8 alignment/coupling notes for the resolved component/hook → feature edges.
Add docs/references/renderer-architecture.md as the canonical reference for src/renderer organization: the two-axis model (type x domain), four-layer downward dependency direction, per-directory responsibilities, the features/ definition, curated-barrel public API with import/no-restricted-paths enforcement, closed top-level governance, anti-patterns, a target-vs-current-state section, and industry references.
Align the existing docs: collapse the renderer subtree in architecture-overview.md to a pointer, and in naming-conventions.md list renderer services/ in the type-bucket set and link features/ placement to the new doc.