@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,1248 @@
1
+ // WebSocket chat handler — wires together the tenant context, the
2
+ // message store, pi-agent-core's runAgentLoop, and the plugin tool
3
+ // surface.
4
+ //
5
+ // Per-turn flow:
6
+ // 1. user prompt arrives → maybe-compact → persist user message
7
+ // 2. hand the prompt to piRunAgentLoop with the tenant's tools
8
+ // and skills, plus a config that caps assistant turns at
9
+ // MAX_TURNS
10
+ // 3. emit() callback bridges pi events to the WS protocol:
11
+ // text_delta deltas → stream_delta
12
+ // toolcall_start → tool_call (UI shows chips early)
13
+ // message_end (assistant) → persist + message_added
14
+ // message_end (toolResult) → persist + tool_result + message_added
15
+ // agent_end → stream_end
16
+ //
17
+ // MAX_TURNS exists because a model that decides to call its tools
18
+ // in a loop with no productive progress would otherwise burn budget
19
+ // forever. shouldStopAfterTurn enforces it.
20
+ import { AgentHarness, DEFAULT_COMPACTION_SETTINGS, Session as PiSession, estimateContextTokens, shouldCompact, } from "@earendil-works/pi-agent-core";
21
+ import fs from "node:fs";
22
+ import path from "node:path";
23
+ import { buildModel, findModel, getDefaultModel, resolveApiKey, } from "../core/index.js";
24
+ import { buildToolset } from "../tools/index.js";
25
+ import { adaptToolset } from "./agent-tool-adapter.js";
26
+ import { dumpSystemPrompt } from "./dump-system-prompt.js";
27
+ import { SqliteSessionRepo } from "./sqlite-session-repo.js";
28
+ import { drainPending as drainInbox, renderForPrompt as renderInboxForPrompt, markDeliveredFromMessage, } from "./session-inbox.js";
29
+ import { registerActiveHarness, registerUserSendChannel, } from "./active-harnesses.js";
30
+ import { SqliteSessionStorage } from "./sqlite-session-storage.js";
31
+ import { makeStubExecutionEnv } from "./stub-execution-env.js";
32
+ import { filterSkillsForTenant, loadSkillsForPlugin, } from "../core/plugins/skills.js";
33
+ import { loadTenantSkills } from "../core/tenant-skills.js";
34
+ import { fileURLToPath } from "node:url";
35
+ import { ensureActiveSession, listMessagesForUserPage, loadAgentHistoryForSession, } from "./messages.js";
36
+ import { CompactSkippedError, compactSession } from "./compact.js";
37
+ import { toWire, } from "./ws-protocol.js";
38
+ import { cacheGet, cachePut, fitToLimit, imageFitCacheKey, } from "./image-fit.js";
39
+ const MAX_TURNS = 16;
40
+ export function attachChatHandler(opts) {
41
+ const { ctx, userId, socket, pluginRegistry, homeDir } = opts;
42
+ const send = (msg) => {
43
+ if (socket.readyState !== socket.OPEN)
44
+ return;
45
+ socket.send(JSON.stringify(msg));
46
+ };
47
+ send({ type: "connected", tenantId: ctx.tenantId, userId });
48
+ // Register this socket's send thunk so the session-inbox idle
49
+ // runner can broadcast a background turn's stream to every
50
+ // tab the user has open. unregister fires on `close` below.
51
+ const unregisterUserChannel = registerUserSendChannel(userId, send);
52
+ let aborter = null;
53
+ socket.on("message", (raw) => {
54
+ let parsed;
55
+ try {
56
+ parsed = JSON.parse(raw.toString());
57
+ }
58
+ catch {
59
+ return;
60
+ }
61
+ switch (parsed.type) {
62
+ case "hello":
63
+ send({ type: "connected", tenantId: ctx.tenantId, userId });
64
+ return;
65
+ case "history": {
66
+ const opts = makeWireOpts(ctx);
67
+ const page = listMessagesForUserPage(ctx, userId, {
68
+ limit: parsed.limit,
69
+ });
70
+ send({
71
+ type: "history",
72
+ messages: page.messages.map((m) => toWire(m, opts)),
73
+ hasMore: page.hasMore,
74
+ });
75
+ return;
76
+ }
77
+ case "history_more": {
78
+ const opts = makeWireOpts(ctx);
79
+ const page = listMessagesForUserPage(ctx, userId, {
80
+ limit: parsed.limit,
81
+ before: parsed.before,
82
+ });
83
+ send({
84
+ type: "history_page",
85
+ messages: page.messages.map((m) => toWire(m, opts)),
86
+ hasMore: page.hasMore,
87
+ before: parsed.before,
88
+ });
89
+ return;
90
+ }
91
+ case "prompt": {
92
+ if (aborter)
93
+ aborter.abort(); // single in-flight prompt per socket
94
+ aborter = new AbortController();
95
+ // Slash-command: `/compact` runs an immediate compaction
96
+ // pass without sending a fresh user prompt. Recognised when
97
+ // the typed body is exactly the marker plus optional
98
+ // whitespace and (for parity with the legacy CLI) `!`.
99
+ const trimmed = parsed.content.trim();
100
+ if (trimmed === "/compact" || trimmed === "/compact!") {
101
+ runManualCompact({
102
+ ctx,
103
+ userId,
104
+ send,
105
+ modelId: parsed.modelId,
106
+ signal: aborter.signal,
107
+ }).catch((err) => {
108
+ send({
109
+ type: "stream_error",
110
+ reason: err instanceof Error ? err.message : String(err),
111
+ });
112
+ });
113
+ return;
114
+ }
115
+ runPrompt({
116
+ ctx,
117
+ userId,
118
+ send,
119
+ content: parsed.content,
120
+ modelId: parsed.modelId,
121
+ attachments: parsed.attachments,
122
+ signal: aborter.signal,
123
+ pluginRegistry,
124
+ homeDir,
125
+ }).catch((err) => {
126
+ send({
127
+ type: "stream_error",
128
+ reason: err instanceof Error ? err.message : String(err),
129
+ });
130
+ });
131
+ return;
132
+ }
133
+ case "abort": {
134
+ aborter?.abort();
135
+ aborter = null;
136
+ return;
137
+ }
138
+ }
139
+ });
140
+ socket.on("close", () => {
141
+ aborter?.abort();
142
+ aborter = null;
143
+ unregisterUserChannel();
144
+ });
145
+ }
146
+ export async function runPrompt(args) {
147
+ const { ctx, userId, send, content, modelId, attachments, signal, pluginRegistry, homeDir } = args;
148
+ const wireOpts = makeWireOpts(ctx);
149
+ const repo = new SqliteSessionRepo(ctx);
150
+ let session = ensureActiveSession(ctx, userId);
151
+ // Resolve the model up front — we need imageMaxBytes / context
152
+ // window for both auto-compact and the LLM call below.
153
+ const modelInfo = (modelId ? findModel(ctx.config, modelId) : undefined) ?? getDefaultModel(ctx.config);
154
+ if (!modelInfo) {
155
+ send({
156
+ type: "stream_error",
157
+ reason: "no models configured (set models in ~/.tianshu/config.json)",
158
+ });
159
+ return;
160
+ }
161
+ const piModel = buildModel(modelInfo);
162
+ const apiKey = resolveApiKey(modelInfo);
163
+ const userHome = ctx.userHomeDir(userId);
164
+ // MCP toolsets (e.g. plugin-microsandbox's Playwright server)
165
+ // expose a `tools/list` only after the upstream is reachable.
166
+ // Plugin activation kicks off a fire-and-forget initial refresh,
167
+ // but the upstream often isn't ready yet (sandbox still booting,
168
+ // user-configured server still being saved). Without a per-turn
169
+ // warmup the agent never sees these tools until someone hits
170
+ // `/admin/mcp` to refresh by hand. Run the same opportunistic
171
+ // refresh the admin route does, but with a tighter deadline so
172
+ // we don't block a chat turn for too long when an upstream is
173
+ // genuinely down.
174
+ if (pluginRegistry) {
175
+ try {
176
+ await pluginRegistry.refreshStaleToolsets(ctx.tenantId, 1500);
177
+ }
178
+ catch {
179
+ // refreshStaleToolsets already swallows per-toolset errors;
180
+ // a thrown one would mean the registry itself faulted, which
181
+ // we don't want to surface as a chat failure either — the
182
+ // agent will simply see whatever toolset state we already
183
+ // had.
184
+ }
185
+ }
186
+ const pluginTools = pluginRegistry?.toolsForTenant(ctx.tenantId) ?? [];
187
+ // Skill priority (later wins on the dedup key, which is the
188
+ // directory name for tenant skills and the contribution id for
189
+ // host/plugin skills): host+plugin (mirrored) → tenant scope.
190
+ // Tenant scope wins by design — the user can override or shadow a
191
+ // shipped skill by dropping a same-named directory under
192
+ // `_tenant/config/{skills,main/skills}/`. The mirrored copies
193
+ // live under `_tenant/config/skills/_host/<pid>/<id>/SKILL.md`
194
+ // and carry tenant-config:/// filePaths so the system prompt's
195
+ // <available_skills> block can advertise them in the same shape
196
+ // as user-authored skills.
197
+ const allSkills = [
198
+ ...(pluginRegistry?.mirroredSkillsForTenant(ctx.tenantId) ?? []),
199
+ ...loadTenantSkills({
200
+ tenantId: ctx.tenantId,
201
+ scope: { kind: "main" },
202
+ onFailure: (f) => console.warn(`[tenant-skills:${f.scope}] ${f.filePath}: ${f.reason}`),
203
+ }),
204
+ ];
205
+ // Build a set of registered tool names from pluginTools' schemas.
206
+ // We don't yet know what `available()` will say, so we use the
207
+ // schema name; this slightly over-includes skills that depend on
208
+ // a tool that ends up hidden, but the agent simply won't reach
209
+ // for those. Conservative on the side of more visibility.
210
+ const declaredToolNames = new Set(pluginTools.map(({ tool }) => tool.schema.name));
211
+ const hostCaps = pluginRegistry?.hostCapabilities(ctx.tenantId) ?? emptyHostCapabilities();
212
+ const skills = filterSkillsForTenant(allSkills, {
213
+ hasTool: (n) => declaredToolNames.has(n),
214
+ hasCapability: (n) => hostCaps.has(n),
215
+ agentScope: "main",
216
+ });
217
+ // Plugin-contributed prompt fragments: short imperative
218
+ // sentences declared in `manifest.contributes.systemPromptFragments`,
219
+ // injected on every turn for every active plugin in the tenant.
220
+ // Workers don't get these (the agent-loop's worker path uses a
221
+ // separate prompt path).
222
+ const pluginFragments = pluginRegistry?.systemPromptFragmentsForTenant(ctx.tenantId) ?? [];
223
+ const toolset = await buildToolset({
224
+ pluginTools,
225
+ toolContext: {
226
+ tenantId: ctx.tenantId,
227
+ userId,
228
+ capabilities: hostCaps,
229
+ userHomeDir: userHome,
230
+ tenantHomeDir: homeDir ?? "",
231
+ // Main chat agent. Drives `tenant_config_write` boundary in
232
+ // the files plugin: main may write to `main/skills/` and
233
+ // shared `skills/`.
234
+ agentScope: { kind: "main" },
235
+ log: makeLogger(ctx.tenantId, userId, send),
236
+ sessionId: session.id,
237
+ },
238
+ });
239
+ // Convert wire attachments into:
240
+ // * `images` — base64 ImageContent[] for vision-capable models
241
+ // * `prompt prefix` — a short text note for non-image files
242
+ // pointing the agent at the path
243
+ //
244
+ // Non-image bytes never reach the LLM directly; the agent reads
245
+ // them via tools (`read_file`, or shell `pdftotext` for pdfs).
246
+ const { promptText: rawPromptText, images, originalAttachments } = await prepareUserInput(content, attachments, ctx.userHomeDir(userId), modelInfo);
247
+ // Drain the session inbox before the agent sees the user's
248
+ // prompt. Anything dropped here while the session was idle
249
+ // (e.g. a worker pool reporting task_done) is rendered as a
250
+ // system-note prefix above the user's text. The agent thus
251
+ // gets full context: "these messages arrived for you while
252
+ // you were idle, AND here's the next thing the user said".
253
+ const inboxDelivered = drainInbox(ctx, session.id);
254
+ const inboxPrefix = renderInboxForPrompt(inboxDelivered);
255
+ const promptText = inboxPrefix
256
+ ? `${inboxPrefix}<user>\n${rawPromptText}\n</user>`
257
+ : rawPromptText;
258
+ // Build the harness session ourselves so we can keep a handle
259
+ // on the storage — we need to stash sibling attachments on it
260
+ // before the harness's user-message persistence fires, and we
261
+ // hand it the model's vision profile so its `getPathToRoot`
262
+ // reads + base64-encodes images on demand at LLM-call time.
263
+ const storage = new SqliteSessionStorage(ctx, session.id, {
264
+ imageInflate: {
265
+ userHome,
266
+ imageMaxBytes: modelInfo.imageMaxBytes,
267
+ supportsImages: modelInfo.supportsImages,
268
+ },
269
+ });
270
+ const piSession = new PiSession(storage);
271
+ if (originalAttachments && originalAttachments.length > 0) {
272
+ storage.pendingUserAttachments = {
273
+ attachments: originalAttachments,
274
+ };
275
+ }
276
+ void repo;
277
+ send({ type: "stream_start" });
278
+ const adapted = adaptToolset(toolset);
279
+ const systemPrompt = defaultSystemPrompt(ctx, userId, skills, pluginFragments);
280
+ dumpSystemPrompt({ ctx, role: "main", userId, systemPrompt });
281
+ const harness = new AgentHarness({
282
+ env: makeStubExecutionEnv(ctx.userHomeDir(userId)),
283
+ session: piSession,
284
+ tools: adapted.tools,
285
+ systemPrompt,
286
+ model: piModel,
287
+ getApiKeyAndHeaders: async () => ({ apiKey }),
288
+ });
289
+ // External abort → harness.abort()
290
+ const onAbort = () => void harness.abort();
291
+ signal.addEventListener("abort", onAbort, { once: true });
292
+ // Register this harness in the process-local registry so the
293
+ // session inbox can route a live `enqueue()` through
294
+ // `harness.followUp(...)` instead of leaving the message stuck
295
+ // in `pending` until the user types again. Cleared in finally.
296
+ const unregisterHarness = registerActiveHarness(session.id, harness);
297
+ let lastAssistantRow = null;
298
+ let assistantTurns = 0;
299
+ let streamErrorSent = false;
300
+ // Track tool calls the agent emitted but never produced a
301
+ // tool_result for. Provider terminations / aborts can leave a
302
+ // toolCall hanging — the UI shows a perpetual spinner. We
303
+ // synthesise a failed tool_result for any leftover entry in
304
+ // the finally block so the chip resolves.
305
+ const outstandingToolCalls = new Map();
306
+ const unsubscribe = harness.subscribe((event) => {
307
+ const ev = event;
308
+ if (ev.type === "tool_execution_start") {
309
+ const tc = event;
310
+ outstandingToolCalls.set(tc.toolCallId, { name: tc.toolName });
311
+ }
312
+ else if (ev.type === "tool_execution_end") {
313
+ const te = event;
314
+ outstandingToolCalls.delete(te.toolCallId);
315
+ }
316
+ bridgeHarnessEventToWs(event, {
317
+ ctx,
318
+ session,
319
+ send,
320
+ wireOpts,
321
+ onAssistantPersisted: (row) => {
322
+ lastAssistantRow = row;
323
+ assistantTurns++;
324
+ if (assistantTurns >= MAX_TURNS) {
325
+ void harness.abort();
326
+ }
327
+ },
328
+ onStreamError: () => {
329
+ streamErrorSent = true;
330
+ },
331
+ });
332
+ });
333
+ try {
334
+ await harness.prompt(promptText, images.length > 0 ? { images } : undefined);
335
+ await harness.waitForIdle();
336
+ }
337
+ catch (err) {
338
+ if (!streamErrorSent) {
339
+ send({
340
+ type: "stream_error",
341
+ reason: err instanceof Error ? err.message : String(err),
342
+ });
343
+ streamErrorSent = true;
344
+ }
345
+ }
346
+ finally {
347
+ // Resolve any tool-call chip the UI is still showing as
348
+ // running. Provider termination after a `tool_call` event
349
+ // but before the matching `tool_execution_end` strands the
350
+ // chip in `running` state forever; emit a synthetic failed
351
+ // result so the bubble renders an error and the run can
352
+ // visually move on.
353
+ for (const [callId, info] of outstandingToolCalls) {
354
+ send({
355
+ type: "tool_result",
356
+ callId,
357
+ name: info.name,
358
+ ok: false,
359
+ text: streamErrorSent
360
+ ? "Tool call interrupted by stream error."
361
+ : "Tool call did not return before the run ended.",
362
+ });
363
+ }
364
+ outstandingToolCalls.clear();
365
+ unsubscribe();
366
+ unregisterHarness();
367
+ signal.removeEventListener("abort", onAbort);
368
+ if (storage)
369
+ storage.pendingUserAttachments = null;
370
+ }
371
+ // Auto-compact: pi-agent-core ships compact() but no auto-trigger.
372
+ // After every successful turn, decide whether to fire it.
373
+ if (!streamErrorSent) {
374
+ await maybeAutoCompact({
375
+ session,
376
+ piSession,
377
+ harness,
378
+ modelInfo,
379
+ send,
380
+ onSuccessRefresh: () => {
381
+ // Refresh after compaction: same default page size as the
382
+ // initial fetch. The compacted session is what the client
383
+ // wants to see; we don't try to preserve the older paged-in
384
+ // window because compaction logically replaces it.
385
+ const page = listMessagesForUserPage(ctx, userId);
386
+ send({
387
+ type: "history",
388
+ messages: page.messages.map((m) => toWire(m, makeWireOpts(ctx))),
389
+ hasMore: page.hasMore,
390
+ });
391
+ },
392
+ });
393
+ }
394
+ // Emit stream_end so the UI re-enables the send button.
395
+ //
396
+ // Skip the persisted row when its rendered text is empty —
397
+ // those happen when the agent only emitted tool calls in the
398
+ // final turn and never said anything user-facing. Showing
399
+ // them produces a content-less bubble ("…") that just
400
+ // confuses the user; the tool result chips above already
401
+ // tell the story. Synthesise the placeholder branch instead
402
+ // so the UI re-enables the send button without rendering an
403
+ // empty bubble.
404
+ const lastWire = lastAssistantRow ? toWire(lastAssistantRow, wireOpts) : null;
405
+ const lastIsEmpty = !!lastWire && !hasVisibleAssistantText(lastWire);
406
+ if (!streamErrorSent) {
407
+ if (lastWire && !lastIsEmpty) {
408
+ send({ type: "stream_end", message: lastWire });
409
+ }
410
+ else {
411
+ // Synthetic placeholder so the UI doesn't get stuck.
412
+ send({
413
+ type: "stream_end",
414
+ message: toWire({
415
+ id: `msg_empty_${Date.now()}`,
416
+ sessionId: session.id,
417
+ role: "assistant",
418
+ content: "",
419
+ createdAt: Date.now(),
420
+ }, wireOpts),
421
+ });
422
+ }
423
+ }
424
+ }
425
+ /**
426
+ * True iff the wire-encoded assistant message has at least one
427
+ * visible text segment. Tool calls / tool results don't count
428
+ * — they render as their own chips elsewhere; an assistant
429
+ * "message" with only those segments is a content-less bubble
430
+ * we should suppress.
431
+ */
432
+ function hasVisibleAssistantText(m) {
433
+ if (m.role !== "assistant")
434
+ return true;
435
+ if (typeof m.text === "string" && m.text.trim().length > 0)
436
+ return true;
437
+ return false;
438
+ }
439
+ /**
440
+ * Translate (text, wire-attachments) → a single text + ImageContent[]
441
+ * suitable for `harness.prompt(text, { images })`.
442
+ *
443
+ * * Image attachments → fitted to the model's byte budget +
444
+ * emitted as ImageContent[].
445
+ * * Non-image attachments → a one-liner prepended to the user
446
+ * text pointing the agent at the file path.
447
+ * * Vision-incapable model → every image is replaced by a
448
+ * [Attached image: name (no vision support)] note.
449
+ */
450
+ async function prepareUserInput(content, attachments, userHome, modelInfo) {
451
+ const atts = attachments ?? [];
452
+ if (atts.length === 0) {
453
+ return { promptText: content, images: [], originalAttachments: atts };
454
+ }
455
+ const fileLines = [];
456
+ const images = [];
457
+ for (const att of atts) {
458
+ const isImage = att.mimeType.startsWith("image/");
459
+ if (!isImage) {
460
+ fileLines.push(`[Attached file: ${att.name ?? att.path} (${att.mimeType}) — readable at .${att.path}]`);
461
+ continue;
462
+ }
463
+ if (!modelInfo.supportsImages) {
464
+ fileLines.push(`[Attached image (current model has no vision support): ${att.name ?? att.path}]`);
465
+ continue;
466
+ }
467
+ const abs = path.join(userHome, att.path.startsWith("/") ? att.path.slice(1) : att.path);
468
+ try {
469
+ const stat = fs.statSync(abs);
470
+ const cacheKey = imageFitCacheKey(abs, stat.mtimeMs, modelInfo.imageMaxBytes);
471
+ const cached = cacheGet(cacheKey);
472
+ let buf;
473
+ let mimeType;
474
+ if (cached) {
475
+ buf = cached.buf;
476
+ mimeType = cached.mimeType;
477
+ }
478
+ else {
479
+ const raw = fs.readFileSync(abs);
480
+ const fitted = await fitToLimit(raw, att.mimeType, modelInfo.imageMaxBytes);
481
+ buf = fitted.buf;
482
+ mimeType = fitted.mimeType;
483
+ cachePut(cacheKey, buf, mimeType);
484
+ }
485
+ images.push({
486
+ type: "image",
487
+ data: buf.toString("base64"),
488
+ mimeType,
489
+ });
490
+ }
491
+ catch (err) {
492
+ const reason = err?.message ?? "read failed";
493
+ fileLines.push(`[Attached image: ${att.name ?? att.path} — read failed: ${reason}]`);
494
+ }
495
+ }
496
+ const prefix = fileLines.length > 0 ? fileLines.join("\n") + "\n\n" : "";
497
+ return {
498
+ promptText: prefix + content,
499
+ images,
500
+ originalAttachments: atts,
501
+ };
502
+ }
503
+ /**
504
+ * Translate one harness event into the legacy chat WS protocol.
505
+ * Every assistant / toolResult message that lands in the harness
506
+ * session is re-broadcast here so the existing UI flow keeps
507
+ * working unchanged.
508
+ */
509
+ function bridgeHarnessEventToWs(event, args) {
510
+ const { ctx, session, send, wireOpts, onAssistantPersisted, onStreamError } = args;
511
+ const e = event;
512
+ // Pi-low-level events first (text_delta etc).
513
+ const lowType = event.type;
514
+ if (lowType === "message_update") {
515
+ const upd = event;
516
+ if (upd.assistantMessageEvent.type === "text_delta" &&
517
+ typeof upd.assistantMessageEvent.delta === "string") {
518
+ send({ type: "stream_delta", delta: upd.assistantMessageEvent.delta });
519
+ }
520
+ return;
521
+ }
522
+ if (lowType === "message_end") {
523
+ const m = event.message;
524
+ if (m.role === "assistant") {
525
+ const row = readBackLatestMessage(ctx, session.id, "assistant");
526
+ if (row) {
527
+ // Always notify the run controller (lastAssistantRow gets
528
+ // tracked here) so MAX_TURNS counting and the stream_end
529
+ // selection in the caller stay correct, even if we
530
+ // suppress the wire message below.
531
+ onAssistantPersisted(row);
532
+ const wire = toWire(row, wireOpts);
533
+ // Suppress empty assistant messages (no user-visible
534
+ // text segments). They show up as bare "…" bubbles
535
+ // when the agent's final turn was tool-only — the tool
536
+ // result chips above already tell the story. The same
537
+ // filter is applied at stream_end below.
538
+ if (hasVisibleAssistantText(wire)) {
539
+ send({ type: "message_added", message: wire });
540
+ }
541
+ }
542
+ }
543
+ else if (m.role === "user") {
544
+ const row = readBackLatestMessage(ctx, session.id, "user");
545
+ if (row) {
546
+ // pi just persisted a user message. If it carries inbox
547
+ // markers, this is the proof we needed that the inbox
548
+ // followUp was actually consumed — mark those rows
549
+ // delivered now so they don't get redelivered as a
550
+ // prefix on the next user prompt. See
551
+ // session-inbox.ts's markDeliveredFromMessage.
552
+ try {
553
+ markDeliveredFromMessage(ctx, row.content);
554
+ }
555
+ catch (err) {
556
+ // eslint-disable-next-line no-console
557
+ console.warn("[handler] markDeliveredFromMessage failed:", err instanceof Error ? err.message : err);
558
+ }
559
+ send({ type: "message_added", message: toWire(row, wireOpts) });
560
+ }
561
+ }
562
+ else if (m.role === "toolResult") {
563
+ // SqliteSessionStorage just wrote the tool-result row;
564
+ // forward it to the UI so the chip materialises into a
565
+ // proper message in the transcript.
566
+ const row = readBackLatestMessage(ctx, session.id, "tool");
567
+ if (row) {
568
+ send({ type: "message_added", message: toWire(row, wireOpts) });
569
+ }
570
+ }
571
+ return;
572
+ }
573
+ // Pi's low-level tool events: tool_execution_start fires when
574
+ // the harness begins running a tool, tool_execution_end after
575
+ // it completes. We emit the legacy tianshu chip events around
576
+ // them so the existing UI flow keeps working.
577
+ if (lowType === "tool_execution_start") {
578
+ const tc = event;
579
+ send({
580
+ type: "tool_call",
581
+ callId: tc.toolCallId,
582
+ name: tc.toolName,
583
+ arguments: tc.args ?? {},
584
+ });
585
+ return;
586
+ }
587
+ if (lowType === "tool_execution_end") {
588
+ const te = event;
589
+ const blocks = te.result?.content ?? [];
590
+ const text = blocks
591
+ .map((c) => (c.type === "text" && typeof c.text === "string" ? c.text : ""))
592
+ .join("");
593
+ send({
594
+ type: "tool_result",
595
+ callId: te.toolCallId,
596
+ name: te.toolName,
597
+ ok: !te.isError,
598
+ text,
599
+ });
600
+ return;
601
+ }
602
+ // Surface stream-level errors as the legacy stream_error so the
603
+ // UI handles them the same way it always has.
604
+ //
605
+ // pi-agent-core encodes LLM failures (401, rate limit, network,
606
+ // anything thrown by the streamFn) by setting stopReason="error"
607
+ // + errorMessage on the final AssistantMessage — then it emits
608
+ // a normal `agent_end`. If we don't introspect agent_end, the
609
+ // server happily reports stream_end with an empty assistant body,
610
+ // the UI re-enables the send button, and the user can't tell
611
+ // why nothing came back. Caught 2026-06-21 on a tenant whose
612
+ // qwen apiKey was placeholder text (`sk-4e8…581e`); dashscope
613
+ // 401'd, pi flagged the assistant with stopReason="error", server
614
+ // returned a silent empty bubble.
615
+ if (lowType === "agent_end") {
616
+ const messages = event.messages;
617
+ const last = messages[messages.length - 1];
618
+ if (last &&
619
+ last.role === "assistant" &&
620
+ (last.stopReason === "error" || last.stopReason === "aborted")) {
621
+ const reason = last.errorMessage ??
622
+ `assistant turn ended with stopReason=${last.stopReason}`;
623
+ send({ type: "stream_error", reason });
624
+ onStreamError();
625
+ }
626
+ return;
627
+ }
628
+ if (lowType === "settled") {
629
+ return;
630
+ }
631
+ }
632
+ /** Read the most recently persisted message of a given role from
633
+ * `messages`. Used by the WS bridge to pick up the row the harness
634
+ * just wrote (so we can `toWire` it for the client). */
635
+ function readBackLatestMessage(ctx, sessionId, role) {
636
+ const row = ctx.db
637
+ .prepare(`SELECT id, session_id, role, content, created_at
638
+ FROM messages
639
+ WHERE session_id = ? AND role = ? AND entry_type = 'message'
640
+ ORDER BY created_at DESC, rowid DESC
641
+ LIMIT 1`)
642
+ .get(sessionId, role);
643
+ if (!row)
644
+ return null;
645
+ return {
646
+ id: row.id,
647
+ sessionId: row.session_id,
648
+ role: row.role,
649
+ content: row.content,
650
+ createdAt: row.created_at,
651
+ };
652
+ }
653
+ /** Build a `ToWireOpts` bound to the current tenant config. The
654
+ * resolver lets `toWire` stamp `meta.contextWindow` on every
655
+ * assistant row without each caller having to do the lookup. */
656
+ function makeWireOpts(ctx) {
657
+ return {
658
+ contextWindowFor: (modelId) => {
659
+ const info = findModel(ctx.config, modelId);
660
+ return info?.contextWindow;
661
+ },
662
+ };
663
+ }
664
+ /**
665
+ * Pure decision function: given a branch (the entries pi's
666
+ * harness sees as the active turn history) and the model's
667
+ * context window, return whether the next turn should run
668
+ * compaction first.
669
+ *
670
+ * Exported for tests; runtime callers go through
671
+ * `maybeAutoCompact` which folds storage + harness in.
672
+ */
673
+ export function shouldCompactBranch(input) {
674
+ const settings = input.settings ?? DEFAULT_COMPACTION_SETTINGS;
675
+ if (!settings.enabled)
676
+ return false;
677
+ if (!input.contextWindow || input.contextWindow <= 0)
678
+ return false;
679
+ const messages = [];
680
+ for (const entry of input.branch) {
681
+ if (entry.type === "message")
682
+ messages.push(entry.message);
683
+ }
684
+ if (messages.length === 0)
685
+ return false;
686
+ const usage = estimateContextTokens(messages);
687
+ return shouldCompact(usage.tokens, input.contextWindow, settings);
688
+ }
689
+ export async function tryAutoCompact(args) {
690
+ const { piSession, harness, contextWindow } = args;
691
+ let branch;
692
+ try {
693
+ branch = await piSession.getBranch();
694
+ }
695
+ catch (err) {
696
+ console.warn(`[chat] auto-compact decision failed: ${err instanceof Error ? err.message : String(err)}`);
697
+ return { compacted: false };
698
+ }
699
+ if (!shouldCompactBranch({ branch, contextWindow })) {
700
+ return { compacted: false };
701
+ }
702
+ try {
703
+ const result = await harness.compact();
704
+ return { compacted: true, tokensBefore: result.tokensBefore };
705
+ }
706
+ catch (err) {
707
+ return {
708
+ compacted: false,
709
+ error: err instanceof Error ? err.message : String(err),
710
+ };
711
+ }
712
+ }
713
+ async function maybeAutoCompact(args) {
714
+ const { session, piSession, harness, modelInfo, send, onSuccessRefresh } = args;
715
+ const decision = await tryAutoCompact({
716
+ piSession,
717
+ harness,
718
+ contextWindow: modelInfo.contextWindow,
719
+ });
720
+ if (decision.error) {
721
+ // Auto-compact failure on the chat path: surface as a
722
+ // stream_error so the user knows next turn may be expensive.
723
+ send({
724
+ type: "stream_error",
725
+ reason: `auto-compact failed: ${decision.error} (continuing without compact)`,
726
+ });
727
+ return;
728
+ }
729
+ if (!decision.compacted)
730
+ return;
731
+ send({
732
+ type: "history_compacted",
733
+ reason: "auto",
734
+ // Old protocol carried oldSessionId/newSessionId because
735
+ // the legacy compactSession forked. pi's compact() writes
736
+ // a compaction entry into the SAME session — no fork — so
737
+ // both ids point at the current one.
738
+ oldSessionId: session.id,
739
+ newSessionId: session.id,
740
+ // Pi's compact() doesn't tell us how many entries it
741
+ // summarised / kept. The UI uses these counts for a small
742
+ // "📌 N messages compressed" badge; we leave them at 0
743
+ // until pi exposes the figures.
744
+ summarisedCount: 0,
745
+ keptCount: 0,
746
+ durationMs: 0,
747
+ tokensBefore: decision.tokensBefore,
748
+ });
749
+ onSuccessRefresh();
750
+ }
751
+ async function runManualCompact(args) {
752
+ const { ctx, userId, send, modelId, signal } = args;
753
+ const session = ensureActiveSession(ctx, userId);
754
+ const modelInfo = (modelId ? findModel(ctx.config, modelId) : undefined) ??
755
+ getDefaultModel(ctx.config);
756
+ if (!modelInfo) {
757
+ send({
758
+ type: "stream_error",
759
+ reason: "no models configured",
760
+ });
761
+ return;
762
+ }
763
+ const { messages, rows } = loadAgentHistoryForSession(ctx, session.id, {
764
+ api: modelInfo.api,
765
+ provider: modelInfo.providerId,
766
+ model: modelInfo.modelId,
767
+ });
768
+ if (messages.length === 0) {
769
+ send({
770
+ type: "stream_error",
771
+ reason: "nothing to compact (no messages yet)",
772
+ });
773
+ return;
774
+ }
775
+ try {
776
+ const result = await compactSession({
777
+ ctx,
778
+ userId,
779
+ oldSession: session,
780
+ pi: messages,
781
+ rows,
782
+ modelInfo,
783
+ signal,
784
+ });
785
+ send({
786
+ type: "history_compacted",
787
+ reason: "manual",
788
+ oldSessionId: result.oldSessionId,
789
+ newSessionId: result.newSession.id,
790
+ summarisedCount: result.summarisedCount,
791
+ keptCount: result.keptCount,
792
+ durationMs: result.durationMs,
793
+ });
794
+ // Push a refreshed history so the UI swaps to the new session
795
+ // immediately (the fork ack + summary stub plus any kept tail).
796
+ const page = listMessagesForUserPage(ctx, userId);
797
+ send({
798
+ type: "history",
799
+ messages: page.messages.map((m) => toWire(m, makeWireOpts(ctx))),
800
+ hasMore: page.hasMore,
801
+ });
802
+ }
803
+ catch (err) {
804
+ if (err instanceof CompactSkippedError) {
805
+ send({ type: "stream_error", reason: `compact skipped: ${err.message}` });
806
+ return;
807
+ }
808
+ send({
809
+ type: "stream_error",
810
+ reason: `compact failed: ${err instanceof Error ? err.message : String(err)}`,
811
+ });
812
+ }
813
+ }
814
+ export function defaultSystemPrompt(ctx, userId, skills = [], pluginFragments = []) {
815
+ const brand = ctx.config.branding?.name ?? "Tianshu";
816
+ const lines = [
817
+ `You are ${brand}, an open-source AI assistant.`,
818
+ `Tenant: "${ctx.tenantId}". User: "${userId}".`,
819
+ ];
820
+ // Workspace layout / directory conventions / file-reference
821
+ // rules used to live here as a host-hardcoded block. Per
822
+ // ADR-0006 they now belong to the `files` plugin's
823
+ // `manifest.contributes.systemPromptFragments` and reach the
824
+ // prompt via `formatPluginPromptFragments(pluginFragments)`
825
+ // below — same path as every other plugin's guidance, and the
826
+ // same path workers already take. Disabling the `files` plugin
827
+ // cleanly drops its guidance from the prompt.
828
+ //
829
+ // The host stays plugin-agnostic, and main + worker prompts
830
+ // reach symmetric layout text without the host having to inject
831
+ // a separate workspace block on each side.
832
+ // Execution Bias — host-level behaviour rules that shape every
833
+ // turn, regardless of which plugins are loaded. Borrowed from
834
+ // OpenClaw's main prompt because the failure modes it prevents
835
+ // ("finish with a plan/promise instead of doing the work",
836
+ // "weak tool result → give up rather than vary the query")
837
+ // matched real stalls we saw on long task runs (PR #141
838
+ // workboard tasks ending without task_complete being a typical
839
+ // case). Phrasing kept tight on purpose: the LLM only needs the
840
+ // rule, not a long argument for it.
841
+ lines.push(``, formatExecutionBiasBlock());
842
+ // Workspace context files. Each is optional; missing files emit
843
+ // nothing. We inject content (not paths) so the agent has them
844
+ // in context without having to read_file first.
845
+ //
846
+ // Layout:
847
+ // _tenant/AGENTS.md — tenant working agreements (main agent)
848
+ // _tenant/SOUL.md — main agent persona
849
+ // _tenant/MEMORY.md — tenant long-term memory
850
+ // users/<userId>/USER.md — per-user preferences
851
+ //
852
+ // Files larger than the per-file cap get a head + tail snippet
853
+ // with a [… truncated …] marker so a runaway log can't blow the
854
+ // prompt budget.
855
+ const userHomeDir = ctx.userHomeDir(userId);
856
+ const ctxBlock = formatMainAgentContextBlock(ctx.workspaceDir, userHomeDir);
857
+ if (ctxBlock)
858
+ lines.push("", ctxBlock);
859
+ // Plugin guidance + skills first; the User Profile rule lands
860
+ // last on purpose because it overrides the "reply concisely"
861
+ // / "delegate to a worker" defaults on the very first turn
862
+ // when USER.md is still scaffold.
863
+ lines.push(``, `Reply concisely. When you make changes, briefly say what you changed.`);
864
+ const fragmentBlock = formatPluginPromptFragments(pluginFragments);
865
+ if (fragmentBlock)
866
+ lines.push("", fragmentBlock);
867
+ const skillBlock = formatAvailableSkillsBlock(skills);
868
+ if (skillBlock)
869
+ lines.push("", skillBlock);
870
+ // User onboarding rule — placed last so it wins recency-bias
871
+ // over the brevity / delegate-to-worker rules above. Without
872
+ // this position the LLM responds to a one-word "hi" by replying
873
+ // "hi" back instead of capturing the user's profile.
874
+ const hasUserFile = userMdExists(userHomeDir);
875
+ lines.push(``, formatUserOnboardingBlock(hasUserFile));
876
+ // Final pass: bind `<self>` / `<userId>` placeholders that
877
+ // appear anywhere in the assembled prompt (manifest fragments,
878
+ // tool descriptions, context-block labels, our own onboarding
879
+ // text) to the caller's actual userId. Plugin authors can't
880
+ // know the runtime value, so they ship the placeholder; we
881
+ // substitute here. Without this the LLM has been observed to
882
+ // hallucinate a userId (`user1`, `user3`, `user_x`) and burn a
883
+ // run on a path that doesn't exist.
884
+ return substituteUserIdPlaceholders(lines.join("\n"), userId);
885
+ }
886
+ /**
887
+ * Whether `users/<self>/USER.md` already exists for the caller.
888
+ * Wraps the same fs check the context block uses, but exported
889
+ * separately so the onboarding prompt can branch its wording
890
+ * without re-reading the file content.
891
+ */
892
+ function userMdExists(userHomeDir) {
893
+ try {
894
+ const p = path.join(userHomeDir, "USER.md");
895
+ return fs.existsSync(p) && fs.statSync(p).size > 0;
896
+ }
897
+ catch {
898
+ return false;
899
+ }
900
+ }
901
+ /**
902
+ * User onboarding block. Tells main agents to actively curate the
903
+ * per-user USER.md — ask before going off-script, then write what
904
+ * was learnt back so future runs start with concrete preferences.
905
+ *
906
+ * Branches on whether USER.md exists today. The cold-start wording
907
+ * is more proactive ("propose to start one"); the populated
908
+ * wording skips the proposal step and only nudges on missing /
909
+ * stale facts. Both versions are short — the LLM doesn't need a
910
+ * lecture, just the rule + the file path to write to.
911
+ */
912
+ function formatUserOnboardingBlock(userMdPresent) {
913
+ // Same prompt regardless of whether the file exists — the LLM
914
+ // makes the call by inspecting the Workspace Context block above.
915
+ // (We tried branching on `userMdExists` but a USER.md that's
916
+ // just the empty template scaffolding got treated as "populated"
917
+ // and the cold-start questions never fired. Pushing the
918
+ // "populated vs scaffold" judgement into the LLM is more robust
919
+ // than parsing markdown templates here.)
920
+ void userMdPresent;
921
+ return [
922
+ `## User Profile (USER.md) — read this first`,
923
+ `Look at \`### users/<self>/USER.md\` in the Workspace Context block above and decide right now whether it's POPULATED or a SCAFFOLD.`,
924
+ `- POPULATED = real concrete entries (real name, the user's actual projects, communication preferences they've stated, etc.)`,
925
+ `- SCAFFOLD = mostly headings + italics hints + empty form fields like \`**Name:**\` / \`**Pronouns:**\` / a single seeded value (e.g. a default time zone) with everything else blank.`,
926
+ `On a fresh conversation where USER.md is missing OR a scaffold:`,
927
+ `1. Even if the user just says "hi", do NOT just reply hi back. First proactively ask 3-5 short questions to fill USER.md (preferred name, current projects, communication style, anything that should never be forgotten). Keep it conversational, not a form.`,
928
+ `2. When they answer, immediately \`write_file({ path: "USER.md", content: ... })\` (relative path resolves to their workspace home) with what you learnt, plus a one-line ack like "saved that to your profile".`,
929
+ `3. If they explicitly decline, drop it for this run — don't re-ask the same session.`,
930
+ `On a populated USER.md: don't ask the intro questions again. Just keep it accurate during normal work — when a durable new fact surfaces, \`edit_file\` it in. Fix stale entries when contradicted. Don't announce these edits unless they're material.`,
931
+ `This rule wins over any "reply concisely" or "delegate first" guidance above — first-time profile capture is more valuable than a short hi.`,
932
+ ].join("\n");
933
+ }
934
+ /**
935
+ * Host-level Execution Bias block. Exported so the worker
936
+ * agent-loop path (which builds its own systemPrompt by
937
+ * concatenating SOUL + fragments + skills, bypassing
938
+ * defaultSystemPrompt) can include the same rules without copying
939
+ * the strings.
940
+ */
941
+ export function formatExecutionBiasBlock() {
942
+ return [
943
+ `## Execution Bias`,
944
+ `- Actionable request: act in this turn.`,
945
+ `- Non-final turn: use tools to advance, or ask for the one missing decision that blocks safe progress.`,
946
+ `- Continue until done or genuinely blocked; do not finish with a plan/promise when tools can move it forward.`,
947
+ `- Weak/empty tool result: vary query, path, command, or source before concluding.`,
948
+ `- Mutable facts need live checks: files, git, clocks, versions, services, processes, package state.`,
949
+ `- Final answer needs evidence: test/build/lint, screenshot, inspection, tool output, or a named blocker.`,
950
+ `- Longer work: brief progress update, then keep going; use background work or sub-agents when they fit.`,
951
+ ].join("\n");
952
+ }
953
+ // Per-file cap (in bytes). Files bigger than this get truncated
954
+ // with a head + tail snippet so the prompt stays bounded even
955
+ // when AGENTS.md / SOUL.md / MEMORY.md grow into multi-page docs.
956
+ const WORKSPACE_FILE_HEAD_BYTES = 4_000;
957
+ const WORKSPACE_FILE_TAIL_BYTES = 1_000;
958
+ const WORKSPACE_FILE_FULL_CAP_BYTES = 6_000;
959
+ /**
960
+ * Read a workspace file from `userHome`, returning its (possibly
961
+ * truncated) content or null when the file doesn't exist or is
962
+ * unreadable. We swallow read errors deliberately — missing files
963
+ * are the steady state and an unreadable file should never break
964
+ * prompt assembly.
965
+ */
966
+ function readWorkspaceFile(filePath) {
967
+ try {
968
+ if (!fs.existsSync(filePath))
969
+ return null;
970
+ const stat = fs.statSync(filePath);
971
+ if (!stat.isFile() || stat.size === 0)
972
+ return null;
973
+ if (stat.size <= WORKSPACE_FILE_FULL_CAP_BYTES) {
974
+ return fs.readFileSync(filePath, "utf8");
975
+ }
976
+ // Big file: head + tail.
977
+ const fd = fs.openSync(filePath, "r");
978
+ try {
979
+ const headBuf = Buffer.alloc(WORKSPACE_FILE_HEAD_BYTES);
980
+ fs.readSync(fd, headBuf, 0, headBuf.length, 0);
981
+ const tailBuf = Buffer.alloc(WORKSPACE_FILE_TAIL_BYTES);
982
+ fs.readSync(fd, tailBuf, 0, tailBuf.length, Math.max(0, stat.size - tailBuf.length));
983
+ const omitted = stat.size - headBuf.length - tailBuf.length;
984
+ return [
985
+ headBuf.toString("utf8"),
986
+ ``,
987
+ `[… ${omitted} bytes truncated …]`,
988
+ ``,
989
+ tailBuf.toString("utf8"),
990
+ ].join("\n");
991
+ }
992
+ finally {
993
+ fs.closeSync(fd);
994
+ }
995
+ }
996
+ catch {
997
+ return null;
998
+ }
999
+ }
1000
+ /**
1001
+ * Render a Workspace Context section from a list of files. Each
1002
+ * present file becomes a `### <label>` block so the agent can
1003
+ * attribute statements ("per `_tenant/AGENTS.md` the team
1004
+ * prefers X"). Returns an empty string when none of the files
1005
+ * exist on disk.
1006
+ */
1007
+ function renderContextBlock(specs) {
1008
+ const sections = [];
1009
+ for (const spec of specs) {
1010
+ const content = readWorkspaceFile(spec.absPath);
1011
+ if (content === null)
1012
+ continue;
1013
+ sections.push(`### ${spec.label}`, content.trimEnd());
1014
+ }
1015
+ if (sections.length === 0)
1016
+ return "";
1017
+ return [`## Workspace Context`, ``, ...sections].join("\n");
1018
+ }
1019
+ /**
1020
+ * Main-agent context: tenant-shared working files plus the
1021
+ * caller's per-user USER.md. SOUL / MEMORY / AGENTS live at the
1022
+ * tenant root because they're team-wide; USER.md is the only
1023
+ * per-user file because it captures preferences that don't
1024
+ * generalise.
1025
+ */
1026
+ export function formatMainAgentContextBlock(workspaceDir, userHome) {
1027
+ const tenantRoot = path.join(workspaceDir, "_tenant");
1028
+ return renderContextBlock([
1029
+ { absPath: path.join(tenantRoot, "AGENTS.md"), label: "_tenant/AGENTS.md" },
1030
+ { absPath: path.join(tenantRoot, "SOUL.md"), label: "_tenant/SOUL.md" },
1031
+ { absPath: path.join(tenantRoot, "MEMORY.md"), label: "_tenant/MEMORY.md" },
1032
+ { absPath: path.join(userHome, "USER.md"), label: "users/<self>/USER.md" },
1033
+ ]);
1034
+ }
1035
+ /**
1036
+ * Worker-agent context: the worker's own bundle (AGENTS.md /
1037
+ * MEMORY.md — SOUL.md is already injected upstream via
1038
+ * req.systemPrompt) plus the caller's USER.md. Workers don't
1039
+ * read the tenant-shared SOUL/AGENTS/MEMORY because each worker
1040
+ * has its own personality + own long-term notes scoped to its
1041
+ * specialisation.
1042
+ */
1043
+ export function formatWorkerAgentContextBlock(workspaceDir, userHome, workerSlug) {
1044
+ const bundleRoot = path.join(workspaceDir, "_tenant", "config", "workers", workerSlug);
1045
+ return renderContextBlock([
1046
+ {
1047
+ absPath: path.join(bundleRoot, "AGENTS.md"),
1048
+ label: `_tenant/config/workers/${workerSlug}/AGENTS.md`,
1049
+ },
1050
+ {
1051
+ absPath: path.join(bundleRoot, "MEMORY.md"),
1052
+ label: `_tenant/config/workers/${workerSlug}/MEMORY.md`,
1053
+ },
1054
+ { absPath: path.join(userHome, "USER.md"), label: "users/<self>/USER.md" },
1055
+ ]);
1056
+ }
1057
+ /**
1058
+ * Backwards-compatible thin wrapper. The previous shape pointed
1059
+ * to user home only; kept as an alias for tests / external
1060
+ * callers but new code should use formatMainAgentContextBlock.
1061
+ */
1062
+ export function formatWorkspaceContextBlock(userHome) {
1063
+ return renderContextBlock([
1064
+ { absPath: path.join(userHome, "AGENTS.md"), label: "AGENTS.md" },
1065
+ { absPath: path.join(userHome, "SOUL.md"), label: "SOUL.md" },
1066
+ { absPath: path.join(userHome, "USER.md"), label: "USER.md" },
1067
+ ]);
1068
+ }
1069
+ /**
1070
+ * Replace `<self>` and `<userId>` placeholders with the caller's
1071
+ * concrete userId throughout an assembled system prompt.
1072
+ *
1073
+ * Plugin manifests + tool descriptions write paths like
1074
+ * `/workspace/users/<self>/...` because the plugin author can't
1075
+ * know the runtime userId. Without substitution the LLM sees a
1076
+ * literal `<self>` and either invents a userId (we caught
1077
+ * `user1` / `user3` / `user_x` in production) or just guesses
1078
+ * wrong. Substituting at the very end of prompt assembly — after
1079
+ * SOUL, plugin fragments, context block, skills are all stitched
1080
+ * together — means every appearance of these placeholders
1081
+ * resolves to the right value, regardless of which layer wrote
1082
+ * it.
1083
+ *
1084
+ * Idempotent and safe to call on prompts that don't contain
1085
+ * either placeholder.
1086
+ */
1087
+ export function substituteUserIdPlaceholders(prompt, userId) {
1088
+ if (!userId)
1089
+ return prompt;
1090
+ return prompt
1091
+ .replace(/<self>/g, userId)
1092
+ .replace(/<userId>/g, userId);
1093
+ }
1094
+ /** Render plugin-contributed system-prompt fragments. Grouped by
1095
+ * plugin so the agent sees one section per plugin (workboard
1096
+ * rules in one block, microsandbox rules in another, etc), and
1097
+ * so debugging prompts is straightforward ("this guidance came
1098
+ * from plugin X"). Returns an empty string when no fragments
1099
+ * are contributed. */
1100
+ export function formatPluginPromptFragments(fragments) {
1101
+ if (fragments.length === 0)
1102
+ return "";
1103
+ const byPlugin = new Map();
1104
+ for (const f of fragments) {
1105
+ const slot = byPlugin.get(f.pluginId);
1106
+ if (slot) {
1107
+ slot.texts.push(f.text);
1108
+ }
1109
+ else {
1110
+ byPlugin.set(f.pluginId, {
1111
+ displayName: f.pluginDisplayName,
1112
+ texts: [f.text],
1113
+ });
1114
+ }
1115
+ }
1116
+ const lines = ["## Plugin guidance"];
1117
+ for (const [pid, slot] of byPlugin) {
1118
+ lines.push(``, `### ${slot.displayName} (${pid})`);
1119
+ for (const t of slot.texts) {
1120
+ lines.push(t.trim());
1121
+ }
1122
+ }
1123
+ return lines.join("\n");
1124
+ }
1125
+ /**
1126
+ * Render the `<available_skills>` block that's appended to every
1127
+ * system prompt — the host default prompt for the main chat agent,
1128
+ * AND any custom worker prompt coming from `worker_agents.system_prompt`.
1129
+ *
1130
+ * Worker LLMs need this just as badly as the main agent: without
1131
+ * it they only see plugin-shipped skills via `tenant_config_list`,
1132
+ * not their per-tenant ones. Workers ship a kind-specific
1133
+ * `system_prompt` in the worker_agents table, and the agent-loop
1134
+ * bypasses `defaultSystemPrompt` when that's set; so we expose the
1135
+ * skill block as a reusable helper and the loop appends it after
1136
+ * the kind-specific prompt.
1137
+ *
1138
+ * Returns "" when the skills list is empty so callers can drop the
1139
+ * block entirely (no leading blank lines, no half-empty XML).
1140
+ */
1141
+ export function formatAvailableSkillsBlock(skills) {
1142
+ if (skills.length === 0)
1143
+ return "";
1144
+ const lines = [
1145
+ `## Skills`,
1146
+ `Scan <available_skills>. If one clearly applies, read its SKILL.md at the exact <location> with \`tenant_config_read\`, then follow it. All skill locations are tenant-config:/// URIs — host / plugin skills are mirrored into the tenant config tree at boot, so one tool reads them all.`,
1147
+ `If several apply, choose the most specific. If none clearly apply, read none.`,
1148
+ `One skill up front max. Never guess/fabricate skill paths.`,
1149
+ `Skill bundles may ship sibling files (\`scripts/\`, \`references/\`, \`assets/\`) next to SKILL.md — those still go through the regular file tools (\`read_file\` for workspace paths, \`tenant_config_read\` for tenant-config paths) using the relative paths SKILL.md mentions.`,
1150
+ ``,
1151
+ `<available_skills>`,
1152
+ ];
1153
+ for (const skill of skills) {
1154
+ lines.push(` <skill>`, ` <name>${skill.name}</name>`, ` <description>${skill.description}</description>`, ` <location>${skillLocationUri(skill)}</location>`, ` </skill>`);
1155
+ }
1156
+ lines.push(`</available_skills>`);
1157
+ return lines.join("\n");
1158
+ }
1159
+ /** Build the location URI we expose to the agent for a skill.
1160
+ *
1161
+ * - Tenant skills (loaded via `loadTenantSkills`) get a
1162
+ * `tenant-config:///...` URI rooted at `_tenant/config/`.
1163
+ * - Host + plugin skills (read-only, shipped on disk under host
1164
+ * or plugin dirs) fall back to their absolute filePath — the
1165
+ * agent can't read them anyway through `tenant_config_read`,
1166
+ * but the URI gives it a stable identifier to mention.
1167
+ */
1168
+ function skillLocationUri(skill) {
1169
+ // Every skill that lives under a tenant config tree — user-
1170
+ // authored, plugin-mirrored, host-mirrored — emits a portable
1171
+ // `tenant-config:///<rest>` URI. The pluginId no longer
1172
+ // matters here; the mirror layer in the registry stamps
1173
+ // plugin/host skills with `_tenant/config/skills/_host/...`
1174
+ // filePaths just like user skills.
1175
+ const idx = skill.filePath.indexOf("_tenant/config/");
1176
+ if (idx >= 0) {
1177
+ const rel = skill.filePath
1178
+ .slice(idx + "_tenant/config/".length)
1179
+ .replace(/\\/g, "/");
1180
+ return `tenant-config:///${rel}`;
1181
+ }
1182
+ // Fall-through: a skill whose filePath isn't under _tenant/
1183
+ // config/. This shouldn't happen post-mirror; if it does, we'd
1184
+ // rather surface the absolute path than silently hide the
1185
+ // skill, so the agent can at least diagnose the gap.
1186
+ return skill.filePath;
1187
+ }
1188
+ /**
1189
+ * Load skills shipped with the host repo (under `<repoRoot>/skills/`).
1190
+ * These are surfaced to every tenant alongside plugin-contributed
1191
+ * skills. Any with `when:` predicates are filtered later by
1192
+ * `filterSkillsForTenant`.
1193
+ *
1194
+ * Result is cached per process — host skills are read-only at
1195
+ * runtime, no need to re-stat per request.
1196
+ */
1197
+ let hostSkillsCache = null;
1198
+ export function loadHostSkills() {
1199
+ if (hostSkillsCache)
1200
+ return hostSkillsCache;
1201
+ const here = path.dirname(fileURLToPath(import.meta.url));
1202
+ // dist/chat/handler.js → ../../../skills, source/chat/handler.ts
1203
+ // → ../../../skills. Either way, three levels up gets us to the
1204
+ // server package root, which contains a `skills/` dir at build
1205
+ // time. We override via TIANSHU_HOST_SKILLS_DIR for tests.
1206
+ const fromEnv = process.env.TIANSHU_HOST_SKILLS_DIR;
1207
+ const skillsDir = fromEnv
1208
+ ? path.resolve(fromEnv)
1209
+ : path.resolve(here, "..", "..", "skills");
1210
+ if (!fs.existsSync(skillsDir)) {
1211
+ hostSkillsCache = [];
1212
+ return hostSkillsCache;
1213
+ }
1214
+ // Treat host skills as if they came from a synthetic `tianshu`
1215
+ // plugin so log lines and plugin-id-derived names stay readable.
1216
+ const contributions = fs
1217
+ .readdirSync(skillsDir, { withFileTypes: true })
1218
+ .filter((d) => d.isFile() && d.name.endsWith(".md"))
1219
+ .map((d) => ({ id: d.name.replace(/\.md$/, ""), path: d.name }));
1220
+ const result = loadSkillsForPlugin({
1221
+ pluginId: "tianshu",
1222
+ pluginDir: skillsDir,
1223
+ contributions,
1224
+ });
1225
+ for (const f of result.failures) {
1226
+ // eslint-disable-next-line no-console
1227
+ console.warn(`[host-skills] ${f.source.contributionId} (${f.filePath}): ${f.reason}`);
1228
+ }
1229
+ hostSkillsCache = result.skills;
1230
+ return hostSkillsCache;
1231
+ }
1232
+ function emptyHostCapabilities() {
1233
+ return {
1234
+ get: () => undefined,
1235
+ has: () => false,
1236
+ };
1237
+ }
1238
+ function makeLogger(tenantId, userId, _send) {
1239
+ // Tools log to the server console for now; future PR can route
1240
+ // structured tool logs to the chat UI as separate events.
1241
+ const prefix = `[tenant:${tenantId}][user:${userId}][tool]`;
1242
+ return {
1243
+ info: (msg, meta) => console.log(`${prefix} ${msg}`, meta ?? ""),
1244
+ warn: (msg, meta) => console.warn(`${prefix} ${msg}`, meta ?? ""),
1245
+ error: (msg, meta) => console.error(`${prefix} ${msg}`, meta ?? ""),
1246
+ };
1247
+ }
1248
+ //# sourceMappingURL=handler.js.map