@tt-a1i/hive 0.6.0-alpha.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 (326) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/LICENSE +202 -0
  3. package/README.md +175 -0
  4. package/SECURITY.md +48 -0
  5. package/dist/bin/team +7 -0
  6. package/dist/bin/team.cmd +2 -0
  7. package/dist/src/cli/hive.d.ts +9 -0
  8. package/dist/src/cli/hive.js +104 -0
  9. package/dist/src/cli/hive.js.map +1 -0
  10. package/dist/src/cli/team.d.ts +1 -0
  11. package/dist/src/cli/team.js +137 -0
  12. package/dist/src/cli/team.js.map +1 -0
  13. package/dist/src/server/agent-command-resolver.d.ts +8 -0
  14. package/dist/src/server/agent-command-resolver.js +72 -0
  15. package/dist/src/server/agent-command-resolver.js.map +1 -0
  16. package/dist/src/server/agent-launch-cache.d.ts +20 -0
  17. package/dist/src/server/agent-launch-cache.js +55 -0
  18. package/dist/src/server/agent-launch-cache.js.map +1 -0
  19. package/dist/src/server/agent-manager-support.d.ts +7 -0
  20. package/dist/src/server/agent-manager-support.js +68 -0
  21. package/dist/src/server/agent-manager-support.js.map +1 -0
  22. package/dist/src/server/agent-manager.d.ts +51 -0
  23. package/dist/src/server/agent-manager.js +92 -0
  24. package/dist/src/server/agent-manager.js.map +1 -0
  25. package/dist/src/server/agent-run-bootstrap.d.ts +62 -0
  26. package/dist/src/server/agent-run-bootstrap.js +64 -0
  27. package/dist/src/server/agent-run-bootstrap.js.map +1 -0
  28. package/dist/src/server/agent-run-exit-handler.d.ts +8 -0
  29. package/dist/src/server/agent-run-exit-handler.js +27 -0
  30. package/dist/src/server/agent-run-exit-handler.js.map +1 -0
  31. package/dist/src/server/agent-run-start-context.d.ts +24 -0
  32. package/dist/src/server/agent-run-start-context.js +2 -0
  33. package/dist/src/server/agent-run-start-context.js.map +1 -0
  34. package/dist/src/server/agent-run-starter.d.ts +23 -0
  35. package/dist/src/server/agent-run-starter.js +117 -0
  36. package/dist/src/server/agent-run-starter.js.map +1 -0
  37. package/dist/src/server/agent-run-store.d.ts +47 -0
  38. package/dist/src/server/agent-run-store.js +131 -0
  39. package/dist/src/server/agent-run-store.js.map +1 -0
  40. package/dist/src/server/agent-run-sync.d.ts +10 -0
  41. package/dist/src/server/agent-run-sync.js +25 -0
  42. package/dist/src/server/agent-run-sync.js.map +1 -0
  43. package/dist/src/server/agent-runtime-active-run.d.ts +3 -0
  44. package/dist/src/server/agent-runtime-active-run.js +11 -0
  45. package/dist/src/server/agent-runtime-active-run.js.map +1 -0
  46. package/dist/src/server/agent-runtime-close.d.ts +4 -0
  47. package/dist/src/server/agent-runtime-close.js +15 -0
  48. package/dist/src/server/agent-runtime-close.js.map +1 -0
  49. package/dist/src/server/agent-runtime-contract.d.ts +31 -0
  50. package/dist/src/server/agent-runtime-contract.js +2 -0
  51. package/dist/src/server/agent-runtime-contract.js.map +1 -0
  52. package/dist/src/server/agent-runtime-flow-adapter.d.ts +10 -0
  53. package/dist/src/server/agent-runtime-flow-adapter.js +15 -0
  54. package/dist/src/server/agent-runtime-flow-adapter.js.map +1 -0
  55. package/dist/src/server/agent-runtime-list-runs.d.ts +3 -0
  56. package/dist/src/server/agent-runtime-list-runs.js +19 -0
  57. package/dist/src/server/agent-runtime-list-runs.js.map +1 -0
  58. package/dist/src/server/agent-runtime-ports.d.ts +22 -0
  59. package/dist/src/server/agent-runtime-ports.js +2 -0
  60. package/dist/src/server/agent-runtime-ports.js.map +1 -0
  61. package/dist/src/server/agent-runtime-stop-run.d.ts +4 -0
  62. package/dist/src/server/agent-runtime-stop-run.js +17 -0
  63. package/dist/src/server/agent-runtime-stop-run.js.map +1 -0
  64. package/dist/src/server/agent-runtime-types.d.ts +4 -0
  65. package/dist/src/server/agent-runtime-types.js +2 -0
  66. package/dist/src/server/agent-runtime-types.js.map +1 -0
  67. package/dist/src/server/agent-runtime.d.ts +8 -0
  68. package/dist/src/server/agent-runtime.js +101 -0
  69. package/dist/src/server/agent-runtime.js.map +1 -0
  70. package/dist/src/server/agent-session-store.d.ts +7 -0
  71. package/dist/src/server/agent-session-store.js +52 -0
  72. package/dist/src/server/agent-session-store.js.map +1 -0
  73. package/dist/src/server/agent-startup-instructions.d.ts +13 -0
  74. package/dist/src/server/agent-startup-instructions.js +26 -0
  75. package/dist/src/server/agent-startup-instructions.js.map +1 -0
  76. package/dist/src/server/agent-stdin-dispatcher.d.ts +19 -0
  77. package/dist/src/server/agent-stdin-dispatcher.js +60 -0
  78. package/dist/src/server/agent-stdin-dispatcher.js.map +1 -0
  79. package/dist/src/server/agent-tokens.d.ts +15 -0
  80. package/dist/src/server/agent-tokens.js +26 -0
  81. package/dist/src/server/agent-tokens.js.map +1 -0
  82. package/dist/src/server/app-state-store.d.ts +10 -0
  83. package/dist/src/server/app-state-store.js +15 -0
  84. package/dist/src/server/app-state-store.js.map +1 -0
  85. package/dist/src/server/app.d.ts +14 -0
  86. package/dist/src/server/app.js +118 -0
  87. package/dist/src/server/app.js.map +1 -0
  88. package/dist/src/server/claude-command-defaults.d.ts +1 -0
  89. package/dist/src/server/claude-command-defaults.js +6 -0
  90. package/dist/src/server/claude-command-defaults.js.map +1 -0
  91. package/dist/src/server/claude-session-coordinator.d.ts +10 -0
  92. package/dist/src/server/claude-session-coordinator.js +69 -0
  93. package/dist/src/server/claude-session-coordinator.js.map +1 -0
  94. package/dist/src/server/claude-session-support.d.ts +1 -0
  95. package/dist/src/server/claude-session-support.js +2 -0
  96. package/dist/src/server/claude-session-support.js.map +1 -0
  97. package/dist/src/server/command-preset-defaults.d.ts +11 -0
  98. package/dist/src/server/command-preset-defaults.js +52 -0
  99. package/dist/src/server/command-preset-defaults.js.map +1 -0
  100. package/dist/src/server/command-preset-store.d.ts +49 -0
  101. package/dist/src/server/command-preset-store.js +90 -0
  102. package/dist/src/server/command-preset-store.js.map +1 -0
  103. package/dist/src/server/dispatch-ledger-serializer.d.ts +15 -0
  104. package/dist/src/server/dispatch-ledger-serializer.js +15 -0
  105. package/dist/src/server/dispatch-ledger-serializer.js.map +1 -0
  106. package/dist/src/server/dispatch-ledger-store.d.ts +45 -0
  107. package/dist/src/server/dispatch-ledger-store.js +196 -0
  108. package/dist/src/server/dispatch-ledger-store.js.map +1 -0
  109. package/dist/src/server/env-sync-message.d.ts +9 -0
  110. package/dist/src/server/env-sync-message.js +30 -0
  111. package/dist/src/server/env-sync-message.js.map +1 -0
  112. package/dist/src/server/fs-browse.d.ts +25 -0
  113. package/dist/src/server/fs-browse.js +130 -0
  114. package/dist/src/server/fs-browse.js.map +1 -0
  115. package/dist/src/server/fs-pick-folder.d.ts +25 -0
  116. package/dist/src/server/fs-pick-folder.js +132 -0
  117. package/dist/src/server/fs-pick-folder.js.map +1 -0
  118. package/dist/src/server/fs-sandbox.d.ts +13 -0
  119. package/dist/src/server/fs-sandbox.js +26 -0
  120. package/dist/src/server/fs-sandbox.js.map +1 -0
  121. package/dist/src/server/hive-team-guidance.d.ts +2 -0
  122. package/dist/src/server/hive-team-guidance.js +14 -0
  123. package/dist/src/server/hive-team-guidance.js.map +1 -0
  124. package/dist/src/server/http-errors.d.ts +16 -0
  125. package/dist/src/server/http-errors.js +33 -0
  126. package/dist/src/server/http-errors.js.map +1 -0
  127. package/dist/src/server/live-run-registry.d.ts +21 -0
  128. package/dist/src/server/live-run-registry.js +53 -0
  129. package/dist/src/server/live-run-registry.js.map +1 -0
  130. package/dist/src/server/message-log-store.d.ts +48 -0
  131. package/dist/src/server/message-log-store.js +144 -0
  132. package/dist/src/server/message-log-store.js.map +1 -0
  133. package/dist/src/server/orchestrator-autostart.d.ts +30 -0
  134. package/dist/src/server/orchestrator-autostart.js +103 -0
  135. package/dist/src/server/orchestrator-autostart.js.map +1 -0
  136. package/dist/src/server/orchestrator-launch.d.ts +22 -0
  137. package/dist/src/server/orchestrator-launch.js +75 -0
  138. package/dist/src/server/orchestrator-launch.js.map +1 -0
  139. package/dist/src/server/post-start-input-writer.d.ts +6 -0
  140. package/dist/src/server/post-start-input-writer.js +118 -0
  141. package/dist/src/server/post-start-input-writer.js.map +1 -0
  142. package/dist/src/server/preset-launch-support.d.ts +6 -0
  143. package/dist/src/server/preset-launch-support.js +67 -0
  144. package/dist/src/server/preset-launch-support.js.map +1 -0
  145. package/dist/src/server/pty-output-bus.d.ts +8 -0
  146. package/dist/src/server/pty-output-bus.js +33 -0
  147. package/dist/src/server/pty-output-bus.js.map +1 -0
  148. package/dist/src/server/recovery-summary.d.ts +10 -0
  149. package/dist/src/server/recovery-summary.js +89 -0
  150. package/dist/src/server/recovery-summary.js.map +1 -0
  151. package/dist/src/server/restart-policy-support.d.ts +23 -0
  152. package/dist/src/server/restart-policy-support.js +12 -0
  153. package/dist/src/server/restart-policy-support.js.map +1 -0
  154. package/dist/src/server/restart-policy.d.ts +14 -0
  155. package/dist/src/server/restart-policy.js +42 -0
  156. package/dist/src/server/restart-policy.js.map +1 -0
  157. package/dist/src/server/role-template-store.d.ts +44 -0
  158. package/dist/src/server/role-template-store.js +71 -0
  159. package/dist/src/server/role-template-store.js.map +1 -0
  160. package/dist/src/server/role-templates.d.ts +7 -0
  161. package/dist/src/server/role-templates.js +55 -0
  162. package/dist/src/server/role-templates.js.map +1 -0
  163. package/dist/src/server/route-helpers.d.ts +7 -0
  164. package/dist/src/server/route-helpers.js +48 -0
  165. package/dist/src/server/route-helpers.js.map +1 -0
  166. package/dist/src/server/route-types.d.ts +58 -0
  167. package/dist/src/server/route-types.js +2 -0
  168. package/dist/src/server/route-types.js.map +1 -0
  169. package/dist/src/server/routes-dispatches.d.ts +2 -0
  170. package/dist/src/server/routes-dispatches.js +53 -0
  171. package/dist/src/server/routes-dispatches.js.map +1 -0
  172. package/dist/src/server/routes-fs.d.ts +2 -0
  173. package/dist/src/server/routes-fs.js +25 -0
  174. package/dist/src/server/routes-fs.js.map +1 -0
  175. package/dist/src/server/routes-runtime.d.ts +2 -0
  176. package/dist/src/server/routes-runtime.js +46 -0
  177. package/dist/src/server/routes-runtime.js.map +1 -0
  178. package/dist/src/server/routes-settings.d.ts +2 -0
  179. package/dist/src/server/routes-settings.js +124 -0
  180. package/dist/src/server/routes-settings.js.map +1 -0
  181. package/dist/src/server/routes-tasks.d.ts +2 -0
  182. package/dist/src/server/routes-tasks.js +25 -0
  183. package/dist/src/server/routes-tasks.js.map +1 -0
  184. package/dist/src/server/routes-team.d.ts +2 -0
  185. package/dist/src/server/routes-team.js +50 -0
  186. package/dist/src/server/routes-team.js.map +1 -0
  187. package/dist/src/server/routes-ui.d.ts +2 -0
  188. package/dist/src/server/routes-ui.js +8 -0
  189. package/dist/src/server/routes-ui.js.map +1 -0
  190. package/dist/src/server/routes-workspaces.d.ts +2 -0
  191. package/dist/src/server/routes-workspaces.js +154 -0
  192. package/dist/src/server/routes-workspaces.js.map +1 -0
  193. package/dist/src/server/routes.d.ts +6 -0
  194. package/dist/src/server/routes.js +36 -0
  195. package/dist/src/server/routes.js.map +1 -0
  196. package/dist/src/server/runtime-database.d.ts +2 -0
  197. package/dist/src/server/runtime-database.js +13 -0
  198. package/dist/src/server/runtime-database.js.map +1 -0
  199. package/dist/src/server/runtime-message-builders.d.ts +6 -0
  200. package/dist/src/server/runtime-message-builders.js +52 -0
  201. package/dist/src/server/runtime-message-builders.js.map +1 -0
  202. package/dist/src/server/runtime-restart-policy.d.ts +14 -0
  203. package/dist/src/server/runtime-restart-policy.js +11 -0
  204. package/dist/src/server/runtime-restart-policy.js.map +1 -0
  205. package/dist/src/server/runtime-store-helpers.d.ts +71 -0
  206. package/dist/src/server/runtime-store-helpers.js +174 -0
  207. package/dist/src/server/runtime-store-helpers.js.map +1 -0
  208. package/dist/src/server/runtime-store.d.ts +70 -0
  209. package/dist/src/server/runtime-store.js +82 -0
  210. package/dist/src/server/runtime-store.js.map +1 -0
  211. package/dist/src/server/session-capture-claude.d.ts +11 -0
  212. package/dist/src/server/session-capture-claude.js +78 -0
  213. package/dist/src/server/session-capture-claude.js.map +1 -0
  214. package/dist/src/server/session-capture-codex.d.ts +5 -0
  215. package/dist/src/server/session-capture-codex.js +72 -0
  216. package/dist/src/server/session-capture-codex.js.map +1 -0
  217. package/dist/src/server/session-capture-gemini.d.ts +5 -0
  218. package/dist/src/server/session-capture-gemini.js +80 -0
  219. package/dist/src/server/session-capture-gemini.js.map +1 -0
  220. package/dist/src/server/session-capture-opencode.d.ts +4 -0
  221. package/dist/src/server/session-capture-opencode.js +43 -0
  222. package/dist/src/server/session-capture-opencode.js.map +1 -0
  223. package/dist/src/server/session-capture.d.ts +71 -0
  224. package/dist/src/server/session-capture.js +92 -0
  225. package/dist/src/server/session-capture.js.map +1 -0
  226. package/dist/src/server/settings-store.d.ts +19 -0
  227. package/dist/src/server/settings-store.js +22 -0
  228. package/dist/src/server/settings-store.js.map +1 -0
  229. package/dist/src/server/sqlite-schema-v10.d.ts +2 -0
  230. package/dist/src/server/sqlite-schema-v10.js +14 -0
  231. package/dist/src/server/sqlite-schema-v10.js.map +1 -0
  232. package/dist/src/server/sqlite-schema-v11.d.ts +2 -0
  233. package/dist/src/server/sqlite-schema-v11.js +11 -0
  234. package/dist/src/server/sqlite-schema-v11.js.map +1 -0
  235. package/dist/src/server/sqlite-schema-v12.d.ts +2 -0
  236. package/dist/src/server/sqlite-schema-v12.js +22 -0
  237. package/dist/src/server/sqlite-schema-v12.js.map +1 -0
  238. package/dist/src/server/sqlite-schema-v13.d.ts +2 -0
  239. package/dist/src/server/sqlite-schema-v13.js +5 -0
  240. package/dist/src/server/sqlite-schema-v13.js.map +1 -0
  241. package/dist/src/server/sqlite-schema-v14.d.ts +2 -0
  242. package/dist/src/server/sqlite-schema-v14.js +85 -0
  243. package/dist/src/server/sqlite-schema-v14.js.map +1 -0
  244. package/dist/src/server/sqlite-schema-v5.d.ts +2 -0
  245. package/dist/src/server/sqlite-schema-v5.js +62 -0
  246. package/dist/src/server/sqlite-schema-v5.js.map +1 -0
  247. package/dist/src/server/sqlite-schema-v7.d.ts +2 -0
  248. package/dist/src/server/sqlite-schema-v7.js +71 -0
  249. package/dist/src/server/sqlite-schema-v7.js.map +1 -0
  250. package/dist/src/server/sqlite-schema-v8.d.ts +2 -0
  251. package/dist/src/server/sqlite-schema-v8.js +7 -0
  252. package/dist/src/server/sqlite-schema-v8.js.map +1 -0
  253. package/dist/src/server/sqlite-schema-v9.d.ts +2 -0
  254. package/dist/src/server/sqlite-schema-v9.js +7 -0
  255. package/dist/src/server/sqlite-schema-v9.js.map +1 -0
  256. package/dist/src/server/sqlite-schema.d.ts +3 -0
  257. package/dist/src/server/sqlite-schema.js +185 -0
  258. package/dist/src/server/sqlite-schema.js.map +1 -0
  259. package/dist/src/server/system-message.d.ts +1 -0
  260. package/dist/src/server/system-message.js +2 -0
  261. package/dist/src/server/system-message.js.map +1 -0
  262. package/dist/src/server/tasks-file-watcher.d.ts +8 -0
  263. package/dist/src/server/tasks-file-watcher.js +60 -0
  264. package/dist/src/server/tasks-file-watcher.js.map +1 -0
  265. package/dist/src/server/tasks-file.d.ts +11 -0
  266. package/dist/src/server/tasks-file.js +33 -0
  267. package/dist/src/server/tasks-file.js.map +1 -0
  268. package/dist/src/server/tasks-websocket-server.d.ts +7 -0
  269. package/dist/src/server/tasks-websocket-server.js +72 -0
  270. package/dist/src/server/tasks-websocket-server.js.map +1 -0
  271. package/dist/src/server/team-authz.d.ts +13 -0
  272. package/dist/src/server/team-authz.js +33 -0
  273. package/dist/src/server/team-authz.js.map +1 -0
  274. package/dist/src/server/team-list-serializer.d.ts +8 -0
  275. package/dist/src/server/team-list-serializer.js +8 -0
  276. package/dist/src/server/team-list-serializer.js.map +1 -0
  277. package/dist/src/server/team-operations.d.ts +41 -0
  278. package/dist/src/server/team-operations.js +105 -0
  279. package/dist/src/server/team-operations.js.map +1 -0
  280. package/dist/src/server/terminal-flow-control.d.ts +19 -0
  281. package/dist/src/server/terminal-flow-control.js +117 -0
  282. package/dist/src/server/terminal-flow-control.js.map +1 -0
  283. package/dist/src/server/terminal-protocol.d.ts +29 -0
  284. package/dist/src/server/terminal-protocol.js +42 -0
  285. package/dist/src/server/terminal-protocol.js.map +1 -0
  286. package/dist/src/server/terminal-state-mirror.d.ts +15 -0
  287. package/dist/src/server/terminal-state-mirror.js +47 -0
  288. package/dist/src/server/terminal-state-mirror.js.map +1 -0
  289. package/dist/src/server/terminal-stream-hub.d.ts +9 -0
  290. package/dist/src/server/terminal-stream-hub.js +179 -0
  291. package/dist/src/server/terminal-stream-hub.js.map +1 -0
  292. package/dist/src/server/terminal-ws-server.d.ts +5 -0
  293. package/dist/src/server/terminal-ws-server.js +85 -0
  294. package/dist/src/server/terminal-ws-server.js.map +1 -0
  295. package/dist/src/server/ui-auth-helpers.d.ts +4 -0
  296. package/dist/src/server/ui-auth-helpers.js +23 -0
  297. package/dist/src/server/ui-auth-helpers.js.map +1 -0
  298. package/dist/src/server/ui-auth.d.ts +5 -0
  299. package/dist/src/server/ui-auth.js +13 -0
  300. package/dist/src/server/ui-auth.js.map +1 -0
  301. package/dist/src/server/workspace-store-contract.d.ts +28 -0
  302. package/dist/src/server/workspace-store-contract.js +2 -0
  303. package/dist/src/server/workspace-store-contract.js.map +1 -0
  304. package/dist/src/server/workspace-store-hydration.d.ts +5 -0
  305. package/dist/src/server/workspace-store-hydration.js +64 -0
  306. package/dist/src/server/workspace-store-hydration.js.map +1 -0
  307. package/dist/src/server/workspace-store-mutations.d.ts +13 -0
  308. package/dist/src/server/workspace-store-mutations.js +49 -0
  309. package/dist/src/server/workspace-store-mutations.js.map +1 -0
  310. package/dist/src/server/workspace-store-support.d.ts +29 -0
  311. package/dist/src/server/workspace-store-support.js +25 -0
  312. package/dist/src/server/workspace-store-support.js.map +1 -0
  313. package/dist/src/server/workspace-store.d.ts +5 -0
  314. package/dist/src/server/workspace-store.js +114 -0
  315. package/dist/src/server/workspace-store.js.map +1 -0
  316. package/dist/src/shared/types.d.ts +36 -0
  317. package/dist/src/shared/types.js +2 -0
  318. package/dist/src/shared/types.js.map +1 -0
  319. package/package.json +108 -0
  320. package/scripts/fix-runtime-artifacts.mjs +33 -0
  321. package/web/dist/assets/addon-fit-DX4qG4td.js +1 -0
  322. package/web/dist/assets/index-CjlaoOoA.css +1 -0
  323. package/web/dist/assets/index-CwdRvXrs.js +63 -0
  324. package/web/dist/assets/xterm-B-qIQCd3.js +16 -0
  325. package/web/dist/favicon.svg +58 -0
  326. package/web/dist/index.html +22 -0
