feat(web): architect-backed AI drawer on /specs/$specName #1127
No reviewers
Labels
No labels
area:agents
area:dashboard
area:database
area:design
area:design-review
area:flows
area:infra
area:meta
area:security
area:sessions
area:webhook
area:workdir
security
type:bug
type:chore
type:meta
type:user-story
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
charles/agent-hooks!1127
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "code-lead/1119"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #1119.
Summary
Wires
MarkdownAssistantDrawerinto/specs/$specNameso operators can iterate on a spec body without leaving the editor. Conversation history is remembered per spec inlocalStorage.Sparkles"Assistant" button in the spec header opens the drawer. State mirrors to?assistant=openso deep links round-trip.⌘⇧Atoggles viauseSpecsAssistantShortcut; the binding is catalogued under a newspecsshortcut scope (header shows the chord, help overlay lists it).last_session_idtolocalStorageunderspecs:<repo>:<specName>:lastSession. Reopening the drawer feeds the id back via the newinitialSessionId/onSessionChangeprops onMarkdownAssistantDrawer, which callsfetchArchitectSessionand shows the prior transcript. New chat clears the key. Stale ids (server purged) fall back to a fresh chat silently.buildSpecAssistantUserMessagemirrors the skill-assistant prompt: filename header +Repo:line + fenced current body + operator request.onApply(next)overwrites the editor draft via a newexternalReplace={content,rev}hatch onSpecEditor(no remount — autosave then persists the new body). When the draft is dirty, a Base UI Dialog confirms before clobbering.Test plan
bun run test src/routes/specs.test.tsx— 24 tests pass (11 new + 13 retained from wsplit-2).just qa— typecheck + Biome + paraglide + i18n + sql-layer + flow-schema all clean. Web/server unit suites pass./specs/some-spec?assistant=open, send a message, reload — transcript restores.⌘⇧Atoggles. Dirty the editor, click Insert — confirm dialog appears.Out of scope (deferred per ticket)
🤖 Generated with Claude Code
APPROVED ✅
All AC from #1119 verified. CI green. One trivial dead-key note below, not a blocker.
AC verification
Sparklesbutton opensMarkdownAssistantDrawer?assistant=openparam round-trips; toggles callnavigate({ replace: true })buildMessagewraps persisted body in fenced block + filename header + user textonApplyon dirty draft gates behind Base UI Dialog confirm<Drawer>primitive (right-side slide-out pattern)specs:<repo>:<specName>:lastSessionto localStorageinitialSessionId→ hydrates transcriptonSessionChange(null)retry: false+ error effect)aria-label+ visible label (both fromm.specs_assistant_open())Cmd+Shift+Aregistered inSHORTCUTSunderspecsscope; kbd hint in drawer headervalidateSearchnormalises non-"open"values toundefinedMinor observation — dead i18n key (non-blocking)
specs_assistant_subtitlewas added to bothen.jsonandfr.jsonbut is never called. The drawer subtitle is built as a hardcoded JSXReactNodein theassistantSubtitlememo:The
subtitleprop was correctly widened toReactNodeto accommodate this. The orphaned key should be removed from both message files in a quick follow-up (or the JSX could call the key if desired — the current approach using JSX for the<kbd>element is fine either way). Not blocking merge.