@pi-harness/pi-harness 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (911) hide show
  1. package/LICENSE +9 -0
  2. package/README.md +31 -7
  3. package/apps/web/dist/assets/index-BoEwZu6r.css +2 -0
  4. package/apps/web/dist/assets/index-alZn4u37.js +20 -0
  5. package/apps/web/dist/assets/markdown-vendor-DUdMWn0M.js +66 -0
  6. package/apps/web/dist/assets/react-vendor-BD7-wQo9.js +9 -0
  7. package/apps/web/dist/icons/app/android-192.png +0 -0
  8. package/apps/web/dist/icons/app/android-512.png +0 -0
  9. package/apps/web/dist/icons/app/app-blue-512.png +0 -0
  10. package/apps/web/dist/icons/app/app-store-1024.png +0 -0
  11. package/apps/web/dist/icons/app/apple-touch-icon-180.png +0 -0
  12. package/apps/web/dist/icons/app/maskable-512.png +0 -0
  13. package/apps/web/dist/icons/favicon/favicon-16.png +0 -0
  14. package/apps/web/dist/icons/favicon/favicon-32.png +0 -0
  15. package/apps/web/dist/icons/favicon/favicon-48.png +0 -0
  16. package/apps/web/dist/icons/png-blue/pi-256.png +0 -0
  17. package/apps/web/dist/icons/png-blue/pi-512.png +0 -0
  18. package/apps/web/dist/icons/png-ink/pi-1024.png +0 -0
  19. package/apps/web/dist/icons/png-ink/pi-128.png +0 -0
  20. package/apps/web/dist/icons/png-ink/pi-16.png +0 -0
  21. package/apps/web/dist/icons/png-ink/pi-24.png +0 -0
  22. package/apps/web/dist/icons/png-ink/pi-256.png +0 -0
  23. package/apps/web/dist/icons/png-ink/pi-32.png +0 -0
  24. package/apps/web/dist/icons/png-ink/pi-48.png +0 -0
  25. package/apps/web/dist/icons/png-ink/pi-512.png +0 -0
  26. package/apps/web/dist/icons/png-ink/pi-64.png +0 -0
  27. package/apps/web/dist/icons/png-white/pi-1024.png +0 -0
  28. package/apps/web/dist/icons/png-white/pi-128.png +0 -0
  29. package/apps/web/dist/icons/png-white/pi-16.png +0 -0
  30. package/apps/web/dist/icons/png-white/pi-24.png +0 -0
  31. package/apps/web/dist/icons/png-white/pi-256.png +0 -0
  32. package/apps/web/dist/icons/png-white/pi-32.png +0 -0
  33. package/apps/web/dist/icons/png-white/pi-48.png +0 -0
  34. package/apps/web/dist/icons/png-white/pi-512.png +0 -0
  35. package/apps/web/dist/icons/png-white/pi-64.png +0 -0
  36. package/apps/web/dist/icons/social/og-1200x630.png +0 -0
  37. package/apps/web/dist/icons/svg/app-icon-blue.svg +13 -0
  38. package/apps/web/dist/icons/svg/app-icon-ink.svg +13 -0
  39. package/apps/web/dist/icons/svg/favicon.svg +10 -0
  40. package/apps/web/dist/icons/svg/lockup-horizontal.svg +13 -0
  41. package/apps/web/dist/icons/svg/mark-blue.svg +10 -0
  42. package/apps/web/dist/icons/svg/mark-compact.svg +10 -0
  43. package/apps/web/dist/icons/svg/mark-ink.svg +10 -0
  44. package/apps/web/dist/icons/svg/mark-white.svg +10 -0
  45. package/apps/web/dist/icons/svg/mark.svg +10 -0
  46. package/apps/web/dist/index.html +18 -6
  47. package/apps/web/dist/manifest.webmanifest +14 -0
  48. package/apps/web/index.html +14 -4
  49. package/apps/web/package.json +11 -9
  50. package/apps/web/profile/cordis.yml +222 -1
  51. package/apps/web/public/icons/app/android-192.png +0 -0
  52. package/apps/web/public/icons/app/android-512.png +0 -0
  53. package/apps/web/public/icons/app/app-blue-512.png +0 -0
  54. package/apps/web/public/icons/app/app-store-1024.png +0 -0
  55. package/apps/web/public/icons/app/apple-touch-icon-180.png +0 -0
  56. package/apps/web/public/icons/app/maskable-512.png +0 -0
  57. package/apps/web/public/icons/favicon/favicon-16.png +0 -0
  58. package/apps/web/public/icons/favicon/favicon-32.png +0 -0
  59. package/apps/web/public/icons/favicon/favicon-48.png +0 -0
  60. package/apps/web/public/icons/png-blue/pi-256.png +0 -0
  61. package/apps/web/public/icons/png-blue/pi-512.png +0 -0
  62. package/apps/web/public/icons/png-ink/pi-1024.png +0 -0
  63. package/apps/web/public/icons/png-ink/pi-128.png +0 -0
  64. package/apps/web/public/icons/png-ink/pi-16.png +0 -0
  65. package/apps/web/public/icons/png-ink/pi-24.png +0 -0
  66. package/apps/web/public/icons/png-ink/pi-256.png +0 -0
  67. package/apps/web/public/icons/png-ink/pi-32.png +0 -0
  68. package/apps/web/public/icons/png-ink/pi-48.png +0 -0
  69. package/apps/web/public/icons/png-ink/pi-512.png +0 -0
  70. package/apps/web/public/icons/png-ink/pi-64.png +0 -0
  71. package/apps/web/public/icons/png-white/pi-1024.png +0 -0
  72. package/apps/web/public/icons/png-white/pi-128.png +0 -0
  73. package/apps/web/public/icons/png-white/pi-16.png +0 -0
  74. package/apps/web/public/icons/png-white/pi-24.png +0 -0
  75. package/apps/web/public/icons/png-white/pi-256.png +0 -0
  76. package/apps/web/public/icons/png-white/pi-32.png +0 -0
  77. package/apps/web/public/icons/png-white/pi-48.png +0 -0
  78. package/apps/web/public/icons/png-white/pi-512.png +0 -0
  79. package/apps/web/public/icons/png-white/pi-64.png +0 -0
  80. package/apps/web/public/icons/social/og-1200x630.png +0 -0
  81. package/apps/web/public/icons/svg/app-icon-blue.svg +13 -0
  82. package/apps/web/public/icons/svg/app-icon-ink.svg +13 -0
  83. package/apps/web/public/icons/svg/favicon.svg +10 -0
  84. package/apps/web/public/icons/svg/lockup-horizontal.svg +13 -0
  85. package/apps/web/public/icons/svg/mark-blue.svg +10 -0
  86. package/apps/web/public/icons/svg/mark-compact.svg +10 -0
  87. package/apps/web/public/icons/svg/mark-ink.svg +10 -0
  88. package/apps/web/public/icons/svg/mark-white.svg +10 -0
  89. package/apps/web/public/icons/svg/mark.svg +10 -0
  90. package/apps/web/public/manifest.webmanifest +14 -0
  91. package/apps/web/server-dist/bin.js +19 -6
  92. package/apps/web/server-dist/bin.js.map +1 -1
  93. package/apps/web/src/command-palette.ts +28 -7
  94. package/apps/web/src/file-diff.ts +15 -10
  95. package/apps/web/src/main.ts +4 -1
  96. package/apps/web/src/runtime.css +17 -4
  97. package/apps/web/src/server/bin.ts +24 -7
  98. package/apps/web/src/style.css +2604 -7
  99. package/apps/web/src/tailwind.css +25 -0
  100. package/apps/web/tsconfig.build.json +5 -1
  101. package/apps/web/tsconfig.json +1 -1
  102. package/apps/web/vite.config.ts +20 -0
  103. package/package.json +29 -17
  104. package/packages/api-gateway/LICENSE +9 -0
  105. package/packages/api-gateway/dist/index.d.ts.map +1 -1
  106. package/packages/api-gateway/dist/index.js +1202 -37
  107. package/packages/api-gateway/dist/index.js.map +1 -1
  108. package/packages/api-gateway/dist/marketplace-entries/official/agent-teams.json +16 -0
  109. package/packages/api-gateway/dist/marketplace-entries/official/anchored-standard.json +16 -0
  110. package/packages/api-gateway/dist/marketplace-entries/official/annotation.json +16 -0
  111. package/packages/api-gateway/dist/marketplace-entries/official/archify.json +16 -0
  112. package/packages/api-gateway/dist/marketplace-entries/official/at-file.json +16 -0
  113. package/packages/api-gateway/dist/marketplace-entries/official/auto-mode.json +25 -0
  114. package/packages/api-gateway/dist/marketplace-entries/official/better-sidebar.json +16 -0
  115. package/packages/api-gateway/dist/marketplace-entries/official/browser-fetch.json +16 -0
  116. package/packages/api-gateway/dist/marketplace-entries/official/browser-session.json +16 -0
  117. package/packages/api-gateway/dist/marketplace-entries/official/canvas-draw.json +16 -0
  118. package/packages/api-gateway/dist/marketplace-entries/official/change-verifier.json +16 -0
  119. package/packages/api-gateway/dist/marketplace-entries/official/cleaner.json +16 -0
  120. package/packages/api-gateway/dist/marketplace-entries/official/cli-notifier.json +16 -0
  121. package/packages/api-gateway/dist/marketplace-entries/official/code2skill.json +16 -0
  122. package/packages/api-gateway/dist/marketplace-entries/official/colleague-skill.json +16 -0
  123. package/packages/api-gateway/dist/marketplace-entries/official/context-doctor.json +22 -0
  124. package/packages/api-gateway/dist/marketplace-entries/official/context.json +16 -0
  125. package/packages/api-gateway/dist/marketplace-entries/official/cordis-group.json +16 -0
  126. package/packages/api-gateway/dist/marketplace-entries/official/cordis-logger-console.json +16 -0
  127. package/packages/api-gateway/dist/marketplace-entries/official/cordis-timer.json +16 -0
  128. package/packages/api-gateway/dist/marketplace-entries/official/cost-meter.json +16 -0
  129. package/packages/api-gateway/dist/marketplace-entries/official/dependency-checker.json +16 -0
  130. package/packages/api-gateway/dist/marketplace-entries/official/docker-sandbox.json +16 -0
  131. package/packages/api-gateway/dist/marketplace-entries/official/fail-logger.json +16 -0
  132. package/packages/api-gateway/dist/marketplace-entries/official/genui.json +16 -0
  133. package/packages/api-gateway/dist/marketplace-entries/official/git-time-capsule.json +16 -0
  134. package/packages/api-gateway/dist/marketplace-entries/official/graph-memory.json +16 -0
  135. package/packages/api-gateway/dist/marketplace-entries/official/history-compressor.json +25 -0
  136. package/packages/api-gateway/dist/marketplace-entries/official/hol-guard.json +16 -0
  137. package/packages/api-gateway/dist/marketplace-entries/official/i18n-pair.json +16 -0
  138. package/packages/api-gateway/dist/marketplace-entries/official/image-compressor.json +16 -0
  139. package/packages/api-gateway/dist/marketplace-entries/official/llm-verifier.json +16 -0
  140. package/packages/api-gateway/dist/marketplace-entries/official/mcp-client.json +16 -0
  141. package/packages/api-gateway/dist/marketplace-entries/official/mcp-panel.json +16 -0
  142. package/packages/api-gateway/dist/marketplace-entries/official/memory.json +16 -0
  143. package/packages/api-gateway/dist/marketplace-entries/official/mirage-bridge.json +19 -0
  144. package/packages/api-gateway/dist/marketplace-entries/official/mock-server.json +16 -0
  145. package/packages/api-gateway/dist/marketplace-entries/official/modlens.json +16 -0
  146. package/packages/api-gateway/dist/marketplace-entries/official/module-search.json +16 -0
  147. package/packages/api-gateway/dist/marketplace-entries/official/obsidian-sync.json +16 -0
  148. package/packages/api-gateway/dist/marketplace-entries/official/openpets.json +16 -0
  149. package/packages/api-gateway/dist/marketplace-entries/official/plan-execute.json +16 -0
  150. package/packages/api-gateway/dist/marketplace-entries/official/plugin-check.json +16 -0
  151. package/packages/api-gateway/dist/marketplace-entries/official/plugin-dev.json +16 -0
  152. package/packages/api-gateway/dist/marketplace-entries/official/plugin-finder.json +16 -0
  153. package/packages/api-gateway/dist/marketplace-entries/official/plugin-radar.json +16 -0
  154. package/packages/api-gateway/dist/marketplace-entries/official/plugin-stars.json +16 -0
  155. package/packages/api-gateway/dist/marketplace-entries/official/prompt-guard.json +16 -0
  156. package/packages/api-gateway/dist/marketplace-entries/official/prompt-library.json +16 -0
  157. package/packages/api-gateway/dist/marketplace-entries/official/readme-gen.json +16 -0
  158. package/packages/api-gateway/dist/marketplace-entries/official/recall-unread.json +16 -0
  159. package/packages/api-gateway/dist/marketplace-entries/official/reverse-skill.json +16 -0
  160. package/packages/api-gateway/dist/marketplace-entries/official/reviewer-bot.json +22 -0
  161. package/packages/api-gateway/dist/marketplace-entries/official/runtime-doctor.json +16 -0
  162. package/packages/api-gateway/dist/marketplace-entries/official/secure-audit.json +16 -0
  163. package/packages/api-gateway/dist/marketplace-entries/official/session-bookmarks.json +16 -0
  164. package/packages/api-gateway/dist/marketplace-entries/official/session-bridge.json +16 -0
  165. package/packages/api-gateway/dist/marketplace-entries/official/session-compare.json +16 -0
  166. package/packages/api-gateway/dist/marketplace-entries/official/session-export.json +16 -0
  167. package/packages/api-gateway/dist/marketplace-entries/official/session-insights.json +16 -0
  168. package/packages/api-gateway/dist/marketplace-entries/official/session-search.json +16 -0
  169. package/packages/api-gateway/dist/marketplace-entries/official/skill-catalog.json +16 -0
  170. package/packages/api-gateway/dist/marketplace-entries/official/skill-guard.json +16 -0
  171. package/packages/api-gateway/dist/marketplace-entries/official/sql-lens.json +16 -0
  172. package/packages/api-gateway/dist/marketplace-entries/official/synapse.json +16 -0
  173. package/packages/api-gateway/dist/marketplace-entries/official/tab-manager.json +16 -0
  174. package/packages/api-gateway/dist/marketplace-entries/official/taskboard.json +16 -0
  175. package/packages/api-gateway/dist/marketplace-entries/official/telemetry-blocker.json +16 -0
  176. package/packages/api-gateway/dist/marketplace-entries/official/test-harness.json +16 -0
  177. package/packages/api-gateway/dist/marketplace-entries/official/theme-studio.json +19 -0
  178. package/packages/api-gateway/dist/marketplace-entries/official/token-guard.json +16 -0
  179. package/packages/api-gateway/dist/marketplace-entries/official/turn-rewind.json +22 -0
  180. package/packages/api-gateway/dist/marketplace-entries/official/undo-savepoint.json +16 -0
  181. package/packages/api-gateway/dist/marketplace-entries/official/vision-toolkit.json +16 -0
  182. package/packages/api-gateway/dist/marketplace-entries/official/web-research.json +16 -0
  183. package/packages/api-gateway/dist/marketplace-entries/official/workspace-navigator.json +16 -0
  184. package/packages/api-gateway/dist/marketplace-entries/official/workspace-search.json +16 -0
  185. package/packages/api-gateway/dist/marketplace-entries/official/yaml-validator.json +16 -0
  186. package/packages/api-gateway/dist/marketplace.d.ts +60 -0
  187. package/packages/api-gateway/dist/marketplace.d.ts.map +1 -0
  188. package/packages/api-gateway/dist/marketplace.js +235 -0
  189. package/packages/api-gateway/dist/marketplace.js.map +1 -0
  190. package/packages/api-gateway/dist/workspaces.d.ts +8 -0
  191. package/packages/api-gateway/dist/workspaces.d.ts.map +1 -0
  192. package/packages/api-gateway/dist/workspaces.js +14 -0
  193. package/packages/api-gateway/dist/workspaces.js.map +1 -0
  194. package/packages/api-gateway/package.json +20 -10
  195. package/packages/api-gateway/scripts/copy-marketplace-entries.mjs +13 -0
  196. package/packages/api-gateway/src/index.ts +1272 -56
  197. package/packages/api-gateway/src/marketplace-entries/official/agent-teams.json +16 -0
  198. package/packages/api-gateway/src/marketplace-entries/official/anchored-standard.json +16 -0
  199. package/packages/api-gateway/src/marketplace-entries/official/annotation.json +16 -0
  200. package/packages/api-gateway/src/marketplace-entries/official/archify.json +16 -0
  201. package/packages/api-gateway/src/marketplace-entries/official/at-file.json +16 -0
  202. package/packages/api-gateway/src/marketplace-entries/official/auto-mode.json +25 -0
  203. package/packages/api-gateway/src/marketplace-entries/official/better-sidebar.json +16 -0
  204. package/packages/api-gateway/src/marketplace-entries/official/browser-fetch.json +16 -0
  205. package/packages/api-gateway/src/marketplace-entries/official/browser-session.json +16 -0
  206. package/packages/api-gateway/src/marketplace-entries/official/canvas-draw.json +16 -0
  207. package/packages/api-gateway/src/marketplace-entries/official/change-verifier.json +16 -0
  208. package/packages/api-gateway/src/marketplace-entries/official/cleaner.json +16 -0
  209. package/packages/api-gateway/src/marketplace-entries/official/cli-notifier.json +16 -0
  210. package/packages/api-gateway/src/marketplace-entries/official/code2skill.json +16 -0
  211. package/packages/api-gateway/src/marketplace-entries/official/colleague-skill.json +16 -0
  212. package/packages/api-gateway/src/marketplace-entries/official/context-doctor.json +22 -0
  213. package/packages/api-gateway/src/marketplace-entries/official/context.json +16 -0
  214. package/packages/api-gateway/src/marketplace-entries/official/cordis-group.json +16 -0
  215. package/packages/api-gateway/src/marketplace-entries/official/cordis-logger-console.json +16 -0
  216. package/packages/api-gateway/src/marketplace-entries/official/cordis-timer.json +16 -0
  217. package/packages/api-gateway/src/marketplace-entries/official/cost-meter.json +16 -0
  218. package/packages/api-gateway/src/marketplace-entries/official/dependency-checker.json +16 -0
  219. package/packages/api-gateway/src/marketplace-entries/official/docker-sandbox.json +16 -0
  220. package/packages/api-gateway/src/marketplace-entries/official/fail-logger.json +16 -0
  221. package/packages/api-gateway/src/marketplace-entries/official/genui.json +16 -0
  222. package/packages/api-gateway/src/marketplace-entries/official/git-time-capsule.json +16 -0
  223. package/packages/api-gateway/src/marketplace-entries/official/graph-memory.json +16 -0
  224. package/packages/api-gateway/src/marketplace-entries/official/history-compressor.json +25 -0
  225. package/packages/api-gateway/src/marketplace-entries/official/hol-guard.json +16 -0
  226. package/packages/api-gateway/src/marketplace-entries/official/i18n-pair.json +16 -0
  227. package/packages/api-gateway/src/marketplace-entries/official/image-compressor.json +16 -0
  228. package/packages/api-gateway/src/marketplace-entries/official/llm-verifier.json +16 -0
  229. package/packages/api-gateway/src/marketplace-entries/official/mcp-client.json +16 -0
  230. package/packages/api-gateway/src/marketplace-entries/official/mcp-panel.json +16 -0
  231. package/packages/api-gateway/src/marketplace-entries/official/memory.json +16 -0
  232. package/packages/api-gateway/src/marketplace-entries/official/mirage-bridge.json +19 -0
  233. package/packages/api-gateway/src/marketplace-entries/official/mock-server.json +16 -0
  234. package/packages/api-gateway/src/marketplace-entries/official/modlens.json +16 -0
  235. package/packages/api-gateway/src/marketplace-entries/official/module-search.json +16 -0
  236. package/packages/api-gateway/src/marketplace-entries/official/obsidian-sync.json +16 -0
  237. package/packages/api-gateway/src/marketplace-entries/official/openpets.json +16 -0
  238. package/packages/api-gateway/src/marketplace-entries/official/plan-execute.json +16 -0
  239. package/packages/api-gateway/src/marketplace-entries/official/plugin-check.json +16 -0
  240. package/packages/api-gateway/src/marketplace-entries/official/plugin-dev.json +16 -0
  241. package/packages/api-gateway/src/marketplace-entries/official/plugin-finder.json +16 -0
  242. package/packages/api-gateway/src/marketplace-entries/official/plugin-radar.json +16 -0
  243. package/packages/api-gateway/src/marketplace-entries/official/plugin-stars.json +16 -0
  244. package/packages/api-gateway/src/marketplace-entries/official/prompt-guard.json +16 -0
  245. package/packages/api-gateway/src/marketplace-entries/official/prompt-library.json +16 -0
  246. package/packages/api-gateway/src/marketplace-entries/official/readme-gen.json +16 -0
  247. package/packages/api-gateway/src/marketplace-entries/official/recall-unread.json +16 -0
  248. package/packages/api-gateway/src/marketplace-entries/official/reverse-skill.json +16 -0
  249. package/packages/api-gateway/src/marketplace-entries/official/reviewer-bot.json +22 -0
  250. package/packages/api-gateway/src/marketplace-entries/official/runtime-doctor.json +16 -0
  251. package/packages/api-gateway/src/marketplace-entries/official/secure-audit.json +16 -0
  252. package/packages/api-gateway/src/marketplace-entries/official/session-bookmarks.json +16 -0
  253. package/packages/api-gateway/src/marketplace-entries/official/session-bridge.json +16 -0
  254. package/packages/api-gateway/src/marketplace-entries/official/session-compare.json +16 -0
  255. package/packages/api-gateway/src/marketplace-entries/official/session-export.json +16 -0
  256. package/packages/api-gateway/src/marketplace-entries/official/session-insights.json +16 -0
  257. package/packages/api-gateway/src/marketplace-entries/official/session-search.json +16 -0
  258. package/packages/api-gateway/src/marketplace-entries/official/skill-catalog.json +16 -0
  259. package/packages/api-gateway/src/marketplace-entries/official/skill-guard.json +16 -0
  260. package/packages/api-gateway/src/marketplace-entries/official/sql-lens.json +16 -0
  261. package/packages/api-gateway/src/marketplace-entries/official/synapse.json +16 -0
  262. package/packages/api-gateway/src/marketplace-entries/official/tab-manager.json +16 -0
  263. package/packages/api-gateway/src/marketplace-entries/official/taskboard.json +16 -0
  264. package/packages/api-gateway/src/marketplace-entries/official/telemetry-blocker.json +16 -0
  265. package/packages/api-gateway/src/marketplace-entries/official/test-harness.json +16 -0
  266. package/packages/api-gateway/src/marketplace-entries/official/theme-studio.json +19 -0
  267. package/packages/api-gateway/src/marketplace-entries/official/token-guard.json +16 -0
  268. package/packages/api-gateway/src/marketplace-entries/official/turn-rewind.json +22 -0
  269. package/packages/api-gateway/src/marketplace-entries/official/undo-savepoint.json +16 -0
  270. package/packages/api-gateway/src/marketplace-entries/official/vision-toolkit.json +16 -0
  271. package/packages/api-gateway/src/marketplace-entries/official/web-research.json +16 -0
  272. package/packages/api-gateway/src/marketplace-entries/official/workspace-navigator.json +16 -0
  273. package/packages/api-gateway/src/marketplace-entries/official/workspace-search.json +16 -0
  274. package/packages/api-gateway/src/marketplace-entries/official/yaml-validator.json +16 -0
  275. package/packages/api-gateway/src/marketplace.ts +293 -0
  276. package/packages/api-gateway/src/workspaces.ts +20 -0
  277. package/packages/api-gateway/test/index.test.ts +501 -31
  278. package/packages/api-gateway/test/marketplace.test.ts +296 -0
  279. package/packages/api-gateway/test/workspaces.test.ts +13 -0
  280. package/packages/api-gateway/tsconfig.build.json +1 -1
  281. package/packages/api-gateway/tsconfig.json +1 -1
  282. package/packages/bundle-web-app/LICENSE +9 -0
  283. package/packages/bundle-web-app/package.json +19 -9
  284. package/packages/bundle-web-app/tsconfig.build.json +1 -1
  285. package/packages/bundle-web-app/tsconfig.json +1 -1
  286. package/packages/cli/LICENSE +9 -0
  287. package/packages/cli/dist/args.d.ts.map +1 -1
  288. package/packages/cli/dist/args.js +16 -9
  289. package/packages/cli/dist/args.js.map +1 -1
  290. package/packages/cli/dist/bin.js +12 -3
  291. package/packages/cli/dist/bin.js.map +1 -1
  292. package/packages/cli/dist/main.d.ts +1 -0
  293. package/packages/cli/dist/main.d.ts.map +1 -1
  294. package/packages/cli/dist/main.js +49 -9
  295. package/packages/cli/dist/main.js.map +1 -1
  296. package/packages/cli/dist/node-stdio.d.ts +3 -1
  297. package/packages/cli/dist/node-stdio.d.ts.map +1 -1
  298. package/packages/cli/dist/node-stdio.js +91 -13
  299. package/packages/cli/dist/node-stdio.js.map +1 -1
  300. package/packages/cli/dist/relaunch.d.ts.map +1 -1
  301. package/packages/cli/dist/relaunch.js +23 -10
  302. package/packages/cli/dist/relaunch.js.map +1 -1
  303. package/packages/cli/package.json +18 -8
  304. package/packages/cli/src/args.ts +16 -10
  305. package/packages/cli/src/bin.ts +12 -3
  306. package/packages/cli/src/main.ts +54 -10
  307. package/packages/cli/src/node-stdio.ts +85 -13
  308. package/packages/cli/src/relaunch.ts +19 -6
  309. package/packages/cli/test/args.test.ts +22 -3
  310. package/packages/cli/test/binary.test.ts +58 -0
  311. package/packages/cli/test/broken-pipe.test.ts +32 -0
  312. package/packages/cli/test/cli.test.ts +57 -8
  313. package/packages/cli/test/node-stdio.test.ts +89 -0
  314. package/packages/cli/test/relaunch.test.ts +30 -2
  315. package/packages/cli/test/stdin-shutdown.test.ts +59 -0
  316. package/packages/cli/tsconfig.build.json +1 -3
  317. package/packages/cli/tsconfig.json +1 -4
  318. package/packages/client-web/LICENSE +9 -0
  319. package/packages/client-web/dist/annotation-ui.d.ts +11 -0
  320. package/packages/client-web/dist/annotation-ui.d.ts.map +1 -0
  321. package/packages/client-web/dist/annotation-ui.js +24 -0
  322. package/packages/client-web/dist/annotation-ui.js.map +1 -0
  323. package/packages/client-web/dist/browser-session-view.d.ts +7 -0
  324. package/packages/client-web/dist/browser-session-view.d.ts.map +1 -0
  325. package/packages/client-web/dist/browser-session-view.js +8 -0
  326. package/packages/client-web/dist/browser-session-view.js.map +1 -0
  327. package/packages/client-web/dist/control-room.d.ts +169 -2
  328. package/packages/client-web/dist/control-room.d.ts.map +1 -1
  329. package/packages/client-web/dist/control-room.js +156 -11
  330. package/packages/client-web/dist/control-room.js.map +1 -1
  331. package/packages/client-web/dist/design-contract.d.ts.map +1 -1
  332. package/packages/client-web/dist/design-contract.js +178 -19
  333. package/packages/client-web/dist/design-contract.js.map +1 -1
  334. package/packages/client-web/dist/index.d.ts +4 -1
  335. package/packages/client-web/dist/index.d.ts.map +1 -1
  336. package/packages/client-web/dist/index.js +11 -3
  337. package/packages/client-web/dist/index.js.map +1 -1
  338. package/packages/client-web/dist/markdown.d.ts +5 -0
  339. package/packages/client-web/dist/markdown.d.ts.map +1 -0
  340. package/packages/client-web/dist/markdown.js +20 -0
  341. package/packages/client-web/dist/markdown.js.map +1 -0
  342. package/packages/client-web/dist/marketplace-catalog.d.ts +3 -0
  343. package/packages/client-web/dist/marketplace-catalog.d.ts.map +1 -0
  344. package/packages/client-web/dist/marketplace-catalog.js +10 -0
  345. package/packages/client-web/dist/marketplace-catalog.js.map +1 -0
  346. package/packages/client-web/dist/marketplace-navigation.d.ts +19 -0
  347. package/packages/client-web/dist/marketplace-navigation.d.ts.map +1 -0
  348. package/packages/client-web/dist/marketplace-navigation.js +31 -0
  349. package/packages/client-web/dist/marketplace-navigation.js.map +1 -0
  350. package/packages/client-web/dist/message-content.d.ts +9 -0
  351. package/packages/client-web/dist/message-content.d.ts.map +1 -0
  352. package/packages/client-web/dist/message-content.js +54 -0
  353. package/packages/client-web/dist/message-content.js.map +1 -0
  354. package/packages/client-web/dist/plugin-navigation.d.ts +3 -0
  355. package/packages/client-web/dist/plugin-navigation.d.ts.map +1 -0
  356. package/packages/client-web/dist/plugin-navigation.js +10 -0
  357. package/packages/client-web/dist/plugin-navigation.js.map +1 -0
  358. package/packages/client-web/dist/plugin-search.d.ts +2 -0
  359. package/packages/client-web/dist/plugin-search.d.ts.map +1 -0
  360. package/packages/client-web/dist/plugin-search.js +7 -0
  361. package/packages/client-web/dist/plugin-search.js.map +1 -0
  362. package/packages/client-web/dist/plugin-stars-view.d.ts +12 -0
  363. package/packages/client-web/dist/plugin-stars-view.d.ts.map +1 -0
  364. package/packages/client-web/dist/plugin-stars-view.js +8 -0
  365. package/packages/client-web/dist/plugin-stars-view.js.map +1 -0
  366. package/packages/client-web/dist/prompt-completion.d.ts +13 -0
  367. package/packages/client-web/dist/prompt-completion.d.ts.map +1 -0
  368. package/packages/client-web/dist/prompt-completion.js +17 -0
  369. package/packages/client-web/dist/prompt-completion.js.map +1 -0
  370. package/packages/client-web/dist/react-room.d.ts +2 -1
  371. package/packages/client-web/dist/react-room.d.ts.map +1 -1
  372. package/packages/client-web/dist/react-room.js +2349 -84
  373. package/packages/client-web/dist/react-room.js.map +1 -1
  374. package/packages/client-web/dist/runtime-events.d.ts +4 -0
  375. package/packages/client-web/dist/runtime-events.d.ts.map +1 -0
  376. package/packages/client-web/dist/runtime-events.js +29 -0
  377. package/packages/client-web/dist/runtime-events.js.map +1 -0
  378. package/packages/client-web/package.json +19 -7
  379. package/packages/client-web/src/annotation-ui.ts +29 -0
  380. package/packages/client-web/src/browser-session-view.ts +13 -0
  381. package/packages/client-web/src/control-room.ts +359 -10
  382. package/packages/client-web/src/design-contract.ts +248 -26
  383. package/packages/client-web/src/index.ts +17 -4
  384. package/packages/client-web/src/markdown.tsx +22 -0
  385. package/packages/client-web/src/marketplace-catalog.ts +10 -0
  386. package/packages/client-web/src/marketplace-navigation.ts +46 -0
  387. package/packages/client-web/src/message-content.ts +51 -0
  388. package/packages/client-web/src/plugin-navigation.ts +9 -0
  389. package/packages/client-web/src/plugin-search.ts +5 -0
  390. package/packages/client-web/src/plugin-stars-view.ts +19 -0
  391. package/packages/client-web/src/prompt-completion.ts +24 -0
  392. package/packages/client-web/src/react-room.tsx +7365 -49
  393. package/packages/client-web/src/runtime-events.ts +29 -0
  394. package/packages/client-web/test/annotation-ui.test.ts +21 -0
  395. package/packages/client-web/test/browser-session-view.test.ts +17 -0
  396. package/packages/client-web/test/design-contract.test.ts +46 -1
  397. package/packages/client-web/test/marketplace-catalog.test.ts +52 -0
  398. package/packages/client-web/test/message-content.test.ts +43 -0
  399. package/packages/client-web/test/plugin-navigation.test.ts +16 -0
  400. package/packages/client-web/test/plugin-search.test.ts +22 -0
  401. package/packages/client-web/test/plugin-stars-view.test.ts +20 -0
  402. package/packages/client-web/test/prompt-completion.test.ts +21 -0
  403. package/packages/client-web/test/runtime-events.test.ts +28 -0
  404. package/packages/client-web/tsconfig.build.json +13 -1
  405. package/packages/client-web/tsconfig.json +11 -1
  406. package/packages/core/LICENSE +9 -0
  407. package/packages/core/dist/boot.d.ts.map +1 -1
  408. package/packages/core/dist/boot.js +42 -3
  409. package/packages/core/dist/boot.js.map +1 -1
  410. package/packages/core/dist/config.d.ts +2 -0
  411. package/packages/core/dist/config.d.ts.map +1 -0
  412. package/packages/core/dist/config.js +8 -0
  413. package/packages/core/dist/config.js.map +1 -0
  414. package/packages/core/dist/http.d.ts +8 -0
  415. package/packages/core/dist/http.d.ts.map +1 -0
  416. package/packages/core/dist/http.js +27 -0
  417. package/packages/core/dist/http.js.map +1 -0
  418. package/packages/core/dist/index.d.ts +2 -0
  419. package/packages/core/dist/index.d.ts.map +1 -1
  420. package/packages/core/dist/index.js +2 -0
  421. package/packages/core/dist/index.js.map +1 -1
  422. package/packages/core/dist/plugins/agent-teams.d.ts +17 -0
  423. package/packages/core/dist/plugins/agent-teams.d.ts.map +1 -0
  424. package/packages/core/dist/plugins/agent-teams.js +298 -0
  425. package/packages/core/dist/plugins/agent-teams.js.map +1 -0
  426. package/packages/core/dist/plugins/anchored-standard.d.ts +14 -0
  427. package/packages/core/dist/plugins/anchored-standard.d.ts.map +1 -0
  428. package/packages/core/dist/plugins/anchored-standard.js +84 -0
  429. package/packages/core/dist/plugins/anchored-standard.js.map +1 -0
  430. package/packages/core/dist/plugins/annotation.d.ts +18 -0
  431. package/packages/core/dist/plugins/annotation.d.ts.map +1 -0
  432. package/packages/core/dist/plugins/annotation.js +94 -0
  433. package/packages/core/dist/plugins/annotation.js.map +1 -0
  434. package/packages/core/dist/plugins/archify.d.ts +23 -0
  435. package/packages/core/dist/plugins/archify.d.ts.map +1 -0
  436. package/packages/core/dist/plugins/archify.js +98 -0
  437. package/packages/core/dist/plugins/archify.js.map +1 -0
  438. package/packages/core/dist/plugins/at-file.d.ts +8 -0
  439. package/packages/core/dist/plugins/at-file.d.ts.map +1 -0
  440. package/packages/core/dist/plugins/at-file.js +52 -0
  441. package/packages/core/dist/plugins/at-file.js.map +1 -0
  442. package/packages/core/dist/plugins/auto-mode.d.ts +15 -0
  443. package/packages/core/dist/plugins/auto-mode.d.ts.map +1 -0
  444. package/packages/core/dist/plugins/auto-mode.js +114 -0
  445. package/packages/core/dist/plugins/auto-mode.js.map +1 -0
  446. package/packages/core/dist/plugins/better-sidebar.d.ts +37 -0
  447. package/packages/core/dist/plugins/better-sidebar.d.ts.map +1 -0
  448. package/packages/core/dist/plugins/better-sidebar.js +89 -0
  449. package/packages/core/dist/plugins/better-sidebar.js.map +1 -0
  450. package/packages/core/dist/plugins/browser-fetch.d.ts +14 -0
  451. package/packages/core/dist/plugins/browser-fetch.d.ts.map +1 -0
  452. package/packages/core/dist/plugins/browser-fetch.js +167 -0
  453. package/packages/core/dist/plugins/browser-fetch.js.map +1 -0
  454. package/packages/core/dist/plugins/browser-session.d.ts +14 -0
  455. package/packages/core/dist/plugins/browser-session.d.ts.map +1 -0
  456. package/packages/core/dist/plugins/browser-session.js +265 -0
  457. package/packages/core/dist/plugins/browser-session.js.map +1 -0
  458. package/packages/core/dist/plugins/canvas-draw.d.ts +8 -0
  459. package/packages/core/dist/plugins/canvas-draw.d.ts.map +1 -0
  460. package/packages/core/dist/plugins/canvas-draw.js +88 -0
  461. package/packages/core/dist/plugins/canvas-draw.js.map +1 -0
  462. package/packages/core/dist/plugins/change-verifier.d.ts +8 -0
  463. package/packages/core/dist/plugins/change-verifier.d.ts.map +1 -0
  464. package/packages/core/dist/plugins/change-verifier.js +67 -0
  465. package/packages/core/dist/plugins/change-verifier.js.map +1 -0
  466. package/packages/core/dist/plugins/cleaner.d.ts +8 -0
  467. package/packages/core/dist/plugins/cleaner.d.ts.map +1 -0
  468. package/packages/core/dist/plugins/cleaner.js +56 -0
  469. package/packages/core/dist/plugins/cleaner.js.map +1 -0
  470. package/packages/core/dist/plugins/cli-notifier.d.ts +15 -0
  471. package/packages/core/dist/plugins/cli-notifier.d.ts.map +1 -0
  472. package/packages/core/dist/plugins/cli-notifier.js +110 -0
  473. package/packages/core/dist/plugins/cli-notifier.js.map +1 -0
  474. package/packages/core/dist/plugins/code2skill.d.ts +8 -0
  475. package/packages/core/dist/plugins/code2skill.d.ts.map +1 -0
  476. package/packages/core/dist/plugins/code2skill.js +95 -0
  477. package/packages/core/dist/plugins/code2skill.js.map +1 -0
  478. package/packages/core/dist/plugins/colleague-skill.d.ts +27 -0
  479. package/packages/core/dist/plugins/colleague-skill.d.ts.map +1 -0
  480. package/packages/core/dist/plugins/colleague-skill.js +99 -0
  481. package/packages/core/dist/plugins/colleague-skill.js.map +1 -0
  482. package/packages/core/dist/plugins/context-doctor.d.ts +30 -0
  483. package/packages/core/dist/plugins/context-doctor.d.ts.map +1 -0
  484. package/packages/core/dist/plugins/context-doctor.js +95 -0
  485. package/packages/core/dist/plugins/context-doctor.js.map +1 -0
  486. package/packages/core/dist/plugins/context.d.ts +8 -0
  487. package/packages/core/dist/plugins/context.d.ts.map +1 -0
  488. package/packages/core/dist/plugins/context.js +87 -0
  489. package/packages/core/dist/plugins/context.js.map +1 -0
  490. package/packages/core/dist/plugins/cost-meter.d.ts +32 -0
  491. package/packages/core/dist/plugins/cost-meter.d.ts.map +1 -0
  492. package/packages/core/dist/plugins/cost-meter.js +204 -0
  493. package/packages/core/dist/plugins/cost-meter.js.map +1 -0
  494. package/packages/core/dist/plugins/dependency-checker.d.ts +27 -0
  495. package/packages/core/dist/plugins/dependency-checker.d.ts.map +1 -0
  496. package/packages/core/dist/plugins/dependency-checker.js +221 -0
  497. package/packages/core/dist/plugins/dependency-checker.js.map +1 -0
  498. package/packages/core/dist/plugins/docker-sandbox.d.ts +8 -0
  499. package/packages/core/dist/plugins/docker-sandbox.d.ts.map +1 -0
  500. package/packages/core/dist/plugins/docker-sandbox.js +102 -0
  501. package/packages/core/dist/plugins/docker-sandbox.js.map +1 -0
  502. package/packages/core/dist/plugins/fail-logger.d.ts +8 -0
  503. package/packages/core/dist/plugins/fail-logger.d.ts.map +1 -0
  504. package/packages/core/dist/plugins/fail-logger.js +51 -0
  505. package/packages/core/dist/plugins/fail-logger.js.map +1 -0
  506. package/packages/core/dist/plugins/genui.d.ts +8 -0
  507. package/packages/core/dist/plugins/genui.d.ts.map +1 -0
  508. package/packages/core/dist/plugins/genui.js +79 -0
  509. package/packages/core/dist/plugins/genui.js.map +1 -0
  510. package/packages/core/dist/plugins/git-time-capsule.d.ts +9 -0
  511. package/packages/core/dist/plugins/git-time-capsule.d.ts.map +1 -0
  512. package/packages/core/dist/plugins/git-time-capsule.js +90 -0
  513. package/packages/core/dist/plugins/git-time-capsule.js.map +1 -0
  514. package/packages/core/dist/plugins/graph-memory.d.ts +16 -0
  515. package/packages/core/dist/plugins/graph-memory.d.ts.map +1 -0
  516. package/packages/core/dist/plugins/graph-memory.js +382 -0
  517. package/packages/core/dist/plugins/graph-memory.js.map +1 -0
  518. package/packages/core/dist/plugins/history-compressor.d.ts +15 -0
  519. package/packages/core/dist/plugins/history-compressor.d.ts.map +1 -0
  520. package/packages/core/dist/plugins/history-compressor.js +80 -0
  521. package/packages/core/dist/plugins/history-compressor.js.map +1 -0
  522. package/packages/core/dist/plugins/hol-guard.d.ts +29 -0
  523. package/packages/core/dist/plugins/hol-guard.d.ts.map +1 -0
  524. package/packages/core/dist/plugins/hol-guard.js +139 -0
  525. package/packages/core/dist/plugins/hol-guard.js.map +1 -0
  526. package/packages/core/dist/plugins/i18n-pair.d.ts +8 -0
  527. package/packages/core/dist/plugins/i18n-pair.d.ts.map +1 -0
  528. package/packages/core/dist/plugins/i18n-pair.js +76 -0
  529. package/packages/core/dist/plugins/i18n-pair.js.map +1 -0
  530. package/packages/core/dist/plugins/image-compressor.d.ts +8 -0
  531. package/packages/core/dist/plugins/image-compressor.d.ts.map +1 -0
  532. package/packages/core/dist/plugins/image-compressor.js +150 -0
  533. package/packages/core/dist/plugins/image-compressor.js.map +1 -0
  534. package/packages/core/dist/plugins/llm-verifier.d.ts +42 -0
  535. package/packages/core/dist/plugins/llm-verifier.d.ts.map +1 -0
  536. package/packages/core/dist/plugins/llm-verifier.js +128 -0
  537. package/packages/core/dist/plugins/llm-verifier.js.map +1 -0
  538. package/packages/core/dist/plugins/mcp-client.d.ts +19 -0
  539. package/packages/core/dist/plugins/mcp-client.d.ts.map +1 -0
  540. package/packages/core/dist/plugins/mcp-client.js +534 -0
  541. package/packages/core/dist/plugins/mcp-client.js.map +1 -0
  542. package/packages/core/dist/plugins/mcp-panel.d.ts +14 -0
  543. package/packages/core/dist/plugins/mcp-panel.d.ts.map +1 -0
  544. package/packages/core/dist/plugins/mcp-panel.js +180 -0
  545. package/packages/core/dist/plugins/mcp-panel.js.map +1 -0
  546. package/packages/core/dist/plugins/memory.d.ts +15 -0
  547. package/packages/core/dist/plugins/memory.d.ts.map +1 -0
  548. package/packages/core/dist/plugins/memory.js +161 -0
  549. package/packages/core/dist/plugins/memory.js.map +1 -0
  550. package/packages/core/dist/plugins/mirage-bridge.d.ts +23 -0
  551. package/packages/core/dist/plugins/mirage-bridge.d.ts.map +1 -0
  552. package/packages/core/dist/plugins/mirage-bridge.js +149 -0
  553. package/packages/core/dist/plugins/mirage-bridge.js.map +1 -0
  554. package/packages/core/dist/plugins/mock-server.d.ts +22 -0
  555. package/packages/core/dist/plugins/mock-server.d.ts.map +1 -0
  556. package/packages/core/dist/plugins/mock-server.js +149 -0
  557. package/packages/core/dist/plugins/mock-server.js.map +1 -0
  558. package/packages/core/dist/plugins/model.d.ts +1 -1
  559. package/packages/core/dist/plugins/model.d.ts.map +1 -1
  560. package/packages/core/dist/plugins/model.js +3 -1
  561. package/packages/core/dist/plugins/model.js.map +1 -1
  562. package/packages/core/dist/plugins/models.d.ts.map +1 -1
  563. package/packages/core/dist/plugins/models.js +5 -2
  564. package/packages/core/dist/plugins/models.js.map +1 -1
  565. package/packages/core/dist/plugins/modlens.d.ts +8 -0
  566. package/packages/core/dist/plugins/modlens.d.ts.map +1 -0
  567. package/packages/core/dist/plugins/modlens.js +63 -0
  568. package/packages/core/dist/plugins/modlens.js.map +1 -0
  569. package/packages/core/dist/plugins/module-search.d.ts +27 -0
  570. package/packages/core/dist/plugins/module-search.d.ts.map +1 -0
  571. package/packages/core/dist/plugins/module-search.js +174 -0
  572. package/packages/core/dist/plugins/module-search.js.map +1 -0
  573. package/packages/core/dist/plugins/obsidian-sync.d.ts +14 -0
  574. package/packages/core/dist/plugins/obsidian-sync.d.ts.map +1 -0
  575. package/packages/core/dist/plugins/obsidian-sync.js +79 -0
  576. package/packages/core/dist/plugins/obsidian-sync.js.map +1 -0
  577. package/packages/core/dist/plugins/openpets.d.ts +14 -0
  578. package/packages/core/dist/plugins/openpets.d.ts.map +1 -0
  579. package/packages/core/dist/plugins/openpets.js +99 -0
  580. package/packages/core/dist/plugins/openpets.js.map +1 -0
  581. package/packages/core/dist/plugins/plan-execute.d.ts +8 -0
  582. package/packages/core/dist/plugins/plan-execute.d.ts.map +1 -0
  583. package/packages/core/dist/plugins/plan-execute.js +70 -0
  584. package/packages/core/dist/plugins/plan-execute.js.map +1 -0
  585. package/packages/core/dist/plugins/plugin-check.d.ts +38 -0
  586. package/packages/core/dist/plugins/plugin-check.d.ts.map +1 -0
  587. package/packages/core/dist/plugins/plugin-check.js +227 -0
  588. package/packages/core/dist/plugins/plugin-check.js.map +1 -0
  589. package/packages/core/dist/plugins/plugin-dev.d.ts +8 -0
  590. package/packages/core/dist/plugins/plugin-dev.d.ts.map +1 -0
  591. package/packages/core/dist/plugins/plugin-dev.js +44 -0
  592. package/packages/core/dist/plugins/plugin-dev.js.map +1 -0
  593. package/packages/core/dist/plugins/plugin-finder.d.ts +16 -0
  594. package/packages/core/dist/plugins/plugin-finder.d.ts.map +1 -0
  595. package/packages/core/dist/plugins/plugin-finder.js +98 -0
  596. package/packages/core/dist/plugins/plugin-finder.js.map +1 -0
  597. package/packages/core/dist/plugins/plugin-radar.d.ts +29 -0
  598. package/packages/core/dist/plugins/plugin-radar.d.ts.map +1 -0
  599. package/packages/core/dist/plugins/plugin-radar.js +146 -0
  600. package/packages/core/dist/plugins/plugin-radar.js.map +1 -0
  601. package/packages/core/dist/plugins/plugin-stars.d.ts +45 -0
  602. package/packages/core/dist/plugins/plugin-stars.d.ts.map +1 -0
  603. package/packages/core/dist/plugins/plugin-stars.js +165 -0
  604. package/packages/core/dist/plugins/plugin-stars.js.map +1 -0
  605. package/packages/core/dist/plugins/prompt-guard.d.ts +8 -0
  606. package/packages/core/dist/plugins/prompt-guard.d.ts.map +1 -0
  607. package/packages/core/dist/plugins/prompt-guard.js +114 -0
  608. package/packages/core/dist/plugins/prompt-guard.js.map +1 -0
  609. package/packages/core/dist/plugins/prompt-library.d.ts +25 -0
  610. package/packages/core/dist/plugins/prompt-library.d.ts.map +1 -0
  611. package/packages/core/dist/plugins/prompt-library.js +142 -0
  612. package/packages/core/dist/plugins/prompt-library.js.map +1 -0
  613. package/packages/core/dist/plugins/readme-gen.d.ts +25 -0
  614. package/packages/core/dist/plugins/readme-gen.d.ts.map +1 -0
  615. package/packages/core/dist/plugins/readme-gen.js +139 -0
  616. package/packages/core/dist/plugins/readme-gen.js.map +1 -0
  617. package/packages/core/dist/plugins/recall-unread.d.ts +24 -0
  618. package/packages/core/dist/plugins/recall-unread.d.ts.map +1 -0
  619. package/packages/core/dist/plugins/recall-unread.js +124 -0
  620. package/packages/core/dist/plugins/recall-unread.js.map +1 -0
  621. package/packages/core/dist/plugins/resources.d.ts +1 -0
  622. package/packages/core/dist/plugins/resources.d.ts.map +1 -1
  623. package/packages/core/dist/plugins/resources.js +31 -22
  624. package/packages/core/dist/plugins/resources.js.map +1 -1
  625. package/packages/core/dist/plugins/reverse-skill.d.ts +23 -0
  626. package/packages/core/dist/plugins/reverse-skill.d.ts.map +1 -0
  627. package/packages/core/dist/plugins/reverse-skill.js +60 -0
  628. package/packages/core/dist/plugins/reverse-skill.js.map +1 -0
  629. package/packages/core/dist/plugins/reviewer-bot.d.ts +14 -0
  630. package/packages/core/dist/plugins/reviewer-bot.d.ts.map +1 -0
  631. package/packages/core/dist/plugins/reviewer-bot.js +133 -0
  632. package/packages/core/dist/plugins/reviewer-bot.js.map +1 -0
  633. package/packages/core/dist/plugins/runtime-doctor.d.ts +33 -0
  634. package/packages/core/dist/plugins/runtime-doctor.d.ts.map +1 -0
  635. package/packages/core/dist/plugins/runtime-doctor.js +114 -0
  636. package/packages/core/dist/plugins/runtime-doctor.js.map +1 -0
  637. package/packages/core/dist/plugins/runtime.d.ts.map +1 -1
  638. package/packages/core/dist/plugins/runtime.js +63 -14
  639. package/packages/core/dist/plugins/runtime.js.map +1 -1
  640. package/packages/core/dist/plugins/secure-audit.d.ts +31 -0
  641. package/packages/core/dist/plugins/secure-audit.d.ts.map +1 -0
  642. package/packages/core/dist/plugins/secure-audit.js +121 -0
  643. package/packages/core/dist/plugins/secure-audit.js.map +1 -0
  644. package/packages/core/dist/plugins/session-bookmarks.d.ts +15 -0
  645. package/packages/core/dist/plugins/session-bookmarks.d.ts.map +1 -0
  646. package/packages/core/dist/plugins/session-bookmarks.js +87 -0
  647. package/packages/core/dist/plugins/session-bookmarks.js.map +1 -0
  648. package/packages/core/dist/plugins/session-bridge.d.ts +44 -0
  649. package/packages/core/dist/plugins/session-bridge.d.ts.map +1 -0
  650. package/packages/core/dist/plugins/session-bridge.js +265 -0
  651. package/packages/core/dist/plugins/session-bridge.js.map +1 -0
  652. package/packages/core/dist/plugins/session-compare.d.ts +33 -0
  653. package/packages/core/dist/plugins/session-compare.d.ts.map +1 -0
  654. package/packages/core/dist/plugins/session-compare.js +150 -0
  655. package/packages/core/dist/plugins/session-compare.js.map +1 -0
  656. package/packages/core/dist/plugins/session-export.d.ts +9 -0
  657. package/packages/core/dist/plugins/session-export.d.ts.map +1 -0
  658. package/packages/core/dist/plugins/session-export.js +93 -0
  659. package/packages/core/dist/plugins/session-export.js.map +1 -0
  660. package/packages/core/dist/plugins/session-insights.d.ts +8 -0
  661. package/packages/core/dist/plugins/session-insights.d.ts.map +1 -0
  662. package/packages/core/dist/plugins/session-insights.js +47 -0
  663. package/packages/core/dist/plugins/session-insights.js.map +1 -0
  664. package/packages/core/dist/plugins/session-search.d.ts +20 -0
  665. package/packages/core/dist/plugins/session-search.d.ts.map +1 -0
  666. package/packages/core/dist/plugins/session-search.js +122 -0
  667. package/packages/core/dist/plugins/session-search.js.map +1 -0
  668. package/packages/core/dist/plugins/session.d.ts.map +1 -1
  669. package/packages/core/dist/plugins/session.js +4 -2
  670. package/packages/core/dist/plugins/session.js.map +1 -1
  671. package/packages/core/dist/plugins/skill-catalog.d.ts +26 -0
  672. package/packages/core/dist/plugins/skill-catalog.d.ts.map +1 -0
  673. package/packages/core/dist/plugins/skill-catalog.js +97 -0
  674. package/packages/core/dist/plugins/skill-catalog.js.map +1 -0
  675. package/packages/core/dist/plugins/skill-guard.d.ts +26 -0
  676. package/packages/core/dist/plugins/skill-guard.d.ts.map +1 -0
  677. package/packages/core/dist/plugins/skill-guard.js +139 -0
  678. package/packages/core/dist/plugins/skill-guard.js.map +1 -0
  679. package/packages/core/dist/plugins/sql-lens.d.ts +8 -0
  680. package/packages/core/dist/plugins/sql-lens.d.ts.map +1 -0
  681. package/packages/core/dist/plugins/sql-lens.js +85 -0
  682. package/packages/core/dist/plugins/sql-lens.js.map +1 -0
  683. package/packages/core/dist/plugins/stdio.d.ts +1 -1
  684. package/packages/core/dist/plugins/stdio.d.ts.map +1 -1
  685. package/packages/core/dist/plugins/stdio.js +3 -1
  686. package/packages/core/dist/plugins/stdio.js.map +1 -1
  687. package/packages/core/dist/plugins/synapse.d.ts +38 -0
  688. package/packages/core/dist/plugins/synapse.d.ts.map +1 -0
  689. package/packages/core/dist/plugins/synapse.js +93 -0
  690. package/packages/core/dist/plugins/synapse.js.map +1 -0
  691. package/packages/core/dist/plugins/tab-manager.d.ts +8 -0
  692. package/packages/core/dist/plugins/tab-manager.d.ts.map +1 -0
  693. package/packages/core/dist/plugins/tab-manager.js +135 -0
  694. package/packages/core/dist/plugins/tab-manager.js.map +1 -0
  695. package/packages/core/dist/plugins/taskboard.d.ts +15 -0
  696. package/packages/core/dist/plugins/taskboard.d.ts.map +1 -0
  697. package/packages/core/dist/plugins/taskboard.js +347 -0
  698. package/packages/core/dist/plugins/taskboard.js.map +1 -0
  699. package/packages/core/dist/plugins/telemetry-blocker.d.ts +8 -0
  700. package/packages/core/dist/plugins/telemetry-blocker.d.ts.map +1 -0
  701. package/packages/core/dist/plugins/telemetry-blocker.js +57 -0
  702. package/packages/core/dist/plugins/telemetry-blocker.js.map +1 -0
  703. package/packages/core/dist/plugins/test-harness.d.ts +8 -0
  704. package/packages/core/dist/plugins/test-harness.d.ts.map +1 -0
  705. package/packages/core/dist/plugins/test-harness.js +64 -0
  706. package/packages/core/dist/plugins/test-harness.js.map +1 -0
  707. package/packages/core/dist/plugins/theme-studio.d.ts +29 -0
  708. package/packages/core/dist/plugins/theme-studio.d.ts.map +1 -0
  709. package/packages/core/dist/plugins/theme-studio.js +141 -0
  710. package/packages/core/dist/plugins/theme-studio.js.map +1 -0
  711. package/packages/core/dist/plugins/token-guard.d.ts +15 -0
  712. package/packages/core/dist/plugins/token-guard.d.ts.map +1 -0
  713. package/packages/core/dist/plugins/token-guard.js +78 -0
  714. package/packages/core/dist/plugins/token-guard.js.map +1 -0
  715. package/packages/core/dist/plugins/tools.d.ts.map +1 -1
  716. package/packages/core/dist/plugins/tools.js +5 -2
  717. package/packages/core/dist/plugins/tools.js.map +1 -1
  718. package/packages/core/dist/plugins/turn-rewind.d.ts +19 -0
  719. package/packages/core/dist/plugins/turn-rewind.d.ts.map +1 -0
  720. package/packages/core/dist/plugins/turn-rewind.js +74 -0
  721. package/packages/core/dist/plugins/turn-rewind.js.map +1 -0
  722. package/packages/core/dist/plugins/undo-savepoint.d.ts +17 -0
  723. package/packages/core/dist/plugins/undo-savepoint.d.ts.map +1 -0
  724. package/packages/core/dist/plugins/undo-savepoint.js +247 -0
  725. package/packages/core/dist/plugins/undo-savepoint.js.map +1 -0
  726. package/packages/core/dist/plugins/vision-toolkit.d.ts +17 -0
  727. package/packages/core/dist/plugins/vision-toolkit.d.ts.map +1 -0
  728. package/packages/core/dist/plugins/vision-toolkit.js +145 -0
  729. package/packages/core/dist/plugins/vision-toolkit.js.map +1 -0
  730. package/packages/core/dist/plugins/web-research.d.ts +17 -0
  731. package/packages/core/dist/plugins/web-research.d.ts.map +1 -0
  732. package/packages/core/dist/plugins/web-research.js +275 -0
  733. package/packages/core/dist/plugins/web-research.js.map +1 -0
  734. package/packages/core/dist/plugins/workspace-navigator.d.ts +36 -0
  735. package/packages/core/dist/plugins/workspace-navigator.d.ts.map +1 -0
  736. package/packages/core/dist/plugins/workspace-navigator.js +150 -0
  737. package/packages/core/dist/plugins/workspace-navigator.js.map +1 -0
  738. package/packages/core/dist/plugins/workspace-search.d.ts +8 -0
  739. package/packages/core/dist/plugins/workspace-search.d.ts.map +1 -0
  740. package/packages/core/dist/plugins/workspace-search.js +134 -0
  741. package/packages/core/dist/plugins/workspace-search.js.map +1 -0
  742. package/packages/core/dist/plugins/yaml-validator.d.ts +8 -0
  743. package/packages/core/dist/plugins/yaml-validator.d.ts.map +1 -0
  744. package/packages/core/dist/plugins/yaml-validator.js +94 -0
  745. package/packages/core/dist/plugins/yaml-validator.js.map +1 -0
  746. package/packages/core/dist/profile.d.ts +1 -0
  747. package/packages/core/dist/profile.d.ts.map +1 -1
  748. package/packages/core/dist/profile.js +3 -0
  749. package/packages/core/dist/profile.js.map +1 -1
  750. package/packages/core/dist/runtime.d.ts.map +1 -1
  751. package/packages/core/dist/runtime.js +13 -4
  752. package/packages/core/dist/runtime.js.map +1 -1
  753. package/packages/core/dist/services.d.ts +55 -0
  754. package/packages/core/dist/services.d.ts.map +1 -1
  755. package/packages/core/dist/services.js +58 -2
  756. package/packages/core/dist/services.js.map +1 -1
  757. package/packages/core/dist/stdio.d.ts +13 -2
  758. package/packages/core/dist/stdio.d.ts.map +1 -1
  759. package/packages/core/dist/stdio.js +75 -9
  760. package/packages/core/dist/stdio.js.map +1 -1
  761. package/packages/core/dist/workspace-path.d.ts +12 -0
  762. package/packages/core/dist/workspace-path.d.ts.map +1 -0
  763. package/packages/core/dist/workspace-path.js +62 -0
  764. package/packages/core/dist/workspace-path.js.map +1 -0
  765. package/packages/core/package.json +18 -8
  766. package/packages/core/profiles/default/cordis.yml +85 -0
  767. package/packages/core/profiles/development/cordis.yml +1 -1
  768. package/packages/core/src/boot.ts +38 -2
  769. package/packages/core/src/config.ts +5 -0
  770. package/packages/core/src/http.ts +32 -0
  771. package/packages/core/src/index.ts +2 -0
  772. package/packages/core/src/plugins/agent-teams.ts +291 -0
  773. package/packages/core/src/plugins/anchored-standard.ts +88 -0
  774. package/packages/core/src/plugins/annotation.ts +106 -0
  775. package/packages/core/src/plugins/archify.ts +124 -0
  776. package/packages/core/src/plugins/at-file.ts +54 -0
  777. package/packages/core/src/plugins/auto-mode.ts +123 -0
  778. package/packages/core/src/plugins/better-sidebar.ts +117 -0
  779. package/packages/core/src/plugins/browser-fetch.ts +171 -0
  780. package/packages/core/src/plugins/browser-session.ts +287 -0
  781. package/packages/core/src/plugins/canvas-draw.ts +90 -0
  782. package/packages/core/src/plugins/change-verifier.ts +79 -0
  783. package/packages/core/src/plugins/cleaner.ts +61 -0
  784. package/packages/core/src/plugins/cli-notifier.ts +125 -0
  785. package/packages/core/src/plugins/code2skill.ts +96 -0
  786. package/packages/core/src/plugins/colleague-skill.ts +122 -0
  787. package/packages/core/src/plugins/context-doctor.ts +117 -0
  788. package/packages/core/src/plugins/context.ts +102 -0
  789. package/packages/core/src/plugins/cost-meter.ts +231 -0
  790. package/packages/core/src/plugins/dependency-checker.ts +241 -0
  791. package/packages/core/src/plugins/docker-sandbox.ts +100 -0
  792. package/packages/core/src/plugins/fail-logger.ts +51 -0
  793. package/packages/core/src/plugins/genui.ts +88 -0
  794. package/packages/core/src/plugins/git-time-capsule.ts +97 -0
  795. package/packages/core/src/plugins/graph-memory.ts +394 -0
  796. package/packages/core/src/plugins/history-compressor.ts +81 -0
  797. package/packages/core/src/plugins/hol-guard.ts +153 -0
  798. package/packages/core/src/plugins/i18n-pair.ts +82 -0
  799. package/packages/core/src/plugins/image-compressor.ts +144 -0
  800. package/packages/core/src/plugins/llm-verifier.ts +164 -0
  801. package/packages/core/src/plugins/mcp-client.ts +559 -0
  802. package/packages/core/src/plugins/mcp-panel.ts +190 -0
  803. package/packages/core/src/plugins/memory.ts +176 -0
  804. package/packages/core/src/plugins/mirage-bridge.ts +179 -0
  805. package/packages/core/src/plugins/mock-server.ts +158 -0
  806. package/packages/core/src/plugins/model.ts +3 -1
  807. package/packages/core/src/plugins/models.ts +5 -2
  808. package/packages/core/src/plugins/modlens.ts +63 -0
  809. package/packages/core/src/plugins/module-search.ts +201 -0
  810. package/packages/core/src/plugins/obsidian-sync.ts +83 -0
  811. package/packages/core/src/plugins/openpets.ts +109 -0
  812. package/packages/core/src/plugins/plan-execute.ts +76 -0
  813. package/packages/core/src/plugins/plugin-check.ts +232 -0
  814. package/packages/core/src/plugins/plugin-dev.ts +47 -0
  815. package/packages/core/src/plugins/plugin-finder.ts +108 -0
  816. package/packages/core/src/plugins/plugin-radar.ts +179 -0
  817. package/packages/core/src/plugins/plugin-stars.ts +205 -0
  818. package/packages/core/src/plugins/prompt-guard.ts +122 -0
  819. package/packages/core/src/plugins/prompt-library.ts +165 -0
  820. package/packages/core/src/plugins/readme-gen.ts +147 -0
  821. package/packages/core/src/plugins/recall-unread.ts +142 -0
  822. package/packages/core/src/plugins/resources.ts +28 -21
  823. package/packages/core/src/plugins/reverse-skill.ts +79 -0
  824. package/packages/core/src/plugins/reviewer-bot.ts +146 -0
  825. package/packages/core/src/plugins/runtime-doctor.ts +137 -0
  826. package/packages/core/src/plugins/runtime.ts +61 -14
  827. package/packages/core/src/plugins/secure-audit.ts +146 -0
  828. package/packages/core/src/plugins/session-bookmarks.ts +89 -0
  829. package/packages/core/src/plugins/session-bridge.ts +299 -0
  830. package/packages/core/src/plugins/session-compare.ts +180 -0
  831. package/packages/core/src/plugins/session-export.ts +99 -0
  832. package/packages/core/src/plugins/session-insights.ts +47 -0
  833. package/packages/core/src/plugins/session-search.ts +126 -0
  834. package/packages/core/src/plugins/session.ts +4 -2
  835. package/packages/core/src/plugins/skill-catalog.ts +117 -0
  836. package/packages/core/src/plugins/skill-guard.ts +152 -0
  837. package/packages/core/src/plugins/sql-lens.ts +92 -0
  838. package/packages/core/src/plugins/stdio.ts +3 -1
  839. package/packages/core/src/plugins/synapse.ts +130 -0
  840. package/packages/core/src/plugins/tab-manager.ts +135 -0
  841. package/packages/core/src/plugins/taskboard.ts +412 -0
  842. package/packages/core/src/plugins/telemetry-blocker.ts +62 -0
  843. package/packages/core/src/plugins/test-harness.ts +67 -0
  844. package/packages/core/src/plugins/theme-studio.ts +165 -0
  845. package/packages/core/src/plugins/token-guard.ts +84 -0
  846. package/packages/core/src/plugins/tools.ts +5 -2
  847. package/packages/core/src/plugins/turn-rewind.ts +86 -0
  848. package/packages/core/src/plugins/undo-savepoint.ts +284 -0
  849. package/packages/core/src/plugins/vision-toolkit.ts +153 -0
  850. package/packages/core/src/plugins/web-research.ts +289 -0
  851. package/packages/core/src/plugins/workspace-navigator.ts +164 -0
  852. package/packages/core/src/plugins/workspace-search.ts +139 -0
  853. package/packages/core/src/plugins/yaml-validator.ts +97 -0
  854. package/packages/core/src/profile.ts +3 -0
  855. package/packages/core/src/runtime.ts +11 -4
  856. package/packages/core/src/services.ts +110 -3
  857. package/packages/core/src/stdio.ts +79 -9
  858. package/packages/core/src/workspace-path.ts +69 -0
  859. package/packages/core/test/agent-teams.test.ts +24 -0
  860. package/packages/core/test/archify.test.ts +33 -0
  861. package/packages/core/test/better-sidebar.test.ts +125 -0
  862. package/packages/core/test/boot.test.ts +49 -6
  863. package/packages/core/test/colleague-skill.test.ts +74 -0
  864. package/packages/core/test/config.test.ts +121 -0
  865. package/packages/core/test/context-doctor.test.ts +32 -0
  866. package/packages/core/test/dependency-checker.test.ts +60 -0
  867. package/packages/core/test/git-time-capsule.test.ts +115 -0
  868. package/packages/core/test/http.test.ts +34 -0
  869. package/packages/core/test/llm-verifier.test.ts +72 -0
  870. package/packages/core/test/mirage-bridge.test.ts +54 -0
  871. package/packages/core/test/module-search.test.ts +78 -0
  872. package/packages/core/test/plugin-check.test.ts +16 -0
  873. package/packages/core/test/plugin-stars.test.ts +55 -0
  874. package/packages/core/test/profiles.integration.test.ts +49 -15
  875. package/packages/core/test/prompt-library.test.ts +56 -0
  876. package/packages/core/test/readme-gen.test.ts +45 -0
  877. package/packages/core/test/recall-unread.test.ts +35 -0
  878. package/packages/core/test/registry.test.ts +48 -0
  879. package/packages/core/test/reverse-skill.test.ts +40 -0
  880. package/packages/core/test/runtime-doctor.test.ts +55 -0
  881. package/packages/core/test/runtime-fixture.ts +4 -4
  882. package/packages/core/test/runtime.test.ts +90 -1
  883. package/packages/core/test/secure-audit.test.ts +16 -0
  884. package/packages/core/test/services.test.ts +2024 -5
  885. package/packages/core/test/session-bookmarks.test.ts +62 -0
  886. package/packages/core/test/session-bridge.test.ts +103 -0
  887. package/packages/core/test/session-compare.test.ts +94 -0
  888. package/packages/core/test/session-export.test.ts +54 -0
  889. package/packages/core/test/session-search.test.ts +30 -0
  890. package/packages/core/test/skill-catalog.test.ts +18 -0
  891. package/packages/core/test/skill-guard.test.ts +21 -0
  892. package/packages/core/test/stdio-args.test.ts +178 -0
  893. package/packages/core/test/theme-studio.test.ts +39 -0
  894. package/packages/core/test/token-guard.test.ts +34 -0
  895. package/packages/core/test/turn-rewind.test.ts +19 -0
  896. package/packages/core/test/vision-toolkit.test.ts +38 -0
  897. package/packages/core/test/workspace-git-status.test.ts +37 -0
  898. package/packages/core/test/workspace-navigator.test.ts +33 -0
  899. package/packages/core/test/workspace-path.test.ts +34 -0
  900. package/packages/core/tsconfig.build.json +1 -3
  901. package/packages/core/tsconfig.json +1 -4
  902. package/packages/host-webserver/LICENSE +9 -0
  903. package/packages/host-webserver/dist/index.js +1 -1
  904. package/packages/host-webserver/dist/index.js.map +1 -1
  905. package/packages/host-webserver/package.json +17 -7
  906. package/packages/host-webserver/src/index.ts +1 -1
  907. package/packages/host-webserver/test/index.test.ts +4 -1
  908. package/packages/host-webserver/tsconfig.build.json +1 -1
  909. package/packages/host-webserver/tsconfig.json +1 -1
  910. package/apps/web/dist/assets/index-C4tLweAB.js +0 -20
  911. package/apps/web/dist/assets/index-DPgRbQ4_.css +0 -1
