|
2 | 2 | applyTo: "src/webview/**/*.ts,src/webview/**/*.tsx" |
3 | 3 | --- |
4 | 4 |
|
5 | | -The `src/webview/**` tree contains the Preact-based frontend code for the Judge and Stress webviews. These run in an isolated browser-like environment, not in the VS Code extension host. |
| 5 | +The `src/webview/**` tree contains the React-based frontend code for the Judge and Stress webviews. These run in an isolated browser-like environment, not in the VS Code extension host. |
6 | 6 |
|
7 | 7 | When changing files under `src/webview/**`: |
8 | 8 |
|
9 | | -- Do not import the `vscode` module here; webview code should communicate with the extension only via the typed message contracts defined in `src/shared/*-messages.ts`. |
10 | | -- Treat the `App.tsx` components under `src/webview/judge/` and `src/webview/stress/` as entry points for each view. They receive initial state and subsequent updates exclusively through message types defined in the shared message unions. |
11 | | -- When you need new messages or actions from the webview to the extension, first extend the shared enums and message interfaces in `src/shared/*-messages.ts`, then update both the extension providers and the webview components to handle the new types. Avoid magic string message names. |
12 | | -- Assume styles are provided by an external CSS file built from `src/styles/global.css` into `dist/styles.css` via Tailwind CLI. Do not import CSS directly into TypeScript/TSX; the extension side (`BaseViewProvider`) injects the stylesheet as a `<link>` in the webview HTML. |
13 | | -- Prefer the existing lightweight stack (Preact + signals) for state management. Avoid introducing heavier frontend state libraries; instead, follow the current patterns used in the Judge and Stress apps. |
| 9 | +- Do not import the `vscode` module here; webview code should communicate with the extension only via `postProviderMessage()` from each view's `message.ts` file, which wraps `vscode.postMessage()` with typed contracts from `src/shared/*-messages.ts`. |
| 10 | +- Treat the `App.tsx` components under `src/webview/judge/` and `src/webview/stress/` as entry points for each view. They receive initial state and subsequent updates exclusively through message types defined in the shared message unions via `window.addEventListener("message", ...)`. |
| 11 | +- Codicons are the icon set used across the webviews. The backend already exposes `@vscode/codicons/dist/codicon.css`; prefer the existing `codicon-` classes instead of adding new icon libraries or custom SVG sprite sheets unless strictly necessary. |
| 12 | +- When you need new messages or actions from the webview to the extension, first extend the shared enums and Valibot schemas in `src/shared/*-messages.ts`, then update both the extension providers and the webview components to handle the new types. Avoid magic string message names. |
| 13 | +- Each webview has its own `index.css` stylesheet (e.g., `src/webview/judge/index.css`, `src/webview/stress/index.css`). Import it in the webview's entry file (`index.tsx`). The CSS is bundled by Rspack alongside the webview JavaScript. |
| 14 | +- Use `@legendapp/state` for reactive state management: |
| 15 | + - Wrap components with `observer()` from `@legendapp/state/react` for automatic re-rendering. |
| 16 | + - Access observable values with `.get()` and mutate with `.set(value)` or `.set(prev => newValue)`. |
| 17 | + - Use `<For each={obs$}>` for reactive list rendering; it efficiently handles additions/removals without re-rendering the entire list. |
| 18 | + - Use `useObservable(value)` for component-local observable state. |
| 19 | + - Collections like `Map` and `Set` have fine-grained reactivity; use `state$.map.get(key)` to get an observable for a specific entry. |
| 20 | + - Avoid introducing additional state libraries; follow the patterns in the Judge and Stress apps. |
| 21 | +- Shared webview utilities live in `src/webview/utils.ts` (e.g., `getStatusColor`). |
14 | 22 | - Keep UI logic decoupled from process execution details. The webview should focus on rendering state and sending/receiving typed messages, not on spawning processes or resolving filesystem paths. |
15 | 23 | - Maintain consistency with existing components such as `AutoresizeTextarea`, `Testcase`, and `State` in terms of props, message handling, and minimal DOM manipulation. |
| 24 | +- Keep the file layout lean (e.g., flat component files per view) and avoid introducing extra nested directories unless there's a clear benefit; mirror the existing Judge/Stress structure when adding new pieces. |
16 | 25 | - Keep changes surgical: avoid large-scale refactors or stylistic rewrites unless they are necessary for a specific task. |
0 commit comments