@opentabs-dev/mcp-server 0.0.22 → 0.0.25
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/dist/adapter-files.d.ts +53 -0
- package/dist/adapter-files.d.ts.map +1 -0
- package/dist/adapter-files.js +176 -0
- package/dist/adapter-files.js.map +1 -0
- package/dist/audit-disk.d.ts.map +1 -1
- package/dist/audit-disk.js +5 -6
- package/dist/audit-disk.js.map +1 -1
- package/dist/browser-tool-names.d.ts +14 -0
- package/dist/browser-tool-names.d.ts.map +1 -0
- package/dist/browser-tool-names.js +52 -0
- package/dist/browser-tool-names.js.map +1 -0
- package/dist/browser-tools/analyze-site/detect-auth.d.ts.map +1 -1
- package/dist/browser-tools/analyze-site/detect-auth.js +2 -1
- package/dist/browser-tools/analyze-site/detect-auth.js.map +1 -1
- package/dist/browser-tools/analyze-site/index.d.ts.map +1 -1
- package/dist/browser-tools/analyze-site/index.js +111 -15
- package/dist/browser-tools/analyze-site/index.js.map +1 -1
- package/dist/browser-tools/execute-script.js +1 -1
- package/dist/browser-tools/execute-script.js.map +1 -1
- package/dist/browser-tools/extension-get-logs.d.ts +2 -2
- package/dist/browser-tools/focus-tab.js +1 -1
- package/dist/browser-tools/focus-tab.js.map +1 -1
- package/dist/browser-tools/get-console-logs.d.ts +2 -2
- package/dist/browser-tools/index.d.ts +4 -0
- package/dist/browser-tools/index.d.ts.map +1 -1
- package/dist/browser-tools/index.js +19 -0
- package/dist/browser-tools/index.js.map +1 -1
- package/dist/browser-tools/select-option.d.ts.map +1 -1
- package/dist/browser-tools/select-option.js +11 -6
- package/dist/browser-tools/select-option.js.map +1 -1
- package/dist/config.d.ts +13 -16
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +43 -109
- package/dist/config.js.map +1 -1
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +9 -12
- package/dist/discovery.js.map +1 -1
- package/dist/extension-handlers.d.ts +102 -0
- package/dist/extension-handlers.d.ts.map +1 -0
- package/dist/extension-handlers.js +443 -0
- package/dist/extension-handlers.js.map +1 -0
- package/dist/extension-protocol.d.ts +6 -38
- package/dist/extension-protocol.d.ts.map +1 -1
- package/dist/extension-protocol.js +47 -535
- package/dist/extension-protocol.js.map +1 -1
- package/dist/file-watcher.d.ts.map +1 -1
- package/dist/file-watcher.js +106 -104
- package/dist/file-watcher.js.map +1 -1
- package/dist/http-routes.d.ts +9 -7
- package/dist/http-routes.d.ts.map +1 -1
- package/dist/http-routes.js +275 -265
- package/dist/http-routes.js.map +1 -1
- package/dist/index.js +17 -10
- package/dist/index.js.map +1 -1
- package/dist/loader.d.ts +14 -3
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +42 -22
- package/dist/loader.js.map +1 -1
- package/dist/log-buffer.d.ts.map +1 -1
- package/dist/log-buffer.js +17 -6
- package/dist/log-buffer.js.map +1 -1
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +5 -2
- package/dist/logger.js.map +1 -1
- package/dist/mcp-setup.d.ts +3 -18
- package/dist/mcp-setup.d.ts.map +1 -1
- package/dist/mcp-setup.js +13 -407
- package/dist/mcp-setup.js.map +1 -1
- package/dist/mcp-tool-dispatch.d.ts +51 -0
- package/dist/mcp-tool-dispatch.d.ts.map +1 -0
- package/dist/mcp-tool-dispatch.js +410 -0
- package/dist/mcp-tool-dispatch.js.map +1 -0
- package/dist/plugin-management.d.ts +123 -0
- package/dist/plugin-management.d.ts.map +1 -0
- package/dist/plugin-management.js +340 -0
- package/dist/plugin-management.js.map +1 -0
- package/dist/registry.d.ts +2 -13
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +2 -24
- package/dist/registry.js.map +1 -1
- package/dist/reload.d.ts.map +1 -1
- package/dist/reload.js +13 -2
- package/dist/reload.js.map +1 -1
- package/dist/resolver.d.ts.map +1 -1
- package/dist/resolver.js +33 -25
- package/dist/resolver.js.map +1 -1
- package/dist/state.d.ts +30 -21
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +14 -10
- package/dist/state.js.map +1 -1
- package/dist/version-check.d.ts.map +1 -1
- package/dist/version-check.js +36 -14
- package/dist/version-check.js.map +1 -1
- package/package.json +2 -2
package/dist/discovery.js
CHANGED
|
@@ -3,11 +3,10 @@ import { loadPlugin } from './loader.js';
|
|
|
3
3
|
import { log } from './logger.js';
|
|
4
4
|
import { buildRegistry } from './registry.js';
|
|
5
5
|
import { discoverGlobalNpmPlugins, resolvePluginPath } from './resolver.js';
|
|
6
|
-
import { isErr } from '@opentabs-dev/shared';
|
|
6
|
+
import { isErr, OFFICIAL_SCOPE, toErrorMessage } from '@opentabs-dev/shared';
|
|
7
7
|
/** Determine trust tier for an npm plugin directory path based on its package name. */
|
|
8
8
|
const npmTrustTier = (dir) => {
|
|
9
|
-
|
|
10
|
-
if (dir.includes('/@opentabs-dev/'))
|
|
9
|
+
if (dir.includes(`/${OFFICIAL_SCOPE}/`))
|
|
11
10
|
return 'official';
|
|
12
11
|
return 'community';
|
|
13
12
|
};
|
|
@@ -43,15 +42,13 @@ const discoverPlugins = async (localPlugins, configDir) => {
|
|
|
43
42
|
const loadLocal = localPlugins.map(async (specifier) => {
|
|
44
43
|
const resolveResult = await resolvePluginPath(specifier, configDir);
|
|
45
44
|
if (isErr(resolveResult)) {
|
|
46
|
-
// "Path not found" means the directory no longer exists
|
|
47
|
-
//
|
|
48
|
-
|
|
49
|
-
if (resolveResult.error.startsWith('Path not found:')) {
|
|
50
|
-
log.warn(`Skipping stale local plugin path: ${specifier} — directory no longer exists`);
|
|
51
|
-
return null;
|
|
52
|
-
}
|
|
45
|
+
// "Path not found" means the directory no longer exists — treat as a stale config
|
|
46
|
+
// entry and skip silently (only log, don't add to failedPlugins).
|
|
47
|
+
const isStale = resolveResult.error.startsWith('Path not found:');
|
|
53
48
|
errors.push({ specifier, error: resolveResult.error });
|
|
54
|
-
|
|
49
|
+
if (!isStale) {
|
|
50
|
+
failures.push({ path: specifier, error: resolveResult.error });
|
|
51
|
+
}
|
|
55
52
|
return null;
|
|
56
53
|
}
|
|
57
54
|
const dir = resolveResult.value;
|
|
@@ -72,7 +69,7 @@ const discoverPlugins = async (localPlugins, configDir) => {
|
|
|
72
69
|
loaded.push(result.value);
|
|
73
70
|
}
|
|
74
71
|
else if (result.status === 'rejected') {
|
|
75
|
-
const errorMsg =
|
|
72
|
+
const errorMsg = toErrorMessage(result.reason);
|
|
76
73
|
errors.push({ specifier: '(unknown)', error: errorMsg });
|
|
77
74
|
}
|
|
78
75
|
}
|
package/dist/discovery.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"AAAA,yEAAyE;AAEzE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAC5E,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extension WebSocket message handlers.
|
|
3
|
+
* Each handler processes a specific JSON-RPC method from the Chrome extension.
|
|
4
|
+
* Exported individually so they can be unit tested independently of the
|
|
5
|
+
* handleExtensionMessage router in extension-protocol.ts.
|
|
6
|
+
*/
|
|
7
|
+
import type { PluginLogEntry } from './log-buffer.js';
|
|
8
|
+
import type { RegisteredPlugin, ServerState, TabMapping } from './state.js';
|
|
9
|
+
import type { JsonRpcError, JsonRpcNotification, JsonRpcRequest, JsonRpcResult } from '@opentabs-dev/shared';
|
|
10
|
+
/** Callbacks the extension protocol can invoke on the MCP side */
|
|
11
|
+
interface McpCallbacks {
|
|
12
|
+
onToolConfigChanged: () => void;
|
|
13
|
+
onToolConfigPersist: () => void;
|
|
14
|
+
onPluginLog: (entry: PluginLogEntry) => void;
|
|
15
|
+
onReload: () => Promise<{
|
|
16
|
+
plugins: number;
|
|
17
|
+
durationMs: number;
|
|
18
|
+
}>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Send a JSON-serialized message to the extension WebSocket if connected.
|
|
22
|
+
* Centralizes the null check on state.extensionWs so callers don't repeat it.
|
|
23
|
+
* Returns true if the message was sent, false if the extension is not connected.
|
|
24
|
+
*/
|
|
25
|
+
declare const sendToExtension: (state: ServerState, msg: JsonRpcNotification | JsonRpcResult | JsonRpcRequest | JsonRpcError) => boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Send a JSON-RPC error response to the extension.
|
|
28
|
+
* Shorthand for the common pattern of sending { jsonrpc: '2.0', error: { code, message }, id }.
|
|
29
|
+
*/
|
|
30
|
+
declare const sendJsonRpcError: (state: ServerState, id: string | number, code: number, message: string) => void;
|
|
31
|
+
/**
|
|
32
|
+
* Extract error details from a caught plugin management error and send a JSON-RPC error response.
|
|
33
|
+
* Handles code, message, data, and retryAfterMs fields that plugin management functions may throw.
|
|
34
|
+
*/
|
|
35
|
+
declare const sendPluginManagementError: (state: ServerState, id: string | number, err: unknown) => void;
|
|
36
|
+
/**
|
|
37
|
+
* Serialize a plugin's metadata and tools into the wire format sent to the extension.
|
|
38
|
+
* Returns the common core shape shared by sync.full, plugin.update, and config.getState.
|
|
39
|
+
* Callers can spread additional fields on top (e.g., sourcePath, adapterHash for sync messages,
|
|
40
|
+
* or tabState, source, sdkVersion for config.getState).
|
|
41
|
+
*/
|
|
42
|
+
declare const serializePluginForExtension: (plugin: RegisteredPlugin, state: ServerState) => {
|
|
43
|
+
name: string;
|
|
44
|
+
version: string;
|
|
45
|
+
displayName: string;
|
|
46
|
+
urlPatterns: string[];
|
|
47
|
+
trustTier: string;
|
|
48
|
+
iconSvg?: string;
|
|
49
|
+
iconInactiveSvg?: string;
|
|
50
|
+
tools: {
|
|
51
|
+
name: string;
|
|
52
|
+
displayName: string;
|
|
53
|
+
description: string;
|
|
54
|
+
icon: string;
|
|
55
|
+
iconSvg?: string;
|
|
56
|
+
iconInactiveSvg?: string;
|
|
57
|
+
enabled: boolean;
|
|
58
|
+
}[];
|
|
59
|
+
};
|
|
60
|
+
/** Wire shape for tab mapping entries — all fields may be absent or wrong type */
|
|
61
|
+
interface WireTabMapping {
|
|
62
|
+
state?: string;
|
|
63
|
+
tabId?: number | null;
|
|
64
|
+
url?: string | null;
|
|
65
|
+
}
|
|
66
|
+
declare const parseTabMapping: (wire: WireTabMapping) => TabMapping;
|
|
67
|
+
declare const handleTabSyncAll: (state: ServerState, params: Record<string, unknown> | undefined) => void;
|
|
68
|
+
declare const handleTabStateChanged: (state: ServerState, params: Record<string, unknown> | undefined, id?: string | number) => void;
|
|
69
|
+
declare const handleConfigGetState: (state: ServerState, id: string | number) => void;
|
|
70
|
+
declare const handleConfigSetToolEnabled: (state: ServerState, params: Record<string, unknown> | undefined, id: string | number, callbacks: McpCallbacks) => void;
|
|
71
|
+
declare const handleConfigSetAllToolsEnabled: (state: ServerState, params: Record<string, unknown> | undefined, id: string | number, callbacks: McpCallbacks) => void;
|
|
72
|
+
/**
|
|
73
|
+
* Handle tool.progress notification from the extension.
|
|
74
|
+
* Looks up the pending dispatch by dispatchId, invokes the onProgress callback
|
|
75
|
+
* to emit an MCP ProgressNotification to the client, and resets the dispatch
|
|
76
|
+
* timeout timer (the tool is alive). The timer reset is bounded by
|
|
77
|
+
* MAX_DISPATCH_TIMEOUT_MS — if the dispatch has been running longer than the
|
|
78
|
+
* absolute maximum, it is rejected immediately regardless of progress.
|
|
79
|
+
*/
|
|
80
|
+
declare const handleToolProgress: (state: ServerState, params: Record<string, unknown> | undefined) => void;
|
|
81
|
+
/** Valid plugin log levels (matches MCP LoggingLevel subset used by the SDK) */
|
|
82
|
+
declare const VALID_LOG_LEVELS: Set<string>;
|
|
83
|
+
declare const handlePluginLog: (params: Record<string, unknown> | undefined, callbacks: McpCallbacks) => void;
|
|
84
|
+
/**
|
|
85
|
+
* Handle a confirmation.response from the extension.
|
|
86
|
+
* Resolves the pending confirmation promise with the user's decision.
|
|
87
|
+
* For 'allow_always', also adds a session permission rule.
|
|
88
|
+
*/
|
|
89
|
+
declare const handleConfirmationResponse: (state: ServerState, params: Record<string, unknown> | undefined) => void;
|
|
90
|
+
/**
|
|
91
|
+
* Reject all pending confirmations. Called when the extension disconnects
|
|
92
|
+
* to clean up any confirmation promises that can no longer be fulfilled.
|
|
93
|
+
*/
|
|
94
|
+
declare const rejectAllPendingConfirmations: (state: ServerState) => void;
|
|
95
|
+
declare const handlePluginSearch: (state: ServerState, params: Record<string, unknown> | undefined, id: string | number) => Promise<void>;
|
|
96
|
+
declare const handlePluginInstall: (state: ServerState, params: Record<string, unknown> | undefined, id: string | number, callbacks: McpCallbacks) => Promise<void>;
|
|
97
|
+
declare const handlePluginUpdateFromRegistry: (state: ServerState, params: Record<string, unknown> | undefined, id: string | number, callbacks: McpCallbacks) => Promise<void>;
|
|
98
|
+
declare const handlePluginRemove: (state: ServerState, params: Record<string, unknown> | undefined, id: string | number, callbacks: McpCallbacks) => Promise<void>;
|
|
99
|
+
declare const handlePluginCheckUpdates: (state: ServerState, id: string | number) => Promise<void>;
|
|
100
|
+
export type { McpCallbacks, WireTabMapping };
|
|
101
|
+
export { sendToExtension, sendJsonRpcError, sendPluginManagementError, serializePluginForExtension, parseTabMapping, VALID_LOG_LEVELS, handleTabSyncAll, handleTabStateChanged, handleConfigGetState, handleConfigSetToolEnabled, handleConfigSetAllToolsEnabled, handlePluginSearch, handlePluginInstall, handlePluginUpdateFromRegistry, handlePluginRemove, handlePluginCheckUpdates, handleToolProgress, handlePluginLog, handleConfirmationResponse, rejectAllPendingConfirmations, };
|
|
102
|
+
//# sourceMappingURL=extension-handlers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension-handlers.d.ts","sourceRoot":"","sources":["../src/extension-handlers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,443 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extension WebSocket message handlers.
|
|
3
|
+
* Each handler processes a specific JSON-RPC method from the Chrome extension.
|
|
4
|
+
* Exported individually so they can be unit tested independently of the
|
|
5
|
+
* handleExtensionMessage router in extension-protocol.ts.
|
|
6
|
+
*/
|
|
7
|
+
import { appendLog } from './log-buffer.js';
|
|
8
|
+
import { log } from './logger.js';
|
|
9
|
+
import { searchNpmPlugins, installPlugin, updatePlugin, removePlugin, checkPluginUpdates, } from './plugin-management.js';
|
|
10
|
+
import { prefixedToolName, isToolEnabled, getNextRequestId, DISPATCH_TIMEOUT_MS, MAX_DISPATCH_TIMEOUT_MS, } from './state.js';
|
|
11
|
+
/**
|
|
12
|
+
* Send a JSON-serialized message to the extension WebSocket if connected.
|
|
13
|
+
* Centralizes the null check on state.extensionWs so callers don't repeat it.
|
|
14
|
+
* Returns true if the message was sent, false if the extension is not connected.
|
|
15
|
+
*/
|
|
16
|
+
const sendToExtension = (state, msg) => {
|
|
17
|
+
if (!state.extensionWs)
|
|
18
|
+
return false;
|
|
19
|
+
try {
|
|
20
|
+
state.extensionWs.send(JSON.stringify(msg));
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
log.warn('Failed to send to extension:', err);
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Send a JSON-RPC error response to the extension.
|
|
30
|
+
* Shorthand for the common pattern of sending { jsonrpc: '2.0', error: { code, message }, id }.
|
|
31
|
+
*/
|
|
32
|
+
const sendJsonRpcError = (state, id, code, message) => {
|
|
33
|
+
sendToExtension(state, { jsonrpc: '2.0', error: { code, message }, id });
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Extract error details from a caught plugin management error and send a JSON-RPC error response.
|
|
37
|
+
* Handles code, message, data, and retryAfterMs fields that plugin management functions may throw.
|
|
38
|
+
*/
|
|
39
|
+
const sendPluginManagementError = (state, id, err) => {
|
|
40
|
+
const code = typeof err.code === 'number' ? err.code : -32603;
|
|
41
|
+
const message = err instanceof Error ? err.message : 'Unknown error';
|
|
42
|
+
const rawData = err.data;
|
|
43
|
+
const data = typeof rawData === 'object' && rawData !== null ? rawData : undefined;
|
|
44
|
+
const retryAfterMs = typeof err.retryAfterMs === 'number'
|
|
45
|
+
? err.retryAfterMs
|
|
46
|
+
: undefined;
|
|
47
|
+
const errorData = { ...(data ?? {}), ...(retryAfterMs !== undefined ? { retryAfterMs } : {}) };
|
|
48
|
+
const hasData = Object.keys(errorData).length > 0;
|
|
49
|
+
sendToExtension(state, {
|
|
50
|
+
jsonrpc: '2.0',
|
|
51
|
+
error: { code, message, ...(hasData ? { data: errorData } : {}) },
|
|
52
|
+
id,
|
|
53
|
+
});
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Serialize a plugin's metadata and tools into the wire format sent to the extension.
|
|
57
|
+
* Returns the common core shape shared by sync.full, plugin.update, and config.getState.
|
|
58
|
+
* Callers can spread additional fields on top (e.g., sourcePath, adapterHash for sync messages,
|
|
59
|
+
* or tabState, source, sdkVersion for config.getState).
|
|
60
|
+
*/
|
|
61
|
+
const serializePluginForExtension = (plugin, state) => ({
|
|
62
|
+
name: plugin.name,
|
|
63
|
+
version: plugin.version,
|
|
64
|
+
displayName: plugin.displayName,
|
|
65
|
+
urlPatterns: plugin.urlPatterns,
|
|
66
|
+
trustTier: plugin.trustTier,
|
|
67
|
+
...(plugin.iconSvg ? { iconSvg: plugin.iconSvg } : {}),
|
|
68
|
+
...(plugin.iconInactiveSvg ? { iconInactiveSvg: plugin.iconInactiveSvg } : {}),
|
|
69
|
+
tools: plugin.tools.map(t => ({
|
|
70
|
+
name: t.name,
|
|
71
|
+
displayName: t.displayName,
|
|
72
|
+
description: t.description,
|
|
73
|
+
icon: t.icon,
|
|
74
|
+
...(t.iconSvg ? { iconSvg: t.iconSvg } : {}),
|
|
75
|
+
...(t.iconInactiveSvg ? { iconInactiveSvg: t.iconInactiveSvg } : {}),
|
|
76
|
+
enabled: isToolEnabled(state, prefixedToolName(plugin.name, t.name)),
|
|
77
|
+
})),
|
|
78
|
+
});
|
|
79
|
+
const parseTabMapping = (wire) => ({
|
|
80
|
+
state: wire.state === 'closed' || wire.state === 'unavailable' || wire.state === 'ready' ? wire.state : 'closed',
|
|
81
|
+
tabId: typeof wire.tabId === 'number' ? wire.tabId : null,
|
|
82
|
+
url: typeof wire.url === 'string' ? wire.url : null,
|
|
83
|
+
});
|
|
84
|
+
const handleTabSyncAll = (state, params) => {
|
|
85
|
+
if (!params)
|
|
86
|
+
return;
|
|
87
|
+
const tabSyncParams = params;
|
|
88
|
+
const tabs = tabSyncParams.tabs;
|
|
89
|
+
if (!tabs)
|
|
90
|
+
return;
|
|
91
|
+
state.tabMapping.clear();
|
|
92
|
+
for (const [pluginName, mapping] of Object.entries(tabs)) {
|
|
93
|
+
state.tabMapping.set(pluginName, parseTabMapping(mapping));
|
|
94
|
+
}
|
|
95
|
+
log.info(`tab.syncAll received — ${state.tabMapping.size} plugin(s) mapped`);
|
|
96
|
+
};
|
|
97
|
+
const handleTabStateChanged = (state, params, id) => {
|
|
98
|
+
const sendError = (message) => {
|
|
99
|
+
if (id !== undefined) {
|
|
100
|
+
sendJsonRpcError(state, id, -32602, message);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
log.warn(`tab.stateChanged: ${message}`);
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
if (!params) {
|
|
107
|
+
sendError('Missing params');
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const plugin = params.plugin;
|
|
111
|
+
if (typeof plugin !== 'string' || plugin.length === 0) {
|
|
112
|
+
sendError('Missing or invalid "plugin" field (expected non-empty string)');
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (!state.registry.plugins.has(plugin)) {
|
|
116
|
+
sendError(`Unknown plugin: ${plugin}`);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
if (typeof params.state !== 'string') {
|
|
120
|
+
sendError('Missing or invalid "state" field (expected string)');
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
if (params.state !== 'closed' && params.state !== 'unavailable' && params.state !== 'ready') {
|
|
124
|
+
sendError(`Invalid tab state: ${params.state} (expected closed, unavailable, or ready)`);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const wire = {
|
|
128
|
+
state: params.state,
|
|
129
|
+
tabId: typeof params.tabId === 'number' ? params.tabId : null,
|
|
130
|
+
url: typeof params.url === 'string' ? params.url : null,
|
|
131
|
+
};
|
|
132
|
+
state.tabMapping.set(plugin, parseTabMapping(wire));
|
|
133
|
+
log.info(`tab.stateChanged: ${plugin} → ${wire.state ?? 'unknown'}`);
|
|
134
|
+
};
|
|
135
|
+
// --- Config handlers ---
|
|
136
|
+
const handleConfigGetState = (state, id) => {
|
|
137
|
+
const outdatedByPkg = new Map(state.outdatedPlugins.map(o => [o.name, { latestVersion: o.latestVersion, updateCommand: o.updateCommand }]));
|
|
138
|
+
const plugins = Array.from(state.registry.plugins.values())
|
|
139
|
+
.sort((a, b) => a.name.localeCompare(b.name))
|
|
140
|
+
.map(p => {
|
|
141
|
+
const tabInfo = state.tabMapping.get(p.name);
|
|
142
|
+
const update = p.npmPackageName ? outdatedByPkg.get(p.npmPackageName) : undefined;
|
|
143
|
+
return {
|
|
144
|
+
...serializePluginForExtension(p, state),
|
|
145
|
+
source: p.source,
|
|
146
|
+
tabState: tabInfo?.state ?? 'closed',
|
|
147
|
+
...(p.sdkVersion ? { sdkVersion: p.sdkVersion } : {}),
|
|
148
|
+
...(update ? { update } : {}),
|
|
149
|
+
};
|
|
150
|
+
});
|
|
151
|
+
sendToExtension(state, {
|
|
152
|
+
jsonrpc: '2.0',
|
|
153
|
+
result: {
|
|
154
|
+
plugins,
|
|
155
|
+
failedPlugins: state.discoveryErrors.map(e => ({ specifier: e.specifier, error: e.error })),
|
|
156
|
+
},
|
|
157
|
+
id,
|
|
158
|
+
});
|
|
159
|
+
};
|
|
160
|
+
const handleConfigSetToolEnabled = (state, params, id, callbacks) => {
|
|
161
|
+
if (!params) {
|
|
162
|
+
sendJsonRpcError(state, id, -32602, 'Missing params');
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
const toolEnabledParams = params;
|
|
166
|
+
const pluginName = toolEnabledParams.plugin;
|
|
167
|
+
const tool = toolEnabledParams.tool;
|
|
168
|
+
const enabled = toolEnabledParams.enabled;
|
|
169
|
+
if (typeof pluginName !== 'string' || typeof tool !== 'string' || typeof enabled !== 'boolean') {
|
|
170
|
+
sendJsonRpcError(state, id, -32602, 'Invalid params: expected plugin (string), tool (string), enabled (boolean)');
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
const plugin = state.registry.plugins.get(pluginName);
|
|
174
|
+
if (!plugin) {
|
|
175
|
+
sendJsonRpcError(state, id, -32602, `Plugin not found: ${pluginName}`);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
if (!plugin.tools.some(t => t.name === tool)) {
|
|
179
|
+
sendJsonRpcError(state, id, -32602, `Tool not found: ${tool} in plugin ${pluginName}`);
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
const prefixed = prefixedToolName(pluginName, tool);
|
|
183
|
+
state.toolConfig[prefixed] = enabled;
|
|
184
|
+
callbacks.onToolConfigChanged();
|
|
185
|
+
callbacks.onToolConfigPersist();
|
|
186
|
+
sendToExtension(state, {
|
|
187
|
+
jsonrpc: '2.0',
|
|
188
|
+
result: { ok: true },
|
|
189
|
+
id,
|
|
190
|
+
});
|
|
191
|
+
};
|
|
192
|
+
const handleConfigSetAllToolsEnabled = (state, params, id, callbacks) => {
|
|
193
|
+
if (!params) {
|
|
194
|
+
sendJsonRpcError(state, id, -32602, 'Missing params');
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
const allToolsEnabledParams = params;
|
|
198
|
+
const pluginName = allToolsEnabledParams.plugin;
|
|
199
|
+
const enabled = allToolsEnabledParams.enabled;
|
|
200
|
+
if (typeof pluginName !== 'string' || typeof enabled !== 'boolean') {
|
|
201
|
+
sendJsonRpcError(state, id, -32602, 'Invalid params: expected plugin (string), enabled (boolean)');
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
const plugin = state.registry.plugins.get(pluginName);
|
|
205
|
+
if (!plugin) {
|
|
206
|
+
sendJsonRpcError(state, id, -32602, `Plugin not found: ${pluginName}`);
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
for (const tool of plugin.tools) {
|
|
210
|
+
const prefixed = prefixedToolName(pluginName, tool.name);
|
|
211
|
+
state.toolConfig[prefixed] = enabled;
|
|
212
|
+
}
|
|
213
|
+
callbacks.onToolConfigChanged();
|
|
214
|
+
callbacks.onToolConfigPersist();
|
|
215
|
+
sendToExtension(state, {
|
|
216
|
+
jsonrpc: '2.0',
|
|
217
|
+
result: { ok: true },
|
|
218
|
+
id,
|
|
219
|
+
});
|
|
220
|
+
};
|
|
221
|
+
// --- Tool progress handler ---
|
|
222
|
+
/**
|
|
223
|
+
* Handle tool.progress notification from the extension.
|
|
224
|
+
* Looks up the pending dispatch by dispatchId, invokes the onProgress callback
|
|
225
|
+
* to emit an MCP ProgressNotification to the client, and resets the dispatch
|
|
226
|
+
* timeout timer (the tool is alive). The timer reset is bounded by
|
|
227
|
+
* MAX_DISPATCH_TIMEOUT_MS — if the dispatch has been running longer than the
|
|
228
|
+
* absolute maximum, it is rejected immediately regardless of progress.
|
|
229
|
+
*/
|
|
230
|
+
const handleToolProgress = (state, params) => {
|
|
231
|
+
if (!params)
|
|
232
|
+
return;
|
|
233
|
+
const dispatchId = params.dispatchId;
|
|
234
|
+
if (typeof dispatchId !== 'string')
|
|
235
|
+
return;
|
|
236
|
+
const progress = params.progress;
|
|
237
|
+
const total = params.total;
|
|
238
|
+
if (typeof progress !== 'number' || typeof total !== 'number')
|
|
239
|
+
return;
|
|
240
|
+
const message = typeof params.message === 'string' ? params.message : undefined;
|
|
241
|
+
const pending = state.pendingDispatches.get(dispatchId);
|
|
242
|
+
if (!pending)
|
|
243
|
+
return;
|
|
244
|
+
pending.lastProgressTs = Date.now();
|
|
245
|
+
// Forward the progress notification to the MCP client
|
|
246
|
+
if (pending.onProgress) {
|
|
247
|
+
try {
|
|
248
|
+
pending.onProgress(progress, total, message);
|
|
249
|
+
}
|
|
250
|
+
catch {
|
|
251
|
+
// Fire-and-forget — errors in the progress chain must not affect tool execution
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
// Reset the dispatch timeout — the tool is alive and making progress.
|
|
255
|
+
// Bounded by MAX_DISPATCH_TIMEOUT_MS from the dispatch start time.
|
|
256
|
+
clearTimeout(pending.timerId);
|
|
257
|
+
const elapsed = Date.now() - pending.startTs;
|
|
258
|
+
const remainingMax = MAX_DISPATCH_TIMEOUT_MS - elapsed;
|
|
259
|
+
if (remainingMax <= 0) {
|
|
260
|
+
// Absolute max exceeded — reject immediately
|
|
261
|
+
state.pendingDispatches.delete(dispatchId);
|
|
262
|
+
pending.reject(new Error(`Dispatch ${pending.label} exceeded absolute max timeout of ${MAX_DISPATCH_TIMEOUT_MS}ms`));
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
const nextTimeout = Math.min(DISPATCH_TIMEOUT_MS, remainingMax);
|
|
266
|
+
pending.timerId = setTimeout(() => {
|
|
267
|
+
if (state.pendingDispatches.has(dispatchId)) {
|
|
268
|
+
state.pendingDispatches.delete(dispatchId);
|
|
269
|
+
pending.reject(new Error(`Dispatch ${pending.label} timed out after ${DISPATCH_TIMEOUT_MS}ms`));
|
|
270
|
+
}
|
|
271
|
+
}, nextTimeout);
|
|
272
|
+
};
|
|
273
|
+
// --- Plugin log handler ---
|
|
274
|
+
/** Valid plugin log levels (matches MCP LoggingLevel subset used by the SDK) */
|
|
275
|
+
const VALID_LOG_LEVELS = new Set(['debug', 'info', 'warning', 'error']);
|
|
276
|
+
const handlePluginLog = (params, callbacks) => {
|
|
277
|
+
if (!params)
|
|
278
|
+
return;
|
|
279
|
+
const plugin = params.plugin;
|
|
280
|
+
const level = params.level;
|
|
281
|
+
const message = params.message;
|
|
282
|
+
if (typeof plugin !== 'string' || plugin.length === 0)
|
|
283
|
+
return;
|
|
284
|
+
if (typeof level !== 'string' || !VALID_LOG_LEVELS.has(level))
|
|
285
|
+
return;
|
|
286
|
+
if (typeof message !== 'string')
|
|
287
|
+
return;
|
|
288
|
+
const ts = typeof params.ts === 'string' ? params.ts : new Date().toISOString();
|
|
289
|
+
const entry = {
|
|
290
|
+
level,
|
|
291
|
+
plugin,
|
|
292
|
+
message,
|
|
293
|
+
data: params.data,
|
|
294
|
+
ts,
|
|
295
|
+
};
|
|
296
|
+
appendLog(plugin, entry);
|
|
297
|
+
callbacks.onPluginLog(entry);
|
|
298
|
+
};
|
|
299
|
+
// --- Confirmation handler ---
|
|
300
|
+
/**
|
|
301
|
+
* Handle a confirmation.response from the extension.
|
|
302
|
+
* Resolves the pending confirmation promise with the user's decision.
|
|
303
|
+
* For 'allow_always', also adds a session permission rule.
|
|
304
|
+
*/
|
|
305
|
+
const handleConfirmationResponse = (state, params) => {
|
|
306
|
+
if (!params)
|
|
307
|
+
return;
|
|
308
|
+
const id = params.id;
|
|
309
|
+
if (typeof id !== 'string')
|
|
310
|
+
return;
|
|
311
|
+
const decision = params.decision;
|
|
312
|
+
if (decision !== 'allow_once' && decision !== 'allow_always' && decision !== 'deny')
|
|
313
|
+
return;
|
|
314
|
+
const pending = state.pendingConfirmations.get(id);
|
|
315
|
+
if (!pending)
|
|
316
|
+
return;
|
|
317
|
+
clearTimeout(pending.timerId);
|
|
318
|
+
state.pendingConfirmations.delete(id);
|
|
319
|
+
// For allow_always, add a session permission rule based on the scope
|
|
320
|
+
if (decision === 'allow_always') {
|
|
321
|
+
const scope = typeof params.scope === 'string' ? params.scope : 'tool_domain';
|
|
322
|
+
const rule = { tool: pending.tool, domain: pending.domain, scope };
|
|
323
|
+
// Adjust rule fields based on scope
|
|
324
|
+
if (scope === 'tool_all') {
|
|
325
|
+
rule.domain = null;
|
|
326
|
+
}
|
|
327
|
+
else if (scope === 'domain_all') {
|
|
328
|
+
rule.tool = null;
|
|
329
|
+
}
|
|
330
|
+
state.sessionPermissions.push(rule);
|
|
331
|
+
}
|
|
332
|
+
pending.resolve(decision);
|
|
333
|
+
};
|
|
334
|
+
/**
|
|
335
|
+
* Reject all pending confirmations. Called when the extension disconnects
|
|
336
|
+
* to clean up any confirmation promises that can no longer be fulfilled.
|
|
337
|
+
*/
|
|
338
|
+
const rejectAllPendingConfirmations = (state) => {
|
|
339
|
+
for (const [id, pending] of state.pendingConfirmations) {
|
|
340
|
+
clearTimeout(pending.timerId);
|
|
341
|
+
pending.reject(new Error('Extension disconnected — confirmation cancelled'));
|
|
342
|
+
state.pendingConfirmations.delete(id);
|
|
343
|
+
}
|
|
344
|
+
};
|
|
345
|
+
// --- Plugin management handlers ---
|
|
346
|
+
const handlePluginSearch = async (state, params, id) => {
|
|
347
|
+
const query = params?.query;
|
|
348
|
+
if (query !== undefined && typeof query !== 'string') {
|
|
349
|
+
sendJsonRpcError(state, id, -32602, 'Invalid params: query must be a string if provided');
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
try {
|
|
353
|
+
const results = await searchNpmPlugins(query ?? undefined);
|
|
354
|
+
sendToExtension(state, {
|
|
355
|
+
jsonrpc: '2.0',
|
|
356
|
+
result: { results },
|
|
357
|
+
id,
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
catch (err) {
|
|
361
|
+
sendPluginManagementError(state, id, err);
|
|
362
|
+
}
|
|
363
|
+
};
|
|
364
|
+
const handlePluginInstall = async (state, params, id, callbacks) => {
|
|
365
|
+
if (!params || typeof params.name !== 'string' || params.name.length === 0) {
|
|
366
|
+
sendJsonRpcError(state, id, -32602, 'Invalid params: name must be a non-empty string');
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
try {
|
|
370
|
+
const result = await installPlugin(params.name, state, callbacks.onReload);
|
|
371
|
+
// Notify the side panel so the UI refreshes with the new plugin
|
|
372
|
+
sendToExtension(state, { jsonrpc: '2.0', method: 'plugins.changed', params: {} });
|
|
373
|
+
sendToExtension(state, {
|
|
374
|
+
jsonrpc: '2.0',
|
|
375
|
+
result,
|
|
376
|
+
id,
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
catch (err) {
|
|
380
|
+
sendPluginManagementError(state, id, err);
|
|
381
|
+
}
|
|
382
|
+
};
|
|
383
|
+
const handlePluginUpdateFromRegistry = async (state, params, id, callbacks) => {
|
|
384
|
+
if (!params || typeof params.name !== 'string' || params.name.length === 0) {
|
|
385
|
+
sendJsonRpcError(state, id, -32602, 'Invalid params: name must be a non-empty string');
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
try {
|
|
389
|
+
const result = await updatePlugin(params.name, state, callbacks.onReload);
|
|
390
|
+
// Notify the side panel so the UI refreshes
|
|
391
|
+
sendToExtension(state, { jsonrpc: '2.0', method: 'plugins.changed', params: {} });
|
|
392
|
+
sendToExtension(state, {
|
|
393
|
+
jsonrpc: '2.0',
|
|
394
|
+
result,
|
|
395
|
+
id,
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
catch (err) {
|
|
399
|
+
sendPluginManagementError(state, id, err);
|
|
400
|
+
}
|
|
401
|
+
};
|
|
402
|
+
const handlePluginRemove = async (state, params, id, callbacks) => {
|
|
403
|
+
if (!params || typeof params.name !== 'string' || params.name.length === 0) {
|
|
404
|
+
sendJsonRpcError(state, id, -32602, 'Invalid params: name must be a non-empty string');
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
try {
|
|
408
|
+
const pluginName = params.name;
|
|
409
|
+
const result = await removePlugin(pluginName, state, callbacks.onReload);
|
|
410
|
+
// Send plugin.uninstall to extension to clean up adapters in matching tabs
|
|
411
|
+
sendToExtension(state, {
|
|
412
|
+
jsonrpc: '2.0',
|
|
413
|
+
method: 'plugin.uninstall',
|
|
414
|
+
params: { name: pluginName },
|
|
415
|
+
id: getNextRequestId(),
|
|
416
|
+
});
|
|
417
|
+
// Notify the side panel so the UI refreshes
|
|
418
|
+
sendToExtension(state, { jsonrpc: '2.0', method: 'plugins.changed', params: {} });
|
|
419
|
+
sendToExtension(state, {
|
|
420
|
+
jsonrpc: '2.0',
|
|
421
|
+
result,
|
|
422
|
+
id,
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
catch (err) {
|
|
426
|
+
sendPluginManagementError(state, id, err);
|
|
427
|
+
}
|
|
428
|
+
};
|
|
429
|
+
const handlePluginCheckUpdates = async (state, id) => {
|
|
430
|
+
try {
|
|
431
|
+
const result = await checkPluginUpdates(state);
|
|
432
|
+
sendToExtension(state, {
|
|
433
|
+
jsonrpc: '2.0',
|
|
434
|
+
result,
|
|
435
|
+
id,
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
catch (err) {
|
|
439
|
+
sendPluginManagementError(state, id, err);
|
|
440
|
+
}
|
|
441
|
+
};
|
|
442
|
+
export { sendToExtension, sendJsonRpcError, sendPluginManagementError, serializePluginForExtension, parseTabMapping, VALID_LOG_LEVELS, handleTabSyncAll, handleTabStateChanged, handleConfigGetState, handleConfigSetToolEnabled, handleConfigSetAllToolsEnabled, handlePluginSearch, handlePluginInstall, handlePluginUpdateFromRegistry, handlePluginRemove, handlePluginCheckUpdates, handleToolProgress, handlePluginLog, handleConfirmationResponse, rejectAllPendingConfirmations, };
|
|
443
|
+
//# sourceMappingURL=extension-handlers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension-handlers.js","sourceRoot":"","sources":["../src/extension-handlers.ts"],"names":[],"mappings":"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"}
|