feat(dashboard): /config Prompt section — template editor + live preview #477

Merged
code-lead merged 4 commits from dev/458 into main 2026-04-27 21:39:07 +00:00
Collaborator

Adds the Prompt section editor to the /config form for each agent type.

Test plan

  • Open /config, select any agent type, click the Prompt tab
  • Textarea is monospace; ${var} chips insert at cursor (mousedown preserves caret)
  • Edit sample values (repo, issue_number, etc.) → preview updates immediately
  • Type an unknown var like ${nope} → warning chip appears; known vars are clean
  • Reset button re-enables after editing; click restores the server-loaded template
  • All other section tabs still show their existing placeholders
  • bun x vitest run → 562 tests pass

Closes #458

Adds the Prompt section editor to the `/config` form for each agent type. ## Test plan - Open `/config`, select any agent type, click the **Prompt** tab - Textarea is monospace; `${var}` chips insert at cursor (mousedown preserves caret) - Edit sample values (repo, issue_number, etc.) → preview updates immediately - Type an unknown var like `${nope}` → warning chip appears; known vars are clean - Reset button re-enables after editing; click restores the server-loaded template - All other section tabs still show their existing placeholders - `bun x vitest run` → 562 tests pass Closes #458
feat(dashboard): /config Prompt section — template editor + live preview
Some checks failed
qa / qa (pull_request) Failing after 3m23s
qa / dockerfile (pull_request) Successful in 11s
a6a50300e2
Implements issue #458. Adds a `PromptSection` component rendered under the
Prompt tab of the /config form. Operators get a monospace textarea, clickable
\${var} chips that insert at the cursor, a live preview pane interpolated
against editable sample values, unknown-var warning chips, and a Reset button
that restores the server-loaded template.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
fix(ci): annotate useState with AgentTypeConfig in config.test.tsx
All checks were successful
qa / qa (pull_request) Successful in 9m6s
qa / dockerfile (pull_request) Successful in 13s
74ba809fb1
Two Harness components inferred { system_prompt_template: string } (required)
instead of AgentTypeConfig (where the field is optional), making the inferred
Dispatch incompatible with the onTypeConfigChange prop type.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
dev requested review from reviewer 2026-04-27 20:58:15 +00:00
reviewer requested changes 2026-04-27 20:59:54 +00:00
Dismissed
reviewer left a comment
  • behavior apps/web/src/lib/prompt.tsdetectUnknownVars scans the raw template string, so any template using ${if:parent_pr}…${endif} conditional syntax always emits a spurious ${endif} warning chip. parent_pr (the stacked-PR var) is the obvious candidate for a conditional wrapper, so this will fire on real production templates.

    The test at line 61 acknowledges it but doesn't assert endif is absent — the comment says "users shouldn't write bare ${endif}" while ${if:…}${endif} is valid and expected syntax.

    Fix: strip conditional blocks before scanning, mirroring the first pass of interpolatePromptTemplate:

    export function detectUnknownVars(template: string): string[] {
        const stripped = template.replace(/\$\{if:\w+\}[\s\S]*?\$\{endif\}/g, "");
        const known = new Set<string>(KNOWN_PROMPT_VARS);
        const found = new Set<string>();
        for (const [, key] of stripped.matchAll(/\$\{(\w+)\}/g)) {
            if (key && !known.has(key)) found.add(key);
        }
        return [...found];
    }
    

    Update the "ignores conditional keywords" test to assert expect(unknowns).not.toContain("endif") after the fix.

- **behavior** `apps/web/src/lib/prompt.ts` — `detectUnknownVars` scans the raw template string, so any template using `${if:parent_pr}…${endif}` conditional syntax always emits a spurious `${endif}` warning chip. `parent_pr` (the stacked-PR var) is the obvious candidate for a conditional wrapper, so this will fire on real production templates. The test at line 61 acknowledges it but doesn't assert `endif` is absent — the comment says "users shouldn't write bare `${endif}`" while `${if:…}${endif}` is valid and expected syntax. Fix: strip conditional blocks before scanning, mirroring the first pass of `interpolatePromptTemplate`: ```ts export function detectUnknownVars(template: string): string[] { const stripped = template.replace(/\$\{if:\w+\}[\s\S]*?\$\{endif\}/g, ""); const known = new Set<string>(KNOWN_PROMPT_VARS); const found = new Set<string>(); for (const [, key] of stripped.matchAll(/\$\{(\w+)\}/g)) { if (key && !known.has(key)) found.add(key); } return [...found]; } ``` Update the `"ignores conditional keywords"` test to assert `expect(unknowns).not.toContain("endif")` after the fix.
fix(web): strip conditional blocks in detectUnknownVars to suppress spurious \${endif} warnings
Some checks are pending
qa / qa (pull_request) Waiting to run
qa / dockerfile (pull_request) Waiting to run
38b02a677e
Mirrors interpolatePromptTemplate pass 1: strip \${if:NAME}…\${endif}
blocks before scanning for unknown tokens, so production templates with
conditional wrappers no longer emit false-positive warning chips.

Update the "ignores conditional keywords" test to assert \`endif\` is
absent; add a companion test that verifies unknowns outside the block
are still caught.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Author
Collaborator

Fixed in latest commit. detectUnknownVars now strips ${if:NAME}…${endif} blocks before scanning (mirrors interpolatePromptTemplate pass 1), so ${endif} and vars inside conditional blocks are never flagged as unknown. Updated the test to assert not.toContain("endif"); added a companion case verifying unknowns outside blocks are still caught. All 12 tests pass.

Fixed in latest commit. `detectUnknownVars` now strips `${if:NAME}…${endif}` blocks before scanning (mirrors `interpolatePromptTemplate` pass 1), so `${endif}` and vars inside conditional blocks are never flagged as unknown. Updated the test to assert `not.toContain("endif")`; added a companion case verifying unknowns outside blocks are still caught. All 12 tests pass.
dev force-pushed dev/458 from 38b02a677e
Some checks are pending
qa / qa (pull_request) Waiting to run
qa / dockerfile (pull_request) Waiting to run
to fd5635eba2
All checks were successful
qa / qa (pull_request) Successful in 10m21s
qa / dockerfile (pull_request) Successful in 14s
2026-04-27 21:13:48 +00:00
Compare
dev requested review from reviewer 2026-04-27 21:38:04 +00:00
reviewer approved these changes 2026-04-27 21:38:43 +00:00
reviewer left a comment

detectUnknownVars now correctly strips conditional blocks before scanning — ${endif} no longer surfaces as a spurious warning. Test coverage is thorough. CI green.

`detectUnknownVars` now correctly strips conditional blocks before scanning — `${endif}` no longer surfaces as a spurious warning. Test coverage is thorough. CI green.
code-lead deleted branch dev/458 2026-04-27 21:39:08 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
charles/claude-hooks!477
No description provided.