flow-atelier 0.1.7__tar.gz

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 (304) hide show
  1. flow_atelier-0.1.7/.env.example +43 -0
  2. flow_atelier-0.1.7/.github/workflows/ci.yml +36 -0
  3. flow_atelier-0.1.7/.github/workflows/cla.yml +36 -0
  4. flow_atelier-0.1.7/.github/workflows/frontend.yml +77 -0
  5. flow_atelier-0.1.7/.github/workflows/release.yml +123 -0
  6. flow_atelier-0.1.7/.gitignore +32 -0
  7. flow_atelier-0.1.7/.pre-commit-config.yaml +15 -0
  8. flow_atelier-0.1.7/.python-version +1 -0
  9. flow_atelier-0.1.7/CLA.md +121 -0
  10. flow_atelier-0.1.7/CONTRIBUTING.md +50 -0
  11. flow_atelier-0.1.7/DEVELOPMENT.md +192 -0
  12. flow_atelier-0.1.7/LICENSE +201 -0
  13. flow_atelier-0.1.7/NOTICE +12 -0
  14. flow_atelier-0.1.7/PKG-INFO +530 -0
  15. flow_atelier-0.1.7/README.md +508 -0
  16. flow_atelier-0.1.7/atelier.png +0 -0
  17. flow_atelier-0.1.7/flow_atelier/__init__.py +8 -0
  18. flow_atelier-0.1.7/flow_atelier/cli/__init__.py +1 -0
  19. flow_atelier-0.1.7/flow_atelier/cli/_shared.py +224 -0
  20. flow_atelier-0.1.7/flow_atelier/cli/commands/__init__.py +0 -0
  21. flow_atelier-0.1.7/flow_atelier/cli/commands/add.py +127 -0
  22. flow_atelier-0.1.7/flow_atelier/cli/commands/check.py +84 -0
  23. flow_atelier-0.1.7/flow_atelier/cli/commands/create.py +53 -0
  24. flow_atelier-0.1.7/flow_atelier/cli/commands/init.py +39 -0
  25. flow_atelier-0.1.7/flow_atelier/cli/commands/list.py +187 -0
  26. flow_atelier-0.1.7/flow_atelier/cli/commands/logs.py +185 -0
  27. flow_atelier-0.1.7/flow_atelier/cli/commands/outputs.py +57 -0
  28. flow_atelier-0.1.7/flow_atelier/cli/commands/plan.py +44 -0
  29. flow_atelier-0.1.7/flow_atelier/cli/commands/rm.py +163 -0
  30. flow_atelier-0.1.7/flow_atelier/cli/commands/run.py +306 -0
  31. flow_atelier-0.1.7/flow_atelier/cli/commands/schedule.py +262 -0
  32. flow_atelier-0.1.7/flow_atelier/cli/commands/scheduler.py +75 -0
  33. flow_atelier-0.1.7/flow_atelier/cli/commands/serve.py +206 -0
  34. flow_atelier-0.1.7/flow_atelier/cli/commands/status.py +87 -0
  35. flow_atelier-0.1.7/flow_atelier/cli/commands/stop.py +112 -0
  36. flow_atelier-0.1.7/flow_atelier/cli/commands/timing.py +89 -0
  37. flow_atelier-0.1.7/flow_atelier/cli/main.py +87 -0
  38. flow_atelier-0.1.7/flow_atelier/cli/rendering/__init__.py +0 -0
  39. flow_atelier-0.1.7/flow_atelier/cli/rendering/multiline_input.py +60 -0
  40. flow_atelier-0.1.7/flow_atelier/cli/rendering/render.py +524 -0
  41. flow_atelier-0.1.7/flow_atelier/cli/updater.py +268 -0
  42. flow_atelier-0.1.7/flow_atelier/core/__init__.py +0 -0
  43. flow_atelier-0.1.7/flow_atelier/core/atelier.py +781 -0
  44. flow_atelier-0.1.7/flow_atelier/core/settings.py +89 -0
  45. flow_atelier-0.1.7/flow_atelier/dist/assets/index-7nAy0WDh.css +1 -0
  46. flow_atelier-0.1.7/flow_atelier/dist/assets/index-CSAN2y3V.js +70 -0
  47. flow_atelier-0.1.7/flow_atelier/dist/favicon.svg +1 -0
  48. flow_atelier-0.1.7/flow_atelier/dist/index.html +20 -0
  49. flow_atelier-0.1.7/flow_atelier/main.py +5 -0
  50. flow_atelier-0.1.7/flow_atelier/modules/__init__.py +0 -0
  51. flow_atelier-0.1.7/flow_atelier/modules/conditions.py +274 -0
  52. flow_atelier-0.1.7/flow_atelier/modules/engine.py +1125 -0
  53. flow_atelier-0.1.7/flow_atelier/modules/liveness.py +187 -0
  54. flow_atelier-0.1.7/flow_atelier/modules/plan.py +180 -0
  55. flow_atelier-0.1.7/flow_atelier/modules/templating.py +198 -0
  56. flow_atelier-0.1.7/flow_atelier/routes/__init__.py +28 -0
  57. flow_atelier-0.1.7/flow_atelier/routes/conduits.py +118 -0
  58. flow_atelier-0.1.7/flow_atelier/routes/flows.py +42 -0
  59. flow_atelier-0.1.7/flow_atelier/routes/schedules.py +78 -0
  60. flow_atelier-0.1.7/flow_atelier/routes/tasks.py +26 -0
  61. flow_atelier-0.1.7/flow_atelier/routes/ws.py +426 -0
  62. flow_atelier-0.1.7/flow_atelier/schemas/__init__.py +0 -0
  63. flow_atelier-0.1.7/flow_atelier/schemas/api.py +272 -0
  64. flow_atelier-0.1.7/flow_atelier/schemas/conduit.py +238 -0
  65. flow_atelier-0.1.7/flow_atelier/schemas/flow.py +42 -0
  66. flow_atelier-0.1.7/flow_atelier/schemas/log.py +144 -0
  67. flow_atelier-0.1.7/flow_atelier/schemas/package.py +48 -0
  68. flow_atelier-0.1.7/flow_atelier/schemas/progress.py +42 -0
  69. flow_atelier-0.1.7/flow_atelier/schemas/ws.py +138 -0
  70. flow_atelier-0.1.7/flow_atelier/services/__init__.py +0 -0
  71. flow_atelier-0.1.7/flow_atelier/services/api/__init__.py +5 -0
  72. flow_atelier-0.1.7/flow_atelier/services/api/app.py +89 -0
  73. flow_atelier-0.1.7/flow_atelier/services/api/base.py +53 -0
  74. flow_atelier-0.1.7/flow_atelier/services/api/scheduler_bus.py +90 -0
  75. flow_atelier-0.1.7/flow_atelier/services/api/ws_hitl.py +95 -0
  76. flow_atelier-0.1.7/flow_atelier/services/api/ws_manager.py +137 -0
  77. flow_atelier-0.1.7/flow_atelier/services/api/ws_sink.py +85 -0
  78. flow_atelier-0.1.7/flow_atelier/services/executor/__init__.py +0 -0
  79. flow_atelier-0.1.7/flow_atelier/services/executor/base.py +85 -0
  80. flow_atelier-0.1.7/flow_atelier/services/executor/bash.py +123 -0
  81. flow_atelier-0.1.7/flow_atelier/services/executor/conduit.py +106 -0
  82. flow_atelier-0.1.7/flow_atelier/services/executor/harness.py +923 -0
  83. flow_atelier-0.1.7/flow_atelier/services/executor/hitl.py +86 -0
  84. flow_atelier-0.1.7/flow_atelier/services/executor/prompt_sink.py +223 -0
  85. flow_atelier-0.1.7/flow_atelier/services/package.py +334 -0
  86. flow_atelier-0.1.7/flow_atelier/services/scheduler/__init__.py +17 -0
  87. flow_atelier-0.1.7/flow_atelier/services/scheduler/runner.py +392 -0
  88. flow_atelier-0.1.7/flow_atelier/services/scheduler/store.py +418 -0
  89. flow_atelier-0.1.7/flow_atelier/services/scheduler/triggers.py +89 -0
  90. flow_atelier-0.1.7/flow_atelier/services/store/__init__.py +0 -0
  91. flow_atelier-0.1.7/flow_atelier/services/store/base.py +184 -0
  92. flow_atelier-0.1.7/flow_atelier/services/store/filesystem.py +548 -0
  93. flow_atelier-0.1.7/frontend/.env.example +3 -0
  94. flow_atelier-0.1.7/frontend/README.md +138 -0
  95. flow_atelier-0.1.7/frontend/index.html +19 -0
  96. flow_atelier-0.1.7/frontend/package-lock.json +4177 -0
  97. flow_atelier-0.1.7/frontend/package.json +55 -0
  98. flow_atelier-0.1.7/frontend/public/favicon.svg +1 -0
  99. flow_atelier-0.1.7/frontend/src/App.tsx +38 -0
  100. flow_atelier-0.1.7/frontend/src/assets/styles/index.css +21 -0
  101. flow_atelier-0.1.7/frontend/src/components/FlowDrawer.tsx +670 -0
  102. flow_atelier-0.1.7/frontend/src/components/ui/badge.tsx +30 -0
  103. flow_atelier-0.1.7/frontend/src/components/ui/button.tsx +51 -0
  104. flow_atelier-0.1.7/frontend/src/components/ui/dialog.tsx +93 -0
  105. flow_atelier-0.1.7/frontend/src/components/ui/input.tsx +18 -0
  106. flow_atelier-0.1.7/frontend/src/components/ui/label.tsx +18 -0
  107. flow_atelier-0.1.7/frontend/src/components/ui/popover.tsx +25 -0
  108. flow_atelier-0.1.7/frontend/src/components/ui/scroll-area.tsx +26 -0
  109. flow_atelier-0.1.7/frontend/src/components/ui/select.tsx +72 -0
  110. flow_atelier-0.1.7/frontend/src/components/ui/separator.tsx +26 -0
  111. flow_atelier-0.1.7/frontend/src/components/ui/sheet.tsx +101 -0
  112. flow_atelier-0.1.7/frontend/src/components/ui/toaster.tsx +23 -0
  113. flow_atelier-0.1.7/frontend/src/components/ui/tooltip.tsx +25 -0
  114. flow_atelier-0.1.7/frontend/src/config/env.ts +9 -0
  115. flow_atelier-0.1.7/frontend/src/constants/dashboard.ts +11 -0
  116. flow_atelier-0.1.7/frontend/src/constants/kanban.ts +19 -0
  117. flow_atelier-0.1.7/frontend/src/context/ThemeContext.tsx +55 -0
  118. flow_atelier-0.1.7/frontend/src/features/dashboard/Dashboard.tsx +165 -0
  119. flow_atelier-0.1.7/frontend/src/features/dashboard/components/conduit-picker.tsx +56 -0
  120. flow_atelier-0.1.7/frontend/src/features/dashboard/components/conduit-row.tsx +52 -0
  121. flow_atelier-0.1.7/frontend/src/features/dashboard/components/flow-history.tsx +434 -0
  122. flow_atelier-0.1.7/frontend/src/features/dashboard/components/hist-row.tsx +72 -0
  123. flow_atelier-0.1.7/frontend/src/features/dashboard/components/input-form.tsx +181 -0
  124. flow_atelier-0.1.7/frontend/src/features/dashboard/components/schedule-dialog.tsx +407 -0
  125. flow_atelier-0.1.7/frontend/src/features/dashboard/components/scheduled-jobs.tsx +152 -0
  126. flow_atelier-0.1.7/frontend/src/features/designer/Designer.tsx +689 -0
  127. flow_atelier-0.1.7/frontend/src/features/designer/components/Canvas.tsx +557 -0
  128. flow_atelier-0.1.7/frontend/src/features/designer/components/CanvasRulers.tsx +18 -0
  129. flow_atelier-0.1.7/frontend/src/features/designer/components/ConduitList.tsx +52 -0
  130. flow_atelier-0.1.7/frontend/src/features/designer/components/DepEdge.tsx +108 -0
  131. flow_atelier-0.1.7/frontend/src/features/designer/components/EdgeTypePopup.tsx +63 -0
  132. flow_atelier-0.1.7/frontend/src/features/designer/components/Inspector.tsx +602 -0
  133. flow_atelier-0.1.7/frontend/src/features/designer/components/Palette.tsx +139 -0
  134. flow_atelier-0.1.7/frontend/src/features/designer/components/TaskNode.tsx +71 -0
  135. flow_atelier-0.1.7/frontend/src/features/designer/components/ToolPanel.tsx +199 -0
  136. flow_atelier-0.1.7/frontend/src/features/designer/edge-popup-context.ts +13 -0
  137. flow_atelier-0.1.7/frontend/src/features/kanban/Kanban.tsx +388 -0
  138. flow_atelier-0.1.7/frontend/src/features/kanban/components/ConduitFlow.tsx +104 -0
  139. flow_atelier-0.1.7/frontend/src/features/kanban/components/DateRangePicker.tsx +96 -0
  140. flow_atelier-0.1.7/frontend/src/features/kanban/components/DeleteProjectDialog.tsx +91 -0
  141. flow_atelier-0.1.7/frontend/src/features/kanban/components/FieldRow.tsx +19 -0
  142. flow_atelier-0.1.7/frontend/src/features/kanban/components/KanbanColumn.tsx +65 -0
  143. flow_atelier-0.1.7/frontend/src/features/kanban/components/NewProjectDialog.tsx +68 -0
  144. flow_atelier-0.1.7/frontend/src/features/kanban/components/NewTaskDialog.tsx +217 -0
  145. flow_atelier-0.1.7/frontend/src/features/kanban/components/ProjectSelector.tsx +34 -0
  146. flow_atelier-0.1.7/frontend/src/features/kanban/components/RemoveTaskDialog.tsx +49 -0
  147. flow_atelier-0.1.7/frontend/src/features/kanban/components/TaskCard.tsx +100 -0
  148. flow_atelier-0.1.7/frontend/src/features/kanban/components/TaskCardRunning.tsx +129 -0
  149. flow_atelier-0.1.7/frontend/src/features/kanban/components/TaskDrawer.tsx +189 -0
  150. flow_atelier-0.1.7/frontend/src/features/kanban/components/TaskFlow.tsx +157 -0
  151. flow_atelier-0.1.7/frontend/src/features/kanban/components/useNewTaskDialog.ts +215 -0
  152. flow_atelier-0.1.7/frontend/src/features/kanban/toolMeta.ts +20 -0
  153. flow_atelier-0.1.7/frontend/src/hooks/useConduit.ts +442 -0
  154. flow_atelier-0.1.7/frontend/src/hooks/useIsMobile.ts +20 -0
  155. flow_atelier-0.1.7/frontend/src/hooks/useUndoState.ts +52 -0
  156. flow_atelier-0.1.7/frontend/src/layout/AppFrame.tsx +14 -0
  157. flow_atelier-0.1.7/frontend/src/layout/Footer.tsx +34 -0
  158. flow_atelier-0.1.7/frontend/src/layout/NavBar.tsx +49 -0
  159. flow_atelier-0.1.7/frontend/src/layout/ThemeToggle.tsx +25 -0
  160. flow_atelier-0.1.7/frontend/src/lib/cn.ts +6 -0
  161. flow_atelier-0.1.7/frontend/src/main.tsx +5 -0
  162. flow_atelier-0.1.7/frontend/src/pages/Designer.tsx +1 -0
  163. flow_atelier-0.1.7/frontend/src/pages/dashboard.tsx +5 -0
  164. flow_atelier-0.1.7/frontend/src/pages/kanban.tsx +3 -0
  165. flow_atelier-0.1.7/frontend/src/runner/engine.ts +377 -0
  166. flow_atelier-0.1.7/frontend/src/runner/hitl.ts +15 -0
  167. flow_atelier-0.1.7/frontend/src/runner/index.ts +15 -0
  168. flow_atelier-0.1.7/frontend/src/runner/prng.ts +17 -0
  169. flow_atelier-0.1.7/frontend/src/runner/store.ts +76 -0
  170. flow_atelier-0.1.7/frontend/src/services/ConduitProvider.tsx +68 -0
  171. flow_atelier-0.1.7/frontend/src/services/api/conduit-inputs.ts +29 -0
  172. flow_atelier-0.1.7/frontend/src/services/api/conduit-run-path.ts +26 -0
  173. flow_atelier-0.1.7/frontend/src/services/api/conduits.ts +74 -0
  174. flow_atelier-0.1.7/frontend/src/services/api/flows.ts +164 -0
  175. flow_atelier-0.1.7/frontend/src/services/api/run-conduit.ts +75 -0
  176. flow_atelier-0.1.7/frontend/src/services/api/run-task.ts +42 -0
  177. flow_atelier-0.1.7/frontend/src/services/api/schedules.ts +41 -0
  178. flow_atelier-0.1.7/frontend/src/services/client.ts +33 -0
  179. flow_atelier-0.1.7/frontend/src/services/conduits.ts +67 -0
  180. flow_atelier-0.1.7/frontend/src/services/mock/conduits.ts +319 -0
  181. flow_atelier-0.1.7/frontend/src/services/mock/flows.ts +118 -0
  182. flow_atelier-0.1.7/frontend/src/services/mock/logs.ts +214 -0
  183. flow_atelier-0.1.7/frontend/src/services/mock/run-task.ts +22 -0
  184. flow_atelier-0.1.7/frontend/src/services/mock/schedules.ts +121 -0
  185. flow_atelier-0.1.7/frontend/src/services/mock/tasks.ts +47 -0
  186. flow_atelier-0.1.7/frontend/src/services/mock/ws.ts +242 -0
  187. flow_atelier-0.1.7/frontend/src/services/storage/draft-conduit.ts +25 -0
  188. flow_atelier-0.1.7/frontend/src/services/storage/projects.ts +26 -0
  189. flow_atelier-0.1.7/frontend/src/services/transforms.ts +28 -0
  190. flow_atelier-0.1.7/frontend/src/styles/globals.css +157 -0
  191. flow_atelier-0.1.7/frontend/src/tests/cn.test.ts +36 -0
  192. flow_atelier-0.1.7/frontend/src/tests/conduit-reducer.test.ts +473 -0
  193. flow_atelier-0.1.7/frontend/src/tests/conduits.test.ts +85 -0
  194. flow_atelier-0.1.7/frontend/src/tests/format.test.ts +149 -0
  195. flow_atelier-0.1.7/frontend/src/tests/hitl.test.ts +57 -0
  196. flow_atelier-0.1.7/frontend/src/tests/logs.test.ts +33 -0
  197. flow_atelier-0.1.7/frontend/src/tests/prng.test.ts +56 -0
  198. flow_atelier-0.1.7/frontend/src/tests/run-task.test.ts +90 -0
  199. flow_atelier-0.1.7/frontend/src/tests/store.test.ts +141 -0
  200. flow_atelier-0.1.7/frontend/src/tests/transforms.test.ts +97 -0
  201. flow_atelier-0.1.7/frontend/src/tests/useIsMobile.test.ts +63 -0
  202. flow_atelier-0.1.7/frontend/src/tests/useUndoState.test.ts +130 -0
  203. flow_atelier-0.1.7/frontend/src/tests/yaml.test.ts +103 -0
  204. flow_atelier-0.1.7/frontend/src/types/api.ts +25 -0
  205. flow_atelier-0.1.7/frontend/src/types/conduit.ts +58 -0
  206. flow_atelier-0.1.7/frontend/src/types/flow.ts +9 -0
  207. flow_atelier-0.1.7/frontend/src/types/log.ts +6 -0
  208. flow_atelier-0.1.7/frontend/src/types/new.ts +0 -0
  209. flow_atelier-0.1.7/frontend/src/types/project.ts +4 -0
  210. flow_atelier-0.1.7/frontend/src/types/schedule.ts +22 -0
  211. flow_atelier-0.1.7/frontend/src/types/task.ts +49 -0
  212. flow_atelier-0.1.7/frontend/src/types/ws.ts +131 -0
  213. flow_atelier-0.1.7/frontend/src/utils/format.ts +45 -0
  214. flow_atelier-0.1.7/frontend/src/utils/yaml.ts +39 -0
  215. flow_atelier-0.1.7/frontend/src/vite-env.d.ts +1 -0
  216. flow_atelier-0.1.7/frontend/tsconfig.app.json +36 -0
  217. flow_atelier-0.1.7/frontend/tsconfig.json +7 -0
  218. flow_atelier-0.1.7/frontend/tsconfig.node.json +14 -0
  219. flow_atelier-0.1.7/frontend/vite.config.ts +72 -0
  220. flow_atelier-0.1.7/install.ps1 +123 -0
  221. flow_atelier-0.1.7/install.sh +114 -0
  222. flow_atelier-0.1.7/pyproject.toml +71 -0
  223. flow_atelier-0.1.7/scripts/atelier_entry.py +5 -0
  224. flow_atelier-0.1.7/scripts/verify_scheduler.sh +312 -0
  225. flow_atelier-0.1.7/tests/__init__.py +0 -0
  226. flow_atelier-0.1.7/tests/cli/test_add_cmd.py +159 -0
  227. flow_atelier-0.1.7/tests/cli/test_check_cmd.py +87 -0
  228. flow_atelier-0.1.7/tests/cli/test_create_cmd.py +82 -0
  229. flow_atelier-0.1.7/tests/cli/test_format_conduit_error.py +42 -0
  230. flow_atelier-0.1.7/tests/cli/test_init_cmd.py +55 -0
  231. flow_atelier-0.1.7/tests/cli/test_multiline_input.py +101 -0
  232. flow_atelier-0.1.7/tests/cli/test_parse_inputs.py +30 -0
  233. flow_atelier-0.1.7/tests/cli/test_plan_command.py +101 -0
  234. flow_atelier-0.1.7/tests/cli/test_render_steps.py +322 -0
  235. flow_atelier-0.1.7/tests/cli/test_rm_prune.py +217 -0
  236. flow_atelier-0.1.7/tests/cli/test_run_again.py +95 -0
  237. flow_atelier-0.1.7/tests/cli/test_run_readiness.py +46 -0
  238. flow_atelier-0.1.7/tests/cli/test_stop_cmd.py +115 -0
  239. flow_atelier-0.1.7/tests/cli/test_timing.py +149 -0
  240. flow_atelier-0.1.7/tests/cli/test_updater.py +219 -0
  241. flow_atelier-0.1.7/tests/conftest.py +40 -0
  242. flow_atelier-0.1.7/tests/core/__init__.py +0 -0
  243. flow_atelier-0.1.7/tests/core/test_atelier_conduit_crud.py +219 -0
  244. flow_atelier-0.1.7/tests/core/test_atelier_history.py +74 -0
  245. flow_atelier-0.1.7/tests/core/test_atelier_readiness.py +74 -0
  246. flow_atelier-0.1.7/tests/core/test_atelier_rerun.py +112 -0
  247. flow_atelier-0.1.7/tests/core/test_atelier_resume.py +250 -0
  248. flow_atelier-0.1.7/tests/core/test_atelier_run_task.py +73 -0
  249. flow_atelier-0.1.7/tests/core/test_atelier_schedules.py +169 -0
  250. flow_atelier-0.1.7/tests/core/test_settings.py +45 -0
  251. flow_atelier-0.1.7/tests/fixtures/fake_acp_agent.py +325 -0
  252. flow_atelier-0.1.7/tests/modules/__init__.py +0 -0
  253. flow_atelier-0.1.7/tests/modules/test_conditions.py +410 -0
  254. flow_atelier-0.1.7/tests/modules/test_engine.py +1968 -0
  255. flow_atelier-0.1.7/tests/modules/test_engine_resume.py +623 -0
  256. flow_atelier-0.1.7/tests/modules/test_engine_steps.py +217 -0
  257. flow_atelier-0.1.7/tests/modules/test_engine_stop.py +99 -0
  258. flow_atelier-0.1.7/tests/modules/test_liveness.py +176 -0
  259. flow_atelier-0.1.7/tests/modules/test_plan.py +164 -0
  260. flow_atelier-0.1.7/tests/modules/test_templating.py +228 -0
  261. flow_atelier-0.1.7/tests/schemas/__init__.py +0 -0
  262. flow_atelier-0.1.7/tests/schemas/test_api_schemas.py +246 -0
  263. flow_atelier-0.1.7/tests/schemas/test_intermediate_steps.py +142 -0
  264. flow_atelier-0.1.7/tests/schemas/test_schemas.py +539 -0
  265. flow_atelier-0.1.7/tests/schemas/test_ws_schemas.py +235 -0
  266. flow_atelier-0.1.7/tests/services/__init__.py +0 -0
  267. flow_atelier-0.1.7/tests/services/api/__init__.py +0 -0
  268. flow_atelier-0.1.7/tests/services/api/test_scheduler_bus.py +84 -0
  269. flow_atelier-0.1.7/tests/services/api/test_ws_hitl.py +97 -0
  270. flow_atelier-0.1.7/tests/services/executor/__init__.py +0 -0
  271. flow_atelier-0.1.7/tests/services/executor/test_bash.py +119 -0
  272. flow_atelier-0.1.7/tests/services/executor/test_conduit.py +297 -0
  273. flow_atelier-0.1.7/tests/services/executor/test_harness.py +996 -0
  274. flow_atelier-0.1.7/tests/services/executor/test_harness_steps.py +392 -0
  275. flow_atelier-0.1.7/tests/services/executor/test_hitl.py +170 -0
  276. flow_atelier-0.1.7/tests/services/executor/test_prompt_sink.py +256 -0
  277. flow_atelier-0.1.7/tests/services/executor/test_prompt_sink_steps.py +88 -0
  278. flow_atelier-0.1.7/tests/services/scheduler/__init__.py +0 -0
  279. flow_atelier-0.1.7/tests/services/scheduler/test_runner.py +553 -0
  280. flow_atelier-0.1.7/tests/services/scheduler/test_store.py +526 -0
  281. flow_atelier-0.1.7/tests/services/scheduler/test_triggers.py +208 -0
  282. flow_atelier-0.1.7/tests/services/store/__init__.py +0 -0
  283. flow_atelier-0.1.7/tests/services/store/test_filesystem.py +572 -0
  284. flow_atelier-0.1.7/tests/services/store/test_filesystem_resume.py +128 -0
  285. flow_atelier-0.1.7/tests/services/test_package.py +225 -0
  286. flow_atelier-0.1.7/tests/test_api/__init__.py +0 -0
  287. flow_atelier-0.1.7/tests/test_api/test_app_factory.py +130 -0
  288. flow_atelier-0.1.7/tests/test_api/test_conduits_api.py +272 -0
  289. flow_atelier-0.1.7/tests/test_api/test_flows_api.py +97 -0
  290. flow_atelier-0.1.7/tests/test_api/test_schedules_api.py +208 -0
  291. flow_atelier-0.1.7/tests/test_api/test_serve_smoke.py +75 -0
  292. flow_atelier-0.1.7/tests/test_api/test_tasks_api.py +104 -0
  293. flow_atelier-0.1.7/tests/test_api/test_ws_hitl_executor.py +158 -0
  294. flow_atelier-0.1.7/tests/test_api/test_ws_manager.py +175 -0
  295. flow_atelier-0.1.7/tests/test_api/test_ws_resume.py +129 -0
  296. flow_atelier-0.1.7/tests/test_api/test_ws_run_conduit.py +233 -0
  297. flow_atelier-0.1.7/tests/test_api/test_ws_scheduler_bus.py +87 -0
  298. flow_atelier-0.1.7/tests/test_api/test_ws_sink.py +68 -0
  299. flow_atelier-0.1.7/tests/test_api/test_ws_step_messages.py +52 -0
  300. flow_atelier-0.1.7/tests/test_init.py +98 -0
  301. flow_atelier-0.1.7/tests/test_integration.py +441 -0
  302. flow_atelier-0.1.7/tests/test_live_harness.py +188 -0
  303. flow_atelier-0.1.7/tests/test_main.py +1955 -0
  304. flow_atelier-0.1.7/uv.lock +921 -0