@@ -1,7 +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";
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();
5
9
  function sendJson(response, status, payload) {
6
10
  const body = JSON.stringify(payload);
7
11
  response.writeHead(status, { "content-type": "application/json; charset=utf-8", "cache-control": "no-store", "content-length": Buffer.byteLength(body) });
@@ -45,6 +49,7 @@ function jsonSafe(value, seen = new WeakSet()) {
45
49
  }
46
50
  function createStatus(services, events) {
47
51
  const activeModel = services.runtime.session.model ?? services.models.model;
52
+ const cwd = activeCwd(services);
48
53
  return {
49
54
  status: services.runtime.session.isStreaming ? "running" : "ready",
50
55
  model: activeModel.provider + "/" + activeModel.id,
@@ -52,19 +57,269 @@ function createStatus(services, events) {
52
57
  events: events.length,
53
58
  sessionId: services.runtime.session.sessionId,
54
59
  sessionFile: services.runtime.session.sessionFile,
55
- cwd: services.launch.cwd,
60
+ cwd,
56
61
  agentDir: services.launch.agentDir,
57
62
  plugins: services.loader ? [...services.loader.entries()].filter((entry) => !entry.disabled).map((entry) => entry.options.name) : [],
58
63
  };
59
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
+ }
60
160
  function modelSummary(model, active) {
61
- 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);
62
189
  }
63
190
  function pluginSummary(entry) {
64
191
  const states = ["pending", "loading", "active", "failed", "disposed", "unloading"];
192
+ const marketplacePlugin = marketplacePluginForEntry(entry);
65
193
  const rawState = entry.fiber?.state;
66
- const state = typeof rawState === "number" ? states[rawState] ?? String(rawState) : typeof rawState === "string" ? rawState : rawState === undefined || rawState === null ? "unloaded" : "unknown";
67
- 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;
68
323
  }
69
324
  function writeSse(response, payload) {
70
325
  response.write(`data: ${JSON.stringify(jsonSafe(payload))}\n\n`);
@@ -87,6 +342,48 @@ function gitCommand(cwd, args) {
87
342
  });
88
343
  });
