@pi-harness/pi-harness 0.1.13 → 0.1.14

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 (1333) hide show
  1. package/README.md +678 -2
  2. package/apps/web/dist/assets/index-BVI_IS-R.css +2 -0
  3. package/apps/web/dist/assets/index-C98SJjJd.js +22 -0
  4. package/apps/web/dist/index.html +2 -2
  5. package/apps/web/package.json +6 -6
  6. package/node_modules/@pi-harness/api-gateway/dist/index.d.ts.map +1 -1
  7. package/node_modules/@pi-harness/api-gateway/dist/index.js +97 -9
  8. package/node_modules/@pi-harness/api-gateway/dist/index.js.map +1 -1
  9. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/agent-teams.json +6 -6
  10. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/anchored-standard.json +1 -1
  11. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/annotation.json +1 -2
  12. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/archify.json +1 -1
  13. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/at-file.json +11 -5
  14. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/auto-mode.json +1 -1
  15. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/better-sidebar.json +1 -1
  16. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/browser-fetch.json +12 -5
  17. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/browser-session.json +14 -8
  18. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/canvas-draw.json +3 -4
  19. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/change-verifier.json +1 -1
  20. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/cleaner.json +11 -6
  21. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/cli-notifier.json +5 -5
  22. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/code2skill.json +5 -5
  23. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/colleague-skill.json +1 -2
  24. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/context-doctor.json +12 -7
  25. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/context.json +10 -5
  26. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/cordis-group.json +2 -2
  27. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/cordis-logger-console.json +4 -4
  28. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/cordis-timer.json +3 -3
  29. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/cost-meter.json +9 -6
  30. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/dependency-checker.json +13 -10
  31. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/docker-sandbox.json +10 -5
  32. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/fail-logger.json +11 -6
  33. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/genui.json +7 -5
  34. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/git-time-capsule.json +13 -8
  35. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/graph-memory.json +13 -7
  36. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/history-compressor.json +1 -1
  37. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/hol-guard.json +1 -1
  38. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/i18n-pair.json +9 -6
  39. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/image-compressor.json +1 -1
  40. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/llm-verifier.json +1 -1
  41. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/mcp-client.json +12 -7
  42. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/mcp-panel.json +1 -1
  43. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/memory.json +1 -1
  44. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/mirage-bridge.json +1 -1
  45. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/mock-server.json +1 -1
  46. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/modlens.json +4 -4
  47. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/module-search.json +1 -1
  48. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/obsidian-sync.json +1 -1
  49. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/openpets.json +9 -5
  50. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/plan-execute.json +1 -1
  51. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/plugin-check.json +1 -1
  52. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/plugin-dev.json +8 -6
  53. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/plugin-finder.json +1 -1
  54. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/plugin-radar.json +1 -1
  55. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/plugin-stars.json +15 -7
  56. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/prompt-guard.json +1 -1
  57. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/prompt-library.json +1 -1
  58. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/readme-gen.json +12 -8
  59. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/recall-unread.json +11 -6
  60. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/reverse-skill.json +1 -1
  61. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/reviewer-bot.json +1 -1
  62. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/runtime-doctor.json +1 -1
  63. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/secure-audit.json +1 -1
  64. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/session-bookmarks.json +1 -1
  65. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/session-bridge.json +13 -8
  66. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/session-compare.json +1 -1
  67. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/session-export.json +1 -1
  68. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/session-insights.json +12 -6
  69. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/session-search.json +1 -1
  70. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/skill-catalog.json +1 -1
  71. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/skill-guard.json +9 -5
  72. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/sql-lens.json +13 -7
  73. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/synapse.json +1 -1
  74. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/tab-manager.json +1 -1
  75. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/taskboard.json +1 -1
  76. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/telemetry-blocker.json +1 -1
  77. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/test-harness.json +14 -7
  78. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/theme-studio.json +1 -1
  79. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/token-guard.json +12 -6
  80. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/turn-rewind.json +11 -6
  81. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/undo-savepoint.json +1 -1
  82. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/vision-toolkit.json +8 -5
  83. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/web-research.json +1 -1
  84. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/workspace-navigator.json +1 -1
  85. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/workspace-search.json +1 -1
  86. package/node_modules/@pi-harness/api-gateway/dist/marketplace-entries/official/yaml-validator.json +8 -5
  87. package/node_modules/@pi-harness/api-gateway/package.json +1 -1
  88. package/node_modules/@pi-harness/cli/dist/node-stdio.d.ts.map +1 -1
  89. package/node_modules/@pi-harness/cli/dist/node-stdio.js +83 -20
  90. package/node_modules/@pi-harness/cli/dist/node-stdio.js.map +1 -1
  91. package/node_modules/@pi-harness/cli/package.json +1 -1
  92. package/node_modules/@pi-harness/core/dist/atomic-write.d.ts +8 -0
  93. package/node_modules/@pi-harness/core/dist/atomic-write.d.ts.map +1 -0
  94. package/node_modules/@pi-harness/core/dist/atomic-write.js +40 -0
  95. package/node_modules/@pi-harness/core/dist/atomic-write.js.map +1 -0
  96. package/node_modules/@pi-harness/core/dist/boot.d.ts.map +1 -1
  97. package/node_modules/@pi-harness/core/dist/boot.js +132 -10
  98. package/node_modules/@pi-harness/core/dist/boot.js.map +1 -1
  99. package/node_modules/@pi-harness/core/dist/bounded-file.d.ts +7 -0
  100. package/node_modules/@pi-harness/core/dist/bounded-file.d.ts.map +1 -0
  101. package/node_modules/@pi-harness/core/dist/bounded-file.js +50 -0
  102. package/node_modules/@pi-harness/core/dist/bounded-file.js.map +1 -0
  103. package/node_modules/@pi-harness/core/dist/config.d.ts +2 -0
  104. package/node_modules/@pi-harness/core/dist/config.d.ts.map +1 -1
  105. package/node_modules/@pi-harness/core/dist/config.js +21 -0
  106. package/node_modules/@pi-harness/core/dist/config.js.map +1 -1
  107. package/node_modules/@pi-harness/core/dist/cordis-timer.d.ts +15 -0
  108. package/node_modules/@pi-harness/core/dist/cordis-timer.d.ts.map +1 -0
  109. package/node_modules/@pi-harness/core/dist/cordis-timer.js +99 -0
  110. package/node_modules/@pi-harness/core/dist/cordis-timer.js.map +1 -0
  111. package/node_modules/@pi-harness/core/dist/plugins/agent-teams.d.ts +5 -1
  112. package/node_modules/@pi-harness/core/dist/plugins/agent-teams.d.ts.map +1 -1
  113. package/node_modules/@pi-harness/core/dist/plugins/agent-teams.js +986 -105
  114. package/node_modules/@pi-harness/core/dist/plugins/agent-teams.js.map +1 -1
  115. package/node_modules/@pi-harness/core/dist/plugins/anchored-standard.d.ts +1 -0
  116. package/node_modules/@pi-harness/core/dist/plugins/anchored-standard.d.ts.map +1 -1
  117. package/node_modules/@pi-harness/core/dist/plugins/anchored-standard.js +39 -11
  118. package/node_modules/@pi-harness/core/dist/plugins/anchored-standard.js.map +1 -1
  119. package/node_modules/@pi-harness/core/dist/plugins/annotation.d.ts +1 -0
  120. package/node_modules/@pi-harness/core/dist/plugins/annotation.d.ts.map +1 -1
  121. package/node_modules/@pi-harness/core/dist/plugins/annotation.js +35 -17
  122. package/node_modules/@pi-harness/core/dist/plugins/annotation.js.map +1 -1
  123. package/node_modules/@pi-harness/core/dist/plugins/archify.d.ts +1 -0
  124. package/node_modules/@pi-harness/core/dist/plugins/archify.d.ts.map +1 -1
  125. package/node_modules/@pi-harness/core/dist/plugins/archify.js +69 -22
  126. package/node_modules/@pi-harness/core/dist/plugins/archify.js.map +1 -1
  127. package/node_modules/@pi-harness/core/dist/plugins/at-file.d.ts +5 -1
  128. package/node_modules/@pi-harness/core/dist/plugins/at-file.d.ts.map +1 -1
  129. package/node_modules/@pi-harness/core/dist/plugins/at-file.js +120 -29
  130. package/node_modules/@pi-harness/core/dist/plugins/at-file.js.map +1 -1
  131. package/node_modules/@pi-harness/core/dist/plugins/auto-mode.d.ts.map +1 -1
  132. package/node_modules/@pi-harness/core/dist/plugins/auto-mode.js +89 -20
  133. package/node_modules/@pi-harness/core/dist/plugins/auto-mode.js.map +1 -1
  134. package/node_modules/@pi-harness/core/dist/plugins/better-sidebar.d.ts +1 -0
  135. package/node_modules/@pi-harness/core/dist/plugins/better-sidebar.d.ts.map +1 -1
  136. package/node_modules/@pi-harness/core/dist/plugins/better-sidebar.js +14 -4
  137. package/node_modules/@pi-harness/core/dist/plugins/better-sidebar.js.map +1 -1
  138. package/node_modules/@pi-harness/core/dist/plugins/browser-fetch.d.ts +1 -0
  139. package/node_modules/@pi-harness/core/dist/plugins/browser-fetch.d.ts.map +1 -1
  140. package/node_modules/@pi-harness/core/dist/plugins/browser-fetch.js +288 -96
  141. package/node_modules/@pi-harness/core/dist/plugins/browser-fetch.js.map +1 -1
  142. package/node_modules/@pi-harness/core/dist/plugins/browser-session.d.ts.map +1 -1
  143. package/node_modules/@pi-harness/core/dist/plugins/browser-session.js +445 -106
  144. package/node_modules/@pi-harness/core/dist/plugins/browser-session.js.map +1 -1
  145. package/node_modules/@pi-harness/core/dist/plugins/canvas-draw.d.ts +1 -0
  146. package/node_modules/@pi-harness/core/dist/plugins/canvas-draw.d.ts.map +1 -1
  147. package/node_modules/@pi-harness/core/dist/plugins/canvas-draw.js +71 -19
  148. package/node_modules/@pi-harness/core/dist/plugins/canvas-draw.js.map +1 -1
  149. package/node_modules/@pi-harness/core/dist/plugins/change-verifier.d.ts +1 -0
  150. package/node_modules/@pi-harness/core/dist/plugins/change-verifier.d.ts.map +1 -1
  151. package/node_modules/@pi-harness/core/dist/plugins/change-verifier.js +30 -9
  152. package/node_modules/@pi-harness/core/dist/plugins/change-verifier.js.map +1 -1
  153. package/node_modules/@pi-harness/core/dist/plugins/cleaner.d.ts +5 -1
  154. package/node_modules/@pi-harness/core/dist/plugins/cleaner.d.ts.map +1 -1
  155. package/node_modules/@pi-harness/core/dist/plugins/cleaner.js +337 -40
  156. package/node_modules/@pi-harness/core/dist/plugins/cleaner.js.map +1 -1
  157. package/node_modules/@pi-harness/core/dist/plugins/cli-notifier.d.ts +2 -1
  158. package/node_modules/@pi-harness/core/dist/plugins/cli-notifier.d.ts.map +1 -1
  159. package/node_modules/@pi-harness/core/dist/plugins/cli-notifier.js +99 -42
  160. package/node_modules/@pi-harness/core/dist/plugins/cli-notifier.js.map +1 -1
  161. package/node_modules/@pi-harness/core/dist/plugins/code2skill.d.ts +1 -0
  162. package/node_modules/@pi-harness/core/dist/plugins/code2skill.d.ts.map +1 -1
  163. package/node_modules/@pi-harness/core/dist/plugins/code2skill.js +178 -38
  164. package/node_modules/@pi-harness/core/dist/plugins/code2skill.js.map +1 -1
  165. package/node_modules/@pi-harness/core/dist/plugins/colleague-skill.d.ts +2 -1
  166. package/node_modules/@pi-harness/core/dist/plugins/colleague-skill.d.ts.map +1 -1
  167. package/node_modules/@pi-harness/core/dist/plugins/colleague-skill.js +79 -49
  168. package/node_modules/@pi-harness/core/dist/plugins/colleague-skill.js.map +1 -1
  169. package/node_modules/@pi-harness/core/dist/plugins/context-doctor.d.ts +6 -1
  170. package/node_modules/@pi-harness/core/dist/plugins/context-doctor.d.ts.map +1 -1
  171. package/node_modules/@pi-harness/core/dist/plugins/context-doctor.js +403 -39
  172. package/node_modules/@pi-harness/core/dist/plugins/context-doctor.js.map +1 -1
  173. package/node_modules/@pi-harness/core/dist/plugins/context.d.ts +1 -0
  174. package/node_modules/@pi-harness/core/dist/plugins/context.d.ts.map +1 -1
  175. package/node_modules/@pi-harness/core/dist/plugins/context.js +169 -42
  176. package/node_modules/@pi-harness/core/dist/plugins/context.js.map +1 -1
  177. package/node_modules/@pi-harness/core/dist/plugins/cost-meter.d.ts +4 -0
  178. package/node_modules/@pi-harness/core/dist/plugins/cost-meter.d.ts.map +1 -1
  179. package/node_modules/@pi-harness/core/dist/plugins/cost-meter.js +319 -93
  180. package/node_modules/@pi-harness/core/dist/plugins/cost-meter.js.map +1 -1
  181. package/node_modules/@pi-harness/core/dist/plugins/dependency-checker.d.ts +11 -2
  182. package/node_modules/@pi-harness/core/dist/plugins/dependency-checker.d.ts.map +1 -1
  183. package/node_modules/@pi-harness/core/dist/plugins/dependency-checker.js +463 -114
  184. package/node_modules/@pi-harness/core/dist/plugins/dependency-checker.js.map +1 -1
  185. package/node_modules/@pi-harness/core/dist/plugins/docker-sandbox.d.ts +1 -0
  186. package/node_modules/@pi-harness/core/dist/plugins/docker-sandbox.d.ts.map +1 -1
  187. package/node_modules/@pi-harness/core/dist/plugins/docker-sandbox.js +322 -80
  188. package/node_modules/@pi-harness/core/dist/plugins/docker-sandbox.js.map +1 -1
  189. package/node_modules/@pi-harness/core/dist/plugins/fail-logger.d.ts +1 -0
  190. package/node_modules/@pi-harness/core/dist/plugins/fail-logger.d.ts.map +1 -1
  191. package/node_modules/@pi-harness/core/dist/plugins/fail-logger.js +187 -20
  192. package/node_modules/@pi-harness/core/dist/plugins/fail-logger.js.map +1 -1
  193. package/node_modules/@pi-harness/core/dist/plugins/genui.d.ts +1 -0
  194. package/node_modules/@pi-harness/core/dist/plugins/genui.d.ts.map +1 -1
  195. package/node_modules/@pi-harness/core/dist/plugins/genui.js +103 -38
  196. package/node_modules/@pi-harness/core/dist/plugins/genui.js.map +1 -1
  197. package/node_modules/@pi-harness/core/dist/plugins/git-time-capsule.d.ts +8 -2
  198. package/node_modules/@pi-harness/core/dist/plugins/git-time-capsule.d.ts.map +1 -1
  199. package/node_modules/@pi-harness/core/dist/plugins/git-time-capsule.js +400 -54
  200. package/node_modules/@pi-harness/core/dist/plugins/git-time-capsule.js.map +1 -1
  201. package/node_modules/@pi-harness/core/dist/plugins/graph-memory.d.ts.map +1 -1
  202. package/node_modules/@pi-harness/core/dist/plugins/graph-memory.js +329 -42
  203. package/node_modules/@pi-harness/core/dist/plugins/graph-memory.js.map +1 -1
  204. package/node_modules/@pi-harness/core/dist/plugins/history-compressor.d.ts.map +1 -1
  205. package/node_modules/@pi-harness/core/dist/plugins/history-compressor.js +31 -12
  206. package/node_modules/@pi-harness/core/dist/plugins/history-compressor.js.map +1 -1
  207. package/node_modules/@pi-harness/core/dist/plugins/hol-guard.d.ts.map +1 -1
  208. package/node_modules/@pi-harness/core/dist/plugins/hol-guard.js +33 -13
  209. package/node_modules/@pi-harness/core/dist/plugins/hol-guard.js.map +1 -1
  210. package/node_modules/@pi-harness/core/dist/plugins/i18n-pair.d.ts +5 -1
  211. package/node_modules/@pi-harness/core/dist/plugins/i18n-pair.d.ts.map +1 -1
  212. package/node_modules/@pi-harness/core/dist/plugins/i18n-pair.js +308 -52
  213. package/node_modules/@pi-harness/core/dist/plugins/i18n-pair.js.map +1 -1
  214. package/node_modules/@pi-harness/core/dist/plugins/image-compressor.d.ts +7 -0
  215. package/node_modules/@pi-harness/core/dist/plugins/image-compressor.d.ts.map +1 -1
  216. package/node_modules/@pi-harness/core/dist/plugins/image-compressor.js +98 -25
  217. package/node_modules/@pi-harness/core/dist/plugins/image-compressor.js.map +1 -1
  218. package/node_modules/@pi-harness/core/dist/plugins/llm-verifier.d.ts.map +1 -1
  219. package/node_modules/@pi-harness/core/dist/plugins/llm-verifier.js +21 -11
  220. package/node_modules/@pi-harness/core/dist/plugins/llm-verifier.js.map +1 -1
  221. package/node_modules/@pi-harness/core/dist/plugins/mcp-client.d.ts.map +1 -1
  222. package/node_modules/@pi-harness/core/dist/plugins/mcp-client.js +986 -232
  223. package/node_modules/@pi-harness/core/dist/plugins/mcp-client.js.map +1 -1
  224. package/node_modules/@pi-harness/core/dist/plugins/mcp-panel.d.ts.map +1 -1
  225. package/node_modules/@pi-harness/core/dist/plugins/mcp-panel.js +30 -16
  226. package/node_modules/@pi-harness/core/dist/plugins/mcp-panel.js.map +1 -1
  227. package/node_modules/@pi-harness/core/dist/plugins/memory.d.ts.map +1 -1
  228. package/node_modules/@pi-harness/core/dist/plugins/memory.js +292 -59
  229. package/node_modules/@pi-harness/core/dist/plugins/memory.js.map +1 -1
  230. package/node_modules/@pi-harness/core/dist/plugins/mirage-bridge.d.ts.map +1 -1
  231. package/node_modules/@pi-harness/core/dist/plugins/mirage-bridge.js +20 -10
  232. package/node_modules/@pi-harness/core/dist/plugins/mirage-bridge.js.map +1 -1
  233. package/node_modules/@pi-harness/core/dist/plugins/mock-server.d.ts.map +1 -1
  234. package/node_modules/@pi-harness/core/dist/plugins/mock-server.js +85 -54
  235. package/node_modules/@pi-harness/core/dist/plugins/mock-server.js.map +1 -1
  236. package/node_modules/@pi-harness/core/dist/plugins/model.d.ts +3 -0
  237. package/node_modules/@pi-harness/core/dist/plugins/model.d.ts.map +1 -1
  238. package/node_modules/@pi-harness/core/dist/plugins/model.js +3 -0
  239. package/node_modules/@pi-harness/core/dist/plugins/model.js.map +1 -1
  240. package/node_modules/@pi-harness/core/dist/plugins/models.d.ts.map +1 -1
  241. package/node_modules/@pi-harness/core/dist/plugins/models.js +10 -2
  242. package/node_modules/@pi-harness/core/dist/plugins/models.js.map +1 -1
  243. package/node_modules/@pi-harness/core/dist/plugins/modlens.d.ts +8 -1
  244. package/node_modules/@pi-harness/core/dist/plugins/modlens.d.ts.map +1 -1
  245. package/node_modules/@pi-harness/core/dist/plugins/modlens.js +438 -31
  246. package/node_modules/@pi-harness/core/dist/plugins/modlens.js.map +1 -1
  247. package/node_modules/@pi-harness/core/dist/plugins/module-search.d.ts +1 -0
  248. package/node_modules/@pi-harness/core/dist/plugins/module-search.d.ts.map +1 -1
  249. package/node_modules/@pi-harness/core/dist/plugins/module-search.js +35 -16
  250. package/node_modules/@pi-harness/core/dist/plugins/module-search.js.map +1 -1
  251. package/node_modules/@pi-harness/core/dist/plugins/obsidian-sync.d.ts.map +1 -1
  252. package/node_modules/@pi-harness/core/dist/plugins/obsidian-sync.js +20 -11
  253. package/node_modules/@pi-harness/core/dist/plugins/obsidian-sync.js.map +1 -1
  254. package/node_modules/@pi-harness/core/dist/plugins/openpets.d.ts.map +1 -1
  255. package/node_modules/@pi-harness/core/dist/plugins/openpets.js +203 -44
  256. package/node_modules/@pi-harness/core/dist/plugins/openpets.js.map +1 -1
  257. package/node_modules/@pi-harness/core/dist/plugins/plan-execute.d.ts +4 -1
  258. package/node_modules/@pi-harness/core/dist/plugins/plan-execute.d.ts.map +1 -1
  259. package/node_modules/@pi-harness/core/dist/plugins/plan-execute.js +42 -21
  260. package/node_modules/@pi-harness/core/dist/plugins/plan-execute.js.map +1 -1
  261. package/node_modules/@pi-harness/core/dist/plugins/plugin-check.d.ts +12 -3
  262. package/node_modules/@pi-harness/core/dist/plugins/plugin-check.d.ts.map +1 -1
  263. package/node_modules/@pi-harness/core/dist/plugins/plugin-check.js +83 -12
  264. package/node_modules/@pi-harness/core/dist/plugins/plugin-check.js.map +1 -1
  265. package/node_modules/@pi-harness/core/dist/plugins/plugin-dev.d.ts +1 -0
  266. package/node_modules/@pi-harness/core/dist/plugins/plugin-dev.d.ts.map +1 -1
  267. package/node_modules/@pi-harness/core/dist/plugins/plugin-dev.js +156 -23
  268. package/node_modules/@pi-harness/core/dist/plugins/plugin-dev.js.map +1 -1
  269. package/node_modules/@pi-harness/core/dist/plugins/plugin-finder.d.ts +1 -0
  270. package/node_modules/@pi-harness/core/dist/plugins/plugin-finder.d.ts.map +1 -1
  271. package/node_modules/@pi-harness/core/dist/plugins/plugin-finder.js +131 -13
  272. package/node_modules/@pi-harness/core/dist/plugins/plugin-finder.js.map +1 -1
  273. package/node_modules/@pi-harness/core/dist/plugins/plugin-radar.d.ts +4 -0
  274. package/node_modules/@pi-harness/core/dist/plugins/plugin-radar.d.ts.map +1 -1
  275. package/node_modules/@pi-harness/core/dist/plugins/plugin-radar.js +137 -36
  276. package/node_modules/@pi-harness/core/dist/plugins/plugin-radar.js.map +1 -1
  277. package/node_modules/@pi-harness/core/dist/plugins/plugin-stars.d.ts.map +1 -1
  278. package/node_modules/@pi-harness/core/dist/plugins/plugin-stars.js +282 -81
  279. package/node_modules/@pi-harness/core/dist/plugins/plugin-stars.js.map +1 -1
  280. package/node_modules/@pi-harness/core/dist/plugins/prompt-guard.d.ts +1 -0
  281. package/node_modules/@pi-harness/core/dist/plugins/prompt-guard.d.ts.map +1 -1
  282. package/node_modules/@pi-harness/core/dist/plugins/prompt-guard.js +60 -9
  283. package/node_modules/@pi-harness/core/dist/plugins/prompt-guard.js.map +1 -1
  284. package/node_modules/@pi-harness/core/dist/plugins/prompt-library.d.ts +1 -0
  285. package/node_modules/@pi-harness/core/dist/plugins/prompt-library.d.ts.map +1 -1
  286. package/node_modules/@pi-harness/core/dist/plugins/prompt-library.js +4 -1
  287. package/node_modules/@pi-harness/core/dist/plugins/prompt-library.js.map +1 -1
  288. package/node_modules/@pi-harness/core/dist/plugins/readme-gen.d.ts +6 -2
  289. package/node_modules/@pi-harness/core/dist/plugins/readme-gen.d.ts.map +1 -1
  290. package/node_modules/@pi-harness/core/dist/plugins/readme-gen.js +514 -73
  291. package/node_modules/@pi-harness/core/dist/plugins/readme-gen.js.map +1 -1
  292. package/node_modules/@pi-harness/core/dist/plugins/recall-unread.d.ts +1 -1
  293. package/node_modules/@pi-harness/core/dist/plugins/recall-unread.d.ts.map +1 -1
  294. package/node_modules/@pi-harness/core/dist/plugins/recall-unread.js +411 -68
  295. package/node_modules/@pi-harness/core/dist/plugins/recall-unread.js.map +1 -1
  296. package/node_modules/@pi-harness/core/dist/plugins/resources.d.ts.map +1 -1
  297. package/node_modules/@pi-harness/core/dist/plugins/resources.js +66 -3
  298. package/node_modules/@pi-harness/core/dist/plugins/resources.js.map +1 -1
  299. package/node_modules/@pi-harness/core/dist/plugins/reverse-skill.d.ts.map +1 -1
  300. package/node_modules/@pi-harness/core/dist/plugins/reverse-skill.js +2 -1
  301. package/node_modules/@pi-harness/core/dist/plugins/reverse-skill.js.map +1 -1
  302. package/node_modules/@pi-harness/core/dist/plugins/reviewer-bot.d.ts +1 -0
  303. package/node_modules/@pi-harness/core/dist/plugins/reviewer-bot.d.ts.map +1 -1
  304. package/node_modules/@pi-harness/core/dist/plugins/reviewer-bot.js +35 -16
  305. package/node_modules/@pi-harness/core/dist/plugins/reviewer-bot.js.map +1 -1
  306. package/node_modules/@pi-harness/core/dist/plugins/runtime-doctor.d.ts +1 -0
  307. package/node_modules/@pi-harness/core/dist/plugins/runtime-doctor.d.ts.map +1 -1
  308. package/node_modules/@pi-harness/core/dist/plugins/runtime-doctor.js +4 -1
  309. package/node_modules/@pi-harness/core/dist/plugins/runtime-doctor.js.map +1 -1
  310. package/node_modules/@pi-harness/core/dist/plugins/runtime.d.ts.map +1 -1
  311. package/node_modules/@pi-harness/core/dist/plugins/runtime.js +104 -70
  312. package/node_modules/@pi-harness/core/dist/plugins/runtime.js.map +1 -1
  313. package/node_modules/@pi-harness/core/dist/plugins/secure-audit.d.ts +1 -0
  314. package/node_modules/@pi-harness/core/dist/plugins/secure-audit.d.ts.map +1 -1
  315. package/node_modules/@pi-harness/core/dist/plugins/secure-audit.js +30 -12
  316. package/node_modules/@pi-harness/core/dist/plugins/secure-audit.js.map +1 -1
  317. package/node_modules/@pi-harness/core/dist/plugins/session-bookmarks.d.ts +1 -0
  318. package/node_modules/@pi-harness/core/dist/plugins/session-bookmarks.d.ts.map +1 -1
  319. package/node_modules/@pi-harness/core/dist/plugins/session-bookmarks.js +4 -1
  320. package/node_modules/@pi-harness/core/dist/plugins/session-bookmarks.js.map +1 -1
  321. package/node_modules/@pi-harness/core/dist/plugins/session-bridge.d.ts +1 -0
  322. package/node_modules/@pi-harness/core/dist/plugins/session-bridge.d.ts.map +1 -1
  323. package/node_modules/@pi-harness/core/dist/plugins/session-bridge.js +401 -88
  324. package/node_modules/@pi-harness/core/dist/plugins/session-bridge.js.map +1 -1
  325. package/node_modules/@pi-harness/core/dist/plugins/session-compare.d.ts +1 -0
  326. package/node_modules/@pi-harness/core/dist/plugins/session-compare.d.ts.map +1 -1
  327. package/node_modules/@pi-harness/core/dist/plugins/session-compare.js +4 -1
  328. package/node_modules/@pi-harness/core/dist/plugins/session-compare.js.map +1 -1
  329. package/node_modules/@pi-harness/core/dist/plugins/session-export.d.ts +1 -0
  330. package/node_modules/@pi-harness/core/dist/plugins/session-export.d.ts.map +1 -1
  331. package/node_modules/@pi-harness/core/dist/plugins/session-export.js +6 -6
  332. package/node_modules/@pi-harness/core/dist/plugins/session-export.js.map +1 -1
  333. package/node_modules/@pi-harness/core/dist/plugins/session-insights.d.ts +37 -1
  334. package/node_modules/@pi-harness/core/dist/plugins/session-insights.d.ts.map +1 -1
  335. package/node_modules/@pi-harness/core/dist/plugins/session-insights.js +406 -21
  336. package/node_modules/@pi-harness/core/dist/plugins/session-insights.js.map +1 -1
  337. package/node_modules/@pi-harness/core/dist/plugins/session-search.d.ts +1 -0
  338. package/node_modules/@pi-harness/core/dist/plugins/session-search.d.ts.map +1 -1
  339. package/node_modules/@pi-harness/core/dist/plugins/session-search.js +4 -1
  340. package/node_modules/@pi-harness/core/dist/plugins/session-search.js.map +1 -1
  341. package/node_modules/@pi-harness/core/dist/plugins/session.d.ts.map +1 -1
  342. package/node_modules/@pi-harness/core/dist/plugins/session.js +8 -1
  343. package/node_modules/@pi-harness/core/dist/plugins/session.js.map +1 -1
  344. package/node_modules/@pi-harness/core/dist/plugins/skill-catalog.d.ts +1 -0
  345. package/node_modules/@pi-harness/core/dist/plugins/skill-catalog.d.ts.map +1 -1
  346. package/node_modules/@pi-harness/core/dist/plugins/skill-catalog.js +6 -5
  347. package/node_modules/@pi-harness/core/dist/plugins/skill-catalog.js.map +1 -1
  348. package/node_modules/@pi-harness/core/dist/plugins/skill-guard.d.ts +2 -1
  349. package/node_modules/@pi-harness/core/dist/plugins/skill-guard.d.ts.map +1 -1
  350. package/node_modules/@pi-harness/core/dist/plugins/skill-guard.js +241 -61
  351. package/node_modules/@pi-harness/core/dist/plugins/skill-guard.js.map +1 -1
  352. package/node_modules/@pi-harness/core/dist/plugins/sql-lens-worker.d.ts +2 -0
  353. package/node_modules/@pi-harness/core/dist/plugins/sql-lens-worker.d.ts.map +1 -0
  354. package/node_modules/@pi-harness/core/dist/plugins/sql-lens-worker.js +206 -0
  355. package/node_modules/@pi-harness/core/dist/plugins/sql-lens-worker.js.map +1 -0
  356. package/node_modules/@pi-harness/core/dist/plugins/sql-lens.d.ts +7 -1
  357. package/node_modules/@pi-harness/core/dist/plugins/sql-lens.d.ts.map +1 -1
  358. package/node_modules/@pi-harness/core/dist/plugins/sql-lens.js +301 -68
  359. package/node_modules/@pi-harness/core/dist/plugins/sql-lens.js.map +1 -1
  360. package/node_modules/@pi-harness/core/dist/plugins/stdio.d.ts +3 -0
  361. package/node_modules/@pi-harness/core/dist/plugins/stdio.d.ts.map +1 -1
  362. package/node_modules/@pi-harness/core/dist/plugins/stdio.js +62 -4
  363. package/node_modules/@pi-harness/core/dist/plugins/stdio.js.map +1 -1
  364. package/node_modules/@pi-harness/core/dist/plugins/synapse.d.ts.map +1 -1
  365. package/node_modules/@pi-harness/core/dist/plugins/synapse.js +17 -9
  366. package/node_modules/@pi-harness/core/dist/plugins/synapse.js.map +1 -1
  367. package/node_modules/@pi-harness/core/dist/plugins/tab-manager.d.ts +1 -0
  368. package/node_modules/@pi-harness/core/dist/plugins/tab-manager.d.ts.map +1 -1
  369. package/node_modules/@pi-harness/core/dist/plugins/tab-manager.js +167 -62
  370. package/node_modules/@pi-harness/core/dist/plugins/tab-manager.js.map +1 -1
  371. package/node_modules/@pi-harness/core/dist/plugins/taskboard.d.ts.map +1 -1
  372. package/node_modules/@pi-harness/core/dist/plugins/taskboard.js +50 -22
  373. package/node_modules/@pi-harness/core/dist/plugins/taskboard.js.map +1 -1
  374. package/node_modules/@pi-harness/core/dist/plugins/telemetry-blocker.d.ts +4 -1
  375. package/node_modules/@pi-harness/core/dist/plugins/telemetry-blocker.d.ts.map +1 -1
  376. package/node_modules/@pi-harness/core/dist/plugins/telemetry-blocker.js +30 -11
  377. package/node_modules/@pi-harness/core/dist/plugins/telemetry-blocker.js.map +1 -1
  378. package/node_modules/@pi-harness/core/dist/plugins/test-harness.d.ts +7 -1
  379. package/node_modules/@pi-harness/core/dist/plugins/test-harness.d.ts.map +1 -1
  380. package/node_modules/@pi-harness/core/dist/plugins/test-harness.js +255 -43
  381. package/node_modules/@pi-harness/core/dist/plugins/test-harness.js.map +1 -1
  382. package/node_modules/@pi-harness/core/dist/plugins/theme-studio.d.ts.map +1 -1
  383. package/node_modules/@pi-harness/core/dist/plugins/theme-studio.js +4 -2
  384. package/node_modules/@pi-harness/core/dist/plugins/theme-studio.js.map +1 -1
  385. package/node_modules/@pi-harness/core/dist/plugins/token-guard.d.ts.map +1 -1
  386. package/node_modules/@pi-harness/core/dist/plugins/token-guard.js +164 -32
  387. package/node_modules/@pi-harness/core/dist/plugins/token-guard.js.map +1 -1
  388. package/node_modules/@pi-harness/core/dist/plugins/tools.d.ts.map +1 -1
  389. package/node_modules/@pi-harness/core/dist/plugins/tools.js +4 -1
  390. package/node_modules/@pi-harness/core/dist/plugins/tools.js.map +1 -1
  391. package/node_modules/@pi-harness/core/dist/plugins/turn-rewind.d.ts +17 -0
  392. package/node_modules/@pi-harness/core/dist/plugins/turn-rewind.d.ts.map +1 -1
  393. package/node_modules/@pi-harness/core/dist/plugins/turn-rewind.js +340 -36
  394. package/node_modules/@pi-harness/core/dist/plugins/turn-rewind.js.map +1 -1
  395. package/node_modules/@pi-harness/core/dist/plugins/undo-savepoint.d.ts.map +1 -1
  396. package/node_modules/@pi-harness/core/dist/plugins/undo-savepoint.js +157 -51
  397. package/node_modules/@pi-harness/core/dist/plugins/undo-savepoint.js.map +1 -1
  398. package/node_modules/@pi-harness/core/dist/plugins/vision-toolkit.d.ts +22 -3
  399. package/node_modules/@pi-harness/core/dist/plugins/vision-toolkit.d.ts.map +1 -1
  400. package/node_modules/@pi-harness/core/dist/plugins/vision-toolkit.js +389 -66
  401. package/node_modules/@pi-harness/core/dist/plugins/vision-toolkit.js.map +1 -1
  402. package/node_modules/@pi-harness/core/dist/plugins/web-research.d.ts.map +1 -1
  403. package/node_modules/@pi-harness/core/dist/plugins/web-research.js +13 -4
  404. package/node_modules/@pi-harness/core/dist/plugins/web-research.js.map +1 -1
  405. package/node_modules/@pi-harness/core/dist/plugins/workspace-navigator.d.ts +8 -2
  406. package/node_modules/@pi-harness/core/dist/plugins/workspace-navigator.d.ts.map +1 -1
  407. package/node_modules/@pi-harness/core/dist/plugins/workspace-navigator.js +28 -10
  408. package/node_modules/@pi-harness/core/dist/plugins/workspace-navigator.js.map +1 -1
  409. package/node_modules/@pi-harness/core/dist/plugins/workspace-search.d.ts +7 -0
  410. package/node_modules/@pi-harness/core/dist/plugins/workspace-search.d.ts.map +1 -1
  411. package/node_modules/@pi-harness/core/dist/plugins/workspace-search.js +67 -34
  412. package/node_modules/@pi-harness/core/dist/plugins/workspace-search.js.map +1 -1
  413. package/node_modules/@pi-harness/core/dist/plugins/yaml-validator.d.ts +1 -0
  414. package/node_modules/@pi-harness/core/dist/plugins/yaml-validator.d.ts.map +1 -1
  415. package/node_modules/@pi-harness/core/dist/plugins/yaml-validator.js +156 -47
  416. package/node_modules/@pi-harness/core/dist/plugins/yaml-validator.js.map +1 -1
  417. package/node_modules/@pi-harness/core/dist/runtime.d.ts.map +1 -1
  418. package/node_modules/@pi-harness/core/dist/runtime.js +8 -3
  419. package/node_modules/@pi-harness/core/dist/runtime.js.map +1 -1
  420. package/node_modules/@pi-harness/core/dist/services.d.ts.map +1 -1
  421. package/node_modules/@pi-harness/core/dist/services.js +22 -2
  422. package/node_modules/@pi-harness/core/dist/services.js.map +1 -1
  423. package/node_modules/@pi-harness/core/dist/stdio.d.ts +1 -0
  424. package/node_modules/@pi-harness/core/dist/stdio.d.ts.map +1 -1
  425. package/node_modules/@pi-harness/core/dist/stdio.js +241 -25
  426. package/node_modules/@pi-harness/core/dist/stdio.js.map +1 -1
  427. package/node_modules/@pi-harness/core/dist/workspace-path.d.ts +1 -0
  428. package/node_modules/@pi-harness/core/dist/workspace-path.d.ts.map +1 -1
  429. package/node_modules/@pi-harness/core/dist/workspace-path.js +9 -0
  430. package/node_modules/@pi-harness/core/dist/workspace-path.js.map +1 -1
  431. package/node_modules/@pi-harness/core/package.json +1 -1
  432. package/node_modules/@pi-harness/core/profiles/default/cordis.yml +4 -2
  433. package/node_modules/@pi-harness/host-webserver/package.json +1 -1
  434. package/node_modules/@pi-harness/web-app/package.json +1 -1
  435. package/package.json +12 -7
  436. package/packages/api-gateway/dist/index.d.ts.map +1 -1
  437. package/packages/api-gateway/dist/index.js +97 -9
  438. package/packages/api-gateway/dist/index.js.map +1 -1
  439. package/packages/api-gateway/dist/marketplace-entries/official/agent-teams.json +6 -6
  440. package/packages/api-gateway/dist/marketplace-entries/official/anchored-standard.json +1 -1
  441. package/packages/api-gateway/dist/marketplace-entries/official/annotation.json +1 -2
  442. package/packages/api-gateway/dist/marketplace-entries/official/archify.json +1 -1
  443. package/packages/api-gateway/dist/marketplace-entries/official/at-file.json +11 -5
  444. package/packages/api-gateway/dist/marketplace-entries/official/auto-mode.json +1 -1
  445. package/packages/api-gateway/dist/marketplace-entries/official/better-sidebar.json +1 -1
  446. package/packages/api-gateway/dist/marketplace-entries/official/browser-fetch.json +12 -5
  447. package/packages/api-gateway/dist/marketplace-entries/official/browser-session.json +14 -8
  448. package/packages/api-gateway/dist/marketplace-entries/official/canvas-draw.json +3 -4
  449. package/packages/api-gateway/dist/marketplace-entries/official/change-verifier.json +1 -1
  450. package/packages/api-gateway/dist/marketplace-entries/official/cleaner.json +11 -6
  451. package/packages/api-gateway/dist/marketplace-entries/official/cli-notifier.json +5 -5
  452. package/packages/api-gateway/dist/marketplace-entries/official/code2skill.json +5 -5
  453. package/packages/api-gateway/dist/marketplace-entries/official/colleague-skill.json +1 -2
  454. package/packages/api-gateway/dist/marketplace-entries/official/context-doctor.json +12 -7
  455. package/packages/api-gateway/dist/marketplace-entries/official/context.json +10 -5
  456. package/packages/api-gateway/dist/marketplace-entries/official/cordis-group.json +2 -2
  457. package/packages/api-gateway/dist/marketplace-entries/official/cordis-logger-console.json +4 -4
  458. package/packages/api-gateway/dist/marketplace-entries/official/cordis-timer.json +3 -3
  459. package/packages/api-gateway/dist/marketplace-entries/official/cost-meter.json +9 -6
  460. package/packages/api-gateway/dist/marketplace-entries/official/dependency-checker.json +13 -10
  461. package/packages/api-gateway/dist/marketplace-entries/official/docker-sandbox.json +10 -5
  462. package/packages/api-gateway/dist/marketplace-entries/official/fail-logger.json +11 -6
  463. package/packages/api-gateway/dist/marketplace-entries/official/genui.json +7 -5
  464. package/packages/api-gateway/dist/marketplace-entries/official/git-time-capsule.json +13 -8
  465. package/packages/api-gateway/dist/marketplace-entries/official/graph-memory.json +13 -7
  466. package/packages/api-gateway/dist/marketplace-entries/official/history-compressor.json +1 -1
  467. package/packages/api-gateway/dist/marketplace-entries/official/hol-guard.json +1 -1
  468. package/packages/api-gateway/dist/marketplace-entries/official/i18n-pair.json +9 -6
  469. package/packages/api-gateway/dist/marketplace-entries/official/image-compressor.json +1 -1
  470. package/packages/api-gateway/dist/marketplace-entries/official/llm-verifier.json +1 -1
  471. package/packages/api-gateway/dist/marketplace-entries/official/mcp-client.json +12 -7
  472. package/packages/api-gateway/dist/marketplace-entries/official/mcp-panel.json +1 -1
  473. package/packages/api-gateway/dist/marketplace-entries/official/memory.json +1 -1
  474. package/packages/api-gateway/dist/marketplace-entries/official/mirage-bridge.json +1 -1
  475. package/packages/api-gateway/dist/marketplace-entries/official/mock-server.json +1 -1
  476. package/packages/api-gateway/dist/marketplace-entries/official/modlens.json +4 -4
  477. package/packages/api-gateway/dist/marketplace-entries/official/module-search.json +1 -1
  478. package/packages/api-gateway/dist/marketplace-entries/official/obsidian-sync.json +1 -1
  479. package/packages/api-gateway/dist/marketplace-entries/official/openpets.json +9 -5
  480. package/packages/api-gateway/dist/marketplace-entries/official/plan-execute.json +1 -1
  481. package/packages/api-gateway/dist/marketplace-entries/official/plugin-check.json +1 -1
  482. package/packages/api-gateway/dist/marketplace-entries/official/plugin-dev.json +8 -6
  483. package/packages/api-gateway/dist/marketplace-entries/official/plugin-finder.json +1 -1
  484. package/packages/api-gateway/dist/marketplace-entries/official/plugin-radar.json +1 -1
  485. package/packages/api-gateway/dist/marketplace-entries/official/plugin-stars.json +15 -7
  486. package/packages/api-gateway/dist/marketplace-entries/official/prompt-guard.json +1 -1
  487. package/packages/api-gateway/dist/marketplace-entries/official/prompt-library.json +1 -1
  488. package/packages/api-gateway/dist/marketplace-entries/official/readme-gen.json +12 -8
  489. package/packages/api-gateway/dist/marketplace-entries/official/recall-unread.json +11 -6
  490. package/packages/api-gateway/dist/marketplace-entries/official/reverse-skill.json +1 -1
  491. package/packages/api-gateway/dist/marketplace-entries/official/reviewer-bot.json +1 -1
  492. package/packages/api-gateway/dist/marketplace-entries/official/runtime-doctor.json +1 -1
  493. package/packages/api-gateway/dist/marketplace-entries/official/secure-audit.json +1 -1
  494. package/packages/api-gateway/dist/marketplace-entries/official/session-bookmarks.json +1 -1
  495. package/packages/api-gateway/dist/marketplace-entries/official/session-bridge.json +13 -8
  496. package/packages/api-gateway/dist/marketplace-entries/official/session-compare.json +1 -1
  497. package/packages/api-gateway/dist/marketplace-entries/official/session-export.json +1 -1
  498. package/packages/api-gateway/dist/marketplace-entries/official/session-insights.json +12 -6
  499. package/packages/api-gateway/dist/marketplace-entries/official/session-search.json +1 -1
  500. package/packages/api-gateway/dist/marketplace-entries/official/skill-catalog.json +1 -1
  501. package/packages/api-gateway/dist/marketplace-entries/official/skill-guard.json +9 -5
  502. package/packages/api-gateway/dist/marketplace-entries/official/sql-lens.json +13 -7
  503. package/packages/api-gateway/dist/marketplace-entries/official/synapse.json +1 -1
  504. package/packages/api-gateway/dist/marketplace-entries/official/tab-manager.json +1 -1
  505. package/packages/api-gateway/dist/marketplace-entries/official/taskboard.json +1 -1
  506. package/packages/api-gateway/dist/marketplace-entries/official/telemetry-blocker.json +1 -1
  507. package/packages/api-gateway/dist/marketplace-entries/official/test-harness.json +14 -7
  508. package/packages/api-gateway/dist/marketplace-entries/official/theme-studio.json +1 -1
  509. package/packages/api-gateway/dist/marketplace-entries/official/token-guard.json +12 -6
  510. package/packages/api-gateway/dist/marketplace-entries/official/turn-rewind.json +11 -6
  511. package/packages/api-gateway/dist/marketplace-entries/official/undo-savepoint.json +1 -1
  512. package/packages/api-gateway/dist/marketplace-entries/official/vision-toolkit.json +8 -5
  513. package/packages/api-gateway/dist/marketplace-entries/official/web-research.json +1 -1
  514. package/packages/api-gateway/dist/marketplace-entries/official/workspace-navigator.json +1 -1
  515. package/packages/api-gateway/dist/marketplace-entries/official/workspace-search.json +1 -1
  516. package/packages/api-gateway/dist/marketplace-entries/official/yaml-validator.json +8 -5
  517. package/packages/api-gateway/package.json +1 -1
  518. package/packages/api-gateway/src/index.ts +90 -9
  519. package/packages/api-gateway/src/marketplace-entries/official/agent-teams.json +6 -6
  520. package/packages/api-gateway/src/marketplace-entries/official/anchored-standard.json +1 -1
  521. package/packages/api-gateway/src/marketplace-entries/official/annotation.json +1 -2
  522. package/packages/api-gateway/src/marketplace-entries/official/archify.json +1 -1
  523. package/packages/api-gateway/src/marketplace-entries/official/at-file.json +11 -5
  524. package/packages/api-gateway/src/marketplace-entries/official/auto-mode.json +1 -1
  525. package/packages/api-gateway/src/marketplace-entries/official/better-sidebar.json +1 -1
  526. package/packages/api-gateway/src/marketplace-entries/official/browser-fetch.json +12 -5
  527. package/packages/api-gateway/src/marketplace-entries/official/browser-session.json +14 -8
  528. package/packages/api-gateway/src/marketplace-entries/official/canvas-draw.json +3 -4
  529. package/packages/api-gateway/src/marketplace-entries/official/change-verifier.json +1 -1
  530. package/packages/api-gateway/src/marketplace-entries/official/cleaner.json +11 -6
  531. package/packages/api-gateway/src/marketplace-entries/official/cli-notifier.json +5 -5
  532. package/packages/api-gateway/src/marketplace-entries/official/code2skill.json +5 -5
  533. package/packages/api-gateway/src/marketplace-entries/official/colleague-skill.json +1 -2
  534. package/packages/api-gateway/src/marketplace-entries/official/context-doctor.json +12 -7
  535. package/packages/api-gateway/src/marketplace-entries/official/context.json +10 -5
  536. package/packages/api-gateway/src/marketplace-entries/official/cordis-group.json +2 -2
  537. package/packages/api-gateway/src/marketplace-entries/official/cordis-logger-console.json +4 -4
  538. package/packages/api-gateway/src/marketplace-entries/official/cordis-timer.json +3 -3
  539. package/packages/api-gateway/src/marketplace-entries/official/cost-meter.json +9 -6
  540. package/packages/api-gateway/src/marketplace-entries/official/dependency-checker.json +13 -10
  541. package/packages/api-gateway/src/marketplace-entries/official/docker-sandbox.json +10 -5
  542. package/packages/api-gateway/src/marketplace-entries/official/fail-logger.json +11 -6
  543. package/packages/api-gateway/src/marketplace-entries/official/genui.json +7 -5
  544. package/packages/api-gateway/src/marketplace-entries/official/git-time-capsule.json +13 -8
  545. package/packages/api-gateway/src/marketplace-entries/official/graph-memory.json +13 -7
  546. package/packages/api-gateway/src/marketplace-entries/official/history-compressor.json +1 -1
  547. package/packages/api-gateway/src/marketplace-entries/official/hol-guard.json +1 -1
  548. package/packages/api-gateway/src/marketplace-entries/official/i18n-pair.json +9 -6
  549. package/packages/api-gateway/src/marketplace-entries/official/image-compressor.json +1 -1
  550. package/packages/api-gateway/src/marketplace-entries/official/llm-verifier.json +1 -1
  551. package/packages/api-gateway/src/marketplace-entries/official/mcp-client.json +12 -7
  552. package/packages/api-gateway/src/marketplace-entries/official/mcp-panel.json +1 -1
  553. package/packages/api-gateway/src/marketplace-entries/official/memory.json +1 -1
  554. package/packages/api-gateway/src/marketplace-entries/official/mirage-bridge.json +1 -1
  555. package/packages/api-gateway/src/marketplace-entries/official/mock-server.json +1 -1
  556. package/packages/api-gateway/src/marketplace-entries/official/modlens.json +4 -4
  557. package/packages/api-gateway/src/marketplace-entries/official/module-search.json +1 -1
  558. package/packages/api-gateway/src/marketplace-entries/official/obsidian-sync.json +1 -1
  559. package/packages/api-gateway/src/marketplace-entries/official/openpets.json +9 -5
  560. package/packages/api-gateway/src/marketplace-entries/official/plan-execute.json +1 -1
  561. package/packages/api-gateway/src/marketplace-entries/official/plugin-check.json +1 -1
  562. package/packages/api-gateway/src/marketplace-entries/official/plugin-dev.json +8 -6
  563. package/packages/api-gateway/src/marketplace-entries/official/plugin-finder.json +1 -1
  564. package/packages/api-gateway/src/marketplace-entries/official/plugin-radar.json +1 -1
  565. package/packages/api-gateway/src/marketplace-entries/official/plugin-stars.json +15 -7
  566. package/packages/api-gateway/src/marketplace-entries/official/prompt-guard.json +1 -1
  567. package/packages/api-gateway/src/marketplace-entries/official/prompt-library.json +1 -1
  568. package/packages/api-gateway/src/marketplace-entries/official/readme-gen.json +12 -8
  569. package/packages/api-gateway/src/marketplace-entries/official/recall-unread.json +11 -6
  570. package/packages/api-gateway/src/marketplace-entries/official/reverse-skill.json +1 -1
  571. package/packages/api-gateway/src/marketplace-entries/official/reviewer-bot.json +1 -1
  572. package/packages/api-gateway/src/marketplace-entries/official/runtime-doctor.json +1 -1
  573. package/packages/api-gateway/src/marketplace-entries/official/secure-audit.json +1 -1
  574. package/packages/api-gateway/src/marketplace-entries/official/session-bookmarks.json +1 -1
  575. package/packages/api-gateway/src/marketplace-entries/official/session-bridge.json +13 -8
  576. package/packages/api-gateway/src/marketplace-entries/official/session-compare.json +1 -1
  577. package/packages/api-gateway/src/marketplace-entries/official/session-export.json +1 -1
  578. package/packages/api-gateway/src/marketplace-entries/official/session-insights.json +12 -6
  579. package/packages/api-gateway/src/marketplace-entries/official/session-search.json +1 -1
  580. package/packages/api-gateway/src/marketplace-entries/official/skill-catalog.json +1 -1
  581. package/packages/api-gateway/src/marketplace-entries/official/skill-guard.json +9 -5
  582. package/packages/api-gateway/src/marketplace-entries/official/sql-lens.json +13 -7
  583. package/packages/api-gateway/src/marketplace-entries/official/synapse.json +1 -1
  584. package/packages/api-gateway/src/marketplace-entries/official/tab-manager.json +1 -1
  585. package/packages/api-gateway/src/marketplace-entries/official/taskboard.json +1 -1
  586. package/packages/api-gateway/src/marketplace-entries/official/telemetry-blocker.json +1 -1
  587. package/packages/api-gateway/src/marketplace-entries/official/test-harness.json +14 -7
  588. package/packages/api-gateway/src/marketplace-entries/official/theme-studio.json +1 -1
  589. package/packages/api-gateway/src/marketplace-entries/official/token-guard.json +12 -6
  590. package/packages/api-gateway/src/marketplace-entries/official/turn-rewind.json +11 -6
  591. package/packages/api-gateway/src/marketplace-entries/official/undo-savepoint.json +1 -1
  592. package/packages/api-gateway/src/marketplace-entries/official/vision-toolkit.json +8 -5
  593. package/packages/api-gateway/src/marketplace-entries/official/web-research.json +1 -1
  594. package/packages/api-gateway/src/marketplace-entries/official/workspace-navigator.json +1 -1
  595. package/packages/api-gateway/src/marketplace-entries/official/workspace-search.json +1 -1
  596. package/packages/api-gateway/src/marketplace-entries/official/yaml-validator.json +8 -5
  597. package/packages/api-gateway/test/index.test.ts +1594 -2
  598. package/packages/api-gateway/test/marketplace.test.ts +389 -2
  599. package/packages/api-gateway/test/release-package.test.ts +1 -0
  600. package/packages/bundle-web-app/package.json +1 -1
  601. package/packages/cli/dist/node-stdio.d.ts.map +1 -1
  602. package/packages/cli/dist/node-stdio.js +83 -20
  603. package/packages/cli/dist/node-stdio.js.map +1 -1
  604. package/packages/cli/package.json +1 -1
  605. package/packages/cli/src/node-stdio.ts +77 -20
  606. package/packages/cli/test/node-stdio.test.ts +118 -2
  607. package/packages/client-web/dist/agent-teams-view.d.ts +70 -0
  608. package/packages/client-web/dist/agent-teams-view.d.ts.map +1 -0
  609. package/packages/client-web/dist/agent-teams-view.js +159 -0
  610. package/packages/client-web/dist/agent-teams-view.js.map +1 -0
  611. package/packages/client-web/dist/at-file-view.d.ts +10 -0
  612. package/packages/client-web/dist/at-file-view.d.ts.map +1 -0
  613. package/packages/client-web/dist/at-file-view.js +65 -0
  614. package/packages/client-web/dist/at-file-view.js.map +1 -0
  615. package/packages/client-web/dist/browser-fetch-view.d.ts +22 -0
  616. package/packages/client-web/dist/browser-fetch-view.d.ts.map +1 -0
  617. package/packages/client-web/dist/browser-fetch-view.js +101 -0
  618. package/packages/client-web/dist/browser-fetch-view.js.map +1 -0
  619. package/packages/client-web/dist/browser-session-view.d.ts +32 -0
  620. package/packages/client-web/dist/browser-session-view.d.ts.map +1 -1
  621. package/packages/client-web/dist/browser-session-view.js +206 -3
  622. package/packages/client-web/dist/browser-session-view.js.map +1 -1
  623. package/packages/client-web/dist/cleaner-view.d.ts +29 -0
  624. package/packages/client-web/dist/cleaner-view.d.ts.map +1 -0
  625. package/packages/client-web/dist/cleaner-view.js +191 -0
  626. package/packages/client-web/dist/cleaner-view.js.map +1 -0
  627. package/packages/client-web/dist/context-doctor-view.d.ts +35 -0
  628. package/packages/client-web/dist/context-doctor-view.d.ts.map +1 -0
  629. package/packages/client-web/dist/context-doctor-view.js +129 -0
  630. package/packages/client-web/dist/context-doctor-view.js.map +1 -0
  631. package/packages/client-web/dist/context-insights-view.d.ts +31 -0
  632. package/packages/client-web/dist/context-insights-view.d.ts.map +1 -0
  633. package/packages/client-web/dist/context-insights-view.js +90 -0
  634. package/packages/client-web/dist/context-insights-view.js.map +1 -0
  635. package/packages/client-web/dist/cost-meter-view.d.ts +16 -0
  636. package/packages/client-web/dist/cost-meter-view.d.ts.map +1 -0
  637. package/packages/client-web/dist/cost-meter-view.js +43 -0
  638. package/packages/client-web/dist/cost-meter-view.js.map +1 -0
  639. package/packages/client-web/dist/dependency-checker-view.d.ts +24 -0
  640. package/packages/client-web/dist/dependency-checker-view.d.ts.map +1 -0
  641. package/packages/client-web/dist/dependency-checker-view.js +195 -0
  642. package/packages/client-web/dist/dependency-checker-view.js.map +1 -0
  643. package/packages/client-web/dist/docker-sandbox-view.d.ts +28 -0
  644. package/packages/client-web/dist/docker-sandbox-view.d.ts.map +1 -0
  645. package/packages/client-web/dist/docker-sandbox-view.js +152 -0
  646. package/packages/client-web/dist/docker-sandbox-view.js.map +1 -0
  647. package/packages/client-web/dist/fail-logger-view.d.ts +16 -0
  648. package/packages/client-web/dist/fail-logger-view.d.ts.map +1 -0
  649. package/packages/client-web/dist/fail-logger-view.js +97 -0
  650. package/packages/client-web/dist/fail-logger-view.js.map +1 -0
  651. package/packages/client-web/dist/genui-view.d.ts +28 -0
  652. package/packages/client-web/dist/genui-view.d.ts.map +1 -0
  653. package/packages/client-web/dist/genui-view.js +62 -0
  654. package/packages/client-web/dist/genui-view.js.map +1 -0
  655. package/packages/client-web/dist/git-time-capsule-view.d.ts +31 -0
  656. package/packages/client-web/dist/git-time-capsule-view.d.ts.map +1 -0
  657. package/packages/client-web/dist/git-time-capsule-view.js +203 -0
  658. package/packages/client-web/dist/git-time-capsule-view.js.map +1 -0
  659. package/packages/client-web/dist/graph-memory-view.d.ts +39 -0
  660. package/packages/client-web/dist/graph-memory-view.d.ts.map +1 -0
  661. package/packages/client-web/dist/graph-memory-view.js +82 -0
  662. package/packages/client-web/dist/graph-memory-view.js.map +1 -0
  663. package/packages/client-web/dist/i18n-pair-view.d.ts +32 -0
  664. package/packages/client-web/dist/i18n-pair-view.d.ts.map +1 -0
  665. package/packages/client-web/dist/i18n-pair-view.js +182 -0
  666. package/packages/client-web/dist/i18n-pair-view.js.map +1 -0
  667. package/packages/client-web/dist/mcp-client-view.d.ts +58 -0
  668. package/packages/client-web/dist/mcp-client-view.d.ts.map +1 -0
  669. package/packages/client-web/dist/mcp-client-view.js +121 -0
  670. package/packages/client-web/dist/mcp-client-view.js.map +1 -0
  671. package/packages/client-web/dist/modlens-view.d.ts +43 -0
  672. package/packages/client-web/dist/modlens-view.d.ts.map +1 -0
  673. package/packages/client-web/dist/modlens-view.js +176 -0
  674. package/packages/client-web/dist/modlens-view.js.map +1 -0
  675. package/packages/client-web/dist/openpets-view.d.ts +26 -0
  676. package/packages/client-web/dist/openpets-view.d.ts.map +1 -0
  677. package/packages/client-web/dist/openpets-view.js +62 -0
  678. package/packages/client-web/dist/openpets-view.js.map +1 -0
  679. package/packages/client-web/dist/panel-safe.d.ts +5 -0
  680. package/packages/client-web/dist/panel-safe.d.ts.map +1 -0
  681. package/packages/client-web/dist/panel-safe.js +58 -0
  682. package/packages/client-web/dist/panel-safe.js.map +1 -0
  683. package/packages/client-web/dist/plugin-dev-view.d.ts +15 -0
  684. package/packages/client-web/dist/plugin-dev-view.d.ts.map +1 -0
  685. package/packages/client-web/dist/plugin-dev-view.js +33 -0
  686. package/packages/client-web/dist/plugin-dev-view.js.map +1 -0
  687. package/packages/client-web/dist/plugin-stars-view.d.ts +28 -0
  688. package/packages/client-web/dist/plugin-stars-view.d.ts.map +1 -1
  689. package/packages/client-web/dist/plugin-stars-view.js +209 -1
  690. package/packages/client-web/dist/plugin-stars-view.js.map +1 -1
  691. package/packages/client-web/dist/react-room.d.ts +5 -1
  692. package/packages/client-web/dist/react-room.d.ts.map +1 -1
  693. package/packages/client-web/dist/react-room.js +463 -219
  694. package/packages/client-web/dist/react-room.js.map +1 -1
  695. package/packages/client-web/dist/readme-gen-view.d.ts +30 -0
  696. package/packages/client-web/dist/readme-gen-view.d.ts.map +1 -0
  697. package/packages/client-web/dist/readme-gen-view.js +134 -0
  698. package/packages/client-web/dist/readme-gen-view.js.map +1 -0
  699. package/packages/client-web/dist/recall-unread-view.d.ts +46 -0
  700. package/packages/client-web/dist/recall-unread-view.d.ts.map +1 -0
  701. package/packages/client-web/dist/recall-unread-view.js +104 -0
  702. package/packages/client-web/dist/recall-unread-view.js.map +1 -0
  703. package/packages/client-web/dist/session-bridge-view.d.ts +50 -0
  704. package/packages/client-web/dist/session-bridge-view.d.ts.map +1 -0
  705. package/packages/client-web/dist/session-bridge-view.js +113 -0
  706. package/packages/client-web/dist/session-bridge-view.js.map +1 -0
  707. package/packages/client-web/dist/session-insights-view.d.ts +40 -0
  708. package/packages/client-web/dist/session-insights-view.d.ts.map +1 -0
  709. package/packages/client-web/dist/session-insights-view.js +157 -0
  710. package/packages/client-web/dist/session-insights-view.js.map +1 -0
  711. package/packages/client-web/dist/skill-guard-view.d.ts +47 -0
  712. package/packages/client-web/dist/skill-guard-view.d.ts.map +1 -0
  713. package/packages/client-web/dist/skill-guard-view.js +93 -0
  714. package/packages/client-web/dist/skill-guard-view.js.map +1 -0
  715. package/packages/client-web/dist/sql-lens-view.d.ts +37 -0
  716. package/packages/client-web/dist/sql-lens-view.d.ts.map +1 -0
  717. package/packages/client-web/dist/sql-lens-view.js +235 -0
  718. package/packages/client-web/dist/sql-lens-view.js.map +1 -0
  719. package/packages/client-web/dist/test-harness-view.d.ts +24 -0
  720. package/packages/client-web/dist/test-harness-view.d.ts.map +1 -0
  721. package/packages/client-web/dist/test-harness-view.js +149 -0
  722. package/packages/client-web/dist/test-harness-view.js.map +1 -0
  723. package/packages/client-web/dist/token-guard-view.d.ts +19 -0
  724. package/packages/client-web/dist/token-guard-view.d.ts.map +1 -0
  725. package/packages/client-web/dist/token-guard-view.js +56 -0
  726. package/packages/client-web/dist/token-guard-view.js.map +1 -0
  727. package/packages/client-web/dist/turn-rewind-view.d.ts +41 -0
  728. package/packages/client-web/dist/turn-rewind-view.d.ts.map +1 -0
  729. package/packages/client-web/dist/turn-rewind-view.js +117 -0
  730. package/packages/client-web/dist/turn-rewind-view.js.map +1 -0
  731. package/packages/client-web/dist/vision-toolkit-view.d.ts +66 -0
  732. package/packages/client-web/dist/vision-toolkit-view.d.ts.map +1 -0
  733. package/packages/client-web/dist/vision-toolkit-view.js +238 -0
  734. package/packages/client-web/dist/vision-toolkit-view.js.map +1 -0
  735. package/packages/client-web/dist/yaml-validator-view.d.ts +52 -0
  736. package/packages/client-web/dist/yaml-validator-view.d.ts.map +1 -0
  737. package/packages/client-web/dist/yaml-validator-view.js +96 -0
  738. package/packages/client-web/dist/yaml-validator-view.js.map +1 -0
  739. package/packages/client-web/package.json +1 -1
  740. package/packages/client-web/src/agent-teams-view.ts +189 -0
  741. package/packages/client-web/src/at-file-view.ts +69 -0
  742. package/packages/client-web/src/browser-fetch-view.ts +114 -0
  743. package/packages/client-web/src/browser-session-view.ts +222 -3
  744. package/packages/client-web/src/cleaner-view.ts +207 -0
  745. package/packages/client-web/src/context-doctor-view.ts +140 -0
  746. package/packages/client-web/src/context-insights-view.ts +125 -0
  747. package/packages/client-web/src/cost-meter-view.ts +63 -0
  748. package/packages/client-web/src/dependency-checker-view.ts +215 -0
  749. package/packages/client-web/src/docker-sandbox-view.ts +177 -0
  750. package/packages/client-web/src/fail-logger-view.ts +112 -0
  751. package/packages/client-web/src/genui-view.ts +88 -0
  752. package/packages/client-web/src/git-time-capsule-view.ts +215 -0
  753. package/packages/client-web/src/graph-memory-view.ts +91 -0
  754. package/packages/client-web/src/i18n-pair-view.ts +194 -0
  755. package/packages/client-web/src/mcp-client-view.ts +122 -0
  756. package/packages/client-web/src/modlens-view.ts +210 -0
  757. package/packages/client-web/src/openpets-view.ts +67 -0
  758. package/packages/client-web/src/panel-safe.ts +47 -0
  759. package/packages/client-web/src/plugin-dev-view.ts +39 -0
  760. package/packages/client-web/src/plugin-stars-view.ts +239 -1
  761. package/packages/client-web/src/react-room.tsx +1770 -900
  762. package/packages/client-web/src/readme-gen-view.ts +145 -0
  763. package/packages/client-web/src/recall-unread-view.ts +105 -0
  764. package/packages/client-web/src/session-bridge-view.ts +118 -0
  765. package/packages/client-web/src/session-insights-view.ts +205 -0
  766. package/packages/client-web/src/skill-guard-view.ts +94 -0
  767. package/packages/client-web/src/sql-lens-view.ts +247 -0
  768. package/packages/client-web/src/test-harness-view.ts +170 -0
  769. package/packages/client-web/src/token-guard-view.ts +75 -0
  770. package/packages/client-web/src/turn-rewind-view.ts +120 -0
  771. package/packages/client-web/src/vision-toolkit-view.ts +280 -0
  772. package/packages/client-web/src/yaml-validator-view.ts +102 -0
  773. package/packages/client-web/test/agent-teams-view.test.ts +198 -0
  774. package/packages/client-web/test/at-file-panel.test.ts +76 -0
  775. package/packages/client-web/test/browser-fetch-panel.test.ts +44 -0
  776. package/packages/client-web/test/browser-fetch-view.test.ts +89 -0
  777. package/packages/client-web/test/browser-session-panel.test.ts +55 -0
  778. package/packages/client-web/test/browser-session-view.test.ts +99 -1
  779. package/packages/client-web/test/cleaner-panel.test.ts +66 -0
  780. package/packages/client-web/test/cleaner-view.test.ts +143 -0
  781. package/packages/client-web/test/context-doctor-view.test.ts +169 -0
  782. package/packages/client-web/test/context-insights-view.test.ts +120 -0
  783. package/packages/client-web/test/cost-meter-view.test.ts +53 -0
  784. package/packages/client-web/test/dependency-checker-panel.test.ts +51 -0
  785. package/packages/client-web/test/dependency-checker-view.test.ts +266 -0
  786. package/packages/client-web/test/docker-sandbox-panel.test.ts +44 -0
  787. package/packages/client-web/test/docker-sandbox-view.test.ts +127 -0
  788. package/packages/client-web/test/fail-logger-view.test.ts +155 -0
  789. package/packages/client-web/test/genui-view.test.ts +55 -0
  790. package/packages/client-web/test/git-time-capsule-view.test.ts +252 -0
  791. package/packages/client-web/test/graph-memory-view.test.ts +67 -0
  792. package/packages/client-web/test/i18n-pair-panel.test.ts +72 -0
  793. package/packages/client-web/test/i18n-pair-view.test.ts +164 -0
  794. package/packages/client-web/test/mcp-client-view.test.ts +106 -0
  795. package/packages/client-web/test/modlens-view.test.ts +198 -0
  796. package/packages/client-web/test/openpets-view.test.ts +57 -0
  797. package/packages/client-web/test/plugin-dev-view.test.ts +63 -0
  798. package/packages/client-web/test/plugin-stars-panel.test.ts +44 -0
  799. package/packages/client-web/test/plugin-stars-view.test.ts +88 -1
  800. package/packages/client-web/test/readme-gen-panel.test.ts +81 -0
  801. package/packages/client-web/test/readme-gen-view.test.ts +91 -0
  802. package/packages/client-web/test/recall-unread-view.test.ts +153 -0
  803. package/packages/client-web/test/session-bridge-view.test.ts +102 -0
  804. package/packages/client-web/test/session-insights-panel.test.ts +85 -0
  805. package/packages/client-web/test/session-insights-view.test.ts +152 -0
  806. package/packages/client-web/test/skill-guard-view.test.ts +138 -0
  807. package/packages/client-web/test/sql-lens-panel.test.ts +52 -0
  808. package/packages/client-web/test/sql-lens-view.test.ts +134 -0
  809. package/packages/client-web/test/test-harness-panel.test.ts +228 -0
  810. package/packages/client-web/test/token-guard-view.test.ts +93 -0
  811. package/packages/client-web/test/turn-rewind-view.test.ts +159 -0
  812. package/packages/client-web/test/vision-toolkit-view.test.ts +152 -0
  813. package/packages/client-web/test/yaml-validator-view.test.ts +100 -0
  814. package/packages/core/dist/atomic-write.d.ts +8 -0
  815. package/packages/core/dist/atomic-write.d.ts.map +1 -0
  816. package/packages/core/dist/atomic-write.js +40 -0
  817. package/packages/core/dist/atomic-write.js.map +1 -0
  818. package/packages/core/dist/boot.d.ts.map +1 -1
  819. package/packages/core/dist/boot.js +132 -10
  820. package/packages/core/dist/boot.js.map +1 -1
  821. package/packages/core/dist/bounded-file.d.ts +7 -0
  822. package/packages/core/dist/bounded-file.d.ts.map +1 -0
  823. package/packages/core/dist/bounded-file.js +50 -0
  824. package/packages/core/dist/bounded-file.js.map +1 -0
  825. package/packages/core/dist/config.d.ts +2 -0
  826. package/packages/core/dist/config.d.ts.map +1 -1
  827. package/packages/core/dist/config.js +21 -0
  828. package/packages/core/dist/config.js.map +1 -1
  829. package/packages/core/dist/cordis-timer.d.ts +15 -0
  830. package/packages/core/dist/cordis-timer.d.ts.map +1 -0
  831. package/packages/core/dist/cordis-timer.js +99 -0
  832. package/packages/core/dist/cordis-timer.js.map +1 -0
  833. package/packages/core/dist/plugins/agent-teams.d.ts +5 -1
  834. package/packages/core/dist/plugins/agent-teams.d.ts.map +1 -1
  835. package/packages/core/dist/plugins/agent-teams.js +986 -105
  836. package/packages/core/dist/plugins/agent-teams.js.map +1 -1
  837. package/packages/core/dist/plugins/anchored-standard.d.ts +1 -0
  838. package/packages/core/dist/plugins/anchored-standard.d.ts.map +1 -1
  839. package/packages/core/dist/plugins/anchored-standard.js +39 -11
  840. package/packages/core/dist/plugins/anchored-standard.js.map +1 -1
  841. package/packages/core/dist/plugins/annotation.d.ts +1 -0
  842. package/packages/core/dist/plugins/annotation.d.ts.map +1 -1
  843. package/packages/core/dist/plugins/annotation.js +35 -17
  844. package/packages/core/dist/plugins/annotation.js.map +1 -1
  845. package/packages/core/dist/plugins/archify.d.ts +1 -0
  846. package/packages/core/dist/plugins/archify.d.ts.map +1 -1
  847. package/packages/core/dist/plugins/archify.js +69 -22
  848. package/packages/core/dist/plugins/archify.js.map +1 -1
  849. package/packages/core/dist/plugins/at-file.d.ts +5 -1
  850. package/packages/core/dist/plugins/at-file.d.ts.map +1 -1
  851. package/packages/core/dist/plugins/at-file.js +120 -29
  852. package/packages/core/dist/plugins/at-file.js.map +1 -1
  853. package/packages/core/dist/plugins/auto-mode.d.ts.map +1 -1
  854. package/packages/core/dist/plugins/auto-mode.js +89 -20
  855. package/packages/core/dist/plugins/auto-mode.js.map +1 -1
  856. package/packages/core/dist/plugins/better-sidebar.d.ts +1 -0
  857. package/packages/core/dist/plugins/better-sidebar.d.ts.map +1 -1
  858. package/packages/core/dist/plugins/better-sidebar.js +14 -4
  859. package/packages/core/dist/plugins/better-sidebar.js.map +1 -1
  860. package/packages/core/dist/plugins/browser-fetch.d.ts +1 -0
  861. package/packages/core/dist/plugins/browser-fetch.d.ts.map +1 -1
  862. package/packages/core/dist/plugins/browser-fetch.js +288 -96
  863. package/packages/core/dist/plugins/browser-fetch.js.map +1 -1
  864. package/packages/core/dist/plugins/browser-session.d.ts.map +1 -1
  865. package/packages/core/dist/plugins/browser-session.js +445 -106
  866. package/packages/core/dist/plugins/browser-session.js.map +1 -1
  867. package/packages/core/dist/plugins/canvas-draw.d.ts +1 -0
  868. package/packages/core/dist/plugins/canvas-draw.d.ts.map +1 -1
  869. package/packages/core/dist/plugins/canvas-draw.js +71 -19
  870. package/packages/core/dist/plugins/canvas-draw.js.map +1 -1
  871. package/packages/core/dist/plugins/change-verifier.d.ts +1 -0
  872. package/packages/core/dist/plugins/change-verifier.d.ts.map +1 -1
  873. package/packages/core/dist/plugins/change-verifier.js +30 -9
  874. package/packages/core/dist/plugins/change-verifier.js.map +1 -1
  875. package/packages/core/dist/plugins/cleaner.d.ts +5 -1
  876. package/packages/core/dist/plugins/cleaner.d.ts.map +1 -1
  877. package/packages/core/dist/plugins/cleaner.js +337 -40
  878. package/packages/core/dist/plugins/cleaner.js.map +1 -1
  879. package/packages/core/dist/plugins/cli-notifier.d.ts +2 -1
  880. package/packages/core/dist/plugins/cli-notifier.d.ts.map +1 -1
  881. package/packages/core/dist/plugins/cli-notifier.js +99 -42
  882. package/packages/core/dist/plugins/cli-notifier.js.map +1 -1
  883. package/packages/core/dist/plugins/code2skill.d.ts +1 -0
  884. package/packages/core/dist/plugins/code2skill.d.ts.map +1 -1
  885. package/packages/core/dist/plugins/code2skill.js +178 -38
  886. package/packages/core/dist/plugins/code2skill.js.map +1 -1
  887. package/packages/core/dist/plugins/colleague-skill.d.ts +2 -1
  888. package/packages/core/dist/plugins/colleague-skill.d.ts.map +1 -1
  889. package/packages/core/dist/plugins/colleague-skill.js +79 -49
  890. package/packages/core/dist/plugins/colleague-skill.js.map +1 -1
  891. package/packages/core/dist/plugins/context-doctor.d.ts +6 -1
  892. package/packages/core/dist/plugins/context-doctor.d.ts.map +1 -1
  893. package/packages/core/dist/plugins/context-doctor.js +403 -39
  894. package/packages/core/dist/plugins/context-doctor.js.map +1 -1
  895. package/packages/core/dist/plugins/context.d.ts +1 -0
  896. package/packages/core/dist/plugins/context.d.ts.map +1 -1
  897. package/packages/core/dist/plugins/context.js +169 -42
  898. package/packages/core/dist/plugins/context.js.map +1 -1
  899. package/packages/core/dist/plugins/cost-meter.d.ts +4 -0
  900. package/packages/core/dist/plugins/cost-meter.d.ts.map +1 -1
  901. package/packages/core/dist/plugins/cost-meter.js +319 -93
  902. package/packages/core/dist/plugins/cost-meter.js.map +1 -1
  903. package/packages/core/dist/plugins/dependency-checker.d.ts +11 -2
  904. package/packages/core/dist/plugins/dependency-checker.d.ts.map +1 -1
  905. package/packages/core/dist/plugins/dependency-checker.js +463 -114
  906. package/packages/core/dist/plugins/dependency-checker.js.map +1 -1
  907. package/packages/core/dist/plugins/docker-sandbox.d.ts +1 -0
  908. package/packages/core/dist/plugins/docker-sandbox.d.ts.map +1 -1
  909. package/packages/core/dist/plugins/docker-sandbox.js +322 -80
  910. package/packages/core/dist/plugins/docker-sandbox.js.map +1 -1
  911. package/packages/core/dist/plugins/fail-logger.d.ts +1 -0
  912. package/packages/core/dist/plugins/fail-logger.d.ts.map +1 -1
  913. package/packages/core/dist/plugins/fail-logger.js +187 -20
  914. package/packages/core/dist/plugins/fail-logger.js.map +1 -1
  915. package/packages/core/dist/plugins/genui.d.ts +1 -0
  916. package/packages/core/dist/plugins/genui.d.ts.map +1 -1
  917. package/packages/core/dist/plugins/genui.js +103 -38
  918. package/packages/core/dist/plugins/genui.js.map +1 -1
  919. package/packages/core/dist/plugins/git-time-capsule.d.ts +8 -2
  920. package/packages/core/dist/plugins/git-time-capsule.d.ts.map +1 -1
  921. package/packages/core/dist/plugins/git-time-capsule.js +400 -54
  922. package/packages/core/dist/plugins/git-time-capsule.js.map +1 -1
  923. package/packages/core/dist/plugins/graph-memory.d.ts.map +1 -1
  924. package/packages/core/dist/plugins/graph-memory.js +329 -42
  925. package/packages/core/dist/plugins/graph-memory.js.map +1 -1
  926. package/packages/core/dist/plugins/history-compressor.d.ts.map +1 -1
  927. package/packages/core/dist/plugins/history-compressor.js +31 -12
  928. package/packages/core/dist/plugins/history-compressor.js.map +1 -1
  929. package/packages/core/dist/plugins/hol-guard.d.ts.map +1 -1
  930. package/packages/core/dist/plugins/hol-guard.js +33 -13
  931. package/packages/core/dist/plugins/hol-guard.js.map +1 -1
  932. package/packages/core/dist/plugins/i18n-pair.d.ts +5 -1
  933. package/packages/core/dist/plugins/i18n-pair.d.ts.map +1 -1
  934. package/packages/core/dist/plugins/i18n-pair.js +308 -52
  935. package/packages/core/dist/plugins/i18n-pair.js.map +1 -1
  936. package/packages/core/dist/plugins/image-compressor.d.ts +7 -0
  937. package/packages/core/dist/plugins/image-compressor.d.ts.map +1 -1
  938. package/packages/core/dist/plugins/image-compressor.js +98 -25
  939. package/packages/core/dist/plugins/image-compressor.js.map +1 -1
  940. package/packages/core/dist/plugins/llm-verifier.d.ts.map +1 -1
  941. package/packages/core/dist/plugins/llm-verifier.js +21 -11
  942. package/packages/core/dist/plugins/llm-verifier.js.map +1 -1
  943. package/packages/core/dist/plugins/mcp-client.d.ts.map +1 -1
  944. package/packages/core/dist/plugins/mcp-client.js +986 -232
  945. package/packages/core/dist/plugins/mcp-client.js.map +1 -1
  946. package/packages/core/dist/plugins/mcp-panel.d.ts.map +1 -1
  947. package/packages/core/dist/plugins/mcp-panel.js +30 -16
  948. package/packages/core/dist/plugins/mcp-panel.js.map +1 -1
  949. package/packages/core/dist/plugins/memory.d.ts.map +1 -1
  950. package/packages/core/dist/plugins/memory.js +292 -59
  951. package/packages/core/dist/plugins/memory.js.map +1 -1
  952. package/packages/core/dist/plugins/mirage-bridge.d.ts.map +1 -1
  953. package/packages/core/dist/plugins/mirage-bridge.js +20 -10
  954. package/packages/core/dist/plugins/mirage-bridge.js.map +1 -1
  955. package/packages/core/dist/plugins/mock-server.d.ts.map +1 -1
  956. package/packages/core/dist/plugins/mock-server.js +85 -54
  957. package/packages/core/dist/plugins/mock-server.js.map +1 -1
  958. package/packages/core/dist/plugins/model.d.ts +3 -0
  959. package/packages/core/dist/plugins/model.d.ts.map +1 -1
  960. package/packages/core/dist/plugins/model.js +3 -0
  961. package/packages/core/dist/plugins/model.js.map +1 -1
  962. package/packages/core/dist/plugins/models.d.ts.map +1 -1
  963. package/packages/core/dist/plugins/models.js +10 -2
  964. package/packages/core/dist/plugins/models.js.map +1 -1
  965. package/packages/core/dist/plugins/modlens.d.ts +8 -1
  966. package/packages/core/dist/plugins/modlens.d.ts.map +1 -1
  967. package/packages/core/dist/plugins/modlens.js +438 -31
  968. package/packages/core/dist/plugins/modlens.js.map +1 -1
  969. package/packages/core/dist/plugins/module-search.d.ts +1 -0
  970. package/packages/core/dist/plugins/module-search.d.ts.map +1 -1
  971. package/packages/core/dist/plugins/module-search.js +35 -16
  972. package/packages/core/dist/plugins/module-search.js.map +1 -1
  973. package/packages/core/dist/plugins/obsidian-sync.d.ts.map +1 -1
  974. package/packages/core/dist/plugins/obsidian-sync.js +20 -11
  975. package/packages/core/dist/plugins/obsidian-sync.js.map +1 -1
  976. package/packages/core/dist/plugins/openpets.d.ts.map +1 -1
  977. package/packages/core/dist/plugins/openpets.js +203 -44
  978. package/packages/core/dist/plugins/openpets.js.map +1 -1
  979. package/packages/core/dist/plugins/plan-execute.d.ts +4 -1
  980. package/packages/core/dist/plugins/plan-execute.d.ts.map +1 -1
  981. package/packages/core/dist/plugins/plan-execute.js +42 -21
  982. package/packages/core/dist/plugins/plan-execute.js.map +1 -1
  983. package/packages/core/dist/plugins/plugin-check.d.ts +12 -3
  984. package/packages/core/dist/plugins/plugin-check.d.ts.map +1 -1
  985. package/packages/core/dist/plugins/plugin-check.js +83 -12
  986. package/packages/core/dist/plugins/plugin-check.js.map +1 -1
  987. package/packages/core/dist/plugins/plugin-dev.d.ts +1 -0
  988. package/packages/core/dist/plugins/plugin-dev.d.ts.map +1 -1
  989. package/packages/core/dist/plugins/plugin-dev.js +156 -23
  990. package/packages/core/dist/plugins/plugin-dev.js.map +1 -1
  991. package/packages/core/dist/plugins/plugin-finder.d.ts +1 -0
  992. package/packages/core/dist/plugins/plugin-finder.d.ts.map +1 -1
  993. package/packages/core/dist/plugins/plugin-finder.js +131 -13
  994. package/packages/core/dist/plugins/plugin-finder.js.map +1 -1
  995. package/packages/core/dist/plugins/plugin-radar.d.ts +4 -0
  996. package/packages/core/dist/plugins/plugin-radar.d.ts.map +1 -1
  997. package/packages/core/dist/plugins/plugin-radar.js +137 -36
  998. package/packages/core/dist/plugins/plugin-radar.js.map +1 -1
  999. package/packages/core/dist/plugins/plugin-stars.d.ts.map +1 -1
  1000. package/packages/core/dist/plugins/plugin-stars.js +282 -81
  1001. package/packages/core/dist/plugins/plugin-stars.js.map +1 -1
  1002. package/packages/core/dist/plugins/prompt-guard.d.ts +1 -0
  1003. package/packages/core/dist/plugins/prompt-guard.d.ts.map +1 -1
  1004. package/packages/core/dist/plugins/prompt-guard.js +60 -9
  1005. package/packages/core/dist/plugins/prompt-guard.js.map +1 -1
  1006. package/packages/core/dist/plugins/prompt-library.d.ts +1 -0
  1007. package/packages/core/dist/plugins/prompt-library.d.ts.map +1 -1
  1008. package/packages/core/dist/plugins/prompt-library.js +4 -1
  1009. package/packages/core/dist/plugins/prompt-library.js.map +1 -1
  1010. package/packages/core/dist/plugins/readme-gen.d.ts +6 -2
  1011. package/packages/core/dist/plugins/readme-gen.d.ts.map +1 -1
  1012. package/packages/core/dist/plugins/readme-gen.js +514 -73
  1013. package/packages/core/dist/plugins/readme-gen.js.map +1 -1
  1014. package/packages/core/dist/plugins/recall-unread.d.ts +1 -1
  1015. package/packages/core/dist/plugins/recall-unread.d.ts.map +1 -1
  1016. package/packages/core/dist/plugins/recall-unread.js +411 -68
  1017. package/packages/core/dist/plugins/recall-unread.js.map +1 -1
  1018. package/packages/core/dist/plugins/resources.d.ts.map +1 -1
  1019. package/packages/core/dist/plugins/resources.js +66 -3
  1020. package/packages/core/dist/plugins/resources.js.map +1 -1
  1021. package/packages/core/dist/plugins/reverse-skill.d.ts.map +1 -1
  1022. package/packages/core/dist/plugins/reverse-skill.js +2 -1
  1023. package/packages/core/dist/plugins/reverse-skill.js.map +1 -1
  1024. package/packages/core/dist/plugins/reviewer-bot.d.ts +1 -0
  1025. package/packages/core/dist/plugins/reviewer-bot.d.ts.map +1 -1
  1026. package/packages/core/dist/plugins/reviewer-bot.js +35 -16
  1027. package/packages/core/dist/plugins/reviewer-bot.js.map +1 -1
  1028. package/packages/core/dist/plugins/runtime-doctor.d.ts +1 -0
  1029. package/packages/core/dist/plugins/runtime-doctor.d.ts.map +1 -1
  1030. package/packages/core/dist/plugins/runtime-doctor.js +4 -1
  1031. package/packages/core/dist/plugins/runtime-doctor.js.map +1 -1
  1032. package/packages/core/dist/plugins/runtime.d.ts.map +1 -1
  1033. package/packages/core/dist/plugins/runtime.js +104 -70
  1034. package/packages/core/dist/plugins/runtime.js.map +1 -1
  1035. package/packages/core/dist/plugins/secure-audit.d.ts +1 -0
  1036. package/packages/core/dist/plugins/secure-audit.d.ts.map +1 -1
  1037. package/packages/core/dist/plugins/secure-audit.js +30 -12
  1038. package/packages/core/dist/plugins/secure-audit.js.map +1 -1
  1039. package/packages/core/dist/plugins/session-bookmarks.d.ts +1 -0
  1040. package/packages/core/dist/plugins/session-bookmarks.d.ts.map +1 -1
  1041. package/packages/core/dist/plugins/session-bookmarks.js +4 -1
  1042. package/packages/core/dist/plugins/session-bookmarks.js.map +1 -1
  1043. package/packages/core/dist/plugins/session-bridge.d.ts +1 -0
  1044. package/packages/core/dist/plugins/session-bridge.d.ts.map +1 -1
  1045. package/packages/core/dist/plugins/session-bridge.js +401 -88
  1046. package/packages/core/dist/plugins/session-bridge.js.map +1 -1
  1047. package/packages/core/dist/plugins/session-compare.d.ts +1 -0
  1048. package/packages/core/dist/plugins/session-compare.d.ts.map +1 -1
  1049. package/packages/core/dist/plugins/session-compare.js +4 -1
  1050. package/packages/core/dist/plugins/session-compare.js.map +1 -1
  1051. package/packages/core/dist/plugins/session-export.d.ts +1 -0
  1052. package/packages/core/dist/plugins/session-export.d.ts.map +1 -1
  1053. package/packages/core/dist/plugins/session-export.js +6 -6
  1054. package/packages/core/dist/plugins/session-export.js.map +1 -1
  1055. package/packages/core/dist/plugins/session-insights.d.ts +37 -1
  1056. package/packages/core/dist/plugins/session-insights.d.ts.map +1 -1
  1057. package/packages/core/dist/plugins/session-insights.js +406 -21
  1058. package/packages/core/dist/plugins/session-insights.js.map +1 -1
  1059. package/packages/core/dist/plugins/session-search.d.ts +1 -0
  1060. package/packages/core/dist/plugins/session-search.d.ts.map +1 -1
  1061. package/packages/core/dist/plugins/session-search.js +4 -1
  1062. package/packages/core/dist/plugins/session-search.js.map +1 -1
  1063. package/packages/core/dist/plugins/session.d.ts.map +1 -1
  1064. package/packages/core/dist/plugins/session.js +8 -1
  1065. package/packages/core/dist/plugins/session.js.map +1 -1
  1066. package/packages/core/dist/plugins/skill-catalog.d.ts +1 -0
  1067. package/packages/core/dist/plugins/skill-catalog.d.ts.map +1 -1
  1068. package/packages/core/dist/plugins/skill-catalog.js +6 -5
  1069. package/packages/core/dist/plugins/skill-catalog.js.map +1 -1
  1070. package/packages/core/dist/plugins/skill-guard.d.ts +2 -1
  1071. package/packages/core/dist/plugins/skill-guard.d.ts.map +1 -1
  1072. package/packages/core/dist/plugins/skill-guard.js +241 -61
  1073. package/packages/core/dist/plugins/skill-guard.js.map +1 -1
  1074. package/packages/core/dist/plugins/sql-lens-worker.d.ts +2 -0
  1075. package/packages/core/dist/plugins/sql-lens-worker.d.ts.map +1 -0
  1076. package/packages/core/dist/plugins/sql-lens-worker.js +206 -0
  1077. package/packages/core/dist/plugins/sql-lens-worker.js.map +1 -0
  1078. package/packages/core/dist/plugins/sql-lens.d.ts +7 -1
  1079. package/packages/core/dist/plugins/sql-lens.d.ts.map +1 -1
  1080. package/packages/core/dist/plugins/sql-lens.js +301 -68
  1081. package/packages/core/dist/plugins/sql-lens.js.map +1 -1
  1082. package/packages/core/dist/plugins/stdio.d.ts +3 -0
  1083. package/packages/core/dist/plugins/stdio.d.ts.map +1 -1
  1084. package/packages/core/dist/plugins/stdio.js +62 -4
  1085. package/packages/core/dist/plugins/stdio.js.map +1 -1
  1086. package/packages/core/dist/plugins/synapse.d.ts.map +1 -1
  1087. package/packages/core/dist/plugins/synapse.js +17 -9
  1088. package/packages/core/dist/plugins/synapse.js.map +1 -1
  1089. package/packages/core/dist/plugins/tab-manager.d.ts +1 -0
  1090. package/packages/core/dist/plugins/tab-manager.d.ts.map +1 -1
  1091. package/packages/core/dist/plugins/tab-manager.js +167 -62
  1092. package/packages/core/dist/plugins/tab-manager.js.map +1 -1
  1093. package/packages/core/dist/plugins/taskboard.d.ts.map +1 -1
  1094. package/packages/core/dist/plugins/taskboard.js +50 -22
  1095. package/packages/core/dist/plugins/taskboard.js.map +1 -1
  1096. package/packages/core/dist/plugins/telemetry-blocker.d.ts +4 -1
  1097. package/packages/core/dist/plugins/telemetry-blocker.d.ts.map +1 -1
  1098. package/packages/core/dist/plugins/telemetry-blocker.js +30 -11
  1099. package/packages/core/dist/plugins/telemetry-blocker.js.map +1 -1
  1100. package/packages/core/dist/plugins/test-harness.d.ts +7 -1
  1101. package/packages/core/dist/plugins/test-harness.d.ts.map +1 -1
  1102. package/packages/core/dist/plugins/test-harness.js +255 -43
  1103. package/packages/core/dist/plugins/test-harness.js.map +1 -1
  1104. package/packages/core/dist/plugins/theme-studio.d.ts.map +1 -1
  1105. package/packages/core/dist/plugins/theme-studio.js +4 -2
  1106. package/packages/core/dist/plugins/theme-studio.js.map +1 -1
  1107. package/packages/core/dist/plugins/token-guard.d.ts.map +1 -1
  1108. package/packages/core/dist/plugins/token-guard.js +164 -32
  1109. package/packages/core/dist/plugins/token-guard.js.map +1 -1
  1110. package/packages/core/dist/plugins/tools.d.ts.map +1 -1
  1111. package/packages/core/dist/plugins/tools.js +4 -1
  1112. package/packages/core/dist/plugins/tools.js.map +1 -1
  1113. package/packages/core/dist/plugins/turn-rewind.d.ts +17 -0
  1114. package/packages/core/dist/plugins/turn-rewind.d.ts.map +1 -1
  1115. package/packages/core/dist/plugins/turn-rewind.js +340 -36
  1116. package/packages/core/dist/plugins/turn-rewind.js.map +1 -1
  1117. package/packages/core/dist/plugins/undo-savepoint.d.ts.map +1 -1
  1118. package/packages/core/dist/plugins/undo-savepoint.js +157 -51
  1119. package/packages/core/dist/plugins/undo-savepoint.js.map +1 -1
  1120. package/packages/core/dist/plugins/vision-toolkit.d.ts +22 -3
  1121. package/packages/core/dist/plugins/vision-toolkit.d.ts.map +1 -1
  1122. package/packages/core/dist/plugins/vision-toolkit.js +389 -66
  1123. package/packages/core/dist/plugins/vision-toolkit.js.map +1 -1
  1124. package/packages/core/dist/plugins/web-research.d.ts.map +1 -1
  1125. package/packages/core/dist/plugins/web-research.js +13 -4
  1126. package/packages/core/dist/plugins/web-research.js.map +1 -1
  1127. package/packages/core/dist/plugins/workspace-navigator.d.ts +8 -2
  1128. package/packages/core/dist/plugins/workspace-navigator.d.ts.map +1 -1
  1129. package/packages/core/dist/plugins/workspace-navigator.js +28 -10
  1130. package/packages/core/dist/plugins/workspace-navigator.js.map +1 -1
  1131. package/packages/core/dist/plugins/workspace-search.d.ts +7 -0
  1132. package/packages/core/dist/plugins/workspace-search.d.ts.map +1 -1
  1133. package/packages/core/dist/plugins/workspace-search.js +67 -34
  1134. package/packages/core/dist/plugins/workspace-search.js.map +1 -1
  1135. package/packages/core/dist/plugins/yaml-validator.d.ts +1 -0
  1136. package/packages/core/dist/plugins/yaml-validator.d.ts.map +1 -1
  1137. package/packages/core/dist/plugins/yaml-validator.js +156 -47
  1138. package/packages/core/dist/plugins/yaml-validator.js.map +1 -1
  1139. package/packages/core/dist/runtime.d.ts.map +1 -1
  1140. package/packages/core/dist/runtime.js +8 -3
  1141. package/packages/core/dist/runtime.js.map +1 -1
  1142. package/packages/core/dist/services.d.ts.map +1 -1
  1143. package/packages/core/dist/services.js +22 -2
  1144. package/packages/core/dist/services.js.map +1 -1
  1145. package/packages/core/dist/stdio.d.ts +1 -0
  1146. package/packages/core/dist/stdio.d.ts.map +1 -1
  1147. package/packages/core/dist/stdio.js +241 -25
  1148. package/packages/core/dist/stdio.js.map +1 -1
  1149. package/packages/core/dist/workspace-path.d.ts +1 -0
  1150. package/packages/core/dist/workspace-path.d.ts.map +1 -1
  1151. package/packages/core/dist/workspace-path.js +9 -0
  1152. package/packages/core/dist/workspace-path.js.map +1 -1
  1153. package/packages/core/package.json +1 -1
  1154. package/packages/core/profiles/default/cordis.yml +4 -2
  1155. package/packages/core/src/atomic-write.ts +45 -0
  1156. package/packages/core/src/boot.ts +123 -11
  1157. package/packages/core/src/bounded-file.ts +41 -0
  1158. package/packages/core/src/config.ts +18 -0
  1159. package/packages/core/src/cordis-timer.ts +107 -0
  1160. package/packages/core/src/plugins/agent-teams.ts +1003 -103
  1161. package/packages/core/src/plugins/anchored-standard.ts +41 -14
  1162. package/packages/core/src/plugins/annotation.ts +36 -19
  1163. package/packages/core/src/plugins/archify.ts +80 -33
  1164. package/packages/core/src/plugins/at-file.ts +110 -26
  1165. package/packages/core/src/plugins/auto-mode.ts +91 -24
  1166. package/packages/core/src/plugins/better-sidebar.ts +15 -4
  1167. package/packages/core/src/plugins/browser-fetch.ts +286 -95
  1168. package/packages/core/src/plugins/browser-session.ts +421 -102
  1169. package/packages/core/src/plugins/canvas-draw.ts +74 -21
  1170. package/packages/core/src/plugins/change-verifier.ts +33 -9
  1171. package/packages/core/src/plugins/cleaner.ts +339 -37
  1172. package/packages/core/src/plugins/cli-notifier.ts +110 -41
  1173. package/packages/core/src/plugins/code2skill.ts +175 -34
  1174. package/packages/core/src/plugins/colleague-skill.ts +72 -47
  1175. package/packages/core/src/plugins/context-doctor.ts +410 -40
  1176. package/packages/core/src/plugins/context.ts +164 -39
  1177. package/packages/core/src/plugins/cost-meter.ts +360 -113
  1178. package/packages/core/src/plugins/dependency-checker.ts +456 -119
  1179. package/packages/core/src/plugins/docker-sandbox.ts +312 -76
  1180. package/packages/core/src/plugins/fail-logger.ts +169 -18
  1181. package/packages/core/src/plugins/genui.ts +104 -42
  1182. package/packages/core/src/plugins/git-time-capsule.ts +424 -55
  1183. package/packages/core/src/plugins/graph-memory.ts +333 -60
  1184. package/packages/core/src/plugins/history-compressor.ts +29 -12
  1185. package/packages/core/src/plugins/hol-guard.ts +31 -13
  1186. package/packages/core/src/plugins/i18n-pair.ts +296 -52
  1187. package/packages/core/src/plugins/image-compressor.ts +98 -25
  1188. package/packages/core/src/plugins/llm-verifier.ts +39 -21
  1189. package/packages/core/src/plugins/mcp-client.ts +1069 -249
  1190. package/packages/core/src/plugins/mcp-panel.ts +37 -21
  1191. package/packages/core/src/plugins/memory.ts +262 -57
  1192. package/packages/core/src/plugins/mirage-bridge.ts +22 -10
  1193. package/packages/core/src/plugins/mock-server.ts +91 -60
  1194. package/packages/core/src/plugins/model.ts +4 -0
  1195. package/packages/core/src/plugins/models.ts +10 -2
  1196. package/packages/core/src/plugins/modlens.ts +463 -29
  1197. package/packages/core/src/plugins/module-search.ts +40 -19
  1198. package/packages/core/src/plugins/obsidian-sync.ts +26 -15
  1199. package/packages/core/src/plugins/openpets.ts +193 -42
  1200. package/packages/core/src/plugins/plan-execute.ts +49 -21
  1201. package/packages/core/src/plugins/plugin-check.ts +100 -16
  1202. package/packages/core/src/plugins/plugin-dev.ts +167 -23
  1203. package/packages/core/src/plugins/plugin-finder.ts +119 -12
  1204. package/packages/core/src/plugins/plugin-radar.ts +130 -39
  1205. package/packages/core/src/plugins/plugin-stars.ts +252 -80
  1206. package/packages/core/src/plugins/prompt-guard.ts +51 -12
  1207. package/packages/core/src/plugins/prompt-library.ts +14 -8
  1208. package/packages/core/src/plugins/readme-gen.ts +476 -79
  1209. package/packages/core/src/plugins/recall-unread.ts +412 -68
  1210. package/packages/core/src/plugins/resources.ts +70 -2
  1211. package/packages/core/src/plugins/reverse-skill.ts +9 -5
  1212. package/packages/core/src/plugins/reviewer-bot.ts +34 -16
  1213. package/packages/core/src/plugins/runtime-doctor.ts +4 -1
  1214. package/packages/core/src/plugins/runtime.ts +98 -68
  1215. package/packages/core/src/plugins/secure-audit.ts +33 -12
  1216. package/packages/core/src/plugins/session-bookmarks.ts +12 -6
  1217. package/packages/core/src/plugins/session-bridge.ts +404 -89
  1218. package/packages/core/src/plugins/session-compare.ts +10 -4
  1219. package/packages/core/src/plugins/session-export.ts +12 -9
  1220. package/packages/core/src/plugins/session-insights.ts +454 -31
  1221. package/packages/core/src/plugins/session-search.ts +4 -1
  1222. package/packages/core/src/plugins/session.ts +8 -1
  1223. package/packages/core/src/plugins/skill-catalog.ts +13 -8
  1224. package/packages/core/src/plugins/skill-guard.ts +254 -61
  1225. package/packages/core/src/plugins/sql-lens-worker.ts +202 -0
  1226. package/packages/core/src/plugins/sql-lens.ts +323 -71
  1227. package/packages/core/src/plugins/stdio.ts +58 -3
  1228. package/packages/core/src/plugins/synapse.ts +16 -9
  1229. package/packages/core/src/plugins/tab-manager.ts +163 -65
  1230. package/packages/core/src/plugins/taskboard.ts +81 -47
  1231. package/packages/core/src/plugins/telemetry-blocker.ts +27 -11
  1232. package/packages/core/src/plugins/test-harness.ts +275 -42
  1233. package/packages/core/src/plugins/theme-studio.ts +7 -2
  1234. package/packages/core/src/plugins/token-guard.ts +171 -31
  1235. package/packages/core/src/plugins/tools.ts +4 -1
  1236. package/packages/core/src/plugins/turn-rewind.ts +351 -37
  1237. package/packages/core/src/plugins/undo-savepoint.ts +160 -59
  1238. package/packages/core/src/plugins/vision-toolkit.ts +420 -63
  1239. package/packages/core/src/plugins/web-research.ts +19 -7
  1240. package/packages/core/src/plugins/workspace-navigator.ts +39 -14
  1241. package/packages/core/src/plugins/workspace-search.ts +75 -37
  1242. package/packages/core/src/plugins/yaml-validator.ts +165 -46
  1243. package/packages/core/src/runtime.ts +8 -2
  1244. package/packages/core/src/services.ts +22 -2
  1245. package/packages/core/src/stdio.ts +220 -25
  1246. package/packages/core/src/workspace-path.ts +10 -0
  1247. package/packages/core/test/agent-teams.test.ts +495 -2
  1248. package/packages/core/test/anchored-standard.test.ts +60 -0
  1249. package/packages/core/test/annotation.test.ts +69 -0
  1250. package/packages/core/test/archify.test.ts +212 -1
  1251. package/packages/core/test/at-file.test.ts +666 -0
  1252. package/packages/core/test/atomic-write.test.ts +52 -0
  1253. package/packages/core/test/auto-mode.test.ts +629 -0
  1254. package/packages/core/test/better-sidebar.test.ts +108 -1
  1255. package/packages/core/test/boot.test.ts +129 -1
  1256. package/packages/core/test/bounded-file.test.ts +55 -0
  1257. package/packages/core/test/browser-fetch-rebinding.test.ts +93 -0
  1258. package/packages/core/test/browser-fetch.test.ts +844 -0
  1259. package/packages/core/test/browser-session.test.ts +1236 -0
  1260. package/packages/core/test/canvas-draw.test.ts +164 -0
  1261. package/packages/core/test/change-verifier.test.ts +200 -0
  1262. package/packages/core/test/cleaner.test.ts +316 -0
  1263. package/packages/core/test/cli-notifier.test.ts +235 -0
  1264. package/packages/core/test/code2skill.test.ts +264 -0
  1265. package/packages/core/test/colleague-skill.test.ts +167 -0
  1266. package/packages/core/test/config.test.ts +8 -0
  1267. package/packages/core/test/context-doctor.test.ts +597 -2
  1268. package/packages/core/test/context-insights.test.ts +396 -0
  1269. package/packages/core/test/cordis-timer.test.ts +147 -0
  1270. package/packages/core/test/cost-meter.test.ts +362 -0
  1271. package/packages/core/test/dependency-checker.test.ts +576 -3
  1272. package/packages/core/test/docker-sandbox.test.ts +170 -0
  1273. package/packages/core/test/fail-logger.test.ts +363 -0
  1274. package/packages/core/test/genui.test.ts +162 -0
  1275. package/packages/core/test/git-time-capsule.test.ts +1364 -3
  1276. package/packages/core/test/graph-memory.test.ts +508 -0
  1277. package/packages/core/test/history-compressor.test.ts +47 -0
  1278. package/packages/core/test/hol-guard.test.ts +61 -0
  1279. package/packages/core/test/i18n-pair.test.ts +367 -0
  1280. package/packages/core/test/image-compressor.test.ts +59 -0
  1281. package/packages/core/test/llm-verifier.test.ts +4 -0
  1282. package/packages/core/test/mcp-client.test.ts +1037 -0
  1283. package/packages/core/test/mcp-panel.test.ts +91 -0
  1284. package/packages/core/test/memory.test.ts +125 -0
  1285. package/packages/core/test/mirage-bridge.test.ts +4 -0
  1286. package/packages/core/test/mock-server.test.ts +63 -0
  1287. package/packages/core/test/model.test.ts +62 -0
  1288. package/packages/core/test/models.test.ts +85 -0
  1289. package/packages/core/test/modlens.test.ts +615 -0
  1290. package/packages/core/test/module-search.test.ts +20 -0
  1291. package/packages/core/test/obsidian-sync.test.ts +57 -0
  1292. package/packages/core/test/openpets.test.ts +273 -0
  1293. package/packages/core/test/plan-execute.test.ts +86 -0
  1294. package/packages/core/test/plugin-dev.test.ts +246 -0
  1295. package/packages/core/test/plugin-finder.test.ts +105 -0
  1296. package/packages/core/test/plugin-radar.test.ts +87 -0
  1297. package/packages/core/test/plugin-stars.test.ts +429 -4
  1298. package/packages/core/test/profiles.integration.test.ts +451 -2
  1299. package/packages/core/test/prompt-guard.test.ts +78 -0
  1300. package/packages/core/test/readme-gen.test.ts +403 -3
  1301. package/packages/core/test/recall-unread.test.ts +559 -2
  1302. package/packages/core/test/registry.test.ts +16 -0
  1303. package/packages/core/test/resources.test.ts +310 -0
  1304. package/packages/core/test/reviewer-bot.test.ts +55 -0
  1305. package/packages/core/test/runtime-fixture.ts +10 -1
  1306. package/packages/core/test/runtime.test.ts +155 -2
  1307. package/packages/core/test/secure-audit.test.ts +14 -1
  1308. package/packages/core/test/services.test.ts +2772 -117
  1309. package/packages/core/test/session-bridge.test.ts +309 -1
  1310. package/packages/core/test/session-insights.test.ts +486 -0
  1311. package/packages/core/test/session.test.ts +153 -0
  1312. package/packages/core/test/skill-guard.test.ts +261 -2
  1313. package/packages/core/test/sql-lens.test.ts +244 -0
  1314. package/packages/core/test/stdio-args.test.ts +484 -1
  1315. package/packages/core/test/stdio.test.ts +159 -0
  1316. package/packages/core/test/synapse.test.ts +67 -0
  1317. package/packages/core/test/tab-manager.test.ts +58 -0
  1318. package/packages/core/test/taskboard.test.ts +73 -0
  1319. package/packages/core/test/telemetry-blocker.test.ts +61 -0
  1320. package/packages/core/test/test-harness.test.ts +297 -0
  1321. package/packages/core/test/token-guard.test.ts +362 -1
  1322. package/packages/core/test/tools.test.ts +118 -0
  1323. package/packages/core/test/turn-rewind.test.ts +532 -2
  1324. package/packages/core/test/undo-savepoint.test.ts +222 -0
  1325. package/packages/core/test/vision-toolkit.test.ts +480 -7
  1326. package/packages/core/test/web-research.test.ts +63 -0
  1327. package/packages/core/test/workspace-git-status.test.ts +19 -2
  1328. package/packages/core/test/workspace-navigator.test.ts +11 -1
  1329. package/packages/core/test/workspace-search.test.ts +88 -0
  1330. package/packages/core/test/yaml-validator.test.ts +195 -0
  1331. package/packages/host-webserver/package.json +1 -1
  1332. package/apps/web/dist/assets/index-C_AdODuM.js +0 -20
  1333. package/apps/web/dist/assets/index-De8Rm01Z.css +0 -2
