Skip to content

feat(workflow): guided-canvas — docked inspector, upstream picker, self-documenting nodes#2602

Open
simlarsen wants to merge 2 commits into
feat/workflow-json-input-safetyfrom
feat/workflow-guided-canvas
Open

feat(workflow): guided-canvas — docked inspector, upstream picker, self-documenting nodes#2602
simlarsen wants to merge 2 commits into
feat/workflow-json-input-safetyfrom
feat/workflow-guided-canvas

Conversation

@simlarsen

@simlarsen simlarsen commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Continues the workflow-builder simplification. Stacked on #2601 (base is that branch, so this diff is only the new work; GitHub retargets it to master once #2601 merges).

All changes are in Common/UI/Components/Workflow/* (+ a new pure-logic GraphUtils.ts). No storage or executor changes — existing workflows are unaffected.

What changed

1. Docked inspector panel. Configuring a step used to open a full-screen modal that hid the whole graph. It's now a docked panel on the right edge of the canvas, so you see the graph and the step's settings together. ComponentSettingsModalComponentSettingsPanel: same sections + ArgumentsForm, rendered with its own header (title + close) and footer (Delete + Save, Save disabled on validation errors). It overlays the canvas absolutely, so React Flow's layout is untouched (no canvas-sizing regression), and remounts (key={internalId}) when you select a different node.

2. Upstream-only data picker. Inserting "a value from another step" now offers only steps that run before the current one (backward graph walk). A "Show all steps" escape covers loops/fan-out, plus a helpful empty state when the step isn't connected yet.

3. Self-documenting node faces. Each node shows what it's configured to do (Channel: #alerts · Message: …) instead of the same static description. Secret-safe by construction: safe-type allowlist shown; URL creds + query stripped; JSON / headers / DB queries and secret-named/typed fields → ••••; {{ tokens }} humanized to {title}.

4. Tidier config. The technical Identifier field is tucked behind an "Advanced" disclosure.

Verification

Per the reviewer's suggestion, components are exercised directly with React Testing Library (jsdom) — no full-app run needed:

  • ComponentSettingsPanel.test.tsx (5 tests): renders title + settings; Save/Close/Delete call their callbacks; delete requires confirmation; Advanced reveals the Identifier.
  • GraphUtils.test.ts (12 tests): graph traversal (chains, diamonds, cycles, roots) + summary redaction / URL-masking / token-humanizing / whitespace-skip.
  • 26 workflow tests total pass. tsc --noEmit ✓ · eslint ✓.

Adversarial review hardening (earlier pass)

A multi-agent adversarial review (3 lenses → per-finding verification) caught 5 confirmed findings I fixed before pushing, notably:

  • Secret leak (major): node summary printed URL/header/JSON values verbatim (basic-auth URLs, Authorization headers). → redact by type + mask URLs.
  • Blank-frame anti-pattern (major): picker list held in useState+useEffect. → compute during render.
  • Placeholder crash (major): "Show all steps" surfaced the empty-id placeholder and crashed search on undefined return values. → exclude empty-id + guard the loop.

Deferred (next)

Inline data chips replacing the {{…}} string-append (highest-risk — needs a token-input with golden round-trip serialization tests).

🤖 Generated with Claude Code

…r, self-documenting nodes

Continues making the workflow builder simpler to understand. Three changes,
all in Common/UI/Components/Workflow/*, with a new pure-logic GraphUtils.ts
(unit-tested) and no storage/executor changes.

1. Upstream-only data picker. When inserting "a value from another step", the
   picker now offers only steps that actually run BEFORE the current one
   (computed by walking the graph backwards from the selected node), so you
   can no longer reference data that won't exist at runtime. A "Show all
   steps" escape covers loops / fan-out, and a helpful empty state guides you
   when the step isn't connected yet. The picker title/description are now
   plain-language.

2. Self-documenting node faces. Each node shows a short summary of what it is
   actually configured to do (e.g. "Channel: #alerts · Message: …") instead
   of the same static description on every node. Secret-safe by construction:
   values are shown only for a small allowlist of safe input types; URLs have
   their credentials and query string stripped; JSON / headers / queries and
   secret-named/typed fields are redacted to ••••; {{ tokens }} are humanized
   to friendly names like {title}.

3. Tidier config. The technical "Identifier" field is tucked behind an
   "Advanced" disclosure so the settings panel stays focused.

Hardening from an adversarial review pass:
- Redact structured/URL values on the node face so secrets (basic-auth URLs,
  Authorization headers) can't leak onto the shareable canvas.
- Compute the picker's filtered list during render instead of via
  useState+useEffect — removes a blank first frame and redundant recomputes.
- Exclude the empty-id placeholder trigger from the picker and guard the
  search loop against missing returnValues (prevents a crash under "Show all
  steps").
- Wrap long unbroken summary values and skip whitespace-only values.

Tests: 12 GraphUtils cases (graph traversal + redaction/masking/humanizing) +
existing JSON tests, 21 total passing. tsc + eslint clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@simlarsen

simlarsen commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

…the canvas

Configuring a step used to open a full-screen modal that hid the whole graph.
This replaces that modal with a docked inspector panel on the right edge of
the canvas, so you can see the graph and the step's settings at the same time.

- New ComponentSettingsPanel (renamed/reshaped from ComponentSettingsModal):
  same sections + ArgumentsForm, but rendered as a panel with its own header
  (title + close) and footer (Delete + Save, Save disabled on validation
  errors) instead of a <Modal>.
- Workflow.tsx renders it as an absolute overlay on the canvas's right edge,
  so React Flow's own layout is untouched (no canvas-sizing regression). Full
  width on narrow viewports.
- Remount the panel via key={internalId} when the selected node changes —
  because the canvas stays clickable behind the panel, selecting another node
  must re-initialise the form to that step.

Verified by rendering the panel directly with React Testing Library (jsdom):
5 tests covering render, Save/Close/Delete callbacks, delete-needs-confirm,
and the Advanced-identifier disclosure. tsc + eslint clean; 26 workflow tests
pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@simlarsen simlarsen changed the title feat(workflow): guided-canvas — upstream-only data picker + self-documenting nodes feat(workflow): guided-canvas — docked inspector, upstream picker, self-documenting nodes Jul 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants