@xdelivered/emberflow 0.2.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 (414) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +153 -0
  3. package/bin/commands.test.ts +185 -0
  4. package/bin/commands.ts +306 -0
  5. package/bin/emberflow.mjs +38 -0
  6. package/bin/init.test.ts +165 -0
  7. package/bin/init.ts +297 -0
  8. package/bin/runtime.mjs +105 -0
  9. package/bin/runtime.test.ts +167 -0
  10. package/bin/skillTargets.test.ts +108 -0
  11. package/bin/skillTargets.ts +36 -0
  12. package/bin/skillTemplates.test.ts +37 -0
  13. package/bin/tsconfig.json +23 -0
  14. package/dist/bin/commands.d.ts +24 -0
  15. package/dist/bin/commands.js +252 -0
  16. package/dist/bin/init.d.ts +17 -0
  17. package/dist/bin/init.js +241 -0
  18. package/dist/bin/runtime.d.mts +39 -0
  19. package/dist/bin/runtime.mjs +96 -0
  20. package/dist/bin/skillTargets.d.ts +13 -0
  21. package/dist/bin/skillTargets.js +22 -0
  22. package/dist/server/agents/claudeAdapter.d.ts +8 -0
  23. package/dist/server/agents/claudeAdapter.js +190 -0
  24. package/dist/server/agents/claudeParse.d.ts +2 -0
  25. package/dist/server/agents/claudeParse.js +162 -0
  26. package/dist/server/agents/codexAdapter.d.ts +13 -0
  27. package/dist/server/agents/codexAdapter.js +174 -0
  28. package/dist/server/agents/codexParse.d.ts +2 -0
  29. package/dist/server/agents/codexParse.js +74 -0
  30. package/dist/server/agents/detect.d.ts +23 -0
  31. package/dist/server/agents/detect.js +35 -0
  32. package/dist/server/agents/gitScope.d.ts +24 -0
  33. package/dist/server/agents/gitScope.js +95 -0
  34. package/dist/server/agents/modelRejectionHint.d.ts +8 -0
  35. package/dist/server/agents/modelRejectionHint.js +12 -0
  36. package/dist/server/agents/prompt.d.ts +79 -0
  37. package/dist/server/agents/prompt.js +364 -0
  38. package/dist/server/agents/runManager.d.ts +90 -0
  39. package/dist/server/agents/runManager.js +259 -0
  40. package/dist/server/agents/types.d.ts +15 -0
  41. package/dist/server/agents/types.js +1 -0
  42. package/dist/server/apiStore.d.ts +60 -0
  43. package/dist/server/apiStore.js +249 -0
  44. package/dist/server/auth/enforce.d.ts +1 -0
  45. package/dist/server/auth/enforce.js +6 -0
  46. package/dist/server/auth/types.d.ts +1 -0
  47. package/dist/server/auth/types.js +1 -0
  48. package/dist/server/auth/verifiers.d.ts +1 -0
  49. package/dist/server/auth/verifiers.js +4 -0
  50. package/dist/server/authAttach.d.ts +19 -0
  51. package/dist/server/authAttach.js +79 -0
  52. package/dist/server/cli.d.ts +7 -0
  53. package/dist/server/cli.js +804 -0
  54. package/dist/server/client.d.ts +130 -0
  55. package/dist/server/client.js +247 -0
  56. package/dist/server/environments.d.ts +103 -0
  57. package/dist/server/environments.js +486 -0
  58. package/dist/server/flowStore.d.ts +37 -0
  59. package/dist/server/flowStore.js +117 -0
  60. package/dist/server/httpOperations.d.ts +32 -0
  61. package/dist/server/httpOperations.js +62 -0
  62. package/dist/server/index.d.ts +1 -0
  63. package/dist/server/index.js +1022 -0
  64. package/dist/server/infrastructure.d.ts +51 -0
  65. package/dist/server/infrastructure.js +116 -0
  66. package/dist/server/login.d.ts +21 -0
  67. package/dist/server/login.js +44 -0
  68. package/dist/server/mcp.d.ts +1 -0
  69. package/dist/server/mcp.js +182 -0
  70. package/dist/server/migrateFlows.d.ts +8 -0
  71. package/dist/server/migrateFlows.js +25 -0
  72. package/dist/server/mockHandler.d.ts +15 -0
  73. package/dist/server/mockHandler.js +35 -0
  74. package/dist/server/nodesPayload.d.ts +14 -0
  75. package/dist/server/nodesPayload.js +14 -0
  76. package/dist/server/normalizeFlow.d.ts +21 -0
  77. package/dist/server/normalizeFlow.js +48 -0
  78. package/dist/server/openBrowser.d.ts +8 -0
  79. package/dist/server/openBrowser.js +16 -0
  80. package/dist/server/operationResult.d.ts +12 -0
  81. package/dist/server/operationResult.js +26 -0
  82. package/dist/server/pathGuard.d.ts +1 -0
  83. package/dist/server/pathGuard.js +16 -0
  84. package/dist/server/pathSafety.d.ts +20 -0
  85. package/dist/server/pathSafety.js +35 -0
  86. package/dist/server/projectConfig.d.ts +47 -0
  87. package/dist/server/projectConfig.js +61 -0
  88. package/dist/server/projectMode.d.ts +26 -0
  89. package/dist/server/projectMode.js +44 -0
  90. package/dist/server/redact.d.ts +6 -0
  91. package/dist/server/redact.js +37 -0
  92. package/dist/server/runRegistry.d.ts +84 -0
  93. package/dist/server/runRegistry.js +200 -0
  94. package/dist/server/runtime/RuntimeAdapter.d.ts +22 -0
  95. package/dist/server/runtime/RuntimeAdapter.js +1 -0
  96. package/dist/server/runtime/expressAdapter.d.ts +19 -0
  97. package/dist/server/runtime/expressAdapter.js +56 -0
  98. package/dist/server/scenarioTest.d.ts +14 -0
  99. package/dist/server/scenarioTest.js +66 -0
  100. package/dist/server/subflowRunner.d.ts +32 -0
  101. package/dist/server/subflowRunner.js +72 -0
  102. package/dist/server/testRunner.d.ts +70 -0
  103. package/dist/server/testRunner.js +151 -0
  104. package/dist/src/config.d.ts +3 -0
  105. package/dist/src/config.js +2 -0
  106. package/dist/src/engine/authVerify.d.ts +33 -0
  107. package/dist/src/engine/authVerify.js +63 -0
  108. package/dist/src/engine/diagnostics.d.ts +62 -0
  109. package/dist/src/engine/diagnostics.js +148 -0
  110. package/dist/src/engine/executor.d.ts +151 -0
  111. package/dist/src/engine/executor.js +684 -0
  112. package/dist/src/engine/httpError.d.ts +7 -0
  113. package/dist/src/engine/httpError.js +14 -0
  114. package/dist/src/engine/index.d.ts +11 -0
  115. package/dist/src/engine/index.js +11 -0
  116. package/dist/src/engine/output.d.ts +11 -0
  117. package/dist/src/engine/output.js +20 -0
  118. package/dist/src/engine/publish.d.ts +30 -0
  119. package/dist/src/engine/publish.js +95 -0
  120. package/dist/src/engine/registry.d.ts +34 -0
  121. package/dist/src/engine/registry.js +67 -0
  122. package/dist/src/engine/scenarios.d.ts +12 -0
  123. package/dist/src/engine/scenarios.js +19 -0
  124. package/dist/src/engine/schemaCheck.d.ts +4 -0
  125. package/dist/src/engine/schemaCheck.js +34 -0
  126. package/dist/src/engine/trace.d.ts +12 -0
  127. package/dist/src/engine/trace.js +12 -0
  128. package/dist/src/engine/types.d.ts +308 -0
  129. package/dist/src/engine/types.js +1 -0
  130. package/dist/src/engine/validation.d.ts +26 -0
  131. package/dist/src/engine/validation.js +318 -0
  132. package/dist/src/flows/anomaly-flows.d.ts +23 -0
  133. package/dist/src/flows/anomaly-flows.js +151 -0
  134. package/dist/src/flows/city-sweep-flow.d.ts +10 -0
  135. package/dist/src/flows/city-sweep-flow.js +127 -0
  136. package/dist/src/flows/login-flow.d.ts +13 -0
  137. package/dist/src/flows/login-flow.js +145 -0
  138. package/dist/src/flows/pradar-flows.d.ts +5 -0
  139. package/dist/src/flows/pradar-flows.js +375 -0
  140. package/dist/src/flows/weather-flow.d.ts +12 -0
  141. package/dist/src/flows/weather-flow.js +150 -0
  142. package/dist/src/lib/pathParams.d.ts +3 -0
  143. package/dist/src/lib/pathParams.js +6 -0
  144. package/dist/src/nodes/anomaly.d.ts +2 -0
  145. package/dist/src/nodes/anomaly.js +556 -0
  146. package/dist/src/nodes/flow-control.d.ts +7 -0
  147. package/dist/src/nodes/flow-control.js +270 -0
  148. package/dist/src/nodes/index.d.ts +3 -0
  149. package/dist/src/nodes/index.js +20 -0
  150. package/dist/src/nodes/login.d.ts +7 -0
  151. package/dist/src/nodes/login.js +158 -0
  152. package/dist/src/nodes/loops.d.ts +11 -0
  153. package/dist/src/nodes/loops.js +60 -0
  154. package/dist/src/nodes/pradar/index.d.ts +7 -0
  155. package/dist/src/nodes/pradar/index.js +9 -0
  156. package/dist/src/nodes/pradar/logic.d.ts +189 -0
  157. package/dist/src/nodes/pradar/logic.js +370 -0
  158. package/dist/src/nodes/pradar/nodes.d.ts +42 -0
  159. package/dist/src/nodes/pradar/nodes.js +801 -0
  160. package/dist/src/nodes/requireAuth.d.ts +20 -0
  161. package/dist/src/nodes/requireAuth.js +48 -0
  162. package/dist/src/nodes/response.d.ts +8 -0
  163. package/dist/src/nodes/response.js +33 -0
  164. package/dist/src/nodes/weather.d.ts +33 -0
  165. package/dist/src/nodes/weather.js +260 -0
  166. package/package.json +92 -0
  167. package/server/agentRoute.test.ts +157 -0
  168. package/server/agents/__fixtures__/fake-claude-writer.mjs +23 -0
  169. package/server/agents/__fixtures__/fake-claude.mjs +55 -0
  170. package/server/agents/__fixtures__/fake-codex-writer.mjs +27 -0
  171. package/server/agents/__fixtures__/fake-codex.mjs +52 -0
  172. package/server/agents/__fixtures__/fake-version-empty.mjs +3 -0
  173. package/server/agents/__fixtures__/fake-version-fail.mjs +4 -0
  174. package/server/agents/__fixtures__/fake-version-garbage.mjs +4 -0
  175. package/server/agents/__fixtures__/fake-version-good.mjs +4 -0
  176. package/server/agents/__fixtures__/fake-version-hang.mjs +3 -0
  177. package/server/agents/claudeAdapter.test.ts +127 -0
  178. package/server/agents/claudeAdapter.ts +212 -0
  179. package/server/agents/claudeParse.ts +193 -0
  180. package/server/agents/codexAdapter.test.ts +125 -0
  181. package/server/agents/codexAdapter.ts +198 -0
  182. package/server/agents/codexParse.test.ts +58 -0
  183. package/server/agents/codexParse.ts +126 -0
  184. package/server/agents/detect.test.ts +65 -0
  185. package/server/agents/detect.ts +43 -0
  186. package/server/agents/gitScope.test.ts +129 -0
  187. package/server/agents/gitScope.ts +110 -0
  188. package/server/agents/modelRejectionHint.test.ts +30 -0
  189. package/server/agents/modelRejectionHint.ts +14 -0
  190. package/server/agents/prompt.test.ts +613 -0
  191. package/server/agents/prompt.ts +527 -0
  192. package/server/agents/runManager.test.ts +251 -0
  193. package/server/agents/runManager.ts +286 -0
  194. package/server/agents/types.ts +17 -0
  195. package/server/apiMount.test.ts +591 -0
  196. package/server/apiStore.test.ts +324 -0
  197. package/server/apiStore.ts +241 -0
  198. package/server/auth/enforce.test.ts +61 -0
  199. package/server/auth/enforce.ts +6 -0
  200. package/server/auth/types.ts +5 -0
  201. package/server/auth/verifiers.test.ts +37 -0
  202. package/server/auth/verifiers.ts +9 -0
  203. package/server/authAttach.test.ts +175 -0
  204. package/server/authAttach.ts +99 -0
  205. package/server/cli.ts +847 -0
  206. package/server/cliAuth.test.ts +229 -0
  207. package/server/cliCreate.test.ts +131 -0
  208. package/server/cliDoctor.test.ts +326 -0
  209. package/server/cliTest.test.ts +735 -0
  210. package/server/client.ts +314 -0
  211. package/server/demoProject.test.ts +29 -0
  212. package/server/diagnosticsRoute.test.ts +169 -0
  213. package/server/environments.test.ts +620 -0
  214. package/server/environments.ts +603 -0
  215. package/server/environmentsRoute.test.ts +385 -0
  216. package/server/errorWorkflow.test.ts +205 -0
  217. package/server/flowStore.test.ts +84 -0
  218. package/server/flowStore.ts +125 -0
  219. package/server/httpOperations.test.ts +377 -0
  220. package/server/httpOperations.ts +96 -0
  221. package/server/index.ts +1111 -0
  222. package/server/infrastructure.test.ts +154 -0
  223. package/server/infrastructure.ts +161 -0
  224. package/server/infrastructureRoute.test.ts +105 -0
  225. package/server/login.test.ts +153 -0
  226. package/server/login.ts +67 -0
  227. package/server/mcp.ts +278 -0
  228. package/server/migrateFlows.test.ts +55 -0
  229. package/server/migrateFlows.ts +23 -0
  230. package/server/mockHandler.test.ts +138 -0
  231. package/server/mockHandler.ts +52 -0
  232. package/server/mockRun.test.ts +367 -0
  233. package/server/mockServe.test.ts +467 -0
  234. package/server/nodesPayload.test.ts +29 -0
  235. package/server/nodesPayload.ts +26 -0
  236. package/server/normalizeFlow.test.ts +80 -0
  237. package/server/normalizeFlow.ts +59 -0
  238. package/server/openBrowser.test.ts +20 -0
  239. package/server/openBrowser.ts +22 -0
  240. package/server/operationResult.test.ts +67 -0
  241. package/server/operationResult.ts +27 -0
  242. package/server/pathGuard.test.ts +19 -0
  243. package/server/pathGuard.ts +12 -0
  244. package/server/pathSafety.test.ts +38 -0
  245. package/server/pathSafety.ts +33 -0
  246. package/server/projectConfig.test.ts +67 -0
  247. package/server/projectConfig.ts +101 -0
  248. package/server/projectMode.test.ts +106 -0
  249. package/server/projectMode.ts +59 -0
  250. package/server/redact.test.ts +88 -0
  251. package/server/redact.ts +35 -0
  252. package/server/redactEgress.test.ts +281 -0
  253. package/server/runRegistry.ts +270 -0
  254. package/server/runsAuth.test.ts +119 -0
  255. package/server/runtime/RuntimeAdapter.ts +24 -0
  256. package/server/runtime/expressAdapter.test.ts +38 -0
  257. package/server/runtime/expressAdapter.ts +70 -0
  258. package/server/scenarioTest.test.ts +148 -0
  259. package/server/scenarioTest.ts +88 -0
  260. package/server/setupStatus.test.ts +127 -0
  261. package/server/subflowRunner.ts +104 -0
  262. package/server/testRunner.ts +216 -0
  263. package/server/tsconfig.json +20 -0
  264. package/server/workflowTestRoute.test.ts +297 -0
  265. package/src/App.tsx +233 -0
  266. package/src/components/AgentConsole.tsx +461 -0
  267. package/src/components/BranchRulesEditor.tsx +156 -0
  268. package/src/components/CreateModal.tsx +275 -0
  269. package/src/components/Dock.tsx +487 -0
  270. package/src/components/EnvironmentDialog.tsx +569 -0
  271. package/src/components/EnvironmentPicker.tsx +357 -0
  272. package/src/components/EnvironmentsDialog.tsx +144 -0
  273. package/src/components/ExecutionPager.tsx +67 -0
  274. package/src/components/InfraPanel.test.tsx +103 -0
  275. package/src/components/InfraPanel.tsx +171 -0
  276. package/src/components/Inspector.tsx +1182 -0
  277. package/src/components/Json.tsx +50 -0
  278. package/src/components/JsonModal.tsx +52 -0
  279. package/src/components/LogMessage.tsx +61 -0
  280. package/src/components/NodeRunModal.tsx +213 -0
  281. package/src/components/RunLogPanel.tsx +397 -0
  282. package/src/components/RunbookView.tsx +1085 -0
  283. package/src/components/Scenarios.tsx +476 -0
  284. package/src/components/SettingsDialog.tsx +229 -0
  285. package/src/components/Sidebar.tsx +436 -0
  286. package/src/components/StatusBar.tsx +302 -0
  287. package/src/components/Toolbar.tsx +663 -0
  288. package/src/components/WelcomeDialog.test.tsx +107 -0
  289. package/src/components/WelcomeDialog.tsx +412 -0
  290. package/src/components/agentMarkdown.test.tsx +91 -0
  291. package/src/components/agentMarkdown.tsx +158 -0
  292. package/src/components/ui/badge.tsx +31 -0
  293. package/src/components/ui/button.tsx +46 -0
  294. package/src/components/ui/combobox.tsx +114 -0
  295. package/src/components/ui/command.tsx +82 -0
  296. package/src/components/ui/dialog.tsx +73 -0
  297. package/src/components/ui/input.tsx +20 -0
  298. package/src/components/ui/popover.tsx +32 -0
  299. package/src/components/ui/resizable.tsx +44 -0
  300. package/src/components/ui/tabs.tsx +36 -0
  301. package/src/config.ts +4 -0
  302. package/src/engine/authVerify.ts +81 -0
  303. package/src/engine/diagnostics.test.ts +437 -0
  304. package/src/engine/diagnostics.ts +211 -0
  305. package/src/engine/executor.test.ts +1339 -0
  306. package/src/engine/executor.ts +840 -0
  307. package/src/engine/httpError.test.ts +12 -0
  308. package/src/engine/httpError.ts +16 -0
  309. package/src/engine/index.ts +11 -0
  310. package/src/engine/output.ts +21 -0
  311. package/src/engine/publish.test.ts +176 -0
  312. package/src/engine/publish.ts +127 -0
  313. package/src/engine/registry.test.ts +64 -0
  314. package/src/engine/registry.ts +80 -0
  315. package/src/engine/scenarios.test.ts +55 -0
  316. package/src/engine/scenarios.ts +29 -0
  317. package/src/engine/schemaCheck.test.ts +21 -0
  318. package/src/engine/schemaCheck.ts +35 -0
  319. package/src/engine/trace.test.ts +19 -0
  320. package/src/engine/trace.ts +23 -0
  321. package/src/engine/types.test.ts +22 -0
  322. package/src/engine/types.ts +316 -0
  323. package/src/engine/validation.test.ts +314 -0
  324. package/src/engine/validation.ts +354 -0
  325. package/src/flows/anomaly-flows.test.ts +81 -0
  326. package/src/flows/anomaly-flows.ts +202 -0
  327. package/src/flows/city-sweep-flow.ts +131 -0
  328. package/src/flows/flows.test.ts +30 -0
  329. package/src/flows/login-flow.ts +150 -0
  330. package/src/flows/pradar-flows.test.ts +204 -0
  331. package/src/flows/pradar-flows.ts +419 -0
  332. package/src/flows/weather-flow.ts +154 -0
  333. package/src/globals.css +147 -0
  334. package/src/lib/pathParams.test.ts +24 -0
  335. package/src/lib/pathParams.ts +6 -0
  336. package/src/lib/registerLens.test.ts +79 -0
  337. package/src/lib/registerLens.ts +59 -0
  338. package/src/lib/runbookModel.test.ts +61 -0
  339. package/src/lib/runbookModel.ts +290 -0
  340. package/src/lib/runbookProjection.test.ts +417 -0
  341. package/src/lib/runbookProjection.ts +254 -0
  342. package/src/lib/useTailAnchor.ts +53 -0
  343. package/src/lib/utils.ts +7 -0
  344. package/src/main.tsx +13 -0
  345. package/src/nodes/anomaly.test.ts +98 -0
  346. package/src/nodes/anomaly.ts +637 -0
  347. package/src/nodes/effects-scan.test.ts +44 -0
  348. package/src/nodes/flow-control.test.ts +280 -0
  349. package/src/nodes/flow-control.ts +305 -0
  350. package/src/nodes/index.ts +22 -0
  351. package/src/nodes/login.test.ts +81 -0
  352. package/src/nodes/login.ts +186 -0
  353. package/src/nodes/loops.ts +69 -0
  354. package/src/nodes/pradar/index.ts +11 -0
  355. package/src/nodes/pradar/logic.test.ts +288 -0
  356. package/src/nodes/pradar/logic.ts +582 -0
  357. package/src/nodes/pradar/nodes.test.ts +146 -0
  358. package/src/nodes/pradar/nodes.ts +955 -0
  359. package/src/nodes/requireAuth.test.ts +75 -0
  360. package/src/nodes/requireAuth.ts +55 -0
  361. package/src/nodes/response.test.ts +33 -0
  362. package/src/nodes/response.ts +39 -0
  363. package/src/nodes/traceDetail.test.ts +39 -0
  364. package/src/nodes/weather.test.ts +65 -0
  365. package/src/nodes/weather.ts +306 -0
  366. package/src/store/agentClient.test.ts +103 -0
  367. package/src/store/agentClient.ts +131 -0
  368. package/src/store/apiTree.test.ts +17 -0
  369. package/src/store/apiTree.ts +73 -0
  370. package/src/store/builderStore.test.ts +1234 -0
  371. package/src/store/builderStore.ts +1879 -0
  372. package/src/store/infraClient.ts +63 -0
  373. package/src/store/nodeMeta.test.ts +24 -0
  374. package/src/store/nodeMeta.ts +21 -0
  375. package/src/store/persistence.test.ts +15 -0
  376. package/src/store/persistence.ts +54 -0
  377. package/src/store/serverRunner.ts +381 -0
  378. package/src/store/setupClient.ts +57 -0
  379. package/studio-dist/assets/ibm-plex-mono-cyrillic-400-normal-BSMlKf0J.woff2 +0 -0
  380. package/studio-dist/assets/ibm-plex-mono-cyrillic-400-normal-CEL4l2ZJ.woff +0 -0
  381. package/studio-dist/assets/ibm-plex-mono-cyrillic-500-normal-Ael50iVv.woff +0 -0
  382. package/studio-dist/assets/ibm-plex-mono-cyrillic-500-normal-Bq9vWWag.woff2 +0 -0
  383. package/studio-dist/assets/ibm-plex-mono-cyrillic-ext-400-normal-DMdlQ8Kv.woff +0 -0
  384. package/studio-dist/assets/ibm-plex-mono-cyrillic-ext-400-normal-xuaO2J-f.woff2 +0 -0
  385. package/studio-dist/assets/ibm-plex-mono-cyrillic-ext-500-normal-BIfNGwUT.woff +0 -0
  386. package/studio-dist/assets/ibm-plex-mono-cyrillic-ext-500-normal-BqneJy0T.woff2 +0 -0
  387. package/studio-dist/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
  388. package/studio-dist/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
  389. package/studio-dist/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
  390. package/studio-dist/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
  391. package/studio-dist/assets/ibm-plex-mono-latin-ext-400-normal-BmRBH3aV.woff2 +0 -0
  392. package/studio-dist/assets/ibm-plex-mono-latin-ext-400-normal-D3D2R8hC.woff +0 -0
  393. package/studio-dist/assets/ibm-plex-mono-latin-ext-500-normal-CAhNIIs5.woff2 +0 -0
  394. package/studio-dist/assets/ibm-plex-mono-latin-ext-500-normal-CZ70TYgx.woff +0 -0
  395. package/studio-dist/assets/ibm-plex-mono-vietnamese-400-normal-BulugwFq.woff2 +0 -0
  396. package/studio-dist/assets/ibm-plex-mono-vietnamese-400-normal-DDuiU_S-.woff +0 -0
  397. package/studio-dist/assets/ibm-plex-mono-vietnamese-500-normal-C8zxqsMH.woff +0 -0
  398. package/studio-dist/assets/ibm-plex-mono-vietnamese-500-normal-DZ4AoWbu.woff2 +0 -0
  399. package/studio-dist/assets/index-DNJwW-hM.css +1 -0
  400. package/studio-dist/assets/index-O26dKRjW.js +65 -0
  401. package/studio-dist/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
  402. package/studio-dist/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
  403. package/studio-dist/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
  404. package/studio-dist/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
  405. package/studio-dist/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
  406. package/studio-dist/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
  407. package/studio-dist/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
  408. package/studio-dist/favicon.svg +1 -0
  409. package/studio-dist/icons.svg +24 -0
  410. package/studio-dist/index.html +14 -0
  411. package/templates/skills/emberflow-basics/SKILL.md +316 -0
  412. package/templates/skills/emberflow-model-process/SKILL.md +209 -0
  413. package/templates/skills/emberflow-new-workflow/SKILL.md +211 -0
  414. package/templates/skills/emberflow-review-workflow/SKILL.md +148 -0
