@pi-harness/pi-harness 0.1.1 → 0.1.3

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 (911) hide show
  1. package/LICENSE +9 -0
  2. package/README.md +31 -7
  3. package/apps/web/dist/assets/index-BoEwZu6r.css +2 -0
  4. package/apps/web/dist/assets/index-alZn4u37.js +20 -0
  5. package/apps/web/dist/assets/markdown-vendor-DUdMWn0M.js +66 -0
  6. package/apps/web/dist/assets/react-vendor-BD7-wQo9.js +9 -0
  7. package/apps/web/dist/icons/app/android-192.png +0 -0
  8. package/apps/web/dist/icons/app/android-512.png +0 -0
  9. package/apps/web/dist/icons/app/app-blue-512.png +0 -0
  10. package/apps/web/dist/icons/app/app-store-1024.png +0 -0
  11. package/apps/web/dist/icons/app/apple-touch-icon-180.png +0 -0
  12. package/apps/web/dist/icons/app/maskable-512.png +0 -0
  13. package/apps/web/dist/icons/favicon/favicon-16.png +0 -0
  14. package/apps/web/dist/icons/favicon/favicon-32.png +0 -0
  15. package/apps/web/dist/icons/favicon/favicon-48.png +0 -0
  16. package/apps/web/dist/icons/png-blue/pi-256.png +0 -0
  17. package/apps/web/dist/icons/png-blue/pi-512.png +0 -0
  18. package/apps/web/dist/icons/png-ink/pi-1024.png +0 -0
  19. package/apps/web/dist/icons/png-ink/pi-128.png +0 -0
  20. package/apps/web/dist/icons/png-ink/pi-16.png +0 -0
  21. package/apps/web/dist/icons/png-ink/pi-24.png +0 -0
  22. package/apps/web/dist/icons/png-ink/pi-256.png +0 -0
  23. package/apps/web/dist/icons/png-ink/pi-32.png +0 -0
  24. package/apps/web/dist/icons/png-ink/pi-48.png +0 -0
  25. package/apps/web/dist/icons/png-ink/pi-512.png +0 -0
  26. package/apps/web/dist/icons/png-ink/pi-64.png +0 -0
  27. package/apps/web/dist/icons/png-white/pi-1024.png +0 -0
  28. package/apps/web/dist/icons/png-white/pi-128.png +0 -0
  29. package/apps/web/dist/icons/png-white/pi-16.png +0 -0
  30. package/apps/web/dist/icons/png-white/pi-24.png +0 -0
  31. package/apps/web/dist/icons/png-white/pi-256.png +0 -0
  32. package/apps/web/dist/icons/png-white/pi-32.png +0 -0
  33. package/apps/web/dist/icons/png-white/pi-48.png +0 -0
  34. package/apps/web/dist/icons/png-white/pi-512.png +0 -0
  35. package/apps/web/dist/icons/png-white/pi-64.png +0 -0
  36. package/apps/web/dist/icons/social/og-1200x630.png +0 -0
  37. package/apps/web/dist/icons/svg/app-icon-blue.svg +13 -0
  38. package/apps/web/dist/icons/svg/app-icon-ink.svg +13 -0
  39. package/apps/web/dist/icons/svg/favicon.svg +10 -0
  40. package/apps/web/dist/icons/svg/lockup-horizontal.svg +13 -0
  41. package/apps/web/dist/icons/svg/mark-blue.svg +10 -0
  42. package/apps/web/dist/icons/svg/mark-compact.svg +10 -0
  43. package/apps/web/dist/icons/svg/mark-ink.svg +10 -0
  44. package/apps/web/dist/icons/svg/mark-white.svg +10 -0
  45. package/apps/web/dist/icons/svg/mark.svg +10 -0
  46. package/apps/web/dist/index.html +18 -6
  47. package/apps/web/dist/manifest.webmanifest +14 -0
  48. package/apps/web/index.html +14 -4
  49. package/apps/web/package.json +11 -9
  50. package/apps/web/profile/cordis.yml +222 -1
  51. package/apps/web/public/icons/app/android-192.png +0 -0
  52. package/apps/web/public/icons/app/android-512.png +0 -0
  53. package/apps/web/public/icons/app/app-blue-512.png +0 -0
  54. package/apps/web/public/icons/app/app-store-1024.png +0 -0
  55. package/apps/web/public/icons/app/apple-touch-icon-180.png +0 -0
  56. package/apps/web/public/icons/app/maskable-512.png +0 -0
  57. package/apps/web/public/icons/favicon/favicon-16.png +0 -0
  58. package/apps/web/public/icons/favicon/favicon-32.png +0 -0
  59. package/apps/web/public/icons/favicon/favicon-48.png +0 -0
  60. package/apps/web/public/icons/png-blue/pi-256.png +0 -0
  61. package/apps/web/public/icons/png-blue/pi-512.png +0 -0
  62. package/apps/web/public/icons/png-ink/pi-1024.png +0 -0
  63. package/apps/web/public/icons/png-ink/pi-128.png +0 -0
  64. package/apps/web/public/icons/png-ink/pi-16.png +0 -0
  65. package/apps/web/public/icons/png-ink/pi-24.png +0 -0
  66. package/apps/web/public/icons/png-ink/pi-256.png +0 -0
  67. package/apps/web/public/icons/png-ink/pi-32.png +0 -0
  68. package/apps/web/public/icons/png-ink/pi-48.png +0 -0
  69. package/apps/web/public/icons/png-ink/pi-512.png +0 -0
  70. package/apps/web/public/icons/png-ink/pi-64.png +0 -0
  71. package/apps/web/public/icons/png-white/pi-1024.png +0 -0
  72. package/apps/web/public/icons/png-white/pi-128.png +0 -0
  73. package/apps/web/public/icons/png-white/pi-16.png +0 -0
  74. package/apps/web/public/icons/png-white/pi-24.png +0 -0
  75. package/apps/web/public/icons/png-white/pi-256.png +0 -0
  76. package/apps/web/public/icons/png-white/pi-32.png +0 -0
  77. package/apps/web/public/icons/png-white/pi-48.png +0 -0
  78. package/apps/web/public/icons/png-white/pi-512.png +0 -0
  79. package/apps/web/public/icons/png-white/pi-64.png +0 -0
  80. package/apps/web/public/icons/social/og-1200x630.png +0 -0
  81. package/apps/web/public/icons/svg/app-icon-blue.svg +13 -0
  82. package/apps/web/public/icons/svg/app-icon-ink.svg +13 -0
  83. package/apps/web/public/icons/svg/favicon.svg +10 -0
  84. package/apps/web/public/icons/svg/lockup-horizontal.svg +13 -0
  85. package/apps/web/public/icons/svg/mark-blue.svg +10 -0
  86. package/apps/web/public/icons/svg/mark-compact.svg +10 -0
  87. package/apps/web/public/icons/svg/mark-ink.svg +10 -0
  88. package/apps/web/public/icons/svg/mark-white.svg +10 -0
  89. package/apps/web/public/icons/svg/mark.svg +10 -0
  90. package/apps/web/public/manifest.webmanifest +14 -0
  91. package/apps/web/server-dist/bin.js +19 -6
  92. package/apps/web/server-dist/bin.js.map +1 -1
  93. package/apps/web/src/command-palette.ts +28 -7
  94. package/apps/web/src/file-diff.ts +15 -10
  95. package/apps/web/src/main.ts +4 -1
  96. package/apps/web/src/runtime.css +17 -4
  97. package/apps/web/src/server/bin.ts +24 -7
  98. package/apps/web/src/style.css +2604 -7
  99. package/apps/web/src/tailwind.css +25 -0
  100. package/apps/web/tsconfig.build.json +5 -1
  101. package/apps/web/tsconfig.json +1 -1
  102. package/apps/web/vite.config.ts +20 -0
  103. package/package.json +29 -17
  104. package/packages/api-gateway/LICENSE +9 -0
  105. package/packages/api-gateway/dist/index.d.ts.map +1 -1
  106. package/packages/api-gateway/dist/index.js +1202 -37
  107. package/packages/api-gateway/dist/index.js.map +1 -1
  108. package/packages/api-gateway/dist/marketplace-entries/official/agent-teams.json +16 -0
  109. package/packages/api-gateway/dist/marketplace-entries/official/anchored-standard.json +16 -0
  110. package/packages/api-gateway/dist/marketplace-entries/official/annotation.json +16 -0
  111. package/packages/api-gateway/dist/marketplace-entries/official/archify.json +16 -0
  112. package/packages/api-gateway/dist/marketplace-entries/official/at-file.json +16 -0
  113. package/packages/api-gateway/dist/marketplace-entries/official/auto-mode.json +25 -0
  114. package/packages/api-gateway/dist/marketplace-entries/official/better-sidebar.json +16 -0
  115. package/packages/api-gateway/dist/marketplace-entries/official/browser-fetch.json +16 -0
  116. package/packages/api-gateway/dist/marketplace-entries/official/browser-session.json +16 -0
  117. package/packages/api-gateway/dist/marketplace-entries/official/canvas-draw.json +16 -0
  118. package/packages/api-gateway/dist/marketplace-entries/official/change-verifier.json +16 -0
  119. package/packages/api-gateway/dist/marketplace-entries/official/cleaner.json +16 -0
  120. package/packages/api-gateway/dist/marketplace-entries/official/cli-notifier.json +16 -0
  121. package/packages/api-gateway/dist/marketplace-entries/official/code2skill.json +16 -0
  122. package/packages/api-gateway/dist/marketplace-entries/official/colleague-skill.json +16 -0
  123. package/packages/api-gateway/dist/marketplace-entries/official/context-doctor.json +22 -0
  124. package/packages/api-gateway/dist/marketplace-entries/official/context.json +16 -0
  125. package/packages/api-gateway/dist/marketplace-entries/official/cordis-group.json +16 -0
  126. package/packages/api-gateway/dist/marketplace-entries/official/cordis-logger-console.json +16 -0
  127. package/packages/api-gateway/dist/marketplace-entries/official/cordis-timer.json +16 -0
  128. package/packages/api-gateway/dist/marketplace-entries/official/cost-meter.json +16 -0
  129. package/packages/api-gateway/dist/marketplace-entries/official/dependency-checker.json +16 -0
  130. package/packages/api-gateway/dist/marketplace-entries/official/docker-sandbox.json +16 -0
  131. package/packages/api-gateway/dist/marketplace-entries/official/fail-logger.json +16 -0
  132. package/packages/api-gateway/dist/marketplace-entries/official/genui.json +16 -0
  133. package/packages/api-gateway/dist/marketplace-entries/official/git-time-capsule.json +16 -0
  134. package/packages/api-gateway/dist/marketplace-entries/official/graph-memory.json +16 -0
  135. package/packages/api-gateway/dist/marketplace-entries/official/history-compressor.json +25 -0
  136. package/packages/api-gateway/dist/marketplace-entries/official/hol-guard.json +16 -0
  137. package/packages/api-gateway/dist/marketplace-entries/official/i18n-pair.json +16 -0
  138. package/packages/api-gateway/dist/marketplace-entries/official/image-compressor.json +16 -0
  139. package/packages/api-gateway/dist/marketplace-entries/official/llm-verifier.json +16 -0
  140. package/packages/api-gateway/dist/marketplace-entries/official/mcp-client.json +16 -0
  141. package/packages/api-gateway/dist/marketplace-entries/official/mcp-panel.json +16 -0
  142. package/packages/api-gateway/dist/marketplace-entries/official/memory.json +16 -0
  143. package/packages/api-gateway/dist/marketplace-entries/official/mirage-bridge.json +19 -0
  144. package/packages/api-gateway/dist/marketplace-entries/official/mock-server.json +16 -0
  145. package/packages/api-gateway/dist/marketplace-entries/official/modlens.json +16 -0
  146. package/packages/api-gateway/dist/marketplace-entries/official/module-search.json +16 -0
  147. package/packages/api-gateway/dist/marketplace-entries/official/obsidian-sync.json +16 -0
  148. package/packages/api-gateway/dist/marketplace-entries/official/openpets.json +16 -0
  149. package/packages/api-gateway/dist/marketplace-entries/official/plan-execute.json +16 -0
  150. package/packages/api-gateway/dist/marketplace-entries/official/plugin-check.json +16 -0
  151. package/packages/api-gateway/dist/marketplace-entries/official/plugin-dev.json +16 -0
  152. package/packages/api-gateway/dist/marketplace-entries/official/plugin-finder.json +16 -0
  153. package/packages/api-gateway/dist/marketplace-entries/official/plugin-radar.json +16 -0
  154. package/packages/api-gateway/dist/marketplace-entries/official/plugin-stars.json +16 -0
  155. package/packages/api-gateway/dist/marketplace-entries/official/prompt-guard.json +16 -0
  156. package/packages/api-gateway/dist/marketplace-entries/official/prompt-library.json +16 -0
  157. package/packages/api-gateway/dist/marketplace-entries/official/readme-gen.json +16 -0
  158. package/packages/api-gateway/dist/marketplace-entries/official/recall-unread.json +16 -0
  159. package/packages/api-gateway/dist/marketplace-entries/official/reverse-skill.json +16 -0
  160. package/packages/api-gateway/dist/marketplace-entries/official/reviewer-bot.json +22 -0
  161. package/packages/api-gateway/dist/marketplace-entries/official/runtime-doctor.json +16 -0
  162. package/packages/api-gateway/dist/marketplace-entries/official/secure-audit.json +16 -0
  163. package/packages/api-gateway/dist/marketplace-entries/official/session-bookmarks.json +16 -0
  164. package/packages/api-gateway/dist/marketplace-entries/official/session-bridge.json +16 -0
  165. package/packages/api-gateway/dist/marketplace-entries/official/session-compare.json +16 -0
  166. package/packages/api-gateway/dist/marketplace-entries/official/session-export.json +16 -0
  167. package/packages/api-gateway/dist/marketplace-entries/official/session-insights.json +16 -0
  168. package/packages/api-gateway/dist/marketplace-entries/official/session-search.json +16 -0
  169. package/packages/api-gateway/dist/marketplace-entries/official/skill-catalog.json +16 -0
  170. package/packages/api-gateway/dist/marketplace-entries/official/skill-guard.json +16 -0
  171. package/packages/api-gateway/dist/marketplace-entries/official/sql-lens.json +16 -0
  172. package/packages/api-gateway/dist/marketplace-entries/official/synapse.json +16 -0
  173. package/packages/api-gateway/dist/marketplace-entries/official/tab-manager.json +16 -0
  174. package/packages/api-gateway/dist/marketplace-entries/official/taskboard.json +16 -0
  175. package/packages/api-gateway/dist/marketplace-entries/official/telemetry-blocker.json +16 -0
  176. package/packages/api-gateway/dist/marketplace-entries/official/test-harness.json +16 -0
  177. package/packages/api-gateway/dist/marketplace-entries/official/theme-studio.json +19 -0
  178. package/packages/api-gateway/dist/marketplace-entries/official/token-guard.json +16 -0
  179. package/packages/api-gateway/dist/marketplace-entries/official/turn-rewind.json +22 -0
  180. package/packages/api-gateway/dist/marketplace-entries/official/undo-savepoint.json +16 -0
  181. package/packages/api-gateway/dist/marketplace-entries/official/vision-toolkit.json +16 -0
  182. package/packages/api-gateway/dist/marketplace-entries/official/web-research.json +16 -0
  183. package/packages/api-gateway/dist/marketplace-entries/official/workspace-navigator.json +16 -0
  184. package/packages/api-gateway/dist/marketplace-entries/official/workspace-search.json +16 -0
  185. package/packages/api-gateway/dist/marketplace-entries/official/yaml-validator.json +16 -0
  186. package/packages/api-gateway/dist/marketplace.d.ts +60 -0
  187. package/packages/api-gateway/dist/marketplace.d.ts.map +1 -0
  188. package/packages/api-gateway/dist/marketplace.js +235 -0
  189. package/packages/api-gateway/dist/marketplace.js.map +1 -0
  190. package/packages/api-gateway/dist/workspaces.d.ts +8 -0
  191. package/packages/api-gateway/dist/workspaces.d.ts.map +1 -0
  192. package/packages/api-gateway/dist/workspaces.js +14 -0
  193. package/packages/api-gateway/dist/workspaces.js.map +1 -0
  194. package/packages/api-gateway/package.json +20 -10
  195. package/packages/api-gateway/scripts/copy-marketplace-entries.mjs +13 -0
  196. package/packages/api-gateway/src/index.ts +1272 -56
  197. package/packages/api-gateway/src/marketplace-entries/official/agent-teams.json +16 -0
  198. package/packages/api-gateway/src/marketplace-entries/official/anchored-standard.json +16 -0
  199. package/packages/api-gateway/src/marketplace-entries/official/annotation.json +16 -0
  200. package/packages/api-gateway/src/marketplace-entries/official/archify.json +16 -0
  201. package/packages/api-gateway/src/marketplace-entries/official/at-file.json +16 -0
  202. package/packages/api-gateway/src/marketplace-entries/official/auto-mode.json +25 -0
  203. package/packages/api-gateway/src/marketplace-entries/official/better-sidebar.json +16 -0
  204. package/packages/api-gateway/src/marketplace-entries/official/browser-fetch.json +16 -0
  205. package/packages/api-gateway/src/marketplace-entries/official/browser-session.json +16 -0
  206. package/packages/api-gateway/src/marketplace-entries/official/canvas-draw.json +16 -0
  207. package/packages/api-gateway/src/marketplace-entries/official/change-verifier.json +16 -0
  208. package/packages/api-gateway/src/marketplace-entries/official/cleaner.json +16 -0
  209. package/packages/api-gateway/src/marketplace-entries/official/cli-notifier.json +16 -0
  210. package/packages/api-gateway/src/marketplace-entries/official/code2skill.json +16 -0
  211. package/packages/api-gateway/src/marketplace-entries/official/colleague-skill.json +16 -0
  212. package/packages/api-gateway/src/marketplace-entries/official/context-doctor.json +22 -0
  213. package/packages/api-gateway/src/marketplace-entries/official/context.json +16 -0
  214. package/packages/api-gateway/src/marketplace-entries/official/cordis-group.json +16 -0
  215. package/packages/api-gateway/src/marketplace-entries/official/cordis-logger-console.json +16 -0
  216. package/packages/api-gateway/src/marketplace-entries/official/cordis-timer.json +16 -0
  217. package/packages/api-gateway/src/marketplace-entries/official/cost-meter.json +16 -0
  218. package/packages/api-gateway/src/marketplace-entries/official/dependency-checker.json +16 -0
  219. package/packages/api-gateway/src/marketplace-entries/official/docker-sandbox.json +16 -0
  220. package/packages/api-gateway/src/marketplace-entries/official/fail-logger.json +16 -0
  221. package/packages/api-gateway/src/marketplace-entries/official/genui.json +16 -0
  222. package/packages/api-gateway/src/marketplace-entries/official/git-time-capsule.json +16 -0
  223. package/packages/api-gateway/src/marketplace-entries/official/graph-memory.json +16 -0
  224. package/packages/api-gateway/src/marketplace-entries/official/history-compressor.json +25 -0
  225. package/packages/api-gateway/src/marketplace-entries/official/hol-guard.json +16 -0
  226. package/packages/api-gateway/src/marketplace-entries/official/i18n-pair.json +16 -0
  227. package/packages/api-gateway/src/marketplace-entries/official/image-compressor.json +16 -0
  228. package/packages/api-gateway/src/marketplace-entries/official/llm-verifier.json +16 -0
  229. package/packages/api-gateway/src/marketplace-entries/official/mcp-client.json +16 -0
  230. package/packages/api-gateway/src/marketplace-entries/official/mcp-panel.json +16 -0
  231. package/packages/api-gateway/src/marketplace-entries/official/memory.json +16 -0
  232. package/packages/api-gateway/src/marketplace-entries/official/mirage-bridge.json +19 -0
  233. package/packages/api-gateway/src/marketplace-entries/official/mock-server.json +16 -0
  234. package/packages/api-gateway/src/marketplace-entries/official/modlens.json +16 -0
  235. package/packages/api-gateway/src/marketplace-entries/official/module-search.json +16 -0
  236. package/packages/api-gateway/src/marketplace-entries/official/obsidian-sync.json +16 -0
  237. package/packages/api-gateway/src/marketplace-entries/official/openpets.json +16 -0
  238. package/packages/api-gateway/src/marketplace-entries/official/plan-execute.json +16 -0
  239. package/packages/api-gateway/src/marketplace-entries/official/plugin-check.json +16 -0
  240. package/packages/api-gateway/src/marketplace-entries/official/plugin-dev.json +16 -0
  241. package/packages/api-gateway/src/marketplace-entries/official/plugin-finder.json +16 -0
  242. package/packages/api-gateway/src/marketplace-entries/official/plugin-radar.json +16 -0
  243. package/packages/api-gateway/src/marketplace-entries/official/plugin-stars.json +16 -0
  244. package/packages/api-gateway/src/marketplace-entries/official/prompt-guard.json +16 -0
  245. package/packages/api-gateway/src/marketplace-entries/official/prompt-library.json +16 -0
  246. package/packages/api-gateway/src/marketplace-entries/official/readme-gen.json +16 -0
  247. package/packages/api-gateway/src/marketplace-entries/official/recall-unread.json +16 -0
  248. package/packages/api-gateway/src/marketplace-entries/official/reverse-skill.json +16 -0
  249. package/packages/api-gateway/src/marketplace-entries/official/reviewer-bot.json +22 -0
  250. package/packages/api-gateway/src/marketplace-entries/official/runtime-doctor.json +16 -0
  251. package/packages/api-gateway/src/marketplace-entries/official/secure-audit.json +16 -0
  252. package/packages/api-gateway/src/marketplace-entries/official/session-bookmarks.json +16 -0
  253. package/packages/api-gateway/src/marketplace-entries/official/session-bridge.json +16 -0
  254. package/packages/api-gateway/src/marketplace-entries/official/session-compare.json +16 -0
  255. package/packages/api-gateway/src/marketplace-entries/official/session-export.json +16 -0
  256. package/packages/api-gateway/src/marketplace-entries/official/session-insights.json +16 -0
  257. package/packages/api-gateway/src/marketplace-entries/official/session-search.json +16 -0
  258. package/packages/api-gateway/src/marketplace-entries/official/skill-catalog.json +16 -0
  259. package/packages/api-gateway/src/marketplace-entries/official/skill-guard.json +16 -0
  260. package/packages/api-gateway/src/marketplace-entries/official/sql-lens.json +16 -0
  261. package/packages/api-gateway/src/marketplace-entries/official/synapse.json +16 -0
  262. package/packages/api-gateway/src/marketplace-entries/official/tab-manager.json +16 -0
  263. package/packages/api-gateway/src/marketplace-entries/official/taskboard.json +16 -0
  264. package/packages/api-gateway/src/marketplace-entries/official/telemetry-blocker.json +16 -0
  265. package/packages/api-gateway/src/marketplace-entries/official/test-harness.json +16 -0
  266. package/packages/api-gateway/src/marketplace-entries/official/theme-studio.json +19 -0
  267. package/packages/api-gateway/src/marketplace-entries/official/token-guard.json +16 -0
  268. package/packages/api-gateway/src/marketplace-entries/official/turn-rewind.json +22 -0
  269. package/packages/api-gateway/src/marketplace-entries/official/undo-savepoint.json +16 -0
  270. package/packages/api-gateway/src/marketplace-entries/official/vision-toolkit.json +16 -0
  271. package/packages/api-gateway/src/marketplace-entries/official/web-research.json +16 -0
  272. package/packages/api-gateway/src/marketplace-entries/official/workspace-navigator.json +16 -0
  273. package/packages/api-gateway/src/marketplace-entries/official/workspace-search.json +16 -0
  274. package/packages/api-gateway/src/marketplace-entries/official/yaml-validator.json +16 -0
  275. package/packages/api-gateway/src/marketplace.ts +293 -0
  276. package/packages/api-gateway/src/workspaces.ts +20 -0
  277. package/packages/api-gateway/test/index.test.ts +501 -31
  278. package/packages/api-gateway/test/marketplace.test.ts +296 -0
  279. package/packages/api-gateway/test/workspaces.test.ts +13 -0
  280. package/packages/api-gateway/tsconfig.build.json +1 -1
  281. package/packages/api-gateway/tsconfig.json +1 -1
  282. package/packages/bundle-web-app/LICENSE +9 -0
  283. package/packages/bundle-web-app/package.json +19 -9
  284. package/packages/bundle-web-app/tsconfig.build.json +1 -1
  285. package/packages/bundle-web-app/tsconfig.json +1 -1
  286. package/packages/cli/LICENSE +9 -0
  287. package/packages/cli/dist/args.d.ts.map +1 -1
  288. package/packages/cli/dist/args.js +16 -9
  289. package/packages/cli/dist/args.js.map +1 -1
  290. package/packages/cli/dist/bin.js +12 -3
  291. package/packages/cli/dist/bin.js.map +1 -1
  292. package/packages/cli/dist/main.d.ts +1 -0
  293. package/packages/cli/dist/main.d.ts.map +1 -1
  294. package/packages/cli/dist/main.js +49 -9
  295. package/packages/cli/dist/main.js.map +1 -1
  296. package/packages/cli/dist/node-stdio.d.ts +3 -1
  297. package/packages/cli/dist/node-stdio.d.ts.map +1 -1
  298. package/packages/cli/dist/node-stdio.js +91 -13
  299. package/packages/cli/dist/node-stdio.js.map +1 -1
  300. package/packages/cli/dist/relaunch.d.ts.map +1 -1
  301. package/packages/cli/dist/relaunch.js +23 -10
  302. package/packages/cli/dist/relaunch.js.map +1 -1
  303. package/packages/cli/package.json +18 -8
  304. package/packages/cli/src/args.ts +16 -10
  305. package/packages/cli/src/bin.ts +12 -3
  306. package/packages/cli/src/main.ts +54 -10
  307. package/packages/cli/src/node-stdio.ts +85 -13
  308. package/packages/cli/src/relaunch.ts +19 -6
  309. package/packages/cli/test/args.test.ts +22 -3
  310. package/packages/cli/test/binary.test.ts +58 -0
  311. package/packages/cli/test/broken-pipe.test.ts +32 -0
  312. package/packages/cli/test/cli.test.ts +57 -8
  313. package/packages/cli/test/node-stdio.test.ts +89 -0
  314. package/packages/cli/test/relaunch.test.ts +30 -2
  315. package/packages/cli/test/stdin-shutdown.test.ts +59 -0
  316. package/packages/cli/tsconfig.build.json +1 -3
  317. package/packages/cli/tsconfig.json +1 -4
  318. package/packages/client-web/LICENSE +9 -0
  319. package/packages/client-web/dist/annotation-ui.d.ts +11 -0
  320. package/packages/client-web/dist/annotation-ui.d.ts.map +1 -0
  321. package/packages/client-web/dist/annotation-ui.js +24 -0
  322. package/packages/client-web/dist/annotation-ui.js.map +1 -0
  323. package/packages/client-web/dist/browser-session-view.d.ts +7 -0
  324. package/packages/client-web/dist/browser-session-view.d.ts.map +1 -0
  325. package/packages/client-web/dist/browser-session-view.js +8 -0
  326. package/packages/client-web/dist/browser-session-view.js.map +1 -0
  327. package/packages/client-web/dist/control-room.d.ts +169 -2
  328. package/packages/client-web/dist/control-room.d.ts.map +1 -1
  329. package/packages/client-web/dist/control-room.js +156 -11
  330. package/packages/client-web/dist/control-room.js.map +1 -1
  331. package/packages/client-web/dist/design-contract.d.ts.map +1 -1
  332. package/packages/client-web/dist/design-contract.js +178 -19
  333. package/packages/client-web/dist/design-contract.js.map +1 -1
  334. package/packages/client-web/dist/index.d.ts +4 -1
  335. package/packages/client-web/dist/index.d.ts.map +1 -1
  336. package/packages/client-web/dist/index.js +11 -3
  337. package/packages/client-web/dist/index.js.map +1 -1
  338. package/packages/client-web/dist/markdown.d.ts +5 -0
  339. package/packages/client-web/dist/markdown.d.ts.map +1 -0
  340. package/packages/client-web/dist/markdown.js +20 -0
  341. package/packages/client-web/dist/markdown.js.map +1 -0
  342. package/packages/client-web/dist/marketplace-catalog.d.ts +3 -0
  343. package/packages/client-web/dist/marketplace-catalog.d.ts.map +1 -0
  344. package/packages/client-web/dist/marketplace-catalog.js +10 -0
  345. package/packages/client-web/dist/marketplace-catalog.js.map +1 -0
  346. package/packages/client-web/dist/marketplace-navigation.d.ts +19 -0
  347. package/packages/client-web/dist/marketplace-navigation.d.ts.map +1 -0
  348. package/packages/client-web/dist/marketplace-navigation.js +31 -0
  349. package/packages/client-web/dist/marketplace-navigation.js.map +1 -0
  350. package/packages/client-web/dist/message-content.d.ts +9 -0
  351. package/packages/client-web/dist/message-content.d.ts.map +1 -0
  352. package/packages/client-web/dist/message-content.js +54 -0
  353. package/packages/client-web/dist/message-content.js.map +1 -0
  354. package/packages/client-web/dist/plugin-navigation.d.ts +3 -0
  355. package/packages/client-web/dist/plugin-navigation.d.ts.map +1 -0
  356. package/packages/client-web/dist/plugin-navigation.js +10 -0
  357. package/packages/client-web/dist/plugin-navigation.js.map +1 -0
  358. package/packages/client-web/dist/plugin-search.d.ts +2 -0
  359. package/packages/client-web/dist/plugin-search.d.ts.map +1 -0
  360. package/packages/client-web/dist/plugin-search.js +7 -0
  361. package/packages/client-web/dist/plugin-search.js.map +1 -0
  362. package/packages/client-web/dist/plugin-stars-view.d.ts +12 -0
  363. package/packages/client-web/dist/plugin-stars-view.d.ts.map +1 -0
  364. package/packages/client-web/dist/plugin-stars-view.js +8 -0
  365. package/packages/client-web/dist/plugin-stars-view.js.map +1 -0
  366. package/packages/client-web/dist/prompt-completion.d.ts +13 -0
  367. package/packages/client-web/dist/prompt-completion.d.ts.map +1 -0
  368. package/packages/client-web/dist/prompt-completion.js +17 -0
  369. package/packages/client-web/dist/prompt-completion.js.map +1 -0
  370. package/packages/client-web/dist/react-room.d.ts +2 -1
  371. package/packages/client-web/dist/react-room.d.ts.map +1 -1
  372. package/packages/client-web/dist/react-room.js +2349 -84
  373. package/packages/client-web/dist/react-room.js.map +1 -1
  374. package/packages/client-web/dist/runtime-events.d.ts +4 -0
  375. package/packages/client-web/dist/runtime-events.d.ts.map +1 -0
  376. package/packages/client-web/dist/runtime-events.js +29 -0
  377. package/packages/client-web/dist/runtime-events.js.map +1 -0
  378. package/packages/client-web/package.json +19 -7
  379. package/packages/client-web/src/annotation-ui.ts +29 -0
  380. package/packages/client-web/src/browser-session-view.ts +13 -0
  381. package/packages/client-web/src/control-room.ts +359 -10
  382. package/packages/client-web/src/design-contract.ts +248 -26
  383. package/packages/client-web/src/index.ts +17 -4
  384. package/packages/client-web/src/markdown.tsx +22 -0
  385. package/packages/client-web/src/marketplace-catalog.ts +10 -0
  386. package/packages/client-web/src/marketplace-navigation.ts +46 -0
  387. package/packages/client-web/src/message-content.ts +51 -0
  388. package/packages/client-web/src/plugin-navigation.ts +9 -0
  389. package/packages/client-web/src/plugin-search.ts +5 -0
  390. package/packages/client-web/src/plugin-stars-view.ts +19 -0
  391. package/packages/client-web/src/prompt-completion.ts +24 -0
  392. package/packages/client-web/src/react-room.tsx +7365 -49
  393. package/packages/client-web/src/runtime-events.ts +29 -0
  394. package/packages/client-web/test/annotation-ui.test.ts +21 -0
  395. package/packages/client-web/test/browser-session-view.test.ts +17 -0
  396. package/packages/client-web/test/design-contract.test.ts +46 -1
  397. package/packages/client-web/test/marketplace-catalog.test.ts +52 -0
  398. package/packages/client-web/test/message-content.test.ts +43 -0
  399. package/packages/client-web/test/plugin-navigation.test.ts +16 -0
  400. package/packages/client-web/test/plugin-search.test.ts +22 -0
  401. package/packages/client-web/test/plugin-stars-view.test.ts +20 -0
  402. package/packages/client-web/test/prompt-completion.test.ts +21 -0
  403. package/packages/client-web/test/runtime-events.test.ts +28 -0
  404. package/packages/client-web/tsconfig.build.json +13 -1
  405. package/packages/client-web/tsconfig.json +11 -1
  406. package/packages/core/LICENSE +9 -0
  407. package/packages/core/dist/boot.d.ts.map +1 -1
  408. package/packages/core/dist/boot.js +42 -3
  409. package/packages/core/dist/boot.js.map +1 -1
  410. package/packages/core/dist/config.d.ts +2 -0
  411. package/packages/core/dist/config.d.ts.map +1 -0
  412. package/packages/core/dist/config.js +8 -0
  413. package/packages/core/dist/config.js.map +1 -0
  414. package/packages/core/dist/http.d.ts +8 -0
  415. package/packages/core/dist/http.d.ts.map +1 -0
  416. package/packages/core/dist/http.js +27 -0
  417. package/packages/core/dist/http.js.map +1 -0
  418. package/packages/core/dist/index.d.ts +2 -0
  419. package/packages/core/dist/index.d.ts.map +1 -1
  420. package/packages/core/dist/index.js +2 -0
  421. package/packages/core/dist/index.js.map +1 -1
  422. package/packages/core/dist/plugins/agent-teams.d.ts +17 -0
  423. package/packages/core/dist/plugins/agent-teams.d.ts.map +1 -0
  424. package/packages/core/dist/plugins/agent-teams.js +298 -0
  425. package/packages/core/dist/plugins/agent-teams.js.map +1 -0
  426. package/packages/core/dist/plugins/anchored-standard.d.ts +14 -0
  427. package/packages/core/dist/plugins/anchored-standard.d.ts.map +1 -0
  428. package/packages/core/dist/plugins/anchored-standard.js +84 -0
  429. package/packages/core/dist/plugins/anchored-standard.js.map +1 -0
  430. package/packages/core/dist/plugins/annotation.d.ts +18 -0
  431. package/packages/core/dist/plugins/annotation.d.ts.map +1 -0
  432. package/packages/core/dist/plugins/annotation.js +94 -0
  433. package/packages/core/dist/plugins/annotation.js.map +1 -0
  434. package/packages/core/dist/plugins/archify.d.ts +23 -0
  435. package/packages/core/dist/plugins/archify.d.ts.map +1 -0
  436. package/packages/core/dist/plugins/archify.js +98 -0
  437. package/packages/core/dist/plugins/archify.js.map +1 -0
  438. package/packages/core/dist/plugins/at-file.d.ts +8 -0
  439. package/packages/core/dist/plugins/at-file.d.ts.map +1 -0
  440. package/packages/core/dist/plugins/at-file.js +52 -0
  441. package/packages/core/dist/plugins/at-file.js.map +1 -0
  442. package/packages/core/dist/plugins/auto-mode.d.ts +15 -0
  443. package/packages/core/dist/plugins/auto-mode.d.ts.map +1 -0
  444. package/packages/core/dist/plugins/auto-mode.js +114 -0
  445. package/packages/core/dist/plugins/auto-mode.js.map +1 -0
  446. package/packages/core/dist/plugins/better-sidebar.d.ts +37 -0
  447. package/packages/core/dist/plugins/better-sidebar.d.ts.map +1 -0
  448. package/packages/core/dist/plugins/better-sidebar.js +89 -0
  449. package/packages/core/dist/plugins/better-sidebar.js.map +1 -0
  450. package/packages/core/dist/plugins/browser-fetch.d.ts +14 -0
  451. package/packages/core/dist/plugins/browser-fetch.d.ts.map +1 -0
  452. package/packages/core/dist/plugins/browser-fetch.js +167 -0
  453. package/packages/core/dist/plugins/browser-fetch.js.map +1 -0
  454. package/packages/core/dist/plugins/browser-session.d.ts +14 -0
  455. package/packages/core/dist/plugins/browser-session.d.ts.map +1 -0
  456. package/packages/core/dist/plugins/browser-session.js +265 -0
  457. package/packages/core/dist/plugins/browser-session.js.map +1 -0
  458. package/packages/core/dist/plugins/canvas-draw.d.ts +8 -0
  459. package/packages/core/dist/plugins/canvas-draw.d.ts.map +1 -0
  460. package/packages/core/dist/plugins/canvas-draw.js +88 -0
  461. package/packages/core/dist/plugins/canvas-draw.js.map +1 -0
  462. package/packages/core/dist/plugins/change-verifier.d.ts +8 -0
  463. package/packages/core/dist/plugins/change-verifier.d.ts.map +1 -0
  464. package/packages/core/dist/plugins/change-verifier.js +67 -0
  465. package/packages/core/dist/plugins/change-verifier.js.map +1 -0
  466. package/packages/core/dist/plugins/cleaner.d.ts +8 -0
  467. package/packages/core/dist/plugins/cleaner.d.ts.map +1 -0
  468. package/packages/core/dist/plugins/cleaner.js +56 -0
  469. package/packages/core/dist/plugins/cleaner.js.map +1 -0
  470. package/packages/core/dist/plugins/cli-notifier.d.ts +15 -0
  471. package/packages/core/dist/plugins/cli-notifier.d.ts.map +1 -0
  472. package/packages/core/dist/plugins/cli-notifier.js +110 -0
  473. package/packages/core/dist/plugins/cli-notifier.js.map +1 -0
  474. package/packages/core/dist/plugins/code2skill.d.ts +8 -0
  475. package/packages/core/dist/plugins/code2skill.d.ts.map +1 -0
  476. package/packages/core/dist/plugins/code2skill.js +95 -0
  477. package/packages/core/dist/plugins/code2skill.js.map +1 -0
  478. package/packages/core/dist/plugins/colleague-skill.d.ts +27 -0
  479. package/packages/core/dist/plugins/colleague-skill.d.ts.map +1 -0
  480. package/packages/core/dist/plugins/colleague-skill.js +99 -0
  481. package/packages/core/dist/plugins/colleague-skill.js.map +1 -0
  482. package/packages/core/dist/plugins/context-doctor.d.ts +30 -0
  483. package/packages/core/dist/plugins/context-doctor.d.ts.map +1 -0
  484. package/packages/core/dist/plugins/context-doctor.js +95 -0
  485. package/packages/core/dist/plugins/context-doctor.js.map +1 -0
  486. package/packages/core/dist/plugins/context.d.ts +8 -0
  487. package/packages/core/dist/plugins/context.d.ts.map +1 -0
  488. package/packages/core/dist/plugins/context.js +87 -0
  489. package/packages/core/dist/plugins/context.js.map +1 -0
  490. package/packages/core/dist/plugins/cost-meter.d.ts +32 -0
  491. package/packages/core/dist/plugins/cost-meter.d.ts.map +1 -0
  492. package/packages/core/dist/plugins/cost-meter.js +204 -0
  493. package/packages/core/dist/plugins/cost-meter.js.map +1 -0
  494. package/packages/core/dist/plugins/dependency-checker.d.ts +27 -0
  495. package/packages/core/dist/plugins/dependency-checker.d.ts.map +1 -0
  496. package/packages/core/dist/plugins/dependency-checker.js +221 -0
  497. package/packages/core/dist/plugins/dependency-checker.js.map +1 -0
  498. package/packages/core/dist/plugins/docker-sandbox.d.ts +8 -0
  499. package/packages/core/dist/plugins/docker-sandbox.d.ts.map +1 -0
  500. package/packages/core/dist/plugins/docker-sandbox.js +102 -0
  501. package/packages/core/dist/plugins/docker-sandbox.js.map +1 -0
  502. package/packages/core/dist/plugins/fail-logger.d.ts +8 -0
  503. package/packages/core/dist/plugins/fail-logger.d.ts.map +1 -0
  504. package/packages/core/dist/plugins/fail-logger.js +51 -0
  505. package/packages/core/dist/plugins/fail-logger.js.map +1 -0
  506. package/packages/core/dist/plugins/genui.d.ts +8 -0
  507. package/packages/core/dist/plugins/genui.d.ts.map +1 -0
  508. package/packages/core/dist/plugins/genui.js +79 -0
  509. package/packages/core/dist/plugins/genui.js.map +1 -0
  510. package/packages/core/dist/plugins/git-time-capsule.d.ts +9 -0
  511. package/packages/core/dist/plugins/git-time-capsule.d.ts.map +1 -0
  512. package/packages/core/dist/plugins/git-time-capsule.js +90 -0
  513. package/packages/core/dist/plugins/git-time-capsule.js.map +1 -0
  514. package/packages/core/dist/plugins/graph-memory.d.ts +16 -0
  515. package/packages/core/dist/plugins/graph-memory.d.ts.map +1 -0
  516. package/packages/core/dist/plugins/graph-memory.js +382 -0
  517. package/packages/core/dist/plugins/graph-memory.js.map +1 -0
  518. package/packages/core/dist/plugins/history-compressor.d.ts +15 -0
  519. package/packages/core/dist/plugins/history-compressor.d.ts.map +1 -0
  520. package/packages/core/dist/plugins/history-compressor.js +80 -0
  521. package/packages/core/dist/plugins/history-compressor.js.map +1 -0
  522. package/packages/core/dist/plugins/hol-guard.d.ts +29 -0
  523. package/packages/core/dist/plugins/hol-guard.d.ts.map +1 -0
  524. package/packages/core/dist/plugins/hol-guard.js +139 -0
  525. package/packages/core/dist/plugins/hol-guard.js.map +1 -0
  526. package/packages/core/dist/plugins/i18n-pair.d.ts +8 -0
  527. package/packages/core/dist/plugins/i18n-pair.d.ts.map +1 -0
  528. package/packages/core/dist/plugins/i18n-pair.js +76 -0
  529. package/packages/core/dist/plugins/i18n-pair.js.map +1 -0
  530. package/packages/core/dist/plugins/image-compressor.d.ts +8 -0
  531. package/packages/core/dist/plugins/image-compressor.d.ts.map +1 -0
  532. package/packages/core/dist/plugins/image-compressor.js +150 -0
  533. package/packages/core/dist/plugins/image-compressor.js.map +1 -0
  534. package/packages/core/dist/plugins/llm-verifier.d.ts +42 -0
  535. package/packages/core/dist/plugins/llm-verifier.d.ts.map +1 -0
  536. package/packages/core/dist/plugins/llm-verifier.js +128 -0
  537. package/packages/core/dist/plugins/llm-verifier.js.map +1 -0
  538. package/packages/core/dist/plugins/mcp-client.d.ts +19 -0
  539. package/packages/core/dist/plugins/mcp-client.d.ts.map +1 -0
  540. package/packages/core/dist/plugins/mcp-client.js +534 -0
  541. package/packages/core/dist/plugins/mcp-client.js.map +1 -0
  542. package/packages/core/dist/plugins/mcp-panel.d.ts +14 -0
  543. package/packages/core/dist/plugins/mcp-panel.d.ts.map +1 -0
  544. package/packages/core/dist/plugins/mcp-panel.js +180 -0
  545. package/packages/core/dist/plugins/mcp-panel.js.map +1 -0
  546. package/packages/core/dist/plugins/memory.d.ts +15 -0
  547. package/packages/core/dist/plugins/memory.d.ts.map +1 -0
  548. package/packages/core/dist/plugins/memory.js +161 -0
  549. package/packages/core/dist/plugins/memory.js.map +1 -0
  550. package/packages/core/dist/plugins/mirage-bridge.d.ts +23 -0
  551. package/packages/core/dist/plugins/mirage-bridge.d.ts.map +1 -0
  552. package/packages/core/dist/plugins/mirage-bridge.js +149 -0
  553. package/packages/core/dist/plugins/mirage-bridge.js.map +1 -0
  554. package/packages/core/dist/plugins/mock-server.d.ts +22 -0
  555. package/packages/core/dist/plugins/mock-server.d.ts.map +1 -0
  556. package/packages/core/dist/plugins/mock-server.js +149 -0
  557. package/packages/core/dist/plugins/mock-server.js.map +1 -0
  558. package/packages/core/dist/plugins/model.d.ts +1 -1
  559. package/packages/core/dist/plugins/model.d.ts.map +1 -1
  560. package/packages/core/dist/plugins/model.js +3 -1
  561. package/packages/core/dist/plugins/model.js.map +1 -1
  562. package/packages/core/dist/plugins/models.d.ts.map +1 -1
  563. package/packages/core/dist/plugins/models.js +5 -2
  564. package/packages/core/dist/plugins/models.js.map +1 -1
  565. package/packages/core/dist/plugins/modlens.d.ts +8 -0
  566. package/packages/core/dist/plugins/modlens.d.ts.map +1 -0
  567. package/packages/core/dist/plugins/modlens.js +63 -0
  568. package/packages/core/dist/plugins/modlens.js.map +1 -0
  569. package/packages/core/dist/plugins/module-search.d.ts +27 -0
  570. package/packages/core/dist/plugins/module-search.d.ts.map +1 -0
  571. package/packages/core/dist/plugins/module-search.js +174 -0
  572. package/packages/core/dist/plugins/module-search.js.map +1 -0
  573. package/packages/core/dist/plugins/obsidian-sync.d.ts +14 -0
  574. package/packages/core/dist/plugins/obsidian-sync.d.ts.map +1 -0
  575. package/packages/core/dist/plugins/obsidian-sync.js +79 -0
  576. package/packages/core/dist/plugins/obsidian-sync.js.map +1 -0
  577. package/packages/core/dist/plugins/openpets.d.ts +14 -0
  578. package/packages/core/dist/plugins/openpets.d.ts.map +1 -0
  579. package/packages/core/dist/plugins/openpets.js +99 -0
  580. package/packages/core/dist/plugins/openpets.js.map +1 -0
  581. package/packages/core/dist/plugins/plan-execute.d.ts +8 -0
  582. package/packages/core/dist/plugins/plan-execute.d.ts.map +1 -0
  583. package/packages/core/dist/plugins/plan-execute.js +70 -0
  584. package/packages/core/dist/plugins/plan-execute.js.map +1 -0
  585. package/packages/core/dist/plugins/plugin-check.d.ts +38 -0
  586. package/packages/core/dist/plugins/plugin-check.d.ts.map +1 -0
  587. package/packages/core/dist/plugins/plugin-check.js +227 -0
  588. package/packages/core/dist/plugins/plugin-check.js.map +1 -0
  589. package/packages/core/dist/plugins/plugin-dev.d.ts +8 -0
  590. package/packages/core/dist/plugins/plugin-dev.d.ts.map +1 -0
  591. package/packages/core/dist/plugins/plugin-dev.js +44 -0
  592. package/packages/core/dist/plugins/plugin-dev.js.map +1 -0
  593. package/packages/core/dist/plugins/plugin-finder.d.ts +16 -0
  594. package/packages/core/dist/plugins/plugin-finder.d.ts.map +1 -0
  595. package/packages/core/dist/plugins/plugin-finder.js +98 -0
  596. package/packages/core/dist/plugins/plugin-finder.js.map +1 -0
  597. package/packages/core/dist/plugins/plugin-radar.d.ts +29 -0
  598. package/packages/core/dist/plugins/plugin-radar.d.ts.map +1 -0
  599. package/packages/core/dist/plugins/plugin-radar.js +146 -0
  600. package/packages/core/dist/plugins/plugin-radar.js.map +1 -0
  601. package/packages/core/dist/plugins/plugin-stars.d.ts +45 -0
  602. package/packages/core/dist/plugins/plugin-stars.d.ts.map +1 -0
  603. package/packages/core/dist/plugins/plugin-stars.js +165 -0
  604. package/packages/core/dist/plugins/plugin-stars.js.map +1 -0
  605. package/packages/core/dist/plugins/prompt-guard.d.ts +8 -0
  606. package/packages/core/dist/plugins/prompt-guard.d.ts.map +1 -0
  607. package/packages/core/dist/plugins/prompt-guard.js +114 -0
  608. package/packages/core/dist/plugins/prompt-guard.js.map +1 -0
  609. package/packages/core/dist/plugins/prompt-library.d.ts +25 -0
  610. package/packages/core/dist/plugins/prompt-library.d.ts.map +1 -0
  611. package/packages/core/dist/plugins/prompt-library.js +142 -0
  612. package/packages/core/dist/plugins/prompt-library.js.map +1 -0
  613. package/packages/core/dist/plugins/readme-gen.d.ts +25 -0
  614. package/packages/core/dist/plugins/readme-gen.d.ts.map +1 -0
  615. package/packages/core/dist/plugins/readme-gen.js +139 -0
  616. package/packages/core/dist/plugins/readme-gen.js.map +1 -0
  617. package/packages/core/dist/plugins/recall-unread.d.ts +24 -0
  618. package/packages/core/dist/plugins/recall-unread.d.ts.map +1 -0
  619. package/packages/core/dist/plugins/recall-unread.js +124 -0
  620. package/packages/core/dist/plugins/recall-unread.js.map +1 -0
  621. package/packages/core/dist/plugins/resources.d.ts +1 -0
  622. package/packages/core/dist/plugins/resources.d.ts.map +1 -1
  623. package/packages/core/dist/plugins/resources.js +31 -22
  624. package/packages/core/dist/plugins/resources.js.map +1 -1
  625. package/packages/core/dist/plugins/reverse-skill.d.ts +23 -0
  626. package/packages/core/dist/plugins/reverse-skill.d.ts.map +1 -0
  627. package/packages/core/dist/plugins/reverse-skill.js +60 -0
  628. package/packages/core/dist/plugins/reverse-skill.js.map +1 -0
  629. package/packages/core/dist/plugins/reviewer-bot.d.ts +14 -0
  630. package/packages/core/dist/plugins/reviewer-bot.d.ts.map +1 -0
  631. package/packages/core/dist/plugins/reviewer-bot.js +133 -0
  632. package/packages/core/dist/plugins/reviewer-bot.js.map +1 -0
  633. package/packages/core/dist/plugins/runtime-doctor.d.ts +33 -0
  634. package/packages/core/dist/plugins/runtime-doctor.d.ts.map +1 -0
  635. package/packages/core/dist/plugins/runtime-doctor.js +114 -0
  636. package/packages/core/dist/plugins/runtime-doctor.js.map +1 -0
  637. package/packages/core/dist/plugins/runtime.d.ts.map +1 -1
  638. package/packages/core/dist/plugins/runtime.js +63 -14
  639. package/packages/core/dist/plugins/runtime.js.map +1 -1
  640. package/packages/core/dist/plugins/secure-audit.d.ts +31 -0
  641. package/packages/core/dist/plugins/secure-audit.d.ts.map +1 -0
  642. package/packages/core/dist/plugins/secure-audit.js +121 -0
  643. package/packages/core/dist/plugins/secure-audit.js.map +1 -0
  644. package/packages/core/dist/plugins/session-bookmarks.d.ts +15 -0
  645. package/packages/core/dist/plugins/session-bookmarks.d.ts.map +1 -0
  646. package/packages/core/dist/plugins/session-bookmarks.js +87 -0
  647. package/packages/core/dist/plugins/session-bookmarks.js.map +1 -0
  648. package/packages/core/dist/plugins/session-bridge.d.ts +44 -0
  649. package/packages/core/dist/plugins/session-bridge.d.ts.map +1 -0
  650. package/packages/core/dist/plugins/session-bridge.js +265 -0
  651. package/packages/core/dist/plugins/session-bridge.js.map +1 -0
  652. package/packages/core/dist/plugins/session-compare.d.ts +33 -0
  653. package/packages/core/dist/plugins/session-compare.d.ts.map +1 -0
  654. package/packages/core/dist/plugins/session-compare.js +150 -0
  655. package/packages/core/dist/plugins/session-compare.js.map +1 -0
  656. package/packages/core/dist/plugins/session-export.d.ts +9 -0
  657. package/packages/core/dist/plugins/session-export.d.ts.map +1 -0
  658. package/packages/core/dist/plugins/session-export.js +93 -0
  659. package/packages/core/dist/plugins/session-export.js.map +1 -0
  660. package/packages/core/dist/plugins/session-insights.d.ts +8 -0
  661. package/packages/core/dist/plugins/session-insights.d.ts.map +1 -0
  662. package/packages/core/dist/plugins/session-insights.js +47 -0
  663. package/packages/core/dist/plugins/session-insights.js.map +1 -0
  664. package/packages/core/dist/plugins/session-search.d.ts +20 -0
  665. package/packages/core/dist/plugins/session-search.d.ts.map +1 -0
  666. package/packages/core/dist/plugins/session-search.js +122 -0
  667. package/packages/core/dist/plugins/session-search.js.map +1 -0
  668. package/packages/core/dist/plugins/session.d.ts.map +1 -1
  669. package/packages/core/dist/plugins/session.js +4 -2
  670. package/packages/core/dist/plugins/session.js.map +1 -1
  671. package/packages/core/dist/plugins/skill-catalog.d.ts +26 -0
  672. package/packages/core/dist/plugins/skill-catalog.d.ts.map +1 -0
  673. package/packages/core/dist/plugins/skill-catalog.js +97 -0
  674. package/packages/core/dist/plugins/skill-catalog.js.map +1 -0
  675. package/packages/core/dist/plugins/skill-guard.d.ts +26 -0
  676. package/packages/core/dist/plugins/skill-guard.d.ts.map +1 -0
  677. package/packages/core/dist/plugins/skill-guard.js +139 -0
  678. package/packages/core/dist/plugins/skill-guard.js.map +1 -0
  679. package/packages/core/dist/plugins/sql-lens.d.ts +8 -0
  680. package/packages/core/dist/plugins/sql-lens.d.ts.map +1 -0
  681. package/packages/core/dist/plugins/sql-lens.js +85 -0
  682. package/packages/core/dist/plugins/sql-lens.js.map +1 -0
  683. package/packages/core/dist/plugins/stdio.d.ts +1 -1
  684. package/packages/core/dist/plugins/stdio.d.ts.map +1 -1
  685. package/packages/core/dist/plugins/stdio.js +3 -1
  686. package/packages/core/dist/plugins/stdio.js.map +1 -1
  687. package/packages/core/dist/plugins/synapse.d.ts +38 -0
  688. package/packages/core/dist/plugins/synapse.d.ts.map +1 -0
  689. package/packages/core/dist/plugins/synapse.js +93 -0
  690. package/packages/core/dist/plugins/synapse.js.map +1 -0
  691. package/packages/core/dist/plugins/tab-manager.d.ts +8 -0
  692. package/packages/core/dist/plugins/tab-manager.d.ts.map +1 -0
  693. package/packages/core/dist/plugins/tab-manager.js +135 -0
  694. package/packages/core/dist/plugins/tab-manager.js.map +1 -0
  695. package/packages/core/dist/plugins/taskboard.d.ts +15 -0
  696. package/packages/core/dist/plugins/taskboard.d.ts.map +1 -0
  697. package/packages/core/dist/plugins/taskboard.js +347 -0
  698. package/packages/core/dist/plugins/taskboard.js.map +1 -0
  699. package/packages/core/dist/plugins/telemetry-blocker.d.ts +8 -0
  700. package/packages/core/dist/plugins/telemetry-blocker.d.ts.map +1 -0
  701. package/packages/core/dist/plugins/telemetry-blocker.js +57 -0
  702. package/packages/core/dist/plugins/telemetry-blocker.js.map +1 -0
  703. package/packages/core/dist/plugins/test-harness.d.ts +8 -0
  704. package/packages/core/dist/plugins/test-harness.d.ts.map +1 -0
  705. package/packages/core/dist/plugins/test-harness.js +64 -0
  706. package/packages/core/dist/plugins/test-harness.js.map +1 -0
  707. package/packages/core/dist/plugins/theme-studio.d.ts +29 -0
  708. package/packages/core/dist/plugins/theme-studio.d.ts.map +1 -0
  709. package/packages/core/dist/plugins/theme-studio.js +141 -0
  710. package/packages/core/dist/plugins/theme-studio.js.map +1 -0
  711. package/packages/core/dist/plugins/token-guard.d.ts +15 -0
  712. package/packages/core/dist/plugins/token-guard.d.ts.map +1 -0
  713. package/packages/core/dist/plugins/token-guard.js +78 -0
  714. package/packages/core/dist/plugins/token-guard.js.map +1 -0
  715. package/packages/core/dist/plugins/tools.d.ts.map +1 -1
  716. package/packages/core/dist/plugins/tools.js +5 -2
  717. package/packages/core/dist/plugins/tools.js.map +1 -1
  718. package/packages/core/dist/plugins/turn-rewind.d.ts +19 -0
  719. package/packages/core/dist/plugins/turn-rewind.d.ts.map +1 -0
  720. package/packages/core/dist/plugins/turn-rewind.js +74 -0
  721. package/packages/core/dist/plugins/turn-rewind.js.map +1 -0
  722. package/packages/core/dist/plugins/undo-savepoint.d.ts +17 -0
  723. package/packages/core/dist/plugins/undo-savepoint.d.ts.map +1 -0
  724. package/packages/core/dist/plugins/undo-savepoint.js +247 -0
  725. package/packages/core/dist/plugins/undo-savepoint.js.map +1 -0
  726. package/packages/core/dist/plugins/vision-toolkit.d.ts +17 -0
  727. package/packages/core/dist/plugins/vision-toolkit.d.ts.map +1 -0
  728. package/packages/core/dist/plugins/vision-toolkit.js +145 -0
  729. package/packages/core/dist/plugins/vision-toolkit.js.map +1 -0
  730. package/packages/core/dist/plugins/web-research.d.ts +17 -0
  731. package/packages/core/dist/plugins/web-research.d.ts.map +1 -0
  732. package/packages/core/dist/plugins/web-research.js +275 -0
  733. package/packages/core/dist/plugins/web-research.js.map +1 -0
  734. package/packages/core/dist/plugins/workspace-navigator.d.ts +36 -0
  735. package/packages/core/dist/plugins/workspace-navigator.d.ts.map +1 -0
  736. package/packages/core/dist/plugins/workspace-navigator.js +150 -0
  737. package/packages/core/dist/plugins/workspace-navigator.js.map +1 -0
  738. package/packages/core/dist/plugins/workspace-search.d.ts +8 -0
  739. package/packages/core/dist/plugins/workspace-search.d.ts.map +1 -0
  740. package/packages/core/dist/plugins/workspace-search.js +134 -0
  741. package/packages/core/dist/plugins/workspace-search.js.map +1 -0
  742. package/packages/core/dist/plugins/yaml-validator.d.ts +8 -0
  743. package/packages/core/dist/plugins/yaml-validator.d.ts.map +1 -0
  744. package/packages/core/dist/plugins/yaml-validator.js +94 -0
  745. package/packages/core/dist/plugins/yaml-validator.js.map +1 -0
  746. package/packages/core/dist/profile.d.ts +1 -0
  747. package/packages/core/dist/profile.d.ts.map +1 -1
  748. package/packages/core/dist/profile.js +3 -0
  749. package/packages/core/dist/profile.js.map +1 -1
  750. package/packages/core/dist/runtime.d.ts.map +1 -1
  751. package/packages/core/dist/runtime.js +13 -4
  752. package/packages/core/dist/runtime.js.map +1 -1
  753. package/packages/core/dist/services.d.ts +55 -0
  754. package/packages/core/dist/services.d.ts.map +1 -1
  755. package/packages/core/dist/services.js +58 -2
  756. package/packages/core/dist/services.js.map +1 -1
  757. package/packages/core/dist/stdio.d.ts +13 -2
  758. package/packages/core/dist/stdio.d.ts.map +1 -1
  759. package/packages/core/dist/stdio.js +75 -9
  760. package/packages/core/dist/stdio.js.map +1 -1
  761. package/packages/core/dist/workspace-path.d.ts +12 -0
  762. package/packages/core/dist/workspace-path.d.ts.map +1 -0
  763. package/packages/core/dist/workspace-path.js +62 -0
  764. package/packages/core/dist/workspace-path.js.map +1 -0
  765. package/packages/core/package.json +18 -8
  766. package/packages/core/profiles/default/cordis.yml +85 -0
  767. package/packages/core/profiles/development/cordis.yml +1 -1
  768. package/packages/core/src/boot.ts +38 -2
  769. package/packages/core/src/config.ts +5 -0
  770. package/packages/core/src/http.ts +32 -0
  771. package/packages/core/src/index.ts +2 -0
  772. package/packages/core/src/plugins/agent-teams.ts +291 -0
  773. package/packages/core/src/plugins/anchored-standard.ts +88 -0
  774. package/packages/core/src/plugins/annotation.ts +106 -0
  775. package/packages/core/src/plugins/archify.ts +124 -0
  776. package/packages/core/src/plugins/at-file.ts +54 -0
  777. package/packages/core/src/plugins/auto-mode.ts +123 -0
  778. package/packages/core/src/plugins/better-sidebar.ts +117 -0
  779. package/packages/core/src/plugins/browser-fetch.ts +171 -0
  780. package/packages/core/src/plugins/browser-session.ts +287 -0
  781. package/packages/core/src/plugins/canvas-draw.ts +90 -0
  782. package/packages/core/src/plugins/change-verifier.ts +79 -0
  783. package/packages/core/src/plugins/cleaner.ts +61 -0
  784. package/packages/core/src/plugins/cli-notifier.ts +125 -0
  785. package/packages/core/src/plugins/code2skill.ts +96 -0
  786. package/packages/core/src/plugins/colleague-skill.ts +122 -0
  787. package/packages/core/src/plugins/context-doctor.ts +117 -0
  788. package/packages/core/src/plugins/context.ts +102 -0
  789. package/packages/core/src/plugins/cost-meter.ts +231 -0
  790. package/packages/core/src/plugins/dependency-checker.ts +241 -0
  791. package/packages/core/src/plugins/docker-sandbox.ts +100 -0
  792. package/packages/core/src/plugins/fail-logger.ts +51 -0
  793. package/packages/core/src/plugins/genui.ts +88 -0
  794. package/packages/core/src/plugins/git-time-capsule.ts +97 -0
  795. package/packages/core/src/plugins/graph-memory.ts +394 -0
  796. package/packages/core/src/plugins/history-compressor.ts +81 -0
  797. package/packages/core/src/plugins/hol-guard.ts +153 -0
  798. package/packages/core/src/plugins/i18n-pair.ts +82 -0
  799. package/packages/core/src/plugins/image-compressor.ts +144 -0
  800. package/packages/core/src/plugins/llm-verifier.ts +164 -0
  801. package/packages/core/src/plugins/mcp-client.ts +559 -0
  802. package/packages/core/src/plugins/mcp-panel.ts +190 -0
  803. package/packages/core/src/plugins/memory.ts +176 -0
  804. package/packages/core/src/plugins/mirage-bridge.ts +179 -0
  805. package/packages/core/src/plugins/mock-server.ts +158 -0
  806. package/packages/core/src/plugins/model.ts +3 -1
  807. package/packages/core/src/plugins/models.ts +5 -2
  808. package/packages/core/src/plugins/modlens.ts +63 -0
  809. package/packages/core/src/plugins/module-search.ts +201 -0
  810. package/packages/core/src/plugins/obsidian-sync.ts +83 -0
  811. package/packages/core/src/plugins/openpets.ts +109 -0
  812. package/packages/core/src/plugins/plan-execute.ts +76 -0
  813. package/packages/core/src/plugins/plugin-check.ts +232 -0
  814. package/packages/core/src/plugins/plugin-dev.ts +47 -0
  815. package/packages/core/src/plugins/plugin-finder.ts +108 -0
  816. package/packages/core/src/plugins/plugin-radar.ts +179 -0
  817. package/packages/core/src/plugins/plugin-stars.ts +205 -0
  818. package/packages/core/src/plugins/prompt-guard.ts +122 -0
  819. package/packages/core/src/plugins/prompt-library.ts +165 -0
  820. package/packages/core/src/plugins/readme-gen.ts +147 -0
  821. package/packages/core/src/plugins/recall-unread.ts +142 -0
  822. package/packages/core/src/plugins/resources.ts +28 -21
  823. package/packages/core/src/plugins/reverse-skill.ts +79 -0
  824. package/packages/core/src/plugins/reviewer-bot.ts +146 -0
  825. package/packages/core/src/plugins/runtime-doctor.ts +137 -0
  826. package/packages/core/src/plugins/runtime.ts +61 -14
  827. package/packages/core/src/plugins/secure-audit.ts +146 -0
  828. package/packages/core/src/plugins/session-bookmarks.ts +89 -0
  829. package/packages/core/src/plugins/session-bridge.ts +299 -0
  830. package/packages/core/src/plugins/session-compare.ts +180 -0
  831. package/packages/core/src/plugins/session-export.ts +99 -0
  832. package/packages/core/src/plugins/session-insights.ts +47 -0
  833. package/packages/core/src/plugins/session-search.ts +126 -0
  834. package/packages/core/src/plugins/session.ts +4 -2
  835. package/packages/core/src/plugins/skill-catalog.ts +117 -0
  836. package/packages/core/src/plugins/skill-guard.ts +152 -0
  837. package/packages/core/src/plugins/sql-lens.ts +92 -0
  838. package/packages/core/src/plugins/stdio.ts +3 -1
  839. package/packages/core/src/plugins/synapse.ts +130 -0
  840. package/packages/core/src/plugins/tab-manager.ts +135 -0
  841. package/packages/core/src/plugins/taskboard.ts +412 -0
  842. package/packages/core/src/plugins/telemetry-blocker.ts +62 -0
  843. package/packages/core/src/plugins/test-harness.ts +67 -0
  844. package/packages/core/src/plugins/theme-studio.ts +165 -0
  845. package/packages/core/src/plugins/token-guard.ts +84 -0
  846. package/packages/core/src/plugins/tools.ts +5 -2
  847. package/packages/core/src/plugins/turn-rewind.ts +86 -0
  848. package/packages/core/src/plugins/undo-savepoint.ts +284 -0
  849. package/packages/core/src/plugins/vision-toolkit.ts +153 -0
  850. package/packages/core/src/plugins/web-research.ts +289 -0
  851. package/packages/core/src/plugins/workspace-navigator.ts +164 -0
  852. package/packages/core/src/plugins/workspace-search.ts +139 -0
  853. package/packages/core/src/plugins/yaml-validator.ts +97 -0
  854. package/packages/core/src/profile.ts +3 -0
  855. package/packages/core/src/runtime.ts +11 -4
  856. package/packages/core/src/services.ts +110 -3
  857. package/packages/core/src/stdio.ts +79 -9
  858. package/packages/core/src/workspace-path.ts +69 -0
  859. package/packages/core/test/agent-teams.test.ts +24 -0
  860. package/packages/core/test/archify.test.ts +33 -0
  861. package/packages/core/test/better-sidebar.test.ts +125 -0
  862. package/packages/core/test/boot.test.ts +49 -6
  863. package/packages/core/test/colleague-skill.test.ts +74 -0
  864. package/packages/core/test/config.test.ts +121 -0
  865. package/packages/core/test/context-doctor.test.ts +32 -0
  866. package/packages/core/test/dependency-checker.test.ts +60 -0
  867. package/packages/core/test/git-time-capsule.test.ts +115 -0
  868. package/packages/core/test/http.test.ts +34 -0
  869. package/packages/core/test/llm-verifier.test.ts +72 -0
  870. package/packages/core/test/mirage-bridge.test.ts +54 -0
  871. package/packages/core/test/module-search.test.ts +78 -0
  872. package/packages/core/test/plugin-check.test.ts +16 -0
  873. package/packages/core/test/plugin-stars.test.ts +55 -0
  874. package/packages/core/test/profiles.integration.test.ts +49 -15
  875. package/packages/core/test/prompt-library.test.ts +56 -0
  876. package/packages/core/test/readme-gen.test.ts +45 -0
  877. package/packages/core/test/recall-unread.test.ts +35 -0
  878. package/packages/core/test/registry.test.ts +48 -0
  879. package/packages/core/test/reverse-skill.test.ts +40 -0
  880. package/packages/core/test/runtime-doctor.test.ts +55 -0
  881. package/packages/core/test/runtime-fixture.ts +4 -4
  882. package/packages/core/test/runtime.test.ts +90 -1
  883. package/packages/core/test/secure-audit.test.ts +16 -0
  884. package/packages/core/test/services.test.ts +2024 -5
  885. package/packages/core/test/session-bookmarks.test.ts +62 -0
  886. package/packages/core/test/session-bridge.test.ts +103 -0
  887. package/packages/core/test/session-compare.test.ts +94 -0
  888. package/packages/core/test/session-export.test.ts +54 -0
  889. package/packages/core/test/session-search.test.ts +30 -0
  890. package/packages/core/test/skill-catalog.test.ts +18 -0
  891. package/packages/core/test/skill-guard.test.ts +21 -0
  892. package/packages/core/test/stdio-args.test.ts +178 -0
  893. package/packages/core/test/theme-studio.test.ts +39 -0
  894. package/packages/core/test/token-guard.test.ts +34 -0
  895. package/packages/core/test/turn-rewind.test.ts +19 -0
  896. package/packages/core/test/vision-toolkit.test.ts +38 -0
  897. package/packages/core/test/workspace-git-status.test.ts +37 -0
  898. package/packages/core/test/workspace-navigator.test.ts +33 -0
  899. package/packages/core/test/workspace-path.test.ts +34 -0
  900. package/packages/core/tsconfig.build.json +1 -3
  901. package/packages/core/tsconfig.json +1 -4
  902. package/packages/host-webserver/LICENSE +9 -0
  903. package/packages/host-webserver/dist/index.js +1 -1
  904. package/packages/host-webserver/dist/index.js.map +1 -1
  905. package/packages/host-webserver/package.json +17 -7
  906. package/packages/host-webserver/src/index.ts +1 -1
  907. package/packages/host-webserver/test/index.test.ts +4 -1
  908. package/packages/host-webserver/tsconfig.build.json +1 -1
  909. package/packages/host-webserver/tsconfig.json +1 -1
  910. package/apps/web/dist/assets/index-C4tLweAB.js +0 -20
  911. package/apps/web/dist/assets/index-DPgRbQ4_.css +0 -1
