@agent-spaces/server 0.3.4 → 0.3.5

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 (288) hide show
  1. package/dist/adapters/claude-code-runtime/index.js +19 -1
  2. package/dist/adapters/codex-runtime.js +13 -3
  3. package/dist/agents/agent-message-parts.js +9 -1
  4. package/dist/agents/commit-agent.js +7 -15
  5. package/dist/app.js +26 -0
  6. package/dist/package.json +2 -0
  7. package/dist/routes/code-favorites.js +60 -0
  8. package/dist/routes/file.js +13 -0
  9. package/dist/routes/prompt-template.js +48 -0
  10. package/dist/services/agent.js +45 -3
  11. package/dist/services/code-favorites.js +23 -0
  12. package/dist/services/file.js +4 -0
  13. package/dist/services/persistent-agent-context.js +3 -2
  14. package/dist/services/prompt-template.js +93 -0
  15. package/dist/services/pty.js +18 -1
  16. package/dist/storage/code-favorites-store.js +15 -0
  17. package/dist/web/404.html +1 -1
  18. package/dist/web/__next.__PAGE__.txt +4 -4
  19. package/dist/web/__next._full.txt +21 -21
  20. package/dist/web/__next._head.txt +4 -4
  21. package/dist/web/__next._index.txt +13 -13
  22. package/dist/web/__next._tree.txt +2 -2
  23. package/dist/web/_next/static/chunks/0-1pn22sg~67u.js +2 -0
  24. package/dist/web/_next/static/chunks/0-lseun2l1m_t.js +2 -0
  25. package/dist/web/_next/static/chunks/0-wkj-hzh444r.css +4 -0
  26. package/dist/web/_next/static/chunks/{0f6vrjsdauiwl.js → 0-~4vw4_9z_0_.js} +2 -2
  27. package/dist/web/_next/static/chunks/0..g0jl-8qup7.js +1 -0
  28. package/dist/web/_next/static/chunks/0.006.ycpe92w.js +496 -0
  29. package/dist/web/_next/static/chunks/0.6x8f.mb-1qf.js +1 -0
  30. package/dist/web/_next/static/chunks/{0qe5wvs8fe9ip.js → 004wt62de8617.js} +1 -1
  31. package/dist/web/_next/static/chunks/016xz2o-hv3am.js +1 -0
  32. package/dist/web/_next/static/chunks/01gi~q0c6ez6..js +1 -0
  33. package/dist/web/_next/static/chunks/023lpc7n70tav.css +1 -0
  34. package/dist/web/_next/static/chunks/03me5_ir..2ix.js +1 -0
  35. package/dist/web/_next/static/chunks/04fk~8rnrvs44.js +1 -0
  36. package/dist/web/_next/static/chunks/05eu2fdixf7c9.js +1 -0
  37. package/dist/web/_next/static/chunks/05gt_g_vbzh-5.css +1 -0
  38. package/dist/web/_next/static/chunks/06vadtvw631k5.css +1 -0
  39. package/dist/web/_next/static/chunks/07ge_85i__6pb.js +1 -0
  40. package/dist/web/_next/static/chunks/07ne4g8zopykv.js +1 -0
  41. package/dist/web/_next/static/chunks/07xvadmf~8bow.js +1 -0
  42. package/dist/web/_next/static/chunks/08.u~dmq20cak.css +23 -0
  43. package/dist/web/_next/static/chunks/08ag2f8y6f8cr.js +1 -0
  44. package/dist/web/_next/static/chunks/{03sd~wmqw.9gc.js → 08kpa0nox.bb1.js} +2 -2
  45. package/dist/web/_next/static/chunks/08o-zmr-40r5g.js +1 -0
  46. package/dist/web/_next/static/chunks/0_-c.y2qq4ax4.js +270 -0
  47. package/dist/web/_next/static/chunks/0a1rewz7xr-xi.js +1 -0
  48. package/dist/web/_next/static/chunks/0amcocbojo4v2.js +1 -0
  49. package/dist/web/_next/static/chunks/0brrgp3ki5w4_.css +17 -0
  50. package/dist/web/_next/static/chunks/0bzmgi.ynrn.0.css +3 -0
  51. package/dist/web/_next/static/chunks/0c_vfzf1z7-rt.js +2 -0
  52. package/dist/web/_next/static/chunks/0cjmfclopcxho.css +1 -0
  53. package/dist/web/_next/static/chunks/0cs830n97dgjy.js +1 -0
  54. package/dist/web/_next/static/chunks/0d_dp_4ofz0l3.css +3 -0
  55. package/dist/web/_next/static/chunks/0dws-faof-ryx.css +13 -0
  56. package/dist/web/_next/static/chunks/0ejc_zlyocy_r.css +1 -0
  57. package/dist/web/_next/static/chunks/0esty_4gmxfq3.js +1 -0
  58. package/dist/web/_next/static/chunks/0evjw7bao5_e~.js +1 -0
  59. package/dist/web/_next/static/chunks/{0ag4p6m9rze~n.js → 0g-0n6glz_z6w.js} +1 -1
  60. package/dist/web/_next/static/chunks/{145qu5b0tgm9w.js → 0gig.k.rq8d0x.js} +1 -1
  61. package/dist/web/_next/static/chunks/0hl_7y464qll6.css +2 -0
  62. package/dist/web/_next/static/chunks/0hrbuvzuxrjfl.js +1 -0
  63. package/dist/web/_next/static/chunks/0i_3.3rdsu2mw.js +2 -0
  64. package/dist/web/_next/static/chunks/0i_gi.kq2dau8.css +1 -0
  65. package/dist/web/_next/static/chunks/0j00r2f_n-.lx.js +1 -0
  66. package/dist/web/_next/static/chunks/0jh9xnkimjkyh.js +1 -0
  67. package/dist/web/_next/static/chunks/0jokpgh485~28.js +167 -0
  68. package/dist/web/_next/static/chunks/0kvsjgpj7zcb9.css +9 -0
  69. package/dist/web/_next/static/chunks/0l5ab99s37x5f.js +1 -0
  70. package/dist/web/_next/static/chunks/0lcc9r.o.p.sc.js +1 -0
  71. package/dist/web/_next/static/chunks/0lh~x2tf~i1hd.css +2 -0
  72. package/dist/web/_next/static/chunks/0me8ho8j4tq7_.css +2 -0
  73. package/dist/web/_next/static/chunks/0mny8i81aenx3.js +1 -0
  74. package/dist/web/_next/static/chunks/0mt-7av8yrg0o.css +3 -0
  75. package/dist/web/_next/static/chunks/0njy89g5coeyi.js +60 -0
  76. package/dist/web/_next/static/chunks/0nsu~f3voe~0i.js +5 -0
  77. package/dist/web/_next/static/chunks/0ow~co9wcleka.js +173 -0
  78. package/dist/web/_next/static/chunks/0pldvk5_h__t7.css +3 -0
  79. package/dist/web/_next/static/chunks/0qad.lgvtlt0b.css +16 -0
  80. package/dist/web/_next/static/chunks/0qpq0~_58fe9a.js +18 -0
  81. package/dist/web/_next/static/chunks/{0.335m_d-cd_g.js → 0qtc_rbo1oghu.js} +1 -1
  82. package/dist/web/_next/static/chunks/0qz5~3wquy~3q.css +2 -0
  83. package/dist/web/_next/static/chunks/0rv0nj__24y60.js +10 -0
  84. package/dist/web/_next/static/chunks/{145gbwitjxamg.js → 0sz8_nijfiz0p.js} +1 -1
  85. package/dist/web/_next/static/chunks/0tvd~rxgf0oh_.js +1 -0
  86. package/dist/web/_next/static/chunks/0wv0h27jafag4.js +1 -0
  87. package/dist/web/_next/static/chunks/0wwvc4zc2q6bn.js +1 -0
  88. package/dist/web/_next/static/chunks/0x4b-a2ixww6m.js +1 -0
  89. package/dist/web/_next/static/chunks/0z8ipjj2z-3al.css +8 -0
  90. package/dist/web/_next/static/chunks/0zd1o3u04~qvo.js +127 -0
  91. package/dist/web/_next/static/chunks/0~2l1-8o4delc.js +1 -0
  92. package/dist/web/_next/static/chunks/0~w6ugk9s5p-h.css +1 -0
  93. package/dist/web/_next/static/chunks/10jfi.9fw5g48.js +1 -0
  94. package/dist/web/_next/static/chunks/11_tltlhc8.sj.js +1 -0
  95. package/dist/web/_next/static/chunks/125nunjfj2fj0.js +1 -0
  96. package/dist/web/_next/static/chunks/12md9ajfx2o85.css +1 -0
  97. package/dist/web/_next/static/chunks/12odetnu-lyrr.js +167 -0
  98. package/dist/web/_next/static/chunks/12u4g4uzrlten.js +2 -0
  99. package/dist/web/_next/static/chunks/134ozsnbd~0qw.js +1 -0
  100. package/dist/web/_next/static/chunks/13ess~4pdmxma.js +1 -0
  101. package/dist/web/_next/static/chunks/13xfagjq0q~tf.js +1 -0
  102. package/dist/web/_next/static/chunks/143.pbs8a1ivm.js +1 -0
  103. package/dist/web/_next/static/chunks/14_y_s_5rhsd1.css +5 -0
  104. package/dist/web/_next/static/chunks/15hca2.5le07..js +3 -0
  105. package/dist/web/_next/static/chunks/15rf3~h7sugz4.css +19 -0
  106. package/dist/web/_next/static/chunks/16i87txo0qh0h.css +6 -0
  107. package/dist/web/_next/static/chunks/16~udgv7eel6a.css +2 -0
  108. package/dist/web/_next/static/chunks/{turbopack-0-j2hpomozegf.js → turbopack-000x5q9w-wx10.js} +1 -1
  109. package/dist/web/_next/static/chunks/{turbopack-0rrhp9pbrv0p3.js → turbopack-0hrx111grzq49.js} +1 -1
  110. package/dist/web/_next/static/chunks/{turbopack-0_zn00zg5kmqz.js → turbopack-0w-kua.9ymd0x.js} +1 -1
  111. package/dist/web/_next/static/chunks/{turbopack-0l~pq1hytx49z.js → turbopack-15zqm_4ixj.18.js} +1 -1
  112. package/dist/web/_next/static/media/code-icon.0g3wskzlr7oxf.svg +1 -0
  113. package/dist/web/_next/static/media/codicon.0pqe-t5rtghj8.ttf +0 -0
  114. package/dist/web/_next/static/media/continue-tb.0qei4mru4tzd2.png +0 -0
  115. package/dist/web/_next/static/media/dark_modern.09.uq6bp373zs.json +1 -0
  116. package/dist/web/_next/static/media/dark_plus.187umr0~d1_r7.json +1 -0
  117. package/dist/web/_next/static/media/dark_vs.12ju8ocr7rg--.json +1 -0
  118. package/dist/web/_next/static/media/document-dark.0vvlbsi_fdy~4.svg +3 -0
  119. package/dist/web/_next/static/media/document-light.0bfi_yt9e~vk7.svg +3 -0
  120. package/dist/web/_next/static/media/editor.worker.0ffjdaaj15t6e.js +1 -0
  121. package/dist/web/_next/static/media/extensionHost.worker.14sz5xf8-1efr.js +2 -0
  122. package/dist/web/_next/static/media/fake.16yx0-xxqj4pc.html +10 -0
  123. package/dist/web/_next/static/media/folder-dark.02kdicw3013tb.svg +3 -0
  124. package/dist/web/_next/static/media/folder-light.0s165k4fp3.53.svg +3 -0
  125. package/dist/web/_next/static/media/folder-open-dark.0sk6.yh45uqs3.svg +4 -0
  126. package/dist/web/_next/static/media/folder-open-light.10k1v_ugaq8ic.svg +4 -0
  127. package/dist/web/_next/static/media/hc_black.0-ul9e2oc5twb.json +1 -0
  128. package/dist/web/_next/static/media/hc_light.0vi.a7fr.z4gy.json +1 -0
  129. package/dist/web/_next/static/media/index.0jmafs_mwcjgg.html +1341 -0
  130. package/dist/web/_next/static/media/keyboard-dark.0t86n~1rrhj2-.svg +10 -0
  131. package/dist/web/_next/static/media/keyboard-light.0abw0ukjcd9ox.svg +10 -0
  132. package/dist/web/_next/static/media/letterpress-dark.181s2xkw~lfyo.svg +3 -0
  133. package/dist/web/_next/static/media/letterpress-hcDark.0ftfw8fess-5y.svg +3 -0
  134. package/dist/web/_next/static/media/letterpress-hcLight.06x23d0.aixf_.svg +3 -0
  135. package/dist/web/_next/static/media/letterpress-light.0xb1bapis~iw7.svg +3 -0
  136. package/dist/web/_next/static/media/light_modern.00ps-apoc9ph7.json +1 -0
  137. package/dist/web/_next/static/media/light_plus.0ow37ouyuazdz.json +1 -0
  138. package/dist/web/_next/static/media/light_vs.0fdbve5sxkgq1.json +1 -0
  139. package/dist/web/_next/static/media/onig.0dk~55st~1x8..wasm +0 -0
  140. package/dist/web/_next/static/media/opacity-background.0-9.t0ta0ko23.png +0 -0
  141. package/dist/web/_next/static/media/package.0_p8a~hpmb_uj.json +1 -0
  142. package/dist/web/_next/static/media/package.nls.0e5hn-g497b64.json +1 -0
  143. package/dist/web/_next/static/media/pause-tb.0ttrm1r1uuz_c.png +0 -0
  144. package/dist/web/_next/static/media/restart-tb.086872s_sc2qv.png +0 -0
  145. package/dist/web/_next/static/media/root-folder-dark.14iwnfb7p2na~.svg +5 -0
  146. package/dist/web/_next/static/media/root-folder-light.0ljk9fi7sw3.2.svg +5 -0
  147. package/dist/web/_next/static/media/root-folder-open-dark.08vw3g9zvki33.svg +5 -0
  148. package/dist/web/_next/static/media/root-folder-open-light.0f46.ahns5c~..svg +5 -0
  149. package/dist/web/_next/static/media/run-with-debugging-tb.0j1h52k~h~72z.png +0 -0
  150. package/dist/web/_next/static/media/service-worker.0_udu6mraxn4k.js +543 -0
  151. package/dist/web/_next/static/media/stepinto-tb.0cl87yt4ub_j8.png +0 -0
  152. package/dist/web/_next/static/media/stepout-tb.0vjib_bn-_xax.png +0 -0
  153. package/dist/web/_next/static/media/stepover-tb.04beeu~7cxr4l.png +0 -0
  154. package/dist/web/_next/static/media/stop-tb.1498tmu97_y9j.png +0 -0
  155. package/dist/web/_next/static/media/vs_minimal-icon-theme.0-qs73lvw4voi.json +1 -0
  156. package/dist/web/_next/static/media/webWorkerExtensionHostIframe.0x2r1o97s.m0m.html +156 -0
  157. package/dist/web/_next/static/media/worker.081j0x4avp1l1.js +2 -0
  158. package/dist/web/_not-found/__next._full.txt +19 -19
  159. package/dist/web/_not-found/__next._head.txt +4 -4
  160. package/dist/web/_not-found/__next._index.txt +13 -13
  161. package/dist/web/_not-found/__next._not-found.__PAGE__.txt +2 -2
  162. package/dist/web/_not-found/__next._not-found.txt +3 -3
  163. package/dist/web/_not-found/__next._tree.txt +2 -2
  164. package/dist/web/_not-found.html +1 -1
  165. package/dist/web/_not-found.txt +19 -19
  166. package/dist/web/index.html +1 -1
  167. package/dist/web/index.txt +21 -21
  168. package/dist/web/login/__next._full.txt +21 -21
  169. package/dist/web/login/__next._head.txt +4 -4
  170. package/dist/web/login/__next._index.txt +13 -13
  171. package/dist/web/login/__next._tree.txt +2 -2
  172. package/dist/web/login/__next.login.__PAGE__.txt +4 -4
  173. package/dist/web/login/__next.login.txt +3 -3
  174. package/dist/web/login.html +1 -1
  175. package/dist/web/login.txt +21 -21
  176. package/dist/web/settings/__next._full.txt +23 -23
  177. package/dist/web/settings/__next._head.txt +4 -4
  178. package/dist/web/settings/__next._index.txt +13 -13
  179. package/dist/web/settings/__next._tree.txt +2 -2
  180. package/dist/web/settings/__next.settings.__PAGE__.txt +4 -4
  181. package/dist/web/settings/__next.settings.txt +5 -5
  182. package/dist/web/settings/agents/__next._full.txt +23 -23
  183. package/dist/web/settings/agents/__next._head.txt +4 -4
  184. package/dist/web/settings/agents/__next._index.txt +13 -13
  185. package/dist/web/settings/agents/__next._tree.txt +2 -2
  186. package/dist/web/settings/agents/__next.settings.agents.__PAGE__.txt +4 -4
  187. package/dist/web/settings/agents/__next.settings.agents.txt +3 -3
  188. package/dist/web/settings/agents/__next.settings.txt +5 -5
  189. package/dist/web/settings/agents.html +1 -1
  190. package/dist/web/settings/agents.txt +23 -23
  191. package/dist/web/settings/mcps/__next._full.txt +23 -23
  192. package/dist/web/settings/mcps/__next._head.txt +4 -4
  193. package/dist/web/settings/mcps/__next._index.txt +13 -13
  194. package/dist/web/settings/mcps/__next._tree.txt +2 -2
  195. package/dist/web/settings/mcps/__next.settings.mcps.__PAGE__.txt +4 -4
  196. package/dist/web/settings/mcps/__next.settings.mcps.txt +3 -3
  197. package/dist/web/settings/mcps/__next.settings.txt +5 -5
  198. package/dist/web/settings/mcps.html +1 -1
  199. package/dist/web/settings/mcps.txt +23 -23
  200. package/dist/web/settings/models/__next._full.txt +23 -23
  201. package/dist/web/settings/models/__next._head.txt +4 -4
  202. package/dist/web/settings/models/__next._index.txt +13 -13
  203. package/dist/web/settings/models/__next._tree.txt +2 -2
  204. package/dist/web/settings/models/__next.settings.models.__PAGE__.txt +4 -4
  205. package/dist/web/settings/models/__next.settings.models.txt +3 -3
  206. package/dist/web/settings/models/__next.settings.txt +5 -5
  207. package/dist/web/settings/models.html +1 -1
  208. package/dist/web/settings/models.txt +23 -23
  209. package/dist/web/settings/prompts/__next._full.txt +42 -0
  210. package/dist/web/settings/prompts/__next._head.txt +6 -0
  211. package/dist/web/settings/prompts/__next._index.txt +15 -0
  212. package/dist/web/settings/prompts/__next._tree.txt +8 -0
  213. package/dist/web/settings/prompts/__next.settings.prompts.__PAGE__.txt +9 -0
  214. package/dist/web/settings/prompts/__next.settings.prompts.txt +5 -0
  215. package/dist/web/settings/prompts/__next.settings.txt +7 -0
  216. package/dist/web/settings/prompts.html +1 -0
  217. package/dist/web/settings/prompts.txt +42 -0
  218. package/dist/web/settings/providers/__next._full.txt +23 -23
  219. package/dist/web/settings/providers/__next._head.txt +4 -4
  220. package/dist/web/settings/providers/__next._index.txt +13 -13
  221. package/dist/web/settings/providers/__next._tree.txt +2 -2
  222. package/dist/web/settings/providers/__next.settings.providers.__PAGE__.txt +4 -4
  223. package/dist/web/settings/providers/__next.settings.providers.txt +3 -3
  224. package/dist/web/settings/providers/__next.settings.txt +5 -5
  225. package/dist/web/settings/providers.html +1 -1
  226. package/dist/web/settings/providers.txt +23 -23
  227. package/dist/web/settings/skills/__next._full.txt +23 -23
  228. package/dist/web/settings/skills/__next._head.txt +4 -4
  229. package/dist/web/settings/skills/__next._index.txt +13 -13
  230. package/dist/web/settings/skills/__next._tree.txt +2 -2
  231. package/dist/web/settings/skills/__next.settings.skills.__PAGE__.txt +4 -4
  232. package/dist/web/settings/skills/__next.settings.skills.txt +3 -3
  233. package/dist/web/settings/skills/__next.settings.txt +5 -5
  234. package/dist/web/settings/skills.html +1 -1
  235. package/dist/web/settings/skills.txt +23 -23
  236. package/dist/web/settings.html +1 -1
  237. package/dist/web/settings.txt +23 -23
  238. package/dist/web/workflows/__next._full.txt +21 -21
  239. package/dist/web/workflows/__next._head.txt +4 -4
  240. package/dist/web/workflows/__next._index.txt +13 -13
  241. package/dist/web/workflows/__next._tree.txt +2 -2
  242. package/dist/web/workflows/__next.workflows.__PAGE__.txt +4 -4
  243. package/dist/web/workflows/__next.workflows.txt +3 -3
  244. package/dist/web/workflows.html +1 -1
  245. package/dist/web/workflows.txt +21 -21
  246. package/dist/web/workspace/_/__next._full.txt +68 -35
  247. package/dist/web/workspace/_/__next._head.txt +4 -4
  248. package/dist/web/workspace/_/__next._index.txt +13 -13
  249. package/dist/web/workspace/_/__next._tree.txt +15 -3
  250. package/dist/web/workspace/_/__next.workspace.$d$id.__PAGE__.txt +16 -4
  251. package/dist/web/workspace/_/__next.workspace.$d$id.txt +3 -3
  252. package/dist/web/workspace/_/__next.workspace.txt +3 -3
  253. package/dist/web/workspace/_.html +1 -1
  254. package/dist/web/workspace/_.txt +68 -35
  255. package/dist/web/workspaces/__next._full.txt +21 -21
  256. package/dist/web/workspaces/__next._head.txt +4 -4
  257. package/dist/web/workspaces/__next._index.txt +13 -13
  258. package/dist/web/workspaces/__next._tree.txt +2 -2
  259. package/dist/web/workspaces/__next.workspaces.__PAGE__.txt +4 -4
  260. package/dist/web/workspaces/__next.workspaces.txt +3 -3
  261. package/dist/web/workspaces.html +1 -1
  262. package/dist/web/workspaces.txt +21 -21
  263. package/dist/ws/agent-runner.js +158 -20
  264. package/dist/ws/handler.js +6 -1
  265. package/dist/ws/message-parts.js +20 -1
  266. package/dist/ws/terminal-handler.js +12 -7
  267. package/dist/ws/typescript-lsp.js +78 -0
  268. package/package.json +3 -1
  269. package/dist/web/_next/static/chunks/0-a17~4piefz_.js +0 -1
  270. package/dist/web/_next/static/chunks/01tyftu_-l7tm.css +0 -1
  271. package/dist/web/_next/static/chunks/028b9_5cyq-_m.js +0 -1
  272. package/dist/web/_next/static/chunks/0anuxr11yn5iv.js +0 -2
  273. package/dist/web/_next/static/chunks/0e.z4v3cd78dx.js +0 -1
  274. package/dist/web/_next/static/chunks/0egot8y~i-ge3.js +0 -1
  275. package/dist/web/_next/static/chunks/0eq7wt-l.fetc.js +0 -1
  276. package/dist/web/_next/static/chunks/0gtbd3yt7y1gx.js +0 -1
  277. package/dist/web/_next/static/chunks/0j2w71psq6w9u.js +0 -1
  278. package/dist/web/_next/static/chunks/0kyv5yika-41a.js +0 -1
  279. package/dist/web/_next/static/chunks/0ms3tsu4men_j.js +0 -204
  280. package/dist/web/_next/static/chunks/0plreh4_gkxf9.js +0 -1
  281. package/dist/web/_next/static/chunks/0qxk21zejhdbm.js +0 -1
  282. package/dist/web/_next/static/chunks/12gvpt~z9mn8w.js +0 -1
  283. package/dist/web/_next/static/chunks/14iaqoj9-09g..js +0 -2
  284. package/dist/web/_next/static/chunks/15dyaigebtnwg.js +0 -5
  285. package/dist/web/_next/static/chunks/17oc2l.ekcs8b.css +0 -1
  286. /package/dist/web/_next/static/{O5-QCW1u2YNyAUyaoYh6s → Pf6ZjtN82szw-ZzU9lITd}/_buildManifest.js +0 -0
  287. /package/dist/web/_next/static/{O5-QCW1u2YNyAUyaoYh6s → Pf6ZjtN82szw-ZzU9lITd}/_clientMiddlewareManifest.js +0 -0
  288. /package/dist/web/_next/static/{O5-QCW1u2YNyAUyaoYh6s → Pf6ZjtN82szw-ZzU9lITd}/_ssgManifest.js +0 -0