@@ -0,0 +1,196 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ const parseArtifacts = (value) => {
3
+ if (!value)
4
+ return [];
5
+ try {
6
+ const parsed = JSON.parse(value);
7
+ return Array.isArray(parsed)
8
+ ? parsed.filter((artifact) => typeof artifact === 'string')
9
+ : [];
10
+ }
11
+ catch {
12
+ return [];
13
+ }
14
+ };
15
+ const toRecord = (row) => ({
16
+ artifacts: parseArtifacts(row.artifacts),
17
+ createdAt: row.created_at,
18
+ deliveredAt: row.delivered_at,
19
+ fromAgentId: row.from_agent_id,
20
+ id: row.id,
21
+ reportedAt: row.reported_at,
22
+ reportText: row.report_text,
23
+ sequence: row.sequence,
24
+ status: row.status,
25
+ submittedAt: row.submitted_at,
26
+ text: row.text,
27
+ toAgentId: row.to_agent_id,
28
+ workspaceId: row.workspace_id,
29
+ });
30
+ export const createDispatchLedgerStore = (db) => {
31
+ const memoryDispatches = new Map();
32
+ const createDispatch = (input) => {
33
+ const record = {
34
+ artifacts: [],
35
+ createdAt: Date.now(),
36
+ deliveredAt: null,
37
+ fromAgentId: input.fromAgentId ?? null,
38
+ id: randomUUID(),
39
+ reportedAt: null,
40
+ reportText: null,
41
+ sequence: null,
42
+ status: 'queued',
43
+ submittedAt: null,
44
+ text: input.text,
45
+ toAgentId: input.toAgentId,
46
+ workspaceId: input.workspaceId,
47
+ };
48
+ if (!db) {
49
+ record.sequence = memoryDispatches.size + 1;
50
+ memoryDispatches.set(record.id, record);
51
+ return record;
52
+ }
53
+ db.prepare(`INSERT INTO dispatches (
54
+ id,
55
+ workspace_id,
56
+ from_agent_id,
57
+ to_agent_id,
58
+ text,
59
+ status,
60
+ created_at,
61
+ delivered_at,
62
+ submitted_at,
63
+ reported_at,
64
+ report_text,
65
+ artifacts
66
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(record.id, record.workspaceId, record.fromAgentId, record.toAgentId, record.text, record.status, record.createdAt, record.deliveredAt, record.submittedAt, record.reportedAt, record.reportText, JSON.stringify(record.artifacts));
67
+ return record;
68
+ };
69
+ const deleteDispatch = (dispatchId) => {
70
+ if (!db) {
71
+ memoryDispatches.delete(dispatchId);
72
+ return;
73
+ }
74
+ db.prepare('DELETE FROM dispatches WHERE id = ?').run(dispatchId);
75
+ };
76
+ const markSubmitted = (dispatchId) => {
77
+ const submittedAt = Date.now();
78
+ if (!db) {
79
+ const record = memoryDispatches.get(dispatchId);
80
+ if (record) {
81
+ record.status = 'submitted';
82
+ record.submittedAt = submittedAt;
83
+ }
84
+ return;
85
+ }
86
+ db.prepare(`UPDATE dispatches
87
+ SET status = ?, submitted_at = ?
88
+ WHERE id = ?`).run('submitted', submittedAt, dispatchId);
89
+ };
90
+ const findOpenDispatch = (workspaceId, toAgentId) => {
91
+ if (!db) {
92
+ return Array.from(memoryDispatches.values())
93
+ .filter((record) => record.workspaceId === workspaceId &&
94
+ record.toAgentId === toAgentId &&
95
+ record.status !== 'reported')
96
+ .sort((a, b) => (a.sequence ?? a.createdAt) - (b.sequence ?? b.createdAt))[0];
97
+ }
98
+ const row = db
99
+ .prepare(`SELECT *
100
+ FROM dispatches
101
+ WHERE workspace_id = ?
102
+ AND to_agent_id = ?
103
+ AND status != 'reported'
104
+ ORDER BY sequence ASC
105
+ LIMIT 1`)
106
+ .get(workspaceId, toAgentId);
107
+ return row ? toRecord(row) : undefined;
108
+ };
109
+ const markReportedByWorker = (input) => {
110
+ const dispatch = findOpenDispatch(input.workspaceId, input.toAgentId);
111
+ if (!dispatch) {
112
+ return undefined;
113
+ }
114
+ const reportedAt = Date.now();
115
+ if (!db) {
116
+ dispatch.status = 'reported';
117
+ dispatch.reportedAt = reportedAt;
118
+ dispatch.reportText = input.reportText;
119
+ dispatch.artifacts = input.artifacts;
120
+ return dispatch;
121
+ }
122
+ db.prepare(`UPDATE dispatches
123
+ SET status = ?,
124
+ reported_at = ?,
125
+ report_text = ?,
126
+ artifacts = ?
127
+ WHERE id = ?`).run('reported', reportedAt, input.reportText, JSON.stringify(input.artifacts), dispatch.id);
128
+ return {
129
+ ...dispatch,
130
+ artifacts: input.artifacts,
131
+ reportedAt,
132
+ reportText: input.reportText,
133
+ status: 'reported',
134
+ };
135
+ };
136
+ const listWorkspaceDispatches = (workspaceId, options = {}) => {
137
+ const offset = options.offset ?? 0;
138
+ const limit = options.limit ?? 100;
139
+ if (!db) {
140
+ return Array.from(memoryDispatches.values())
141
+ .filter((record) => record.workspaceId === workspaceId &&
142
+ (options.status === undefined || record.status === options.status))
143
+ .sort((a, b) => (a.sequence ?? a.createdAt) - (b.sequence ?? b.createdAt))
144
+ .slice(offset, offset + limit);
145
+ }
146
+ if (options.status) {
147
+ return db
148
+ .prepare(`SELECT *
149
+ FROM dispatches
150
+ WHERE workspace_id = ?
151
+ AND status = ?
152
+ ORDER BY sequence ASC
153
+ LIMIT ? OFFSET ?`)
154
+ .all(workspaceId, options.status, limit, offset).map(toRecord);
155
+ }
156
+ return db
157
+ .prepare(`SELECT *
158
+ FROM dispatches
159
+ WHERE workspace_id = ?
160
+ ORDER BY sequence ASC
161
+ LIMIT ? OFFSET ?`)
162
+ .all(workspaceId, limit, offset).map(toRecord);
163
+ };
164
+ const deleteWorkspaceDispatches = (workspaceId) => {
165
+ if (!db) {
166
+ for (const [id, record] of memoryDispatches) {
167
+ if (record.workspaceId === workspaceId)
168
+ memoryDispatches.delete(id);
169
+ }
170
+ return;
171
+ }
172
+ db.prepare('DELETE FROM dispatches WHERE workspace_id = ?').run(workspaceId);
173
+ };
174
+ const deleteWorkerDispatches = (workspaceId, workerId) => {
175
+ if (!db) {
176
+ for (const [id, record] of memoryDispatches) {
177
+ if (record.workspaceId === workspaceId && record.toAgentId === workerId) {
178
+ memoryDispatches.delete(id);
179
+ }
180
+ }
181
+ return;
182
+ }
183
+ db.prepare('DELETE FROM dispatches WHERE workspace_id = ? AND to_agent_id = ?').run(workspaceId, workerId);
184
+ };
185
+ return {
186
+ createDispatch,
187
+ deleteDispatch,
188
+ deleteWorkerDispatches,
189
+ deleteWorkspaceDispatches,
190
+ findOpenDispatch,
191
+ listWorkspaceDispatches,
192
+ markReportedByWorker,
193
+ markSubmitted,
194
+ };
195
+ };
196
+ //# sourceMappingURL=dispatch-ledger-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatch-ledger-store.js","sourceRoot":"","sources":["../../../src/server/dispatch-ledger-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { AgentSummary, WorkspaceSummary } from '../shared/types.js';
2
+ import type { RecoveryMessage } from './message-log-store.js';
3
+ export declare const buildEnvSyncMessage: ({ agent, tasksContent, workers, workspace, restartWindowMessages, }: {
4
+ agent: AgentSummary;
5
+ tasksContent: string;
6
+ workers: AgentSummary[];
7
+ workspace: WorkspaceSummary;
8
+ restartWindowMessages: RecoveryMessage[];
9
+ }) => string;
@@ -0,0 +1,30 @@
1
+ import { getHiveTeamRules } from './hive-team-guidance.js';
2
+ import { wrapSystemMessage } from './system-message.js';
3
+ import { TASKS_RELATIVE_PATH } from './tasks-file.js';
4
+ const TASKS_HEAD_LIMIT = 1024;
5
+ const formatWorkers = (workers) => {
6
+ if (workers.length === 0)
7
+ return ['- 当前没有其他 worker'];
8
+ return workers.map((worker) => `- ${worker.name} (${worker.role}, ${worker.status}, pending_task_count: ${worker.pendingTaskCount})`);
9
+ };
10
+ const formatRestartWindow = (messages) => {
11
+ const sends = messages.filter((message) => {
12
+ return message.type === 'send';
13
+ });
14
+ if (sends.length === 0)
15
+ return ['- 重启期间未派新单'];
16
+ return sends.slice(-5).map((message) => `- send -> ${message.to}: ${message.text}`);
17
+ };
18
+ export const buildEnvSyncMessage = ({ agent, tasksContent, workers, workspace, restartWindowMessages, }) => wrapSystemMessage([
19
+ '你刚被 Hive 重启了。期间环境变化:',
20
+ `- 当前 workspace: ${workspace.name}`,
21
+ '- 现有 worker:',
22
+ ...formatWorkers(workers),
23
+ `- ${TASKS_RELATIVE_PATH} 当前内容:`,
24
+ tasksContent.slice(0, TASKS_HEAD_LIMIT) || '(空)',
25
+ ...formatRestartWindow(restartWindowMessages),
26
+ agent.role === 'orchestrator' ? '- Hive worker 派单规则:' : '- Hive worker 边界:',
27
+ ...getHiveTeamRules(agent).map((rule) => ` - ${rule}`),
28
+ `请继续。如果不确定,用 team list / Read ${TASKS_RELATIVE_PATH} 自查或问 user。`,
29
+ ].join('\n'));
30
+ //# sourceMappingURL=env-sync-message.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-sync-message.js","sourceRoot":"","sources":["../../../src/server/env-sync-message.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAE1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAErD,MAAM,gBAAgB,GAAG,IAAI,CAAA;AAE7B,MAAM,aAAa,GAAG,CAAC,OAAuB,EAAE,EAAE;IAChD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,iBAAiB,CAAC,CAAA;IACpD,OAAO,OAAO,CAAC,GAAG,CAChB,CAAC,MAAM,EAAE,EAAE,CACT,KAAK,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,MAAM,yBAAyB,MAAM,CAAC,gBAAgB,GAAG,CACxG,CAAA;AACH,CAAC,CAAA;AAED,MAAM,mBAAmB,GAAG,CAAC,QAA2B,EAAE,EAAE;IAC1D,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAC3B,CAAC,OAAO,EAAyD,EAAE;QACjE,OAAO,OAAO,CAAC,IAAI,KAAK,MAAM,CAAA;IAChC,CAAC,CACF,CAAA;IACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,YAAY,CAAC,CAAA;IAC7C,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,aAAa,OAAO,CAAC,EAAE,KAAK,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;AACrF,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,EAClC,KAAK,EACL,YAAY,EACZ,OAAO,EACP,SAAS,EACT,qBAAqB,GAOtB,EAAE,EAAE,CACH,iBAAiB,CACf;IACE,sBAAsB;IACtB,mBAAmB,SAAS,CAAC,IAAI,EAAE;IACnC,cAAc;IACd,GAAG,aAAa,CAAC,OAAO,CAAC;IACzB,KAAK,mBAAmB,QAAQ;IAChC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,CAAC,IAAI,KAAK;IAChD,GAAG,mBAAmB,CAAC,qBAAqB,CAAC;IAC7C,KAAK,CAAC,IAAI,KAAK,cAAc,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,mBAAmB;IAC3E,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC;IACvD,gCAAgC,mBAAmB,aAAa;CACjE,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAA"}
@@ -0,0 +1,25 @@
1
+ export interface FsBrowseEntry {
2
+ is_dir: true;
3
+ is_git_repository: boolean;
4
+ name: string;
5
+ path: string;
6
+ }
7
+ export interface FsBrowseResponse {
8
+ current_path: string;
9
+ entries: FsBrowseEntry[];
10
+ error: string | null;
11
+ ok: boolean;
12
+ parent_path: string | null;
13
+ root_path: string;
14
+ }
15
+ export interface FsProbeResponse {
16
+ current_branch: string | null;
17
+ exists: boolean;
18
+ is_dir: boolean;
19
+ is_git_repository: boolean;
20
+ ok: boolean;
21
+ path: string;
22
+ suggested_name: string;
23
+ }
24
+ export declare const browseDirectory: (requestedPath: string) => Promise<FsBrowseResponse>;
25
+ export declare const probeDirectory: (requestedPath: string) => Promise<FsProbeResponse>;
@@ -0,0 +1,130 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { readdir, stat } from 'node:fs/promises';
3
+ import { dirname, resolve } from 'node:path';
4
+ import { promisify } from 'node:util';
5
+ import { getFsBrowseRoot, isPathWithinRoot } from './fs-sandbox.js';
6
+ const execFileP = promisify(execFile);
7
+ const GIT_BRANCH_TIMEOUT_MS = 800;
8
+ const detectGitRepository = async (entryPath) => {
9
+ try {
10
+ const info = await stat(resolve(entryPath, '.git'));
11
+ return info.isDirectory() || info.isFile();
12
+ }
13
+ catch {
14
+ return false;
15
+ }
16
+ };
17
+ const readCurrentBranch = async (repoPath) => {
18
+ try {
19
+ const { stdout } = await execFileP('git', ['-C', repoPath, 'rev-parse', '--abbrev-ref', 'HEAD'], {
20
+ timeout: GIT_BRANCH_TIMEOUT_MS,
21
+ windowsHide: true,
22
+ });
23
+ const branch = stdout.trim();
24
+ return branch.length > 0 ? branch : null;
25
+ }
26
+ catch {
27
+ return null;
28
+ }
29
+ };
30
+ export const browseDirectory = async (requestedPath) => {
31
+ const rootPath = getFsBrowseRoot();
32
+ const trimmed = requestedPath.trim();
33
+ const candidate = trimmed.length === 0 ? rootPath : resolve(rootPath, trimmed);
34
+ if (!isPathWithinRoot(rootPath, candidate)) {
35
+ return {
36
+ current_path: rootPath,
37
+ entries: [],
38
+ error: 'Access denied: path is outside the browse root.',
39
+ ok: false,
40
+ parent_path: null,
41
+ root_path: rootPath,
42
+ };
43
+ }
44
+ let dirStat;
45
+ try {
46
+ dirStat = await stat(candidate);
47
+ }
48
+ catch (error) {
49
+ return {
50
+ current_path: candidate,
51
+ entries: [],
52
+ error: error instanceof Error ? error.message : 'Failed to stat directory',
53
+ ok: false,
54
+ parent_path: null,
55
+ root_path: rootPath,
56
+ };
57
+ }
58
+ if (!dirStat.isDirectory()) {
59
+ return {
60
+ current_path: candidate,
61
+ entries: [],
62
+ error: 'The specified path is not a directory.',
63
+ ok: false,
64
+ parent_path: null,
65
+ root_path: rootPath,
66
+ };
67
+ }
68
+ const rawEntries = await readdir(candidate, { withFileTypes: true });
69
+ const directoryEntries = rawEntries
70
+ .filter((entry) => entry.isDirectory() && !entry.name.startsWith('.'))
71
+ .sort((a, b) => a.name.localeCompare(b.name));
72
+ const entries = await Promise.all(directoryEntries.map(async (entry) => {
73
+ const entryPath = resolve(candidate, entry.name);
74
+ return {
75
+ is_dir: true,
76
+ is_git_repository: await detectGitRepository(entryPath),
77
+ name: entry.name,
78
+ path: entryPath,
79
+ };
80
+ }));
81
+ const isAtRoot = candidate === rootPath;
82
+ const rawParent = dirname(candidate);
83
+ const parentIsWithinRoot = isPathWithinRoot(rootPath, rawParent);
84
+ const parent_path = isAtRoot ? null : parentIsWithinRoot ? rawParent : null;
85
+ return {
86
+ current_path: candidate,
87
+ entries,
88
+ error: null,
89
+ ok: true,
90
+ parent_path,
91
+ root_path: rootPath,
92
+ };
93
+ };
94
+ export const probeDirectory = async (requestedPath) => {
95
+ const rootPath = getFsBrowseRoot();
96
+ const candidate = resolve(rootPath, requestedPath.trim());
97
+ const base = {
98
+ current_branch: null,
99
+ exists: false,
100
+ is_dir: false,
101
+ is_git_repository: false,
102
+ ok: false,
103
+ path: candidate,
104
+ suggested_name: candidate.split(/[\\/]/).filter(Boolean).pop() ?? '',
105
+ };
106
+ if (!isPathWithinRoot(rootPath, candidate)) {
107
+ return base;
108
+ }
109
+ try {
110
+ const info = await stat(candidate);
111
+ if (!info.isDirectory()) {
112
+ return { ...base, exists: true, is_dir: false, ok: true };
113
+ }
114
+ const is_git_repository = await detectGitRepository(candidate);
115
+ const current_branch = is_git_repository ? await readCurrentBranch(candidate) : null;
116
+ return {
117
+ current_branch,
118
+ exists: true,
119
+ is_dir: true,
120
+ is_git_repository,
121
+ ok: true,
122
+ path: candidate,
123
+ suggested_name: base.suggested_name,
124
+ };
125
+ }
126
+ catch {
127
+ return base;
128
+ }
129
+ };
130
+ //# sourceMappingURL=fs-browse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs-browse.js","sourceRoot":"","sources":["../../../src/server/fs-browse.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { type ExecFileOptions } from 'node:child_process';
2
+ import { type FsProbeResponse } from './fs-browse.js';
3
+ type SpawnResult = {
4
+ stderr: string;
5
+ stdout: string;
6
+ status: number | null;
7
+ signal: string | null;
8
+ timedOut: boolean;
9
+ spawnError: NodeJS.ErrnoException | null;
10
+ };
11
+ export type RunPickCommand = (command: string, args: string[], options: ExecFileOptions) => Promise<SpawnResult>;
12
+ export interface PickFolderOptions {
13
+ now?: () => number;
14
+ platform?: NodeJS.Platform;
15
+ runCommand?: RunPickCommand;
16
+ }
17
+ export interface PickFolderResponse {
18
+ canceled: boolean;
19
+ error: string | null;
20
+ path: string | null;
21
+ probe: FsProbeResponse | null;
22
+ supported: boolean;
23
+ }
24
+ export declare const pickFolder: (options?: PickFolderOptions) => Promise<PickFolderResponse>;
25
+ export {};
@@ -0,0 +1,132 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { probeDirectory } from './fs-browse.js';
3
+ // macOS Cocoa returns -1743 when the user clicks Cancel in `choose folder`.
4
+ // osascript maps that to exit code 1 with the message on stderr.
5
+ const MACOS_CANCEL_PATTERNS = [/-128/, /-1743/, /user canceled/i, /execution error/i];
6
+ // zenity documents exit code 1 on Cancel. kdialog uses exit code 1 as well.
7
+ const LINUX_CANCEL_EXIT_CODES = new Set([1]);
8
+ const defaultRunCommand = (command, args, options) => new Promise((resolve) => {
9
+ const child = execFile(command, args, options, (error, stdout, stderr) => {
10
+ const errno = error;
11
+ const timedOut = !!errno?.killed && errno?.signal === 'SIGTERM';
12
+ // execFile surfaces ENOENT when the binary is missing; keep the raw errno
13
+ // so the caller can distinguish "command not installed" from "user cancel".
14
+ resolve({
15
+ stderr: String(stderr ?? ''),
16
+ stdout: String(stdout ?? ''),
17
+ status: typeof errno?.code === 'number' ? errno.code : (child.exitCode ?? 0),
18
+ signal: typeof errno?.signal === 'string' ? errno.signal : null,
19
+ spawnError: errno && typeof errno.code === 'string' ? errno : null,
20
+ timedOut,
21
+ });
22
+ });
23
+ });
24
+ const emptyResponse = (overrides = {}) => ({
25
+ canceled: false,
26
+ error: null,
27
+ path: null,
28
+ probe: null,
29
+ supported: true,
30
+ ...overrides,
31
+ });
32
+ const finalizeWithProbe = async (path) => {
33
+ const probe = await probeDirectory(path);
34
+ if (!probe.ok || !probe.is_dir) {
35
+ return emptyResponse({
36
+ error: 'Selected path is outside the Hive browse sandbox or is not a directory.',
37
+ path,
38
+ probe,
39
+ });
40
+ }
41
+ return emptyResponse({ path: probe.path, probe });
42
+ };
43
+ const macOsPick = async (run) => {
44
+ const script = 'POSIX path of (choose folder with prompt "Select Hive workspace")';
45
+ const result = await run('osascript', ['-e', script], {});
46
+ if (result.spawnError?.code === 'ENOENT') {
47
+ return emptyResponse({ error: 'osascript is unavailable on this host.', supported: false });
48
+ }
49
+ if (result.timedOut) {
50
+ return emptyResponse({ error: 'Folder picker timed out before a folder was selected.' });
51
+ }
52
+ const combinedStderr = result.stderr.toLowerCase();
53
+ if (result.status !== 0) {
54
+ if (MACOS_CANCEL_PATTERNS.some((re) => re.test(combinedStderr))) {
55
+ return emptyResponse({ canceled: true });
56
+ }
57
+ // Any non-zero exit code without stdout is treated as cancel rather than a
58
+ // hard failure — the user is just closing the dialog.
59
+ if (result.stdout.trim().length === 0)
60
+ return emptyResponse({ canceled: true });
61
+ }
62
+ const picked = result.stdout.trim().replace(/\/$/, '');
63
+ if (picked.length === 0)
64
+ return emptyResponse({ canceled: true });
65
+ return finalizeWithProbe(picked);
66
+ };
67
+ const linuxPick = async (run) => {
68
+ const result = await run('zenity', ['--file-selection', '--directory', '--title=Select Hive workspace'], {});
69
+ if (result.spawnError?.code === 'ENOENT') {
70
+ return emptyResponse({
71
+ error: 'zenity not installed. Install zenity or use Advanced: paste path.',
72
+ supported: false,
73
+ });
74
+ }
75
+ if (result.timedOut) {
76
+ return emptyResponse({ error: 'Folder picker timed out before a folder was selected.' });
77
+ }
78
+ if (result.status !== 0 && LINUX_CANCEL_EXIT_CODES.has(result.status ?? 0)) {
79
+ return emptyResponse({ canceled: true });
80
+ }
81
+ const picked = result.stdout.trim();
82
+ if (picked.length === 0)
83
+ return emptyResponse({ canceled: true });
84
+ return finalizeWithProbe(picked);
85
+ };
86
+ const windowsPick = async (run) => {
87
+ const script = [
88
+ 'Add-Type -AssemblyName System.Windows.Forms',
89
+ '$dialog = New-Object System.Windows.Forms.FolderBrowserDialog',
90
+ '$dialog.Description = "Select Hive workspace"',
91
+ '$dialog.ShowNewFolderButton = $false',
92
+ '$result = $dialog.ShowDialog()',
93
+ 'if ($result -eq [System.Windows.Forms.DialogResult]::OK) { [Console]::Out.WriteLine($dialog.SelectedPath); exit 0 }',
94
+ 'exit 1',
95
+ ].join('; ');
96
+ const result = await run('powershell.exe', ['-NoProfile', '-STA', '-ExecutionPolicy', 'Bypass', '-Command', script], {});
97
+ if (result.spawnError?.code === 'ENOENT') {
98
+ return emptyResponse({
99
+ error: 'PowerShell is unavailable on this host. Use Advanced: paste path.',
100
+ supported: false,
101
+ });
102
+ }
103
+ if (result.timedOut) {
104
+ return emptyResponse({ error: 'Folder picker timed out before a folder was selected.' });
105
+ }
106
+ if (result.status !== 0) {
107
+ const stderr = result.stderr.trim();
108
+ if (stderr.length > 0) {
109
+ return emptyResponse({ error: `Folder picker failed: ${stderr}` });
110
+ }
111
+ return emptyResponse({ canceled: true });
112
+ }
113
+ const picked = result.stdout.trim();
114
+ if (picked.length === 0)
115
+ return emptyResponse({ canceled: true });
116
+ return finalizeWithProbe(picked);
117
+ };
118
+ export const pickFolder = async (options = {}) => {
119
+ const platform = options.platform ?? process.platform;
120
+ const run = options.runCommand ?? defaultRunCommand;
121
+ if (platform === 'darwin')
122
+ return macOsPick(run);
123
+ if (platform === 'linux')
124
+ return linuxPick(run);
125
+ if (platform === 'win32')
126
+ return windowsPick(run);
127
+ return emptyResponse({
128
+ error: 'Native folder picker not supported on this platform. Use Advanced: paste path.',
129
+ supported: false,
130
+ });
131
+ };
132
+ //# sourceMappingURL=fs-pick-folder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs-pick-folder.js","sourceRoot":"","sources":["../../../src/server/fs-pick-folder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Root directory the FS-browse API is allowed to reveal. We sandbox to
3
+ * `$HOME` (override via `HIVE_FS_BROWSE_ROOT` for tests). Anything outside
4
+ * this prefix is rejected before readdir/stat even runs.
5
+ */
6
+ export declare const getFsBrowseRoot: () => string;
7
+ /**
8
+ * True when `candidatePath` is `rootPath` itself or a descendant of it.
9
+ * Uses `path.relative` + separator check so Windows back-slashes and drive
10
+ * boundaries are handled correctly — identical shape to kanban's
11
+ * isPathWithinRoot so the semantics match a project we already trust.
12
+ */
13
+ export declare const isPathWithinRoot: (rootPath: string, candidatePath: string) => boolean;
@@ -0,0 +1,26 @@
1
+ import { homedir } from 'node:os';
2
+ import { isAbsolute, relative, resolve, sep } from 'node:path';
3
+ /**
4
+ * Root directory the FS-browse API is allowed to reveal. We sandbox to
5
+ * `$HOME` (override via `HIVE_FS_BROWSE_ROOT` for tests). Anything outside
6
+ * this prefix is rejected before readdir/stat even runs.
7
+ */
8
+ export const getFsBrowseRoot = () => {
9
+ const override = process.env.HIVE_FS_BROWSE_ROOT;
10
+ return override && override.length > 0 ? resolve(override) : resolve(homedir());
11
+ };
12
+ /**
13
+ * True when `candidatePath` is `rootPath` itself or a descendant of it.
14
+ * Uses `path.relative` + separator check so Windows back-slashes and drive
15
+ * boundaries are handled correctly — identical shape to kanban's
16
+ * isPathWithinRoot so the semantics match a project we already trust.
17
+ */
18
+ export const isPathWithinRoot = (rootPath, candidatePath) => {
19
+ const resolvedRoot = resolve(rootPath);
20
+ const resolvedCandidate = resolve(candidatePath);
21
+ if (resolvedCandidate === resolvedRoot)
22
+ return true;
23
+ const rel = relative(resolvedRoot, resolvedCandidate);
24
+ return rel !== '..' && !rel.startsWith(`..${sep}`) && !isAbsolute(rel);
25
+ };
26
+ //# sourceMappingURL=fs-sandbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs-sandbox.js","sourceRoot":"","sources":["../../../src/server/fs-sandbox.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAA;AAE9D;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,GAAW,EAAE;IAC1C,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAA;IAChD,OAAO,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;AACjF,CAAC,CAAA;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,QAAgB,EAAE,aAAqB,EAAW,EAAE;IACnF,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;IACtC,MAAM,iBAAiB,GAAG,OAAO,CAAC,aAAa,CAAC,CAAA;IAChD,IAAI,iBAAiB,KAAK,YAAY;QAAE,OAAO,IAAI,CAAA;IACnD,MAAM,GAAG,GAAG,QAAQ,CAAC,YAAY,EAAE,iBAAiB,CAAC,CAAA;IACrD,OAAO,GAAG,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;AACxE,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ import type { AgentSummary } from '../shared/types.js';
2
+ export declare const getHiveTeamRules: (agent: Pick<AgentSummary, "role">) => string[];
@@ -0,0 +1,14 @@
1
+ const ORCHESTRATOR_RULES = [
2
+ 'Hive worker 是右侧卡片里的真实 CLI agent,不是 Claude Code 内置的 Task / Explore / subagent。',
3
+ '当 user 要你“让 worker ... / 给 worker 找活 / 让成员处理”时,先执行 `team list` 确认真实 Hive worker。',
4
+ '如果只有一个可用 worker,直接用 `team send <worker-name> "<task>"` 派给它;不要把选择题丢回给 user。',
5
+ '当 user 要你“让 worker ...”时,必须用 `team send <worker-name> "<task>"` 派给 Hive worker。',
6
+ '不要使用 Claude Code 内置的 Task / Explore / subagent 来代替 Hive worker;它们不会出现在 Hive UI,也不会触发 pending_task_count / team report。',
7
+ ];
8
+ const WORKER_RULES = [
9
+ '你是 Hive 右侧卡片里的真实 CLI worker,不是 Claude Code 内置 subagent。',
10
+ '不要调用 team send,也不要再启动 Claude Code 内置的 Task / Explore / subagent 来替你完成派单。',
11
+ '完成或阻塞时必须用 `team report` 汇报给 Orchestrator。',
12
+ ];
13
+ export const getHiveTeamRules = (agent) => agent.role === 'orchestrator' ? ORCHESTRATOR_RULES : WORKER_RULES;
14
+ //# sourceMappingURL=hive-team-guidance.js.map