@pi-harness/pi-harness 0.1.2 → 0.1.4

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