The imperative approach inserted overlay elements directly into
Lexical-managed CodeNode DOM elements. Lexical's MutationObserver
detected the foreign DOM nodes, reconciled them away, which triggered
update listeners that re-inserted them — causing an infinite loop
that froze the app.
The new approach renders overlay elements via React, positioned
absolutely in a pointer-events:none container that sits over the
content editable. Overlay positions are computed from each code
element's bounding rect and updated via requestAnimationFrame on
editor updates and scroll events. This avoids all Lexical DOM
mutation and eliminates the freeze.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Language selector:
- Replaced toolbar dropdown with an imperative overlay rendered
directly inside each code block's DOM element
- Overlay uses contentEditable='false' + position:absolute at the
top-right of the code block, styled as a compact native select
- Plugin re-inserts overlays after each Lexical reconciliation to
survive DOM diffing
Code block insertion:
- toggleCodeBlock now inserts a trailing paragraph after the code
block when it would otherwise be the last element, so the user
can always type regular text below a code block
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When the cursor is inside a code block, the formatting toolbar shows
a language dropdown (22 languages). Selecting a language updates the
CodeNode, which the markdown serializer writes as the fenced code
block language tag (e.g. \\\ ypescript).
A CodeBlockLabelPlugin syncs a data-code-language attribute on each
code block element so CSS ::before shows the friendly language name
as a small label at the top of the block.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Increase editable min-height from 40px to 52px and padding from 8px
to 10px so the send button (32px + 8px bottom offset) has 12px
clearance from the toolbar border instead of 0px
- Add display: block to .mc-code-block — Lexical CodeNode renders as
<code> which is inline by default, causing border/padding to split
visually across lines instead of forming a proper block
- Revert empty code block to code.select() without synthetic TextNode
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Move send button into MarkdownComposer children slot so it positions
relative to the editor content area, not the full container
- Always create a text node when inserting a code block to prevent
Lexical from rendering a split/empty code block artifact
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace the plain <textarea> in ChatPane with a full WYSIWYG
markdown composer built on Lexical 0.42.0.
Composer features:
- Rich text editing with inline formatting (bold, italic, code)
- Block-level elements: headings, bullet/numbered lists, code blocks,
blockquotes, links via markdown shortcuts (e.g. ## , - , \\\)
- Formatting toolbar with active-state indicators
- Markdown paste auto-import when the editor is empty
- Enter to send, Shift+Enter for newline (matches prior behavior)
- Disabled state syncs with session busy/config states
- Serializes to markdown on submit via the backend helpers
Files:
- New: MarkdownComposer.tsx (Lexical editor, toolbar, internal plugins)
- Modified: ChatPane.tsx (swap textarea for MarkdownComposer, simplify state)
- Modified: styles.css (add markdown composer theme classes)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add CSS styling for selected edges (indigo highlight with glow)
- Enable orchestrator↔agent connections in group-chat mode
- Downgrade disconnected-agent validation from error to warning
- Rename addHandoffEdge to addEdge (generic for all modes)
- Add tests for group-chat connection rules
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Extend edge deletion to group-chat orchestrator↔agent edges in addition
to handoff agent↔agent edges. Structural edges (user-input/output,
distributor/collector) remain non-deletable across all modes.
Sequential, concurrent, and single modes keep fully structural topologies
with no user-deletable edges.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Enable Delete-key removal of agent nodes on the canvas; system nodes
remain non-deletable. Removals route through the authoritative
removeAgent path which prevents deleting the last agent.
- Stack Model and Reasoning selects vertically in the inspector panel
so they fit within the 320px-wide column without truncation.
- Add right padding (pr-36 / 144px) to the editor header so the Save
and Delete buttons clear the Windows title-bar overlay controls.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Color-code edges by semantic role: structural edges (system↔node) in
muted zinc, agent-to-agent edges in indigo for clear visual separation
- Switch from smoothstep to bezier curves for smoother, more natural
edge routing that reduces right-angle overlaps
- Stagger agent nodes at alternating X offsets in concurrent, handoff,
and group-chat layouts so parallel fan-out/fan-in edges take distinct
bezier paths instead of stacking
- Increase spacing in all layouts to give edges more room
- Add dagre-powered auto-layout button (top-right of canvas) that
computes optimal left-to-right hierarchical node positions
- Add 2 new tests for auto-layout across all orchestration modes
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Hide the target (left) handle on SystemNode and AgentNode so each node
displays only one visible circle. The directional arrow marker on edges
communicates flow direction, halving the visual handle count.
- user-input: source handle on right (visible)
- user-output: target handle on left (visible)
- all others: source handle on right (visible), target on left (hidden)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add ArrowClosed markers to all graph edges for clear directional flow
- Replace generic Bot icon with AI provider logos (OpenAI, Anthropic,
Google) on agent nodes, inferred from the agent's model id
- Show model display name as subtitle on agent nodes (e.g. 'GPT-5.4',
'Claude Opus 4.5')
- Thread availableModels catalog from PatternEditor through canvas to
resolve friendly model names; falls back to raw model id
- Add 3 new tests for arrow markers, provider icons, and model labels
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Hide input handle on User Input nodes and output handle on User Output
nodes (separate userInputNode/userOutputNode node types)
- Enable edge deletion in handoff mode only (Delete key or React Flow UI);
only agent-to-agent edges are deletable, structural edges are protected
- Block all edge mutations (add/delete) in concurrent and group chat modes
- Add agent as disconnected node without auto-rebuilding the graph
- Add sequential reorder controls (↑↓) in the inspector panel with
position/order swap and automatic edge rebuilding
- Replace circular group chat layout with vertical column to prevent
bidirectional edge crossings
- Tighten handoff layout spacing so edges between triage and specialists
don't overlap nodes
- Use smoothstep edge type for cleaner edge routing across all modes
- Add 6 new tests covering reorder, disconnected add, edge deletion rules,
and node type assertions
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace the flat agent list and static flow diagrams in PatternEditor with
an interactive React Flow canvas backed by the authoritative PatternGraph
model. Users can now see and manipulate orchestration topology visually.
Changes:
- Add @xyflow/react (React Flow) as a canvas library
- Create patternGraph view-model layer for graph-to-canvas projection
- Create GraphNodes with custom system/agent node components
- Create PatternGraphCanvas with drag, connect, and selection support
- Create PatternGraphInspector for selected node/agent details
- Rewrite PatternEditor with split layout: canvas + inspector sidebar
- Add dark theme CSS overrides for React Flow
- Add 11 tests covering view-model projection, connection rules, and
graph mutation helpers
- Update ARCHITECTURE.md to reflect the new renderer graph boundary
The canvas projects PatternGraph into React Flow nodes/edges. Handoff mode
supports drawing new agent-to-agent edges interactively. Node positions
persist to the graph on drag completion. Agent editing moves from inline
forms to the inspector panel on node selection.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- correlate permission requests to tool names via ToolCallId when the
workflow request stream exposes matching CallId values
- keep the url-to-web_fetch alias only as a narrow fallback when a
matching tool call cannot be recovered
- cover generic permission-category lookup for url, shell, and read in
sidecar tests
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Move interactive tool toggles and auto-approval overrides from the
ActivityPanel side panel into compact pill-style popovers above the
chat composer in ChatPane. This cleanly separates concerns:
- ActivityPanel is now purely read-only (agents + timeline)
- ChatPane owns all session-level interactive controls
- Tools pill: popover with MCP/LSP enable/disable toggles
- Auto-approval pill: popover with grouped tool auto-approval overrides
including session override state and reset action
Follows the existing InlineModelPill/InlineThinkingPill pattern for
scratchpad sessions, giving non-scratchpad sessions the same kind
of inline configuration experience.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- fix double-toggle bug in PatternEditor (nested buttons caused clicks to cancel out)
- only show tool auto-approval section when tool-call checkpoint is enabled
- group tools by kind (built-in, MCP, LSP) with sub-headers when mixed
- remove redundant per-row shield icons and kind badges from ActivityPanel
- fix missing bottom margin on Tools section in ActivityPanel
- shorten and clarify status badges and empty-state messages
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- load runtime tools dynamically from Copilot CLI capabilities via tools.list
- merge runtime tools with configured MCP and LSP tools in the approval catalog
- keep a fallback builtin runtime tool list when capabilities are unavailable
- move approval-tool pruning to the app service so dynamic tools are not dropped on load
- update approval UI and docs to use the corrected runtime-tool model
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- PatternEditor: tool auto-approval defaults section with toggles per tool
- ActivityPanel: per-session override section with inherited/custom state and reset action
- ChatPane: surface toolName in approval banner and queued approval list
- Disable controls while running; scratchpad non-interactive explanation
- Use listApprovalToolDefinitions() exclusively for tool identity
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- ChatPane: show 'Approval 1 of N' label, queued-approvals accordion preview,
queue count badge in header, and hint text for queue advancement
- Sidebar: show '+N queued' count next to 'Awaiting approval' badge
- ActivityPanel: show total approval count in header badge
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Rewrite ARCHITECTURE.md as a higher-level system document.
The new version removes file-by-file detail, adds mermaid diagrams,
and focuses on runtime boundaries, communication links, security,
state ownership, and cross-cutting concerns so readers can understand
how the app is architected without reading the code first.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Create ARCHITECTURE.md with a concrete overview of the Electron app,
its renderer/main/preload boundaries, shared domain model, .NET
sidecar, persistence model, workflow execution path, tooling model,
and build/release pipeline.
Also update AGENTS.md so future agents keep ARCHITECTURE.md in sync
when a change materially affects the system design.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The Windows title bar overlay (minimize/maximize/close buttons) was
hardcoded to dark colors and did not update when switching themes.
- Add titleBarTheme helper that maps AppearanceTheme to overlay and
background colors, using nativeTheme for the system preference
- Call applyTitleBarTheme from the setTheme IPC handler so the overlay
updates immediately on theme change
- Apply persisted theme on startup so the overlay matches from launch
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add appearance theme support (dark/light/system) using CSS custom
property overrides. In light mode the Tailwind zinc scale is inverted
and semantic surface/border tokens are swapped, so all existing
utility classes pick up the new palette automatically.
- Add AppearanceTheme type and theme field to WorkspaceSettings
- Add setTheme IPC channel wiring (contracts, preload, handler, service)
- Add [data-theme='light'] CSS overrides for zinc scale, surface tokens,
scrollbar, and markdown prose colours
- Add Appearance section to SettingsPanel with radio-button theme picker
- Apply data-theme attribute on document root via useEffect in App.tsx,
with matchMedia listener for the system option
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Tighten font sizes to match the app's compact design language:
- WelcomePane: heading from text-xl (20px) to text-base (16px),
buttons and descriptions from text-sm (14px) to text-[13px]
- SettingsPanel: all section headings from text-sm to text-[13px]
- NewSessionModal: title from text-sm to text-[13px]
- PatternEditor: title from text-sm to text-[13px]
- ChatPane: empty-state prompt from text-sm to text-[13px]
- Markdown prose: h1 from 1.25rem to 1.125rem, h2 from 1.125rem
to 1rem, h3 from 1rem to 0.9375rem
Keeps text-sm only for the app brand name, loading state, and error
headings where larger text is intentional.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add a GitHub Actions workflow that validates the app on pushes and pull requests, and publishes Windows, macOS, and Linux release assets when a tag is pushed.
Also replace the Windows-only packaging flow with cross-platform Bun scripts for sidecar publishing and Electron packaging so the release job can package each runner natively.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>