diff --git a/docs/development.md b/docs/development.md index fc425808..599502b0 100644 --- a/docs/development.md +++ b/docs/development.md @@ -7,34 +7,30 @@ npm run check npm run build ``` -Run `npm run format` after edits and before `npm run check` so Prettier-only issues are fixed upfront. `npm run check` runs TypeScript type checking, unit tests, lint checks, Prettier check, CSS build verification, and a production esbuild bundle. -The local `npm run check` path runs checks in parallel and uses local caches where available. Use `npm run check:ci` when you need to reproduce the sequential, non-cached CI validation path. +Run `npm run format` after edits and before `npm run check` so Prettier-only issues are fixed upfront. `npm run check` runs TypeScript type checking, unit tests, lint checks, Prettier check, CSS build verification, and a production esbuild bundle. The local `npm run check` path runs checks in parallel and uses local caches where available. Use `npm run check:ci` when you need to reproduce the sequential, non-cached CI validation path. -`main.js`, `styles.css`, `data.json`, and `node_modules/` are ignored by Git. `main.js` and `styles.css` are still the files Obsidian loads, so run `npm run build` after source changes. -CSS is authored in `src/styles/` and generated into the ignored root `styles.css` release asset. Use `npm run build:styles` when only regenerating CSS, or `npm run build:styles:check` to verify that the authored CSS can be rendered. +`main.js`, `styles.css`, `data.json`, and `node_modules/` are ignored by Git. `main.js` and `styles.css` are still the files Obsidian loads, so run `npm run build` after source changes. CSS is authored in `src/styles/` and generated into the ignored root `styles.css` release asset. Use `npm run build:styles` when only regenerating CSS, or `npm run build:styles:check` to verify that the authored CSS can be rendered. ## Source Layout The source tree is organized by responsibility rather than by the original single Obsidian plugin entrypoint: - `src/main.ts` registers Obsidian views, commands, settings, and lifecycle hooks. -- `src/app-server/` owns the app-server boundary: transport, connection lifecycle, compatibility helpers, runtime payload helpers, RPC facades, protocol adapters, and shared app-server-backed cache state. Generated app-server payloads should stay behind this boundary; exported app-server services should expose panel-owned domain models or small local projection types unless an explicit boundary exception is documented. +- `src/app-server/` owns the app-server boundary. Generated app-server payloads should stay behind this boundary; exported app-server services should expose panel-owned domain models or small local projection types unless an explicit boundary exception is documented. - `src/features/chat/` owns the main Codex chat surface: Obsidian `ItemView` classes, panel orchestration, request/app-server controllers, composer behavior, display models, chat-only UI renderers, runtime state and status projection, approvals, user input, thread actions, and panel-specific state. +- `src/features/thread-picker/` owns the Obsidian thread picker modal and its thread search/opening behavior. +- `src/features/threads/` contains thread-related services shared by chat, the thread picker, and the Threads view, including archive export settings, thread operations, and title generation. - `src/features/threads-view/` owns the dedicated Obsidian thread list view, including app-server thread list rendering and live open-panel snapshot aggregation. - `src/features/selection-rewrite/` owns the Markdown editor selection rewrite command, popover, prompt/output handling, and ephemeral rewrite thread runner. - `src/workspace/` owns Obsidian workspace coordination across Codex surfaces, including panel discovery/opening, open-panel snapshots, and thread surface broadcasts. - `src/shared/` contains feature-neutral helpers, including reusable DOM pieces and unified diff display helpers shared by chat and selection rewrite. - `src/settings/` contains Obsidian settings models, settings-tab rendering, and app-server-backed dynamic settings data. -- `src/domain/` contains panel-owned, generated-independent meaning models and pure derivations shared by app-server, features, workspace, and settings code. This includes catalog metadata, runtime policy/settings/metrics, server metadata/diagnostics, chat input, and thread title/history/reference/transcript/archive helpers. Domain code must not import app-server protocol, generated bindings, feature modules, UI, or Obsidian APIs; app-server protocol and service modules adapt generated payloads into domain models at the boundary. +- `src/domain/` contains panel-owned, generated-independent meaning models and pure derivations shared by app-server, features, workspace, and settings code. Domain code must not import app-server protocol, generated bindings, feature modules, UI, or Obsidian APIs; app-server protocol and service modules adapt generated payloads into domain models at the boundary. - `src/styles/` contains the authored CSS modules and `order.json` concatenation order. `scripts/build-styles.mjs` concatenates them into the ignored root `styles.css`, which remains the Obsidian release asset. -Keep new code near the state or API it owns. Feature-to-feature imports are allowed when the imported feature owns a concrete capability or integration point, such as thread export, thread title generation, or an Obsidian view. Do not use another feature as a generic utility bucket; move truly feature-neutral behavior to `src/shared/`, `src/domain/`, or `src/app-server/`. Lower-level modules in `src/app-server/`, `src/domain/`, and `src/shared/` must remain independent from `src/features/`; ESLint enforces that dependency direction. Within the lower-level modules, `src/domain/` and `src/shared/` remain below the app-server boundary: app-server code may depend on domain models to adapt protocol data, but domain and shared code must not depend on app-server modules or generated app-server bindings. +Keep new code near the state or API it owns. A feature may import another feature only for a capability that feature owns; feature-neutral behavior belongs in `src/shared/`, `src/domain/`, or `src/app-server/`. Lower-level modules must not import `src/features/`, and generated app-server types should stay behind `src/app-server/`. -Codex Panel's runtime UI is Preact-owned through direct Preact APIs. Keep chat panel UI, the Threads view, and the selection rewrite popover in Preact components; use imperative DOM writes only for explicit bridge modules or Obsidian-owned API boundaries such as `MarkdownRenderer`, message content rendering and measurement, virtualizer measurement glue, diff rendering, icon rendering, `SuggestModal`, and the Obsidian `Setting`-based settings tab. - -Chat message stream rendering is split by display family. Presentation modules project domain message stream items into `text`, `detail`, and `status` views, and UI modules render those families from `text.tsx`, `detail.tsx`, and `status.tsx`. Keep Codex-specific item shape knowledge inside the presentation family projection, not in UI components. Keep imperative text content rendering and overflow measurement in the explicit `text-content.tsx` bridge rather than in the family renderer. - -Chat panel state belongs in `ChatStateStore`. Panel-visible state changes should dispatch named reducer actions and flow through the shell-state adapter; do not add controller-owned signals, ad hoc Preact state mirrors, generic state patch actions, or a non-Preact UI runtime without revisiting the project design notes. +Codex Panel's runtime UI is Preact-owned. Use imperative DOM writes only for explicit bridge modules, Obsidian-owned API boundaries, or rendering and measurement code that cannot be expressed cleanly as Preact components. Chat panel-visible state belongs in `ChatStateStore` and should flow through named reducer actions and the shell-state adapter. Revisit the project design notes before adding a parallel UI state or runtime path. ## App-Server Bindings