From d50c7979c1b565daa39f9a0f7eb0a6dc05f5b7d9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 3 May 2026 02:56:26 +0000 Subject: [PATCH 1/3] Initial plan From 450956b39e93f2d3bdee8735d2777b691a569135 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 3 May 2026 03:01:12 +0000 Subject: [PATCH 2/3] docs: document external postMessage API parameter spec in DownloadButton Agent-Logs-Url: https://github.com/ujiro99/selection-command/sessions/6057d242-e07f-4fda-8ff3-5cc13a2fa233 Co-authored-by: ujiro99 <677231+ujiro99@users.noreply.github.com> --- .../components/commandHub/DownloadButton.tsx | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/packages/extension/src/components/commandHub/DownloadButton.tsx b/packages/extension/src/components/commandHub/DownloadButton.tsx index 41171685..e482fbbd 100644 --- a/packages/extension/src/components/commandHub/DownloadButton.tsx +++ b/packages/extension/src/components/commandHub/DownloadButton.tsx @@ -121,6 +121,56 @@ export const DownloadButton = (): JSX.Element => { return () => clearTimeout(timer) }, [open]) + /** + * External postMessage API for adding/deleting commands from the Hub. + * + * This content script listens for messages from the Hub page (origin must match HUB_URL). + * The message object must have the following shape: + * + * --- AddCommand --- + * { + * action: "AddCommand", + * command: string // JSON-stringified command object (see below) + * } + * + * The `command` field is a JSON string representing either a SearchCommand or a PageActionCommand. + * + * SearchCommand (openMode is one of "popup" | "tab" | "window" | "backgroundTab" | "sidePanel"): + * { + * id: string, // Unique command identifier + * title: string, // Display name of the command + * searchUrl: string, // Search URL template (%s is replaced with selected text) + * iconUrl: string, // URL of the command icon + * openMode: string, // How to open the result: "popup" | "tab" | "window" | "backgroundTab" | "sidePanel" + * openModeSecondary?: string, // Secondary open mode (optional) + * spaceEncoding?: string, // Space encoding in URL: "plus" | "percent" (optional) + * sourceType?: string, // Origin of the command: "default" | "selfCreated" | "hubCommunity" | "unknown" (optional) + * sourceId?: string // Identifier of the source (optional) + * } + * + * PageActionCommand (openMode is "pageAction"): + * { + * id: string, // Unique command identifier + * title: string, // Display name of the command + * iconUrl: string, // URL of the command icon + * openMode: "pageAction", // Must be "pageAction" for page action commands + * pageActionOption: { + * startUrl: string, // URL to open when executing the page action + * pageUrl?: string, // URL pattern for command enablement (currentTab mode only, optional) + * openMode: string, // How to open the page: "none" | "popup" | "tab" | "backgroundTab" | "window" | "currentTab" + * steps: Array, // Sequence of automation steps to execute + * userVariables?: Array<{ name: string, value: string }> // User-defined variables (optional) + * }, + * sourceType?: string, // Origin of the command: "default" | "selfCreated" | "hubCommunity" | "unknown" (optional) + * sourceId?: string // Identifier of the source (optional) + * } + * + * --- DeleteCommand --- + * { + * action: "DeleteCommand", + * id: string // ID of the command to remove + * } + */ useEffect(() => { const hubOrigin = new URL(HUB_URL).origin const handleMessage = (event: MessageEvent) => { From 12bbf99308198bd7ee1a84e603c958b7858abf63 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 3 May 2026 05:00:13 +0000 Subject: [PATCH 3/3] feat: add AiPromptCommand support to addCommand handler and API docs Agent-Logs-Url: https://github.com/ujiro99/selection-command/sessions/b7ce3bf4-c252-41f3-9969-1693c260c17d Co-authored-by: ujiro99 <677231+ujiro99@users.noreply.github.com> --- packages/extension/src/background_script.ts | 18 +++++++++++++++--- .../components/commandHub/DownloadButton.tsx | 17 ++++++++++++++++- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/packages/extension/src/background_script.ts b/packages/extension/src/background_script.ts index 01170493..ea41b3df 100644 --- a/packages/extension/src/background_script.ts +++ b/packages/extension/src/background_script.ts @@ -21,6 +21,7 @@ import { PopupAutoClose } from "@/services/popupAutoClose" import { isSearchCommand, isPageActionCommand, + isAiPromptCommand, findMatchingPageRule, } from "@/lib/utils" import { execute } from "@/action/background" @@ -161,6 +162,7 @@ const commandFuncs = { const params = JSON.parse(param.command) const isSearch = isSearchCommand(params) const isPageAction = isPageActionCommand(params) + const isAiPrompt = isAiPromptCommand(params) const sourceType = (params as { sourceType?: unknown }).sourceType const sourceId = (params as { sourceId?: unknown }).sourceId const normalizedSourceType = Object.values(COMMAND_SOURCE_TYPE).includes( @@ -185,17 +187,27 @@ const commandFuncs = { spaceEncoding: params.spaceEncoding, popupOption: PopupOption, } - : isPageAction + : isAiPrompt ? { id: params.id, title: params.title, iconUrl: params.iconUrl, ...sourceInfo, openMode: params.openMode, - pageActionOption: params.pageActionOption, + aiPromptOption: params.aiPromptOption, popupOption: PopupOption, } - : null + : isPageAction + ? { + id: params.id, + title: params.title, + iconUrl: params.iconUrl, + ...sourceInfo, + openMode: params.openMode, + pageActionOption: params.pageActionOption, + popupOption: PopupOption, + } + : null if (!cmd) { console.error("invalid command", param.command) diff --git a/packages/extension/src/components/commandHub/DownloadButton.tsx b/packages/extension/src/components/commandHub/DownloadButton.tsx index e482fbbd..f9561ac2 100644 --- a/packages/extension/src/components/commandHub/DownloadButton.tsx +++ b/packages/extension/src/components/commandHub/DownloadButton.tsx @@ -133,7 +133,7 @@ export const DownloadButton = (): JSX.Element => { * command: string // JSON-stringified command object (see below) * } * - * The `command` field is a JSON string representing either a SearchCommand or a PageActionCommand. + * The `command` field is a JSON string representing a SearchCommand, an AiPromptCommand, or a PageActionCommand. * * SearchCommand (openMode is one of "popup" | "tab" | "window" | "backgroundTab" | "sidePanel"): * { @@ -148,6 +148,21 @@ export const DownloadButton = (): JSX.Element => { * sourceId?: string // Identifier of the source (optional) * } * + * AiPromptCommand (openMode is "aiPrompt"): + * { + * id: string, // Unique command identifier + * title: string, // Display name of the command + * iconUrl: string, // URL of the command icon + * openMode: "aiPrompt", // Must be "aiPrompt" for AI prompt commands + * aiPromptOption: { + * serviceId: string, // ID of the AI service to use (see hub/public/data/ai-services.json) + * prompt: string, // Prompt text sent to the AI service (supports variable placeholders) + * openMode: string // How to open the AI service result: "popup" | "tab" | "window" | etc. + * }, + * sourceType?: string, // Origin of the command: "default" | "selfCreated" | "hubCommunity" | "unknown" (optional) + * sourceId?: string // Identifier of the source (optional) + * } + * * PageActionCommand (openMode is "pageAction"): * { * id: string, // Unique command identifier