Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

feat: redesign onboarding tour and add empty state#723

Merged
breaking-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
Apr 10, 2026
Merged

feat: redesign onboarding tour and add empty state#723
breaking-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

@breaking-brake
Copy link
Copy Markdown
Owner

@breaking-brake breaking-brake commented Apr 9, 2026

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

  • The existing 22-step tour was too verbose, pointing at each UI element one by one ("見ればわかる" - self-explanatory)
  • The sample workflow was loaded without explanation on first launch, and subsequent launches showed an empty canvas with no guidance
  • Users needed a way to interact with the UI during the tour without the popover blocking them

Changes

New Files:

  • src/webview/src/components/EmptyState.tsx - Empty state dialog with New / Load / Sample Workflow actions using Radix UI Dialog

Modified Files:

  • src/webview/src/constants/tour-steps.ts - Reduced from 22 to 7 steps; allowClose: false for custom control
  • src/webview/src/components/Tour.tsx - Added minimize/resume (destroy + drive(index)), custom close/minimize buttons via DOM injection, click-outside-to-minimize
  • src/webview/src/components/WorkflowEditor.tsx - Integrated EmptyState overlay on canvas
  • src/webview/src/App.tsx - Empty canvas detection logic, callbacks for empty state actions
  • src/webview/src/components/Toolbar.tsx - Added data-tour="toolbar-actions" attribute
  • src/webview/src/styles/main.css - Minimap shift when tour floating button is visible
  • src/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 languages

Tour Steps (New)

# Highlight Content
1 Welcome with sample workflow
2 Canvas Drag nodes, connect via handles
3 Property Panel Click node to configure
4 Node Palette Add nodes (all types)
5 Toolbar Save / Load / Convert / Run
6 AI Refine Generate or improve with AI
7 Finish message

Testing

  • Manual E2E testing completed
  • Tour: 7 steps work correctly with sample workflow
  • Tour minimize: click (−) or outside popover → floating resume button
  • Tour resume: click resume button → same step restored
  • Tour close: click (×) → tour ends
  • Empty state: shows on empty canvas with 3 actions
  • Empty state: dismissed on "New", reappears after workflow reset

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added an empty-state dialog for new workflows (start from scratch, load, or open a sample) with persistence/dismiss behavior and a load action that opens the file picker.
    • Workflow editor now shows the empty-state overlay when appropriate.
  • New Features — Onboarding

    • Redesigned tour into a condensed 7-step flow with minimize/resume controls and click-outside-to-minimize behavior; resume button floats when minimized.
  • Localization

    • Simplified and consolidated tour copy across languages; added minimize/resume labels.
  • Style

    • Adjusted layout to avoid the tour resume button overlapping the minimap.

- 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>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 9, 2026

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

Adds 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

Cohort / File(s) Summary
Empty State UI
src/webview/src/App.tsx, src/webview/src/components/EmptyState.tsx, src/webview/src/components/WorkflowEditor.tsx
Added EmptyState component and emptyStateDismissed state; compute showEmptyState from canvas/workflow state and tour status; provide handlers for New (dismiss), Load (posts OPEN_FILE_PICKER), and Sample; pass props into WorkflowEditor.
Tour redesign & runtime controls
src/webview/src/components/Tour.tsx, src/webview/src/constants/tour-steps.ts
Replaced long, granular tour with a 7-step flow; changed indices/callbacks; added minimize/resume flow with persisted stepIndexRef, click-outside-to-minimize, injected popover controls, and updated Driver.js lifecycle/config.
i18n: tour translations & keys
src/webview/src/i18n/translation-keys.ts, src/webview/src/i18n/translations/en.ts, src/webview/src/i18n/translations/ja.ts, src/webview/src/i18n/translations/ko.ts, src/webview/src/i18n/translations/zh-CN.ts, src/webview/src/i18n/translations/zh-TW.ts
Removed many granular tour.* keys/strings and added consolidated tour keys (tour.canvas, tour.propertyPanel, tour.toolbarActions, tour.finish) plus tour.button.minimize / tour.button.resume; updated translations across locales.
Styling & Toolbar minor change
src/webview/src/components/Toolbar.tsx, src/webview/src/styles/main.css
Added data-tour="toolbar-actions" attribute; added CSS rule to shift React Flow minimap up when body.tour-floating-visible is set.

Sequence Diagrams

sequenceDiagram
    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
Loading
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
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly Related PRs

Suggested Labels

released

Poem

🐰 I hopped in to tidy the empty scene,
A friendly dialog where the canvas is clean.
The tour can nap and later resume,
Load, sample, or start — growth will bloom.
Carrots and confetti for onboarding's tune!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and concisely describes the two primary changes: redesigning the onboarding tour and adding an empty state component for improved onboarding UX.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/redesign-onboarding-tour-and-empty-state

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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/onMouseLeave style mutation is harder to maintain; a shared CSS class with :hover/:focus-visible will 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

📥 Commits

Reviewing files that changed from the base of the PR and between d436d2e and f6a6abf.

📒 Files selected for processing (13)
  • src/webview/src/App.tsx
  • src/webview/src/components/EmptyState.tsx
  • src/webview/src/components/Toolbar.tsx
  • src/webview/src/components/Tour.tsx
  • src/webview/src/components/WorkflowEditor.tsx
  • src/webview/src/constants/tour-steps.ts
  • src/webview/src/i18n/translation-keys.ts
  • src/webview/src/i18n/translations/en.ts
  • src/webview/src/i18n/translations/ja.ts
  • src/webview/src/i18n/translations/ko.ts
  • src/webview/src/i18n/translations/zh-CN.ts
  • src/webview/src/i18n/translations/zh-TW.ts
  • src/webview/src/styles/main.css

Comment on lines +80 to +81
CC Workflow Studio
</Dialog.Title>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

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.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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`.

Comment thread src/webview/src/components/Tour.tsx
Comment thread src/webview/src/constants/tour-steps.ts Outdated
Comment on lines +352 to 354
'tour.toolbarActions':
'从工具栏保存、加载、转换和运行工作流。\n\n"Run"按钮可直接在Claude Code中执行工作流。',
'tour.refineWithAI':
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

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".

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intentional. "Run" is used as the English function name across all locales — the toolbar button labels are English by design in this project.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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.

Comment thread src/webview/src/i18n/translations/zh-TW.ts
… 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>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
src/webview/src/constants/tour-steps.ts (1)

47-56: ⚠️ Potential issue | 🟠 Major

Bound the Property Panel wait loop.

If .property-panel never appears, this requestAnimationFrame poll never stops. After a minimize/close, it can keep running in the background and later call moveNext() 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

📥 Commits

Reviewing files that changed from the base of the PR and between f6a6abf and 79b390d.

📒 Files selected for processing (2)
  • src/webview/src/components/Tour.tsx
  • src/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>
@breaking-brake breaking-brake merged commit 8f72a24 into main Apr 10, 2026
3 of 4 checks passed
@breaking-brake breaking-brake deleted the feat/redesign-onboarding-tour-and-empty-state branch April 10, 2026 03:47
braking-brake-semantic-release Bot pushed a commit that referenced this pull request Apr 12, 2026
## [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))
@braking-brake-semantic-release
Copy link
Copy Markdown

🎉 This PR is included in version 3.33.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Morty Proxy This is a proxified and sanitized view of the page, visit original site.