@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
package/dist/loader.js ADDED
@@ -0,0 +1,402 @@
1
+ /**
2
+ * Plugin loader module.
3
+ *
4
+ * Reads plugin artifacts from a resolved directory: package.json (validated
5
+ * via parsePluginPackageJson), dist/adapter.iife.js, and dist/tools.json.
6
+ * Returns a Result so errors are explicitly propagated, not thrown.
7
+ *
8
+ * Pure function: takes a directory path and trust tier, reads files, validates,
9
+ * returns a Result. No side effects, no state mutation.
10
+ */
11
+ import { browserTools } from './browser-tools/index.js';
12
+ import { log } from './logger.js';
13
+ import { sdkVersion as serverSdkVersion } from './sdk-version.js';
14
+ import { err, ok, parsePluginPackageJson, validatePluginName, validateUrlPattern } from '@opentabs-dev/shared';
15
+ import { join } from 'node:path';
16
+ /** Maximum allowed size for the adapter IIFE (5 MB) */
17
+ const MAX_IIFE_SIZE = 5 * 1024 * 1024;
18
+ /**
19
+ * Extract the internal plugin name from an npm package name.
20
+ * opentabs-plugin-slack → slack
21
+ * @myorg/opentabs-plugin-jira → myorg-jira
22
+ */
23
+ const pluginNameFromPackage = (pkgName) => {
24
+ if (pkgName.startsWith('@')) {
25
+ const parts = pkgName.split('/');
26
+ const scopePart = parts[0] ?? '';
27
+ const namePart = parts[1] ?? '';
28
+ const scope = scopePart.slice(1);
29
+ const pluginSuffix = namePart.replace(/^opentabs-plugin-/, '');
30
+ return `${scope}-${pluginSuffix}`;
31
+ }
32
+ return pkgName.replace(/^opentabs-plugin-/, '');
33
+ };
34
+ /**
35
+ * Browser tool names that should not appear in plugin tool descriptions.
36
+ * Presence of these names may indicate a prompt injection attempt where
37
+ * a plugin tries to instruct the AI agent to invoke browser-level tools.
38
+ */
39
+ const BROWSER_TOOL_NAMES = browserTools.map(t => t.name);
40
+ /**
41
+ * Check plugin tool descriptions for references to browser tool names.
42
+ * Returns an array of { toolName, browserToolName } for each match found.
43
+ */
44
+ const checkBrowserToolReferences = (tools) => {
45
+ const matches = [];
46
+ for (const tool of tools) {
47
+ const descLower = tool.description.toLowerCase();
48
+ for (const btName of BROWSER_TOOL_NAMES) {
49
+ if (descLower.includes(btName)) {
50
+ matches.push({ toolName: tool.name, browserToolName: btName });
51
+ }
52
+ }
53
+ }
54
+ return matches;
55
+ };
56
+ /**
57
+ * Validate an array of tool definitions from dist/tools.json.
58
+ * Each tool must have name, displayName, description, icon, input_schema, output_schema.
59
+ */
60
+ const validateTools = (tools, sourcePath) => {
61
+ if (!Array.isArray(tools)) {
62
+ return err(`Invalid tools.json at ${sourcePath}: expected an array`);
63
+ }
64
+ const validated = [];
65
+ for (let i = 0; i < tools.length; i++) {
66
+ const raw = tools[i];
67
+ if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {
68
+ return err(`Invalid tools.json at ${sourcePath}: tools[${i}] must be an object`);
69
+ }
70
+ const toolRecord = raw;
71
+ const name = toolRecord.name;
72
+ if (typeof name !== 'string' || name.length === 0) {
73
+ return err(`Invalid tools.json at ${sourcePath}: tools[${i}].name must be a non-empty string`);
74
+ }
75
+ const displayName = toolRecord.displayName;
76
+ if (typeof displayName !== 'string' || displayName.length === 0) {
77
+ return err(`Invalid tools.json at ${sourcePath}: tools[${i}].displayName must be a non-empty string`);
78
+ }
79
+ const description = toolRecord.description;
80
+ if (typeof description !== 'string' || description.length === 0) {
81
+ return err(`Invalid tools.json at ${sourcePath}: tools[${i}].description must be a non-empty string`);
82
+ }
83
+ if (description.length > 1000) {
84
+ return err(`Invalid tools.json at ${sourcePath}: tools[${i}].description must be at most 1000 characters`);
85
+ }
86
+ const icon = toolRecord.icon;
87
+ if (typeof icon !== 'string' || icon.length === 0) {
88
+ return err(`Invalid tools.json at ${sourcePath}: tools[${i}].icon must be a non-empty string`);
89
+ }
90
+ // Optional SVG icons
91
+ const iconSvg = typeof toolRecord.iconSvg === 'string' ? toolRecord.iconSvg : undefined;
92
+ const iconInactiveSvg = typeof toolRecord.iconInactiveSvg === 'string' ? toolRecord.iconInactiveSvg : undefined;
93
+ const inputSchema = toolRecord.input_schema;
94
+ if (typeof inputSchema !== 'object' || inputSchema === null || Array.isArray(inputSchema)) {
95
+ return err(`Invalid tools.json at ${sourcePath}: tools[${i}].input_schema must be an object`);
96
+ }
97
+ const outputSchema = toolRecord.output_schema;
98
+ if (typeof outputSchema !== 'object' || outputSchema === null || Array.isArray(outputSchema)) {
99
+ return err(`Invalid tools.json at ${sourcePath}: tools[${i}].output_schema must be an object`);
100
+ }
101
+ validated.push({
102
+ name,
103
+ displayName,
104
+ description,
105
+ icon,
106
+ iconSvg,
107
+ iconInactiveSvg,
108
+ input_schema: inputSchema,
109
+ output_schema: outputSchema,
110
+ });
111
+ }
112
+ return ok(validated);
113
+ };
114
+ /**
115
+ * Validate an array of resource definitions from dist/tools.json.
116
+ * Invalid entries are filtered out with a warning, not a hard failure.
117
+ */
118
+ const validateResources = (resources, pluginName, sourcePath) => {
119
+ const validated = [];
120
+ for (let i = 0; i < resources.length; i++) {
121
+ const raw = resources[i];
122
+ if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {
123
+ log.warn(`Plugin "${pluginName}" resources[${i}] at ${sourcePath} is not an object — skipping`);
124
+ continue;
125
+ }
126
+ const r = raw;
127
+ if (typeof r.uri !== 'string' || r.uri.length === 0) {
128
+ log.warn(`Plugin "${pluginName}" resources[${i}] at ${sourcePath} has invalid uri — skipping`);
129
+ continue;
130
+ }
131
+ if (typeof r.name !== 'string' || r.name.length === 0) {
132
+ log.warn(`Plugin "${pluginName}" resources[${i}] at ${sourcePath} has invalid name — skipping`);
133
+ continue;
134
+ }
135
+ if (r.description !== undefined && typeof r.description !== 'string') {
136
+ log.warn(`Plugin "${pluginName}" resources[${i}] at ${sourcePath} has invalid description — skipping`);
137
+ continue;
138
+ }
139
+ if (r.mimeType !== undefined && typeof r.mimeType !== 'string') {
140
+ log.warn(`Plugin "${pluginName}" resources[${i}] at ${sourcePath} has invalid mimeType — skipping`);
141
+ continue;
142
+ }
143
+ validated.push({
144
+ uri: r.uri,
145
+ name: r.name,
146
+ description: typeof r.description === 'string' ? r.description : undefined,
147
+ mimeType: typeof r.mimeType === 'string' ? r.mimeType : undefined,
148
+ });
149
+ }
150
+ return validated;
151
+ };
152
+ /**
153
+ * Validate an array of prompt definitions from dist/tools.json.
154
+ * Invalid entries are filtered out with a warning, not a hard failure.
155
+ */
156
+ const validatePrompts = (prompts, pluginName, sourcePath) => {
157
+ const validated = [];
158
+ for (let i = 0; i < prompts.length; i++) {
159
+ const raw = prompts[i];
160
+ if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {
161
+ log.warn(`Plugin "${pluginName}" prompts[${i}] at ${sourcePath} is not an object — skipping`);
162
+ continue;
163
+ }
164
+ const p = raw;
165
+ if (typeof p.name !== 'string' || p.name.length === 0) {
166
+ log.warn(`Plugin "${pluginName}" prompts[${i}] at ${sourcePath} has invalid name — skipping`);
167
+ continue;
168
+ }
169
+ if (p.description !== undefined && typeof p.description !== 'string') {
170
+ log.warn(`Plugin "${pluginName}" prompts[${i}] at ${sourcePath} has invalid description — skipping`);
171
+ continue;
172
+ }
173
+ if (p.arguments !== undefined && !Array.isArray(p.arguments)) {
174
+ log.warn(`Plugin "${pluginName}" prompts[${i}] at ${sourcePath} has invalid arguments — skipping`);
175
+ continue;
176
+ }
177
+ validated.push({
178
+ name: p.name,
179
+ description: typeof p.description === 'string' ? p.description : undefined,
180
+ arguments: Array.isArray(p.arguments)
181
+ ? validatePromptArguments(p.arguments, pluginName, i, sourcePath)
182
+ : undefined,
183
+ });
184
+ }
185
+ return validated;
186
+ };
187
+ /**
188
+ * Validate prompt arguments within a prompt entry.
189
+ * Invalid arguments are filtered out with a warning.
190
+ */
191
+ const validatePromptArguments = (args, pluginName, promptIndex, sourcePath) => {
192
+ const validated = [];
193
+ for (let j = 0; j < args.length; j++) {
194
+ const raw = args[j];
195
+ if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {
196
+ log.warn(`Plugin "${pluginName}" prompts[${promptIndex}].arguments[${j}] at ${sourcePath} is not an object — skipping`);
197
+ continue;
198
+ }
199
+ const a = raw;
200
+ if (typeof a.name !== 'string' || a.name.length === 0) {
201
+ log.warn(`Plugin "${pluginName}" prompts[${promptIndex}].arguments[${j}] at ${sourcePath} has invalid name — skipping`);
202
+ continue;
203
+ }
204
+ validated.push({
205
+ name: a.name,
206
+ description: typeof a.description === 'string' ? a.description : undefined,
207
+ required: typeof a.required === 'boolean' ? a.required : undefined,
208
+ });
209
+ }
210
+ return validated;
211
+ };
212
+ /**
213
+ * Compute SHA-256 hex hash of content using the Web Crypto API.
214
+ */
215
+ const computeHash = async (content) => {
216
+ const encoded = new TextEncoder().encode(content);
217
+ const hashBuffer = await crypto.subtle.digest('SHA-256', encoded);
218
+ const hashArray = new Uint8Array(hashBuffer);
219
+ return Array.from(hashArray)
220
+ .map(byte => byte.toString(16).padStart(2, '0'))
221
+ .join('');
222
+ };
223
+ /**
224
+ * Parse a semver string into [major, minor] components.
225
+ * Returns null if the string is not a valid semver-like version.
226
+ */
227
+ const parseMajorMinor = (version) => {
228
+ const match = version.match(/^(\d+)\.(\d+)\.\d+/);
229
+ if (!match)
230
+ return null;
231
+ return [Number(match[1]), Number(match[2])];
232
+ };
233
+ /**
234
+ * Check SDK version compatibility between a plugin and the server.
235
+ *
236
+ * Compatibility rule: the plugin's sdkVersion major.minor must be <= the
237
+ * server's SDK major.minor. A plugin built with a newer SDK than the server
238
+ * might use APIs the server doesn't have. A plugin built with an older SDK
239
+ * is assumed backward-compatible.
240
+ */
241
+ const checkSdkCompatibility = (pluginSdkVersion, currentServerSdkVersion) => {
242
+ if (pluginSdkVersion === undefined) {
243
+ return { compatible: true };
244
+ }
245
+ const pluginMM = parseMajorMinor(pluginSdkVersion);
246
+ if (!pluginMM) {
247
+ return { compatible: true };
248
+ }
249
+ const serverMM = parseMajorMinor(currentServerSdkVersion);
250
+ if (!serverMM) {
251
+ return { compatible: true };
252
+ }
253
+ const [pluginMajor, pluginMinor] = pluginMM;
254
+ const [serverMajor, serverMinor] = serverMM;
255
+ if (pluginMajor > serverMajor || (pluginMajor === serverMajor && pluginMinor > serverMinor)) {
256
+ return {
257
+ compatible: false,
258
+ error: `Plugin built with SDK ${pluginSdkVersion}, server has SDK ${currentServerSdkVersion}`,
259
+ };
260
+ }
261
+ return { compatible: true };
262
+ };
263
+ /**
264
+ * Load a plugin from a resolved directory.
265
+ *
266
+ * Reads package.json (validated via parsePluginPackageJson), dist/adapter.iife.js,
267
+ * and dist/tools.json. Derives the internal plugin name from the npm package name.
268
+ *
269
+ * @param dir - Absolute path to the plugin directory containing package.json
270
+ * @param trustTier - Trust classification for this plugin
271
+ * @param source - How the plugin was discovered: 'npm' or 'local'
272
+ */
273
+ const loadPlugin = async (dir, trustTier, source) => {
274
+ // Read and validate package.json
275
+ const pkgJsonPath = join(dir, 'package.json');
276
+ let pkgJsonRaw;
277
+ try {
278
+ pkgJsonRaw = await Bun.file(pkgJsonPath).json();
279
+ }
280
+ catch {
281
+ return err(`Failed to read package.json at ${dir}: file missing or invalid JSON`);
282
+ }
283
+ const pkgResult = parsePluginPackageJson(pkgJsonRaw, dir);
284
+ if (!pkgResult.ok) {
285
+ return err(pkgResult.error);
286
+ }
287
+ const pkg = pkgResult.value;
288
+ // Derive internal plugin name from npm package name
289
+ const pluginName = pluginNameFromPackage(pkg.name);
290
+ const nameError = validatePluginName(pluginName);
291
+ if (nameError) {
292
+ return err(`Invalid plugin name derived from "${pkg.name}" at ${dir}: ${nameError}`);
293
+ }
294
+ // Validate URL patterns
295
+ for (const pattern of pkg.opentabs.urlPatterns) {
296
+ const patternError = validateUrlPattern(pattern);
297
+ if (patternError) {
298
+ return err(`Invalid URL pattern in ${dir}: ${patternError}`);
299
+ }
300
+ }
301
+ // Read adapter IIFE
302
+ const iifePath = join(dir, 'dist', 'adapter.iife.js');
303
+ const iifeFile = Bun.file(iifePath);
304
+ if (!(await iifeFile.exists())) {
305
+ return err(`Adapter IIFE not found at ${iifePath}`);
306
+ }
307
+ const iifeSize = iifeFile.size;
308
+ if (iifeSize > MAX_IIFE_SIZE) {
309
+ return err(`Adapter IIFE for "${pluginName}" is ${(iifeSize / 1024 / 1024).toFixed(1)}MB, exceeding the 5MB limit`);
310
+ }
311
+ const iife = await iifeFile.text();
312
+ if (iife.length === 0) {
313
+ return err(`Adapter IIFE at ${iifePath} is empty — rebuild the plugin`);
314
+ }
315
+ // Read and validate tools.json
316
+ // Supports two formats:
317
+ // - Legacy: a plain array of tool definitions (pre-resources/prompts)
318
+ // - Current: { tools: [...], resources: [...], prompts: [...] }
319
+ const toolsJsonPath = join(dir, 'dist', 'tools.json');
320
+ let manifestRaw;
321
+ try {
322
+ manifestRaw = await Bun.file(toolsJsonPath).json();
323
+ }
324
+ catch {
325
+ return err(`Failed to read dist/tools.json at ${dir}: file missing or invalid JSON`);
326
+ }
327
+ // Extract the tools array from either format
328
+ const manifestObj = typeof manifestRaw === 'object' && manifestRaw !== null && !Array.isArray(manifestRaw)
329
+ ? manifestRaw
330
+ : null;
331
+ const toolsArray = Array.isArray(manifestRaw)
332
+ ? manifestRaw
333
+ : manifestObj && 'tools' in manifestObj
334
+ ? manifestObj.tools
335
+ : manifestRaw;
336
+ const toolsResult = validateTools(toolsArray, dir);
337
+ if (!toolsResult.ok) {
338
+ return err(toolsResult.error);
339
+ }
340
+ const tools = toolsResult.value;
341
+ // Extract and validate resources and prompts (default to [] for legacy format)
342
+ const resources = manifestObj && Array.isArray(manifestObj.resources)
343
+ ? validateResources(manifestObj.resources, pluginName, dir)
344
+ : [];
345
+ const prompts = manifestObj && Array.isArray(manifestObj.prompts)
346
+ ? validatePrompts(manifestObj.prompts, pluginName, dir)
347
+ : [];
348
+ // Extract sdkVersion and check compatibility
349
+ const pluginSdkVersion = manifestObj && typeof manifestObj.sdkVersion === 'string' ? manifestObj.sdkVersion : undefined;
350
+ if (pluginSdkVersion === undefined) {
351
+ log.warn(`Plugin "${pluginName}" does not declare sdkVersion — skipping compatibility check`);
352
+ }
353
+ else {
354
+ const compat = checkSdkCompatibility(pluginSdkVersion, serverSdkVersion);
355
+ if (!compat.compatible && compat.error) {
356
+ return err(`${compat.error}. Rebuild the plugin: cd ${dir} && bun install && bun run build`);
357
+ }
358
+ }
359
+ // Warn about browser tool references in tool descriptions (prompt injection detection)
360
+ for (const match of checkBrowserToolReferences(tools)) {
361
+ log.warn(`Plugin "${pluginName}" tool "${match.toolName}" description references browser tool "${match.browserToolName}" — possible prompt injection attempt`);
362
+ }
363
+ // Compute adapter hash from IIFE content
364
+ const adapterHash = await computeHash(iife);
365
+ // Read source map if available (optional — older plugins won't have one)
366
+ const sourceMapPath = join(dir, 'dist', 'adapter.iife.js.map');
367
+ let iifeSourceMap;
368
+ try {
369
+ const sourceMapFile = Bun.file(sourceMapPath);
370
+ if (await sourceMapFile.exists()) {
371
+ iifeSourceMap = await sourceMapFile.text();
372
+ }
373
+ }
374
+ catch {
375
+ // Source map not available — not an error
376
+ }
377
+ // Extract optional SVG icons from manifest
378
+ const iconSvg = manifestObj && typeof manifestObj.iconSvg === 'string' ? manifestObj.iconSvg : undefined;
379
+ const iconInactiveSvg = manifestObj && typeof manifestObj.iconInactiveSvg === 'string' ? manifestObj.iconInactiveSvg : undefined;
380
+ return ok({
381
+ name: pluginName,
382
+ version: pkg.version,
383
+ displayName: pkg.opentabs.displayName,
384
+ description: pkg.opentabs.description,
385
+ urlPatterns: pkg.opentabs.urlPatterns,
386
+ trustTier,
387
+ iife,
388
+ tools,
389
+ resources,
390
+ prompts,
391
+ source,
392
+ sourcePath: dir,
393
+ adapterHash,
394
+ npmPackageName: pkg.name,
395
+ sdkVersion: pluginSdkVersion,
396
+ iifeSourceMap,
397
+ iconSvg,
398
+ iconInactiveSvg,
399
+ });
400
+ };
401
+ export { checkBrowserToolReferences, checkSdkCompatibility, loadPlugin, parseMajorMinor, pluginNameFromPackage, validatePrompts, validateResources, validateTools, };
402
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Per-plugin circular log buffer.
3
+ *
4
+ * Stores the most recent log entries from plugin adapters, keyed by plugin name.
5
+ * Each plugin gets its own fixed-size ring buffer that overwrites oldest entries
6
+ * when full. The buffer is used for:
7
+ * 1. Forwarding log entries to MCP clients via sendLoggingMessage
8
+ * 2. Surfacing log counts in the /health endpoint
9
+ */
10
+ /** A single buffered plugin log entry */
11
+ interface PluginLogEntry {
12
+ level: string;
13
+ plugin: string;
14
+ message: string;
15
+ data: unknown;
16
+ ts: string;
17
+ }
18
+ /** Append a log entry to a plugin's ring buffer */
19
+ declare const appendLog: (plugin: string, entry: PluginLogEntry) => void;
20
+ /**
21
+ * Retrieve recent log entries for a plugin, oldest first.
22
+ * Returns at most `limit` entries (defaults to all buffered entries).
23
+ */
24
+ declare const getLogs: (plugin: string, limit?: number) => PluginLogEntry[];
25
+ /** Get the number of buffered entries for a plugin */
26
+ declare const getLogCount: (plugin: string) => number;
27
+ /** Get all plugin names that have buffered entries */
28
+ declare const getBufferedPlugins: () => string[];
29
+ /** Clear all buffered entries (used during testing or state reset) */
30
+ declare const clearAllLogs: () => void;
31
+ export { appendLog, clearAllLogs, getBufferedPlugins, getLogCount, getLogs };
32
+ export type { PluginLogEntry };
33
+ //# sourceMappingURL=log-buffer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-buffer.d.ts","sourceRoot":"","sources":["../src/log-buffer.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,yCAAyC;AACzC,UAAU,cAAc;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;CACZ;AAkBD,mDAAmD;AACnD,QAAA,MAAM,SAAS,GAAI,QAAQ,MAAM,EAAE,OAAO,cAAc,KAAG,IAY1D,CAAC;AAEF;;;GAGG;AACH,QAAA,MAAM,OAAO,GAAI,QAAQ,MAAM,EAAE,QAAQ,MAAM,KAAG,cAAc,EAmB/D,CAAC;AAEF,sDAAsD;AACtD,QAAA,MAAM,WAAW,GAAI,QAAQ,MAAM,KAAG,MAAwC,CAAC;AAE/E,sDAAsD;AACtD,QAAA,MAAM,kBAAkB,QAAO,MAAM,EAAgC,CAAC;AAEtE,sEAAsE;AACtE,QAAA,MAAM,YAAY,QAAO,IAExB,CAAC;AAEF,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,kBAAkB,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;AAC7E,YAAY,EAAE,cAAc,EAAE,CAAC"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Per-plugin circular log buffer.
3
+ *
4
+ * Stores the most recent log entries from plugin adapters, keyed by plugin name.
5
+ * Each plugin gets its own fixed-size ring buffer that overwrites oldest entries
6
+ * when full. The buffer is used for:
7
+ * 1. Forwarding log entries to MCP clients via sendLoggingMessage
8
+ * 2. Surfacing log counts in the /health endpoint
9
+ */
10
+ /** Maximum log entries retained per plugin */
11
+ const MAX_ENTRIES_PER_PLUGIN = 1000;
12
+ const createRingBuffer = () => ({
13
+ entries: new Array(MAX_ENTRIES_PER_PLUGIN).fill(undefined),
14
+ writeIndex: 0,
15
+ size: 0,
16
+ });
17
+ /** Per-plugin ring buffers */
18
+ const buffers = new Map();
19
+ /** Append a log entry to a plugin's ring buffer */
20
+ const appendLog = (plugin, entry) => {
21
+ let ring = buffers.get(plugin);
22
+ if (!ring) {
23
+ ring = createRingBuffer();
24
+ buffers.set(plugin, ring);
25
+ }
26
+ ring.entries[ring.writeIndex] = entry;
27
+ ring.writeIndex = (ring.writeIndex + 1) % MAX_ENTRIES_PER_PLUGIN;
28
+ if (ring.size < MAX_ENTRIES_PER_PLUGIN) {
29
+ ring.size++;
30
+ }
31
+ };
32
+ /**
33
+ * Retrieve recent log entries for a plugin, oldest first.
34
+ * Returns at most `limit` entries (defaults to all buffered entries).
35
+ */
36
+ const getLogs = (plugin, limit) => {
37
+ const ring = buffers.get(plugin);
38
+ if (!ring || ring.size === 0)
39
+ return [];
40
+ const cap = limit !== undefined && limit < ring.size ? limit : ring.size;
41
+ const result = [];
42
+ // Read from oldest to newest. When the buffer has wrapped, oldest is at writeIndex.
43
+ const startIndex = ring.size < MAX_ENTRIES_PER_PLUGIN ? 0 : ring.writeIndex;
44
+ const skip = ring.size - cap;
45
+ for (let i = 0; i < ring.size; i++) {
46
+ if (i < skip)
47
+ continue;
48
+ const idx = (startIndex + i) % MAX_ENTRIES_PER_PLUGIN;
49
+ const entry = ring.entries[idx];
50
+ if (entry)
51
+ result.push(entry);
52
+ }
53
+ return result;
54
+ };
55
+ /** Get the number of buffered entries for a plugin */
56
+ const getLogCount = (plugin) => buffers.get(plugin)?.size ?? 0;
57
+ /** Get all plugin names that have buffered entries */
58
+ const getBufferedPlugins = () => Array.from(buffers.keys());
59
+ /** Clear all buffered entries (used during testing or state reset) */
60
+ const clearAllLogs = () => {
61
+ buffers.clear();
62
+ };
63
+ export { appendLog, clearAllLogs, getBufferedPlugins, getLogCount, getLogs };
64
+ //# sourceMappingURL=log-buffer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-buffer.js","sourceRoot":"","sources":["../src/log-buffer.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,8CAA8C;AAC9C,MAAM,sBAAsB,GAAG,IAAI,CAAC;AAkBpC,MAAM,gBAAgB,GAAG,GAAe,EAAE,CAAC,CAAC;IAC1C,OAAO,EAAE,IAAI,KAAK,CAA6B,sBAAsB,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC;IACtF,UAAU,EAAE,CAAC;IACb,IAAI,EAAE,CAAC;CACR,CAAC,CAAC;AAEH,8BAA8B;AAC9B,MAAM,OAAO,GAAG,IAAI,GAAG,EAAsB,CAAC;AAE9C,mDAAmD;AACnD,MAAM,SAAS,GAAG,CAAC,MAAc,EAAE,KAAqB,EAAQ,EAAE;IAChE,IAAI,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC/B,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,IAAI,GAAG,gBAAgB,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC5B,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,KAAK,CAAC;IACtC,IAAI,CAAC,UAAU,GAAG,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,GAAG,sBAAsB,CAAC;IACjE,IAAI,IAAI,CAAC,IAAI,GAAG,sBAAsB,EAAE,CAAC;QACvC,IAAI,CAAC,IAAI,EAAE,CAAC;IACd,CAAC;AACH,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,OAAO,GAAG,CAAC,MAAc,EAAE,KAAc,EAAoB,EAAE;IACnE,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAExC,MAAM,GAAG,GAAG,KAAK,KAAK,SAAS,IAAI,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;IACzE,MAAM,MAAM,GAAqB,EAAE,CAAC;IAEpC,oFAAoF;IACpF,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC;IAC5E,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC;IAE7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,IAAI,CAAC,GAAG,IAAI;YAAE,SAAS;QACvB,MAAM,GAAG,GAAG,CAAC,UAAU,GAAG,CAAC,CAAC,GAAG,sBAAsB,CAAC;QACtD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAChC,IAAI,KAAK;YAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,sDAAsD;AACtD,MAAM,WAAW,GAAG,CAAC,MAAc,EAAU,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,IAAI,CAAC,CAAC;AAE/E,sDAAsD;AACtD,MAAM,kBAAkB,GAAG,GAAa,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;AAEtE,sEAAsE;AACtE,MAAM,YAAY,GAAG,GAAS,EAAE;IAC9B,OAAO,CAAC,KAAK,EAAE,CAAC;AAClB,CAAC,CAAC;AAEF,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,kBAAkB,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Lightweight structured logger with level filtering.
3
+ *
4
+ * All server log output flows through this module so that verbosity can be
5
+ * controlled via the OPENTABS_LOG_LEVEL environment variable:
6
+ *
7
+ * OPENTABS_LOG_LEVEL=debug — all messages (debug + info + warn + error)
8
+ * OPENTABS_LOG_LEVEL=info — info + warn + error (default)
9
+ * OPENTABS_LOG_LEVEL=warn — warn + error only
10
+ * OPENTABS_LOG_LEVEL=error — errors only
11
+ * OPENTABS_LOG_LEVEL=silent — suppress all output
12
+ *
13
+ * Each method prepends the [opentabs] tag automatically and detects Error
14
+ * instances passed as the last argument: at info/warn/error level, the Error
15
+ * is replaced with its message string; at debug level, the stack trace is
16
+ * appended. Callers should pass raw Error objects (not err.message) so the
17
+ * logger can format them appropriately per level.
18
+ *
19
+ * Hot reload safe: reads the env var once at module evaluation time. Under
20
+ * bun --hot, the module is re-evaluated on each reload, picking up any
21
+ * runtime changes to the environment variable.
22
+ */
23
+ declare const log: {
24
+ /** Verbose diagnostic output — suppressed by default */
25
+ debug: (...args: unknown[]) => void;
26
+ /** Normal operational messages */
27
+ info: (...args: unknown[]) => void;
28
+ /** Potential problems that don't prevent operation */
29
+ warn: (...args: unknown[]) => void;
30
+ /** Failures that affect functionality */
31
+ error: (...args: unknown[]) => void;
32
+ };
33
+ export { log };
34
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAuCH,QAAA,MAAM,GAAG;IACP,wDAAwD;qBACvC,OAAO,EAAE,KAAG,IAAI;IAMjC,kCAAkC;oBAClB,OAAO,EAAE,KAAG,IAAI;IAMhC,sDAAsD;oBACtC,OAAO,EAAE,KAAG,IAAI;IAMhC,yCAAyC;qBACxB,OAAO,EAAE,KAAG,IAAI;CAKlC,CAAC;AAEF,OAAO,EAAE,GAAG,EAAE,CAAC"}
package/dist/logger.js ADDED
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Lightweight structured logger with level filtering.
3
+ *
4
+ * All server log output flows through this module so that verbosity can be
5
+ * controlled via the OPENTABS_LOG_LEVEL environment variable:
6
+ *
7
+ * OPENTABS_LOG_LEVEL=debug — all messages (debug + info + warn + error)
8
+ * OPENTABS_LOG_LEVEL=info — info + warn + error (default)
9
+ * OPENTABS_LOG_LEVEL=warn — warn + error only
10
+ * OPENTABS_LOG_LEVEL=error — errors only
11
+ * OPENTABS_LOG_LEVEL=silent — suppress all output
12
+ *
13
+ * Each method prepends the [opentabs] tag automatically and detects Error
14
+ * instances passed as the last argument: at info/warn/error level, the Error
15
+ * is replaced with its message string; at debug level, the stack trace is
16
+ * appended. Callers should pass raw Error objects (not err.message) so the
17
+ * logger can format them appropriately per level.
18
+ *
19
+ * Hot reload safe: reads the env var once at module evaluation time. Under
20
+ * bun --hot, the module is re-evaluated on each reload, picking up any
21
+ * runtime changes to the environment variable.
22
+ */
23
+ const LEVELS = {
24
+ debug: 0,
25
+ info: 1,
26
+ warn: 2,
27
+ error: 3,
28
+ silent: 4,
29
+ };
30
+ const TAG = '[opentabs]';
31
+ /**
32
+ * Format log arguments, detecting Error instances as the last argument.
33
+ * At debug level (includeStack = true), appends the stack trace indented
34
+ * on the next line. At other levels, replaces the Error object with its
35
+ * message string so stack traces don't clutter normal output.
36
+ */
37
+ const formatArgs = (args, includeStack) => {
38
+ const last = args[args.length - 1];
39
+ if (last instanceof Error) {
40
+ const rest = args.slice(0, -1);
41
+ if (includeStack && last.stack) {
42
+ return [...rest, last.message + '\n ' + last.stack];
43
+ }
44
+ return [...rest, last.message];
45
+ }
46
+ return args;
47
+ };
48
+ const parseLevel = (raw) => {
49
+ if (raw && raw in LEVELS)
50
+ return raw;
51
+ return 'info';
52
+ };
53
+ const currentLevel = LEVELS[parseLevel(Bun.env.OPENTABS_LOG_LEVEL)];
54
+ const log = {
55
+ /** Verbose diagnostic output — suppressed by default */
56
+ debug: (...args) => {
57
+ if (currentLevel <= LEVELS.debug) {
58
+ console.debug(TAG, new Date().toISOString(), ...formatArgs(args, true));
59
+ }
60
+ },
61
+ /** Normal operational messages */
62
+ info: (...args) => {
63
+ if (currentLevel <= LEVELS.info) {
64
+ console.log(TAG, new Date().toISOString(), ...formatArgs(args, false));
65
+ }
66
+ },
67
+ /** Potential problems that don't prevent operation */
68
+ warn: (...args) => {
69
+ if (currentLevel <= LEVELS.warn) {
70
+ console.warn(TAG, new Date().toISOString(), ...formatArgs(args, false));
71
+ }
72
+ },
73
+ /** Failures that affect functionality */
74
+ error: (...args) => {
75
+ if (currentLevel <= LEVELS.error) {
76
+ console.error(TAG, new Date().toISOString(), ...formatArgs(args, false));
77
+ }
78
+ },
79
+ };
80
+ export { log };
81
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAIH,MAAM,MAAM,GAA6B;IACvC,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC;CACV,CAAC;AAEF,MAAM,GAAG,GAAG,YAAY,CAAC;AAEzB;;;;;GAKG;AACH,MAAM,UAAU,GAAG,CAAC,IAAe,EAAE,YAAqB,EAAa,EAAE;IACvE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACnC,IAAI,IAAI,YAAY,KAAK,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAI,YAAY,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC/B,OAAO,CAAC,GAAG,IAAI,EAAE,IAAI,CAAC,OAAO,GAAG,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QACvD,CAAC;QACD,OAAO,CAAC,GAAG,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,GAAuB,EAAY,EAAE;IACvD,IAAI,GAAG,IAAI,GAAG,IAAI,MAAM;QAAE,OAAO,GAAe,CAAC;IACjD,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC;AAEpE,MAAM,GAAG,GAAG;IACV,wDAAwD;IACxD,KAAK,EAAE,CAAC,GAAG,IAAe,EAAQ,EAAE;QAClC,IAAI,YAAY,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACjC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,GAAG,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QAC1E,CAAC;IACH,CAAC;IAED,kCAAkC;IAClC,IAAI,EAAE,CAAC,GAAG,IAAe,EAAQ,EAAE;QACjC,IAAI,YAAY,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,GAAG,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;IAED,sDAAsD;IACtD,IAAI,EAAE,CAAC,GAAG,IAAe,EAAQ,EAAE;QACjC,IAAI,YAAY,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YAChC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,GAAG,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;QAC1E,CAAC;IACH,CAAC;IAED,yCAAyC;IACzC,KAAK,EAAE,CAAC,GAAG,IAAe,EAAQ,EAAE;QAClC,IAAI,YAAY,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACjC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,GAAG,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC;CACF,CAAC;AAEF,OAAO,EAAE,GAAG,EAAE,CAAC"}