@opentabs-dev/mcp-server 0.0.19

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.
Files changed (309) hide show
  1. package/dist/audit-disk.d.ts +23 -0
  2. package/dist/audit-disk.d.ts.map +1 -0
  3. package/dist/audit-disk.js +74 -0
  4. package/dist/audit-disk.js.map +1 -0
  5. package/dist/browser-tools/analyze-site/detect-apis.d.ts +36 -0
  6. package/dist/browser-tools/analyze-site/detect-apis.d.ts.map +1 -0
  7. package/dist/browser-tools/analyze-site/detect-apis.js +383 -0
  8. package/dist/browser-tools/analyze-site/detect-apis.js.map +1 -0
  9. package/dist/browser-tools/analyze-site/detect-auth.d.ts +72 -0
  10. package/dist/browser-tools/analyze-site/detect-auth.d.ts.map +1 -0
  11. package/dist/browser-tools/analyze-site/detect-auth.js +384 -0
  12. package/dist/browser-tools/analyze-site/detect-auth.js.map +1 -0
  13. package/dist/browser-tools/analyze-site/detect-dom.d.ts +65 -0
  14. package/dist/browser-tools/analyze-site/detect-dom.d.ts.map +1 -0
  15. package/dist/browser-tools/analyze-site/detect-dom.js +45 -0
  16. package/dist/browser-tools/analyze-site/detect-dom.js.map +1 -0
  17. package/dist/browser-tools/analyze-site/detect-framework.d.ts +48 -0
  18. package/dist/browser-tools/analyze-site/detect-framework.d.ts.map +1 -0
  19. package/dist/browser-tools/analyze-site/detect-framework.js +31 -0
  20. package/dist/browser-tools/analyze-site/detect-framework.js.map +1 -0
  21. package/dist/browser-tools/analyze-site/detect-globals.d.ts +41 -0
  22. package/dist/browser-tools/analyze-site/detect-globals.d.ts.map +1 -0
  23. package/dist/browser-tools/analyze-site/detect-globals.js +42 -0
  24. package/dist/browser-tools/analyze-site/detect-globals.js.map +1 -0
  25. package/dist/browser-tools/analyze-site/detect-storage.d.ts +39 -0
  26. package/dist/browser-tools/analyze-site/detect-storage.d.ts.map +1 -0
  27. package/dist/browser-tools/analyze-site/detect-storage.js +34 -0
  28. package/dist/browser-tools/analyze-site/detect-storage.js.map +1 -0
  29. package/dist/browser-tools/analyze-site/index.d.ts +52 -0
  30. package/dist/browser-tools/analyze-site/index.d.ts.map +1 -0
  31. package/dist/browser-tools/analyze-site/index.js +827 -0
  32. package/dist/browser-tools/analyze-site/index.js.map +1 -0
  33. package/dist/browser-tools/analyze-site.d.ts +17 -0
  34. package/dist/browser-tools/analyze-site.d.ts.map +1 -0
  35. package/dist/browser-tools/analyze-site.js +41 -0
  36. package/dist/browser-tools/analyze-site.js.map +1 -0
  37. package/dist/browser-tools/clear-console-logs.d.ts +9 -0
  38. package/dist/browser-tools/clear-console-logs.d.ts.map +1 -0
  39. package/dist/browser-tools/clear-console-logs.js +16 -0
  40. package/dist/browser-tools/clear-console-logs.js.map +1 -0
  41. package/dist/browser-tools/click-element.d.ts +10 -0
  42. package/dist/browser-tools/click-element.d.ts.map +1 -0
  43. package/dist/browser-tools/click-element.js +22 -0
  44. package/dist/browser-tools/click-element.js.map +1 -0
  45. package/dist/browser-tools/close-tab.d.ts +9 -0
  46. package/dist/browser-tools/close-tab.d.ts.map +1 -0
  47. package/dist/browser-tools/close-tab.js +16 -0
  48. package/dist/browser-tools/close-tab.js.map +1 -0
  49. package/dist/browser-tools/definition.d.ts +26 -0
  50. package/dist/browser-tools/definition.d.ts.map +1 -0
  51. package/dist/browser-tools/definition.js +16 -0
  52. package/dist/browser-tools/definition.js.map +1 -0
  53. package/dist/browser-tools/delete-cookies.d.ts +10 -0
  54. package/dist/browser-tools/delete-cookies.d.ts.map +1 -0
  55. package/dist/browser-tools/delete-cookies.js +19 -0
  56. package/dist/browser-tools/delete-cookies.js.map +1 -0
  57. package/dist/browser-tools/disable-network-capture.d.ts +9 -0
  58. package/dist/browser-tools/disable-network-capture.d.ts.map +1 -0
  59. package/dist/browser-tools/disable-network-capture.js +16 -0
  60. package/dist/browser-tools/disable-network-capture.js.map +1 -0
  61. package/dist/browser-tools/enable-network-capture.d.ts +12 -0
  62. package/dist/browser-tools/enable-network-capture.d.ts.map +1 -0
  63. package/dist/browser-tools/enable-network-capture.js +42 -0
  64. package/dist/browser-tools/enable-network-capture.js.map +1 -0
  65. package/dist/browser-tools/execute-script.d.ts +19 -0
  66. package/dist/browser-tools/execute-script.d.ts.map +1 -0
  67. package/dist/browser-tools/execute-script.js +51 -0
  68. package/dist/browser-tools/execute-script.js.map +1 -0
  69. package/dist/browser-tools/extension-check-adapter.d.ts +11 -0
  70. package/dist/browser-tools/extension-check-adapter.d.ts.map +1 -0
  71. package/dist/browser-tools/extension-check-adapter.js +22 -0
  72. package/dist/browser-tools/extension-check-adapter.js.map +1 -0
  73. package/dist/browser-tools/extension-force-reconnect.d.ts +9 -0
  74. package/dist/browser-tools/extension-force-reconnect.d.ts.map +1 -0
  75. package/dist/browser-tools/extension-force-reconnect.js +19 -0
  76. package/dist/browser-tools/extension-force-reconnect.js.map +1 -0
  77. package/dist/browser-tools/extension-get-logs.d.ts +24 -0
  78. package/dist/browser-tools/extension-get-logs.d.ts.map +1 -0
  79. package/dist/browser-tools/extension-get-logs.js +34 -0
  80. package/dist/browser-tools/extension-get-logs.js.map +1 -0
  81. package/dist/browser-tools/extension-get-side-panel.d.ts +8 -0
  82. package/dist/browser-tools/extension-get-side-panel.d.ts.map +1 -0
  83. package/dist/browser-tools/extension-get-side-panel.js +17 -0
  84. package/dist/browser-tools/extension-get-side-panel.js.map +1 -0
  85. package/dist/browser-tools/extension-get-state.d.ts +9 -0
  86. package/dist/browser-tools/extension-get-state.d.ts.map +1 -0
  87. package/dist/browser-tools/extension-get-state.js +19 -0
  88. package/dist/browser-tools/extension-get-state.js.map +1 -0
  89. package/dist/browser-tools/focus-tab.d.ts +9 -0
  90. package/dist/browser-tools/focus-tab.d.ts.map +1 -0
  91. package/dist/browser-tools/focus-tab.js +17 -0
  92. package/dist/browser-tools/focus-tab.js.map +1 -0
  93. package/dist/browser-tools/get-console-logs.d.ts +18 -0
  94. package/dist/browser-tools/get-console-logs.d.ts.map +1 -0
  95. package/dist/browser-tools/get-console-logs.js +30 -0
  96. package/dist/browser-tools/get-console-logs.js.map +1 -0
  97. package/dist/browser-tools/get-cookies.d.ts +10 -0
  98. package/dist/browser-tools/get-cookies.d.ts.map +1 -0
  99. package/dist/browser-tools/get-cookies.js +23 -0
  100. package/dist/browser-tools/get-cookies.js.map +1 -0
  101. package/dist/browser-tools/get-network-requests.d.ts +10 -0
  102. package/dist/browser-tools/get-network-requests.d.ts.map +1 -0
  103. package/dist/browser-tools/get-network-requests.js +27 -0
  104. package/dist/browser-tools/get-network-requests.js.map +1 -0
  105. package/dist/browser-tools/get-page-html.d.ts +11 -0
  106. package/dist/browser-tools/get-page-html.d.ts.map +1 -0
  107. package/dist/browser-tools/get-page-html.js +32 -0
  108. package/dist/browser-tools/get-page-html.js.map +1 -0
  109. package/dist/browser-tools/get-resource-content.d.ts +11 -0
  110. package/dist/browser-tools/get-resource-content.d.ts.map +1 -0
  111. package/dist/browser-tools/get-resource-content.js +31 -0
  112. package/dist/browser-tools/get-resource-content.js.map +1 -0
  113. package/dist/browser-tools/get-storage.d.ts +14 -0
  114. package/dist/browser-tools/get-storage.d.ts.map +1 -0
  115. package/dist/browser-tools/get-storage.js +28 -0
  116. package/dist/browser-tools/get-storage.js.map +1 -0
  117. package/dist/browser-tools/get-tab-content.d.ts +11 -0
  118. package/dist/browser-tools/get-tab-content.d.ts.map +1 -0
  119. package/dist/browser-tools/get-tab-content.js +29 -0
  120. package/dist/browser-tools/get-tab-content.js.map +1 -0
  121. package/dist/browser-tools/get-tab-info.d.ts +9 -0
  122. package/dist/browser-tools/get-tab-info.d.ts.map +1 -0
  123. package/dist/browser-tools/get-tab-info.js +17 -0
  124. package/dist/browser-tools/get-tab-info.js.map +1 -0
  125. package/dist/browser-tools/handle-dialog.d.ts +14 -0
  126. package/dist/browser-tools/handle-dialog.d.ts.map +1 -0
  127. package/dist/browser-tools/handle-dialog.js +30 -0
  128. package/dist/browser-tools/handle-dialog.js.map +1 -0
  129. package/dist/browser-tools/hover-element.d.ts +11 -0
  130. package/dist/browser-tools/hover-element.d.ts.map +1 -0
  131. package/dist/browser-tools/hover-element.js +24 -0
  132. package/dist/browser-tools/hover-element.js.map +1 -0
  133. package/dist/browser-tools/index.d.ts +7 -0
  134. package/dist/browser-tools/index.d.ts.map +1 -0
  135. package/dist/browser-tools/index.js +81 -0
  136. package/dist/browser-tools/index.js.map +1 -0
  137. package/dist/browser-tools/list-resources.d.ts +10 -0
  138. package/dist/browser-tools/list-resources.d.ts.map +1 -0
  139. package/dist/browser-tools/list-resources.js +29 -0
  140. package/dist/browser-tools/list-resources.js.map +1 -0
  141. package/dist/browser-tools/list-tabs.d.ts +7 -0
  142. package/dist/browser-tools/list-tabs.d.ts.map +1 -0
  143. package/dist/browser-tools/list-tabs.js +16 -0
  144. package/dist/browser-tools/list-tabs.js.map +1 -0
  145. package/dist/browser-tools/navigate-tab.d.ts +10 -0
  146. package/dist/browser-tools/navigate-tab.d.ts.map +1 -0
  147. package/dist/browser-tools/navigate-tab.js +18 -0
  148. package/dist/browser-tools/navigate-tab.js.map +1 -0
  149. package/dist/browser-tools/open-tab.d.ts +9 -0
  150. package/dist/browser-tools/open-tab.d.ts.map +1 -0
  151. package/dist/browser-tools/open-tab.js +18 -0
  152. package/dist/browser-tools/open-tab.js.map +1 -0
  153. package/dist/browser-tools/press-key.d.ts +17 -0
  154. package/dist/browser-tools/press-key.d.ts.map +1 -0
  155. package/dist/browser-tools/press-key.js +43 -0
  156. package/dist/browser-tools/press-key.js.map +1 -0
  157. package/dist/browser-tools/query-elements.d.ts +12 -0
  158. package/dist/browser-tools/query-elements.d.ts.map +1 -0
  159. package/dist/browser-tools/query-elements.js +30 -0
  160. package/dist/browser-tools/query-elements.js.map +1 -0
  161. package/dist/browser-tools/reload-extension.d.ts +13 -0
  162. package/dist/browser-tools/reload-extension.d.ts.map +1 -0
  163. package/dist/browser-tools/reload-extension.js +35 -0
  164. package/dist/browser-tools/reload-extension.js.map +1 -0
  165. package/dist/browser-tools/screenshot-tab.d.ts +9 -0
  166. package/dist/browser-tools/screenshot-tab.d.ts.map +1 -0
  167. package/dist/browser-tools/screenshot-tab.js +22 -0
  168. package/dist/browser-tools/screenshot-tab.js.map +1 -0
  169. package/dist/browser-tools/scroll.d.ts +23 -0
  170. package/dist/browser-tools/scroll.d.ts.map +1 -0
  171. package/dist/browser-tools/scroll.js +56 -0
  172. package/dist/browser-tools/scroll.js.map +1 -0
  173. package/dist/browser-tools/select-option.d.ts +12 -0
  174. package/dist/browser-tools/select-option.d.ts.map +1 -0
  175. package/dist/browser-tools/select-option.js +25 -0
  176. package/dist/browser-tools/select-option.js.map +1 -0
  177. package/dist/browser-tools/set-cookie.d.ts +16 -0
  178. package/dist/browser-tools/set-cookie.d.ts.map +1 -0
  179. package/dist/browser-tools/set-cookie.js +42 -0
  180. package/dist/browser-tools/set-cookie.js.map +1 -0
  181. package/dist/browser-tools/type-text.d.ts +12 -0
  182. package/dist/browser-tools/type-text.d.ts.map +1 -0
  183. package/dist/browser-tools/type-text.js +25 -0
  184. package/dist/browser-tools/type-text.js.map +1 -0
  185. package/dist/browser-tools/url-validation.d.ts +13 -0
  186. package/dist/browser-tools/url-validation.d.ts.map +1 -0
  187. package/dist/browser-tools/url-validation.js +23 -0
  188. package/dist/browser-tools/url-validation.js.map +1 -0
  189. package/dist/browser-tools/wait-for-element.d.ts +12 -0
  190. package/dist/browser-tools/wait-for-element.d.ts.map +1 -0
  191. package/dist/browser-tools/wait-for-element.js +29 -0
  192. package/dist/browser-tools/wait-for-element.js.map +1 -0
  193. package/dist/config.d.ts +99 -0
  194. package/dist/config.d.ts.map +1 -0
  195. package/dist/config.js +344 -0
  196. package/dist/config.js.map +1 -0
  197. package/dist/dev-mode.d.ts +14 -0
  198. package/dist/dev-mode.d.ts.map +1 -0
  199. package/dist/dev-mode.js +15 -0
  200. package/dist/dev-mode.js.map +1 -0
  201. package/dist/discovery-legacy.d.ts +32 -0
  202. package/dist/discovery-legacy.d.ts.map +1 -0
  203. package/dist/discovery-legacy.js +415 -0
  204. package/dist/discovery-legacy.js.map +1 -0
  205. package/dist/discovery.d.ts +28 -0
  206. package/dist/discovery.d.ts.map +1 -0
  207. package/dist/discovery.js +97 -0
  208. package/dist/discovery.js.map +1 -0
  209. package/dist/extension-install.d.ts +27 -0
  210. package/dist/extension-install.d.ts.map +1 -0
  211. package/dist/extension-install.js +75 -0
  212. package/dist/extension-install.js.map +1 -0
  213. package/dist/extension-protocol.d.ts +130 -0
  214. package/dist/extension-protocol.d.ts.map +1 -0
  215. package/dist/extension-protocol.js +869 -0
  216. package/dist/extension-protocol.js.map +1 -0
  217. package/dist/file-watcher.d.ts +75 -0
  218. package/dist/file-watcher.d.ts.map +1 -0
  219. package/dist/file-watcher.js +616 -0
  220. package/dist/file-watcher.js.map +1 -0
  221. package/dist/http-routes.d.ts +88 -0
  222. package/dist/http-routes.d.ts.map +1 -0
  223. package/dist/http-routes.js +545 -0
  224. package/dist/http-routes.js.map +1 -0
  225. package/dist/index.d.ts +45 -0
  226. package/dist/index.d.ts.map +1 -0
  227. package/dist/index.js +187 -0
  228. package/dist/index.js.map +1 -0
  229. package/dist/loader.d.ts +100 -0
  230. package/dist/loader.d.ts.map +1 -0
  231. package/dist/loader.js +402 -0
  232. package/dist/loader.js.map +1 -0
  233. package/dist/log-buffer.d.ts +33 -0
  234. package/dist/log-buffer.d.ts.map +1 -0
  235. package/dist/log-buffer.js +64 -0
  236. package/dist/log-buffer.js.map +1 -0
  237. package/dist/logger.d.ts +34 -0
  238. package/dist/logger.d.ts.map +1 -0
  239. package/dist/logger.js +81 -0
  240. package/dist/logger.js.map +1 -0
  241. package/dist/manifest-schema.d.ts +14 -0
  242. package/dist/manifest-schema.d.ts.map +1 -0
  243. package/dist/manifest-schema.js +51 -0
  244. package/dist/manifest-schema.js.map +1 -0
  245. package/dist/mcp-setup.d.ts +131 -0
  246. package/dist/mcp-setup.d.ts.map +1 -0
  247. package/dist/mcp-setup.js +673 -0
  248. package/dist/mcp-setup.js.map +1 -0
  249. package/dist/permissions.d.ts +59 -0
  250. package/dist/permissions.d.ts.map +1 -0
  251. package/dist/permissions.js +141 -0
  252. package/dist/permissions.js.map +1 -0
  253. package/dist/registry.d.ts +78 -0
  254. package/dist/registry.d.ts.map +1 -0
  255. package/dist/registry.js +187 -0
  256. package/dist/registry.js.map +1 -0
  257. package/dist/reload.d.ts +52 -0
  258. package/dist/reload.d.ts.map +1 -0
  259. package/dist/reload.js +326 -0
  260. package/dist/reload.js.map +1 -0
  261. package/dist/resolver.d.ts +53 -0
  262. package/dist/resolver.d.ts.map +1 -0
  263. package/dist/resolver.js +272 -0
  264. package/dist/resolver.js.map +1 -0
  265. package/dist/sanitize-error.d.ts +8 -0
  266. package/dist/sanitize-error.d.ts.map +1 -0
  267. package/dist/sanitize-error.js +25 -0
  268. package/dist/sanitize-error.js.map +1 -0
  269. package/dist/sanitize-tool-output.d.ts +20 -0
  270. package/dist/sanitize-tool-output.d.ts.map +1 -0
  271. package/dist/sanitize-tool-output.js +52 -0
  272. package/dist/sanitize-tool-output.js.map +1 -0
  273. package/dist/sdk-version.d.ts +11 -0
  274. package/dist/sdk-version.d.ts.map +1 -0
  275. package/dist/sdk-version.js +23 -0
  276. package/dist/sdk-version.js.map +1 -0
  277. package/dist/shutdown.d.ts +28 -0
  278. package/dist/shutdown.d.ts.map +1 -0
  279. package/dist/shutdown.js +68 -0
  280. package/dist/shutdown.js.map +1 -0
  281. package/dist/skip-confirmation.d.ts +15 -0
  282. package/dist/skip-confirmation.d.ts.map +1 -0
  283. package/dist/skip-confirmation.js +16 -0
  284. package/dist/skip-confirmation.js.map +1 -0
  285. package/dist/skip-sanitization.d.ts +17 -0
  286. package/dist/skip-sanitization.d.ts.map +1 -0
  287. package/dist/skip-sanitization.js +18 -0
  288. package/dist/skip-sanitization.js.map +1 -0
  289. package/dist/skip-verification.d.ts +11 -0
  290. package/dist/skip-verification.d.ts.map +1 -0
  291. package/dist/skip-verification.js +12 -0
  292. package/dist/skip-verification.js.map +1 -0
  293. package/dist/state.d.ts +290 -0
  294. package/dist/state.d.ts.map +1 -0
  295. package/dist/state.js +111 -0
  296. package/dist/state.js.map +1 -0
  297. package/dist/verify-plugin.d.ts +53 -0
  298. package/dist/verify-plugin.d.ts.map +1 -0
  299. package/dist/verify-plugin.js +123 -0
  300. package/dist/verify-plugin.js.map +1 -0
  301. package/dist/version-check.d.ts +35 -0
  302. package/dist/version-check.d.ts.map +1 -0
  303. package/dist/version-check.js +111 -0
  304. package/dist/version-check.js.map +1 -0
  305. package/dist/version.d.ts +10 -0
  306. package/dist/version.d.ts.map +1 -0
  307. package/dist/version.js +22 -0
  308. package/dist/version.js.map +1 -0
  309. package/package.json +28 -0
