Copy nodes, bind the keys, and keep publish within reach

The floating bars used to make way for a side panel, which hid Publish
exactly when a node had just been edited. They keep their lane now and
the panel is inset out of it; the enlarged code editor stays a floating
surface between the two bars rather than covering them.

Shortcuts are one small registry (`lib/shortcuts.ts`): undo, redo, ⌘K,
copy, paste, and ⌘S — which publishes the flow, or applies the code when
the editor has focus. Copying carries a node's own source through
localStorage, so a paste works in another flow too.

A flow is now named where a node is, at the top of its panel and only
there, and both take effect on Confirm. Flow-level edits go through the
undo stack with everything else, clicking the canvas puts the flow panel
away, a failing node opens the logs filtered to its own traceback, and
the panel carries its test id on a phone as well.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H7LwYgJfpkbLCTeiAf8U4A
This commit is contained in:
2026-08-16 16:43:41 +02:00
co-authored by Claude Fable 5
parent 929bb56662
commit fa12ffd323
9 changed files with 477 additions and 222 deletions
+5 -2
View File
@@ -27,7 +27,7 @@ import {
} from "@/components/ui/tooltip"
import { slideUp, transitions } from "@/lib/motion"
import { cn } from "@/lib/utils"
import { LogsPanel } from "./LogsPanel"
import { type LogsFilter, LogsPanel } from "./LogsPanel"
/**
* What "fit" means on this canvas: the view a flow opens with, and the one the
@@ -47,6 +47,7 @@ export function FlowDock({
running,
enabled,
paused,
logs,
onAddNode,
onRun,
onTogglePause,
@@ -57,6 +58,8 @@ export function FlowDock({
running: boolean
enabled: boolean
paused: boolean
/** Owned by the editor, because a failing node can open it too. */
logs: LogsFilter
onAddNode: () => void
onRun: () => void
onTogglePause: () => void
@@ -164,7 +167,7 @@ export function FlowDock({
<Separator orientation="vertical" className="mx-0.5 !h-5" />
<LogsPanel flow={flow} />
<LogsPanel flow={flow} {...logs} />
<Tooltip>
<TooltipTrigger asChild>