@tianshu-ai/tianshu 0.3.0

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 (917) hide show
  1. package/LICENSE +200 -0
  2. package/README.md +284 -0
  3. package/README.zh-CN.md +136 -0
  4. package/bin/tianshu.mjs +32 -0
  5. package/package.json +60 -0
  6. package/packages/plugin-sdk/dist/agent-loop.d.ts +96 -0
  7. package/packages/plugin-sdk/dist/agent-loop.d.ts.map +1 -0
  8. package/packages/plugin-sdk/dist/agent-loop.js +11 -0
  9. package/packages/plugin-sdk/dist/agent-loop.js.map +1 -0
  10. package/packages/plugin-sdk/dist/capabilities.d.ts +48 -0
  11. package/packages/plugin-sdk/dist/capabilities.d.ts.map +1 -0
  12. package/packages/plugin-sdk/dist/capabilities.js +61 -0
  13. package/packages/plugin-sdk/dist/capabilities.js.map +1 -0
  14. package/packages/plugin-sdk/dist/catalog.d.ts +60 -0
  15. package/packages/plugin-sdk/dist/catalog.d.ts.map +1 -0
  16. package/packages/plugin-sdk/dist/catalog.js +11 -0
  17. package/packages/plugin-sdk/dist/catalog.js.map +1 -0
  18. package/packages/plugin-sdk/dist/client.d.ts +171 -0
  19. package/packages/plugin-sdk/dist/client.d.ts.map +1 -0
  20. package/packages/plugin-sdk/dist/client.js +96 -0
  21. package/packages/plugin-sdk/dist/client.js.map +1 -0
  22. package/packages/plugin-sdk/dist/index.d.ts +9 -0
  23. package/packages/plugin-sdk/dist/index.d.ts.map +1 -0
  24. package/packages/plugin-sdk/dist/index.js +19 -0
  25. package/packages/plugin-sdk/dist/index.js.map +1 -0
  26. package/packages/plugin-sdk/dist/lsp.d.ts +32 -0
  27. package/packages/plugin-sdk/dist/lsp.d.ts.map +1 -0
  28. package/packages/plugin-sdk/dist/lsp.js +19 -0
  29. package/packages/plugin-sdk/dist/lsp.js.map +1 -0
  30. package/packages/plugin-sdk/dist/manifest.d.ts +423 -0
  31. package/packages/plugin-sdk/dist/manifest.d.ts.map +1 -0
  32. package/packages/plugin-sdk/dist/manifest.js +7 -0
  33. package/packages/plugin-sdk/dist/manifest.js.map +1 -0
  34. package/packages/plugin-sdk/dist/mcp-client.d.ts +74 -0
  35. package/packages/plugin-sdk/dist/mcp-client.d.ts.map +1 -0
  36. package/packages/plugin-sdk/dist/mcp-client.js +226 -0
  37. package/packages/plugin-sdk/dist/mcp-client.js.map +1 -0
  38. package/packages/plugin-sdk/dist/mcp-fetch.d.ts +10 -0
  39. package/packages/plugin-sdk/dist/mcp-fetch.d.ts.map +1 -0
  40. package/packages/plugin-sdk/dist/mcp-fetch.js +130 -0
  41. package/packages/plugin-sdk/dist/mcp-fetch.js.map +1 -0
  42. package/packages/plugin-sdk/dist/mcp-toolset.d.ts +128 -0
  43. package/packages/plugin-sdk/dist/mcp-toolset.d.ts.map +1 -0
  44. package/packages/plugin-sdk/dist/mcp-toolset.js +246 -0
  45. package/packages/plugin-sdk/dist/mcp-toolset.js.map +1 -0
  46. package/packages/plugin-sdk/dist/server.d.ts +486 -0
  47. package/packages/plugin-sdk/dist/server.d.ts.map +1 -0
  48. package/packages/plugin-sdk/dist/server.js +10 -0
  49. package/packages/plugin-sdk/dist/server.js.map +1 -0
  50. package/packages/plugin-sdk/dist/session-inbox.d.ts +56 -0
  51. package/packages/plugin-sdk/dist/session-inbox.d.ts.map +1 -0
  52. package/packages/plugin-sdk/dist/session-inbox.js +12 -0
  53. package/packages/plugin-sdk/dist/session-inbox.js.map +1 -0
  54. package/packages/plugin-sdk/package.json +36 -0
  55. package/packages/server/builtinConfig/plugins/README.md +1 -0
  56. package/packages/server/builtinConfig/plugins/files/manifest.json +100 -0
  57. package/packages/server/builtinConfig/plugins/files/skills/files-workspace-layout.md +29 -0
  58. package/packages/server/builtinConfig/plugins/microsandbox/manifest.json +177 -0
  59. package/packages/server/builtinConfig/plugins/microsandbox/skills/microsandbox-browser-howto.md +155 -0
  60. package/packages/server/builtinConfig/plugins/microsandbox/skills/microsandbox-build-use.md +201 -0
  61. package/packages/server/builtinConfig/plugins/microsandbox/skills/microsandbox-config.md +38 -0
  62. package/packages/server/builtinConfig/plugins/microsandbox/skills/microsandbox-exec-howto.md +144 -0
  63. package/packages/server/builtinConfig/plugins/microsandbox/skills/microsandbox-libreoffice.md +159 -0
  64. package/packages/server/builtinConfig/plugins/microsandbox/skills/microsandbox-main-orchestration.md +75 -0
  65. package/packages/server/builtinConfig/plugins/microsandbox/templates/README.md +26 -0
  66. package/packages/server/builtinConfig/plugins/microsandbox/templates/browser.yaml +105 -0
  67. package/packages/server/builtinConfig/plugins/microsandbox/templates/task-runner-with-browser.yaml +80 -0
  68. package/packages/server/builtinConfig/plugins/microsandbox/templates/task-runner.yaml +80 -0
  69. package/packages/server/builtinConfig/plugins/web-search/manifest.json +65 -0
  70. package/packages/server/builtinConfig/plugins/web-search/skills/web-search-howto.md +69 -0
  71. package/packages/server/builtinConfig/plugins/workboard/agent-seeds/echo-demo/agent.json +7 -0
  72. package/packages/server/builtinConfig/plugins/workboard/agent-seeds/llm-default/SOUL.md +53 -0
  73. package/packages/server/builtinConfig/plugins/workboard/agent-seeds/llm-default/agent.json +7 -0
  74. package/packages/server/builtinConfig/plugins/workboard/manifest.json +180 -0
  75. package/packages/server/builtinConfig/plugins/workboard/skills/large-input-large-output.md +185 -0
  76. package/packages/server/builtinConfig/plugins/workboard/skills/workboard-howto.md +166 -0
  77. package/packages/server/builtinConfig/plugins/workboard/skills/worker-creator.md +267 -0
  78. package/packages/server/builtinConfig/plugins/workboard/skills/worker-fleet.md +431 -0
  79. package/packages/server/dist/catalog.d.ts +52 -0
  80. package/packages/server/dist/catalog.d.ts.map +1 -0
  81. package/packages/server/dist/catalog.js +189 -0
  82. package/packages/server/dist/catalog.js.map +1 -0
  83. package/packages/server/dist/chat/active-harnesses.d.ts +34 -0
  84. package/packages/server/dist/chat/active-harnesses.d.ts.map +1 -0
  85. package/packages/server/dist/chat/active-harnesses.js +118 -0
  86. package/packages/server/dist/chat/active-harnesses.js.map +1 -0
  87. package/packages/server/dist/chat/agent-loop.d.ts +64 -0
  88. package/packages/server/dist/chat/agent-loop.d.ts.map +1 -0
  89. package/packages/server/dist/chat/agent-loop.js +597 -0
  90. package/packages/server/dist/chat/agent-loop.js.map +1 -0
  91. package/packages/server/dist/chat/agent-tool-adapter.d.ts +33 -0
  92. package/packages/server/dist/chat/agent-tool-adapter.d.ts.map +1 -0
  93. package/packages/server/dist/chat/agent-tool-adapter.js +260 -0
  94. package/packages/server/dist/chat/agent-tool-adapter.js.map +1 -0
  95. package/packages/server/dist/chat/compact.d.ts +52 -0
  96. package/packages/server/dist/chat/compact.d.ts.map +1 -0
  97. package/packages/server/dist/chat/compact.js +248 -0
  98. package/packages/server/dist/chat/compact.js.map +1 -0
  99. package/packages/server/dist/chat/dump-system-prompt.d.ts +17 -0
  100. package/packages/server/dist/chat/dump-system-prompt.d.ts.map +1 -0
  101. package/packages/server/dist/chat/dump-system-prompt.js +58 -0
  102. package/packages/server/dist/chat/dump-system-prompt.js.map +1 -0
  103. package/packages/server/dist/chat/handler.d.ts +186 -0
  104. package/packages/server/dist/chat/handler.d.ts.map +1 -0
  105. package/packages/server/dist/chat/handler.js +1248 -0
  106. package/packages/server/dist/chat/handler.js.map +1 -0
  107. package/packages/server/dist/chat/image-fit.d.ts +34 -0
  108. package/packages/server/dist/chat/image-fit.d.ts.map +1 -0
  109. package/packages/server/dist/chat/image-fit.js +157 -0
  110. package/packages/server/dist/chat/image-fit.js.map +1 -0
  111. package/packages/server/dist/chat/messages.d.ts +118 -0
  112. package/packages/server/dist/chat/messages.d.ts.map +1 -0
  113. package/packages/server/dist/chat/messages.js +341 -0
  114. package/packages/server/dist/chat/messages.js.map +1 -0
  115. package/packages/server/dist/chat/session-inbox.d.ts +114 -0
  116. package/packages/server/dist/chat/session-inbox.d.ts.map +1 -0
  117. package/packages/server/dist/chat/session-inbox.js +418 -0
  118. package/packages/server/dist/chat/session-inbox.js.map +1 -0
  119. package/packages/server/dist/chat/sqlite-session-repo.d.ts +26 -0
  120. package/packages/server/dist/chat/sqlite-session-repo.d.ts.map +1 -0
  121. package/packages/server/dist/chat/sqlite-session-repo.js +132 -0
  122. package/packages/server/dist/chat/sqlite-session-repo.js.map +1 -0
  123. package/packages/server/dist/chat/sqlite-session-storage.d.ts +83 -0
  124. package/packages/server/dist/chat/sqlite-session-storage.d.ts.map +1 -0
  125. package/packages/server/dist/chat/sqlite-session-storage.js +418 -0
  126. package/packages/server/dist/chat/sqlite-session-storage.js.map +1 -0
  127. package/packages/server/dist/chat/stub-execution-env.d.ts +3 -0
  128. package/packages/server/dist/chat/stub-execution-env.d.ts.map +1 -0
  129. package/packages/server/dist/chat/stub-execution-env.js +87 -0
  130. package/packages/server/dist/chat/stub-execution-env.js.map +1 -0
  131. package/packages/server/dist/chat/token-estimate.d.ts +11 -0
  132. package/packages/server/dist/chat/token-estimate.d.ts.map +1 -0
  133. package/packages/server/dist/chat/token-estimate.js +67 -0
  134. package/packages/server/dist/chat/token-estimate.js.map +1 -0
  135. package/packages/server/dist/chat/ws-protocol.d.ts +244 -0
  136. package/packages/server/dist/chat/ws-protocol.d.ts.map +1 -0
  137. package/packages/server/dist/chat/ws-protocol.js +193 -0
  138. package/packages/server/dist/chat/ws-protocol.js.map +1 -0
  139. package/packages/server/dist/cli.d.ts +9 -0
  140. package/packages/server/dist/cli.d.ts.map +1 -0
  141. package/packages/server/dist/cli.js +329 -0
  142. package/packages/server/dist/cli.js.map +1 -0
  143. package/packages/server/dist/core/agent-seeds.d.ts +25 -0
  144. package/packages/server/dist/core/agent-seeds.d.ts.map +1 -0
  145. package/packages/server/dist/core/agent-seeds.js +69 -0
  146. package/packages/server/dist/core/agent-seeds.js.map +1 -0
  147. package/packages/server/dist/core/config.d.ts +172 -0
  148. package/packages/server/dist/core/config.d.ts.map +1 -0
  149. package/packages/server/dist/core/config.js +155 -0
  150. package/packages/server/dist/core/config.js.map +1 -0
  151. package/packages/server/dist/core/db-pool.d.ts +32 -0
  152. package/packages/server/dist/core/db-pool.d.ts.map +1 -0
  153. package/packages/server/dist/core/db-pool.js +108 -0
  154. package/packages/server/dist/core/db-pool.js.map +1 -0
  155. package/packages/server/dist/core/dev-mode.d.ts +13 -0
  156. package/packages/server/dist/core/dev-mode.d.ts.map +1 -0
  157. package/packages/server/dist/core/dev-mode.js +51 -0
  158. package/packages/server/dist/core/dev-mode.js.map +1 -0
  159. package/packages/server/dist/core/global-ops.d.ts +54 -0
  160. package/packages/server/dist/core/global-ops.d.ts.map +1 -0
  161. package/packages/server/dist/core/global-ops.js +143 -0
  162. package/packages/server/dist/core/global-ops.js.map +1 -0
  163. package/packages/server/dist/core/identity-resolvers.d.ts +102 -0
  164. package/packages/server/dist/core/identity-resolvers.d.ts.map +1 -0
  165. package/packages/server/dist/core/identity-resolvers.js +176 -0
  166. package/packages/server/dist/core/identity-resolvers.js.map +1 -0
  167. package/packages/server/dist/core/index.d.ts +13 -0
  168. package/packages/server/dist/core/index.d.ts.map +1 -0
  169. package/packages/server/dist/core/index.js +18 -0
  170. package/packages/server/dist/core/index.js.map +1 -0
  171. package/packages/server/dist/core/llm.d.ts +45 -0
  172. package/packages/server/dist/core/llm.d.ts.map +1 -0
  173. package/packages/server/dist/core/llm.js +140 -0
  174. package/packages/server/dist/core/llm.js.map +1 -0
  175. package/packages/server/dist/core/mcp-manager.d.ts +47 -0
  176. package/packages/server/dist/core/mcp-manager.d.ts.map +1 -0
  177. package/packages/server/dist/core/mcp-manager.js +129 -0
  178. package/packages/server/dist/core/mcp-manager.js.map +1 -0
  179. package/packages/server/dist/core/middleware.d.ts +31 -0
  180. package/packages/server/dist/core/middleware.d.ts.map +1 -0
  181. package/packages/server/dist/core/middleware.js +102 -0
  182. package/packages/server/dist/core/middleware.js.map +1 -0
  183. package/packages/server/dist/core/migrations/001-initial.d.ts +4 -0
  184. package/packages/server/dist/core/migrations/001-initial.d.ts.map +1 -0
  185. package/packages/server/dist/core/migrations/001-initial.js +66 -0
  186. package/packages/server/dist/core/migrations/001-initial.js.map +1 -0
  187. package/packages/server/dist/core/migrations/002-task-dependencies.d.ts +4 -0
  188. package/packages/server/dist/core/migrations/002-task-dependencies.d.ts.map +1 -0
  189. package/packages/server/dist/core/migrations/002-task-dependencies.js +20 -0
  190. package/packages/server/dist/core/migrations/002-task-dependencies.js.map +1 -0
  191. package/packages/server/dist/core/migrations/003-session-tree.d.ts +4 -0
  192. package/packages/server/dist/core/migrations/003-session-tree.d.ts.map +1 -0
  193. package/packages/server/dist/core/migrations/003-session-tree.js +96 -0
  194. package/packages/server/dist/core/migrations/003-session-tree.js.map +1 -0
  195. package/packages/server/dist/core/migrations/003-worker-agents.d.ts +4 -0
  196. package/packages/server/dist/core/migrations/003-worker-agents.d.ts.map +1 -0
  197. package/packages/server/dist/core/migrations/003-worker-agents.js +65 -0
  198. package/packages/server/dist/core/migrations/003-worker-agents.js.map +1 -0
  199. package/packages/server/dist/core/migrations/004-rebuild-message-chain.d.ts +4 -0
  200. package/packages/server/dist/core/migrations/004-rebuild-message-chain.d.ts.map +1 -0
  201. package/packages/server/dist/core/migrations/004-rebuild-message-chain.js +52 -0
  202. package/packages/server/dist/core/migrations/004-rebuild-message-chain.js.map +1 -0
  203. package/packages/server/dist/core/migrations/005-task-status-rename.d.ts +4 -0
  204. package/packages/server/dist/core/migrations/005-task-status-rename.d.ts.map +1 -0
  205. package/packages/server/dist/core/migrations/005-task-status-rename.js +64 -0
  206. package/packages/server/dist/core/migrations/005-task-status-rename.js.map +1 -0
  207. package/packages/server/dist/core/migrations/006-task-labels.d.ts +4 -0
  208. package/packages/server/dist/core/migrations/006-task-labels.d.ts.map +1 -0
  209. package/packages/server/dist/core/migrations/006-task-labels.js +43 -0
  210. package/packages/server/dist/core/migrations/006-task-labels.js.map +1 -0
  211. package/packages/server/dist/core/migrations/007-session-inbox.d.ts +4 -0
  212. package/packages/server/dist/core/migrations/007-session-inbox.d.ts.map +1 -0
  213. package/packages/server/dist/core/migrations/007-session-inbox.js +67 -0
  214. package/packages/server/dist/core/migrations/007-session-inbox.js.map +1 -0
  215. package/packages/server/dist/core/migrations/008-task-intervention.d.ts +4 -0
  216. package/packages/server/dist/core/migrations/008-task-intervention.d.ts.map +1 -0
  217. package/packages/server/dist/core/migrations/008-task-intervention.js +60 -0
  218. package/packages/server/dist/core/migrations/008-task-intervention.js.map +1 -0
  219. package/packages/server/dist/core/migrations/index.d.ts +12 -0
  220. package/packages/server/dist/core/migrations/index.d.ts.map +1 -0
  221. package/packages/server/dist/core/migrations/index.js +58 -0
  222. package/packages/server/dist/core/migrations/index.js.map +1 -0
  223. package/packages/server/dist/core/paths.d.ts +53 -0
  224. package/packages/server/dist/core/paths.d.ts.map +1 -0
  225. package/packages/server/dist/core/paths.js +125 -0
  226. package/packages/server/dist/core/paths.js.map +1 -0
  227. package/packages/server/dist/core/plugins/builtin-loader.d.ts +56 -0
  228. package/packages/server/dist/core/plugins/builtin-loader.d.ts.map +1 -0
  229. package/packages/server/dist/core/plugins/builtin-loader.js +153 -0
  230. package/packages/server/dist/core/plugins/builtin-loader.js.map +1 -0
  231. package/packages/server/dist/core/plugins/discovery.d.ts +28 -0
  232. package/packages/server/dist/core/plugins/discovery.d.ts.map +1 -0
  233. package/packages/server/dist/core/plugins/discovery.js +97 -0
  234. package/packages/server/dist/core/plugins/discovery.js.map +1 -0
  235. package/packages/server/dist/core/plugins/index.d.ts +6 -0
  236. package/packages/server/dist/core/plugins/index.d.ts.map +1 -0
  237. package/packages/server/dist/core/plugins/index.js +6 -0
  238. package/packages/server/dist/core/plugins/index.js.map +1 -0
  239. package/packages/server/dist/core/plugins/manifest.d.ts +9 -0
  240. package/packages/server/dist/core/plugins/manifest.d.ts.map +1 -0
  241. package/packages/server/dist/core/plugins/manifest.js +584 -0
  242. package/packages/server/dist/core/plugins/manifest.js.map +1 -0
  243. package/packages/server/dist/core/plugins/registry.d.ts +269 -0
  244. package/packages/server/dist/core/plugins/registry.d.ts.map +1 -0
  245. package/packages/server/dist/core/plugins/registry.js +1003 -0
  246. package/packages/server/dist/core/plugins/registry.js.map +1 -0
  247. package/packages/server/dist/core/plugins/secrets.d.ts +46 -0
  248. package/packages/server/dist/core/plugins/secrets.d.ts.map +1 -0
  249. package/packages/server/dist/core/plugins/secrets.js +174 -0
  250. package/packages/server/dist/core/plugins/secrets.js.map +1 -0
  251. package/packages/server/dist/core/plugins/skills.d.ts +131 -0
  252. package/packages/server/dist/core/plugins/skills.d.ts.map +1 -0
  253. package/packages/server/dist/core/plugins/skills.js +389 -0
  254. package/packages/server/dist/core/plugins/skills.js.map +1 -0
  255. package/packages/server/dist/core/templates.d.ts +28 -0
  256. package/packages/server/dist/core/templates.d.ts.map +1 -0
  257. package/packages/server/dist/core/templates.js +103 -0
  258. package/packages/server/dist/core/templates.js.map +1 -0
  259. package/packages/server/dist/core/tenant-context.d.ts +18 -0
  260. package/packages/server/dist/core/tenant-context.d.ts.map +1 -0
  261. package/packages/server/dist/core/tenant-context.js +42 -0
  262. package/packages/server/dist/core/tenant-context.js.map +1 -0
  263. package/packages/server/dist/core/tenant-id.d.ts +8 -0
  264. package/packages/server/dist/core/tenant-id.d.ts.map +1 -0
  265. package/packages/server/dist/core/tenant-id.js +53 -0
  266. package/packages/server/dist/core/tenant-id.js.map +1 -0
  267. package/packages/server/dist/core/tenant-skills.d.ts +29 -0
  268. package/packages/server/dist/core/tenant-skills.d.ts.map +1 -0
  269. package/packages/server/dist/core/tenant-skills.js +77 -0
  270. package/packages/server/dist/core/tenant-skills.js.map +1 -0
  271. package/packages/server/dist/core/worker-agents-fs.d.ts +44 -0
  272. package/packages/server/dist/core/worker-agents-fs.d.ts.map +1 -0
  273. package/packages/server/dist/core/worker-agents-fs.js +86 -0
  274. package/packages/server/dist/core/worker-agents-fs.js.map +1 -0
  275. package/packages/server/dist/core/worker-agents.d.ts +77 -0
  276. package/packages/server/dist/core/worker-agents.d.ts.map +1 -0
  277. package/packages/server/dist/core/worker-agents.js +191 -0
  278. package/packages/server/dist/core/worker-agents.js.map +1 -0
  279. package/packages/server/dist/index.d.ts +2 -0
  280. package/packages/server/dist/index.d.ts.map +1 -0
  281. package/packages/server/dist/index.js +623 -0
  282. package/packages/server/dist/index.js.map +1 -0
  283. package/packages/server/dist/lsp/client.d.ts +53 -0
  284. package/packages/server/dist/lsp/client.d.ts.map +1 -0
  285. package/packages/server/dist/lsp/client.js +258 -0
  286. package/packages/server/dist/lsp/client.js.map +1 -0
  287. package/packages/server/dist/lsp/format.d.ts +13 -0
  288. package/packages/server/dist/lsp/format.d.ts.map +1 -0
  289. package/packages/server/dist/lsp/format.js +55 -0
  290. package/packages/server/dist/lsp/format.js.map +1 -0
  291. package/packages/server/dist/lsp/index.d.ts +20 -0
  292. package/packages/server/dist/lsp/index.d.ts.map +1 -0
  293. package/packages/server/dist/lsp/index.js +32 -0
  294. package/packages/server/dist/lsp/index.js.map +1 -0
  295. package/packages/server/dist/lsp/language-registry.d.ts +29 -0
  296. package/packages/server/dist/lsp/language-registry.d.ts.map +1 -0
  297. package/packages/server/dist/lsp/language-registry.js +62 -0
  298. package/packages/server/dist/lsp/language-registry.js.map +1 -0
  299. package/packages/server/dist/lsp/manager.d.ts +77 -0
  300. package/packages/server/dist/lsp/manager.d.ts.map +1 -0
  301. package/packages/server/dist/lsp/manager.js +300 -0
  302. package/packages/server/dist/lsp/manager.js.map +1 -0
  303. package/packages/server/dist/plugins-routes.d.ts +96 -0
  304. package/packages/server/dist/plugins-routes.d.ts.map +1 -0
  305. package/packages/server/dist/plugins-routes.js +627 -0
  306. package/packages/server/dist/plugins-routes.js.map +1 -0
  307. package/packages/server/dist/setup/checks/config.d.ts +9 -0
  308. package/packages/server/dist/setup/checks/config.d.ts.map +1 -0
  309. package/packages/server/dist/setup/checks/config.js +66 -0
  310. package/packages/server/dist/setup/checks/config.js.map +1 -0
  311. package/packages/server/dist/setup/checks/db.d.ts +6 -0
  312. package/packages/server/dist/setup/checks/db.d.ts.map +1 -0
  313. package/packages/server/dist/setup/checks/db.js +79 -0
  314. package/packages/server/dist/setup/checks/db.js.map +1 -0
  315. package/packages/server/dist/setup/checks/known-models.d.ts +18 -0
  316. package/packages/server/dist/setup/checks/known-models.d.ts.map +1 -0
  317. package/packages/server/dist/setup/checks/known-models.js +119 -0
  318. package/packages/server/dist/setup/checks/known-models.js.map +1 -0
  319. package/packages/server/dist/setup/checks/network.d.ts +11 -0
  320. package/packages/server/dist/setup/checks/network.d.ts.map +1 -0
  321. package/packages/server/dist/setup/checks/network.js +176 -0
  322. package/packages/server/dist/setup/checks/network.js.map +1 -0
  323. package/packages/server/dist/setup/checks/plugins.d.ts +9 -0
  324. package/packages/server/dist/setup/checks/plugins.d.ts.map +1 -0
  325. package/packages/server/dist/setup/checks/plugins.js +194 -0
  326. package/packages/server/dist/setup/checks/plugins.js.map +1 -0
  327. package/packages/server/dist/setup/checks/providers.d.ts +12 -0
  328. package/packages/server/dist/setup/checks/providers.d.ts.map +1 -0
  329. package/packages/server/dist/setup/checks/providers.js +368 -0
  330. package/packages/server/dist/setup/checks/providers.js.map +1 -0
  331. package/packages/server/dist/setup/checks/runtime.d.ts +3 -0
  332. package/packages/server/dist/setup/checks/runtime.d.ts.map +1 -0
  333. package/packages/server/dist/setup/checks/runtime.js +44 -0
  334. package/packages/server/dist/setup/checks/runtime.js.map +1 -0
  335. package/packages/server/dist/setup/checks/sandbox.d.ts +9 -0
  336. package/packages/server/dist/setup/checks/sandbox.d.ts.map +1 -0
  337. package/packages/server/dist/setup/checks/sandbox.js +110 -0
  338. package/packages/server/dist/setup/checks/sandbox.js.map +1 -0
  339. package/packages/server/dist/setup/checks/tenants.d.ts +9 -0
  340. package/packages/server/dist/setup/checks/tenants.d.ts.map +1 -0
  341. package/packages/server/dist/setup/checks/tenants.js +509 -0
  342. package/packages/server/dist/setup/checks/tenants.js.map +1 -0
  343. package/packages/server/dist/setup/cli-agent.d.ts +39 -0
  344. package/packages/server/dist/setup/cli-agent.d.ts.map +1 -0
  345. package/packages/server/dist/setup/cli-agent.js +1353 -0
  346. package/packages/server/dist/setup/cli-agent.js.map +1 -0
  347. package/packages/server/dist/setup/doctor.d.ts +32 -0
  348. package/packages/server/dist/setup/doctor.d.ts.map +1 -0
  349. package/packages/server/dist/setup/doctor.js +80 -0
  350. package/packages/server/dist/setup/doctor.js.map +1 -0
  351. package/packages/server/dist/setup/launchd.d.ts +107 -0
  352. package/packages/server/dist/setup/launchd.d.ts.map +1 -0
  353. package/packages/server/dist/setup/launchd.js +309 -0
  354. package/packages/server/dist/setup/launchd.js.map +1 -0
  355. package/packages/server/dist/setup/load-env.d.ts +21 -0
  356. package/packages/server/dist/setup/load-env.d.ts.map +1 -0
  357. package/packages/server/dist/setup/load-env.js +88 -0
  358. package/packages/server/dist/setup/load-env.js.map +1 -0
  359. package/packages/server/dist/setup/probe-default-model.d.ts +28 -0
  360. package/packages/server/dist/setup/probe-default-model.d.ts.map +1 -0
  361. package/packages/server/dist/setup/probe-default-model.js +133 -0
  362. package/packages/server/dist/setup/probe-default-model.js.map +1 -0
  363. package/packages/server/dist/setup/render.d.ts +28 -0
  364. package/packages/server/dist/setup/render.d.ts.map +1 -0
  365. package/packages/server/dist/setup/render.js +60 -0
  366. package/packages/server/dist/setup/render.js.map +1 -0
  367. package/packages/server/dist/setup/repo-root.d.ts +3 -0
  368. package/packages/server/dist/setup/repo-root.d.ts.map +1 -0
  369. package/packages/server/dist/setup/repo-root.js +43 -0
  370. package/packages/server/dist/setup/repo-root.js.map +1 -0
  371. package/packages/server/dist/setup/service.d.ts +60 -0
  372. package/packages/server/dist/setup/service.d.ts.map +1 -0
  373. package/packages/server/dist/setup/service.js +345 -0
  374. package/packages/server/dist/setup/service.js.map +1 -0
  375. package/packages/server/dist/setup/start-server.d.ts +23 -0
  376. package/packages/server/dist/setup/start-server.d.ts.map +1 -0
  377. package/packages/server/dist/setup/start-server.js +465 -0
  378. package/packages/server/dist/setup/start-server.js.map +1 -0
  379. package/packages/server/dist/setup/wizard.d.ts +59 -0
  380. package/packages/server/dist/setup/wizard.d.ts.map +1 -0
  381. package/packages/server/dist/setup/wizard.js +556 -0
  382. package/packages/server/dist/setup/wizard.js.map +1 -0
  383. package/packages/server/dist/tools/edit-file.d.ts +13 -0
  384. package/packages/server/dist/tools/edit-file.d.ts.map +1 -0
  385. package/packages/server/dist/tools/edit-file.js +90 -0
  386. package/packages/server/dist/tools/edit-file.js.map +1 -0
  387. package/packages/server/dist/tools/glob.d.ts +12 -0
  388. package/packages/server/dist/tools/glob.d.ts.map +1 -0
  389. package/packages/server/dist/tools/glob.js +82 -0
  390. package/packages/server/dist/tools/glob.js.map +1 -0
  391. package/packages/server/dist/tools/index.d.ts +82 -0
  392. package/packages/server/dist/tools/index.d.ts.map +1 -0
  393. package/packages/server/dist/tools/index.js +72 -0
  394. package/packages/server/dist/tools/index.js.map +1 -0
  395. package/packages/server/dist/tools/list-dir.d.ts +24 -0
  396. package/packages/server/dist/tools/list-dir.d.ts.map +1 -0
  397. package/packages/server/dist/tools/list-dir.js +99 -0
  398. package/packages/server/dist/tools/list-dir.js.map +1 -0
  399. package/packages/server/dist/tools/path-helper.d.ts +15 -0
  400. package/packages/server/dist/tools/path-helper.d.ts.map +1 -0
  401. package/packages/server/dist/tools/path-helper.js +72 -0
  402. package/packages/server/dist/tools/path-helper.js.map +1 -0
  403. package/packages/server/dist/tools/read-file.d.ts +17 -0
  404. package/packages/server/dist/tools/read-file.d.ts.map +1 -0
  405. package/packages/server/dist/tools/read-file.js +94 -0
  406. package/packages/server/dist/tools/read-file.js.map +1 -0
  407. package/packages/server/dist/tools/sandbox.d.ts +57 -0
  408. package/packages/server/dist/tools/sandbox.d.ts.map +1 -0
  409. package/packages/server/dist/tools/sandbox.js +291 -0
  410. package/packages/server/dist/tools/sandbox.js.map +1 -0
  411. package/packages/server/dist/tools/write-file.d.ts +12 -0
  412. package/packages/server/dist/tools/write-file.d.ts.map +1 -0
  413. package/packages/server/dist/tools/write-file.js +67 -0
  414. package/packages/server/dist/tools/write-file.js.map +1 -0
  415. package/packages/server/dist/worker-agents-routes.d.ts +11 -0
  416. package/packages/server/dist/worker-agents-routes.d.ts.map +1 -0
  417. package/packages/server/dist/worker-agents-routes.js +253 -0
  418. package/packages/server/dist/worker-agents-routes.js.map +1 -0
  419. package/packages/server/package.json +41 -0
  420. package/packages/web/dist/assets/index-DH-gJ09_.js +60 -0
  421. package/packages/web/dist/assets/index-xU4lYYqY.css +2 -0
  422. package/packages/web/dist/index.html +14 -0
  423. package/packages/web/package.json +36 -0
  424. package/plugins/README.md +64 -0
  425. package/plugins/files/dist/client.d.ts +5 -0
  426. package/plugins/files/dist/client.d.ts.map +1 -0
  427. package/plugins/files/dist/client.js +354 -0
  428. package/plugins/files/dist/client.js.map +1 -0
  429. package/plugins/files/dist/server.d.ts +32 -0
  430. package/plugins/files/dist/server.d.ts.map +1 -0
  431. package/plugins/files/dist/server.js +514 -0
  432. package/plugins/files/dist/server.js.map +1 -0
  433. package/plugins/files/dist/tools/edit-file.d.ts +29 -0
  434. package/plugins/files/dist/tools/edit-file.d.ts.map +1 -0
  435. package/plugins/files/dist/tools/edit-file.js +230 -0
  436. package/plugins/files/dist/tools/edit-file.js.map +1 -0
  437. package/plugins/files/dist/tools/edit-file.prompt.md +36 -0
  438. package/plugins/files/dist/tools/glob.d.ts +12 -0
  439. package/plugins/files/dist/tools/glob.d.ts.map +1 -0
  440. package/plugins/files/dist/tools/glob.js +84 -0
  441. package/plugins/files/dist/tools/glob.js.map +1 -0
  442. package/plugins/files/dist/tools/index.d.ts +13 -0
  443. package/plugins/files/dist/tools/index.d.ts.map +1 -0
  444. package/plugins/files/dist/tools/index.js +158 -0
  445. package/plugins/files/dist/tools/index.js.map +1 -0
  446. package/plugins/files/dist/tools/list-dir.d.ts +24 -0
  447. package/plugins/files/dist/tools/list-dir.d.ts.map +1 -0
  448. package/plugins/files/dist/tools/list-dir.js +104 -0
  449. package/plugins/files/dist/tools/list-dir.js.map +1 -0
  450. package/plugins/files/dist/tools/load-prompt.d.ts +5 -0
  451. package/plugins/files/dist/tools/load-prompt.d.ts.map +1 -0
  452. package/plugins/files/dist/tools/load-prompt.js +39 -0
  453. package/plugins/files/dist/tools/load-prompt.js.map +1 -0
  454. package/plugins/files/dist/tools/path-helper.d.ts +32 -0
  455. package/plugins/files/dist/tools/path-helper.d.ts.map +1 -0
  456. package/plugins/files/dist/tools/path-helper.js +113 -0
  457. package/plugins/files/dist/tools/path-helper.js.map +1 -0
  458. package/plugins/files/dist/tools/read-file.d.ts +17 -0
  459. package/plugins/files/dist/tools/read-file.d.ts.map +1 -0
  460. package/plugins/files/dist/tools/read-file.js +109 -0
  461. package/plugins/files/dist/tools/read-file.js.map +1 -0
  462. package/plugins/files/dist/tools/read-tracker.d.ts +28 -0
  463. package/plugins/files/dist/tools/read-tracker.d.ts.map +1 -0
  464. package/plugins/files/dist/tools/read-tracker.js +135 -0
  465. package/plugins/files/dist/tools/read-tracker.js.map +1 -0
  466. package/plugins/files/dist/tools/replacers.d.ts +27 -0
  467. package/plugins/files/dist/tools/replacers.d.ts.map +1 -0
  468. package/plugins/files/dist/tools/replacers.js +221 -0
  469. package/plugins/files/dist/tools/replacers.js.map +1 -0
  470. package/plugins/files/dist/tools/tenant-config-delete.d.ts +12 -0
  471. package/plugins/files/dist/tools/tenant-config-delete.d.ts.map +1 -0
  472. package/plugins/files/dist/tools/tenant-config-delete.js +70 -0
  473. package/plugins/files/dist/tools/tenant-config-delete.js.map +1 -0
  474. package/plugins/files/dist/tools/tenant-config-edit.d.ts +25 -0
  475. package/plugins/files/dist/tools/tenant-config-edit.d.ts.map +1 -0
  476. package/plugins/files/dist/tools/tenant-config-edit.js +142 -0
  477. package/plugins/files/dist/tools/tenant-config-edit.js.map +1 -0
  478. package/plugins/files/dist/tools/tenant-config-glob.d.ts +12 -0
  479. package/plugins/files/dist/tools/tenant-config-glob.d.ts.map +1 -0
  480. package/plugins/files/dist/tools/tenant-config-glob.js +64 -0
  481. package/plugins/files/dist/tools/tenant-config-glob.js.map +1 -0
  482. package/plugins/files/dist/tools/tenant-config-helper.d.ts +64 -0
  483. package/plugins/files/dist/tools/tenant-config-helper.d.ts.map +1 -0
  484. package/plugins/files/dist/tools/tenant-config-helper.js +162 -0
  485. package/plugins/files/dist/tools/tenant-config-helper.js.map +1 -0
  486. package/plugins/files/dist/tools/tenant-config-list.d.ts +20 -0
  487. package/plugins/files/dist/tools/tenant-config-list.d.ts.map +1 -0
  488. package/plugins/files/dist/tools/tenant-config-list.js +95 -0
  489. package/plugins/files/dist/tools/tenant-config-list.js.map +1 -0
  490. package/plugins/files/dist/tools/tenant-config-read.d.ts +17 -0
  491. package/plugins/files/dist/tools/tenant-config-read.d.ts.map +1 -0
  492. package/plugins/files/dist/tools/tenant-config-read.js +87 -0
  493. package/plugins/files/dist/tools/tenant-config-read.js.map +1 -0
  494. package/plugins/files/dist/tools/tenant-config-write.d.ts +14 -0
  495. package/plugins/files/dist/tools/tenant-config-write.d.ts.map +1 -0
  496. package/plugins/files/dist/tools/tenant-config-write.js +78 -0
  497. package/plugins/files/dist/tools/tenant-config-write.js.map +1 -0
  498. package/plugins/files/dist/tools/text-shape.d.ts +20 -0
  499. package/plugins/files/dist/tools/text-shape.d.ts.map +1 -0
  500. package/plugins/files/dist/tools/text-shape.js +57 -0
  501. package/plugins/files/dist/tools/text-shape.js.map +1 -0
  502. package/plugins/files/dist/tools/write-file.d.ts +12 -0
  503. package/plugins/files/dist/tools/write-file.d.ts.map +1 -0
  504. package/plugins/files/dist/tools/write-file.js +89 -0
  505. package/plugins/files/dist/tools/write-file.js.map +1 -0
  506. package/plugins/files/dist/tools/write-file.prompt.md +14 -0
  507. package/plugins/files/manifest.json +100 -0
  508. package/plugins/files/package.json +39 -0
  509. package/plugins/files/skills/files-workspace-layout.md +29 -0
  510. package/plugins/microsandbox/dist/admin/browser-routes.d.ts +41 -0
  511. package/plugins/microsandbox/dist/admin/browser-routes.d.ts.map +1 -0
  512. package/plugins/microsandbox/dist/admin/browser-routes.js +208 -0
  513. package/plugins/microsandbox/dist/admin/browser-routes.js.map +1 -0
  514. package/plugins/microsandbox/dist/admin/preview-exec.d.ts +38 -0
  515. package/plugins/microsandbox/dist/admin/preview-exec.d.ts.map +1 -0
  516. package/plugins/microsandbox/dist/admin/preview-exec.js +185 -0
  517. package/plugins/microsandbox/dist/admin/preview-exec.js.map +1 -0
  518. package/plugins/microsandbox/dist/admin/routes.d.ts +35 -0
  519. package/plugins/microsandbox/dist/admin/routes.d.ts.map +1 -0
  520. package/plugins/microsandbox/dist/admin/routes.js +728 -0
  521. package/plugins/microsandbox/dist/admin/routes.js.map +1 -0
  522. package/plugins/microsandbox/dist/admin/sandboxfile-io.d.ts +11 -0
  523. package/plugins/microsandbox/dist/admin/sandboxfile-io.d.ts.map +1 -0
  524. package/plugins/microsandbox/dist/admin/sandboxfile-io.js +72 -0
  525. package/plugins/microsandbox/dist/admin/sandboxfile-io.js.map +1 -0
  526. package/plugins/microsandbox/dist/admin/templates.d.ts +16 -0
  527. package/plugins/microsandbox/dist/admin/templates.d.ts.map +1 -0
  528. package/plugins/microsandbox/dist/admin/templates.js +66 -0
  529. package/plugins/microsandbox/dist/admin/templates.js.map +1 -0
  530. package/plugins/microsandbox/dist/admin.d.ts +5 -0
  531. package/plugins/microsandbox/dist/admin.d.ts.map +1 -0
  532. package/plugins/microsandbox/dist/admin.js +256 -0
  533. package/plugins/microsandbox/dist/admin.js.map +1 -0
  534. package/plugins/microsandbox/dist/build/builder.d.ts +69 -0
  535. package/plugins/microsandbox/dist/build/builder.d.ts.map +1 -0
  536. package/plugins/microsandbox/dist/build/builder.js +257 -0
  537. package/plugins/microsandbox/dist/build/builder.js.map +1 -0
  538. package/plugins/microsandbox/dist/build/metadata.d.ts +27 -0
  539. package/plugins/microsandbox/dist/build/metadata.d.ts.map +1 -0
  540. package/plugins/microsandbox/dist/build/metadata.js +55 -0
  541. package/plugins/microsandbox/dist/build/metadata.js.map +1 -0
  542. package/plugins/microsandbox/dist/build/pointer.d.ts +51 -0
  543. package/plugins/microsandbox/dist/build/pointer.d.ts.map +1 -0
  544. package/plugins/microsandbox/dist/build/pointer.js +130 -0
  545. package/plugins/microsandbox/dist/build/pointer.js.map +1 -0
  546. package/plugins/microsandbox/dist/build/sandboxfile.d.ts +15 -0
  547. package/plugins/microsandbox/dist/build/sandboxfile.d.ts.map +1 -0
  548. package/plugins/microsandbox/dist/build/sandboxfile.js +176 -0
  549. package/plugins/microsandbox/dist/build/sandboxfile.js.map +1 -0
  550. package/plugins/microsandbox/dist/client.d.ts +5 -0
  551. package/plugins/microsandbox/dist/client.d.ts.map +1 -0
  552. package/plugins/microsandbox/dist/client.js +941 -0
  553. package/plugins/microsandbox/dist/client.js.map +1 -0
  554. package/plugins/microsandbox/dist/runner/browser.d.ts +50 -0
  555. package/plugins/microsandbox/dist/runner/browser.d.ts.map +1 -0
  556. package/plugins/microsandbox/dist/runner/browser.js +142 -0
  557. package/plugins/microsandbox/dist/runner/browser.js.map +1 -0
  558. package/plugins/microsandbox/dist/runner/free-port.d.ts +6 -0
  559. package/plugins/microsandbox/dist/runner/free-port.d.ts.map +1 -0
  560. package/plugins/microsandbox/dist/runner/free-port.js +53 -0
  561. package/plugins/microsandbox/dist/runner/free-port.js.map +1 -0
  562. package/plugins/microsandbox/dist/runner/index.d.ts +28 -0
  563. package/plugins/microsandbox/dist/runner/index.d.ts.map +1 -0
  564. package/plugins/microsandbox/dist/runner/index.js +72 -0
  565. package/plugins/microsandbox/dist/runner/index.js.map +1 -0
  566. package/plugins/microsandbox/dist/runner/microsandbox.d.ts +64 -0
  567. package/plugins/microsandbox/dist/runner/microsandbox.d.ts.map +1 -0
  568. package/plugins/microsandbox/dist/runner/microsandbox.js +668 -0
  569. package/plugins/microsandbox/dist/runner/microsandbox.js.map +1 -0
  570. package/plugins/microsandbox/dist/runner/nullable.d.ts +36 -0
  571. package/plugins/microsandbox/dist/runner/nullable.d.ts.map +1 -0
  572. package/plugins/microsandbox/dist/runner/nullable.js +82 -0
  573. package/plugins/microsandbox/dist/runner/nullable.js.map +1 -0
  574. package/plugins/microsandbox/dist/runner/pool.d.ts +97 -0
  575. package/plugins/microsandbox/dist/runner/pool.d.ts.map +1 -0
  576. package/plugins/microsandbox/dist/runner/pool.js +494 -0
  577. package/plugins/microsandbox/dist/runner/pool.js.map +1 -0
  578. package/plugins/microsandbox/dist/runner/types.d.ts +33 -0
  579. package/plugins/microsandbox/dist/runner/types.d.ts.map +1 -0
  580. package/plugins/microsandbox/dist/runner/types.js +79 -0
  581. package/plugins/microsandbox/dist/runner/types.js.map +1 -0
  582. package/plugins/microsandbox/dist/server.d.ts +7 -0
  583. package/plugins/microsandbox/dist/server.d.ts.map +1 -0
  584. package/plugins/microsandbox/dist/server.js +276 -0
  585. package/plugins/microsandbox/dist/server.js.map +1 -0
  586. package/plugins/microsandbox/dist/tools/browser.d.ts +25 -0
  587. package/plugins/microsandbox/dist/tools/browser.d.ts.map +1 -0
  588. package/plugins/microsandbox/dist/tools/browser.js +78 -0
  589. package/plugins/microsandbox/dist/tools/browser.js.map +1 -0
  590. package/plugins/microsandbox/dist/tools/build.d.ts +5 -0
  591. package/plugins/microsandbox/dist/tools/build.d.ts.map +1 -0
  592. package/plugins/microsandbox/dist/tools/build.js +243 -0
  593. package/plugins/microsandbox/dist/tools/build.js.map +1 -0
  594. package/plugins/microsandbox/dist/tools/index.d.ts +9 -0
  595. package/plugins/microsandbox/dist/tools/index.d.ts.map +1 -0
  596. package/plugins/microsandbox/dist/tools/index.js +430 -0
  597. package/plugins/microsandbox/dist/tools/index.js.map +1 -0
  598. package/plugins/microsandbox/dist/tools/mcp-client.d.ts +63 -0
  599. package/plugins/microsandbox/dist/tools/mcp-client.d.ts.map +1 -0
  600. package/plugins/microsandbox/dist/tools/mcp-client.js +226 -0
  601. package/plugins/microsandbox/dist/tools/mcp-client.js.map +1 -0
  602. package/plugins/microsandbox/manifest.json +177 -0
  603. package/plugins/microsandbox/package.json +38 -0
  604. package/plugins/microsandbox/skills/microsandbox-browser-howto.md +155 -0
  605. package/plugins/microsandbox/skills/microsandbox-build-use.md +201 -0
  606. package/plugins/microsandbox/skills/microsandbox-config.md +38 -0
  607. package/plugins/microsandbox/skills/microsandbox-exec-howto.md +144 -0
  608. package/plugins/microsandbox/skills/microsandbox-libreoffice.md +159 -0
  609. package/plugins/microsandbox/templates/README.md +26 -0
  610. package/plugins/web-search/dist/server.d.ts +4 -0
  611. package/plugins/web-search/dist/server.d.ts.map +1 -0
  612. package/plugins/web-search/dist/server.js +73 -0
  613. package/plugins/web-search/dist/server.js.map +1 -0
  614. package/plugins/web-search/dist/tools/health.d.ts +31 -0
  615. package/plugins/web-search/dist/tools/health.d.ts.map +1 -0
  616. package/plugins/web-search/dist/tools/health.js +59 -0
  617. package/plugins/web-search/dist/tools/health.js.map +1 -0
  618. package/plugins/web-search/dist/tools/index.d.ts +3 -0
  619. package/plugins/web-search/dist/tools/index.d.ts.map +1 -0
  620. package/plugins/web-search/dist/tools/index.js +2 -0
  621. package/plugins/web-search/dist/tools/index.js.map +1 -0
  622. package/plugins/web-search/dist/tools/providers.d.ts +43 -0
  623. package/plugins/web-search/dist/tools/providers.d.ts.map +1 -0
  624. package/plugins/web-search/dist/tools/providers.js +140 -0
  625. package/plugins/web-search/dist/tools/providers.js.map +1 -0
  626. package/plugins/web-search/dist/tools/web-search.d.ts +15 -0
  627. package/plugins/web-search/dist/tools/web-search.d.ts.map +1 -0
  628. package/plugins/web-search/dist/tools/web-search.js +244 -0
  629. package/plugins/web-search/dist/tools/web-search.js.map +1 -0
  630. package/plugins/web-search/manifest.json +65 -0
  631. package/plugins/web-search/node_modules/@esbuild/darwin-arm64/README.md +3 -0
  632. package/plugins/web-search/node_modules/@esbuild/darwin-arm64/package.json +20 -0
  633. package/plugins/web-search/node_modules/@vitest/expect/LICENSE +21 -0
  634. package/plugins/web-search/node_modules/@vitest/expect/README.md +21 -0
  635. package/plugins/web-search/node_modules/@vitest/expect/dist/index.d.ts +808 -0
  636. package/plugins/web-search/node_modules/@vitest/expect/dist/index.js +1799 -0
  637. package/plugins/web-search/node_modules/@vitest/expect/package.json +46 -0
  638. package/plugins/web-search/node_modules/@vitest/mocker/LICENSE +21 -0
  639. package/plugins/web-search/node_modules/@vitest/mocker/README.md +5 -0
  640. package/plugins/web-search/node_modules/@vitest/mocker/dist/auto-register.d.ts +2 -0
  641. package/plugins/web-search/node_modules/@vitest/mocker/dist/auto-register.js +9 -0
  642. package/plugins/web-search/node_modules/@vitest/mocker/dist/browser.d.ts +53 -0
  643. package/plugins/web-search/node_modules/@vitest/mocker/dist/browser.js +91 -0
  644. package/plugins/web-search/node_modules/@vitest/mocker/dist/chunk-interceptor-native.js +15 -0
  645. package/plugins/web-search/node_modules/@vitest/mocker/dist/chunk-mocker.js +1602 -0
  646. package/plugins/web-search/node_modules/@vitest/mocker/dist/chunk-pathe.M-eThtNZ.js +174 -0
  647. package/plugins/web-search/node_modules/@vitest/mocker/dist/chunk-registry.js +182 -0
  648. package/plugins/web-search/node_modules/@vitest/mocker/dist/chunk-utils.js +16 -0
  649. package/plugins/web-search/node_modules/@vitest/mocker/dist/index.d.ts +21 -0
  650. package/plugins/web-search/node_modules/@vitest/mocker/dist/index.js +174 -0
  651. package/plugins/web-search/node_modules/@vitest/mocker/dist/mocker.d-Ce9_ySj5.d.ts +83 -0
  652. package/plugins/web-search/node_modules/@vitest/mocker/dist/node.d.ts +821 -0
  653. package/plugins/web-search/node_modules/@vitest/mocker/dist/node.js +1306 -0
  654. package/plugins/web-search/node_modules/@vitest/mocker/dist/redirect.d.ts +3 -0
  655. package/plugins/web-search/node_modules/@vitest/mocker/dist/redirect.js +75 -0
  656. package/plugins/web-search/node_modules/@vitest/mocker/dist/register.d.ts +9 -0
  657. package/plugins/web-search/node_modules/@vitest/mocker/dist/register.js +41 -0
  658. package/plugins/web-search/node_modules/@vitest/mocker/dist/registry.d-D765pazg.d.ts +87 -0
  659. package/plugins/web-search/node_modules/@vitest/mocker/dist/types.d-D_aRZRdy.d.ts +8 -0
  660. package/plugins/web-search/node_modules/@vitest/mocker/package.json +82 -0
  661. package/plugins/web-search/node_modules/@vitest/pretty-format/LICENSE +21 -0
  662. package/plugins/web-search/node_modules/@vitest/pretty-format/dist/index.d.ts +119 -0
  663. package/plugins/web-search/node_modules/@vitest/pretty-format/dist/index.js +1387 -0
  664. package/plugins/web-search/node_modules/@vitest/pretty-format/package.json +44 -0
  665. package/plugins/web-search/node_modules/@vitest/runner/LICENSE +21 -0
  666. package/plugins/web-search/node_modules/@vitest/runner/README.md +5 -0
  667. package/plugins/web-search/node_modules/@vitest/runner/dist/chunk-hooks.js +2254 -0
  668. package/plugins/web-search/node_modules/@vitest/runner/dist/index.d.ts +261 -0
  669. package/plugins/web-search/node_modules/@vitest/runner/dist/index.js +6 -0
  670. package/plugins/web-search/node_modules/@vitest/runner/dist/tasks.d-CkscK4of.d.ts +558 -0
  671. package/plugins/web-search/node_modules/@vitest/runner/dist/types.d.ts +163 -0
  672. package/plugins/web-search/node_modules/@vitest/runner/dist/types.js +1 -0
  673. package/plugins/web-search/node_modules/@vitest/runner/dist/utils.d.ts +47 -0
  674. package/plugins/web-search/node_modules/@vitest/runner/dist/utils.js +6 -0
  675. package/plugins/web-search/node_modules/@vitest/runner/package.json +49 -0
  676. package/plugins/web-search/node_modules/@vitest/snapshot/LICENSE +21 -0
  677. package/plugins/web-search/node_modules/@vitest/snapshot/README.md +84 -0
  678. package/plugins/web-search/node_modules/@vitest/snapshot/dist/environment.d-DHdQ1Csl.d.ts +22 -0
  679. package/plugins/web-search/node_modules/@vitest/snapshot/dist/environment.d.ts +16 -0
  680. package/plugins/web-search/node_modules/@vitest/snapshot/dist/environment.js +40 -0
  681. package/plugins/web-search/node_modules/@vitest/snapshot/dist/index.d.ts +137 -0
  682. package/plugins/web-search/node_modules/@vitest/snapshot/dist/index.js +2305 -0
  683. package/plugins/web-search/node_modules/@vitest/snapshot/dist/manager.d.ts +18 -0
  684. package/plugins/web-search/node_modules/@vitest/snapshot/dist/manager.js +73 -0
  685. package/plugins/web-search/node_modules/@vitest/snapshot/dist/rawSnapshot.d-lFsMJFUd.d.ts +61 -0
  686. package/plugins/web-search/node_modules/@vitest/snapshot/package.json +54 -0
  687. package/plugins/web-search/node_modules/@vitest/spy/LICENSE +21 -0
  688. package/plugins/web-search/node_modules/@vitest/spy/README.md +3 -0
  689. package/plugins/web-search/node_modules/@vitest/spy/dist/index.d.ts +356 -0
  690. package/plugins/web-search/node_modules/@vitest/spy/dist/index.js +191 -0
  691. package/plugins/web-search/node_modules/@vitest/spy/package.json +38 -0
  692. package/plugins/web-search/node_modules/@vitest/utils/LICENSE +21 -0
  693. package/plugins/web-search/node_modules/@vitest/utils/dist/chunk-_commonjsHelpers.js +158 -0
  694. package/plugins/web-search/node_modules/@vitest/utils/dist/diff.d.ts +104 -0
  695. package/plugins/web-search/node_modules/@vitest/utils/dist/diff.js +2185 -0
  696. package/plugins/web-search/node_modules/@vitest/utils/dist/error.d.ts +9 -0
  697. package/plugins/web-search/node_modules/@vitest/utils/dist/error.js +162 -0
  698. package/plugins/web-search/node_modules/@vitest/utils/dist/helpers.d.ts +56 -0
  699. package/plugins/web-search/node_modules/@vitest/utils/dist/helpers.js +251 -0
  700. package/plugins/web-search/node_modules/@vitest/utils/dist/index.d.ts +57 -0
  701. package/plugins/web-search/node_modules/@vitest/utils/dist/index.js +633 -0
  702. package/plugins/web-search/node_modules/@vitest/utils/dist/source-map.d.ts +139 -0
  703. package/plugins/web-search/node_modules/@vitest/utils/dist/source-map.js +996 -0
  704. package/plugins/web-search/node_modules/@vitest/utils/dist/types.d-BCElaP-c.d.ts +53 -0
  705. package/plugins/web-search/node_modules/@vitest/utils/dist/types.d.ts +53 -0
  706. package/plugins/web-search/node_modules/@vitest/utils/dist/types.js +1 -0
  707. package/plugins/web-search/node_modules/@vitest/utils/package.json +77 -0
  708. package/plugins/web-search/node_modules/chai/LICENSE +21 -0
  709. package/plugins/web-search/node_modules/chai/README.md +162 -0
  710. package/plugins/web-search/node_modules/chai/package.json +74 -0
  711. package/plugins/web-search/node_modules/esbuild/README.md +3 -0
  712. package/plugins/web-search/node_modules/esbuild/package.json +49 -0
  713. package/plugins/web-search/node_modules/std-env/README.md +118 -0
  714. package/plugins/web-search/node_modules/std-env/dist/index.cjs +1 -0
  715. package/plugins/web-search/node_modules/std-env/dist/index.d.cts +92 -0
  716. package/plugins/web-search/node_modules/std-env/dist/index.d.mts +92 -0
  717. package/plugins/web-search/node_modules/std-env/dist/index.d.ts +92 -0
  718. package/plugins/web-search/node_modules/std-env/dist/index.mjs +1 -0
  719. package/plugins/web-search/node_modules/std-env/package.json +46 -0
  720. package/plugins/web-search/node_modules/tinyexec/LICENSE +21 -0
  721. package/plugins/web-search/node_modules/tinyexec/README.md +256 -0
  722. package/plugins/web-search/node_modules/tinyexec/dist/main.cjs +575 -0
  723. package/plugins/web-search/node_modules/tinyexec/dist/main.d.cts +70 -0
  724. package/plugins/web-search/node_modules/tinyexec/dist/main.d.ts +70 -0
  725. package/plugins/web-search/node_modules/tinyexec/dist/main.js +578 -0
  726. package/plugins/web-search/node_modules/tinyexec/package.json +66 -0
  727. package/plugins/web-search/node_modules/tinyrainbow/README.md +28 -0
  728. package/plugins/web-search/node_modules/tinyrainbow/dist/browser.d.ts +8 -0
  729. package/plugins/web-search/node_modules/tinyrainbow/dist/browser.js +20 -0
  730. package/plugins/web-search/node_modules/tinyrainbow/dist/chunk-BVHSVHOK.js +90 -0
  731. package/plugins/web-search/node_modules/tinyrainbow/dist/index-8b61d5bc.d.ts +59 -0
  732. package/plugins/web-search/node_modules/tinyrainbow/dist/node.d.ts +8 -0
  733. package/plugins/web-search/node_modules/tinyrainbow/dist/node.js +22 -0
  734. package/plugins/web-search/node_modules/tinyrainbow/package.json +37 -0
  735. package/plugins/web-search/node_modules/typescript/README.md +50 -0
  736. package/plugins/web-search/node_modules/typescript/package.json +120 -0
  737. package/plugins/web-search/node_modules/vite/README.md +20 -0
  738. package/plugins/web-search/node_modules/vite/dist/client/client.mjs +1106 -0
  739. package/plugins/web-search/node_modules/vite/dist/client/env.mjs +19 -0
  740. package/plugins/web-search/node_modules/vite/dist/node/chunks/build.js +4 -0
  741. package/plugins/web-search/node_modules/vite/dist/node/chunks/build2.js +5538 -0
  742. package/plugins/web-search/node_modules/vite/dist/node/chunks/chunk.js +48 -0
  743. package/plugins/web-search/node_modules/vite/dist/node/chunks/config.js +36065 -0
  744. package/plugins/web-search/node_modules/vite/dist/node/chunks/config2.js +4 -0
  745. package/plugins/web-search/node_modules/vite/dist/node/chunks/dist.js +6758 -0
  746. package/plugins/web-search/node_modules/vite/dist/node/chunks/lib.js +377 -0
  747. package/plugins/web-search/node_modules/vite/dist/node/chunks/logger.js +329 -0
  748. package/plugins/web-search/node_modules/vite/dist/node/chunks/moduleRunnerTransport.d.ts +96 -0
  749. package/plugins/web-search/node_modules/vite/dist/node/chunks/optimizer.js +4 -0
  750. package/plugins/web-search/node_modules/vite/dist/node/chunks/postcss-import.js +479 -0
  751. package/plugins/web-search/node_modules/vite/dist/node/chunks/preview.js +4 -0
  752. package/plugins/web-search/node_modules/vite/dist/node/chunks/server.js +4 -0
  753. package/plugins/web-search/node_modules/vite/dist/node/cli.js +698 -0
  754. package/plugins/web-search/node_modules/vite/dist/node/index.d.ts +3717 -0
  755. package/plugins/web-search/node_modules/vite/dist/node/index.js +30 -0
  756. package/plugins/web-search/node_modules/vite/dist/node/module-runner.d.ts +311 -0
  757. package/plugins/web-search/node_modules/vite/dist/node/module-runner.js +1160 -0
  758. package/plugins/web-search/node_modules/vite/package.json +199 -0
  759. package/plugins/web-search/node_modules/vite/types/package.json +4 -0
  760. package/plugins/web-search/node_modules/vitest/README.md +7 -0
  761. package/plugins/web-search/node_modules/vitest/dist/browser.d.ts +34 -0
  762. package/plugins/web-search/node_modules/vitest/dist/browser.js +8 -0
  763. package/plugins/web-search/node_modules/vitest/dist/chunks/_commonjsHelpers.BFTU3MAI.js +7 -0
  764. package/plugins/web-search/node_modules/vitest/dist/chunks/base.DfmxU-tU.js +38 -0
  765. package/plugins/web-search/node_modules/vitest/dist/chunks/benchmark.CYdenmiT.js +37 -0
  766. package/plugins/web-search/node_modules/vitest/dist/chunks/benchmark.d.BwvBVTda.d.ts +24 -0
  767. package/plugins/web-search/node_modules/vitest/dist/chunks/cac.0BJqEUeA.js +1469 -0
  768. package/plugins/web-search/node_modules/vitest/dist/chunks/cli-api.DWGBtMmz.js +10660 -0
  769. package/plugins/web-search/node_modules/vitest/dist/chunks/config.d.BKdhh7Zx.d.ts +224 -0
  770. package/plugins/web-search/node_modules/vitest/dist/chunks/console.CtFJOzRO.js +153 -0
  771. package/plugins/web-search/node_modules/vitest/dist/chunks/constants.DnKduX2e.js +44 -0
  772. package/plugins/web-search/node_modules/vitest/dist/chunks/coverage.DVF1vEu8.js +25 -0
  773. package/plugins/web-search/node_modules/vitest/dist/chunks/coverage.DfSpMS-b.js +4350 -0
  774. package/plugins/web-search/node_modules/vitest/dist/chunks/coverage.d.S9RMNXIe.d.ts +35 -0
  775. package/plugins/web-search/node_modules/vitest/dist/chunks/creator.GK6I-cL4.js +640 -0
  776. package/plugins/web-search/node_modules/vitest/dist/chunks/date.Bq6ZW5rf.js +73 -0
  777. package/plugins/web-search/node_modules/vitest/dist/chunks/defaults.B7q_naMc.js +115 -0
  778. package/plugins/web-search/node_modules/vitest/dist/chunks/env.D4Lgay0q.js +8 -0
  779. package/plugins/web-search/node_modules/vitest/dist/chunks/environment.d.cL3nLXbE.d.ts +119 -0
  780. package/plugins/web-search/node_modules/vitest/dist/chunks/execute.B7h3T_Hc.js +708 -0
  781. package/plugins/web-search/node_modules/vitest/dist/chunks/git.BVQ8w_Sw.js +72 -0
  782. package/plugins/web-search/node_modules/vitest/dist/chunks/global.d.MAmajcmJ.d.ts +136 -0
  783. package/plugins/web-search/node_modules/vitest/dist/chunks/globals.DEHgCU4V.js +26 -0
  784. package/plugins/web-search/node_modules/vitest/dist/chunks/index.B521nVV-.js +157 -0
  785. package/plugins/web-search/node_modules/vitest/dist/chunks/index.BCWujgDG.js +231 -0
  786. package/plugins/web-search/node_modules/vitest/dist/chunks/index.CdQS2e2Q.js +37 -0
  787. package/plugins/web-search/node_modules/vitest/dist/chunks/index.CmSc2RE5.js +587 -0
  788. package/plugins/web-search/node_modules/vitest/dist/chunks/index.CwejwG0H.js +105 -0
  789. package/plugins/web-search/node_modules/vitest/dist/chunks/index.D3XRDfWc.js +213 -0
  790. package/plugins/web-search/node_modules/vitest/dist/chunks/index.VByaPkjc.js +2183 -0
  791. package/plugins/web-search/node_modules/vitest/dist/chunks/index.X0nbfr6-.js +6584 -0
  792. package/plugins/web-search/node_modules/vitest/dist/chunks/inspector.C914Efll.js +57 -0
  793. package/plugins/web-search/node_modules/vitest/dist/chunks/mocker.d.BE_2ls6u.d.ts +17 -0
  794. package/plugins/web-search/node_modules/vitest/dist/chunks/node.fjCdwEIl.js +15 -0
  795. package/plugins/web-search/node_modules/vitest/dist/chunks/reporters.d.BuRON0I0.d.ts +3168 -0
  796. package/plugins/web-search/node_modules/vitest/dist/chunks/rpc.-pEldfrD.js +83 -0
  797. package/plugins/web-search/node_modules/vitest/dist/chunks/runBaseTests.9Ij9_de-.js +129 -0
  798. package/plugins/web-search/node_modules/vitest/dist/chunks/setup-common.Dd054P77.js +60 -0
  799. package/plugins/web-search/node_modules/vitest/dist/chunks/suite.d.FvehnV49.d.ts +10 -0
  800. package/plugins/web-search/node_modules/vitest/dist/chunks/typechecker.DRKU1-1g.js +874 -0
  801. package/plugins/web-search/node_modules/vitest/dist/chunks/utils.CAioKnHs.js +61 -0
  802. package/plugins/web-search/node_modules/vitest/dist/chunks/utils.XdZDrNZV.js +65 -0
  803. package/plugins/web-search/node_modules/vitest/dist/chunks/vi.bdSIJ99Y.js +4015 -0
  804. package/plugins/web-search/node_modules/vitest/dist/chunks/vite.d.BnOPPc46.d.ts +25 -0
  805. package/plugins/web-search/node_modules/vitest/dist/chunks/vm.BThCzidc.js +756 -0
  806. package/plugins/web-search/node_modules/vitest/dist/chunks/worker.d.CUgIPz9V.d.ts +176 -0
  807. package/plugins/web-search/node_modules/vitest/dist/chunks/worker.d.uzWsCv9X.d.ts +8 -0
  808. package/plugins/web-search/node_modules/vitest/dist/cli.js +27 -0
  809. package/plugins/web-search/node_modules/vitest/dist/config.cjs +148 -0
  810. package/plugins/web-search/node_modules/vitest/dist/config.d.ts +100 -0
  811. package/plugins/web-search/node_modules/vitest/dist/config.js +21 -0
  812. package/plugins/web-search/node_modules/vitest/dist/coverage.d.ts +108 -0
  813. package/plugins/web-search/node_modules/vitest/dist/coverage.js +34 -0
  814. package/plugins/web-search/node_modules/vitest/dist/environments.d.ts +26 -0
  815. package/plugins/web-search/node_modules/vitest/dist/environments.js +2 -0
  816. package/plugins/web-search/node_modules/vitest/dist/execute.d.ts +150 -0
  817. package/plugins/web-search/node_modules/vitest/dist/execute.js +13 -0
  818. package/plugins/web-search/node_modules/vitest/dist/index.d.ts +651 -0
  819. package/plugins/web-search/node_modules/vitest/dist/index.js +18 -0
  820. package/plugins/web-search/node_modules/vitest/dist/mocker.d.ts +1 -0
  821. package/plugins/web-search/node_modules/vitest/dist/mocker.js +1 -0
  822. package/plugins/web-search/node_modules/vitest/dist/node.d.ts +158 -0
  823. package/plugins/web-search/node_modules/vitest/dist/node.js +105 -0
  824. package/plugins/web-search/node_modules/vitest/dist/path.js +7 -0
  825. package/plugins/web-search/node_modules/vitest/dist/reporters.d.ts +25 -0
  826. package/plugins/web-search/node_modules/vitest/dist/reporters.js +23 -0
  827. package/plugins/web-search/node_modules/vitest/dist/runners.d.ts +46 -0
  828. package/plugins/web-search/node_modules/vitest/dist/runners.js +235 -0
  829. package/plugins/web-search/node_modules/vitest/dist/snapshot.d.ts +9 -0
  830. package/plugins/web-search/node_modules/vitest/dist/snapshot.js +4 -0
  831. package/plugins/web-search/node_modules/vitest/dist/spy.js +1 -0
  832. package/plugins/web-search/node_modules/vitest/dist/suite.d.ts +5 -0
  833. package/plugins/web-search/node_modules/vitest/dist/suite.js +5 -0
  834. package/plugins/web-search/node_modules/vitest/dist/worker.js +124 -0
  835. package/plugins/web-search/node_modules/vitest/dist/workers/forks.js +43 -0
  836. package/plugins/web-search/node_modules/vitest/dist/workers/runVmTests.js +90 -0
  837. package/plugins/web-search/node_modules/vitest/dist/workers/threads.js +31 -0
  838. package/plugins/web-search/node_modules/vitest/dist/workers/vmForks.js +47 -0
  839. package/plugins/web-search/node_modules/vitest/dist/workers/vmThreads.js +37 -0
  840. package/plugins/web-search/node_modules/vitest/dist/workers.d.ts +40 -0
  841. package/plugins/web-search/node_modules/vitest/dist/workers.js +30 -0
  842. package/plugins/web-search/node_modules/vitest/package.json +207 -0
  843. package/plugins/web-search/package.json +30 -0
  844. package/plugins/web-search/skills/web-search-howto.md +69 -0
  845. package/plugins/workboard/agent-seeds/echo-demo/agent.json +7 -0
  846. package/plugins/workboard/agent-seeds/llm-default/SOUL.md +53 -0
  847. package/plugins/workboard/agent-seeds/llm-default/agent.json +7 -0
  848. package/plugins/workboard/dist/client.d.ts +5 -0
  849. package/plugins/workboard/dist/client.d.ts.map +1 -0
  850. package/plugins/workboard/dist/client.js +895 -0
  851. package/plugins/workboard/dist/client.js.map +1 -0
  852. package/plugins/workboard/dist/db/agents.d.ts +100 -0
  853. package/plugins/workboard/dist/db/agents.d.ts.map +1 -0
  854. package/plugins/workboard/dist/db/agents.js +280 -0
  855. package/plugins/workboard/dist/db/agents.js.map +1 -0
  856. package/plugins/workboard/dist/db/schema.d.ts +3 -0
  857. package/plugins/workboard/dist/db/schema.d.ts.map +1 -0
  858. package/plugins/workboard/dist/db/schema.js +31 -0
  859. package/plugins/workboard/dist/db/schema.js.map +1 -0
  860. package/plugins/workboard/dist/db/session-history.d.ts +28 -0
  861. package/plugins/workboard/dist/db/session-history.d.ts.map +1 -0
  862. package/plugins/workboard/dist/db/session-history.js +224 -0
  863. package/plugins/workboard/dist/db/session-history.js.map +1 -0
  864. package/plugins/workboard/dist/db/tasks.d.ts +260 -0
  865. package/plugins/workboard/dist/db/tasks.d.ts.map +1 -0
  866. package/plugins/workboard/dist/db/tasks.js +451 -0
  867. package/plugins/workboard/dist/db/tasks.js.map +1 -0
  868. package/plugins/workboard/dist/db/worker-agents.d.ts +16 -0
  869. package/plugins/workboard/dist/db/worker-agents.d.ts.map +1 -0
  870. package/plugins/workboard/dist/db/worker-agents.js +62 -0
  871. package/plugins/workboard/dist/db/worker-agents.js.map +1 -0
  872. package/plugins/workboard/dist/effective-skills.d.ts +13 -0
  873. package/plugins/workboard/dist/effective-skills.d.ts.map +1 -0
  874. package/plugins/workboard/dist/effective-skills.js +126 -0
  875. package/plugins/workboard/dist/effective-skills.js.map +1 -0
  876. package/plugins/workboard/dist/fs-worker-agents.d.ts +35 -0
  877. package/plugins/workboard/dist/fs-worker-agents.d.ts.map +1 -0
  878. package/plugins/workboard/dist/fs-worker-agents.js +199 -0
  879. package/plugins/workboard/dist/fs-worker-agents.js.map +1 -0
  880. package/plugins/workboard/dist/migrate-worker-agents.d.ts +11 -0
  881. package/plugins/workboard/dist/migrate-worker-agents.d.ts.map +1 -0
  882. package/plugins/workboard/dist/migrate-worker-agents.js +89 -0
  883. package/plugins/workboard/dist/migrate-worker-agents.js.map +1 -0
  884. package/plugins/workboard/dist/routes/handlers.d.ts +106 -0
  885. package/plugins/workboard/dist/routes/handlers.d.ts.map +1 -0
  886. package/plugins/workboard/dist/routes/handlers.js +668 -0
  887. package/plugins/workboard/dist/routes/handlers.js.map +1 -0
  888. package/plugins/workboard/dist/server.d.ts +6 -0
  889. package/plugins/workboard/dist/server.d.ts.map +1 -0
  890. package/plugins/workboard/dist/server.js +368 -0
  891. package/plugins/workboard/dist/server.js.map +1 -0
  892. package/plugins/workboard/dist/tools/index.d.ts +70 -0
  893. package/plugins/workboard/dist/tools/index.d.ts.map +1 -0
  894. package/plugins/workboard/dist/tools/index.js +963 -0
  895. package/plugins/workboard/dist/tools/index.js.map +1 -0
  896. package/plugins/workboard/dist/types.d.ts +27 -0
  897. package/plugins/workboard/dist/types.d.ts.map +1 -0
  898. package/plugins/workboard/dist/types.js +16 -0
  899. package/plugins/workboard/dist/types.js.map +1 -0
  900. package/plugins/workboard/dist/worker/pool.d.ts +220 -0
  901. package/plugins/workboard/dist/worker/pool.d.ts.map +1 -0
  902. package/plugins/workboard/dist/worker/pool.js +866 -0
  903. package/plugins/workboard/dist/worker/pool.js.map +1 -0
  904. package/plugins/workboard/dist/worker/tool-policy.d.ts +27 -0
  905. package/plugins/workboard/dist/worker/tool-policy.d.ts.map +1 -0
  906. package/plugins/workboard/dist/worker/tool-policy.js +76 -0
  907. package/plugins/workboard/dist/worker/tool-policy.js.map +1 -0
  908. package/plugins/workboard/dist/worker-agents-page.d.ts +4 -0
  909. package/plugins/workboard/dist/worker-agents-page.d.ts.map +1 -0
  910. package/plugins/workboard/dist/worker-agents-page.js +193 -0
  911. package/plugins/workboard/dist/worker-agents-page.js.map +1 -0
  912. package/plugins/workboard/manifest.json +180 -0
  913. package/plugins/workboard/package.json +37 -0
  914. package/plugins/workboard/skills/large-input-large-output.md +185 -0
  915. package/plugins/workboard/skills/workboard-howto.md +166 -0
  916. package/plugins/workboard/skills/worker-creator.md +267 -0
  917. package/plugins/workboard/skills/worker-fleet.md +431 -0
