Skip to content

Commit a8ac5ff

Browse files
committed
Update copilot instructions
1 parent 3bd5264 commit a8ac5ff

File tree

5 files changed

+90
-13
lines changed

5 files changed

+90
-13
lines changed

.github/instructions/extension-backend.instructions.md

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,28 +10,50 @@ applyTo: "src/extension/**/*.ts"
1010

1111
## File Persistence Lifecycle
1212

13-
Both Judge and Stress implement the same file-switching pattern:
13+
Both Judge and Stress implement the same file-switching pattern defined in `BaseViewProvider`:
1414

1515
1. `loadCurrentFileData()` is the entry point when the webview becomes visible
1616
2. `_ensureActiveEditorListener()` subscribes to editor changes
17-
3. `_handleActiveEditorChange()` filters non-file schemes and calls `_switchToFile()`
18-
4. `_switchToFile(file)` loads persisted data from workspaceState, creates in-memory state, and rehydrates the webview
19-
5. `_switchToNoFile()` handles cases where no valid file is open
20-
6. `_rehydrateWebviewFromState()` sends current in-memory state to the webview
17+
3. `_handleActiveEditorChange()` filters non-file/untitled schemes and calls `_switchToFile()`
18+
4. `_syncOrSwitchToTargetFile()` decides between rehydrating the current file or switching:
19+
- Same file with existing state → `_rehydrateWebviewFromState()`
20+
- Different file → `_switchToFile(file)`
21+
- No file → `_sendShowMessage(false)`
22+
5. `_switchToFile(file)` loads persisted data from workspaceState, creates in-memory state, and rehydrates the webview
23+
6. `_switchToNoFile()` handles cases where no valid file is open
24+
7. `_rehydrateWebviewFromState()` sends current in-memory state to the webview
25+
26+
Subclasses must implement these abstract methods:
27+
28+
- `_switchToFile(file)` / `_switchToNoFile()` / `_rehydrateWebviewFromState()` / `_sendShowMessage(visible)`
29+
- `_hasState()`: Override to control same-file rehydration (e.g., Judge checks `_runtime.state.length > 0`)
2130

2231
When switching files, processes are **not** stopped. Instead, they are moved to the background (e.g., via `_moveCurrentStateToBackground`) and trigger `_onDidChangeBackgroundTasks`. The `PanelViewProvider` monitors and displays these running background tasks.
2332

2433
## Run Settings
2534

26-
- **`runSettingsCommands.ts`**: Registers commands (`editRunSettings`, `resetRunSettings`) and provides default `languageTemplates`.
35+
- **`runSettingsCommands.ts`**: Registers commands (`editRunSettings`, `resetRunSettings`) and provides default `languageTemplates` for various languages (C++/GCC, C++/Clang, Python, PyPy, Java, Go, Rust, JavaScript, etc.).
2736
- **`vscode.ts`**: Provides `getFileRunSettings`, `initializeRunSettingsWatcher`, and `resolveVariables` to parse and resolve VS Code variables (like `${fileDirname}`) in commands.
2837

38+
### Hierarchical Run Settings Merging
39+
40+
`getFileRunSettings(file)` traverses from the file's directory up to the workspace root, loading and merging `runSettings.json` files along the way via `deepMerge()`. Closer-to-file settings override ancestor settings. The function also:
41+
42+
- Applies defaults from the `runSettings.schema.json` schema file
43+
- Resolves VS Code variables via `resolveVariables()`
44+
- Validates via `RunSettingsSchema` (Valibot)
45+
- Caches loaded settings per directory; cache is invalidated by a `FileSystemWatcher`
46+
- Returns `FileRunSettings` which includes the merged settings plus the resolved `languageSettings` for the file's extension
47+
2948
## Extended VS Code Utilities (`vscode.ts`)
3049

3150
- **`TextHandler`**: For all streamed output. Keeps full data internally, truncates display output, normalizes CRLF to LF, ensures trailing newline. Write modes: `"batch"`, `"force"`, `"final"`. Always call `.reset()` before a fresh run.
3251
- **`ReadonlyStringProvider`**: Manages the custom `fastolympiccoding` URI scheme for displaying read-only text documents.
3352
- **`openInNewEditor` / `openInTerminalTab`**: Helpers for displaying output. Terminal tabs support ANSI colors and native clickable file links.
3453
- **`openOrCreateFile`**: Helper for file management.
54+
- **`getFileWorkspace`**: Returns workspace folder or file directory. Used for run settings and CC target resolution.
55+
- **`getAttachDebugConfiguration`**: Looks up a named debug configuration from workspace `launch.json`.
56+
- **`showOpenRunSettingsErrorWindow` / `showAddLanguageSettingsError`**: Error UI helpers that offer quick-fix actions.
3557