@@ -0,0 +1,367 @@
1
+ import { afterAll, beforeAll, describe, expect, it } from 'vitest';
2
+ import { spawn, type ChildProcess } from 'node:child_process';
3
+ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
4
+ import { tmpdir } from 'node:os';
5
+ import { join } from 'node:path';
6
+
7
+ // Task 2: Mock serving mode executes runs against scenario mocks, and never
8
+ // auto-attaches credentials. Boots the actual runner subprocess (server/index.ts)
9
+ // against a scratch project dir carrying: a project node with traceKind 'db'
10
+ // (so an unmocked run fails loud with the binding infrastructure message), an
11
+ // environment WITH auth configured + a stored secret (so "credential
12
+ // auto-attach was skipped" is a meaningful assertion, not a vacuous one), an
13
+ // op using the db node, and a scenarios sidecar with op-level mocks + one
14
+ // scenario overriding a nodeId. Mirrors the harness in runsAuth.test.ts /
15
+ // workflowTestRoute.test.ts.
16
+
17
+ let proc: ChildProcess;
18
+ const PORT = 8152;
19
+ const base = `http://127.0.0.1:${PORT}`;
20
+ let projectDir: string;
21
+
22
+ async function waitHealthy(url: string, tries = 40): Promise<void> {
23
+ for (let i = 0; i < tries; i++) {
24
+ try {
25
+ if ((await fetch(url)).ok) return;
26
+ } catch {
27
+ /* not up yet */
28
+ }
29
+ await new Promise((r) => setTimeout(r, 150));
30
+ }
31
+ throw new Error('runner did not become healthy');
32
+ }
33
+
34
+ function bootRunner(port: number, env: Record<string, string | undefined>): ChildProcess {
35
+ return spawn('npx', ['tsx', 'server/index.ts'], {
36
+ env: { ...process.env, EMBERFLOW_RUNNER_PORT: String(port), ...env },
37
+ stdio: 'ignore',
38
+ });
39
+ }
40
+
41
+ const dbFlow = {
42
+ id: 'db-op',
43
+ name: 'DB Op',
44
+ version: 1,
45
+ createdAt: '2026-01-01T00:00:00Z',
46
+ updatedAt: '2026-01-01T00:00:00Z',
47
+ nodes: [
48
+ {
49
+ id: 'input',
50
+ type: 'Input',
51
+ label: 'Input',
52
+ position: { x: 0, y: 0 },
53
+ config: { fields: [] },
54
+ },
55
+ {
56
+ id: 'dbRead',
57
+ type: 'DbRead',
58
+ label: 'DB Read',
59
+ position: { x: 200, y: 0 },
60
+ config: {},
61
+ },
62
+ ],
63
+ edges: [{ id: 'e1', source: 'input', target: 'dbRead' }],
64
+ };
65
+
66
+ // Task 2 (Critical fix): the child op has its own `traceKind: 'db'` node and
67
+ // its own op-level mock — nodeIds are scoped per-flow, so the child must
68
+ // consult its OWN sidecar mocks, never the parent's.
69
+ const childMockedFlow = {
70
+ id: 'child-mocked-op',
71
+ name: 'Child Mocked Op',
72
+ version: 1,
73
+ createdAt: '2026-01-01T00:00:00Z',
74
+ updatedAt: '2026-01-01T00:00:00Z',
75
+ nodes: [
76
+ { id: 'input', type: 'Input', label: 'Input', position: { x: 0, y: 0 }, config: { fields: [] } },
77
+ { id: 'childDbRead', type: 'DbRead', label: 'Child DB Read', position: { x: 200, y: 0 }, config: {} },
78
+ {
79
+ id: 'result',
80
+ type: 'Result',
81
+ label: 'Result',
82
+ position: { x: 400, y: 0 },
83
+ config: {},
84
+ inputMap: { data: { sourceNodeId: 'childDbRead', sourceField: '$' } },
85
+ },
86
+ ],
87
+ edges: [
88
+ { id: 'e1', source: 'input', target: 'childDbRead' },
89
+ { id: 'e2', source: 'childDbRead', target: 'result', targetHandle: 'data' },
90
+ ],
91
+ };
92
+
93
+ // A second child op whose db node has NO mock configured anywhere — the
94
+ // binding infra failure must surface through the parent's Subflow node.
95
+ const childUnmockedFlow = {
96
+ id: 'child-unmocked-op',
97
+ name: 'Child Unmocked Op',
98
+ version: 1,
99
+ createdAt: '2026-01-01T00:00:00Z',
100
+ updatedAt: '2026-01-01T00:00:00Z',
101
+ nodes: [
102
+ { id: 'input', type: 'Input', label: 'Input', position: { x: 0, y: 0 }, config: { fields: [] } },
103
+ { id: 'childDbRead', type: 'DbRead', label: 'Child DB Read', position: { x: 200, y: 0 }, config: {} },
104
+ ],
105
+ edges: [{ id: 'e1', source: 'input', target: 'childDbRead' }],
106
+ };
107
+
108
+ function subflowParentFlow(id: string, name: string, workflowId: string): Record<string, unknown> {
109
+ return {
110
+ id,
111
+ name,
112
+ version: 1,
113
+ createdAt: '2026-01-01T00:00:00Z',
114
+ updatedAt: '2026-01-01T00:00:00Z',
115
+ nodes: [
116
+ { id: 'input', type: 'Input', label: 'Input', position: { x: 0, y: 0 }, config: { fields: [] } },
117
+ {
118
+ id: 'subflow',
119
+ type: 'Subflow',
120
+ label: 'Subflow',
121
+ position: { x: 200, y: 0 },
122
+ config: { workflowId },
123
+ },
124
+ ],
125
+ edges: [{ id: 'e1', source: 'input', target: 'subflow' }],
126
+ };
127
+ }
128
+
129
+ /** Fetches the flow (with sidecar-merged scenarios/mocks) via the API,
130
+ * mirroring how the studio would build the POST /runs body. */
131
+ async function loadFlow(opId: string): Promise<any> {
132
+ const listRes = await fetch(`${base}/api/workflows`);
133
+ const { flows } = await listRes.json();
134
+ return flows.find((f: { id: string }) => f.id === opId);
135
+ }
136
+
137
+ async function postRun(body: Record<string, unknown>): Promise<Response> {
138
+ return fetch(`${base}/api/runs`, {
139
+ method: 'POST',
140
+ headers: { 'Content-Type': 'application/json' },
141
+ body: JSON.stringify(body),
142
+ });
143
+ }
144
+
145
+ async function getRun(runId: string): Promise<any> {
146
+ // Drain the SSE replay buffer for the finished event (or latest state) via
147
+ // a short-lived EventSource-less fetch: the events route is SSE, so read
148
+ // the raw stream and parse the last "finished" frame.
149
+ const res = await fetch(`${base}/api/runs/${runId}/events`);
150
+ const reader = res.body!.getReader();
151
+ const decoder = new TextDecoder();
152
+ let text = '';
153
+ let finished: any;
154
+ const events: any[] = [];
155
+ // eslint-disable-next-line no-constant-condition
156
+ while (true) {
157
+ const { value, done } = await reader.read();
158
+ if (done) break;
159
+ text += decoder.decode(value, { stream: true });
160
+ const frames = text.split('\n\n');
161
+ text = frames.pop() ?? '';
162
+ for (const frame of frames) {
163
+ const dataLine = frame.split('\n').find((l) => l.startsWith('data: '));
164
+ if (!dataLine) continue;
165
+ const event = JSON.parse(dataLine.slice('data: '.length));
166
+ events.push(event);
167
+ if (event.type === 'finished') finished = event;
168
+ }
169
+ if (finished) break;
170
+ }
171
+ reader.cancel().catch(() => {});
172
+ return { finished, events };
173
+ }
174
+
175
+ beforeAll(async () => {
176
+ projectDir = mkdtempSync(join(tmpdir(), 'mockrun-'));
177
+ writeFileSync(
178
+ join(projectDir, 'emberflow.config.mjs'),
179
+ `export default {
180
+ registerNodes(registry) {
181
+ registry.register(
182
+ { type: 'DbRead', label: 'DB Read', traceKind: 'db', inputSchema: { fields: [] } },
183
+ async () => ({ rows: [{ id: 'real-row' }] }),
184
+ );
185
+ },
186
+ };\n`,
187
+ );
188
+ writeFileSync(
189
+ join(projectDir, 'emberflow.environments.json'),
190
+ JSON.stringify({
191
+ defaultEnvironment: 'local',
192
+ environments: {
193
+ local: {
194
+ vars: {},
195
+ secrets: { sessionCookie: 'supersecretcookievalue' },
196
+ auth: { attach: { as: 'cookie', name: 'session', secretRef: 'sessionCookie' } },
197
+ },
198
+ },
199
+ }),
200
+ );
201
+
202
+ const apisDir = join(projectDir, 'emberflow', 'apis', 'default');
203
+ mkdirSync(apisDir, { recursive: true });
204
+ writeFileSync(join(apisDir, 'db-op.json'), JSON.stringify(dbFlow));
205
+ writeFileSync(
206
+ join(apisDir, 'db-op.scenarios.json'),
207
+ JSON.stringify({
208
+ scenarios: [
209
+ { id: 's-override', name: 'override', input: {}, mocks: { dbRead: { rows: [{ id: 'scenario-row' }] } } },
210
+ ],
211
+ mocks: { dbRead: { rows: [{ id: 'op-level-row' }] } },
212
+ }),
213
+ );
214
+
215
+ // Child op with its OWN op-level mock (nodeId `childDbRead`, disjoint from
216
+ // the parent's mock map — never reused across flows).
217
+ writeFileSync(join(apisDir, 'child-mocked-op.json'), JSON.stringify(childMockedFlow));
218
+ writeFileSync(
219
+ join(apisDir, 'child-mocked-op.scenarios.json'),
220
+ JSON.stringify({ scenarios: [], mocks: { childDbRead: { rows: [{ id: 'child-mocked-row' }] } } }),
221
+ );
222
+
223
+ // Child op with NO mocks configured anywhere — forces the infra-no-mock path.
224
+ writeFileSync(join(apisDir, 'child-unmocked-op.json'), JSON.stringify(childUnmockedFlow));
225
+
226
+ writeFileSync(
227
+ join(apisDir, 'parent-subflow-mocked-op.json'),
228
+ JSON.stringify(subflowParentFlow('parent-subflow-mocked-op', 'Parent Subflow Mocked Op', 'child-mocked-op')),
229
+ );
230
+ writeFileSync(
231
+ join(apisDir, 'parent-subflow-unmocked-op.json'),
232
+ JSON.stringify(subflowParentFlow('parent-subflow-unmocked-op', 'Parent Subflow Unmocked Op', 'child-unmocked-op')),
233
+ );
234
+
235
+ proc = bootRunner(PORT, { EMBERFLOW_PROJECT: projectDir, EMBERFLOW_MOCK: '1' });
236
+ await waitHealthy(`${base}/healthz`);
237
+ }, 20_000);
238
+
239
+ afterAll(() => {
240
+ proc?.kill();
241
+ if (projectDir) rmSync(projectDir, { recursive: true, force: true });
242
+ });
243
+
244
+ describe('POST /runs in Mock serving mode', () => {
245
+ it('plain run (no scenario) uses op-level mocks and marks the mocked node', async () => {
246
+ const flow = await loadFlow('db-op');
247
+ expect(flow.mocks).toEqual({ dbRead: { rows: [{ id: 'op-level-row' }] } });
248
+
249
+ const createRes = await postRun({ flow, mode: 'run', input: {} });
250
+ expect(createRes.status).toBe(201);
251
+ const { runId } = await createRes.json();
252
+
253
+ const { finished } = await getRun(runId);
254
+ expect(finished.run.status).toBe('succeeded');
255
+ expect(finished.run.nodeStates.dbRead.mocked).toBe(true);
256
+ expect(finished.run.nodeStates.dbRead.output).toEqual({ rows: [{ id: 'op-level-row' }] });
257
+ });
258
+
259
+ it('a named scenario\'s mocks win over op-level mocks for the same nodeId', async () => {
260
+ const flow = await loadFlow('db-op');
261
+ const createRes = await postRun({ flow, mode: 'run', input: {}, scenarioName: 'override' });
262
+ expect(createRes.status).toBe(201);
263
+ const { runId } = await createRes.json();
264
+
265
+ const { finished } = await getRun(runId);
266
+ expect(finished.run.status).toBe('succeeded');
267
+ expect(finished.run.nodeStates.dbRead.mocked).toBe(true);
268
+ expect(finished.run.nodeStates.dbRead.output).toEqual({ rows: [{ id: 'scenario-row' }] });
269
+ });
270
+
271
+ it('credential auto-attach is skipped entirely in a mock run', async () => {
272
+ const flow = await loadFlow('db-op');
273
+ const createRes = await postRun({ flow, mode: 'run', input: {} });
274
+ const { runId } = await createRes.json();
275
+ const { finished } = await getRun(runId);
276
+ expect(finished.run.status).toBe('succeeded');
277
+ // The Input node's recorded input must carry NO attached cookie — the
278
+ // environment's auth.attach would otherwise inject a `session=...` cookie.
279
+ const inputState = finished.run.nodeStates.input;
280
+ expect(inputState.output?.headers?.cookie).toBeUndefined();
281
+ });
282
+
283
+ it('an unmocked infra node fails with the binding infrastructure message (not silently mocked)', async () => {
284
+ const flow = await loadFlow('db-op');
285
+ // Strip mocks entirely to force the infra-no-mock path.
286
+ const flowNoMocks = { ...flow, mocks: undefined, scenarios: undefined };
287
+ const createRes = await postRun({ flow: flowNoMocks, mode: 'run', input: {} });
288
+ const { runId } = await createRes.json();
289
+ const { finished } = await getRun(runId);
290
+ expect(finished.run.status).toBe('failed');
291
+ expect(finished.run.nodeStates.dbRead.error).toContain('would touch real infrastructure');
292
+ expect(finished.run.nodeStates.dbRead.error).toContain('db');
293
+ });
294
+
295
+ it('stepped mock runs inherit mockRun/mocks set at creation: stepping through yields the canned output mid-step', async () => {
296
+ const flow = await loadFlow('db-op');
297
+ const createRes = await postRun({ flow, mode: 'step', input: {} });
298
+ expect(createRes.status).toBe(201);
299
+ const { runId } = await createRes.json();
300
+
301
+ // Step 1: Input node.
302
+ await fetch(`${base}/api/runs/${runId}/step`, { method: 'POST' });
303
+ // Step 2: dbRead node — should short-circuit to the mocked output.
304
+ await fetch(`${base}/api/runs/${runId}/step`, { method: 'POST' });
305
+
306
+ const { finished } = await getRun(runId);
307
+ expect(finished.run.nodeStates.dbRead.mocked).toBe(true);
308
+ expect(finished.run.nodeStates.dbRead.output).toEqual({ rows: [{ id: 'op-level-row' }] });
309
+ });
310
+
311
+ it('a Subflow child run in a mock run consults the CHILD op\'s own op-level mocks, never real execution', async () => {
312
+ const flow = await loadFlow('parent-subflow-mocked-op');
313
+ const createRes = await postRun({ flow, mode: 'run', input: {} });
314
+ expect(createRes.status).toBe(201);
315
+ const { runId } = await createRes.json();
316
+
317
+ const { finished } = await getRun(runId);
318
+ expect(finished.run.status).toBe('succeeded');
319
+ // The Subflow node itself is traceKind 'compute' (no boundary fires on
320
+ // it directly) — the mock propagation must reach INSIDE the child run.
321
+ // The child's own canned mock ('child-mocked-row') must win — never the
322
+ // parent's mock map (which has no `childDbRead` entry at all) and never
323
+ // the real handler's 'real-row'.
324
+ expect(finished.run.status).toBe('succeeded');
325
+ const output = finished.run.nodeStates.subflow?.output;
326
+ expect(JSON.stringify(output)).toContain('child-mocked-row');
327
+ expect(JSON.stringify(output)).not.toContain('real-row');
328
+ });
329
+
330
+ it('a Subflow child with an unmocked infra node fails the parent with the binding infrastructure message', async () => {
331
+ const flow = await loadFlow('parent-subflow-unmocked-op');
332
+ const createRes = await postRun({ flow, mode: 'run', input: {} });
333
+ expect(createRes.status).toBe(201);
334
+ const { runId } = await createRes.json();
335
+
336
+ const { finished } = await getRun(runId);
337
+ expect(finished.run.status).toBe('failed');
338
+ expect(finished.run.nodeStates.subflow.error).toContain('would touch real infrastructure');
339
+ });
340
+ });
341
+
342
+ describe('POST /runs in Real serving mode (regression: byte-identical)', () => {
343
+ it('runs for real, attaches credentials, and never mocks', async () => {
344
+ await fetch(`${base}/api/serving`, {
345
+ method: 'POST',
346
+ headers: { 'Content-Type': 'application/json' },
347
+ body: JSON.stringify({ mode: 'real' }),
348
+ });
349
+ try {
350
+ const flow = await loadFlow('db-op');
351
+ const createRes = await postRun({ flow, mode: 'run', input: {} });
352
+ const { runId } = await createRes.json();
353
+ const { finished } = await getRun(runId);
354
+ expect(finished.run.status).toBe('succeeded');
355
+ expect(finished.run.nodeStates.dbRead.mocked).toBeUndefined();
356
+ expect(finished.run.nodeStates.dbRead.output).toEqual({ rows: [{ id: 'real-row' }] });
357
+ // Credential auto-attach happened for real.
358
+ expect(finished.run.nodeStates.input.output?.headers?.cookie).toContain('session=');
359
+ } finally {
360
+ await fetch(`${base}/api/serving`, {
361
+ method: 'POST',
362
+ headers: { 'Content-Type': 'application/json' },
363
+ body: JSON.stringify({ mode: 'mock' }),
364
+ });
365
+ }
366
+ });
367
+ });