@@ -0,0 +1,1353 @@
1
+ // CLI agent — runs an interactive chat loop in the terminal after
2
+ // `tianshu setup --wizard` finishes provisioning the LLM. Lets the
3
+ // user finish the rest of setup (enabling plugins, creating
4
+ // tenants, configuring web-search keys, etc.) by talking to the
5
+ // agent rather than learning a CLI surface.
6
+ //
7
+ // Why CLI rather than browser:
8
+ // the user is already in a terminal having just run the wizard;
9
+ // jumping to a browser breaks the flow. The CLI agent shares a
10
+ // minimal toolset (tenant / config / doctor) but does NOT spin up
11
+ // the full plugin runtime — those tools cover everything the
12
+ // post-setup phase needs.
13
+ //
14
+ // Out of scope:
15
+ // - full chat history (this is a one-shot setup conversation)
16
+ // - sandbox exec (microsandbox lives in plugin-land; if the user
17
+ // needs the microsandbox npm dep installed, the agent tells
18
+ // them which `npm install` step likely failed)
19
+ // - workboard (worker spawn is overkill for setup)
20
+ //
21
+ // Tools shipped (12): tenant_list, tenant_create, user_create,
22
+ // plugin_enable, plugin_disable, config_read, config_write,
23
+ // run_doctor, read_service_logs, read_env_file,
24
+ // build_sandbox, use_sandbox_build. Plus the implicit "done"
25
+ // sentinel.
26
+ import * as p from "@clack/prompts";
27
+ import fs from "node:fs";
28
+ import os from "node:os";
29
+ import path from "node:path";
30
+ import { complete } from "@earendil-works/pi-ai";
31
+ import { GlobalOps } from "../core/global-ops.js";
32
+ import { buildModel, getDefaultModel, resolveApiKey, } from "../core/llm.js";
33
+ import { loadGlobalConfig, writeGlobalConfig, writeTenantConfig, TenantConfigForbiddenFieldError, } from "../core/config.js";
34
+ import { getTenantsRoot, getTianshuHome, getGlobalConfigPath, } from "../core/paths.js";
35
+ import { applyPluginSecretPatch, loadPluginSecrets, } from "../core/plugins/index.js";
36
+ import { collectDoctorReport } from "./doctor.js";
37
+ import * as launchd from "./launchd.js";
38
+ import { findRepoRoot } from "./repo-root.js";
39
+ const SETUP_SYSTEM_PROMPT = `You are the tianshu setup assistant.
40
+
41
+ The user just finished configuring an LLM provider. Your job is
42
+ to walk them through the remaining setup decisions — not to
43
+ silently auto-configure things behind their back. Every state-
44
+ changing tool call (tenant_create, user_create, plugin_enable,
45
+ plugin_disable, config_write) is intercepted by the CLI and the
46
+ user is asked to confirm before it runs. Plan accordingly: don't
47
+ batch 10 actions in one turn; propose a small, named change,
48
+ call the tool, then continue based on what the user accepts.
49
+
50
+ Workflow on the FIRST turn:
51
+
52
+ 1. Call run_doctor to see what's set up. If doctor reports the server isn't running or isn't responding, call read_service_logs to see *why* before suggesting fixes.
53
+ 2. Look at the report and write ONE message to the user:
54
+ - In plain language, summarise what's already working.
55
+ - List what looks like it should be set up next (e.g.
56
+ 'workboard plugin is disabled', 'microsandbox runtime
57
+ binary not found', 'no Tavily API key for web-search').
58
+ - For each item, propose the action you'd like to take and
59
+ which tool call you'd run. Don't run them yet.
60
+ - End by asking the user which they want to do first, or
61
+ whether to skip ahead.
62
+
63
+ From turn 2 onward:
64
+ - Run one tool at a time, narrate why before each one (the CLI
65
+ will pop a confirmation — the user already sees the
66
+ one-liner you described, but your message gives the reason).
67
+ - After a tool runs, narrate what happened (one short line)
68
+ and propose the next step.
69
+ - If the user declines a confirmation, drop that idea and
70
+ move on — don't retry the same tool with the same args.
71
+
72
+ Style: brief, direct, no fluff. Don't ask the user to copy-paste
73
+ shell commands; either run a tool, or tell them clearly what
74
+ they need to do outside this CLI (e.g. 'run \`npx microsandbox
75
+ install\` in another terminal then re-run setup').
76
+
77
+ Domain knowledge you must apply when relevant:
78
+
79
+ GLOBAL VS TENANT CONFIG (config_read / config_write):
80
+ - Two scopes live side by side:
81
+ * GLOBAL = ~/.tianshu/config.json. System-wide. Controls server port,
82
+ logging, the *baseline* provider catalog (models.providers), the
83
+ baseline default model, autoCreateDefault. New tenants inherit
84
+ everything in here unless they override.
85
+ * TENANT = ~/.tianshu/tenants/<id>/config.json. Per-tenant. Can
86
+ override the overridable subset: plugins (enable/disable per
87
+ tenant), models (a tenant-specific catalog that wholesale-
88
+ replaces global's), defaultModel, branding, apiKeys, mcp.
89
+ Tenants CAN'T set server.port / logging / autoCreateDefault —
90
+ those are GlobalOnlyConfig; writeTenantConfig rejects them.
91
+ - Which one to write to when a user asks for something:
92
+ * "add a provider" / "set the default model" / "server settings"
93
+ → GLOBAL, unless the user explicitly says "for tenant X".
94
+ GLOBAL is the right default for first-time setup and most
95
+ config changes; new tenants will inherit from there.
96
+ * "enable / disable a plugin for me" or "for my tenant"
97
+ → TENANT. Plugin enablement is per-tenant.
98
+ * "my tenant should use a different model than everyone else"
99
+ → TENANT. Set defaultModel on the tenant; also set
100
+ models.providers on the tenant if the model isn't in global.
101
+ * Bad \`api\` value flagged by run_doctor: the doctor output
102
+ tells you which scope ('LLM providers' section = global,
103
+ 'Tenants & plugins' section = tenant) — fix it at the same
104
+ scope it was reported.
105
+ - Both scopes use shallow top-level merge: \`config_write\` reads the
106
+ existing file, spreads it, overlays your patch, writes back. So
107
+ a patch like \`{"defaultModel": "x"}\` only touches that one key.
108
+ - Trying to set a global-only field on a tenant returns
109
+ \`error: tenant_forbidden_field\` with a hint. Switch to
110
+ which='global' and retry.
111
+
112
+ WEB SEARCH (web-search plugin):
113
+ - API keys go to SECRETS, not regular config. Use \`secret_write\`
114
+ with pluginId='web-search' and key='tavilyApiKey' (Tavily) or
115
+ 'braveApiKey' (Brave). DO NOT use \`config_write\` for these.
116
+ config.json is committable, secrets/ is not.
117
+ - Check \`secret_list\` first to see what's already configured
118
+ before asking the user for a key.
119
+
120
+ PROVIDERS / MODELS (config.json's \`models.providers\` map):
121
+ - The \`api\` field MUST be a value pi-ai recognises. The only
122
+ ones in current use are:
123
+ * \`openai-completions\` — use for OpenAI itself AND for any
124
+ OpenAI-compatible vendor: dashscope, deepseek, moonshot,
125
+ siliconflow, together, groq, llama-server, ollama, anything
126
+ that exposes \`/v1/chat/completions\`. The name is
127
+ confusingly historical — it points at \`/v1/chat/completions\`
128
+ not the legacy \`/v1/completions\`. Use this whenever the
129
+ upstream advertises "OpenAI-compatible".
130
+ * \`anthropic-messages\` — Anthropic native API (\`/v1/messages\`).
131
+ * \`google-generative-ai\` — Google Gemini native API.
132
+ * \`openai-responses\` — OpenAI's newer Responses API. Only
133
+ use when the user explicitly wants it; the default for
134
+ OpenAI itself is still \`openai-completions\`.
135
+ Common typos to NEVER write: "openai-chat" (does not exist),
136
+ "chat-completions" (does not exist), "openai" (no api type).
137
+ - A typical OpenAI-compatible provider entry looks like:
138
+ "qwen": {
139
+ "api": "openai-completions",
140
+ "baseUrl": "https://dashscope.aliyuncs.com/compatible-mode/v1",
141
+ "apiKey": "sk-...",
142
+ "group": "Cloud",
143
+ "models": [
144
+ { "id": "qwen3-max-preview", "name": "Qwen3 Max Preview",
145
+ "contextWindow": 256000, "maxTokens": 8192 }
146
+ ]
147
+ }
148
+ baseUrl is the *prefix* before /chat/completions — NOT the full
149
+ endpoint URL. pi-ai appends the path itself.
150
+ - defaultModel must point at a model that exists in the catalog:
151
+ "defaultModel": "qwen/qwen3-max-preview" matches
152
+ models.providers.qwen.models[].id = "qwen3-max-preview".
153
+ If the tenant overrides \`models\` but doesn't set defaultModel,
154
+ the server auto-picks the first provider's first model, but
155
+ setting defaultModel explicitly is clearer and survives catalog
156
+ edits.
157
+ - apiKey can be a literal string (default since 2026-06; lands
158
+ in config.json which is chmod 600) or a \`\${ENV_VAR}\`
159
+ placeholder if the user opted into --use-env mode.
160
+ - Each model entry SHOULD carry \`contextWindow\` and \`maxTokens\`
161
+ (both in tokens). Meaning:
162
+ * \`contextWindow\` = total token budget for the request
163
+ (system prompt + history + tools + the new response). The
164
+ server uses this for context-overflow detection.
165
+ * \`maxTokens\` = the per-response output cap sent to the
166
+ provider as max_tokens / generation_config.max_output_tokens.
167
+ Truncates generation at this many tokens.
168
+ Rules:
169
+ * maxTokens MUST be ≤ contextWindow (doctor flags inversion
170
+ as a blocker).
171
+ * If either field is missing the server falls back to 128_000 /
172
+ 4_096 (see core/llm.ts buildModelInfoFromEntry). Modern
173
+ models support much more on both axes — leaving them blank
174
+ silently caps real capability.
175
+ * When the user asks to "set them to the max" or when doctor
176
+ flags either field as missing / suspiciously low / below the
177
+ known ceiling: FIRST look at \`docs/known-models.md\` in the
178
+ tianshu repo. That file is a curated reference with source
179
+ URLs and lastVerified dates; if it has the model id, use
180
+ those values. If the model id isn't in the table, fall back
181
+ to fetching the provider's docs (web_fetch / web_search
182
+ when available) and PR the new row into known-models.md
183
+ along with the catalog update so the next setup gets the
184
+ benefit.
185
+ * Do NOT guess from memory — these limits drift release-over-
186
+ release (we've seen qwen3-max-preview ship at maxTokens=8192
187
+ in catalogs while the provider already supported 32k).
188
+ * If you can't reach the docs in this session, ask the user
189
+ to paste them, or fill in conservative round numbers and
190
+ note in the response that these are placeholders to verify
191
+ against the provider's docs.
192
+ * Doctor's "below known ceiling" warning is a *suggestion*,
193
+ not a blocker. If the user picked a lower cap deliberately
194
+ (cost control, slow models, etc.), respect their choice —
195
+ don't auto-bump on their behalf, just confirm they meant it.
196
+
197
+ WORKBOARD WORKERS (workboard plugin):
198
+ - When the user enables workboard, the LLM worker pool starts up
199
+ with one worker per enabled \`agent.json\` in the tenant's
200
+ agent-seeds bundle. There is no "worker count" setting at the
201
+ config level — if the user wants more workers, they add more
202
+ agent.json files. The cli-agent doesn't manage agent files
203
+ directly; that's the user / chat agent's job.
204
+ - Each LLM worker picks its model in this order:
205
+ 1. \`modelId\` field in the worker's own agent.json (per-worker
206
+ override; rare)
207
+ 2. resolved tenant defaultModel (\`tenant.defaultModel\` else
208
+ auto-pick from tenant.models else global.defaultModel)
209
+ - If \`run_doctor\` says "workboard: no defaultModel resolvable",
210
+ set tenant.defaultModel (via \`config_write\` which='tenant')
211
+ or global.defaultModel (which='global'). Don't try to find a
212
+ worker-specific setting; there isn't one.
213
+ - The schema still carries a \`worker: { count, pollMs, model }\`
214
+ field for backwards compat. It has NO runtime effect; doctor
215
+ flags it as deprecated. Do not write to it. If a user asks to
216
+ "configure worker count / polling / model", explain that those
217
+ are not real settings in this build, and steer them toward
218
+ what actually matters: tenant.defaultModel for which model the
219
+ workers use, and the agent-seeds bundle for how many workers
220
+ there are.
221
+
222
+ MICROSANDBOX (sandbox-based plugins: microsandbox, browser):
223
+ - microsandbox uses TWO sandbox role pointers: 'task' (per-task
224
+ ephemeral sandboxes for the workboard's exec/coding work) and
225
+ 'browser' (the long-lived sandbox hosting the headless Chromium
226
+ + playwright-mcp sidecar). They share an underlying snapshot —
227
+ one snapshot can serve both roles.
228
+ - The two relevant tools — build_sandbox and use_sandbox_build —
229
+ ARE available here in the setup wizard. Use them when the user
230
+ asks to set up / rebuild / refresh sandboxes. Don't tell them
231
+ they have to go to the chat shell.
232
+ - Standard setup flow when a user wants sandboxes ready. This
233
+ is a TWO-snapshot layered build, NOT one big monolith. Why:
234
+ the task pool runs lots of short-lived sandboxes and shouldn't
235
+ carry Chromium's ~2.5 GB; the browser sandbox is long-lived
236
+ and DOES need Chromium. Layering also reuses apt cache between
237
+ the two builds, saving the second pull.
238
+ 1. build_sandbox(template='task-runner') → returns
239
+ {buildId: B1, snapshotName: S1}. WARN THE USER FIRST: this
240
+ takes 5-7 min; the wizard's UI hangs on a single spinner.
241
+ 2. use_sandbox_build(buildId=B1, role='task') → publishes
242
+ S1 as the task-pool snapshot.
243
+ 3. build_sandbox(template='task-runner-with-browser',
244
+ fromSnapshot=S1) → returns {buildId: B2, snapshotName: S2}.
245
+ Another 3-5 min spinner. Skipping fromSnapshot here is a
246
+ hard error; the build_sandbox tool guards against it but
247
+ you should know.
248
+ 4. use_sandbox_build(buildId=B2, role='browser') → publishes
249
+ S2 as the long-lived browser sandbox.
250
+ After step 4 the user can immediately use the chat / workboard.
251
+ If the user explicitly wants a no-browser setup, stop after
252
+ step 2 and tell them they can build the browser layer later.
253
+ - If \`run_doctor\` reports "microsandbox SDK not available" or
254
+ "Sandbox class missing", the platform-specific NAPI binding
255
+ didn't install. You can NOT build sandboxes yet. Tell the user:
256
+ 'run \`npm install\` from the tianshu checkout root and watch
257
+ for any error in the output — the binding ships as an optional
258
+ dependency (\`@superradcompany/microsandbox-<triple>\`), and
259
+ optional dep failures are silent by default.' Do NOT recommend
260
+ \`npx microsandbox install\` — in current msb versions that's
261
+ \`msb install <image>\` (a different command, different purpose)
262
+ and will fail with a missing-argument error. Don't try to call
263
+ build_sandbox before the SDK is present; the server will return
264
+ runner_not_ready (503).
265
+ - Template choice cheat-sheet:
266
+ * task-runner → first build in the standard layered flow.
267
+ Also the only build needed if the user wants no browser.
268
+ * task-runner-with-browser → second build, layered on top of
269
+ the task-runner snapshot via fromSnapshot=<S1's snapshotName>.
270
+ Without fromSnapshot it errors out (build_sandbox catches
271
+ that and returns missing_from_snapshot).
272
+ * browser → the monolithic alternative (full stack, ~3.2 GB,
273
+ no layering). Use only if the user specifically wants a
274
+ single-snapshot setup; the layered flow is preferred.
275
+ - If the wizard installed a launchd agent but the server isn't
276
+ responding (run_doctor reports "Server port free" or "port in
277
+ use, no HTTP response", or the user says "server didn't come
278
+ up"), call \`read_service_logs\` *first*. The actual error
279
+ message from npm/node will be in there. Don't guess; don't
280
+ ask the user to run \`tail\`. Common patterns to look for:
281
+ * "command not found: npm" → launchd's PATH doesn't have npm.
282
+ Check whether \`which npm\` from the user's shell points
283
+ somewhere unusual (volta, fnm, asdf). The fix is to bump
284
+ PATH in the plist's EnvironmentVariables and reinstall via
285
+ \`tianshu setup --wizard\`.
286
+ * "EADDRINUSE" → port collision. Run \`run_doctor\` to confirm
287
+ and ask the user to pick a different PORT/WEB_PORT in .env.
288
+ * "Cannot find module" / "ENOENT package.json" → wizard
289
+ captured the wrong WorkingDirectory. Check
290
+ \`~/Library/LaunchAgents/ai.tianshu.dev*.plist\`.
291
+ * "API key not set" / "references env var but it's empty"
292
+ → first call \`config_read\` and check the providers'
293
+ apiKey field. As of 2026-06 the wizard's default is to
294
+ write the literal key into config.json (chmod 600), NOT
295
+ into .env. So if config.json shows a placeholder like
296
+ \`"\${ANTHROPIC_API_KEY}"\` and the user expected the key
297
+ to just work, propose the fix: edit config.json directly
298
+ (use the \`config_write\` tool) with the actual key. Only
299
+ fall back to \`read_env_file\` if the user explicitly
300
+ chose --use-env mode (apiKey is a placeholder by design)
301
+ or the config shows a literal key but doctor still says
302
+ it's empty (config.json malformed).
303
+ Don't ask the user to grep their own files.
304
+ * Empty logs but lastExitStatus \!= 0 → the process was
305
+ killed pre-stdio (signal). The hint field in
306
+ read_service_logs's result will spell this out.
307
+ Then propose the *specific* fix to the user before mutating
308
+ anything.
309
+
310
+ When the user says they're done / satisfied / wants to exit, run
311
+ run_doctor one last time, summarise, then end with:
312
+ "All set. Run 'tianshu dev' (or 'npm run dev' in a checkout)
313
+ to start the server."`;
314
+ /**
315
+ * The user's identity for HTTP calls. The server-side dev
316
+ * resolver chain accepts a `tianshu_identity=<tenant>/<user>`
317
+ * cookie, so we forge one matching whatever tenant the agent is
318
+ * targeting in each call. We always go in as the tenant's `dev`
319
+ * user (the bootstrap user) since the wizard hasn't created
320
+ * anyone else yet.
321
+ */
322
+ function identityCookie(tenantId) {
323
+ return `tianshu_identity=${encodeURIComponent(`${tenantId}/dev`)}`;
324
+ }
325
+ /**
326
+ * Make an HTTP request against the running server, returning the
327
+ * parsed JSON body or throwing an Error with the response text.
328
+ * Used by the HTTP-backed tools when the wizard has spun up a
329
+ * server already.
330
+ */
331
+ async function serverFetch(serverUrl, method, pathSegment, tenantId, body, timeoutMs = 30_000) {
332
+ const ac = new AbortController();
333
+ const timer = setTimeout(() => ac.abort(), timeoutMs);
334
+ try {
335
+ const res = await fetch(`${serverUrl}${pathSegment}`, {
336
+ method,
337
+ headers: {
338
+ "content-type": "application/json",
339
+ cookie: identityCookie(tenantId),
340
+ },
341
+ body: body !== undefined ? JSON.stringify(body) : undefined,
342
+ signal: ac.signal,
343
+ });
344
+ const text = await res.text();
345
+ let parsed;
346
+ try {
347
+ parsed = text ? JSON.parse(text) : {};
348
+ }
349
+ catch {
350
+ parsed = { raw: text };
351
+ }
352
+ if (!res.ok) {
353
+ throw new Error(`${method} ${pathSegment} → HTTP ${res.status}: ${text.slice(0, 400)}`);
354
+ }
355
+ return parsed;
356
+ }
357
+ finally {
358
+ clearTimeout(timer);
359
+ }
360
+ }
361
+ /**
362
+ * Exported for tests only — production callers go through
363
+ * runSetupAgent, which constructs tools and the system prompt
364
+ * together. Tests can grab a single tool's `execute` to verify
365
+ * its behaviour in isolation.
366
+ */
367
+ export function buildTools(home, serverUrl) {
368
+ const ops = new GlobalOps({ home });
369
+ return {
370
+ tenant_list: {
371
+ schema: {
372
+ name: "tenant_list",
373
+ description: "List all tenants on disk under ~/.tianshu/tenants/. Returns an array of tenant ids.",
374
+ parameters: {
375
+ type: "object",
376
+ properties: {},
377
+ required: [],
378
+ },
379
+ },
380
+ execute: async () => {
381
+ const ids = ops.list();
382
+ return JSON.stringify({ tenants: ids });
383
+ },
384
+ },
385
+ tenant_create: {
386
+ mutating: true,
387
+ describe: (args) => `Create new tenant '${String(args.id ?? "?")}'`,
388
+ schema: {
389
+ name: "tenant_create",
390
+ description: "Create a new tenant with the given id. Tenant ids must be a-z, 0-9, hyphen. Idempotent: returns the tenant whether or not it pre-existed.",
391
+ parameters: {
392
+ type: "object",
393
+ properties: {
394
+ id: {
395
+ type: "string",
396
+ description: "Tenant id (a-z 0-9 hyphen). Examples: 'work', 'sandbox', 'team-foo'.",
397
+ },
398
+ },
399
+ required: ["id"],
400
+ },
401
+ },
402
+ execute: async (args) => {
403
+ const id = String(args.id ?? "");
404
+ const ctx = ops.exists(id) ? ops.open(id) : ops.create(id);
405
+ return JSON.stringify({
406
+ tenantId: ctx.tenantId,
407
+ root: ctx.root,
408
+ alreadyExisted: ops.exists(id),
409
+ });
410
+ },
411
+ },
412
+ user_create: {
413
+ mutating: true,
414
+ describe: (args) => `Create user '${String(args.userId ?? "?")}' in tenant '${String(args.tenantId ?? "?")}'`,
415
+ schema: {
416
+ name: "user_create",
417
+ description: "Create a user inside an existing tenant. Idempotent (re-creating a user is a no-op).",
418
+ parameters: {
419
+ type: "object",
420
+ properties: {
421
+ tenantId: { type: "string", description: "Tenant id." },
422
+ userId: {
423
+ type: "string",
424
+ description: "User id (a-z 0-9 hyphen).",
425
+ },
426
+ displayName: {
427
+ type: "string",
428
+ description: "Optional display name.",
429
+ },
430
+ },
431
+ required: ["tenantId", "userId"],
432
+ },
433
+ },
434
+ execute: async (args) => {
435
+ const tenantId = String(args.tenantId);
436
+ const userId = String(args.userId);
437
+ const ctx = ops.open(tenantId);
438
+ ops.ensureUser(ctx, {
439
+ userId,
440
+ provider: "dev",
441
+ externalId: `${userId}@local`,
442
+ displayName: args.displayName ? String(args.displayName) : undefined,
443
+ });
444
+ return JSON.stringify({ tenantId, userId });
445
+ },
446
+ },
447
+ plugin_enable: {
448
+ mutating: true,
449
+ describe: (args) => `Enable plugin '${String(args.pluginId ?? "?")}' in tenant '${String(args.tenantId ?? "?")}'`,
450
+ schema: {
451
+ name: "plugin_enable",
452
+ description: "Enable a built-in plugin (files | workboard | microsandbox | web-search) inside a tenant. When the wizard has a running server, this routes through PATCH /api/plugins/:id so plugin lifecycle hooks fire (activation, registry refresh, plugins_changed broadcast) — the same path the admin UI uses. Without a server we fall back to editing the config.json directly; the plugin will activate next time the server boots.",
453
+ parameters: {
454
+ type: "object",
455
+ properties: {
456
+ tenantId: { type: "string" },
457
+ pluginId: {
458
+ type: "string",
459
+ enum: ["files", "workboard", "microsandbox", "web-search"],
460
+ },
461
+ },
462
+ required: ["tenantId", "pluginId"],
463
+ },
464
+ },
465
+ execute: async (args) => {
466
+ const tenantId = String(args.tenantId);
467
+ const pluginId = String(args.pluginId);
468
+ if (serverUrl) {
469
+ const r = await serverFetch(serverUrl, "PATCH", `/api/plugins/${encodeURIComponent(pluginId)}`, tenantId, { enabled: true });
470
+ return JSON.stringify({
471
+ tenantId,
472
+ pluginId,
473
+ enabled: true,
474
+ via: "http",
475
+ response: r,
476
+ });
477
+ }
478
+ const cfgPath = path.join(getTenantsRoot(home), tenantId, "config.json");
479
+ const cfg = readJsonOrEmpty(cfgPath);
480
+ cfg.plugins = cfg.plugins ?? {};
481
+ const existing = cfg.plugins[pluginId] ?? {};
482
+ cfg.plugins[pluginId] = {
483
+ ...existing,
484
+ enabled: true,
485
+ };
486
+ writeJsonAtomic(cfgPath, cfg);
487
+ return JSON.stringify({
488
+ tenantId,
489
+ pluginId,
490
+ enabled: true,
491
+ via: "file",
492
+ });
493
+ },
494
+ },
495
+ plugin_disable: {
496
+ mutating: true,
497
+ describe: (args) => `Disable plugin '${String(args.pluginId ?? "?")}' in tenant '${String(args.tenantId ?? "?")}'`,
498
+ schema: {
499
+ name: "plugin_disable",
500
+ description: "Disable a plugin in the given tenant. Routes through PATCH /api/plugins/:id when a server is running so the plugin's deactivate hook fires; otherwise edits config.json directly.",
501
+ parameters: {
502
+ type: "object",
503
+ properties: {
504
+ tenantId: { type: "string" },
505
+ pluginId: { type: "string" },
506
+ },
507
+ required: ["tenantId", "pluginId"],
508
+ },
509
+ },
510
+ execute: async (args) => {
511
+ const tenantId = String(args.tenantId);
512
+ const pluginId = String(args.pluginId);
513
+ if (serverUrl) {
514
+ const r = await serverFetch(serverUrl, "PATCH", `/api/plugins/${encodeURIComponent(pluginId)}`, tenantId, { enabled: false });
515
+ return JSON.stringify({
516
+ tenantId,
517
+ pluginId,
518
+ enabled: false,
519
+ via: "http",
520
+ response: r,
521
+ });
522
+ }
523
+ const cfgPath = path.join(getTenantsRoot(home), tenantId, "config.json");
524
+ const cfg = readJsonOrEmpty(cfgPath);
525
+ cfg.plugins = cfg.plugins ?? {};
526
+ const existing = cfg.plugins[pluginId] ?? {};
527
+ cfg.plugins[pluginId] = {
528
+ ...existing,
529
+ enabled: false,
530
+ };
531
+ writeJsonAtomic(cfgPath, cfg);
532
+ return JSON.stringify({
533
+ tenantId,
534
+ pluginId,
535
+ enabled: false,
536
+ via: "file",
537
+ });
538
+ },
539
+ },
540
+ config_read: {
541
+ schema: {
542
+ name: "config_read",
543
+ description: "Read a config file. `which='global'` for ~/.tianshu/config.json; `which='tenant'` requires `tenantId` and reads ~/.tianshu/tenants/<id>/config.json.",
544
+ parameters: {
545
+ type: "object",
546
+ properties: {
547
+ which: { type: "string", enum: ["global", "tenant"] },
548
+ tenantId: { type: "string" },
549
+ },
550
+ required: ["which"],
551
+ },
552
+ },
553
+ execute: async (args) => {
554
+ const which = String(args.which);
555
+ if (which === "global") {
556
+ const cfg = readJsonOrEmpty(getGlobalConfigPath(home));
557
+ return JSON.stringify(cfg);
558
+ }
559
+ const tenantId = String(args.tenantId ?? "");
560
+ if (!tenantId)
561
+ return JSON.stringify({ error: "tenantId required" });
562
+ const cfg = readJsonOrEmpty(path.join(getTenantsRoot(home), tenantId, "config.json"));
563
+ return JSON.stringify(cfg);
564
+ },
565
+ },
566
+ config_write: {
567
+ mutating: true,
568
+ describe: (args) => {
569
+ const which = String(args.which ?? "tenant");
570
+ const patch = args.patch ?? {};
571
+ const keys = Object.keys(patch).join(", ") || "(empty patch)";
572
+ if (which === "global") {
573
+ return `Patch ~/.tianshu/config.json (keys: ${keys})`;
574
+ }
575
+ return `Patch tenant '${String(args.tenantId ?? "?")}' config (keys: ${keys})`;
576
+ },
577
+ schema: {
578
+ name: "config_write",
579
+ description: "Write a config file by merging the supplied object into the existing file. Top-level keys in the patch overwrite existing values; non-mentioned keys are preserved (shallow merge).\n\n which='global' → ~/.tianshu/config.json. Use this for cross-tenant settings: the server-wide provider catalog (models.providers), the default model, server-only fields (server.port, logging.level, autoCreateDefault), or to fix a bad `api` value doctor flagged on the global pass.\n which='tenant' → ~/.tianshu/tenants/<id>/config.json. Use for per-tenant overrides: enabling/disabling plugins for one tenant, giving one tenant a different defaultModel, swapping in a tenant-specific provider catalog. Requires `tenantId`.\n\nGoes through the same write path the server uses (writeGlobalConfig / writeTenantConfig), so the tenant write enforces the OverridableConfig whitelist: trying to set server.port / logging on a tenant returns a TenantConfigForbiddenFieldError and the patch is rejected.",
580
+ parameters: {
581
+ type: "object",
582
+ properties: {
583
+ which: {
584
+ type: "string",
585
+ enum: ["global", "tenant"],
586
+ description: "'global' = ~/.tianshu/config.json (system-wide). 'tenant' = ~/.tianshu/tenants/<id>/config.json (per-tenant). Defaults to 'tenant' for backward compatibility, but be explicit — the agent's earlier behaviour silently assumed tenant which was wrong when the user wanted a global change.",
587
+ },
588
+ tenantId: {
589
+ type: "string",
590
+ description: "Required when which='tenant'.",
591
+ },
592
+ patch: {
593
+ type: "object",
594
+ description: "Object to merge into the existing config (top-level shallow merge).",
595
+ },
596
+ },
597
+ required: ["patch"],
598
+ },
599
+ },
600
+ execute: async (args) => {
601
+ const which = String(args.which ?? "tenant");
602
+ const patch = args.patch ?? {};
603
+ if (which === "global") {
604
+ // Read-merge-write so partial patches don't drop
605
+ // existing keys (preserves the documented shallow-
606
+ // merge semantics).
607
+ const cfg = readJsonOrEmpty(getGlobalConfigPath(home));
608
+ const merged = { ...cfg, ...patch };
609
+ writeGlobalConfig(merged, home);
610
+ return JSON.stringify({
611
+ which: "global",
612
+ path: getGlobalConfigPath(home),
613
+ patched: Object.keys(patch),
614
+ });
615
+ }
616
+ // tenant
617
+ const tenantId = String(args.tenantId ?? "");
618
+ if (!tenantId) {
619
+ return JSON.stringify({
620
+ error: "missing_tenant_id",
621
+ message: "which='tenant' requires tenantId. Pass which='global' if you meant the global config.",
622
+ });
623
+ }
624
+ const cfgPath = path.join(getTenantsRoot(home), tenantId, "config.json");
625
+ const cfg = readJsonOrEmpty(cfgPath);
626
+ const merged = { ...cfg, ...patch };
627
+ try {
628
+ writeTenantConfig(tenantId, merged, home);
629
+ }
630
+ catch (err) {
631
+ if (err instanceof TenantConfigForbiddenFieldError) {
632
+ return JSON.stringify({
633
+ error: "tenant_forbidden_field",
634
+ message: err.message,
635
+ hint: "That field can only be set on the global config (which='global'). Tenants override the catalog of models / plugins / branding only.",
636
+ });
637
+ }
638
+ throw err;
639
+ }
640
+ return JSON.stringify({
641
+ which: "tenant",
642
+ tenantId,
643
+ patched: Object.keys(patch),
644
+ });
645
+ },
646
+ },
647
+ secret_list: {
648
+ schema: {
649
+ name: "secret_list",
650
+ description: "List secret keys configured for a plugin in a tenant. Returns key names only — NEVER values. Reads via the same plugin-secrets module the plugin runtime uses at activation time, so what you see matches what the plugin will see.",
651
+ parameters: {
652
+ type: "object",
653
+ properties: {
654
+ tenantId: { type: "string" },
655
+ pluginId: { type: "string" },
656
+ },
657
+ required: ["tenantId", "pluginId"],
658
+ },
659
+ },
660
+ execute: async (args) => {
661
+ const tenantId = String(args.tenantId);
662
+ const pluginId = String(args.pluginId);
663
+ if (!ops.exists(tenantId)) {
664
+ return JSON.stringify({
665
+ tenantId,
666
+ pluginId,
667
+ keys: [],
668
+ error: `tenant ${tenantId} does not exist`,
669
+ });
670
+ }
671
+ const ctx = ops.open(tenantId);
672
+ const secrets = loadPluginSecrets(ctx.secretsDir, pluginId);
673
+ return JSON.stringify({
674
+ tenantId,
675
+ pluginId,
676
+ keys: Object.keys(secrets),
677
+ });
678
+ },
679
+ },
680
+ secret_write: {
681
+ mutating: true,
682
+ describe: (args) => `Set secret '${String(args.key ?? "?")}' for plugin '${String(args.pluginId ?? "?")}' in tenant '${String(args.tenantId ?? "?")}'`,
683
+ schema: {
684
+ name: "secret_write",
685
+ description: "Set a plugin secret (API key, token) for a tenant. Goes through the same applyPluginSecretPatch the PATCH /api/plugins/:id route uses, so the file format, mode 0600, and atomic write semantics all match what the plugin runtime expects. Do NOT use config_write for API keys.\n\nWeb-search keys go here:\n pluginId='web-search', key='tavilyApiKey' or 'braveApiKey'.\n\nNew secrets merge with existing ones; other keys for the same plugin are preserved.",
686
+ parameters: {
687
+ type: "object",
688
+ properties: {
689
+ tenantId: { type: "string" },
690
+ pluginId: { type: "string" },
691
+ key: {
692
+ type: "string",
693
+ description: "Dotted secret name. For web-search use 'tavilyApiKey' or 'braveApiKey'.",
694
+ },
695
+ value: { type: "string" },
696
+ },
697
+ required: ["tenantId", "pluginId", "key", "value"],
698
+ },
699
+ },
700
+ execute: async (args) => {
701
+ const tenantId = String(args.tenantId);
702
+ const pluginId = String(args.pluginId);
703
+ const key = String(args.key);
704
+ const value = String(args.value);
705
+ if (serverUrl) {
706
+ // PATCH /api/plugins/:id with { config: { <key>: <value> } }.
707
+ // The route checks the plugin's manifest configSchema and
708
+ // routes secret-typed fields to <tenant>/secrets/...
709
+ // automatically. We send a patch with just our key; other
710
+ // existing secrets / cleartext config are preserved.
711
+ const r = await serverFetch(serverUrl, "PATCH", `/api/plugins/${encodeURIComponent(pluginId)}`, tenantId, { config: { [key]: value } });
712
+ return JSON.stringify({
713
+ tenantId,
714
+ pluginId,
715
+ key,
716
+ via: "http",
717
+ response: r,
718
+ });
719
+ }
720
+ const ctx = ops.exists(tenantId)
721
+ ? ops.open(tenantId)
722
+ : ops.create(tenantId);
723
+ const result = applyPluginSecretPatch(ctx.secretsDir, pluginId, {
724
+ [key]: value,
725
+ });
726
+ return JSON.stringify({
727
+ tenantId,
728
+ pluginId,
729
+ keysAfter: Object.keys(result.secrets),
730
+ changed: result.changed,
731
+ via: "file",
732
+ });
733
+ },
734
+ },
735
+ run_doctor: {
736
+ schema: {
737
+ name: "run_doctor",
738
+ description: "Run `tianshu doctor` and return the structured report. Use this to check setup state before suggesting next steps.",
739
+ parameters: {
740
+ type: "object",
741
+ properties: {},
742
+ required: [],
743
+ },
744
+ },
745
+ execute: async () => {
746
+ const r = await collectDoctorReport({});
747
+ return JSON.stringify({
748
+ ok: r.blocker === 0,
749
+ tally: { ok: r.ok, warning: r.warning, blocker: r.blocker },
750
+ groups: r.groups.map((g) => ({
751
+ title: g.title,
752
+ lines: g.lines.map((l) => ({
753
+ severity: l.severity,
754
+ text: l.text,
755
+ detail: l.detail,
756
+ })),
757
+ })),
758
+ });
759
+ },
760
+ },
761
+ read_service_logs: {
762
+ schema: {
763
+ name: "read_service_logs",
764
+ description: "Read the launchd-managed dev server's stdout/stderr logs. " +
765
+ "Use this when the wizard installed a launchd agent but the server " +
766
+ "didn't pass the health check, or when `run_doctor` reports the " +
767
+ "server isn't responding. Returns the most recent log lines along " +
768
+ "with the agent's installed/loaded/pid status so you can correlate. " +
769
+ "This is your *primary diagnostic tool* for boot failures — call it " +
770
+ "before guessing what went wrong.",
771
+ parameters: {
772
+ type: "object",
773
+ properties: {
774
+ lines: {
775
+ type: "number",
776
+ description: "How many trailing lines to return per stream. Default 80. Bump to 200+ if you don't see the error in 80.",
777
+ },
778
+ stream: {
779
+ type: "string",
780
+ enum: ["err", "out", "both"],
781
+ description: "Which stream(s) to read. Boot errors usually land in 'err' first; 'out' carries normal startup messages. Default 'both'.",
782
+ },
783
+ },
784
+ required: [],
785
+ },
786
+ },
787
+ execute: async (args) => {
788
+ const repoRoot = findRepoRoot();
789
+ const label = launchd.resolveLabel(repoRoot);
790
+ const status = launchd.readStatus(label);
791
+ const { out, err } = launchd.logPathsFor(label);
792
+ const linesArg = Number(args.lines);
793
+ const lines = Number.isFinite(linesArg) && linesArg > 0 ? Math.min(linesArg, 1000) : 80;
794
+ const streamArg = String(args.stream ?? "both");
795
+ const stream = streamArg === "out" || streamArg === "err" || streamArg === "both"
796
+ ? streamArg
797
+ : "both";
798
+ const result = {
799
+ label,
800
+ installed: status.installed,
801
+ loaded: status.loaded,
802
+ pid: status.pid,
803
+ lastExitStatus: status.lastExitStatus,
804
+ };
805
+ const tail = (file) => {
806
+ if (!fs.existsSync(file))
807
+ return [];
808
+ try {
809
+ const body = fs.readFileSync(file, "utf8");
810
+ return body.split(/\r?\n/).slice(-lines).filter((l) => l.length > 0);
811
+ }
812
+ catch {
813
+ return [];
814
+ }
815
+ };
816
+ if (stream === "err" || stream === "both") {
817
+ result.stderr = { path: err, lines: tail(err) };
818
+ }
819
+ if (stream === "out" || stream === "both") {
820
+ result.stdout = { path: out, lines: tail(out) };
821
+ }
822
+ // If both streams are empty, give the agent an explicit
823
+ // hint about what that means — saves it from guessing.
824
+ const stdoutEmpty = !result.stdout || result.stdout.lines.length === 0;
825
+ const stderrEmpty = !result.stderr || result.stderr.lines.length === 0;
826
+ if (stdoutEmpty && stderrEmpty) {
827
+ if (!status.installed) {
828
+ result.hint =
829
+ "Service isn't installed (no plist on disk). Tell the user to run `tianshu setup --wizard` and walk them through it.";
830
+ }
831
+ else if (!status.loaded) {
832
+ result.hint =
833
+ "Plist exists but launchd hasn't loaded it. Run `tianshu start` (or have the user run it). If start fails, the launchctl error is itself the diagnostic.";
834
+ }
835
+ else if (status.pid !== null) {
836
+ result.hint =
837
+ "Service is running (loaded + pid present) but logs are empty. Most likely the service just started and hasn't flushed yet — wait 10s and call read_service_logs again. If logs stay empty for a minute, the process may be wedged on something pre-stdio (e.g. waiting for stdin).";
838
+ }
839
+ else {
840
+ result.hint =
841
+ "Service is loaded but no pid — it crashed and launchd is between restarts (ThrottleInterval=30s). Wait, then read again, and look for the actual exit reason in lastExitStatus.";
842
+ }
843
+ }
844
+ else if (stderrEmpty &&
845
+ status.loaded &&
846
+ status.pid === null &&
847
+ status.lastExitStatus !== null &&
848
+ status.lastExitStatus !== 0) {
849
+ result.hint = `Service exited (lastExitStatus=${status.lastExitStatus}) and stderr is empty. Look in stdout for the last messages before the exit; if those don't explain it, the process may have been killed by a signal (e.g. OOM → 137; SIGTERM → 143) rather than crashing with output.`;
850
+ }
851
+ return JSON.stringify(result);
852
+ },
853
+ },
854
+ read_env_file: {
855
+ schema: {
856
+ name: "read_env_file",
857
+ description: "List the keys (and value lengths, NOT values) in the .env file the dev server actually loads. Use this when run_doctor or read_service_logs reports a missing env var (e.g. 'ANTHROPIC_API_KEY references env var but it's empty') — you can see directly whether the key is present, whether the user accidentally put it in `~/.env` instead of the repo's `.env`, and whether the value is suspiciously short (<8 chars) or empty.\n\nReturns ONLY key names + length + a 4-char prefix for sanity, NEVER the full value, so it's safe to print to the user. The file path returned is the canonical path the server reads from (resolved by the same logic loadEnv() uses, so what you see matches what the running server sees).",
858
+ parameters: {
859
+ type: "object",
860
+ properties: {
861
+ keyFilter: {
862
+ type: "string",
863
+ description: "Optional substring — only return keys containing this string (case-insensitive). Example: 'API_KEY' to filter to provider keys.",
864
+ },
865
+ },
866
+ required: [],
867
+ },
868
+ },
869
+ execute: async (args) => {
870
+ const repoRoot = findRepoRoot();
871
+ const envPath = path.join(repoRoot, ".env");
872
+ const homeEnvPath = path.join(os.homedir(), ".env");
873
+ const filter = args.keyFilter
874
+ ? String(args.keyFilter).toLowerCase()
875
+ : null;
876
+ const summarize = (filepath) => {
877
+ if (!fs.existsSync(filepath)) {
878
+ return { path: filepath, exists: false, keys: [] };
879
+ }
880
+ let body;
881
+ try {
882
+ body = fs.readFileSync(filepath, "utf8");
883
+ }
884
+ catch (e) {
885
+ return {
886
+ path: filepath,
887
+ exists: true,
888
+ error: e.message,
889
+ keys: [],
890
+ };
891
+ }
892
+ const keys = [];
893
+ for (const rawLine of body.split(/\r?\n/)) {
894
+ const line = rawLine.trim();
895
+ if (!line || line.startsWith("#"))
896
+ continue;
897
+ const eq = line.indexOf("=");
898
+ if (eq < 1)
899
+ continue;
900
+ const key = line.slice(0, eq).trim();
901
+ // Strip surrounding quotes (single, double) so length
902
+ // reflects what dotenv actually parses.
903
+ let raw = line.slice(eq + 1).trim();
904
+ if ((raw.startsWith('"') && raw.endsWith('"')) ||
905
+ (raw.startsWith("'") && raw.endsWith("'"))) {
906
+ raw = raw.slice(1, -1);
907
+ }
908
+ if (filter && !key.toLowerCase().includes(filter))
909
+ continue;
910
+ keys.push({
911
+ key,
912
+ length: raw.length,
913
+ prefix: raw.slice(0, 4),
914
+ empty: raw.length === 0,
915
+ suspicious: raw.length > 0 && raw.length < 8,
916
+ });
917
+ }
918
+ return { path: filepath, exists: true, keys };
919
+ };
920
+ const result = {
921
+ // The canonical path the server *should* be reading.
922
+ // This matches the wizard's writePath, which matches
923
+ // load-env.ts's repo-root walk.
924
+ serverEnv: summarize(envPath),
925
+ // Common user mistake: put keys in ~/.env. We surface
926
+ // it so the agent can spot it and tell the user to
927
+ // move/copy the line.
928
+ homeEnv: envPath === homeEnvPath ? null : summarize(homeEnvPath),
929
+ note: "Values are NEVER returned. `length` and `prefix` are for diagnostic sanity only. If `serverEnv.keys` doesn't include the key the user expects but `homeEnv.keys` does, the user put it in the wrong file — tell them to move/copy the line into serverEnv.path.",
930
+ };
931
+ return JSON.stringify(result);
932
+ },
933
+ },
934
+ build_sandbox: {
935
+ mutating: true,
936
+ describe: (args) => {
937
+ const tpl = String(args.template ?? "task-runner-with-browser");
938
+ const tenantId = String(args.tenantId ?? "default");
939
+ return `Build a microsandbox snapshot from the '${tpl}' template (tenant '${tenantId}'). This downloads the base image, installs Chromium / LibreOffice / Node / Python inside the VM, and saves a snapshot. Cold builds take 5-10 min, cache hits 3-5 min. The wizard will block on this call until done.`;
940
+ },
941
+ schema: {
942
+ name: "build_sandbox",
943
+ description: "Build a microsandbox snapshot from a packaged template ('browser' or 'task-runner') and return its build id. This is the one-shot equivalent of the chat-shell `build_sandbox` tool: it (1) writes the chosen template into the user's Sandboxfile via PUT /api/p/microsandbox/sandboxfile, then (2) calls POST /api/p/microsandbox/builds to actually build the snapshot.\n\nUse this when the user asks to set up sandboxes during initial install. Cold build = 5-10 min (apt + Chromium + Playwright + LibreOffice tarball pulls); the wizard's whole UI will hang on the spinner. Tell the user that up front.\n\nAfter build, call use_sandbox_build with the returned buildId to publish the snapshot to a role pointer (browser / task / both).",
944
+ parameters: {
945
+ type: "object",
946
+ properties: {
947
+ tenantId: {
948
+ type: "string",
949
+ description: "Tenant whose Sandboxfile to write. Defaults to 'default'. The build runs against this tenant's user-home Sandboxfile.",
950
+ },
951
+ template: {
952
+ type: "string",
953
+ enum: ["task-runner", "browser", "task-runner-with-browser"],
954
+ description: "Which packaged template to write into the Sandboxfile before building.\n\n* 'task-runner' — Node + Python + LibreOffice + office libs, no browser. ~700 MB. Foundation for the layered approach below; also the right choice for users who explicitly don't need a browser.\n* 'task-runner-with-browser' — *layered* template that adds Chromium + Playwright MCP + noVNC on top of an existing task-runner snapshot. MUST be built with `fromSnapshot` set to the snapshotName of a previously-built 'task-runner' (otherwise the build fails at the first apt step). This is the recommended browser-role snapshot for the standard two-step setup flow.\n* 'browser' — monolithic full-stack template (task-runner contents + browser stack from scratch). ~3.2 GB. Builds standalone with no fromSnapshot, but you pay the apt + LibreOffice install twice across builds. Generally avoid in setup; prefer the layered task-runner → task-runner-with-browser sequence.",
955
+ },
956
+ fromSnapshot: {
957
+ type: "string",
958
+ description: "Snapshot name (NOT buildId) to layer this build on top of. Required for template='task-runner-with-browser'; ignored otherwise. Get this from the `snapshotName` field of a previous build_sandbox(template='task-runner') response.",
959
+ },
960
+ },
961
+ required: ["template"],
962
+ },
963
+ },
964
+ execute: async (args) => {
965
+ if (!serverUrl) {
966
+ return JSON.stringify({
967
+ error: "server_not_running",
968
+ message: "build_sandbox needs a running server (the wizard's HTTP plugin API). The wizard normally starts the server before running the agent; if you got here without a server, run `tianshu start` first.",
969
+ });
970
+ }
971
+ const tenantId = String(args.tenantId ?? "default");
972
+ const template = String(args.template);
973
+ const fromSnapshot = typeof args.fromSnapshot === "string" && args.fromSnapshot.length > 0
974
+ ? args.fromSnapshot
975
+ : undefined;
976
+ // Guardrail: task-runner-with-browser is layered. Without
977
+ // fromSnapshot it will fail at the first apt step. Catch
978
+ // that here so the agent gets an actionable error instead
979
+ // of a generic BuildFailedError after 30 seconds of pulling.
980
+ if (template === "task-runner-with-browser" && !fromSnapshot) {
981
+ return JSON.stringify({
982
+ error: "missing_from_snapshot",
983
+ message: "template 'task-runner-with-browser' is layered — it must be built on top of an existing task-runner snapshot. First call build_sandbox(template='task-runner'), then call build_sandbox(template='task-runner-with-browser', fromSnapshot=<snapshotName from step 1>).",
984
+ });
985
+ }
986
+ // Step 1: read the requested template body, write it into
987
+ // the tenant's Sandboxfile. The plugin's PUT /sandboxfile
988
+ // accepts the raw text and validates it. We resolve the
989
+ // template path relative to the plugin's installed
990
+ // location, which the server has already loaded.
991
+ const templateBody = await fetchSandboxfileTemplate(serverUrl, tenantId, template);
992
+ if (typeof templateBody !== "string") {
993
+ return JSON.stringify({
994
+ error: "template_not_found",
995
+ template,
996
+ available: templateBody,
997
+ });
998
+ }
999
+ await serverFetch(serverUrl, "PUT", "/api/p/microsandbox/sandboxfile", tenantId, { content: templateBody });
1000
+ // Step 2: kick the build. We DON'T use the streaming
1001
+ // (?stream=1) endpoint here — the agent runs in a CLI
1002
+ // wizard and reading NDJSON line-by-line through fetch
1003
+ // doesn't buy anything; we just wait for the final
1004
+ // {type:"done"} or HTTP 500. Timeout is 20 min, well
1005
+ // above the worst observed cold build.
1006
+ const buildResp = await serverFetch(serverUrl, "POST", "/api/p/microsandbox/builds", tenantId, fromSnapshot ? { from_snapshot: fromSnapshot } : {}, 20 * 60_000);
1007
+ // Non-streaming response shape: { build: { buildId, snapshotName, ... } }
1008
+ // (or { error, message } on failure, which serverFetch turns into a thrown Error)
1009
+ const build = buildResp?.build;
1010
+ if (!build || !build.buildId) {
1011
+ return JSON.stringify({
1012
+ error: "build_response_unexpected",
1013
+ response: buildResp,
1014
+ });
1015
+ }
1016
+ // Suggest the right next step based on which template
1017
+ // we just built. The standard layered flow is:
1018
+ // task-runner → publish to role='task', then build
1019
+ // task-runner-with-browser fromSnapshot=<task snapshot>
1020
+ // → publish to role='browser'.
1021
+ let nextStep;
1022
+ if (template === "task-runner") {
1023
+ nextStep = `Call use_sandbox_build with buildId='${build.buildId}' and role='task' to publish this as the task-pool snapshot. Then call build_sandbox again with template='task-runner-with-browser' and fromSnapshot='${build.snapshotName}' to layer the browser stack on top.`;
1024
+ }
1025
+ else if (template === "task-runner-with-browser") {
1026
+ nextStep = `Call use_sandbox_build with buildId='${build.buildId}' and role='browser' to publish this as the long-lived browser sandbox snapshot. The task pointer should already be set from the task-runner step.`;
1027
+ }
1028
+ else {
1029
+ // monolithic 'browser'
1030
+ nextStep = `Call use_sandbox_build with buildId='${build.buildId}' and role='both' to publish this snapshot to both pointers.`;
1031
+ }
1032
+ return JSON.stringify({
1033
+ ok: true,
1034
+ buildId: build.buildId,
1035
+ snapshotName: build.snapshotName,
1036
+ baseImage: build.baseImage,
1037
+ durationMs: build.durationMs,
1038
+ template,
1039
+ fromSnapshot: fromSnapshot ?? null,
1040
+ tenantId,
1041
+ nextStep,
1042
+ });
1043
+ },
1044
+ },
1045
+ use_sandbox_build: {
1046
+ mutating: true,
1047
+ describe: (args) => `Publish snapshot from build '${String(args.buildId ?? "?")}' to role '${String(args.role ?? "both")}' (tenant '${String(args.tenantId ?? "default")}')`,
1048
+ schema: {
1049
+ name: "use_sandbox_build",
1050
+ description: "Publish a built snapshot to a sandbox role pointer. Roles: 'browser' (long-lived chat sandbox with the Chromium sidecar), 'task' (per-task workboard runner pool), or 'both' (recommended when the user just wants everything to work).\n\nUnder the hood: POST /api/p/microsandbox/builds/use?build_id=...&role=...&reset=1. The reset flag bounces the live VM so it boots from the new snapshot — without it the pointer is durable but the running browser sandbox stays on the old snapshot until the next manual restart.\n\nCall this *after* build_sandbox returns a buildId. If the user asked you to 'set up sandboxes' or similar, the natural sequence is build_sandbox → use_sandbox_build with role='both'.",
1051
+ parameters: {
1052
+ type: "object",
1053
+ properties: {
1054
+ tenantId: {
1055
+ type: "string",
1056
+ description: "Tenant whose pointers to update. Defaults to 'default'.",
1057
+ },
1058
+ buildId: {
1059
+ type: "string",
1060
+ description: "Build id returned by build_sandbox. Looks like 'build-20260620-abc123'.",
1061
+ },
1062
+ role: {
1063
+ type: "string",
1064
+ enum: ["browser", "task", "both"],
1065
+ description: "Which role pointer(s) to update. 'browser' = the long-lived browser sandbox. 'task' = the per-task runner pool. 'both' = both, recommended unless the user is doing something specific.",
1066
+ },
1067
+ reset: {
1068
+ type: "boolean",
1069
+ description: "If true (default), bounce the live VM so it boots from the new snapshot immediately. Set false only if you want the pointer change without disrupting an in-flight session.",
1070
+ },
1071
+ },
1072
+ required: ["buildId", "role"],
1073
+ },
1074
+ },
1075
+ execute: async (args) => {
1076
+ if (!serverUrl) {
1077
+ return JSON.stringify({
1078
+ error: "server_not_running",
1079
+ message: "use_sandbox_build needs a running server.",
1080
+ });
1081
+ }
1082
+ const tenantId = String(args.tenantId ?? "default");
1083
+ const buildId = String(args.buildId);
1084
+ const role = String(args.role);
1085
+ const reset = args.reset !== false; // default true
1086
+ if (!buildId) {
1087
+ return JSON.stringify({
1088
+ error: "missing_build_id",
1089
+ message: "buildId is required.",
1090
+ });
1091
+ }
1092
+ const qs = new URLSearchParams({
1093
+ build_id: buildId,
1094
+ role,
1095
+ ...(reset ? { reset: "1" } : {}),
1096
+ });
1097
+ const resp = await serverFetch(serverUrl, "POST", `/api/p/microsandbox/builds/use?${qs.toString()}`, tenantId, {},
1098
+ // VM bounce can take 20-40s; give it 90s for safety.
1099
+ 90_000);
1100
+ return JSON.stringify({
1101
+ ok: true,
1102
+ buildId,
1103
+ role,
1104
+ reset,
1105
+ tenantId,
1106
+ response: resp,
1107
+ });
1108
+ },
1109
+ },
1110
+ };
1111
+ }
1112
+ /**
1113
+ * Fetch a packaged Sandboxfile template body from the running
1114
+ * server. The microsandbox plugin exposes this via
1115
+ * GET /sandboxfile/templates, returning a record of
1116
+ * { name → content }. We look up the requested name and return
1117
+ * its content (or, on miss, the list of available names so the
1118
+ * agent can correct itself).
1119
+ */
1120
+ async function fetchSandboxfileTemplate(serverUrl, tenantId, name) {
1121
+ const resp = (await serverFetch(serverUrl, "GET", "/api/p/microsandbox/sandboxfile/templates", tenantId));
1122
+ const list = resp.templates ?? [];
1123
+ const hit = list.find((t) => t.id === name);
1124
+ if (hit)
1125
+ return hit.content;
1126
+ return { available: list.map((t) => t.id) };
1127
+ }
1128
+ function readJsonOrEmpty(filepath) {
1129
+ try {
1130
+ return JSON.parse(fs.readFileSync(filepath, "utf8"));
1131
+ }
1132
+ catch {
1133
+ return {};
1134
+ }
1135
+ }
1136
+ function writeJsonAtomic(filepath, payload) {
1137
+ fs.mkdirSync(path.dirname(filepath), { recursive: true });
1138
+ const tmp = `${filepath}.tmp.${process.pid}`;
1139
+ fs.writeFileSync(tmp, JSON.stringify(payload, null, 2) + "\n");
1140
+ fs.renameSync(tmp, filepath);
1141
+ }
1142
+ /**
1143
+ * Run the post-wizard CLI agent loop. Resolves when the user exits
1144
+ * (Ctrl-C / "done" / "exit" / "bye") or when the configured turn cap
1145
+ * is hit.
1146
+ */
1147
+ export async function runCliAgent(opts = {}) {
1148
+ const home = opts.home ?? getTianshuHome();
1149
+ const maxTurns = opts.maxTurns ?? 25;
1150
+ let config;
1151
+ try {
1152
+ config = loadGlobalConfig(home);
1153
+ }
1154
+ catch {
1155
+ p.log.error("Could not load ~/.tianshu/config.json; finish the wizard first.");
1156
+ return;
1157
+ }
1158
+ const info = getDefaultModel(config);
1159
+ if (!info) {
1160
+ p.log.error("No default model configured; finish the wizard first.");
1161
+ return;
1162
+ }
1163
+ const apiKey = resolveApiKey(info);
1164
+ let model;
1165
+ try {
1166
+ model = buildModel(info);
1167
+ }
1168
+ catch (err) {
1169
+ p.log.error(`buildModel failed: ${err instanceof Error ? err.message : String(err)}`);
1170
+ return;
1171
+ }
1172
+ const tools = buildTools(home, opts.serverUrl);
1173
+ const toolSchemas = Object.values(tools).map((t) => t.schema);
1174
+ const messages = [];
1175
+ p.log.info(`Setup assistant running on ${info.id}. Every state-changing action will ask for your confirmation. Type 'exit' / Ctrl-C any time.`);
1176
+ // Kick the agent off with the diagnose-and-propose workflow
1177
+ // described in the system prompt. Agent runs run_doctor and
1178
+ // proposes next actions; nothing state-changing happens until
1179
+ // the user explicitly confirms each one.
1180
+ messages.push({
1181
+ role: "user",
1182
+ content: [
1183
+ {
1184
+ type: "text",
1185
+ text: "Begin: run run_doctor, then summarise what's working and propose the next setup decisions for me to choose from. Don't run any state-changing tools yet — wait for me to pick.",
1186
+ },
1187
+ ],
1188
+ timestamp: Date.now(),
1189
+ });
1190
+ let turns = 0;
1191
+ while (turns < maxTurns) {
1192
+ turns += 1;
1193
+ let assistant;
1194
+ const ctx = {
1195
+ systemPrompt: SETUP_SYSTEM_PROMPT,
1196
+ messages,
1197
+ tools: toolSchemas,
1198
+ };
1199
+ try {
1200
+ assistant = await complete(model, ctx, { apiKey });
1201
+ }
1202
+ catch (err) {
1203
+ p.log.error(`LLM call failed: ${err instanceof Error ? err.message : String(err)}`);
1204
+ return;
1205
+ }
1206
+ messages.push(assistant);
1207
+ // Print any text the assistant emitted.
1208
+ const textParts = assistant.content.filter((c) => c.type === "text");
1209
+ if (textParts.length > 0) {
1210
+ p.log.message(textParts.map((c) => c.text).join("\n"), {
1211
+ symbol: "🌱",
1212
+ });
1213
+ }
1214
+ else {
1215
+ // Agent returned no text. Either the model short-circuited
1216
+ // the turn or it only emitted tool calls. Surface a
1217
+ // breadcrumb so the operator knows the turn happened.
1218
+ const toolNames = assistant.content
1219
+ .filter((c) => c.type === "toolCall")
1220
+ .map((c) => c.name);
1221
+ if (toolNames.length === 0) {
1222
+ const debug = `stopReason=${assistant.stopReason}` +
1223
+ (assistant.errorMessage ? `, errorMessage=${assistant.errorMessage}` : "") +
1224
+ `, content=${JSON.stringify(assistant.content)}`;
1225
+ p.log.warn(`(model returned an empty turn; ${debug})`);
1226
+ // No useful response. Bail rather than spinning silently.
1227
+ p.outro("The model didn't respond \u2014 it returned an empty message. " +
1228
+ "This usually means the proxy / endpoint stripped the response. " +
1229
+ "Try a different default model, or check the proxy logs.");
1230
+ return;
1231
+ }
1232
+ }
1233
+ // Resolve any tool calls.
1234
+ const toolCalls = assistant.content.filter((c) => c.type === "toolCall");
1235
+ if (toolCalls.length === 0) {
1236
+ // No tool calls → wait for user input.
1237
+ const reply = await p.text({
1238
+ message: "you:",
1239
+ placeholder: "(type your reply, or 'exit' to leave)",
1240
+ });
1241
+ if (p.isCancel(reply) || /^(exit|quit|bye|done)$/i.test(String(reply).trim())) {
1242
+ p.outro("All set. Start the server with `tianshu dev` or `npm run dev`.");
1243
+ return;
1244
+ }
1245
+ messages.push({
1246
+ role: "user",
1247
+ content: [{ type: "text", text: String(reply) }],
1248
+ timestamp: Date.now(),
1249
+ });
1250
+ continue;
1251
+ }
1252
+ // Execute every tool call in order.
1253
+ for (const call of toolCalls) {
1254
+ const handler = tools[call.name];
1255
+ let result;
1256
+ if (!handler) {
1257
+ result = {
1258
+ role: "toolResult",
1259
+ toolCallId: call.id,
1260
+ toolName: call.name,
1261
+ content: [
1262
+ {
1263
+ type: "text",
1264
+ text: `unknown tool: ${call.name}`,
1265
+ },
1266
+ ],
1267
+ isError: true,
1268
+ timestamp: Date.now(),
1269
+ };
1270
+ }
1271
+ else {
1272
+ // For mutating tools, surface the intent and ask the user
1273
+ // for explicit confirmation before running. Read-only
1274
+ // tools (run_doctor, tenant_list, config_read) execute
1275
+ // silently — they don't change state.
1276
+ if (handler.mutating) {
1277
+ const summary = handler.describe
1278
+ ? handler.describe(call.arguments)
1279
+ : `${call.name}(${shortArgs(call.arguments)})`;
1280
+ const ok = await p.confirm({
1281
+ message: `\ud83d\udd11 Agent wants to: ${summary}`,
1282
+ initialValue: true,
1283
+ });
1284
+ if (p.isCancel(ok) || ok === false) {
1285
+ result = {
1286
+ role: "toolResult",
1287
+ toolCallId: call.id,
1288
+ toolName: call.name,
1289
+ content: [
1290
+ {
1291
+ type: "text",
1292
+ text: `User declined this action. Do not retry without asking. Move on or ask the user what to do instead.`,
1293
+ },
1294
+ ],
1295
+ isError: false,
1296
+ timestamp: Date.now(),
1297
+ };
1298
+ p.log.warn(`declined: ${summary}`);
1299
+ messages.push(result);
1300
+ continue;
1301
+ }
1302
+ }
1303
+ try {
1304
+ const out = await handler.execute(call.arguments);
1305
+ result = {
1306
+ role: "toolResult",
1307
+ toolCallId: call.id,
1308
+ toolName: call.name,
1309
+ content: [{ type: "text", text: out }],
1310
+ isError: false,
1311
+ timestamp: Date.now(),
1312
+ };
1313
+ // Surface what the agent did with enough context that
1314
+ // the user can audit it. Read-only tools just show
1315
+ // name + args; mutating tools were already confirmed
1316
+ // above, so we just confirm completion.
1317
+ if (handler.mutating) {
1318
+ const summary = handler.describe
1319
+ ? handler.describe(call.arguments)
1320
+ : `${call.name}(${shortArgs(call.arguments)})`;
1321
+ p.log.success(`done: ${summary}`);
1322
+ }
1323
+ else {
1324
+ p.log.step(`${call.name}(${shortArgs(call.arguments)})`);
1325
+ }
1326
+ }
1327
+ catch (err) {
1328
+ result = {
1329
+ role: "toolResult",
1330
+ toolCallId: call.id,
1331
+ toolName: call.name,
1332
+ content: [
1333
+ {
1334
+ type: "text",
1335
+ text: err instanceof Error ? err.message : String(err),
1336
+ },
1337
+ ],
1338
+ isError: true,
1339
+ timestamp: Date.now(),
1340
+ };
1341
+ p.log.warn(`${call.name} failed: ${err instanceof Error ? err.message : String(err)}`);
1342
+ }
1343
+ }
1344
+ messages.push(result);
1345
+ }
1346
+ }
1347
+ p.log.warn(`Reached ${maxTurns}-turn cap; exiting. You can re-enter with \`tianshu setup --wizard\`.`);
1348
+ }
1349
+ function shortArgs(args) {
1350
+ const s = JSON.stringify(args);
1351
+ return s.length > 80 ? s.slice(0, 77) + "..." : s;
1352
+ }
1353
+ //# sourceMappingURL=cli-agent.js.map