@@ -0,0 +1,43 @@
1
+ # flow-atelier environment variables
2
+ # Copy to .env and uncomment/override as needed. All have sensible defaults.
3
+
4
+ # Base directory for conduits/ and flows/. Default: ./.atelier
5
+ # ATELIER_ATELIER_DIR=.atelier
6
+
7
+ # Global directory for shared conduits (flows are always project-local).
8
+ # Default: ~/.atelier
9
+ # ATELIER_GLOBAL_ATELIER_DIR=~/.atelier
10
+
11
+ # Per-task default timeout in seconds. Default: 3600
12
+ # ATELIER_DEFAULT_TIMEOUT=3600
13
+
14
+ # Max tasks running in parallel within a conduit. Default: 3
15
+ # ATELIER_DEFAULT_MAX_CONCURRENCY=3
16
+
17
+ # Override the argv used to launch the harness:claude-code ACP agent.
18
+ # JSON array. Empty (default) uses: ["npx","-y","@zed-industries/claude-code-acp@0.16.2"]
19
+ # ATELIER_CLAUDE_LAUNCH_CMD=["npx","-y","@zed-industries/claude-code-acp@0.16.2"]
20
+
21
+ # Override the argv used to launch the harness:codex ACP agent.
22
+ # JSON array. Empty (default) uses: ["npx","-y","@zed-industries/codex-acp@0.11.1"]
23
+ # ATELIER_CODEX_LAUNCH_CMD=["npx","-y","@zed-industries/codex-acp@0.11.1"]
24
+
25
+ # Override the argv used to launch the harness:opencode ACP agent.
26
+ # JSON array. Empty (default) uses: ["opencode","acp"]
27
+ # ATELIER_OPENCODE_LAUNCH_CMD=["opencode","acp"]
28
+
29
+ # Override the argv used to launch the harness:copilot ACP agent.
30
+ # JSON array. Empty (default) uses: ["copilot","--acp"]
31
+ # ATELIER_COPILOT_LAUNCH_CMD=["copilot","--acp"]
32
+
33
+ # Override the argv used to launch the harness:cursor ACP agent.
34
+ # JSON array. Empty (default) uses: ["npx","-y","@blowmage/cursor-agent-acp@0.7.1"]
35
+ # ATELIER_CURSOR_LAUNCH_CMD=["npx","-y","@blowmage/cursor-agent-acp@0.7.1"]
36
+
37
+ # Token the harness looks for in interactive mode. Default: [ATELIER_DONE]
38
+ # ATELIER_DONE_MARKER=[ATELIER_DONE]
39
+
40
+ # Optional bearer token for the HTTP/WS API served by `atelier serve`.
41
+ # When set, REST requests need 'Authorization: Bearer <token>' and WS
42
+ # connections need '?token=<token>'. Empty (default) = no auth.
43
+ # ATELIER_API_TOKEN=
@@ -0,0 +1,36 @@
1
+ name: CI
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [main]
6
+ push:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ lint:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+ - uses: astral-sh/setup-uv@v5
15
+ with:
16
+ enable-cache: true
17
+ - run: uv python install 3.13
18
+ - run: uv sync --dev
19
+ - name: Lint (ruff)
20
+ run: uv run ruff check .
21
+
22
+ test:
23
+ strategy:
24
+ fail-fast: false
25
+ matrix:
26
+ os: [ubuntu-latest, macos-latest, windows-latest]
27
+ runs-on: ${{ matrix.os }}
28
+ steps:
29
+ - uses: actions/checkout@v4
30
+ - uses: astral-sh/setup-uv@v5
31
+ with:
32
+ enable-cache: true
33
+ - run: uv python install 3.13
34
+ - run: uv sync --dev
35
+ - name: Tests (live harness excluded via marker)
36
+ run: uv run pytest
@@ -0,0 +1,36 @@
1
+ name: "CLA Assistant"
2
+
3
+ on:
4
+ issue_comment:
5
+ types: [created]
6
+ pull_request_target:
7
+ types: [opened, closed, synchronize]
8
+
9
+ # Required so the action can store signatures and set the PR status.
10
+ permissions:
11
+ actions: write
12
+ contents: write
13
+ pull-requests: write
14
+ statuses: write
15
+
16
+ jobs:
17
+ CLAAssistant:
18
+ runs-on: ubuntu-latest
19
+ steps:
20
+ - name: "CLA Assistant"
21
+ if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target'
22
+ # Pin: verify the latest release at
23
+ # https://github.com/contributor-assistant/github-action/releases and bump as needed.
24
+ uses: contributor-assistant/github-action@v2.6.1
25
+ env:
26
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
27
+ with:
28
+ path-to-signatures: "signatures/version1/cla.json"
29
+ path-to-document: "https://github.com/LGuillermoAngaritaG/flow-atelier/blob/main/CLA.md"
30
+ # Signatures are committed here directly; it must be an UNPROTECTED
31
+ # branch (the main ruleset requires PRs, which blocks the action).
32
+ branch: "cla-signatures"
33
+ allowlist: LGuillermoAngaritaG,dependabot[bot],*[bot]
34
+ custom-notsigned-prcomment: "Thank you for your contribution. Before we can merge it, please read our [Contributor License Agreement](https://github.com/LGuillermoAngaritaG/flow-atelier/blob/main/CLA.md) and sign it by posting the comment below."
35
+ custom-pr-sign-comment: "I have read the CLA Document and I hereby sign the CLA"
36
+ custom-allsigned-prcomment: "All contributors have signed the CLA. Thank you!"
@@ -0,0 +1,77 @@
1
+ name: Frontend
2
+
3
+ # Builds the React/Vite UI under frontend/ and syncs its build output into
4
+ # flow_atelier/dist/ — the bundled SPA that ships in the wheel and is served by
5
+ # the FastAPI app (see flow_atelier/services/api/app.py, _STATIC_DIR).
6
+ #
7
+ # On pushes to main the rebuilt bundle is committed back so the repo (and the
8
+ # published wheel) always carry a current UI. The commit is made with
9
+ # GITHUB_TOKEN and tagged [skip ci]; GITHUB_TOKEN pushes do not re-trigger
10
+ # workflows, so there is no build loop. On PRs the workflow builds as a check
11
+ # only and does not commit.
12
+
13
+ on:
14
+ workflow_dispatch:
15
+ push:
16
+ branches: [main]
17
+ paths:
18
+ - "frontend/**"
19
+ - ".github/workflows/frontend.yml"
20
+ pull_request:
21
+ branches: [main]
22
+ paths:
23
+ - "frontend/**"
24
+ - ".github/workflows/frontend.yml"
25
+
26
+ permissions:
27
+ contents: write
28
+
29
+ concurrency:
30
+ group: frontend-${{ github.ref }}
31
+ # Do not cancel a run that may be mid-commit/push to main.
32
+ cancel-in-progress: false
33
+
34
+ jobs:
35
+ build:
36
+ runs-on: ubuntu-latest
37
+ defaults:
38
+ run:
39
+ working-directory: frontend
40
+ steps:
41
+ - uses: actions/checkout@v4
42
+
43
+ - uses: actions/setup-node@v4
44
+ with:
45
+ node-version: "22"
46
+ cache: npm
47
+ cache-dependency-path: frontend/package-lock.json
48
+
49
+ - name: Install dependencies
50
+ run: npm ci
51
+
52
+ - name: Build
53
+ # For a production bundle set VITE_USE_MOCK_API / VITE_BACKEND_URL via
54
+ # repo variables or secrets; left unset, the build ships mock data.
55
+ run: npm run build
56
+
57
+ - name: Sync build output to flow_atelier/dist
58
+ working-directory: .
59
+ run: |
60
+ rm -rf flow_atelier/dist
61
+ cp -r frontend/dist flow_atelier/dist
62
+
63
+ - name: Commit bundled UI
64
+ if: >-
65
+ (github.event_name == 'push' || github.event_name == 'workflow_dispatch')
66
+ && github.ref == 'refs/heads/main'
67
+ working-directory: .
68
+ run: |
69
+ git config user.name "github-actions[bot]"
70
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
71
+ git add flow_atelier/dist
72
+ if git diff --cached --quiet; then
73
+ echo "No UI changes — nothing to commit."
74
+ else
75
+ git commit -m "chore(ui): rebuild bundled frontend [skip ci]"
76
+ git push
77
+ fi
@@ -0,0 +1,123 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags: ["v*"]
6
+
7
+ permissions:
8
+ contents: write
9
+ id-token: write
10
+
11
+ jobs:
12
+ verify-version:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ - name: Tag matches pyproject version
17
+ run: |
18
+ tag="${GITHUB_REF_NAME#v}"
19
+ pyver=$(grep -E '^version = ' pyproject.toml | head -1 | cut -d'"' -f2)
20
+ test "$tag" = "$pyver" || { echo "tag $tag != pyproject $pyver"; exit 1; }
21
+
22
+ test:
23
+ runs-on: ubuntu-latest
24
+ steps:
25
+ - uses: actions/checkout@v4
26
+ - uses: astral-sh/setup-uv@v5
27
+ with:
28
+ enable-cache: true
29
+ - run: uv python install 3.13
30
+ - run: uv sync --dev
31
+ - run: uv run ruff check .
32
+ - run: uv run pytest
33
+
34
+ build-wheel:
35
+ needs: [verify-version, test]
36
+ runs-on: ubuntu-latest
37
+ steps:
38
+ - uses: actions/checkout@v4
39
+ - uses: astral-sh/setup-uv@v5
40
+ with:
41
+ enable-cache: true
42
+ - run: uv python install 3.13
43
+ - run: uv build
44
+ - uses: actions/upload-artifact@v4
45
+ with:
46
+ name: dist
47
+ path: dist/*
48
+
49
+ build-binary:
50
+ needs: [verify-version, test]
51
+ strategy:
52
+ fail-fast: false
53
+ matrix:
54
+ include:
55
+ - os: ubuntu-latest
56
+ asset: atelier-linux-x86_64
57
+ bin: atelier
58
+ - os: macos-latest
59
+ asset: atelier-macos-arm64
60
+ bin: atelier
61
+ - os: windows-latest
62
+ asset: atelier-windows-x86_64.exe
63
+ bin: atelier.exe
64
+ runs-on: ${{ matrix.os }}
65
+ steps:
66
+ - uses: actions/checkout@v4
67
+ - uses: astral-sh/setup-uv@v5
68
+ with:
69
+ enable-cache: true
70
+ - run: uv python install 3.13
71
+ - run: uv sync --dev
72
+ - name: Build binary
73
+ shell: bash
74
+ run: |
75
+ uv run pyinstaller scripts/atelier_entry.py \
76
+ --onefile --name atelier --clean --noconfirm \
77
+ --copy-metadata flow-atelier \
78
+ --collect-all uvicorn \
79
+ --collect-all apscheduler \
80
+ --collect-all tzdata \
81
+ --collect-all agent_client_protocol
82
+ - name: Smoke test the binary
83
+ shell: bash
84
+ run: |
85
+ ./dist/${{ matrix.bin }} --help
86
+ ./dist/${{ matrix.bin }} --version
87
+ - name: Rename for upload
88
+ shell: bash
89
+ run: mv dist/${{ matrix.bin }} dist/${{ matrix.asset }}
90
+ - uses: actions/upload-artifact@v4
91
+ with:
92
+ name: bin-${{ matrix.os }}
93
+ path: dist/${{ matrix.asset }}
94
+
95
+ publish-pypi:
96
+ needs: [build-wheel, build-binary]
97
+ runs-on: ubuntu-latest
98
+ environment: pypi
99
+ steps:
100
+ - uses: actions/download-artifact@v4
101
+ with:
102
+ name: dist
103
+ path: dist
104
+ - uses: pypa/gh-action-pypi-publish@release/v1
105
+
106
+ github-release:
107
+ needs: [build-wheel, build-binary]
108
+ runs-on: ubuntu-latest
109
+ steps:
110
+ - uses: actions/checkout@v4
111
+ - uses: actions/download-artifact@v4
112
+ with:
113
+ path: artifacts
114
+ - name: Flatten artifacts
115
+ run: mkdir -p release && find artifacts -type f -exec cp {} release/ \;
116
+ - name: Generate SHA256SUMS
117
+ working-directory: release
118
+ run: sha256sum * > SHA256SUMS
119
+ - uses: softprops/action-gh-release@v2
120
+ with:
121
+ files: release/*
122
+ generate_release_notes: true
123
+ fail_on_unmatched_files: true
@@ -0,0 +1,32 @@
1
+ .env
2
+ # Python-generated files
3
+ __pycache__/
4
+ *.py[oc]
5
+ build/
6
+ /dist/
7
+ wheels/
8
+ *.egg-info
9
+ *.spec
10
+ .ruff_cache/
11
+
12
+ # Virtual environments
13
+ .venv*
14
+ .claude
15
+ .atelier/flows
16
+ .devtool
17
+ claude.md
18
+ .pytest_cache
19
+ .DS_Store
20
+ .opencode
21
+ AGENTS.md
22
+ .agents/
23
+ .atelier/
24
+
25
+ # Frontend (React/Vite) — tooling & local build artifacts under frontend/.
26
+ # NOTE: flow_atelier/dist/ is intentionally NOT ignored — it is the committed
27
+ frontend/node_modules/
28
+ frontend/dist/
29
+ frontend/coverage/
30
+ frontend/.devtool/
31
+ frontend/.env
32
+ *.tsbuildinfo
@@ -0,0 +1,15 @@
1
+ repos:
2
+ - repo: https://github.com/astral-sh/ruff-pre-commit
3
+ rev: v0.15.12
4
+ hooks:
5
+ - id: ruff
6
+ args: [--fix]
7
+
8
+ - repo: local
9
+ hooks:
10
+ - id: pytest
11
+ name: pytest (live harness excluded via marker)
12
+ entry: uv run pytest
13
+ language: system
14
+ pass_filenames: false
15
+ stages: [pre-push]
@@ -0,0 +1 @@
1
+ 3.13
@@ -0,0 +1,121 @@
1
+ # flow-atelier Individual Contributor License Agreement (CLA)
2
+
3
+ Thank you for your interest in contributing to flow-atelier (the "Project"),
4
+ maintained by Guillermo Angarita (the "Owner").
5
+
6
+ This Contributor License Agreement ("Agreement") documents the rights granted by
7
+ contributors to the Owner. It protects the Project and its users, and it lets
8
+ the Owner offer the Project under open source and, where applicable, commercial
9
+ terms. By signing this Agreement, you accept and agree to the following terms
10
+ for your present and future Contributions submitted to the Project. Except for
11
+ the licenses granted here to the Owner, you retain all right, title, and
12
+ interest in and to your Contributions.
13
+
14
+ ## 1. Definitions
15
+
16
+ "You" (or "Your") means the individual who submits a Contribution to the
17
+ Project, or the legal entity on behalf of whom this Agreement is signed.
18
+
19
+ "Contribution" means any original work of authorship, including any
20
+ modifications or additions to an existing work, that is intentionally submitted
21
+ by You to the Owner for inclusion in, or documentation of, the Project. For the
22
+ purposes of this definition, "submitted" means any form of electronic, verbal,
23
+ or written communication sent to the Owner or its representatives, including but
24
+ not limited to communication on electronic mailing lists, source code control
25
+ systems, and issue tracking systems that are managed by, or on behalf of, the
26
+ Owner, but excluding communication that is conspicuously marked or otherwise
27
+ designated in writing by You as "Not a Contribution."
28
+
29
+ ## 2. Grant of Copyright License
30
+
31
+ Subject to the terms and conditions of this Agreement, You hereby grant to the
32
+ Owner and to recipients of software distributed by the Owner a perpetual,
33
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license
34
+ to reproduce, prepare derivative works of, publicly display, publicly perform,
35
+ and distribute Your Contributions and such derivative works.
36
+
37
+ You further grant the Owner the right to **license and sublicense Your
38
+ Contributions, and derivative works of them, under any license terms**,
39
+ including open source licenses, source-available licenses, and proprietary or
40
+ commercial licenses, and to relicense the Project (including Your Contributions)
41
+ under different terms in the future. This right is what allows the Owner to
42
+ maintain the Project as open source while also offering commercial or
43
+ dual-licensed editions.
44
+
45
+ ## 3. Grant of Patent License
46
+
47
+ Subject to the terms and conditions of this Agreement, You hereby grant to the
48
+ Owner and to recipients of software distributed by the Owner a perpetual,
49
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated
50
+ in this section) patent license to make, have made, use, offer to sell, sell,
51
+ import, and otherwise transfer Your Contributions, where such license applies
52
+ only to those patent claims licensable by You that are necessarily infringed by
53
+ Your Contribution(s) alone or by combination of Your Contribution(s) with the
54
+ work to which such Contribution(s) was submitted. If any entity institutes
55
+ patent litigation against You or any other entity (including a cross-claim or
56
+ counterclaim in a lawsuit) alleging that Your Contribution, or the work to which
57
+ You have contributed, constitutes direct or contributory patent infringement,
58
+ then any patent licenses granted to that entity under this Agreement for that
59
+ Contribution or work shall terminate as of the date such litigation is filed.
60
+
61
+ ## 4. Your Representations
62
+
63
+ You represent that:
64
+
65
+ (a) You are legally entitled to grant the above licenses. If Your employer(s)
66
+ have rights to intellectual property that You create that includes Your
67
+ Contributions, You represent that You have received permission to make
68
+ Contributions on behalf of that employer, that Your employer has waived such
69
+ rights for Your Contributions to the Owner, or that Your employer has
70
+ executed a separate Corporate CLA with the Owner.
71
+
72
+ (b) Each of Your Contributions is Your original creation (see Section 5 for
73
+ submissions on behalf of others).
74
+
75
+ (c) Your Contribution submissions include complete details of any third-party
76
+ license or other restriction (including, but not limited to, related
77
+ patents and trademarks) of which You are personally aware and which are
78
+ associated with any part of Your Contributions.
79
+
80
+ ## 5. Third-Party Works
81
+
82
+ Should You wish to submit work that is not Your original creation, You may submit
83
+ it to the Owner separately from any Contribution, identifying the complete
84
+ details of its source and of any license or other restriction (including, but
85
+ not limited to, related patents, trademarks, and license agreements) of which
86
+ You are personally aware, and conspicuously marking the work as "Submitted on
87
+ behalf of a third-party: [named here]".
88
+
89
+ ## 6. No Obligation; No Warranty
90
+
91
+ You are not expected to provide support for Your Contributions, except to the
92
+ extent You desire to provide support. You may provide support for free, for a
93
+ fee, or not at all. Unless required by applicable law or agreed to in writing,
94
+ You provide Your Contributions on an "AS IS" BASIS, WITHOUT WARRANTIES OR
95
+ CONDITIONS OF ANY KIND, either express or implied, including, without
96
+ limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT,
97
+ MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE.
98
+
99
+ The Owner is not obligated to use, include, or distribute Your Contributions.
100
+
101
+ ## 7. Notification
102
+
103
+ You agree to notify the Owner of any facts or circumstances of which You become
104
+ aware that would make these representations inaccurate in any respect.
105
+
106
+ ---
107
+
108
+ ## How to sign
109
+
110
+ You sign this Agreement electronically when you open your first pull request: an
111
+ automated assistant will comment on the PR with instructions. To sign, you post
112
+ a comment on the pull request containing exactly:
113
+
114
+ > I have read the CLA Document and I hereby sign the CLA
115
+
116
+ Your GitHub username and the signing event are recorded in
117
+ `signatures/version1/cla.json` in this repository. One signature covers all of
118
+ your present and future Contributions to the Project.
119
+
120
+ **Corporate contributors:** if you are contributing on behalf of a company,
121
+ contact the Owner to arrange a Corporate CLA before submitting.
@@ -0,0 +1,50 @@
1
+ # Contributing to flow-atelier
2
+
3
+ Thanks for your interest in contributing. This document explains how to submit
4
+ changes and the legal terms under which contributions are accepted.
5
+
6
+ ## License of contributions
7
+
8
+ flow-atelier is open source under the [Apache License, Version 2.0](LICENSE).
9
+ The Project is also developed as an open-core product: some editions or
10
+ companion services may be offered under commercial terms. To keep both models
11
+ possible, contributions are accepted under a Contributor License Agreement.
12
+
13
+ ## Contributor License Agreement (CLA)
14
+
15
+ Before your contribution can be merged, you must sign the
16
+ [Contributor License Agreement](CLA.md). The CLA confirms you have the right to
17
+ submit your work and grants the Owner the rights needed to distribute it as open
18
+ source and, where applicable, under commercial terms. You keep the copyright to
19
+ your contributions.
20
+
21
+ Signing is a one-time, automated step:
22
+
23
+ 1. Open your pull request.
24
+ 2. The CLA Assistant bot will comment on the PR with a link to the CLA.
25
+ 3. Reply on the PR with exactly:
26
+
27
+ > I have read the CLA Document and I hereby sign the CLA
28
+
29
+ 4. The bot records your signature in `signatures/version1/cla.json`. One
30
+ signature covers all your present and future contributions.
31
+
32
+ If you are contributing on behalf of a company, contact the Owner to arrange a
33
+ Corporate CLA before submitting.
34
+
35
+ ## How to contribute
36
+
37
+ 1. Fork the repository and create a branch from `main`.
38
+ 2. Make your change. Keep commits focused and write clear messages.
39
+ 3. Run the test suite and linters locally before opening a PR:
40
+ ```bash
41
+ uv run pytest
42
+ uv run ruff check .
43
+ ```
44
+ 4. Open a pull request describing what the change does and why.
45
+ 5. Sign the CLA when the bot prompts you (see above).
46
+
47
+ ## Reporting bugs and requesting features
48
+
49
+ Open an issue on GitHub. For bugs, include the flow-atelier version, your OS,
50
+ the conduit or command you ran, and the full output.