@agent-spaces/server 0.3.65 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (278) hide show
  1. package/dist/adapters/agent-runtime.js +8 -0
  2. package/dist/adapters/codex-function-tool-bridge.js +152 -0
  3. package/dist/adapters/codex-runtime.js +23 -4
  4. package/dist/adapters/git.js +25 -3
  5. package/dist/adapters/hermes-runtime.js +813 -0
  6. package/dist/adapters/langchain-runtime.js +384 -21
  7. package/dist/adapters/oh-my-pi-runtime.js +858 -0
  8. package/dist/adapters/open-agent-sdk-runtime.js +202 -5
  9. package/dist/adapters/open-agent-sdk-runtime.test.js +35 -0
  10. package/dist/agents/agent-message-parts.js +52 -2
  11. package/dist/agents/issue-task-controller.js +71 -2
  12. package/dist/agents/pull-request-agent.js +115 -0
  13. package/dist/agents/scheduler-agent.js +1 -1
  14. package/dist/agents/title-generator-agent.js +120 -0
  15. package/dist/app.js +61 -4
  16. package/dist/middleware/auth.js +1 -1
  17. package/dist/package.json +2 -1
  18. package/dist/routes/agent-sse.js +70 -6
  19. package/dist/routes/channel.js +23 -2
  20. package/dist/routes/chat-run.js +191 -0
  21. package/dist/routes/chat.js +142 -0
  22. package/dist/routes/command.js +16 -0
  23. package/dist/routes/data.js +189 -0
  24. package/dist/routes/git.js +10 -1
  25. package/dist/routes/import.js +199 -0
  26. package/dist/routes/issue.js +17 -5
  27. package/dist/routes/notification.js +10 -0
  28. package/dist/routes/plugin.js +69 -0
  29. package/dist/routes/version.js +95 -0
  30. package/dist/routes/workflow-hook.js +71 -0
  31. package/dist/routes/workflow.js +282 -7
  32. package/dist/routes/workspace.js +13 -4
  33. package/dist/routes/worktree.js +93 -0
  34. package/dist/services/agent.js +123 -36
  35. package/dist/services/ai-text.js +185 -0
  36. package/dist/services/builtin-tools/index.js +1 -0
  37. package/dist/services/builtin-tools/workflow-editor-tools.js +509 -0
  38. package/dist/services/builtin-tools/workflow-exec-tools.js +320 -0
  39. package/dist/services/chat.js +134 -0
  40. package/dist/services/command-process-manager.js +16 -0
  41. package/dist/services/execution-manager.js +1346 -0
  42. package/dist/services/generated-title.js +59 -0
  43. package/dist/services/gitignore.js +22 -18
  44. package/dist/services/interaction-manager.js +114 -0
  45. package/dist/services/issue-retry.js +25 -0
  46. package/dist/services/notification-center.js +9 -0
  47. package/dist/services/output-style.js +8 -1
  48. package/dist/services/plugin.js +257 -0
  49. package/dist/services/prompt-template.js +8 -1
  50. package/dist/services/pty.js +20 -0
  51. package/dist/services/search.js +16 -6
  52. package/dist/services/skill.js +2 -0
  53. package/dist/services/version.js +69 -0
  54. package/dist/services/workflow-command-runner.js +24 -0
  55. package/dist/services/workflow-trigger-service.js +137 -0
  56. package/dist/services/workflow.js +219 -39
  57. package/dist/services/workspace.js +23 -1
  58. package/dist/services/worktree.js +207 -0
  59. package/dist/storage/agent-store.js +8 -0
  60. package/dist/storage/chat-store.js +151 -0
  61. package/dist/storage/database-store.js +6 -0
  62. package/dist/storage/json-store.js +2 -1
  63. package/dist/storage/kanban-store.js +6 -0
  64. package/dist/storage/workflow-store.js +386 -22
  65. package/dist/storage/worktree-store.js +33 -0
  66. package/dist/web/404.html +1 -1
  67. package/dist/web/__next.__PAGE__.txt +4 -4
  68. package/dist/web/__next._full.txt +21 -21
  69. package/dist/web/__next._head.txt +4 -4
  70. package/dist/web/__next._index.txt +13 -13
  71. package/dist/web/__next._tree.txt +2 -2
  72. package/dist/web/_next/static/chunks/{08x85faoz58i7.js → 0-92u-tiuy40a.js} +4 -4
  73. package/dist/web/_next/static/chunks/{0db14450oqzhg.js → 0-yizd8osmas2.js} +1 -1
  74. package/dist/web/_next/static/chunks/0.ln~3mnv8.69.js +1 -0
  75. package/dist/web/_next/static/chunks/{11cchuwoupmbf.js → 01y3e9pemva7b.js} +10 -10
  76. package/dist/web/_next/static/chunks/02l~tmzrgny.~.js +1 -0
  77. package/dist/web/_next/static/chunks/03f1bwuynjdmk.js +1 -0
  78. package/dist/web/_next/static/chunks/04cb4kc9r2pd1.js +1 -0
  79. package/dist/web/_next/static/chunks/04de6ha5_e3pp.js +1 -0
  80. package/dist/web/_next/static/chunks/09he0p79ov1rn.js +1 -0
  81. package/dist/web/_next/static/chunks/09vpocs4zuc8h.js +1 -0
  82. package/dist/web/_next/static/chunks/0_o2exgr0e_nh.js +1 -0
  83. package/dist/web/_next/static/chunks/{0xbaakj0dfc0..js → 0_y9nskc-xt2k.js} +1 -1
  84. package/dist/web/_next/static/chunks/0clnj-1fi6u8j.js +3 -0
  85. package/dist/web/_next/static/chunks/0gv40by0zzxs_.js +1 -0
  86. package/dist/web/_next/static/chunks/0iusr8y88.kjg.js +1 -0
  87. package/dist/web/_next/static/chunks/{0-a.-hl3wv99k.js → 0j-8418fxvkd1.js} +1 -1
  88. package/dist/web/_next/static/chunks/0j.wxxyoclma5.js +1 -0
  89. package/dist/web/_next/static/chunks/{0.6b64sy0g5.3.js → 0jq.16sozqik..js} +1 -1
  90. package/dist/web/_next/static/chunks/0jw8xdk_fpnp0.css +1 -0
  91. package/dist/web/_next/static/chunks/0l1lkd-wcotma.js +1 -0
  92. package/dist/web/_next/static/chunks/{0u6h-hqc_i52e.js → 0ncxf_zr4n839.js} +1 -1
  93. package/dist/web/_next/static/chunks/0ndo7um~v7vco.js +1 -0
  94. package/dist/web/_next/static/chunks/0ngk.~kan8wq_.js +1 -0
  95. package/dist/web/_next/static/chunks/0ppr271hz0xoq.js +1 -0
  96. package/dist/web/_next/static/chunks/0rt9bofnn6qvn.js +1 -0
  97. package/dist/web/_next/static/chunks/0t64.9jd00hio.js +3 -0
  98. package/dist/web/_next/static/chunks/0taui9--5n6-5.js +1 -0
  99. package/dist/web/_next/static/chunks/0ty39169lh~z3.js +1 -0
  100. package/dist/web/_next/static/chunks/0v8nof~waedlu.js +1 -0
  101. package/dist/web/_next/static/chunks/{0-pi.67w.ymsr.js → 0vcfoagnpf.aw.js} +1 -1
  102. package/dist/web/_next/static/chunks/{0vis~lx0nxgn-.js → 0wwwq.gyyz0vg.js} +3 -3
  103. package/dist/web/_next/static/chunks/0x5lak8yz7pm7.js +1 -0
  104. package/dist/web/_next/static/chunks/0xon_.4-o0_zq.js +7 -0
  105. package/dist/web/_next/static/chunks/0zjnrbt7inime.js +1 -0
  106. package/dist/web/_next/static/chunks/0zwebpitvpuv1.js +1 -0
  107. package/dist/web/_next/static/chunks/0~02o4g-o6n~m.js +1 -0
  108. package/dist/web/_next/static/chunks/{0w7.tb29958zj.js → 0~fjezp.k4qk3.js} +1 -1
  109. package/dist/web/_next/static/chunks/0~sh93re1-_rp.js +1 -0
  110. package/dist/web/_next/static/chunks/10_niiq0k6o-p.js +5 -0
  111. package/dist/web/_next/static/chunks/12tjr0_2ccrtq.js +2 -0
  112. package/dist/web/_next/static/chunks/12x5.go_x9mfk.js +1 -0
  113. package/dist/web/_next/static/chunks/{0l2w0qz1ea7ql.js → 12~5dk9i9d16t.js} +2 -2
  114. package/dist/web/_next/static/chunks/13iye4rv5p31b.js +1 -0
  115. package/dist/web/_next/static/chunks/{01~quun6sefgl.js → 13~y-b.b9rrw4.js} +1 -1
  116. package/dist/web/_next/static/chunks/151wzhb5q0lo5.js +1 -0
  117. package/dist/web/_not-found/__next._full.txt +19 -19
  118. package/dist/web/_not-found/__next._head.txt +4 -4
  119. package/dist/web/_not-found/__next._index.txt +13 -13
  120. package/dist/web/_not-found/__next._not-found.__PAGE__.txt +2 -2
  121. package/dist/web/_not-found/__next._not-found.txt +3 -3
  122. package/dist/web/_not-found/__next._tree.txt +2 -2
  123. package/dist/web/_not-found.html +1 -1
  124. package/dist/web/_not-found.txt +19 -19
  125. package/dist/web/index.html +1 -1
  126. package/dist/web/index.txt +21 -21
  127. package/dist/web/login/__next._full.txt +21 -21
  128. package/dist/web/login/__next._head.txt +4 -4
  129. package/dist/web/login/__next._index.txt +13 -13
  130. package/dist/web/login/__next._tree.txt +2 -2
  131. package/dist/web/login/__next.login.__PAGE__.txt +4 -4
  132. package/dist/web/login/__next.login.txt +3 -3
  133. package/dist/web/login.html +1 -1
  134. package/dist/web/login.txt +21 -21
  135. package/dist/web/settings/__next._full.txt +23 -23
  136. package/dist/web/settings/__next._head.txt +4 -4
  137. package/dist/web/settings/__next._index.txt +13 -13
  138. package/dist/web/settings/__next._tree.txt +2 -2
  139. package/dist/web/settings/__next.settings.__PAGE__.txt +4 -4
  140. package/dist/web/settings/__next.settings.txt +5 -5
  141. package/dist/web/settings/agents/__next._full.txt +23 -23
  142. package/dist/web/settings/agents/__next._head.txt +4 -4
  143. package/dist/web/settings/agents/__next._index.txt +13 -13
  144. package/dist/web/settings/agents/__next._tree.txt +2 -2
  145. package/dist/web/settings/agents/__next.settings.agents.__PAGE__.txt +4 -4
  146. package/dist/web/settings/agents/__next.settings.agents.txt +3 -3
  147. package/dist/web/settings/agents/__next.settings.txt +5 -5
  148. package/dist/web/settings/agents.html +1 -1
  149. package/dist/web/settings/agents.txt +23 -23
  150. package/dist/web/settings/mcps/__next._full.txt +23 -23
  151. package/dist/web/settings/mcps/__next._head.txt +4 -4
  152. package/dist/web/settings/mcps/__next._index.txt +13 -13
  153. package/dist/web/settings/mcps/__next._tree.txt +2 -2
  154. package/dist/web/settings/mcps/__next.settings.mcps.__PAGE__.txt +4 -4
  155. package/dist/web/settings/mcps/__next.settings.mcps.txt +3 -3
  156. package/dist/web/settings/mcps/__next.settings.txt +5 -5
  157. package/dist/web/settings/mcps.html +1 -1
  158. package/dist/web/settings/mcps.txt +23 -23
  159. package/dist/web/settings/models/__next._full.txt +23 -23
  160. package/dist/web/settings/models/__next._head.txt +4 -4
  161. package/dist/web/settings/models/__next._index.txt +13 -13
  162. package/dist/web/settings/models/__next._tree.txt +2 -2
  163. package/dist/web/settings/models/__next.settings.models.__PAGE__.txt +4 -4
  164. package/dist/web/settings/models/__next.settings.models.txt +3 -3
  165. package/dist/web/settings/models/__next.settings.txt +5 -5
  166. package/dist/web/settings/models.html +1 -1
  167. package/dist/web/settings/models.txt +23 -23
  168. package/dist/web/settings/output-styles/__next._full.txt +23 -23
  169. package/dist/web/settings/output-styles/__next._head.txt +4 -4
  170. package/dist/web/settings/output-styles/__next._index.txt +13 -13
  171. package/dist/web/settings/output-styles/__next._tree.txt +2 -2
  172. package/dist/web/settings/output-styles/__next.settings.output-styles.__PAGE__.txt +4 -4
  173. package/dist/web/settings/output-styles/__next.settings.output-styles.txt +3 -3
  174. package/dist/web/settings/output-styles/__next.settings.txt +5 -5
  175. package/dist/web/settings/output-styles.html +1 -1
  176. package/dist/web/settings/output-styles.txt +23 -23
  177. package/dist/web/settings/prompts/__next._full.txt +23 -23
  178. package/dist/web/settings/prompts/__next._head.txt +4 -4
  179. package/dist/web/settings/prompts/__next._index.txt +13 -13
  180. package/dist/web/settings/prompts/__next._tree.txt +2 -2
  181. package/dist/web/settings/prompts/__next.settings.prompts.__PAGE__.txt +4 -4
  182. package/dist/web/settings/prompts/__next.settings.prompts.txt +3 -3
  183. package/dist/web/settings/prompts/__next.settings.txt +5 -5
  184. package/dist/web/settings/prompts.html +1 -1
  185. package/dist/web/settings/prompts.txt +23 -23
  186. package/dist/web/settings/providers/__next._full.txt +23 -23
  187. package/dist/web/settings/providers/__next._head.txt +4 -4
  188. package/dist/web/settings/providers/__next._index.txt +13 -13
  189. package/dist/web/settings/providers/__next._tree.txt +2 -2
  190. package/dist/web/settings/providers/__next.settings.providers.__PAGE__.txt +4 -4
  191. package/dist/web/settings/providers/__next.settings.providers.txt +3 -3
  192. package/dist/web/settings/providers/__next.settings.txt +5 -5
  193. package/dist/web/settings/providers.html +1 -1
  194. package/dist/web/settings/providers.txt +23 -23
  195. package/dist/web/settings/skills/__next._full.txt +23 -23
  196. package/dist/web/settings/skills/__next._head.txt +4 -4
  197. package/dist/web/settings/skills/__next._index.txt +13 -13
  198. package/dist/web/settings/skills/__next._tree.txt +2 -2
  199. package/dist/web/settings/skills/__next.settings.skills.__PAGE__.txt +4 -4
  200. package/dist/web/settings/skills/__next.settings.skills.txt +3 -3
  201. package/dist/web/settings/skills/__next.settings.txt +5 -5
  202. package/dist/web/settings/skills.html +1 -1
  203. package/dist/web/settings/skills.txt +23 -23
  204. package/dist/web/settings/tools/__next._full.txt +23 -23
  205. package/dist/web/settings/tools/__next._head.txt +4 -4
  206. package/dist/web/settings/tools/__next._index.txt +13 -13
  207. package/dist/web/settings/tools/__next._tree.txt +2 -2
  208. package/dist/web/settings/tools/__next.settings.tools.__PAGE__.txt +4 -4
  209. package/dist/web/settings/tools/__next.settings.tools.txt +3 -3
  210. package/dist/web/settings/tools/__next.settings.txt +5 -5
  211. package/dist/web/settings/tools.html +1 -1
  212. package/dist/web/settings/tools.txt +23 -23
  213. package/dist/web/settings.html +1 -1
  214. package/dist/web/settings.txt +23 -23
  215. package/dist/web/workflows/__next._full.txt +22 -22
  216. package/dist/web/workflows/__next._head.txt +4 -4
  217. package/dist/web/workflows/__next._index.txt +13 -13
  218. package/dist/web/workflows/__next._tree.txt +2 -2
  219. package/dist/web/workflows/__next.workflows.__PAGE__.txt +4 -4
  220. package/dist/web/workflows/__next.workflows.txt +3 -3
  221. package/dist/web/workflows.html +1 -1
  222. package/dist/web/workflows.txt +22 -22
  223. package/dist/web/workspace/_/__next._full.txt +20 -20
  224. package/dist/web/workspace/_/__next._head.txt +4 -4
  225. package/dist/web/workspace/_/__next._index.txt +13 -13
  226. package/dist/web/workspace/_/__next._tree.txt +2 -2
  227. package/dist/web/workspace/_/__next.workspace.$d$id.__PAGE__.txt +3 -3
  228. package/dist/web/workspace/_/__next.workspace.$d$id.txt +3 -3
  229. package/dist/web/workspace/_/__next.workspace.txt +3 -3
  230. package/dist/web/workspace/_.html +1 -1
  231. package/dist/web/workspace/_.txt +20 -20
  232. package/dist/web/workspaces/__next._full.txt +21 -21
  233. package/dist/web/workspaces/__next._head.txt +4 -4
  234. package/dist/web/workspaces/__next._index.txt +13 -13
  235. package/dist/web/workspaces/__next._tree.txt +2 -2
  236. package/dist/web/workspaces/__next.workspaces.__PAGE__.txt +4 -4
  237. package/dist/web/workspaces/__next.workspaces.txt +3 -3
  238. package/dist/web/workspaces.html +1 -1
  239. package/dist/web/workspaces.txt +21 -21
  240. package/dist/ws/agent-prompt.js +36 -3
  241. package/dist/ws/agent-runner.js +30 -18
  242. package/dist/ws/chat-handler.js +89 -0
  243. package/dist/ws/connection-manager.js +49 -2
  244. package/dist/ws/execution-channels.js +88 -0
  245. package/dist/ws/handler.js +32 -5
  246. package/dist/ws/message-parts.js +130 -12
  247. package/dist/ws/terminal-handler.js +26 -0
  248. package/package.json +13 -1
  249. package/public/avatars/user.jpg +0 -0
  250. package/dist/web/_next/static/chunks/0-v_p6j5u3_9l.js +0 -1
  251. package/dist/web/_next/static/chunks/0.-x29t-8gk0r.js +0 -1
  252. package/dist/web/_next/static/chunks/0.l5e8~r7_0~p.js +0 -1
  253. package/dist/web/_next/static/chunks/0.n~yfwf4~6w-.js +0 -1
  254. package/dist/web/_next/static/chunks/00-syqzi-6zxr.js +0 -1
  255. package/dist/web/_next/static/chunks/02j4sr9psucf-.js +0 -1
  256. package/dist/web/_next/static/chunks/06si8l0doqe8p.js +0 -1
  257. package/dist/web/_next/static/chunks/08kfx8on9oty~.js +0 -1
  258. package/dist/web/_next/static/chunks/08ugbvzr20drp.js +0 -2
  259. package/dist/web/_next/static/chunks/0_cqojbge48kq.js +0 -5
  260. package/dist/web/_next/static/chunks/0d6~~lv0-6kex.js +0 -3
  261. package/dist/web/_next/static/chunks/0gdwop9cnpmtu.js +0 -1
  262. package/dist/web/_next/static/chunks/0ghx3j_.-gdyd.js +0 -1
  263. package/dist/web/_next/static/chunks/0kbvoxla7f751.js +0 -1
  264. package/dist/web/_next/static/chunks/0paaat8y96ayc.js +0 -7
  265. package/dist/web/_next/static/chunks/0pq318f8xgafg.js +0 -1
  266. package/dist/web/_next/static/chunks/0t6s8of0qr6nc.js +0 -1
  267. package/dist/web/_next/static/chunks/0xt-8wk21gs7g.js +0 -1
  268. package/dist/web/_next/static/chunks/0yd.m1afqg.2t.js +0 -3
  269. package/dist/web/_next/static/chunks/0yhbr8hl09b-5.js +0 -1
  270. package/dist/web/_next/static/chunks/0z~vqzbm_q371.js +0 -1
  271. package/dist/web/_next/static/chunks/0~~_ltu6dx_ch.js +0 -1
  272. package/dist/web/_next/static/chunks/12oxcgyhpaxw~.js +0 -1
  273. package/dist/web/_next/static/chunks/1452eibz62gs6.css +0 -1
  274. package/dist/web/_next/static/chunks/16zlreiems5cn.js +0 -1
  275. package/dist/web/_next/static/chunks/18awqjk9-o5m0.js +0 -1
  276. /package/dist/web/_next/static/{x4-CsKe6qUQyFDWVtfvUg → rGXyAK8rgod1NjF3bLZAY}/_buildManifest.js +0 -0
  277. /package/dist/web/_next/static/{x4-CsKe6qUQyFDWVtfvUg → rGXyAK8rgod1NjF3bLZAY}/_clientMiddlewareManifest.js +0 -0
  278. /package/dist/web/_next/static/{x4-CsKe6qUQyFDWVtfvUg → rGXyAK8rgod1NjF3bLZAY}/_ssgManifest.js +0 -0
