@agent-spaces/server 0.3.64 → 0.3.67

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 (332) hide show
  1. package/dist/adapters/agent-runtime.js +4 -0
  2. package/dist/adapters/claude-code-runtime/index.js +68 -2
  3. package/dist/adapters/claude-code-runtime/message-format.js +26 -0
  4. package/dist/adapters/claude-code-runtime/sdk-config.js +12 -0
  5. package/dist/adapters/codex-function-tool-bridge.js +144 -0
  6. package/dist/adapters/codex-runtime.js +23 -4
  7. package/dist/adapters/git.js +25 -7
  8. package/dist/adapters/hermes-runtime.js +210 -0
  9. package/dist/agents/agent-message-parts.js +1 -1
  10. package/dist/agents/commit-agent.js +4 -2
  11. package/dist/agents/issue-task-controller.js +75 -4
  12. package/dist/agents/pull-request-agent.js +115 -0
  13. package/dist/agents/scheduler-agent.js +1 -1
  14. package/dist/app.js +12 -70
  15. package/dist/middleware/auth.js +1 -1
  16. package/dist/package.json +2 -1
  17. package/dist/routes/agent-sse.js +2 -0
  18. package/dist/routes/agent.js +3 -0
  19. package/dist/routes/database.js +1 -0
  20. package/dist/routes/git.js +197 -317
  21. package/dist/routes/issue.js +1 -1
  22. package/dist/routes/notification.js +10 -0
  23. package/dist/routes/robot-account.js +68 -0
  24. package/dist/routes/version.js +94 -0
  25. package/dist/routes/worktree.js +93 -0
  26. package/dist/services/agent.js +37 -3
  27. package/dist/services/builtin-tools/kanban-tools.js +4 -0
  28. package/dist/services/git-operation-log.js +40 -0
  29. package/dist/services/global-wechat-qr.js +72 -0
  30. package/dist/services/hook-engine.js +175 -17
  31. package/dist/services/notification-center.js +9 -0
  32. package/dist/services/notification-hub/bot-agent.js +3 -1
  33. package/dist/services/notification-hub/service.js +12 -2
  34. package/dist/services/robot-account.js +34 -0
  35. package/dist/services/version.js +59 -0
  36. package/dist/services/workflow-command-runner.js +23 -0
  37. package/dist/services/workflow.js +25 -8
  38. package/dist/services/workspace.js +25 -1
  39. package/dist/services/worktree.js +207 -0
  40. package/dist/storage/robot-account-store.js +39 -0
  41. package/dist/storage/worktree-store.js +33 -0
  42. package/dist/web/404.html +1 -1
  43. package/dist/web/__next.__PAGE__.txt +4 -4
  44. package/dist/web/__next._full.txt +23 -25
  45. package/dist/web/__next._head.txt +4 -4
  46. package/dist/web/__next._index.txt +13 -13
  47. package/dist/web/__next._tree.txt +2 -2
  48. package/dist/web/_next/static/chunks/{0n6_4so_afuwk.js → 0-92u-tiuy40a.js} +4 -4
  49. package/dist/web/_next/static/chunks/{0vbqaynjq8ga..js → 0-yizd8osmas2.js} +1 -1
  50. package/dist/web/_next/static/chunks/0.ln~3mnv8.69.js +1 -0
  51. package/dist/web/_next/static/chunks/{0iuf30t0rjsjv.js → 01y3e9pemva7b.js} +10 -10
  52. package/dist/web/_next/static/chunks/02802taez976w.js +67 -0
  53. package/dist/web/_next/static/chunks/02l~tmzrgny.~.js +1 -0
  54. package/dist/web/_next/static/chunks/033.awk90g6eh.js +1 -0
  55. package/dist/web/_next/static/chunks/03f1bwuynjdmk.js +1 -0
  56. package/dist/web/_next/static/chunks/04cb4kc9r2pd1.js +1 -0
  57. package/dist/web/_next/static/chunks/04de6ha5_e3pp.js +1 -0
  58. package/dist/web/_next/static/chunks/06.kdsa9rr2h1.js +1 -0
  59. package/dist/web/_next/static/chunks/09he0p79ov1rn.js +1 -0
  60. package/dist/web/_next/static/chunks/09vpocs4zuc8h.js +1 -0
  61. package/dist/web/_next/static/chunks/0_o2exgr0e_nh.js +1 -0
  62. package/dist/web/_next/static/chunks/{0xbaakj0dfc0..js → 0_y9nskc-xt2k.js} +1 -1
  63. package/dist/web/_next/static/chunks/0clnj-1fi6u8j.js +3 -0
  64. package/dist/web/_next/static/chunks/0gv40by0zzxs_.js +1 -0
  65. package/dist/web/_next/static/chunks/0iusr8y88.kjg.js +1 -0
  66. package/dist/web/_next/static/chunks/{04a4vsq2wknm4.js → 0j-8418fxvkd1.js} +1 -1
  67. package/dist/web/_next/static/chunks/0j-l7l_k9jt45.js +1 -0
  68. package/dist/web/_next/static/chunks/0j.wxxyoclma5.js +1 -0
  69. package/dist/web/_next/static/chunks/0jq.16sozqik..js +3 -0
  70. package/dist/web/_next/static/chunks/0jw8xdk_fpnp0.css +1 -0
  71. package/dist/web/_next/static/chunks/0l1lkd-wcotma.js +1 -0
  72. package/dist/web/_next/static/chunks/0ncxf_zr4n839.js +1 -0
  73. package/dist/web/_next/static/chunks/0ndo7um~v7vco.js +1 -0
  74. package/dist/web/_next/static/chunks/0ngk.~kan8wq_.js +1 -0
  75. package/dist/web/_next/static/chunks/0p3h-h3zj5ujg.js +30 -0
  76. package/dist/web/_next/static/chunks/0pm-un~-sy3rl.js +1 -0
  77. package/dist/web/_next/static/chunks/0rt9bofnn6qvn.js +1 -0
  78. package/dist/web/_next/static/chunks/0t64.9jd00hio.js +3 -0
  79. package/dist/web/_next/static/chunks/0taui9--5n6-5.js +1 -0
  80. package/dist/web/_next/static/chunks/0ty39169lh~z3.js +1 -0
  81. package/dist/web/_next/static/chunks/0uxzi~9b~k4mn.js +31 -0
  82. package/dist/web/_next/static/chunks/0v8nof~waedlu.js +1 -0
  83. package/dist/web/_next/static/chunks/{0ctg5qmw7uu.1.js → 0vcfoagnpf.aw.js} +3 -3
  84. package/dist/web/_next/static/chunks/{08ckpwmmwlors.js → 0wwwq.gyyz0vg.js} +3 -3
  85. package/dist/web/_next/static/chunks/0x5lak8yz7pm7.js +1 -0
  86. package/dist/web/_next/static/chunks/0xon_.4-o0_zq.js +7 -0
  87. package/dist/web/_next/static/chunks/0zjnrbt7inime.js +1 -0
  88. package/dist/web/_next/static/chunks/0zncg76rgtbm-.js +1 -0
  89. package/dist/web/_next/static/chunks/0zwebpitvpuv1.js +1 -0
  90. package/dist/web/_next/static/chunks/0~02o4g-o6n~m.js +1 -0
  91. package/dist/web/_next/static/chunks/{10l-9myrdo3x9.js → 0~fjezp.k4qk3.js} +1 -1
  92. package/dist/web/_next/static/chunks/0~sh93re1-_rp.js +1 -0
  93. package/dist/web/_next/static/chunks/10_niiq0k6o-p.js +5 -0
  94. package/dist/web/_next/static/chunks/12tjr0_2ccrtq.js +2 -0
  95. package/dist/web/_next/static/chunks/12x5.go_x9mfk.js +1 -0
  96. package/dist/web/_next/static/chunks/{1442stwa0gbxe.js → 12~5dk9i9d16t.js} +2 -2
  97. package/dist/web/_next/static/chunks/13iye4rv5p31b.js +1 -0
  98. package/dist/web/_next/static/chunks/{01~quun6sefgl.js → 13~y-b.b9rrw4.js} +1 -1
  99. package/dist/web/_next/static/chunks/151wzhb5q0lo5.js +1 -0
  100. package/dist/web/_next/static/chunks/18c7g84y01mj0.js +1 -0
  101. package/dist/web/_next/static/chunks/{turbopack-0ndm2zc_pdptk.js → turbopack-11qjwlynmfc-n.js} +1 -1
  102. package/dist/web/_not-found/__next._full.txt +30 -29
  103. package/dist/web/_not-found/__next._head.txt +4 -4
  104. package/dist/web/_not-found/__next._index.txt +13 -13
  105. package/dist/web/_not-found/__next._not-found.__PAGE__.txt +2 -2
  106. package/dist/web/_not-found/__next._not-found.txt +3 -3
  107. package/dist/web/_not-found/__next._tree.txt +2 -2
  108. package/dist/web/_not-found.html +1 -1
  109. package/dist/web/_not-found.txt +30 -29
  110. package/dist/web/index.html +1 -1
  111. package/dist/web/index.txt +23 -25
  112. package/dist/web/login/__next._full.txt +28 -28
  113. package/dist/web/login/__next._head.txt +4 -4
  114. package/dist/web/login/__next._index.txt +13 -13
  115. package/dist/web/login/__next._tree.txt +2 -2
  116. package/dist/web/login/__next.login.__PAGE__.txt +4 -4
  117. package/dist/web/login/__next.login.txt +3 -3
  118. package/dist/web/login.html +1 -1
  119. package/dist/web/login.txt +28 -28
  120. package/dist/web/settings/__next._full.txt +33 -32
  121. package/dist/web/settings/__next._head.txt +4 -4
  122. package/dist/web/settings/__next._index.txt +13 -13
  123. package/dist/web/settings/__next._tree.txt +2 -2
  124. package/dist/web/settings/__next.settings.__PAGE__.txt +4 -4
  125. package/dist/web/settings/__next.settings.txt +5 -5
  126. package/dist/web/settings/agents/__next._full.txt +24 -24
  127. package/dist/web/settings/agents/__next._head.txt +4 -4
  128. package/dist/web/settings/agents/__next._index.txt +13 -13
  129. package/dist/web/settings/agents/__next._tree.txt +2 -2
  130. package/dist/web/settings/agents/__next.settings.agents.__PAGE__.txt +4 -4
  131. package/dist/web/settings/agents/__next.settings.agents.txt +3 -3
  132. package/dist/web/settings/agents/__next.settings.txt +5 -5
  133. package/dist/web/settings/agents.html +1 -1
  134. package/dist/web/settings/agents.txt +24 -24
  135. package/dist/web/settings/mcps/__next._full.txt +24 -24
  136. package/dist/web/settings/mcps/__next._head.txt +4 -4
  137. package/dist/web/settings/mcps/__next._index.txt +13 -13
  138. package/dist/web/settings/mcps/__next._tree.txt +2 -2
  139. package/dist/web/settings/mcps/__next.settings.mcps.__PAGE__.txt +4 -4
  140. package/dist/web/settings/mcps/__next.settings.mcps.txt +3 -3
  141. package/dist/web/settings/mcps/__next.settings.txt +5 -5
  142. package/dist/web/settings/mcps.html +1 -1
  143. package/dist/web/settings/mcps.txt +24 -24
  144. package/dist/web/settings/models/__next._full.txt +24 -24
  145. package/dist/web/settings/models/__next._head.txt +4 -4
  146. package/dist/web/settings/models/__next._index.txt +13 -13
  147. package/dist/web/settings/models/__next._tree.txt +2 -2
  148. package/dist/web/settings/models/__next.settings.models.__PAGE__.txt +4 -4
  149. package/dist/web/settings/models/__next.settings.models.txt +3 -3
  150. package/dist/web/settings/models/__next.settings.txt +5 -5
  151. package/dist/web/settings/models.html +1 -1
  152. package/dist/web/settings/models.txt +24 -24
  153. package/dist/web/settings/output-styles/__next._full.txt +24 -24
  154. package/dist/web/settings/output-styles/__next._head.txt +4 -4
  155. package/dist/web/settings/output-styles/__next._index.txt +13 -13
  156. package/dist/web/settings/output-styles/__next._tree.txt +2 -2
  157. package/dist/web/settings/output-styles/__next.settings.output-styles.__PAGE__.txt +4 -4
  158. package/dist/web/settings/output-styles/__next.settings.output-styles.txt +3 -3
  159. package/dist/web/settings/output-styles/__next.settings.txt +5 -5
  160. package/dist/web/settings/output-styles.html +1 -1
  161. package/dist/web/settings/output-styles.txt +24 -24
  162. package/dist/web/settings/prompts/__next._full.txt +24 -24
  163. package/dist/web/settings/prompts/__next._head.txt +4 -4
  164. package/dist/web/settings/prompts/__next._index.txt +13 -13
  165. package/dist/web/settings/prompts/__next._tree.txt +2 -2
  166. package/dist/web/settings/prompts/__next.settings.prompts.__PAGE__.txt +4 -4
  167. package/dist/web/settings/prompts/__next.settings.prompts.txt +3 -3
  168. package/dist/web/settings/prompts/__next.settings.txt +5 -5
  169. package/dist/web/settings/prompts.html +1 -1
  170. package/dist/web/settings/prompts.txt +24 -24
  171. package/dist/web/settings/providers/__next._full.txt +24 -24
  172. package/dist/web/settings/providers/__next._head.txt +4 -4
  173. package/dist/web/settings/providers/__next._index.txt +13 -13
  174. package/dist/web/settings/providers/__next._tree.txt +2 -2
  175. package/dist/web/settings/providers/__next.settings.providers.__PAGE__.txt +4 -4
  176. package/dist/web/settings/providers/__next.settings.providers.txt +3 -3
  177. package/dist/web/settings/providers/__next.settings.txt +5 -5
  178. package/dist/web/settings/providers.html +1 -1
  179. package/dist/web/settings/providers.txt +24 -24
  180. package/dist/web/settings/skills/__next._full.txt +24 -24
  181. package/dist/web/settings/skills/__next._head.txt +4 -4
  182. package/dist/web/settings/skills/__next._index.txt +13 -13
  183. package/dist/web/settings/skills/__next._tree.txt +2 -2
  184. package/dist/web/settings/skills/__next.settings.skills.__PAGE__.txt +4 -4
  185. package/dist/web/settings/skills/__next.settings.skills.txt +3 -3
  186. package/dist/web/settings/skills/__next.settings.txt +5 -5
  187. package/dist/web/settings/skills.html +1 -1
  188. package/dist/web/settings/skills.txt +24 -24
  189. package/dist/web/settings/tools/__next._full.txt +24 -24
  190. package/dist/web/settings/tools/__next._head.txt +4 -4
  191. package/dist/web/settings/tools/__next._index.txt +13 -13
  192. package/dist/web/settings/tools/__next._tree.txt +2 -2
  193. package/dist/web/settings/tools/__next.settings.tools.__PAGE__.txt +4 -4
  194. package/dist/web/settings/tools/__next.settings.tools.txt +3 -3
  195. package/dist/web/settings/tools/__next.settings.txt +5 -5
  196. package/dist/web/settings/tools.html +1 -1
  197. package/dist/web/settings/tools.txt +24 -24
  198. package/dist/web/settings.html +1 -1
  199. package/dist/web/settings.txt +33 -32
  200. package/dist/web/workflows/__next._full.txt +31 -33
  201. package/dist/web/workflows/__next._head.txt +4 -4
  202. package/dist/web/workflows/__next._index.txt +13 -13
  203. package/dist/web/workflows/__next._tree.txt +2 -2
  204. package/dist/web/workflows/__next.workflows.__PAGE__.txt +4 -4
  205. package/dist/web/workflows/__next.workflows.txt +3 -3
  206. package/dist/web/workflows.html +1 -1
  207. package/dist/web/workflows.txt +31 -33
  208. package/dist/web/workspace/_/__next._full.txt +28 -29
  209. package/dist/web/workspace/_/__next._head.txt +4 -4
  210. package/dist/web/workspace/_/__next._index.txt +13 -13
  211. package/dist/web/workspace/_/__next._tree.txt +2 -2
  212. package/dist/web/workspace/_/__next.workspace.$d$id.__PAGE__.txt +3 -3
  213. package/dist/web/workspace/_/__next.workspace.$d$id.txt +3 -3
  214. package/dist/web/workspace/_/__next.workspace.txt +3 -3
  215. package/dist/web/workspace/_.html +1 -1
  216. package/dist/web/workspace/_.txt +28 -29
  217. package/dist/web/workspaces/__next._full.txt +29 -31
  218. package/dist/web/workspaces/__next._head.txt +4 -4
  219. package/dist/web/workspaces/__next._index.txt +13 -13
  220. package/dist/web/workspaces/__next._tree.txt +2 -2
  221. package/dist/web/workspaces/__next.workspaces.__PAGE__.txt +4 -4
  222. package/dist/web/workspaces/__next.workspaces.txt +3 -3
  223. package/dist/web/workspaces.html +1 -1
  224. package/dist/web/workspaces.txt +29 -31
  225. package/dist/ws/agent-prompt.js +32 -3
  226. package/dist/ws/agent-runner.js +83 -6
  227. package/package.json +11 -11
  228. package/dist/web/_next/static/chunks/0-9194nbxy_6d.js +0 -1
  229. package/dist/web/_next/static/chunks/0.n~yfwf4~6w-.js +0 -1
  230. package/dist/web/_next/static/chunks/02mf61htij8g0.js +0 -31
  231. package/dist/web/_next/static/chunks/04dg4l4hv11q2.js +0 -3
  232. package/dist/web/_next/static/chunks/04fxddw-y20~-.js +0 -7
  233. package/dist/web/_next/static/chunks/04w7~5ooz_pwm.js +0 -1
  234. package/dist/web/_next/static/chunks/05oc21sj24wtq.js +0 -1
  235. package/dist/web/_next/static/chunks/08kfx8on9oty~.js +0 -1
  236. package/dist/web/_next/static/chunks/08k~meqbd8d6v.js +0 -1
  237. package/dist/web/_next/static/chunks/099h96wjsdb25.js +0 -2
  238. package/dist/web/_next/static/chunks/09h23logvq65m.js +0 -1
  239. package/dist/web/_next/static/chunks/0a5y-vhf4i5id.js +0 -3
  240. package/dist/web/_next/static/chunks/0ake2f3x2uan4.js +0 -24
  241. package/dist/web/_next/static/chunks/0ck8dw_9-1cdx.js +0 -1
  242. package/dist/web/_next/static/chunks/0ewceguykiut5.js +0 -1
  243. package/dist/web/_next/static/chunks/0f7cb9li~3jra.js +0 -67
  244. package/dist/web/_next/static/chunks/0ghs9on7wodrm.js +0 -1
  245. package/dist/web/_next/static/chunks/0ghx3j_.-gdyd.js +0 -1
  246. package/dist/web/_next/static/chunks/0h9cu-k6z5o08.js +0 -1
  247. package/dist/web/_next/static/chunks/0jb4~3qqkw2ps.js +0 -1
  248. package/dist/web/_next/static/chunks/0nb8.iteznuvx.js +0 -1
  249. package/dist/web/_next/static/chunks/0os58q93stt7j.js +0 -3
  250. package/dist/web/_next/static/chunks/0s9lmk8iauou3.js +0 -1
  251. package/dist/web/_next/static/chunks/0sp_zbx~w0am7.js +0 -1
  252. package/dist/web/_next/static/chunks/0tel~zsv4z8l_.js +0 -1
  253. package/dist/web/_next/static/chunks/0twamv4wr_dbv.js +0 -1
  254. package/dist/web/_next/static/chunks/0uhol5wafdbl~.js +0 -1
  255. package/dist/web/_next/static/chunks/0v3a_x4vt42kx.js +0 -5
  256. package/dist/web/_next/static/chunks/0v7q4mys.mnm..css +0 -1
  257. package/dist/web/_next/static/chunks/0xt-8wk21gs7g.js +0 -1
  258. package/dist/web/_next/static/chunks/0z~vqzbm_q371.js +0 -1
  259. package/dist/web/_next/static/chunks/0~3xm80~j9ddg.js +0 -1
  260. package/dist/web/_next/static/chunks/14s37n6h0_q3x.js +0 -16
  261. package/dist/web/_next/static/chunks/161ik5kfyuwtd.js +0 -1
  262. package/dist/web/_next/static/chunks/17k~zbv0_4rep.js +0 -1
  263. package/public/output-styles/carmack-mode.md +0 -381
  264. package/public/output-styles/codex-rigor-mode.md +0 -114
  265. package/public/output-styles/dhh-mode.md +0 -265
  266. package/public/output-styles/evan-you-mode.md +0 -539
  267. package/public/output-styles/index.json +0 -37
  268. package/public/output-styles/jobs-mode.md +0 -369
  269. package/public/output-styles/linus-mode.md +0 -135
  270. package/public/output-styles/uncle-bob-mode.md +0 -221
  271. package/public/prompt/andrej-karpathy-skills.md +0 -65
  272. package/public/prompt/claude-token-efficient-coding.md +0 -35
  273. package/public/prompt/index.json +0 -12
  274. package/public/skills/index.json +0 -92
  275. package/public/skills/planning-with-files/planning-with-files-zh/SKILL.md +0 -243
  276. package/public/skills/planning-with-files/planning-with-files-zh/scripts/check-complete.ps1 +0 -44
  277. package/public/skills/planning-with-files/planning-with-files-zh/scripts/check-complete.sh +0 -46
  278. package/public/skills/planning-with-files/planning-with-files-zh/scripts/init-session.ps1 +0 -124
  279. package/public/skills/planning-with-files/planning-with-files-zh/scripts/init-session.sh +0 -124
  280. package/public/skills/planning-with-files/planning-with-files-zh/scripts/session-catchup.py +0 -438
  281. package/public/skills/planning-with-files/planning-with-files-zh/templates/findings.md +0 -29
  282. package/public/skills/planning-with-files/planning-with-files-zh/templates/progress.md +0 -40
  283. package/public/skills/planning-with-files/planning-with-files-zh/templates/task_plan.md +0 -58
  284. package/public/skills/superpowers/brainstorming/SKILL.md +0 -164
  285. package/public/skills/superpowers/brainstorming/scripts/frame-template.html +0 -214
  286. package/public/skills/superpowers/brainstorming/scripts/helper.js +0 -88
  287. package/public/skills/superpowers/brainstorming/scripts/server.cjs +0 -354
  288. package/public/skills/superpowers/brainstorming/scripts/start-server.sh +0 -148
  289. package/public/skills/superpowers/brainstorming/scripts/stop-server.sh +0 -56
  290. package/public/skills/superpowers/brainstorming/spec-document-reviewer-prompt.md +0 -49
  291. package/public/skills/superpowers/brainstorming/visual-companion.md +0 -287
  292. package/public/skills/superpowers/dispatching-parallel-agents/SKILL.md +0 -182
  293. package/public/skills/superpowers/executing-plans/SKILL.md +0 -70
  294. package/public/skills/superpowers/finishing-a-development-branch/SKILL.md +0 -251
  295. package/public/skills/superpowers/receiving-code-review/SKILL.md +0 -213
  296. package/public/skills/superpowers/requesting-code-review/SKILL.md +0 -103
  297. package/public/skills/superpowers/requesting-code-review/code-reviewer.md +0 -168
  298. package/public/skills/superpowers/subagent-driven-development/SKILL.md +0 -279
  299. package/public/skills/superpowers/subagent-driven-development/code-quality-reviewer-prompt.md +0 -25
  300. package/public/skills/superpowers/subagent-driven-development/implementer-prompt.md +0 -113
  301. package/public/skills/superpowers/subagent-driven-development/spec-reviewer-prompt.md +0 -61
  302. package/public/skills/superpowers/systematic-debugging/CREATION-LOG.md +0 -119
  303. package/public/skills/superpowers/systematic-debugging/SKILL.md +0 -296
  304. package/public/skills/superpowers/systematic-debugging/condition-based-waiting-example.ts +0 -158
  305. package/public/skills/superpowers/systematic-debugging/condition-based-waiting.md +0 -115
  306. package/public/skills/superpowers/systematic-debugging/defense-in-depth.md +0 -122
  307. package/public/skills/superpowers/systematic-debugging/find-polluter.sh +0 -63
  308. package/public/skills/superpowers/systematic-debugging/root-cause-tracing.md +0 -169
  309. package/public/skills/superpowers/systematic-debugging/test-academic.md +0 -14
  310. package/public/skills/superpowers/systematic-debugging/test-pressure-1.md +0 -58
  311. package/public/skills/superpowers/systematic-debugging/test-pressure-2.md +0 -68
  312. package/public/skills/superpowers/systematic-debugging/test-pressure-3.md +0 -69
  313. package/public/skills/superpowers/test-driven-development/SKILL.md +0 -371
  314. package/public/skills/superpowers/test-driven-development/testing-anti-patterns.md +0 -299
  315. package/public/skills/superpowers/using-git-worktrees/SKILL.md +0 -215
  316. package/public/skills/superpowers/using-superpowers/SKILL.md +0 -117
  317. package/public/skills/superpowers/using-superpowers/references/codex-tools.md +0 -59
  318. package/public/skills/superpowers/using-superpowers/references/copilot-tools.md +0 -42
  319. package/public/skills/superpowers/using-superpowers/references/gemini-tools.md +0 -51
  320. package/public/skills/superpowers/verification-before-completion/SKILL.md +0 -139
  321. package/public/skills/superpowers/writing-plans/SKILL.md +0 -152
  322. package/public/skills/superpowers/writing-plans/plan-document-reviewer-prompt.md +0 -49
  323. package/public/skills/superpowers/writing-skills/SKILL.md +0 -655
  324. package/public/skills/superpowers/writing-skills/anthropic-best-practices.md +0 -1150
  325. package/public/skills/superpowers/writing-skills/examples/CLAUDE_MD_TESTING.md +0 -189
  326. package/public/skills/superpowers/writing-skills/graphviz-conventions.dot +0 -172
  327. package/public/skills/superpowers/writing-skills/persuasion-principles.md +0 -187
  328. package/public/skills/superpowers/writing-skills/render-graphs.js +0 -168
  329. package/public/skills/superpowers/writing-skills/testing-skills-with-subagents.md +0 -384
  330. /package/dist/web/_next/static/{e8w3vd9Eov_LDYWj_0zsE → rGXyAK8rgod1NjF3bLZAY}/_buildManifest.js +0 -0
  331. /package/dist/web/_next/static/{e8w3vd9Eov_LDYWj_0zsE → rGXyAK8rgod1NjF3bLZAY}/_clientMiddlewareManifest.js +0 -0
  332. /package/dist/web/_next/static/{e8w3vd9Eov_LDYWj_0zsE → rGXyAK8rgod1NjF3bLZAY}/_ssgManifest.js +0 -0