89
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
+ }
90
387
  function workspacePaths(root, paths) {
91
388
  if (!Array.isArray(paths) || paths.length === 0 || paths.some((path) => typeof path !== "string" || path.trim() === ""))
92
389
  return new Error("paths must be a non-empty array of strings");
@@ -106,12 +403,14 @@ export default {
106
403
  inject: ["webServer", "piRuntime", "piModels", "piHarnessLaunch"],
107
404
  apply(context) {
108
405
  const services = {
109
- runtime: context.piRuntime,
110
- models: context.piModels,
111
- launch: context.piHarnessLaunch,
406
+ runtime: context.reflect.get("piRuntime"),
407
+ models: context.reflect.get("piModels"),
408
+ launch: context.reflect.get("piHarnessLaunch"),
112
409
  webServer: context.webServer,
113
410
  loader: context.reflect.get("loader"),
411
+ pluginUi: context.reflect.get("piPluginUi"),
114
412
  };
413
+ const disposePluginPanels = registerPluginPanels(context, services);
115
414
  let busy = false;
116
415
  const events = [];
117
416
  const eventClients = new Set();
@@ -134,11 +433,144 @@ export default {
134
433
  sendJson(response, 200, createStatus(services, events));
135
434
  },
136
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
+ });
137
563
  const disposeModels = services.webServer.register({
138
564
  path: "/api/models",
139
565
  handler(_request, response) {
140
566
  const active = services.runtime.session.model ?? services.models.model;
141
- 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
+ }));
142
574
  },