@@ -1,12 +1,26 @@
1
1
  import { execFile } from "node:child_process";
2
- import { rm } from "node:fs/promises";
2
+ import { mkdir, mkdtemp, readFile, rm, stat, unlink, writeFile } from "node:fs/promises";
3
3
  import type { IncomingMessage, ServerResponse } from "node:http";
4
- import { isAbsolute, relative, resolve } from "node:path";
4
+ import { basename, isAbsolute, join, relative, resolve } from "node:path";
5
+ import { tmpdir } from "node:os";
5
6
  import type { Context } from "@deepseek-ai/cordis";
6
- import { SessionManager, type AgentSessionEvent } from "@earendil-works/pi-coding-agent";
7
+ import { SessionManager, type AgentSessionEvent, type ExtensionUIContext } from "@earendil-works/pi-coding-agent";
7
8
  import type Loader from "@deepseek-ai/cordis-plugin-loader";
8
- import type { PiRuntimeService, PiModelsService, PiHarnessLaunch } from "@pi-harness/core";
9
+ import type { PiPluginUiRegistry, PiRuntimeService, PiModelsService, PiHarnessLaunch } from "@pi-harness/core";
9
10
  import type { WebServer } from "@pi-harness/host-webserver";
11
+ import {
12
+ MARKETPLACE_CAPABILITIES,
13
+ MARKETPLACE_CATEGORIES,
14
+ MARKETPLACE_PLUGINS,
15
+ attachMarketplaceStatistics,
16
+ createMarketplaceStatisticsLoader,
17
+ paginateMarketplace,
18
+ searchMarketplace,
19
+ needsMarketplacePackageInstall,
20
+ sortMarketplaceByRecommendation,
21
+ type MarketplacePlugin,
22
+ } from "./marketplace.js";
23
+ import { parseGitWorktrees, type WorkspaceSummary } from "./workspaces.js";
10
24
 