@@ -1,5 +1,12 @@
1
1
  import { exec } from 'node:child_process';
2
2
  import { listHooks } from '../storage/hook-store.js';
3
+ function logDebug(message, details) {
4
+ if (details) {
5
+ console.debug(`[HookEngine] ${message}`, details);
6
+ return;
7
+ }
8
+ console.debug(`[HookEngine] ${message}`);
9
+ }
3
10
  function matchToolName(matcher, toolName) {
4
11
  if (matcher === '*')
5
12
  return true;
@@ -8,7 +15,12 @@ function matchToolName(matcher, toolName) {
8
15
  const regex = new RegExp(matcher.slice(1, -1));
9
16
  return regex.test(toolName);
10
17
  }
11
- catch {
18
+ catch (error) {
19
+ console.warn(`[HookEngine] invalid matcher regex, falling back to exact match`, {
20
+ matcher,
21
+ toolName,
22
+ error: error.message,
23
+ });
12
24
  return matcher === toolName;
13
25
  }
14
26
  }
@@ -16,7 +28,8 @@ function matchToolName(matcher, toolName) {
16
28
  }
17
29
  function executeCommand(command, env, timeout) {
18
30
  return new Promise((resolve) => {
19
- exec(command, { env: { ...process.env, ...env }, timeout: Math.min(timeout, 30000) }, (error) => {
31
+ const cappedTimeout = Math.min(timeout, 30000);
32
+ exec(command, { env: { ...process.env, ...env }, timeout: cappedTimeout }, (error) => {
20
33
  if (error)
21
34
  console.warn(`[HookEngine] command error: ${error.message}`);
22
35
  resolve();
@@ -26,43 +39,101 @@ function executeCommand(command, env, timeout) {
26
39
  async function executeWebhook(url, body, timeout) {
27
40
  try {
28
41
  const controller = new AbortController();
29
- const timer = setTimeout(() => controller.abort(), Math.min(timeout, 30000));
30
- await fetch(url, {
42
+ const cappedTimeout = Math.min(timeout, 30000);
43
+ const timer = setTimeout(() => controller.abort(), cappedTimeout);
44
+ const response = await fetch(url, {
31
45
  method: 'POST',
32
46
  headers: { 'Content-Type': 'application/json' },
33
47
  body: JSON.stringify(body),
34
48
  signal: controller.signal,
35
49
  });
36
50
  clearTimeout(timer);
51
+ if (!response.ok) {
52
+ console.warn(`[HookEngine] webhook non-2xx response`, {
53
+ url,
54
+ status: response.status,
55
+ statusText: response.statusText,
56
+ });
57
+ }
37
58
  }
38
59
  catch (error) {
39
60
  console.warn(`[HookEngine] webhook error: ${error.message}`);
40
61
  }
41
62
  }
42
- async function executeRule(rule, phase, toolName, workspaceId, context) {
63
+ async function executeRule(rule, phase, matcherValue, workspaceId, context, hookName) {
43
64
  const timeout = rule.timeout ?? 10000;
65
+ const startedAt = Date.now();
66
+ logDebug('rule start', {
67
+ workspaceId,
68
+ phase,
69
+ hookName,
70
+ matcherValue,
71
+ matcher: rule.matcher,
72
+ type: rule.type,
73
+ timeout,
74
+ });
44
75
  if (rule.type === 'command' && rule.command) {
45
76
  await executeCommand(rule.command, {
46
- HOOK_TOOL_NAME: toolName,
77
+ HOOK_NAME: hookName ?? '',
78
+ HOOK_RULE_MATCHER: rule.matcher,
79
+ HOOK_RULE_TYPE: rule.type,
80
+ HOOK_RULE_TIMEOUT: String(timeout),
81
+ HOOK_EVENT_NAME: context.eventName ?? phase,
82
+ HOOK_EVENT_PAYLOAD: JSON.stringify(context.eventPayload ?? {}),
83
+ HOOK_MATCHER_VALUE: matcherValue,
84
+ HOOK_TOOL_NAME: matcherValue,
85
+ HOOK_TOOL_USE_ID: context.toolUseId ?? '',
47
86
  HOOK_TOOL_INPUT: JSON.stringify(context.toolInput ?? {}),
48
87
  HOOK_TOOL_RESULT: JSON.stringify(context.toolResult ?? ''),
49
88
  HOOK_WORKSPACE_ID: workspaceId,
50
89
  HOOK_PHASE: phase,
90
+ HOOK_TRIGGER_CHECKED_RULES: String(context.checkedRules ?? ''),
91
+ HOOK_TRIGGER_MATCHED_RULES: String(context.matchedRules ?? ''),
92
+ HOOK_TRIGGERED_AT: new Date().toISOString(),
51
93
  }, timeout);
52
94
  }
53
95
  else if (rule.type === 'webhook' && rule.url) {
54
96
  await executeWebhook(rule.url, {
55
97
  event: phase,
56
- toolName,
98
+ toolName: matcherValue,
99
+ matcherValue,
57
100
  toolInput: context.toolInput,
58
101
  toolResult: context.toolResult ?? undefined,
102
+ payload: context.eventPayload,
59
103
  timestamp: new Date().toISOString(),
60
104
  workspaceId,
61
105
  }, timeout);
62
106
  }
63
107
  else if (rule.type === 'script') {
64
- console.warn(`[HookEngine] script type not implemented, skipping rule in ${phase}`);
108
+ console.warn(`[HookEngine] script type not implemented, skipping rule`, {
109
+ workspaceId,
110
+ phase,
111
+ hookName,
112
+ matcherValue,
113
+ matcher: rule.matcher,
114
+ });
65
115
  }
116
+ else {
117
+ console.warn(`[HookEngine] invalid rule configuration, skipping rule`, {
118
+ workspaceId,
119
+ phase,
120
+ hookName,
121
+ matcherValue,
122
+ matcher: rule.matcher,
123
+ type: rule.type,
124
+ hasCommand: Boolean(rule.command),
125
+ hasUrl: Boolean(rule.url),
126
+ });
127
+ }
128
+ logDebug('rule finished', {
129
+ workspaceId,
130
+ phase,
131
+ hookName,
132
+ matcherValue,
133
+ matcher: rule.matcher,
134
+ type: rule.type,
135
+ durationMs: Date.now() - startedAt,
136
+ });
66
137
  }
67
138
  export class HookEngine {
68
139
  hooks = [];
@@ -72,6 +143,12 @@ export class HookEngine {
72
143
  }
73
144
  load() {
74
145
  this.hooks = listHooks(this.workspaceId);
146
+ logDebug('loaded hooks', {
147
+ workspaceId: this.workspaceId,
148
+ totalHooks: this.hooks.length,
149
+ enabledHooks: this.hooks.filter(h => h.enabled).length,
150
+ hookNames: this.hooks.map(h => h.name),
151
+ });
75
152
  }
76
153
  reload() {
77
154
  this.load();
@@ -79,40 +156,121 @@ export class HookEngine {
79
156
  getHooks() {
80
157
  return this.hooks;
81
158
  }
82
- async executeHooks(phase, toolName, context) {
159
+ async executeHooks(phase, matcherValue, context) {
83
160
  const enabledHooks = this.hooks.filter(h => h.enabled);
84
161
  const promises = [];
162
+ const matchedRuleEntries = [];
163
+ let checkedRules = 0;
164
+ let matchedRules = 0;
165
+ logDebug('trigger received', {
166
+ workspaceId: this.workspaceId,
167
+ phase,
168
+ matcherValue,
169
+ totalHooks: this.hooks.length,
170
+ enabledHooks: enabledHooks.length,
171
+ hasToolInput: context.toolInput !== undefined,
172
+ hasToolResult: context.toolResult !== undefined,
173
+ });
85
174
  for (const hook of enabledHooks) {
86
175
  const rules = hook.hooks[phase];
87
176
  if (!rules)
88
177
  continue;
89
178
  for (const rule of rules) {
90
- if (matchToolName(rule.matcher, toolName)) {
91
- promises.push(executeRule(rule, phase, toolName, this.workspaceId, context));
179
+ checkedRules += 1;
180
+ if (matchToolName(rule.matcher, matcherValue)) {
181
+ matchedRules += 1;
182
+ logDebug('rule matched', {
183
+ workspaceId: this.workspaceId,
184
+ phase,
185
+ hookName: hook.name,
186
+ matcherValue,
187
+ matcher: rule.matcher,
188
+ type: rule.type,
189
+ });
190
+ matchedRuleEntries.push({ hookName: hook.name, rule });
92
191
  }
93
192
  }
94
193
  }
95
- await Promise.allSettled(promises);
194
+ for (const { hookName, rule } of matchedRuleEntries) {
195
+ promises.push(executeRule(rule, phase, matcherValue, this.workspaceId, {
196
+ ...context,
197
+ checkedRules,
198
+ matchedRules,
199
+ }, hookName));
200
+ }
201
+ const results = await Promise.allSettled(promises);
202
+ const rejectedRules = results.filter(result => result.status === 'rejected').length;
203
+ logDebug('trigger finished', {
204
+ workspaceId: this.workspaceId,
205
+ phase,
206
+ matcherValue,
207
+ checkedRules,
208
+ matchedRules,
209
+ rejectedRules,
210
+ });
96
211
  }
97
212
  }
98
213
  export function wrapOnEventWithHooks(onEvent, workspaceId, hooksEnabled) {
99
- if (!hooksEnabled)
214
+ if (!hooksEnabled) {
215
+ logDebug('hooks disabled for workspace', { workspaceId });
100
216
  return onEvent;
217
+ }
101
218
  const engine = new HookEngine(workspaceId);
102
219
  engine.load();
103
220
  const toolNameById = new Map();
221
+ let lastToolUse = null;
104
222
  return (event) => {
105
- onEvent(event);
223
+ if (event.type !== 'hook_event')
224
+ onEvent(event);
106
225
  if (event.type === 'tool_use') {
107
226
  toolNameById.set(event.id, event.name);
108
- engine.executeHooks('PreToolUse', event.name, { toolInput: event.input });
227
+ lastToolUse = { id: event.id, name: event.name };
228
+ logDebug('tool_use event mapped', {
229
+ workspaceId,
230
+ toolUseId: event.id,
231
+ toolName: event.name,
232
+ });
233
+ engine.executeHooks('PreToolUse', event.name, { toolInput: event.input, toolUseId: event.id });
109
234
  }
110
235
  if (event.type === 'tool_result') {
111
- const toolName = event.toolUseId ? (toolNameById.get(event.toolUseId) ?? '') : '';
236
+ const resolvedToolUseId = event.toolUseId || lastToolUse?.id;
237
+ const toolName = resolvedToolUseId ? (toolNameById.get(resolvedToolUseId) ?? '') : '';
112
238
  if (toolName) {
113
- engine.executeHooks('PostToolUse', toolName, { toolResult: event.result });
239
+ logDebug('tool_result event resolved', {
240
+ workspaceId,
241
+ toolUseId: resolvedToolUseId,
242
+ originalToolUseId: event.toolUseId,
243
+ toolName,
244
+ });
245
+ engine.executeHooks('PostToolUse', toolName, { toolResult: event.result, toolUseId: resolvedToolUseId });
246
+ if (isToolFailureResult(event.result)) {
247
+ engine.executeHooks('PostToolUseFailure', toolName, { toolResult: event.result, toolUseId: resolvedToolUseId });
248
+ }
249
+ }
250
+ else {
251
+ logDebug('tool_result event skipped without matching tool_use', {
252
+ workspaceId,
253
+ toolUseId: event.toolUseId,
254
+ });
114
255
  }
115
256
  }
257
+ if (event.type === 'hook_event') {
258
+ logDebug('hook_event received', {
259
+ workspaceId,
260
+ event: event.event,
261
+ matcher: event.matcher ?? '*',
262
+ });
263
+ engine.executeHooks(event.event, event.matcher ?? '*', {
264
+ eventName: event.event,
265
+ eventPayload: event.payload,
266
+ });
267
+ }
116
268
  };
117
269
  }
270
+ function isToolFailureResult(result) {
271
+ if (!result || typeof result !== 'object')
272
+ return false;
273
+ const record = result;
274
+ return record.error !== undefined || record.is_error === true || record.success === false;
275
+ }
118
276
  //# sourceMappingURL=hook-engine.js.map
@@ -46,6 +46,15 @@ export function clearAll(workspaceId) {
46
46
  writeAll(workspaceId, []);
47
47
  broadcastToWorkspace(workspaceId, 'notification.cleared', null);
48
48
  }
49
+ export function removeNotification(workspaceId, notificationId) {
50
+ const all = readAll(workspaceId);
51
+ const idx = all.findIndex((n) => n.id === notificationId);
52
+ if (idx === -1)
53
+ return null;
54
+ const [removed] = all.splice(idx, 1);
55
+ writeAll(workspaceId, all);
56
+ return removed;
57
+ }
49
58
  export function unreadCount(workspaceId) {
50
59
  return readAll(workspaceId).filter((n) => !n.read).length;
51
60
  }
@@ -28,7 +28,8 @@ export async function runBotAgent(workspaceId, preset, message) {
28
28
  const workingDir = agentService.resolveWorkingDir(workspaceId, preset);
29
29
  const workspace = workspaceService.getById(workspaceId);
30
30
  try {
31
- const result = await runtime.execute(prependPersistentAgentContext(buildBotPrompt(message), {
31
+ const userPrompt = buildBotPrompt(message);
32
+ const result = await runtime.execute(prependPersistentAgentContext(userPrompt, {
32
33
  workspaceId,
33
34
  workingDir,
34
35
  boundDirs: workspace?.boundDirs,
@@ -36,6 +37,7 @@ export async function runBotAgent(workspaceId, preset, message) {
36
37
  excludeNativeClaudeMd: preset.runtimeKind === 'claude-code',
37
38
  }), workingDir, {
38
39
  maxTurns: 20,
40
+ userPrompt,
39
41
  mcpServers: agentService.getMcpServers(preset.mcps),
40
42
  skills: agentService.getAvailableSkillNames(agentService.getAgentConfigDir(workspaceId, preset), preset.skills),
41
43
  configDir: agentService.getAgentConfigDir(workspaceId, preset),
@@ -1,4 +1,5 @@
1
1
  import * as workspaceService from '../workspace.js';
2
+ import { resolveCredentials } from '../robot-account.js';
2
3
  import { adapters } from './types.js';
3
4
  import { persistServiceRunning } from './helpers.js';
4
5
  import { WeChatNotificationAdapter } from './wechat-adapter.js';
@@ -9,15 +10,24 @@ export async function startWorkspaceNotificationService(workspaceId) {
9
10
  if (!workspace || !settings?.enabled)
10
11
  return { started: false };
11
12
  await stopWorkspaceNotificationService(workspaceId);
13
+ const credentials = resolveCredentials(settings);
12
14
  if (settings.provider === 'lark') {
13
- const adapter = new LarkNotificationAdapter(workspace, settings);
15
+ if (!credentials || credentials.type !== 'lark') {
16
+ throw new Error('Lark credentials not found. Link a Robot Account or configure appId/appSecret.');
17
+ }
18
+ const mergedSettings = { ...settings, lark: { ...settings.lark, appId: credentials.appId, appSecret: credentials.appSecret } };
19
+ const adapter = new LarkNotificationAdapter(workspace, mergedSettings);
14
20
  await adapter.start();
15
21
  adapters.set(workspaceId, adapter);
16
22
  persistServiceRunning(workspaceId, true);
17
23
  return { started: true, provider: 'lark' };
18
24
  }
19
25
  if (settings.provider === 'wechat') {
20
- const adapter = new WeChatNotificationAdapter(workspace, settings);
26
+ if (!credentials || credentials.type !== 'wechat') {
27
+ throw new Error('WeChat credentials not found. Link a Robot Account or scan QR code first.');
28
+ }
29
+ const mergedSettings = { ...settings, wechat: { ...settings.wechat, token: credentials.token, baseUrl: credentials.baseUrl, accountId: credentials.accountId, userId: credentials.userId } };
30
+ const adapter = new WeChatNotificationAdapter(workspace, mergedSettings);
21
31
  await adapter.start();
22
32
  adapters.set(workspaceId, adapter);
23
33
  persistServiceRunning(workspaceId, true);
@@ -0,0 +1,34 @@
1
+ import { v4 as uuid } from 'uuid';
2
+ import { listRobotAccounts, getRobotAccount, createRobotAccount, updateRobotAccount, deleteRobotAccount } from '../storage/robot-account-store.js';
3
+ export { listRobotAccounts, getRobotAccount, deleteRobotAccount };
4
+ export function createAccount(input) {
5
+ const now = new Date().toISOString();
6
+ const account = { id: uuid(), name: input.name, type: input.type, lark: input.lark, wechat: input.wechat, createdAt: now, updatedAt: now };
7
+ createRobotAccount(account);
8
+ return account;
9
+ }
10
+ export function updateAccount(id, patch) {
11
+ return updateRobotAccount(id, patch);
12
+ }
13
+ export function resolveCredentials(settings) {
14
+ if (settings.robotAccountId) {
15
+ const account = getRobotAccount(settings.robotAccountId);
16
+ if (account) {
17
+ if (account.type === 'lark' && account.lark) {
18
+ return { type: 'lark', appId: account.lark.appId, appSecret: account.lark.appSecret };
19
+ }
20
+ if (account.type === 'wechat' && account.wechat) {
21
+ return { type: 'wechat', token: account.wechat.token, baseUrl: account.wechat.baseUrl || 'https://qyapi.weixin.qq.com', accountId: account.wechat.accountId, userId: account.wechat.userId };
22
+ }
23
+ }
24
+ }
25
+ // fallback to inline credentials
26
+ if (settings.provider === 'lark' && settings.lark?.appId && settings.lark?.appSecret) {
27
+ return { type: 'lark', appId: settings.lark.appId, appSecret: settings.lark.appSecret };
28
+ }
29
+ if (settings.provider === 'wechat' && settings.wechat?.token && settings.wechat?.accountId) {
30
+ return { type: 'wechat', token: settings.wechat.token, baseUrl: settings.wechat.baseUrl || 'https://qyapi.weixin.qq.com', accountId: settings.wechat.accountId, userId: settings.wechat.userId };
31
+ }
32
+ return null;
33
+ }
34
+ //# sourceMappingURL=robot-account.js.map
@@ -0,0 +1,59 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { join, dirname } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ const __dirname = dirname(fileURLToPath(import.meta.url));
5
+ let localVersion = '';
6
+ let cachedLatest = null;
7
+ const CACHE_TTL = 3600_000; // 1 hour
8
+ export function getLocalVersion() {
9
+ if (localVersion !== '')
10
+ return localVersion;
11
+ try {
12
+ const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8'));
13
+ localVersion = pkg.version || '0.0.0';
14
+ }
15
+ catch {
16
+ localVersion = '0.0.0';
17
+ }
18
+ return localVersion;
19
+ }
20
+ export function getCachedLatest() {
21
+ if (cachedLatest && Date.now() - cachedLatest.ts < CACHE_TTL) {
22
+ return cachedLatest.version;
23
+ }
24
+ return null;
25
+ }
26
+ export async function fetchLatestVersion(forceRefresh = false) {
27
+ if (!forceRefresh && cachedLatest && Date.now() - cachedLatest.ts < CACHE_TTL) {
28
+ return cachedLatest.version;
29
+ }
30
+ try {
31
+ const res = await fetch('https://registry.npmjs.org/@agent-spaces/server', {
32
+ signal: AbortSignal.timeout(8000),
33
+ });
34
+ if (!res.ok)
35
+ return cachedLatest?.version ?? null;
36
+ const data = await res.json();
37
+ const latest = data?.['dist-tags']?.latest;
38
+ if (latest) {
39
+ cachedLatest = { version: latest, ts: Date.now() };
40
+ }
41
+ return latest ?? cachedLatest?.version ?? null;
42
+ }
43
+ catch {
44
+ return cachedLatest?.version ?? null;
45
+ }
46
+ }
47
+ export function isNewerVersion(latest, local) {
48
+ const parse = (v) => v.replace(/^v/, '').split('.').map(Number);
49
+ const a = parse(latest);
50
+ const b = parse(local);
51
+ for (let i = 0; i < 3; i++) {
52
+ if ((a[i] || 0) > (b[i] || 0))
53
+ return true;
54
+ if ((a[i] || 0) < (b[i] || 0))
55
+ return false;
56
+ }
57
+ return false;
58
+ }
59
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1,23 @@
1
+ import { exec } from 'child_process';
2
+ import { getWorkspace } from '../storage/workspace-store.js';
3
+ export async function executeCommandNode(workspaceId, node) {
4
+ const workspace = getWorkspace(workspaceId);
5
+ const cwd = node.data.cwd || workspace?.boundDirs?.[0] || process.cwd();
6
+ return new Promise((resolve) => {
7
+ exec(node.data.script, {
8
+ cwd,
9
+ env: { ...process.env, ...node.data.env },
10
+ shell: node.data.shell || undefined,
11
+ timeout: 300_000,
12
+ maxBuffer: 10 * 1024 * 1024,
13
+ }, (error, stdout, stderr) => {
14
+ resolve({
15
+ success: !error,
16
+ exitCode: error ? (typeof error.code === 'number' ? error.code : 1) : 0,
17
+ stdout: stdout || '',
18
+ stderr: stderr || '',
19
+ });
20
+ });
21
+ });
22
+ }
23
+ //# sourceMappingURL=workflow-command-runner.js.map
@@ -72,6 +72,8 @@ function resolveStaleRoles(nodes) {
72
72
  const agentMap = new Map(listTemplates().map(a => [a.id, a]));
73
73
  const invalidIds = [];
74
74
  const resolved = nodes.map(node => {
75
+ if (node.type === 'command')
76
+ return node;
75
77
  const agent = agentMap.get(node.data.agentConfigId);
76
78
  if (!agent) {
77
79
  invalidIds.push(node.id);
@@ -177,19 +179,34 @@ export function mapWorkflowToTaskDrafts(template) {
177
179
  for (const edge of template.edges) {
178
180
  dependsOn.get(edge.target)?.push(edge.source);
179
181
  }
180
- return template.nodes.map(node => ({
181
- key: node.id,
182
- title: node.data.taskTitleTemplate || node.data.label,
183
- description: node.data.taskDescriptionTemplate || `Task assigned to ${node.data.label} (${node.data.role})`,
184
- agentConfigId: node.data.agentConfigId,
185
- dependsOnKeys: dependsOn.get(node.id)?.length ? dependsOn.get(node.id) : undefined,
186
- sandboxDirs: undefined,
187
- }));
182
+ return template.nodes.map(node => {
183
+ if (node.type === 'command') {
184
+ return {
185
+ key: node.id,
186
+ title: node.data.label,
187
+ description: `Run command: ${node.data.label}`,
188
+ agentConfigId: undefined,
189
+ dependsOnKeys: dependsOn.get(node.id)?.length ? dependsOn.get(node.id) : undefined,
190
+ sandboxDirs: undefined,
191
+ commandNode: node,
192
+ };
193
+ }
194
+ return {
195
+ key: node.id,
196
+ title: node.data.taskTitleTemplate || node.data.label,
197
+ description: node.data.taskDescriptionTemplate || `Task assigned to ${node.data.label} (${node.data.role})`,
198
+ agentConfigId: node.data.agentConfigId,
199
+ dependsOnKeys: dependsOn.get(node.id)?.length ? dependsOn.get(node.id) : undefined,
200
+ sandboxDirs: undefined,
201
+ };
202
+ });
188
203
  }
189
204
  // --- Run-time Validation ---
190
205
  export function validateWorkflowForRun(_workspaceId, template, memberAgentIds) {
191
206
  const agentMap = new Map(listTemplates().map((a) => [a.id, a]));
192
207
  for (const node of template.nodes) {
208
+ if (node.type === 'command')
209
+ continue;
193
210
  const agent = agentMap.get(node.data.agentConfigId);
194
211
  if (!agent)
195
212
  return `Agent "${node.data.label}" (${node.data.agentConfigId}) no longer exists`;
@@ -1,5 +1,6 @@
1
1
  import { v4 as uuid } from 'uuid';
2
2
  import { listWorkspaces, getWorkspace, createWorkspace, updateWorkspace, deleteWorkspace } from '../storage/workspace-store.js';
3
+ import { listWorktrees } from '../storage/worktree-store.js';
3
4
  import { ensureDir } from '../storage/json-store.js';
4
5
  import { join } from 'node:path';
5
6
  import { existsSync, writeFileSync } from 'node:fs';
@@ -21,7 +22,14 @@ function initAgentspace(agentspaceDir) {
21
22
  }
22
23
  }
23
24
  export function getAll() {
24
- return listWorkspaces();
25
+ const workspaces = listWorkspaces();
26
+ const workspaceIds = new Set(workspaces.map((workspace) => workspace.id));
27
+ const worktreeWorkspaces = workspaces
28
+ .filter((workspace) => !workspace.isWorktree)
29
+ .flatMap((workspace) => listWorktrees(workspace.id)
30
+ .filter((worktree) => worktree.status === 'active' && !workspaceIds.has(worktree.id))
31
+ .map(worktreeToWorkspace));
32
+ return [...workspaces, ...worktreeWorkspaces];
25
33
  }
26
34
  export function getById(id) {
27
35
  return getWorkspace(id);
@@ -59,6 +67,8 @@ export function update(id, data) {
59
67
  allowed.autoProcessIssues = data.autoProcessIssues;
60
68
  if (Object.hasOwn(data, 'notificationSettings'))
61
69
  allowed.notificationSettings = data.notificationSettings;
70
+ if (Object.hasOwn(data, 'hooksEnabled'))
71
+ allowed.hooksEnabled = data.hooksEnabled;
62
72
  Object.assign(ws, allowed, { updatedAt: new Date().toISOString() });
63
73
  updateWorkspace(ws);
64
74
  return ws;
@@ -70,4 +80,18 @@ export function remove(id) {
70
80
  deleteWorkspace(id);
71
81
  return true;
72
82
  }
83
+ function worktreeToWorkspace(worktree) {
84
+ return {
85
+ id: worktree.id,
86
+ name: `${worktree.name} (Worktree)`,
87
+ boundDirs: [worktree.path],
88
+ agentspaceDir: join(worktree.path, '.agentspace'),
89
+ isWorktree: true,
90
+ parentWorkspaceId: worktree.workspaceId,
91
+ createdAt: worktree.createdAt,
92
+ updatedAt: worktree.updatedAt,
93
+ activeChannels: [],
94
+ activeIssues: [],
95
+ };
96
+ }
73
97
  //# sourceMappingURL=workspace.js.map