Skip to content

Dev 1.3.0 - #460

Merged
ujiro99 merged 77 commits into
mainfrom
dev-1.3.0
Sep 23, 2026
Merged

ujiro99 merged 77 commits into
mainfrom
dev-1.3.0

Conversation

@ujiro99

@ujiro99 ujiro99 commented Sep 17, 2026

Copy link
Copy Markdown
Owner

No description provided.

ujiro99 and others added 30 commits September 13, 2026 14:31
Adds the experiment plumbing for the onboarding A/B test (#455):

- packages/hub/public/data/experiments.json serves the allocation ratio,
  so the split can be changed - or the test stopped - by deploying the
  hub, with no Chrome Web Store release.
- services/experiments assigns a variant once per install and persists it
  in chrome.storage.local. On a fetch failure it still assigns, using the
  build-time allocation, and records config_source so a hub outage can be
  separated out during analysis.
- The assignment runs in onInstalled right before the onboarding tab is
  created, so the page renders its first frame from storage.
- Every onboarding_* event now carries a `variant` param.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VeTTSrCxM9ifQatx6XjCxo
The B arm of the onboarding A/B test (#455), aimed at the 60% drop-off on
the intro screen:

- Drops the INTRO step and opens directly on the search command step.
- Shows the logo and a welcome message first, in a new WELCOME phase.
  It advances after 2s, or immediately on click - there is nothing to
  read there, so the timer should not be a second thing to sit through.
- Enter and exit use a blur + fade transition (Linear-style), added as
  an `effect` option on OnboardingFadeIn so variant A keeps its current
  rise animation untouched.
- `?variant=A|B` lands on either arm in dev/e2e builds, and the
  screenshot spec captures the welcome overlay.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VeTTSrCxM9ifQatx6XjCxo
- Hold onDone in a ref so the 2s auto-advance timer survives parent
  re-renders. Callers pass an inline callback, so depending on it
  directly restarted the pending timer on every render of the flow.
- Withhold the progress indicator and the Skip button during the
  WELCOME phase: the overlay only hid the button visually, leaving it
  reachable by keyboard.
- Correct the concurrency comment in ensureOnboardingAssignment -
  Storage.update is a plain get/set, so the re-read is best-effort, not
  atomic.
- Note that the build-time fallback allocation deliberately duplicates
  the hub's experiments.json, and has to be updated alongside it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VeTTSrCxM9ifQatx6XjCxo
… icon library check

- Replace custom registrable domain parsing with tldts
- Keep isIconLibrary generic and keep service-specific asset checks explicit
- Determine favicon classification based on actual icon URL instead of command openMode
- Update favicon detection tests
…me setting

- Rename overrideGlobalIconColor to excludeFromGlobalIconColor across types, schemas, and locales
- Automatically preserve original colors for genuine favicons without persisting manual settings
- Enable recoloring for custom icons when manual exclusion is off
- Keep manual exclusion toggle functional for custom icons
…icon protection

- Add tests for MenuItem and MenuImage rendering paths with custom icons and genuine favicons
- Add tests for dynamic URL changes and state preservation in IconField
- Verify recoloring for AI Prompt command with custom Flaticon/Iconfinder PNGs
tldts only recognizes IPv6 literals in bracket notation, so `parse("::1")`
returned a null hostname and getRegistrableDomain fell through to "".
Wrap bare IPv6 input in brackets before parsing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SNWxGCYuTCZoiZbmgkovDc
- Extract the inline pattern lists into named constants so each heuristic is
  self-describing instead of a numbered comment block.
- Split isFaviconIcon into isFaviconUrl / isSameSiteIcon / getCommandTargetUrl,
  and rename the entry point to shouldPreserveIconColor: the check also covers
  brand assets and same-site icons, which are not favicons.
- Drop the `as any` casts. searchUrl is an optional property of every Command,
  and pageActionOption is reachable through the existing isPageActionCommand
  type guard.
- Remove redundant normalization in getRegistrableDomain: tldts already returns
  the eTLD+1, so stripping "www." on input and at the call site was a no-op.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SNWxGCYuTCZoiZbmgkovDc
The context lived in Menu.tsx while MenuItem.tsx imported it, which closed a
cycle: Menu -> MenuFolder -> MenuItem -> Menu. Move it to components/menu/
iconUrls.ts and expose a useCommandIconUrl hook so call sites no longer reach
into the raw map.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SNWxGCYuTCZoiZbmgkovDc
MenuFolder passed the cached icon URL to MenuImage without a detection result,
so the fallback inside MenuImage always ran against a `data:` URL and reported
"not a favicon". Folder favicons were recolored while command favicons were not.

Track the configured folder icon URLs the same way commands already do and run
the detection against them. While here, deduplicate the two identical image
cache blocks in useSettingsWithImageCache.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SNWxGCYuTCZoiZbmgkovDc
- Replace the nested ternary with an early-return per variant and move the
  masked span and the inline SVG into their own components.
- Extract the repeated aria-hidden / role="img" spread into helpers.
- Move the mask fill color from an inline style into .itemImgMasked.
- Stop adding css.itemImg inside the masked branch. Sizing comes from the
  caller's className, as it already does for the plain <img> branch; adding it
  here made the icon size unpredictable for callers that pass their own size
  (e.g. the IconField preview uses w-6 h-6).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SNWxGCYuTCZoiZbmgkovDc
Popup.tsx searched userStyles three times through `(s: any)` predicates and
built the `--sc-*` custom properties inline with hardcoded variable names.
Move both into services/option/userStyles.ts as findUserStyleValue,
hasUserStyle and toCssVariables. userStyles is already typed as
StyleVariable[], so the casts were never needed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SNWxGCYuTCZoiZbmgkovDc
- Move the ~40 line exclusion toggle into a GlobalIconColorToggle component.
- Move the two imports that sat in the middle of the file up to the top.
- Tie the default field name to CommandFolder instead of repeating the literal.
- Drop the redundant isEmpty guard (shouldPreserveIconColor already rejects an
  empty URL) and simplify `isAutoPreserved ? true : x` to `isAutoPreserved || x`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SNWxGCYuTCZoiZbmgkovDc
- Remove BaseCommand.originalIconUrl: nothing in the monorepo reads or writes it.
- Collapse the FolderEditDialog reset branch; spreading over DefaultValue
  already fills in a missing excludeFromGlobalIconColor.
- Drop the needless computed-key syntax on the "hover:bg-accent" class.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SNWxGCYuTCZoiZbmgkovDc
The 6 keys added for this feature (Option_userStyles_option_icon_color,
Option_userStyles_desc_icon_color, Option_excludeFromGlobalIconColor,
Option_excludeFromGlobalIconColor_desc,
Option_excludeFromGlobalIconColor_favicon_desc,
Option_excludeFromGlobalIconColor_automatic) were left as English text in all
12 non-English, non-Japanese locale files (de, fr, es, ko, zh_CN, ru, it, hi,
id, ms, pt_BR, pt_PT). Translate them, following each locale's existing
terminology for "icon" (Symbol/icône/icono/아이콘/图标/иконка/icona/आइकन/
Ikon/ícone) and "global" (globale/전역/全局/глобальный/वैश्विक/global) as used
elsewhere in that locale's messages.json.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SNWxGCYuTCZoiZbmgkovDc
…geCache

- Move useSettingsWithImageCache (and applyImageCache) out of useSettings.ts
  into its own file, along with its tests.
- Resolve the recoloring decision there, while the user-configured icon URL is
  still known, and expose it as ResolvedCommand/ResolvedFolder's
  preserveOriginalColor. It used to be computed on every MenuItem render; now
  it is computed once per settings change.
- Drop IconUrlsContext and its lookup hooks: only shouldPreserveIconColor
  needed the pre-cache URL, so the menu no longer has to reach for it.
- MenuItem/MenuFolder just pass the flag to MenuImage, which also removes the
  hook call nested in an argument in MenuFolder.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…r toggle

- Extract the info icon + Tooltip pair duplicated across SelectField,
  InputField and SwitchField into an InfoTooltip component.
- Anchor it with a state-backed ref: SelectField and InputField passed
  span.current, which is null on the first render and never triggered one, so
  their tooltips stayed inert until something else re-rendered the field.
- Move the global icon color toggle's description from a FormDescription into
  that tooltip, which collapses its label area to a single row.
- Follow the description in IconField's tests by hovering the info icon.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Render the icon preview with the global icon color by providing the
`--sc-icon-color` variable and `hasIconColor` around MenuImage, which is
drawn outside the popup. The preview follows the exclusion toggle live,
since its form value is passed straight to MenuImage.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The exclusion toggle and the icon preview called shouldPreserveIconColor
without a command, so the isSameSiteIcon branch that the menu applies via
useSettingsWithImageCache never ran in the editor. A command whose icon is
served by the site it targets showed an operable toggle and a recolored
preview, while the menu kept the icon's original colors regardless.

Give shouldPreserveIconColor a targetUrl option, resolve the decision once
in IconField, and hand it to both the toggle and the preview's MenuImage so
they always agree with the menu. getCommandTargetUrl moves to lib/utils so
naming a command's target does not require the Public Suffix List.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
react-hook-form keeps the value a field was first mounted with whenever
reset() omits that key, so editing a folder that stores only an iconSvg put
the new-folder default iconUrl into the form: the dialog showed the default
PNG instead of the SVG, and saving replaced the user's icon with it.
Merging the whole DefaultValue made the same overwrite explicit and also
forced onlyIcon to true on folders that never set it.

Reset an existing folder over a neutral value for every schema key instead,
and keep the new-folder defaults for creation only.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
lib/favicon.ts reaches the content script through MenuImage and
useSettingsWithImageCache, and the tldts Public Suffix List it carries for
the same-site check doubled the chunk injected into every page:
SelectContextProvider went from 126.23 kB (gzip 43.30 kB) to 237.80 kB
(gzip 86.65 kB).

Answer the check over IPC instead. BgCommand.resolveIconColors takes
{url, targetUrl} queries and returns the decisions in order, so only the
service worker and the options page import the list. The menu caches the
answers per query, and MenuImage no longer detects the origin itself -
every caller in a recoloring context already passes preserveOriginalColor.

The injected chunk is now 133.04 kB (gzip 44.82 kB), and tldts sits in a
separate chunk that only background_script and options_page import.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ujiro99 and others added 9 commits September 21, 2026 16:44
convReadableKeysToSymbols / convSymbolsToReadableKeys replaced built-in
symbols anywhere in the string, so a user variable whose name merely
contained one (Language, MyUrl) was mangled on display and silently
corrupted the saved template once edited.

Match whole placeholder names inside {{...}} instead, matching how
InputPopup inserts them and how safeInterpolate resolves them.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QtwK1EqDWkJW3ASeoqkQyq
Unresolved placeholders are left as literal {{Name}} at runtime, so
removing or renaming a referenced variable silently made steps type
"{{Prompt}}" into the target page.

Pass the page action step values into UserVariablesField, confirm a
removal that would orphan references, and warn in the edit dialog when
a referenced variable is renamed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QtwK1EqDWkJW3ASeoqkQyq
Left behind with no callers when validateUserVariables was removed; the
zod schema owns this rule now.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QtwK1EqDWkJW3ASeoqkQyq
feat(pageAction): prompt プロパティをテンプレート対応のユーザー変数へ統合
- Escape quotes/backslashes/newlines in the mask-image url() of MaskedImage
- Cap answerCache in useSettingsWithImageCache with oldest-first eviction
- Memoize shouldPreserveIconColor in IconField

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HoVyYp5KNh7bYH9uMAaqHR

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🔵 Needs a closer look

変更範囲が広く(ABテスト配信・ストレージ永続化・オンボーディングフロー・アイコンrecolor/同一サイト判定・PageAction実行経路など)リスク評価に追加の人手確認が必要です。

Review effort: Lite
Findings: 1 Medium severity · 1 Low severity

Open (2)
What changed in this PR

概要

本PRは、Selection Command 拡張機能の v1.3.0 として、(1) オンボーディングの A/B テスト配信基盤(hub 経由の experiments.json)を導入し、(2) グローバルなアイコン色(recolor)とその除外/自動保護(favicon 等)を追加し、(3) PageAction のユーザー変数・Side Panel 対応など周辺の UX/機能拡張を行う変更です。

変更点(要約)

  • Hub 配信の experiments.json と Extension 側の割当・永続化により、オンボーディング Variant A/B を実現
  • グローバルアイコン色(mask 描画)と、favicon/ブランドアイコン等の「元色保持」判定(tldts + SW 判定)を導入
  • PageAction: Side Panel openMode 対応、ユーザー変数のバリデーション/解決/挿入 UI を追加

懸念点

  • 装飾画像の alt/aria-hidden の扱い(アクセシビリティ)
  • filter: blur() を用いたアニメーション(パフォーマンス/ガイドライン観点で注意)

改善提案 (type "custom")

  • blur 演出が必須でない場合は、opacity/transform 中心のアニメーションへ寄せる(ペイントコスト低減)
  • 装飾画像は alt="" を徹底し、読み上げノイズを避ける
File Description
packages/​shared/​src/​types/​command.ts コマンド型に excludeFromGlobalIconColor を追加
packages/​shared/​src/​constants/​open-mode.ts PAGE_ACTION_OPEN_MODE に SIDE_PANEL を追加
packages/​hub/​src/​types/​pageAction.ts 型の整形(インデント調整)
packages/​hub/​public/​data/​experiments.json AB テスト配分のリモート設定を追加
packages/​hub/​AGENTS.md hub の責務に experiments 配信を追記
packages/​extension/​tailwind.config.js オンボーディング用 blur in/out アニメーション追加
packages/​extension/​src/​types/​schema.ts userVariables の強化(重複/予約語/長さ)・excludeFromGlobalIconColor をスキーマへ追加
packages/​extension/​src/​types/​onboarding.ts StepPhase に WELCOME を追加
packages/​extension/​src/​types/​index.ts 型整形・excludeFromGlobalIconColor をコマンド/フォルダへ追加
packages/​extension/​src/​services/​storage/​index.ts LOCAL_STORAGE_KEY.EXPERIMENTS のデフォルト追加
packages/​extension/​src/​services/​storage/​const.ts LOCAL_STORAGE_KEY.EXPERIMENTS を追加
packages/​extension/​src/​services/​storage/​commandStorage.test.ts PageAction Side Panel openMode の保存/復元テスト追加
packages/​extension/​src/​services/​pageAction/​pageActionTypes.ts 型の整形(Union を1行化)
packages/​extension/​src/​services/​pageAction/​dispatcher.ts 入力値の変数解決を helper 経由に集約
packages/​extension/​src/​services/​pageAction/​dispatcher.test.ts ユーザー変数解決のテスト追加
packages/​extension/​src/​services/​pageAction/​backgroundDispatcher.ts 変数解決を helper 経由に集約
packages/​extension/​src/​services/​pageAction/​backgroundDispatcher.test.ts InsertSymbol モック更新(PROMPT追加)
packages/​extension/​src/​services/​pageAction/​background.ts preview 実行時の userVariables 受け渡し整理
packages/​extension/​src/​services/​pageAction/​background-sidePanel.ts Side Panel 実行メッセージに userVariables を含める
packages/​extension/​src/​services/​pageAction/​background-sidePanel.test.ts Side Panel で userVariables 伝搬のテスト追加
packages/​extension/​src/​services/​option/​userStyles.ts CSS 変数生成・スタイル値取得ヘルパー追加(ICON_COLOR含む)
packages/​extension/​src/​services/​option/​defaultSettings.ts Hub 検索URLを /commands に更新
packages/​extension/​src/​services/​ipc.ts resolveIconColors コマンド・IconColorQuery 等を追加
packages/​extension/​src/​services/​iconColor/​background.ts SW 側でアイコン色保持判定を解決するエンドポイント追加
packages/​extension/​src/​services/​iconColor/​background.test.ts resolveIconColors のテスト追加
packages/​extension/​src/​services/​experiments/​types.ts experiments の型定義追加
packages/​extension/​src/​services/​experiments/​onboardingExperiment.ts onboarding_v2 割当の解決/永続化・同期参照を追加
packages/​extension/​src/​services/​experiments/​onboardingExperiment.test.ts onboarding 割当ロジックのテスト追加
packages/​extension/​src/​services/​experiments/​index.ts experiments バレル export 追加
packages/​extension/​src/​services/​experiments/​experimentConfig.ts hub から配分設定を取得(timeout + fallback)
packages/​extension/​src/​services/​experiments/​experimentConfig.test.ts experimentConfig のテスト追加
packages/​extension/​src/​services/​aiPromptByUrl.test.ts URL から AI サービス解決のテスト追加
packages/​extension/​src/​services/​aiPrompt.ts findAiServiceByUrl を追加(origin で照合)
packages/​extension/​src/​lib/​utils.ts getCommandTargetUrl / 予約変数名判定を追加、旧 validate を整理
packages/​extension/​src/​lib/​utils.test.ts getCommandTargetUrl のテスト追加
packages/​extension/​src/​lib/​favicon.ts tldts を使った同一サイト判定・色保持判定を追加
packages/​extension/​src/​hooks/​useSettings.ts useSettingsWithImageCache を切り出し(削除)
packages/​extension/​src/​hooks/​usePopupContext.tsx hasIconColor を Context に追加
packages/​extension/​src/​hooks/​option/​useGlobalIconColor.ts userStyles からグローバルアイコン色を読むフック追加
packages/​extension/​src/​hooks/​option/​useAiServiceForUrl.ts URL→AIサービス解決フック追加(debounce)
packages/​extension/​src/​const.ts STYLE_VARIABLE.ICON_COLOR を追加
packages/​extension/​src/​components/​ui/​input.tsx 残り文字数表示オプション追加
packages/​extension/​src/​components/​ui/​input.test.tsx 残り文字数表示のテスト追加
packages/​extension/​src/​components/​Popup.tsx userStyles 変換を共通関数化・hasIconColor を提供
packages/​extension/​src/​components/​pageAction/​PageActionRecorder.tsx recorder に userVariables を流す
packages/​extension/​src/​components/​pageAction/​InputPopup.tsx InputMenu に userVariables を表示・挿入
packages/​extension/​src/​components/​pageAction/​InputPopup.test.tsx userVariables のメニュー表示/挿入テスト追加
packages/​extension/​src/​components/​pageAction/​InputEditor.tsx InputMenu に userVariables を渡す
packages/​extension/​src/​components/​option/​HubBanner.tsx Hub へのリンクを /commands に更新
packages/​extension/​src/​components/​option/​field/​SwitchField.tsx InfoTooltip へ置換して共通化
packages/​extension/​src/​components/​option/​field/​SelectField.tsx InfoTooltip へ置換して共通化
packages/​extension/​src/​components/​option/​field/​OpenModeToggleField.tsx Edge 判定安全化・SIDE_PANEL を PageAction に追加・レイアウト可変化
packages/​extension/​src/​components/​option/​field/​OpenModeToggleField.test.tsx mode 配列のテスト追加
packages/​extension/​src/​components/​option/​field/​InputField.tsx InfoTooltip へ置換して共通化
packages/​extension/​src/​components/​option/​field/​InfoTooltip.tsx ツールチップ用アイコンコンポーネント追加
packages/​extension/​src/​components/​option/​editor/​UserStyleList.tsx ICON_COLOR を editor に反映
packages/​extension/​src/​components/​option/​editor/​PageActionSection.tsx UserVariablesField を有効化・AIサービス起点で提案
packages/​extension/​src/​components/​option/​editor/​FolderEditDialog.tsx reset 時の既定値マージ改善・excludeFromGlobalIconColor を追加
packages/​extension/​src/​components/​option/​editor/​FolderEditDialog.test.tsx reset/save の回帰テスト追加
packages/​extension/​src/​components/​option/​editor/​CommandTypeSelectionDialog.tsx Hub へのリンクを /commands に更新
packages/​extension/​src/​components/​option/​editor/​CommandEditDialog.tsx excludeFromGlobalIconColor/targetUrl/userVariables の受け渡し等を追加
packages/​extension/​src/​components/​option/​editor/​commandChangedDetector.ts userVariables の空配列/undefined 同一視
packages/​extension/​src/​components/​option/​editor/​commandChangedDetector.test.ts userVariables の差分判定テスト追加
packages/​extension/​src/​components/​onboarding/​useOnboardingVariant.ts variant 解決(override含む)のフック追加
packages/​extension/​src/​components/​onboarding/​useOnboardingState.ts variant 別初期状態・analytics へ config_source 付与
packages/​extension/​src/​components/​onboarding/​useOnboardingState.test.tsx 初期状態/experiment_id 付与のテスト追加
packages/​extension/​src/​components/​onboarding/​steps/​StepSearchCommand.tsx 文言スタイル調整(text-base→text-lg)
packages/​extension/​src/​components/​onboarding/​steps/​StepLinkPreview.tsx 文言スタイル調整(text-base→text-lg)
packages/​extension/​src/​components/​onboarding/​steps/​StepAiPromptCommand.tsx 文言スタイル調整(text-base→text-lg)
packages/​extension/​src/​components/​onboarding/​OnboardingWelcome.tsx Variant B の welcome overlay 追加
packages/​extension/​src/​components/​onboarding/​OnboardingWelcome.test.tsx overlay のタイミング/クリックのテスト追加
packages/​extension/​src/​components/​onboarding/​onboardingProgress.ts phase 対応(WELCOME では非表示/skip無効)
packages/​extension/​src/​components/​onboarding/​onboardingProgress.test.ts phase 対応のテスト追加
packages/​extension/​src/​components/​onboarding/​OnboardingPage.tsx variant 解決後にフロー描画・WELCOME 分岐追加
packages/​extension/​src/​components/​onboarding/​OnboardingLayout.tsx progress/skip の phase 対応
packages/​extension/​src/​components/​onboarding/​OnboardingFadeIn.tsx effect(rise/blur)を導入
packages/​extension/​src/​components/​onboarding/​onboardingAnalytics.ts onboarding イベントに variant 付与
packages/​extension/​src/​components/​onboarding/​onboardingAnalytics.test.ts variant 付与のテスト追加
packages/​extension/​src/​components/​menu/​MenuItem.tsx MenuImage 導入・recolor/除外/保持フラグを反映
packages/​extension/​src/​components/​menu/​MenuItem.test.tsx AI Prompt の recolor 分岐テスト追加
packages/​extension/​src/​components/​menu/​MenuImage.tsx mask recolor 表示・SVG を data URL 化して安全に描画
packages/​extension/​src/​components/​menu/​MenuFolder.tsx Resolved* 型へ移行・recolor/除外/保持フラグ反映
packages/​extension/​src/​components/​menu/​MenuFolder.test.tsx Folder icon recolor 分岐テスト追加
packages/​extension/​src/​components/​menu/​Menu.tsx useSettingsWithImageCache の import 先更新
packages/​extension/​src/​components/​menu/​Menu.module.css mask 用クラス追加・フォント色の変数化
packages/​extension/​src/​components/​menu/​InvisibleItem.tsx 体裁調整(1行化)
packages/​extension/​src/​background_script.ts install 時に onboarding assignment を事前解決・iconColor ハンドラ登録
packages/​extension/​src/​action/​pageAction.ts Side Panel での pending 保存・clipboard 必要判定強化
packages/​extension/​public/​_locales/​en/​messages.json userVariables/アイコン色/歓迎文言など i18n 追加・文言調整
packages/​extension/​public/​_locales/​ja/​messages.json 同上(日本語)
packages/​extension/​public/​_locales/​zh_CN/​messages.json 同上(中国語)
packages/​extension/​public/​_locales/​ru/​messages.json 同上(ロシア語)
packages/​extension/​public/​_locales/​pt_PT/​messages.json 同上(ポルトガル語)
packages/​extension/​public/​_locales/​pt_BR/​messages.json 同上(ポルトガル語BR)
packages/​extension/​public/​_locales/​ms/​messages.json 同上(マレー語)
packages/​extension/​public/​_locales/​ko/​messages.json 同上(韓国語)
packages/​extension/​public/​_locales/​it/​messages.json 同上(イタリア語)
packages/​extension/​public/​_locales/​id/​messages.json 同上(インドネシア語)
packages/​extension/​public/​_locales/​fr/​messages.json 同上(フランス語)
packages/​extension/​public/​_locales/​es/​messages.json 同上(スペイン語)
packages/​extension/​public/​_locales/​de/​messages.json 同上(ドイツ語)
packages/​extension/​package.json v1.3.0 + tldts 追加
packages/​extension/​manifest.json v1.3.0 反映
packages/​extension/​e2e/​page-action.spec.ts userVariables 展開の E2E 追加
packages/​extension/​e2e/​onboarding-shots.spec.ts variant=B のスクショ対応
packages/​extension/​e2e/​hub.spec.ts Hub 遷移先パスを /commands に更新
packages/​extension/​e2e/​generated-command-urls.ts Hub 検索 URL を /commands に更新
packages/​extension/​e2e/​data/​test-settings.json userVariables 用の PageAction テストコマンド追加
package.json ルートバージョンを 1.3.0 に更新
AGENTS.md experiments.json 配信の説明を追記

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/extension/tailwind.config.js
Comment thread packages/extension/src/components/onboarding/OnboardingWelcome.tsx
ujiro99 and others added 16 commits September 22, 2026 18:34
The Hub sends GA4's `uninstall` event on our behalf - by the time Chrome
removes the extension this service worker is already gone, so the uninstall
URL is the only hook left. It has no way to know which version the user
left on, so hand that over on the URL, next to the client_id it already
carries.

The fallback URL used when the client_id lookup fails stays as it was: the
Hub records nothing without a client_id, so a version on its own would say
nothing.

Refs ujiro99/selection-command-hub#275

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HtiybZS7tYtWXK78B89PQJ
feat: アンインストールURLに拡張バージョンを付与
Both notes explained at length why the extension can't send the event
itself, which the linked issue already covers.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HtiybZS7tYtWXK78B89PQJ
Both notes explained at length why the extension can't send the event
itself, which the linked issue already covers.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HtiybZS7tYtWXK78B89PQJ
style: アンインストールURL周りのコメントを削減
An outdated service worker can answer resolveIconColors with null,
which left the menu stuck in the loading state. Render unanswered
icons with the default colors instead, while still leaving them
uncached so the next menu retries.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Move React-independent import/export/backup logic to
  services/settings/importExport.ts
- Add useImportExport hook that only holds state and wires service calls
- Keep ImportExport.tsx focused on rendering
- Add unit tests for the importExport service

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Backups with an empty commands array were shown as restorable but
always failed to restore. Treat them as unavailable instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
debouncedSyncSet cleared the pending buffer and resolved all waiting
promises when a write completed, so data added while chrome.storage.sync.set
was in flight was silently dropped. Detach the batch when the write starts
and serialize writes so later batches land after earlier ones.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replace the callback API with async/await. Errors are caught and
logged so waiting callers still resolve and the write chain keeps
running after a failed write.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An invalid JSON file caused an unhandled rejection with no feedback.
Catch the error, alert the user and clear the previously selected
file so it is not imported by mistake.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fix: インポート/バックアップ復元と sync ストレージ書き込みの不具合修正
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
When an AI prompt command was run from a shortcut without a selection, the
query URL approach expanded {{SelectedText}} to an empty string and never
asked the background to read the clipboard. Prompts containing {{Clipboard}}
also had to fall back to DOM input.

Leave the clipboard-dependent placeholders unresolved in the prompt and let
toUrl() resolve them after the background reads the clipboard. Side panel
mode keeps using DOM input, since the side panel must be opened before the
clipboard can be read.

Also pass the clipboard text to toUrl() in openTab, which previously dropped it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rams

useClipboard meant two different things: in ExecuteCommandParams it is a
permission to use the clipboard in place of an empty selection, while in
UrlParam it is an instruction for the background to read the clipboard.
Rename the permission side to make the distinction explicit.

UrlParam.useClipboard, SidePanelPendingAction.useClipboard and the persisted
SHORTCUT_NO_SELECTION_BEHAVIOR value are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ujiro99
ujiro99 merged commit 2e55149 into main Sep 23, 2026
6 checks passed
@ujiro99
ujiro99 deleted the dev-1.3.0 branch September 23, 2026 08:02
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.

4 participants