@jshookmcp/jshook 0.2.2 → 0.2.5

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 (414) hide show
  1. package/LICENSE +661 -661
  2. package/README.md +15 -6
  3. package/README.zh.md +19 -4
  4. package/dist/native/scripts/linux/enum-windows.sh +12 -12
  5. package/dist/native/scripts/macos/enum-windows.applescript +22 -22
  6. package/dist/native/scripts/windows/enum-windows-by-class.ps1 +51 -51
  7. package/dist/native/scripts/windows/enum-windows.ps1 +44 -44
  8. package/dist/native/scripts/windows/inject-dll.ps1 +21 -21
  9. package/dist/packages/extension-sdk/src/bridges/shared.js +2 -2
  10. package/dist/packages/extension-sdk/src/plugin.d.ts +5 -0
  11. package/dist/packages/extension-sdk/src/plugin.js +119 -33
  12. package/dist/packages/extension-sdk/src/workflow.d.ts +156 -0
  13. package/dist/packages/extension-sdk/src/workflow.js +236 -0
  14. package/dist/src/config/search-defaults.js +161 -0
  15. package/dist/src/constants.d.ts +3 -0
  16. package/dist/src/constants.js +4 -1
  17. package/dist/src/index.d.ts +1 -1
  18. package/dist/src/index.js +13 -17
  19. package/dist/src/modules/analyzer/CodeAnalyzer.d.ts +1 -3
  20. package/dist/src/modules/analyzer/CodeAnalyzer.js +16 -28
  21. package/dist/src/modules/analyzer/CodeAnalyzerDataFlow.d.ts +1 -2
  22. package/dist/src/modules/analyzer/CodeAnalyzerDataFlow.js +1 -45
  23. package/dist/src/modules/analyzer/IntelligentAnalyzer.d.ts +1 -37
  24. package/dist/src/modules/analyzer/IntelligentAnalyzer.js +9 -142
  25. package/dist/src/modules/analyzer/PatternDetector.js +3 -3
  26. package/dist/src/modules/analyzer/PatternDetectorAuthPatterns.js +1 -1
  27. package/dist/src/modules/browser/BrowserDiscovery.d.ts +6 -5
  28. package/dist/src/modules/browser/BrowserDiscovery.js +3 -3
  29. package/dist/src/modules/browser/BrowserModeManager.d.ts +1 -1
  30. package/dist/src/modules/browser/BrowserModeManager.js +11 -10
  31. package/dist/src/modules/browser/TabRegistry.js +2 -2
  32. package/dist/src/modules/browser/UnifiedBrowserManager.d.ts +1 -0
  33. package/dist/src/modules/browser/UnifiedBrowserManager.js +19 -4
  34. package/dist/src/modules/captcha/AICaptchaDetector.d.ts +14 -23
  35. package/dist/src/modules/captcha/AICaptchaDetector.js +8 -202
  36. package/dist/src/modules/captcha/CaptchaDetector.d.ts +31 -17
  37. package/dist/src/modules/captcha/CaptchaDetector.js +1 -1
  38. package/dist/src/modules/collector/CodeCache.d.ts +2 -2
  39. package/dist/src/modules/collector/CodeCollector.d.ts +12 -9
  40. package/dist/src/modules/collector/CodeCollector.js +5 -6
  41. package/dist/src/modules/collector/DOMInspector.d.ts +3 -2
  42. package/dist/src/modules/collector/DOMInspector.js +49 -59
  43. package/dist/src/modules/collector/PageController.d.ts +17 -4
  44. package/dist/src/modules/collector/PageController.js +2 -5
  45. package/dist/src/modules/collector/PageScriptCollectors.js +3 -3
  46. package/dist/src/modules/crypto/CryptoDetector.d.ts +1 -4
  47. package/dist/src/modules/crypto/CryptoDetector.js +2 -42
  48. package/dist/src/modules/crypto/CryptoRules.js +1 -1
  49. package/dist/src/modules/debugger/BlackboxManager.js +1 -1
  50. package/dist/src/modules/debugger/DebuggerManager.impl.core.scope.js +1 -1
  51. package/dist/src/modules/debugger/ScriptManager.impl.extract-function-tree.js +5 -3
  52. package/dist/src/modules/debugger/WatchExpressionManager.js +1 -1
  53. package/dist/src/modules/deobfuscator/Deobfuscator.d.ts +1 -4
  54. package/dist/src/modules/deobfuscator/Deobfuscator.js +4 -39
  55. package/dist/src/modules/deobfuscator/JSVMPDeobfuscator.d.ts +0 -3
  56. package/dist/src/modules/deobfuscator/JSVMPDeobfuscator.js +2 -8
  57. package/dist/src/modules/deobfuscator/JSVMPDeobfuscator.restore.d.ts +2 -3
  58. package/dist/src/modules/deobfuscator/JSVMPDeobfuscator.restore.js +5 -57
  59. package/dist/src/modules/deobfuscator/JScramblerDeobfuscator.js +3 -4
  60. package/dist/src/modules/deobfuscator/PackerDeobfuscator.js +1 -1
  61. package/dist/src/modules/deobfuscator/VMDeobfuscator.d.ts +2 -10
  62. package/dist/src/modules/deobfuscator/VMDeobfuscator.js +3 -128
  63. package/dist/src/modules/deobfuscator/webcrack.js +15 -2
  64. package/dist/src/modules/emulator/AIEnvironmentAnalyzer.d.ts +5 -8
  65. package/dist/src/modules/emulator/AIEnvironmentAnalyzer.js +10 -102
  66. package/dist/src/modules/emulator/EnvironmentEmulator.d.ts +1 -5
  67. package/dist/src/modules/emulator/EnvironmentEmulator.js +7 -91
  68. package/dist/src/modules/emulator/EnvironmentEmulatorFetch.js +58 -61
  69. package/dist/src/modules/emulator/templates/chrome-env.d.ts +17 -7
  70. package/dist/src/modules/emulator/templates/chrome-env.js +14 -7
  71. package/dist/src/modules/external/ExternalToolRunner.d.ts +1 -1
  72. package/dist/src/modules/external/ExternalToolRunner.js +26 -23
  73. package/dist/src/modules/monitor/ConsoleMonitor.impl.core.class.d.ts +13 -0
  74. package/dist/src/modules/monitor/ConsoleMonitor.impl.core.class.js +42 -0
  75. package/dist/src/modules/monitor/FetchInterceptor.d.ts +46 -0
  76. package/dist/src/modules/monitor/FetchInterceptor.js +191 -0
  77. package/dist/src/modules/monitor/PerformanceMonitor.js +8 -7
  78. package/dist/src/modules/process/BaseMemoryManager.d.ts +1 -1
  79. package/dist/src/modules/process/LinuxProcessManager.js +4 -2
  80. package/dist/src/modules/process/MacProcessManager.js +1 -1
  81. package/dist/src/modules/process/MemoryManager.d.ts +1 -1
  82. package/dist/src/modules/process/MemoryManager.js +2 -2
  83. package/dist/src/modules/process/ProcessManager.impl.js +1 -1
  84. package/dist/src/modules/process/memory/AuditTrail.js +1 -1
  85. package/dist/src/modules/process/memory/reader.js +35 -3
  86. package/dist/src/modules/process/memory/regions.enumerate.js +1 -1
  87. package/dist/src/modules/process/memory/regions.protection.js +42 -9
  88. package/dist/src/modules/process/memory/scanner.d.ts +5 -1
  89. package/dist/src/modules/process/memory/scanner.darwin.js +57 -0
  90. package/dist/src/modules/process/memory/scanner.js +88 -4
  91. package/dist/src/modules/process/memory/writer.js +44 -4
  92. package/dist/src/modules/security/ExecutionSandbox.js +7 -8
  93. package/dist/src/modules/stealth/FingerprintManager.js +1 -1
  94. package/dist/src/modules/stealth/StealthScripts.d.ts +4 -2
  95. package/dist/src/modules/stealth/StealthScripts.js +53 -14
  96. package/dist/src/modules/stealth/StealthVerifier.d.ts +1 -1
  97. package/dist/src/modules/stealth/StealthVerifier.js +2 -4
  98. package/dist/src/modules/symbolic/JSVMPSymbolicExecutor.d.ts +14 -0
  99. package/dist/src/modules/symbolic/JSVMPSymbolicExecutor.js +181 -2
  100. package/dist/src/modules/trace/TraceDB.js +12 -6
  101. package/dist/src/modules/trace/TraceRecorder.js +1 -5
  102. package/dist/src/native/AntiCheatDetector.js +67 -16
  103. package/dist/src/native/CodeInjector.js +4 -4
  104. package/dist/src/native/HardwareBreakpoint.js +25 -16
  105. package/dist/src/native/HeapAnalyzer.js +2 -2
  106. package/dist/src/native/MemoryController.js +1 -1
  107. package/dist/src/native/MemoryScanSession.js +2 -2
  108. package/dist/src/native/MemoryScanner.js +4 -8
  109. package/dist/src/native/NativeMemoryManager.impl.js +2 -2
  110. package/dist/src/native/PEAnalyzer.js +14 -15
  111. package/dist/src/native/PointerChainEngine.js +2 -4
  112. package/dist/src/native/ScriptLoader.js +4 -9
  113. package/dist/src/native/Speedhack.js +1 -1
  114. package/dist/src/native/StructureAnalyzer.js +52 -33
  115. package/dist/src/native/Win32API.d.ts +1 -0
  116. package/dist/src/native/Win32API.js +13 -0
  117. package/dist/src/native/Win32Debug.js +19 -19
  118. package/dist/src/native/platform/darwin/DarwinAPI.d.ts +2 -0
  119. package/dist/src/native/platform/darwin/DarwinAPI.js +8 -0
  120. package/dist/src/native/platform/darwin/DarwinMemoryProvider.js +6 -1
  121. package/dist/src/server/MCPServer.context.d.ts +2 -1
  122. package/dist/src/server/MCPServer.d.ts +2 -1
  123. package/dist/src/server/MCPServer.domain.d.ts +1 -1
  124. package/dist/src/server/MCPServer.domain.js +81 -16
  125. package/dist/src/server/MCPServer.js +42 -14
  126. package/dist/src/server/MCPServer.resources.d.ts +2 -0
  127. package/dist/src/server/MCPServer.resources.js +91 -0
  128. package/dist/src/server/MCPServer.search.handlers.call.js +2 -1
  129. package/dist/src/server/MCPServer.search.helpers.js +2 -2
  130. package/dist/src/server/MCPServer.tools.js +1 -1
  131. package/dist/src/server/MCPServer.transport.js +12 -0
  132. package/dist/src/server/ToolCallContextGuard.d.ts +5 -0
  133. package/dist/src/server/ToolCallContextGuard.js +85 -0
  134. package/dist/src/server/ToolRouter.d.ts +26 -10
  135. package/dist/src/server/ToolRouter.intent.d.ts +26 -0
  136. package/dist/src/server/ToolRouter.intent.js +77 -0
  137. package/dist/src/server/ToolRouter.js +103 -284
  138. package/dist/src/server/ToolRouter.policy.d.ts +22 -0
  139. package/dist/src/server/ToolRouter.policy.js +163 -0
  140. package/dist/src/server/ToolRouter.probe.d.ts +17 -0
  141. package/dist/src/server/ToolRouter.probe.js +103 -0
  142. package/dist/src/server/ToolRouter.renderer.d.ts +9 -0
  143. package/dist/src/server/ToolRouter.renderer.js +52 -0
  144. package/dist/src/server/activation/ActivationController.js +15 -12
  145. package/dist/src/server/activation/CompoundConditionEngine.js +1 -1
  146. package/dist/src/server/activation/PredictiveBooster.js +1 -3
  147. package/dist/src/server/domains/analysis/definitions.js +155 -655
  148. package/dist/src/server/domains/analysis/handlers.impl.d.ts +8 -8
  149. package/dist/src/server/domains/analysis/handlers.impl.js +34 -28
  150. package/dist/src/server/domains/analysis/handlers.web-tools.js +4 -3
  151. package/dist/src/server/domains/analysis/manifest.js +6 -4
  152. package/dist/src/server/domains/antidebug/definitions.js +25 -111
  153. package/dist/src/server/domains/browser/definitions.tools.advanced.js +59 -88
  154. package/dist/src/server/domains/browser/definitions.tools.behavior.js +120 -227
  155. package/dist/src/server/domains/browser/definitions.tools.page-core.js +157 -386
  156. package/dist/src/server/domains/browser/definitions.tools.page-system.js +108 -250
  157. package/dist/src/server/domains/browser/definitions.tools.runtime.js +61 -174
  158. package/dist/src/server/domains/browser/definitions.tools.security.js +92 -237
  159. package/dist/src/server/domains/browser/handlers/camoufox-browser.js +3 -2
  160. package/dist/src/server/domains/browser/handlers/captcha-solver.js +3 -3
  161. package/dist/src/server/domains/browser/handlers/dom-query.js +2 -1
  162. package/dist/src/server/domains/browser/handlers/facade-initializer.d.ts +3 -3
  163. package/dist/src/server/domains/browser/handlers/facade-initializer.js +3 -3
  164. package/dist/src/server/domains/browser/handlers/framework-state.js +231 -3
  165. package/dist/src/server/domains/browser/handlers/indexeddb-dump.js +21 -20
  166. package/dist/src/server/domains/browser/handlers/script-management.js +1 -1
  167. package/dist/src/server/domains/browser/handlers/stealth-injection.js +8 -2
  168. package/dist/src/server/domains/browser/handlers.impl.d.ts +15 -12
  169. package/dist/src/server/domains/browser/handlers.impl.js +5 -6
  170. package/dist/src/server/domains/browser/manifest.js +37 -13
  171. package/dist/src/server/domains/coordination/definitions.js +50 -149
  172. package/dist/src/server/domains/coordination/index.d.ts +20 -1
  173. package/dist/src/server/domains/coordination/index.js +133 -0
  174. package/dist/src/server/domains/coordination/manifest.js +15 -0
  175. package/dist/src/server/domains/debugger/definitions.tools.advanced.js +72 -189
  176. package/dist/src/server/domains/debugger/definitions.tools.core.js +114 -288
  177. package/dist/src/server/domains/debugger/manifest.js +9 -2
  178. package/dist/src/server/domains/encoding/definitions.js +43 -153
  179. package/dist/src/server/domains/encoding/handlers.base.js +2 -2
  180. package/dist/src/server/domains/evidence/definitions.d.ts +2 -0
  181. package/dist/src/server/domains/evidence/definitions.js +42 -0
  182. package/dist/src/server/domains/evidence/handlers.d.ts +582 -0
  183. package/dist/src/server/domains/evidence/handlers.js +60 -0
  184. package/dist/src/server/domains/evidence/index.d.ts +2 -0
  185. package/dist/src/server/domains/evidence/index.js +2 -0
  186. package/dist/src/server/domains/evidence/manifest.d.ts +63 -0
  187. package/dist/src/server/domains/evidence/manifest.js +78 -0
  188. package/dist/src/server/domains/graphql/definitions.js +53 -141
  189. package/dist/src/server/domains/graphql/handlers.impl.core.runtime.replay.js +92 -114
  190. package/dist/src/server/domains/hooks/ai-handlers.d.ts +0 -7
  191. package/dist/src/server/domains/hooks/ai-handlers.js +4 -70
  192. package/dist/src/server/domains/hooks/definitions.js +69 -335
  193. package/dist/src/server/domains/hooks/manifest.d.ts +1 -1
  194. package/dist/src/server/domains/hooks/manifest.js +1 -2
  195. package/dist/src/server/domains/instrumentation/definitions.d.ts +2 -0
  196. package/dist/src/server/domains/instrumentation/definitions.js +99 -0
  197. package/dist/src/server/domains/instrumentation/handlers.d.ts +78 -0
  198. package/dist/src/server/domains/instrumentation/handlers.js +206 -0
  199. package/dist/src/server/domains/instrumentation/index.d.ts +2 -0
  200. package/dist/src/server/domains/instrumentation/index.js +2 -0
  201. package/dist/src/server/domains/instrumentation/manifest.d.ts +63 -0
  202. package/dist/src/server/domains/instrumentation/manifest.js +114 -0
  203. package/dist/src/server/domains/macro/definitions.js +16 -43
  204. package/dist/src/server/domains/maintenance/definitions.js +60 -219
  205. package/dist/src/server/domains/maintenance/handlers.d.ts +2 -2
  206. package/dist/src/server/domains/maintenance/handlers.extensions.js +78 -20
  207. package/dist/src/server/domains/maintenance/handlers.js +2 -2
  208. package/dist/src/server/domains/memory/definitions.js +387 -559
  209. package/dist/src/server/domains/memory/handlers/hooks.d.ts +55 -0
  210. package/dist/src/server/domains/memory/handlers/hooks.js +115 -0
  211. package/dist/src/server/domains/memory/handlers/integrity.d.ts +77 -0
  212. package/dist/src/server/domains/memory/handlers/integrity.js +180 -0
  213. package/dist/src/server/domains/memory/handlers/pointer-chain.d.ts +29 -0
  214. package/dist/src/server/domains/memory/handlers/pointer-chain.js +82 -0
  215. package/dist/src/server/domains/memory/handlers/readwrite.d.ts +41 -0
  216. package/dist/src/server/domains/memory/handlers/readwrite.js +78 -0
  217. package/dist/src/server/domains/memory/handlers/scan.d.ts +35 -0
  218. package/dist/src/server/domains/memory/handlers/scan.js +97 -0
  219. package/dist/src/server/domains/memory/handlers/session.d.ts +23 -0
  220. package/dist/src/server/domains/memory/handlers/session.js +49 -0
  221. package/dist/src/server/domains/memory/handlers/structure.d.ts +29 -0
  222. package/dist/src/server/domains/memory/handlers/structure.js +74 -0
  223. package/dist/src/server/domains/memory/handlers.impl.d.ts +49 -54
  224. package/dist/src/server/domains/memory/handlers.impl.js +63 -494
  225. package/dist/src/server/domains/memory/manifest.js +236 -64
  226. package/dist/src/server/domains/native-bridge/definitions.js +54 -192
  227. package/dist/src/server/domains/native-bridge/index.d.ts +1 -0
  228. package/dist/src/server/domains/native-bridge/index.js +2 -1
  229. package/dist/src/server/domains/network/auth-extractor.js +1 -1
  230. package/dist/src/server/domains/network/definitions.js +175 -578
  231. package/dist/src/server/domains/network/handlers.base.core.d.ts +64 -0
  232. package/dist/src/server/domains/network/handlers.base.core.js +623 -0
  233. package/dist/src/server/domains/network/handlers.base.d.ts +2 -124
  234. package/dist/src/server/domains/network/handlers.base.js +3 -878
  235. package/dist/src/server/domains/network/handlers.base.performance.d.ts +63 -0
  236. package/dist/src/server/domains/network/handlers.base.performance.js +193 -0
  237. package/dist/src/server/domains/network/handlers.base.types.d.ts +42 -0
  238. package/dist/src/server/domains/network/handlers.base.types.js +89 -0
  239. package/dist/src/server/domains/network/handlers.impl.core.runtime.d.ts +1 -1
  240. package/dist/src/server/domains/network/handlers.impl.core.runtime.intercept.d.ts +21 -0
  241. package/dist/src/server/domains/network/handlers.impl.core.runtime.intercept.js +186 -0
  242. package/dist/src/server/domains/network/handlers.impl.core.runtime.js +1 -1
  243. package/dist/src/server/domains/network/manifest.js +15 -0
  244. package/dist/src/server/domains/network/replay.js +1 -4
  245. package/dist/src/server/domains/platform/definitions.js +121 -112
  246. package/dist/src/server/domains/platform/handlers/bridge-handlers.d.ts +5 -1
  247. package/dist/src/server/domains/platform/handlers/bridge-handlers.js +194 -5
  248. package/dist/src/server/domains/platform/handlers/electron-asar-helpers.js +26 -6
  249. package/dist/src/server/domains/platform/handlers/electron-dual-cdp.d.ts +3 -0
  250. package/dist/src/server/domains/platform/handlers/electron-dual-cdp.js +170 -0
  251. package/dist/src/server/domains/platform/handlers/electron-fuse-handler.d.ts +3 -0
  252. package/dist/src/server/domains/platform/handlers/electron-fuse-handler.js +193 -0
  253. package/dist/src/server/domains/platform/handlers/electron-handlers.d.ts +6 -0
  254. package/dist/src/server/domains/platform/handlers/electron-handlers.js +95 -2
  255. package/dist/src/server/domains/platform/handlers/electron-ipc-sniffer.d.ts +2 -0
  256. package/dist/src/server/domains/platform/handlers/electron-ipc-sniffer.js +370 -0
  257. package/dist/src/server/domains/platform/handlers/electron-userdata-handler.d.ts +2 -0
  258. package/dist/src/server/domains/platform/handlers/electron-userdata-handler.js +78 -0
  259. package/dist/src/server/domains/platform/handlers/miniapp-handlers.d.ts +1 -1
  260. package/dist/src/server/domains/platform/handlers/miniapp-handlers.js +4 -4
  261. package/dist/src/server/domains/platform/handlers/v8-bytecode-handler.d.ts +2 -0
  262. package/dist/src/server/domains/platform/handlers/v8-bytecode-handler.js +207 -0
  263. package/dist/src/server/domains/platform/handlers.d.ts +48 -0
  264. package/dist/src/server/domains/platform/handlers.js +29 -0
  265. package/dist/src/server/domains/platform/manifest.js +38 -0
  266. package/dist/src/server/domains/process/definitions.js +163 -647
  267. package/dist/src/server/domains/process/handlers.base.d.ts +3 -95
  268. package/dist/src/server/domains/process/handlers.base.js +7 -462
  269. package/dist/src/server/domains/process/handlers.base.process.d.ts +61 -0
  270. package/dist/src/server/domains/process/handlers.base.process.js +417 -0
  271. package/dist/src/server/domains/process/handlers.base.types.d.ts +57 -0
  272. package/dist/src/server/domains/process/handlers.base.types.js +50 -0
  273. package/dist/src/server/domains/process/handlers.impl.core.runtime.inject.js +19 -17
  274. package/dist/src/server/domains/process/manifest.js +6 -1
  275. package/dist/src/server/domains/sandbox/definitions.js +11 -33
  276. package/dist/src/server/domains/sandbox/handlers.js +8 -3
  277. package/dist/src/server/domains/shared/ResponseBuilder.d.ts +209 -0
  278. package/dist/src/server/domains/shared/ResponseBuilder.js +48 -0
  279. package/dist/src/server/domains/shared/modules.d.ts +0 -2
  280. package/dist/src/server/domains/shared/modules.js +0 -1
  281. package/dist/src/server/domains/sourcemap/definitions.js +27 -111
  282. package/dist/src/server/domains/sourcemap/handlers.impl.sourcemap-common.js +7 -2
  283. package/dist/src/server/domains/sourcemap/handlers.impl.sourcemap-main.js +1 -1
  284. package/dist/src/server/domains/sourcemap/handlers.impl.sourcemap-parse-base.js +1 -1
  285. package/dist/src/server/domains/sourcemap/manifest.d.ts +1 -1
  286. package/dist/src/server/domains/sourcemap/manifest.js +1 -1
  287. package/dist/src/server/domains/streaming/definitions.js +36 -148
  288. package/dist/src/server/domains/streaming/handlers.impl.streaming-sse.js +163 -164
  289. package/dist/src/server/domains/streaming/handlers.impl.streaming-ws.js +1 -1
  290. package/dist/src/server/domains/trace/TraceSummarizer.d.ts +60 -0
  291. package/dist/src/server/domains/trace/TraceSummarizer.js +112 -0
  292. package/dist/src/server/domains/trace/definitions.tools.js +51 -176
  293. package/dist/src/server/domains/trace/handlers.d.ts +2 -1
  294. package/dist/src/server/domains/trace/handlers.js +62 -9
  295. package/dist/src/server/domains/trace/index.d.ts +2 -1
  296. package/dist/src/server/domains/trace/index.js +2 -1
  297. package/dist/src/server/domains/trace/manifest.js +18 -4
  298. package/dist/src/server/domains/transform/definitions.js +50 -210
  299. package/dist/src/server/domains/transform/handlers.impl.transform-base.js +6 -6
  300. package/dist/src/server/domains/transform/handlers.impl.transform-crypto.js +18 -19
  301. package/dist/src/server/domains/transform/manifest.d.ts +1 -1
  302. package/dist/src/server/domains/transform/manifest.js +1 -1
  303. package/dist/src/server/domains/wasm/definitions.js +55 -232
  304. package/dist/src/server/domains/wasm/handlers.js +3 -3
  305. package/dist/src/server/domains/workflow/definitions.js +144 -414
  306. package/dist/src/server/domains/workflow/handlers.impl.workflow-account-bundle.js +2 -2
  307. package/dist/src/server/domains/workflow/handlers.impl.workflow-base.d.ts +2 -0
  308. package/dist/src/server/domains/workflow/handlers.impl.workflow-base.js +126 -87
  309. package/dist/src/server/domains/workflow/handlers.impl.workflow-batch.js +5 -5
  310. package/dist/src/server/evidence/ReverseEvidenceGraph.d.ts +20 -0
  311. package/dist/src/server/evidence/ReverseEvidenceGraph.js +208 -0
  312. package/dist/src/server/evidence/index.d.ts +2 -0
  313. package/dist/src/server/evidence/index.js +1 -0
  314. package/dist/src/server/evidence/types.d.ts +22 -0
  315. package/dist/src/server/evidence/types.js +1 -0
  316. package/dist/src/server/extensions/ExtensionManager.d.ts +1 -0
  317. package/dist/src/server/extensions/ExtensionManager.discovery.js +72 -9
  318. package/dist/src/server/extensions/ExtensionManager.integrity.js +1 -1
  319. package/dist/src/server/extensions/ExtensionManager.js +193 -40
  320. package/dist/src/server/extensions/ExtensionManager.roots.d.ts +1 -1
  321. package/dist/src/server/extensions/ExtensionManager.roots.js +19 -9
  322. package/dist/src/server/extensions/plugin-config.js +1 -1
  323. package/dist/src/server/extensions/plugin-env.d.ts +1 -1
  324. package/dist/src/server/extensions/plugin-env.js +10 -4
  325. package/dist/src/server/extensions/types.d.ts +17 -0
  326. package/dist/src/server/extensions/types.js +1 -1
  327. package/dist/src/server/http/HttpMiddleware.js +1 -1
  328. package/dist/src/server/instrumentation/EvidenceGraphBridge.d.ts +13 -0
  329. package/dist/src/server/instrumentation/EvidenceGraphBridge.js +150 -0
  330. package/dist/src/server/instrumentation/InstrumentationSession.d.ts +60 -0
  331. package/dist/src/server/instrumentation/InstrumentationSession.js +269 -0
  332. package/dist/src/server/instrumentation/index.d.ts +2 -0
  333. package/dist/src/server/instrumentation/index.js +2 -0
  334. package/dist/src/server/instrumentation/types.d.ts +62 -0
  335. package/dist/src/server/instrumentation/types.js +7 -0
  336. package/dist/src/server/macros/MacroConfigLoader.d.ts +6 -5
  337. package/dist/src/server/macros/MacroConfigLoader.js +61 -59
  338. package/dist/src/server/macros/MacroRunner.js +6 -2
  339. package/dist/src/server/macros/builtins/index.d.ts +2 -3
  340. package/dist/src/server/macros/builtins/index.js +51 -7
  341. package/dist/src/server/plugins/PluginContract.d.ts +1 -1
  342. package/dist/src/server/registry/contracts.d.ts +7 -1
  343. package/dist/src/server/registry/discovery.js +5 -4
  344. package/dist/src/server/registry/ensure-browser-core.js +0 -3
  345. package/dist/src/server/registry/index.js +4 -4
  346. package/dist/src/server/registry/tool-builder.d.ts +46 -0
  347. package/dist/src/server/registry/tool-builder.js +105 -0
  348. package/dist/src/server/sandbox/MCPBridge.d.ts +9 -0
  349. package/dist/src/server/sandbox/MCPBridge.js +22 -0
  350. package/dist/src/server/sandbox/QuickJSSandbox.d.ts +4 -1
  351. package/dist/src/server/sandbox/QuickJSSandbox.js +162 -2
  352. package/dist/src/server/sandbox/types.d.ts +13 -0
  353. package/dist/src/server/search/AffinityGraph.d.ts +7 -1
  354. package/dist/src/server/search/AffinityGraph.js +24 -3
  355. package/dist/src/server/search/EmbeddingWorker.js +5 -3
  356. package/dist/src/server/search/FeedbackTracker.d.ts +9 -0
  357. package/dist/src/server/search/FeedbackTracker.js +26 -0
  358. package/dist/src/server/search/QueryNormalizer.d.ts +6 -0
  359. package/dist/src/server/search/QueryNormalizer.js +94 -0
  360. package/dist/src/server/search/ToolSearchEngineImpl.d.ts +2 -3
  361. package/dist/src/server/search/ToolSearchEngineImpl.js +38 -88
  362. package/dist/src/server/workflows/WorkflowContract.d.ts +24 -0
  363. package/dist/src/server/workflows/WorkflowContract.js +12 -0
  364. package/dist/src/server/workflows/WorkflowEngine.d.ts +1 -0
  365. package/dist/src/server/workflows/WorkflowEngine.js +136 -3
  366. package/dist/src/types/config.d.ts +0 -14
  367. package/dist/src/types/deobfuscator.d.ts +0 -1
  368. package/dist/src/types/index.d.ts +1 -1
  369. package/dist/src/utils/DetailedDataManager.js +2 -0
  370. package/dist/src/utils/RingBuffer.js +5 -5
  371. package/dist/src/utils/TokenBudgetManager.js +1 -1
  372. package/dist/src/utils/UnifiedCacheManager.d.ts +1 -1
  373. package/dist/src/utils/UnifiedCacheManager.js +3 -3
  374. package/dist/src/utils/artifactRetention.js +2 -2
  375. package/dist/src/utils/betterSqlite3.d.ts +11 -0
  376. package/dist/src/utils/betterSqlite3.js +88 -0
  377. package/dist/src/utils/browserExecutable.js +2 -2
  378. package/dist/src/utils/cliFastPath.js +17 -6
  379. package/dist/src/utils/config.js +4 -26
  380. package/dist/src/utils/environmentDoctor.js +138 -11
  381. package/dist/src/utils/outputPaths.js +16 -9
  382. package/dist/src/utils/parallel.js +1 -3
  383. package/package.json +76 -72
  384. package/scripts/postinstall.cjs +37 -37
  385. package/src/native/scripts/linux/enum-windows.sh +12 -12
  386. package/src/native/scripts/macos/enum-windows.applescript +22 -22
  387. package/src/native/scripts/windows/enum-windows-by-class.ps1 +51 -51
  388. package/src/native/scripts/windows/enum-windows.ps1 +44 -44
  389. package/src/native/scripts/windows/inject-dll.ps1 +21 -21
  390. package/workflows/.gitkeep +0 -0
  391. package/dist/src/modules/analyzer/AISummarizer.d.ts +0 -39
  392. package/dist/src/modules/analyzer/AISummarizer.js +0 -122
  393. package/dist/src/modules/hook/AIHookGenerator.d.ts +0 -52
  394. package/dist/src/modules/hook/AIHookGenerator.js +0 -360
  395. package/dist/src/modules/hook/AIHookGeneratorTemplates.d.ts +0 -9
  396. package/dist/src/modules/hook/AIHookGeneratorTemplates.js +0 -157
  397. package/dist/src/server/macros/builtins/deobfuscate-ast-flow.d.ts +0 -2
  398. package/dist/src/server/macros/builtins/deobfuscate-ast-flow.js +0 -25
  399. package/dist/src/server/macros/builtins/unpacker-flow.d.ts +0 -2
  400. package/dist/src/server/macros/builtins/unpacker-flow.js +0 -25
  401. package/dist/src/services/LLMService.d.ts +0 -37
  402. package/dist/src/services/LLMService.js +0 -233
  403. package/dist/src/services/prompts/analysis.d.ts +0 -9
  404. package/dist/src/services/prompts/analysis.js +0 -158
  405. package/dist/src/services/prompts/crypto.d.ts +0 -2
  406. package/dist/src/services/prompts/crypto.js +0 -108
  407. package/dist/src/services/prompts/deobfuscation.d.ts +0 -6
  408. package/dist/src/services/prompts/deobfuscation.js +0 -300
  409. package/dist/src/services/prompts/environment.d.ts +0 -16
  410. package/dist/src/services/prompts/environment.js +0 -372
  411. package/dist/src/services/prompts/intelligence.d.ts +0 -4
  412. package/dist/src/services/prompts/intelligence.js +0 -250
  413. package/dist/src/services/prompts/taint.d.ts +0 -2
  414. package/dist/src/services/prompts/taint.js +0 -54
