Add first-run onboarding flow for new installs - #453
Conversation
Guides new users through the popup menu, AI prompt command, and link preview right after install via a dedicated onboarding tab, with a final Customize/Complete screen that persists hasShownOnboarding so it only runs once. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019NHfjgYsFbd7tPbEdQSg4p
…d Hub link Add a slow-blink hint on Step1 while waiting for the user to return from the search command's tab, short pattern captions on Steps 1-3 to reinforce the select-command-result mental model, and a Command Hub link on Step4. Also route onboarding tab close through the background script (closeTab) so the settings write completes before the tab closes. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017QRxn2pRzMCWvf9nK2w7Kq
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #453 +/- ##
==========================================
- Coverage 46.57% 44.38% -2.20%
==========================================
Files 239 267 +28
Lines 25710 27488 +1778
Branches 2053 2145 +92
==========================================
+ Hits 11975 12200 +225
- Misses 13735 15288 +1553 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
コードレビュー新規インストール時のオンボーディングフロー追加、お疲れ様です。全体的にステップの状態管理( 以下、気になった点を挙げます。 1.
|
…orcement Replace the per-step spotlight overlay with a constant vignette, add a persistent select-command-result progress rail, demonstrate the drag-to- select gesture at runtime (locale-proof via Range.getClientRects), and distinguish actionable buttons from decorative state with fill/tint. Move CSS off Onboarding.module.css onto Tailwind, and add a canvas-confetti celebration on the completion screen. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WaFfYLgE9pcwo3wSwEeG8D
コードレビュー: #453 初回インストール向けオンボーディングフロー追加大規模な機能追加(新規ファイル約30個、全14ロケールの 1.
|
Moves the context definition out of Popup.tsx and into a dedicated hooks/usePopupContext.tsx, matching the pattern used by the other context providers, and switches consumers to the usePopupContext() hook instead of importing the raw context from Popup.tsx. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Shorten onboarding intro copy, add a return-hint callout, translate the changes into every supported locale, give the callout bubble a gentle float animation, replace hardcoded #082f49 with the equivalent sky-950 token, and suppress the regular Tooltip while onboarding is active or the popup is mid-transition. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…payoff Steps 1-3 each switched their whole render tree to a separate <OnboardingValueShown> once the payoff phase was reached, mounting a second, independent OnboardingRail and restarting its beat animation instead of carrying it through from the first "select" beat. Unify each step's JSX into a single return so the rail (and its wrapping fade-in) stays mounted at the same position across every phase, with only its activeBeat prop changing - OnboardingValueShown is now dead code and removed. Also folds in a few small, related touch-ups already in progress on this branch: an IPC broadcast fix so onboarding tabs receive sendAllTab commands, a return-hint copy tweak, and minor button/timing adjustments. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Propagates four ja/messages.json wording changes (step1 return-hint clarifying the popup window auto-closes, step2 target/callout text, and a trimmed step3 explain string) to the other 13 locales. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Simplify onboarding step phase checks into named booleans, position the onboarding menu item toward the screen edge during onboarding, skip analytics for commands run from extension pages, add a completion emoji to the search step's value message, and drop the trailing punctuation from the search step's value message across all locales. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… copy Give the AiPrompt (Step2) and Link Preview (Step3) steps their own WAIT_RETURN phase - Step2 shows a brief in-flight message before the value message, and Step3 detects the user switching back from the preview popup/tab via visibilitychange/focus, matching Step1's pattern. Step3's Shift+click hint now renders as an OnboardingCallout targeting the sample link itself, like every other "do this next" hint, instead of a static keycap graphic. Also drops the trailing punctuation from the step2/step3 value messages and adds the new step2WaitReturn/step3ReturnHint/step3Callout copy to all 14 locales, removing the now-unused clickKeycap key. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…fetti timing Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Group each step's OnboardingFadeIn/OnboardingCallout delays into a delays object keyed directly by StepPhase, and thread OnboardingTargetText's callout delay through the same structure instead of hardcoding it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…cking per step Rename ONBOARDING_FIRST_SELECTION/FIRST_VALUE to ONBOARDING_TEXT_SELECTION/ VALUE_REACHED, and fire VALUE_REACHED automatically per-step whenever that step's phase reaches VALUE_SHOWN (with a step param) instead of only from StepSearchCommand. Also guard complete() before sending ONBOARDING_COMPLETE, since StrictMode's dev-only double effect invocation was sending it twice. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
…guages Change step3 value sub-message to emphasize returning quickly after finding info, render completeBody as multiline, and update the step3 link-preview sample link. Localize both message changes across all supported languages. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Avoid sending the link_preview analytics event when running inside the extension's own onboarding page, since that traffic doesn't represent real user link-preview usage. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Fixes several correctness issues found while reviewing the onboarding flow branch: unfiltered command-executed events on the search step, an unchecked close-tab response leaving the onboarding tab open, an uncleared setPhase timer that could fire after teardown, and an analytics-suppression guard that blocked events on any extension page instead of just onboarding. Also normalizes the GA4 step param to a stable string label, renames completion_time to completion_time_sec, dedupes the per-step PhaseDelays type, and fixes two stale comments. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…me title
Moves the per-locale title/prompt text for the onboarding AiPrompt
command out of defaultSettings.ts and into onboardingCommand.ts, so
the localized content lives alongside the command factory it belongs
to. Also extracts INSERT/InsertSymbol/toInsertTemplate into their own
insertSymbols.ts module so onboardingCommand.ts can reuse the
{{SelectedText}} placeholder symbol without pulling in pageAction's
listener/ipc side effects, and renames the command title across all
locales to reflect that it executes a prompt rather than just "asks".
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Production builds hardcoded two CSS filenames when injecting styles into the content script's Shadow DOM, missing chunks shared with other entry points (e.g. LinkSelector) that crxjs splits out with content-hashed names. Inject the real, build-computed file list into the bundle via a placeholder token instead, so styles no longer break after `yarn build`. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
manualChunks/assetFileNames only existed to give content_script's CSS assets fixed, predictable names so content_script.tsx could hardcode fetch paths to them. That lookup is now dynamic, so let Rollup use its default per-entry chunking and hashed asset names. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
There was a problem hiding this comment.
🟡 Changes recommended
オンボーディング体験の安定性に直結するタブ対象URLの扱いとPopup位置決めに不具合/不整合があるため。
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
新規インストール時にオンボーディング用タブ(Step 0〜5)を自動表示し、ユーザーに「選択 → コマンド → 結果」の基本体験を短時間で提供するための実装を追加するPRです。拡張機能(packages/extension)側にオンボーディングUI・状態管理・計測・タブクローズ経路を統合し、各ロケール文字列とビルド周り(content_script CSS注入)も合わせて更新しています。
Changes:
- 初回インストール時にオンボーディングタブを開く導線と、完了/スキップ時の永続化(hasShownOnboarding)・計測イベントを追加
- オンボーディングUI(Layout/Rail/Callout/各Step/Confetti)と、選択デモ(Range.getClientRects ベース)を実装
- content_script の CSS 注入方式を「ビルド後に実CSSファイル一覧をバンドルへ注入」する方式へ変更し、ハッシュ変動に強く
概要
- 目的(Issue #452):初回ユーザーのTTV短縮を狙ったインタラクティブ・オンボーディングを提供
- 実装は extension 内に閉じており、初回インストール判定は
chrome.runtime.onInstalledの INSTALL reason を利用
懸念点
- オンボーディング中のPopup位置決めが
window.screen.width依存のため、ウィンドウサイズ/複数モニタ環境で画面外配置になり得ます。 Ipc.sendAllTabの tabs.query url がオンボーディングURL(クエリ付き)にマッチしないケースがあり得ます(e2e/開発の step override 等)。- デザインレビュー用 e2e ツールで headless 指定が矛盾しており、環境によって挙動が不明確です。
改善提案 (type "custom")
- Popup のオンボーディング時位置は
window.innerWidthベースにし、0以上へクランプして安全に配置する。 sendAllTabのオンボーディングURLはワイルドカードを付け、?step=&phase=等の派生URLも対象にする。onboarding-shots.spec.tsの headless 指定は「headless: false で統一」or「headless: true で統一」のどちらかに寄せる。
File summaries
| File | Description |
|---|---|
| yarn.lock | canvas-confetti 関連の依存解決を反映 |
| packages/extension/package.json | canvas-confetti と型定義を追加 |
| packages/extension/vite.config.ts | onboarding entry 追加・content_script CSSファイル注入用 define を追加・ビルド出力設定更新 |
| packages/extension/tailwind.config.js | オンボーディング専用キーフレーム/アニメーションを追加 |
| packages/extension/src/types/vite-env.d.ts | __CONTENT_SCRIPT_CSS_FILES__ の型定義を追加 |
| packages/extension/src/types/onboarding.ts | OnboardingStep/StepPhase を追加 |
| packages/extension/src/types/index.ts | UserStats に hasShownOnboarding を追加 |
| packages/extension/src/services/storage/index.ts | デフォルトUserStatsに hasShownOnboarding を追加 |
| packages/extension/src/services/settings/settings.ts | 設定保存・移行対象に hasShownOnboarding を追加 |
| packages/extension/src/services/settings/settings.test.ts | hasShownOnboarding のテスト更新 |
| packages/extension/src/services/settings/enhancedSettings.ts | 初期値・マージ対象に hasShownOnboarding を追加 |
| packages/extension/src/services/pageAction/insertSymbols.ts | INSERT/テンプレート記号を副作用分離した新モジュールへ移動 |
| packages/extension/src/services/pageAction/index.ts | insertSymbols を再export する形へ変更 |
| packages/extension/src/services/pageAction/elementWait.ts | 条件評価時の debug ログ追加 |
| packages/extension/src/services/pageAction/dispatcher.ts | click 実行時の debug ログ追加 |
| packages/extension/src/services/option/defaultSettings.ts | オンボーディング用 AiPrompt コマンドを全ロケールへ追加・空設定に hasShownOnboarding を追加 |
| packages/extension/src/services/option/defaultSettings.test.ts | 全ロケールにオンボーディングAiPromptコマンドが含まれることを検証 |
| packages/extension/src/services/ipc.ts | sendAllTab の対象にオンボーディングURLを追加 |
| packages/extension/src/services/analytics.ts | onboarding 計測イベント名を追加 |
| packages/extension/src/services/analytics.test.ts | onboarding 計測イベント名のテスト追加 |
| packages/extension/src/providers/SelectContextProvider.tsx | 選択検出の有効/無効を制御できるようにし、Context に setSelectionText を公開 |
| packages/extension/src/hooks/useSelectContext.tsx | Context 型に setSelectionText / setDetectSelectionEnabled を追加 |
| packages/extension/src/hooks/usePrefersReducedMotion.ts | OSのreduce motionを取得するフックを追加 |
| packages/extension/src/hooks/usePopupContext.tsx | Popup 状態の Context を hooks 側へ分離 |
| packages/extension/src/hooks/useDetectLinkCommand.ts | オンボーディング用 command executed イベント通知・オンボーディング時は一部分析を抑制 |
| packages/extension/src/hooks/pageAction/usePageActionRunner.ts | 受信/登録の debug ログ追加 |
| packages/extension/src/hooks/useSettings.test.tsx | hasShownOnboarding のテスト更新 |
| packages/extension/src/components/Tooltip.tsx | PopupContext の取得経路変更・オンボーディング/遷移中は非表示 |
| packages/extension/src/components/Popup.tsx | PopupContext を hooks 側へ移動・ホバー中は選択検出を停止・オンボーディングフラグを提供 |
| packages/extension/src/components/menu/MenuItem.tsx | data-command-id 追加・オンボーディング時のpopup位置調整・Tooltip制御変更 |
| packages/extension/src/components/menu/MenuFolder.tsx | PopupContext の取得経路変更 |
| packages/extension/src/components/option/Option.tsx | プレビューPopupを SelectContextProvider でラップ |
| packages/extension/src/components/option/ImportExport.tsx | import/export マイグレーションに hasShownOnboarding を反映 |
| packages/extension/src/components/App.tsx | SelectContextProvider の props を簡素化し Popup 連携を更新 |
| packages/extension/src/content_script.tsx | content_script のCSS注入を __CONTENT_SCRIPT_CSS_FILES__ ベースに変更 |
| packages/extension/src/lib/contentScriptCss.ts | CSSファイル一覧注入のためのプレースホルダ定義を追加 |
| packages/extension/src/lib/vite-plugin-manifest.ts | ビルド後に content_script CSSファイル一覧をJSへ注入する処理を追加 |
| packages/extension/src/const.ts | ONBOARDING の screen と ONBOARDING_PAGE_PATH を追加 |
| packages/extension/src/onboarding_page.html | onboarding 用のHTML entry を追加 |
| packages/extension/src/onboarding_page.tsx | onboarding の React entry を追加(Sentry/locale設定含む) |
| packages/extension/src/components/onboarding/OnboardingPage.tsx | オンボーディングページのルート(Layout + Step切替 + Popup/LinkSelector)を追加 |
| packages/extension/src/components/onboarding/useOnboardingState.ts | step/phase管理、完了フラグ永続化、イベント送信を追加(e2e/dev override対応) |
| packages/extension/src/components/onboarding/onboardingAnalytics.ts | onboardingイベント送信のラッパーを追加(step正規化) |
| packages/extension/src/components/onboarding/onboardingAnalytics.test.ts | onboardingAnalytics のテスト追加 |
| packages/extension/src/components/onboarding/onboardingEvents.ts | command executed の window event と onboarding 判定を追加 |
| packages/extension/src/components/onboarding/onboardingProgress.ts | ヘッダ進捗(4ステップ)計算を追加 |
| packages/extension/src/components/onboarding/onboardingProgress.test.ts | onboardingProgress のテスト追加 |
| packages/extension/src/components/onboarding/OnboardingLayout.tsx | 共通レイアウト(ヘッダ進捗/スキップ/ビネット)を追加 |
| packages/extension/src/components/onboarding/OnboardingRail.tsx | 「select→command→result」のレールUIを追加 |
| packages/extension/src/components/onboarding/OnboardingCallout.tsx | 任意要素に紐づく吹き出しCalloutを追加 |
| packages/extension/src/components/onboarding/OnboardingFadeIn.tsx | フェードイン演出用ラッパーを追加 |
| packages/extension/src/components/onboarding/OnboardingConfetti.tsx | 完了時のconfetti演出(reduced motion対応・CSP対応)を追加 |
| packages/extension/src/components/onboarding/OnboardingTargetText.tsx | ターゲットテキストカード+選択デモ統合を追加 |
| packages/extension/src/components/onboarding/useSelectionDemo.ts | Range.getClientRects を使ったドラッグ選択デモ(WAAPI)を追加 |
| packages/extension/src/components/onboarding/useSelectionDemo.test.ts | buildKeyframes/useSelectionDemo のテスト追加 |
| packages/extension/src/components/onboarding/textUtils.tsx | i18n文字列の \\n を <br> に変換するユーティリティを追加 |
| packages/extension/src/components/onboarding/phaseDelays.ts | フェーズ別遅延の共通型を追加 |
| packages/extension/src/components/onboarding/onboardingWindow.ts | BgCommand.closeTab 経由でオンボーディングタブを閉じる関数を追加 |
| packages/extension/src/components/onboarding/onboardingCommand.ts | Step2 用の固定ID AiPrompt コマンド生成を追加(全ロケール対応) |
| packages/extension/src/components/onboarding/steps/StepIntro.tsx | Step0 追加 |
| packages/extension/src/components/onboarding/steps/StepSearchCommand.tsx | Step1 追加(Search体験) |
| packages/extension/src/components/onboarding/steps/StepAiPromptCommand.tsx | Step2 追加(AiPrompt体験) |
| packages/extension/src/components/onboarding/steps/StepLinkPreview.tsx | Step3 追加(Link Preview体験) |
| packages/extension/src/components/onboarding/steps/StepCustomize.tsx | Step4 追加(カスタマイズ導線) |
| packages/extension/src/components/onboarding/steps/StepComplete.tsx | Step5 追加(完了・confetti・クローズ) |
| packages/extension/src/background_script.ts | INSTALL時にオンボーディングタブを開く& closeTab コマンド追加 |
| packages/extension/src/background_script.test.ts | onInstalled のオンボーディング起動有無テスト追加 |
| packages/extension/src/action/executor.ts | onboarding ページ上では分析イベントを抑制し、command executed イベントをdispatch |
| packages/extension/src/action/executor.test.ts | onboardingページ時の分析抑制・イベントdispatch のテスト追加 |
| packages/extension/e2e/onboarding-shots.spec.ts | デザインレビュー用のスクリーンショット撮影ツールを追加(CAPTURE=1時のみ) |
| packages/extension/public/_locales/en/messages.json | オンボーディング文言を追加 |
| packages/extension/public/_locales/ja/messages.json | オンボーディング文言を追加 |
| packages/extension/public/_locales/de/messages.json | オンボーディング文言を追加 |
| packages/extension/public/_locales/es/messages.json | オンボーディング文言を追加 |
| packages/extension/public/_locales/fr/messages.json | オンボーディング文言を追加 |
| packages/extension/public/_locales/hi/messages.json | オンボーディング文言を追加 |
| packages/extension/public/_locales/id/messages.json | オンボーディング文言を追加 |
| packages/extension/public/_locales/it/messages.json | オンボーディング文言を追加 |
| packages/extension/public/_locales/ko/messages.json | オンボーディング文言を追加 |
| packages/extension/public/_locales/ms/messages.json | オンボーディング文言を追加 |
| packages/extension/public/_locales/pt_BR/messages.json | オンボーディング文言を追加 |
| packages/extension/public/_locales/pt_PT/messages.json | オンボーディング文言を追加 |
| packages/extension/public/_locales/ru/messages.json | オンボーディング文言を追加 |
| packages/extension/public/_locales/zh_CN/messages.json | オンボーディング文言を追加 |
| docs/design/storybook-investigation.md | Storybook導入調査メモを追加 |
Review details
- Files reviewed: 83/88 changed files
- Comments generated: 3
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
@copilot Fix the code for all comments in this review thread. When a review comment includes a suggested change, apply the suggestion exactly. Do not make changes beyond what is described in the linked review thread. |
Co-authored-by: ujiro99 <677231+ujiro99@users.noreply.github.com>
レビューコメントの3点を修正しました。Popup位置計算を |
Instead of passing iconUrl in from the caller, derive it internally from aiPromptOption.serviceId via ai-services.json, keeping the icon and the AI service it represents in sync. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Summary
BgCommand.closeTab) sohasShownOnboardingis persisted before the tab closesmessages.jsonfiles updated with the onboarding stringsRedesign pass
OnboardingLayout(brand header, 4-segment progress + counter, fixed-position Skip) replaces per-step chrome and the old per-step spotlight overlay with a constant vignette so nothing shifts between screensOnboardingRailreinforces the mental model across Steps 1-3 and the value-shown payoff screensuseSelectionDemo, measured viaRange.getClientRects()so it's correct across all 14 locales' line-wrapping, not hardcoded pixel keyframes)canvas-confetticelebration and closes to "try it now" as the primary actionOnboarding.module.cssonto Tailwind (tailwind.config.jskeyframes + utility classes)e2e/onboarding-shots.spec.ts,CAPTURE=1 yarn test:e2e onboarding-shots) using a?step=&phase=dev-only override inuseOnboardingStateto capture every step/phase across locales for design reviewCloses #452
Test plan
tsc --noEmitpassesyarn lintpasses (0 errors)yarn test:runpasses (1057 tests, including newonboardingProgress/useSelectionDemocoverage)yarn build/yarn build:e2epass🤖 Generated with Claude Code
https://claude.ai/code/session_01WaFfYLgE9pcwo3wSwEeG8D