Repository navigation
Edit with your agent: copy a prompt for a code-managed template's file #503
Copy link
Copy link
Closed
Labels
Description
Map: Map: send code-managed email templates with one PostHog call
Spec: Spec: copy-as-code and open-a-PR for code-managed templates (revision 3), sections "Edit with your agent (stack A)" and "Usage events"
Cast: Opus 5.5, high
Repository: PostHog/posthog (frontend only)
Stack: A, second slice
Question
Can a person start a change to a code-managed template from its page, and hand their coding agent a prompt that names the file, the contract, and how the change goes live?
Delivers end to end.
- Button. A code-managed template shows "Edit with your agent" in the Save slot. The read-only preview, Duplicate and "Stop managing in code" stay. The notice gets the spec's new text.
- Popover. Clicking opens a popover anchored to the button, with:
- a text area "Describe the change", autofocused, prefilled with the template's
change_prompt_starterfrom Code-managed templates: the change prompt on the template API #512, with the cursor at the end; - a collapsed "Show full prompt";
- "Copy prompt", disabled with "Describe the change first" while the text equals the starter or is blank.
- a text area "Describe the change", autofocused, prefilled with the template's
- The prompt is the person's sentence, a blank line, and the template's
change_prompt_contextfrom Code-managed templates: the change prompt on the template API #512, verbatim. There is no prompt builder in the frontend. - The text lives in page state only, and survives closing and reopening the popover.
- After copy: the spec's toast; the popover closes. No request leaves the page.
- Events:
message template agent prompt openedandmessage template agent prompt copied, with no prompt text, path or repository in properties;message template duplicatedandmessage template released from codeon the adjacent Email templates: show "Managed by code" and the source file in the library #489/Email templates: read-only view of code-managed templates #492 actions, if they have no event yet.
Test seams.
- Kea logic test at the API boundary:
- the starter comes from the API field;
- copy is disabled until the sentence changes;
- the clipboard holds the sentence plus the context verbatim;
- no write request.
- A story for the popover with a path, without a path, and expanded.
- Prior art:
messageTemplateLogic.test.ts; clipboard and pending handling of feat(workflows): copy a workflow as @posthog/workflows code PostHog/posthog#104452 (fork branchfeat/workflows-copy-code).
Write scope. products/workflows/frontend/TemplateLibrary/: a new popover component and its story, MessageTemplate.tsx, messageTemplateLogic.ts, MessageTemplateMenu.tsx, templateCopy.ts.
Proof.
- Red: the "copy holds the sentence plus the context" logic test fails.
- Green: the logic tests pass.
- Local:
- Upload a template from a file inside a git checkout through posthog-node (with posthog-node: fill the template source repository, path and ref on upload #510, or with an explicit
source). - Open the template, complete the sentence, and copy the prompt.
- Paste it into a coding agent session in that checkout. The agent edits the file.
- Send through the SDK. The dev mail catcher shows the change, and the first send uploads (
template_outdated, then success).
- Upload a template from a file inside a git checkout through posthog-node (with posthog-node: fill the template source repository, path and ref on upload #510, or with an explicit
- Screenshots at 1280px with the side panel open and at full width, in the PR.
Acceptance criteria
- The copied prompt starts with the person's sentence and carries the server's context block verbatim.
- A template without a path still gets a usable prompt, with no dialog.
- No request leaves the page.
- Screenshots and the agent round trip in the PR.
Blockers
Blocked by #512 (the context and starter fields).
How to build (map #461)
/tddred-green-refactor, outside-in, at the seams named above. Real Postgres, Valkey and ClickHouse; mock only what the seam section allows.- Repo skills apply where the diff touches their area:
/writing-tests,/writing-ui-components,/writing-kea-logics,/writing-user-facing-copy,/writing-code-comments,/improving-drf-endpoints,/routing-outbound-api-calls. - Read code from
origin/spec/code-managed-templates(the fork's integration branch for feat(messaging): upload, send and lock code-managed email templates PostHog/posthog#118924), not frommaster. - Public repo: no usage numbers, customer names, internal metrics, Slack content or security reasoning in code, commits or the PR. Fixture addresses use
example.com. The private note the map points at is background only; never quote it. - Shipped means a draft PR handed off for review (see the map's Notes for remotes and branches). Never mark ready, enqueue or merge. The conductor names the stack's integration branch.
Reactions are currently unavailable
Activity
[-]Copy as code: copy a code-managed template as its HTML file[/-][+]Edit with your agent: copy a prompt for a code-managed template's file[/+]Silthus commentedon Oct 17, 2026
Runtime: T3 child task
Task:
node:delegated-task:command%3Amcp%3A1778d880-5a25-404c-80d0-25fc5ccca3b2%3Adelegate-task%3Awf-email-impl-503-1Cast: Opus 5.5, high.
Silthus commentedon Oct 17, 2026
Note
🤖 Opus 5.5 responding on behalf of Michael
Resolution
Landed
62c695af6cbonspec/template-agent-editas a fast-forward from0ba8f7972c2. The ship ticket #516 owns the PR and the review.EditWithAgentButton.tsx), anchored to the button:change_prompt_starter, caret at the end;change_prompt_contextverbatim. The frontend builds nothing else.messageTemplateLogiconly. The sentence survives closing and reopening the popover.message template agent prompt opened{template_id, has_path, has_repository},message template agent prompt copied(plusvariable_count),message template duplicated{template_id, code_managed},message template released from code{template_id}. No prompt text, path or repository in properties.Proof
Red (red.log), the new tests on the base tree:
7 failed, 30 passed.copies the sentence and the server context verbatim, and sends nothing:TypeError: logic.actions.setAgentPromptOpen is not a function.Expected: "message template duplicated" … Received: "$pageview".Green:
messageTemplateLogic.test.ts:37 passed(green.log).TemplateLibrary/pluslib/components/Git:7 suites, 88 passed, nothing skipped (green-library.log).messageTemplateLogic, API mocked at HTTPcopyAgentPromptDisabledReasonis "Describe the change first"openedevent with exact propertiesnavigator.clipboard.writeTextgets the sentence,\n\n, the context verbatim; noPATCHorPOST; popover closed; spec toast;copiedevent withvariable_count: 2Local gate on the landed tree:
tsgo --noEmit --checkers 1infrontend/throughfleet heavy: exit 0.pnpm --filter=@posthog/frontend fix: exit 0.pnpm install --frozen-lockfile: consistent.hogli ci:preflight --strict):"failures": 0.build:openapior mypy run.Browser check (Storybook from this worktree, real
Appscene, API mocked at HTTP, log): the text area is focused with the caret at 33 of 33 characters; the clipboard holds the expected prompt; the popover closes; reopening keeps the sentence; zero non-GET/api/requests.Screenshots (MockHog project,
example.comrepository, invented copy, no customer data). Narrow is a 560px window, about the scene of a 1280px window with the side panel open. Wide is 1440px.Committed stories,
Products/Workflows/Template library/Edit with your agent: with a path, without a path, full prompt shown.Agent round trip, partial:
originhttps://github.com/example/app.git) withemails/welcome.htmlcommitted.template_change_prompt.change_promptran on that file, with its commit assource_ref. That is the function Code-managed templates: the change prompt on the template API #512 proved through the API.claude -psession (Sonnet) in the checkout, with only read and edit tools. The agent changed the button color in the file and nothing else (diff). It did not upload, and it said that a send-by-key app needs a re-upload (session).Gaps
Calls made
nulluntil the person types, and a selector falls back to the starter. So a template that loads after the popover mounts still shows its starter.variable_countcounts the distinct{{ variables.<name> }}in the server's context, with the server's name pattern. The frontend doesn't scan the template content.copyToClipboard's toasts ("Could not copy prompt to clipboard", or the HTTPS warning), and the popover stays open with the sentence.MessageTemplateMenu.tsx. The page menu and the notice both dispatchduplicateTemplate, so one event covers both.templateCopy.tsandMessageTemplateMenu.tsxare unchanged.change_prompt_*joined the server-owned fields, so a released template's save never sends them.playuses@testing-library/dom, which the lint rule requires.products/workflowsnow declares it anduser-eventas devDependencies, the wayproducts/legal_documentsdoes. The lockfile gains 6 lines. I dropped an unrelatedunlayer-typesbump thatpnpm installadded.Follow-ups
EditWithAgentButton. The button already shows the dropdown chevron, so the side action should replace it rather than add a second one.AgentPromptand reads the samechangeSentence.messageTemplatesLogic.duplicateTemplate) has nomessage template duplicatedevent. It was outside this ticket's write scope. The ship ticket or Copy as code: copy a code-managed template as its HTML file #509 can add it withcode_managed.Full prompt shownstory.