143
575
  });
144
576
  const disposeProviders = services.webServer.register({
@@ -147,15 +579,85 @@ export default {
147
579
  const active = services.runtime.session.model ?? services.models.model;
148
580
  const runtime = services.models.runtime;
149
581
  const providers = typeof runtime.getProviders === "function" ? runtime.getProviders() : [{ id: active.provider, name: active.provider }];
150
- const visible = providers.filter((provider) => {
151
- if (provider.id === active.provider)
152
- return true;
153
- if (typeof runtime.getProviderAuthStatus !== "function")
154
- return false;
155
- const auth = runtime.getProviderAuthStatus(provider.id);
156
- return typeof auth === "object" && auth !== null && auth.configured === true;
157
- });
158
- 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
+ }
159
661
  },
160
662
  });
161
663
  const disposeProviderTest = services.webServer.register({
@@ -177,6 +679,11 @@ export default {
177
679
  return;
178
680
  }
179
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
+ }
180
687
  sendJson(response, 200, jsonSafe({ provider: payload.provider, reachable: auth !== undefined, auth }));
181
688
  }
182
689
  catch (error) {
@@ -217,14 +724,306 @@ export default {
217
724
  sendJson(response, 200, jsonSafe({ items }));
218
725
  },
219
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
+ });
743
+ const disposeMarketplace = services.webServer.register({
744
+ path: "/api/marketplace",
745
+ async handler(request, response) {
746
+ if (request.method !== "GET") {
747
+ sendJson(response, 405, { error: "Method not allowed" });
748
+ return;
749
+ }
750
+ const url = new URL(request.url ?? "/api/marketplace", "http://localhost");
751
+ const query = url.searchParams.get("q") ?? "";
752
+ const capability = url.searchParams.get("capability") ?? "";
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" });
767
+ return;
768
+ }
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
+ }
982
+ },
983
+ });
220
984
  const disposeCommands = services.webServer.register({
221
985
  path: "/api/commands",
222
986
  handler(_request, response) {
223
987
  const commands = services.runtime.session.extensionRunner.getRegisteredCommands();
224
- 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
+ }));
225
994
  sendJson(response, 200, jsonSafe({ items }));
