feat: redesign onboarding tour and add empty state#723
feat: redesign onboarding tour and add empty state#723breaking-brake merged 3 commits intomainbreaking-brake/cc-wf-studio:mainfrom feat/redesign-onboarding-tour-and-empty-statebreaking-brake/cc-wf-studio:feat/redesign-onboarding-tour-and-empty-stateCopy head branch name to clipboard
Conversation
- Reduce tour from 22 steps to 7 focused steps using sample workflow - Add minimize/resume functionality to tour (destroy + drive(index)) - Use allowClose: false with custom close/minimize buttons - Click outside popover triggers minimize - Add empty state dialog with New / Load / Sample Workflow actions - Update translations for all 5 languages Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Caution Review failedPull request was closed or merged during review 📝 WalkthroughWalkthroughAdds a dismissible EmptyState dialog shown when no workflow is loaded and wires it into App → WorkflowEditor (New / Load / Sample actions). Reworks the onboarding Tour into a condensed 7-step flow with minimize/resume behavior and driver lifecycle changes, updates tour translation keys/strings across locales, and adds a small CSS/toolbar attribute tweak. Changes
Sequence DiagramssequenceDiagram
participant User
participant App
participant WorkflowEditor
participant EmptyState
participant FileSystem
User->>App: Open editor (no active workflow)
App->>App: Compute showEmptyState (2 nodes, 0 edges, no activeWorkflow, !runTour, not dismissed)
App->>WorkflowEditor: Render with showEmptyState + handlers
WorkflowEditor->>EmptyState: Render isOpen=true
EmptyState->>User: Show dialog (New / Load / Sample)
alt User clicks "Load"
User->>EmptyState: Click Load
EmptyState->>App: onLoadWorkflow
App->>FileSystem: Post OPEN_FILE_PICKER message
FileSystem->>App: Return chosen file
else User clicks "Sample"
User->>EmptyState: Click Sample
EmptyState->>App: onOpenSample
App->>WorkflowEditor: Load sample workflow
else User clicks "New" / dismiss
User->>EmptyState: Click New / dismiss
EmptyState->>App: onStartFromScratch/onDismissEmptyState
App->>App: Set emptyStateDismissed = true
end
sequenceDiagram
participant User
participant Tour
participant DriverJS as Driver.js
participant DOM
User->>Tour: Start tour (run=true)
Tour->>DriverJS: Instantiate driver at stepIndexRef (0)
DriverJS->>DOM: Highlight element, show popover with injected controls
User->>DOM: Click outside or minimize button
DOM->>Tour: doMinimize invoked
Tour->>DriverJS: Destroy instance
Tour->>Tour: Set minimized=true (persist stepIndexRef)
Tour->>DOM: Render floating resume button
User->>DOM: Click resume
DOM->>Tour: Clear minimized
Tour->>DriverJS: Create new driver and resume at stepIndexRef
DriverJS->>DOM: Continue tour from saved step
Estimated Code Review Effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly Related PRs
Suggested Labels
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (2)
src/webview/src/App.tsx (1)
244-249: Avoid hardcoded default-node IDs in empty-state detection.This logic is tightly coupled to literal IDs; if defaults are renamed, empty-state visibility silently breaks. Prefer shared constants or a store helper that exposes “is default canvas” directly.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/webview/src/App.tsx` around lines 244 - 249, Replace the fragile hardcoded ID checks in isCanvasEmpty with a single source of truth: either import shared constants (e.g. DEFAULT_START_NODE_ID, DEFAULT_END_NODE_ID) or call a store helper like isDefaultCanvas() that encapsulates the logic; then update the isCanvasEmpty expression to use those constants/helper instead of the string literals ('start-node-default' and 'end_node_default') while keeping the same checks for nodes.length, edges.length, and activeWorkflow. Ensure the constants/helper are exported from the shared constants/store module and referenced by the App.tsx isCanvasEmpty calculation so renaming defaults won't break the empty-state detection.src/webview/src/components/EmptyState.tsx (1)
87-92: Prefer class-based hover/focus styles over inline style mutation.The repeated
onMouseEnter/onMouseLeavestyle mutation is harder to maintain; a shared CSS class with:hover/:focus-visiblewill be cleaner and more accessible.Also applies to: 102-107, 119-124
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/webview/src/components/EmptyState.tsx` around lines 87 - 92, Replace the inline onMouseEnter/onMouseLeave backgroundColor mutations in the EmptyState component with a reusable CSS class (e.g., .empty-state-item) that defines :hover and :focus-visible background colors (use the same CSS variables --vscode-list-hoverBackground and --vscode-editor-background). Update the JSX elements that currently use onMouseEnter/onMouseLeave (the elements with those handlers in EmptyState.tsx) to remove those handlers and add the new className instead, and apply the same refactor to the other occurrences noted (the blocks around lines 102-107 and 119-124) so all items use the shared class for hover/focus styling.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/webview/src/components/EmptyState.tsx`:
- Around line 80-81: In EmptyState.tsx, the user-visible strings in the JSX
(e.g., the Dialog.Title "CC Workflow Studio", the subtitle/paragraph text, and
the primary/secondary button labels rendered in this component) are hardcoded;
replace them with i18n keys by importing and using the project's translation
helper (e.g., useTranslation or t) and call t('emptyState.title'),
t('emptyState.subtitle'), t('emptyState.ctaPrimary'),
t('emptyState.ctaSecondary') (or similarly named keys) where those literals
currently appear (including the other occurrences noted in the review), and add
corresponding entries to the locale resource files so the new onboarding labels
are localized.
In `@src/webview/src/components/Tour.tsx`:
- Around line 101-111: The doMinimize callback currently clears the selected
node when minimizing, which breaks resuming on the Property Panel step; modify
doMinimize so it does NOT call setSelectedNodeIdRef.current(null) when
stepIndexRef.current === PROPERTY_PANEL_STEP_INDEX (only clear selection for
other steps), leaving driverRef cleanup and setMinimized(true) unchanged; update
the conditional around setSelectedNodeIdRef to skip clearing for
PROPERTY_PANEL_STEP_INDEX to preserve the .property-panel target for resume.
In `@src/webview/src/constants/tour-steps.ts`:
- Around line 46-51: Replace the brittle setTimeout in the onNextClick handler
(which calls callbacks?.onSelectSampleNode?() and then setTimeout(() =>
callbacks?.moveNext?(), 50)) with logic that waits for the .property-panel DOM
node to actually appear before invoking callbacks?.moveNext?. Use either a
MutationObserver or a short-poll loop that checks
document.querySelector('.property-panel') and resolves when found (with a
reasonable overall timeout/fallback to avoid hanging); keep the call to
callbacks?.onSelectSampleNode?() and then await the presence of
'.property-panel' before calling callbacks?.moveNext?().
In `@src/webview/src/i18n/translations/zh-CN.ts`:
- Around line 352-354: The tour copy under the translation key
'tour.toolbarActions' hardcodes the English action name "Run" instead of using
the localized label; update that string to use the localized toolbar action name
(reference the translation key 'toolbar.run') or reword to avoid hardcoded
English so the Chinese locale displays the translated action ('执行') consistently
with the toolbar. Ensure you edit the 'tour.toolbarActions' value in the zh-CN
translations to reference or match 'toolbar.run' rather than the literal "Run".
In `@src/webview/src/i18n/translations/zh-TW.ts`:
- Around line 352-354: The tour copy under the translation key
'tour.toolbarActions' uses the English word "Run" which mismatches the localized
button label; update that string to use the localized action name '執行' (or
interpolate the existing action label if your project uses a key like
'actions.run') so the guidance text matches the actual toolbar button label.
---
Nitpick comments:
In `@src/webview/src/App.tsx`:
- Around line 244-249: Replace the fragile hardcoded ID checks in isCanvasEmpty
with a single source of truth: either import shared constants (e.g.
DEFAULT_START_NODE_ID, DEFAULT_END_NODE_ID) or call a store helper like
isDefaultCanvas() that encapsulates the logic; then update the isCanvasEmpty
expression to use those constants/helper instead of the string literals
('start-node-default' and 'end_node_default') while keeping the same checks for
nodes.length, edges.length, and activeWorkflow. Ensure the constants/helper are
exported from the shared constants/store module and referenced by the App.tsx
isCanvasEmpty calculation so renaming defaults won't break the empty-state
detection.
In `@src/webview/src/components/EmptyState.tsx`:
- Around line 87-92: Replace the inline onMouseEnter/onMouseLeave
backgroundColor mutations in the EmptyState component with a reusable CSS class
(e.g., .empty-state-item) that defines :hover and :focus-visible background
colors (use the same CSS variables --vscode-list-hoverBackground and
--vscode-editor-background). Update the JSX elements that currently use
onMouseEnter/onMouseLeave (the elements with those handlers in EmptyState.tsx)
to remove those handlers and add the new className instead, and apply the same
refactor to the other occurrences noted (the blocks around lines 102-107 and
119-124) so all items use the shared class for hover/focus styling.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 846f6040-beb5-475b-bca0-140305c06623
📒 Files selected for processing (13)
src/webview/src/App.tsxsrc/webview/src/components/EmptyState.tsxsrc/webview/src/components/Toolbar.tsxsrc/webview/src/components/Tour.tsxsrc/webview/src/components/WorkflowEditor.tsxsrc/webview/src/constants/tour-steps.tssrc/webview/src/i18n/translation-keys.tssrc/webview/src/i18n/translations/en.tssrc/webview/src/i18n/translations/ja.tssrc/webview/src/i18n/translations/ko.tssrc/webview/src/i18n/translations/zh-CN.tssrc/webview/src/i18n/translations/zh-TW.tssrc/webview/src/styles/main.css
| CC Workflow Studio | ||
| </Dialog.Title> |
There was a problem hiding this comment.
Localize the new empty-state labels.
These user-visible labels are hardcoded, so the new onboarding entry point won’t respect the active locale. Please move them to i18n keys.
Also applies to: 96-97, 111-112, 139-140
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/webview/src/components/EmptyState.tsx` around lines 80 - 81, In
EmptyState.tsx, the user-visible strings in the JSX (e.g., the Dialog.Title "CC
Workflow Studio", the subtitle/paragraph text, and the primary/secondary button
labels rendered in this component) are hardcoded; replace them with i18n keys by
importing and using the project's translation helper (e.g., useTranslation or t)
and call t('emptyState.title'), t('emptyState.subtitle'),
t('emptyState.ctaPrimary'), t('emptyState.ctaSecondary') (or similarly named
keys) where those literals currently appear (including the other occurrences
noted in the review), and add corresponding entries to the locale resource files
so the new onboarding labels are localized.
There was a problem hiding this comment.
Intentionally hardcoded in English. This was a deliberate design decision — the title ("CC Workflow Studio") is the product name, and the action labels ("New", "Load", "Sample Workflow") are kept in English to match the toolbar button style throughout the app.
There was a problem hiding this comment.
@breaking-brake, understood — that's a consistent and reasonable design choice. I'll note this for future reviews.
✏️ Learnings added
Learnt from: breaking-brake
Repo: breaking-brake/cc-wf-studio PR: 723
File: src/webview/src/components/EmptyState.tsx:80-81
Timestamp: 2026-04-10T03:34:30.595Z
Learning: In `src/webview/src/components/EmptyState.tsx`, the user-visible strings "CC Workflow Studio" (Dialog.Title/product name) and the action labels "New", "Load", and "Sample Workflow" are intentionally hardcoded in English and should NOT be flagged as missing i18n/localization. This is a deliberate design decision to keep the product name and these action labels in English to match the toolbar button style throughout the app.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
🧠 Learnings used
Learnt from: CR
Repo: breaking-brake/cc-wf-studio PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-04T07:37:53.326Z
Learning: Applies to src/webview/src/components/**/*Dialog*.{ts,tsx} : Always use Radix UI Dialog (`radix-ui/react-dialog`) for new dialog components
Learnt from: breaking-brake
Repo: breaking-brake/cc-wf-studio PR: 695
File: src/webview/src/components/toolbar/MoreActionsDropdown.tsx:236-258
Timestamp: 2026-03-31T09:22:16.456Z
Learning: In the `breaking-brake/cc-wf-studio` repository, "Commentary AI" is intentionally kept as a hardcoded English string (not localized) across all locales, both in `src/webview/src/components/toolbar/MoreActionsDropdown.tsx` and in the `CommentaryPanel.tsx` header. Do not flag this as a missing i18n/localization issue in future reviews.
Learnt from: breaking-brake
Repo: breaking-brake/cc-wf-studio PR: 719
File: src/webview/src/i18n/translations/ko.ts:1027-1027
Timestamp: 2026-04-09T03:24:24.646Z
Learning: In the `breaking-brake/cc-wf-studio` repository, the i18n runtime (`src/webview/src/i18n/i18n-context.tsx`, lines ~78-84) explicitly supports BOTH `{{paramKey}}` and `{paramKey}` placeholder formats via two separate `.replace()` passes. Do not flag `{{count}}` (double-brace) in translation strings as an incorrect placeholder format — both styles are valid and functionally equivalent.
Learnt from: breaking-brake
Repo: breaking-brake/cc-wf-studio PR: 719
File: src/webview/src/i18n/translations/zh-TW.ts:994-994
Timestamp: 2026-04-09T03:24:28.748Z
Learning: In the `breaking-brake/cc-wf-studio` repository, the i18n interpolation logic in `src/webview/src/i18n/i18n-context.tsx` explicitly supports BOTH `{{paramKey}}` and `{paramKey}` placeholder formats for backward compatibility. Do not flag `{{count}}` or other double-brace placeholders as incorrect in translation files — both formats are valid and will interpolate correctly.
Learnt from: breaking-brake
Repo: breaking-brake/cc-wf-studio PR: 699
File: src/webview/src/components/UndoRedoControls.tsx:55-89
Timestamp: 2026-04-02T12:27:24.241Z
Learning: For toolbar-related components under src/webview/src/components/ that intentionally implement a hover-only popover using the shared usePopoverHover hook (e.g., Popover.Root with open={isHovered}), do not raise code review findings about missing keyboard/focus support for that popover implementation while the unified accessibility fix is still pending. This exemption applies specifically when the hover-only pattern is clearly wired through usePopoverHover and the popover’s open state is controlled by hover (isHovered).
Learnt from: breaking-brake
Repo: breaking-brake/cc-wf-studio PR: 695
File: src/webview/src/components/toolbar/CommentaryOptionsDropdown.tsx:8-39
Timestamp: 2026-03-31T09:22:07.702Z
Learning: In this repo’s webview code (src/webview/src/**/*.tsx), it’s acceptable to reference React types such as `React.CSSProperties` without importing `React`. `types/react` provides the global `React` namespace, so `React.CSSProperties` should resolve correctly even with the `react-jsx` JSX transform. Do not flag missing `import React` for this specific type-usage pattern as an error during future code reviews.
Learnt from: breaking-brake
Repo: breaking-brake/cc-wf-studio PR: 699
File: src/webview/src/stores/workflow-store.ts:1301-1306
Timestamp: 2026-04-02T12:27:32.573Z
Learning: In `src/webview/src/stores/workflow-store.ts`, the project uses `reactflow@^11.10.0` (v11), NOT `xyflow/react` (v12). The `measured` field on the `Node` type does not exist in reactflow v11 — it was introduced in v12. Attempting to destructure `measured` from a Node in v11 causes a TypeScript compilation error. The partialize config correctly excludes only `selected`, `width`, and `height` for v11 compatibility.
Learnt from: CR
Repo: breaking-brake/cc-wf-studio PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-04T07:37:53.326Z
Learning: Applies to **/*.{ts,tsx} : Follow standard TypeScript 5.x and React 18.x conventions for VSCode Extension Host and Webview UI development
Learnt from: breaking-brake
Repo: breaking-brake/cc-wf-studio PR: 699
File: src/webview/src/App.tsx:252-254
Timestamp: 2026-04-02T12:31:50.534Z
Learning: In `src/webview/src/stores/workflow-store.ts`, `useWorkflowStore.temporal.getState().clear()` must be called after every full canvas context swap. The complete set of clear sites is: `clearWorkflow()`, `setActiveWorkflow()`, `addGeneratedWorkflow()`, all three `set(...)` paths inside `setActiveSubAgentFlowId()` (main→sub, sub→main, sub→sub), and `cancelSubAgentFlowEditing()`. The clear must happen AFTER the `set(...)` call so the new canvas state becomes the history baseline.
Learnt from: breaking-brake
Repo: breaking-brake/cc-wf-studio PR: 702
File: src/webview/src/stores/workflow-store.ts:1332-1360
Timestamp: 2026-04-02T14:49:29.374Z
Learning: In `src/webview/src/App.tsx`, `handleAcceptMcpApply` does NOT need a re-check of canvas revision at accept time. Two guards already prevent concurrent/stale-revision races: (1) `DiffPreviewDialog` is a modal overlay that blocks all canvas interaction while open, and (2) `pendingMcpApplyRef.current` causes any new incoming MCP apply request to be auto-rejected while a review dialog is showing. No additional optimistic-concurrency guard is required in `handleAcceptMcpApply`.
| 'tour.toolbarActions': | ||
| '从工具栏保存、加载、转换和运行工作流。\n\n"Run"按钮可直接在Claude Code中执行工作流。', | ||
| 'tour.refineWithAI': |
There was a problem hiding this comment.
Use localized action name in tour copy instead of “Run”.
In this locale, the toolbar action label is translated ('toolbar.run': '执行'), so hardcoding “Run” can confuse users.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/webview/src/i18n/translations/zh-CN.ts` around lines 352 - 354, The tour
copy under the translation key 'tour.toolbarActions' hardcodes the English
action name "Run" instead of using the localized label; update that string to
use the localized toolbar action name (reference the translation key
'toolbar.run') or reword to avoid hardcoded English so the Chinese locale
displays the translated action ('执行') consistently with the toolbar. Ensure you
edit the 'tour.toolbarActions' value in the zh-CN translations to reference or
match 'toolbar.run' rather than the literal "Run".
There was a problem hiding this comment.
Intentional. "Run" is used as the English function name across all locales — the toolbar button labels are English by design in this project.
There was a problem hiding this comment.
@breaking-brake, understood — thanks for the clarification! I'll remember that toolbar button labels (including "Run", "Save", "Load", "Convert", etc.) are intentionally kept in English across all locales as a deliberate design decision for this project.
✏️ Learnings added
Learnt from: breaking-brake
Repo: breaking-brake/cc-wf-studio PR: 723
File: src/webview/src/i18n/translations/zh-CN.ts:352-354
Timestamp: 2026-04-10T03:34:59.081Z
Learning: In the `breaking-brake/cc-wf-studio` repository, toolbar button labels such as "Run", "Save", "Load", "Convert", and similar action names are intentionally hardcoded in English across all locales (including zh-CN, zh-TW, ja, ko). This is a deliberate design decision — do not flag these as missing i18n/localization issues in future reviews, including when they appear embedded in translated tour/help copy strings (e.g., `tour.toolbarActions`).
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
🧠 Learnings used
Learnt from: breaking-brake
Repo: breaking-brake/cc-wf-studio PR: 695
File: src/webview/src/components/toolbar/MoreActionsDropdown.tsx:236-258
Timestamp: 2026-03-31T09:22:16.456Z
Learning: In the `breaking-brake/cc-wf-studio` repository, "Commentary AI" is intentionally kept as a hardcoded English string (not localized) across all locales, both in `src/webview/src/components/toolbar/MoreActionsDropdown.tsx` and in the `CommentaryPanel.tsx` header. Do not flag this as a missing i18n/localization issue in future reviews.
Learnt from: breaking-brake
Repo: breaking-brake/cc-wf-studio PR: 719
File: src/webview/src/i18n/translations/ko.ts:1027-1027
Timestamp: 2026-04-09T03:24:24.646Z
Learning: For this repo’s i18n translation strings under `src/webview/src/i18n/translations/`, do not flag `{{paramKey}}` (double-brace) as an incorrect placeholder format. The i18n runtime supports both `{{paramKey}}` and `{paramKey}` placeholders (via two replacement passes), and they are functionally equivalent—so both styles should be treated as valid placeholder syntax.
Learnt from: breaking-brake
Repo: breaking-brake/cc-wf-studio PR: 723
File: src/webview/src/components/EmptyState.tsx:80-81
Timestamp: 2026-04-10T03:34:30.595Z
Learning: In `src/webview/src/components/EmptyState.tsx`, the user-visible strings "CC Workflow Studio" (Dialog.Title/product name) and the action labels "New", "Load", and "Sample Workflow" are intentionally hardcoded in English and should NOT be flagged as missing i18n/localization. This is a deliberate design decision to keep the product name and these action labels in English to match the toolbar button style throughout the app.
Learnt from: breaking-brake
Repo: breaking-brake/cc-wf-studio PR: 719
File: src/webview/src/i18n/translations/zh-TW.ts:994-994
Timestamp: 2026-04-09T03:24:28.748Z
Learning: In this repo’s webview i18n translations, don’t flag double-brace placeholders like `{{count}}` (or other `{{param}}` forms) as incorrect. The i18n interpolation layer supports both `{{paramKey}}` and `{paramKey}` placeholder formats for backward compatibility, and both should be treated as valid as long as the placeholder name matches the expected key.
… for panel wait - Remove node deselection in doMinimize to preserve Property Panel target on resume - Replace setTimeout(50ms) with requestAnimationFrame loop for .property-panel detection Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
♻️ Duplicate comments (1)
src/webview/src/constants/tour-steps.ts (1)
47-56:⚠️ Potential issue | 🟠 MajorBound the Property Panel wait loop.
If
.property-panelnever appears, thisrequestAnimationFramepoll never stops. After a minimize/close, it can keep running in the background and later callmoveNext()against stale tour state. Add a timeout and a cancellation condition tied to the popover/tour still being mounted.Suggested fix
onNextClick: () => { callbacks?.onSelectSampleNode?.(); + const deadline = performance.now() + 3000; + const waitForPropertyPanel = () => { + if (!document.querySelector('.driver-popover')) { + return; + } + if (document.querySelector('.property-panel')) { callbacks?.moveNext?.(); return; } + + if (performance.now() >= deadline) { + return; + } + requestAnimationFrame(waitForPropertyPanel); }; + waitForPropertyPanel(); },🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/webview/src/constants/tour-steps.ts` around lines 47 - 56, The wait loop in onNextClick (the inner waitForPropertyPanel function using requestAnimationFrame to poll for '.property-panel' and then calling callbacks?.moveNext) can run indefinitely; modify waitForPropertyPanel to include a bounded timeout (e.g., max elapsed ms or max frames) and a cancellation check tied to the tour/popover mounted state (e.g., a local "isMounted" flag or callback like callbacks?.isMounted) before scheduling the next requestAnimationFrame and before invoking callbacks?.moveNext; ensure any scheduled RAF is not continued after unmount by checking the cancellation condition and stop polling when timeout is exceeded to avoid calling moveNext on stale state.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@src/webview/src/constants/tour-steps.ts`:
- Around line 47-56: The wait loop in onNextClick (the inner
waitForPropertyPanel function using requestAnimationFrame to poll for
'.property-panel' and then calling callbacks?.moveNext) can run indefinitely;
modify waitForPropertyPanel to include a bounded timeout (e.g., max elapsed ms
or max frames) and a cancellation check tied to the tour/popover mounted state
(e.g., a local "isMounted" flag or callback like callbacks?.isMounted) before
scheduling the next requestAnimationFrame and before invoking
callbacks?.moveNext; ensure any scheduled RAF is not continued after unmount by
checking the cancellation condition and stop polling when timeout is exceeded to
avoid calling moveNext on stale state.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 0700c2e6-bb41-4fd1-be29-15b13a68401e
📒 Files selected for processing (2)
src/webview/src/components/Tour.tsxsrc/webview/src/constants/tour-steps.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- src/webview/src/components/Tour.tsx
- Remove sample workflow references from tour text (all 5 languages) - Add timeout to property panel step detection with skip fallback - Tour now works on empty canvas and user-created workflows Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
## [3.33.0](v3.32.2...v3.33.0) (2026-04-12) ### Features * add sample workflow feature with tour integration ([#719](#719)) ([aaf2ab1](aaf2ab1)) * enhance StartMenu with version display and recent workflows ([#731](#731)) ([0b4138a](0b4138a)) * redesign onboarding tour and add empty state ([#723](#723)) ([8f72a24](8f72a24)) ### Bug Fixes * update broken Frontmatter Reference links in all languages ([#725](#725)) ([642b9ab](642b9ab)) ### Improvements * allow edge selection inside group nodes and animate on select ([#724](#724)) ([a813d49](a813d49)) * refine github-issue-planning sample workflow ([#733](#733)) ([7c1473b](7c1473b)), closes [#732](#732) * use fixed MCP server port with user-configurable setting ([#722](#722)) ([d436d2e](d436d2e)) ### Documentation * update README hero section with catchphrase and deck link ([#721](#721)) ([ba6aa52](ba6aa52))
|
🎉 This PR is included in version 3.33.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
Summary
Redesign the onboarding tour from 22 steps to 7 focused steps using the sample workflow as teaching context, and add an empty state dialog when no workflow is loaded.
Motivation
Changes
New Files:
src/webview/src/components/EmptyState.tsx- Empty state dialog with New / Load / Sample Workflow actions using Radix UI DialogModified Files:
src/webview/src/constants/tour-steps.ts- Reduced from 22 to 7 steps;allowClose: falsefor custom controlsrc/webview/src/components/Tour.tsx- Added minimize/resume (destroy + drive(index)), custom close/minimize buttons via DOM injection, click-outside-to-minimizesrc/webview/src/components/WorkflowEditor.tsx- Integrated EmptyState overlay on canvassrc/webview/src/App.tsx- Empty canvas detection logic, callbacks for empty state actionssrc/webview/src/components/Toolbar.tsx- Addeddata-tour="toolbar-actions"attributesrc/webview/src/styles/main.css- Minimap shift when tour floating button is visiblesrc/webview/src/i18n/translation-keys.ts- Updated tour keys (removed 16, added 4)src/webview/src/i18n/translations/{en,ja,ko,zh-CN,zh-TW}.ts- Updated tour translations for all 5 languagesTour Steps (New)
Testing
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
New Features — Onboarding
Localization
Style