3658
## UI/UX Features
3759

@@ -59,6 +81,16 @@ Termination mapping helpers:
5981

6082
Use `compile()` for compilation (caches by file checksum and compile command).
6183

84+
### Debounced Saving
85+
86+
JudgeViewProvider uses a debounced save pattern:
87+
88+
- `requestSave()`: Schedules a bulk save after 200ms (resets timer on repeated calls)
89+
- `forceSave()`: Immediately saves all state (used during `onDispose()`)
90+
- `_saveAllState()`: Writes all contexts to workspaceState in a single bulk update
91+
92+
StressViewProvider saves state synchronously via `_saveState(file)` after each operation.
93+
6294
## Debug Workflow
6395

6496
Debug support uses **attach mode**:

.github/instructions/judge-provider.instructions.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ The `handleMessage` method dispatches based on `msg.type`. Top-level message typ
6868
- `NEW_INTERACTOR_SECRET`: Generates a new interactor secret
6969
- `ACTION`: Calls `this._action(msg)` which dispatches based on the `action` field
7070

71+
- `REORDER`: Reorders a testcase to a new index position
72+
7173
Actions handled by `_action`:
7274

7375
- `RUN`: Execute single testcase
@@ -79,9 +81,10 @@ Actions handled by `_action`:
7981
- `TOGGLE_SKIP`: Toggle skip flag
8082
- `COMPARE`: Open diff view
8183
- `DEBUG`: Run in debug mode
82-
- `OPEN_INTERACTOR`: Open interactor file
8384
- `TOGGLE_INTERACTIVE`: Toggle interactive mode
8485

86+
> Note: `REQUEST_DATA` exists in `ActionValues` but is not handled in `_action`.
87+
8588
## Background Task Tracking
8689

8790
`_contexts` map holds contexts for all files (not just active). Methods:
@@ -101,3 +104,17 @@ Actions handled by `_action`:
101104
- `addTestcaseToFile(file, testcase, timeLimit?, memoryLimit?)`: Adds testcase from external source (Competitive Companion)
102105
- `exportTestcasesForFile(file)`: Serializes and exports testcases for a given file
103106
- `appendImportedTestcasesForFile(file, rawData)`: Parses, imports, and appends testcases to a file
107+
108+
## Public API Methods
109+
110+
- `getActiveFilePath()`: Returns the currently active file path
111+
- `runAll()` / `debugAll()` / `stopAll()`: Batch operations on all testcases for the current file
112+
- `deleteAll(file?)`: Delete all testcases for a file (defaults to current file)
113+
- `toggleWebviewSettings()`: Sends `SETTINGS_TOGGLE` to toggle the webview settings panel
114+
- `openInteractorFile()`: Opens the interactor file from run settings (separate from action dispatch)
115+
116+
## Debounced Save Pattern
117+
118+
- `requestSave()`: Schedules a bulk save after 200ms (debounced)
119+
- `forceSave()`: Immediately saves all state, used during `onDispose()`
120+
- `_saveAllState()`: Writes all contexts to workspaceState in a single bulk update