226
995
  },
227
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
+ });
228
1027
  const disposeModel = services.webServer.register({
229
1028
  path: "/api/model",
230
1029
  async handler(request, response) {
@@ -262,10 +1061,18 @@ export default {
262
1061
  const disposeFiles = services.webServer.register({
263
1062
  path: "/api/files",
264
1063
  async handler(_request, response) {
265
- const output = await gitStatus(services.launch.cwd);
266
- 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) => {
267
1070
  const status = line.slice(0, 2).trim() || "??";
268
- 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
+ };
269
1076
  });
270
1077
  sendJson(response, 200, { items });
271
1078
  },
@@ -283,7 +1090,7 @@ export default {
283
1090
  sendJson(response, 400, { error: "path is required" });
284
1091
  return;
285
1092
  }
286
- const root = resolve(services.launch.cwd);
1093
+ const root = resolve(activeCwd(services));
287
1094
  const absolute = resolve(root, requested);
288
1095
  const relativePath = relative(root, absolute);
289
1096
  if (isAbsolute(relativePath) || relativePath === ".." || relativePath.startsWith(".." + "/")) {
@@ -302,7 +1109,7 @@ export default {
302
1109
  }
303
1110
  try {
304
1111
  const payload = JSON.parse(await bodyText(request));
305
- const paths = workspacePaths(resolve(services.launch.cwd), payload.paths);
1112
+ const paths = workspacePaths(resolve(activeCwd(services)), payload.paths);
306
1113
  if (paths instanceof Error) {
307
1114
  sendJson(response, 400, { error: paths.message });
308
1115
  return;
@@ -311,7 +1118,7 @@ export default {
311
1118
  sendJson(response, 400, { error: "message is required" });
312
1119
  return;
313
1120
  }
314
- const root = resolve(services.launch.cwd);
1121
+ const root = resolve(activeCwd(services));
315
1122
  const add = await gitCommand(root, ["add", "-A", "--", ...paths]);
316
1123
  if (add.code !== 0) {
317
1124
  sendJson(response, 409, { error: add.stderr.trim() || "Unable to stage workspace files" });
@@ -343,7 +1150,7 @@ export default {
343
1150
  sendJson(response, 400, { error: "confirm must be true to discard workspace changes" });
344
1151
  return;
345
1152
  }
346
- const root = resolve(services.launch.cwd);
1153
+ const root = resolve(activeCwd(services));
347
1154
  const paths = workspacePaths(root, payload.paths);
348
1155
  if (paths instanceof Error) {
349
1156
  sendJson(response, 400, { error: paths.message });
@@ -355,7 +1162,10 @@ export default {
355
1162
  sendJson(response, 409, { error: restore.stderr.trim() || "Unable to restore workspace files" });
356
1163
  return;
357
1164
  }
358
- 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)) {
359
1169
  await rm(resolve(root, path), { recursive: true, force: true });
360
1170
  }
361
1171
  sendJson(response, 200, { reverted: true, paths });
@@ -368,7 +1178,12 @@ export default {
368
1178
  const disposeEvents = services.webServer.register({
369
1179
  path: "/api/events",
370
1180
  handler(_request, response) {
371
- 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
+ });
372
1187
  writeSse(response, { type: "snapshot", sessionId: services.runtime.session.sessionId, events });
373
1188
  eventClients.add(response);
374
1189
  const heartbeat = setInterval(() => {
@@ -465,8 +1280,36 @@ export default {
465
1280
  return;
466
1281
  }
467
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
+ }
468
1296
  if (services.runtime.sessionRuntime) {
469
- 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
+ }
470
1313
  if (result.cancelled) {
471
1314
  sendJson(response, 409, { error: "Session creation was cancelled by an extension" });
472
1315
  return;
@@ -481,7 +1324,12 @@ export default {
481
1324
  const session = services.runtime.session;
482
1325
  for (const client of eventClients)
483
1326
  writeSse(client, { type: "session", sessionId: session.sessionId, events: [] });
484
- 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
+ }));
485
1333
  }
486
1334
  catch (error) {
487
1335
  sendJson(response, 500, { error: errorText(error) });
@@ -513,7 +1361,7 @@ export default {
513
1361
  return;
514
1362
  }
515
1363
  if (services.runtime.sessionRuntime) {
516
- 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 }));
517
1365
  if (result.cancelled) {
518
1366
  sendJson(response, 409, { error: "Session switch was cancelled by an extension" });
519
1367
  return;
@@ -529,23 +1377,321 @@ export default {
529
1377
  events.length = 0;
530
1378
  for (const client of eventClients)
531
1379
  writeSse(client, { type: "session", sessionId: services.runtime.session.sessionId, events: [] });
532
- 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 });
533
1456
  }
534
1457
  catch (error) {
535
1458
  sendJson(response, 400, { error: errorText(error) });
536
1459
  }
537
1460
  },
538
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] });
1487
+ }
1488
+ catch (error) {
1489
+ sendJson(response, 400, { error: errorText(error) });
1490
+ }
1491
+ },
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
+ });
539
1662
  const disposeSessions = services.webServer.register({
540
1663
  path: "/api/sessions",
541
1664
  async handler(_request, response) {
542
1665
  try {
543
1666
  const session = services.runtime.session;
544
1667
  const manager = session.sessionManager;
545
- const items = typeof manager.isPersisted === "function" && manager.isPersisted()
546
- ? await SessionManager.list(services.launch.cwd, manager.getSessionDir())
547
- : [];
548
- 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
+ }));
549
1695
  }
