@mcp-b/extension-tools
Version:
62+ Chrome Extension API tools for Model Context Protocol (MCP) - Let AI agents control tabs, bookmarks, history, storage, and more
1 lines • 471 kB
JavaScript
import{z as e}from"zod";import t,{zodToJsonSchema as n}from"zod-to-json-schema";import{SMART_DOM_READER_BUNDLE as r}from"@mcp-b/smart-dom-reader/bundle-string";var i=class{constructor(e,t={}){this.server=e,this.options=t}shouldRegisterTool(e){return this.options[e]!==!1}formatError(e){return{content:[{type:`text`,text:`Error: ${e instanceof Error?e.message:String(e)}`}],isError:!0}}formatSuccess(e,t){return{content:[{type:`text`,text:t?`${e}\n${JSON.stringify(t,null,2)}`:e}]}}formatJson(e){return{content:[{type:`text`,text:JSON.stringify(e,null,2)}]}}register(){let e=this.checkAvailability();if(!e.available){console.warn(`✗ ${this.apiName} API not available: ${e.message}`),e.details&&console.warn(` Details: ${e.details}`);return}console.log(`✓ ${this.apiName} API available`),this.registerTools()}},a=class extends i{apiName=`Alarms`;constructor(e,t={}){super(e,t)}checkAvailability(){try{return chrome.alarms?typeof chrome.alarms.getAll==`function`?(chrome.alarms.getAll(e=>{if(chrome.runtime.lastError)throw Error(chrome.runtime.lastError.message)}),{available:!0,message:`Alarms API is fully available`}):{available:!1,message:`chrome.alarms.getAll is not available`,details:`The alarms API appears to be partially available. Check manifest permissions.`}:{available:!1,message:`chrome.alarms API is not defined`,details:`This extension needs the "alarms" permission in its manifest.json`}}catch(e){return{available:!1,message:`Failed to access chrome.alarms API`,details:e instanceof Error?e.message:`Unknown error occurred`}}}registerTools(){this.shouldRegisterTool(`createAlarm`)&&this.registerCreateAlarm(),this.shouldRegisterTool(`getAlarm`)&&this.registerGetAlarm(),this.shouldRegisterTool(`getAllAlarms`)&&this.registerGetAllAlarms(),this.shouldRegisterTool(`clearAlarm`)&&this.registerClearAlarm(),this.shouldRegisterTool(`clearAllAlarms`)&&this.registerClearAllAlarms()}registerCreateAlarm(){this.server.registerTool(`extension_tool_create_alarm`,{description:`Create an alarm that fires at a specific time or periodically`,inputSchema:{name:e.string().optional().describe(`Optional name to identify this alarm`),delayInMinutes:e.number().min(.5).optional().describe(`Time in minutes from now when the alarm should first fire. Minimum is 0.5 minutes (30 seconds)`),periodInMinutes:e.number().min(.5).optional().describe(`If set, the alarm will repeat every periodInMinutes minutes after the initial event. Minimum is 0.5 minutes (30 seconds)`),when:e.number().optional().describe(`Time at which the alarm should fire, in milliseconds past the epoch (e.g. Date.now() + n)`)}},async({name:e,delayInMinutes:t,periodInMinutes:n,when:r})=>{try{if(t===void 0&&r===void 0)return this.formatError(`Either delayInMinutes or when must be specified to create an alarm`);let i={};t!==void 0&&(i.delayInMinutes=t),n!==void 0&&(i.periodInMinutes=n),r!==void 0&&(i.when=r),await new Promise((t,n)=>{e?chrome.alarms.create(e,i,()=>{chrome.runtime.lastError?n(Error(chrome.runtime.lastError.message)):t()}):chrome.alarms.create(i,()=>{chrome.runtime.lastError?n(Error(chrome.runtime.lastError.message)):t()})});let a=await new Promise((t,n)=>{chrome.alarms.get(e||``,e=>{chrome.runtime.lastError?n(Error(chrome.runtime.lastError.message)):t(e)})});return this.formatSuccess(`Alarm created successfully`,{name:a?.name||e||`unnamed`,scheduledTime:a?.scheduledTime,periodInMinutes:a?.periodInMinutes})}catch(e){return this.formatError(e)}})}registerGetAlarm(){this.server.registerTool(`extension_tool_get_alarm`,{description:`Get details about a specific alarm`,inputSchema:{name:e.string().optional().describe(`Name of the alarm to retrieve. If not specified, gets the default unnamed alarm`)}},async({name:e})=>{try{let t=await new Promise((t,n)=>{e?chrome.alarms.get(e,e=>{chrome.runtime.lastError?n(Error(chrome.runtime.lastError.message)):t(e)}):chrome.alarms.get(e=>{chrome.runtime.lastError?n(Error(chrome.runtime.lastError.message)):t(e)})});return t?this.formatJson({name:t.name,scheduledTime:t.scheduledTime,scheduledTimeFormatted:new Date(t.scheduledTime).toISOString(),periodInMinutes:t.periodInMinutes}):this.formatSuccess(`No alarm found`,{name:e||`unnamed`})}catch(e){return this.formatError(e)}})}registerGetAllAlarms(){this.server.registerTool(`extension_tool_get_all_alarms`,{description:`Get all active alarms`,inputSchema:{}},async()=>{try{let e=await new Promise((e,t)=>{chrome.alarms.getAll(n=>{chrome.runtime.lastError?t(Error(chrome.runtime.lastError.message)):e(n)})});return this.formatJson({count:e.length,alarms:e.map(e=>({name:e.name,scheduledTime:e.scheduledTime,scheduledTimeFormatted:new Date(e.scheduledTime).toISOString(),periodInMinutes:e.periodInMinutes}))})}catch(e){return this.formatError(e)}})}registerClearAlarm(){this.server.registerTool(`extension_tool_clear_alarm`,{description:`Clear a specific alarm`,inputSchema:{name:e.string().optional().describe(`Name of the alarm to clear. If not specified, clears the default unnamed alarm`)}},async({name:e})=>{try{return await new Promise((t,n)=>{e?chrome.alarms.clear(e,e=>{chrome.runtime.lastError?n(Error(chrome.runtime.lastError.message)):t(e)}):chrome.alarms.clear(e=>{chrome.runtime.lastError?n(Error(chrome.runtime.lastError.message)):t(e)})})?this.formatSuccess(`Alarm cleared successfully`,{name:e||`unnamed`}):this.formatSuccess(`No alarm found to clear`,{name:e||`unnamed`})}catch(e){return this.formatError(e)}})}registerClearAllAlarms(){this.server.registerTool(`extension_tool_clear_all_alarms`,{description:`Clear all alarms`,inputSchema:{}},async()=>{try{let e=await new Promise((e,t)=>{chrome.alarms.getAll(n=>{chrome.runtime.lastError?t(Error(chrome.runtime.lastError.message)):e(n)})});return await new Promise((e,t)=>{chrome.alarms.clearAll(n=>{chrome.runtime.lastError?t(Error(chrome.runtime.lastError.message)):e(n)})})?this.formatSuccess(`All alarms cleared successfully`,{clearedCount:e.length,clearedAlarms:e.map(e=>e.name)}):this.formatSuccess(`No alarms to clear`)}catch(e){return this.formatError(e)}})}},o=class extends i{apiName=`Audio`;constructor(e,t={}){super(e,t)}checkAvailability(){try{return chrome.audio?typeof chrome.audio.getDevices==`function`?(chrome.audio.getDevices({},e=>{if(chrome.runtime.lastError)throw Error(chrome.runtime.lastError.message)}),{available:!0,message:`Audio API is fully available`}):{available:!1,message:`chrome.audio.getDevices is not available`,details:`The audio API appears to be partially available. Check manifest permissions and ensure you are on ChromeOS.`}:{available:!1,message:`chrome.audio API is not defined`,details:`This extension needs the "audio" permission in its manifest.json and only works on ChromeOS`}}catch(e){return{available:!1,message:`Failed to access chrome.audio API`,details:e instanceof Error?e.message:`Unknown error occurred`}}}registerTools(){this.shouldRegisterTool(`getDevices`)&&this.registerGetDevices(),this.shouldRegisterTool(`getMute`)&&this.registerGetMute(),this.shouldRegisterTool(`setActiveDevices`)&&this.registerSetActiveDevices(),this.shouldRegisterTool(`setMute`)&&this.registerSetMute(),this.shouldRegisterTool(`setProperties`)&&this.registerSetProperties()}registerGetDevices(){this.server.registerTool(`extension_tool_get_audio_devices`,{description:`Get a list of audio devices filtered based on criteria`,inputSchema:{isActive:e.boolean().optional().describe(`If set, only audio devices whose active state matches this value will be returned`),streamTypes:e.array(e.enum([`INPUT`,`OUTPUT`])).optional().describe(`If set, only audio devices whose stream type is included in this list will be returned`)}},async({isActive:e,streamTypes:t})=>{try{let n={};e!==void 0&&(n.isActive=e),t!==void 0&&(n.streamTypes=t);let r=await new Promise((e,t)=>{chrome.audio.getDevices(n,n=>{chrome.runtime.lastError?t(Error(chrome.runtime.lastError.message)):e(n)})});return this.formatJson({count:r.length,devices:r.map(e=>({id:e.id,deviceName:e.deviceName,deviceType:e.deviceType,displayName:e.displayName,isActive:e.isActive,level:e.level,stableDeviceId:e.stableDeviceId,streamType:e.streamType}))})}catch(e){return this.formatError(e)}})}registerGetMute(){this.server.registerTool(`extension_tool_get_audio_mute`,{description:`Get the system-wide mute state for the specified stream type`,inputSchema:{streamType:e.enum([`INPUT`,`OUTPUT`]).describe(`Stream type for which mute state should be fetched`)}},async({streamType:e})=>{try{let t=await new Promise((t,n)=>{chrome.audio.getMute(e,e=>{chrome.runtime.lastError?n(Error(chrome.runtime.lastError.message)):t(e)})});return this.formatJson({streamType:e,isMuted:t})}catch(e){return this.formatError(e)}})}registerSetActiveDevices(){this.server.registerTool(`extension_tool_set_active_audio_devices`,{description:`Set lists of active input and/or output devices`,inputSchema:{input:e.array(e.string()).optional().describe(`List of input device IDs that should be active. Leave unset to not affect input devices`),output:e.array(e.string()).optional().describe(`List of output device IDs that should be active. Leave unset to not affect output devices`)}},async({input:e,output:t})=>{try{if(e===void 0&&t===void 0)return this.formatError(`At least one of input or output device lists must be specified`);let n={};return e!==void 0&&(n.input=e),t!==void 0&&(n.output=t),await new Promise((e,t)=>{chrome.audio.setActiveDevices(n,()=>{chrome.runtime.lastError?t(Error(chrome.runtime.lastError.message)):e()})}),this.formatSuccess(`Active audio devices set successfully`,{inputDevices:e,outputDevices:t})}catch(e){return this.formatError(e)}})}registerSetMute(){this.server.registerTool(`extension_tool_set_audio_mute`,{description:`Set mute state for a stream type. The mute state will apply to all audio devices with the specified audio stream type`,inputSchema:{streamType:e.enum([`INPUT`,`OUTPUT`]).describe(`Stream type for which mute state should be set`),isMuted:e.boolean().describe(`New mute value`)}},async({streamType:e,isMuted:t})=>{try{return await new Promise((n,r)=>{chrome.audio.setMute(e,t,()=>{chrome.runtime.lastError?r(Error(chrome.runtime.lastError.message)):n()})}),this.formatSuccess(`Audio mute state set successfully`,{streamType:e,isMuted:t})}catch(e){return this.formatError(e)}})}registerSetProperties(){this.server.registerTool(`extension_tool_set_audio_device_properties`,{description:`Set the properties for the input or output device`,inputSchema:{id:e.string().describe(`ID of the audio device to modify`),level:e.number().min(0).max(100).optional().describe(`The audio device's desired sound level. For input devices, represents gain. For output devices, represents volume`)}},async({id:e,level:t})=>{try{let n={};return t!==void 0&&(n.level=t),await new Promise((t,r)=>{chrome.audio.setProperties(e,n,()=>{chrome.runtime.lastError?r(Error(chrome.runtime.lastError.message)):t()})}),this.formatSuccess(`Audio device properties set successfully`,{deviceId:e,level:t})}catch(e){return this.formatError(e)}})}};const s=[`create`,`get`,`getChildren`,`getRecent`,`getSubTree`,`getTree`,`move`,`remove`,`removeTree`,`search`,`update`],c=e.enum(s);var l=class extends i{apiName=`Bookmarks`;constructor(e,t={}){super(e,t)}checkAvailability(){try{return chrome.bookmarks?typeof chrome.bookmarks.getTree==`function`?(chrome.bookmarks.getTree(e=>{if(chrome.runtime.lastError)throw Error(chrome.runtime.lastError.message)}),{available:!0,message:`Bookmarks API is fully available`}):{available:!1,message:`chrome.bookmarks.getTree is not available`,details:`The bookmarks API appears to be partially available. Check manifest permissions.`}:{available:!1,message:`chrome.bookmarks API is not defined`,details:`This extension needs the "bookmarks" permission in its manifest.json`}}catch(e){return{available:!1,message:`Failed to access chrome.bookmarks API`,details:e instanceof Error?e.message:`Unknown error occurred`}}}registerTools(){this.server.registerTool(`extension_tool_bookmark_operations`,{description:`Perform bookmark operations. Choose an action and supply the corresponding parameters.`,inputSchema:{action:c,params:e.record(e.any()).optional().describe(`Parameters for the chosen action`)}},async({action:e,params:t={}})=>{try{if(!this.isActionEnabled(e))return this.formatError(`Action '${e}' is disabled by configuration`);switch(e){case`create`:return await this.handleCreate(t);case`get`:return await this.handleGet(t);case`getChildren`:return await this.handleGetChildren(t);case`getRecent`:return await this.handleGetRecent(t);case`getSubTree`:return await this.handleGetSubTree(t);case`getTree`:return await this.handleGetTree();case`move`:return await this.handleMove(t);case`remove`:return await this.handleRemove(t);case`removeTree`:return await this.handleRemoveTree(t);case`search`:return await this.handleSearch(t);case`update`:return await this.handleUpdate(t);default:return this.formatError(`Unknown action: ${String(e)}`)}}catch(e){return this.formatError(e)}}),this.server.registerTool(`extension_tool_bookmark_parameters_description`,{description:`Get the parameters for extension_tool_bookmark_operations tool and the description for the associated action, this tool should be used first before extension_tool_bookmark_operations`,inputSchema:{action:c}},async({action:e})=>{try{if(!this.isActionEnabled(e))return this.formatError(`Action '${e}' is disabled by configuration`);let t=(e,t)=>n(e,{name:t,$refStrategy:`none`}),r={tool:`extension_tool_bookmark_operations`,action:e,note:`Use the description to double check if the correct action is chosen. Use this JSON Schema for the params field when calling the tool. The top-level tool input is { action, params }.`};switch(e){case`create`:{let e=t(this.createSchema,`BookmarksCreateParams`),n={title:`My Site`,url:`https://example.com`,parentId:`1`},i={params:e,description:`Create a bookmark or folder under the specified parent. A folder must have a title and no url`};return this.formatJson({...r,...i,example:n})}case`get`:{let e=t(this.getSchema,`BookmarksGetParams`),n={idOrIdList:`123`},i={params:e,description:`Retrieve the specified bookmark(s) by ID`};return this.formatJson({...r,...i,example:n})}case`getChildren`:{let e=t(this.getChildrenSchema,`BookmarksGetChildrenParams`),n={id:`1`},i={params:e,description:`Retrieve the children of the specified bookmark folder`};return this.formatJson({...r,...i,example:n})}case`getRecent`:{let e=t(this.getRecentSchema,`BookmarksGetRecentParams`),n={numberOfItems:10},i={params:e,description:`Retrieve the recently added bookmarks`};return this.formatJson({...r,...i,example:n})}case`getSubTree`:{let e=t(this.getSubTreeSchema,`BookmarksGetSubTreeParams`),n={id:`1`},i={params:e,description:`Retrieve part of the bookmarks hierarchy, starting at the specified node`};return this.formatJson({...r,...i,example:n})}case`getTree`:{let e={type:`object`,properties:{},additionalProperties:!1},t={},n={params:e,description:`Retrieve the entire bookmarks hierarchy`};return this.formatJson({...r,...n,example:t})}case`move`:{let e=t(this.moveSchema,`BookmarksMoveParams`),n={id:`123`,parentId:`1`,index:0},i={params:e,description:`Move the specified bookmark or folder to a new location`};return this.formatJson({...r,...i,example:n})}case`remove`:{let e=t(this.removeSchema,`BookmarksRemoveParams`),n={id:`123`},i={params:e,description:`Remove the specified bookmark or empty folder`};return this.formatJson({...r,...i,example:n})}case`removeTree`:{let e=t(this.removeTreeSchema,`BookmarksRemoveTreeParams`),n={id:`1`},i={params:e,description:`Recursively remove a bookmark folder and all its contents`};return this.formatJson({...r,...i,example:n})}case`search`:{let e=t(this.searchSchema,`BookmarksSearchParams`),n={query:`recipes`},i={params:e,description:`Search for bookmarks matching the given query`};return this.formatJson({...r,...i,example:n})}case`update`:{let e=t(this.updateSchema,`BookmarksUpdateParams`),n={id:`123`,title:`New title`},i={params:e,description:`Update the properties of a bookmark or folder. Only title and url can be changed`};return this.formatJson({...r,...i,example:n})}default:return this.formatError(`Unknown action: ${String(e)}`)}}catch(e){return this.formatError(e)}})}createSchema=e.object({parentId:e.string().optional().describe(`Parent folder ID. Defaults to the Other Bookmarks folder`),title:e.string().optional().describe(`The title of the bookmark or folder`),url:e.string().optional().describe(`The URL for the bookmark. Omit for folders`),index:e.number().optional().describe(`The position within the parent folder`)});getSchema=e.object({idOrIdList:e.union([e.string(),e.array(e.string())]).describe(`A single bookmark ID or array of bookmark IDs`)});getChildrenSchema=e.object({id:e.string().describe(`The ID of the folder to get children from`)});getRecentSchema=e.object({numberOfItems:e.number().min(1).describe(`The maximum number of items to return`)});getSubTreeSchema=e.object({id:e.string().describe(`The ID of the root of the subtree to retrieve`)});moveSchema=e.object({id:e.string().describe(`The ID of the bookmark or folder to move`),parentId:e.string().optional().describe(`The new parent folder ID`),index:e.number().optional().describe(`The new position within the parent folder`)});removeSchema=e.object({id:e.string().describe(`The ID of the bookmark or empty folder to remove`)});removeTreeSchema=e.object({id:e.string().describe(`The ID of the folder to remove recursively`)});searchSchema=e.object({query:e.union([e.string(),e.object({query:e.string().optional().describe(`Words and phrases to match against URLs and titles`),url:e.string().optional().describe(`URL to match exactly`),title:e.string().optional().describe(`Title to match exactly`)})])});updateSchema=e.object({id:e.string().describe(`The ID of the bookmark or folder to update`),title:e.string().optional().describe(`The new title`),url:e.string().optional().describe(`The new URL (bookmarks only)`)});async handleCreate(e){let{parentId:t,title:n,url:r,index:i}=this.createSchema.parse(e);if(n===void 0&&r===void 0||n?.length===0&&r?.length===0)throw Error(`Either title or url must be provided`);let a={};t!==void 0&&(a.parentId=t),n!==void 0&&(a.title=n),r!==void 0&&(a.url=r),i!==void 0&&(a.index=i);let o=await new Promise((e,t)=>{chrome.bookmarks.create(a,n=>{chrome.runtime.lastError?t(Error(chrome.runtime.lastError.message)):e(n)})});return this.formatJson({id:o.id,title:o.title,url:o.url,parentId:o.parentId,index:o.index,dateAdded:o.dateAdded,type:o.url?`bookmark`:`folder`})}async handleGet(e){let{idOrIdList:t}=this.getSchema.parse(e),n=await new Promise((e,n)=>{chrome.bookmarks.get(t,t=>{chrome.runtime.lastError?n(Error(chrome.runtime.lastError.message)):e(t)})});return this.formatJson({count:n.length,bookmarks:n.map(e=>({id:e.id,title:e.title,url:e.url,parentId:e.parentId,index:e.index,dateAdded:e.dateAdded,dateAddedFormatted:e.dateAdded?new Date(e.dateAdded).toISOString():void 0,type:e.url?`bookmark`:`folder`}))})}async handleGetChildren(e){let{id:t}=this.getChildrenSchema.parse(e),n=await new Promise((e,n)=>{chrome.bookmarks.getChildren(t,t=>{chrome.runtime.lastError?n(Error(chrome.runtime.lastError.message)):e(t)})});return this.formatJson({parentId:t,count:n.length,children:n.map(e=>({id:e.id,title:e.title,url:e.url,parentId:e.parentId,index:e.index,dateAdded:e.dateAdded,dateAddedFormatted:e.dateAdded?new Date(e.dateAdded).toISOString():void 0,type:e.url?`bookmark`:`folder`}))})}async handleGetRecent(e){let{numberOfItems:t}=this.getRecentSchema.parse(e),n=await new Promise((e,n)=>{chrome.bookmarks.getRecent(t,t=>{chrome.runtime.lastError?n(Error(chrome.runtime.lastError.message)):e(t)})});return this.formatJson({count:n.length,recentBookmarks:n.map(e=>({id:e.id,title:e.title,url:e.url,parentId:e.parentId,index:e.index,dateAdded:e.dateAdded,dateAddedFormatted:e.dateAdded?new Date(e.dateAdded).toISOString():void 0}))})}async handleGetSubTree(e){let{id:t}=this.getSubTreeSchema.parse(e),n=await new Promise((e,n)=>{chrome.bookmarks.getSubTree(t,t=>{chrome.runtime.lastError?n(Error(chrome.runtime.lastError.message)):e(t)})}),r=e=>({id:e.id,title:e.title,url:e.url,parentId:e.parentId,index:e.index,dateAdded:e.dateAdded,dateAddedFormatted:e.dateAdded?new Date(e.dateAdded).toISOString():void 0,type:e.url?`bookmark`:`folder`,children:e.children?e.children.map(r):void 0});return this.formatJson({rootId:t,subtree:n.map(r)})}async handleGetTree(){let e=await new Promise((e,t)=>{chrome.bookmarks.getTree(n=>{chrome.runtime.lastError?t(Error(chrome.runtime.lastError.message)):e(n)})}),t=e=>({id:e.id,title:e.title,url:e.url,parentId:e.parentId,index:e.index,dateAdded:e.dateAdded,dateAddedFormatted:e.dateAdded?new Date(e.dateAdded).toISOString():void 0,type:e.url?`bookmark`:`folder`,children:e.children?e.children.map(t):void 0});return this.formatJson({tree:e.map(t)})}async handleMove(e){let{id:t,parentId:n,index:r}=this.moveSchema.parse(e),i={};n!==void 0&&(i.parentId=n),r!==void 0&&(i.index=r);let a=await new Promise((e,n)=>{chrome.bookmarks.move(t,i,t=>{chrome.runtime.lastError?n(Error(chrome.runtime.lastError.message)):e(t)})});return this.formatSuccess(`Bookmark moved successfully`,{id:a.id,title:a.title,url:a.url,parentId:a.parentId,index:a.index,type:a.url?`bookmark`:`folder`})}async handleRemove(e){let{id:t}=this.removeSchema.parse(e);return await new Promise((e,n)=>{chrome.bookmarks.remove(t,()=>{chrome.runtime.lastError?n(Error(chrome.runtime.lastError.message)):e()})}),this.formatSuccess(`Bookmark removed successfully`,{id:t})}async handleRemoveTree(e){let{id:t}=this.removeTreeSchema.parse(e);return await new Promise((e,n)=>{chrome.bookmarks.removeTree(t,()=>{chrome.runtime.lastError?n(Error(chrome.runtime.lastError.message)):e()})}),this.formatSuccess(`Bookmark folder and all contents removed successfully`,{id:t})}async handleSearch(e){let{query:t}=this.searchSchema.parse(e),n=await new Promise((e,n)=>{chrome.bookmarks.search(t,t=>{chrome.runtime.lastError?n(Error(chrome.runtime.lastError.message)):e(t)})});return this.formatJson({query:typeof t==`string`?t:JSON.stringify(t),count:n.length,results:n.map(e=>({id:e.id,title:e.title,url:e.url,parentId:e.parentId,index:e.index,dateAdded:e.dateAdded,dateAddedFormatted:e.dateAdded?new Date(e.dateAdded).toISOString():void 0,type:e.url?`bookmark`:`folder`}))})}async handleUpdate(e){let{id:t,title:n,url:r}=this.updateSchema.parse(e),i={};if(n!==void 0&&(i.title=n),r!==void 0&&(i.url=r),Object.keys(i).length===0)return this.formatError(`At least one property (title or url) must be specified to update`);let a=await new Promise((e,n)=>{chrome.bookmarks.update(t,i,t=>{chrome.runtime.lastError?n(Error(chrome.runtime.lastError.message)):e(t)})});return this.formatSuccess(`Bookmark updated successfully`,{id:a.id,title:a.title,url:a.url,parentId:a.parentId,index:a.index,type:a.url?`bookmark`:`folder`,changes:i})}isActionEnabled(e){let t={create:`create`,get:`get`,getChildren:`getChildren`,getRecent:`getRecent`,getSubTree:`getSubTree`,getTree:`getTree`,move:`move`,remove:`remove`,removeTree:`removeTree`,search:`search`,update:`update`}[e];return this.options[t]!==!1}},u=class extends i{apiName=`BrowsingData`;constructor(e,t={}){super(e,t)}checkAvailability(){try{return chrome.browsingData?typeof chrome.browsingData.settings==`function`?(chrome.browsingData.settings(e=>{if(chrome.runtime.lastError)throw Error(chrome.runtime.lastError.message)}),{available:!0,message:`BrowsingData API is fully available`}):{available:!1,message:`chrome.browsingData.settings is not available`,details:`The browsingData API appears to be partially available. Check manifest permissions.`}:{available:!1,message:`chrome.browsingData API is not defined`,details:`This extension needs the "browsingData" permission in its manifest.json`}}catch(e){return{available:!1,message:`Failed to access chrome.browsingData API`,details:e instanceof Error?e.message:`Unknown error occurred`}}}registerTools(){this.shouldRegisterTool(`remove`)&&this.registerRemove(),this.shouldRegisterTool(`removeAppcache`)&&this.registerRemoveAppcache(),this.shouldRegisterTool(`removeCache`)&&this.registerRemoveCache(),this.shouldRegisterTool(`removeCacheStorage`)&&this.registerRemoveCacheStorage(),this.shouldRegisterTool(`removeCookies`)&&this.registerRemoveCookies(),this.shouldRegisterTool(`removeDownloads`)&&this.registerRemoveDownloads(),this.shouldRegisterTool(`removeFileSystems`)&&this.registerRemoveFileSystems(),this.shouldRegisterTool(`removeFormData`)&&this.registerRemoveFormData(),this.shouldRegisterTool(`removeHistory`)&&this.registerRemoveHistory(),this.shouldRegisterTool(`removeIndexedDB`)&&this.registerRemoveIndexedDB(),this.shouldRegisterTool(`removeLocalStorage`)&&this.registerRemoveLocalStorage(),this.shouldRegisterTool(`removePasswords`)&&this.registerRemovePasswords(),this.shouldRegisterTool(`removeServiceWorkers`)&&this.registerRemoveServiceWorkers(),this.shouldRegisterTool(`removeWebSQL`)&&this.registerRemoveWebSQL(),this.shouldRegisterTool(`settings`)&&this.registerSettings()}registerRemove(){this.server.registerTool(`extension_tool_remove_browsing_data`,{description:`Remove various types of browsing data from the user's profile`,inputSchema:{since:e.number().optional().describe(`Remove data accumulated on or after this date (milliseconds since epoch)`),origins:e.array(e.string()).optional().describe(`Only remove data for these origins (cookies, storage, cache only)`),excludeOrigins:e.array(e.string()).optional().describe(`Exclude data for these origins from deletion`),originTypes:e.object({unprotectedWeb:e.boolean().optional(),protectedWeb:e.boolean().optional(),extension:e.boolean().optional()}).optional().describe(`Types of origins to clear`),appcache:e.boolean().optional().describe(`Remove websites' appcaches`),cache:e.boolean().optional().describe(`Remove browser cache`),cacheStorage:e.boolean().optional().describe(`Remove cache storage`),cookies:e.boolean().optional().describe(`Remove cookies`),downloads:e.boolean().optional().describe(`Remove download list`),fileSystems:e.boolean().optional().describe(`Remove websites' file systems`),formData:e.boolean().optional().describe(`Remove stored form data`),history:e.boolean().optional().describe(`Remove browser history`),indexedDB:e.boolean().optional().describe(`Remove IndexedDB data`),localStorage:e.boolean().optional().describe(`Remove local storage data`),passwords:e.boolean().optional().describe(`Remove stored passwords`),serviceWorkers:e.boolean().optional().describe(`Remove service workers`),webSQL:e.boolean().optional().describe(`Remove WebSQL data`)}},async({since:e,origins:t,excludeOrigins:n,originTypes:r,appcache:i,cache:a,cacheStorage:o,cookies:s,downloads:c,fileSystems:l,formData:u,history:d,indexedDB:f,localStorage:p,passwords:m,serviceWorkers:h,webSQL:g})=>{try{let _={};e!==void 0&&(_.since=e),t!==void 0&&(_.origins=t),n!==void 0&&(_.excludeOrigins=n),r!==void 0&&(_.originTypes=r);let v={};return i!==void 0&&(v.appcache=i),a!==void 0&&(v.cache=a),o!==void 0&&(v.cacheStorage=o),s!==void 0&&(v.cookies=s),c!==void 0&&(v.downloads=c),l!==void 0&&(v.fileSystems=l),u!==void 0&&(v.formData=u),d!==void 0&&(v.history=d),f!==void 0&&(v.indexedDB=f),p!==void 0&&(v.localStorage=p),m!==void 0&&(v.passwords=m),h!==void 0&&(v.serviceWorkers=h),g!==void 0&&(v.webSQL=g),await new Promise((e,t)=>{chrome.browsingData.remove(_,v,()=>{chrome.runtime.lastError?t(Error(chrome.runtime.lastError.message)):e()})}),this.formatSuccess(`Browsing data removed successfully`,{options:_,dataTypes:Object.keys(v).filter(e=>v[e])})}catch(e){return this.formatError(e)}})}registerRemoveAppcache(){this.server.registerTool(`extension_tool_remove_appcache`,{description:`Remove websites' appcache data`,inputSchema:{since:e.number().optional().describe(`Remove data accumulated on or after this date (milliseconds since epoch)`),origins:e.array(e.string()).optional().describe(`Only remove data for these origins`),excludeOrigins:e.array(e.string()).optional().describe(`Exclude data for these origins from deletion`),originTypes:e.object({unprotectedWeb:e.boolean().optional(),protectedWeb:e.boolean().optional(),extension:e.boolean().optional()}).optional().describe(`Types of origins to clear`)}},async({since:e,origins:t,excludeOrigins:n,originTypes:r})=>{try{let i={};return e!==void 0&&(i.since=e),t!==void 0&&(i.origins=t),n!==void 0&&(i.excludeOrigins=n),r!==void 0&&(i.originTypes=r),await new Promise((e,t)=>{chrome.browsingData.removeAppcache(i,()=>{chrome.runtime.lastError?t(Error(chrome.runtime.lastError.message)):e()})}),this.formatSuccess(`Appcache data removed successfully`,{options:i})}catch(e){return this.formatError(e)}})}registerRemoveCache(){this.server.registerTool(`extension_tool_remove_cache`,{description:`Remove browser cache`,inputSchema:{since:e.number().optional().describe(`Remove data accumulated on or after this date (milliseconds since epoch)`),origins:e.array(e.string()).optional().describe(`Only remove data for these origins`),excludeOrigins:e.array(e.string()).optional().describe(`Exclude data for these origins from deletion`),originTypes:e.object({unprotectedWeb:e.boolean().optional(),protectedWeb:e.boolean().optional(),extension:e.boolean().optional()}).optional().describe(`Types of origins to clear`)}},async({since:e,origins:t,excludeOrigins:n,originTypes:r})=>{try{let i={};return e!==void 0&&(i.since=e),t!==void 0&&(i.origins=t),n!==void 0&&(i.excludeOrigins=n),r!==void 0&&(i.originTypes=r),await new Promise((e,t)=>{chrome.browsingData.removeCache(i,()=>{chrome.runtime.lastError?t(Error(chrome.runtime.lastError.message)):e()})}),this.formatSuccess(`Cache removed successfully`,{options:i})}catch(e){return this.formatError(e)}})}registerRemoveCacheStorage(){this.server.registerTool(`extension_tool_remove_cache_storage`,{description:`Remove websites' cache storage data`,inputSchema:{since:e.number().optional().describe(`Remove data accumulated on or after this date (milliseconds since epoch)`),origins:e.array(e.string()).optional().describe(`Only remove data for these origins`),excludeOrigins:e.array(e.string()).optional().describe(`Exclude data for these origins from deletion`),originTypes:e.object({unprotectedWeb:e.boolean().optional(),protectedWeb:e.boolean().optional(),extension:e.boolean().optional()}).optional().describe(`Types of origins to clear`)}},async({since:e,origins:t,excludeOrigins:n,originTypes:r})=>{try{let i={};return e!==void 0&&(i.since=e),t!==void 0&&(i.origins=t),n!==void 0&&(i.excludeOrigins=n),r!==void 0&&(i.originTypes=r),await new Promise((e,t)=>{chrome.browsingData.removeCacheStorage(i,()=>{chrome.runtime.lastError?t(Error(chrome.runtime.lastError.message)):e()})}),this.formatSuccess(`Cache storage removed successfully`,{options:i})}catch(e){return this.formatError(e)}})}registerRemoveCookies(){this.server.registerTool(`extension_tool_remove_cookies`,{description:`Remove browser cookies and server-bound certificates`,inputSchema:{since:e.number().optional().describe(`Remove data accumulated on or after this date (milliseconds since epoch)`),origins:e.array(e.string()).optional().describe(`Only remove data for these origins`),excludeOrigins:e.array(e.string()).optional().describe(`Exclude data for these origins from deletion`),originTypes:e.object({unprotectedWeb:e.boolean().optional(),protectedWeb:e.boolean().optional(),extension:e.boolean().optional()}).optional().describe(`Types of origins to clear`)}},async({since:e,origins:t,excludeOrigins:n,originTypes:r})=>{try{let i={};return e!==void 0&&(i.since=e),t!==void 0&&(i.origins=t),n!==void 0&&(i.excludeOrigins=n),r!==void 0&&(i.originTypes=r),await new Promise((e,t)=>{chrome.browsingData.removeCookies(i,()=>{chrome.runtime.lastError?t(Error(chrome.runtime.lastError.message)):e()})}),this.formatSuccess(`Cookies removed successfully`,{options:i})}catch(e){return this.formatError(e)}})}registerRemoveDownloads(){this.server.registerTool(`extension_tool_remove_downloads`,{description:`Remove browser download list (not the downloaded files themselves)`,inputSchema:{since:e.number().optional().describe(`Remove data accumulated on or after this date (milliseconds since epoch)`),originTypes:e.object({unprotectedWeb:e.boolean().optional(),protectedWeb:e.boolean().optional(),extension:e.boolean().optional()}).optional().describe(`Types of origins to clear`)}},async({since:e,originTypes:t})=>{try{let n={};return e!==void 0&&(n.since=e),t!==void 0&&(n.originTypes=t),await new Promise((e,t)=>{chrome.browsingData.removeDownloads(n,()=>{chrome.runtime.lastError?t(Error(chrome.runtime.lastError.message)):e()})}),this.formatSuccess(`Download list removed successfully`,{options:n})}catch(e){return this.formatError(e)}})}registerRemoveFileSystems(){this.server.registerTool(`extension_tool_remove_file_systems`,{description:`Remove websites' file system data`,inputSchema:{since:e.number().optional().describe(`Remove data accumulated on or after this date (milliseconds since epoch)`),origins:e.array(e.string()).optional().describe(`Only remove data for these origins`),excludeOrigins:e.array(e.string()).optional().describe(`Exclude data for these origins from deletion`),originTypes:e.object({unprotectedWeb:e.boolean().optional(),protectedWeb:e.boolean().optional(),extension:e.boolean().optional()}).optional().describe(`Types of origins to clear`)}},async({since:e,origins:t,excludeOrigins:n,originTypes:r})=>{try{let i={};return e!==void 0&&(i.since=e),t!==void 0&&(i.origins=t),n!==void 0&&(i.excludeOrigins=n),r!==void 0&&(i.originTypes=r),await new Promise((e,t)=>{chrome.browsingData.removeFileSystems(i,()=>{chrome.runtime.lastError?t(Error(chrome.runtime.lastError.message)):e()})}),this.formatSuccess(`File systems removed successfully`,{options:i})}catch(e){return this.formatError(e)}})}registerRemoveFormData(){this.server.registerTool(`extension_tool_remove_form_data`,{description:`Remove browser stored form data (autofill)`,inputSchema:{since:e.number().optional().describe(`Remove data accumulated on or after this date (milliseconds since epoch)`),originTypes:e.object({unprotectedWeb:e.boolean().optional(),protectedWeb:e.boolean().optional(),extension:e.boolean().optional()}).optional().describe(`Types of origins to clear`)}},async({since:e,originTypes:t})=>{try{let n={};return e!==void 0&&(n.since=e),t!==void 0&&(n.originTypes=t),await new Promise((e,t)=>{chrome.browsingData.removeFormData(n,()=>{chrome.runtime.lastError?t(Error(chrome.runtime.lastError.message)):e()})}),this.formatSuccess(`Form data removed successfully`,{options:n})}catch(e){return this.formatError(e)}})}registerRemoveHistory(){this.server.registerTool(`extension_tool_remove_history`,{description:`Remove browser history`,inputSchema:{since:e.number().optional().describe(`Remove data accumulated on or after this date (milliseconds since epoch)`),originTypes:e.object({unprotectedWeb:e.boolean().optional(),protectedWeb:e.boolean().optional(),extension:e.boolean().optional()}).optional().describe(`Types of origins to clear`)}},async({since:e,originTypes:t})=>{try{let n={};return e!==void 0&&(n.since=e),t!==void 0&&(n.originTypes=t),await new Promise((e,t)=>{chrome.browsingData.removeHistory(n,()=>{chrome.runtime.lastError?t(Error(chrome.runtime.lastError.message)):e()})}),this.formatSuccess(`History removed successfully`,{options:n})}catch(e){return this.formatError(e)}})}registerRemoveIndexedDB(){this.server.registerTool(`extension_tool_remove_indexed_db`,{description:`Remove websites' IndexedDB data`,inputSchema:{since:e.number().optional().describe(`Remove data accumulated on or after this date (milliseconds since epoch)`),origins:e.array(e.string()).optional().describe(`Only remove data for these origins`),excludeOrigins:e.array(e.string()).optional().describe(`Exclude data for these origins from deletion`),originTypes:e.object({unprotectedWeb:e.boolean().optional(),protectedWeb:e.boolean().optional(),extension:e.boolean().optional()}).optional().describe(`Types of origins to clear`)}},async({since:e,origins:t,excludeOrigins:n,originTypes:r})=>{try{let i={};return e!==void 0&&(i.since=e),t!==void 0&&(i.origins=t),n!==void 0&&(i.excludeOrigins=n),r!==void 0&&(i.originTypes=r),await new Promise((e,t)=>{chrome.browsingData.removeIndexedDB(i,()=>{chrome.runtime.lastError?t(Error(chrome.runtime.lastError.message)):e()})}),this.formatSuccess(`IndexedDB data removed successfully`,{options:i})}catch(e){return this.formatError(e)}})}registerRemoveLocalStorage(){this.server.registerTool(`extension_tool_remove_local_storage`,{description:`Remove websites' local storage data`,inputSchema:{since:e.number().optional().describe(`Remove data accumulated on or after this date (milliseconds since epoch)`),origins:e.array(e.string()).optional().describe(`Only remove data for these origins`),excludeOrigins:e.array(e.string()).optional().describe(`Exclude data for these origins from deletion`),originTypes:e.object({unprotectedWeb:e.boolean().optional(),protectedWeb:e.boolean().optional(),extension:e.boolean().optional()}).optional().describe(`Types of origins to clear`)}},async({since:e,origins:t,excludeOrigins:n,originTypes:r})=>{try{let i={};return e!==void 0&&(i.since=e),t!==void 0&&(i.origins=t),n!==void 0&&(i.excludeOrigins=n),r!==void 0&&(i.originTypes=r),await new Promise((e,t)=>{chrome.browsingData.removeLocalStorage(i,()=>{chrome.runtime.lastError?t(Error(chrome.runtime.lastError.message)):e()})}),this.formatSuccess(`Local storage removed successfully`,{options:i})}catch(e){return this.formatError(e)}})}registerRemovePasswords(){this.server.registerTool(`extension_tool_remove_passwords`,{description:`Remove browser stored passwords`,inputSchema:{since:e.number().optional().describe(`Remove data accumulated on or after this date (milliseconds since epoch)`),originTypes:e.object({unprotectedWeb:e.boolean().optional(),protectedWeb:e.boolean().optional(),extension:e.boolean().optional()}).optional().describe(`Types of origins to clear`)}},async({since:e,originTypes:t})=>{try{let n={};return e!==void 0&&(n.since=e),t!==void 0&&(n.originTypes=t),await new Promise((e,t)=>{chrome.browsingData.removePasswords(n,()=>{chrome.runtime.lastError?t(Error(chrome.runtime.lastError.message)):e()})}),this.formatSuccess(`Passwords removed successfully`,{options:n})}catch(e){return this.formatError(e)}})}registerRemoveServiceWorkers(){this.server.registerTool(`extension_tool_remove_service_workers`,{description:`Remove websites' service workers`,inputSchema:{since:e.number().optional().describe(`Remove data accumulated on or after this date (milliseconds since epoch)`),origins:e.array(e.string()).optional().describe(`Only remove data for these origins`),excludeOrigins:e.array(e.string()).optional().describe(`Exclude data for these origins from deletion`),originTypes:e.object({unprotectedWeb:e.boolean().optional(),protectedWeb:e.boolean().optional(),extension:e.boolean().optional()}).optional().describe(`Types of origins to clear`)}},async({since:e,origins:t,excludeOrigins:n,originTypes:r})=>{try{let i={};return e!==void 0&&(i.since=e),t!==void 0&&(i.origins=t),n!==void 0&&(i.excludeOrigins=n),r!==void 0&&(i.originTypes=r),await new Promise((e,t)=>{chrome.browsingData.removeServiceWorkers(i,()=>{chrome.runtime.lastError?t(Error(chrome.runtime.lastError.message)):e()})}),this.formatSuccess(`Service workers removed successfully`,{options:i})}catch(e){return this.formatError(e)}})}registerRemoveWebSQL(){this.server.registerTool(`extension_tool_remove_web_sql`,{description:`Remove websites' WebSQL data`,inputSchema:{since:e.number().optional().describe(`Remove data accumulated on or after this date (milliseconds since epoch)`),origins:e.array(e.string()).optional().describe(`Only remove data for these origins`),excludeOrigins:e.array(e.string()).optional().describe(`Exclude data for these origins from deletion`),originTypes:e.object({unprotectedWeb:e.boolean().optional(),protectedWeb:e.boolean().optional(),extension:e.boolean().optional()}).optional().describe(`Types of origins to clear`)}},async({since:e,origins:t,excludeOrigins:n,originTypes:r})=>{try{let i={};return e!==void 0&&(i.since=e),t!==void 0&&(i.origins=t),n!==void 0&&(i.excludeOrigins=n),r!==void 0&&(i.originTypes=r),await new Promise((e,t)=>{chrome.browsingData.removeWebSQL(i,()=>{chrome.runtime.lastError?t(Error(chrome.runtime.lastError.message)):e()})}),this.formatSuccess(`WebSQL data removed successfully`,{options:i})}catch(e){return this.formatError(e)}})}registerSettings(){this.server.registerTool(`extension_tool_get_browsing_data_settings`,{description:`Get current browsing data settings from the Clear browsing data UI`,inputSchema:{}},async()=>{try{let e=await new Promise((e,t)=>{chrome.browsingData.settings(n=>{chrome.runtime.lastError?t(Error(chrome.runtime.lastError.message)):e(n)})});return this.formatJson({dataRemovalPermitted:e.dataRemovalPermitted,dataToRemove:e.dataToRemove,options:e.options})}catch(e){return this.formatError(e)}})}},d=class extends i{apiName=`CertificateProvider`;constructor(e,t={}){super(e,t)}checkAvailability(){try{return chrome.certificateProvider?typeof chrome.certificateProvider.setCertificates==`function`?{available:!0,message:`CertificateProvider API is fully available`}:{available:!1,message:`chrome.certificateProvider.setCertificates is not available`,details:`The certificateProvider API appears to be partially available. Check manifest permissions and ensure running on ChromeOS.`}:{available:!1,message:`chrome.certificateProvider API is not defined`,details:`This extension needs the "certificateProvider" permission in its manifest.json and only works on ChromeOS`}}catch(e){return{available:!1,message:`Failed to access chrome.certificateProvider API`,details:e instanceof Error?e.message:`Unknown error occurred`}}}registerTools(){this.shouldRegisterTool(`setCertificates`)&&this.registerSetCertificates(),this.shouldRegisterTool(`reportSignature`)&&this.registerReportSignature(),this.shouldRegisterTool(`requestPin`)&&this.registerRequestPin(),this.shouldRegisterTool(`stopPinRequest`)&&this.registerStopPinRequest(),this.shouldRegisterTool(`onCertificatesUpdateRequested`)&&this.registerOnCertificatesUpdateRequested(),this.shouldRegisterTool(`onSignatureRequested`)&&this.registerOnSignatureRequested()}registerSetCertificates(){this.server.registerTool(`extension_tool_set_certificates`,{description:`Sets a list of certificates to use in the browser for TLS client authentication`,inputSchema:{certificatesRequestId:e.number().optional().describe(`Request ID when responding to onCertificatesUpdateRequested event`),clientCertificates:e.array(e.object({certificateChain:e.array(e.string()).describe(`Array of base64-encoded DER certificates, with client cert first`),supportedAlgorithms:e.array(e.string()).describe(`Supported signature algorithms for this certificate`)})).describe(`List of client certificates to provide`),error:e.enum([`GENERAL_ERROR`]).optional().describe(`Error that occurred while extracting certificates`)}},async({certificatesRequestId:e,clientCertificates:t,error:n})=>{try{let r={clientCertificates:t.map(e=>({certificateChain:e.certificateChain.map(e=>{let t=atob(e),n=new Uint8Array(t.length);for(let e=0;e<t.length;e++)n[e]=t.charCodeAt(e);return n.buffer}),supportedAlgorithms:e.supportedAlgorithms}))};return e!==void 0&&(r.certificatesRequestId=e),n!==void 0&&(r.error=n),await new Promise((e,t)=>{chrome.certificateProvider.setCertificates(r,()=>{chrome.runtime.lastError?t(Error(chrome.runtime.lastError.message)):e()})}),this.formatSuccess(`Certificates set successfully`,{certificateCount:t.length,requestId:e})}catch(e){return this.formatError(e)}})}registerReportSignature(){this.server.registerTool(`extension_tool_report_signature`,{description:`Reports the signature for a signing request from the browser`,inputSchema:{signRequestId:e.number().describe(`Request identifier from onSignatureRequested event`),signature:e.string().optional().describe(`Base64-encoded signature data, if successfully generated`),error:e.enum([`GENERAL_ERROR`]).optional().describe(`Error that occurred while generating the signature`)}},async({signRequestId:e,signature:t,error:n})=>{try{let r={signRequestId:e};if(t!==void 0){let e=atob(t),n=new Uint8Array(e.length);for(let t=0;t<e.length;t++)n[t]=e.charCodeAt(t);r.signature=n.buffer}return n!==void 0&&(r.error=n),await new Promise((e,t)=>{chrome.certificateProvider.reportSignature(r,()=>{chrome.runtime.lastError?t(Error(chrome.runtime.lastError.message)):e()})}),this.formatSuccess(`Signature reported successfully`,{signRequestId:e,hasSignature:t!==void 0,hasError:n!==void 0})}catch(e){return this.formatError(e)}})}registerRequestPin(){this.server.registerTool(`extension_tool_request_pin`,{description:`Requests PIN or PUK from the user for certificate operations`,inputSchema:{signRequestId:e.number().describe(`The ID from SignRequest`),requestType:e.enum([`PIN`,`PUK`]).optional().describe(`Type of code being requested (default: PIN)`),errorType:e.enum([`INVALID_PIN`,`INVALID_PUK`,`MAX_ATTEMPTS_EXCEEDED`,`UNKNOWN_ERROR`]).optional().describe(`Error from previous request to show to user`),attemptsLeft:e.number().optional().describe(`Number of attempts remaining for user information`)}},async({signRequestId:e,requestType:t,errorType:n,attemptsLeft:r})=>{try{let i={signRequestId:e};t!==void 0&&(i.requestType=t),n!==void 0&&(i.errorType=n),r!==void 0&&(i.attemptsLeft=r);let a=await new Promise((e,t)=>{chrome.certificateProvider.requestPin(i,n=>{chrome.runtime.lastError?t(Error(chrome.runtime.lastError.message)):e(n)})});return this.formatJson({signRequestId:e,userInput:a?.userInput||null,success:!!a?.userInput})}catch(e){return this.formatError(e)}})}registerStopPinRequest(){this.server.registerTool(`extension_tool_stop_pin_request`,{description:`Stops an ongoing PIN request flow`,inputSchema:{signRequestId:e.number().describe(`The ID from SignRequest`),errorType:e.enum([`INVALID_PIN`,`INVALID_PUK`,`MAX_ATTEMPTS_EXCEEDED`,`UNKNOWN_ERROR`]).optional().describe(`Error reason for stopping the flow`)}},async({signRequestId:e,errorType:t})=>{try{let n={signRequestId:e};return t!==void 0&&(n.errorType=t),await new Promise((e,t)=>{chrome.certificateProvider.stopPinRequest(n,()=>{chrome.runtime.lastError?t(Error(chrome.runtime.lastError.message)):e()})}),this.formatSuccess(`PIN request stopped successfully`,{signRequestId:e,errorType:t})}catch(e){return this.formatError(e)}})}registerOnCertificatesUpdateRequested(){this.server.registerTool(`extension_tool_listen_certificates_update_requested`,{description:`Sets up listener for certificate update requests from the browser`,inputSchema:{}},async()=>{try{return chrome.certificateProvider.onCertificatesUpdateRequested.hasListeners()&&chrome.certificateProvider.onCertificatesUpdateRequested.removeListener(this.handleCertificatesUpdateRequested),chrome.certificateProvider.onCertificatesUpdateRequested.addListener(this.handleCertificatesUpdateRequested),this.formatSuccess(`Certificate update request listener registered`,{event:`onCertificatesUpdateRequested`,hasListeners:chrome.certificateProvider.onCertificatesUpdateRequested.hasListeners()})}catch(e){return this.formatError(e)}})}registerOnSignatureRequested(){this.server.registerTool(`extension_tool_listen_signature_requested`,{description:`Sets up listener for signature requests from the browser`,inputSchema:{}},async()=>{try{return chrome.certificateProvider.onSignatureRequested.hasListeners()&&chrome.certificateProvider.onSignatureRequested.removeListener(this.handleSignatureRequested),chrome.certificateProvider.onSignatureRequested.addListener(this.handleSignatureRequested),this.formatSuccess(`Signature request listener registered`,{event:`onSignatureRequested`,hasListeners:chrome.certificateProvider.onSignatureRequested.hasListeners()})}catch(e){return this.formatError(e)}})}handleCertificatesUpdateRequested=e=>{console.log(`Certificate update requested:`,{certificatesRequestId:e.certificatesRequestId,timestamp:new Date().toISOString()})};handleSignatureRequested=e=>{let t=new Uint8Array(e.certificate),n=new Uint8Array(e.input);console.log(`Signature requested:`,{signRequestId:e.signRequestId,algorithm:e.algorithm,certificateLength:t.length,inputLength:n.length,timestamp:new Date().toISOString()})}},f=class extends i{apiName=`Commands`;constructor(e,t={}){super(e,t)}checkAvailability(){try{return chrome.commands?typeof chrome.commands.getAll==`function`?(chrome.commands.getAll(e=>{if(chrome.runtime.lastError)throw Error(chrome.runtime.lastError.message)}),{available:!0,message:`Commands API is fully available`}):{available:!1,message:`chrome.commands.getAll is not available`,details:`The commands API appears to be partially available. Check manifest permissions.`}:{available:!1,message:`chrome.commands API is not defined`,details:`This extension needs the "commands" permission in its manifest.json`}}catch(e){return{available:!1,message:`Failed to access chrome.commands API`,details:e instanceof Error?e.message:`Unknown error occurred`}}}registerTools(){this.shouldRegisterTool(`getAll`)&&this.registerGetAll()}registerGetAll(){this.server.registerTool(`extension_tool_get_all_commands`,{description:`Get all registered extension commands and their keyboard shortcuts`,inputSchema:{}},async()=>{try{let e=await new Promise((e,t)=>{chrome.commands.getAll(n=>{chrome.runtime.lastError?t(Error(chrome.runtime.lastError.message)):e(n)})});return this.formatJson({count:e.length,commands:e.map(e=>({name:e.name,description:e.description,shortcut:e.shortcut||`Not assigned`,isActive:!!e.shortcut}))})}catch(e){return this.formatError(e)}})}},p=class extends i{apiName=`ContentSettings`;constructor(e,t={}){super(e,t)}checkAvailability(){try{return chrome.contentSettings?!chrome.contentSettings.cookies||typeof chrome.contentSettings.cookies.get!=`function`?{available:!1,message:`chrome.contentSettings.co