@pokutuna/mcp-chrome-tabs 0.1.4 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,78 +1,121 @@
1
1
  # @pokutuna/mcp-chrome-tabs
2
2
 
3
- > [!NOTE]
4
- > **macOS only** - This MCP server uses AppleScript and only works on macOS.
3
+ [![npm version](https://badge.fury.io/js/@pokutuna%2Fmcp-chrome-tabs.svg)](https://badge.fury.io/js/@pokutuna%2Fmcp-chrome-tabs)
5
4
 
6
5
  Model Context Protocol (MCP) server that provides direct access to your browser's open tabs content. No additional fetching or authentication required - simply access what you're already viewing.
7
6
 
8
- ## Features
7
+ ## Key Features
8
+
9
+ - **Direct browser tab access** - No web scraping needed, reads content from already open tabs
10
+ - **Content optimized for AI** - Automatic readability processing and markdown conversion to reduce token usage
11
+ - **Active tab shortcut** - Instant access to currently focused tab without specifying IDs
12
+ - **MCP listChanged notifications** - Follows MCP protocol to notify tab changes (support is limited in most clients)
9
13
 
10
- - **Access browser tabs** - Direct access to content from tabs currently open in your browser
11
- - **Active tab shortcut** - Quick reference to currently active tab without specifying tab ID
12
- - **URL opening** - Open AI-provided URLs directly in new browser tabs
13
- - **Tools & Resources** - Dual interface supporting both MCP tools and resources with automatic refresh notifications when tab collection changes
14
+ ## Requirements
15
+
16
+ > [!IMPORTANT]
17
+ > **macOS only** - This MCP server uses AppleScript and only works on macOS.
14
18
 
15
- ## Installation
19
+ - **Node.js** 20 or newer
20
+ - **MCP Client** such as Claude Desktop, Claude Code, or any MCP-compatible client
21
+ - **macOS** only (uses AppleScript for browser automation)
16
22
 
17
- > [!IMPORTANT]
18
- > **Requirements**: Enable "Allow JavaScript from Apple Events" in Chrome
19
- > - (en) **View** > **Developer** > **Allow JavaScript from Apple Events**
20
- > - (ja) **表示** > **開発 / 管理** > **Apple Events からのJavaScript を許可**
23
+ ## Getting Started
21
24
 
22
- ### Manual Configuration
23
- Add to your MCP configuration file (e.g., `claude_desktop_config.json`):
25
+ First, enable "Allow JavaScript from Apple Events" in Chrome:
26
+
27
+ - (en) **View** > **Developer** > **Allow JavaScript from Apple Events**
28
+ - (ja) **表示** > **開発 / 管理** > **Apple Events からのJavaScript を許可**
29
+
30
+ Standard config works in most MCP clients (e.g., `.claude.json`, `.mcp.json`):
24
31
 
25
32
  ```json
26
33
  {
27
34
  "mcpServers": {
28
35
  "chrome-tabs": {
29
36
  "command": "npx",
30
- "args": ["-y", "@pokutuna/mcp-chrome-tabs"]
37
+ "args": ["-y", "@pokutuna/mcp-chrome-tabs@latest"]
31
38
  }
32
39
  }
33
40
  }
34
41
  ```
35
42
 
36
- ### For Claude Code
43
+ Or for Claude Code:
44
+
37
45
  ```bash
38
- claude mcp add -s user chrome-tabs -- npx -y @pokutuna/mcp-chrome-tabs
46
+ claude mcp add -s user chrome-tabs -- npx -y @pokutuna/mcp-chrome-tabs@latest
39
47
  ```
40
48
 
41
49
  ### Command Line Options
50
+
42
51
  The server accepts optional command line arguments for configuration:
43
52
 
44
53
  - `--application-name` - Application name to control (default: "Google Chrome")
45
54
  - `--exclude-hosts` - Comma-separated list of domains to exclude from tab listing and content access
46
55
  - `--check-interval` - Interval in milliseconds to check for tab changes and notify clients (default: 3000, set to 0 to disable)
47
56
 
57
+ #### Experimental Safari Support
58
+
59
+ Limited Safari support is available. Note that Safari lacks unique tab IDs, making it sensitive to tab order changes during execution:
60
+
61
+ ```bash
62
+ npx @pokutuna/mcp-chrome-tabs --application-name=Safari --experimental-browser=safari
63
+ ```
64
+
65
+ ## MCP Features
66
+
67
+ ### Tools
48
68
 
49
- ## Tools
69
+ <details>
70
+ <summary><code>list_tabs</code></summary>
50
71
 
51
- ### `list_tabs`
52
72
  List all open tabs in the user's browser with their titles, URLs, and tab references.
73
+
53
74
  - Returns: Markdown formatted list of tabs with tab IDs for reference
54
75
 
55
- ### `read_tab_content`
76
+ </details>
77
+
78
+ <details>
79
+ <summary><code>read_tab_content</code></summary>
80
+
56
81
  Get readable content from a tab in the user's browser.
82
+
57
83
  - `id` (optional): Tab reference from `list_tabs` output (e.g., `ID:12345:67890`)
58
84
  - If `id` is omitted, uses the currently active tab
59
85
  - Returns: Clean, readable content extracted using Mozilla Readability
60
86
 
61
- ### `open_in_new_tab`
87
+ </details>
88
+
89
+ <details>
90
+ <summary><code>open_in_new_tab</code></summary>
91
+
62
92
  Open a URL in a new tab to present content or enable user interaction with webpages.
93
+
63
94
  - `url` (required): URL to open in the browser
64
95
 
65
- ## Resources
96
+ </details>
97
+
98
+ ### Resources
99
+
100
+ <details>
101
+ <summary><code>tab://current</code></summary>
66
102
 
67
- ### `tab://current`
68
103
  Resource representing the content of the currently active tab.
104
+
69
105
  - **URI**: `tab://current`
70
106
  - **MIME type**: `text/markdown`
71
107
  - **Content**: Real-time content of the active browser tab
72
108
 
73
- ### `tab://{windowId}/{tabId}`
109
+ </details>
110
+
111
+ <details>
112
+ <summary><code>tab://{windowId}/{tabId}</code></summary>
113
+
74
114
  Resource template for accessing specific tabs.
115
+
75
116
  - **URI pattern**: `tab://{windowId}/{tabId}`
76
117
  - **MIME type**: `text/markdown`
77
118
  - **Content**: Content of the specified tab
78
119
  - Resources are dynamically generated based on currently open tabs
120
+
121
+ </details>
@@ -0,0 +1,20 @@
1
+ export type Browser = "chrome" | "safari";
2
+ export type TabRef = {
3
+ windowId: string;
4
+ tabId: string;
5
+ };
6
+ export type Tab = TabRef & {
7
+ title: string;
8
+ url: string;
9
+ };
10
+ export type TabContent = {
11
+ title: string;
12
+ url: string;
13
+ content: string;
14
+ };
15
+ export type BrowserInterface = {
16
+ getTabList(applicationName: string): Promise<Tab[]>;
17
+ getPageContent(applicationName: string, tab?: TabRef | null): Promise<TabContent>;
18
+ openURL(applicationName: string, url: string): Promise<void>;
19
+ };
20
+ export declare function getInterface(browser: Browser): BrowserInterface;
@@ -0,0 +1,8 @@
1
+ import { chromeBrowser } from "./chrome.js";
2
+ import { safariBrowser } from "./safari.js";
3
+ export function getInterface(browser) {
4
+ if (browser === "safari") {
5
+ return safariBrowser;
6
+ }
7
+ return chromeBrowser;
8
+ }
@@ -0,0 +1,2 @@
1
+ import type { BrowserInterface } from "./browser.js";
2
+ export declare const chromeBrowser: BrowserInterface;
@@ -1,18 +1,9 @@
1
- import { execFile } from "child_process";
2
1
  import { JSDOM } from "jsdom";
3
2
  import { Readability } from "@mozilla/readability";
4
- import { promisify } from "util";
5
3
  import TurndownService from "turndown";
6
4
  import turndownPluginGfm from "turndown-plugin-gfm";
7
- const execFileAsync = promisify(execFile);
8
- function escapeAppleScript(str) {
9
- return str
10
- .replace(/\\/g, "\\\\")
11
- .replace(/"/g, '\\"')
12
- .replace(/\n/g, "\\n")
13
- .replace(/\r/g, "\\r");
14
- }
15
- export async function getChromeTabList(applicationName) {
5
+ import { escapeAppleScript, executeAppleScript, separator, } from "./osascript.js";
6
+ async function getChromeTabList(applicationName) {
16
7
  const sep = separator();
17
8
  const appleScript = `
18
9
  tell application "${applicationName}"
@@ -45,7 +36,7 @@ export async function getChromeTabList(applicationName) {
45
36
  }
46
37
  return tabs;
47
38
  }
48
- export async function getPageContent(applicationName, tab) {
39
+ async function getPageContent(applicationName, tab) {
49
40
  const sep = separator();
50
41
  const inner = `
51
42
  set tabTitle to title
@@ -114,7 +105,7 @@ export async function getPageContent(applicationName, tab) {
114
105
  content: md,
115
106
  };
116
107
  }
117
- export async function openURL(applicationName, url) {
108
+ async function openURL(applicationName, url) {
118
109
  const escapedUrl = escapeAppleScript(url);
119
110
  const appleScript = `
120
111
  tell application "${applicationName}"
@@ -123,34 +114,8 @@ export async function openURL(applicationName, url) {
123
114
  `;
124
115
  await executeAppleScript(appleScript);
125
116
  }
126
- async function retry(fn, options) {
127
- const { maxRetries = 2, retryDelay = 1000 } = options || {};
128
- for (let attempt = 0; attempt <= maxRetries; attempt++) {
129
- try {
130
- return await fn();
131
- }
132
- catch (error) {
133
- if (attempt === maxRetries) {
134
- console.error("retry failed after maximum attempts:", error);
135
- throw error;
136
- }
137
- await new Promise((resolve) => setTimeout(resolve, retryDelay * Math.pow(2, attempt)));
138
- }
139
- }
140
- throw new Error("unreachable");
141
- }
142
- async function executeAppleScript(script) {
143
- return retry(async () => {
144
- const { stdout, stderr } = await execFileAsync("osascript", ["-e", script], {
145
- timeout: 5 * 1000,
146
- maxBuffer: 5 * 1024 * 1024, // 5MB
147
- });
148
- if (stderr)
149
- console.error("AppleScript stderr:", stderr);
150
- return stdout.trim();
151
- });
152
- }
153
- function separator() {
154
- const uniqueId = Math.random().toString(36).substring(2);
155
- return `<|SEP:${uniqueId}|>`;
156
- }
117
+ export const chromeBrowser = {
118
+ getTabList: getChromeTabList,
119
+ getPageContent,
120
+ openURL,
121
+ };
@@ -0,0 +1,7 @@
1
+ export declare function escapeAppleScript(str: string): string;
2
+ export declare function retry<T>(fn: () => Promise<T>, options?: {
3
+ maxRetries?: number;
4
+ retryDelay?: number;
5
+ }): Promise<T>;
6
+ export declare function executeAppleScript(script: string): Promise<string>;
7
+ export declare function separator(): string;
@@ -0,0 +1,41 @@
1
+ import { execFile } from "child_process";
2
+ import { promisify } from "util";
3
+ const execFileAsync = promisify(execFile);
4
+ export function escapeAppleScript(str) {
5
+ return str
6
+ .replace(/\\/g, "\\\\")
7
+ .replace(/"/g, '\\"')
8
+ .replace(/\n/g, "\\n")
9
+ .replace(/\r/g, "\\r");
10
+ }
11
+ export async function retry(fn, options) {
12
+ const { maxRetries = 2, retryDelay = 1000 } = options || {};
13
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
14
+ try {
15
+ return await fn();
16
+ }
17
+ catch (error) {
18
+ if (attempt === maxRetries) {
19
+ console.error("retry failed after maximum attempts:", error);
20
+ throw error;
21
+ }
22
+ await new Promise((resolve) => setTimeout(resolve, retryDelay * Math.pow(2, attempt)));
23
+ }
24
+ }
25
+ throw new Error("unreachable");
26
+ }
27
+ export async function executeAppleScript(script) {
28
+ return retry(async () => {
29
+ const { stdout, stderr } = await execFileAsync("osascript", ["-e", script], {
30
+ timeout: 5 * 1000,
31
+ maxBuffer: 5 * 1024 * 1024, // 5MB
32
+ });
33
+ if (stderr)
34
+ console.error("AppleScript stderr:", stderr);
35
+ return stdout.trim();
36
+ });
37
+ }
38
+ export function separator() {
39
+ const uniqueId = Math.random().toString(36).substring(2);
40
+ return `<|SEP:${uniqueId}|>`;
41
+ }
@@ -0,0 +1,2 @@
1
+ import type { BrowserInterface } from "./browser.js";
2
+ export declare const safariBrowser: BrowserInterface;
@@ -0,0 +1,121 @@
1
+ import { JSDOM } from "jsdom";
2
+ import { Readability } from "@mozilla/readability";
3
+ import TurndownService from "turndown";
4
+ import turndownPluginGfm from "turndown-plugin-gfm";
5
+ import { escapeAppleScript, executeAppleScript, separator, } from "./osascript.js";
6
+ async function getSafariTabList(applicationName) {
7
+ const sep = separator();
8
+ const appleScript = `
9
+ tell application "${applicationName}"
10
+ set output to ""
11
+ repeat with aWindow in (every window)
12
+ set windowId to id of aWindow
13
+ repeat with aTab in (every tab of aWindow)
14
+ set tabIndex to index of aTab
15
+ set tabTitle to name of aTab
16
+ set tabURL to URL of aTab
17
+ set output to output & windowId & "${sep}" & tabIndex & "${sep}" & tabTitle & "${sep}" & tabURL & "\\n"
18
+ end repeat
19
+ end repeat
20
+ return output
21
+ end tell
22
+ `;
23
+ const result = await executeAppleScript(appleScript);
24
+ const lines = result.trim().split("\n");
25
+ const tabs = [];
26
+ for (const line of lines) {
27
+ const [wId, tId, title, url] = line.split(sep);
28
+ if (!/^https?:\/\//.test(url))
29
+ continue;
30
+ // Note: Safari tab IDs are volatile indices that change when tabs are closed
31
+ // Unlike Chrome, Safari doesn't provide stable unique tab identifiers
32
+ tabs.push({
33
+ windowId: wId,
34
+ tabId: tId,
35
+ title: title.trim(),
36
+ url: url.trim(),
37
+ });
38
+ }
39
+ return tabs;
40
+ }
41
+ async function getPageContent(applicationName, tab) {
42
+ const sep = separator();
43
+ const inner = `
44
+ set tabTitle to name
45
+ set tabURL to URL
46
+ set tabContent to do JavaScript "document.documentElement.outerHTML"
47
+ return tabTitle & "${sep}" & tabURL & "${sep}" & tabContent
48
+ `;
49
+ const appleScript = tab
50
+ ? `
51
+ try
52
+ tell application "${applicationName}"
53
+ tell window id "${tab.windowId}"
54
+ tell tab ${tab.tabId}
55
+ with timeout of 3 seconds
56
+ ${inner}
57
+ end timeout
58
+ end tell
59
+ end tell
60
+ end tell
61
+ on error errMsg
62
+ return "ERROR" & "${sep}" & errMsg
63
+ end try
64
+ `
65
+ : `
66
+ try
67
+ tell application "${applicationName}"
68
+ tell front window
69
+ set t to current tab
70
+ if URL of t is not "about:blank" then
71
+ tell t
72
+ with timeout of 3 seconds
73
+ ${inner}
74
+ end timeout
75
+ end tell
76
+ else
77
+ error "No active tab found"
78
+ end if
79
+ end tell
80
+ end tell
81
+ on error errMsg
82
+ return "ERROR" & "${sep}" & errMsg
83
+ end try
84
+ `;
85
+ const result = await executeAppleScript(appleScript);
86
+ if (result.startsWith(`ERROR${sep}`))
87
+ throw new Error(result.split(sep)[1]);
88
+ const parts = result.split(sep).map((part) => part.trim());
89
+ if (parts.length < 3)
90
+ throw new Error("Failed to read the tab content");
91
+ const [title, url, content] = parts;
92
+ const dom = new JSDOM(content, { url });
93
+ const reader = new Readability(dom.window.document, {
94
+ charThreshold: 10,
95
+ });
96
+ const article = reader.parse();
97
+ if (!article?.content)
98
+ throw new Error("Failed to parse the page content");
99
+ const turndownService = new TurndownService();
100
+ turndownService.use(turndownPluginGfm.gfm);
101
+ const md = turndownService.turndown(article.content);
102
+ return {
103
+ title,
104
+ url,
105
+ content: md,
106
+ };
107
+ }
108
+ async function openURL(applicationName, url) {
109
+ const escapedUrl = escapeAppleScript(url);
110
+ const appleScript = `
111
+ tell application "${applicationName}"
112
+ open location "${escapedUrl}"
113
+ end tell
114
+ `;
115
+ await executeAppleScript(appleScript);
116
+ }
117
+ export const safariBrowser = {
118
+ getTabList: getSafariTabList,
119
+ getPageContent,
120
+ openURL,
121
+ };
package/dist/cli.js CHANGED
@@ -10,26 +10,31 @@ USAGE:
10
10
  mcp-chrome-tabs [OPTIONS]
11
11
 
12
12
  OPTIONS:
13
- --application-name=<name> Application name to control via AppleScript
14
- (default: "Google Chrome")
15
- Example: "Google Chrome Canary"
13
+ --application-name=<name> Application name to control via AppleScript
14
+ (default: "Google Chrome")
15
+ Example: "Google Chrome Canary"
16
16
 
17
- --exclude-hosts=<hosts> Comma-separated list of hosts to exclude
18
- (default: "")
19
- Example: "github.com,example.com,test.com"
17
+ --exclude-hosts=<hosts> Comma-separated list of hosts to exclude
18
+ (default: "")
19
+ Example: "github.com,example.com,test.com"
20
20
 
21
- --check-interval=<ms> Interval for checking browser tabs in milliseconds
22
- (default: 3000, set to 0 to disable)
23
- Example: 1000
21
+ --check-interval=<ms> Interval for checking browser tabs in milliseconds
22
+ (default: 3000, set to 0 to disable)
23
+ Example: 1000
24
24
 
25
- --help Show this help message
25
+ --experimental-browser=<b> Browser implementation to use
26
+ (default: "chrome")
27
+ Options: "chrome", "safari"
28
+
29
+ --help Show this help message
26
30
 
27
31
 
28
32
  REQUIREMENTS:
29
- Chrome must allow JavaScript from Apple Events:
30
- 1. Open Chrome
31
- 2. Go to View > Developer > Allow JavaScript from Apple Events
32
- 3. Enable the option
33
+ Chrome:
34
+ Chrome must allow JavaScript from Apple Events:
35
+ 1. Open Chrome
36
+ 2. Go to View > Developer > Allow JavaScript from Apple Events
37
+ 3. Enable the option
33
38
 
34
39
  MCP CONFIGURATION EXAMPLE:
35
40
  {
@@ -58,6 +63,10 @@ function parseCliArgs(args) {
58
63
  type: "string",
59
64
  default: "3000",
60
65
  },
66
+ "experimental-browser": {
67
+ type: "string",
68
+ default: "",
69
+ },
61
70
  help: {
62
71
  type: "boolean",
63
72
  default: false,
@@ -66,8 +75,16 @@ function parseCliArgs(args) {
66
75
  allowPositionals: false,
67
76
  tokens: true,
68
77
  });
78
+ function parseBrowserOption(browser) {
79
+ if (browser === "" || browser === "chrome")
80
+ return "chrome";
81
+ if (browser === "safari")
82
+ return "safari";
83
+ throw new Error(`Invalid --experimental-browser option: "${browser}". Use "chrome" or "safari".`);
84
+ }
69
85
  const parsed = {
70
86
  applicationName: values["application-name"],
87
+ browser: parseBrowserOption(values["experimental-browser"]),
71
88
  excludeHosts: values["exclude-hosts"]
72
89
  .split(",")
73
90
  .map((d) => d.trim())
package/dist/mcp.d.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { Browser } from "./browser/browser.js";
2
3
  export type McpServerOptions = {
3
4
  applicationName: string;
4
5
  excludeHosts: string[];
5
6
  checkInterval: number;
7
+ browser: Browser;
6
8
  };
7
9
  export declare function createMcpServer(options: McpServerOptions): Promise<McpServer>;
package/dist/mcp.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { McpServer, ResourceTemplate, } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { z } from "zod";
3
- import * as chrome from "./chrome.js";
3
+ import { getInterface, } from "./browser/browser.js";
4
4
  import { readFile } from "fs/promises";
5
5
  import { dirname, join } from "path";
6
6
  import { fileURLToPath } from "url";
@@ -11,11 +11,13 @@ function isExcludedHost(url, excludeHosts) {
11
11
  return excludeHosts.some((d) => u.hostname === d || u.hostname.endsWith("." + d));
12
12
  }
13
13
  async function listTabs(opts) {
14
- const tabs = await chrome.getChromeTabList(opts.applicationName);
14
+ const browser = getInterface(opts.browser);
15
+ const tabs = await browser.getTabList(opts.applicationName);
15
16
  return tabs.filter((t) => !isExcludedHost(t.url, opts.excludeHosts));
16
17
  }
17
18
  async function getTab(tabRef, opts) {
18
- const content = await chrome.getPageContent(opts.applicationName, tabRef);
19
+ const browser = getInterface(opts.browser);
20
+ const content = await browser.getPageContent(opts.applicationName, tabRef);
19
21
  if (isExcludedHost(content.url, opts.excludeHosts)) {
20
22
  throw new Error("Content not available for excluded host");
21
23
  }
@@ -44,6 +46,7 @@ export async function createMcpServer(options) {
44
46
  name: "chrome-tabs",
45
47
  version: await packageVersion(),
46
48
  }, {
49
+ instructions: "Use this server to access the user's open browser tabs.",
47
50
  capabilities: {
48
51
  resources: {
49
52
  listChanged: true,
@@ -92,7 +95,8 @@ export async function createMcpServer(options) {
92
95
  },
93
96
  }, async (args) => {
94
97
  const { url } = args;
95
- await chrome.openURL(options.applicationName, url);
98
+ const browser = getInterface(options.browser);
99
+ await browser.openURL(options.applicationName, url);
96
100
  return {
97
101
  content: [
98
102
  {
package/dist/view.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Tab, TabRef, TabContent } from "./chrome.js";
1
+ import type { Tab, TabRef, TabContent } from "./browser/browser.js";
2
2
  export declare function formatTabRef(tab: Tab): string;
3
3
  export declare function parseTabRef(tabRef: string): TabRef | null;
4
4
  export declare function formatList(tabs: Tab[]): string;
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@pokutuna/mcp-chrome-tabs",
3
- "version": "0.1.4",
4
- "license": "MIT",
3
+ "version": "0.2.0",
5
4
  "repository": {
6
5
  "type": "git",
7
6
  "url": "https://github.com/pokutuna/mcp-chrome-tabs"
8
7
  },
8
+ "license": "MIT",
9
9
  "type": "module",
10
10
  "bin": {
11
11
  "mcp-chrome-tabs": "./dist/cli.js"
@@ -18,9 +18,11 @@
18
18
  "scripts": {
19
19
  "build": "tsc",
20
20
  "dev": "node --import tsx src/cli.ts",
21
+ "inspector": "npx @modelcontextprotocol/inspector",
22
+ "lint": "prettier --check .",
23
+ "lint:fix": "prettier --write .",
21
24
  "prepublishOnly": "npm run build",
22
25
  "start": "node dist/index.js",
23
- "inspector": "npx @modelcontextprotocol/inspector",
24
26
  "test": "vitest",
25
27
  "test:run": "vitest run"
26
28
  },
@@ -36,6 +38,7 @@
36
38
  "@types/jsdom": "^21.1.7",
37
39
  "@types/node": "^20.11.17",
38
40
  "@types/turndown": "^5.0.5",
41
+ "prettier": "^3.6.2",
39
42
  "tsx": "^4.7.1",
40
43
  "typescript": "~5.8.3",
41
44
  "vitest": "^3.2.4"
package/dist/chrome.d.ts DELETED
@@ -1,16 +0,0 @@
1
- export type TabRef = {
2
- windowId: string;
3
- tabId: string;
4
- };
5
- export type Tab = TabRef & {
6
- title: string;
7
- url: string;
8
- };
9
- export type TabContent = {
10
- title: string;
11
- url: string;
12
- content: string;
13
- };
14
- export declare function getChromeTabList(applicationName: string): Promise<Tab[]>;
15
- export declare function getPageContent(applicationName: string, tab?: TabRef | null): Promise<TabContent>;
16
- export declare function openURL(applicationName: string, url: string): Promise<void>;