550
1696
  catch (error) {
551
1697
  sendJson(response, 500, { error: errorText(error) });
@@ -554,14 +1700,26 @@ export default {
554
1700
  });
555
1701
  context.effect(() => () => {
556
1702
  disposeStatus();
1703
+ disposeConfig();
1704
+ disposeConfigReload();
1705
+ disposeConfigSource();
557
1706
  disposeEvents();
558
1707
  disposeModels();
559
1708
  disposeProviders();
560
1709
  disposeProviderTest();
561
1710
  disposeProviderRefresh();
1711
+ disposeProviderAdd();
562
1712
  disposePlugins();
1713
+ disposePluginUi();
1714
+ disposePluginPanels();
1715
+ disposeMarketplace();
1716
+ disposeMarketplaceInstall();
1717
+ disposePluginToggle();
1718
+ disposePluginUninstall();
563
1719
  disposeCommands();
564
1720
  disposeModel();
1721
+ disposeWorkspaces();
1722
+ disposePickDirectory();
565
1723
  disposeFiles();
566
1724
  disposeFileDiff();
567
1725
  disposeFileCommit();
@@ -571,6 +1729,13 @@ export default {
571
1729
  disposeSession();
572
1730
  disposeNewSession();
573
1731
  disposeOpenSession();
1732
+ disposeRenameSession();
1733
+ disposeDeleteSession();
1734
+ disposeSessionMetadata();
1735
+ disposeBatchSessions();
1736
+ disposeForkSession();
1737
+ disposeImportSession();
1738
+ disposeExportSession();
574
1739
  disposeSessions();
575
1740
  unsubscribeEvents();
576
1741
  for (const response of eventClients)