@@ -0,0 +1,69 @@
1
+ import { Router } from 'express';
2
+ import * as pluginService from '../services/plugin.js';
3
+ const router = Router();
4
+ router.get('/', (_req, res) => {
5
+ try {
6
+ res.json(pluginService.listPlugins());
7
+ }
8
+ catch (error) {
9
+ res.status(500).json({ error: error.message });
10
+ }
11
+ });
12
+ router.get('/workflow', (_req, res) => {
13
+ try {
14
+ res.json(pluginService.listWorkflowPlugins());
15
+ }
16
+ catch (error) {
17
+ res.status(500).json({ error: error.message });
18
+ }
19
+ });
20
+ router.post('/store/:pluginId/install', (req, res) => {
21
+ try {
22
+ res.json(pluginService.installTemplatePlugin(req.params.pluginId));
23
+ }
24
+ catch (error) {
25
+ res.status(400).json({ error: error.message });
26
+ }
27
+ });
28
+ router.post('/:pluginId/enable', (req, res) => {
29
+ try {
30
+ res.json(pluginService.setPluginEnabled(req.params.pluginId, true));
31
+ }
32
+ catch (error) {
33
+ res.status(400).json({ error: error.message });
34
+ }
35
+ });
36
+ router.post('/:pluginId/disable', (req, res) => {
37
+ try {
38
+ res.json(pluginService.setPluginEnabled(req.params.pluginId, false));
39
+ }
40
+ catch (error) {
41
+ res.status(400).json({ error: error.message });
42
+ }
43
+ });
44
+ router.get('/:pluginId/config', (req, res) => {
45
+ try {
46
+ res.json(pluginService.getPluginConfig(req.params.pluginId));
47
+ }
48
+ catch (error) {
49
+ res.status(400).json({ error: error.message });
50
+ }
51
+ });
52
+ router.put('/:pluginId/config', (req, res) => {
53
+ try {
54
+ res.json(pluginService.savePluginConfig(req.params.pluginId, req.body || {}));
55
+ }
56
+ catch (error) {
57
+ res.status(400).json({ success: false, error: error.message });
58
+ }
59
+ });
60
+ router.get('/:pluginId/workflow-nodes', (req, res) => {
61
+ try {
62
+ res.json({ pluginId: req.params.pluginId, nodes: pluginService.getWorkflowNodes(req.params.pluginId) });
63
+ }
64
+ catch (error) {
65
+ res.status(400).json({ error: error.message });
66
+ }
67
+ });
68
+ export default router;
69
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1,95 @@
1
+ import { Router } from 'express';
2
+ import { spawn } from 'node:child_process';
3
+ import { writeFileSync, unlinkSync } from 'node:fs';
4
+ import { tmpdir } from 'node:os';
5
+ import { join } from 'node:path';
6
+ import { getLocalVersion, getCachedLatest, fetchLatestVersion, isNewerVersion } from '../services/version.js';
7
+ const router = Router();
8
+ const isSourceRuntime = /[\\/]src[\\/]routes$/.test(import.meta.dirname);
9
+ const isDev = process.env.NODE_ENV === 'development' || (!process.env.NODE_ENV && isSourceRuntime);
10
+ let isUpdating = false;
11
+ // GET /version — cached version info (openPaths in auth.ts)
12
+ router.get('/version', async (_req, res) => {
13
+ const local = getLocalVersion();
14
+ if (isDev) {
15
+ res.json({ local, latest: null, updateAvailable: false, dev: true });
16
+ return;
17
+ }
18
+ let latest = getCachedLatest();
19
+ if (!latest) {
20
+ latest = await fetchLatestVersion(false);
21
+ }
22
+ res.json({ local, latest, updateAvailable: latest ? isNewerVersion(latest, local) : false });
23
+ });
24
+ // GET /version/check — force npm lookup (openPaths in auth.ts)
25
+ router.get('/version/check', async (_req, res) => {
26
+ const local = getLocalVersion();
27
+ if (isDev) {
28
+ res.json({ local, latest: null, updateAvailable: false, dev: true });
29
+ return;
30
+ }
31
+ const latest = await fetchLatestVersion(true);
32
+ res.json({
33
+ local,
34
+ latest,
35
+ updateAvailable: latest ? isNewerVersion(latest, local) : false,
36
+ });
37
+ });
38
+ // POST /version/update — trigger self-update (requires auth)
39
+ router.post('/version/update', (_req, res) => {
40
+ if (isDev) {
41
+ res.status(403).json({ error: 'Updates are disabled in development mode' });
42
+ return;
43
+ }
44
+ if (isUpdating) {
45
+ res.status(409).json({ error: 'Update already in progress' });
46
+ return;
47
+ }
48
+ isUpdating = true;
49
+ const pid = process.pid;
50
+ const ppid = process.ppid;
51
+ const projectRoot = join(import.meta.dirname, '..', '..');
52
+ const isWin = process.platform === 'win32';
53
+ let scriptPath;
54
+ if (isWin) {
55
+ scriptPath = join(tmpdir(), `agent-spaces-update-${pid}.cmd`);
56
+ const cmd = [
57
+ '@echo off',
58
+ 'timeout /t 2 /nobreak >nul',
59
+ `taskkill /pid ${ppid} /f /t >nul 2>&1`,
60
+ `taskkill /pid ${pid} /f /t >nul 2>&1`,
61
+ `cd /d "${projectRoot}"`,
62
+ 'call pnpm install',
63
+ 'call pnpm start',
64
+ ].join('\r\n');
65
+ writeFileSync(scriptPath, cmd, 'utf-8');
66
+ }
67
+ else {
68
+ scriptPath = join(tmpdir(), `agent-spaces-update-${pid}.sh`);
69
+ const sh = [
70
+ '#!/bin/sh',
71
+ 'sleep 2',
72
+ `kill -9 ${ppid} 2>/dev/null || true`,
73
+ `kill -9 ${pid} 2>/dev/null || true`,
74
+ `cd "${projectRoot}"`,
75
+ 'pnpm install',
76
+ 'pnpm start',
77
+ ].join('\n');
78
+ writeFileSync(scriptPath, sh, 'utf-8');
79
+ }
80
+ const child = spawn(isWin ? 'cmd' : '/bin/sh', isWin ? ['/c', scriptPath] : [scriptPath], {
81
+ detached: true,
82
+ stdio: 'ignore',
83
+ windowsHide: true,
84
+ });
85
+ child.unref();
86
+ setTimeout(() => {
87
+ try {
88
+ unlinkSync(scriptPath);
89
+ }
90
+ catch { }
91
+ }, 10_000);
92
+ res.json({ ok: true });
93
+ });
94
+ export default router;
95
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1,71 @@
1
+ // Workflow webhook hook handler — SSE streaming of execution results
2
+ import { Router } from 'express';
3
+ const SSE_TIMEOUT_MS = 5 * 60_000;
4
+ export function createWorkflowHookRouter(triggerService, executionManager) {
5
+ const router = Router();
6
+ router.post('/hook/:hookName', (req, res) => {
7
+ const hookName = req.params.hookName;
8
+ const bindings = triggerService.getHookBindings(hookName);
9
+ if (bindings.length === 0) {
10
+ res.status(404).json({ error: `No workflows bound to hook "${hookName}"` });
11
+ return;
12
+ }
13
+ const body = req.body || {};
14
+ let targets = bindings;
15
+ if (body.workflowId) {
16
+ targets = bindings.filter(b => b.workflowId === body.workflowId);
17
+ if (targets.length === 0) {
18
+ res.status(404).json({ error: `Workflow ${body.workflowId} not bound to hook "${hookName}"` });
19
+ return;
20
+ }
21
+ }
22
+ res.writeHead(200, {
23
+ 'Content-Type': 'text/event-stream',
24
+ 'Cache-Control': 'no-cache',
25
+ 'Connection': 'keep-alive',
26
+ 'X-Accel-Buffering': 'no',
27
+ });
28
+ let completed = 0;
29
+ let closed = false;
30
+ const sse = (event, payload) => {
31
+ if (closed)
32
+ return;
33
+ res.write(`event: ${event}\ndata: ${JSON.stringify(payload)}\n\n`);
34
+ };
35
+ const timeoutId = setTimeout(() => {
36
+ if (!closed) {
37
+ sse('timeout', { message: 'SSE timeout, closing' });
38
+ res.write('event: done\ndata: {}\n\n');
39
+ closed = true;
40
+ res.end();
41
+ }
42
+ }, SSE_TIMEOUT_MS);
43
+ res.on('close', () => {
44
+ closed = true;
45
+ clearTimeout(timeoutId);
46
+ });
47
+ const total = targets.length;
48
+ for (const binding of targets) {
49
+ executionManager.execute({ workflowId: binding.workflowId, input: body.input || {} }, '__hook__', (channel, payload) => sse(channel, payload)).then(() => {
50
+ completed++;
51
+ if (completed === total && !closed) {
52
+ clearTimeout(timeoutId);
53
+ res.write('event: done\ndata: {}\n\n');
54
+ closed = true;
55
+ res.end();
56
+ }
57
+ }).catch((err) => {
58
+ sse('workflow:error', { workflowId: binding.workflowId, error: err.message });
59
+ completed++;
60
+ if (completed === total && !closed) {
61
+ clearTimeout(timeoutId);
62
+ res.write('event: done\ndata: {}\n\n');
63
+ closed = true;
64
+ res.end();
65
+ }
66
+ });
67
+ }
68
+ });
69
+ return router;
70
+ }
71
+ //# sourceMappingURL=workflow-hook.js.map
@@ -1,18 +1,79 @@
1
1
  import { Router } from 'express';