@@ -54,6 +54,7 @@ export class ClaudeCodeRuntime {
54
54
  additionalDirectories,
55
55
  permissionMode,
56
56
  allowDangerouslySkipPermissions: permissionMode === 'bypassPermissions' ? true : undefined,
57
+ resume: options?.resumeSessionId,
57
58
  abortController: this.abortController,
58
59
  env: buildEnv(this.config, configDir, { baseURL, apiKey }),
59
60
  stderr: (data) => {
@@ -72,10 +73,16 @@ export class ClaudeCodeRuntime {
72
73
  let usageLine = null;
73
74
  let usage;
74
75
  let costUsd;
76
+ let sessionId = options?.resumeSessionId;
75
77
  let sawResult = false;
76
78
  const pendingAskUserQuestionToolIds = new Set();
77
79
  let waitingForUserAnswer = false;
78
80
  for await (const message of this.activeQuery) {
81
+ const nextSessionId = readSessionId(message);
82
+ if (nextSessionId && nextSessionId !== sessionId) {
83
+ sessionId = nextSessionId;
84
+ options?.onEvent?.({ type: 'session', sessionId });
85
+ }
79
86
  const toolUses = extractToolUseEvents(message);
80
87
  for (const toolUse of toolUses) {
81
88
  if (toolUse.name === 'AskUserQuestion') {
@@ -116,6 +123,7 @@ export class ClaudeCodeRuntime {
116
123
  usageLine = formatUsageLine(message.usage);
117
124
  usage = normalizeUsage(message.usage);
118
125
  costUsd = readTotalCostUsd(message);
126
+ sessionId = readSessionId(message) ?? sessionId;
119
127
  if (message.subtype === 'success') {
120
128
  if (!isAskUserQuestionAutoResult(message.result)) {
121
129
  resultText = message.result;
@@ -141,6 +149,7 @@ export class ClaudeCodeRuntime {
141
149
  output,
142
150
  usage,
143
151
  costUsd,
152
+ sessionId,
144
153
  };
145
154
  }
146
155
  if (waitingForUserAnswer && (!error || isAskUserQuestionAutoResult(error))) {
@@ -154,6 +163,7 @@ export class ClaudeCodeRuntime {
154
163
  output,
155
164
  usage,
156
165
  costUsd,
166
+ sessionId,
157
167
  };
158
168
  }
159
169
  if (error) {
@@ -170,6 +180,7 @@ export class ClaudeCodeRuntime {
170
180
  output,
171
181
  usage,
172
182
  costUsd,
183
+ sessionId,
173
184
  };
174
185
  }
175
186
  const text = resultText || output.at(-1) || '';
@@ -187,6 +198,7 @@ export class ClaudeCodeRuntime {
187
198
  output: finalOutput,
188
199
  usage,
189
200
  costUsd,
201
+ sessionId,
190
202
  };
191
203
  }
192
204
  catch (err) {
@@ -198,7 +210,7 @@ export class ClaudeCodeRuntime {
198
210
  console.error(err.stack);
199
211
  appendUnique(output, stderrLines);
200
212
  appendUnique(output, [runtimeError]);
201
- return { success: false, summary: 'Claude Code execution failed', artifacts: [], error: runtimeError, output };
213
+ return { success: false, summary: 'Claude Code execution failed', artifacts: [], error: runtimeError, output, sessionId: options?.resumeSessionId };
202
214
  }
203
215
  finally {
204
216
  this.activeQuery?.close();
@@ -215,6 +227,12 @@ export class ClaudeCodeRuntime {
215
227
  });
216
228
  }
217
229
  }
230
+ function readSessionId(message) {
231
+ if (!message || typeof message !== 'object')
232
+ return undefined;
233
+ const value = message.session_id;
234
+ return typeof value === 'string' && value.trim() ? value : undefined;
235
+ }
218
236
  function readTotalCostUsd(message) {
219
237
  if (!message || typeof message !== 'object')
220
238
  return undefined;
@@ -35,7 +35,7 @@ export class CodexRuntime {
35
35
  config: configOverrides,
36
36
  env: buildEnv(this.config, codexHome),
37
37
  });
38
- const thread = codex.startThread({
38
+ const threadOptions = {
39
39
  model: this.config.model,
40
40
  sandboxMode,
41
41
  approvalPolicy,
@@ -44,7 +44,10 @@ export class CodexRuntime {
44
44
  additionalDirectories: options?.sandboxDirs,
45
45
  networkAccessEnabled: true,
46
46
  webSearchMode: 'live',
47
- });
47
+ };
48
+ const thread = options?.resumeSessionId
49
+ ? codex.resumeThread(options.resumeSessionId, threadOptions)
50
+ : codex.startThread(threadOptions);
48
51
  const { events } = await thread.runStreamed(prompt, {
49
52
  signal: this.abortController.signal,
50
53
  });
@@ -52,8 +55,13 @@ export class CodexRuntime {
52
55
  let tokenCount = 0;
53
56
  let usage;
54
57
  let error;
58
+ let sessionId = options?.resumeSessionId ?? thread.id ?? undefined;
55
59
  const emittedItemLines = new Set();
56
60
  for await (const event of events) {
61
+ if (event.type === 'thread.started') {
62
+ sessionId = event.thread_id;
63
+ options?.onEvent?.({ type: 'session', sessionId });
64
+ }
57
65
  logEventDebug(event, d);
58
66
  const mappedEvents = mapRuntimeEvents(event);
59
67
  const mappedEventLines = new Set(mappedEvents.flatMap((runtimeEvent) => (runtimeEvent.type === 'tool_use' ? [runtimeEvent.line] : [])));
@@ -95,6 +103,7 @@ export class CodexRuntime {
95
103
  artifacts: [],
96
104
  error,
97
105
  output,
106
+ sessionId,
98
107
  usage,
99
108
  };
100
109
  }
@@ -105,6 +114,7 @@ export class CodexRuntime {
105
114
  summary: summarizeResult(text),
106
115
  artifacts: [],
107
116
  output,
117
+ sessionId,
108
118
  usage,
109
119
  };
110
120
  }
@@ -114,7 +124,7 @@ export class CodexRuntime {
114
124
  d(`failed ${elapsed}ms | ${message}`);
115
125
  if (err instanceof Error && err.stack)
116
126
  console.error(err.stack);
117
- return { success: false, summary: 'Codex execution failed', artifacts: [], error: message, output };
127
+ return { success: false, summary: 'Codex execution failed', artifacts: [], error: message, output, sessionId: options?.resumeSessionId };
118
128
  }
119
129
  finally {
120
130
  this.abortController = null;
@@ -41,6 +41,8 @@ export function createAgentMessagePartsTracker(input) {
41
41
  }
42
42
  return;
43
43
  }
44
+ if (event.type === 'session')
45
+ return;
44
46
  output.push(event.line);
45
47
  input.onOutput?.(event.line);
46
48
  },
@@ -432,11 +434,17 @@ function isToolLikeLine(line) {
432
434
  return /^(Using|Tool:|Read|Write|Edit|MultiEdit|Bash|Search|Grep|Glob|Todo|Task|Web|Fetch|Claude Code initialized|Codex initialized|.+ running \(\d+s\))/i.test(line.trim());
433
435
  }
434
436
  function isIgnorableToolProgressLine(line) {
435
- const trimmed = line.trim();
437
+ const raw = line.trim();
438
+ const trimmed = stripSubagentProgressPrefix(raw);
439
+ const isSubagentProgress = trimmed !== raw;
436
440
  return /^Claude$/i.test(trimmed)
437
441
  || /^(Reading|Searching)(\.{1,3}|…)?$/i.test(trimmed)
442
+ || (isSubagentProgress && /^(Reading|Searching)\s+\S.+$/i.test(trimmed))
438
443
  || /^(Read|Search|Grep|Glob|SemanticSearch|WebSearch)\s+running\s+\(\d+s\)$/i.test(trimmed);
439
444
  }
445
+ function stripSubagentProgressPrefix(line) {
446
+ return line.replace(/^\[[^\]]+\]\s+subagent progress\s+\|\s*/i, '');
447
+ }
440
448
  function isFinalAnswerLine(line) {
441
449
  return !isToolLikeLine(line) && !/^(\[.*\]|Agent runtime configuration:|Conversation history:)/.test(line.trim());
442
450
  }
@@ -1,19 +1,11 @@
1
1
  import * as agentService from '../services/agent.js';
2
+ import { AGENT_COMMIT_PRESET_ID, getDefaultCommitAgentPreset } from '../services/agent.js';
2
3
  import { createAgentRuntime } from '../adapters/agent-runtime.js';
3
4
  import { getWorkspace } from '../storage/workspace-store.js';
4
5
  import { getThinkingRuntimeConfig } from '../services/llm-model-config.js';
5
6
  import { prependPersistentAgentContext } from '../services/persistent-agent-context.js';
6
7
  import { simpleGit } from 'simple-git';
7
- const DEFAULT_SYSTEM_PROMPT = [
8
- 'You are a git commit message generator.',
9
- 'Return exactly one concise commit message for the provided git diff.',
10
- 'Use conventional format: type: description.',
11
- 'Allowed types: feat, fix, docs, style, refactor, perf, test, chore.',
12
- 'Keep the subject under 72 characters.',
13
- 'If a body is needed, add one blank line and at most 3 short bullet lines.',
14
- 'Do not greet, explain, ask questions, provide options, use markdown, or wrap in code fences.',
15
- 'Output only the final commit message text.',
16
- ].join(' ');
8
+ const DEFAULT_SYSTEM_PROMPT = 'You are a git commit message generator. Return exactly one concise commit message for the provided git diff. Use conventional format: type: description. Allowed types: feat, fix, docs, style, refactor, perf, test, chore. Keep the subject under 72 characters. If a body is needed, add one blank line and at most 3 short bullet lines. Do not greet, explain, ask questions, provide options, use markdown, or wrap in code fences. Output only the final commit message text.';
17
9
  export async function runCommitAgent(workspaceId) {
18
10
  const ws = getWorkspace(workspaceId);
19
11
  if (!ws)
@@ -22,8 +14,6 @@ export async function runCommitAgent(workspaceId) {
22
14
  if (!diff.trim())
23
15
  throw new Error('No changes found');
24
16
  const commitAgent = findCommitAgent(workspaceId);
25
- if (!commitAgent)
26
- throw new Error('No commit agent configured. Add a commit-type agent preset.');
27
17
  const session = agentService.getOrCreateSessionForConfig(workspaceId, commitAgent);
28
18
  agentService.updateStatus(workspaceId, session.id, 'active');
29
19
  const runtime = createAgentRuntime({
@@ -199,9 +189,11 @@ function inferType(subject) {
199
189
  }
200
190
  function findCommitAgent(workspaceId) {
201
191
  const presets = agentService.listPresets(workspaceId);
202
- if (!presets)
203
- return null;
204
- return presets.find((a) => a.role === 'commit' && a.enabled !== false) ?? null;
192
+ const preset = presets?.find((a) => a.id === AGENT_COMMIT_PRESET_ID);
193
+ if (preset)
194
+ return preset;
195
+ const template = agentService.readAgentTemplate(AGENT_COMMIT_PRESET_ID);
196
+ return template ?? getDefaultCommitAgentPreset();
205
197
  }
206
198
  async function collectDiff(ws) {
207
199
  const git = simpleGit(ws.boundDirs[0]);
package/dist/app.js CHANGED
@@ -21,7 +21,9 @@ import llmRouter from './routes/llm.js';
21
21
  import authRouter from './routes/auth.js';
22
22
  import folderRouter from './routes/folder.js';
23
23
  import commandRouter from './routes/command.js';
24
+ import codeFavoritesRouter from './routes/code-favorites.js';
24
25
  import skillRouter from './routes/skill.js';
26
+ import promptTemplateRouter from './routes/prompt-template.js';
25
27
  import mcpRouter from './routes/mcp.js';
26
28
  import subscriptionRouter from './routes/subscription.js';
27
29
  import agentSseRouter from './routes/agent-sse.js';
@@ -31,6 +33,7 @@ import speechRecognitionRouter, { handleSpeechStream } from './routes/speech-rec
31
33
  import { getUserSettings, setUserAvatarUrl, removeUserAvatarUrl } from './storage/user-settings-store.js';
32
34
  import { authMiddleware, verifyToken } from './middleware/auth.js';
33
35
  import { handleConnection } from './ws/handler.js';
36
+ import { handleTypeScriptLspConnection } from './ws/typescript-lsp.js';
34
37
  import { broadcastToAll } from './ws/connection-manager.js';
35
38
  import { startScheduler, stopScheduler } from './agents/scheduler-agent.js';
36
39
  import { recoverRunningWorkOnStartup } from './services/issue-retry.js';
@@ -109,6 +112,7 @@ app.use('/api/workspaces/:id/channels', channelRouter);
109
112
  app.use('/api/workspaces/:id/issues', issueRouter);
110
113
  app.use('/api/workflows', workflowRouter);
111
114
  app.use('/api/workspaces/:id/commands', commandRouter);
115
+ app.use('/api/workspaces/:id/code-favorites', codeFavoritesRouter);
112
116
  app.use('/api/workspaces/:id/agents', agentRouter);
113
117
  app.use('/api/workspaces/:id/tasks', taskRouter);
114
118
  app.use('/api/workspaces/:id/git', gitRouter);
@@ -139,6 +143,7 @@ app.use('/api/agents', agentRouter);
139
143
  app.use('/api', llmRouter);
140
144
  app.use('/api/folder', folderRouter);
141
145
  app.use('/api/skills', skillRouter);
146
+ app.use('/api/prompt-templates', promptTemplateRouter);
142
147
  app.use('/api/mcps', mcpRouter);
143
148
  app.use('/api/subscriptions', subscriptionRouter);
144
149
  app.use('/api/speech-recognition', speechRecognitionRouter);
@@ -169,6 +174,7 @@ else {
169
174
  }
170
175
  const server = createServer(app);
171
176
  const wss = new WebSocketServer({ noServer: true });
177
+ const typescriptLspWss = new WebSocketServer({ noServer: true });
172
178
  // Speech recognition WebSocket on /ws/speech
173
179
  const speechWss = new WebSocketServer({ noServer: true });
174
180
  speechWss.on('connection', (ws, req) => {
@@ -194,6 +200,20 @@ wss.on('connection', (ws, req) => {
194
200
  }
195
201
  handleConnection(ws, workspaceId);
196
202
  });
203
+ typescriptLspWss.on('connection', (ws, req) => {
204
+ const url = new URL(req.url || '', `http://localhost:${PORT}`);
205
+ const workspaceId = url.searchParams.get('workspaceId');
206
+ if (!workspaceId) {
207
+ ws.close(4001, 'workspaceId required');
208
+ return;
209
+ }
210
+ const token = url.searchParams.get('token');
211
+ if (!verifyToken(token)) {
212
+ ws.close(4003, 'Unauthorized');
213
+ return;
214
+ }
215
+ handleTypeScriptLspConnection(ws, workspaceId);
216
+ });
197
217
  server.on('upgrade', (req, socket, head) => {
198
218
  const { pathname } = new URL(req.url || '/', `http://localhost:${PORT}`);
199
219
  if (pathname === '/ws') {
@@ -208,6 +228,12 @@ server.on('upgrade', (req, socket, head) => {
208
228
  });
209
229
  return;
210
230
  }
231
+ if (pathname === '/ws/lsp/typescript') {
232
+ typescriptLspWss.handleUpgrade(req, socket, head, (ws) => {
233
+ typescriptLspWss.emit('connection', ws, req);
234
+ });
235
+ return;
236
+ }
211
237
  socket.destroy();
212
238
  });
213
239
  const HOST = process.env.HOST || '0.0.0.0';
package/dist/package.json CHANGED
@@ -24,7 +24,9 @@
24
24
  "minimatch": "^10.2.5",
25
25
  "node-pty": "^1.1.0",
26
26
  "simple-git": "^3.36.0",
27
+ "typescript-language-server": "^5.2.0",
27
28
  "uuid": "^11.1.0",
29
+ "vscode-ws-jsonrpc": "^3.5.0",
28
30
  "ws": "^8.18.2",
29
31
  "zod": "^4.0.0"
30
32
  },
@@ -0,0 +1,60 @@
1
+ import { Router } from 'express';
2
+ import * as svc from '../services/code-favorites.js';
3
+ const router = Router({ mergeParams: true });
4
+ router.get('/', (req, res) => {
5
+ const workspaceId = req.params.id;
6
+ if (!workspaceId) {
7
+ res.status(400).json({ error: 'workspaceId required' });
8
+ return;
9
+ }
10
+ try {
11
+ res.json(svc.listFavorites(workspaceId));
12
+ }
13
+ catch (error) {
14
+ res.status(500).json({ error: error.message });
15
+ }
16
+ });
17
+ router.post('/', (req, res) => {
18
+ const workspaceId = req.params.id;
19
+ if (!workspaceId) {
20
+ res.status(400).json({ error: 'workspaceId required' });
21
+ return;
22
+ }
23
+ try {
24
+ const fav = svc.addFavorite(workspaceId, req.body);
25
+ res.status(201).json(fav);
26
+ }
27
+ catch (error) {
28
+ res.status(400).json({ error: error.message });
29
+ }
30
+ });
31
+ router.delete('/:favId', (req, res) => {
32
+ const { id: workspaceId, favId } = req.params;
33
+ if (!workspaceId || !favId) {
34
+ res.status(400).json({ error: 'workspaceId and favId required' });
35
+ return;
36
+ }
37
+ try {
38
+ svc.removeFavorite(workspaceId, favId);
39
+ res.status(204).send();
40
+ }
41
+ catch (error) {
42
+ res.status(400).json({ error: error.message });
43
+ }
44
+ });
45
+ router.delete('/', (req, res) => {
46
+ const workspaceId = req.params.id;
47
+ if (!workspaceId) {
48
+ res.status(400).json({ error: 'workspaceId required' });
49
+ return;
50
+ }
51
+ try {
52
+ svc.clearFavorites(workspaceId);
53
+ res.status(204).send();
54
+ }
55
+ catch (error) {
56
+ res.status(400).json({ error: error.message });
57
+ }
58
+ });
59
+ export default router;
60
+ //# sourceMappingURL=code-favorites.js.map
@@ -34,6 +34,19 @@ router.get('/content', async (req, res) => {
34
34
  }
35
35
  res.json(result);
36
36
  });
37
+ router.get('/exists', async (req, res) => {
38
+ const ws = fileService.getWorkspace(req.params.id);
39
+ if (!ws) {
40
+ res.status(404).json({ error: 'Workspace not found' });
41
+ return;
42
+ }
43
+ const path = req.query.path;
44
+ if (!path) {
45
+ res.status(400).json({ error: 'path is required' });
46
+ return;
47
+ }
48
+ res.json({ exists: fileService.fileExists(ws, path) });
49
+ });
37
50
  router.put('/content', async (req, res) => {
38
51
  const ws = fileService.getWorkspace(req.params.id);
39
52
  if (!ws) {
@@ -0,0 +1,48 @@
1
+ import { Router } from 'express';
2
+ import { listPromptTemplates, createPromptTemplate, updatePromptTemplate, deletePromptTemplate, applyPromptToAgents, listAgentCandidates, } from '../services/prompt-template.js';
3
+ const router = Router();
4
+ router.get('/', (_req, res) => {
5
+ res.json(listPromptTemplates());
6
+ });
7
+ router.post('/', (req, res) => {
8
+ const { name, content } = req.body;
9
+ if (!name || !content) {
10
+ res.status(400).json({ error: 'name and content required' });
11
+ return;
12
+ }
13
+ res.json(createPromptTemplate(name, content));
14
+ });
15
+ router.put('/:id', (req, res) => {
16
+ const id = typeof req.params.id === 'string' ? req.params.id : req.params.id[0];
17
+ const data = req.body;
18
+ const tmpl = updatePromptTemplate(id, data);
19
+ if (!tmpl) {
20
+ res.status(404).json({ error: 'Template not found' });
21
+ return;
22
+ }
23
+ res.json(tmpl);
24
+ });
25
+ router.delete('/:id', (req, res) => {
26
+ const id = typeof req.params.id === 'string' ? req.params.id : req.params.id[0];
27
+ const ok = deletePromptTemplate(id);
28
+ if (!ok) {
29
+ res.status(404).json({ error: 'Template not found' });
30
+ return;
31
+ }
32
+ res.json({ success: true });
33
+ });
34
+ router.post('/:id/apply', (req, res) => {
35
+ const id = typeof req.params.id === 'string' ? req.params.id : req.params.id[0];
36
+ const { agentIds } = req.body;
37
+ if (!Array.isArray(agentIds) || agentIds.length === 0) {
38
+ res.status(400).json({ error: 'agentIds required' });
39
+ return;
40
+ }
41
+ const applied = applyPromptToAgents(id, agentIds);
42
+ res.json({ applied });
43
+ });
44
+ router.get('/agents', (_req, res) => {
45
+ res.json(listAgentCandidates());
46
+ });
47
+ export default router;
48
+ //# sourceMappingURL=prompt-template.js.map
@@ -10,6 +10,7 @@ import { ensureDir, getDataDir } from '../storage/json-store.js';
10
10
  import { extractUsageFromOutput } from '../storage/usage.js';
11
11
  const DEFAULT_AGENT_ROLE = 'agent';
12
12
  export const AGENT_GENERATOR_PRESET_ID = 'agent-generator';
13
+ export const AGENT_COMMIT_PRESET_ID = 'commit-agent';
13
14
  const VALID_RUNTIME_KINDS = ['open-agent-sdk', 'claude-code', 'codex', 'langchain'];
14
15
  const VALID_TOOL_NAMES = new Set(BUILT_IN_AGENT_TOOLS.map((tool) => tool.name));
15
16
  const ANTHROPIC_BRIDGE_PROVIDERS = [
@@ -25,7 +26,7 @@ export function isValidRole(role) {
25
26
  export function listTemplates() {
26
27
  const root = getGlobalAgentTemplatesDir();
27
28
  if (!existsSync(root))
28
- return [getDefaultAgentGeneratorPreset()];
29
+ return [getDefaultAgentGeneratorPreset(), getDefaultCommitAgentPreset()];
29
30
  const templates = readdirSync(root, { withFileTypes: true })
30
31
  .filter((entry) => entry.isDirectory())
31
32
  .map((entry) => readAgentTemplate(entry.name))
@@ -33,6 +34,9 @@ export function listTemplates() {
33
34
  if (!templates.some((template) => template.id === AGENT_GENERATOR_PRESET_ID)) {
34
35
  templates.unshift(getDefaultAgentGeneratorPreset());
35
36
  }
37
+ if (!templates.some((template) => template.id === AGENT_COMMIT_PRESET_ID)) {
38
+ templates.unshift(getDefaultCommitAgentPreset());
39
+ }
36
40
  return templates;
37
41
  }
38
42
  export async function testConnection(workspaceId, data) {
@@ -515,13 +519,17 @@ function ensureWorkspaceAgentCopy(preset, agentspaceDir) {
515
519
  export function readAgentTemplate(agentId) {
516
520
  const filePath = join(getGlobalAgentTemplateDir(agentId), 'agent.json');
517
521
  if (!existsSync(filePath)) {
518
- return agentId === AGENT_GENERATOR_PRESET_ID ? getDefaultAgentGeneratorPreset() : null;
522
+ return agentId === AGENT_GENERATOR_PRESET_ID ? getDefaultAgentGeneratorPreset()
523
+ : agentId === AGENT_COMMIT_PRESET_ID ? getDefaultCommitAgentPreset()
524
+ : null;
519
525
  }
520
526
  try {
521
527
  return JSON.parse(readFileSync(filePath, 'utf-8'));
522
528
  }
523
529
  catch {
524
- return agentId === AGENT_GENERATOR_PRESET_ID ? getDefaultAgentGeneratorPreset() : null;
530
+ return agentId === AGENT_GENERATOR_PRESET_ID ? getDefaultAgentGeneratorPreset()
531
+ : agentId === AGENT_COMMIT_PRESET_ID ? getDefaultCommitAgentPreset()
532
+ : null;
525
533
  }
526
534
  }
527
535
  function getDefaultAgentGeneratorPreset() {
@@ -557,6 +565,36 @@ function getDefaultAgentGeneratorPreset() {
557
565
  enabled: true,
558
566
  };
559
567
  }
568
+ export function getDefaultCommitAgentPreset() {
569
+ return {
570
+ id: AGENT_COMMIT_PRESET_ID,
571
+ name: 'Commit Agent',
572
+ role: 'commit',
573
+ description: '根据 git diff 自动生成 conventional commit message。',
574
+ runtimeKind: 'claude-code',
575
+ modelProvider: undefined,
576
+ modelId: '',
577
+ apiBase: '',
578
+ apiKey: '',
579
+ workingDir: '',
580
+ mcps: {},
581
+ skills: [],
582
+ tools: [],
583
+ systemPrompt: [
584
+ 'You are a git commit message generator.',
585
+ 'Return exactly one concise commit message for the provided git diff.',
586
+ 'Use conventional format: type: description.',
587
+ 'Allowed types: feat, fix, docs, style, refactor, perf, test, chore.',
588
+ 'Keep the subject under 72 characters.',
589
+ 'If a body is needed, add one blank line and at most 3 short bullet lines.',
590
+ 'Do not greet, explain, ask questions, provide options, use markdown, or wrap in code fences.',
591
+ 'Output only the final commit message text.',
592
+ ].join(' '),
593
+ temperature: 0,
594
+ maxTokens: 512,
595
+ enabled: true,
596
+ };
597
+ }
560
598
  function sanitizeMarkdownFilename(name) {
561
599
  const raw = basename(name).replace(/\.md$/i, '');
562
600
  const safe = raw.replace(/[^a-zA-Z0-9._-]+/g, '-').replace(/^-+|-+$/g, '') || 'skill';
@@ -565,6 +603,8 @@ function sanitizeMarkdownFilename(name) {
565
603
  export function deletePreset(workspaceId, presetId) {
566
604
  if (presetId === AGENT_GENERATOR_PRESET_ID)
567
605
  return false;
606
+ if (presetId === AGENT_COMMIT_PRESET_ID)
607
+ return false;
568
608
  const ws = getWorkspace(workspaceId);
569
609
  if (!ws)
570
610
  return null;
@@ -654,6 +694,8 @@ export function updateGlobalPreset(presetId, data) {
654
694
  export function deleteGlobalPreset(presetId) {
655
695
  if (presetId === AGENT_GENERATOR_PRESET_ID)
656
696
  return false;
697
+ if (presetId === AGENT_COMMIT_PRESET_ID)
698
+ return false;
657
699
  const templateDir = getGlobalAgentTemplateDir(presetId);
658
700
  if (!existsSync(templateDir))
659
701
  return false;
@@ -0,0 +1,23 @@
1
+ import * as store from '../storage/code-favorites-store.js';
2
+ export function listFavorites(workspaceId) {
3
+ return store.listFavorites(workspaceId);
4
+ }
5
+ export function addFavorite(workspaceId, fav) {
6
+ const entry = {
7
+ ...fav,
8
+ id: `${fav.path}:${fav.line}:${Date.now()}`,
9
+ createdAt: Date.now(),
10
+ };
11
+ const favorites = store.listFavorites(workspaceId);
12
+ favorites.unshift(entry);
13
+ store.saveFavorites(workspaceId, favorites);
14
+ return entry;
15
+ }
16
+ export function removeFavorite(workspaceId, id) {
17
+ const favorites = store.listFavorites(workspaceId).filter(f => f.id !== id);
18
+ store.saveFavorites(workspaceId, favorites);
19
+ }
20
+ export function clearFavorites(workspaceId) {
21
+ store.saveFavorites(workspaceId, []);
22
+ }
23
+ //# sourceMappingURL=code-favorites.js.map
@@ -15,6 +15,10 @@ export function resolvePath(workspace, relPath) {
15
15
  return null;
16
16
  return abs;
17
17
  }
18
+ export function fileExists(workspace, relPath) {
19
+ const abs = resolvePath(workspace, relPath);
20
+ return !!abs && existsSync(abs);
21
+ }
18
22
  export async function readTree(workspace, relPath = '', depth = Infinity) {
19
23
  const dirPath = resolvePath(workspace, relPath);
20
24
  if (!dirPath)
@@ -1,6 +1,7 @@
1
1
  import { existsSync, realpathSync, readFileSync, statSync } from 'node:fs';
2
2
  import { homedir } from 'node:os';
3
3
  import { dirname, isAbsolute, join, relative, resolve } from 'node:path';
4
+ import { getDataDir } from '../storage/json-store.js';
4
5
  import { readWorkspacePrompt } from './workspace-prompt.js';
5
6
  const INSTRUCTION_FILENAMES = ['CLAUDE.md', 'claude.md', 'AGENTS.md', 'agents.md'];
6
7
  const MAX_FILE_CHARS = 48_000;
@@ -67,8 +68,8 @@ function collectInstructionFiles(workingDir, boundDirs, options = {}) {
67
68
  return files;
68
69
  }
69
70
  function globalInstructionPaths(options) {
70
- const claudeDir = join(homedir(), '.claude');
71
- return getInstructionFilenames(options).map((filename) => join(claudeDir, filename));
71
+ const dataDir = getDataDir();
72
+ return getInstructionFilenames(options).map((filename) => join(dataDir, filename));
72
73
  }
73
74
  function getInstructionFilenames(options) {
74
75
  if (!options.excludeNativeClaudeMd)