@oomol-lab/open-flow 0.1.0-beta.73 → 0.1.0-beta.75

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 (444) hide show
  1. package/LICENSE +36 -0
  2. package/NOTICE +7 -0
  3. package/README.md +41 -0
  4. package/dist/browser/{ContentIcon-CUQHjQIw.js → ContentIcon-FCpKiwjp.js} +2 -1
  5. package/dist/browser/{FlowCanvas-Dtf8_cQp.js → FlowCanvas-dzRBnlUT.js} +1 -1
  6. package/dist/browser/{createResourceDialog-BWJkjiOO.js → createResourceDialog-BeYDdUl-.js} +2 -2
  7. package/dist/browser/{dialog-CUy_fwx9.js → dialog-ZtpsFbl4.js} +337 -31
  8. package/dist/browser/{exportSvg-BOoy7-Db.js → exportSvg-DqXw1yf-.js} +2 -2
  9. package/dist/browser/{flowChanges-CgSnSqqP.js → flowChanges-b_5UobFj.js} +586 -87
  10. package/dist/browser/{flowWorkspace-Bf7H-r0t.js → flowWorkspace-ItojZbO4.js} +21162 -20242
  11. package/dist/browser/preview.css +254 -179
  12. package/dist/browser/preview.js +22201 -20625
  13. package/dist/browser/{typeScriptSession-B0hC-C8y.js → typeScriptSession-CSRwWmZm.js} +1 -1
  14. package/dist/browser/ui.css +72 -2
  15. package/dist/browser/workbench.css +254 -179
  16. package/dist/browser/workbench.js +22 -78
  17. package/dist/browser/{workbenchSelect-C3e4J93X.js → workbenchSelect-M441Lz0d.js} +1 -1
  18. package/dist/command/index.js +42 -42
  19. package/dist/common/authoring.d.ts +5 -5
  20. package/dist/common/authoringExamples.d.ts +3 -2
  21. package/dist/common/authoringFields.d.ts +1 -1
  22. package/dist/common/authoringSchema.d.ts +95 -8
  23. package/dist/common/connector-proxy.d.ts +1 -1
  24. package/dist/common/control-api-conformance.d.ts +1 -1
  25. package/dist/common/control-api-conformance.js +119 -31
  26. package/dist/common/control-api.d.ts +4 -3
  27. package/dist/common/control-api.js +117 -29
  28. package/dist/common/control-requests.d.ts +5 -4
  29. package/dist/common/control-requests.js +437 -103
  30. package/dist/common/cron-trigger.d.ts +1 -1
  31. package/dist/common/decision.d.ts +1 -1
  32. package/dist/common/draftOperations.d.ts +1 -1
  33. package/dist/common/engine-contract.d.ts +4 -2
  34. package/dist/common/event-source-definition.d.ts +1 -1
  35. package/dist/common/flow-agent.d.ts +1 -1
  36. package/dist/{browser → common}/flow-authoring-node.d.ts +3 -3
  37. package/dist/{browser → common}/flow-authoring.js +131 -30
  38. package/dist/{browser → common}/flow-change-schema.d.ts +177 -6
  39. package/dist/{browser → common}/flow-change.d.ts +35 -15
  40. package/dist/{browser → common}/flow-change.js +133 -32
  41. package/dist/common/flow-connectionUsage.d.ts +1 -1
  42. package/dist/common/flow-encoding.d.ts +1 -1
  43. package/dist/common/flow-encoding.js +89 -23
  44. package/dist/common/flow-errorHandling.d.ts +1 -1
  45. package/dist/common/flow-graph.d.ts +3 -2
  46. package/dist/common/flow-modules.d.ts +1 -1
  47. package/dist/common/flow-promptTemplate.d.ts +1 -1
  48. package/dist/common/flow-retry.d.ts +2 -2
  49. package/dist/common/flow-semantics.d.ts +1 -1
  50. package/dist/common/flow-semantics.js +966 -614
  51. package/dist/common/flow-workflowFile.d.ts +1 -1
  52. package/dist/common/flowInspection.d.ts +3 -3
  53. package/dist/common/http-request.d.ts +156 -0
  54. package/dist/common/http-request.js +5254 -0
  55. package/dist/common/integration-trigger.d.ts +1 -1
  56. package/dist/common/licenses.md +118 -1
  57. package/dist/common/liveDetails.d.ts +1 -1
  58. package/dist/common/mcp.d.ts +5 -4
  59. package/dist/common/mcp.js +117 -29
  60. package/dist/common/openapi.d.ts +1 -1
  61. package/dist/common/poll-trigger.d.ts +1 -1
  62. package/dist/common/run-events.js +11 -9
  63. package/dist/common/run-results.d.ts +8 -1
  64. package/dist/common/runtime-contract.d.ts +8 -2
  65. package/dist/common/runtime-contract.js +25 -5
  66. package/dist/common/scheduler-checkpoint.d.ts +1 -1
  67. package/dist/common/scheduler-dependencies.d.ts +1 -1
  68. package/dist/common/scheduler-node-execution.d.ts +1 -1
  69. package/dist/common/scheduler.d.ts +3 -3
  70. package/dist/common/scheduler.js +101 -33
  71. package/dist/common/trigger-catalog.d.ts +1 -1
  72. package/dist/common/trigger-config-options.d.ts +1 -1
  73. package/dist/common/trigger-config.d.ts +1 -1
  74. package/dist/common/trigger-contract.d.ts +2 -2
  75. package/dist/common/trigger-localization.d.ts +1 -1
  76. package/dist/common/webhook-response.d.ts +1 -3
  77. package/dist/common/webhook-trigger.d.ts +1 -1
  78. package/dist/common/webhook-trigger.js +12 -11
  79. package/dist/common/workflow.d.ts +17 -1
  80. package/dist/common/workflow.js +68 -22
  81. package/dist/index.d.ts +6 -3
  82. package/package.json +11 -6
  83. package/skills/open-flow/references/flow-authoring.md +1 -0
  84. package/skills/open-flow/references/flow-n8n-conversion.md +19 -15
  85. package/src/base/common/json.ts +90 -0
  86. package/src/canvas/common/commands.ts +15 -0
  87. package/src/connector/common/actionSchema.ts +168 -0
  88. package/src/connector/common/proxy.ts +44 -0
  89. package/src/control/common/api.ts +1506 -0
  90. package/src/control/common/authoring.ts +923 -0
  91. package/src/control/common/authoringCondition.ts +110 -0
  92. package/src/control/common/authoringDiagnosticFields.ts +136 -0
  93. package/src/control/common/authoringExamples.ts +200 -0
  94. package/src/control/common/authoringFields.ts +53 -0
  95. package/src/control/common/authoringLlm.ts +70 -0
  96. package/src/control/common/authoringOpenApi.ts +129 -0
  97. package/src/control/common/authoringSchema.ts +410 -0
  98. package/src/control/common/authoringTools.ts +123 -0
  99. package/src/control/common/authoringTriggers.ts +26 -0
  100. package/src/control/common/checkDecoders.ts +65 -0
  101. package/src/control/common/conformance.ts +1989 -0
  102. package/src/control/common/connectorDecoders.ts +370 -0
  103. package/src/control/common/connectorQueries.ts +61 -0
  104. package/src/control/common/decoding.ts +60 -0
  105. package/src/control/common/draftOperations.ts +61 -0
  106. package/src/control/common/errors.ts +114 -0
  107. package/src/control/common/eventSourceSchemas.ts +13 -0
  108. package/src/control/common/eventSources.ts +186 -0
  109. package/src/control/common/flowDecoders.ts +153 -0
  110. package/src/control/common/flowInspection.ts +181 -0
  111. package/src/control/common/flowNotifications.ts +37 -0
  112. package/src/control/common/liveDetails.ts +124 -0
  113. package/src/control/common/mcp.ts +241 -0
  114. package/src/control/common/mcpConformance.ts +142 -0
  115. package/src/control/common/providerAccess.ts +28 -0
  116. package/src/control/common/providerIconSprite.ts +42 -0
  117. package/src/control/common/publicationDecoders.ts +98 -0
  118. package/src/control/common/random.ts +16 -0
  119. package/src/control/common/requests.ts +112 -0
  120. package/src/control/common/resultQuery.ts +8 -0
  121. package/src/control/common/results.ts +176 -0
  122. package/src/control/common/revisionDecoders.ts +52 -0
  123. package/src/control/common/runDecoders.ts +240 -0
  124. package/src/control/common/triggerCatalog.ts +89 -0
  125. package/src/control/common/triggerDecoders.ts +175 -0
  126. package/src/decision/common/decision.ts +168 -0
  127. package/src/event-source/common/catalog.generated.json +65 -0
  128. package/src/event-source/common/definition.ts +66 -0
  129. package/src/event-source/common/index.ts +99 -0
  130. package/src/execution/common/checkpoint.ts +311 -0
  131. package/src/execution/common/dependencies.ts +440 -0
  132. package/src/execution/common/engineContract.ts +84 -0
  133. package/src/execution/common/events.ts +331 -0
  134. package/src/execution/common/node-execution.ts +469 -0
  135. package/src/execution/common/runLifecycle.ts +250 -0
  136. package/src/execution/common/runtime.ts +563 -0
  137. package/src/execution/common/scheduler.ts +697 -0
  138. package/src/execution/common/wait.ts +36 -0
  139. package/src/flow/common/agent.ts +305 -0
  140. package/src/flow/common/authoring.ts +30 -0
  141. package/src/flow/common/change.ts +1037 -0
  142. package/src/flow/common/changeSchema.ts +792 -0
  143. package/src/flow/common/codePermissions.ts +2 -0
  144. package/src/flow/common/condition.ts +265 -0
  145. package/src/flow/common/connectionUsage.ts +131 -0
  146. package/src/flow/common/edgeChanges.ts +35 -0
  147. package/src/flow/common/encoding.ts +437 -0
  148. package/src/flow/common/errorHandling.ts +34 -0
  149. package/src/flow/common/graph.ts +898 -0
  150. package/src/flow/common/inputValue.ts +16 -0
  151. package/src/flow/common/json.ts +8 -0
  152. package/src/flow/common/moduleChanges.ts +31 -0
  153. package/src/flow/common/modules.ts +292 -0
  154. package/src/flow/common/nodeChanges.ts +762 -0
  155. package/src/flow/common/portChanges.ts +36 -0
  156. package/src/flow/common/promptTemplate.ts +15 -0
  157. package/src/flow/common/retry.ts +20 -0
  158. package/src/flow/common/schema.ts +162 -0
  159. package/src/flow/common/schemaCompare.ts +176 -0
  160. package/src/flow/common/schemaComparer.ts +178 -0
  161. package/src/flow/common/schemaKeywords.ts +53 -0
  162. package/src/flow/common/semantics.ts +531 -0
  163. package/src/flow/common/sourceField.ts +35 -0
  164. package/src/flow/common/triggerScheduleSchema.ts +8 -0
  165. package/src/flow/common/wait.ts +30 -0
  166. package/src/flow/common/webhookMethod.ts +7 -0
  167. package/src/flow/common/webhookResponse.ts +71 -0
  168. package/src/flow/common/workflowFile.ts +97 -0
  169. package/src/http/common/authBindings.ts +12 -0
  170. package/src/http/common/headers.ts +5 -0
  171. package/src/http/common/httpRequest.ts +251 -0
  172. package/src/json-schema-subset/checker/array.ts +142 -0
  173. package/src/json-schema-subset/checker/cache.ts +57 -0
  174. package/src/json-schema-subset/checker/checker.ts +230 -0
  175. package/src/json-schema-subset/checker/enumAndConst.ts +113 -0
  176. package/src/json-schema-subset/checker/equals.ts +93 -0
  177. package/src/json-schema-subset/checker/numeric/checker.ts +50 -0
  178. package/src/json-schema-subset/checker/numeric/float.ts +121 -0
  179. package/src/json-schema-subset/checker/numeric/index.ts +1 -0
  180. package/src/json-schema-subset/checker/numeric/integer.ts +119 -0
  181. package/src/json-schema-subset/checker/numeric/integerNormalizer.ts +72 -0
  182. package/src/json-schema-subset/checker/object.ts +354 -0
  183. package/src/json-schema-subset/checker/range.ts +91 -0
  184. package/src/json-schema-subset/checker/string.ts +60 -0
  185. package/src/json-schema-subset/checker/tools/index.ts +3 -0
  186. package/src/json-schema-subset/checker/tools/mark.ts +82 -0
  187. package/src/json-schema-subset/checker/tools/quantum.ts +106 -0
  188. package/src/json-schema-subset/checker/tools/range.ts +210 -0
  189. package/src/json-schema-subset/checker/validator.ts +23 -0
  190. package/src/json-schema-subset/compiler/array.ts +163 -0
  191. package/src/json-schema-subset/compiler/combination.ts +109 -0
  192. package/src/json-schema-subset/compiler/common.ts +99 -0
  193. package/src/json-schema-subset/compiler/compiler.ts +188 -0
  194. package/src/json-schema-subset/compiler/enumAndConst.ts +75 -0
  195. package/src/json-schema-subset/compiler/index.ts +11 -0
  196. package/src/json-schema-subset/compiler/object.ts +411 -0
  197. package/src/json-schema-subset/compiler/primitive.ts +144 -0
  198. package/src/json-schema-subset/compiler/utils.ts +24 -0
  199. package/src/json-schema-subset/compiler/wrapper.ts +192 -0
  200. package/src/json-schema-subset/error.ts +55 -0
  201. package/src/json-schema-subset/expression/calculator.ts +442 -0
  202. package/src/json-schema-subset/expression/combination.ts +49 -0
  203. package/src/json-schema-subset/expression/expression.ts +191 -0
  204. package/src/json-schema-subset/expression/index.ts +25 -0
  205. package/src/json-schema-subset/expression/result.ts +88 -0
  206. package/src/json-schema-subset/expression/types.ts +36 -0
  207. package/src/json-schema-subset/extends/extendsContext.ts +89 -0
  208. package/src/json-schema-subset/extends/index.ts +2 -0
  209. package/src/json-schema-subset/extends/types.ts +12 -0
  210. package/src/json-schema-subset/global.ts +60 -0
  211. package/src/json-schema-subset/index.ts +8 -0
  212. package/src/json-schema-subset/preprocessing.ts +74 -0
  213. package/src/json-schema-subset/types.ts +8 -0
  214. package/src/json-schema-subset/utils.ts +95 -0
  215. package/src/localization/common/languages.ts +118 -0
  216. package/src/localization/common/timeZone.ts +25 -0
  217. package/src/openapi/common/openapi.ts +459 -0
  218. package/src/trigger/common/config.ts +56 -0
  219. package/src/trigger/common/configOptions.ts +15 -0
  220. package/src/trigger/common/configSchema.ts +8 -0
  221. package/src/trigger/common/contract.ts +132 -0
  222. package/src/trigger/common/cron.ts +151 -0
  223. package/src/trigger/common/integration.ts +498 -0
  224. package/src/trigger/common/poll.ts +187 -0
  225. package/src/trigger/common/webhook.ts +413 -0
  226. package/src/trigger/providers/airtable/locales/fr.json +18 -0
  227. package/src/trigger/providers/airtable/locales/ja.json +18 -0
  228. package/src/trigger/providers/airtable/locales/ko.json +18 -0
  229. package/src/trigger/providers/airtable/locales/ru.json +18 -0
  230. package/src/trigger/providers/airtable/locales/zh-CN.json +18 -0
  231. package/src/trigger/providers/airtable/locales/zh-TW.json +18 -0
  232. package/src/trigger/providers/asana/locales/fr.json +15 -0
  233. package/src/trigger/providers/asana/locales/ja.json +15 -0
  234. package/src/trigger/providers/asana/locales/ko.json +15 -0
  235. package/src/trigger/providers/asana/locales/ru.json +15 -0
  236. package/src/trigger/providers/asana/locales/zh-CN.json +15 -0
  237. package/src/trigger/providers/asana/locales/zh-TW.json +15 -0
  238. package/src/trigger/providers/calendly/locales/fr.json +16 -0
  239. package/src/trigger/providers/calendly/locales/ja.json +16 -0
  240. package/src/trigger/providers/calendly/locales/ko.json +16 -0
  241. package/src/trigger/providers/calendly/locales/ru.json +16 -0
  242. package/src/trigger/providers/calendly/locales/zh-CN.json +16 -0
  243. package/src/trigger/providers/calendly/locales/zh-TW.json +16 -0
  244. package/src/trigger/providers/catalog.generated.json +4996 -0
  245. package/src/trigger/providers/clickup/locales/fr.json +16 -0
  246. package/src/trigger/providers/clickup/locales/ja.json +16 -0
  247. package/src/trigger/providers/clickup/locales/ko.json +16 -0
  248. package/src/trigger/providers/clickup/locales/ru.json +16 -0
  249. package/src/trigger/providers/clickup/locales/zh-CN.json +16 -0
  250. package/src/trigger/providers/clickup/locales/zh-TW.json +16 -0
  251. package/src/trigger/providers/definitions.ts +19 -0
  252. package/src/trigger/providers/feishu/locales/fr.json +20 -0
  253. package/src/trigger/providers/feishu/locales/ja.json +20 -0
  254. package/src/trigger/providers/feishu/locales/ko.json +20 -0
  255. package/src/trigger/providers/feishu/locales/ru.json +20 -0
  256. package/src/trigger/providers/feishu/locales/zh-CN.json +20 -0
  257. package/src/trigger/providers/feishu/locales/zh-TW.json +20 -0
  258. package/src/trigger/providers/fieldDescriptions.ts +392 -0
  259. package/src/trigger/providers/fieldLabels.ts +256 -0
  260. package/src/trigger/providers/fireflies/locales/fr.json +17 -0
  261. package/src/trigger/providers/fireflies/locales/ja.json +17 -0
  262. package/src/trigger/providers/fireflies/locales/ko.json +17 -0
  263. package/src/trigger/providers/fireflies/locales/ru.json +17 -0
  264. package/src/trigger/providers/fireflies/locales/zh-CN.json +17 -0
  265. package/src/trigger/providers/fireflies/locales/zh-TW.json +17 -0
  266. package/src/trigger/providers/github/locales/fr.json +30 -0
  267. package/src/trigger/providers/github/locales/ja.json +30 -0
  268. package/src/trigger/providers/github/locales/ko.json +30 -0
  269. package/src/trigger/providers/github/locales/ru.json +30 -0
  270. package/src/trigger/providers/github/locales/zh-CN.json +30 -0
  271. package/src/trigger/providers/github/locales/zh-TW.json +30 -0
  272. package/src/trigger/providers/gitlab/locales/fr.json +18 -0
  273. package/src/trigger/providers/gitlab/locales/ja.json +18 -0
  274. package/src/trigger/providers/gitlab/locales/ko.json +18 -0
  275. package/src/trigger/providers/gitlab/locales/ru.json +18 -0
  276. package/src/trigger/providers/gitlab/locales/zh-CN.json +18 -0
  277. package/src/trigger/providers/gitlab/locales/zh-TW.json +18 -0
  278. package/src/trigger/providers/gmail/locales/fr.json +18 -0
  279. package/src/trigger/providers/gmail/locales/ja.json +18 -0
  280. package/src/trigger/providers/gmail/locales/ko.json +18 -0
  281. package/src/trigger/providers/gmail/locales/ru.json +18 -0
  282. package/src/trigger/providers/gmail/locales/zh-CN.json +18 -0
  283. package/src/trigger/providers/gmail/locales/zh-TW.json +18 -0
  284. package/src/trigger/providers/google-calendar/locales/fr.json +15 -0
  285. package/src/trigger/providers/google-calendar/locales/ja.json +15 -0
  286. package/src/trigger/providers/google-calendar/locales/ko.json +15 -0
  287. package/src/trigger/providers/google-calendar/locales/ru.json +15 -0
  288. package/src/trigger/providers/google-calendar/locales/zh-CN.json +15 -0
  289. package/src/trigger/providers/google-calendar/locales/zh-TW.json +15 -0
  290. package/src/trigger/providers/google-drive/locales/fr.json +48 -0
  291. package/src/trigger/providers/google-drive/locales/ja.json +48 -0
  292. package/src/trigger/providers/google-drive/locales/ko.json +48 -0
  293. package/src/trigger/providers/google-drive/locales/ru.json +48 -0
  294. package/src/trigger/providers/google-drive/locales/zh-CN.json +48 -0
  295. package/src/trigger/providers/google-drive/locales/zh-TW.json +48 -0
  296. package/src/trigger/providers/google-sheets/locales/fr.json +19 -0
  297. package/src/trigger/providers/google-sheets/locales/ja.json +19 -0
  298. package/src/trigger/providers/google-sheets/locales/ko.json +19 -0
  299. package/src/trigger/providers/google-sheets/locales/ru.json +19 -0
  300. package/src/trigger/providers/google-sheets/locales/zh-CN.json +19 -0
  301. package/src/trigger/providers/google-sheets/locales/zh-TW.json +19 -0
  302. package/src/trigger/providers/intercom/locales/fr.json +17 -0
  303. package/src/trigger/providers/intercom/locales/ja.json +17 -0
  304. package/src/trigger/providers/intercom/locales/ko.json +17 -0
  305. package/src/trigger/providers/intercom/locales/ru.json +17 -0
  306. package/src/trigger/providers/intercom/locales/zh-CN.json +17 -0
  307. package/src/trigger/providers/intercom/locales/zh-TW.json +17 -0
  308. package/src/trigger/providers/jira/locales/fr.json +17 -0
  309. package/src/trigger/providers/jira/locales/ja.json +17 -0
  310. package/src/trigger/providers/jira/locales/ko.json +17 -0
  311. package/src/trigger/providers/jira/locales/ru.json +17 -0
  312. package/src/trigger/providers/jira/locales/zh-CN.json +17 -0
  313. package/src/trigger/providers/jira/locales/zh-TW.json +17 -0
  314. package/src/trigger/providers/linear/locales/fr.json +13 -0
  315. package/src/trigger/providers/linear/locales/ja.json +13 -0
  316. package/src/trigger/providers/linear/locales/ko.json +13 -0
  317. package/src/trigger/providers/linear/locales/ru.json +13 -0
  318. package/src/trigger/providers/linear/locales/zh-CN.json +13 -0
  319. package/src/trigger/providers/linear/locales/zh-TW.json +13 -0
  320. package/src/trigger/providers/locales/fr.ts +71 -0
  321. package/src/trigger/providers/locales/ja.ts +71 -0
  322. package/src/trigger/providers/locales/ko.ts +71 -0
  323. package/src/trigger/providers/locales/ru.ts +71 -0
  324. package/src/trigger/providers/locales/zh-CN.ts +71 -0
  325. package/src/trigger/providers/locales/zh-TW.ts +71 -0
  326. package/src/trigger/providers/localization.ts +59 -0
  327. package/src/trigger/providers/notion/locales/fr.json +16 -0
  328. package/src/trigger/providers/notion/locales/ja.json +16 -0
  329. package/src/trigger/providers/notion/locales/ko.json +16 -0
  330. package/src/trigger/providers/notion/locales/ru.json +16 -0
  331. package/src/trigger/providers/notion/locales/zh-CN.json +16 -0
  332. package/src/trigger/providers/notion/locales/zh-TW.json +16 -0
  333. package/src/trigger/providers/one-drive/locales/fr.json +16 -0
  334. package/src/trigger/providers/one-drive/locales/ja.json +16 -0
  335. package/src/trigger/providers/one-drive/locales/ko.json +16 -0
  336. package/src/trigger/providers/one-drive/locales/ru.json +16 -0
  337. package/src/trigger/providers/one-drive/locales/zh-CN.json +16 -0
  338. package/src/trigger/providers/one-drive/locales/zh-TW.json +16 -0
  339. package/src/trigger/providers/outlook/locales/fr.json +18 -0
  340. package/src/trigger/providers/outlook/locales/ja.json +18 -0
  341. package/src/trigger/providers/outlook/locales/ko.json +18 -0
  342. package/src/trigger/providers/outlook/locales/ru.json +18 -0
  343. package/src/trigger/providers/outlook/locales/zh-CN.json +18 -0
  344. package/src/trigger/providers/outlook/locales/zh-TW.json +18 -0
  345. package/src/trigger/providers/pandadoc/locales/fr.json +12 -0
  346. package/src/trigger/providers/pandadoc/locales/ja.json +12 -0
  347. package/src/trigger/providers/pandadoc/locales/ko.json +12 -0
  348. package/src/trigger/providers/pandadoc/locales/ru.json +12 -0
  349. package/src/trigger/providers/pandadoc/locales/zh-CN.json +12 -0
  350. package/src/trigger/providers/pandadoc/locales/zh-TW.json +12 -0
  351. package/src/trigger/providers/pipedrive/locales/fr.json +15 -0
  352. package/src/trigger/providers/pipedrive/locales/ja.json +15 -0
  353. package/src/trigger/providers/pipedrive/locales/ko.json +15 -0
  354. package/src/trigger/providers/pipedrive/locales/ru.json +15 -0
  355. package/src/trigger/providers/pipedrive/locales/zh-CN.json +15 -0
  356. package/src/trigger/providers/pipedrive/locales/zh-TW.json +15 -0
  357. package/src/trigger/providers/remote.ts +163 -0
  358. package/src/trigger/providers/resend/locales/fr.json +16 -0
  359. package/src/trigger/providers/resend/locales/ja.json +16 -0
  360. package/src/trigger/providers/resend/locales/ko.json +16 -0
  361. package/src/trigger/providers/resend/locales/ru.json +16 -0
  362. package/src/trigger/providers/resend/locales/zh-CN.json +16 -0
  363. package/src/trigger/providers/resend/locales/zh-TW.json +16 -0
  364. package/src/trigger/providers/sentry/locales/fr.json +19 -0
  365. package/src/trigger/providers/sentry/locales/ja.json +19 -0
  366. package/src/trigger/providers/sentry/locales/ko.json +19 -0
  367. package/src/trigger/providers/sentry/locales/ru.json +19 -0
  368. package/src/trigger/providers/sentry/locales/zh-CN.json +19 -0
  369. package/src/trigger/providers/sentry/locales/zh-TW.json +19 -0
  370. package/src/trigger/providers/shopify/locales/fr.json +18 -0
  371. package/src/trigger/providers/shopify/locales/ja.json +18 -0
  372. package/src/trigger/providers/shopify/locales/ko.json +18 -0
  373. package/src/trigger/providers/shopify/locales/ru.json +18 -0
  374. package/src/trigger/providers/shopify/locales/zh-CN.json +18 -0
  375. package/src/trigger/providers/shopify/locales/zh-TW.json +18 -0
  376. package/src/trigger/providers/slack/locales/fr.json +18 -0
  377. package/src/trigger/providers/slack/locales/ja.json +18 -0
  378. package/src/trigger/providers/slack/locales/ko.json +18 -0
  379. package/src/trigger/providers/slack/locales/ru.json +18 -0
  380. package/src/trigger/providers/slack/locales/zh-CN.json +18 -0
  381. package/src/trigger/providers/slack/locales/zh-TW.json +18 -0
  382. package/src/trigger/providers/slackbot/locales/fr.json +23 -0
  383. package/src/trigger/providers/slackbot/locales/ja.json +23 -0
  384. package/src/trigger/providers/slackbot/locales/ko.json +23 -0
  385. package/src/trigger/providers/slackbot/locales/ru.json +23 -0
  386. package/src/trigger/providers/slackbot/locales/zh-CN.json +23 -0
  387. package/src/trigger/providers/slackbot/locales/zh-TW.json +23 -0
  388. package/src/trigger/providers/source-events.ts +25 -0
  389. package/src/trigger/providers/stripe/locales/fr.json +17 -0
  390. package/src/trigger/providers/stripe/locales/ja.json +17 -0
  391. package/src/trigger/providers/stripe/locales/ko.json +17 -0
  392. package/src/trigger/providers/stripe/locales/ru.json +17 -0
  393. package/src/trigger/providers/stripe/locales/zh-CN.json +17 -0
  394. package/src/trigger/providers/stripe/locales/zh-TW.json +17 -0
  395. package/src/trigger/providers/tally/locales/fr.json +12 -0
  396. package/src/trigger/providers/tally/locales/ja.json +12 -0
  397. package/src/trigger/providers/tally/locales/ko.json +12 -0
  398. package/src/trigger/providers/tally/locales/ru.json +12 -0
  399. package/src/trigger/providers/tally/locales/zh-CN.json +12 -0
  400. package/src/trigger/providers/tally/locales/zh-TW.json +12 -0
  401. package/src/trigger/providers/telegram/locales/fr.json +17 -0
  402. package/src/trigger/providers/telegram/locales/ja.json +17 -0
  403. package/src/trigger/providers/telegram/locales/ko.json +17 -0
  404. package/src/trigger/providers/telegram/locales/ru.json +17 -0
  405. package/src/trigger/providers/telegram/locales/zh-CN.json +17 -0
  406. package/src/trigger/providers/telegram/locales/zh-TW.json +17 -0
  407. package/src/trigger/providers/typeform/locales/fr.json +12 -0
  408. package/src/trigger/providers/typeform/locales/ja.json +12 -0
  409. package/src/trigger/providers/typeform/locales/ko.json +12 -0
  410. package/src/trigger/providers/typeform/locales/ru.json +12 -0
  411. package/src/trigger/providers/typeform/locales/zh-CN.json +12 -0
  412. package/src/trigger/providers/typeform/locales/zh-TW.json +12 -0
  413. package/src/trigger/providers/vercel/locales/fr.json +18 -0
  414. package/src/trigger/providers/vercel/locales/ja.json +18 -0
  415. package/src/trigger/providers/vercel/locales/ko.json +18 -0
  416. package/src/trigger/providers/vercel/locales/ru.json +18 -0
  417. package/src/trigger/providers/vercel/locales/zh-CN.json +18 -0
  418. package/src/trigger/providers/vercel/locales/zh-TW.json +18 -0
  419. package/src/trigger/providers/woocommerce/locales/fr.json +19 -0
  420. package/src/trigger/providers/woocommerce/locales/ja.json +19 -0
  421. package/src/trigger/providers/woocommerce/locales/ko.json +19 -0
  422. package/src/trigger/providers/woocommerce/locales/ru.json +19 -0
  423. package/src/trigger/providers/woocommerce/locales/zh-CN.json +19 -0
  424. package/src/trigger/providers/woocommerce/locales/zh-TW.json +19 -0
  425. package/src/trigger/providers/zendesk/locales/fr.json +15 -0
  426. package/src/trigger/providers/zendesk/locales/ja.json +15 -0
  427. package/src/trigger/providers/zendesk/locales/ko.json +15 -0
  428. package/src/trigger/providers/zendesk/locales/ru.json +15 -0
  429. package/src/trigger/providers/zendesk/locales/zh-CN.json +15 -0
  430. package/src/trigger/providers/zendesk/locales/zh-TW.json +15 -0
  431. package/src/trigger/providers/zoom/locales/fr.json +17 -0
  432. package/src/trigger/providers/zoom/locales/ja.json +17 -0
  433. package/src/trigger/providers/zoom/locales/ko.json +17 -0
  434. package/src/trigger/providers/zoom/locales/ru.json +17 -0
  435. package/src/trigger/providers/zoom/locales/zh-CN.json +17 -0
  436. package/src/trigger/providers/zoom/locales/zh-TW.json +17 -0
  437. package/src/types/index.ts +112 -0
  438. package/src/workflow/common/workflow.ts +273 -0
  439. package/dist/browser/lib-DrKav3HG.js +0 -11403
  440. /package/dist/{browser → common}/flow-authoring-edge.d.ts +0 -0
  441. /package/dist/{browser → common}/flow-authoring-module.d.ts +0 -0
  442. /package/dist/{browser → common}/flow-authoring.d.ts +0 -0
  443. /package/dist/{browser → common}/flow-input-value.d.ts +0 -0
  444. /package/dist/{browser → common}/webhook-method.d.ts +0 -0