2
- import * as workflowService from '../services/workflow.js';
2
+ import * as ws from '../services/workflow.js';
3
3
  const router = Router();
4
+ // ---- Workflow CRUD ----
4
5
  router.get('/', (_req, res) => {
5
6
  try {
6
- const workflows = workflowService.listWorkflows();
7
+ const folderId = _req.query.folderId;
8
+ const workflows = ws.listWorkflows(folderId === 'null' ? null : folderId);
7
9
  res.json(workflows);
8
10
  }
9
11
  catch (error) {
10
12
  res.status(500).json({ error: error.message });
11
13
  }
12
14
  });
15
+ // Static routes must be declared before /:workflowId.
16
+ router.get('/folders', (_req, res) => {
17
+ try {
18
+ res.json(ws.listFolders());
19
+ }
20
+ catch (error) {
21
+ res.status(500).json({ error: error.message });
22
+ }
23
+ });
24
+ router.post('/folders', (req, res) => {
25
+ try {
26
+ const folder = ws.createFolder(req.body);
27
+ res.status(201).json(folder);
28
+ }
29
+ catch (error) {
30
+ res.status(400).json({ error: error.message });
31
+ }
32
+ });
33
+ router.put('/folders/:folderId', (req, res) => {
34
+ try {
35
+ ws.updateFolder(req.params.folderId, req.body);
36
+ const folders = ws.listFolders();
37
+ res.json(folders.find(f => f.id === req.params.folderId));
38
+ }
39
+ catch (error) {
40
+ res.status(400).json({ error: error.message });
41
+ }
42
+ });
43
+ router.delete('/folders/:folderId', (req, res) => {
44
+ try {
45
+ ws.deleteFolder(req.params.folderId);
46
+ res.status(204).send();
47
+ }
48
+ catch (error) {
49
+ res.status(400).json({ error: error.message });
50
+ }
51
+ });
52
+ router.get('/execution-logs/all', (req, res) => {
53
+ try {
54
+ const limit = req.query.limit ? parseInt(req.query.limit, 10) : 50;
55
+ res.json(ws.listAllExecutionLogs(limit));
56
+ }
57
+ catch (error) {
58
+ res.status(500).json({ error: error.message });
59
+ }
60
+ });
61
+ router.post('/validate-cron', (req, res) => {
62
+ try {
63
+ const { cron } = req.body;
64
+ if (typeof cron !== 'string') {
65
+ res.status(400).json({ error: 'cron field is required' });
66
+ return;
67
+ }
68
+ res.json(ws.validateCron(cron));
69
+ }
70
+ catch (error) {
71
+ res.status(400).json({ error: error.message });
72
+ }
73
+ });
13
74
  router.get('/:workflowId', (req, res) => {
14
75
  try {
15
- const workflow = workflowService.getWorkflow(req.params.workflowId);
76
+ const workflow = ws.getWorkflow(req.params.workflowId);
16
77
  if (!workflow) {
17
78
  res.status(404).json({ error: 'Workflow not found' });
18
79
  return;
@@ -25,7 +86,7 @@ router.get('/:workflowId', (req, res) => {
25
86
  });
26
87
  router.post('/', (req, res) => {
27
88
  try {
28
- const workflow = workflowService.createWorkflow(req.body);
89
+ const workflow = ws.createWorkflow(req.body);
29
90
  res.status(201).json(workflow);
30
91
  }
31
92
  catch (error) {
@@ -34,7 +95,7 @@ router.post('/', (req, res) => {
34
95
  });
35
96
  router.put('/:workflowId', (req, res) => {
36
97
  try {
37
- const workflow = workflowService.updateWorkflow(req.params.workflowId, req.body);
98
+ const workflow = ws.updateWorkflow(req.params.workflowId, req.body);
38
99
  res.json(workflow);
39
100
  }
40
101
  catch (error) {
@@ -43,7 +104,7 @@ router.put('/:workflowId', (req, res) => {
43
104
  });
44
105
  router.delete('/:workflowId', (req, res) => {
45
106
  try {
46
- workflowService.deleteWorkflow(req.params.workflowId);
107
+ ws.deleteWorkflow(req.params.workflowId);
47
108
  res.status(204).send();
48
109
  }
49
110
  catch (error) {
@@ -52,12 +113,226 @@ router.delete('/:workflowId', (req, res) => {
52
113
  });
53
114
  router.post('/:workflowId/duplicate', (req, res) => {
54
115
  try {
55
- const workflow = workflowService.duplicateWorkflow(req.params.workflowId);
116
+ const workflow = ws.duplicateWorkflow(req.params.workflowId);
56
117
  res.status(201).json(workflow);
57
118
  }
58
119
  catch (error) {
59
120
  res.status(400).json({ error: error.message });
60
121
  }
61
122
  });
123
+ // ---- Versions ----
124
+ router.get('/:workflowId/versions', (req, res) => {
125
+ try {
126
+ res.json(ws.listVersions(req.params.workflowId));
127
+ }
128
+ catch (error) {
129
+ res.status(500).json({ error: error.message });
130
+ }
131
+ });
132
+ router.post('/:workflowId/versions', (req, res) => {
133
+ try {
134
+ const version = ws.createVersion(req.params.workflowId, req.body?.name);
135
+ res.status(201).json(version);
136
+ }
137
+ catch (error) {
138
+ res.status(400).json({ error: error.message });
139
+ }
140
+ });
141
+ router.get('/:workflowId/versions/:versionId', (req, res) => {
142
+ try {
143
+ const version = ws.getVersion(req.params.workflowId, req.params.versionId);
144
+ if (!version) {
145
+ res.status(404).json({ error: 'Version not found' });
146
+ return;
147
+ }
148
+ res.json(version);
149
+ }
150
+ catch (error) {
151
+ res.status(500).json({ error: error.message });
152
+ }
153
+ });
154
+ router.delete('/:workflowId/versions/:versionId', (req, res) => {
155
+ try {
156
+ ws.deleteVersion(req.params.workflowId, req.params.versionId);
157
+ res.status(204).send();
158
+ }
159
+ catch (error) {
160
+ res.status(400).json({ error: error.message });
161
+ }
162
+ });
163
+ router.delete('/:workflowId/versions', (req, res) => {
164
+ try {
165
+ ws.clearVersions(req.params.workflowId);
166
+ res.status(204).send();
167
+ }
168
+ catch (error) {
169
+ res.status(400).json({ error: error.message });
170
+ }
171
+ });
172
+ // ---- Per-Workflow Execution Logs ----
173
+ router.get('/:workflowId/execution-logs', (req, res) => {
174
+ try {
175
+ res.json(ws.listExecutionLogs(req.params.workflowId));
176
+ }
177
+ catch (error) {
178
+ res.status(500).json({ error: error.message });
179
+ }
180
+ });
181
+ router.get('/:workflowId/execution-logs/:logId', (req, res) => {
182
+ try {
183
+ const log = ws.getExecutionLog(req.params.workflowId, req.params.logId);
184
+ if (!log) {
185
+ res.status(404).json({ error: 'Execution log not found' });
186
+ return;
187
+ }
188
+ res.json(log);
189
+ }
190
+ catch (error) {
191
+ res.status(500).json({ error: error.message });
192
+ }
193
+ });
194
+ router.delete('/:workflowId/execution-logs/:logId', (req, res) => {
195
+ try {
196
+ ws.deleteExecutionLog(req.params.workflowId, req.params.logId);
197
+ res.status(204).send();
198
+ }
199
+ catch (error) {
200
+ res.status(400).json({ error: error.message });
201
+ }
202
+ });
203
+ router.delete('/:workflowId/execution-logs', (req, res) => {
204
+ try {
205
+ ws.clearExecutionLogs(req.params.workflowId);
206
+ res.status(204).send();
207
+ }
208
+ catch (error) {
209
+ res.status(400).json({ error: error.message });
210
+ }
211
+ });
212
+ // ---- Staging ----
213
+ router.get('/:workflowId/staging', (req, res) => {
214
+ try {
215
+ res.json(ws.loadStaging(req.params.workflowId));
216
+ }
217
+ catch (error) {
218
+ res.status(500).json({ error: error.message });
219
+ }
220
+ });
221
+ router.put('/:workflowId/staging', (req, res) => {
222
+ try {
223
+ ws.saveStaging(req.params.workflowId, req.body);
224
+ res.json({ ok: true });
225
+ }
226
+ catch (error) {
227
+ res.status(400).json({ error: error.message });
228
+ }
229
+ });
230
+ router.delete('/:workflowId/staging', (req, res) => {
231
+ try {
232
+ ws.clearStaging(req.params.workflowId);
233
+ res.status(204).send();
234
+ }
235
+ catch (error) {
236
+ res.status(400).json({ error: error.message });
237
+ }
238
+ });
239
+ // ---- Operation History ----
240
+ router.get('/:workflowId/operation-history', (req, res) => {
241
+ try {
242
+ res.json(ws.loadOperationHistory(req.params.workflowId));
243
+ }
244
+ catch (error) {
245
+ res.status(500).json({ error: error.message });
246
+ }
247
+ });
248
+ router.put('/:workflowId/operation-history', (req, res) => {
249
+ try {
250
+ ws.saveOperationHistory(req.params.workflowId, req.body);
251
+ res.json({ ok: true });
252
+ }
253
+ catch (error) {
254
+ res.status(400).json({ error: error.message });
255
+ }
256
+ });
257
+ router.delete('/:workflowId/operation-history', (req, res) => {
258
+ try {
259
+ ws.clearOperationHistory(req.params.workflowId);
260
+ res.status(204).send();
261
+ }
262
+ catch (error) {
263
+ res.status(400).json({ error: error.message });
264
+ }
265
+ });
266
+ // ---- Workflow Agent Chat ----
267
+ router.get('/:workflowId/chat', (req, res) => {
268
+ try {
269
+ res.json(ws.loadChat(req.params.workflowId));
270
+ }
271
+ catch (error) {
272
+ res.status(500).json({ error: error.message });
273
+ }
274
+ });
275
+ router.put('/:workflowId/chat', (req, res) => {
276
+ try {
277
+ ws.saveChat(req.params.workflowId, Array.isArray(req.body?.messages) ? req.body.messages : []);
278
+ res.json({ ok: true });
279
+ }
280
+ catch (error) {
281
+ res.status(400).json({ error: error.message });
282
+ }
283
+ });
284
+ router.delete('/:workflowId/chat', (req, res) => {
285
+ try {
286
+ ws.clearChat(req.params.workflowId);
287
+ res.status(204).send();
288
+ }
289
+ catch (error) {
290
+ res.status(400).json({ error: error.message });
291
+ }
292
+ });
293
+ // ---- Plugin Config Schemes ----
294
+ router.get('/:workflowId/plugin-schemes/:pluginId', (req, res) => {
295
+ try {
296
+ res.json(ws.listPluginSchemes(req.params.workflowId, req.params.pluginId));
297
+ }
298
+ catch (error) {
299
+ res.status(500).json({ error: error.message });
300
+ }
301
+ });
302
+ router.post('/:workflowId/plugin-schemes/:pluginId/:schemeName', (req, res) => {
303
+ try {
304
+ ws.createPluginScheme(req.params.workflowId, req.params.pluginId, req.params.schemeName);
305
+ res.status(201).json({ ok: true });
306
+ }
307
+ catch (error) {
308
+ res.status(400).json({ error: error.message });
309
+ }
310
+ });
311
+ router.get('/:workflowId/plugin-schemes/:pluginId/:schemeName', (req, res) => {
312
+ try {
313
+ res.json(ws.readPluginScheme(req.params.workflowId, req.params.pluginId, req.params.schemeName));
314
+ }
315
+ catch (error) {
316
+ res.status(500).json({ error: error.message });
317
+ }
318
+ });
319
+ router.put('/:workflowId/plugin-schemes/:pluginId/:schemeName', (req, res) => {
320
+ try {
321
+ ws.savePluginScheme(req.params.workflowId, req.params.pluginId, req.params.schemeName, req.body || {});
322
+ res.json({ ok: true });
323
+ }
324
+ catch (error) {
325
+ res.status(400).json({ error: error.message });
326
+ }
327
+ });
328
+ router.delete('/:workflowId/plugin-schemes/:pluginId/:schemeName', (req, res) => {
329
+ try {
330
+ ws.deletePluginScheme(req.params.workflowId, req.params.pluginId, req.params.schemeName);
331
+ res.status(204).send();
332
+ }
333
+ catch (error) {
334
+ res.status(400).json({ error: error.message });
335
+ }
336
+ });
62
337
  export default router;
63
338
  //# sourceMappingURL=workflow.js.map
@@ -1,6 +1,8 @@
1
1
  import { Router } from 'express';
2
+ import { join } from 'node:path';
2
3
  import { exec } from 'child_process';
3
4
  import * as wsService from '../services/workspace.js';
5
+ import { getDataDir } from '../storage/json-store.js';
4
6
  import * as agentService from '../services/agent.js';
5
7
  import { readWorkspacePrompt, writeWorkspacePrompt } from '../services/workspace-prompt.js';
6
8
  import { getWeChatLoginQRCode, pollWeChatLoginStatus, sendTestNotification, startWorkspaceNotificationService, stopWorkspaceNotificationService, } from '../services/notification-hub/index.js';
@@ -148,10 +150,17 @@ router.post('/:id/reveal', (req, res) => {
148
150
  res.status(404).json({ error: 'Workspace not found' });
149
151
  return;
150
152
  }
151
- const dir = ws.boundDirs?.[0];
152
- if (!dir) {
153
- res.status(400).json({ error: 'Workspace has no bound directory' });
154
- return;
153
+ const target = req.query.target;
154
+ let dir;
155
+ if (target === 'data') {
156
+ dir = join(getDataDir(), 'workspaces', ws.id);
157
+ }
158
+ else {
159
+ dir = ws.boundDirs?.[0];
160
+ if (!dir) {
161
+ res.status(400).json({ error: 'Workspace has no bound directory' });
162
+ return;
163
+ }
155
164
  }
156
165
  console.log('[reveal:workspace] workspace:', ws.id, 'dir:', dir);
157
166
  const cmd = process.platform === 'darwin'
@@ -0,0 +1,93 @@
1
+ import { Router } from 'express';
2
+ import { z } from 'zod';
3
+ import { listWorkspaceWorktrees, getWorkspaceWorktree, createWorkspaceWorktree, deleteWorkspaceWorktree, getWorktreeDiff, createWorktreePR, mergeWorktreePR, getWorktreePRDraft, } from '../services/worktree.js';
4
+ export const worktreeRouter = Router({ mergeParams: true });
5
+ const createSchema = z.object({
6
+ name: z.string().min(1),
7
+ branch: z.string().optional(),
8
+ agentId: z.string().optional(),
9
+ issueId: z.string().optional(),
10
+ taskId: z.string().optional(),
11
+ });
12
+ const prSchema = z.object({
13
+ title: z.string().optional(),
14
+ body: z.string().optional(),
15
+ });
16
+ const prDraftSchema = z.object({
17
+ title: z.string().optional(),
18
+ });
19
+ worktreeRouter.get('/', (req, res) => {
20
+ const { id } = req.params;
21
+ res.json(listWorkspaceWorktrees(id));
22
+ });
23
+ worktreeRouter.post('/', async (req, res) => {
24
+ try {
25
+ const { id } = req.params;
26
+ const input = createSchema.parse(req.body);
27
+ const info = await createWorkspaceWorktree(id, input);
28
+ res.status(201).json(info);
29
+ }
30
+ catch (err) {
31
+ res.status(400).json({ error: err.message });
32
+ }
33
+ });
34
+ worktreeRouter.get('/:wtId', (req, res) => {
35
+ const { id, wtId } = req.params;
36
+ const info = getWorkspaceWorktree(id, wtId);
37
+ if (!info)
38
+ return res.status(404).json({ error: 'Worktree not found' });
39
+ res.json(info);
40
+ });
41
+ worktreeRouter.delete('/:wtId', async (req, res) => {
42
+ try {
43
+ const { id, wtId } = req.params;
44
+ await deleteWorkspaceWorktree(id, wtId);
45
+ res.json({ ok: true });
46
+ }
47
+ catch (err) {
48
+ res.status(400).json({ error: err.message });
49
+ }
50
+ });
51
+ worktreeRouter.get('/:wtId/diff', async (req, res) => {
52
+ try {
53
+ const { id, wtId } = req.params;
54
+ const diffs = await getWorktreeDiff(id, wtId);
55
+ res.json(diffs);
56
+ }
57
+ catch (err) {
58
+ res.status(400).json({ error: err.message });
59
+ }
60
+ });
61
+ worktreeRouter.post('/:wtId/pr', async (req, res) => {
62
+ try {
63
+ const { id, wtId } = req.params;
64
+ const { title, body } = prSchema.parse(req.body);
65
+ const prUrl = await createWorktreePR(id, wtId, title, body);
66
+ res.json({ prUrl });
67
+ }
68
+ catch (err) {
69
+ res.status(400).json({ error: err.message });
70
+ }
71
+ });
72
+ worktreeRouter.post('/:wtId/pr/draft', async (req, res) => {
73
+ try {
74
+ const { id, wtId } = req.params;
75
+ const { title } = prDraftSchema.parse(req.body);
76
+ const draft = await getWorktreePRDraft(id, wtId, title);
77
+ res.json(draft);
78
+ }
79
+ catch (err) {
80
+ res.status(400).json({ error: err.message });
81
+ }
82
+ });
83
+ worktreeRouter.post('/:wtId/merge', async (req, res) => {
84
+ try {
85
+ const { id, wtId } = req.params;
86
+ await mergeWorktreePR(id, wtId);
87
+ res.json({ ok: true });
88
+ }
89
+ catch (err) {
90
+ res.status(400).json({ error: err.message });
91
+ }
92
+ });
93
+ //# sourceMappingURL=worktree.js.map