@@ -0,0 +1,290 @@
1
+ /**
2
+ * In-memory state for the MCP server.
3
+ * Tracks plugins, tab-to-plugin mapping, tool config, and pending dispatches.
4
+ *
5
+ * Fields that must survive hot reload (file watcher handles, timers) are stored
6
+ * here rather than at module scope, because module-level variables reset to
7
+ * fresh empty instances on each bun --hot re-evaluation.
8
+ */
9
+ import type { BrowserToolDefinition } from './browser-tools/definition.js';
10
+ import type { PermissionsConfig } from './config.js';
11
+ import type { TabState, TrustTier, ManifestTool, ManifestResource, ManifestPrompt, WsHandle } from '@opentabs-dev/shared';
12
+ import type { FSWatcher } from 'node:fs';
13
+ /** Timeout for tool dispatch and browser command requests (ms) */
14
+ export declare const DISPATCH_TIMEOUT_MS = 30000;
15
+ /** Absolute upper bound for a single dispatch, even with continuous progress (5 minutes) */
16
+ export declare const MAX_DISPATCH_TIMEOUT_MS = 300000;
17
+ /** Active file watcher entry for a single plugin directory */
18
+ export interface FileWatcherEntry {
19
+ pluginDir: string;
20
+ pluginName: string;
21
+ watchers: FSWatcher[];
22
+ /** Last-seen mtime (ms) for each watched file path — used by mtime polling fallback */
23
+ lastSeenMtimes: Map<string, number>;
24
+ }
25
+ /** How a plugin was discovered: auto-discovered from global node_modules or explicitly listed in localPlugins */
26
+ export type PluginSource = 'npm' | 'local';
27
+ /** Plugin registered in the server */
28
+ export interface RegisteredPlugin {
29
+ name: string;
30
+ version: string;
31
+ displayName: string;
32
+ urlPatterns: string[];
33
+ trustTier: TrustTier;
34
+ iife: string;
35
+ tools: ManifestTool[];
36
+ resources: ManifestResource[];
37
+ prompts: ManifestPrompt[];
38
+ /** How this plugin was discovered: 'npm' (global auto-discovery) or 'local' (config localPlugins) */
39
+ source: PluginSource;
40
+ /** SHA-256 hex hash of the adapter IIFE content (from manifest, set by `opentabs-plugin build`) */
41
+ adapterHash?: string;
42
+ /** Source map content for the adapter IIFE (from dist/adapter.iife.js.map). Undefined for old plugins. */
43
+ iifeSourceMap?: string;
44
+ /** Filesystem path for local plugins (used for file watching) */
45
+ sourcePath?: string;
46
+ /** Original npm package name (e.g., 'opentabs-plugin-slack') — only for npm-installed plugins */
47
+ npmPackageName?: string;
48
+ /** SDK version the plugin was built with (from tools.json sdkVersion field). Undefined for old plugins. */
49
+ sdkVersion?: string;
50
+ /** Optional SVG icon for the plugin */
51
+ iconSvg?: string;
52
+ /** Optional SVG icon for the inactive state */
53
+ iconInactiveSvg?: string;
54
+ }
55
+ /** Tab mapping entry for a plugin */
56
+ export interface TabMapping {
57
+ state: TabState;
58
+ tabId: number | null;
59
+ url: string | null;
60
+ }
61
+ /** Pending dispatch awaiting extension response (tool.dispatch or browser.*) */
62
+ export interface PendingDispatch {
63
+ resolve: (value: unknown) => void;
64
+ reject: (error: Error) => void;
65
+ /** Human-readable label for timeout error messages (e.g., "slack/send_message" or "browser.openTab") */
66
+ label: string;
67
+ startTs: number;
68
+ /** Timer ID for the dispatch timeout — cleared when the dispatch settles */
69
+ timerId: ReturnType<typeof setTimeout>;
70
+ /** MCP progressToken from the tools/call request's _meta — used to emit MCP ProgressNotifications */
71
+ progressToken?: string | number;
72
+ /** Callback to emit an MCP ProgressNotification for this dispatch */
73
+ onProgress?: (progress: number, total: number, message?: string) => void;
74
+ /** Timestamp (ms) of the last progress notification — updated by handleToolProgress for observability */
75
+ lastProgressTs?: number;
76
+ }
77
+ /** Resolved tool lookup entry for O(1) dispatch in tools/call */
78
+ export interface ToolLookupEntry {
79
+ pluginName: string;
80
+ toolName: string;
81
+ /** Pre-compiled JSON Schema validator for input args. Null if schema compilation failed. */
82
+ validate: ((data: unknown) => boolean) | null;
83
+ /** Human-readable validation errors from the last validate() call */
84
+ validationErrors: () => string;
85
+ }
86
+ /** Cached browser tool entry with pre-computed JSON Schema */
87
+ export interface CachedBrowserTool {
88
+ name: string;
89
+ description: string;
90
+ inputSchema: Record<string, unknown>;
91
+ tool: BrowserToolDefinition;
92
+ }
93
+ /** Tool config: maps prefixed tool name → enabled boolean */
94
+ export type ToolConfig = Record<string, boolean>;
95
+ /** A plugin path that failed discovery, with a human-readable error */
96
+ export interface FailedPlugin {
97
+ path: string;
98
+ error: string;
99
+ }
100
+ /** Info about an outdated npm plugin */
101
+ export interface OutdatedPlugin {
102
+ name: string;
103
+ currentVersion: string;
104
+ latestVersion: string;
105
+ updateCommand: string;
106
+ }
107
+ /** Resolved resource lookup entry for O(1) dispatch in resources/read */
108
+ export interface ResourceLookupEntry {
109
+ pluginName: string;
110
+ /** Original (unprefixed) resource URI as defined in the plugin manifest */
111
+ originalUri: string;
112
+ }
113
+ /** Resolved prompt lookup entry for O(1) dispatch in prompts/get */
114
+ export interface PromptLookupEntry {
115
+ pluginName: string;
116
+ /** Original (unprefixed) prompt name as defined in the plugin manifest */
117
+ originalName: string;
118
+ }
119
+ /**
120
+ * Immutable registry of discovered plugins.
121
+ *
122
+ * Holds all successfully loaded plugins, a pre-built O(1) tool lookup map
123
+ * with compiled Ajv validators, O(1) resource and prompt lookup maps,
124
+ * and a list of discovery failures. Built once per reload cycle and
125
+ * swapped atomically on ServerState.
126
+ */
127
+ export interface PluginRegistry {
128
+ /** All successfully loaded plugins, keyed by internal plugin name */
129
+ readonly plugins: ReadonlyMap<string, RegisteredPlugin>;
130
+ /** O(1) tool lookup: prefixed tool name → plugin/tool names + validator */
131
+ readonly toolLookup: ReadonlyMap<string, ToolLookupEntry>;
132
+ /** O(1) resource lookup: prefixed URI → plugin name + original URI */
133
+ readonly resourceLookup: ReadonlyMap<string, ResourceLookupEntry>;
134
+ /** O(1) prompt lookup: prefixed name → plugin name + original name */
135
+ readonly promptLookup: ReadonlyMap<string, PromptLookupEntry>;
136
+ /** Plugin paths that failed discovery */
137
+ readonly failures: readonly FailedPlugin[];
138
+ }
139
+ /** Confirmation timeout for human approval (30 seconds) */
140
+ export declare const CONFIRMATION_TIMEOUT_MS = 30000;
141
+ /** Pending confirmation awaiting human approval */
142
+ export interface PendingConfirmation {
143
+ resolve: (decision: ConfirmationDecision) => void;
144
+ reject: (error: Error) => void;
145
+ timerId: ReturnType<typeof setTimeout>;
146
+ tool: string;
147
+ domain: string | null;
148
+ tabId?: number;
149
+ }
150
+ /** Decision from the side panel confirmation dialog */
151
+ export type ConfirmationDecision = 'allow_once' | 'allow_always' | 'deny';
152
+ /** Scope for "Allow Always" session permissions */
153
+ export type ConfirmationScope = 'tool_domain' | 'tool_all' | 'domain_all';
154
+ /** Session-scoped permission rule created by "Allow Always" */
155
+ export interface SessionPermissionRule {
156
+ tool: string | null;
157
+ domain: string | null;
158
+ scope: ConfirmationScope;
159
+ }
160
+ /** Check if a tool+domain combination is allowed by session permissions */
161
+ export declare const isSessionAllowed: (rules: SessionPermissionRule[], toolName: string, domain: string | null) => boolean;
162
+ /** Record of a single tool invocation for audit logging */
163
+ export interface AuditEntry {
164
+ /** ISO 8601 timestamp of the invocation */
165
+ timestamp: string;
166
+ /** Prefixed tool name (e.g., 'slack_send_message') */
167
+ tool: string;
168
+ /** Plugin name (e.g., 'slack') or 'browser' for browser tools */
169
+ plugin: string;
170
+ /** Whether the invocation completed successfully */
171
+ success: boolean;
172
+ /** Execution duration in milliseconds */
173
+ durationMs: number;
174
+ /** Error details, populated on failure */
175
+ error?: {
176
+ code: string;
177
+ message: string;
178
+ category?: string;
179
+ };
180
+ }
181
+ /** Maximum entries retained in the audit log circular buffer */
182
+ export declare const MAX_AUDIT_ENTRIES = 500;
183
+ /** Append an entry to the audit log, trimming oldest entries beyond MAX_AUDIT_ENTRIES.
184
+ * Also persists the entry to ~/.opentabs/audit.log as NDJSON (fire-and-forget). */
185
+ export declare const appendAuditEntry: (state: ServerState, entry: AuditEntry) => void;
186
+ /** Server state singleton — shared across hot reloads via globalThis */
187
+ export interface ServerState {
188
+ /**
189
+ * Schema version for detecting structural changes across hot reloads.
190
+ * If a developer changes the shape of an existing field (e.g., Map → Array),
191
+ * bumping this version triggers a warning on the next hot reload indicating
192
+ * a process restart is needed for full consistency.
193
+ */
194
+ _schemaVersion: number;
195
+ /** Immutable plugin registry — replaced atomically on each reload */
196
+ registry: PluginRegistry;
197
+ /** Tab-to-plugin mapping from extension */
198
+ tabMapping: Map<string, TabMapping>;
199
+ /** Tool enabled/disabled config (in-memory, synced from ~/.opentabs/config.json) */
200
+ toolConfig: ToolConfig;
201
+ /** Browser tool enabled/disabled policy (in-memory, synced from ~/.opentabs/config.json) */
202
+ browserToolPolicy: Record<string, boolean>;
203
+ /** Local plugin paths from config */
204
+ pluginPaths: string[];
205
+ /** Pending tool dispatches keyed by JSON-RPC id */
206
+ pendingDispatches: Map<string | number, PendingDispatch>;
207
+ /** Extension WebSocket connection (single connection) */
208
+ extensionWs: WsHandle | null;
209
+ /** Outdated npm plugins detected on startup */
210
+ outdatedPlugins: OutdatedPlugin[];
211
+ /** Browser tools — updated on each hot reload so existing session handlers see fresh definitions */
212
+ browserTools: BrowserToolDefinition[];
213
+ /** Active file watcher entries — stored on state so hot reload can clean up the previous iteration's handles */
214
+ fileWatcherEntries: FileWatcherEntry[];
215
+ /** File watcher debounce timers — stored on state so hot reload can clear them */
216
+ fileWatcherTimers: Map<string, ReturnType<typeof setTimeout>>;
217
+ /** Shared secret for WebSocket authentication (loaded from config) */
218
+ wsSecret: string | null;
219
+ /** Cached browser tools with pre-computed JSON Schema. Rebuilt on each reload. */
220
+ cachedBrowserTools: CachedBrowserTool[];
221
+ /** Maps each MCP session server to its transport ID for accurate stale session sweeping */
222
+ sessionTransportIds: WeakMap<object, string>;
223
+ /** Async write mutex for config file — stored on state so it survives hot reload */
224
+ configWriteMutex: Promise<void>;
225
+ /** Per-plugin active dispatch count for concurrency limiting */
226
+ activeDispatches: Map<string, number>;
227
+ /** Periodic timer for sweeping stale MCP sessions between hot reloads */
228
+ sweepTimerId: ReturnType<typeof setInterval> | null;
229
+ /** Timestamp (ms since epoch) when the server process first started — survives hot reloads */
230
+ startedAt: number;
231
+ /** Generation counter for file watchers — incremented each time startFileWatching runs.
232
+ * Debounce callbacks capture the current generation and bail out if it has changed,
233
+ * preventing stale closures from the previous module evaluation from executing. */
234
+ fileWatcherGeneration: number;
235
+ /** FSWatcher for ~/.opentabs/ directory, detecting config.json changes */
236
+ configWatcher: FSWatcher | null;
237
+ /** Last-seen mtime (ms) of ~/.opentabs/config.json — used by mtime polling fallback */
238
+ configLastSeenMtime: number | null;
239
+ /** Timer ID for periodic mtime polling — cleared by stopFileWatching */
240
+ mtimePollTimerId: ReturnType<typeof setInterval> | null;
241
+ /** Timestamp (ms since epoch) of the last mtime polling tick, or null if polling hasn't run yet */
242
+ mtimeLastPollAt: number | null;
243
+ /** Running count of times mtime polling detected a change that fs.watch missed */
244
+ mtimePollDetections: number;
245
+ /** Timestamps (ms since epoch) of recent mtime poll detections — used for stale watcher warning */
246
+ mtimePollDetectionTimestamps: number[];
247
+ /** Discovery errors from the most recent reload — used by config.getState for the side panel */
248
+ discoveryErrors: ReadonlyArray<{
249
+ specifier: string;
250
+ error: string;
251
+ }>;
252
+ /** Circular buffer of recent tool invocations for diagnostics and monitoring */
253
+ auditLog: AuditEntry[];
254
+ /** Whether confirmation prompts are bypassed (from CLI flag, env var, or config) */
255
+ skipConfirmation: boolean;
256
+ /** Permission rules for browser tool confirmation */
257
+ permissions: PermissionsConfig;
258
+ /** Pending confirmation requests awaiting human approval in the side panel */
259
+ pendingConfirmations: Map<string, PendingConfirmation>;
260
+ /** Session-scoped permission rules set by "Allow Always" actions during this server lifetime */
261
+ sessionPermissions: SessionPermissionRule[];
262
+ /** Whether an extension reload is pending (set when extension files are updated but extension is not connected) */
263
+ pendingExtensionReload: boolean;
264
+ }
265
+ /** Increment when changing the type of an existing ServerState field */
266
+ export declare const STATE_SCHEMA_VERSION = 3;
267
+ /** Frozen empty registry for initializing ServerState */
268
+ export declare const EMPTY_REGISTRY: PluginRegistry;
269
+ /**
270
+ * Creates a fresh ServerState with all fields initialized to their defaults.
271
+ *
272
+ * @returns A new ServerState instance with empty collections, no WebSocket connection,
273
+ * and default permission rules (localhost/127.0.0.1 trusted).
274
+ */
275
+ export declare const createState: () => ServerState;
276
+ /** Generate a cryptographically random JSON-RPC request ID */
277
+ export declare const getNextRequestId: () => string;
278
+ /** Get the prefixed tool name: plugin_tool */
279
+ export declare const prefixedToolName: (plugin: string, tool: string) => string;
280
+ /** Get the prefixed resource URI: opentabs+<plugin>://<original-uri-path> */
281
+ export declare const prefixedResourceUri: (plugin: string, uri: string) => string;
282
+ /** Get the prefixed prompt name: plugin_prompt (same convention as tools) */
283
+ export declare const prefixedPromptName: (plugin: string, promptName: string) => string;
284
+ /** Check if a tool is enabled in config. Tools are enabled by default — only
285
+ * explicitly disabled tools (set to false) are hidden from MCP clients. */
286
+ export declare const isToolEnabled: (state: ServerState, prefixedName: string) => boolean;
287
+ /** Check if a browser tool is enabled via browserToolPolicy. Browser tools are
288
+ * enabled by default — only explicitly disabled tools (set to false) are hidden. */
289
+ export declare const isBrowserToolEnabled: (state: ServerState, toolName: string) => boolean;
290
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"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"}
package/dist/state.js ADDED
@@ -0,0 +1,111 @@
1
+ /**
2
+ * In-memory state for the MCP server.
3
+ * Tracks plugins, tab-to-plugin mapping, tool config, and pending dispatches.
4
+ *
5
+ * Fields that must survive hot reload (file watcher handles, timers) are stored
6
+ * here rather than at module scope, because module-level variables reset to
7
+ * fresh empty instances on each bun --hot re-evaluation.
8
+ */
9
+ import { appendAuditEntryToDisk } from './audit-disk.js';
10
+ /** Timeout for tool dispatch and browser command requests (ms) */
11
+ export const DISPATCH_TIMEOUT_MS = 30_000;
12
+ /** Absolute upper bound for a single dispatch, even with continuous progress (5 minutes) */
13
+ export const MAX_DISPATCH_TIMEOUT_MS = 300_000;
14
+ /** Confirmation timeout for human approval (30 seconds) */
15
+ export const CONFIRMATION_TIMEOUT_MS = 30_000;
16
+ /** Check if a tool+domain combination is allowed by session permissions */
17
+ export const isSessionAllowed = (rules, toolName, domain) => rules.some(rule => {
18
+ switch (rule.scope) {
19
+ case 'tool_domain':
20
+ return rule.tool === toolName && rule.domain === domain;
21
+ case 'tool_all':
22
+ return rule.tool === toolName;
23
+ case 'domain_all':
24
+ return rule.domain !== null && rule.domain === domain;
25
+ default:
26
+ return false;
27
+ }
28
+ });
29
+ /** Maximum entries retained in the audit log circular buffer */
30
+ export const MAX_AUDIT_ENTRIES = 500;
31
+ /** Append an entry to the audit log, trimming oldest entries beyond MAX_AUDIT_ENTRIES.
32
+ * Also persists the entry to ~/.opentabs/audit.log as NDJSON (fire-and-forget). */
33
+ export const appendAuditEntry = (state, entry) => {
34
+ state.auditLog.push(entry);
35
+ if (state.auditLog.length > MAX_AUDIT_ENTRIES) {
36
+ state.auditLog.splice(0, state.auditLog.length - MAX_AUDIT_ENTRIES);
37
+ }
38
+ // Fire-and-forget disk write — errors are logged internally, never block dispatch
39
+ void appendAuditEntryToDisk(entry);
40
+ };
41
+ /** Increment when changing the type of an existing ServerState field */
42
+ export const STATE_SCHEMA_VERSION = 3;
43
+ /** Frozen empty registry for initializing ServerState */
44
+ export const EMPTY_REGISTRY = Object.freeze({
45
+ plugins: new Map(),
46
+ toolLookup: new Map(),
47
+ resourceLookup: new Map(),
48
+ promptLookup: new Map(),
49
+ failures: [],
50
+ });
51
+ /**
52
+ * Creates a fresh ServerState with all fields initialized to their defaults.
53
+ *
54
+ * @returns A new ServerState instance with empty collections, no WebSocket connection,
55
+ * and default permission rules (localhost/127.0.0.1 trusted).
56
+ */
57
+ export const createState = () => ({
58
+ _schemaVersion: STATE_SCHEMA_VERSION,
59
+ registry: EMPTY_REGISTRY,
60
+ tabMapping: new Map(),
61
+ toolConfig: {},
62
+ browserToolPolicy: {},
63
+ pluginPaths: [],
64
+ pendingDispatches: new Map(),
65
+ extensionWs: null,
66
+ outdatedPlugins: [],
67
+ browserTools: [],
68
+ fileWatcherEntries: [],
69
+ fileWatcherTimers: new Map(),
70
+ wsSecret: null,
71
+ cachedBrowserTools: [],
72
+ sessionTransportIds: new WeakMap(),
73
+ configWriteMutex: Promise.resolve(),
74
+ activeDispatches: new Map(),
75
+ sweepTimerId: null,
76
+ startedAt: Date.now(),
77
+ fileWatcherGeneration: 0,
78
+ configWatcher: null,
79
+ configLastSeenMtime: null,
80
+ mtimePollTimerId: null,
81
+ mtimeLastPollAt: null,
82
+ mtimePollDetections: 0,
83
+ mtimePollDetectionTimestamps: [],
84
+ discoveryErrors: [],
85
+ auditLog: [],
86
+ skipConfirmation: false,
87
+ permissions: {
88
+ trustedDomains: ['localhost', '127.0.0.1'],
89
+ sensitiveDomains: [],
90
+ toolPolicy: {},
91
+ domainToolPolicy: {},
92
+ },
93
+ pendingConfirmations: new Map(),
94
+ sessionPermissions: [],
95
+ pendingExtensionReload: false,
96
+ });
97
+ /** Generate a cryptographically random JSON-RPC request ID */
98
+ export const getNextRequestId = () => crypto.randomUUID();
99
+ /** Get the prefixed tool name: plugin_tool */
100
+ export const prefixedToolName = (plugin, tool) => `${plugin}_${tool}`;
101
+ /** Get the prefixed resource URI: opentabs+<plugin>://<original-uri-path> */
102
+ export const prefixedResourceUri = (plugin, uri) => `opentabs+${plugin}://${uri}`;
103
+ /** Get the prefixed prompt name: plugin_prompt (same convention as tools) */
104
+ export const prefixedPromptName = (plugin, promptName) => `${plugin}_${promptName}`;
105
+ /** Check if a tool is enabled in config. Tools are enabled by default — only
106
+ * explicitly disabled tools (set to false) are hidden from MCP clients. */
107
+ export const isToolEnabled = (state, prefixedName) => state.toolConfig[prefixedName] !== false;
108
+ /** Check if a browser tool is enabled via browserToolPolicy. Browser tools are
109
+ * enabled by default — only explicitly disabled tools (set to false) are hidden. */
110
+ export const isBrowserToolEnabled = (state, toolName) => state.browserToolPolicy[toolName] !== false;
111
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Official plugin verification module.
3
+ *
4
+ * Verifies that plugins in the @opentabs-dev/ scope match what is published
5
+ * on the npm registry by comparing the installed package's integrity hash
6
+ * against the registry's published integrity value.
7
+ *
8
+ * This is a best-effort check that catches the common case of npm package
9
+ * hijacking. It does NOT provide full supply chain security (that would
10
+ * require signing keys).
11
+ */
12
+ interface VerificationResult {
13
+ /** Whether the plugin passed verification */
14
+ verified: boolean;
15
+ /** Human-readable reason when verification fails or is skipped */
16
+ reason?: string;
17
+ }
18
+ /**
19
+ * Read the installed package's integrity hash from its package.json.
20
+ *
21
+ * npm and bun both write _integrity (subresource integrity format, e.g.,
22
+ * "sha512-...") into the installed package.json. Falls back to _shasum
23
+ * (hex SHA-1) if _integrity is not present.
24
+ */
25
+ declare const readInstalledIntegrity: (packagePath: string) => Promise<{
26
+ integrity?: string;
27
+ shasum?: string;
28
+ version?: string;
29
+ }>;
30
+ /**
31
+ * Fetch the registry metadata for a specific package version.
32
+ *
33
+ * Uses the abbreviated registry endpoint to minimize data transfer.
34
+ * Returns the dist object containing integrity and shasum fields.
35
+ */
36
+ declare const fetchRegistryDist: (npmPackageName: string, version: string) => Promise<{
37
+ integrity?: string;
38
+ shasum?: string;
39
+ } | null>;
40
+ /**
41
+ * Verify that an official plugin's installed files match what is published
42
+ * on the npm registry.
43
+ *
44
+ * Compares the _integrity or _shasum field from the installed package.json
45
+ * against the npm registry's published dist metadata for the same version.
46
+ *
47
+ * @param packagePath - Absolute path to the installed plugin directory
48
+ * @param npmPackageName - The npm package name (e.g., "@opentabs-dev/opentabs-plugin-slack")
49
+ */
50
+ declare const verifyOfficialPlugin: (packagePath: string, npmPackageName: string) => Promise<VerificationResult>;
51
+ export { verifyOfficialPlugin, readInstalledIntegrity, fetchRegistryDist };
52
+ export type { VerificationResult };
53
+ //# sourceMappingURL=verify-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-plugin.d.ts","sourceRoot":"","sources":["../src/verify-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,UAAU,kBAAkB;IAC1B,6CAA6C;IAC7C,QAAQ,EAAE,OAAO,CAAC;IAClB,kEAAkE;IAClE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,QAAA,MAAM,sBAAsB,GAC1B,aAAa,MAAM,KAClB,OAAO,CAAC;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAanE,CAAC;AAEF;;;;;GAKG;AACH,QAAA,MAAM,iBAAiB,GACrB,gBAAgB,MAAM,EACtB,SAAS,MAAM,KACd,OAAO,CAAC;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAiCxD,CAAC;AAEF;;;;;;;;;GASG;AACH,QAAA,MAAM,oBAAoB,GAAU,aAAa,MAAM,EAAE,gBAAgB,MAAM,KAAG,OAAO,CAAC,kBAAkB,CAgD3G,CAAC;AAEF,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,CAAC;AAC3E,YAAY,EAAE,kBAAkB,EAAE,CAAC"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Official plugin verification module.
3
+ *
4
+ * Verifies that plugins in the @opentabs-dev/ scope match what is published
5
+ * on the npm registry by comparing the installed package's integrity hash
6
+ * against the registry's published integrity value.
7
+ *
8
+ * This is a best-effort check that catches the common case of npm package
9
+ * hijacking. It does NOT provide full supply chain security (that would
10
+ * require signing keys).
11
+ */
12
+ import { log } from './logger.js';
13
+ import { join } from 'node:path';
14
+ /**
15
+ * Read the installed package's integrity hash from its package.json.
16
+ *
17
+ * npm and bun both write _integrity (subresource integrity format, e.g.,
18
+ * "sha512-...") into the installed package.json. Falls back to _shasum
19
+ * (hex SHA-1) if _integrity is not present.
20
+ */
21
+ const readInstalledIntegrity = async (packagePath) => {
22
+ try {
23
+ const pkgJson = await Bun.file(join(packagePath, 'package.json')).json();
24
+ if (pkgJson === null || typeof pkgJson !== 'object')
25
+ return {};
26
+ const pkg = pkgJson;
27
+ return {
28
+ integrity: typeof pkg._integrity === 'string' ? pkg._integrity : undefined,
29
+ shasum: typeof pkg._shasum === 'string' ? pkg._shasum : undefined,
30
+ version: typeof pkg.version === 'string' ? pkg.version : undefined,
31
+ };
32
+ }
33
+ catch {
34
+ return {};
35
+ }
36
+ };
37
+ /**
38
+ * Fetch the registry metadata for a specific package version.
39
+ *
40
+ * Uses the abbreviated registry endpoint to minimize data transfer.
41
+ * Returns the dist object containing integrity and shasum fields.
42
+ */
43
+ const fetchRegistryDist = async (npmPackageName, version) => {
44
+ const registryUrl = `https://registry.npmjs.org/${encodeURIComponent(npmPackageName).replace('%40', '@')}/${version}`;
45
+ try {
46
+ const controller = new AbortController();
47
+ const timeoutId = setTimeout(() => controller.abort(), 10_000);
48
+ const response = await fetch(registryUrl, {
49
+ signal: controller.signal,
50
+ headers: { Accept: 'application/json' },
51
+ });
52
+ clearTimeout(timeoutId);
53
+ if (!response.ok) {
54
+ return null;
55
+ }
56
+ const data = await response.json();
57
+ if (data === null || typeof data !== 'object')
58
+ return null;
59
+ const record = data;
60
+ const dist = record.dist;
61
+ if (dist === null || typeof dist !== 'object')
62
+ return null;
63
+ const distRecord = dist;
64
+ return {
65
+ integrity: typeof distRecord.integrity === 'string' ? distRecord.integrity : undefined,
66
+ shasum: typeof distRecord.shasum === 'string' ? distRecord.shasum : undefined,
67
+ };
68
+ }
69
+ catch {
70
+ return null;
71
+ }
72
+ };
73
+ /**
74
+ * Verify that an official plugin's installed files match what is published
75
+ * on the npm registry.
76
+ *
77
+ * Compares the _integrity or _shasum field from the installed package.json
78
+ * against the npm registry's published dist metadata for the same version.
79
+ *
80
+ * @param packagePath - Absolute path to the installed plugin directory
81
+ * @param npmPackageName - The npm package name (e.g., "@opentabs-dev/opentabs-plugin-slack")
82
+ */
83
+ const verifyOfficialPlugin = async (packagePath, npmPackageName) => {
84
+ const installed = await readInstalledIntegrity(packagePath);
85
+ if (!installed.version) {
86
+ return { verified: false, reason: 'Could not read version from installed package.json' };
87
+ }
88
+ if (!installed.integrity && !installed.shasum) {
89
+ return {
90
+ verified: false,
91
+ reason: 'No _integrity or _shasum found in installed package.json — package may not have been installed via npm/bun',
92
+ };
93
+ }
94
+ const registryDist = await fetchRegistryDist(npmPackageName, installed.version);
95
+ if (registryDist === null) {
96
+ log.warn(`Could not reach npm registry to verify ${npmPackageName}@${installed.version} — loading at original tier`);
97
+ return { verified: true, reason: 'Registry unreachable — verification skipped' };
98
+ }
99
+ // Prefer integrity (SRI hash, usually sha512) over shasum (SHA-1)
100
+ if (installed.integrity && registryDist.integrity) {
101
+ if (installed.integrity === registryDist.integrity) {
102
+ return { verified: true };
103
+ }
104
+ return {
105
+ verified: false,
106
+ reason: `Integrity mismatch: installed=${installed.integrity}, registry=${registryDist.integrity}`,
107
+ };
108
+ }
109
+ // Fall back to shasum comparison
110
+ if (installed.shasum && registryDist.shasum) {
111
+ if (installed.shasum === registryDist.shasum) {
112
+ return { verified: true };
113
+ }
114
+ return {
115
+ verified: false,
116
+ reason: `Shasum mismatch: installed=${installed.shasum}, registry=${registryDist.shasum}`,
117
+ };
118
+ }
119
+ // One side has integrity, the other has shasum — can't compare directly
120
+ return { verified: true, reason: 'Hash format mismatch between installed and registry — verification skipped' };
121
+ };
122
+ export { verifyOfficialPlugin, readInstalledIntegrity, fetchRegistryDist };
123
+ //# sourceMappingURL=verify-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-plugin.js","sourceRoot":"","sources":["../src/verify-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AASjC;;;;;;GAMG;AACH,MAAM,sBAAsB,GAAG,KAAK,EAClC,WAAmB,EACiD,EAAE;IACtE,IAAI,CAAC;QACH,MAAM,OAAO,GAAY,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAClF,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,OAAO,KAAK,QAAQ;YAAE,OAAO,EAAE,CAAC;QAC/D,MAAM,GAAG,GAAG,OAAkC,CAAC;QAC/C,OAAO;YACL,SAAS,EAAE,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS;YAC1E,MAAM,EAAE,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;YACjE,OAAO,EAAE,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;SACnE,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,iBAAiB,GAAG,KAAK,EAC7B,cAAsB,EACtB,OAAe,EAC0C,EAAE;IAC3D,MAAM,WAAW,GAAG,8BAA8B,kBAAkB,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,OAAO,EAAE,CAAC;IAEtH,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,MAAM,CAAC,CAAC;QAE/D,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,WAAW,EAAE;YACxC,MAAM,EAAE,UAAU,CAAC,MAAM;YACzB,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE;SACxC,CAAC,CAAC;QAEH,YAAY,CAAC,SAAS,CAAC,CAAC;QAExB,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,IAAI,GAAY,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC5C,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QAE3D,MAAM,MAAM,GAAG,IAA+B,CAAC;QAC/C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;QACzB,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QAE3D,MAAM,UAAU,GAAG,IAA+B,CAAC;QACnD,OAAO;YACL,SAAS,EAAE,OAAO,UAAU,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;YACtF,MAAM,EAAE,OAAO,UAAU,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;SAC9E,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,oBAAoB,GAAG,KAAK,EAAE,WAAmB,EAAE,cAAsB,EAA+B,EAAE;IAC9G,MAAM,SAAS,GAAG,MAAM,sBAAsB,CAAC,WAAW,CAAC,CAAC;IAE5D,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;QACvB,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,oDAAoD,EAAE,CAAC;IAC3F,CAAC;IAED,IAAI,CAAC,SAAS,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;QAC9C,OAAO;YACL,QAAQ,EAAE,KAAK;YACf,MAAM,EACJ,4GAA4G;SAC/G,CAAC;IACJ,CAAC;IAED,MAAM,YAAY,GAAG,MAAM,iBAAiB,CAAC,cAAc,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;IAEhF,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;QAC1B,GAAG,CAAC,IAAI,CACN,0CAA0C,cAAc,IAAI,SAAS,CAAC,OAAO,6BAA6B,CAC3G,CAAC;QACF,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,6CAA6C,EAAE,CAAC;IACnF,CAAC;IAED,kEAAkE;IAClE,IAAI,SAAS,CAAC,SAAS,IAAI,YAAY,CAAC,SAAS,EAAE,CAAC;QAClD,IAAI,SAAS,CAAC,SAAS,KAAK,YAAY,CAAC,SAAS,EAAE,CAAC;YACnD,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QAC5B,CAAC;QACD,OAAO;YACL,QAAQ,EAAE,KAAK;YACf,MAAM,EAAE,iCAAiC,SAAS,CAAC,SAAS,cAAc,YAAY,CAAC,SAAS,EAAE;SACnG,CAAC;IACJ,CAAC;IAED,iCAAiC;IACjC,IAAI,SAAS,CAAC,MAAM,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;QAC5C,IAAI,SAAS,CAAC,MAAM,KAAK,YAAY,CAAC,MAAM,EAAE,CAAC;YAC7C,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QAC5B,CAAC;QACD,OAAO;YACL,QAAQ,EAAE,KAAK;YACf,MAAM,EAAE,8BAA8B,SAAS,CAAC,MAAM,cAAc,YAAY,CAAC,MAAM,EAAE;SAC1F,CAAC;IACJ,CAAC;IAED,wEAAwE;IACxE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,4EAA4E,EAAE,CAAC;AAClH,CAAC,CAAC;AAEF,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,CAAC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Outdated plugin version check.
3
+ *
4
+ * On startup, queries the npm registry for each npm-installed plugin
5
+ * to check if a newer version is available. Non-blocking — runs in
6
+ * the background and stores results in server state.
7
+ */
8
+ import type { ServerState } from './state.js';
9
+ /**
10
+ * Query the npm registry for the latest published version of a package.
11
+ * Uses the abbreviated install metadata endpoint with a 10s timeout.
12
+ *
13
+ * @param packageName - npm package name (e.g., 'opentabs-plugin-slack' or '@scope/opentabs-plugin-foo')
14
+ * @returns The latest version string from the registry's dist-tags, or null on failure
15
+ */
16
+ export declare const fetchLatestVersion: (packageName: string) => Promise<string | null>;
17
+ /**
18
+ * Compare two semver version strings (major.minor.patch only).
19
+ * Strips prerelease suffixes (e.g., "1.0.0-beta.1" → [1, 0, 0]) and leading 'v'
20
+ * prefixes so that version strings with hyphens don't produce NaN during parsing.
21
+ *
22
+ * @param current - The currently installed version string
23
+ * @param latest - The latest available version string
24
+ * @returns True if `latest` is strictly newer than `current`
25
+ */
26
+ export declare const isNewer: (current: string, latest: string) => boolean;
27
+ /**
28
+ * Check all npm-installed plugins for newer versions on the registry.
29
+ * Runs version checks in parallel, logs outdated entries, and stores
30
+ * results in `state.outdatedPlugins`. Skips local plugins (filesystem paths).
31
+ *
32
+ * @param state - Server state containing the plugin registry and outdatedPlugins target
33
+ */
34
+ export declare const checkForUpdates: (state: ServerState) => Promise<void>;
35
+ //# sourceMappingURL=version-check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version-check.d.ts","sourceRoot":"","sources":["../src/version-check.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAkB,MAAM,YAAY,CAAC;AAS9D;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,GAAU,aAAa,MAAM,KAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAoBnF,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,OAAO,GAAI,SAAS,MAAM,EAAE,QAAQ,MAAM,KAAG,OAqBzD,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,GAAU,OAAO,WAAW,KAAG,OAAO,CAAC,IAAI,CA8CtE,CAAC"}