@@ -1,5 +1,8 @@
1
- import { basename, dirname } from 'node:path';
1
+ import { existsSync } from 'node:fs';
2
+ import { readFile } from 'node:fs/promises';
3
+ import { basename, dirname, relative, resolve } from 'node:path';
2
4
  import { glob } from 'tinyglobby';
5
+ import { INSTALLED_EXTENSION_METADATA_FILENAME, } from '../extensions/types.js';
3
6
  async function collectMatchingFiles(roots, matcher) {
4
7
  const files = new Set();
5
8
  for (const root of roots) {
@@ -21,7 +24,7 @@ async function collectMatchingFiles(roots, matcher) {
21
24
  }
22
25
  }
23
26
  }
24
- return [...files].sort((a, b) => a.localeCompare(b));
27
+ return [...files].toSorted((a, b) => a.localeCompare(b));
25
28
  }
26
29
  function normalizeExtensionCandidateKey(root, file) {
27
30
  const normalizedRoot = root
@@ -29,8 +32,7 @@ function normalizeExtensionCandidateKey(root, file) {
29
32
  .replace(/\/+/g, '/')
30
33
  .replace(/^\/+|\/+$/g, '')
31
34
  .toLowerCase();
32
- const relDir = dirname(file)
33
- .slice(root.length)
35
+ const relDir = relative(root, dirname(file))
34
36
  .replace(/^[/\\]+/, '')
35
37
  .replace(/\\/g, '/')
36
38
  .replace(/\/+/g, '/')
@@ -49,9 +51,62 @@ function extensionRank(candidate) {
49
51
  return 1;
50
52
  return 2;
51
53
  }
54
+ function isInstalledExtensionMetadata(value, kind) {
55
+ if (!value || typeof value !== 'object')
56
+ return false;
57
+ const record = value;
58
+ if (record.version !== 1 || record.kind !== kind)
59
+ return false;
60
+ if (typeof record.slug !== 'string' || typeof record.id !== 'string')
61
+ return false;
62
+ if (!record.source || typeof record.source !== 'object')
63
+ return false;
64
+ const source = record.source;
65
+ return (typeof source.type === 'string' &&
66
+ typeof source.repo === 'string' &&
67
+ typeof source.ref === 'string' &&
68
+ typeof source.commit === 'string' &&
69
+ typeof source.subpath === 'string' &&
70
+ typeof source.entry === 'string');
71
+ }
72
+ async function collectInstalledEntryCandidates(roots, kind) {
73
+ const candidates = [];
74
+ for (const [rootIndex, root] of roots.entries()) {
75
+ const metadataFiles = await collectMatchingFiles([root], (filename) => filename === INSTALLED_EXTENSION_METADATA_FILENAME);
76
+ for (const metadataFile of metadataFiles) {
77
+ let metadataRaw;
78
+ try {
79
+ metadataRaw = JSON.parse(await readFile(metadataFile, 'utf8'));
80
+ }
81
+ catch {
82
+ continue;
83
+ }
84
+ if (!isInstalledExtensionMetadata(metadataRaw, kind)) {
85
+ continue;
86
+ }
87
+ const entryPath = metadataRaw.source.entry.trim();
88
+ if (!entryPath) {
89
+ continue;
90
+ }
91
+ const file = resolve(dirname(metadataFile), entryPath);
92
+ if (!existsSync(file)) {
93
+ continue;
94
+ }
95
+ candidates.push({
96
+ file,
97
+ key: normalizeExtensionCandidateKey(root, file),
98
+ isJs: file.endsWith('.js'),
99
+ isTs: file.endsWith('.ts'),
100
+ rootIndex,
101
+ priority: 0,
102
+ });
103
+ }
104
+ }
105
+ return candidates;
106
+ }
52
107
  function deduplicateCandidates(candidates) {
53
108
  const byKey = new Map();
54
- for (const candidate of candidates.sort((a, b) => a.file.localeCompare(b.file))) {
109
+ for (const candidate of candidates.toSorted((a, b) => a.file.localeCompare(b.file))) {
55
110
  const existing = byKey.get(candidate.key);
56
111
  if (!existing) {
57
112
  byKey.set(candidate.key, candidate);
@@ -59,21 +114,27 @@ function deduplicateCandidates(candidates) {
59
114
  }
60
115
  const existingRoot = existing.rootIndex;
61
116
  const candidateRoot = candidate.rootIndex;
117
+ const existingPriority = existing.priority;
118
+ const candidatePriority = candidate.priority;
62
119
  const existingExtRank = extensionRank(existing);
63
120
  const candidateExtRank = extensionRank(candidate);
64
121
  const shouldReplace = candidateRoot < existingRoot ||
65
- (candidateRoot === existingRoot && candidateExtRank < existingExtRank) ||
122
+ (candidateRoot === existingRoot && candidatePriority < existingPriority) ||
123
+ (candidateRoot === existingRoot &&
124
+ candidatePriority === existingPriority &&
125
+ candidateExtRank < existingExtRank) ||
66
126
  (candidateRoot === existingRoot &&
127
+ candidatePriority === existingPriority &&
67
128
  candidateExtRank === existingExtRank &&
68
129
  candidate.file.localeCompare(existing.file) < 0);
69
130
  if (shouldReplace) {
70
131
  byKey.set(candidate.key, candidate);
71
132
  }
72
133
  }
73
- return [...byKey.values()].map((item) => item.file).sort((a, b) => a.localeCompare(b));
134
+ return [...byKey.values()].map((item) => item.file).toSorted((a, b) => a.localeCompare(b));
74
135
  }
75
136
  export async function discoverPluginFiles(pluginRoots) {
76
- const candidates = [];
137
+ const candidates = await collectInstalledEntryCandidates(pluginRoots, 'plugin');
77
138
  for (const [rootIndex, root] of pluginRoots.entries()) {
78
139
  const files = await collectMatchingFiles([root], (filename) => filename === 'manifest.js' || filename === 'manifest.ts');
79
140
  for (const file of files) {
@@ -83,13 +144,14 @@ export async function discoverPluginFiles(pluginRoots) {
83
144
  isJs: file.endsWith('.js'),
84
145
  isTs: file.endsWith('.ts'),
85
146
  rootIndex,
147
+ priority: 1,
86
148
  });
87
149
  }
88
150
  }
89
151
  return deduplicateCandidates(candidates);
90
152
  }
91
153
  export async function discoverWorkflowFiles(workflowRoots) {
92
- const candidates = [];
154
+ const candidates = await collectInstalledEntryCandidates(workflowRoots, 'workflow');
93
155
  for (const [rootIndex, root] of workflowRoots.entries()) {
94
156
  const files = await collectMatchingFiles([root], (filename) => filename.endsWith('.workflow.js') ||
95
157
  filename.endsWith('.workflow.ts') ||
@@ -102,6 +164,7 @@ export async function discoverWorkflowFiles(workflowRoots) {
102
164
  isJs: file.endsWith('.js'),
103
165
  isTs: file.endsWith('.ts'),
104
166
  rootIndex,
167
+ priority: 1,
105
168
  });
106
169
  }
107
170
  }
@@ -9,7 +9,7 @@ export function normalizeHex(value) {
9
9
  return value.trim().toLowerCase().replace(/^0x/, '');
10
10
  }
11
11
  function isTruthyEnv(value) {
12
- return ['1', 'true'].includes((value ?? '').toLowerCase());
12
+ return ['1', 'true'].includes(value.toLowerCase());
13
13
  }
14
14
  export function isPluginSignatureRequired() {
15
15
  const raw = process.env.MCP_PLUGIN_SIGNATURE_REQUIRED;
@@ -1,7 +1,8 @@
1
- import { readFileSync } from 'node:fs';
2
- import { dirname, join } from 'node:path';
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { basename, dirname, join } from 'node:path';
3
3
  import { allTools } from '../ToolCatalog.js';
4
4
  import { logger } from '../../utils/logger.js';
5
+ import { INSTALLED_EXTENSION_METADATA_FILENAME } from '../extensions/types.js';
5
6
  import { DEFAULT_PLUGIN_ROOTS, DEFAULT_WORKFLOW_ROOTS, parseRoots, resolveRoots, } from './ExtensionManager.roots.js';
6
7
  import { sha256Hex, normalizeHex, isPluginStrictLoad, parseDigestAllowlist, verifyPluginIntegrity, } from './ExtensionManager.integrity.js';
7
8
  import { isExtensionBuilder, isWorkflowContract } from './ExtensionManager.guards.js';
@@ -34,8 +35,39 @@ function parseSimpleYaml(filePath) {
34
35
  return {};
35
36
  }
36
37
  }
38
+ function findInstalledMetadataRoot(startDir) {
39
+ let currentDir = startDir;
40
+ while (true) {
41
+ if (existsSync(join(currentDir, INSTALLED_EXTENSION_METADATA_FILENAME))) {
42
+ return currentDir;
43
+ }
44
+ const parentDir = dirname(currentDir);
45
+ if (parentDir === currentDir) {
46
+ return null;
47
+ }
48
+ currentDir = parentDir;
49
+ }
50
+ }
51
+ function resolvePluginProjectRoot(pluginFile) {
52
+ const entryDir = dirname(pluginFile);
53
+ const metadataRoot = findInstalledMetadataRoot(entryDir);
54
+ if (metadataRoot) {
55
+ return metadataRoot;
56
+ }
57
+ if (basename(entryDir).toLowerCase() === 'dist') {
58
+ return dirname(entryDir);
59
+ }
60
+ return entryDir;
61
+ }
37
62
  let reloadMutex = Promise.resolve();
38
- export async function reloadExtensions(ctx) {
63
+ const lazyWorkflowLoadAttempted = new WeakSet();
64
+ const STRICT_PLUGIN_ALLOWLIST_ERROR = 'MCP_PLUGIN_ALLOWED_DIGESTS is required when MCP_PLUGIN_SIGNATURE_REQUIRED=true ' +
65
+ 'or MCP_PLUGIN_STRICT_LOAD=true. The digest allowlist is the only pre-import trust boundary — ' +
66
+ 'without it, plugin code executes before integrity verification. No plugins will be loaded.';
67
+ const MISSING_PLUGIN_ALLOWLIST_WARNING = '[extensions] Loading plugins WITHOUT MCP_PLUGIN_ALLOWED_DIGESTS allowlist. ' +
68
+ 'Plugin code will execute on import() before post-load integrity checks. ' +
69
+ 'Set MCP_PLUGIN_STRICT_LOAD=true to enforce allowlist requirement.';
70
+ async function withReloadMutex(operation) {
39
71
  const prev = reloadMutex;
40
72
  let resolve;
41
73
  reloadMutex = new Promise((r) => {
@@ -43,12 +75,39 @@ export async function reloadExtensions(ctx) {
43
75
  });
44
76
  await prev;
45
77
  try {
46
- return await reloadExtensionsInner(ctx);
78
+ return await operation();
47
79
  }
48
80
  finally {
49
81
  resolve();
50
82
  }
51
83
  }
84
+ export async function reloadExtensions(ctx) {
85
+ return withReloadMutex(() => reloadExtensionsInner(ctx));
86
+ }
87
+ export async function ensureWorkflowsLoaded(ctx) {
88
+ if (ctx.extensionWorkflowRuntimeById.size > 0 || lazyWorkflowLoadAttempted.has(ctx)) {
89
+ return;
90
+ }
91
+ await withReloadMutex(async () => {
92
+ if (ctx.extensionWorkflowRuntimeById.size > 0 || lazyWorkflowLoadAttempted.has(ctx)) {
93
+ return;
94
+ }
95
+ lazyWorkflowLoadAttempted.add(ctx);
96
+ const warnings = [];
97
+ const errors = [];
98
+ const pluginRoots = resolveRoots(parseRoots(process.env.MCP_PLUGIN_ROOTS, DEFAULT_PLUGIN_ROOTS));
99
+ const workflowRoots = resolveRoots(parseRoots(process.env.MCP_WORKFLOW_ROOTS, DEFAULT_WORKFLOW_ROOTS));
100
+ await loadPluginWorkflowContributions(ctx, pluginRoots, warnings, errors);
101
+ const workflowFiles = await discoverWorkflowFiles(workflowRoots);
102
+ await loadWorkflows(ctx, workflowFiles, warnings, errors);
103
+ for (const warning of warnings) {
104
+ logger.warn(`[extensions] ${warning}`);
105
+ }
106
+ for (const error of errors) {
107
+ logger.error(`[extensions] ${error}`);
108
+ }
109
+ });
110
+ }
52
111
  async function loadWorkflows(ctx, workflowFiles, warnings, errors) {
53
112
  for (const workflowFile of workflowFiles) {
54
113
  try {
@@ -59,29 +118,124 @@ async function loadWorkflows(ctx, workflowFiles, warnings, errors) {
59
118
  continue;
60
119
  }
61
120
  const workflow = candidate;
62
- if (ctx.extensionWorkflowsById.has(workflow.id)) {
63
- warnings.push(`Skip workflow "${workflow.id}" from ${workflowFile}: duplicate id`);
121
+ registerWorkflowContract(ctx, workflow, workflowFile, warnings);
122
+ }
123
+ catch (error) {
124
+ errors.push(`Failed to import workflow file ${workflowFile}: ${String(error)}`);
125
+ }
126
+ }
127
+ }
128
+ function registerWorkflowContract(ctx, workflow, source, warnings) {
129
+ if (ctx.extensionWorkflowsById.has(workflow.id)) {
130
+ warnings.push(`Skip workflow "${workflow.id}" from ${source}: duplicate id`);
131
+ return false;
132
+ }
133
+ const record = {
134
+ id: workflow.id,
135
+ displayName: workflow.displayName,
136
+ source,
137
+ description: workflow.description,
138
+ tags: workflow.tags,
139
+ timeoutMs: workflow.timeoutMs,
140
+ defaultMaxConcurrency: workflow.defaultMaxConcurrency,
141
+ route: workflow.route,
142
+ };
143
+ ctx.extensionWorkflowsById.set(record.id, record);
144
+ const runtimeRecord = {
145
+ workflow,
146
+ source,
147
+ route: workflow.route,
148
+ };
149
+ ctx.extensionWorkflowRuntimeById.set(record.id, runtimeRecord);
150
+ return true;
151
+ }
152
+ function buildPluginRecord(plugin, pluginFile, loadedTools, loadedWorkflows) {
153
+ return {
154
+ id: plugin.id,
155
+ name: plugin.pluginName,
156
+ source: pluginFile,
157
+ author: plugin.pluginAuthor || undefined,
158
+ sourceRepo: plugin.pluginSourceRepo || undefined,
159
+ domains: [],
160
+ workflows: loadedWorkflows,
161
+ tools: loadedTools,
162
+ };
163
+ }
164
+ async function loadPluginWorkflowContributions(ctx, pluginRoots, warnings, errors) {
165
+ const allowedDigests = parseDigestAllowlist(process.env.MCP_PLUGIN_ALLOWED_DIGESTS);
166
+ const strictLoad = isPluginStrictLoad();
167
+ if (strictLoad && allowedDigests.size === 0) {
168
+ errors.push(STRICT_PLUGIN_ALLOWLIST_ERROR);
169
+ logger.error('[extensions] ' + STRICT_PLUGIN_ALLOWLIST_ERROR);
170
+ return;
171
+ }
172
+ if (allowedDigests.size === 0) {
173
+ logger.warn(MISSING_PLUGIN_ALLOWLIST_WARNING);
174
+ }
175
+ const pluginFiles = await discoverPluginFiles(pluginRoots);
176
+ const coreVersion = ctx.config?.mcp?.version ?? '0.0.0';
177
+ for (const pluginFile of pluginFiles) {
178
+ let fileDigest;
179
+ try {
180
+ fileDigest = normalizeHex(await sha256Hex(pluginFile));
181
+ if (allowedDigests.size > 0 && !allowedDigests.has(fileDigest)) {
182
+ warnings.push(`Skip plugin file not in MCP_PLUGIN_ALLOWED_DIGESTS allowlist: ${pluginFile}`);
64
183
  continue;
65
184
  }
66
- const record = {
67
- id: workflow.id,
68
- displayName: workflow.displayName,
69
- source: workflowFile,
70
- description: workflow.description,
71
- tags: workflow.tags,
72
- timeoutMs: workflow.timeoutMs,
73
- defaultMaxConcurrency: workflow.defaultMaxConcurrency,
74
- };
75
- ctx.extensionWorkflowsById.set(record.id, record);
76
- const runtimeRecord = {
77
- workflow,
78
- source: workflowFile,
79
- };
80
- ctx.extensionWorkflowRuntimeById.set(record.id, runtimeRecord);
81
185
  }
82
186
  catch (error) {
83
- errors.push(`Failed to import workflow file ${workflowFile}: ${String(error)}`);
187
+ errors.push(`Failed to hash plugin file ${pluginFile}: ${String(error)}`);
188
+ continue;
189
+ }
190
+ let plugin;
191
+ try {
192
+ const mod = await import(createFreshImportUrl(pluginFile, 'plugin'));
193
+ const candidate = mod.default ?? mod;
194
+ if (!isExtensionBuilder(candidate)) {
195
+ warnings.push(`Skip plugin file without valid ExtensionBuilder: ${pluginFile}`);
196
+ continue;
197
+ }
198
+ plugin = candidate;
199
+ }
200
+ catch (error) {
201
+ errors.push(`Failed to import plugin file ${pluginFile}: ${String(error)}`);
202
+ continue;
203
+ }
204
+ const pluginProjectRoot = resolvePluginProjectRoot(pluginFile);
205
+ const metaYamlPath = join(pluginProjectRoot, 'meta.yaml');
206
+ const meta = parseSimpleYaml(metaYamlPath);
207
+ plugin.mergeMetadata(meta);
208
+ if (ctx.extensionPluginsById.has(plugin.id)) {
209
+ warnings.push(`Skip plugin "${plugin.id}" from ${pluginFile}: duplicate plugin id`);
210
+ continue;
84
211
  }
212
+ try {
213
+ const verification = await verifyPluginIntegrity(plugin, coreVersion);
214
+ warnings.push(...verification.warnings);
215
+ if (!verification.ok) {
216
+ errors.push(...verification.errors);
217
+ continue;
218
+ }
219
+ }
220
+ catch (error) {
221
+ errors.push(`Failed to verify plugin ${plugin.id}: ${String(error)}`);
222
+ continue;
223
+ }
224
+ const loadedWorkflows = [];
225
+ for (const candidate of plugin.workflows) {
226
+ if (!isWorkflowContract(candidate)) {
227
+ warnings.push(`Skip invalid workflow contribution from plugin "${plugin.id}" in ${pluginFile}`);
228
+ continue;
229
+ }
230
+ const workflowSource = `${pluginFile}#workflow:${candidate.id}`;
231
+ if (registerWorkflowContract(ctx, candidate, workflowSource, warnings)) {
232
+ loadedWorkflows.push(candidate.id);
233
+ }
234
+ }
235
+ if (loadedWorkflows.length === 0) {
236
+ continue;
237
+ }
238
+ ctx.extensionPluginsById.set(plugin.id, buildPluginRecord(plugin, pluginFile, [], loadedWorkflows));
85
239
  }
86
240
  }
87
241
  async function reloadExtensionsInner(ctx) {
@@ -93,9 +247,7 @@ async function reloadExtensionsInner(ctx) {
93
247
  const allowedDigests = parseDigestAllowlist(process.env.MCP_PLUGIN_ALLOWED_DIGESTS);
94
248
  const strictLoad = isPluginStrictLoad();
95
249
  if (strictLoad && allowedDigests.size === 0) {
96
- const msg = 'MCP_PLUGIN_ALLOWED_DIGESTS is required when MCP_PLUGIN_SIGNATURE_REQUIRED=true ' +
97
- 'or MCP_PLUGIN_STRICT_LOAD=true. The digest allowlist is the only pre-import trust boundary — ' +
98
- 'without it, plugin code executes before integrity verification. No plugins will be loaded.';
250
+ const msg = STRICT_PLUGIN_ALLOWLIST_ERROR;
99
251
  errors.push(msg);
100
252
  logger.error('[extensions] ' + msg);
101
253
  const workflowFiles = await discoverWorkflowFiles(workflowRoots);
@@ -105,9 +257,7 @@ async function reloadExtensionsInner(ctx) {
105
257
  return { ...list, addedTools: 0, removedTools, warnings, errors };
106
258
  }
107
259
  if (allowedDigests.size === 0) {
108
- logger.warn('[extensions] Loading plugins WITHOUT MCP_PLUGIN_ALLOWED_DIGESTS allowlist. ' +
109
- 'Plugin code will execute on import() before post-load integrity checks. ' +
110
- 'Set MCP_PLUGIN_STRICT_LOAD=true to enforce allowlist requirement.');
260
+ logger.warn(MISSING_PLUGIN_ALLOWLIST_WARNING);
111
261
  }
112
262
  const baseToolNames = new Set(allTools.map((tool) => tool.name));
113
263
  const pluginFiles = await discoverPluginFiles(pluginRoots);
@@ -139,7 +289,8 @@ async function reloadExtensionsInner(ctx) {
139
289
  errors.push(`Failed to import plugin file ${pluginFile}: ${String(error)}`);
140
290
  continue;
141
291
  }
142
- const metaYamlPath = join(dirname(pluginFile), 'meta.yaml');
292
+ const pluginProjectRoot = resolvePluginProjectRoot(pluginFile);
293
+ const metaYamlPath = join(pluginProjectRoot, 'meta.yaml');
143
294
  const meta = parseSimpleYaml(metaYamlPath);
144
295
  plugin.mergeMetadata(meta);
145
296
  if (ctx.extensionPluginsById.has(plugin.id)) {
@@ -164,7 +315,7 @@ async function reloadExtensionsInner(ctx) {
164
315
  const allowInvokeAll = plugin.allowedTools.includes('*');
165
316
  const lifecycleContext = {
166
317
  pluginId: plugin.id,
167
- pluginRoot: pluginFile,
318
+ pluginRoot: pluginProjectRoot,
168
319
  config: ctx.config,
169
320
  get state() {
170
321
  return pluginState;
@@ -244,16 +395,18 @@ async function reloadExtensionsInner(ctx) {
244
395
  continue;
245
396
  }
246
397
  const loadedTools = plugin.tools.map((t) => t.name);
247
- const record = {
248
- id: plugin.id,
249
- name: plugin.pluginName,
250
- source: pluginFile,
251
- author: plugin.pluginAuthor || undefined,
252
- sourceRepo: plugin.pluginSourceRepo || undefined,
253
- domains: [],
254
- workflows: [],
255
- tools: loadedTools,
256
- };
398
+ const loadedWorkflows = [];
399
+ for (const candidate of plugin.workflows) {
400
+ if (!isWorkflowContract(candidate)) {
401
+ warnings.push(`Skip invalid workflow contribution from plugin "${plugin.id}" in ${pluginFile}`);
402
+ continue;
403
+ }
404
+ const workflowSource = `${pluginFile}#workflow:${candidate.id}`;
405
+ if (registerWorkflowContract(ctx, candidate, workflowSource, warnings)) {
406
+ loadedWorkflows.push(candidate.id);
407
+ }
408
+ }
409
+ const record = buildPluginRecord(plugin, pluginFile, loadedTools, loadedWorkflows);
257
410
  ctx.extensionPluginsById.set(record.id, record);
258
411
  }
259
412
  const workflowFiles = await discoverWorkflowFiles(workflowRoots);
@@ -1,4 +1,4 @@
1
1
  export declare const DEFAULT_PLUGIN_ROOTS: string[];
2
2
  export declare const DEFAULT_WORKFLOW_ROOTS: string[];
3
3
  export declare function parseRoots(raw: string | undefined, fallback: string[]): string[];
4
- export declare function resolveRoots(roots: string[]): string[];
4
+ export declare function resolveRoots(roots: string[], baseDir?: string): string[];
@@ -1,11 +1,21 @@
1
1
  import { dirname, isAbsolute, join, resolve } from 'node:path';
2
+ import { existsSync } from 'node:fs';
2
3
  import { fileURLToPath } from 'node:url';
3
- const IS_TS_RUNTIME = import.meta.url.endsWith('.ts');
4
- const EXTENSION_MANAGER_DIR = dirname(fileURLToPath(import.meta.url));
5
- const EXTENSION_INSTALL_ROOT = resolve(EXTENSION_MANAGER_DIR, '..', '..', '..');
6
- export const DEFAULT_PLUGIN_ROOTS = IS_TS_RUNTIME
7
- ? [join(EXTENSION_INSTALL_ROOT, 'plugins'), join(EXTENSION_INSTALL_ROOT, 'dist', 'plugins')]
8
- : [join(EXTENSION_INSTALL_ROOT, 'dist', 'plugins'), join(EXTENSION_INSTALL_ROOT, 'plugins')];
4
+ function findProjectRoot(startDir) {
5
+ let dir = startDir;
6
+ while (true) {
7
+ if (existsSync(join(dir, 'package.json')))
8
+ return dir;
9
+ const parent = dirname(dir);
10
+ if (parent === dir)
11
+ break;
12
+ dir = parent;
13
+ }
14
+ return resolve(startDir, '..', '..', '..', '..');
15
+ }
16
+ const EXTENSION_MANAGER_DIR = fileURLToPath(new URL('.', import.meta.url));
17
+ const EXTENSION_INSTALL_ROOT = findProjectRoot(EXTENSION_MANAGER_DIR);
18
+ export const DEFAULT_PLUGIN_ROOTS = [join(EXTENSION_INSTALL_ROOT, 'plugins')];
9
19
  export const DEFAULT_WORKFLOW_ROOTS = [join(EXTENSION_INSTALL_ROOT, 'workflows')];
10
20
  export function parseRoots(raw, fallback) {
11
21
  const value = raw?.trim();
@@ -17,7 +27,7 @@ export function parseRoots(raw, fallback) {
17
27
  .filter(Boolean);
18
28
  return roots.length > 0 ? [...new Set(roots)] : fallback;
19
29
  }
20
- export function resolveRoots(roots) {
21
- const resolved = roots.map((root) => (isAbsolute(root) ? root : resolve(process.cwd(), root)));
22
- return [...new Set(resolved)].sort((a, b) => a.localeCompare(b));
30
+ export function resolveRoots(roots, baseDir = EXTENSION_INSTALL_ROOT) {
31
+ const resolved = roots.map((root) => (isAbsolute(root) ? root : resolve(baseDir, root)));
32
+ return [...new Set(resolved)].toSorted((a, b) => a.localeCompare(b));
23
33
  }
@@ -11,7 +11,7 @@ function envCandidates(pluginId, key) {
11
11
  return [`PLUGIN_${pluginSegment}_${keySegment}`, `PLUGINS_${pluginSegment}_${keySegment}`];
12
12
  }
13
13
  function parseBoolean(raw) {
14
- if (raw == null)
14
+ if (raw === undefined)
15
15
  return undefined;
16
16
  const value = raw.trim().toLowerCase();
17
17
  if (['1', 'true', 'yes', 'on'].includes(value))
@@ -1 +1 @@
1
- export declare function loadPluginEnv(manifestUrl: string): void;
1
+ export declare function loadPluginEnv(manifestLocation: string): void;
@@ -1,10 +1,16 @@
1
1
  import { existsSync } from 'node:fs';
2
- import { dirname, join } from 'node:path';
3
- import { fileURLToPath } from 'node:url';
2
+ import { join } from 'node:path';
3
+ import { fileURLToPath, pathToFileURL } from 'node:url';
4
4
  import dotenv from 'dotenv';
5
5
  const loadedEnvPaths = new Set();
6
- export function loadPluginEnv(manifestUrl) {
7
- const pluginDir = dirname(fileURLToPath(manifestUrl));
6
+ function toManifestUrl(manifestLocation) {
7
+ return manifestLocation.startsWith('file:')
8
+ ? new URL(manifestLocation)
9
+ : pathToFileURL(manifestLocation);
10
+ }
11
+ export function loadPluginEnv(manifestLocation) {
12
+ const pluginDirUrl = new URL('.', toManifestUrl(manifestLocation));
13
+ const pluginDir = fileURLToPath(pluginDirUrl);
8
14
  const envPath = join(pluginDir, '.env');
9
15
  if (loadedEnvPaths.has(envPath))
10
16
  return;
@@ -2,6 +2,21 @@ import type { RegisteredTool } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import type { Tool } from '@modelcontextprotocol/sdk/types.js';
3
3
  import type { ExtensionBuilder, PluginLifecycleContext, PluginState } from '../plugins/PluginContract.js';
4
4
  import type { WorkflowContract } from '../workflows/WorkflowContract.js';
5
+ export declare const INSTALLED_EXTENSION_METADATA_FILENAME = ".jshook-install.json";
6
+ export interface InstalledExtensionMetadata {
7
+ version: 1;
8
+ kind: 'plugin' | 'workflow';
9
+ slug: string;
10
+ id: string;
11
+ source: {
12
+ type: string;
13
+ repo: string;
14
+ ref: string;
15
+ commit: string;
16
+ subpath: string;
17
+ entry: string;
18
+ };
19
+ }
5
20
  export interface ExtensionToolRecord {
6
21
  name: string;
7
22
  domain: string;
@@ -30,6 +45,7 @@ export interface ExtensionPluginRuntimeRecord {
30
45
  export interface ExtensionWorkflowRuntimeRecord {
31
46
  workflow: WorkflowContract;
32
47
  source: string;
48
+ route?: WorkflowContract['route'];
33
49
  }
34
50
  export interface ExtensionWorkflowRecord {
35
51
  id: string;
@@ -39,6 +55,7 @@ export interface ExtensionWorkflowRecord {
39
55
  tags?: string[];
40
56
  timeoutMs?: number;
41
57
  defaultMaxConcurrency?: number;
58
+ route?: WorkflowContract['route'];
42
59
  }
43
60
  export interface ExtensionListResult {
44
61
  pluginRoots: string[];
@@ -1 +1 @@
1
- export {};
1
+ export const INSTALLED_EXTENSION_METADATA_FILENAME = '.jshook-install.json';
@@ -36,7 +36,7 @@ export function checkAuth(req, res) {
36
36
  return true;
37
37
  }
38
38
  const header = req.headers.authorization;
39
- if (!header || !header.startsWith('Bearer ')) {
39
+ if (!header?.startsWith('Bearer ')) {
40
40
  res.writeHead(401, { 'Content-Type': 'text/plain' });
41
41
  res.end('Unauthorized – missing or malformed Authorization header');
42
42
  return false;
@@ -0,0 +1,13 @@
1
+ import type { ReverseEvidenceGraph } from '../evidence/ReverseEvidenceGraph.js';
2
+ import type { InstrumentationOperation, InstrumentationArtifact } from './types.js';
3
+ export declare class EvidenceGraphBridge {
4
+ private readonly graph;
5
+ private readonly operationNodeMap;
6
+ private readonly requestNodeMap;
7
+ constructor(graph: ReverseEvidenceGraph);
8
+ private getString;
9
+ private getInitiatorLabel;
10
+ linkRequestToInitiator(requestNodeId: string, initiatorStackNodeId: string): void;
11
+ onOperation(op: InstrumentationOperation): string | null;
12
+ onArtifact(artifact: InstrumentationArtifact): void;
13
+ }