with one click
new-panel
// Scaffold a new Workbench panel — full stack (server DTOs/service/controller/tests + client hooks/store/panel/context-menu/tests + wiring + Playwright canary) that compiles on first invocation
// Scaffold a new Workbench panel — full stack (server DTOs/service/controller/tests + client hooks/store/panel/context-menu/tests + wiring + Playwright canary) that compiles on first invocation
Start / stop / status of the Typhon Workbench dev servers (Kestrel :5200 + Vite :5173) with file-based PID tracking so state survives across Claude Code sessions
Implement a GitHub issue end-to-end — scope it (whole issue or specific phases), build an acceptance-criteria plan from its design doc, get the plan approved, then develop autonomously with tests and a mandatory code review.
Complete work on a GitHub issue - close issue, update artifacts, prompt for doc updates
Create a GitHub issue and add it to the Typhon dev project
Start working on a GitHub issue - updates status, creates branch, verifies design
Run regression benchmarks, track results, and generate trend reports
| name | new-panel |
| description | Scaffold a new Workbench panel — full stack (server DTOs/service/controller/tests + client hooks/store/panel/context-menu/tests + wiring + Playwright canary) that compiles on first invocation |
| argument-hint | <ModuleName> <PanelName> |
Generates every file needed for a new dockable panel in the Typhon Workbench. Output compiles on first invocation: dotnet build green, tsc --noEmit green, npm run lint green, vitest green, one Playwright canary green. The service body returns an empty list / default DTO so you can wire a UI immediately and fill in the engine-read code as a second pass.
$ARGUMENTS should contain two PascalCase identifiers separated by whitespace:
ModuleName — the module this panel belongs to (e.g., QueryConsole, SchemaInspector, DataBrowser). Case-sensitive, no spaces, no dots.PanelName — the specific panel within the module (e.g., QueryEditor, ArchetypeBrowser). Case-sensitive, no spaces.If either is missing, use AskUserQuestion to collect them.
If $ARGUMENTS contains --help or -h, display the block below and stop — do not execute the workflow.
/new-panel <ModuleName> <PanelName>
Scaffold a full-stack Workbench panel that compiles on first invocation.
Arguments:
ModuleName Module this panel belongs to (PascalCase, e.g. QueryConsole)
PanelName Panel name within the module (PascalCase, e.g. QueryEditor)
--help, -h Show this help
What it does:
- Creates/extends the module's service + controller + DTOs on the server
- Creates the panel component + context menu + hook on the client
- Wires dockview registration + menu + palette + open-helper
- Generates a vitest smoke test + a Playwright canary
- Verifies the whole stack compiles
Examples:
/new-panel QueryConsole QueryEditor
/new-panel SchemaInspector DefaultsDiff
Before generating any file:
Parse args — validate both identifiers are PascalCase, no punctuation. Derive:
moduleSlug = lowerCamel of ModuleName (e.g. queryConsole)moduleKebab = kebab of ModuleName (e.g. query-console)panelSlug = lowerCamel of PanelName (e.g. queryEditor)panelKebab = kebab of PanelName (e.g. query-editor)Detect module state — check if a server-side <ModuleName>Service.cs exists under tools/Typhon.Workbench/<ModuleName>/Service/ (or wherever the first module was placed). If missing, this is a new-module scaffold — add the full server stack. If present, this is a new-panel-in-existing-module scaffold — only add the panel-level files and skip the server stack.
Confirm target with the user via AskUserQuestion:
<ModuleName> (generate server + client stack)" OR "Existing module, add panel <PanelName> only"Do not embed long templates in this file. Read the existing implementations and adapt. The authoritative references:
| What | Reference |
|---|---|
| Server service method + error types | tools/Typhon.Workbench/Schema/SchemaService.cs |
Server controller + auth attributes + Invoke<T> error mapping | tools/Typhon.Workbench/Controllers/SchemaController.cs |
| DTO records (camelCase JSON) | tools/Typhon.Workbench/Dtos/Schema/ComponentSummaryDto.cs |
Server tests + WorkbenchFactory.CreateAuthenticatedClient | test/Typhon.Workbench.Tests/Schema/SchemaControllerTests.cs |
| Module-scoped zustand store + selection + touchedAt pattern | tools/Typhon.Workbench/ClientApp/src/stores/useSchemaInspectorStore.ts |
Normalized types + Orval-style normalizeX functions | tools/Typhon.Workbench/ClientApp/src/hooks/schema/types.ts |
| Query hook via Orval generated function + normalizer | tools/Typhon.Workbench/ClientApp/src/hooks/schema/useComponentList.ts |
Query hook via raw customFetch (use this path for the scaffold) | tools/Typhon.Workbench/ClientApp/src/hooks/schema/useArchetypeList.ts |
| Panel component + empty/loading/error states | tools/Typhon.Workbench/ClientApp/src/panels/SchemaInspector/SchemaIndexPanel.tsx |
| Panel with search + filter chips + sortable Table | tools/Typhon.Workbench/ClientApp/src/panels/SchemaBrowser/SchemaBrowserPanel.tsx |
| Co-located context menu | tools/Typhon.Workbench/ClientApp/src/panels/SchemaBrowser/SchemaBrowserContextMenu.tsx |
Module-level dock api registry + openX() helpers | tools/Typhon.Workbench/ClientApp/src/shell/commands/openSchemaBrowser.ts |
| Dockview components-map registration | tools/Typhon.Workbench/ClientApp/src/shell/DockHost.tsx |
| Menu bar entry (possibly gated on selection) | tools/Typhon.Workbench/ClientApp/src/shell/MenuBar.tsx |
| Palette command registration | tools/Typhon.Workbench/ClientApp/src/shell/commands/baseCommands.ts |
| Vitest for a zustand store | tools/Typhon.Workbench/ClientApp/src/stores/__tests__/useSchemaInspectorStore.test.ts |
| Playwright canary — panel opens via menu | tools/Typhon.Workbench/ClientApp/e2e/schema-inspector.spec.ts |
When generating each file, Read the reference, adapt the patterns — don't blindly copy. The Workbench conventions shift and the scaffolder stays current by deferring to the live code.
Execute in this order so intermediate states are buildable:
Server DTOs (tools/Typhon.Workbench/Dtos/<ModuleName>/)
<PanelName>ItemDto — the shape the list-endpoint returns an array of. Example fields: string Name, int Count — just enough to demonstrate camelCase JSON without pretending to model the future data shape.Server service (tools/Typhon.Workbench/<ModuleName>/<ModuleName>Service.cs)
List<PanelName>s(Guid sessionId) returning <PanelName>ItemDto[].return []; plus a // TODO: read real data from the engine comment._sessions + RequireOpenEngine pattern as SchemaService.Server controller (tools/Typhon.Workbench/Controllers/<ModuleName>Controller.cs)
api/sessions/{sessionId:guid}/<moduleKebab>.GET <panelKebab>s endpoint calling the service method, wrapped in the standard Invoke<T> (copy the wrapper from SchemaController).[RequireBootstrapToken][RequireSession][Tags("<ModuleName>")].Server DI registration (tools/Typhon.Workbench/Hosting/ServiceExtensions.cs)
<ModuleName>Service as scoped alongside existing services.Server tests (test/Typhon.Workbench.Tests/<ModuleName>/<ModuleName>ControllerTests.cs)
List_Returns200_WithEmptyArray (happy path against a session) and List_WithoutBootstrapToken_Returns401.WorkbenchFactory.CreateAuthenticatedClient and the fixture-session helper the existing tests use.Client normalized types (tools/Typhon.Workbench/ClientApp/src/hooks/<moduleSlug>/types.ts)
<PanelName>Item mirroring the DTO, a normalize<PanelName>Item(raw) function.customFetch), import the shape from a local interface, not from @/api/generated.Client query hook (tools/Typhon.Workbench/ClientApp/src/hooks/<moduleSlug>/use<PanelName>List.ts)
customFetch + TanStack Query directly (see useArchetypeList.ts). Declare the DTO shape locally as a TS interface so compile works before Orval regen.// TODO: swap to generated hook once npm run generate-types runs note.Client store (tools/Typhon.Workbench/ClientApp/src/stores/use<ModuleName>Store.ts)
selected<PanelName>Id: string | null, a select(id) action, a reset() action, and a touchedAt: number that bumps on select (for DetailPanel recency — follow the pattern in useSchemaInspectorStore).Panel component (tools/Typhon.Workbench/ClientApp/src/panels/<ModuleName>/<PanelName>Panel.tsx)
<Table> of rows with a single "Name" column.store.select(row.id).panels/CLAUDE.md.Context menu (tools/Typhon.Workbench/ClientApp/src/panels/<ModuleName>/<PanelName>ContextMenu.tsx)
Dockview registration — edit shell/DockHost.tsx:
<PanelName>: <PanelName>Panel to the components map.Open helper (tools/Typhon.Workbench/ClientApp/src/shell/commands/open<ModuleName>.ts)
openSchemaBrowser.ts.open<PanelName>() function that calls the same openDockPanel helper.Menu wiring — edit shell/MenuBar.tsx:
MenubarItem under the View menu pointing at open<PanelName>()."Select an item first" if the panel requires a selection state.Palette command — edit shell/commands/baseCommands.ts:
{ id: '<moduleKebab>-<panelKebab>', label: 'Open <PanelName>', keywords: '<module lowercase> <panel lowercase>', action: open<PanelName> }.Vitest smoke (tools/Typhon.Workbench/ClientApp/src/stores/__tests__/use<ModuleName>Store.test.ts)
select persists id, select bumps touchedAt, reset clears.Playwright canary (tools/Typhon.Workbench/ClientApp/e2e/<moduleKebab>.spec.ts)
<PanelName>, assert a unique placeholder or title substring is visible.openDemo(page, request) helper from e2e/schema-inspector.spec.ts — Playwright specs don't share modules yet.Run these sequentially; fail early and report which step broke.
# 1. Server build
dotnet build tools/Typhon.Workbench/Typhon.Workbench.csproj -c Debug --nologo 2>&1 | tail -5
# 2. Server tests (if new-module path)
dotnet test test/Typhon.Workbench.Tests/Typhon.Workbench.Tests.csproj --filter "FullyQualifiedName~<ModuleName>" --nologo --no-build 2>&1 | tail -3
# 3. Client typecheck
cd tools/Typhon.Workbench/ClientApp && npx tsc --noEmit 2>&1 | tail -5
# 4. Client lint
npm run lint 2>&1 | tail -3
# 5. Client vitest (store test)
npm test -- --run src/stores/__tests__/use<ModuleName>Store.test.ts 2>&1 | tail -5
Do not run Playwright in verification — that requires Kestrel + Vite running, which may not be the case. Instead, print a reminder: "run npx playwright test e2e/<moduleKebab>.spec.ts once dev servers are up".
Report to the user:
npm run generate-types as the swap point from customFetch → Orval generated hooknpx playwright test e2e/<moduleKebab>.spec.ts to confirm the canaryselect-none (default for the app) — the panel shell inherits. If any part of the new panel should be copyable, add select-text on that specific region.StatusBadge (not raw Badge + ad-hoc colors) for any status chip — see components/ui/status-badge.tsx.SchemaLayoutRenderer theme-token pattern — read CSS variables, listen for .dark class changes via MutationObserver.panels/CLAUDE.md).index.ts files — import directly (see src/CLAUDE.md).