@agent-spaces/server 0.3.63 → 0.3.65

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 (334) hide show
  1. package/dist/adapters/claude-code-runtime/index.js +68 -2
  2. package/dist/adapters/claude-code-runtime/message-format.js +27 -1
  3. package/dist/adapters/claude-code-runtime/sdk-config.js +12 -0
  4. package/dist/adapters/git.js +168 -57
  5. package/dist/agents/agent-designer.js +66 -12
  6. package/dist/agents/agent-message-parts.js +1 -1
  7. package/dist/agents/commit-agent.js +4 -2
  8. package/dist/agents/issue-task-controller.js +7 -3
  9. package/dist/app.js +56 -69
  10. package/dist/package.json +1 -1
  11. package/dist/routes/agent-commands.js +72 -0
  12. package/dist/routes/agent-sse.js +7 -0
  13. package/dist/routes/agent.js +18 -1
  14. package/dist/routes/database.js +346 -0
  15. package/dist/routes/git.js +198 -267
  16. package/dist/routes/kanban.js +39 -0
  17. package/dist/routes/robot-account.js +68 -0
  18. package/dist/services/agent-commands.js +168 -0
  19. package/dist/services/agent.js +36 -2
  20. package/dist/services/builtin-tools/command-tools.js +117 -0
  21. package/dist/services/builtin-tools/database-tools.js +578 -0
  22. package/dist/services/builtin-tools/index.js +5 -0
  23. package/dist/services/builtin-tools/input-helpers.js +26 -0
  24. package/dist/services/builtin-tools/issue-tools.js +209 -0
  25. package/dist/services/builtin-tools/kanban-tools.js +281 -0
  26. package/dist/services/database-vector.js +244 -0
  27. package/dist/services/git-operation-log.js +40 -0
  28. package/dist/services/global-wechat-qr.js +72 -0
  29. package/dist/services/hook-engine.js +175 -17
  30. package/dist/services/kanban.js +50 -0
  31. package/dist/services/notification-hub/bot-agent.js +3 -1
  32. package/dist/services/notification-hub/service.js +12 -2
  33. package/dist/services/robot-account.js +34 -0
  34. package/dist/services/workspace.js +2 -0
  35. package/dist/storage/database-store.js +365 -0
  36. package/dist/storage/kanban-store.js +142 -0
  37. package/dist/storage/robot-account-store.js +39 -0
  38. package/dist/web/404.html +1 -1
  39. package/dist/web/__next.__PAGE__.txt +4 -4
  40. package/dist/web/__next._full.txt +24 -31
  41. package/dist/web/__next._head.txt +4 -4
  42. package/dist/web/__next._index.txt +14 -14
  43. package/dist/web/__next._tree.txt +3 -8
  44. package/dist/web/_next/static/chunks/0-a.-hl3wv99k.js +1 -0
  45. package/dist/web/_next/static/chunks/{0ctg5qmw7uu.1.js → 0-pi.67w.ymsr.js} +3 -3
  46. package/dist/web/_next/static/chunks/0-v_p6j5u3_9l.js +1 -0
  47. package/dist/web/_next/static/chunks/0.-x29t-8gk0r.js +1 -0
  48. package/dist/web/_next/static/chunks/0.6b64sy0g5.3.js +3 -0
  49. package/dist/web/_next/static/chunks/0.l5e8~r7_0~p.js +1 -0
  50. package/dist/web/_next/static/chunks/00-syqzi-6zxr.js +1 -0
  51. package/dist/web/_next/static/chunks/{13~y-b.b9rrw4.js → 01~quun6sefgl.js} +1 -1
  52. package/dist/web/_next/static/chunks/02802taez976w.js +67 -0
  53. package/dist/web/_next/static/chunks/02j4sr9psucf-.js +1 -0
  54. package/dist/web/_next/static/chunks/033.awk90g6eh.js +1 -0
  55. package/dist/web/_next/static/chunks/06.kdsa9rr2h1.js +1 -0
  56. package/dist/web/_next/static/chunks/{0-oog4zg4_m~m.css → 062f9zqctzg.b.css} +0 -3
  57. package/dist/web/_next/static/chunks/06si8l0doqe8p.js +1 -0
  58. package/dist/web/_next/static/chunks/08ugbvzr20drp.js +2 -0
  59. package/dist/web/_next/static/chunks/{0kof5qdg8c2-k.js → 08x85faoz58i7.js} +37 -37
  60. package/dist/web/_next/static/chunks/0_cqojbge48kq.js +5 -0
  61. package/dist/web/_next/static/chunks/0_mvduwjsm35w.js +1 -0
  62. package/dist/web/_next/static/chunks/0d6~~lv0-6kex.js +3 -0
  63. package/dist/web/_next/static/chunks/{0ogpc3f3keopc.js → 0db14450oqzhg.js} +2 -2
  64. package/dist/web/_next/static/chunks/0fttswpzu69qx.js +1 -0
  65. package/dist/web/_next/static/chunks/0gdwop9cnpmtu.js +1 -0
  66. package/dist/web/_next/static/chunks/0ghx3j_.-gdyd.js +1 -0
  67. package/dist/web/_next/static/chunks/0j-l7l_k9jt45.js +1 -0
  68. package/dist/web/_next/static/chunks/0k4zdm72k_bfy.js +1 -0
  69. package/dist/web/_next/static/chunks/0kbvoxla7f751.js +1 -0
  70. package/dist/web/_next/static/chunks/{0aa6bcdmtpekn.js → 0l2w0qz1ea7ql.js} +2 -2
  71. package/dist/web/_next/static/chunks/0p3h-h3zj5ujg.js +30 -0
  72. package/dist/web/_next/static/chunks/0paaat8y96ayc.js +7 -0
  73. package/dist/web/_next/static/chunks/0pm-un~-sy3rl.js +1 -0
  74. package/dist/web/_next/static/chunks/0pq318f8xgafg.js +1 -0
  75. package/dist/web/_next/static/chunks/0t6s8of0qr6nc.js +1 -0
  76. package/dist/web/_next/static/chunks/0u6h-hqc_i52e.js +1 -0
  77. package/dist/web/_next/static/chunks/0uxzi~9b~k4mn.js +31 -0
  78. package/dist/web/_next/static/chunks/{002-dxhags4dj.js → 0v6hte2z-32ca.js} +2 -2
  79. package/dist/web/_next/static/chunks/{014x2qbuiszni.js → 0vis~lx0nxgn-.js} +3 -3
  80. package/dist/web/_next/static/chunks/{0y09i51u6ixq5.js → 0w7.tb29958zj.js} +1 -1
  81. package/dist/web/_next/static/chunks/0xbaakj0dfc0..js +1 -0
  82. package/dist/web/_next/static/chunks/0yd.m1afqg.2t.js +3 -0
  83. package/dist/web/_next/static/chunks/0yhbr8hl09b-5.js +1 -0
  84. package/dist/web/_next/static/chunks/0zncg76rgtbm-.js +1 -0
  85. package/dist/web/_next/static/chunks/0z~vqzbm_q371.js +1 -0
  86. package/dist/web/_next/static/chunks/0~~_ltu6dx_ch.js +1 -0
  87. package/dist/web/_next/static/chunks/{02c22g~xd-y30.js → 11cchuwoupmbf.js} +2 -2
  88. package/dist/web/_next/static/chunks/12jm4gwmvq-0q.js +90 -0
  89. package/dist/web/_next/static/chunks/12oxcgyhpaxw~.js +1 -0
  90. package/dist/web/_next/static/chunks/1452eibz62gs6.css +1 -0
  91. package/dist/web/_next/static/chunks/16zlreiems5cn.js +1 -0
  92. package/dist/web/_next/static/chunks/18awqjk9-o5m0.js +1 -0
  93. package/dist/web/_next/static/chunks/18c7g84y01mj0.js +1 -0
  94. package/dist/web/_next/static/chunks/{turbopack-0ndm2zc_pdptk.js → turbopack-11qjwlynmfc-n.js} +1 -1
  95. package/dist/web/_not-found/__next._full.txt +31 -30
  96. package/dist/web/_not-found/__next._head.txt +4 -4
  97. package/dist/web/_not-found/__next._index.txt +14 -14
  98. package/dist/web/_not-found/__next._not-found.__PAGE__.txt +2 -2
  99. package/dist/web/_not-found/__next._not-found.txt +3 -3
  100. package/dist/web/_not-found/__next._tree.txt +3 -3
  101. package/dist/web/_not-found.html +1 -1
  102. package/dist/web/_not-found.txt +31 -30
  103. package/dist/web/index.html +1 -1
  104. package/dist/web/index.txt +24 -31
  105. package/dist/web/login/__next._full.txt +32 -36
  106. package/dist/web/login/__next._head.txt +4 -4
  107. package/dist/web/login/__next._index.txt +14 -14
  108. package/dist/web/login/__next._tree.txt +3 -8
  109. package/dist/web/login/__next.login.__PAGE__.txt +4 -4
  110. package/dist/web/login/__next.login.txt +3 -3
  111. package/dist/web/login.html +1 -1
  112. package/dist/web/login.txt +32 -36
  113. package/dist/web/settings/__next._full.txt +34 -38
  114. package/dist/web/settings/__next._head.txt +4 -4
  115. package/dist/web/settings/__next._index.txt +14 -14
  116. package/dist/web/settings/__next._tree.txt +3 -8
  117. package/dist/web/settings/__next.settings.__PAGE__.txt +4 -4
  118. package/dist/web/settings/__next.settings.txt +5 -5
  119. package/dist/web/settings/agents/__next._full.txt +27 -32
  120. package/dist/web/settings/agents/__next._head.txt +4 -4
  121. package/dist/web/settings/agents/__next._index.txt +14 -14
  122. package/dist/web/settings/agents/__next._tree.txt +3 -8
  123. package/dist/web/settings/agents/__next.settings.agents.__PAGE__.txt +4 -4
  124. package/dist/web/settings/agents/__next.settings.agents.txt +3 -3
  125. package/dist/web/settings/agents/__next.settings.txt +5 -5
  126. package/dist/web/settings/agents.html +1 -1
  127. package/dist/web/settings/agents.txt +27 -32
  128. package/dist/web/settings/mcps/__next._full.txt +27 -32
  129. package/dist/web/settings/mcps/__next._head.txt +4 -4
  130. package/dist/web/settings/mcps/__next._index.txt +14 -14
  131. package/dist/web/settings/mcps/__next._tree.txt +3 -8
  132. package/dist/web/settings/mcps/__next.settings.mcps.__PAGE__.txt +4 -4
  133. package/dist/web/settings/mcps/__next.settings.mcps.txt +3 -3
  134. package/dist/web/settings/mcps/__next.settings.txt +5 -5
  135. package/dist/web/settings/mcps.html +1 -1
  136. package/dist/web/settings/mcps.txt +27 -32
  137. package/dist/web/settings/models/__next._full.txt +27 -32
  138. package/dist/web/settings/models/__next._head.txt +4 -4
  139. package/dist/web/settings/models/__next._index.txt +14 -14
  140. package/dist/web/settings/models/__next._tree.txt +3 -8
  141. package/dist/web/settings/models/__next.settings.models.__PAGE__.txt +4 -4
  142. package/dist/web/settings/models/__next.settings.models.txt +3 -3
  143. package/dist/web/settings/models/__next.settings.txt +5 -5
  144. package/dist/web/settings/models.html +1 -1
  145. package/dist/web/settings/models.txt +27 -32
  146. package/dist/web/settings/output-styles/__next._full.txt +27 -32
  147. package/dist/web/settings/output-styles/__next._head.txt +4 -4
  148. package/dist/web/settings/output-styles/__next._index.txt +14 -14
  149. package/dist/web/settings/output-styles/__next._tree.txt +3 -8
  150. package/dist/web/settings/output-styles/__next.settings.output-styles.__PAGE__.txt +4 -4
  151. package/dist/web/settings/output-styles/__next.settings.output-styles.txt +3 -3
  152. package/dist/web/settings/output-styles/__next.settings.txt +5 -5
  153. package/dist/web/settings/output-styles.html +1 -1
  154. package/dist/web/settings/output-styles.txt +27 -32
  155. package/dist/web/settings/prompts/__next._full.txt +27 -32
  156. package/dist/web/settings/prompts/__next._head.txt +4 -4
  157. package/dist/web/settings/prompts/__next._index.txt +14 -14
  158. package/dist/web/settings/prompts/__next._tree.txt +3 -8
  159. package/dist/web/settings/prompts/__next.settings.prompts.__PAGE__.txt +4 -4
  160. package/dist/web/settings/prompts/__next.settings.prompts.txt +3 -3
  161. package/dist/web/settings/prompts/__next.settings.txt +5 -5
  162. package/dist/web/settings/prompts.html +1 -1
  163. package/dist/web/settings/prompts.txt +27 -32
  164. package/dist/web/settings/providers/__next._full.txt +27 -32
  165. package/dist/web/settings/providers/__next._head.txt +4 -4
  166. package/dist/web/settings/providers/__next._index.txt +14 -14
  167. package/dist/web/settings/providers/__next._tree.txt +3 -8
  168. package/dist/web/settings/providers/__next.settings.providers.__PAGE__.txt +4 -4
  169. package/dist/web/settings/providers/__next.settings.providers.txt +3 -3
  170. package/dist/web/settings/providers/__next.settings.txt +5 -5
  171. package/dist/web/settings/providers.html +1 -1
  172. package/dist/web/settings/providers.txt +27 -32
  173. package/dist/web/settings/skills/__next._full.txt +27 -32
  174. package/dist/web/settings/skills/__next._head.txt +4 -4
  175. package/dist/web/settings/skills/__next._index.txt +14 -14
  176. package/dist/web/settings/skills/__next._tree.txt +3 -8
  177. package/dist/web/settings/skills/__next.settings.skills.__PAGE__.txt +4 -4
  178. package/dist/web/settings/skills/__next.settings.skills.txt +3 -3
  179. package/dist/web/settings/skills/__next.settings.txt +5 -5
  180. package/dist/web/settings/skills.html +1 -1
  181. package/dist/web/settings/skills.txt +27 -32
  182. package/dist/web/settings/tools/__next._full.txt +38 -0
  183. package/dist/web/settings/tools/__next._head.txt +6 -0
  184. package/dist/web/settings/tools/__next._index.txt +15 -0
  185. package/dist/web/settings/tools/__next._tree.txt +3 -0
  186. package/dist/web/settings/tools/__next.settings.tools.__PAGE__.txt +9 -0
  187. package/dist/web/settings/tools/__next.settings.tools.txt +5 -0
  188. package/dist/web/settings/tools/__next.settings.txt +7 -0
  189. package/dist/web/settings/tools.html +1 -0
  190. package/dist/web/settings/tools.txt +38 -0
  191. package/dist/web/settings.html +1 -1
  192. package/dist/web/settings.txt +34 -38
  193. package/dist/web/workflows/__next._full.txt +32 -38
  194. package/dist/web/workflows/__next._head.txt +4 -4
  195. package/dist/web/workflows/__next._index.txt +14 -14
  196. package/dist/web/workflows/__next._tree.txt +3 -8
  197. package/dist/web/workflows/__next.workflows.__PAGE__.txt +4 -4
  198. package/dist/web/workflows/__next.workflows.txt +3 -3
  199. package/dist/web/workflows.html +1 -1
  200. package/dist/web/workflows.txt +32 -38
  201. package/dist/web/workspace/_/__next._full.txt +31 -36
  202. package/dist/web/workspace/_/__next._head.txt +4 -4
  203. package/dist/web/workspace/_/__next._index.txt +14 -14
  204. package/dist/web/workspace/_/__next._tree.txt +4 -8
  205. package/dist/web/workspace/_/__next.workspace.$d$id.__PAGE__.txt +3 -3
  206. package/dist/web/workspace/_/__next.workspace.$d$id.txt +3 -3
  207. package/dist/web/workspace/_/__next.workspace.txt +3 -3
  208. package/dist/web/workspace/_.html +1 -1
  209. package/dist/web/workspace/_.txt +31 -36
  210. package/dist/web/workspaces/__next._full.txt +30 -37
  211. package/dist/web/workspaces/__next._head.txt +4 -4
  212. package/dist/web/workspaces/__next._index.txt +14 -14
  213. package/dist/web/workspaces/__next._tree.txt +3 -8
  214. package/dist/web/workspaces/__next.workspaces.__PAGE__.txt +4 -4
  215. package/dist/web/workspaces/__next.workspaces.txt +3 -3
  216. package/dist/web/workspaces.html +1 -1
  217. package/dist/web/workspaces.txt +30 -37
  218. package/dist/ws/agent-prompt.js +45 -8
  219. package/dist/ws/agent-runner.js +88 -10
  220. package/package.json +1 -1
  221. package/dist/web/_next/static/chunks/0-1bfvfwifh-m.js +0 -1
  222. package/dist/web/_next/static/chunks/02mf61htij8g0.js +0 -31
  223. package/dist/web/_next/static/chunks/046me66nilkff.js +0 -1
  224. package/dist/web/_next/static/chunks/04v-pqqs-2lvp.css +0 -1
  225. package/dist/web/_next/static/chunks/06w~.izyfylap.js +0 -1
  226. package/dist/web/_next/static/chunks/09t62a89~jesc.js +0 -3
  227. package/dist/web/_next/static/chunks/09y_3krccdd~u.js +0 -1
  228. package/dist/web/_next/static/chunks/0_e~hmntdfop9.js +0 -1
  229. package/dist/web/_next/static/chunks/0_udc.6.tueey.js +0 -1
  230. package/dist/web/_next/static/chunks/0cke33d38fnby.js +0 -90
  231. package/dist/web/_next/static/chunks/0cyq~8xb~r5fc.js +0 -1
  232. package/dist/web/_next/static/chunks/0ewceguykiut5.js +0 -1
  233. package/dist/web/_next/static/chunks/0fxa1edqr7dve.js +0 -1
  234. package/dist/web/_next/static/chunks/0hra80eyuu37u.js +0 -1
  235. package/dist/web/_next/static/chunks/0ie7y4k2ncvnn.js +0 -1
  236. package/dist/web/_next/static/chunks/0igc~uli58ncw.js +0 -2
  237. package/dist/web/_next/static/chunks/0msb2mi3hiu5_.js +0 -67
  238. package/dist/web/_next/static/chunks/0p1n8bvfnpl41.js +0 -1
  239. package/dist/web/_next/static/chunks/0ppr271hz0xoq.js +0 -1
  240. package/dist/web/_next/static/chunks/0s_dva~eh2yhi.js +0 -3
  241. package/dist/web/_next/static/chunks/0typj55ox8d5i.js +0 -1
  242. package/dist/web/_next/static/chunks/0w2p4ldi2aymp.js +0 -1
  243. package/dist/web/_next/static/chunks/0zc0xgp5ourcn.js +0 -1
  244. package/dist/web/_next/static/chunks/0zmhdridea1s5.js +0 -90
  245. package/dist/web/_next/static/chunks/10.alq.6stmld.js +0 -1
  246. package/dist/web/_next/static/chunks/11b3zgk1etlkw.js +0 -7
  247. package/dist/web/_next/static/chunks/11qp8r5dotf7d.js +0 -1
  248. package/dist/web/_next/static/chunks/12mxlicp247c8.js +0 -1
  249. package/dist/web/_next/static/chunks/135w27dd8c19s.js +0 -5
  250. package/dist/web/_next/static/chunks/176dc-dtokxxi.js +0 -16
  251. package/dist/web/_next/static/chunks/17g-0pqre.anw.js +0 -1
  252. package/dist/web/_next/static/media/0a7740363b4d4863-s.1110aazvokzp..woff2 +0 -0
  253. package/dist/web/_next/static/media/0da9c7f357bd9d4d-s.0ek5sshv8wk3m.woff2 +0 -0
  254. package/dist/web/_next/static/media/1b99372b3eaef0c8-s.p.0gx2haw2tmll8.woff2 +0 -0
  255. package/dist/web/_next/static/media/41e95f694c5c4549-s.0r1jrq7neqdsq.woff2 +0 -0
  256. package/dist/web/_next/static/media/5c285b27cdda1fe8-s.p.0yo6-5yoeeudq.woff2 +0 -0
  257. package/dist/web/_next/static/media/5f9d24ebef5d5292-s.0esuu2f5si~v8.woff2 +0 -0
  258. package/dist/web/_next/static/media/6c55a692938ebbbc-s.0g6rbszwfgn9y.woff2 +0 -0
  259. package/dist/web/_next/static/media/8e6fa89aa22d24ec-s.p.0uvzar8hswo3p.woff2 +0 -0
  260. package/dist/web/_next/static/media/a218039a3287bcfd-s.p.17-1enzs_j91b.woff2 +0 -0
  261. package/dist/web/_next/static/media/b2ea385cb5ae8625-s.0kjod.kaq1k69.woff2 +0 -0
  262. package/dist/web/_next/static/media/bdc7e24a509eb931-s.0apt5mko2.qn3.woff2 +0 -0
  263. package/dist/web/_next/static/media/c3cb240f9c892514-s.163v2i5cux7-c.woff2 +0 -0
  264. package/dist/web/_next/static/media/e2334d715941921e-s.p.12skym0rqknxy.woff2 +0 -0
  265. package/public/output-styles/carmack-mode.md +0 -381
  266. package/public/output-styles/codex-rigor-mode.md +0 -114
  267. package/public/output-styles/dhh-mode.md +0 -265
  268. package/public/output-styles/evan-you-mode.md +0 -539
  269. package/public/output-styles/index.json +0 -37
  270. package/public/output-styles/jobs-mode.md +0 -369
  271. package/public/output-styles/linus-mode.md +0 -135
  272. package/public/output-styles/uncle-bob-mode.md +0 -221
  273. package/public/prompt/andrej-karpathy-skills.md +0 -65
  274. package/public/prompt/claude-token-efficient-coding.md +0 -35
  275. package/public/prompt/index.json +0 -12
  276. package/public/skills/index.json +0 -92
  277. package/public/skills/planning-with-files/planning-with-files-zh/SKILL.md +0 -243
  278. package/public/skills/planning-with-files/planning-with-files-zh/scripts/check-complete.ps1 +0 -44
  279. package/public/skills/planning-with-files/planning-with-files-zh/scripts/check-complete.sh +0 -46
  280. package/public/skills/planning-with-files/planning-with-files-zh/scripts/init-session.ps1 +0 -124
  281. package/public/skills/planning-with-files/planning-with-files-zh/scripts/init-session.sh +0 -124
  282. package/public/skills/planning-with-files/planning-with-files-zh/scripts/session-catchup.py +0 -438
  283. package/public/skills/planning-with-files/planning-with-files-zh/templates/findings.md +0 -29
  284. package/public/skills/planning-with-files/planning-with-files-zh/templates/progress.md +0 -40
  285. package/public/skills/planning-with-files/planning-with-files-zh/templates/task_plan.md +0 -58
  286. package/public/skills/superpowers/brainstorming/SKILL.md +0 -164
  287. package/public/skills/superpowers/brainstorming/scripts/frame-template.html +0 -214
  288. package/public/skills/superpowers/brainstorming/scripts/helper.js +0 -88
  289. package/public/skills/superpowers/brainstorming/scripts/server.cjs +0 -354
  290. package/public/skills/superpowers/brainstorming/scripts/start-server.sh +0 -148
  291. package/public/skills/superpowers/brainstorming/scripts/stop-server.sh +0 -56
  292. package/public/skills/superpowers/brainstorming/spec-document-reviewer-prompt.md +0 -49
  293. package/public/skills/superpowers/brainstorming/visual-companion.md +0 -287
  294. package/public/skills/superpowers/dispatching-parallel-agents/SKILL.md +0 -182
  295. package/public/skills/superpowers/executing-plans/SKILL.md +0 -70
  296. package/public/skills/superpowers/finishing-a-development-branch/SKILL.md +0 -251
  297. package/public/skills/superpowers/receiving-code-review/SKILL.md +0 -213
  298. package/public/skills/superpowers/requesting-code-review/SKILL.md +0 -103
  299. package/public/skills/superpowers/requesting-code-review/code-reviewer.md +0 -168
  300. package/public/skills/superpowers/subagent-driven-development/SKILL.md +0 -279
  301. package/public/skills/superpowers/subagent-driven-development/code-quality-reviewer-prompt.md +0 -25
  302. package/public/skills/superpowers/subagent-driven-development/implementer-prompt.md +0 -113
  303. package/public/skills/superpowers/subagent-driven-development/spec-reviewer-prompt.md +0 -61
  304. package/public/skills/superpowers/systematic-debugging/CREATION-LOG.md +0 -119
  305. package/public/skills/superpowers/systematic-debugging/SKILL.md +0 -296
  306. package/public/skills/superpowers/systematic-debugging/condition-based-waiting-example.ts +0 -158
  307. package/public/skills/superpowers/systematic-debugging/condition-based-waiting.md +0 -115
  308. package/public/skills/superpowers/systematic-debugging/defense-in-depth.md +0 -122
  309. package/public/skills/superpowers/systematic-debugging/find-polluter.sh +0 -63
  310. package/public/skills/superpowers/systematic-debugging/root-cause-tracing.md +0 -169
  311. package/public/skills/superpowers/systematic-debugging/test-academic.md +0 -14
  312. package/public/skills/superpowers/systematic-debugging/test-pressure-1.md +0 -58
  313. package/public/skills/superpowers/systematic-debugging/test-pressure-2.md +0 -68
  314. package/public/skills/superpowers/systematic-debugging/test-pressure-3.md +0 -69
  315. package/public/skills/superpowers/test-driven-development/SKILL.md +0 -371
  316. package/public/skills/superpowers/test-driven-development/testing-anti-patterns.md +0 -299
  317. package/public/skills/superpowers/using-git-worktrees/SKILL.md +0 -215
  318. package/public/skills/superpowers/using-superpowers/SKILL.md +0 -117
  319. package/public/skills/superpowers/using-superpowers/references/codex-tools.md +0 -59
  320. package/public/skills/superpowers/using-superpowers/references/copilot-tools.md +0 -42
  321. package/public/skills/superpowers/using-superpowers/references/gemini-tools.md +0 -51
  322. package/public/skills/superpowers/verification-before-completion/SKILL.md +0 -139
  323. package/public/skills/superpowers/writing-plans/SKILL.md +0 -152
  324. package/public/skills/superpowers/writing-plans/plan-document-reviewer-prompt.md +0 -49
  325. package/public/skills/superpowers/writing-skills/SKILL.md +0 -655
  326. package/public/skills/superpowers/writing-skills/anthropic-best-practices.md +0 -1150
  327. package/public/skills/superpowers/writing-skills/examples/CLAUDE_MD_TESTING.md +0 -189
  328. package/public/skills/superpowers/writing-skills/graphviz-conventions.dot +0 -172
  329. package/public/skills/superpowers/writing-skills/persuasion-principles.md +0 -187
  330. package/public/skills/superpowers/writing-skills/render-graphs.js +0 -168
  331. package/public/skills/superpowers/writing-skills/testing-skills-with-subagents.md +0 -384
  332. /package/dist/web/_next/static/{OoXAsPtrUWjC1l898FSvI → x4-CsKe6qUQyFDWVtfvUg}/_buildManifest.js +0 -0
  333. /package/dist/web/_next/static/{OoXAsPtrUWjC1l898FSvI → x4-CsKe6qUQyFDWVtfvUg}/_clientMiddlewareManifest.js +0 -0
  334. /package/dist/web/_next/static/{OoXAsPtrUWjC1l898FSvI → x4-CsKe6qUQyFDWVtfvUg}/_ssgManifest.js +0 -0
