@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
@@ -1,40 +1,404 @@
1
1
  // packages/server/src/storage/workflow-store.ts
2
- // NOTE: All functions are synchronous to match json-store.ts and issue-store.ts patterns
3
- import { ensureDir, readJsonFile, writeJsonFile, deleteFile, getDataDir } from './json-store.js';
2
+ // Per-workflow directory storage: supports versions, execution logs, plugin configs.
3
+ // Legacy flat-file workflows are auto-migrated on first access.
4
+ import { ensureDir, readJsonFile, writeJsonFile, getDataDir } from './json-store.js';
5
+ import { existsSync, readdirSync, rmSync, unlinkSync, readFileSync } from 'node:fs';
4
6
  import path from 'node:path';
5
- function workflowsDir() {
7
+ // ---- Path helpers ----
8
+ export function workflowsDir() {
6
9
  return path.join(getDataDir(), 'workflows');
7
10
  }
8
- function workflowsIndex() {
11
+ function workflowDir(workflowId) {
12
+ return path.join(workflowsDir(), workflowId);
13
+ }
14
+ function workflowPath(workflowId) {
15
+ return path.join(workflowDir(workflowId), 'workflow.json');
16
+ }
17
+ function workflowIndexPath() {
9
18
  return path.join(workflowsDir(), 'index.json');
10
19
  }
11
- function workflowFile(workflowId) {
20
+ function versionsDir(workflowId) {
21
+ return path.join(workflowDir(workflowId), 'versions');
22
+ }
23
+ function executionHistoryDir(workflowId) {
24
+ return path.join(workflowDir(workflowId), 'execution_history');
25
+ }
26
+ function pluginConfigsDir(workflowId) {
27
+ return path.join(workflowDir(workflowId), 'plugin_configs');
28
+ }
29
+ function pluginSchemePath(workflowId, pluginId, schemeName) {
30
+ return path.join(pluginConfigsDir(workflowId), pluginId, `${schemeName}.json`);
31
+ }
32
+ function workflowFoldersPath() {
33
+ return path.join(workflowsDir(), 'folders.json');
34
+ }
35
+ function stagingPath(workflowId) {
36
+ return path.join(workflowDir(workflowId), 'staging.json');
37
+ }
38
+ function operationHistoryPath(workflowId) {
39
+ return path.join(workflowDir(workflowId), 'operation_history.json');
40
+ }
41
+ function chatPath(workflowId) {
42
+ return path.join(workflowDir(workflowId), 'chat.json');
43
+ }
44
+ // ---- Legacy migration ----
45
+ function legacyWorkflowPath(workflowId) {
12
46
  return path.join(workflowsDir(), `${workflowId}.json`);
13
47
  }
14
- export function listWorkflows() {
15
- return readJsonFile(workflowsIndex()) ?? [];
48
+ function migrateFromLegacyFormat() {
49
+ const dir = workflowsDir();
50
+ if (!existsSync(dir))
51
+ return;
52
+ // Read legacy index
53
+ const indexPath = workflowIndexPath();
54
+ const legacyIndex = readJsonFile(indexPath);
55
+ if (!Array.isArray(legacyIndex) || legacyIndex.length === 0)
56
+ return;
57
+ // Check if already migrated (has per-workflow dirs)
58
+ const entries = readdirSync(dir, { withFileTypes: true });
59
+ const hasWorkflowDirs = entries.some(e => e.isDirectory() && existsSync(path.join(dir, e.name, 'workflow.json')));
60
+ if (hasWorkflowDirs)
61
+ return;
62
+ // Migrate each legacy workflow
63
+ for (const entry of legacyIndex) {
64
+ const legacyFile = legacyWorkflowPath(entry.id);
65
+ if (!existsSync(legacyFile))
66
+ continue;
67
+ try {
68
+ const raw = JSON.parse(readFileSync(legacyFile, 'utf-8'));
69
+ const migrated = migrateLegacyWorkflow(raw);
70
+ ensureDir(workflowDir(migrated.id));
71
+ writeJsonFile(workflowPath(migrated.id), migrated);
72
+ unlinkSync(legacyFile);
73
+ }
74
+ catch {
75
+ // Skip broken files
76
+ }
77
+ }
78
+ // Remove legacy index
79
+ unlinkSync(indexPath);
80
+ }
81
+ function migrateLegacyWorkflow(raw) {
82
+ return {
83
+ id: raw.id,
84
+ name: raw.name,
85
+ folderId: raw.folderId ?? null,
86
+ description: raw.description,
87
+ nodes: Array.isArray(raw.nodes) ? raw.nodes.map(migrateLegacyNode) : [],
88
+ edges: Array.isArray(raw.edges) ? raw.edges.map(migrateLegacyEdge) : [],
89
+ createdAt: typeof raw.createdAt === 'string' ? Date.parse(raw.createdAt) : (raw.createdAt || Date.now()),
90
+ updatedAt: typeof raw.updatedAt === 'string' ? Date.parse(raw.updatedAt) : (raw.updatedAt || Date.now()),
91
+ };
92
+ }
93
+ function migrateLegacyNode(node) {
94
+ return {
95
+ id: node.id,
96
+ type: node.type || 'agent',
97
+ label: node.data?.label || node.label || '',
98
+ position: node.position || { x: 0, y: 0 },
99
+ data: { ...node.data },
100
+ };
101
+ }
102
+ function migrateLegacyEdge(edge) {
103
+ return {
104
+ id: edge.id,
105
+ source: edge.source,
106
+ target: edge.target,
107
+ sourceHandle: edge.sourceHandle ?? null,
108
+ targetHandle: edge.targetHandle ?? null,
109
+ };
110
+ }
111
+ // ---- CRUD ----
112
+ export function listWorkflows(folderId) {
113
+ migrateFromLegacyFormat();
114
+ const items = readAllWorkflowFiles();
115
+ if (folderId !== undefined)
116
+ return items.filter(w => w.folderId === folderId);
117
+ return items;
16
118
  }
17
119
  export function getWorkflow(workflowId) {
18
- return readJsonFile(workflowFile(workflowId));
120
+ migrateFromLegacyFormat();
121
+ return readWorkflowFile(workflowId);
19
122
  }
20
123
  export function createWorkflow(workflow) {
21
- ensureDir(workflowsDir());
22
- writeJsonFile(workflowFile(workflow.id), workflow);
23
- const index = listWorkflows();
24
- index.push(workflow);
25
- writeJsonFile(workflowsIndex(), index);
124
+ ensureDir(workflowDir(workflow.id));
125
+ writeJsonFile(workflowPath(workflow.id), workflow);
26
126
  }
27
127
  export function updateWorkflow(workflow) {
28
- writeJsonFile(workflowFile(workflow.id), workflow);
29
- const index = listWorkflows();
30
- const idx = index.findIndex(w => w.id === workflow.id);
31
- if (idx !== -1)
32
- index[idx] = workflow;
33
- writeJsonFile(workflowsIndex(), index);
128
+ ensureDir(workflowDir(workflow.id));
129
+ writeJsonFile(workflowPath(workflow.id), workflow);
34
130
  }
35
131
  export function deleteWorkflow(workflowId) {
36
- deleteFile(workflowFile(workflowId));
37
- const index = listWorkflows();
38
- writeJsonFile(workflowsIndex(), index.filter(w => w.id !== workflowId));
132
+ const dir = workflowDir(workflowId);
133
+ if (existsSync(dir))
134
+ rmSync(dir, { recursive: true, force: true });
135
+ // Also clean up legacy flat file if it exists
136
+ const legacy = legacyWorkflowPath(workflowId);
137
+ if (existsSync(legacy))
138
+ unlinkSync(legacy);
139
+ }
140
+ // ---- Folders ----
141
+ export function listWorkflowFolders() {
142
+ const data = readJsonFile(workflowFoldersPath());
143
+ const folders = data?.folders ?? [];
144
+ return [...folders].sort((a, b) => a.order - b.order);
145
+ }
146
+ export function createWorkflowFolder(folder) {
147
+ const folders = listWorkflowFolders();
148
+ folders.push(folder);
149
+ writeJsonFile(workflowFoldersPath(), { folders });
150
+ }
151
+ export function updateWorkflowFolder(id, updates) {
152
+ const folders = listWorkflowFolders();
153
+ const idx = folders.findIndex(f => f.id === id);
154
+ if (idx === -1)
155
+ throw new Error(`Folder ${id} not found`);
156
+ folders[idx] = { ...folders[idx], ...updates };
157
+ writeJsonFile(workflowFoldersPath(), { folders });
158
+ }
159
+ export function deleteWorkflowFolder(id) {
160
+ const folders = listWorkflowFolders();
161
+ const childIds = collectChildFolderIds(folders, id);
162
+ const idsToDelete = new Set([id, ...childIds]);
163
+ const remaining = folders.filter(f => !idsToDelete.has(f.id));
164
+ writeJsonFile(workflowFoldersPath(), { folders: remaining });
165
+ // Delete workflows in removed folders
166
+ const workflows = readAllWorkflowFiles().filter(w => idsToDelete.has(w.folderId ?? ''));
167
+ for (const wf of workflows)
168
+ deleteWorkflow(wf.id);
169
+ }
170
+ // ---- Versions ----
171
+ const MAX_VERSIONS = 100;
172
+ export function listVersions(workflowId) {
173
+ const dir = versionsDir(workflowId);
174
+ if (!existsSync(dir))
175
+ return [];
176
+ return readdirSync(dir)
177
+ .filter(f => f.endsWith('.json'))
178
+ .map(f => {
179
+ try {
180
+ return JSON.parse(readFileSync(path.join(dir, f), 'utf-8'));
181
+ }
182
+ catch {
183
+ return null;
184
+ }
185
+ })
186
+ .filter(Boolean)
187
+ .sort((a, b) => b.createdAt - a.createdAt);
188
+ }
189
+ export function addVersion(workflowId, version) {
190
+ const dir = versionsDir(workflowId);
191
+ ensureDir(dir);
192
+ writeJsonFile(path.join(dir, `${version.id}.json`), version);
193
+ // Enforce limit
194
+ const versions = listVersions(workflowId);
195
+ if (versions.length > MAX_VERSIONS) {
196
+ versions.slice(MAX_VERSIONS).forEach((v) => {
197
+ const p = path.join(dir, `${v.id}.json`);
198
+ if (existsSync(p))
199
+ unlinkSync(p);
200
+ });
201
+ }
202
+ return version;
203
+ }
204
+ export function getVersion(workflowId, versionId) {
205
+ const file = path.join(versionsDir(workflowId), `${versionId}.json`);
206
+ return readJsonFile(file);
207
+ }
208
+ export function deleteVersion(workflowId, versionId) {
209
+ const file = path.join(versionsDir(workflowId), `${versionId}.json`);
210
+ if (existsSync(file))
211
+ unlinkSync(file);
212
+ }
213
+ export function clearVersions(workflowId) {
214
+ const dir = versionsDir(workflowId);
215
+ if (!existsSync(dir))
216
+ return;
217
+ readdirSync(dir).filter(f => f.endsWith('.json')).forEach(f => unlinkSync(path.join(dir, f)));
218
+ }
219
+ // ---- Execution Logs ----
220
+ const MAX_LOGS = 100;
221
+ export function listExecutionLogs(workflowId) {
222
+ const dir = executionHistoryDir(workflowId);
223
+ if (!existsSync(dir))
224
+ return [];
225
+ return readdirSync(dir)
226
+ .filter(f => f.endsWith('.json'))
227
+ .map(f => {
228
+ const p = path.join(dir, f);
229
+ try {
230
+ return { log: JSON.parse(readFileSync(p, 'utf-8')), mtime: statSync(p).mtimeMs };
231
+ }
232
+ catch {
233
+ return null;
234
+ }
235
+ })
236
+ .filter(Boolean)
237
+ .sort((a, b) => b.mtime - a.mtime)
238
+ .map((item) => item.log);
239
+ }
240
+ export function addExecutionLog(workflowId, log) {
241
+ const dir = executionHistoryDir(workflowId);
242
+ ensureDir(dir);
243
+ writeJsonFile(path.join(dir, `${log.id}.json`), log);
244
+ // Enforce limit
245
+ const files = readdirSync(dir).filter(f => f.endsWith('.json'));
246
+ if (files.length > MAX_LOGS) {
247
+ files.map(f => ({ f, mtime: statSync(path.join(dir, f)).mtimeMs }))
248
+ .sort((a, b) => b.mtime - a.mtime)
249
+ .slice(MAX_LOGS)
250
+ .forEach(item => { try {
251
+ unlinkSync(path.join(dir, item.f));
252
+ }
253
+ catch { /* ignore */ } });
254
+ }
255
+ return log;
256
+ }
257
+ export function listAllExecutionLogs(limit = 50) {
258
+ const dir = workflowsDir();
259
+ if (!existsSync(dir))
260
+ return [];
261
+ const results = [];
262
+ const wDirs = readdirSync(dir, { withFileTypes: true }).filter(d => d.isDirectory());
263
+ for (const wDir of wDirs) {
264
+ const wId = wDir.name;
265
+ const historyDir = executionHistoryDir(wId);
266
+ if (!existsSync(historyDir))
267
+ continue;
268
+ // Read workflow name for display
269
+ let workflowName = wId;
270
+ const wfPath = workflowPath(wId);
271
+ if (existsSync(wfPath)) {
272
+ try {
273
+ workflowName = JSON.parse(readFileSync(wfPath, 'utf-8')).name || wId;
274
+ }
275
+ catch { /* ignore */ }
276
+ }
277
+ readdirSync(historyDir)
278
+ .filter(f => f.endsWith('.json'))
279
+ .forEach(f => {
280
+ try {
281
+ const log = JSON.parse(readFileSync(path.join(historyDir, f), 'utf-8'));
282
+ results.push({ ...log, workflowName });
283
+ }
284
+ catch { /* ignore */ }
285
+ });
286
+ }
287
+ return results
288
+ .sort((a, b) => (b.startedAt || 0) - (a.startedAt || 0))
289
+ .slice(0, limit);
290
+ }
291
+ export function getExecutionLog(workflowId, logId) {
292
+ return readJsonFile(path.join(executionHistoryDir(workflowId), `${logId}.json`));
293
+ }
294
+ export function deleteExecutionLog(workflowId, logId) {
295
+ const file = path.join(executionHistoryDir(workflowId), `${logId}.json`);
296
+ if (existsSync(file))
297
+ unlinkSync(file);
298
+ }
299
+ export function clearExecutionLogs(workflowId) {
300
+ const dir = executionHistoryDir(workflowId);
301
+ if (!existsSync(dir))
302
+ return;
303
+ readdirSync(dir).filter(f => f.endsWith('.json')).forEach(f => unlinkSync(path.join(dir, f)));
304
+ }
305
+ // ---- Staging ----
306
+ export function loadStaging(workflowId) {
307
+ return readJsonFile(stagingPath(workflowId)) ?? [];
308
+ }
309
+ export function saveStaging(workflowId, nodes) {
310
+ ensureDir(workflowDir(workflowId));
311
+ writeJsonFile(stagingPath(workflowId), nodes);
312
+ }
313
+ export function clearStaging(workflowId) {
314
+ const file = stagingPath(workflowId);
315
+ if (existsSync(file))
316
+ unlinkSync(file);
317
+ }
318
+ // ---- Operation History ----
319
+ export function loadOperationHistory(workflowId) {
320
+ return readJsonFile(operationHistoryPath(workflowId)) ?? [];
321
+ }
322
+ export function saveOperationHistory(workflowId, entries) {
323
+ ensureDir(workflowDir(workflowId));
324
+ writeJsonFile(operationHistoryPath(workflowId), entries);
325
+ }
326
+ export function clearOperationHistory(workflowId) {
327
+ const file = operationHistoryPath(workflowId);
328
+ if (existsSync(file))
329
+ unlinkSync(file);
330
+ }
331
+ // ---- Workflow Agent Chat ----
332
+ export function loadChat(workflowId) {
333
+ return readJsonFile(chatPath(workflowId)) ?? [];
334
+ }
335
+ export function saveChat(workflowId, messages) {
336
+ ensureDir(workflowDir(workflowId));
337
+ writeJsonFile(chatPath(workflowId), messages);
338
+ }
339
+ export function clearChat(workflowId) {
340
+ const file = chatPath(workflowId);
341
+ if (existsSync(file))
342
+ unlinkSync(file);
343
+ }
344
+ // ---- Plugin Schemes ----
345
+ export function listPluginSchemes(workflowId, pluginId) {
346
+ const dir = path.join(pluginConfigsDir(workflowId), pluginId);
347
+ if (!existsSync(dir))
348
+ return [];
349
+ return readdirSync(dir).filter(f => f.endsWith('.json')).map(f => f.replace(/\.json$/, '')).sort();
350
+ }
351
+ export function readPluginScheme(workflowId, pluginId, schemeName) {
352
+ const file = pluginSchemePath(workflowId, pluginId, schemeName);
353
+ if (!existsSync(file))
354
+ throw new Error(`Plugin scheme ${schemeName} not found`);
355
+ return JSON.parse(readFileSync(file, 'utf-8'));
356
+ }
357
+ export function savePluginScheme(workflowId, pluginId, schemeName, data) {
358
+ const dir = path.join(pluginConfigsDir(workflowId), pluginId);
359
+ ensureDir(dir);
360
+ writeJsonFile(pluginSchemePath(workflowId, pluginId, schemeName), data);
361
+ }
362
+ export function deletePluginScheme(workflowId, pluginId, schemeName) {
363
+ const file = pluginSchemePath(workflowId, pluginId, schemeName);
364
+ if (existsSync(file))
365
+ unlinkSync(file);
366
+ }
367
+ // ---- Internal helpers ----
368
+ function readAllWorkflowFiles() {
369
+ const dir = workflowsDir();
370
+ if (!existsSync(dir))
371
+ return [];
372
+ const items = [];
373
+ const entries = readdirSync(dir, { withFileTypes: true });
374
+ for (const entry of entries) {
375
+ if (!entry.isDirectory())
376
+ continue;
377
+ const file = path.join(dir, entry.name, 'workflow.json');
378
+ if (!existsSync(file))
379
+ continue;
380
+ try {
381
+ items.push(JSON.parse(readFileSync(file, 'utf-8')));
382
+ }
383
+ catch { /* skip broken */ }
384
+ }
385
+ return items.sort((a, b) => b.updatedAt - a.updatedAt);
386
+ }
387
+ function readWorkflowFile(workflowId) {
388
+ const file = workflowPath(workflowId);
389
+ if (!existsSync(file))
390
+ return null;
391
+ try {
392
+ return JSON.parse(readFileSync(file, 'utf-8'));
393
+ }
394
+ catch {
395
+ return null;
396
+ }
397
+ }
398
+ function collectChildFolderIds(folders, parentId) {
399
+ const children = folders.filter(f => f.parentId === parentId);
400
+ return children.reduce((acc, child) => [...acc, child.id, ...collectChildFolderIds(folders, child.id)], []);
39
401
  }
402
+ // Need statSync for execution log sorting
403
+ import { statSync } from 'node:fs';
40
404
  //# sourceMappingURL=workflow-store.js.map
@@ -0,0 +1,33 @@
1
+ import { join } from 'node:path';
2
+ import { getDataDir, ensureDir, readJsonFile, writeJsonFile } from './json-store.js';
3
+ function worktreesDir(workspaceId) {
4
+ return join(getDataDir(), 'workspaces', workspaceId, 'worktrees');
5
+ }
6
+ function worktreesIndex(workspaceId) {
7
+ return join(worktreesDir(workspaceId), 'index.json');
8
+ }
9
+ export function listWorktrees(workspaceId) {
10
+ return readJsonFile(worktreesIndex(workspaceId)) || [];
11
+ }
12
+ export function getWorktree(workspaceId, worktreeId) {
13
+ const list = listWorktrees(workspaceId);
14
+ return list.find(wt => wt.id === worktreeId) ?? null;
15
+ }
16
+ export function createWorktree(workspaceId, info) {
17
+ ensureDir(worktreesDir(workspaceId));
18
+ const list = listWorktrees(workspaceId);
19
+ list.push(info);
20
+ writeJsonFile(worktreesIndex(workspaceId), list);
21
+ }
22
+ export function updateWorktree(workspaceId, info) {
23
+ const list = listWorktrees(workspaceId);
24
+ const idx = list.findIndex(wt => wt.id === info.id);
25
+ if (idx >= 0)
26
+ list[idx] = info;
27
+ writeJsonFile(worktreesIndex(workspaceId), list);
28
+ }
29
+ export function deleteWorktreeFromIndex(workspaceId, worktreeId) {
30
+ const list = listWorktrees(workspaceId).filter(wt => wt.id !== worktreeId);
31
+ writeJsonFile(worktreesIndex(workspaceId), list);
32
+ }
33
+ //# sourceMappingURL=worktree-store.js.map