@@ -1,16 +1,18 @@
1
1
  import { spawn, type ChildProcessWithoutNullStreams } from "node:child_process";
2
- import { basename } from "node:path";
3
2
  import type { Context } from "@deepseek-ai/cordis";
4
3
  import z from "@deepseek-ai/schemastery";
5
4
  import { Type } from "@earendil-works/pi-ai";
6
5
  import { defineTool, type AgentToolResult } from "@earendil-works/pi-coding-agent";
6
+ import packageMetadata from "../../package.json" with { type: "json" };
7
7
  import type { PiMcpServerSnapshot } from "../services.js";
8
+ import { assertKnownConfigKeys } from "../config.js";
8
9
 
9
10
  type JsonObject = Record<string, unknown>;
10
11
  type McpTool = { name: string; description?: string; inputSchema?: unknown };
11
- type McpResource = { uri: string; name?: string; description?: string; mimeType?: string };
12
+ type McpResource = { uri: string; name: string; description?: string; mimeType?: string };
12
13
  type McpPrompt = { name: string; description?: string; arguments?: unknown[] };
13
14
  type McpCallResult = { content?: unknown[]; isError?: boolean } & JsonObject;
15
+ type AgentContent = AgentToolResult<unknown>["content"][number];
14
16
  type ManagedServer = {
15
17
  id: string;
16
18
  command: string[];
@@ -19,6 +21,17 @@ type ManagedServer = {
19
21
  nextRequestId: number;
20
22
  queue: Promise<void>;
21
23
  startedAt: number;
24
+ lifecycle: AbortController;
25
+ };
26
+ type PendingRequest = {
27
+ receivedBytes: number;
28
+ resolve: (value: JsonObject) => void;
29
+ reject: (error: Error) => void;
30
+ };
31
+ type StdioRouter = {
32
+ buffer: Buffer<ArrayBufferLike>;
33
+ pending: Map<number, PendingRequest>;
34
+ terminalError?: Error;
22
35
  };
23
36
 
24
37
  export interface McpServerDefinition {
@@ -38,19 +51,438 @@ export const Config: z<McpClientConfig> = z.object({
38
51
  const shellCommands = new Set(["sh", "bash", "zsh", "fish", "cmd", "powershell", "pwsh"]);
39
52
  const maxCommandArgs = 32;
40
53
  const maxArgumentBytes = 4096;
54
+ const maxToolArgumentsBytes = 64 * 1024;
55
+ const maxToolArgumentDepth = 32;
56
+ const maxResponseBytes = 1024 * 1024;
57
+ const maxInventoryItems = 1000;
58
+ const maxPaginationPages = 100;
59
+ const maxManagedServers = 128;
60
+ const maxStderrBytes = 8192;
41
61
  const requestTimeoutMs = 30_000;
62
+ const maxPanelItems = 20;
63
+ const clientVersion = packageMetadata.version;
64
+ const disposedMessage = "MCP client plugin disposed";
65
+ const connectionParameterNames = new Set(["command", "serverId"]);
66
+ const callParameterNames = new Set(["command", "serverId", "name", "arguments"]);
67
+ const stopParameterNames = new Set(["serverId"]);
68
+ const readResourceParameterNames = new Set(["command", "serverId", "uri"]);
69
+ const noParameterNames = new Set<string>();
70
+ const utf8Decoder = new TextDecoder("utf-8", { fatal: true });
71
+
72
+ function decodeFrame(value: Buffer<ArrayBufferLike>): string {
73
+ try {
74
+ return utf8Decoder.decode(value);
75
+ } catch (error) {
76
+ throw new Error("MCP server response must contain valid UTF-8", { cause: error });
77
+ }
78
+ }
79
+
80
+ function inspectParameters(value: unknown, allowed: ReadonlySet<string>): Record<string, unknown> {
81
+ if (value === null || typeof value !== "object" || Array.isArray(value)) throw new Error("MCP parameters must be an object");
82
+ try {
83
+ const prototype = Object.getPrototypeOf(value) as unknown;
84
+ if (prototype !== Object.prototype && prototype !== null) throw new Error("MCP parameters must be a plain object");
85
+ const descriptors = Object.getOwnPropertyDescriptors(value);
86
+ if (Reflect.ownKeys(descriptors).some((key) => typeof key !== "string" || !allowed.has(key))) throw new Error("MCP parameters contain an unknown property");
87
+ if (Object.values(descriptors).some((descriptor) => !("value" in descriptor))) throw new Error("MCP parameters must use data properties");
88
+ return Object.fromEntries(Object.entries(descriptors).map(([key, descriptor]) => [key, descriptor.value]));
89
+ } catch (error) {
90
+ if (
91
+ error instanceof Error &&
92
+ /^(?:MCP parameters must be a plain object|MCP parameters contain an unknown property|MCP parameters must use data properties)$/u.test(error.message)
93
+ )
94
+ throw error;
95
+ throw new Error("MCP parameters must be an accessible plain object", { cause: error });
96
+ }
97
+ }
98
+
99
+ function optionalString(value: unknown, field: string): string | undefined {
100
+ if (value === undefined) return undefined;
101
+ if (typeof value !== "string") throw new Error(`MCP ${field} must be a string`);
102
+ return value;
103
+ }
104
+
105
+ function requiredString(value: unknown, field: string): string {
106
+ const result = optionalString(value, field);
107
+ if (result === undefined) throw new Error(`MCP ${field} is required`);
108
+ return result;
109
+ }
110
+
111
+ function serverIdValue(value: unknown, required = false): string | undefined {
112
+ const result = optionalString(value, "serverId");
113
+ if (result === undefined) {
114
+ if (required) throw new Error("MCP serverId is required");
115
+ return undefined;
116
+ }
117
+ if (!/^[a-z0-9][a-z0-9_-]{0,63}$/iu.test(result)) throw new Error("MCP serverId must use 1-64 letters, numbers, _ or -");
118
+ return result;
119
+ }
120
+
121
+ function boundedInput(value: string, field: string, maximum: number): string {
122
+ if (value.includes("\0")) throw new Error(`MCP ${field} must not contain NUL characters`);
123
+ if (value.length === 0 || value.length > maximum) throw new Error(`MCP ${field} must contain 1-${maximum} characters`);
124
+ return value;
125
+ }
126
+
127
+ function rejectAmbiguousTarget(command: string[] | undefined, serverId: string | undefined): void {
128
+ if (command !== undefined && serverId !== undefined) throw new Error("Provide either command or serverId, not both");
129
+ }
130
+
131
+ function optionalCommand(value: unknown): string[] | undefined {
132
+ if (value === undefined) return undefined;
133
+ if (!Array.isArray(value)) throw new Error("MCP command must be an array of strings");
134
+ const descriptors = Object.getOwnPropertyDescriptors(value) as unknown as Record<PropertyKey, PropertyDescriptor>;
135
+ const length: unknown = descriptors.length?.value as unknown;
136
+ if (typeof length !== "number" || !Number.isSafeInteger(length) || length < 0) throw new Error("MCP command must be a dense array of string data properties");
137
+ const result: string[] = [];
138
+ for (let index = 0; index < length; index += 1) {
139
+ const descriptor = descriptors[String(index)];
140
+ if (descriptor === undefined || !("value" in descriptor) || typeof descriptor.value !== "string")
141
+ throw new Error("MCP command must be a dense array of string data properties");
142
+ result.push(descriptor.value);
143
+ }
144
+ if (Reflect.ownKeys(descriptors).some((key) => typeof key !== "string" || (key !== "length" && !/^(0|[1-9]\d*)$/u.test(key))))
145
+ throw new Error("MCP command contains an unknown property");
146
+ return result;
147
+ }
148
+
149
+ function jsonObject(value: unknown): JsonObject {
150
+ if (value === undefined) return {};
151
+ if (value === null || typeof value !== "object" || Array.isArray(value)) throw new Error("MCP arguments must be a JSON object");
152
+ const result = cloneJsonValue(value, new Set(), 0) as JsonObject;
153
+ if (Buffer.byteLength(JSON.stringify(result), "utf8") > maxToolArgumentsBytes) throw new Error("MCP arguments cannot exceed 64 KiB");
154
+ return result;
155
+ }
156
+
157
+ function promptArguments(value: unknown): JsonObject {
158
+ const result = jsonObject(value);
159
+ if (Object.values(result).some((item) => typeof item !== "string")) throw new Error("MCP prompt arguments must contain string values");
160
+ return result;
161
+ }
162
+
163
+ function cloneJsonValue(value: unknown, ancestors: Set<object>, depth: number): unknown {
164
+ if (value === null || typeof value === "string" || typeof value === "boolean") return value;
165
+ if (typeof value === "number") {
166
+ if (!Number.isFinite(value)) throw new Error("MCP arguments must contain finite JSON numbers");
167
+ return value;
168
+ }
169
+ if (typeof value !== "object") throw new Error("MCP arguments must contain only JSON values");
170
+ if (depth > maxToolArgumentDepth) throw new Error(`MCP arguments cannot exceed ${maxToolArgumentDepth} levels of nesting`);
171
+ if (ancestors.has(value)) throw new Error("MCP arguments must not contain circular references");
172
+ ancestors.add(value);
173
+ try {
174
+ const descriptors: Record<PropertyKey, PropertyDescriptor> = Object.getOwnPropertyDescriptors(value);
175
+ if (Object.values(descriptors).some((descriptor) => !("value" in descriptor))) throw new Error("MCP arguments must use data properties");
176
+ if (Reflect.ownKeys(descriptors).some((key) => typeof key !== "string")) throw new Error("MCP arguments cannot contain symbol properties");
177
+ if (Array.isArray(value)) {
178
+ const length: unknown = descriptors.length?.value as unknown;
179
+ if (typeof length !== "number" || !Number.isSafeInteger(length) || length < 0) throw new Error("MCP argument arrays must be dense");
180
+ const result: unknown[] = [];
181
+ for (let index = 0; index < length; index += 1) {
182
+ const descriptor = descriptors[String(index)];
183
+ if (descriptor === undefined || !("value" in descriptor)) throw new Error("MCP argument arrays must be dense");
184
+ result.push(cloneJsonValue(descriptor.value, ancestors, depth + 1));
185
+ }
186
+ if (Object.keys(descriptors).some((key) => key !== "length" && !/^(0|[1-9]\d*)$/u.test(key)))
187
+ throw new Error("MCP argument arrays contain an unknown property");
188
+ return result;
189
+ }
190
+ const result: JsonObject = {};
191
+ for (const [key, descriptor] of Object.entries(descriptors)) {
192
+ if (descriptor.enumerable !== true) continue;
193
+ result[key] = cloneJsonValue(descriptor.value, ancestors, depth + 1);
194
+ }
195
+ return result;
196
+ } finally {
197
+ ancestors.delete(value);
198
+ }
199
+ }
200
+
201
+ function executionSignal(signal: AbortSignal | undefined, lifecycle: AbortSignal): AbortSignal {
202
+ return signal === undefined ? lifecycle : AbortSignal.any([signal, lifecycle]);
203
+ }
204
+
205
+ function clone<T>(value: T): T {
206
+ return structuredClone(value);
207
+ }
208
+
209
+ function appendByteTail(current: Buffer<ArrayBufferLike>, chunk: Buffer<ArrayBufferLike>, maximum: number): Buffer<ArrayBufferLike> {
210
+ const combined = Buffer.concat([current, chunk]);
211
+ return combined.byteLength <= maximum ? combined : combined.subarray(combined.byteLength - maximum);
212
+ }
213
+
214
+ function toolInventory(value: unknown): McpTool[] {
215
+ if (!Array.isArray(value)) throw new Error("MCP server returned an invalid MCP tools inventory");
216
+ if (value.length > maxInventoryItems) throw new Error(`MCP remote inventory cannot exceed ${maxInventoryItems} items`);
217
+ return value.map((item) => {
218
+ if (item === null || typeof item !== "object" || Array.isArray(item)) throw new Error("MCP server returned an invalid MCP tool descriptor");
219
+ const raw = item as JsonObject;
220
+ if (typeof raw.name !== "string" || raw.name.length === 0 || raw.name.length > 512 || raw.name.includes("\0"))
221
+ throw new Error("MCP server returned an invalid MCP tool descriptor");
222
+ if (raw.description !== undefined && (typeof raw.description !== "string" || raw.description.length > 8192))
223
+ throw new Error("MCP server returned an invalid MCP tool descriptor");
224
+ if (raw.inputSchema === null || typeof raw.inputSchema !== "object" || Array.isArray(raw.inputSchema))
225
+ throw new Error("MCP server returned an invalid MCP tool descriptor");
226
+ return {
227
+ name: raw.name,
228
+ ...(raw.description === undefined ? {} : { description: raw.description }),
229
+ inputSchema: clone(raw.inputSchema),
230
+ };
231
+ });
232
+ }
233
+
234
+ function resourceInventory(value: unknown): McpResource[] {
235
+ if (!Array.isArray(value)) throw new Error("MCP server returned an invalid MCP resources inventory");
236
+ if (value.length > maxInventoryItems) throw new Error(`MCP remote inventory cannot exceed ${maxInventoryItems} items`);
237
+ return value.map((item) => {
238
+ if (item === null || typeof item !== "object" || Array.isArray(item)) throw new Error("MCP server returned an invalid MCP resource descriptor");
239
+ const raw = item as JsonObject;
240
+ if (typeof raw.uri !== "string" || raw.uri.length === 0 || raw.uri.length > 4096 || raw.uri.includes("\0"))
241
+ throw new Error("MCP server returned an invalid MCP resource descriptor");
242
+ if (typeof raw.name !== "string" || raw.name.length === 0 || raw.name.length > 512 || raw.name.includes("\0"))
243
+ throw new Error("MCP server returned an invalid MCP resource descriptor");
244
+ if (raw.description !== undefined && (typeof raw.description !== "string" || raw.description.length > 8192))
245
+ throw new Error("MCP server returned an invalid MCP resource descriptor");
246
+ if (raw.mimeType !== undefined && (typeof raw.mimeType !== "string" || raw.mimeType.length > 256))
247
+ throw new Error("MCP server returned an invalid MCP resource descriptor");
248
+ return {
249
+ uri: raw.uri,
250
+ name: raw.name,
251
+ ...(raw.description === undefined ? {} : { description: raw.description }),
252
+ ...(raw.mimeType === undefined ? {} : { mimeType: raw.mimeType }),
253
+ };
254
+ });
255
+ }
256
+
257
+ function promptInventory(value: unknown): McpPrompt[] {
258
+ if (!Array.isArray(value)) throw new Error("MCP server returned an invalid MCP prompts inventory");
259
+ if (value.length > maxInventoryItems) throw new Error(`MCP remote inventory cannot exceed ${maxInventoryItems} items`);
260
+ return value.map((item) => {
261
+ if (item === null || typeof item !== "object" || Array.isArray(item)) throw new Error("MCP server returned an invalid MCP prompt descriptor");
262
+ const raw = item as JsonObject;
263
+ if (typeof raw.name !== "string" || raw.name.length === 0 || raw.name.length > 512 || raw.name.includes("\0"))
264
+ throw new Error("MCP server returned an invalid MCP prompt descriptor");
265
+ if (raw.description !== undefined && (typeof raw.description !== "string" || raw.description.length > 8192))
266
+ throw new Error("MCP server returned an invalid MCP prompt descriptor");
267
+ if (raw.arguments !== undefined && !Array.isArray(raw.arguments)) throw new Error("MCP server returned an invalid MCP prompt descriptor");
268
+ if (Array.isArray(raw.arguments) && raw.arguments.length > 128) throw new Error("MCP server returned an invalid MCP prompt descriptor");
269
+ const argumentsValue = Array.isArray(raw.arguments)
270
+ ? raw.arguments.map((argument) => {
271
+ if (argument === null || typeof argument !== "object" || Array.isArray(argument))
272
+ throw new Error("MCP server returned an invalid MCP prompt descriptor");
273
+ const candidate = argument as JsonObject;
274
+ if (typeof candidate.name !== "string" || candidate.name.length === 0 || candidate.name.length > 512)
275
+ throw new Error("MCP server returned an invalid MCP prompt descriptor");
276
+ if (candidate.description !== undefined && (typeof candidate.description !== "string" || candidate.description.length > 8192))
277
+ throw new Error("MCP server returned an invalid MCP prompt descriptor");
278
+ if (candidate.required !== undefined && typeof candidate.required !== "boolean")
279
+ throw new Error("MCP server returned an invalid MCP prompt descriptor");
280
+ return {
281
+ name: candidate.name,
282
+ ...(candidate.description === undefined ? {} : { description: candidate.description }),
283
+ ...(candidate.required === undefined ? {} : { required: candidate.required }),
284
+ };
285
+ })
286
+ : undefined;
287
+ return {
288
+ name: raw.name,
289
+ ...(raw.description === undefined ? {} : { description: raw.description }),
290
+ ...(argumentsValue === undefined ? {} : { arguments: argumentsValue }),
291
+ };
292
+ });
293
+ }
294
+
295
+ function paginationCursor(value: unknown): string | undefined {
296
+ if (value === undefined) return undefined;
297
+ if (typeof value !== "string" || value.length === 0 || value.length > 4096 || value.includes("\0"))
298
+ throw new Error("MCP server returned an invalid pagination cursor");
299
+ return value;
300
+ }
301
+
302
+ async function paginatedInventory<T>(
303
+ method: string,
304
+ field: string,
305
+ requestPage: (params?: JsonObject) => Promise<JsonObject>,
306
+ validate: (value: unknown) => T[],
307
+ ): Promise<T[]> {
308
+ const result: T[] = [];
309
+ const seenCursors = new Set<string>();
310
+ let cursor: string | undefined;
311
+ for (let page = 0; page < maxPaginationPages; page += 1) {
312
+ const response = await requestPage(cursor === undefined ? undefined : { cursor });
313
+ const pageItems = validate(response[field]);
314
+ if (result.length + pageItems.length > maxInventoryItems) throw new Error(`MCP remote inventory cannot exceed ${maxInventoryItems} items`);
315
+ result.push(...pageItems);
316
+ const nextCursor = paginationCursor(response.nextCursor);
317
+ if (nextCursor === undefined) return result;
318
+ if (seenCursors.has(nextCursor)) throw new Error(`MCP server repeated a pagination cursor for ${method}`);
319
+ seenCursors.add(nextCursor);
320
+ cursor = nextCursor;
321
+ }
322
+ throw new Error(`MCP ${method} pagination cannot exceed ${maxPaginationPages} pages`);
323
+ }
324
+
325
+ function requiredRemoteString(value: unknown, message: string, maximum = maxResponseBytes): string {
326
+ if (typeof value !== "string" || value.length > maximum || value.includes("\0")) throw new Error(message);
327
+ return value;
328
+ }
329
+
330
+ function base64RemoteString(value: unknown, message: string): string {
331
+ const result = requiredRemoteString(value, message);
332
+ if (!/^(?:[A-Za-z\d+/]{4})*(?:[A-Za-z\d+/]{2}(?:==)?|[A-Za-z\d+/]{3}=?)?$/u.test(result)) throw new Error(message);
333
+ return result;
334
+ }
335
+
336
+ function toolResultContent(result: McpCallResult): AgentContent[] {
337
+ if (!Array.isArray(result.content) || result.content.length > maxInventoryItems) throw new Error("MCP server returned invalid MCP tool result content");
338
+ if (result.isError !== undefined && typeof result.isError !== "boolean") throw new Error("MCP server returned invalid MCP tool result content");
339
+ return result.content.map((item): AgentContent => {
340
+ if (item === null || typeof item !== "object" || Array.isArray(item)) throw new Error("MCP server returned invalid MCP tool result content");
341
+ const raw = item as JsonObject;
342
+ if (raw.type === "text") {
343
+ return { type: "text", text: requiredRemoteString(raw.text, "MCP server returned invalid MCP tool result content") };
344
+ }
345
+ if (raw.type === "image") {
346
+ const data = base64RemoteString(raw.data, "MCP server returned invalid MCP tool result content");
347
+ const mimeType = requiredRemoteString(raw.mimeType, "MCP server returned invalid MCP tool result content", 256);
348
+ if (!mimeType.startsWith("image/")) throw new Error("MCP server returned invalid MCP tool result content");
349
+ return { type: "image", data, mimeType };
350
+ }
351
+ if (raw.type === "audio") {
352
+ const mimeType = requiredRemoteString(raw.mimeType, "MCP server returned invalid MCP tool result content", 256);
353
+ base64RemoteString(raw.data, "MCP server returned invalid MCP tool result content");
354
+ return { type: "text", text: `[MCP audio content omitted: ${mimeType}]` };
355
+ }
356
+ if (raw.type === "resource") {
357
+ if (raw.resource === null || typeof raw.resource !== "object" || Array.isArray(raw.resource))
358
+ throw new Error("MCP server returned invalid MCP tool result content");
359
+ const resource = raw.resource as JsonObject;
360
+ const uri = requiredRemoteString(resource.uri, "MCP server returned invalid MCP tool result content", 4096);
361
+ if (typeof resource.text === "string") return { type: "text", text: resource.text };
362
+ if (typeof resource.blob === "string") {
363
+ const blob = base64RemoteString(resource.blob, "MCP server returned invalid MCP tool result content");
364
+ const mimeType =
365
+ resource.mimeType === undefined ? undefined : requiredRemoteString(resource.mimeType, "MCP server returned invalid MCP tool result content", 256);
366
+ return mimeType?.startsWith("image/") === true
367
+ ? { type: "image", data: blob, mimeType }
368
+ : { type: "text", text: `[MCP binary resource omitted: ${uri} (${mimeType ?? "unknown MIME type"})]` };
369
+ }
370
+ throw new Error("MCP server returned invalid MCP tool result content");
371
+ }
372
+ if (raw.type === "resource_link") {
373
+ const uri = requiredRemoteString(raw.uri, "MCP server returned invalid MCP tool result content", 4096);
374
+ const name = raw.name === undefined ? uri : requiredRemoteString(raw.name, "MCP server returned invalid MCP tool result content", 512);
375
+ return { type: "text", text: `[MCP resource: ${name} — ${uri}]` };
376
+ }
377
+ throw new Error("MCP server returned invalid MCP tool result content");
378
+ });
379
+ }
380
+
381
+ function validateInitializeResult(result: JsonObject): void {
382
+ if (
383
+ result.protocolVersion !== "2025-06-18" ||
384
+ result.capabilities === null ||
385
+ typeof result.capabilities !== "object" ||
386
+ Array.isArray(result.capabilities) ||
387
+ result.serverInfo === null ||
388
+ typeof result.serverInfo !== "object" ||
389
+ Array.isArray(result.serverInfo)
390
+ )
391
+ throw new Error("MCP server returned an invalid MCP initialize result");
392
+ const serverInfo = result.serverInfo as JsonObject;
393
+ if (
394
+ typeof serverInfo.name !== "string" ||
395
+ serverInfo.name.length === 0 ||
396
+ serverInfo.name.length > 512 ||
397
+ typeof serverInfo.version !== "string" ||
398
+ serverInfo.version.length === 0 ||
399
+ serverInfo.version.length > 512 ||
400
+ (result.instructions !== undefined && (typeof result.instructions !== "string" || result.instructions.length > 65_536))
401
+ )
402
+ throw new Error("MCP server returned an invalid MCP initialize result");
403
+ }
404
+
405
+ function resourceResultContent(result: JsonObject): AgentContent[] {
406
+ if (!Array.isArray(result.contents) || result.contents.length > maxInventoryItems) throw new Error("MCP server returned invalid MCP resource contents");
407
+ return result.contents.map((item): AgentContent => {
408
+ if (item === null || typeof item !== "object" || Array.isArray(item)) throw new Error("MCP server returned invalid MCP resource contents");
409
+ const raw = item as JsonObject;
410
+ const uri = requiredRemoteString(raw.uri, "MCP server returned invalid MCP resource contents", 4096);
411
+ if (typeof raw.text === "string") return { type: "text", text: raw.text };
412
+ if (typeof raw.blob === "string") {
413
+ const blob = base64RemoteString(raw.blob, "MCP server returned invalid MCP resource contents");
414
+ const mimeType = raw.mimeType === undefined ? undefined : requiredRemoteString(raw.mimeType, "MCP server returned invalid MCP resource contents", 256);
415
+ return mimeType?.startsWith("image/") === true
416
+ ? { type: "image", data: blob, mimeType }
417
+ : { type: "text", text: `[MCP binary resource omitted: ${uri} (${mimeType ?? "unknown MIME type"})]` };
418
+ }
419
+ throw new Error("MCP server returned invalid MCP resource contents");
420
+ });
421
+ }
422
+
423
+ function promptResultContent(result: JsonObject): AgentContent[] {
424
+ if (result.description !== undefined && (typeof result.description !== "string" || result.description.length > 8192))
425
+ throw new Error("MCP server returned invalid MCP prompt messages");
426
+ if (!Array.isArray(result.messages) || result.messages.length > maxInventoryItems) throw new Error("MCP server returned invalid MCP prompt messages");
427
+ return result.messages.flatMap((item): AgentContent[] => {
428
+ if (item === null || typeof item !== "object" || Array.isArray(item)) throw new Error("MCP server returned invalid MCP prompt messages");
429
+ const raw = item as JsonObject;
430
+ const role = raw.role;
431
+ if (role !== "user" && role !== "assistant") throw new Error("MCP server returned invalid MCP prompt messages");
432
+ const normalized = toolResultContent({ content: [raw.content] });
433
+ return normalized.flatMap((content): AgentContent[] =>
434
+ content.type === "text" ? [{ type: "text", text: `[${role}]\n${content.text}` }] : [{ type: "text", text: `[${role}]` }, content],
435
+ );
436
+ });
437
+ }
42
438
 
43
439
  function validateCommand(command: string[]): void {
44
440
  if (command.length === 0) throw new Error("MCP server command cannot be empty");
45
441
  if (command.length > maxCommandArgs) throw new Error(`MCP server command cannot exceed ${maxCommandArgs} arguments`);
442
+ if (command.some((part) => part.includes("\0"))) throw new Error("MCP server command arguments must not contain NUL characters");
46
443
  if (command.some((part) => part.length === 0 || Buffer.byteLength(part) > maxArgumentBytes))
47
444
  throw new Error("MCP server command contains an invalid argument");
48
- if (shellCommands.has(basename(command[0] ?? "").toLowerCase())) throw new Error("MCP shell wrappers are not allowed; pass an executable argv directly");
445
+ const executable = executableName(command)
446
+ .toLowerCase()
447
+ .replace(/\.(?:exe|cmd|bat|com)$/u, "");
448
+ if (shellCommands.has(executable)) throw new Error("MCP shell wrappers are not allowed; pass an executable argv directly");
449
+ }
450
+
451
+ function executableName(command: readonly string[]): string {
452
+ return (command[0] ?? "").replaceAll("\\", "/").split("/").pop() ?? "";
453
+ }
454
+
455
+ function serverLabel(command: readonly string[]): string {
456
+ const count = Math.max(0, command.length - 1);
457
+ return `${executableName(command)}${count === 0 ? "" : ` (+${count} ${count === 1 ? "arg" : "args"})`}`;
49
458
  }
50
459
 
51
460
  function encodeMessage(message: JsonObject): Buffer<ArrayBufferLike> {
52
- const payload = Buffer.from(JSON.stringify(message), "utf8");
53
- return Buffer.concat([Buffer.from(`Content-Length: ${payload.byteLength}\r\n\r\n`, "ascii"), payload]);
461
+ return Buffer.from(`${JSON.stringify(message)}\n`, "utf8");
462
+ }
463
+
464
+ function waitForChildClose(child: ChildProcessWithoutNullStreams, timeoutMs: number): Promise<boolean> {
465
+ if (child.exitCode !== null || child.signalCode !== null) return Promise.resolve(true);
466
+ return new Promise((resolve) => {
467
+ const onClose = () => finish(true);
468
+ const timer = setTimeout(() => finish(false), timeoutMs);
469
+ timer.unref();
470
+ const finish = (closed: boolean) => {
471
+ clearTimeout(timer);
472
+ child.off("close", onClose);
473
+ resolve(closed);
474
+ };
475
+ child.once("close", onClose);
476
+ });
477
+ }
478
+
479
+ async function terminateChild(child: ChildProcessWithoutNullStreams): Promise<void> {
480
+ if (!child.stdin.destroyed && !child.stdin.writableEnded) child.stdin.end();
481
+ if (child.exitCode !== null || child.signalCode !== null) return;
482
+ child.kill("SIGTERM");
483
+ if (await waitForChildClose(child, 250)) return;
484
+ child.kill("SIGKILL");
485
+ await waitForChildClose(child, 500);
54
486
  }
55
487
 
56
488
  function parseFrames(buffer: Buffer<ArrayBufferLike>): { messages: JsonObject[]; rest: Buffer<ArrayBufferLike> } {
@@ -64,9 +496,10 @@ function parseFrames(buffer: Buffer<ArrayBufferLike>): { messages: JsonObject[];
64
496
  const match = header.match(/content-length\s*:\s*(\d+)/i);
65
497
  if (match === null) throw new Error("MCP server returned an invalid Content-Length header");
66
498
  const length = Number(match[1]);
499
+ if (!Number.isSafeInteger(length) || length > maxResponseBytes) throw new Error("MCP server response exceeded the 1 MiB limit");
67
500
  const bodyStart = separator + 4;
68
501
  if (rest.length < bodyStart + length) break;
69
- const body = rest.subarray(bodyStart, bodyStart + length).toString("utf8");
502
+ const body = decodeFrame(rest.subarray(bodyStart, bodyStart + length));
70
503
  const message = JSON.parse(body) as unknown;
71
504
  if (typeof message === "object" && message !== null) messages.push(message as JsonObject);
72
505
  rest = rest.subarray(bodyStart + length);
@@ -74,7 +507,7 @@ function parseFrames(buffer: Buffer<ArrayBufferLike>): { messages: JsonObject[];
74
507
  }
75
508
  const newline = rest.indexOf(10);
76
509
  if (newline < 0) break;
77
- const line = rest.subarray(0, newline).toString("utf8").trim();
510
+ const line = decodeFrame(rest.subarray(0, newline)).trim();
78
511
  rest = rest.subarray(newline + 1);
79
512
  if (line === "") continue;
80
513
  try {
@@ -87,74 +520,197 @@ function parseFrames(buffer: Buffer<ArrayBufferLike>): { messages: JsonObject[];
87
520
  return { messages, rest };
88
521
  }
89
522
 
90
- async function request(child: ChildProcessWithoutNullStreams, id: number, method: string, params?: JsonObject): Promise<JsonObject> {
91
- return new Promise((resolve, reject) => {
92
- let buffer: Buffer<ArrayBufferLike> = Buffer.alloc(0);
93
- const timer = setTimeout(() => {
94
- cleanup();
95
- reject(new Error(`MCP request timed out: ${method}`));
96
- }, requestTimeoutMs);
97
- const onData = (chunk: Buffer): void => {
98
- buffer = Buffer.concat([buffer, chunk]);
99
- let parsed: { messages: JsonObject[]; rest: Buffer<ArrayBufferLike> };
523
+ function cancellationError(method: string, reason: unknown): Error {
524
+ if (reason instanceof Error && reason.message === disposedMessage) return reason;
525
+ return new Error(`MCP request was cancelled: ${method}${reason instanceof Error ? ` (${reason.message})` : ""}`, { cause: reason });
526
+ }
527
+
528
+ function withCancellation<T>(operation: Promise<T>, signal: AbortSignal | undefined, method: string): Promise<T> {
529
+ if (signal === undefined) return operation;
530
+ if (signal.aborted) return Promise.reject(cancellationError(method, signal.reason));
531
+ return new Promise<T>((resolve, reject) => {
532
+ const onAbort = () => {
533
+ signal.removeEventListener("abort", onAbort);
534
+ reject(cancellationError(method, signal.reason));
535
+ };
536
+ signal.addEventListener("abort", onAbort, { once: true });
537
+ void operation.then(
538
+ (value) => {
539
+ signal.removeEventListener("abort", onAbort);
540
+ resolve(value);
541
+ },
542
+ (error: unknown) => {
543
+ signal.removeEventListener("abort", onAbort);
544
+ reject(error instanceof Error ? error : new Error("MCP operation failed", { cause: error }));
545
+ },
546
+ );
547
+ });
548
+ }
549
+
550
+ const stdioRouters = new WeakMap<ChildProcessWithoutNullStreams, StdioRouter>();
551
+
552
+ function responseResult(message: JsonObject): JsonObject {
553
+ const hasError = Object.hasOwn(message, "error");
554
+ const hasResult = Object.hasOwn(message, "result");
555
+ if (message.jsonrpc !== "2.0" || hasError === hasResult) throw new Error("MCP server returned an invalid JSON-RPC response");
556
+ if (hasError) {
557
+ if (typeof message.error !== "object" || message.error === null || Array.isArray(message.error))
558
+ throw new Error("MCP server returned an invalid JSON-RPC response");
559
+ const errorMessage = (message.error as JsonObject).message;
560
+ const errorCode = (message.error as JsonObject).code;
561
+ if (typeof errorMessage !== "string" || typeof errorCode !== "number" || !Number.isInteger(errorCode))
562
+ throw new Error("MCP server returned an invalid JSON-RPC response");
563
+ throw new Error(errorMessage);
564
+ }
565
+ if (typeof message.result !== "object" || message.result === null || Array.isArray(message.result))
566
+ throw new Error("MCP server returned an invalid response");
567
+ return message.result as JsonObject;
568
+ }
569
+
570
+ function stdioRouter(child: ChildProcessWithoutNullStreams): StdioRouter {
571
+ const existing = stdioRouters.get(child);
572
+ if (existing !== undefined) return existing;
573
+ const router: StdioRouter = { buffer: Buffer.alloc(0), pending: new Map() };
574
+ const fail = (error: Error): void => {
575
+ if (router.terminalError !== undefined) return;
576
+ router.terminalError = error;
577
+ router.buffer = Buffer.alloc(0);
578
+ child.stdout.off("data", onData);
579
+ child.off("error", onError);
580
+ child.off("close", onClose);
581
+ for (const request of [...router.pending.values()]) request.reject(error);
582
+ };
583
+ const onData = (chunk: Buffer): void => {
584
+ for (const request of [...router.pending.values()]) {
585
+ request.receivedBytes += chunk.byteLength;
586
+ if (request.receivedBytes > maxResponseBytes) request.reject(new Error("MCP server response exceeded the 1 MiB limit"));
587
+ }
588
+ if (router.buffer.byteLength + chunk.byteLength > maxResponseBytes) {
589
+ fail(new Error("MCP server response exceeded the 1 MiB limit"));
590
+ return;
591
+ }
592
+ const buffer = router.buffer.byteLength === 0 ? chunk : Buffer.concat([router.buffer, chunk]);
593
+ let parsed: { messages: JsonObject[]; rest: Buffer<ArrayBufferLike> };
594
+ try {
595
+ parsed = parseFrames(buffer);
596
+ } catch (error) {
597
+ fail(error instanceof Error ? error : new Error("Failed to parse MCP response", { cause: error }));
598
+ return;
599
+ }
600
+ router.buffer = parsed.rest.byteLength === 0 ? Buffer.alloc(0) : Buffer.from(parsed.rest);
601
+ for (const message of parsed.messages) {
602
+ if (typeof message.id !== "number") continue;
603
+ const request = router.pending.get(message.id);
604
+ if (request === undefined) continue;
100
605
  try {
101
- parsed = parseFrames(buffer);
606
+ request.resolve(responseResult(message));
102
607
  } catch (error) {
103
- cleanup();
104
- reject(error instanceof Error ? error : new Error("Failed to parse MCP response", { cause: error }));
105
- return;
608
+ request.reject(error instanceof Error ? error : new Error("Failed to validate MCP response", { cause: error }));
106
609
  }
107
- buffer = parsed.rest;
108
- for (const message of parsed.messages) {
109
- if (message.id !== id) continue;
110
- cleanup();
111
- if (typeof message.error === "object" && message.error !== null) {
112
- const errorMessage = (message.error as JsonObject).message;
113
- reject(new Error(typeof errorMessage === "string" ? errorMessage : "MCP request failed"));
114
- } else if (typeof message.result === "object" && message.result !== null) resolve(message.result as JsonObject);
115
- else reject(new Error("MCP server returned an invalid response"));
116
- return;
610
+ }
611
+ };
612
+ const onError = (error: Error): void => fail(error);
613
+ const onClose = (code: number | null): void => fail(new Error(`MCP server exited before responding${code === null ? "" : ` (code ${code})`}`));
614
+ child.stdout.on("data", onData);
615
+ child.once("error", onError);
616
+ child.once("close", onClose);
617
+ stdioRouters.set(child, router);
618
+ return router;
619
+ }
620
+
621
+ async function request(child: ChildProcessWithoutNullStreams, id: number, method: string, params?: JsonObject, signal?: AbortSignal): Promise<JsonObject> {
622
+ if (signal?.aborted === true) throw cancellationError(method, signal.reason);
623
+ return new Promise((resolve, reject) => {
624
+ const router = stdioRouter(child);
625
+ if (router.terminalError !== undefined) {
626
+ reject(router.terminalError);
627
+ return;
628
+ }
629
+ if (router.pending.has(id)) {
630
+ reject(new Error(`MCP request id is already pending: ${id}`));
631
+ return;
632
+ }
633
+ let settled = false;
634
+ let sent = false;
635
+ const sendCancellation = (reason: string): void => {
636
+ if (!sent || method === "initialize" || child.stdin.destroyed || child.stdin.writableEnded) return;
637
+ try {
638
+ child.stdin.write(encodeMessage({ jsonrpc: "2.0", method: "notifications/cancelled", params: { requestId: id, reason } }), () => undefined);
639
+ } catch {
640
+ // The original timeout or cancellation remains the actionable error.
117
641
  }
118
642
  };
119
- const onError = (error: Error): void => {
120
- cleanup();
121
- reject(error);
122
- };
123
- const onClose = (code: number | null): void => {
124
- cleanup();
125
- reject(new Error(`MCP server exited before responding${code === null ? "" : ` (code ${code})`}`));
643
+ const timer = setTimeout(() => {
644
+ sendCancellation(`MCP request timed out: ${method}`);
645
+ rejectRequest(new Error(`MCP request timed out: ${method}`));
646
+ }, requestTimeoutMs);
647
+ timer.unref();
648
+ const onAbort = (): void => {
649
+ sendCancellation(signal?.reason instanceof Error ? signal.reason.message : "MCP client request cancelled");
650
+ rejectRequest(cancellationError(method, signal?.reason));
126
651
  };
127
652
  const cleanup = (): void => {
128
653
  clearTimeout(timer);
129
- child.stdout.off("data", onData);
130
- child.off("error", onError);
131
- child.off("close", onClose);
654
+ router.pending.delete(id);
655
+ signal?.removeEventListener("abort", onAbort);
132
656
  };
133
- child.stdout.on("data", onData);
134
- child.once("error", onError);
135
- child.once("close", onClose);
136
- child.stdin.write(encodeMessage({ jsonrpc: "2.0", id, method, ...(params === undefined ? {} : { params }) }));
657
+ const resolveRequest = (value: JsonObject): void => {
658
+ if (settled) return;
659
+ settled = true;
660
+ cleanup();
661
+ resolve(value);
662
+ };
663
+ const rejectRequest = (error: Error): void => {
664
+ if (settled) return;
665
+ settled = true;
666
+ cleanup();
667
+ reject(error);
668
+ };
669
+ router.pending.set(id, { receivedBytes: 0, resolve: resolveRequest, reject: rejectRequest });
670
+ signal?.addEventListener("abort", onAbort, { once: true });
671
+ try {
672
+ child.stdin.write(encodeMessage({ jsonrpc: "2.0", id, method, ...(params === undefined ? {} : { params }) }), (error) => {
673
+ if (error === null || error === undefined) return;
674
+ rejectRequest(error);
675
+ });
676
+ sent = true;
677
+ } catch (error) {
678
+ rejectRequest(error instanceof Error ? error : new Error("Failed to write MCP request", { cause: error }));
679
+ }
137
680
  });
138
681
  }
139
682
 
140
- async function withServer<T>(command: string[], cwd: string, callback: (child: ChildProcessWithoutNullStreams) => Promise<T>): Promise<T> {
683
+ async function withServer<T>(
684
+ command: string[],
685
+ cwd: string,
686
+ callback: (child: ChildProcessWithoutNullStreams) => Promise<T>,
687
+ signal?: AbortSignal,
688
+ ): Promise<T> {
141
689
  validateCommand(command);
690
+ if (signal?.aborted === true) throw cancellationError("initialize", signal.reason);
142
691
  const child = spawn(command[0]!, command.slice(1), { cwd, shell: false, stdio: ["pipe", "pipe", "pipe"] });
143
- let stderr = "";
144
- child.stderr.setEncoding("utf8");
145
- child.stderr.on("data", (chunk: string) => {
146
- stderr = `${stderr}${chunk}`.slice(-8_000);
692
+ let stderr: Buffer<ArrayBufferLike> = Buffer.alloc(0);
693
+ child.stderr.on("data", (chunk: Buffer) => {
694
+ stderr = appendByteTail(stderr, chunk, maxStderrBytes);
147
695
  });
148
696
  try {
149
- await request(child, 1, "initialize", { protocolVersion: "2025-06-18", capabilities: {}, clientInfo: { name: "pi-harness", version: "0.1.2" } });
697
+ const initializeResult = await request(
698
+ child,
699
+ 1,
700
+ "initialize",
701
+ { protocolVersion: "2025-06-18", capabilities: {}, clientInfo: { name: "pi-harness", version: clientVersion } },
702
+ signal,
703
+ );
704
+ validateInitializeResult(initializeResult);
150
705
  child.stdin.write(encodeMessage({ jsonrpc: "2.0", method: "notifications/initialized" }));
151
706
  return await callback(child);
152
707
  } catch (error) {
153
- if (error instanceof Error && stderr.trim() !== "") throw new Error(`${error.message}: ${stderr.trim()}`, { cause: error });
708
+ if (error instanceof Error && error.message === disposedMessage) throw error;
709
+ const stderrText = stderr.toString("utf8").trim();
710
+ if (error instanceof Error && stderrText !== "") throw new Error(`${error.message}: ${stderrText}`, { cause: error });
154
711
  throw error;
155
712
  } finally {
156
- child.stdin.end();
157
- child.kill();
713
+ await terminateChild(child);
158
714
  }
159
715
  }
160
716
 
@@ -163,26 +719,62 @@ export default {
163
719
  inject: ["piHarnessLaunch", "piPluginUi", "piTools"],
164
720
  Config,
165
721
  async apply(context: Context, config: McpClientConfig) {
722
+ assertKnownConfigKeys("pi-mcp-client", config, ["servers"]);
166
723
  type Latest = { server: string; tools: McpTool[]; resources: McpResource[]; prompts: McpPrompt[]; lastCall?: string };
724
+ const lifecycle = new AbortController();
167
725
  let latest: Latest | undefined;
726
+ let latestKey: string | undefined;
727
+ const previousFor = (key: string): Latest | undefined => (latestKey === key ? latest : undefined);
728
+ const publishLatest = (key: string, value: Latest): Latest => {
729
+ latestKey = key;
730
+ latest = clone(value);
731
+ return clone(value);
732
+ };
168
733
  const servers = new Map<string, ManagedServer>();
734
+ const startingServers = new Set<string>();
735
+ const unregisters: Array<() => void> = [];
736
+ const registerTool = (definition: Parameters<typeof context.piTools.register>[0]): (() => void) => {
737
+ try {
738
+ const unregister = context.piTools.register(definition);
739
+ unregisters.push(unregister);
740
+ return unregister;
741
+ } catch (error) {
742
+ for (const unregister of unregisters.splice(0).reverse()) unregister();
743
+ lifecycle.abort(new Error("MCP client plugin activation failed", { cause: error }));
744
+ throw error;
745
+ }
746
+ };
169
747
  const configured = new Map<string, McpServerDefinition>();
170
- for (const definition of config.servers ?? []) {
171
- if (definition.id.trim() === "") throw new Error("Configured MCP server id cannot be empty");
172
- if (configured.has(definition.id)) throw new Error(`Configured MCP server id is duplicated: ${definition.id}`);
748
+ const definitions = config.servers ?? [];
749
+ if (definitions.length > maxManagedServers) throw new Error(`MCP configured inventory cannot exceed ${maxManagedServers} servers`);
750
+ for (const definition of definitions) {
751
+ const id = serverIdValue(definition.id, true)!;
752
+ if (configured.has(id)) throw new Error(`Configured MCP server id is duplicated: ${id}`);
173
753
  validateCommand(definition.command);
174
- configured.set(definition.id, { id: definition.id, command: [...definition.command], autoStart: definition.autoStart === true });
754
+ configured.set(id, { id, command: [...definition.command], autoStart: definition.autoStart === true });
175
755
  }
176
756
  let nextServerId = 1;
177
- const startServer = async (command: string[], requestedId?: string): Promise<ManagedServer> => {
757
+ const startServer = async (command: string[], requestedId?: string, signal?: AbortSignal): Promise<ManagedServer> => {
178
758
  validateCommand(command);
179
- const id = requestedId ?? `mcp-${nextServerId++}`;
759
+ let id = requestedId;
760
+ if (id === undefined) {
761
+ do id = `mcp-${nextServerId++}`;
762
+ while (configured.has(id) || servers.has(id) || startingServers.has(id));
763
+ }
180
764
  if (servers.has(id)) throw new Error(`MCP server is already running: ${id}`);
181
- const child = spawn(command[0]!, command.slice(1), { cwd: context.piHarnessLaunch.cwd, shell: false, stdio: ["pipe", "pipe", "pipe"] });
182
- let stderr = "";
183
- child.stderr.setEncoding("utf8");
184
- child.stderr.on("data", (chunk: string) => {
185
- stderr = `${stderr}${chunk}`.slice(-8_000);
765
+ if (startingServers.has(id)) throw new Error(`MCP server is already starting: ${id}`);
766
+ if (servers.size + startingServers.size >= maxManagedServers) throw new Error(`MCP client cannot manage more than ${maxManagedServers} running servers`);
767
+ startingServers.add(id);
768
+ let child: ChildProcessWithoutNullStreams;
769
+ try {
770
+ child = spawn(command[0]!, command.slice(1), { cwd: context.piHarnessLaunch.cwd, shell: false, stdio: ["pipe", "pipe", "pipe"] });
771
+ } catch (error) {
772
+ startingServers.delete(id);
773
+ throw error;
774
+ }
775
+ let stderr: Buffer<ArrayBufferLike> = Buffer.alloc(0);
776
+ child.stderr.on("data", (chunk: Buffer) => {
777
+ stderr = appendByteTail(stderr, chunk, maxStderrBytes);
186
778
  });
187
779
  const server: ManagedServer = {
188
780
  id,
@@ -192,41 +784,59 @@ export default {
192
784
  nextRequestId: 2,
193
785
  queue: Promise.resolve(),
194
786
  startedAt: Date.now(),
787
+ lifecycle: new AbortController(),
195
788
  };
196
789
  child.once("close", () => {
197
790
  server.status = "stopping";
791
+ server.lifecycle.abort(new Error(`MCP server exited: ${server.id}`));
198
792
  servers.delete(server.id);
199
793
  });
200
794
  try {
201
- await request(child, 1, "initialize", { protocolVersion: "2025-06-18", capabilities: {}, clientInfo: { name: "pi-harness", version: "0.1.2" } });
202
- child.stdin.write(encodeMessage({ jsonrpc: "2.0", method: "notifications/initialized" }));
795
+ const initializeResult = await request(
796
+ child,
797
+ 1,
798
+ "initialize",
799
+ { protocolVersion: "2025-06-18", capabilities: {}, clientInfo: { name: "pi-harness", version: clientVersion } },
800
+ signal,
801
+ );
802
+ validateInitializeResult(initializeResult);
803
+ if (child.exitCode !== null || child.signalCode !== null) throw new Error(`MCP server exited during initialization: ${id}`);
203
804
  servers.set(server.id, server);
805
+ child.stdin.write(encodeMessage({ jsonrpc: "2.0", method: "notifications/initialized" }));
204
806
  return server;
205
807
  } catch (error) {
206
- child.stdin.end();
207
- child.kill();
208
- if (error instanceof Error && stderr.trim() !== "") throw new Error(`${error.message}: ${stderr.trim()}`, { cause: error });
808
+ servers.delete(server.id);
809
+ await terminateChild(child);
810
+ if (error instanceof Error && error.message === disposedMessage) throw error;
811
+ const stderrText = stderr.toString("utf8").trim();
812
+ if (error instanceof Error && stderrText !== "") throw new Error(`${error.message}: ${stderrText}`, { cause: error });
209
813
  throw error;
814
+ } finally {
815
+ startingServers.delete(id);
210
816
  }
211
817
  };
212
- const stopServer = async (serverId: string): Promise<boolean> => {
818
+ const stopServer = (serverId: string, signal?: AbortSignal): Promise<boolean> => {
213
819
  const server = servers.get(serverId);
214
820
  if (server === undefined) throw new Error(`MCP server is not running: ${serverId}`);
215
821
  server.status = "stopping";
216
- await server.queue;
217
- servers.delete(server.id);
218
- server.child.stdin.end();
219
- server.child.kill();
220
- return true;
822
+ server.lifecycle.abort(new Error(`MCP server stopped: ${server.id}`));
823
+ const operation = (async () => {
824
+ await server.queue;
825
+ servers.delete(server.id);
826
+ await terminateChild(server.child);
827
+ return true;
828
+ })();
829
+ return withCancellation(operation, signal, "server/stop");
221
830
  };
222
- const requestManaged = (server: ManagedServer, method: string, params?: JsonObject): Promise<JsonObject> => {
831
+ const requestManaged = (server: ManagedServer, method: string, params?: JsonObject, signal?: AbortSignal): Promise<JsonObject> => {
223
832
  if (server.status !== "running") throw new Error(`MCP server is not running: ${server.id}`);
224
- const task = server.queue.then(() => request(server.child, server.nextRequestId++, method, params));
833
+ const requestSignal = signal === undefined ? server.lifecycle.signal : AbortSignal.any([signal, server.lifecycle.signal]);
834
+ const task = server.queue.then(() => request(server.child, server.nextRequestId++, method, params, requestSignal));
225
835
  server.queue = task.then(
226
836
  () => undefined,
227
837
  () => undefined,
228
838
  );
229
- return task;
839
+ return withCancellation(task, requestSignal, method);
230
840
  };
231
841
  const getServer = (serverId: string): ManagedServer => {
232
842
  const server = servers.get(serverId);
@@ -238,108 +848,221 @@ export default {
238
848
  if (definition === undefined) throw new Error(`Configured MCP server is not found: ${serverId}`);
239
849
  return [...definition.command];
240
850
  };
241
- const list = async (command?: string[], serverId?: string): Promise<Latest> => {
851
+ const statusSnapshot = () => {
852
+ const running = [...servers.values()].map((server) => ({
853
+ id: server.id,
854
+ executable: executableName(server.command),
855
+ argumentCount: Math.max(0, server.command.length - 1),
856
+ status: server.status,
857
+ startedAt: server.startedAt,
858
+ }));
859
+ const active = new Set(running.map((server) => server.id));
860
+ return [
861
+ ...running,
862
+ ...[...configured.values()]
863
+ .filter((definition) => !active.has(definition.id))
864
+ .map((definition) => ({
865
+ id: definition.id,
866
+ executable: executableName(definition.command),
867
+ argumentCount: Math.max(0, definition.command.length - 1),
868
+ status: "stopped",
869
+ startedAt: 0,
870
+ })),
871
+ ];
872
+ };
873
+ const list = async (command?: string[], serverId?: string, signal?: AbortSignal): Promise<Latest> => {
874
+ rejectAmbiguousTarget(command, serverId);
242
875
  if (serverId !== undefined) {
243
876
  const managed = getServer(serverId);
244
- const result = await requestManaged(managed, "tools/list");
245
- const tools = Array.isArray(result.tools)
246
- ? result.tools.filter((tool): tool is McpTool => typeof tool === "object" && tool !== null && typeof (tool as JsonObject).name === "string")
247
- : [];
248
- latest = { server: managed.command.join(" "), tools, resources: latest?.resources ?? [], prompts: latest?.prompts ?? [] };
249
- return latest;
877
+ const tools = await paginatedInventory("tools/list", "tools", (params) => requestManaged(managed, "tools/list", params, signal), toolInventory);
878
+ const key = `managed:${managed.id}`;
879
+ const server = serverLabel(managed.command);
880
+ const previous = previousFor(key);
881
+ const next = { server, tools, resources: previous?.resources ?? [], prompts: previous?.prompts ?? [] };
882
+ return publishLatest(key, next);
250
883
  }
251
884
  if (command === undefined) throw new Error("Provide command or serverId to list MCP tools");
252
- return withServer(command, context.piHarnessLaunch.cwd, async (child) => {
253
- const result = await request(child, 2, "tools/list");
254
- const tools = Array.isArray(result.tools)
255
- ? result.tools.filter((tool): tool is McpTool => typeof tool === "object" && tool !== null && typeof (tool as JsonObject).name === "string")
256
- : [];
257
- latest = { server: command.join(" "), tools, resources: latest?.resources ?? [], prompts: latest?.prompts ?? [] };
258
- return latest;
259
- });
885
+ return withServer(
886
+ command,
887
+ context.piHarnessLaunch.cwd,
888
+ async (child) => {
889
+ let requestId = 2;
890
+ const tools = await paginatedInventory("tools/list", "tools", (params) => request(child, requestId++, "tools/list", params, signal), toolInventory);
891
+ const key = `command:${JSON.stringify(command)}`;
892
+ const server = serverLabel(command);
893
+ const previous = previousFor(key);
894
+ const next = { server, tools, resources: previous?.resources ?? [], prompts: previous?.prompts ?? [] };
895
+ return publishLatest(key, next);
896
+ },
897
+ signal,
898
+ );
260
899
  };
261
- const call = async (command: string[] | undefined, serverId: string | undefined, name: string, args: JsonObject): Promise<McpCallResult> => {
900
+ const call = async (
901
+ command: string[] | undefined,
902
+ serverId: string | undefined,
903
+ name: string,
904
+ args: JsonObject,
905
+ signal?: AbortSignal,
906
+ ): Promise<McpCallResult> => {
907
+ rejectAmbiguousTarget(command, serverId);
908
+ boundedInput(name, "tool name", 512);
262
909
  if (serverId !== undefined) {
263
910
  const managed = getServer(serverId);
264
- const result = (await requestManaged(managed, "tools/call", { name, arguments: args })) as McpCallResult;
265
- latest = {
266
- server: managed.command.join(" "),
267
- tools: latest?.tools ?? [],
268
- resources: latest?.resources ?? [],
269
- prompts: latest?.prompts ?? [],
911
+ const result = (await requestManaged(managed, "tools/call", { name, arguments: args }, signal)) as McpCallResult;
912
+ toolResultContent(result);
913
+ const key = `managed:${managed.id}`;
914
+ const server = serverLabel(managed.command);
915
+ const previous = previousFor(key);
916
+ publishLatest(key, {
917
+ server,
918
+ tools: previous?.tools ?? [],
919
+ resources: previous?.resources ?? [],
920
+ prompts: previous?.prompts ?? [],
270
921
  lastCall: name,
271
- };
922
+ });
272
923
  return result;
273
924
  }
274
925
  if (command === undefined) throw new Error("Provide command or serverId to call an MCP tool");
275
- return withServer(command, context.piHarnessLaunch.cwd, async (child) => {
276
- const result = (await request(child, 2, "tools/call", { name, arguments: args })) as McpCallResult;
277
- latest = { server: command.join(" "), tools: latest?.tools ?? [], resources: latest?.resources ?? [], prompts: latest?.prompts ?? [], lastCall: name };
278
- return result;
279
- });
926
+ return withServer(
927
+ command,
928
+ context.piHarnessLaunch.cwd,
929
+ async (child) => {
930
+ const result = (await request(child, 2, "tools/call", { name, arguments: args }, signal)) as McpCallResult;
931
+ toolResultContent(result);
932
+ const key = `command:${JSON.stringify(command)}`;
933
+ const server = serverLabel(command);
934
+ const previous = previousFor(key);
935
+ publishLatest(key, {
936
+ server,
937
+ tools: previous?.tools ?? [],
938
+ resources: previous?.resources ?? [],
939
+ prompts: previous?.prompts ?? [],
940
+ lastCall: name,
941
+ });
942
+ return result;
943
+ },
944
+ signal,
945
+ );
280
946
  };
281
- const requestOneShot = async (command: string[], method: string, params?: JsonObject): Promise<JsonObject> =>
282
- withServer(command, context.piHarnessLaunch.cwd, async (child) => request(child, 2, method, params));
947
+ const requestOneShot = async (command: string[], method: string, params?: JsonObject, signal?: AbortSignal): Promise<JsonObject> =>
948
+ withServer(command, context.piHarnessLaunch.cwd, async (child) => request(child, 2, method, params, signal), signal);
283
949
  const requireCommand = (command: string[] | undefined, message: string): string[] => {
284
950
  if (command === undefined) throw new Error(message);
285
951
  return command;
286
952
  };
287
- const resources = async (command: string[] | undefined, serverId: string | undefined): Promise<McpResource[]> => {
288
- const result =
289
- serverId === undefined
290
- ? await requestOneShot(requireCommand(command, "Provide command or serverId to list MCP resources"), "resources/list")
291
- : await requestManaged(getServer(serverId), "resources/list");
292
- const items = Array.isArray(result.resources)
293
- ? result.resources.filter((item): item is McpResource => typeof item === "object" && item !== null && typeof (item as JsonObject).uri === "string")
294
- : [];
295
- latest = {
296
- server: serverId === undefined ? (command ?? []).join(" ") : getServer(serverId).command.join(" "),
297
- tools: latest?.tools ?? [],
953
+ const resources = async (command: string[] | undefined, serverId: string | undefined, signal?: AbortSignal): Promise<McpResource[]> => {
954
+ rejectAmbiguousTarget(command, serverId);
955
+ let items: McpResource[];
956
+ let selectedCommand: string[];
957
+ if (serverId === undefined) {
958
+ selectedCommand = requireCommand(command, "Provide command or serverId to list MCP resources");
959
+ items = await withServer(
960
+ selectedCommand,
961
+ context.piHarnessLaunch.cwd,
962
+ async (child) => {
963
+ let requestId = 2;
964
+ return paginatedInventory(
965
+ "resources/list",
966
+ "resources",
967
+ (params) => request(child, requestId++, "resources/list", params, signal),
968
+ resourceInventory,
969
+ );
970
+ },
971
+ signal,
972
+ );
973
+ } else {
974
+ const managed = getServer(serverId);
975
+ selectedCommand = managed.command;
976
+ items = await paginatedInventory(
977
+ "resources/list",
978
+ "resources",
979
+ (params) => requestManaged(managed, "resources/list", params, signal),
980
+ resourceInventory,
981
+ );
982
+ }
983
+ const key = serverId === undefined ? `command:${JSON.stringify(selectedCommand)}` : `managed:${serverId}`;
984
+ const server = serverLabel(selectedCommand);
985
+ const previous = previousFor(key);
986
+ const next = {
987
+ server,
988
+ tools: previous?.tools ?? [],
298
989
  resources: items,
299
- prompts: latest?.prompts ?? [],
990
+ prompts: previous?.prompts ?? [],
300
991
  };
301
- return items;
992
+ publishLatest(key, next);
993
+ return clone(items);
302
994
  };
303
- const readResource = async (command: string[] | undefined, serverId: string | undefined, uri: string): Promise<JsonObject> => {
304
- if (uri.length === 0 || uri.length > 4096) throw new Error("MCP resource URI must be between 1 and 4096 characters");
995
+ const readResource = async (command: string[] | undefined, serverId: string | undefined, uri: string, signal?: AbortSignal): Promise<JsonObject> => {
996
+ rejectAmbiguousTarget(command, serverId);
997
+ boundedInput(uri, "resource URI", 4096);
305
998
  return serverId === undefined
306
- ? requestOneShot(requireCommand(command, "Provide command or serverId to read an MCP resource"), "resources/read", { uri })
307
- : requestManaged(getServer(serverId), "resources/read", { uri });
999
+ ? requestOneShot(requireCommand(command, "Provide command or serverId to read an MCP resource"), "resources/read", { uri }, signal)
1000
+ : requestManaged(getServer(serverId), "resources/read", { uri }, signal);
308
1001
  };
309
- const prompts = async (command: string[] | undefined, serverId: string | undefined): Promise<McpPrompt[]> => {
310
- const result =
311
- serverId === undefined
312
- ? await requestOneShot(requireCommand(command, "Provide command or serverId to list MCP prompts"), "prompts/list")
313
- : await requestManaged(getServer(serverId), "prompts/list");
314
- const items = Array.isArray(result.prompts)
315
- ? result.prompts.filter((item): item is McpPrompt => typeof item === "object" && item !== null && typeof (item as JsonObject).name === "string")
316
- : [];
317
- latest = {
318
- server: serverId === undefined ? (command ?? []).join(" ") : getServer(serverId).command.join(" "),
319
- tools: latest?.tools ?? [],
320
- resources: latest?.resources ?? [],
1002
+ const prompts = async (command: string[] | undefined, serverId: string | undefined, signal?: AbortSignal): Promise<McpPrompt[]> => {
1003
+ rejectAmbiguousTarget(command, serverId);
1004
+ let items: McpPrompt[];
1005
+ let selectedCommand: string[];
1006
+ if (serverId === undefined) {
1007
+ selectedCommand = requireCommand(command, "Provide command or serverId to list MCP prompts");
1008
+ items = await withServer(
1009
+ selectedCommand,
1010
+ context.piHarnessLaunch.cwd,
1011
+ async (child) => {
1012
+ let requestId = 2;
1013
+ return paginatedInventory("prompts/list", "prompts", (params) => request(child, requestId++, "prompts/list", params, signal), promptInventory);
1014
+ },
1015
+ signal,
1016
+ );
1017
+ } else {
1018
+ const managed = getServer(serverId);
1019
+ selectedCommand = managed.command;
1020
+ items = await paginatedInventory("prompts/list", "prompts", (params) => requestManaged(managed, "prompts/list", params, signal), promptInventory);
1021
+ }
1022
+ const key = serverId === undefined ? `command:${JSON.stringify(selectedCommand)}` : `managed:${serverId}`;
1023
+ const server = serverLabel(selectedCommand);
1024
+ const previous = previousFor(key);
1025
+ const next = {
1026
+ server,
1027
+ tools: previous?.tools ?? [],
1028
+ resources: previous?.resources ?? [],
321
1029
  prompts: items,
322
1030
  };
323
- return items;
1031
+ publishLatest(key, next);
1032
+ return clone(items);
324
1033
  };
325
- const getPrompt = async (command: string[] | undefined, serverId: string | undefined, name: string, args: JsonObject): Promise<JsonObject> => {
326
- if (name.length === 0 || name.length > 512) throw new Error("MCP prompt name must be between 1 and 512 characters");
1034
+ const getPrompt = async (
1035
+ command: string[] | undefined,
1036
+ serverId: string | undefined,
1037
+ name: string,
1038
+ args: JsonObject,
1039
+ signal?: AbortSignal,
1040
+ ): Promise<JsonObject> => {
1041
+ rejectAmbiguousTarget(command, serverId);
1042
+ boundedInput(name, "prompt name", 512);
327
1043
  return serverId === undefined
328
- ? requestOneShot(requireCommand(command, "Provide command or serverId to get an MCP prompt"), "prompts/get", { name, arguments: args })
329
- : requestManaged(getServer(serverId), "prompts/get", { name, arguments: args });
1044
+ ? requestOneShot(requireCommand(command, "Provide command or serverId to get an MCP prompt"), "prompts/get", { name, arguments: args }, signal)
1045
+ : requestManaged(getServer(serverId), "prompts/get", { name, arguments: args }, signal);
330
1046
  };
331
- const unregisterList = context.piTools.register(
1047
+ const unregisterList = registerTool(
332
1048
  defineTool({
333
1049
  name: "mcp_list_tools",
334
1050
  label: "MCP list tools",
335
1051
  description: "Start an MCP stdio server and list its available tools.",
336
1052
  promptSnippet: "discover tools exposed by an MCP stdio server",
337
- parameters: Type.Object({
338
- command: Type.Optional(Type.Array(Type.String(), { description: "MCP server executable and arguments; shell wrappers are rejected" })),
339
- serverId: Type.Optional(Type.String({ description: "A configured or running MCP server id" })),
340
- }),
341
- async execute(_toolCallId, params): Promise<AgentToolResult<{ server: string; tools: McpTool[] }>> {
342
- const result = await list(params.command, params.serverId);
1053
+ parameters: Type.Object(
1054
+ {
1055
+ command: Type.Optional(Type.Array(Type.String(), { description: "MCP server executable and arguments; shell wrappers are rejected" })),
1056
+ serverId: Type.Optional(Type.String({ description: "A configured or running MCP server id" })),
1057
+ },
1058
+ { additionalProperties: false },
1059
+ ),
1060
+ executionMode: "sequential",
1061
+ async execute(_toolCallId, params, signal): Promise<AgentToolResult<{ server: string; tools: McpTool[] }>> {
1062
+ const operationSignal = executionSignal(signal, lifecycle.signal);
1063
+ operationSignal.throwIfAborted();
1064
+ const raw = inspectParameters(params, connectionParameterNames);
1065
+ const result = await list(optionalCommand(raw.command), serverIdValue(raw.serverId), operationSignal);
343
1066
  return {
344
1067
  content: [
345
1068
  { type: "text", text: result.tools.map((tool) => `${tool.name}: ${tool.description ?? ""}`).join("\n") || "MCP server returned no tools." },
@@ -349,104 +1072,136 @@ export default {
349
1072
  },
350
1073
  }),
351
1074
  );
352
- const unregisterCall = context.piTools.register(
1075
+ const unregisterCall = registerTool(
353
1076
  defineTool({
354
1077
  name: "mcp_call",
355
1078
  label: "MCP call tool",
356
1079
  description: "Call a named tool on an MCP stdio server with a JSON object of arguments.",
357
1080
  promptSnippet: "call a tool exposed by an MCP stdio server",
358
- parameters: Type.Object({
359
- command: Type.Optional(Type.Array(Type.String())),
360
- serverId: Type.Optional(Type.String()),
361
- name: Type.String(),
362
- arguments: Type.Optional(Type.Record(Type.String(), Type.Any())),
363
- }),
364
- async execute(_toolCallId, params): Promise<AgentToolResult<McpCallResult>> {
365
- const result = await call(params.command, params.serverId, params.name, params.arguments ?? {});
366
- const content = Array.isArray(result.content) ? result.content : [{ type: "text", text: JSON.stringify(result) }];
367
- return { content: content as AgentToolResult<McpCallResult>["content"], details: result };
1081
+ parameters: Type.Object(
1082
+ {
1083
+ command: Type.Optional(Type.Array(Type.String())),
1084
+ serverId: Type.Optional(Type.String()),
1085
+ name: Type.String(),
1086
+ arguments: Type.Optional(Type.Record(Type.String(), Type.Any())),
1087
+ },
1088
+ { additionalProperties: false },
1089
+ ),
1090
+ executionMode: "sequential",
1091
+ async execute(_toolCallId, params, signal): Promise<AgentToolResult<McpCallResult>> {
1092
+ const operationSignal = executionSignal(signal, lifecycle.signal);
1093
+ operationSignal.throwIfAborted();
1094
+ const raw = inspectParameters(params, callParameterNames);
1095
+ const result = await call(
1096
+ optionalCommand(raw.command),
1097
+ serverIdValue(raw.serverId),
1098
+ requiredString(raw.name, "tool name"),
1099
+ jsonObject(raw.arguments),
1100
+ operationSignal,
1101
+ );
1102
+ return { content: toolResultContent(result), details: clone(result) };
368
1103
  },
369
1104
  }),
370
1105
  );
371
- const unregisterStart = context.piTools.register(
1106
+ const unregisterStart = registerTool(
372
1107
  defineTool({
373
1108
  name: "mcp_server_start",
374
1109
  label: "MCP server start",
375
1110
  description: "Start and initialize a persistent MCP stdio server managed by Pi Harness.",
376
1111
  promptSnippet: "start a persistent MCP stdio server",
377
- parameters: Type.Object({
378
- command: Type.Optional(Type.Array(Type.String(), { description: "MCP server executable and arguments; shell wrappers are rejected" })),
379
- serverId: Type.Optional(Type.String({ description: "Configured server id or a running server id" })),
380
- }),
381
- async execute(_toolCallId, params): Promise<AgentToolResult<{ serverId: string; command: string[]; status: string }>> {
382
- const command = params.command ?? (params.serverId === undefined ? undefined : configuredCommand(params.serverId));
1112
+ parameters: Type.Object(
1113
+ {
1114
+ command: Type.Optional(Type.Array(Type.String(), { description: "MCP server executable and arguments; shell wrappers are rejected" })),
1115
+ serverId: Type.Optional(Type.String({ description: "Configured server id or a running server id" })),
1116
+ },
1117
+ { additionalProperties: false },
1118
+ ),
1119
+ executionMode: "sequential",
1120
+ async execute(_toolCallId, params, signal): Promise<AgentToolResult<{ serverId: string; command: string[]; status: string }>> {
1121
+ const operationSignal = executionSignal(signal, lifecycle.signal);
1122
+ operationSignal.throwIfAborted();
1123
+ const raw = inspectParameters(params, connectionParameterNames);
1124
+ const serverId = serverIdValue(raw.serverId);
1125
+ const command = optionalCommand(raw.command) ?? (serverId === undefined ? undefined : configuredCommand(serverId));
383
1126
  if (command === undefined) throw new Error("Provide command or configured serverId to start an MCP server");
384
- const server = await startServer(command, params.serverId);
1127
+ const server = await startServer(command, serverId, operationSignal);
385
1128
  return {
386
1129
  content: [{ type: "text", text: `MCP server ${server.id} is running.` }],
387
- details: { serverId: server.id, command: server.command, status: server.status },
1130
+ details: { serverId: server.id, command: [...server.command], status: server.status },
388
1131
  };
389
1132
  },
390
1133
  }),
391
1134
  );
392
- const unregisterStatus = context.piTools.register(
1135
+ const unregisterStatus = registerTool(
393
1136
  defineTool({
394
1137
  name: "mcp_server_status",
395
1138
  label: "MCP server status",
396
1139
  description: "List persistent MCP stdio servers managed by Pi Harness.",
397
1140
  promptSnippet: "inspect running MCP server status",
398
- parameters: Type.Object({}),
399
- execute(): Promise<AgentToolResult<{ servers: Array<{ id: string; command: string[]; status: string; startedAt: number }> }>> {
400
- const running = [...servers.values()].map((server) => ({
401
- id: server.id,
402
- command: server.command,
403
- status: server.status,
404
- startedAt: server.startedAt,
405
- }));
406
- const active = new Set(running.map((server) => server.id));
407
- const snapshot = [
408
- ...running,
409
- ...[...configured.values()]
410
- .filter((definition) => !active.has(definition.id))
411
- .map((definition) => ({ id: definition.id, command: definition.command, status: "stopped", startedAt: 0 })),
412
- ];
413
- return Promise.resolve({
414
- content: [
415
- {
416
- type: "text",
417
- text:
418
- snapshot.length === 0
419
- ? "No MCP servers are running."
420
- : snapshot.map((server) => `${server.id}: ${server.status} (${server.command.join(" ")})`).join("\n"),
421
- },
422
- ],
423
- details: { servers: snapshot },
1141
+ parameters: Type.Object({}, { additionalProperties: false }),
1142
+ executionMode: "sequential",
1143
+ execute(
1144
+ _toolCallId,
1145
+ params,
1146
+ signal,
1147
+ ): Promise<AgentToolResult<{ servers: Array<{ id: string; executable: string; argumentCount: number; status: string; startedAt: number }> }>> {
1148
+ return Promise.resolve().then(() => {
1149
+ const operationSignal = executionSignal(signal, lifecycle.signal);
1150
+ operationSignal.throwIfAborted();
1151
+ inspectParameters(params, noParameterNames);
1152
+ const snapshot = statusSnapshot();
1153
+ return {
1154
+ content: [
1155
+ {
1156
+ type: "text",
1157
+ text:
1158
+ snapshot.length === 0
1159
+ ? "No MCP servers are running."
1160
+ : snapshot
1161
+ .map(
1162
+ (server) =>
1163
+ `${server.id}: ${server.status} (${server.executable}, ${server.argumentCount} argument${server.argumentCount === 1 ? "" : "s"})`,
1164
+ )
1165
+ .join("\n"),
1166
+ },
1167
+ ],
1168
+ details: { servers: snapshot },
1169
+ };
424
1170
  });
425
1171
  },
426
1172
  }),
427
1173
  );
428
- const unregisterStop = context.piTools.register(
1174
+ const unregisterStop = registerTool(
429
1175
  defineTool({
430
1176
  name: "mcp_server_stop",
431
1177
  label: "MCP server stop",
432
1178
  description: "Stop a persistent MCP stdio server and remove it from the managed set.",
433
1179
  promptSnippet: "stop a persistent MCP stdio server",
434
- parameters: Type.Object({ serverId: Type.String() }),
435
- async execute(_toolCallId, params): Promise<AgentToolResult<{ serverId: string; stopped: boolean }>> {
436
- const stopped = await stopServer(params.serverId);
437
- return { content: [{ type: "text", text: `MCP server ${params.serverId} stopped.` }], details: { serverId: params.serverId, stopped } };
1180
+ parameters: Type.Object({ serverId: Type.String() }, { additionalProperties: false }),
1181
+ executionMode: "sequential",
1182
+ async execute(_toolCallId, params, signal): Promise<AgentToolResult<{ serverId: string; stopped: boolean }>> {
1183
+ const operationSignal = executionSignal(signal, lifecycle.signal);
1184
+ operationSignal.throwIfAborted();
1185
+ const raw = inspectParameters(params, stopParameterNames);
1186
+ const serverId = serverIdValue(raw.serverId, true)!;
1187
+ const stopped = await stopServer(serverId, operationSignal);
1188
+ return { content: [{ type: "text", text: `MCP server ${serverId} stopped.` }], details: { serverId, stopped } };
438
1189
  },
439
1190
  }),
440
1191
  );
441
- const unregisterListResources = context.piTools.register(
1192
+ const unregisterListResources = registerTool(
442
1193
  defineTool({
443
1194
  name: "mcp_list_resources",
444
1195
  label: "MCP list resources",
445
1196
  description: "List resources exposed by an MCP server.",
446
1197
  promptSnippet: "list resources exposed by an MCP server",
447
- parameters: Type.Object({ command: Type.Optional(Type.Array(Type.String())), serverId: Type.Optional(Type.String()) }),
448
- async execute(_toolCallId, params): Promise<AgentToolResult<{ resources: McpResource[] }>> {
449
- const items = await resources(params.command, params.serverId);
1198
+ parameters: Type.Object({ command: Type.Optional(Type.Array(Type.String())), serverId: Type.Optional(Type.String()) }, { additionalProperties: false }),
1199
+ executionMode: "sequential",
1200
+ async execute(_toolCallId, params, signal): Promise<AgentToolResult<{ resources: McpResource[] }>> {
1201
+ const operationSignal = executionSignal(signal, lifecycle.signal);
1202
+ operationSignal.throwIfAborted();
1203
+ const raw = inspectParameters(params, connectionParameterNames);
1204
+ const items = await resources(optionalCommand(raw.command), serverIdValue(raw.serverId), operationSignal);
450
1205
  return {
451
1206
  content: [{ type: "text", text: items.map((item) => `${item.uri} ${item.name ?? ""}`).join("\n") || "MCP server returned no resources." }],
452
1207
  details: { resources: items },
@@ -454,29 +1209,44 @@ export default {
454
1209
  },
455
1210
  }),
456
1211
  );
457
- const unregisterReadResource = context.piTools.register(
1212
+ const unregisterReadResource = registerTool(
458
1213
  defineTool({
459
1214
  name: "mcp_read_resource",
460
1215
  label: "MCP read resource",
461
1216
  description: "Read one resource exposed by an MCP server.",
462
1217
  promptSnippet: "read a resource exposed by an MCP server",
463
- parameters: Type.Object({ command: Type.Optional(Type.Array(Type.String())), serverId: Type.Optional(Type.String()), uri: Type.String() }),
464
- async execute(_toolCallId, params): Promise<AgentToolResult<JsonObject>> {
465
- const result = await readResource(params.command, params.serverId, params.uri);
466
- const contents = Array.isArray(result.contents) ? result.contents : [{ type: "text", text: JSON.stringify(result) }];
467
- return { content: contents as AgentToolResult<JsonObject>["content"], details: result };
1218
+ parameters: Type.Object(
1219
+ { command: Type.Optional(Type.Array(Type.String())), serverId: Type.Optional(Type.String()), uri: Type.String() },
1220
+ { additionalProperties: false },
1221
+ ),
1222
+ executionMode: "sequential",
1223
+ async execute(_toolCallId, params, signal): Promise<AgentToolResult<JsonObject>> {
1224
+ const operationSignal = executionSignal(signal, lifecycle.signal);
1225
+ operationSignal.throwIfAborted();
1226
+ const raw = inspectParameters(params, readResourceParameterNames);
1227
+ const result = await readResource(
1228
+ optionalCommand(raw.command),
1229
+ serverIdValue(raw.serverId),
1230
+ requiredString(raw.uri, "resource URI"),
1231
+ operationSignal,
1232
+ );
1233
+ return { content: resourceResultContent(result), details: clone(result) };
468
1234
  },
469
1235
  }),
470
1236
  );
471
- const unregisterListPrompts = context.piTools.register(
1237
+ const unregisterListPrompts = registerTool(
472
1238
  defineTool({
473
1239
  name: "mcp_list_prompts",
474
1240
  label: "MCP list prompts",
475
1241
  description: "List prompt templates exposed by an MCP server.",
476
1242
  promptSnippet: "list prompt templates exposed by an MCP server",
477
- parameters: Type.Object({ command: Type.Optional(Type.Array(Type.String())), serverId: Type.Optional(Type.String()) }),
478
- async execute(_toolCallId, params): Promise<AgentToolResult<{ prompts: McpPrompt[] }>> {
479
- const items = await prompts(params.command, params.serverId);
1243
+ parameters: Type.Object({ command: Type.Optional(Type.Array(Type.String())), serverId: Type.Optional(Type.String()) }, { additionalProperties: false }),
1244
+ executionMode: "sequential",
1245
+ async execute(_toolCallId, params, signal): Promise<AgentToolResult<{ prompts: McpPrompt[] }>> {
1246
+ const operationSignal = executionSignal(signal, lifecycle.signal);
1247
+ operationSignal.throwIfAborted();
1248
+ const raw = inspectParameters(params, connectionParameterNames);
1249
+ const items = await prompts(optionalCommand(raw.command), serverIdValue(raw.serverId), operationSignal);
480
1250
  return {
481
1251
  content: [{ type: "text", text: items.map((item) => `${item.name}: ${item.description ?? ""}`).join("\n") || "MCP server returned no prompts." }],
482
1252
  details: { prompts: items },
@@ -484,29 +1254,41 @@ export default {
484
1254
  },
485
1255
  }),
486
1256
  );
487
- const unregisterGetPrompt = context.piTools.register(
1257
+ const unregisterGetPrompt = registerTool(
488
1258
  defineTool({
489
1259
  name: "mcp_get_prompt",
490
1260
  label: "MCP get prompt",
491
1261
  description: "Render a prompt template exposed by an MCP server.",
492
1262
  promptSnippet: "render a prompt template from an MCP server",
493
- parameters: Type.Object({
494
- command: Type.Optional(Type.Array(Type.String())),
495
- serverId: Type.Optional(Type.String()),
496
- name: Type.String(),
497
- arguments: Type.Optional(Type.Record(Type.String(), Type.Any())),
498
- }),
499
- async execute(_toolCallId, params): Promise<AgentToolResult<JsonObject>> {
500
- const result = await getPrompt(params.command, params.serverId, params.name, params.arguments ?? {});
501
- const content = Array.isArray(result.messages) ? result.messages : [{ type: "text", text: JSON.stringify(result) }];
502
- return { content: content as AgentToolResult<JsonObject>["content"], details: result };
1263
+ parameters: Type.Object(
1264
+ {
1265
+ command: Type.Optional(Type.Array(Type.String())),
1266
+ serverId: Type.Optional(Type.String()),
1267
+ name: Type.String(),
1268
+ arguments: Type.Optional(Type.Record(Type.String(), Type.String())),
1269
+ },
1270
+ { additionalProperties: false },
1271
+ ),
1272
+ executionMode: "sequential",
1273
+ async execute(_toolCallId, params, signal): Promise<AgentToolResult<JsonObject>> {
1274
+ const operationSignal = executionSignal(signal, lifecycle.signal);
1275
+ operationSignal.throwIfAborted();
1276
+ const raw = inspectParameters(params, callParameterNames);
1277
+ const result = await getPrompt(
1278
+ optionalCommand(raw.command),
1279
+ serverIdValue(raw.serverId),
1280
+ requiredString(raw.name, "prompt name"),
1281
+ promptArguments(raw.arguments),
1282
+ operationSignal,
1283
+ );
1284
+ return { content: promptResultContent(result), details: clone(result) };
503
1285
  },
504
1286
  }),
505
1287
  );
506
1288
  const serverSnapshot = (): PiMcpServerSnapshot[] => {
507
1289
  const running = [...servers.values()].map((server) => ({
508
1290
  id: server.id,
509
- command: [...server.command],
1291
+ command: [executableName(server.command)],
510
1292
  status: server.status,
511
1293
  startedAt: server.startedAt,
512
1294
  }));
@@ -515,26 +1297,63 @@ export default {
515
1297
  ...running,
516
1298
  ...[...configured.values()]
517
1299
  .filter((definition) => !active.has(definition.id))
518
- .map((definition) => ({ id: definition.id, command: [...definition.command], status: "stopped", startedAt: 0 })),
1300
+ .map((definition) => ({ id: definition.id, command: [executableName(definition.command)], status: "stopped", startedAt: 0 })),
519
1301
  ];
520
1302
  };
521
1303
  context.provide("piMcp", { snapshot: () => ({ servers: serverSnapshot() }) });
522
- const disposePanel = context.piPluginUi.register({
523
- id: "mcp-client-panel",
524
- pluginId: "@pi-harness/core/plugins/mcp-client",
525
- title: "MCP Client",
526
- description: "通过 stdio JSON-RPC 连接外部 MCP 工具服务器。",
527
- icon: "",
528
- read: () => ({
529
- server: latest?.server ?? null,
530
- tools: latest?.tools ?? [],
531
- resources: latest?.resources ?? [],
532
- prompts: latest?.prompts ?? [],
533
- lastCall: latest?.lastCall ?? null,
534
- servers: serverSnapshot(),
535
- }),
536
- });
537
- context.effect(() => () => {
1304
+ let disposePanel: () => void;
1305
+ try {
1306
+ disposePanel = context.piPluginUi.register({
1307
+ id: "mcp-client-panel",
1308
+ pluginId: "@pi-harness/core/plugins/mcp-client",
1309
+ title: "MCP Client",
1310
+ description: "通过 stdio JSON-RPC 连接外部 MCP 工具服务器。",
1311
+ icon: "⌘",
1312
+ read: () => {
1313
+ const tools = latest?.tools ?? [];
1314
+ const resources = latest?.resources ?? [];
1315
+ const prompts = latest?.prompts ?? [];
1316
+ const serverStatuses = statusSnapshot();
1317
+ return clone({
1318
+ server: latest?.server ?? null,
1319
+ tools: tools.slice(0, maxPanelItems),
1320
+ resources: resources.slice(0, maxPanelItems),
1321
+ prompts: prompts.slice(0, maxPanelItems),
1322
+ lastCall: latest?.lastCall ?? null,
1323
+ servers: serverStatuses.slice(0, maxPanelItems),
1324
+ inventory: {
1325
+ tools: { total: tools.length, shown: Math.min(tools.length, maxPanelItems), truncated: tools.length > maxPanelItems },
1326
+ resources: { total: resources.length, shown: Math.min(resources.length, maxPanelItems), truncated: resources.length > maxPanelItems },
1327
+ prompts: { total: prompts.length, shown: Math.min(prompts.length, maxPanelItems), truncated: prompts.length > maxPanelItems },
1328
+ servers: {
1329
+ total: serverStatuses.length,
1330
+ shown: Math.min(serverStatuses.length, maxPanelItems),
1331
+ truncated: serverStatuses.length > maxPanelItems,
1332
+ },
1333
+ },
1334
+ limits: {
1335
+ responseBytes: maxResponseBytes,
1336
+ commandArgs: maxCommandArgs,
1337
+ argumentBytes: maxArgumentBytes,
1338
+ toolArgumentsBytes: maxToolArgumentsBytes,
1339
+ toolArgumentDepth: maxToolArgumentDepth,
1340
+ requestTimeoutMs,
1341
+ panelItems: maxPanelItems,
1342
+ inventoryItems: maxInventoryItems,
1343
+ paginationPages: maxPaginationPages,
1344
+ stderrBytes: maxStderrBytes,
1345
+ managedServers: maxManagedServers,
1346
+ },
1347
+ });
1348
+ },
1349
+ });
1350
+ } catch (error) {
1351
+ for (const unregister of unregisters.splice(0).reverse()) unregister();
1352
+ lifecycle.abort(new Error("MCP client plugin activation failed", { cause: error }));
1353
+ throw error;
1354
+ }
1355
+ context.effect(() => async () => {
1356
+ lifecycle.abort(new Error(disposedMessage));
538
1357
  unregisterList();
539
1358
  unregisterCall();
540
1359
  unregisterStart();
@@ -544,16 +1363,17 @@ export default {
544
1363
  unregisterReadResource();
545
1364
  unregisterListPrompts();
546
1365
  unregisterGetPrompt();
547
- for (const server of servers.values()) {
1366
+ const running = [...servers.values()];
1367
+ for (const server of running) {
548
1368
  server.status = "stopping";
549
- server.child.stdin.end();
550
- server.child.kill();
1369
+ server.lifecycle.abort(new Error(disposedMessage));
551
1370
  }
552
1371
  servers.clear();
553
1372
  disposePanel();
1373
+ await Promise.all(running.map(async (server) => terminateChild(server.child)));
554
1374
  });
555
1375
  for (const definition of configured.values()) {
556
- if (definition.autoStart === true) await startServer(definition.command, definition.id);
1376
+ if (definition.autoStart === true) await startServer(definition.command, definition.id, lifecycle.signal);
557
1377
  }
558
1378
  },
559
1379
  };