T-J3NW-learning-p3-exercise-runners
State: planning/proposed · Impact: high · Complexity: large
Make exercises run. A vim-exercise or sql-exercise fence in a
module renders as an interactive runner in the reader, through the
markdown-ui plugin seam and nothing else. The runners are a plain Vue
package so the print site can mount them too.
| Location | Role today |
|---|---|
packages/ts/markdown-ui/app/composables/useMarkdownPlugins.ts | registerMarkdownPlugin: a plugin’s components map keyed by route; lang:<fence> claims a fence language and receives the hast node |
packages/ts/obsidian-md/src/vue/render.ts | Route keys: obsidian-embed, lang:<language>, class routes, tag names. Overrides receive node and the rendered children |
packages/ts/code-editor/ | CodeSurface with an extensions prop for host CodeMirror extensions |
solutions/augmented/apps/vimit_prototype/app/components/VimEditor/ | The bespoke CodeMirror vim editor with key and command capture; the logic to port |
solutions/augmented/apps/vimit/src-astro/src/lib/review/answer-compare.ts | Tested answer comparison, reusable |
solutions/augmented/apps/learn_web/layers/sqljs/engine.ts | sql.js engine and query library, reusable |
solutions/augmented/apps/augmented-books/src-tauri/src/runners/comparator.rs | The SQL result comparator, to port to TypeScript |
docs/planning/tasks/T-FG8R-editor-settings-toolbar-and-vim.md | Wants a vim extension slot in the shared editor; this task provides it |
Proposed
Section titled “Proposed”@determined/runners exports VimRunner and SqlRunner, each taking a
parsed spec and emitting attempt events with a verdict. A runner
registry maps fence language to runner. The experience registers one
markdown plugin whose components carry lang:vim-exercise and
lang:sql-exercise overrides that parse the fence body and mount the
runner. VimRunner is CodeSurface plus the vim extension plus a
key-capture extension. SqlRunner is sql.js in a worker with the
verification comparator in TypeScript. Both runners need no transport
and no Nuxt.
Approach
Section titled “Approach”- Contribute the vim extension and key-capture to
code-editoras an opt-in extension, not a runner-specific fork. - Port the vim-problem checker: compare document, cursor and selection against the target, with allowed-key enforcement.
- Port the SQL comparator and wire sql.js in a worker.
- Build the two runner components with a shared frame: prompt, hints, attempt, result.
- Register the plugin in the experience; parse the fence body with the book-model spec schemas; render the fence as a code block when the spec fails to parse, with the error visible.
- Storybook stories for both runners, since they are plain Vue.
| Area | Note |
|---|---|
packages/ts/code-editor/ | Vim extension and key capture as an opt-in |
solutions/determined/packages/runners/ | The two runners, registry, comparators, stories |
solutions/determined/experiences/learning/app/plugins/ | The markdown plugin registration |
Acceptance criteria
Section titled “Acceptance criteria”- AC-1: A module with a
vim-exercisefence shows a runner; solving it yields a pass verdict; a wrong key sequence yields a fail with the diff. - AC-2: A
sql-exercisefence runs setup and submission in the browser and verifies rows, columns and expected errors. - AC-3:
@determined/runnershas no dependency on nuxt or on@determined/vault-platform-client. - AC-4: A malformed fence renders as a code block with the parse error, not a crash.
Out of scope
Section titled “Out of scope”- Recording attempts. P4.
- A form-based fence editor in live mode. P7.
Dependencies
Section titled “Dependencies”T-B7Y2for the fence spec schemas and a corpus with fences.
Discovery context
Section titled “Discovery context”- The plugin-seam discussion of 2026-09-13 recorded in
D-LIRI.
Depends on
Section titled “Depends on”T-B7Y2