@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,397 @@
1
+ import { useEffect, useRef, useState } from 'react';
2
+ import { Maximize2Icon, PanelBottomIcon, PanelRightIcon, ShieldIcon, XIcon } from 'lucide-react';
3
+ import { Badge } from '@/components/ui/badge';
4
+ import { Button } from '@/components/ui/button';
5
+ import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from '@/components/ui/resizable';
6
+ import { effectiveConsolePosition, useBuilderStore } from '../store/builderStore';
7
+ import { useTailAnchor } from '../lib/useTailAnchor';
8
+ import { Json } from './Json';
9
+ import { LogMessage } from './LogMessage';
10
+ import { JsonModal } from './JsonModal';
11
+ import { cn } from '@/lib/utils';
12
+ import { filterLogs, formatDuration, payloadOpenByDefault } from '@/lib/registerLens';
13
+ import type { ViewRegister } from '@/lib/registerLens';
14
+ import type { NodeRunState } from '../engine';
15
+
16
+ const statusDot: Record<string, string> = {
17
+ succeeded: 'bg-success',
18
+ failed: 'bg-destructive',
19
+ cancelled: 'bg-muted-foreground',
20
+ running: 'bg-highlight animate-pulse',
21
+ };
22
+
23
+ const levelColor: Record<string, string> = {
24
+ info: 'text-success',
25
+ debug: 'text-muted-foreground/60',
26
+ warn: 'text-yellow-500',
27
+ error: 'text-destructive',
28
+ };
29
+
30
+ /**
31
+ * Whether the run console panel should be docked into the layout. Owned at
32
+ * the App level so the panel can join the resizable panel group like any
33
+ * other IDE panel. Only runs that actually executed while this session
34
+ * watched summon it — browsing run history never does — and it stays after
35
+ * the run finishes until dismissed.
36
+ *
37
+ * In the simple register, starting a run never auto-opens the console — it
38
+ * only opens once the user explicitly asks (the toolbar toggle), which is
39
+ * tracked per-run in `runConsoleOpenedIds`; from then on that run's console
40
+ * behaves exactly like the technical register's (dismiss/reopen). The
41
+ * technical register ignores that tracking and stays open as it always has.
42
+ */
43
+ export function useRunConsole(): { available: boolean; open: boolean; running: boolean } {
44
+ const run = useBuilderStore((s) => s.run);
45
+ const dismissedId = useBuilderStore((s) => s.runConsoleDismissedId);
46
+ const register = useBuilderStore((s) => s.viewRegister);
47
+ const openedIds = useBuilderStore((s) => s.runConsoleOpenedIds);
48
+ const liveRunIds = useRef(new Set<string>());
49
+ if (run?.status === 'running') liveRunIds.current.add(run.id);
50
+ const available = run !== null && liveRunIds.current.has(run.id);
51
+ const userOpenedForThisRun = run !== null && openedIds.has(run.id);
52
+ const open = available && run!.id !== dismissedId && (register === 'technical' || userOpenedForThisRun);
53
+ const running = run?.status === 'running';
54
+ return { available, open, running };
55
+ }
56
+
57
+ /**
58
+ * Node detail: the lower half of the console's master-detail split. Shows the
59
+ * clicked node's LATEST input/output (or error), live as you step,
60
+ * iteration-aware for loop bodies.
61
+ */
62
+ function NodeDetail({
63
+ label,
64
+ typeName,
65
+ state,
66
+ onClose,
67
+ register,
68
+ }: {
69
+ label: string;
70
+ typeName?: string;
71
+ state: NodeRunState | undefined;
72
+ onClose: () => void;
73
+ register: ViewRegister;
74
+ }) {
75
+ const [modal, setModal] = useState<{ title: string; value: unknown } | null>(null);
76
+ const latestExec = state?.executions?.[state.executions.length - 1];
77
+ const input = latestExec ? latestExec.input : state?.input;
78
+ const output = latestExec ? latestExec.output : state?.output;
79
+ const error = latestExec ? latestExec.error : state?.error;
80
+ const durationMs =
81
+ state?.startedAt && state?.completedAt
82
+ ? new Date(state.completedAt).getTime() - new Date(state.startedAt).getTime()
83
+ : null;
84
+
85
+ const pane = (title: string, value: unknown) => (
86
+ <div className="group relative min-w-0 flex-1">
87
+ <div className="mb-1.5 text-[10px] font-medium uppercase tracking-widest text-muted-foreground">
88
+ {title}
89
+ </div>
90
+ {value !== undefined ? (
91
+ <>
92
+ <Json value={value} />
93
+ <Button
94
+ variant="ghost"
95
+ size="icon"
96
+ className="absolute top-6 right-1.5 size-6 text-muted-foreground opacity-0 transition-opacity group-hover:opacity-100 hover:text-foreground"
97
+ onClick={() => setModal({ title: `${label} · ${title.toLowerCase()}`, value })}
98
+ aria-label={`View full ${title.toLowerCase()}`}
99
+ >
100
+ <Maximize2Icon className="size-3.5" />
101
+ </Button>
102
+ </>
103
+ ) : (
104
+ <div className="rounded-md border border-dashed border-border px-3 py-4 text-center text-[11.5px] text-muted-foreground/60">
105
+ nothing captured
106
+ </div>
107
+ )}
108
+ </div>
109
+ );
110
+
111
+ return (
112
+ <div className="flex h-full min-h-0 flex-col bg-background/40">
113
+ <div className="flex h-9 shrink-0 items-center gap-2 border-b border-border/70 px-3">
114
+ <span className={cn('size-1.5 rounded-full', statusDot[state?.status ?? 'running'] ?? 'bg-muted-foreground')} />
115
+ <span className="min-w-0 truncate text-[12px] font-medium">{label}</span>
116
+ {typeName && (
117
+ <span className="hidden truncate font-mono text-[9.5px] text-muted-foreground sm:inline">{typeName}</span>
118
+ )}
119
+ {state?.iteration && (
120
+ <Badge variant="mono" className="shrink-0 text-[9px]">
121
+ {state.iteration.index + 1}/{state.iteration.total}
122
+ </Badge>
123
+ )}
124
+ <span className="ml-auto shrink-0 text-[9.5px] text-muted-foreground/70">
125
+ latest{durationMs !== null ? ` · ${formatDuration(durationMs, register)}` : ''}
126
+ </span>
127
+ <Button
128
+ variant="ghost"
129
+ size="icon"
130
+ className="size-5 shrink-0 text-muted-foreground hover:text-foreground"
131
+ onClick={onClose}
132
+ aria-label="Close node detail"
133
+ >
134
+ <XIcon className="size-3" />
135
+ </Button>
136
+ </div>
137
+ {state ? (
138
+ <div className="min-h-0 flex-1 space-y-3 overflow-y-auto p-3">
139
+ {pane('Input', input)}
140
+ {error !== undefined ? (
141
+ <div className="min-w-0">
142
+ <div className="mb-1.5 text-[10px] font-medium uppercase tracking-widest text-destructive">Error</div>
143
+ <pre className="overflow-auto rounded-md border border-destructive/50 bg-card p-3 font-mono text-[11.5px] leading-relaxed whitespace-pre-wrap text-destructive-foreground">
144
+ {error}
145
+ </pre>
146
+ </div>
147
+ ) : (
148
+ pane('Output', output)
149
+ )}
150
+ </div>
151
+ ) : (
152
+ <div className="p-4 text-[12px] text-muted-foreground/70">Not executed yet.</div>
153
+ )}
154
+ {modal && (
155
+ <JsonModal
156
+ title={modal.title}
157
+ value={modal.value}
158
+ open
159
+ onOpenChange={(open) => {
160
+ if (!open) setModal(null);
161
+ }}
162
+ />
163
+ )}
164
+ </div>
165
+ );
166
+ }
167
+
168
+ /**
169
+ * Run console: a docked IDE-style panel — either the rightmost column of the
170
+ * layout or a panel below the dock (position-agnostic, chosen by the user via
171
+ * the header's dock-side toggle) — that streams a run's logs live. Clicking a
172
+ * node in the log opens a master-detail split with that node's latest
173
+ * input/output.
174
+ */
175
+ export function RunConsole({ onDismiss }: { onDismiss: () => void }) {
176
+ const run = useBuilderStore((s) => s.run);
177
+ const rawLogs = useBuilderStore((s) => s.logs);
178
+ const register = useBuilderStore((s) => s.viewRegister);
179
+ const flowName = useBuilderStore((s) => s.flow.name);
180
+ const flowNodes = useBuilderStore((s) => s.flow.nodes);
181
+ const selectNode = useBuilderStore((s) => s.selectNode);
182
+ const consolePositionChoice = useBuilderStore((s) => s.consolePosition);
183
+ const consolePosition = effectiveConsolePosition(consolePositionChoice, register);
184
+ const setConsolePosition = useBuilderStore((s) => s.setConsolePosition);
185
+ const [peek, setPeek] = useState<{ line: number; nodeId: string } | null>(null);
186
+
187
+ const logs = filterLogs(rawLogs, register);
188
+ const openByDefault = payloadOpenByDefault(register);
189
+
190
+ // Follow the tail only while the reader is at the bottom (and no peek is
191
+ // open) — scrolling up detaches; the pill jumps back.
192
+ const { scrollerRef, endRef: logEndRef, detached, jumpToLatest } = useTailAnchor(logs.length, { suspended: !!peek });
193
+
194
+ // Log indices reset with a new run's log stream — drop any open peek.
195
+ const peekRunRef = useRef<string | null>(null);
196
+ if ((run?.id ?? null) !== peekRunRef.current) {
197
+ peekRunRef.current = run?.id ?? null;
198
+ if (peek) setPeek(null);
199
+ }
200
+
201
+ // Filtering changes which line index maps to which log entry — a peek
202
+ // anchored in one register can point at the wrong line (or nothing) in the
203
+ // other, so drop it on register flips just like a new run does.
204
+ const peekRegisterRef = useRef<ViewRegister>(register);
205
+ if (register !== peekRegisterRef.current) {
206
+ peekRegisterRef.current = register;
207
+ if (peek) setPeek(null);
208
+ }
209
+
210
+ const finished = run !== null && run.status !== 'running';
211
+ const durationMs =
212
+ run?.completedAt && run.startedAt
213
+ ? new Date(run.completedAt).getTime() - new Date(run.startedAt).getTime()
214
+ : null;
215
+
216
+ // Live elapsed while running — a static "running…" undersells real work.
217
+ const [nowTick, setNowTick] = useState(() => Date.now());
218
+ useEffect(() => {
219
+ if (finished) return;
220
+ const t = setInterval(() => setNowTick(Date.now()), 250);
221
+ return () => clearInterval(t);
222
+ }, [finished]);
223
+ const elapsedMs = finished
224
+ ? durationMs
225
+ : run?.startedAt
226
+ ? Math.max(0, nowTick - new Date(run.startedAt).getTime())
227
+ : null;
228
+ const elapsedText = elapsedMs === null ? '' : formatDuration(elapsedMs, register);
229
+
230
+ // Coarse progress: settled nodes over the flow's node count.
231
+ const states = Object.values(run?.nodeStates ?? {});
232
+ const settled = states.filter((s) => s.status === 'succeeded' || s.status === 'failed' || s.status === 'skipped').length;
233
+ const total = Math.max(states.length, 1);
234
+ const errorCount = states.filter((s) => s.status === 'failed').length;
235
+
236
+ const peekNode = peek ? flowNodes.find((n) => n.id === peek.nodeId) : undefined;
237
+
238
+ const logList = (
239
+ <div className="flex h-full min-h-0 flex-col">
240
+ <div ref={scrollerRef as unknown as React.Ref<HTMLDivElement>} className="relative min-h-0 flex-1 overflow-y-auto px-3 py-2">
241
+ {detached && (
242
+ <button
243
+ type="button"
244
+ onClick={jumpToLatest}
245
+ className="sticky top-0 left-1/2 z-10 -translate-x-1/2 rounded-full border border-highlight/40 bg-card px-3 py-0.5 text-[10.5px] text-highlight shadow-md hover:bg-secondary"
246
+ >
247
+ ↓ latest
248
+ </button>
249
+ )}
250
+ {logs.length === 0 && (
251
+ <div className="px-1 py-2 text-[12px] text-muted-foreground/70">Waiting for logs…</div>
252
+ )}
253
+ {logs.map((line, i) => (
254
+ <div
255
+ key={i}
256
+ className={cn(
257
+ 'flex items-baseline gap-2.5 py-0.5 font-mono text-[11px]',
258
+ line.level === 'debug' && 'opacity-60',
259
+ )}
260
+ >
261
+ <span className="shrink-0 text-muted-foreground/50">{line.timestamp.slice(11, 19)}</span>
262
+ <span
263
+ className={cn('w-9 shrink-0 text-[9.5px] uppercase tracking-wider', levelColor[line.level] ?? '')}
264
+ >
265
+ {line.level}
266
+ </span>
267
+ {line.nodeId ? (
268
+ <button
269
+ type="button"
270
+ onClick={() => {
271
+ const already = peek?.line === i;
272
+ setPeek(already ? null : { line: i, nodeId: line.nodeId! });
273
+ if (!already) selectNode(line.nodeId!);
274
+ }}
275
+ title="Inspect latest input/output"
276
+ className={cn(
277
+ 'w-36 shrink-0 cursor-pointer truncate text-left underline-offset-2 transition-colors',
278
+ peek?.line === i
279
+ ? 'text-highlight underline'
280
+ : 'text-foreground/85 hover:text-highlight hover:underline',
281
+ )}
282
+ >
283
+ {line.nodeLabel ?? line.nodeId}
284
+ </button>
285
+ ) : (
286
+ <span className="w-36 shrink-0 truncate text-foreground/85">{line.nodeLabel ?? '—'}</span>
287
+ )}
288
+ <LogMessage message={line.message} defaultOpen={openByDefault} />
289
+ </div>
290
+ ))}
291
+ <div ref={logEndRef} />
292
+ </div>
293
+ </div>
294
+ );
295
+
296
+ return (
297
+ <div
298
+ className={cn(
299
+ 'flex h-full min-h-0 flex-col bg-card/60',
300
+ consolePosition === 'bottom' ? 'border-t border-border' : 'border-l border-border',
301
+ )}
302
+ >
303
+ <header className="relative flex h-11 shrink-0 items-center gap-2.5 border-b border-border/70 px-3.5">
304
+ <span className={cn('size-2 rounded-full', statusDot[run?.status ?? 'running'])} />
305
+ <span className="min-w-0 truncate text-[12.5px] font-medium">{flowName}</span>
306
+ {run?.environment && (
307
+ <Badge variant="outline" className="shrink-0 text-[9px] uppercase">
308
+ {run.environment}
309
+ </Badge>
310
+ )}
311
+ {run?.safeMode && <ShieldIcon className="size-3 shrink-0 text-muted-foreground" />}
312
+ <span className="ml-auto shrink-0 font-mono text-[11px] tabular-nums text-muted-foreground">{elapsedText}</span>
313
+ <div className="flex shrink-0 items-center gap-0.5 border-l border-border/70 pl-1.5">
314
+ <Button
315
+ variant="ghost"
316
+ size="icon"
317
+ className={cn(
318
+ 'size-6 text-muted-foreground hover:text-foreground',
319
+ consolePosition === 'right' && 'bg-secondary/60 text-foreground',
320
+ )}
321
+ onClick={() => setConsolePosition('right')}
322
+ aria-label="Dock right"
323
+ aria-pressed={consolePosition === 'right'}
324
+ title="Dock right"
325
+ >
326
+ <PanelRightIcon className="size-3.5" />
327
+ </Button>
328
+ <Button
329
+ variant="ghost"
330
+ size="icon"
331
+ className={cn(
332
+ 'size-6 text-muted-foreground hover:text-foreground',
333
+ consolePosition === 'bottom' && 'bg-secondary/60 text-foreground',
334
+ )}
335
+ onClick={() => setConsolePosition('bottom')}
336
+ aria-label="Dock bottom"
337
+ aria-pressed={consolePosition === 'bottom'}
338
+ title="Dock bottom"
339
+ >
340
+ <PanelBottomIcon className="size-3.5" />
341
+ </Button>
342
+ </div>
343
+ <Button
344
+ variant="ghost"
345
+ size="icon"
346
+ className="size-6 shrink-0 text-muted-foreground hover:text-foreground"
347
+ onClick={onDismiss}
348
+ aria-label="Dismiss run console"
349
+ >
350
+ <XIcon className="size-3.5" />
351
+ </Button>
352
+ {/* Run progress underlining the header — completes and quietly fades. */}
353
+ <div className="absolute inset-x-0 bottom-0 h-px overflow-visible">
354
+ <div
355
+ className={cn(
356
+ 'h-[2px] rounded-full transition-[width,opacity] duration-500 ease-out',
357
+ run?.status === 'failed' ? 'bg-destructive/80' : 'bg-highlight/80',
358
+ finished && run?.status !== 'failed' && 'opacity-0',
359
+ )}
360
+ style={{ width: `${Math.round((settled / total) * 100)}%` }}
361
+ />
362
+ </div>
363
+ </header>
364
+ {peek ? (
365
+ <ResizablePanelGroup direction="vertical" className="min-h-0 flex-1" autoSaveId="emberflow-run-detail">
366
+ <ResizablePanel id="run-logs" order={1} defaultSize={55} minSize={25}>
367
+ {logList}
368
+ </ResizablePanel>
369
+ <ResizableHandle />
370
+ <ResizablePanel id="run-node" order={2} defaultSize={45} minSize={25}>
371
+ <NodeDetail
372
+ label={peekNode?.label ?? peek.nodeId}
373
+ typeName={peekNode?.type}
374
+ state={run?.nodeStates[peek.nodeId]}
375
+ onClose={() => setPeek(null)}
376
+ register={register}
377
+ />
378
+ </ResizablePanel>
379
+ </ResizablePanelGroup>
380
+ ) : (
381
+ logList
382
+ )}
383
+ {finished && (
384
+ <footer className="flex shrink-0 items-center gap-2 border-t border-border/70 px-3.5 py-2">
385
+ <span className={cn('size-1.5 rounded-full', statusDot[run.status])} />
386
+ <span className="text-[12px] capitalize text-foreground/90">{run.status}</span>
387
+ <span className="text-[11px] text-muted-foreground">
388
+ · {settled}/{total} nodes{errorCount > 0 ? ` · ${errorCount} failed` : ''}
389
+ </span>
390
+ <Button variant="secondary" size="sm" className="ml-auto" onClick={onDismiss}>
391
+ Dismiss
392
+ </Button>
393
+ </footer>
394
+ )}
395
+ </div>
396
+ );
397
+ }