.github/instructions/shared-contracts.instructions.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,17 @@ Derive property types from schemas using TypeScript utility types. For example:
114114
export type TestcaseProperty = Exclude<keyof Testcase, "uuid">;
115115
```
116116

117+
## Data Schemas (`schemas.ts`)
118+
119+
Key schemas for persisted and exchanged data:
120+
121+
- **`TestcaseSchema`**: Judge testcase with `uuid`, stdio fields, `elapsed`, `memoryBytes`, `status`, `shown`, `toggled`, `skipped`, `mode`, `interactorSecret`. Uses `v.fallback()` for all fields.
122+
- **`StressDataSchema`**: Stress state snapshot with `stdin`, `stdout`, `stderr`, `status`, `state` (StateId), `shown`.
123+
- **`RunSettingsSchema`**: Validated via `v.pipe()` with `v.looseObject()` and `v.check()`. Known keys: `interactorFile`, `goodSolutionFile`, `generatorFile`. Additional properties must be file extensions (starting with `.`) and match `LanguageSettingsSchema`.
124+
- **`LanguageSettingsSchema`**: Per-language config with optional `compileCommand`, `runCommand`, `currentWorkingDirectory`, `debugCommand`, `debugAttachConfig`.
125+
- **`ProblemSchema`**: Competitive Companion problem data with `name`, `group`, `url`, `tests`, `timeLimit`, `memoryLimit`, `interactive`, `batch`, `input`, `output`.
126+
- **`TestSchema`**: Simple `{ input, output }` for CC test pairs.
127+
117128
## Append-Only Rule
118129

119130
When adding new enum values or message types, **append to the end** of arrays. Never rename or reorder existing values—they may be persisted in workspaceState.

.github/instructions/stress-provider.instructions.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ In interactive mode:
7171
- Generator produces a "secret" (like interactor in Judge)
7272
- The **Judge** acts as the interactor (running `interactorFile`), communicating back and forth with the **Solution** (the user's solution).
7373
- The **Generator** provides the initial secret to the Judge.
74-
- Uses `interactiveSecretPromise` to wait for webview to receive the secret
74+
- The secret is resolved immediately when the Generator emits stdout data (not when the webview receives it)
75+
- Uses `interactiveSecretPromise` to ensure the secret is sent before Solution stdout is forwarded to Judge
7576

7677
## State Persistence
7778

@@ -100,9 +101,16 @@ The stdio content, status, state, and visibility are all persisted for each comp
100101

101102
- `getRunningStressSessions()`: Returns array of file paths with running stress
102103
- `stopStressSession(file)`: Stop stress for a specific file
103-
- `stopAll()`: Stops all stress sessions across all files in the workspace
104+
- `stopAll()`: Stops all stress sessions across all files
104105
- `onDidChangeBackgroundTasks`: Event for PanelViewProvider
105106

107+
## Public API Methods
108+
109+
- `run()`: Public entry point, calls `_doRun`
110+
- `stop()`: Set stopFlag for the current file
111+
- `clear()`: Stop and clear all state, or set `clearFlag` if running
112+
- `toggleWebviewSettings()`: Sends `SETTINGS_TOGGLE` to toggle the webview settings panel
113+
106114
## Key Methods
107115

108116
- `_createContext(file, persistedState)`: Initialize context with states

.github/instructions/webview-frontend.instructions.md

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,15 @@ Receive messages in `App.svelte` via `window.addEventListener("message", ...)` i
2323

2424
### Judge View (`src/webview/judge/`)
2525

26-
- **App.svelte**: Entry point, message handling, testcase list rendering
27-
- **TestcaseToolbar.svelte**: Status badges, action buttons (run, stop, debug, delete)
28-
- **Testcase.svelte**: Stdio textareas (stdin, stdout, stderr, acceptedStdout, interactorSecret)
26+
- **App.svelte**: Entry point, message handling, testcase list rendering, drag-and-drop reorder
27+
- **TestcaseToolbar.svelte**: Status badges, action buttons (run, stop, debug, delete, skip, drag handle)
28+
- **Testcase.svelte**: Stdio textareas (stdin, stdout, stderr, acceptedStdout, interactorSecret). Exports a `reset()` function called before re-running a testcase.
2929

3030
Rendering pattern:
3131

3232
```svelte
3333
{#each testcases as testcase, index (testcase.uuid)}
34-
<div class="testcase-item">
34+
<div class="testcase-item" data-uuid={testcase.uuid}>
3535
<TestcaseToolbar {testcase} onprerun={() => handlePrerun(testcase.uuid)} />
3636
{#if testcase.status === "COMPILING" || testcase.skipped}
3737
<div class="half-opacity">
@@ -44,6 +44,15 @@ Rendering pattern:
4444
{/each}
4545
```
4646

47+
### Drag-and-Drop Reorder (Judge)
48+
49+
Testcases support reordering via drag-and-drop and keyboard (Alt+Arrow). The flow:
50+
51+
1. `handleDragStart`: Sets `draggingUuid` and `dataTransfer`
52+
2. `handleDragOver`: Calculates drop position (before/after) relative to hovered testcase, updates `separatorIndex`
53+
3. `handleDrop`: Calls `reorderTestcasesLocally()` for immediate UI update, then sends `REORDER` message to extension
54+
4. Keyboard: Alt+ArrowUp/Down in `handleTestcaseKeydown` calls `commitReorder()` directly
55+
4756
### Stress View (`src/webview/stress/`)
4857

4958
- **App.svelte**: Entry point, message handling, state list rendering

0 commit comments

Comments
 (0)