11
25
  interface ApiServices {
12
26
  readonly runtime: PiRuntimeService;
@@ -14,8 +28,11 @@ interface ApiServices {
14
28
  readonly launch: PiHarnessLaunch;
15
29
  readonly webServer: WebServer;
16
30
  readonly loader: Loader | undefined;
31
+ readonly pluginUi: PiPluginUiRegistry | undefined;
17
32
  }
18
33
 
34
+ const loadMarketplaceStatistics = createMarketplaceStatisticsLoader();
35
+
19
36
  function sendJson(response: ServerResponse, status: number, payload: unknown): void {
20
37
  const body = JSON.stringify(payload);
21
38
  response.writeHead(status, { "content-type": "application/json; charset=utf-8", "cache-control": "no-store", "content-length": Buffer.byteLength(body) });
@@ -54,6 +71,7 @@ function jsonSafe(value: unknown, seen = new WeakSet<object>()): unknown {
54
71
 
55
72
  function createStatus(services: ApiServices, events: readonly AgentSessionEvent[]) {
56
73
  const activeModel = services.runtime.session.model ?? services.models.model;
74
+ const cwd = activeCwd(services);
57
75
  return {
58
76
  status: services.runtime.session.isStreaming ? "running" : "ready",
59
77
  model: activeModel.provider + "/" + activeModel.id,
@@ -61,21 +79,292 @@ function createStatus(services: ApiServices, events: readonly AgentSessionEvent[
61
79
  events: events.length,
62
80
  sessionId: services.runtime.session.sessionId,
63
81
  sessionFile: services.runtime.session.sessionFile,
64
- cwd: services.launch.cwd,
82
+ cwd,
65
83
  agentDir: services.launch.agentDir,
66
84
  plugins: services.loader ? [...services.loader.entries()].filter((entry) => !entry.disabled).map((entry) => entry.options.name) : [],
67
85
  };
68
86
  }
69
87
 
88
+ function activeCwd(services: ApiServices): string {
89
+ const runtimeCwd = services.runtime.sessionRuntime?.cwd;
90
+ return typeof runtimeCwd === "string" && runtimeCwd.length > 0 ? runtimeCwd : services.launch.cwd;
91
+ }
92
+
93
+ function piConfig(services: ApiServices) {
94
+ const settings = services.runtime.session.settingsManager;
95
+ const global = settings.getGlobalSettings();
96
+ const compaction = settings.getCompactionSettings();
97
+ return {
98
+ path: join(services.launch.agentDir, "settings.json"),
99
+ scope: "global" as const,
100
+ source: JSON.stringify(global, null, 2) + "\n",
101
+ settings: {
102
+ defaultProvider: global.defaultProvider,
103
+ defaultModel: global.defaultModel,
104
+ defaultThinkingLevel: global.defaultThinkingLevel,
105
+ transport: settings.getTransport(),
106
+ steeringMode: settings.getSteeringMode(),
107
+ followUpMode: settings.getFollowUpMode(),
108
+ hideThinkingBlock: settings.getHideThinkingBlock(),
109
+ compaction,
110
+ retry: settings.getRetrySettings(),
111
+ terminal: {
112
+ showImages: settings.getShowImages(),
113
+ imageAutoResize: settings.getImageAutoResize(),
114
+ autocompleteMaxVisible: settings.getAutocompleteMaxVisible(),
115
+ },
116
+ advanced: {
117
+ quietStartup: settings.getQuietStartup(),
118
+ projectTrust: settings.getDefaultProjectTrust(),
119
+ showCacheMissNotices: settings.getShowCacheMissNotices(),
120
+ enableAnalytics: settings.getEnableAnalytics(),
121
+ enableInstallTelemetry: settings.getEnableInstallTelemetry(),
122
+ shellPath: settings.getShellPath(),
123
+ doubleEscapeAction: settings.getDoubleEscapeAction(),
124
+ treeFilterMode: settings.getTreeFilterMode(),
125
+ mermaid: settings.getMermaidRenderingMode(),
126
+ },
127
+ },
128
+ };
129
+ }
130
+
131
+ interface SessionMetadata {
132
+ readonly archived?: boolean;
133
+ readonly pinned?: boolean;
134
+ }
135
+
136
+ type SessionMetadataMap = Record<string, SessionMetadata>;
137
+
138
+ function sessionMetadataFile(manager: SessionManager): string {
139
+ return resolve(manager.getSessionDir(), ".pi-harness-session-meta.json");
140
+ }
141
+
142
+ async function readSessionMetadata(manager: SessionManager): Promise<SessionMetadataMap> {
143
+ try {
144
+ const parsed: unknown = JSON.parse(await readFile(sessionMetadataFile(manager), "utf8"));
145
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) return {};
146
+ return parsed as SessionMetadataMap;
147
+ } catch {
148
+ return {};
149
+ }
150
+ }
151
+
152
+ async function writeSessionMetadata(manager: SessionManager, metadata: SessionMetadataMap): Promise<void> {
153
+ await mkdir(manager.getSessionDir(), { recursive: true });
154
+ await writeFile(sessionMetadataFile(manager), JSON.stringify(metadata, null, 2) + "\n", "utf8");
155
+ }
156
+
157
+ function sessionPathInDirectory(path: string, manager: SessionManager): boolean {
158
+ const root = resolve(manager.getSessionDir());
159
+ const target = resolve(path);
160
+ const relativePath = relative(root, target);
161
+ return relativePath !== "" && !isAbsolute(relativePath) && relativePath !== ".." && !relativePath.startsWith(".." + "/") && target.endsWith(".jsonl");
162
+ }
163
+
164
+ const webSessionUi = {
165
+ select: (_title: string, options: string[]) => Promise.resolve(options[0]),
166
+ confirm: () => Promise.resolve(true),
167
+ input: () => Promise.resolve(undefined),
168
+ notify: () => {},
169
+ onTerminalInput: () => () => {},
170
+ setStatus: () => {},
171
+ setWorkingMessage: () => {},
172
+ setWorkingVisible: () => {},
173
+ setWorkingIndicator: () => {},
174
+ setHiddenThinkingLabel: () => {},
175
+ setWidget: () => {},
176
+ setFooter: () => {},
177
+ setHeader: () => {},
178
+ setTitle: () => {},
179
+ } as unknown as ExtensionUIContext;
180
+
181
+ async function runWebSessionChange<T>(services: ApiServices, action: () => Promise<T & { cancelled: boolean }>): Promise<T & { cancelled: boolean }> {
182
+ const runner = services.runtime.session.extensionRunner;
183
+ runner.setUIContext(webSessionUi, "rpc");
184
+ try {
185
+ const result = await action();
186
+ if (result.cancelled) runner.setUIContext(undefined, "print");
187
+ return result;
188
+ } catch (error) {
189
+ runner.setUIContext(undefined, "print");
190
+ throw error;
191
+ }
192
+ }
193
+
70
194
  function modelSummary(model: { provider: string; id: string; name?: string; reasoning?: boolean; contextWindow?: number }, active: boolean) {
71
- return { provider: model.provider, id: model.id, name: model.name ?? model.id, reasoning: model.reasoning ?? false, contextWindow: model.contextWindow ?? null, active };
195
+ return {
196
+ provider: model.provider,
197
+ id: model.id,
198
+ name: model.name ?? model.id,
199
+ reasoning: model.reasoning ?? false,
200
+ contextWindow: model.contextWindow ?? null,
201
+ active,
202
+ };
203
+ }
204
+
205
+ function visibleProviderIds(
206
+ runtime: Pick<PiModelsService["runtime"], "getModels"> &
207
+ Partial<Pick<PiModelsService["runtime"], "getProviders" | "getProviderAuthStatus" | "getRegisteredProviderConfig">>,
208
+ activeProvider: string,
209
+ ): Set<string> {
210
+ const providers = typeof runtime.getProviders === "function" ? runtime.getProviders() : [{ id: activeProvider, name: activeProvider }];
211
+ return new Set(
212
+ providers
213
+ .filter((provider) => {
214
+ if (provider.id === activeProvider) return true;
215
+ if (typeof runtime.getProviderAuthStatus !== "function") return false;
216
+ const auth = runtime.getProviderAuthStatus(provider.id);
217
+ if (typeof auth !== "object" || auth === null || (auth as { configured?: unknown }).configured !== true) return false;
218
+ if (typeof runtime.getRegisteredProviderConfig === "function") return runtime.getRegisteredProviderConfig(provider.id) !== undefined;
219
+ return true;
220
+ })
221
+ .map((provider) => provider.id),
222
+ );
223
+ }
224
+
225
+ type LoaderEntrySummary = { options: { id: string; name: string; disabled?: boolean | null }; fiber?: { state: unknown } };
226
+
227
+ function marketplacePluginForEntry(entry: LoaderEntrySummary): MarketplacePlugin | undefined {
228
+ return MARKETPLACE_PLUGINS.find((plugin) => plugin.packageName === entry.options.name);
72
229
  }
73
230
 
74
- function pluginSummary(entry: { options: { id: string; name: string; disabled?: boolean | null }; fiber?: { state: unknown } }) {
231
+ function pluginSummary(entry: LoaderEntrySummary) {
75
232
  const states = ["pending", "loading", "active", "failed", "disposed", "unloading"];
233
+ const marketplacePlugin = marketplacePluginForEntry(entry);
76
234
  const rawState = entry.fiber?.state;
77
- const state = typeof rawState === "number" ? states[rawState] ?? String(rawState) : typeof rawState === "string" ? rawState : rawState === undefined || rawState === null ? "unloaded" : "unknown";
78
- return { id: entry.options.id, name: entry.options.name, enabled: !entry.options.disabled, state };
235
+ const state =
236
+ typeof rawState === "number"
237
+ ? (states[rawState] ?? String(rawState))
238
+ : typeof rawState === "string"
239
+ ? rawState
240
+ : rawState === undefined || rawState === null
241
+ ? "unloaded"
242
+ : "unknown";
243
+ return {
244
+ id: entry.options.id,
245
+ name: entry.options.name,
246
+ enabled: !entry.options.disabled,
247
+ state,
248
+ removable: entry.options.id.startsWith("marketplace-") || marketplacePlugin !== undefined,
249
+ category: marketplacePlugin?.category,
250
+ };
251
+ }
252
+
253
+ function pluginLoaded(services: ApiServices, packageName: string): boolean {
254
+ return services.loader !== undefined && [...services.loader.entries()].some((entry) => entry.options.name === packageName && !entry.disabled);
255
+ }
256
+
257
+ function registerPluginPanels(context: Context, services: ApiServices): () => void {
258
+ if (services.pluginUi === undefined) return () => {};
259
+ const disposers = [
260
+ services.pluginUi.register({
261
+ id: "console-logger-panel",
262
+ pluginId: "@deepseek-ai/cordis-plugin-logger-console",
263
+ title: "运行时日志",
264
+ description: "查看最近的生命周期和运行时诊断输出。",
265
+ icon: "▤",
266
+ visible: () => pluginLoaded(services, "@deepseek-ai/cordis-plugin-logger-console"),
267
+ read: () => ({
268
+ total: context.logger.buffer.length,
269
+ items: context.logger.buffer.slice(-40).map((message) => ({
270
+ time: new Date(message.ts).toISOString(),
271
+ level: message.type,
272
+ source: message.name,
273
+ args: message.args,
274
+ })),
275
+ }),
276
+ }),
277
+ services.pluginUi.register({
278
+ id: "plugin-group-panel",
279
+ pluginId: "@deepseek-ai/cordis-plugin-group",
280
+ title: "插件树",
281
+ description: "查看当前运行时加载的插件树和生命周期状态。",
282
+ icon: "⌘",
283
+ visible: () => pluginLoaded(services, "@deepseek-ai/cordis-plugin-group"),
284
+ read: () => ({
285
+ entries:
286
+ services.loader === undefined
287
+ ? []
288
+ : [...services.loader.entries()].map((entry) => ({
289
+ id: entry.id,
290
+ name: entry.options.name.replace(/^@deepseek-ai\/cordis-plugin-/i, "plugin-").replace(/^cordis:/i, "runtime:"),
291
+ state: pluginSummary(entry).state,
292
+ enabled: !entry.disabled,
293
+ })),
294
+ }),
295
+ }),
296
+ services.pluginUi.register({
297
+ id: "timer-service-panel",
298
+ pluginId: "@deepseek-ai/cordis-plugin-timer",
299
+ title: "定时器服务",
300
+ description: "确认定时器服务已注册,并查看可用的生命周期绑定 API。",
301
+ icon: "◷",
302
+ visible: () => pluginLoaded(services, "@deepseek-ai/cordis-plugin-timer"),
303
+ read: () => ({
304
+ registered: context.reflect.get("timer") !== undefined,
305
+ capabilities: ["timeout", "interval", "throttle", "debounce"],
306
+ }),
307
+ }),
308
+ ];
309
+ return () => disposers.reverse().forEach((dispose) => dispose());
310
+ }
311
+
312
+ function runProcess(executable: string, args: readonly string[], cwd: string): Promise<{ stdout: string; stderr: string }> {
313
+ return new Promise((resolveProcess, rejectProcess) => {
314
+ execFile(executable, [...args], { cwd, timeout: 120_000, maxBuffer: 2 * 1024 * 1024 }, (error, stdout, stderr) => {
315
+ if (error) {
316
+ rejectProcess(new Error(`${executable} ${args.join(" ")} failed: ${stderr || error.message}`, { cause: error }));
317
+ return;
318
+ }
319
+ resolveProcess({ stdout, stderr });
320
+ });
321
+ });
322
+ }
323
+
324
+ async function appendMarketplaceProfile(configPath: string, plugin: MarketplacePlugin): Promise<string> {
325
+ const source = await readFile(configPath, "utf8");
326
+ if (source.includes(`name: ${JSON.stringify(plugin.packageName)}`)) return source;
327
+ const entryId = `marketplace-${plugin.id}`;
328
+ const config = JSON.stringify(plugin.profile.config);
329
+ const group = plugin.profile.group === true ? "\n group: true" : "";
330
+ const entry = `\n- id: ${entryId}\n name: ${JSON.stringify(plugin.packageName)}${group}\n config: ${config}\n`;
331
+ await writeFile(configPath, source.replace(/\s*$/, "") + entry, "utf8");
332
+ return source;
333
+ }
334
+
335
+ async function updateMarketplaceProfile(configPath: string, entryId: string, update: { disabled?: boolean; remove?: boolean }): Promise<string> {
336
+ const source = await readFile(configPath, "utf8");
337
+ const escapedId = entryId.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
338
+ const pattern = new RegExp(`^([ \\t]*)- id: ${escapedId}[ \\t]*(?:\\r?\\n|$)`, "m");
339
+ const match = source.match(pattern);
340
+ if (match === null) throw new Error(`Installed plugin profile entry was not found: ${entryId}`);
341
+ const indent = match[1] ?? "";
342
+ const start = match.index ?? 0;
343
+ let end = source.length;
344
+ const linePattern = /^([ \t]*)(?=\S)/gm;
345
+ linePattern.lastIndex = start + match[0].length;
346
+ for (let line = linePattern.exec(source); line !== null; line = linePattern.exec(source)) {
347
+ const lineIndent = line[1] ?? "";
348
+ const content = source.slice(line.index + lineIndent.length);
349
+ if (lineIndent.length < indent.length || (lineIndent === indent && content.startsWith("- "))) {
350
+ end = line.index;
351
+ break;
352
+ }
353
+ }
354
+ const originalBlock = source.slice(start, end);
355
+ if (update.remove === true) {
356
+ await writeFile(configPath, source.slice(0, start) + source.slice(end), "utf8");
357
+ return source;
358
+ }
359
+ const childIndent = `${indent} `;
360
+ const disabledPattern = new RegExp(`^${childIndent}disabled: .*\\r?\\n`, "m");
361
+ let block = originalBlock.replace(disabledPattern, "");
362
+ if (update.disabled === true) {
363
+ const namePattern = new RegExp(`^(${childIndent}name: .*\\r?\\n)`, "m");
364
+ block = block.replace(namePattern, `$1${childIndent}disabled: true\n`);
365
+ }
366
+ await writeFile(configPath, source.slice(0, start) + block + source.slice(end), "utf8");
367
+ return source;
79
368
  }
80
369
 
81
370
  function writeSse(response: ServerResponse, payload: unknown): void {
@@ -90,7 +379,9 @@ function gitStatus(cwd: string): Promise<string> {
90
379
 
91
380
  function gitDiff(cwd: string, path: string): Promise<string> {
92
381
  return new Promise((resolveOutput) => {
93
- execFile("git", ["diff", "--no-ext-diff", "--", path], { cwd, maxBuffer: 1024 * 1024 }, (error, stdout) => resolveOutput(error && stdout.length === 0 ? "" : stdout));
382
+ execFile("git", ["diff", "--no-ext-diff", "--", path], { cwd, maxBuffer: 1024 * 1024 }, (error, stdout) =>
383
+ resolveOutput(error && stdout.length === 0 ? "" : stdout),
384
+ );
94
385
  });
95
386
  }
96
387
 
@@ -103,8 +394,62 @@ function gitCommand(cwd: string, args: readonly string[]): Promise<{ stdout: str
103
394
  });
104
395
  }
105
396
 
397
+ interface EveryApiCliAuthStatus {
398
+ configured: false;
399
+ source: "everyapi-cli";
400
+ label: string;
401
+ }
402
+
403
+ function probeEveryApiCliAuth(): Promise<EveryApiCliAuthStatus> {
404
+ const executable = process.env.EVERYAPI_CLI_PATH?.trim() || "everyapi";
405
+ return new Promise((resolveStatus) => {
406
+ execFile(executable, ["auth", "status"], { timeout: 3_000, maxBuffer: 128 * 1024 }, (error) => {
407
+ resolveStatus({
408
+ configured: false,
409
+ source: "everyapi-cli",
410
+ label: error ? "未检测到 EveryAPI CLI 登录" : "EveryAPI CLI 已登录,但 relay key 未注入当前进程",
411
+ });
412
+ });
413
+ });
414
+ }
415
+
416
+ async function listWorkspaces(cwd: string): Promise<readonly WorkspaceSummary[]> {
417
+ const result = await gitCommand(cwd, ["worktree", "list", "--porcelain"]);
418
+ const parsed = result.code === 0 ? parseGitWorktrees(result.stdout, cwd) : [];
419
+ if (parsed.some((item) => item.current)) return parsed;
420
+ return [{ path: resolve(cwd), branch: "current", current: true, name: resolve(cwd).split("/").pop() ?? resolve(cwd) }, ...parsed];
421
+ }
422
+
423
+ async function isDirectory(path: string): Promise<boolean> {
424
+ try {
425
+ return (await stat(path)).isDirectory();
426
+ } catch {
427
+ return false;
428
+ }
429
+ }
430
+
431
+ function pickDirectory(): Promise<string> {
432
+ return new Promise((resolvePath, reject) => {
433
+ execFile(
434
+ "osascript",
435
+ ["-e", 'POSIX path of (choose folder with prompt "选择 Pi 工作区")'],
436
+ { timeout: 120_000, maxBuffer: 64 * 1024 },
437
+ (error, stdout, stderr) => {
438
+ if (error) {
439
+ reject(new Error(stderr.trim() || "目录选择已取消"));
440
+ return;
441
+ }
442
+ const path = stdout.trim();
443
+ if (!path) reject(new Error("目录选择已取消"));
444
+ else resolvePath(path);
445
+ },
446
+ );
447
+ });
448
+ }
449
+
106
450
  function workspacePaths(root: string, paths: unknown): string[] | Error {
107
- if (!Array.isArray(paths) || paths.length === 0 || paths.some((path) => typeof path !== "string" || path.trim() === "")) return new Error("paths must be a non-empty array of strings");
451
+ if (!Array.isArray(paths) || paths.length === 0 || paths.some((path) => typeof path !== "string" || path.trim() === ""))
452
+ return new Error("paths must be a non-empty array of strings");
108
453
  const normalized: string[] = [];
109
454
  for (const path of paths) {
110
455
  const requested = path as string;
@@ -121,12 +466,14 @@ export default {
121
466
  inject: ["webServer", "piRuntime", "piModels", "piHarnessLaunch"],
122
467
  apply(context: Context) {
123
468
  const services: ApiServices = {
124
- runtime: context.piRuntime,
125
- models: context.piModels,
126
- launch: context.piHarnessLaunch,
469
+ runtime: context.reflect.get("piRuntime") as PiRuntimeService,
470
+ models: context.reflect.get("piModels") as PiModelsService,
471
+ launch: context.reflect.get("piHarnessLaunch") as PiHarnessLaunch,
127
472
  webServer: context.webServer,
128
473
  loader: context.reflect.get("loader") as Loader | undefined,
474
+ pluginUi: context.reflect.get("piPluginUi") as PiPluginUiRegistry | undefined,
129
475
  };
476
+ const disposePluginPanels = registerPluginPanels(context, services);
130
477
  let busy = false;
131
478
  const events: AgentSessionEvent[] = [];
132
479
  const eventClients = new Set<ServerResponse>();
@@ -141,7 +488,7 @@ export default {
141
488
  }
142
489
  };
143
490
  const unsubscribeEvents = services.runtime.sessionRuntime
144
- ? context.on("pi/session-event", handleEvent)
491
+ ? context.on("pi/session-event" as never, handleEvent as never)
145
492
  : services.runtime.session.subscribe(handleEvent);
146
493
  const disposeStatus = services.webServer.register({
147
494
  path: "/api/status",
@@ -149,26 +496,238 @@ export default {
149
496
  sendJson(response, 200, createStatus(services, events));
150
497
  },
151
498
  });
499
+ const disposeConfig = services.webServer.register({
500
+ path: "/api/config",
501
+ async handler(request, response) {
502
+ if (request.method === "GET") {
503
+ sendJson(response, 200, piConfig(services));
504
+ return;
505
+ }
506
+ if (request.method !== "POST") {
507
+ sendJson(response, 405, { error: "Method not allowed" });
508
+ return;
509
+ }
510
+ try {
511
+ const payload = JSON.parse(await bodyText(request)) as Record<string, unknown>;
512
+ const settings = services.runtime.session.settingsManager;
513
+ if (typeof payload.defaultProvider === "string" && payload.defaultProvider.trim()) settings.setDefaultProvider(payload.defaultProvider.trim());
514
+ if (typeof payload.defaultModel === "string" && payload.defaultModel.trim()) settings.setDefaultModel(payload.defaultModel.trim());
515
+ if (
516
+ payload.defaultThinkingLevel === "off" ||
517
+ payload.defaultThinkingLevel === "minimal" ||
518
+ payload.defaultThinkingLevel === "low" ||
519
+ payload.defaultThinkingLevel === "medium" ||
520
+ payload.defaultThinkingLevel === "high" ||
521
+ payload.defaultThinkingLevel === "xhigh" ||
522
+ payload.defaultThinkingLevel === "max"
523
+ )
524
+ settings.setDefaultThinkingLevel(payload.defaultThinkingLevel);
525
+ if (payload.transport === "sse" || payload.transport === "websocket" || payload.transport === "auto") settings.setTransport(payload.transport);
526
+ if (payload.steeringMode === "all" || payload.steeringMode === "one-at-a-time") settings.setSteeringMode(payload.steeringMode);
527
+ if (payload.followUpMode === "all" || payload.followUpMode === "one-at-a-time") settings.setFollowUpMode(payload.followUpMode);
528
+ if (typeof payload.hideThinkingBlock === "boolean") settings.setHideThinkingBlock(payload.hideThinkingBlock);
529
+ if (typeof payload.retry === "object" && payload.retry !== null) {
530
+ const retry = payload.retry as Record<string, unknown>;
531
+ if (typeof retry.enabled === "boolean") settings.setRetryEnabled(retry.enabled);
532
+ }
533
+ if (typeof payload.terminal === "object" && payload.terminal !== null) {
534
+ const terminal = payload.terminal as Record<string, unknown>;
535
+ if (typeof terminal.showImages === "boolean") settings.setShowImages(terminal.showImages);
536
+ if (typeof terminal.imageAutoResize === "boolean") settings.setImageAutoResize(terminal.imageAutoResize);
537
+ if (typeof terminal.autocompleteMaxVisible === "number" && Number.isInteger(terminal.autocompleteMaxVisible))
538
+ settings.setAutocompleteMaxVisible(Math.min(20, Math.max(3, terminal.autocompleteMaxVisible)));
539
+ }
540
+ if (typeof payload.advanced === "object" && payload.advanced !== null) {
541
+ const advanced = payload.advanced as Record<string, unknown>;
542
+ if (typeof advanced.quietStartup === "boolean") settings.setQuietStartup(advanced.quietStartup);
543
+ if (advanced.projectTrust === "ask" || advanced.projectTrust === "always" || advanced.projectTrust === "never")
544
+ settings.setDefaultProjectTrust(advanced.projectTrust);
545
+ if (typeof advanced.showCacheMissNotices === "boolean") settings.setShowCacheMissNotices(advanced.showCacheMissNotices);
546
+ if (typeof advanced.enableInstallTelemetry === "boolean") settings.setEnableInstallTelemetry(advanced.enableInstallTelemetry);
547
+ if (typeof advanced.shellPath === "string") settings.setShellPath(advanced.shellPath.trim() || undefined);
548
+ if (advanced.doubleEscapeAction === "fork" || advanced.doubleEscapeAction === "tree" || advanced.doubleEscapeAction === "none")
549
+ settings.setDoubleEscapeAction(advanced.doubleEscapeAction);
550
+ if (
551
+ advanced.treeFilterMode === "default" ||
552
+ advanced.treeFilterMode === "no-tools" ||
553
+ advanced.treeFilterMode === "user-only" ||
554
+ advanced.treeFilterMode === "labeled-only" ||
555
+ advanced.treeFilterMode === "all"
556
+ )
557
+ settings.setTreeFilterMode(advanced.treeFilterMode);
558
+ if (advanced.mermaid === "off" || advanced.mermaid === "final" || advanced.mermaid === "streaming")
559
+ settings.setMermaidRenderingMode(advanced.mermaid);
560
+ }
561
+ if (
562
+ typeof payload.compaction === "object" &&
563
+ payload.compaction !== null &&
564
+ typeof (payload.compaction as Record<string, unknown>).enabled === "boolean"
565
+ )
566
+ settings.setCompactionEnabled((payload.compaction as Record<string, boolean>).enabled === true);
567
+ await settings.flush();
568
+ sendJson(response, 200, piConfig(services));
569
+ } catch (error) {
570
+ sendJson(response, 400, { error: errorText(error) });
571
+ }
572
+ },
573
+ });
574
+ const disposeConfigReload = services.webServer.register({
575
+ path: "/api/config/reload",
576
+ async handler(request, response) {
577
+ if (request.method !== "POST") {
578
+ sendJson(response, 405, { error: "Method not allowed" });
579
+ return;
580
+ }
581
+ try {
582
+ await services.runtime.session.settingsManager.reload();
583
+ sendJson(response, 200, piConfig(services));
584
+ } catch (error) {
585
+ sendJson(response, 400, { error: errorText(error) });
586
+ }
587
+ },
588
+ });
589
+ const disposeConfigSource = services.webServer.register({
590
+ path: "/api/config/source",
591
+ async handler(request, response) {
592
+ if (request.method !== "POST") {
593
+ sendJson(response, 405, { error: "Method not allowed" });
594
+ return;
595
+ }
596
+ try {
597
+ const payload = JSON.parse(await bodyText(request)) as { source?: unknown };
598
+ if (typeof payload.source !== "string" || payload.source.length > 128 * 1024) {
599
+ sendJson(response, 400, { error: "source must be a JSON document smaller than 128 KiB" });
600
+ return;
601
+ }
602
+ const parsed: unknown = JSON.parse(payload.source);
603
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
604
+ sendJson(response, 400, { error: "settings source must contain a JSON object" });
605
+ return;
606
+ }
607
+ const path = join(services.launch.agentDir, "settings.json");
608
+ await writeFile(path, JSON.stringify(parsed, null, 2) + "\n", "utf8");
609
+ await services.runtime.session.settingsManager.reload();
610
+ sendJson(response, 200, piConfig(services));
611
+ } catch (error) {
612
+ sendJson(response, 400, { error: errorText(error) });
613
+ }
614
+ },
615
+ });
152
616
  const disposeModels = services.webServer.register({
153
617
  path: "/api/models",
154
618
  handler(_request, response) {
155
619
  const active = services.runtime.session.model ?? services.models.model;
156
- sendJson(response, 200, jsonSafe({ items: services.models.runtime.getModels().map((model) => modelSummary(model, model.provider === active.provider && model.id === active.id)) }));
620
+ const visible = visibleProviderIds(services.models.runtime, active.provider);
621
+ sendJson(
622
+ response,
623
+ 200,
624
+ jsonSafe({
625
+ items: services.models.runtime
626
+ .getModels()
627
+ .filter((model) => visible.has(model.provider))
628
+ .map((model) => modelSummary(model, model.provider === active.provider && model.id === active.id)),
629
+ }),
630
+ );
157
631
  },
158
632
  });
159
633
  const disposeProviders = services.webServer.register({
160
634
  path: "/api/providers",
161
635
  handler(_request, response) {
162
636
  const active = services.runtime.session.model ?? services.models.model;
163
- const runtime = services.models.runtime as typeof services.models.runtime & { getProviders?: () => readonly { id: string; name?: string }[]; getProviderAuthStatus?: (provider: string) => unknown };
637
+ const runtime = services.models.runtime as typeof services.models.runtime & {
638
+ getProviders?: () => readonly { id: string; name?: string }[];
639
+ getProviderAuthStatus?: (provider: string) => unknown;
640
+ };
164
641
  const providers = typeof runtime.getProviders === "function" ? runtime.getProviders() : [{ id: active.provider, name: active.provider }];
165
- const visible = providers.filter((provider) => {
166
- if (provider.id === active.provider) return true;
167
- if (typeof runtime.getProviderAuthStatus !== "function") return false;
168
- const auth = runtime.getProviderAuthStatus(provider.id);
169
- return typeof auth === "object" && auth !== null && (auth as { configured?: unknown }).configured === true;
170
- });
171
- sendJson(response, 200, jsonSafe({ items: visible.map((provider) => ({ provider: provider.id, name: provider.name ?? provider.id, active: provider.id === active.provider, auth: typeof runtime.getProviderAuthStatus === "function" ? runtime.getProviderAuthStatus(provider.id) : undefined, activeModel: provider.id === active.provider ? modelSummary(active, true) : undefined, models: services.models.runtime.getModels(provider.id).map((model) => modelSummary(model, model.provider === active.provider && model.id === active.id)) })) }));
642
+ const visibleIds = visibleProviderIds(runtime, active.provider);
643
+ const visible = providers.filter((provider) => visibleIds.has(provider.id));
644
+ sendJson(
645
+ response,
646
+ 200,
647
+ jsonSafe({
648
+ items: visible.map((provider) => ({
649
+ provider: provider.id,
650
+ name: provider.name ?? provider.id,
651
+ active: provider.id === active.provider,
652
+ auth: typeof runtime.getProviderAuthStatus === "function" ? runtime.getProviderAuthStatus(provider.id) : undefined,
653
+ activeModel: provider.id === active.provider ? modelSummary(active, true) : undefined,
654
+ models: services.models.runtime
655
+ .getModels(provider.id)
656
+ .map((model) => modelSummary(model, model.provider === active.provider && model.id === active.id)),
657
+ })),
658
+ }),
659
+ );
660
+ },
661
+ });
662
+ const disposeProviderAdd = services.webServer.register({
663
+ path: "/api/providers/add",
664
+ async handler(request, response) {
665
+ if (request.method !== "POST") {
666
+ sendJson(response, 405, { error: "Method not allowed" });
667
+ return;
668
+ }
669
+ try {
670
+ const payload = JSON.parse(await bodyText(request)) as {
671
+ provider?: unknown;
672
+ name?: unknown;
673
+ baseUrl?: unknown;
674
+ api?: unknown;
675
+ apiKey?: unknown;
676
+ model?: unknown;
677
+ };
678
+ const provider = typeof payload.provider === "string" ? payload.provider.trim() : "";
679
+ const name = typeof payload.name === "string" && payload.name.trim() !== "" ? payload.name.trim() : provider;
680
+ const baseUrl = typeof payload.baseUrl === "string" ? payload.baseUrl.trim() : "";
681
+ const apiKey = typeof payload.apiKey === "string" ? payload.apiKey.trim() : "";
682
+ const model = typeof payload.model === "string" ? payload.model.trim() : "";
683
+ const api = payload.api === "openai-responses" ? "openai-responses" : "openai-completions";
684
+ if (!/^[a-z0-9][a-z0-9._-]{1,63}$/i.test(provider)) {
685
+ sendJson(response, 400, { error: "provider must be 2-64 characters using letters, numbers, ., _, or -" });
686
+ return;
687
+ }
688
+ if (!/^https?:\/\/[^\s]+$/i.test(baseUrl)) {
689
+ sendJson(response, 400, { error: "baseUrl must be an http(s) URL" });
690
+ return;
691
+ }
692
+ if (!apiKey || !model) {
693
+ sendJson(response, 400, { error: "apiKey and model are required" });
694
+ return;
695
+ }
696
+ const runtime = services.models.runtime;
697
+ if (runtime.getProvider(provider) !== undefined) {
698
+ sendJson(response, 409, { error: `Provider already exists: ${provider}` });
699
+ return;
700
+ }
701
+ runtime.registerProvider(provider, {
702
+ name,
703
+ baseUrl,
704
+ api,
705
+ models: [
706
+ {
707
+ id: model,
708
+ name: model,
709
+ api,
710
+ reasoning: false,
711
+ input: ["text"],
712
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
713
+ contextWindow: 128000,
714
+ maxTokens: 8192,
715
+ },
716
+ ],
717
+ });
718
+ await runtime.setRuntimeApiKey(provider, apiKey);
719
+ sendJson(response, 201, {
720
+ provider: {
721
+ provider,
722
+ name,
723
+ active: false,
724
+ auth: runtime.getProviderAuthStatus(provider),
725
+ models: runtime.getModels(provider).map((item) => modelSummary(item, false)),
726
+ },
727
+ });
728
+ } catch (error) {
729
+ sendJson(response, 400, { error: errorText(error) });
730
+ }
172
731
  },
173
732
  });
174
733
  const disposeProviderTest = services.webServer.register({
@@ -190,6 +749,11 @@ export default {
190
749
  return;
191
750
  }
192
751
  const auth = await runtime.checkAuth(payload.provider);
752
+ if (payload.provider === "everyapi" && auth === undefined && !process.env.EVERYAPI_RELAY_KEY?.trim()) {
753
+ const cliAuth = await probeEveryApiCliAuth();
754
+ sendJson(response, 200, { provider: payload.provider, reachable: false, auth: cliAuth });
755
+ return;
756
+ }
193
757
  sendJson(response, 200, jsonSafe({ provider: payload.provider, reachable: auth !== undefined, auth }));
194
758
  } catch (error) {
195
759
  sendJson(response, 502, { error: errorText(error) });
@@ -228,14 +792,289 @@ export default {
228
792
  sendJson(response, 200, jsonSafe({ items }));
229
793
  },
230
794
  });
795
+ const disposePluginUi = services.webServer.register({
796
+ path: "/api/plugin-ui",
797
+ async handler(request, response) {
798
+ if (request.method !== "GET") {
799
+ sendJson(response, 405, { error: "Method not allowed" });
800
+ return;
801
+ }
802
+ try {
803
+ const items = services.pluginUi === undefined ? [] : await services.pluginUi.snapshot();
804
+ sendJson(response, 200, jsonSafe({ items }));
805
+ } catch (error) {
806
+ sendJson(response, 500, { error: errorText(error) });
807
+ }
808
+ },
809
+ });
810
+ const disposeMarketplace = services.webServer.register({
811
+ path: "/api/marketplace",
812
+ async handler(request, response) {
813
+ if (request.method !== "GET") {
814
+ sendJson(response, 405, { error: "Method not allowed" });
815
+ return;
816
+ }
817
+ const url = new URL(request.url ?? "/api/marketplace", "http://localhost");
818
+ const query = url.searchParams.get("q") ?? "";
819
+ const capability = url.searchParams.get("capability") ?? "";
820
+ const category = url.searchParams.get("category") ?? "";
821
+ const page = Number(url.searchParams.get("page") ?? "0");
822
+ const pageSize = Number(url.searchParams.get("pageSize") ?? "24");
823
+ const sort = url.searchParams.get("sort") ?? "";
824
+ if (
825
+ query.length > 120 ||
826
+ capability.length > 80 ||
827
+ category.length > 80 ||
828
+ !Number.isInteger(page) ||
829
+ page < 0 ||
830
+ !Number.isInteger(pageSize) ||
831
+ pageSize < 1 ||
832
+ pageSize > 100 ||
833
+ (sort !== "" && sort !== "recommended")
834
+ ) {
835
+ sendJson(response, 400, { error: "Invalid marketplace query" });
836
+ return;
837
+ }
838
+ const filtered = searchMarketplace(query, capability, category);
839
+ const items =
840
+ sort === "recommended"
841
+ ? sortMarketplaceByRecommendation(attachMarketplaceStatistics(filtered, await loadMarketplaceStatistics(MARKETPLACE_PLUGINS)))
842
+ : filtered;
843
+ sendJson(response, 200, {
844
+ ...paginateMarketplace(items, page, pageSize),
845
+ capabilities: MARKETPLACE_CAPABILITIES,
846
+ categories: MARKETPLACE_CATEGORIES,
847
+ });
848
+ },
849
+ });
850
+ let marketplaceMutationInFlight = false;
851
+ const disposeMarketplaceInstall = services.webServer.register({
852
+ path: "/api/marketplace/install",
853
+ async handler(request, response) {
854
+ if (request.method !== "POST") {
855
+ sendJson(response, 405, { error: "Method not allowed" });
856
+ return;
857
+ }
858
+ if (marketplaceMutationInFlight) {
859
+ sendJson(response, 409, { error: "Another marketplace plugin change is already running" });
860
+ return;
861
+ }
862
+ const loader = services.loader;
863
+ const configPath = services.launch.configPath;
864
+ if (loader === undefined || configPath === undefined) {
865
+ sendJson(response, 501, { error: "Plugin installation is unavailable for this runtime" });
866
+ return;
867
+ }
868
+ marketplaceMutationInFlight = true;
869
+ try {
870
+ const payload = JSON.parse(await bodyText(request)) as { id?: unknown };
871
+ if (typeof payload.id !== "string" || payload.id.trim() === "") {
872
+ sendJson(response, 400, { error: "id is required" });
873
+ return;
874
+ }
875
+ const plugin = MARKETPLACE_PLUGINS.find((item) => item.id === payload.id);
876
+ if (plugin === undefined) {
877
+ sendJson(response, 404, { error: "Marketplace plugin was not found" });
878
+ return;
879
+ }
880
+ const existing = [...loader.entries()].find((entry) => entry.options.name === plugin.packageName);
881
+ if (existing !== undefined) {
882
+ sendJson(response, 409, { error: "Plugin is already installed", plugin });
883
+ return;
884
+ }
885
+ const packageJsonPath = join(services.launch.cwd, "package.json");
886
+ const packageLockPath = join(services.launch.cwd, "package-lock.json");
887
+ const packageJsonBefore = await readFile(packageJsonPath, "utf8").catch(() => undefined);
888
+ const packageLockBefore = await readFile(packageLockPath, "utf8").catch(() => undefined);
889
+ let profileBefore: string | undefined;
890
+ let entryId: string | undefined;
891
+ try {
892
+ if (needsMarketplacePackageInstall(plugin)) {
893
+ await runProcess("npm", ["install", "--save-exact", "--package-lock=false", `${plugin.packageName}@${plugin.version}`], services.launch.cwd);
894
+ }
895
+ profileBefore = await appendMarketplaceProfile(configPath, plugin);
896
+ if (!needsMarketplacePackageInstall(plugin)) {
897
+ sendJson(response, 200, { plugin, installed: false, restartRequired: true });
898
+ return;
899
+ }
900
+ entryId = await loader.create({
901
+ id: `marketplace-${plugin.id}`,
902
+ name: plugin.packageName,
903
+ ...(plugin.profile.group === true ? { group: true } : {}),
904
+ config: plugin.profile.config,
905
+ } as never);
906
+ const entry = loader.resolve(entryId);
907
+ if (entry.fiber === undefined) throw new Error(`Plugin ${plugin.packageName} did not create a runtime fiber`);
908
+ await entry.fiber.await();
909
+ sendJson(response, 200, { plugin, installed: true });
910
+ } catch (error) {
911
+ if (entryId !== undefined) await loader.remove(entryId).catch(() => {});
912
+ if (profileBefore !== undefined) await writeFile(configPath, profileBefore, "utf8").catch(() => {});
913
+ if (packageJsonBefore !== undefined) await writeFile(packageJsonPath, packageJsonBefore, "utf8").catch(() => {});
914
+ if (packageLockBefore !== undefined) await writeFile(packageLockPath, packageLockBefore, "utf8").catch(() => {});
915
+ sendJson(response, 502, { error: errorText(error) });
916
+ }
917
+ } catch (error) {
918
+ sendJson(response, 400, { error: errorText(error) });
919
+ } finally {
920
+ marketplaceMutationInFlight = false;
921
+ }
922
+ },
923
+ });
924
+ const disposePluginToggle = services.webServer.register({
925
+ path: "/api/plugins/toggle",
926
+ async handler(request, response) {
927
+ if (request.method !== "POST") {
928
+ sendJson(response, 405, { error: "Method not allowed" });
929
+ return;
930
+ }
931
+ const configPath = services.launch.configPath;
932
+ const loader = services.loader;
933
+ if (configPath === undefined || loader === undefined) {
934
+ sendJson(response, 501, { error: "Plugin configuration is unavailable for this runtime" });
935
+ return;
936
+ }
937
+ if (marketplaceMutationInFlight) {
938
+ sendJson(response, 409, { error: "Another marketplace plugin change is already running" });
939
+ return;
940
+ }
941
+ marketplaceMutationInFlight = true;
942
+ try {
943
+ const payload = JSON.parse(await bodyText(request)) as { id?: unknown; enabled?: unknown };
944
+ if (typeof payload.id !== "string" || typeof payload.enabled !== "boolean") {
945
+ sendJson(response, 400, { error: "A marketplace plugin id and enabled boolean are required" });
946
+ return;
947
+ }
948
+ const entry = [...loader.entries()].find((item) => item.id === payload.id || item.options.id === payload.id);
949
+ if (entry === undefined) {
950
+ sendJson(response, 404, { error: "Installed plugin was not found" });
951
+ return;
952
+ }
953
+ const plugin = marketplacePluginForEntry(entry);
954
+ if (plugin === undefined) {
955
+ sendJson(response, 403, { error: "Built-in plugins cannot be changed" });
956
+ return;
957
+ }
958
+ const profileEntryId = entry.options.id;
959
+ const before = await updateMarketplaceProfile(configPath, profileEntryId, { disabled: !payload.enabled });
960
+ try {
961
+ await entry.update({ disabled: !payload.enabled });
962
+ sendJson(response, 200, { plugin: pluginSummary(entry) });
963
+ } catch (error) {
964
+ await writeFile(configPath, before, "utf8").catch(() => {});
965
+ sendJson(response, 502, { error: errorText(error) });
966
+ }
967
+ } catch (error) {
968
+ sendJson(response, 400, { error: errorText(error) });
969
+ } finally {
970
+ marketplaceMutationInFlight = false;
971
+ }
972
+ },
973
+ });
974
+ const disposePluginUninstall = services.webServer.register({
975
+ path: "/api/plugins/uninstall",
976
+ async handler(request, response) {
977
+ if (request.method !== "POST") {
978
+ sendJson(response, 405, { error: "Method not allowed" });
979
+ return;
980
+ }
981
+ const configPath = services.launch.configPath;
982
+ const loader = services.loader;
983
+ if (configPath === undefined || loader === undefined) {
984
+ sendJson(response, 501, { error: "Plugin configuration is unavailable for this runtime" });
985
+ return;
986
+ }
987
+ if (marketplaceMutationInFlight) {
988
+ sendJson(response, 409, { error: "Another marketplace plugin change is already running" });
989
+ return;
990
+ }
991
+ marketplaceMutationInFlight = true;
992
+ try {
993
+ const payload = JSON.parse(await bodyText(request)) as { id?: unknown };
994
+ if (typeof payload.id !== "string") {
995
+ sendJson(response, 400, { error: "A marketplace plugin id is required" });
996
+ return;
997
+ }
998
+ const entry = [...loader.entries()].find((item) => item.id === payload.id || item.options.id === payload.id);
999
+ if (entry === undefined) {
1000
+ sendJson(response, 404, { error: "Installed plugin was not found" });
1001
+ return;
1002
+ }
1003
+ const plugin = marketplacePluginForEntry(entry);
1004
+ if (plugin === undefined) {
1005
+ sendJson(response, 403, { error: "Only marketplace plugins can be uninstalled" });
1006
+ return;
1007
+ }
1008
+ const profileEntryId = entry.options.id;
1009
+ const profileBefore = await readFile(configPath, "utf8");
1010
+ const packageJsonPath = join(services.launch.cwd, "package.json");
1011
+ const packageLockPath = join(services.launch.cwd, "package-lock.json");
1012
+ const packageJsonBefore = await readFile(packageJsonPath, "utf8").catch(() => undefined);
1013
+ const packageLockBefore = await readFile(packageLockPath, "utf8").catch(() => undefined);
1014
+ await entry.parent.remove(entry.options.id);
1015
+ entry.parent.tree.write();
1016
+ try {
1017
+ await updateMarketplaceProfile(configPath, profileEntryId, { remove: true });
1018
+ if (needsMarketplacePackageInstall(plugin)) await runProcess("npm", ["uninstall", "--package-lock=false", plugin.packageName], services.launch.cwd);
1019
+ sendJson(response, 200, { uninstalled: true, id: payload.id });
1020
+ } catch (error) {
1021
+ await writeFile(configPath, profileBefore, "utf8").catch(() => {});
1022
+ if (packageJsonBefore !== undefined) await writeFile(packageJsonPath, packageJsonBefore, "utf8").catch(() => {});
1023
+ if (packageLockBefore !== undefined) await writeFile(packageLockPath, packageLockBefore, "utf8").catch(() => {});
1024
+ const options = entry.options as { name: string; config?: unknown; group?: boolean | null };
1025
+ await loader
1026
+ .create({ id: entry.options.id, name: options.name, config: options.config, ...(options.group ? { group: true } : {}) } as never)
1027
+ .catch(() => {});
1028
+ sendJson(response, 502, { error: errorText(error) });
1029
+ }
1030
+ } catch (error) {
1031
+ sendJson(response, 400, { error: errorText(error) });
1032
+ } finally {
1033
+ marketplaceMutationInFlight = false;
1034
+ }
1035
+ },
1036
+ });
231
1037
  const disposeCommands = services.webServer.register({
232
1038
  path: "/api/commands",
233
1039
  handler(_request, response) {
234
1040
  const commands = services.runtime.session.extensionRunner.getRegisteredCommands();
235
- const items = commands.map((command) => ({ name: command.name, invocationName: command.invocationName, description: command.description, source: command.sourceInfo.path }));
1041
+ const items = commands.map((command) => ({
1042
+ name: command.name,
1043
+ invocationName: command.invocationName,
1044
+ description: command.description,
1045
+ source: command.sourceInfo.path,
1046
+ }));
236
1047
  sendJson(response, 200, jsonSafe({ items }));
237
1048
  },
238
1049
  });
1050
+ const disposeWorkspaces = services.webServer.register({
1051
+ path: "/api/workspaces",
1052
+ async handler(_request, response) {
1053
+ try {
1054
+ sendJson(response, 200, { items: await listWorkspaces(activeCwd(services)) });
1055
+ } catch (error) {
1056
+ sendJson(response, 500, { error: errorText(error) });
1057
+ }
1058
+ },
1059
+ });
1060
+ const disposePickDirectory = services.webServer.register({
1061
+ path: "/api/workspaces/pick",
1062
+ async handler(request, response) {
1063
+ if (request.method !== "POST") {
1064
+ sendJson(response, 405, { error: "Method not allowed" });
1065
+ return;
1066
+ }
1067
+ if (process.platform !== "darwin") {
1068
+ sendJson(response, 501, { error: "Native directory picker is only available on macOS" });
1069
+ return;
1070
+ }
1071
+ try {
1072
+ sendJson(response, 200, { path: await pickDirectory() });
1073
+ } catch (error) {
1074
+ sendJson(response, 409, { error: errorText(error) });
1075
+ }
1076
+ },
1077
+ });
239
1078
  const disposeModel = services.webServer.register({
240
1079
  path: "/api/model",
241
1080
  async handler(request, response) {
@@ -272,11 +1111,19 @@ export default {
272
1111
  const disposeFiles = services.webServer.register({
273
1112
  path: "/api/files",
274
1113
  async handler(_request, response) {
275
- const output = await gitStatus(services.launch.cwd);
276
- const items = output.split("\n").map((line) => line.trimEnd()).filter((line) => line.length > 0).map((line) => {
277
- const status = line.slice(0, 2).trim() || "??";
278
- return { path: line.slice(3), status, label: status === "??" ? "untracked" : status.includes("D") ? "deleted" : status.includes("A") ? "added" : "modified" };
279
- });
1114
+ const output = await gitStatus(activeCwd(services));
1115
+ const items = output
1116
+ .split("\n")
1117
+ .map((line) => line.trimEnd())
1118
+ .filter((line) => line.length > 0)
1119
+ .map((line) => {
1120
+ const status = line.slice(0, 2).trim() || "??";
1121
+ return {
1122
+ path: line.slice(3),
1123
+ status,
1124
+ label: status === "??" ? "untracked" : status.includes("D") ? "deleted" : status.includes("A") ? "added" : "modified",
1125
+ };
1126
+ });
280
1127
  sendJson(response, 200, { items });
281
1128
  },
282
1129
  });
@@ -293,7 +1140,7 @@ export default {
293
1140
  sendJson(response, 400, { error: "path is required" });
294
1141
  return;
295
1142
  }
296
- const root = resolve(services.launch.cwd);
1143
+ const root = resolve(activeCwd(services));
297
1144
  const absolute = resolve(root, requested);
298
1145
  const relativePath = relative(root, absolute);
299
1146
  if (isAbsolute(relativePath) || relativePath === ".." || relativePath.startsWith(".." + "/")) {
@@ -312,7 +1159,7 @@ export default {
312
1159
  }
313
1160
  try {
314
1161
  const payload = JSON.parse(await bodyText(request)) as { paths?: unknown; message?: unknown };
315
- const paths = workspacePaths(resolve(services.launch.cwd), payload.paths);
1162
+ const paths = workspacePaths(resolve(activeCwd(services)), payload.paths);
316
1163
  if (paths instanceof Error) {
317
1164
  sendJson(response, 400, { error: paths.message });
318
1165
  return;
@@ -321,7 +1168,7 @@ export default {
321
1168
  sendJson(response, 400, { error: "message is required" });
322
1169
  return;
323
1170
  }
324
- const root = resolve(services.launch.cwd);
1171
+ const root = resolve(activeCwd(services));
325
1172
  const add = await gitCommand(root, ["add", "-A", "--", ...paths]);
326
1173
  if (add.code !== 0) {
327
1174
  sendJson(response, 409, { error: add.stderr.trim() || "Unable to stage workspace files" });
@@ -352,7 +1199,7 @@ export default {
352
1199
  sendJson(response, 400, { error: "confirm must be true to discard workspace changes" });
353
1200
  return;
354
1201
  }
355
- const root = resolve(services.launch.cwd);
1202
+ const root = resolve(activeCwd(services));
356
1203
  const paths = workspacePaths(root, payload.paths);
357
1204
  if (paths instanceof Error) {
358
1205
  sendJson(response, 400, { error: paths.message });
@@ -364,7 +1211,10 @@ export default {
364
1211
  sendJson(response, 409, { error: restore.stderr.trim() || "Unable to restore workspace files" });
365
1212
  return;
366
1213
  }
367
- for (const path of untracked.stdout.split("\n").map((item) => item.trim()).filter(Boolean)) {
1214
+ for (const path of untracked.stdout
1215
+ .split("\n")
1216
+ .map((item) => item.trim())
1217
+ .filter(Boolean)) {
368
1218
  await rm(resolve(root, path), { recursive: true, force: true });
369
1219
  }
370
1220
  sendJson(response, 200, { reverted: true, paths });
@@ -376,7 +1226,12 @@ export default {
376
1226
  const disposeEvents = services.webServer.register({
377
1227
  path: "/api/events",
378
1228
  handler(_request, response) {
379
- response.writeHead(200, { "content-type": "text/event-stream; charset=utf-8", "cache-control": "no-cache, no-store", connection: "keep-alive", "x-accel-buffering": "no" });
1229
+ response.writeHead(200, {
1230
+ "content-type": "text/event-stream; charset=utf-8",
1231
+ "cache-control": "no-cache, no-store",
1232
+ connection: "keep-alive",
1233
+ "x-accel-buffering": "no",
1234
+ });
380
1235
  writeSse(response, { type: "snapshot", sessionId: services.runtime.session.sessionId, events });
381
1236
  eventClients.add(response);
382
1237
  const heartbeat = setInterval(() => {
@@ -448,13 +1303,17 @@ export default {
448
1303
  handler(_request, response) {
449
1304
  const session = services.runtime.session;
450
1305
  const sessionManager = session.sessionManager;
451
- sendJson(response, 200, jsonSafe({
452
- sessionId: session.sessionId,
453
- sessionFile: session.sessionFile,
454
- messages: session.messages,
455
- entries: typeof sessionManager?.getEntries === "function" ? sessionManager.getEntries() : [],
456
- events,
457
- }));
1306
+ sendJson(
1307
+ response,
1308
+ 200,
1309
+ jsonSafe({
1310
+ sessionId: session.sessionId,
1311
+ sessionFile: session.sessionFile,
1312
+ messages: session.messages,
1313
+ entries: typeof sessionManager?.getEntries === "function" ? sessionManager.getEntries() : [],
1314
+ events,
1315
+ }),
1316
+ );
458
1317
  },
459
1318
  });
460
1319
  const disposeNewSession = services.webServer.register({
@@ -469,14 +1328,40 @@ export default {
469
1328
  return;
470
1329
  }
471
1330
  try {
1331
+ const raw = await bodyText(request);
1332
+ const payload = raw.trim() ? (JSON.parse(raw) as { cwd?: unknown }) : {};
1333
+ const currentCwd = activeCwd(services);
1334
+ const requestedCwd = typeof payload.cwd === "string" ? resolve(payload.cwd) : resolve(currentCwd);
1335
+ const workspaces = await listWorkspaces(currentCwd);
1336
+ const workspace =
1337
+ workspaces.find((item) => item.path === requestedCwd) ??
1338
+ (typeof payload.cwd === "string" && (await isDirectory(requestedCwd))
1339
+ ? { path: requestedCwd, branch: "directory", current: false, name: basename(requestedCwd) || requestedCwd }
1340
+ : undefined);
1341
+ if (!workspace) {
1342
+ sendJson(response, 400, { error: "Workspace is not available" });
1343
+ return;
1344
+ }
472
1345
  if (services.runtime.sessionRuntime) {
473
- const result = await services.runtime.sessionRuntime.newSession();
1346
+ let result;
1347
+ if (workspace.current) {
1348
+ result = await runWebSessionChange(services, () => services.runtime.sessionRuntime.newSession());
1349
+ } else {
1350
+ const manager = services.runtime.session.sessionManager;
1351
+ if (!manager || typeof manager.isPersisted !== "function" || !manager.isPersisted()) {
1352
+ sendJson(response, 409, { error: "Workspace switching requires JSONL session storage" });
1353
+ return;
1354
+ }
1355
+ const created = SessionManager.create(workspace.path, manager.getSessionDir());
1356
+ const sessionFile = created.newSession();
1357
+ if (!sessionFile) throw new Error("Unable to create a workspace session");
1358
+ result = await runWebSessionChange(services, () => services.runtime.sessionRuntime.switchSession(sessionFile, { cwdOverride: workspace.path }));
1359
+ }
474
1360
  if (result.cancelled) {
475
1361
  sendJson(response, 409, { error: "Session creation was cancelled by an extension" });
476
1362
  return;
477
1363
  }
478
- }
479
- else {
1364
+ } else {
480
1365
  const session = services.runtime.session;
481
1366
  session.sessionManager.newSession();
482
1367
  session.agent.state.messages = [];
@@ -484,7 +1369,16 @@ export default {
484
1369
  events.length = 0;
485
1370
  const session = services.runtime.session;
486
1371
  for (const client of eventClients) writeSse(client, { type: "session", sessionId: session.sessionId, events: [] });
487
- sendJson(response, 200, jsonSafe({ sessionId: session.sessionId, sessionFile: session.sessionFile, messages: services.runtime.sessionRuntime ? session.messages : [], events: [] }));
1372
+ sendJson(
1373
+ response,
1374
+ 200,
1375
+ jsonSafe({
1376
+ sessionId: session.sessionId,
1377
+ sessionFile: session.sessionFile,
1378
+ messages: services.runtime.sessionRuntime ? session.messages : [],
1379
+ events: [],
1380
+ }),
1381
+ );
488
1382
  } catch (error) {
489
1383
  sendJson(response, 500, { error: errorText(error) });
490
1384
  }
@@ -509,41 +1403,344 @@ export default {
509
1403
  return;
510
1404
  }
511
1405
  const items = await SessionManager.list(services.launch.cwd, manager.getSessionDir());
512
- const target = items.find((item) => (typeof payload.path === "string" && item.path === payload.path) || (typeof payload.sessionId === "string" && item.id === payload.sessionId));
1406
+ const target = items.find(
1407
+ (item) =>
1408
+ (typeof payload.path === "string" && item.path === payload.path) || (typeof payload.sessionId === "string" && item.id === payload.sessionId),
1409
+ );
513
1410
  if (target === undefined) {
514
1411
  sendJson(response, 404, { error: "Session not found" });
515
1412
  return;
516
1413
  }
517
1414
  if (services.runtime.sessionRuntime) {
518
- const result = await services.runtime.sessionRuntime.switchSession(target.path, { cwdOverride: target.cwd });
1415
+ const result = await runWebSessionChange(services, () => services.runtime.sessionRuntime.switchSession(target.path, { cwdOverride: target.cwd }));
519
1416
  if (result.cancelled) {
520
1417
  sendJson(response, 409, { error: "Session switch was cancelled by an extension" });
521
1418
  return;
522
1419
  }
523
- }
524
- else {
1420
+ } else {
525
1421
  manager.setSessionFile(target.path);
526
1422
  if (typeof services.runtime.session.reload === "function") await services.runtime.session.reload();
527
1423
  else services.runtime.session.agent.state.messages = manager.buildSessionContext().messages;
528
1424
  }
529
1425
  events.length = 0;
530
1426
  for (const client of eventClients) writeSse(client, { type: "session", sessionId: services.runtime.session.sessionId, events: [] });
531
- sendJson(response, 200, jsonSafe({ sessionId: services.runtime.session.sessionId, sessionFile: services.runtime.session.sessionFile, messages: services.runtime.session.messages, events: [] }));
1427
+ sendJson(
1428
+ response,
1429
+ 200,
1430
+ jsonSafe({
1431
+ sessionId: services.runtime.session.sessionId,
1432
+ sessionFile: services.runtime.session.sessionFile,
1433
+ messages: services.runtime.session.messages,
1434
+ events: [],
1435
+ }),
1436
+ );
1437
+ } catch (error) {
1438
+ sendJson(response, 400, { error: errorText(error) });
1439
+ }
1440
+ },
1441
+ });
1442
+ const disposeRenameSession = services.webServer.register({
1443
+ path: "/api/session/rename",
1444
+ async handler(request, response) {
1445
+ if (request.method !== "POST") {
1446
+ sendJson(response, 405, { error: "Method not allowed" });
1447
+ return;
1448
+ }
1449
+ try {
1450
+ const payload = JSON.parse(await bodyText(request)) as { path?: unknown; name?: unknown };
1451
+ const manager = services.runtime.session.sessionManager;
1452
+ const path = typeof payload.path === "string" ? payload.path : services.runtime.session.sessionFile;
1453
+ const name = typeof payload.name === "string" ? payload.name.trim() : "";
1454
+ if (!path || !sessionPathInDirectory(path, manager)) {
1455
+ sendJson(response, 400, { error: "Invalid session path" });
1456
+ return;
1457
+ }
1458
+ if (name.length > 120) {
1459
+ sendJson(response, 400, { error: "Session name must be at most 120 characters" });
1460
+ return;
1461
+ }
1462
+ SessionManager.open(path, manager.getSessionDir()).appendSessionInfo(name);
1463
+ sendJson(response, 200, { path, name: name || undefined });
532
1464
  } catch (error) {
533
1465
  sendJson(response, 400, { error: errorText(error) });
534
1466
  }
535
1467
  },
536
1468
  });
1469
+ const disposeDeleteSession = services.webServer.register({
1470
+ path: "/api/session/delete",
1471
+ async handler(request, response) {
1472
+ if (request.method !== "POST") {
1473
+ sendJson(response, 405, { error: "Method not allowed" });
1474
+ return;
1475
+ }
1476
+ try {
1477
+ const payload = JSON.parse(await bodyText(request)) as { path?: unknown; confirm?: unknown };
1478
+ const manager = services.runtime.session.sessionManager;
1479
+ const path = typeof payload.path === "string" ? payload.path : "";
1480
+ if (payload.confirm !== true) {
1481
+ sendJson(response, 400, { error: "confirm must be true to delete a session" });
1482
+ return;
1483
+ }
1484
+ if (!sessionPathInDirectory(path, manager)) {
1485
+ sendJson(response, 400, { error: "Invalid session path" });
1486
+ return;
1487
+ }
1488
+ if (path === services.runtime.session.sessionFile) {
1489
+ if (services.runtime.session.isStreaming) {
1490
+ sendJson(response, 409, { error: "Cannot delete the active session while a prompt is running" });
1491
+ return;
1492
+ }
1493
+ const result = await runWebSessionChange(services, () => services.runtime.sessionRuntime.newSession());
1494
+ if (result.cancelled) {
1495
+ sendJson(response, 409, { error: "Session deletion was cancelled by an extension" });
1496
+ return;
1497
+ }
1498
+ events.length = 0;
1499
+ }
1500
+ await unlink(path);
1501
+ const metadata = await readSessionMetadata(manager);
1502
+ delete metadata[path];
1503
+ await writeSessionMetadata(manager, metadata);
1504
+ sendJson(response, 200, { deleted: true, path, sessionFile: services.runtime.session.sessionFile });
1505
+ } catch (error) {
1506
+ sendJson(response, 400, { error: errorText(error) });
1507
+ }
1508
+ },
1509
+ });
1510
+ const disposeSessionMetadata = services.webServer.register({
1511
+ path: "/api/session/metadata",
1512
+ async handler(request, response) {
1513
+ if (request.method !== "POST") {
1514
+ sendJson(response, 405, { error: "Method not allowed" });
1515
+ return;
1516
+ }
1517
+ try {
1518
+ const payload = JSON.parse(await bodyText(request)) as { path?: unknown; archived?: unknown; pinned?: unknown };
1519
+ const manager = services.runtime.session.sessionManager;
1520
+ const path = typeof payload.path === "string" ? payload.path : "";
1521
+ if (!sessionPathInDirectory(path, manager)) {
1522
+ sendJson(response, 400, { error: "Invalid session path" });
1523
+ return;
1524
+ }
1525
+ const metadata = await readSessionMetadata(manager);
1526
+ const currentMetadata = metadata[path] ?? {};
1527
+ const nextMetadata: SessionMetadata = {
1528
+ ...currentMetadata,
1529
+ ...(payload.archived === undefined ? {} : { archived: payload.archived === true }),
1530
+ ...(payload.pinned === undefined ? {} : { pinned: payload.pinned === true }),
1531
+ };
1532
+ metadata[path] = nextMetadata;
1533
+ await writeSessionMetadata(manager, metadata);
1534
+ sendJson(response, 200, { path, metadata: metadata[path] });
1535
+ } catch (error) {
1536
+ sendJson(response, 400, { error: errorText(error) });
1537
+ }
1538
+ },
1539
+ });
1540
+ const disposeBatchSessions = services.webServer.register({
1541
+ path: "/api/sessions/batch",
1542
+ async handler(request, response) {
1543
+ if (request.method !== "POST") {
1544
+ sendJson(response, 405, { error: "Method not allowed" });
1545
+ return;
1546
+ }
1547
+ try {
1548
+ const payload = JSON.parse(await bodyText(request)) as { action?: unknown; paths?: unknown; confirm?: unknown };
1549
+ const action = payload.action;
1550
+ const paths = Array.isArray(payload.paths) ? payload.paths.filter((path): path is string => typeof path === "string") : [];
1551
+ const manager = services.runtime.session.sessionManager;
1552
+ if (
1553
+ (action !== "delete" && action !== "archive" && action !== "unarchive" && action !== "pin" && action !== "unpin") ||
1554
+ paths.length === 0 ||
1555
+ paths.length > 100
1556
+ ) {
1557
+ sendJson(response, 400, { error: "action and 1-100 session paths are required" });
1558
+ return;
1559
+ }
1560
+ if (action === "delete" && payload.confirm !== true) {
1561
+ sendJson(response, 400, { error: "confirm must be true to delete sessions" });
1562
+ return;
1563
+ }
1564
+ if (paths.some((path) => !sessionPathInDirectory(path, manager))) {
1565
+ sendJson(response, 400, { error: "Invalid session path" });
1566
+ return;
1567
+ }
1568
+ if (action === "delete" && paths.includes(services.runtime.session.sessionFile ?? "")) {
1569
+ sendJson(response, 409, { error: "Cannot batch-delete the active session" });
1570
+ return;
1571
+ }
1572
+ const metadata = await readSessionMetadata(manager);
1573
+ for (const path of paths) {
1574
+ if (action === "delete") {
1575
+ await unlink(path);
1576
+ delete metadata[path];
1577
+ } else {
1578
+ const current = metadata[path] ?? {};
1579
+ metadata[path] = {
1580
+ ...current,
1581
+ ...(action === "archive" || action === "unarchive" ? { archived: action === "archive" } : {}),
1582
+ ...(action === "pin" || action === "unpin" ? { pinned: action === "pin" } : {}),
1583
+ };
1584
+ }
1585
+ }
1586
+ await writeSessionMetadata(manager, metadata);
1587
+ sendJson(response, 200, { action, count: paths.length });
1588
+ } catch (error) {
1589
+ sendJson(response, 400, { error: errorText(error) });
1590
+ }
1591
+ },
1592
+ });
1593
+ const disposeForkSession = services.webServer.register({
1594
+ path: "/api/session/fork",
1595
+ async handler(request, response) {
1596
+ if (request.method !== "POST") {
1597
+ sendJson(response, 405, { error: "Method not allowed" });
1598
+ return;
1599
+ }
1600
+ try {
1601
+ const payload = JSON.parse(await bodyText(request)) as { path?: unknown; cwd?: unknown };
1602
+ const manager = services.runtime.session.sessionManager;
1603
+ const sourcePath = typeof payload.path === "string" ? payload.path : "";
1604
+ if (!sessionPathInDirectory(sourcePath, manager)) {
1605
+ sendJson(response, 400, { error: "Invalid session path" });
1606
+ return;
1607
+ }
1608
+ const sessions = await SessionManager.list(services.launch.cwd, manager.getSessionDir());
1609
+ const source = sessions.find((item) => item.path === sourcePath);
1610
+ if (!source) {
1611
+ sendJson(response, 404, { error: "Session not found" });
1612
+ return;
1613
+ }
1614
+ const targetCwd = typeof payload.cwd === "string" && payload.cwd.trim() ? resolve(payload.cwd) : source.cwd || activeCwd(services);
1615
+ const forked = SessionManager.forkFrom(source.path, targetCwd, manager.getSessionDir());
1616
+ sendJson(response, 200, { sessionId: forked.getSessionId(), sessionFile: forked.getSessionFile(), cwd: targetCwd });
1617
+ } catch (error) {
1618
+ sendJson(response, 400, { error: errorText(error) });
1619
+ }
1620
+ },
1621
+ });
1622
+ const disposeImportSession = services.webServer.register({
1623
+ path: "/api/session/import",
1624
+ async handler(request, response) {
1625
+ if (request.method !== "POST") {
1626
+ sendJson(response, 405, { error: "Method not allowed" });
1627
+ return;
1628
+ }
1629
+ if (services.runtime.session.isStreaming) {
1630
+ sendJson(response, 409, { error: "Cannot import a session while a prompt is running" });
1631
+ return;
1632
+ }
1633
+ try {
1634
+ const payload = JSON.parse(await bodyText(request)) as { path?: unknown; content?: unknown; filename?: unknown; cwd?: unknown };
1635
+ const suppliedPath = typeof payload.path === "string" ? payload.path : "";
1636
+ const content = typeof payload.content === "string" ? payload.content : undefined;
1637
+ if ((!suppliedPath || !isAbsolute(suppliedPath)) && content === undefined) {
1638
+ sendJson(response, 400, { error: "A JSONL file path or file content is required" });
1639
+ return;
1640
+ }
1641
+ const manager = services.runtime.session.sessionManager;
1642
+ if (!manager.isPersisted()) {
1643
+ sendJson(response, 409, { error: "Session importing requires JSONL session storage" });
1644
+ return;
1645
+ }
1646
+ const targetCwd = typeof payload.cwd === "string" && payload.cwd.trim() ? resolve(payload.cwd) : activeCwd(services);
1647
+ const temporaryDirectory = content === undefined ? undefined : await mkdtemp(join(tmpdir(), "pi-harness-import-"));
1648
+ const importPath =
1649
+ suppliedPath ||
1650
+ join(temporaryDirectory as string, basename(typeof payload.filename === "string" && payload.filename.trim() ? payload.filename : "import.jsonl"));
1651
+ try {
1652
+ if (content !== undefined) {
1653
+ if (Buffer.byteLength(content, "utf8") > 10 * 1024 * 1024) {
1654
+ sendJson(response, 413, { error: "Imported session must be at most 10 MiB" });
1655
+ return;
1656
+ }
1657
+ await writeFile(importPath, content, "utf8");
1658
+ }
1659
+ const imported = SessionManager.forkFrom(importPath, targetCwd, manager.getSessionDir());
1660
+ const importedPath = imported.getSessionFile();
1661
+ if (!importedPath) throw new Error("Unable to persist imported session");
1662
+ const result = await runWebSessionChange(services, () => services.runtime.sessionRuntime.switchSession(importedPath, { cwdOverride: targetCwd }));
1663
+ if (result.cancelled) {
1664
+ sendJson(response, 409, { error: "Session import was cancelled by an extension" });
1665
+ return;
1666
+ }
1667
+ events.length = 0;
1668
+ sendJson(response, 200, {
1669
+ sessionId: services.runtime.session.sessionId,
1670
+ sessionFile: services.runtime.session.sessionFile,
1671
+ messages: services.runtime.session.messages.length,
1672
+ });
1673
+ } finally {
1674
+ if (temporaryDirectory) await rm(temporaryDirectory, { recursive: true, force: true });
1675
+ }
1676
+ } catch (error) {
1677
+ sendJson(response, 400, { error: errorText(error) });
1678
+ }
1679
+ },
1680
+ });
1681
+ const disposeExportSession = services.webServer.register({
1682
+ path: "/api/session/export",
1683
+ async handler(request, response) {
1684
+ try {
1685
+ const url = new URL(request.url ?? "/api/session/export", "http://localhost");
1686
+ const manager = services.runtime.session.sessionManager;
1687
+ const path = url.searchParams.get("path") ?? services.runtime.session.sessionFile;
1688
+ if (!path || !sessionPathInDirectory(path, manager)) {
1689
+ sendJson(response, 400, { error: "Invalid session path" });
1690
+ return;
1691
+ }
1692
+ const content = await readFile(path, "utf8");
1693
+ response.writeHead(200, {
1694
+ "content-type": "application/x-ndjson; charset=utf-8",
1695
+ "content-disposition": `attachment; filename="${basename(path)}"`,
1696
+ "cache-control": "no-store",
1697
+ });
1698
+ response.end(content);
1699
+ } catch (error) {
1700
+ sendJson(response, 404, { error: errorText(error) });
1701
+ }
1702
+ },
1703
+ });
537
1704
  const disposeSessions = services.webServer.register({
538
1705
  path: "/api/sessions",
539
1706
  async handler(_request, response) {
540
1707
  try {
541
1708
  const session = services.runtime.session;
542
1709
  const manager = session.sessionManager;
543
- const items = typeof manager.isPersisted === "function" && manager.isPersisted()
544
- ? await SessionManager.list(services.launch.cwd, manager.getSessionDir())
545
- : [];
546
- sendJson(response, 200, jsonSafe({ items: items.map((item) => ({ sessionId: item.id, path: item.path, name: item.name, cwd: item.cwd, created: item.created, modified: item.modified, messageCount: item.messageCount, firstMessage: item.firstMessage })) }));
1710
+ const url = new URL(_request.url ?? "/api/sessions", "http://localhost");
1711
+ const page = Math.max(0, Number.parseInt(url.searchParams.get("page") ?? "0", 10) || 0);
1712
+ const pageSize = Math.min(100, Math.max(1, Number.parseInt(url.searchParams.get("pageSize") ?? "50", 10) || 50));
1713
+ const includeArchived = url.searchParams.get("includeArchived") === "true";
1714
+ const metadata = await readSessionMetadata(manager);
1715
+ const items =
1716
+ typeof manager.isPersisted === "function" && manager.isPersisted() ? await SessionManager.list(services.launch.cwd, manager.getSessionDir()) : [];
1717
+ const filtered = items.filter((item) => includeArchived || metadata[item.path]?.archived !== true);
1718
+ const sorted = filtered.sort(
1719
+ (a, b) => Number(metadata[b.path]?.pinned === true) - Number(metadata[a.path]?.pinned === true) || b.modified.getTime() - a.modified.getTime(),
1720
+ );
1721
+ const paged = sorted.slice(page * pageSize, (page + 1) * pageSize);
1722
+ sendJson(
1723
+ response,
1724
+ 200,
1725
+ jsonSafe({
1726
+ items: paged.map((item) => ({
1727
+ sessionId: item.id,
1728
+ path: item.path,
1729
+ name: item.name,
1730
+ cwd: item.cwd,
1731
+ created: item.created,
1732
+ modified: item.modified,
1733
+ messageCount: item.messageCount,
1734
+ firstMessage: item.firstMessage,
1735
+ archived: metadata[item.path]?.archived === true,
1736
+ pinned: metadata[item.path]?.pinned === true,
1737
+ })),
1738
+ total: sorted.length,
1739
+ page,
1740
+ pageSize,
1741
+ hasNext: (page + 1) * pageSize < sorted.length,
1742
+ }),
1743
+ );
547
1744
  } catch (error) {
548
1745
  sendJson(response, 500, { error: errorText(error) });
549
1746
  }
@@ -551,14 +1748,26 @@ export default {
551
1748
  });
552
1749
  context.effect(() => () => {
553
1750
  disposeStatus();
1751
+ disposeConfig();
1752
+ disposeConfigReload();
1753
+ disposeConfigSource();
554
1754
  disposeEvents();
555
1755
  disposeModels();
556
1756
  disposeProviders();
557
1757
  disposeProviderTest();
558
1758
  disposeProviderRefresh();
1759
+ disposeProviderAdd();
559
1760
  disposePlugins();
1761
+ disposePluginUi();
1762
+ disposePluginPanels();
1763
+ disposeMarketplace();
1764
+ disposeMarketplaceInstall();
1765
+ disposePluginToggle();
1766
+ disposePluginUninstall();
560
1767
  disposeCommands();
561
1768
  disposeModel();
1769
+ disposeWorkspaces();
1770
+ disposePickDirectory();
562
1771
  disposeFiles();
563
1772
  disposeFileDiff();
564
1773
  disposeFileCommit();
@@ -568,6 +1777,13 @@ export default {
568
1777
  disposeSession();
569
1778
  disposeNewSession();
570
1779
  disposeOpenSession();
1780
+ disposeRenameSession();
1781
+ disposeDeleteSession();
1782
+ disposeSessionMetadata();
1783
+ disposeBatchSessions();
1784
+ disposeForkSession();
1785
+ disposeImportSession();
1786
+ disposeExportSession();
571
1787
  disposeSessions();
572
1788
  unsubscribeEvents();
573
1789
  for (const response of eventClients) response.end();