@@ -4,7 +4,7 @@ import { summarizeResult } from '../agent-runtime-types.js';
4
4
  import { prepareClaudeOutputStyleFile } from '../../services/output-style.js';
5
5
  import { normalizeAdditionalDirectories, normalizePermissionMode, normalizeSkillNames, prepareConfigDir, resolveBundledClaudeExecutable, buildEnv, normalizeMcpServers } from './sdk-config.js';
6
6
  import { startClaudeAdapterIfNeeded, getClaudeCodeModel } from './adapter-pool.js';
7
- import { extractThinkingEvents, extractToolUseEvents, extractToolResultEvent, logToolDebug, formatMessage, isAskUserQuestionAutoResult, countUsageTokens, formatUsageLine, normalizeUsage } from './message-format.js';
7
+ import { extractClaudeHookEvents, extractThinkingEvents, extractToolUseEvents, extractToolResultEvent, logToolDebug, formatMessage, isAskUserQuestionAutoResult, countUsageTokens, formatUsageLine, normalizeUsage } from './message-format.js';
8
8
  export class ClaudeCodeRuntime {
9
9
  config;
10
10
  abortController = null;
@@ -39,7 +39,33 @@ export class ClaudeCodeRuntime {
39
39
  d(`prompt: ${prompt.slice(0, 300)}${prompt.length > 300 ? '...' : ''}`);
40
40
  d(`sdk mcp servers | ${sdkMcpServerNames.join(',') || '-'}`);
41
41
  const stderrLines = [];
42
+ let sessionId = options?.resumeSessionId;
43
+ const emitHook = (event, matcher = '*', payload) => {
44
+ options?.onEvent?.({ type: 'hook_event', event, matcher, payload });
45
+ };
42
46
  try {
47
+ emitHook('SessionStart', '*', {
48
+ cwd,
49
+ model,
50
+ provider: this.config.provider,
51
+ baseURL,
52
+ permissionMode,
53
+ configDir,
54
+ sandboxDirs: additionalDirectories,
55
+ resumeSessionId: options?.resumeSessionId,
56
+ });
57
+ const hookUserPrompt = options?.userPrompt ?? prompt;
58
+ emitHook('UserPromptSubmit', '*', {
59
+ prompt: hookUserPrompt,
60
+ message: hookUserPrompt,
61
+ userMessage: hookUserPrompt,
62
+ fullPrompt: prompt,
63
+ cwd,
64
+ configDir,
65
+ });
66
+ if (/CLAUDE\.md|AGENTS\.md|\.claude\/rules\//.test(prompt)) {
67
+ emitHook('InstructionsLoaded', '*', { source: 'prompt', promptPreview: prompt.slice(0, 1000) });
68
+ }
43
69
  const queryOptions = {
44
70
  cwd,
45
71
  model,
@@ -76,11 +102,13 @@ export class ClaudeCodeRuntime {
76
102
  let usageLine = null;
77
103
  let usage;
78
104
  let costUsd;
79
- let sessionId = options?.resumeSessionId;
80
105
  let sawResult = false;
81
106
  const pendingAskUserQuestionToolIds = new Set();
82
107
  let waitingForUserAnswer = false;
83
108
  for await (const message of this.activeQuery) {
109
+ for (const hookEvent of extractClaudeHookEvents(message)) {
110
+ emitHook(hookEvent.event, hookEvent.matcher, hookEvent.payload);
111
+ }
84
112
  const nextSessionId = readSessionId(message);
85
113
  if (nextSessionId && nextSessionId !== sessionId) {
86
114
  sessionId = nextSessionId;
@@ -145,6 +173,17 @@ export class ClaudeCodeRuntime {
145
173
  const elapsed = Date.now() - startTime;
146
174
  if (waitingForUserAnswer) {
147
175
  d(`waiting for user answer ${elapsed}ms | turns=${turns} tokens=${tokenCount}`);
176
+ const message = resultText || output.at(-1) || 'Waiting for user answer';
177
+ emitHook('Stop', '*', {
178
+ status: 'waiting_for_user_answer',
179
+ message,
180
+ finalMessage: message,
181
+ output,
182
+ elapsedMs: elapsed,
183
+ turns,
184
+ tokenCount,
185
+ sessionId,
186
+ });
148
187
  if (usageLine)
149
188
  output.push(usageLine);
150
189
  return {
@@ -161,6 +200,7 @@ export class ClaudeCodeRuntime {
161
200
  const runtimeError = extractRuntimeError([...stderrLines, ...output])
162
201
  || 'Claude Code execution stopped before reporting a final result';
163
202
  d(`failed ${elapsed}ms | turns=${turns} tokens=${tokenCount} | ${runtimeError}`);
203
+ emitHook('StopFailure', '*', { error: runtimeError, elapsedMs: elapsed, turns, tokenCount, sessionId, stderr: stderrLines });
164
204
  appendUnique(output, stderrLines);
165
205
  appendUnique(output, [runtimeError]);
166
206
  return {
@@ -176,6 +216,17 @@ export class ClaudeCodeRuntime {
176
216
  }
177
217
  if (waitingForUserAnswer && (!error || isAskUserQuestionAutoResult(error))) {
178
218
  d(`waiting for user answer ${elapsed}ms | turns=${turns} tokens=${tokenCount}`);
219
+ const message = resultText || output.at(-1) || 'Waiting for user answer';
220
+ emitHook('Stop', '*', {
221
+ status: 'waiting_for_user_answer',
222
+ message,
223
+ finalMessage: message,
224
+ output,
225
+ elapsedMs: elapsed,
226
+ turns,
227
+ tokenCount,
228
+ sessionId,
229
+ });
179
230
  if (usageLine)
180
231
  output.push(usageLine);
181
232
  return {
@@ -191,6 +242,7 @@ export class ClaudeCodeRuntime {
191
242
  if (error) {
192
243
  const runtimeError = extractRuntimeError([error, ...stderrLines, ...output]) || error;
193
244
  d(`failed ${elapsed}ms | turns=${turns} tokens=${tokenCount} | ${runtimeError}`);
245
+ emitHook('StopFailure', '*', { error: runtimeError, elapsedMs: elapsed, turns, tokenCount, sessionId, stderr: stderrLines });
194
246
  appendUnique(output, stderrLines);
195
247
  if (usageLine)
196
248
  output.push(usageLine);
@@ -213,6 +265,18 @@ export class ClaudeCodeRuntime {
213
265
  const finalOutput = resultText && !output.includes(resultText) ? [...output, resultText] : output;
214
266
  if (usageLine && !finalOutput.includes(usageLine))
215
267
  finalOutput.push(usageLine);
268
+ emitHook('Stop', '*', {
269
+ status: 'success',
270
+ message: text,
271
+ finalMessage: text,
272
+ output: finalOutput,
273
+ elapsedMs: elapsed,
274
+ turns,
275
+ tokenCount,
276
+ sessionId,
277
+ usage,
278
+ costUsd,
279
+ });
216
280
  return {
217
281
  success: true,
218
282
  summary: summarizeResult(text),
@@ -230,11 +294,13 @@ export class ClaudeCodeRuntime {
230
294
  d(`failed ${elapsed}ms | ${runtimeError}`);
231
295
  if (err instanceof Error && err.stack)
232
296
  console.error(err.stack);
297
+ emitHook('StopFailure', '*', { error: runtimeError, elapsedMs: elapsed, stderr: stderrLines, stack: err instanceof Error ? err.stack : undefined });
233
298
  appendUnique(output, stderrLines);
234
299
  appendUnique(output, [runtimeError]);
235
300
  return { success: false, summary: 'Claude Code execution failed', artifacts: [], error: runtimeError, output, sessionId: options?.resumeSessionId };
236
301
  }
237
302
  finally {
303
+ emitHook('SessionEnd', '*', { cwd, sessionId });
238
304
  this.activeQuery?.close();
239
305
  this.activeQuery = null;
240
306
  await this.adapterRun?.release();
@@ -24,7 +24,7 @@ export function formatMessage(message) {
24
24
  case 'tool_progress':
25
25
  return `${message.tool_name} running (${message.elapsed_time_seconds}s)`;
26
26
  case 'tool_use_summary':
27
- return message.summary;
27
+ return null;
28
28
  default:
29
29
  return null;
30
30
  }
@@ -95,6 +95,32 @@ export function extractToolResultEvent(message) {
95
95
  }
96
96
  return null;
97
97
  }
98
+ export function extractClaudeHookEvents(message) {
99
+ const events = [];
100
+ if (message.type === 'system') {
101
+ if (message.subtype === 'task_started') {
102
+ events.push({ event: 'SubagentStart', matcher: '*', payload: message });
103
+ }
104
+ else if (message.subtype === 'task_notification') {
105
+ events.push({ event: 'Notification', matcher: '*', payload: message });
106
+ }
107
+ else if (message.subtype === 'local_command_output') {
108
+ events.push({ event: 'Notification', matcher: 'local_command_output', payload: message });
109
+ }
110
+ }
111
+ if (message.type === 'tool_use_summary') {
112
+ events.push({ event: 'PostToolBatch', matcher: '*', payload: message });
113
+ }
114
+ for (const toolUse of extractToolUseEvents(message)) {
115
+ if (toolUse.name === 'TaskCreate') {
116
+ events.push({ event: 'TaskCreated', matcher: toolUse.name, payload: toolUse });
117
+ }
118
+ if (toolUse.name === 'TaskCompleted') {
119
+ events.push({ event: 'TaskCompleted', matcher: toolUse.name, payload: toolUse });
120
+ }
121
+ }
122
+ return events;
123
+ }
98
124
  export function logToolDebug(message, d, options = {}) {
99
125
  switch (message.type) {
100
126
  case 'assistant':
@@ -5,6 +5,7 @@ import { join } from 'node:path';
5
5
  import { createSdkMcpServer, tool } from '@anthropic-ai/claude-agent-sdk';
6
6
  import { isAnthropicBridgeProvider } from './types.js';
7
7
  const require = createRequire(import.meta.url);
8
+ const CLAUDE_BUILT_IN_DIRS = ['agents', 'commands'];
8
9
  export function buildEnv(config, configDir, override) {
9
10
  const usesAnthropicBridge = isAnthropicBridgeProvider(config.provider);
10
11
  return {
@@ -132,6 +133,7 @@ export function prepareConfigDir(configDir, agentDir) {
132
133
  mkdirSync(configDir, { recursive: true });
133
134
  if (!agentDir)
134
135
  return;
136
+ copyClaudeBuiltInDirs(agentDir, configDir);
135
137
  const sourceSkillsDir = join(agentDir, 'skills');
136
138
  const targetSkillsDir = join(configDir, 'skills');
137
139
  rmSync(targetSkillsDir, { recursive: true, force: true });
@@ -163,6 +165,16 @@ export function prepareConfigDir(configDir, agentDir) {
163
165
  copyFileSync(source, join(targetSkillsDir, `${skillName}.md`));
164
166
  }
165
167
  }
168
+ function copyClaudeBuiltInDirs(agentDir, configDir) {
169
+ for (const dir of CLAUDE_BUILT_IN_DIRS) {
170
+ const sourceDir = join(agentDir, dir);
171
+ const targetDir = join(configDir, dir);
172
+ rmSync(targetDir, { recursive: true, force: true });
173
+ if (!existsSync(sourceDir) || !statSync(sourceDir).isDirectory())
174
+ continue;
175
+ cpSync(sourceDir, targetDir, { recursive: true, force: true });
176
+ }
177
+ }
166
178
  function hasSkillContent(skill, configDir) {
167
179
  if (!configDir)
168
180
  return true;
@@ -36,26 +36,36 @@ function getGit(workspace) {
36
36
  }
37
37
  function mapStatus(raw) {
38
38
  const files = [];
39
+ const addOrUpdate = (file) => {
40
+ const existing = files.find(x => x.path === file.path);
41
+ if (existing) {
42
+ Object.assign(existing, file, {
43
+ staged: existing.staged || file.staged,
44
+ conflicted: existing.conflicted || file.conflicted,
45
+ status: file.conflicted ? 'conflicted' : existing.status,
46
+ });
47
+ }
48
+ else {
49
+ files.push(file);
50
+ }
51
+ };
39
52
  for (const f of raw.staged) {
40
- files.push({ path: f, status: mapStatusCode(raw.files.find(r => r.path === f)?.index) });
53
+ addOrUpdate({ path: f, status: mapStatusCode(raw.files.find(r => r.path === f)?.index), staged: true });
41
54
  }
42
55
  for (const f of raw.modified) {
43
- if (!files.find(x => x.path === f)) {
44
- files.push({ path: f, status: 'modified' });
45
- }
56
+ addOrUpdate({ path: f, status: 'modified' });
46
57
  }
47
58
  for (const f of raw.not_added) {
48
- files.push({ path: f, status: 'untracked' });
59
+ addOrUpdate({ path: f, status: 'untracked' });
49
60
  }
50
61
  for (const f of raw.deleted) {
51
- if (!files.find(x => x.path === f)) {
52
- files.push({ path: f, status: 'deleted' });
53
- }
62
+ addOrUpdate({ path: f, status: 'deleted' });
54
63
  }
55
64
  for (const f of raw.created) {
56
- if (!files.find(x => x.path === f)) {
57
- files.push({ path: f, status: 'added' });
58
- }
65
+ addOrUpdate({ path: f, status: 'added', staged: raw.staged.includes(f) });
66
+ }
67
+ for (const f of raw.conflicted) {
68
+ addOrUpdate({ path: f, status: 'conflicted', conflicted: true });
59
69
  }
60
70
  return {
61
71
  branch: raw.current || 'HEAD',
@@ -67,6 +77,75 @@ function mapStatus(raw) {
67
77
  deletions: 0,
68
78
  };
69
79
  }
80
+ async function getUpstreamRef(git, branch) {
81
+ const refExists = async (ref) => {
82
+ return git.raw(['rev-parse', '--verify', '--quiet', ref])
83
+ .then(() => true)
84
+ .catch(() => false);
85
+ };
86
+ const upstream = await git.raw(['rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{u}'])
87
+ .then(v => v.trim())
88
+ .catch(() => '');
89
+ if (upstream && await refExists(upstream))
90
+ return upstream;
91
+ if (!branch || branch === 'HEAD')
92
+ return null;
93
+ const originBranch = `origin/${branch}`;
94
+ return await refExists(originBranch) ? originBranch : null;
95
+ }
96
+ function splitConflictSides(content) {
97
+ const left = [];
98
+ const right = [];
99
+ let mode = 'both';
100
+ let hasConflict = false;
101
+ for (const line of content.split('\n')) {
102
+ if (line.startsWith('<<<<<<< ')) {
103
+ hasConflict = true;
104
+ mode = 'left';
105
+ continue;
106
+ }
107
+ if (line.startsWith('=======')) {
108
+ mode = 'right';
109
+ continue;
110
+ }
111
+ if (line.startsWith('>>>>>>> ')) {
112
+ mode = 'both';
113
+ continue;
114
+ }
115
+ if (mode === 'both' || mode === 'left')
116
+ left.push(line);
117
+ if (mode === 'both' || mode === 'right')
118
+ right.push(line);
119
+ }
120
+ return { left: left.join('\n'), right: right.join('\n'), hasConflict };
121
+ }
122
+ async function buildWorkingDiff(git, rootDir, filePath, conflicted = false) {
123
+ const binary = isBinaryPath(filePath);
124
+ const workingContent = binary ? '' : await readFile(join(rootDir, filePath), 'utf-8').catch(() => '');
125
+ if (!binary && conflicted) {
126
+ const conflict = splitConflictSides(workingContent);
127
+ if (conflict.hasConflict) {
128
+ return {
129
+ path: filePath,
130
+ oldContent: conflict.left,
131
+ newContent: conflict.right,
132
+ isBinary: false,
133
+ isNew: false,
134
+ isDeleted: false,
135
+ isConflict: true,
136
+ };
137
+ }
138
+ }
139
+ const oldContent = binary ? '' : await git.show([`HEAD:${filePath}`]).catch(() => '');
140
+ return {
141
+ path: filePath,
142
+ oldContent,
143
+ newContent: workingContent,
144
+ isBinary: binary,
145
+ isNew: !oldContent,
146
+ isDeleted: !workingContent,
147
+ };
148
+ }
70
149
  function mapStatusCode(code) {
71
150
  switch (code) {
72
151
  case 'A': return 'added';
@@ -83,6 +162,19 @@ export async function gitStatus(workspaceId) {
83
162
  const git = getGit(ws);
84
163
  const raw = await git.status();
85
164
  const result = mapStatus(raw);
165
+ try {
166
+ const headHash = await git.revparse(['--short', 'HEAD']);
167
+ result.headHash = headHash.trim();
168
+ }
169
+ catch { }
170
+ try {
171
+ const upstream = await getUpstreamRef(git, result.branch);
172
+ if (upstream) {
173
+ const remoteHeadHash = await git.revparse(['--short', upstream]);
174
+ result.remoteHeadHash = remoteHeadHash.trim();
175
+ }
176
+ }
177
+ catch { }
86
178
  if (!result.clean) {
87
179
  try {
88
180
  // Tracked changes: modified/deleted/renamed
@@ -122,66 +214,78 @@ export async function gitDiff(workspaceId, filePath) {
122
214
  throw new Error('Workspace not found');
123
215
  const git = getGit(ws);
124
216
  const diffs = [];
217
+ const status = await git.status();
218
+ const conflicted = new Set(status.conflicted);
125
219
  if (filePath) {
126
- const diff = await git.diff([filePath]);
127
- const oldContent = await git.show([`HEAD:${filePath}`]).catch(() => '');
128
- const newContent = await import('node:fs/promises').then(fs => fs.readFile(`${ws.boundDirs[0]}/${filePath}`, 'utf-8')).catch(() => '');
129
- diffs.push({
130
- path: filePath,
131
- oldContent: isBinaryPath(filePath) ? '' : oldContent,
132
- newContent: isBinaryPath(filePath) ? '' : newContent,
133
- isBinary: isBinaryPath(filePath),
134
- isNew: !oldContent,
135
- isDeleted: !newContent,
136
- });
220
+ diffs.push(await buildWorkingDiff(git, ws.boundDirs[0], filePath, conflicted.has(filePath)));
137
221
  }
138
222
  else {
139
223
  const raw = await git.diff(['--name-only']);
140
- const files = raw.split('\n').filter(Boolean);
224
+ const cachedRaw = await git.diff(['--cached', '--name-only']);
225
+ const files = Array.from(new Set([
226
+ ...raw.split('\n').filter(Boolean),
227
+ ...cachedRaw.split('\n').filter(Boolean),
228
+ ...status.not_added,
229
+ ...status.conflicted,
230
+ ]));
141
231
  for (const f of files) {
142
- const binary = isBinaryPath(f);
143
- const oldContent = binary ? '' : await git.show([`HEAD:${f}`]).catch(() => '');
144
- const newContent = binary ? '' : await import('node:fs/promises').then(fs => fs.readFile(`${ws.boundDirs[0]}/${f}`, 'utf-8')).catch(() => '');
145
- diffs.push({
146
- path: f,
147
- oldContent,
148
- newContent,
149
- isBinary: binary,
150
- isNew: !oldContent,
151
- isDeleted: !newContent,
152
- });
153
- }
154
- // Also check untracked (staged new files)
155
- const status = await git.status();
156
- for (const f of status.not_added) {
157
- const binary = isBinaryPath(f);
158
- const newContent = binary ? '' : await import('node:fs/promises').then(fs => fs.readFile(`${ws.boundDirs[0]}/${f}`, 'utf-8')).catch(() => '');
159
- if (newContent || binary) {
160
- diffs.push({
161
- path: f,
162
- oldContent: '',
163
- newContent: binary ? '' : newContent,
164
- isBinary: binary,
165
- isNew: true,
166
- isDeleted: false,
167
- });
168
- }
232
+ diffs.push(await buildWorkingDiff(git, ws.boundDirs[0], f, conflicted.has(f)));
169
233
  }
170
234
  }
171
235
  return diffs;
172
236
  }
237
+ export async function gitStage(workspaceId, filePath) {
238
+ const ws = getWorkspace(workspaceId);
239
+ if (!ws)
240
+ throw new Error('Workspace not found');
241
+ const git = getGit(ws);
242
+ await git.add(filePath);
243
+ }
244
+ export async function gitUnstage(workspaceId, filePath) {
245
+ const ws = getWorkspace(workspaceId);
246
+ if (!ws)
247
+ throw new Error('Workspace not found');
248
+ const git = getGit(ws);
249
+ await git.raw(['restore', '--staged', '--', filePath]).catch(async () => {
250
+ await git.raw(['reset', 'HEAD', '--', filePath]);
251
+ });
252
+ }
253
+ export async function gitResolveFile(workspaceId, filePath, content, stage = true) {
254
+ const ws = getWorkspace(workspaceId);
255
+ if (!ws)
256
+ throw new Error('Workspace not found');
257
+ const git = getGit(ws);
258
+ await writeFile(join(ws.boundDirs[0], filePath), content, 'utf-8');
259
+ if (stage)
260
+ await git.add(filePath);
261
+ }
173
262
  export async function gitLog(workspaceId, maxCount = 50) {
174
263
  const ws = getWorkspace(workspaceId);
175
264
  if (!ws)
176
265
  throw new Error('Workspace not found');
177
266
  const git = getGit(ws);
178
- const log = await git.log({ maxCount });
179
- return log.all.map(entry => ({
180
- hash: entry.hash.substring(0, 7),
181
- message: entry.message,
182
- author: entry.author_name,
183
- date: entry.date,
184
- }));
267
+ const status = await git.status();
268
+ const upstream = await getUpstreamRef(git, status.current || 'HEAD');
269
+ const refs = upstream ? ['HEAD', upstream] : ['HEAD'];
270
+ const pretty = '%H%x1f%s%x1f%an%x1f%aI%x1e';
271
+ const logArgs = ['log', `--max-count=${maxCount}`, `--pretty=format:${pretty}`];
272
+ const raw = await git.raw([...logArgs, ...refs]).catch((err) => {
273
+ if (!upstream)
274
+ throw err;
275
+ return git.raw([...logArgs, 'HEAD']);
276
+ });
277
+ return raw.split('\x1e')
278
+ .map(record => record.trim())
279
+ .filter(Boolean)
280
+ .map(record => {
281
+ const [hash = '', message = '', author = '', date = ''] = record.split('\x1f');
282
+ return {
283
+ hash: hash.substring(0, 7),
284
+ message,
285
+ author,
286
+ date,
287
+ };
288
+ });
185
289
  }
186
290
  export async function gitCommit(workspaceId, message) {
187
291
  const ws = getWorkspace(workspaceId);
@@ -274,6 +378,13 @@ export async function gitPush(workspaceId) {
274
378
  throw new Error('No remote repository configured. Please add a remote first.');
275
379
  await git.push('origin', branch);
276
380
  }
381
+ export async function gitFetch(workspaceId) {
382
+ const ws = getWorkspace(workspaceId);
383
+ if (!ws)
384
+ throw new Error('Workspace not found');
385
+ const git = getGit(ws);
386
+ await git.fetch('origin');
387
+ }
277
388
  export async function gitPull(workspaceId) {
278
389
  const ws = getWorkspace(workspaceId);
279
390
  if (!ws)
@@ -28,13 +28,36 @@ export async function generateAgentDesign(userPrompt) {
28
28
  apiBase: maskUrl(config.apiBase),
29
29
  promptLength: prompt.length,
30
30
  });
31
- const content = await requestDesign(config, prompt);
31
+ const content = await requestText(config, buildDesignSystemPrompt(config), prompt);
32
32
  console.info('[agent-designer] model text extracted', {
33
33
  length: content.length,
34
34
  preview: content.slice(0, 500),
35
35
  });
36
36
  return normalizeDesign(parseJsonObject(content));
37
37
  }
38
+ export async function optimizeAgentPrompt(userPrompt, currentPrompt) {
39
+ const prompt = userPrompt.trim();
40
+ if (!prompt)
41
+ throw new Error('prompt is required');
42
+ const config = resolveModelConfig();
43
+ if (!config) {
44
+ throw new Error(`Configure model settings for ${AGENT_GENERATOR_PRESET_ID} before optimizing prompts.`);
45
+ }
46
+ console.info('[agent-designer] optimizing agent prompt', {
47
+ agentId: AGENT_GENERATOR_PRESET_ID,
48
+ provider: config.modelProvider ?? inferProvider(config.apiBase),
49
+ modelId: config.modelId,
50
+ apiBase: maskUrl(config.apiBase),
51
+ promptLength: prompt.length,
52
+ currentPromptLength: currentPrompt.trim().length,
53
+ });
54
+ const content = await requestText(config, buildOptimizationSystemPrompt(config), buildPromptOptimizationUserPrompt(prompt, currentPrompt));
55
+ console.info('[agent-designer] optimized prompt received', {
56
+ length: content.length,
57
+ preview: content.slice(0, 500),
58
+ });
59
+ return { systemPrompt: normalizePrompt(content) };
60
+ }
38
61
  function resolveModelConfig() {
39
62
  const preset = readAgentTemplate(AGENT_GENERATOR_PRESET_ID);
40
63
  if (preset?.apiBase && preset.apiKey && preset.modelId) {
@@ -51,14 +74,17 @@ function resolveModelConfig() {
51
74
  return null;
52
75
  }
53
76
  async function requestDesign(config, userPrompt) {
77
+ return requestText(config, buildDesignSystemPrompt(config), userPrompt);
78
+ }
79
+ async function requestText(config, systemPrompt, userPrompt) {
54
80
  const provider = config.modelProvider ?? inferProvider(config.apiBase);
55
81
  if (provider === 'anthropic-messages')
56
- return requestAnthropic(config, userPrompt);
82
+ return requestAnthropic(config, systemPrompt, userPrompt);
57
83
  if (provider === 'gemini-generate-content')
58
- return requestGemini(config, userPrompt);
59
- return requestOpenAICompatible(config, userPrompt, provider === 'openai-responses' || provider === 'openai-responses-to-anthropic-messages');
84
+ return requestGemini(config, systemPrompt, userPrompt);
85
+ return requestOpenAICompatible(config, systemPrompt, userPrompt, provider === 'openai-responses' || provider === 'openai-responses-to-anthropic-messages');
60
86
  }
61
- async function requestOpenAICompatible(config, userPrompt, useResponsesApi) {
87
+ async function requestOpenAICompatible(config, systemPrompt, userPrompt, useResponsesApi) {
62
88
  const url = joinUrl(config.apiBase, useResponsesApi ? '/responses' : '/chat/completions');
63
89
  const response = await fetch(url, {
64
90
  method: 'POST',
@@ -69,14 +95,14 @@ async function requestOpenAICompatible(config, userPrompt, useResponsesApi) {
69
95
  body: JSON.stringify(useResponsesApi
70
96
  ? {
71
97
  model: config.modelId,
72
- input: `${buildSystemPrompt(config)}\n\nUser request:\n${userPrompt}`,
98
+ input: `${systemPrompt}\n\nUser request:\n${userPrompt}`,
73
99
  temperature: config.temperature ?? 0.2,
74
100
  max_output_tokens: config.maxTokens,
75
101
  }
76
102
  : {
77
103
  model: config.modelId,
78
104
  messages: [
79
- { role: 'system', content: buildSystemPrompt(config) },
105
+ { role: 'system', content: systemPrompt },
80
106
  { role: 'user', content: userPrompt },
81
107
  ],
82
108
  temperature: config.temperature ?? 0.2,
@@ -88,7 +114,7 @@ async function requestOpenAICompatible(config, userPrompt, useResponsesApi) {
88
114
  throw new Error(body.error || `Agent design generation failed with status ${response.status}`);
89
115
  return body.text;
90
116
  }
91
- async function requestAnthropic(config, userPrompt) {
117
+ async function requestAnthropic(config, systemPrompt, userPrompt) {
92
118
  const response = await fetch(getAnthropicMessagesUrl(config.apiBase), {
93
119
  method: 'POST',
94
120
  headers: {
@@ -98,7 +124,7 @@ async function requestAnthropic(config, userPrompt) {
98
124
  },
99
125
  body: JSON.stringify({
100
126
  model: config.modelId,
101
- system: buildSystemPrompt(config),
127
+ system: systemPrompt,
102
128
  messages: [{ role: 'user', content: userPrompt }],
103
129
  max_tokens: config.maxTokens ?? 4096,
104
130
  temperature: config.temperature ?? 0.2,
@@ -109,7 +135,7 @@ async function requestAnthropic(config, userPrompt) {
109
135
  throw new Error(body.error || `Agent design generation failed with status ${response.status}`);
110
136
  return body.text;
111
137
  }
112
- async function requestGemini(config, userPrompt) {
138
+ async function requestGemini(config, systemPrompt, userPrompt) {
113
139
  const response = await fetch(joinUrl(config.apiBase, `/models/${encodeURIComponent(config.modelId)}:generateContent`), {
114
140
  method: 'POST',
115
141
  headers: {
@@ -117,7 +143,7 @@ async function requestGemini(config, userPrompt) {
117
143
  'Content-Type': 'application/json',
118
144
  },
119
145
  body: JSON.stringify({
120
- systemInstruction: { parts: [{ text: buildSystemPrompt(config) }] },
146
+ systemInstruction: { parts: [{ text: systemPrompt }] },
121
147
  contents: [{ role: 'user', parts: [{ text: userPrompt }] }],
122
148
  generationConfig: {
123
149
  temperature: config.temperature ?? 0.2,
@@ -130,12 +156,40 @@ async function requestGemini(config, userPrompt) {
130
156
  throw new Error(body.error || `Agent design generation failed with status ${response.status}`);
131
157
  return body.text;
132
158
  }
133
- function buildSystemPrompt(config) {
159
+ function buildDesignSystemPrompt(config) {
134
160
  const custom = config.systemPrompt?.trim();
135
161
  if (!custom)
136
162
  return SYSTEM_PROMPT;
137
163
  return `${custom}\n\n${SYSTEM_PROMPT}`;
138
164
  }
165
+ function buildOptimizationSystemPrompt(config) {
166
+ const custom = config.systemPrompt?.trim();
167
+ const base = [
168
+ 'You optimize agent system prompts.',
169
+ 'Return only the rewritten prompt text.',
170
+ 'Do not wrap the result in markdown fences.',
171
+ 'Do not add commentary, bullets about the process, or any explanation outside the prompt.',
172
+ 'Keep the prompt actionable, concise, and directly usable as a system prompt.',
173
+ 'Preserve important constraints from the current prompt unless the user request clearly asks to change them.',
174
+ ].join('\n');
175
+ if (!custom)
176
+ return base;
177
+ return `${custom}\n\n${base}`;
178
+ }
179
+ function buildPromptOptimizationUserPrompt(userRequest, currentPrompt) {
180
+ return [
181
+ 'User request:',
182
+ userRequest,
183
+ '',
184
+ 'Current system prompt:',
185
+ currentPrompt.trim() || '(empty)',
186
+ '',
187
+ 'Rewrite the current system prompt according to the user request. Return only the final prompt text.',
188
+ ].join('\n');
189
+ }
190
+ function normalizePrompt(text) {
191
+ return text.trim().replace(/^```(?:markdown|md)?\s*/i, '').replace(/\s*```$/i, '');
192
+ }
139
193
  async function readResponseBody(response) {
140
194
  const raw = await response.text();
141
195
  if (!raw)
@@ -41,7 +41,7 @@ export function createAgentMessagePartsTracker(input) {
41
41
  }
42
42
  return;
43
43
  }
44
- if (event.type === 'session')
44
+ if (event.type === 'session' || event.type === 'hook_event')
45
45
  return;
46
46
  output.push(event.line);
47
47
  input.onOutput?.(event.line);