Afterword: prompt templates feature - #55
Conversation
7057d73 to
08448ea
Compare
PR Reviewer Guide 🔍(Review updated until commit 0da318b)Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Latest suggestions up to 0da318b Explore these optional code suggestions:
Previous suggestionsSuggestions up to commit 6792909
Suggestions up to commit 99dec5a
Suggestions up to commit e70194e
|
|
Persistent review updated to latest commit 99dec5a |
|
Persistent review updated to latest commit 6792909 |
6792909 to
0da318b
Compare
|
Persistent review updated to latest commit 0da318b |
…ation A workflow run stalled mid-implementation of AUD-62 (Afterword editor). Preserving the in-progress files rather than discarding them — this is NOT a finished ticket, a future run must verify against AUD-62's full acceptance criteria before treating it as done. Co-Authored-By: Claude Sonnet 5 <[email protected]>
The prior WIP commit's SystemPromptEditor relied on document.activeElement to detect a live cursor, but clicking a chip button blurs the textarea first, so insertion always fell back to appending at the end. Track the last-known caret position in a ref instead so chip clicks insert at the cursor as specced. Also fixes TemplateListPage's overflow-menu "Duplicate & Customise" to navigate to the new editable copy's editor, matching the editor's own Duplicate & Customise action and the AUD-62 acceptance criteria. Verified: typecheck, lint, and e2e (prompt-template-editor.spec.ts, prompt-templates.spec.ts) all pass. The rest of the AUD-62 editor (inline-editable name, monospace resizable textarea, highlighted variable tokens, output section list, action bar, built-in read-only state, delete/ discard dialogs, unsaved-changes tracking) was already implemented by the earlier stalled run and is confirmed working against the ticket's acceptance criteria. Co-Authored-By: Claude Sonnet 5 <[email protected]>
Replace the NewTemplateModal placeholder with the full "Create a new
template" dialog: a "Blank template" option plus a 2x2 grid of built-in
presets (PresetCard). Blank creates an empty template via
templates.create({}); each preset duplicates the matching built-in via
templates.duplicate(id). Both close the modal and navigate straight to
the new copy's editor. Closing via the x button, outside click, or
Escape creates nothing.
Adds e2e/new-template-modal.spec.ts covering all three paths.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Add @dnd-kit/core + @dnd-kit/sortable and wire drag-and-drop into OutputSectionList: the six-dot handle (not the whole row) drives the drag via useSortable, so inline-editable heading/instruction text stays clickable. Reordering only happens on drop — sibling rows don't shift during drag — and a blue drop-zone indicator line renders on whichever row edge the dragged item is currently over, tracked via onDragOver without mutating form state. The original slot renders as a dashed placeholder, and a DragOverlay shows the floating row (shadow, slight rotation, accent-coloured handle) following the pointer. New order is only committed to local form state in onDragEnd, keeping it an unsaved change per the existing Save Changes flow. Keyboard reordering works via dnd-kit's KeyboardSensor + sortableKeyboardCoordinates. Adds e2e/output-section-reorder.spec.ts covering pointer drag, keyboard reorder, and the single-section (no drop indicator) case. Co-Authored-By: Claude Sonnet 5 <[email protected]>
- Preview close button appeared broken: closing while the LLM preview call was still in flight let the resolved promise reopen the modal afterward. A request token now invalidates stale resolutions. - The action bar (Preview / Save / Duplicate & Customise) used `sticky bottom-0` inside a padded scroll container, which let it overlap trailing content instead of pinning to the window bottom. Switched to `fixed` anchored past the sidebar, with matching bottom padding on the editor page so content isn't hidden behind it. Co-Authored-By: Claude Sonnet 5 <[email protected]>
The dropdown was anchored left-0 with a 220px min-width wider than the trigger button, so it grew rightward past the button's bounds. Anchoring right-0 instead so it grows leftward and stays flush with the button. Co-Authored-By: Claude Sonnet 5 <[email protected]>
All templates are always usable — the isActive flag never gated which templates could be selected, it only marked which one a session falls back to when the per-session selector isn't touched. "Default" names that behavior accurately; "Active" implied an exclusivity the feature never had. Renamed end-to-end: data model (isActive -> isDefault, activeTemplateId -> defaultTemplateId), IPC channel and preload API (setActive -> setDefault), and all UI copy/props (ACTIVE badge -> DEFAULT, "Set as Active" -> "Set as Default"). Added a read-time migration in store.ts so existing local templates.json files (old field names) still resolve correctly without user action. Co-Authored-By: Claude Sonnet 5 <[email protected]>
Neither the summary view nor the regenerate button gave any indication of which template produced (or will produce) a session's summary, making it unclear what "Refresh" would actually do. Adds a resolveForSession IPC endpoint that surfaces the same resolution summariseSession already uses, and displays it as "Using template: X" above the summary content. Follow-up filed as AUD-119: the resolved template isn't currently pinned to the session, so regenerating an unpinned session after changing the global default silently switches templates. Co-Authored-By: Claude Sonnet 5 <[email protected]>
Per AUD-104's changelog workflow: per-ticket entries under [Unreleased], compiled into a version block at release time. Co-Authored-By: Claude Sonnet 5 <[email protected]>
PR-Agent's own default pr_actions allow-list excludes "synchronize", so it silently no-ops on every new commit pushed to an existing PR even though our workflow trigger includes that event. Explicitly opting synchronize into GITHUB_ACTION_CONFIG.PR_ACTIONS. Co-Authored-By: Claude Sonnet 5 <[email protected]>
getByText('Meeting Notes') matched two elements once the "Using
template: Default Meeting Notes" label landed in SessionDetail —
both the markdown summary heading and the template name span contain
that substring. Passed locally because the label's async fetch didn't
always resolve before the assertion ran, so it only flaked in CI.
Scoped to getByRole('heading', ...) to target the actual markdown
heading unambiguously.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
PrefsLayout has a blanket "Escape closes the window" listener with no way to know a more local component (a modal, an inline text field) already wants to consume that keystroke. NewTemplateModal and InlineEditableText's own Escape handlers didn't stop propagation, so closing the modal via Escape also hid the entire Preferences window. This is what caused the new-template-modal.spec.ts CI failure on Ubuntu/Windows: the Escape sub-scenario hid the window, and the next scenario's click on a now-hidden window hung until timeout — something macOS's Electron/CDP integration tolerates but Windows/Linux do not. Passed locally on macOS for the same reason, so this was never caught until it hit the real CI matrix. Also bumped output-section-reorder.spec.ts's fixed inter-keystroke waits (50-100ms) to more generous values (200-300ms) — dnd-kit's keyboard sensor state settling apparently doesn't reliably complete within the tighter windows on CI hardware, causing an intermittent "reorder didn't happen" failure on Ubuntu. Co-Authored-By: Claude Sonnet 5 <[email protected]>
|
/review |
Leftover from rebasing an older synchronize-trigger fix on top of main's already-merged rewrite to comment-triggered-only. The pull_request trigger this env var existed to fix no longer exists on this workflow, so it was dead, confusing config. File now matches main's version exactly. Co-Authored-By: Claude Sonnet 5 <[email protected]>
|
Persistent review updated to latest commit 0da318b |
0da318b to
b4430f5
Compare
User description
Summary
Incremental build-out of the Afterword (custom prompt templates) feature. Tickets landed so far on this branch, in order:
This branch is a persistent feature branch and will accumulate further Afterword tickets before a single merge to
main.Test plan
npm run typecheckpassesnpm run lintclean on all touched files (pre-existing warnings elsewhere untouched)npm run buildsucceedsprompt-templates.spec.ts,prompt-template-editor.spec.ts,new-template-modal.spec.ts,output-section-reorder.spec.ts(pointer drag, keyboard reorder, single-section edge case)🤖 Generated with Claude Code
PR Type
Enhancement, Tests, Bug fix, Documentation
Description
Adds full template editor workflow
Supports preset-based template creation
Renames active templates to default
Adds drag reordering and coverage
Diagram Walkthrough
File Walkthrough
17 files
Implements full prompt template editor pageAdds sortable output sections listAdds editable draggable section rowsAdds prompt editor with variable chipsAdds reusable inline editable text controlAdds editor preview save actionsImplements blank and preset creation modalAdds preset option card componentAdds template deletion confirmation dialogAdds unsaved changes confirmation dialogWires default actions and modal dataUpdates card badge to default terminologyRenames active menu action to defaultRenames active template logic to defaultAdds default and session resolution IPCResolves summaries through default templateShows resolved summary template name1 files
Migrates legacy active template storage1 files
Adds output section reordering tests1 files
Documents Afterword feature additions19 files