@@ -0,0 +1,762 @@
1
+ import type { DecisionQuestion } from '../../decision/common/decision.ts'
2
+ import type {
3
+ ChangeOperation,
4
+ CodeModule,
5
+ TaskCapability,
6
+ Graph,
7
+ Group,
8
+ GraphNode,
9
+ InputMapping,
10
+ InputValues,
11
+ InputPort,
12
+ JsonValue,
13
+ Port,
14
+ PortDefinition,
15
+ RetryConfiguration,
16
+ RevisionContent,
17
+ TaskDefinition,
18
+ TriggerKeySnapshot,
19
+ TriggerNode,
20
+ TriggerSchedule,
21
+ WebhookOptions,
22
+ } from './change.ts'
23
+
24
+ import { dequal } from 'dequal/lite'
25
+ import { decisionTask } from '../../decision/common/decision.ts'
26
+ import { isTriggerNode, applyFlowChanges, nextNodeName, normalizeNodeName } from './change.ts'
27
+ import { codeSharedPermissionsEnabled } from './codePermissions.ts'
28
+ import { nodeInputMappings } from './condition.ts'
29
+ import { fixedInputValue, inputValues } from './inputValue.ts'
30
+ import { remapInputMappings, renamedPort, renameOutputMapping } from './portChanges.ts'
31
+
32
+ const codeTaskTemplate = `export default async function (inputs, context) {
33
+ return { result: inputs.value }
34
+ }
35
+ `
36
+ export const defaultCodeTaskPorts: Pick<Extract<TaskDefinition, { readonly moduleId: string }>, 'inputs' | 'outputs' | 'capabilities'> = {
37
+ inputs: [{ handle: 'value', jsonSchema: { type: 'string' }, nullable: true, value: 'foo' }],
38
+ outputs: [{ handle: 'result', jsonSchema: {}, nullable: true }],
39
+ }
40
+
41
+ export interface Settings {
42
+ readonly name?: string
43
+ readonly maxExecutions?: number
44
+ readonly timeoutMs?: number
45
+ readonly onError?: 'stop' | 'error'
46
+ readonly retry?: RetryConfiguration
47
+ }
48
+
49
+ export interface LlmTaskOptions {
50
+ readonly inputs?: Readonly<Partial<Record<LlmInputHandle, JsonValue>>>
51
+ readonly output?: PortDefinition
52
+ }
53
+
54
+ export type LlmInputHandle = 'input' | 'messages' | 'model' | 'template'
55
+
56
+ export function defaultNodeName(_content: RevisionContent, node: GraphNode): string {
57
+ switch (node.kind) {
58
+ case 'webhook-response':
59
+ return 'Webhook Response'
60
+ case 'outputs':
61
+ return 'Workflow Outputs'
62
+ case 'condition':
63
+ return 'Condition'
64
+ case 'value':
65
+ return 'Fixed Values'
66
+ case 'approval':
67
+ return 'Approval'
68
+ case 'wait':
69
+ return 'Wait'
70
+ case 'task':
71
+ return normalizeNodeName(node.task.name) || 'Task'
72
+ case 'error':
73
+ return 'Flow Error'
74
+ case 'manual':
75
+ return 'Manual Trigger'
76
+ case 'start':
77
+ return 'Start'
78
+ case 'webhook':
79
+ return 'Webhook'
80
+ case 'cron':
81
+ return 'Scheduled Trigger'
82
+ case 'integration':
83
+ case 'poll':
84
+ return normalizeNodeName(node.definition.displayName) || 'Trigger'
85
+ }
86
+ }
87
+
88
+ const legacyManualNames = new Set([
89
+ 'Manual trigger',
90
+ 'Manual Trigger',
91
+ '手动触发',
92
+ '手動觸發',
93
+ '手動トリガー',
94
+ 'Déclencheur manuel',
95
+ '수동 트리거',
96
+ 'Ручной триггер',
97
+ ])
98
+
99
+ function graphNameRepairs(content: RevisionContent, targetGraph: Graph, startName: string | undefined): readonly ChangeOperation[] {
100
+ const names = new Set<string>()
101
+ const changed: { readonly nodeId: string; readonly node: GraphNode; readonly name: string }[] = []
102
+ for (const [nodeId, node] of Object.entries(targetGraph.nodes)) {
103
+ const previousName = normalizeNodeName(node.name ?? '')
104
+ const requested =
105
+ node.kind == 'start' && legacyManualNames.has(previousName)
106
+ ? nextNodeName(
107
+ startName ?? defaultNodeName(content, node),
108
+ Object.entries(targetGraph.nodes)
109
+ .filter(([id]) => id != nodeId)
110
+ .map(([, other]) => other.name ?? ''),
111
+ )
112
+ : previousName || defaultNodeName(content, node)
113
+ const name = nextNodeName(requested, names)
114
+ names.add(name)
115
+ if (node.name != name) changed.push({ name, node, nodeId })
116
+ }
117
+ return changed.toReversed().map(({ name, node, nodeId }) => ({ before: node.name, field: 'name', kind: 'graph.node.field.set', nodeId, value: name }))
118
+ }
119
+
120
+ export function repairNodeNames(content: RevisionContent, defaults: { readonly start?: string } = {}): readonly ChangeOperation[] {
121
+ return graphNameRepairs(content, content.document.graph, defaults.start)
122
+ }
123
+
124
+ interface TriggerSettingsBase {
125
+ readonly description?: string
126
+ readonly name: string
127
+ }
128
+
129
+ export type TriggerSettings =
130
+ | (TriggerSettingsBase & { readonly kind: 'manual' })
131
+ | (TriggerSettingsBase & { readonly kind: 'start' })
132
+ | (TriggerSettingsBase & { readonly kind: 'error' })
133
+ | (TriggerSettingsBase & {
134
+ readonly bodyFields: Extract<TriggerNode, { readonly kind: 'webhook' }>['bodyFields']
135
+ readonly kind: 'webhook'
136
+ readonly method: Extract<TriggerNode, { readonly kind: 'webhook' }>['method']
137
+ readonly options: WebhookOptions
138
+ })
139
+ | (TriggerSettingsBase & { readonly kind: 'cron'; readonly schedule: readonly TriggerSchedule[] })
140
+ | (TriggerSettingsBase & {
141
+ readonly config: InputValues
142
+ readonly kind: 'poll'
143
+ readonly schedule: readonly TriggerSchedule[]
144
+ })
145
+ | (TriggerSettingsBase & { readonly config: InputValues; readonly kind: 'integration' })
146
+
147
+ export function createCodeTask(
148
+ identity: { readonly moduleId: string; readonly nodeId: string },
149
+ name: string,
150
+ module: Pick<CodeModule, 'imports' | 'source'> | undefined = undefined,
151
+ ports: Pick<Extract<TaskDefinition, { readonly moduleId: string }>, 'inputs' | 'outputs' | 'capabilities'> = defaultCodeTaskPorts,
152
+ ): readonly ChangeOperation[] {
153
+ const codeModule = module ?? {
154
+ imports: [],
155
+ source: codeTaskTemplate,
156
+ }
157
+ return [
158
+ {
159
+ kind: 'module.create',
160
+ module: { ...codeModule, name },
161
+ moduleId: identity.moduleId,
162
+ },
163
+ {
164
+ kind: 'graph.node.create',
165
+ node: {
166
+ inputs: defaultInputs(ports.inputs),
167
+ kind: 'task',
168
+ name,
169
+ task: {
170
+ capabilities: ports.capabilities ?? [
171
+ codeSharedPermissionsEnabled ? { kind: 'connector', mode: 'shared' } : { kind: 'connector', mode: 'independent', actions: [] },
172
+ ],
173
+ inputs: ports.inputs,
174
+ moduleId: identity.moduleId,
175
+ name,
176
+ outputs: ports.outputs,
177
+ },
178
+ },
179
+ nodeId: identity.nodeId,
180
+ },
181
+ ]
182
+ }
183
+
184
+ export function createManagedTask(
185
+ identity: { readonly nodeId: string },
186
+ task: Extract<TaskDefinition, { readonly executor: unknown }>,
187
+ ): readonly ChangeOperation[] {
188
+ return [
189
+ {
190
+ kind: 'graph.node.create',
191
+ node: {
192
+ inputs: defaultInputs(task.inputs),
193
+ kind: 'task',
194
+ name: task.name,
195
+ task,
196
+ },
197
+ nodeId: identity.nodeId,
198
+ },
199
+ ]
200
+ }
201
+
202
+ export function createAgentTask(
203
+ identity: { readonly nodeId: string },
204
+ name: string,
205
+ defaults: { readonly prompt?: string; readonly outputDescription?: string; readonly inputs?: TaskDefinition['inputs'] } = {},
206
+ ): readonly ChangeOperation[] {
207
+ return createManagedTask(identity, {
208
+ name,
209
+ inputs: defaults.inputs ?? [{ handle: 'input', jsonSchema: { type: 'string' }, nullable: false, value: '' }],
210
+ outputs: [
211
+ {
212
+ handle: 'output',
213
+ jsonSchema: { type: 'string' },
214
+ nullable: false,
215
+ description: defaults.outputDescription ?? 'The final result produced by the Agent.',
216
+ },
217
+ ],
218
+ executor: {
219
+ kind: 'agent',
220
+ model: 'deepseek-v4-flash',
221
+ prompt: defaults.prompt ?? 'Summarize the following content, highlighting key points and next steps.\n\n{{input}}',
222
+ maxRounds: 10,
223
+ tools: [],
224
+ },
225
+ })
226
+ }
227
+
228
+ export function createLlmTask(
229
+ identity: { readonly nodeId: string },
230
+ name: string,
231
+ mode: 'chat' | 'json',
232
+ outputDescription: string,
233
+ options: LlmTaskOptions = {},
234
+ ): readonly ChangeOperation[] {
235
+ const values = options.inputs ?? {}
236
+ return createManagedTask(identity, {
237
+ executor: { kind: 'llm', mode },
238
+ inputs: [
239
+ { handle: 'messages', jsonSchema: { items: { type: 'object' }, type: 'array' }, nullable: true, value: llmInputValue(values, 'messages', null) },
240
+ { handle: 'input', jsonSchema: { type: 'string' }, nullable: false, value: llmInputValue(values, 'input', 'Alex') },
241
+ {
242
+ handle: 'template',
243
+ jsonSchema: { items: { type: 'object' }, minItems: 1, type: 'array' },
244
+ nullable: false,
245
+ value: llmInputValue(values, 'template', [{ content: "Hello, I'm {{input}}", role: 'user' }]),
246
+ },
247
+ { handle: 'model', jsonSchema: { type: 'object' }, nullable: false, value: llmInputValue(values, 'model', { model: 'deepseek-v4-flash' }) },
248
+ ],
249
+ name,
250
+ outputs: [
251
+ {
252
+ ...options.output,
253
+ description: options.output?.description ?? outputDescription,
254
+ handle: 'output',
255
+ jsonSchema: options.output?.jsonSchema ?? (mode == 'chat' ? { type: 'string' } : {}),
256
+ nullable: options.output?.nullable ?? false,
257
+ },
258
+ ],
259
+ })
260
+ }
261
+
262
+ export function createCondition(nodeId: string, name: string): readonly ChangeOperation[] {
263
+ return [
264
+ {
265
+ kind: 'graph.node.create',
266
+ node: {
267
+ cases: [{ groups: [{ expressions: [{ left: { kind: 'value' }, operator: '==', right: { kind: 'value' } }] }], output: 'case' }],
268
+ matchMode: 'first',
269
+ inputs: {},
270
+ kind: 'condition',
271
+ name,
272
+ },
273
+ nodeId,
274
+ },
275
+ ]
276
+ }
277
+
278
+ export function createValue(
279
+ nodeId: string,
280
+ name: string,
281
+ values: readonly InputPort[] = [{ handle: 'value', jsonSchema: {}, nullable: true, value: null }],
282
+ ): readonly ChangeOperation[] {
283
+ return [
284
+ {
285
+ kind: 'graph.node.create',
286
+ node: { inputs: {}, kind: 'value', name, values },
287
+ nodeId,
288
+ },
289
+ ]
290
+ }
291
+
292
+ export function createWait(nodeId: string, name: string): readonly ChangeOperation[] {
293
+ return [
294
+ {
295
+ kind: 'graph.node.create',
296
+ node: {
297
+ inputDefinitions: [],
298
+ inputs: {},
299
+ kind: 'wait',
300
+ name,
301
+ prompt: name,
302
+ },
303
+ nodeId,
304
+ },
305
+ ]
306
+ }
307
+
308
+ export function createApproval(nodeId: string, name: string): readonly ChangeOperation[] {
309
+ return [
310
+ {
311
+ kind: 'graph.node.create',
312
+ node: {
313
+ inputDefinitions: [],
314
+ inputs: {},
315
+ kind: 'approval',
316
+ name,
317
+ prompt: name,
318
+ },
319
+ nodeId,
320
+ },
321
+ ]
322
+ }
323
+
324
+ export function createBuiltinTrigger(
325
+ nodeId: string,
326
+ node: Extract<TriggerNode, { readonly kind: 'error' | 'cron' | 'manual' | 'start' | 'webhook' }>,
327
+ ): readonly ChangeOperation[] {
328
+ return [{ kind: 'graph.node.create', node, nodeId }]
329
+ }
330
+
331
+ export function createProviderTrigger(
332
+ nodeId: string,
333
+ definition: TriggerKeySnapshot,
334
+ options: {
335
+ readonly config: Readonly<Record<string, JsonValue>>
336
+ readonly connectionId?: string
337
+ readonly name?: string
338
+ readonly schedule?: readonly TriggerSchedule[]
339
+ },
340
+ ): readonly ChangeOperation[] {
341
+ const name = options.name ?? definition.displayName
342
+ const node: TriggerNode =
343
+ definition.type == 'poll'
344
+ ? {
345
+ ...(options.connectionId == null ? {} : { connectionId: options.connectionId }),
346
+ config: inputValues(options.config),
347
+ definition,
348
+ kind: 'poll',
349
+ name,
350
+ pollTimes: options.schedule ?? [{ type: 'every', unit: 'minute', value: 5 }],
351
+ }
352
+ : {
353
+ ...(options.connectionId == null ? {} : { connectionId: options.connectionId }),
354
+ config: inputValues(options.config),
355
+ definition,
356
+ kind: 'integration',
357
+ name,
358
+ }
359
+ return [{ kind: 'graph.node.create', node, nodeId }]
360
+ }
361
+
362
+ export function deleteNodes(content: RevisionContent, nodeIds: readonly string[]): readonly ChangeOperation[] {
363
+ const nodes = content.document.graph?.nodes
364
+ if (nodes == null) return []
365
+ const operations: ChangeOperation[] = nodeIds.flatMap((nodeId) => {
366
+ const node = nodes[nodeId]
367
+ if (node == null) return []
368
+ return [
369
+ { kind: 'graph.node.delete' as const, nodeId },
370
+ ...(node.kind == 'task' && 'moduleId' in node.task ? [{ kind: 'module.delete' as const, moduleId: node.task.moduleId }] : []),
371
+ ]
372
+ })
373
+ return cleanVariableBindings(content, operations)
374
+ }
375
+
376
+ export function updateSettings(content: RevisionContent, nodeId: string, settings: Settings): readonly ChangeOperation[] | undefined {
377
+ const node = content.document.graph?.nodes[nodeId]
378
+ if (node == null || isTriggerNode(node)) return
379
+ const operations: ChangeOperation[] = []
380
+
381
+ if (node.name != settings.name) operations.push({ before: node.name, field: 'name', kind: 'graph.node.field.set', nodeId, value: settings.name })
382
+ if (node.maxExecutions != settings.maxExecutions) {
383
+ operations.push({ before: node.maxExecutions, field: 'maxExecutions', kind: 'graph.node.field.set', nodeId, value: settings.maxExecutions })
384
+ }
385
+ if (node.timeoutMs != settings.timeoutMs) {
386
+ operations.push({ before: node.timeoutMs, field: 'timeoutMs', kind: 'graph.node.field.set', nodeId, value: settings.timeoutMs })
387
+ }
388
+ if (Object.hasOwn(settings, 'onError') && node.onError != settings.onError)
389
+ operations.push({ before: node.onError, field: 'onError', kind: 'graph.node.field.set', nodeId, value: settings.onError })
390
+ if (Object.hasOwn(settings, 'retry') && !dequal(node.retry, settings.retry)) {
391
+ operations.push({ before: node.retry, field: 'retry', kind: 'graph.node.field.set', nodeId, value: settings.retry })
392
+ }
393
+ return operations
394
+ }
395
+
396
+ export function setInputValue(content: RevisionContent, nodeId: string, handle: string, value: JsonValue | undefined): readonly ChangeOperation[] | undefined {
397
+ return setInputValues(content, nodeId, { [handle]: value })
398
+ }
399
+
400
+ export function setInputValues(
401
+ content: RevisionContent,
402
+ nodeId: string,
403
+ values: Readonly<Record<string, JsonValue | undefined>>,
404
+ ): readonly ChangeOperation[] | undefined {
405
+ const node = content.document.graph?.nodes[nodeId]
406
+ if (node == null || isTriggerNode(node)) return
407
+ const operations: ChangeOperation[] = []
408
+ for (const [handle, value] of Object.entries(values)) {
409
+ const before = nodeInputMappings(node)[handle]
410
+ const next = fixedInputValue(value)
411
+ if (dequal(before, next)) continue
412
+ operations.push({ before, handle, kind: 'graph.node.input.set', nodeId, value: next })
413
+ }
414
+ return cleanVariableBindings(content, operations)
415
+ }
416
+
417
+ /** Restore inheritance for this form in one undoable change. */
418
+ export function resetInputValues(content: RevisionContent, nodeId: string, handles: readonly string[]): readonly ChangeOperation[] {
419
+ const node = content.document.graph?.nodes[nodeId]
420
+ if (node == null || isTriggerNode(node)) return []
421
+ const mappings = nodeInputMappings(node)
422
+ return cleanVariableBindings(
423
+ content,
424
+ [...new Set(handles)].flatMap((handle): ChangeOperation[] =>
425
+ mappings[handle] == null ? [] : [{ kind: 'graph.node.input.set', nodeId, handle, before: mappings[handle], value: undefined }],
426
+ ),
427
+ )
428
+ }
429
+
430
+ export function setInputSources(
431
+ content: RevisionContent,
432
+ nodeId: string,
433
+ handle: string,
434
+ sources: Extract<InputMapping, { readonly kind: 'sources' }>['sources'],
435
+ ): readonly ChangeOperation[] {
436
+ const node = content.document.graph?.nodes[nodeId]
437
+ if (node == null || isTriggerNode(node)) return []
438
+ return cleanVariableBindings(content, [
439
+ { kind: 'graph.node.input.set', nodeId, handle, before: nodeInputMappings(node)[handle], value: { kind: 'sources', sources } },
440
+ ])
441
+ }
442
+
443
+ export function setInputVariable(
444
+ content: RevisionContent,
445
+ nodeId: string,
446
+ handle: string,
447
+ name: string,
448
+ bindingId: string,
449
+ ): readonly ChangeOperation[] | undefined {
450
+ const node = content.document.graph?.nodes[nodeId]
451
+ if (node == null || isTriggerNode(node)) return
452
+ const mapping = nodeInputMappings(node)[handle]
453
+ const currentId =
454
+ mapping?.kind == 'sources' && mapping.sources.length == 1 && mapping.sources[0]?.kind == 'binding' ? mapping.sources[0].bindingId : undefined
455
+ const current = currentId == null ? undefined : content.document.bindings[currentId]
456
+ const references = bindingReferences(content.document)
457
+ if (currentId != null && current?.kind == 'variable' && (references.get(currentId) ?? 0) == 1) {
458
+ if (current.target == name) return []
459
+ return [{ before: current.target, bindingId: currentId, kind: 'binding.target.set', value: name }]
460
+ }
461
+ const next: InputMapping = { kind: 'sources', sources: [{ bindingId, kind: 'binding' }] }
462
+ return [
463
+ { binding: { kind: 'variable', target: name }, bindingId, kind: 'binding.create' },
464
+ ...cleanVariableBindings(content, [{ before: mapping, handle, kind: 'graph.node.input.set', nodeId, value: next }]),
465
+ ]
466
+ }
467
+
468
+ export function cleanVariableBindings(content: RevisionContent, operations: readonly ChangeOperation[]): readonly ChangeOperation[] {
469
+ const before = bindingReferences(content.document)
470
+ const changed = applyFlowChanges(content, operations)
471
+ const after = bindingReferences(changed.document)
472
+ return [
473
+ ...operations,
474
+ ...[...before.keys()].flatMap((bindingId) =>
475
+ after.has(bindingId) || changed.document.bindings[bindingId]?.kind != 'variable' ? [] : [{ bindingId, kind: 'binding.delete' as const }],
476
+ ),
477
+ ]
478
+ }
479
+
480
+ function bindingReferences(document: RevisionContent['document']): Map<string, number> {
481
+ const references = new Map<string, number>()
482
+ const add = (bindingId: string): void => {
483
+ references.set(bindingId, (references.get(bindingId) ?? 0) + 1)
484
+ }
485
+ for (const node of Object.values(document.graph.nodes)) {
486
+ if (isTriggerNode(node)) continue
487
+ const inputs = Object.values(nodeInputMappings(node))
488
+ for (const mapping of inputs) {
489
+ if (mapping.kind != 'sources') continue
490
+ for (const source of mapping.sources) if (source.kind == 'binding') add(source.bindingId)
491
+ }
492
+ }
493
+ return references
494
+ }
495
+
496
+ export function setConnectorConnection(content: RevisionContent, nodeId: string, connectionId: string | undefined): readonly ChangeOperation[] | undefined {
497
+ const node = content.document.graph.nodes[nodeId]
498
+ if (node?.kind != 'task' || !('executor' in node.task) || node.task.executor.kind != 'connector') return
499
+ const task = node.task
500
+ if (task.executor.kind != 'connector') return
501
+ if (task.executor.connectionId == connectionId) return []
502
+ const { connectionId: _, ...executor } = task.executor
503
+ return [
504
+ {
505
+ before: task,
506
+ kind: 'graph.node.task.set',
507
+ nodeId,
508
+ value: { ...task, executor: { ...executor, ...(connectionId == null ? {} : { connectionId }) } },
509
+ },
510
+ ]
511
+ }
512
+
513
+ /** Update one service’s unresolved or explicitly deferred references as one undoable edit. */
514
+ export function setServiceConnections(
515
+ content: RevisionContent,
516
+ providerId: string,
517
+ connectionId: string | undefined,
518
+ previousConnectionId?: '',
519
+ ): readonly ChangeOperation[] {
520
+ const operations: ChangeOperation[] = []
521
+ const assign = <T extends { readonly action: string; readonly connectionId?: string }>(value: T): T => {
522
+ if (value.connectionId !== previousConnectionId || value.action.split('.')[0] != providerId) return value
523
+ const { connectionId: _, ...rest } = value
524
+ return { ...rest, ...(connectionId == null ? {} : { connectionId }) } as T
525
+ }
526
+ for (const [nodeId, node] of Object.entries(content.document.graph.nodes)) {
527
+ if (
528
+ (node.kind == 'poll' || node.kind == 'integration') &&
529
+ node.definition.provider == providerId &&
530
+ previousConnectionId == null &&
531
+ node.connectionId == null &&
532
+ connectionId !== ''
533
+ ) {
534
+ operations.push(...(setTriggerConnection(content, nodeId, connectionId) ?? []))
535
+ }
536
+ if (node.kind != 'task') continue
537
+ const task = node.task
538
+ if ('moduleId' in task) {
539
+ const capabilities = task.capabilities?.map((capability) =>
540
+ 'mode' in capability && capability.mode == 'independent' ? { ...capability, actions: capability.actions.map(assign) } : capability,
541
+ )
542
+ if (capabilities != null) operations.push(...(setCodeActions(content, nodeId, capabilities) ?? []))
543
+ } else if (task.executor.kind == 'connector') {
544
+ if (assign(task.executor) !== task.executor) operations.push(...(setConnectorConnection(content, nodeId, connectionId) ?? []))
545
+ } else if (task.executor.kind == 'agent') {
546
+ const executor = {
547
+ ...task.executor,
548
+ tools: task.executor.tools.map((tool) => (tool.kind == 'workflow' ? tool : assign(tool))),
549
+ ...(task.executor.notification == null ? {} : { notification: assign(task.executor.notification) }),
550
+ }
551
+ if (!dequal(executor, task.executor)) operations.push({ kind: 'graph.node.task.set', nodeId, before: task, value: { ...task, executor } })
552
+ }
553
+ }
554
+ return operations
555
+ }
556
+
557
+ /** Edit the workflow input contract and preserve references on a single-field rename. */
558
+ export function updateStartInputDefs(content: RevisionContent, nodeId: string, value: readonly Port[]): readonly ChangeOperation[] {
559
+ const node = content.document.graph.nodes[nodeId]
560
+ if (node?.kind != 'start') throw new TypeError('Expected a Start node.')
561
+ const previous = node.inputDefs
562
+ if (dequal(previous, value)) return []
563
+ const operations: ChangeOperation[] = [{ kind: 'graph.node.replace', nodeId, before: node, node: { ...node, inputDefs: value } }]
564
+ const rename = renamedPort(previous, value)
565
+ if (rename != null) {
566
+ const instances = new Set([nodeId])
567
+ for (const [id, downstream] of Object.entries(content.document.graph.nodes)) {
568
+ if (isTriggerNode(downstream)) continue
569
+ for (const [handle, before] of Object.entries(nodeInputMappings(downstream))) {
570
+ const mapping = renameOutputMapping(before, instances, rename)
571
+ if (before !== mapping) operations.push({ before, kind: 'graph.node.input.set', nodeId: id, handle, value: mapping })
572
+ }
573
+ }
574
+ }
575
+ return operations
576
+ }
577
+
578
+ export function updateTrigger(content: RevisionContent, nodeId: string, settings: TriggerSettings): readonly ChangeOperation[] | undefined {
579
+ const trigger = content.document.graph.nodes[nodeId]
580
+ if (trigger == null) return
581
+ const operations: ChangeOperation[] = []
582
+ if (trigger.name != settings.name) {
583
+ operations.push({ before: trigger.name, field: 'name', kind: 'graph.node.field.set', nodeId, value: settings.name })
584
+ }
585
+ if (trigger.description != settings.description) {
586
+ operations.push({ before: trigger.description, field: 'description', kind: 'graph.node.field.set', nodeId, value: settings.description })
587
+ }
588
+ switch (settings.kind) {
589
+ case 'start':
590
+ case 'error':
591
+ case 'manual':
592
+ if (trigger.kind != settings.kind) return
593
+ break
594
+ case 'webhook': {
595
+ if (trigger.kind != 'webhook') return
596
+ const value = {
597
+ bodyFields: settings.bodyFields,
598
+ method: settings.method,
599
+ options: Object.keys(settings.options).length == 0 ? undefined : settings.options,
600
+ }
601
+ const before = { bodyFields: trigger.bodyFields, method: trigger.method, options: trigger.options }
602
+ if (!dequal(before, value)) operations.push({ before, kind: 'graph.node.webhook.set', nodeId, value })
603
+ break
604
+ }
605
+ case 'cron':
606
+ if (trigger.kind != 'cron') return
607
+ if (!dequal(trigger.cronTimes, settings.schedule)) {
608
+ operations.push({ before: trigger.cronTimes, kind: 'graph.trigger.schedule.set', nodeId, value: settings.schedule })
609
+ }
610
+ break
611
+ case 'poll':
612
+ if (trigger.kind != 'poll') return
613
+ for (const name of new Set([...Object.keys(trigger.config), ...Object.keys(settings.config)])) {
614
+ if (!dequal(trigger.config[name], settings.config[name])) {
615
+ operations.push({ before: trigger.config[name], kind: 'graph.trigger.config.set', name, nodeId, value: settings.config[name] })
616
+ }
617
+ }
618
+ if (!dequal(trigger.pollTimes, settings.schedule)) {
619
+ operations.push({ before: trigger.pollTimes, kind: 'graph.trigger.schedule.set', nodeId, value: settings.schedule })
620
+ }
621
+ break
622
+ case 'integration':
623
+ if (trigger.kind != 'integration') return
624
+ for (const name of new Set([...Object.keys(trigger.config), ...Object.keys(settings.config)])) {
625
+ if (!dequal(trigger.config[name], settings.config[name])) {
626
+ operations.push({ before: trigger.config[name], kind: 'graph.trigger.config.set', name, nodeId, value: settings.config[name] })
627
+ }
628
+ }
629
+ break
630
+ }
631
+ return operations
632
+ }
633
+
634
+ export function updateTriggerConfig(
635
+ content: RevisionContent,
636
+ nodeId: string,
637
+ name: string,
638
+ value: JsonValue | undefined,
639
+ ): readonly ChangeOperation[] | undefined {
640
+ const trigger = content.document.graph.nodes[nodeId]
641
+ if (trigger == null || (trigger.kind != 'integration' && trigger.kind != 'poll')) return
642
+ const next = fixedInputValue(value)
643
+ if (dequal(trigger.config[name], next)) return []
644
+ return [{ before: trigger.config[name], kind: 'graph.trigger.config.set', name, nodeId, value: next }]
645
+ }
646
+
647
+ export function updateTriggerSchedule(content: RevisionContent, nodeId: string, schedule: readonly TriggerSchedule[]): readonly ChangeOperation[] | undefined {
648
+ const trigger = content.document.graph.nodes[nodeId]
649
+ if (trigger == null) return
650
+ switch (trigger.kind) {
651
+ case 'cron':
652
+ return dequal(trigger.cronTimes, schedule) ? [] : [{ before: trigger.cronTimes, kind: 'graph.trigger.schedule.set', nodeId, value: schedule }]
653
+ case 'poll':
654
+ return dequal(trigger.pollTimes, schedule) ? [] : [{ before: trigger.pollTimes, kind: 'graph.trigger.schedule.set', nodeId, value: schedule }]
655
+ case 'integration':
656
+ case 'manual':
657
+ case 'webhook':
658
+ return
659
+ default:
660
+ return
661
+ }
662
+ }
663
+
664
+ export function setTriggerConnection(content: RevisionContent, nodeId: string, connectionId: string | undefined): readonly ChangeOperation[] | undefined {
665
+ const trigger = content.document.graph.nodes[nodeId]
666
+ if (trigger == null || (trigger.kind != 'poll' && trigger.kind != 'integration')) return
667
+ if (trigger.connectionId == connectionId) return []
668
+ return [{ before: trigger.connectionId, kind: 'graph.node.field.set', field: 'connectionId', nodeId, value: connectionId }]
669
+ }
670
+
671
+ function defaultInputs(ports: TaskDefinition['inputs']): Readonly<Record<string, InputMapping>> {
672
+ return Object.fromEntries(
673
+ ports.flatMap((port) =>
674
+ 'handle' in port && Object.hasOwn(port, 'value') ? [[port.handle, { kind: 'value' as const, value: port.value as JsonValue }]] : [],
675
+ ),
676
+ )
677
+ }
678
+
679
+ function llmInputValue(values: LlmTaskOptions['inputs'], handle: LlmInputHandle, fallback: JsonValue): JsonValue {
680
+ return values != null && Object.hasOwn(values, handle) ? values[handle]! : fallback
681
+ }
682
+
683
+ export function setCodeActions(content: RevisionContent, nodeId: string, capabilities: readonly TaskCapability[]): readonly ChangeOperation[] | undefined {
684
+ const selected = content.document.graph
685
+ const node = selected?.nodes[nodeId]
686
+ if (node?.kind != 'task' || !('moduleId' in node.task) || dequal(node.task.capabilities ?? [], capabilities)) return
687
+ return [{ kind: 'graph.node.task.capabilities.set', nodeId, before: node.task.capabilities, value: capabilities }]
688
+ }
689
+
690
+ export function createDecisionTask(
691
+ identity: { readonly nodeId: string },
692
+ name = 'AI Decision',
693
+ questions?: readonly DecisionQuestion[],
694
+ ): readonly ChangeOperation[] {
695
+ return createManagedTask(identity, decisionTask(questions, name))
696
+ }
697
+
698
+ /** Edit an Outputs node's definitions and mappings as one undoable change. */
699
+ export function updateOutputsDefs(
700
+ content: RevisionContent,
701
+ nodeId: string,
702
+ value: readonly Port[],
703
+ outputMappings?: Readonly<Record<string, InputMapping>>,
704
+ ): readonly ChangeOperation[] {
705
+ const node = content.document.graph.nodes[nodeId]
706
+ if (node?.kind != 'outputs') throw new TypeError('Expected an Outputs node.')
707
+ const rename = renamedPort(node.outputDefs, value)
708
+ const mappings = outputMappings ?? remapInputMappings(node.outputMappings, value, rename)
709
+ const next = { ...node, outputDefs: value, outputMappings: mappings }
710
+ if (dequal(node, next)) return []
711
+ const changes: ChangeOperation[] = [{ kind: 'graph.node.replace', nodeId, before: node, node: next }]
712
+ if (rename != null) {
713
+ for (const [id, trigger] of Object.entries(content.document.graph.nodes)) {
714
+ if (trigger.kind != 'webhook' || trigger.options == null) continue
715
+ const bodyRenamed = trigger.options.responseBody?.kind === 'workflow-outputs' && trigger.options.responseBody.output === rename[0]
716
+ const statusRenamed = trigger.options.responseStatusCodeOutput === rename[0]
717
+ const headersRenamed = trigger.options.responseHeadersSource?.output === rename[0]
718
+ const headerOutputs = trigger.options.responseHeaderOutputs
719
+ const headerRenamed = Object.values(headerOutputs ?? {}).includes(rename[0])
720
+ if (!bodyRenamed && !statusRenamed && !headersRenamed && !headerRenamed) continue
721
+ changes.push({
722
+ kind: 'graph.node.replace',
723
+ nodeId: id,
724
+ before: trigger,
725
+ node: {
726
+ ...trigger,
727
+ options: {
728
+ ...trigger.options,
729
+ ...(bodyRenamed ? { responseBody: { ...trigger.options.responseBody!, kind: 'workflow-outputs' as const, output: rename[1] } } : {}),
730
+ ...(statusRenamed ? { responseStatusCodeOutput: rename[1] } : {}),
731
+ ...(headersRenamed ? { responseHeadersSource: { ...trigger.options.responseHeadersSource!, output: rename[1] } } : {}),
732
+ ...(headerRenamed
733
+ ? {
734
+ responseHeaderOutputs: Object.fromEntries(
735
+ Object.entries(headerOutputs!).map(([name, output]) => [name, output === rename[0] ? rename[1] : output]),
736
+ ),
737
+ }
738
+ : {}),
739
+ },
740
+ },
741
+ })
742
+ }
743
+ }
744
+ return cleanVariableBindings(content, changes)
745
+ }
746
+
747
+ export function renameFlowOutputSources(
748
+ content: RevisionContent,
749
+ nodeIds: ReadonlySet<string>,
750
+ previous: readonly (Port | Group)[],
751
+ next: readonly (Port | Group)[],
752
+ ): readonly ChangeOperation[] {
753
+ const rename = renamedPort(previous, next)
754
+ if (rename == null) return []
755
+ return Object.entries(content.document.graph.nodes).flatMap(([nodeId, node]): ChangeOperation[] => {
756
+ if (node.kind != 'outputs') return []
757
+ const outputMappings = Object.fromEntries(
758
+ Object.entries(node.outputMappings).map(([name, mapping]) => [name, renameOutputMapping(mapping, nodeIds, rename)]),
759
+ )
760
+ return dequal(node.outputMappings, outputMappings) ? [] : [{ kind: 'graph.node.replace', nodeId, before: node, node: { ...node, outputMappings } }]
761
+ })
762
+ }