feat(canvas): workflows attached to canvases#3535
Conversation
A workflow canvas = a canvas artifact + a PostHog workflow (HogFlow) + the
link between them. The unified canvas generation prompt gains a workflow
intent branch: describing an ongoing action ("Send an email after signup")
makes the build agent draft a workflow over the PostHog MCP workflows-*
tools, author email templates with neutral branding, test every branch,
and publish an observability canvas from a baked-in starter board (health
or engagement) instead of authoring React from scratch.
- Workflow link primitive: the agent-side hooks pair a workflows-create/get
result with the canvas publish and emit _posthog/workflow_built; the app
writes the link into the dashboard row meta (setWorkflow) and stamps
templateId "workflow" (lightning icon in Artifacts, workflow badge in the
canvas header, edit-time prompt resolution).
- Go-live gating: workflows-enable / run-batch / schedule-create /
update-schedule always raise an "Approve & publish" card - even in auto
mode, with no always-allow, never persisted - and the cloud agent-server
parks (never auto-approves) such requests when no client is reachable.
- Generating state now mirrors the agent's live to-do list (StepList) and
flips optimistically on submit; a terminal cloud run now clears
"Generating" even while the chat session lingers connected.
- Hero suggestions gain workflow ideas; repo-less tasks hide the diff chip.
Generated-By: PostHog Code
Task-Id: 3b50883f-cab5-443a-8b92-3d0c948688da
- Parse the PostHog MCP's YAML tool results in the workflow-built pairing: workflows-create/get return a YAML document, not JSON, so the link notification never fired. Add a top-level-line YAML fallback with a regression test against a captured real payload. - Resolve the backend feed channel in useGenerateFreeformCanvas when the caller doesn't pass one (the canvas hero didn't), so hero-initiated builds land in the channel feed like composer submits. - Never demote an auto/bypass session to acceptEdits when the user answers a permission card with "always allow" - the upgrade helper previously preferred acceptEdits unconditionally, which turned one "always allow" click into a prompt storm for the rest of an auto canvas build. Generated-By: PostHog Code Task-Id: 3b50883f-cab5-443a-8b92-3d0c948688da
Export findWorkflowBuilt and test it directly: live-stream and replay method variants, request/response and foreign notifications ignored, malformed payloads skipped. Generated-By: PostHog Code Task-Id: 3b50883f-cab5-443a-8b92-3d0c948688da
|
Merging to
After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here |
|
React Doctor found 2 issues in 2 files · 2 warnings. 2 warnings
Reviewed by React Doctor for commit |
|
PR overviewAll previously flagged issues have been addressed. No open security concerns remain on this pull request. Security reviewNo open security issues remain on this pull request. Fixed/addressed: 2 · PR risk: 0/10 |
Workflow builds were only discoverable via + > New canvas. Add a canvas-kind starter card to the channel task suggestions, shown on both new-task surfaces: - Channel home: selecting it prefills the composer AND arms canvas mode, so the submit runs canvas generation (whose unified prompt handles workflow intent) instead of creating a plain task. - New-task screen: TaskInput hands canvas suggestions to the surface, which creates a canvas in the channel and opens it with the starter prompt dropped into the hero composer (one-shot prefill handoff), ready to edit. Generated-By: PostHog Code Task-Id: 3b50883f-cab5-443a-8b92-3d0c948688da
- Classify go-live calls adapter-neutrally at the cloud relay: Codex forwards PostHog exec approvals without Claude's alwaysGated marker, so the park rule now also inspects the tool call itself (isPostHogGoLiveToolCall: posthog server exec + always-gated sub-tool). - Recognize plugin-installed PostHog servers (mcp__plugin_posthog_*__exec) in the exec-tool matcher, mirroring the renderer's server-name pattern, so both the destructive and go-live gates cover them. - Consume the pendingWorkflow slot after a link is emitted, so a later canvas publish in the same session can't re-emit a stale workflow link. Generated-By: PostHog Code Task-Id: 3b50883f-cab5-443a-8b92-3d0c948688da
What
A workflow canvas = a canvas artifact (desktop-FS
dashboardrow) + a PostHog workflow (HogFlow, built and managed only via theworkflows-*MCP tools) + the link between them (meta.workflow). A user types "Send an email after signup" into the canvas composer; the build agent drafts the workflow, authors the email template (neutral branding), tests every branch, and publishes an observability canvas from a baked-in starter board - then stops for the human to approve going live.There is no "New workflow" button: the standard canvas generation prompt gained a workflow intent branch, so free-typed requests just work and suggestion chips are plain prefilled prompts.
How
freeformPrompt.ts): first builds carry a MODE gate (plain canvas / build a workflow / track an existing workflow) plus a<workflow_instructions>block - discover destinations → draft viaworkflows-create/workflows-patch-graph→ email templates in parallel subagents (neutral branding, never ask mid-run) →workflows-test-runevery branch →workflows-blast-radiusfor batch → publish the canvas → summarise → STOP. Edit prompts are unchanged.workflowStarters.ts):WORKFLOW_HEALTH_STARTER(deliverability/health) andWORKFLOW_ENGAGEMENT_STARTER(email engagement) are embedded in the prompt so the agent edits a proven scaffold instead of authoring React from scratch - this is what cuts the multi-minute UI generation down.workflows-create/workflows-getresult with the subsequent canvas publish and emit_posthog/workflow_built; the app catches it off the session event stream, PATCHesmeta.workflowonto the row, and stampstemplateId: "workflow". That one write drives the lightning-bolt icon in Artifacts, the status badge in the canvas header, edit-time prompt resolution, and the canvas rename. The MCP renders tool results as YAML, so the parser handles both YAML documents and JSON envelopes (regression-tested against a captured live payload).workflows-enable/workflows-run-batch/workflows-schedule-create/workflows-update-schedulealways raise an "Approve & publish" card - even in auto mode, before persisted always-allows, with no always-allow option, never persisted. The cloud agent-server relays these when a client is reachable and otherwise parks them (never falls through to auto-approve).Verification
pnpm --filtertypechecks clean for core / ui / agent / host-router; biome lint clean (no new warnings);check-host-boundariesclean.workflows-test-run, saved-insight-backed canvas published from the engagement starter,_posthog/workflow_builtemitted with the full payload, auto-naming, and the auto-mode demotion fix.Known gaps / follow-ups
agent-server.ts) ships with the sandbox image; verify the go-live card relays after the image rolls out (unit-tested meanwhile).workflowStatuson the badge is link-time only (not kept live).needs_approvalstate onmcp__posthog__execmakes every exec call prompt regardless of mode - pre-existing MCP-approval behavior, not introduced here.Created with PostHog Code