functualize 0.1.0__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 (350) hide show
  1. functualize-0.1.0/.gitignore +101 -0
  2. functualize-0.1.0/CHANGELOG.md +194 -0
  3. functualize-0.1.0/LICENSE +21 -0
  4. functualize-0.1.0/PKG-INFO +922 -0
  5. functualize-0.1.0/README.md +873 -0
  6. functualize-0.1.0/pyproject.toml +253 -0
  7. functualize-0.1.0/src/functualize/__init__.py +27 -0
  8. functualize-0.1.0/src/functualize/__main__.py +8 -0
  9. functualize-0.1.0/src/functualize/_app/__init__.py +101 -0
  10. functualize-0.1.0/src/functualize/_app/boot.py +1226 -0
  11. functualize-0.1.0/src/functualize/_app/decorators.py +151 -0
  12. functualize-0.1.0/src/functualize/_app/environment.py +65 -0
  13. functualize-0.1.0/src/functualize/_app/impl.py +817 -0
  14. functualize-0.1.0/src/functualize/_app/models.py +31 -0
  15. functualize-0.1.0/src/functualize/_app/state.py +50 -0
  16. functualize-0.1.0/src/functualize/_cli/__init__.py +11 -0
  17. functualize-0.1.0/src/functualize/_cli/annotation_utils.py +233 -0
  18. functualize-0.1.0/src/functualize/_cli/builtins.py +1376 -0
  19. functualize-0.1.0/src/functualize/_cli/completions/__init__.py +38 -0
  20. functualize-0.1.0/src/functualize/_cli/completions/cursor_context.py +257 -0
  21. functualize-0.1.0/src/functualize/_cli/completions/data.py +199 -0
  22. functualize-0.1.0/src/functualize/_cli/completions/engine.py +269 -0
  23. functualize-0.1.0/src/functualize/_cli/completions/flag_filtering.py +64 -0
  24. functualize-0.1.0/src/functualize/_cli/completions/provenance.py +240 -0
  25. functualize-0.1.0/src/functualize/_cli/completions/quote_handling.py +95 -0
  26. functualize-0.1.0/src/functualize/_cli/completions/shell_init.py +256 -0
  27. functualize-0.1.0/src/functualize/_cli/config.py +808 -0
  28. functualize-0.1.0/src/functualize/_cli/data/__init__.py +40 -0
  29. functualize-0.1.0/src/functualize/_cli/data/argument_history.py +255 -0
  30. functualize-0.1.0/src/functualize/_cli/data/config_snapshot_store.py +242 -0
  31. functualize-0.1.0/src/functualize/_cli/data/config_target.py +47 -0
  32. functualize-0.1.0/src/functualize/_cli/data/func_settings.py +938 -0
  33. functualize-0.1.0/src/functualize/_cli/data/invocation_preset.py +106 -0
  34. functualize-0.1.0/src/functualize/_cli/data/override_applicator.py +141 -0
  35. functualize-0.1.0/src/functualize/_cli/data/path_suggestion.py +27 -0
  36. functualize-0.1.0/src/functualize/_cli/data/pending_execution.py +124 -0
  37. functualize-0.1.0/src/functualize/_cli/data/resolved_value_compat.py +45 -0
  38. functualize-0.1.0/src/functualize/_cli/data/settings_schema.py +173 -0
  39. functualize-0.1.0/src/functualize/_cli/data/shortcut_generator.py +195 -0
  40. functualize-0.1.0/src/functualize/_cli/data/toml_writer.py +320 -0
  41. functualize-0.1.0/src/functualize/_cli/dispatch.py +815 -0
  42. functualize-0.1.0/src/functualize/_cli/inline_tui.py +251 -0
  43. functualize-0.1.0/src/functualize/_cli/introspect.py +416 -0
  44. functualize-0.1.0/src/functualize/_cli/main.py +1935 -0
  45. functualize-0.1.0/src/functualize/_cli/orchestrator.py +80 -0
  46. functualize-0.1.0/src/functualize/_cli/parallel_output.py +150 -0
  47. functualize-0.1.0/src/functualize/_cli/pep723.py +314 -0
  48. functualize-0.1.0/src/functualize/_cli/scaffold/__init__.py +5 -0
  49. functualize-0.1.0/src/functualize/_cli/scaffold/cli.py +391 -0
  50. functualize-0.1.0/src/functualize/_cli/scaffold/context.py +62 -0
  51. functualize-0.1.0/src/functualize/_cli/scaffold/generator.py +557 -0
  52. functualize-0.1.0/src/functualize/_cli/scaffold/registry.py +69 -0
  53. functualize-0.1.0/src/functualize/_cli/scaffold/templates/__init__.py +0 -0
  54. functualize-0.1.0/src/functualize/_cli/scaffold/templates/_shared/config.base.toml.j2 +11 -0
  55. functualize-0.1.0/src/functualize/_cli/scaffold/templates/_shared/config.dev.toml.j2 +10 -0
  56. functualize-0.1.0/src/functualize/_cli/scaffold/templates/_shared/config.prod.toml.j2 +10 -0
  57. functualize-0.1.0/src/functualize/_cli/scaffold/templates/config.base.ini.j2 +28 -0
  58. functualize-0.1.0/src/functualize/_cli/scaffold/templates/config.base.toml.j2 +36 -0
  59. functualize-0.1.0/src/functualize/_cli/scaffold/templates/domain-plugin/__init__.py.j2 +5 -0
  60. functualize-0.1.0/src/functualize/_cli/scaffold/templates/domain-plugin/_plugin.py.j2 +27 -0
  61. functualize-0.1.0/src/functualize/_cli/scaffold/templates/domain-plugin/pyproject.toml.j2 +20 -0
  62. functualize-0.1.0/src/functualize/_cli/scaffold/templates/domain-plugin/test_plugin.py.j2 +34 -0
  63. functualize-0.1.0/src/functualize/_cli/scaffold/templates/domain-sdk/__init__.py.j2 +12 -0
  64. functualize-0.1.0/src/functualize/_cli/scaffold/templates/domain-sdk/_errors.py.j2 +9 -0
  65. functualize-0.1.0/src/functualize/_cli/scaffold/templates/domain-sdk/_events.py.j2 +6 -0
  66. functualize-0.1.0/src/functualize/_cli/scaffold/templates/domain-sdk/_metadata.py.j2 +37 -0
  67. functualize-0.1.0/src/functualize/_cli/scaffold/templates/domain-sdk/_protocols.py.j2 +12 -0
  68. functualize-0.1.0/src/functualize/_cli/scaffold/templates/domain-sdk/_types.py.j2 +3 -0
  69. functualize-0.1.0/src/functualize/_cli/scaffold/templates/domain-sdk/pyproject.toml.j2 +20 -0
  70. functualize-0.1.0/src/functualize/_cli/scaffold/templates/domain-sdk/testing/__init__.py.j2 +3 -0
  71. functualize-0.1.0/src/functualize/_cli/scaffold/templates/file_plugin.py.j2 +50 -0
  72. functualize-0.1.0/src/functualize/_cli/scaffold/templates/full-interactivity/README.md.j2 +88 -0
  73. functualize-0.1.0/src/functualize/_cli/scaffold/templates/full-interactivity/__init__.py.j2 +3 -0
  74. functualize-0.1.0/src/functualize/_cli/scaffold/templates/full-interactivity/events_job.py.j2 +56 -0
  75. functualize-0.1.0/src/functualize/_cli/scaffold/templates/full-interactivity/interactive_job.py.j2 +62 -0
  76. functualize-0.1.0/src/functualize/_cli/scaffold/templates/full-interactivity/main.py.j2 +30 -0
  77. functualize-0.1.0/src/functualize/_cli/scaffold/templates/full-interactivity/pyproject.toml.j2 +36 -0
  78. functualize-0.1.0/src/functualize/_cli/scaffold/templates/full-interactivity/workflow_job.py.j2 +53 -0
  79. functualize-0.1.0/src/functualize/_cli/scaffold/templates/job-folder/README.md.j2 +84 -0
  80. functualize-0.1.0/src/functualize/_cli/scaffold/templates/job-folder/config.base.toml.j2 +13 -0
  81. functualize-0.1.0/src/functualize/_cli/scaffold/templates/job-folder/file_plugin.py.j2 +56 -0
  82. functualize-0.1.0/src/functualize/_cli/scaffold/templates/job-folder/sample_job.py.j2 +33 -0
  83. functualize-0.1.0/src/functualize/_cli/scaffold/templates/job.py.j2 +63 -0
  84. functualize-0.1.0/src/functualize/_cli/scaffold/templates/main.py.j2 +21 -0
  85. functualize-0.1.0/src/functualize/_cli/scaffold/templates/plugin-project/README.md.j2 +58 -0
  86. functualize-0.1.0/src/functualize/_cli/scaffold/templates/plugin-project/__init__.py.j2 +3 -0
  87. functualize-0.1.0/src/functualize/_cli/scaffold/templates/plugin-project/plugin.py.j2 +10 -0
  88. functualize-0.1.0/src/functualize/_cli/scaffold/templates/plugin-project/provider.py.j2 +29 -0
  89. functualize-0.1.0/src/functualize/_cli/scaffold/templates/plugin-project/pyproject.toml.j2 +20 -0
  90. functualize-0.1.0/src/functualize/_cli/scaffold/templates/plugin-project/renderer.py.j2 +29 -0
  91. functualize-0.1.0/src/functualize/_cli/scaffold/templates/plugin.py.j2 +35 -0
  92. functualize-0.1.0/src/functualize/_cli/scaffold/templates/pyproject.toml.j2 +31 -0
  93. functualize-0.1.0/src/functualize/_cli/scaffold/templates/screen.py.j2 +21 -0
  94. functualize-0.1.0/src/functualize/_cli/scaffold/templates/screen.tcss.j2 +7 -0
  95. functualize-0.1.0/src/functualize/_cli/scaffold/templates/simple/README.md.j2 +71 -0
  96. functualize-0.1.0/src/functualize/_cli/scaffold/templates/simple/__init__.py.j2 +3 -0
  97. functualize-0.1.0/src/functualize/_cli/scaffold/templates/simple/main.py.j2 +21 -0
  98. functualize-0.1.0/src/functualize/_cli/scaffold/templates/simple/pyproject.toml.j2 +31 -0
  99. functualize-0.1.0/src/functualize/_cli/scaffold/templates/simple/sample_job.py.j2 +43 -0
  100. functualize-0.1.0/src/functualize/_cli/scaffold/templates/standalone_job.py.j2 +41 -0
  101. functualize-0.1.0/src/functualize/_cli/stdin_reader.py +176 -0
  102. functualize-0.1.0/src/functualize/_cli/tui/__init__.py +90 -0
  103. functualize-0.1.0/src/functualize/_cli/tui/app.py +2606 -0
  104. functualize-0.1.0/src/functualize/_cli/tui/bar.py +260 -0
  105. functualize-0.1.0/src/functualize/_cli/tui/bar_items.py +132 -0
  106. functualize-0.1.0/src/functualize/_cli/tui/breadcrumb_header_widget.py +67 -0
  107. functualize-0.1.0/src/functualize/_cli/tui/chain_resolution.py +499 -0
  108. functualize-0.1.0/src/functualize/_cli/tui/cli_arg_parser.py +206 -0
  109. functualize-0.1.0/src/functualize/_cli/tui/config_diff.py +108 -0
  110. functualize-0.1.0/src/functualize/_cli/tui/config_target_discovery.py +148 -0
  111. functualize-0.1.0/src/functualize/_cli/tui/descriptor_fields.py +21 -0
  112. functualize-0.1.0/src/functualize/_cli/tui/diff_view_widget.py +408 -0
  113. functualize-0.1.0/src/functualize/_cli/tui/display_affinity.py +144 -0
  114. functualize-0.1.0/src/functualize/_cli/tui/display_chrome.py +45 -0
  115. functualize-0.1.0/src/functualize/_cli/tui/display_provider_discovery.py +229 -0
  116. functualize-0.1.0/src/functualize/_cli/tui/display_slot.py +858 -0
  117. functualize-0.1.0/src/functualize/_cli/tui/dynamic_footer.py +25 -0
  118. functualize-0.1.0/src/functualize/_cli/tui/dynamic_footer_widget.py +62 -0
  119. functualize-0.1.0/src/functualize/_cli/tui/dynamic_input_bar.py +165 -0
  120. functualize-0.1.0/src/functualize/_cli/tui/editable_table.py +406 -0
  121. functualize-0.1.0/src/functualize/_cli/tui/field_priority.py +41 -0
  122. functualize-0.1.0/src/functualize/_cli/tui/focus.py +161 -0
  123. functualize-0.1.0/src/functualize/_cli/tui/functualize_autocomplete.py +365 -0
  124. functualize-0.1.0/src/functualize/_cli/tui/insert_mode.py +241 -0
  125. functualize-0.1.0/src/functualize/_cli/tui/integration.py +155 -0
  126. functualize-0.1.0/src/functualize/_cli/tui/job_execution.py +617 -0
  127. functualize-0.1.0/src/functualize/_cli/tui/job_listing.py +128 -0
  128. functualize-0.1.0/src/functualize/_cli/tui/key_handler.py +263 -0
  129. functualize-0.1.0/src/functualize/_cli/tui/live_panel_widget.py +147 -0
  130. functualize-0.1.0/src/functualize/_cli/tui/missing_args.py +110 -0
  131. functualize-0.1.0/src/functualize/_cli/tui/modals/__init__.py +5 -0
  132. functualize-0.1.0/src/functualize/_cli/tui/models/__init__.py +1 -0
  133. functualize-0.1.0/src/functualize/_cli/tui/models/focus_state.py +206 -0
  134. functualize-0.1.0/src/functualize/_cli/tui/models/panel_ring_controller.py +150 -0
  135. functualize-0.1.0/src/functualize/_cli/tui/models/ring_models.py +287 -0
  136. functualize-0.1.0/src/functualize/_cli/tui/models/source_chain.py +176 -0
  137. functualize-0.1.0/src/functualize/_cli/tui/new_file_picker.py +159 -0
  138. functualize-0.1.0/src/functualize/_cli/tui/panel_host.py +477 -0
  139. functualize-0.1.0/src/functualize/_cli/tui/panel_live_zone.py +287 -0
  140. functualize-0.1.0/src/functualize/_cli/tui/panels/__init__.py +109 -0
  141. functualize-0.1.0/src/functualize/_cli/tui/panels/config_files.py +689 -0
  142. functualize-0.1.0/src/functualize/_cli/tui/panels/config_table.py +513 -0
  143. functualize-0.1.0/src/functualize/_cli/tui/panels/job_browser.py +224 -0
  144. functualize-0.1.0/src/functualize/_cli/tui/panels/ring.py +114 -0
  145. functualize-0.1.0/src/functualize/_cli/tui/panels/settings_files.py +95 -0
  146. functualize-0.1.0/src/functualize/_cli/tui/path_field_editor.py +390 -0
  147. functualize-0.1.0/src/functualize/_cli/tui/path_suggestion_scanner.py +180 -0
  148. functualize-0.1.0/src/functualize/_cli/tui/preflight_summary.py +218 -0
  149. functualize-0.1.0/src/functualize/_cli/tui/preflight_widget.py +168 -0
  150. functualize-0.1.0/src/functualize/_cli/tui/settings_panel.py +415 -0
  151. functualize-0.1.0/src/functualize/_cli/tui/settings_validator.py +24 -0
  152. functualize-0.1.0/src/functualize/_cli/tui/shell_mode.py +322 -0
  153. functualize-0.1.0/src/functualize/_cli/tui/shortcut_save_modal.py +376 -0
  154. functualize-0.1.0/src/functualize/_cli/tui/smart_bar_autocomplete.py +944 -0
  155. functualize-0.1.0/src/functualize/_cli/tui/source_chain_detail.py +502 -0
  156. functualize-0.1.0/src/functualize/_cli/tui/source_chain_providers.py +348 -0
  157. functualize-0.1.0/src/functualize/_cli/tui/sync.py +162 -0
  158. functualize-0.1.0/src/functualize/_cli/tui/theme_manager.py +145 -0
  159. functualize-0.1.0/src/functualize/_cli/tui/thread_marshal.py +62 -0
  160. functualize-0.1.0/src/functualize/_cli/tui/type_hint_formatter.py +118 -0
  161. functualize-0.1.0/src/functualize/_config/__init__.py +44 -0
  162. functualize-0.1.0/src/functualize/_config/_emit.py +62 -0
  163. functualize-0.1.0/src/functualize/_config/chain.py +223 -0
  164. functualize-0.1.0/src/functualize/_config/cli_adapter.py +232 -0
  165. functualize-0.1.0/src/functualize/_config/errors.py +168 -0
  166. functualize-0.1.0/src/functualize/_config/interactivity.py +26 -0
  167. functualize-0.1.0/src/functualize/_config/job_config.py +453 -0
  168. functualize-0.1.0/src/functualize/_config/manifest.py +106 -0
  169. functualize-0.1.0/src/functualize/_config/merge.py +75 -0
  170. functualize-0.1.0/src/functualize/_config/migration.py +91 -0
  171. functualize-0.1.0/src/functualize/_config/protocols.py +145 -0
  172. functualize-0.1.0/src/functualize/_config/providers/__init__.py +16 -0
  173. functualize-0.1.0/src/functualize/_config/providers/ini.py +78 -0
  174. functualize-0.1.0/src/functualize/_config/providers/toml.py +191 -0
  175. functualize-0.1.0/src/functualize/_config/registry.py +213 -0
  176. functualize-0.1.0/src/functualize/_config/roles.py +80 -0
  177. functualize-0.1.0/src/functualize/_config/sources.py +837 -0
  178. functualize-0.1.0/src/functualize/_discovery/__init__.py +59 -0
  179. functualize-0.1.0/src/functualize/_discovery/ast_extractor.py +200 -0
  180. functualize-0.1.0/src/functualize/_discovery/cached_provider.py +868 -0
  181. functualize-0.1.0/src/functualize/_discovery/filter_factory.py +164 -0
  182. functualize-0.1.0/src/functualize/_discovery/group_options_extractor.py +96 -0
  183. functualize-0.1.0/src/functualize/_discovery/hierarchy.py +50 -0
  184. functualize-0.1.0/src/functualize/_discovery/hierarchy_errors.py +21 -0
  185. functualize-0.1.0/src/functualize/_discovery/hierarchy_validator.py +372 -0
  186. functualize-0.1.0/src/functualize/_discovery/lazy_wrapper.py +227 -0
  187. functualize-0.1.0/src/functualize/_discovery/naming.py +85 -0
  188. functualize-0.1.0/src/functualize/_discovery/pipeline.py +227 -0
  189. functualize-0.1.0/src/functualize/_discovery/pre_filter.py +50 -0
  190. functualize-0.1.0/src/functualize/_discovery/providers.py +814 -0
  191. functualize-0.1.0/src/functualize/_discovery/registry.py +626 -0
  192. functualize-0.1.0/src/functualize/_discovery/schema_extractor.py +273 -0
  193. functualize-0.1.0/src/functualize/_discovery/sync.py +431 -0
  194. functualize-0.1.0/src/functualize/_discovery/transforms.py +344 -0
  195. functualize-0.1.0/src/functualize/_discovery/version_resolver.py +221 -0
  196. functualize-0.1.0/src/functualize/_engine/__init__.py +30 -0
  197. functualize-0.1.0/src/functualize/_engine/ambient.py +161 -0
  198. functualize-0.1.0/src/functualize/_engine/capabilities/__init__.py +23 -0
  199. functualize-0.1.0/src/functualize/_engine/capabilities/invoke.py +804 -0
  200. functualize-0.1.0/src/functualize/_engine/capabilities/job_context.py +47 -0
  201. functualize-0.1.0/src/functualize/_engine/capabilities/live.py +119 -0
  202. functualize-0.1.0/src/functualize/_engine/capabilities/log.py +72 -0
  203. functualize-0.1.0/src/functualize/_engine/capabilities/perf.py +100 -0
  204. functualize-0.1.0/src/functualize/_engine/capabilities/prompt.py +148 -0
  205. functualize-0.1.0/src/functualize/_engine/capabilities/protocols.py +65 -0
  206. functualize-0.1.0/src/functualize/_engine/capabilities/runcontext.py +870 -0
  207. functualize-0.1.0/src/functualize/_engine/capabilities/shell.py +1091 -0
  208. functualize-0.1.0/src/functualize/_engine/capabilities/state.py +69 -0
  209. functualize-0.1.0/src/functualize/_engine/capabilities/state_store.py +199 -0
  210. functualize-0.1.0/src/functualize/_engine/capabilities/stdin_collector.py +198 -0
  211. functualize-0.1.0/src/functualize/_engine/capabilities/stdout.py +113 -0
  212. functualize-0.1.0/src/functualize/_engine/capabilities/tty.py +115 -0
  213. functualize-0.1.0/src/functualize/_engine/capabilities/workflow.py +241 -0
  214. functualize-0.1.0/src/functualize/_engine/capabilities/workflow_scope.py +131 -0
  215. functualize-0.1.0/src/functualize/_engine/context.py +80 -0
  216. functualize-0.1.0/src/functualize/_engine/errors.py +10 -0
  217. functualize-0.1.0/src/functualize/_engine/exec_policy.py +153 -0
  218. functualize-0.1.0/src/functualize/_engine/executor.py +2389 -0
  219. functualize-0.1.0/src/functualize/_engine/explain.py +99 -0
  220. functualize-0.1.0/src/functualize/_engine/frontier.py +247 -0
  221. functualize-0.1.0/src/functualize/_engine/guards.py +293 -0
  222. functualize-0.1.0/src/functualize/_engine/job_graph.py +211 -0
  223. functualize-0.1.0/src/functualize/_engine/job_middleware.py +331 -0
  224. functualize-0.1.0/src/functualize/_engine/middleware.py +302 -0
  225. functualize-0.1.0/src/functualize/_engine/missing_value.py +115 -0
  226. functualize-0.1.0/src/functualize/_engine/preflight.py +212 -0
  227. functualize-0.1.0/src/functualize/_engine/resolution.py +266 -0
  228. functualize-0.1.0/src/functualize/_engine/result.py +11 -0
  229. functualize-0.1.0/src/functualize/_engine/scheduler.py +272 -0
  230. functualize-0.1.0/src/functualize/_engine/surface_routing.py +95 -0
  231. functualize-0.1.0/src/functualize/_engine/validation.py +115 -0
  232. functualize-0.1.0/src/functualize/_engine/workflow_runner.py +138 -0
  233. functualize-0.1.0/src/functualize/_engine/workflow_validation.py +198 -0
  234. functualize-0.1.0/src/functualize/_engine/workflow_walker.py +462 -0
  235. functualize-0.1.0/src/functualize/_events/__init__.py +63 -0
  236. functualize-0.1.0/src/functualize/_events/_catalog_entries.py +271 -0
  237. functualize-0.1.0/src/functualize/_events/_obs_types.py +56 -0
  238. functualize-0.1.0/src/functualize/_events/_pattern_matcher.py +95 -0
  239. functualize-0.1.0/src/functualize/_events/adapter.py +111 -0
  240. functualize-0.1.0/src/functualize/_events/bus.py +429 -0
  241. functualize-0.1.0/src/functualize/_events/catalog.py +37 -0
  242. functualize-0.1.0/src/functualize/_events/hooks.py +396 -0
  243. functualize-0.1.0/src/functualize/_events/instrumentation.py +130 -0
  244. functualize-0.1.0/src/functualize/_events/introspection.py +50 -0
  245. functualize-0.1.0/src/functualize/_events/middleware_stack.py +292 -0
  246. functualize-0.1.0/src/functualize/_events/perf.py +269 -0
  247. functualize-0.1.0/src/functualize/_events/tracing.py +160 -0
  248. functualize-0.1.0/src/functualize/_gate/__init__.py +25 -0
  249. functualize-0.1.0/src/functualize/_gate/_context.py +34 -0
  250. functualize-0.1.0/src/functualize/_gate/_registry.py +233 -0
  251. functualize-0.1.0/src/functualize/_gate/_resolver.py +77 -0
  252. functualize-0.1.0/src/functualize/_gate/_strategy.py +17 -0
  253. functualize-0.1.0/src/functualize/_gate/prompt_strategy.py +170 -0
  254. functualize-0.1.0/src/functualize/_plugins/__init__.py +47 -0
  255. functualize-0.1.0/src/functualize/_plugins/config.py +80 -0
  256. functualize-0.1.0/src/functualize/_plugins/domain_metadata.py +42 -0
  257. functualize-0.1.0/src/functualize/_plugins/domain_registry.py +337 -0
  258. functualize-0.1.0/src/functualize/_plugins/loader.py +817 -0
  259. functualize-0.1.0/src/functualize/_primitives/__init__.py +93 -0
  260. functualize-0.1.0/src/functualize/_primitives/cache_format.py +345 -0
  261. functualize-0.1.0/src/functualize/_primitives/di.py +393 -0
  262. functualize-0.1.0/src/functualize/_primitives/display_detection.py +59 -0
  263. functualize-0.1.0/src/functualize/_primitives/fingerprint.py +421 -0
  264. functualize-0.1.0/src/functualize/_primitives/graph.py +200 -0
  265. functualize-0.1.0/src/functualize/_primitives/group_options_detection.py +77 -0
  266. functualize-0.1.0/src/functualize/_primitives/job_filter.py +163 -0
  267. functualize-0.1.0/src/functualize/_primitives/lazy.py +55 -0
  268. functualize-0.1.0/src/functualize/_primitives/locator.py +533 -0
  269. functualize-0.1.0/src/functualize/_primitives/middleware.py +294 -0
  270. functualize-0.1.0/src/functualize/_primitives/modules.py +39 -0
  271. functualize-0.1.0/src/functualize/_primitives/pre_filter.py +482 -0
  272. functualize-0.1.0/src/functualize/_primitives/resilient.py +40 -0
  273. functualize-0.1.0/src/functualize/_primitives/resolution.py +22 -0
  274. functualize-0.1.0/src/functualize/_primitives/state_format.py +273 -0
  275. functualize-0.1.0/src/functualize/_primitives/state_store.py +365 -0
  276. functualize-0.1.0/src/functualize/_primitives/stdout_emitter.py +207 -0
  277. functualize-0.1.0/src/functualize/_types/__init__.py +135 -0
  278. functualize-0.1.0/src/functualize/_types/annotations.py +60 -0
  279. functualize-0.1.0/src/functualize/_types/commands.py +127 -0
  280. functualize-0.1.0/src/functualize/_types/descriptors.py +676 -0
  281. functualize-0.1.0/src/functualize/_types/enums.py +97 -0
  282. functualize-0.1.0/src/functualize/_types/errors.py +206 -0
  283. functualize-0.1.0/src/functualize/_types/exit_codes.py +76 -0
  284. functualize-0.1.0/src/functualize/_types/from_job.py +327 -0
  285. functualize-0.1.0/src/functualize/_types/group_options.py +56 -0
  286. functualize-0.1.0/src/functualize/_types/input_modes.py +125 -0
  287. functualize-0.1.0/src/functualize/_types/interactivity.py +279 -0
  288. functualize-0.1.0/src/functualize/_types/job_declaration.py +528 -0
  289. functualize-0.1.0/src/functualize/_types/naming.py +611 -0
  290. functualize-0.1.0/src/functualize/_types/protocols.py +230 -0
  291. functualize-0.1.0/src/functualize/_types/redaction.py +175 -0
  292. functualize-0.1.0/src/functualize/_types/settings.py +155 -0
  293. functualize-0.1.0/src/functualize/_types/shell.py +165 -0
  294. functualize-0.1.0/src/functualize/_types/stdout.py +49 -0
  295. functualize-0.1.0/src/functualize/_types/workflow.py +614 -0
  296. functualize-0.1.0/src/functualize/app/__init__.py +59 -0
  297. functualize-0.1.0/src/functualize/app/_workflow_resume.py +97 -0
  298. functualize-0.1.0/src/functualize/app/adapters/__init__.py +55 -0
  299. functualize-0.1.0/src/functualize/app/adapters/_validation.py +35 -0
  300. functualize-0.1.0/src/functualize/app/adapters/cli.py +1242 -0
  301. functualize-0.1.0/src/functualize/app/adapters/click_params.py +1123 -0
  302. functualize-0.1.0/src/functualize/app/adapters/lazy_command.py +134 -0
  303. functualize-0.1.0/src/functualize/app/adapters/surface_gate.py +89 -0
  304. functualize-0.1.0/src/functualize/app/adapters/tui.py +107 -0
  305. functualize-0.1.0/src/functualize/app/commands.py +374 -0
  306. functualize-0.1.0/src/functualize/app/config.py +141 -0
  307. functualize-0.1.0/src/functualize/app/core.py +1200 -0
  308. functualize-0.1.0/src/functualize/app/fallback.py +29 -0
  309. functualize-0.1.0/src/functualize/app/presets.py +114 -0
  310. functualize-0.1.0/src/functualize/app/utils.py +1519 -0
  311. functualize-0.1.0/src/functualize/job/__init__.py +124 -0
  312. functualize-0.1.0/src/functualize/job/_invoke.py +8 -0
  313. functualize-0.1.0/src/functualize/job/_job_context.py +8 -0
  314. functualize-0.1.0/src/functualize/job/_log.py +8 -0
  315. functualize-0.1.0/src/functualize/job/_middleware.py +17 -0
  316. functualize-0.1.0/src/functualize/job/_perf.py +8 -0
  317. functualize-0.1.0/src/functualize/job/_prompt.py +20 -0
  318. functualize-0.1.0/src/functualize/job/_protocols.py +5 -0
  319. functualize-0.1.0/src/functualize/job/_runcontext.py +24 -0
  320. functualize-0.1.0/src/functualize/job/_shell.py +21 -0
  321. functualize-0.1.0/src/functualize/job/_state.py +8 -0
  322. functualize-0.1.0/src/functualize/job/_state_store.py +5 -0
  323. functualize-0.1.0/src/functualize/job/_stdout.py +9 -0
  324. functualize-0.1.0/src/functualize/job/_workflow_scope.py +9 -0
  325. functualize-0.1.0/src/functualize/job/capabilities.py +66 -0
  326. functualize-0.1.0/src/functualize/job/context.py +32 -0
  327. functualize-0.1.0/src/functualize/job/decorators.py +326 -0
  328. functualize-0.1.0/src/functualize/job/markers.py +122 -0
  329. functualize-0.1.0/src/functualize/plugin/__init__.py +105 -0
  330. functualize-0.1.0/src/functualize/plugin/protocols.py +266 -0
  331. functualize-0.1.0/src/functualize/py.typed +0 -0
  332. functualize-0.1.0/src/functualize/testing/__init__.py +23 -0
  333. functualize-0.1.0/src/functualize/testing/builder.py +160 -0
  334. functualize-0.1.0/src/functualize/testing/doubles.py +227 -0
  335. functualize-0.1.0/src/functualize/testing/shell.py +117 -0
  336. functualize-0.1.0/src/functualize/testing/stdout.py +62 -0
  337. functualize-0.1.0/src/functualize/types/__init__.py +39 -0
  338. functualize-0.1.0/src/functualize/ui/__init__.py +39 -0
  339. functualize-0.1.0/src/functualize/ui/_prompt_modal.py +295 -0
  340. functualize-0.1.0/src/functualize/ui/display.py +126 -0
  341. functualize-0.1.0/src/functualize/ui/fullscreen/__init__.py +7 -0
  342. functualize-0.1.0/src/functualize/ui/fullscreen/app.py +71 -0
  343. functualize-0.1.0/src/functualize/ui/fullscreen/screens.py +73 -0
  344. functualize-0.1.0/src/functualize/ui/fullscreen/widgets.py +236 -0
  345. functualize-0.1.0/src/functualize/ui/py.typed +0 -0
  346. functualize-0.1.0/src/functualize/ui/stdout_surface.py +246 -0
  347. functualize-0.1.0/src/functualize/ui/textual_app.py +149 -0
  348. functualize-0.1.0/src/functualize/workflow/__init__.py +42 -0
  349. functualize-0.1.0/src/functualize/workflow/_decorator.py +54 -0
  350. functualize-0.1.0/src/functualize/workflow/_validation.py +80 -0
@@ -0,0 +1,101 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ *.egg-info/
7
+ *.egg
8
+ dist/
9
+ build/
10
+ *.whl
11
+
12
+ # Agents
13
+ .spec/archive/
14
+ .spec/features/
15
+ .spec/scrutiny-reports/
16
+ .spec/.agentic-coding
17
+ .spec/STATE.md
18
+ .spec/PROJECT.md
19
+ .spec/REQUIREMENTS.md
20
+ .spec/ROADMAP.md
21
+ .opencode/
22
+
23
+
24
+ # Virtual environments
25
+ .venv/
26
+ venv/
27
+ ENV/
28
+
29
+ # Testing
30
+ .coverage
31
+ .pytest_cache/
32
+ htmlcov/
33
+ .hypothesis/
34
+ snapshot_report.html
35
+ _*_result*.txt
36
+ _debug.txt
37
+ _tui_debug.txt
38
+ _tui_eval_debug.txt
39
+
40
+ # IDE
41
+ .idea/
42
+ *.swp
43
+ *.swo
44
+ *~
45
+ *.code-workspace
46
+
47
+ # Coding-agent tooling state (guards — these dirs are not part of the repo)
48
+ .kiro/
49
+ .moai/
50
+
51
+ # OS
52
+ .DS_Store
53
+ Thumbs.db
54
+
55
+ # Environment / secrets
56
+ .env
57
+ .env.*
58
+ !.env.example
59
+
60
+ # Agent scratch space (test output, temp scripts)
61
+ tmp/
62
+
63
+ # Local-only files (not for the repo)
64
+ *.local.md
65
+ *.local.*
66
+
67
+ # Personal notes
68
+ HUMAN_NOTE.md
69
+
70
+ # Distribution
71
+ dist/
72
+
73
+ # Documentation site build output
74
+ site/
75
+
76
+ # uv
77
+ .python-version
78
+ .functualize/cache.json
79
+ .functualize_cache.json
80
+ .todos/
81
+ .sidecar/
82
+ .sidecar-agent
83
+ .sidecar-task
84
+ .sidecar-pr
85
+ .sidecar-start.sh
86
+ .sidecar-base
87
+ .td-root
88
+ .functualize/
89
+ .import_linter_cache/
90
+ .mypy_cache/
91
+ .pytest_cache/
92
+ .ruff_cache/
93
+
94
+ # OmO / OpenCode agent run-continuation scratch state
95
+ .omo/
96
+ .mcp.json
97
+ .agentsroom/handoff-transcript-*.txt
98
+ .agentsroom/handoff-summary-*.md
99
+
100
+ # Internal pre-release audit reports (contain session IDs / local infra notes)
101
+ .release/
@@ -0,0 +1,194 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0] - 2026-08-04
11
+
12
+ First public release. Functualize turns plain Python functions into jobs that run
13
+ from a CLI, an interactive TUI, an MCP server, or another job — without the
14
+ function knowing which.
15
+
16
+ ### Jobs and execution
17
+
18
+ - **Auto-discovery** of job functions by directory scan, with per-function
19
+ qualification rules (`require_job_prefix`, `require_job_postfix`,
20
+ `require_job_decorators`, `require_file_marker`) settable by config file,
21
+ environment variable, or CLI flag. A filtered-out job is unreachable by name,
22
+ not merely hidden from listings.
23
+ - **Dependency injection by type annotation** (FastAPI / pytest-fixture style).
24
+ Capabilities: `Log`, `Invoke`, `Prompt`, `Perf`, `Shell`, `State`, `Stdout`,
25
+ `TTY`, `Live`, plus `JobConfigView` and `RunContext` itself.
26
+ - **`FromJob`** — declare a parameter as another job's return value. The
27
+ annotation is both the dependency edge and the injection, so there is no second
28
+ place to keep in sync. `FromJob(..., run=False)` reads a recorded value without
29
+ causing work.
30
+ - **`@job(...)` declarations**: `Deps`, `Fingerprint`, `Guards`, `Exec`, `Retry`,
31
+ `Precondition`. Fingerprints and guards give skip-if-fresh behavior, and
32
+ `func builtin why <job>` explains any verdict — including a return value with
33
+ no serializable form, which still caches but cannot feed a `FromJob` dependent.
34
+ - **Lazy boot is the default.** Warm boot imports zero job modules; invoking a job
35
+ imports exactly that one module. Two consequences worth knowing: a job module's
36
+ import-time side effects run at first invocation rather than at boot, and
37
+ DI-binding errors for warm-cached jobs surface at first use rather than at boot.
38
+ `JobSources(lazy=False)` restores fully eager boot.
39
+
40
+ ### Naming
41
+
42
+ - **Job and group names are canonical lowercase-hyphenated.** `def data_sync`
43
+ registers, displays, and is invoked as `data-sync`; a grouped
44
+ `JOB_GROUP = "data_ops"` job becomes `data-ops.run-etl`. Python identifiers
45
+ cannot contain hyphens and command names conventionally do, so the same job
46
+ otherwise has two spellings and each consumer picks one.
47
+ - **Typing the Python spelling still works** — `func data_sync`,
48
+ `rc.invoke("data_sync")`, and `Deps("data_sync")` all reach `data-sync`. That is
49
+ normalization onto the one real name, not an alias.
50
+ - Environment variables keep underscores (`DATA_SYNC_BATCH_SIZE`), since no shell
51
+ can export a hyphen, and config sections are read either way (`[data_sync]` and
52
+ `[data-sync]`).
53
+ - Two functions that normalize to one name are rejected at registration instead of
54
+ one silently replacing the other.
55
+
56
+ ### CLI
57
+
58
+ - `func` / `functualize` entry points, click-native, with single-file, group, and
59
+ CWD-discovery modes. Importing `functualize.app` or `functualize.job` loads no
60
+ CLI dependency.
61
+ - **Global flags go before the group name** — `func --log-level DEBUG infra deploy`,
62
+ matching the git idiom. A global flag placed after a group is a clear error with
63
+ a hint, not a silent no-op. Options after the job name belong to the job.
64
+ - **First-party commands live under `builtin`**, so no first-party name is a name a
65
+ job cannot have: `cache`, `state`, `config`, `domains`, `scaffold`, `workflow`,
66
+ `parallel`, `history`, `env`, `shell-init`, `why`, `version`, `info`.
67
+ - **Group options** — `class DeployOptions(GroupOptions, group="deploy")` declares
68
+ flags every job beneath the group accepts, typed *before* the group segment that
69
+ owns them (`func deploy --env prod web run`). Position is what separates a
70
+ group's flag from the job's own. They resolve as
71
+ `flag > DEPLOY__ENV > [deploy] > default`, identically for `app.execute()` and
72
+ `rc.invoke()`, and appear in MCP tool schemas.
73
+ - **Pinned exit codes**: `0` success · `1` the job raised · `2` usage/config error ·
74
+ `3` refused pre-flight · `4` stale check · `5` blocked awaiting gate input. A
75
+ broken pipe (`func generate | head`) exits `0` quietly.
76
+ - **Explicit stdout.** A job writes through the injected `Stdout` capability
77
+ (`out.emit` / `out.write`); a return value is programmatic — for `FromJob` and
78
+ callers — and is never auto-printed. `--output json|ndjson|raw|none` selects the
79
+ emit format.
80
+ - `sh(...)` splits its channels: the command echo (`$ git status`) goes to stderr
81
+ like `log()`, and `sh(..., stream=True)` sends the command's own output to
82
+ stdout, so `func build | grep …` sees the build output rather than the echo.
83
+ - **Executable scripts (PEP 723)** — a script with `#!/usr/bin/env -S func` and a
84
+ `[tool.functualize] job = "…"` table runs as a program, handing its arguments to
85
+ the declared job. `dependencies` in the same block resolve through `uv run`.
86
+ - **`func builtin shell-init <bash|zsh|fish>`** emits a static completion script
87
+ containing no `func` call, so TAB has no Python start-up cost.
88
+
89
+ ### Configuration
90
+
91
+ - Layered resolution (CLI → env → files → remote → defaults) with the presets
92
+ `classic()`, `twelve_factor()`, `env_only()`, and `remote_first()`.
93
+ - One Pydantic model per job drives CLI options, TUI form fields, and runtime
94
+ validation.
95
+ - **Environment overlays** — `config.base.*` merges beneath the active
96
+ environment's `config.<env>.*`, resolved as
97
+ `FUNCTUALIZE_ENV` > `ENVIRONMENT` > `ENV` > `DEV`. Precedence is
98
+ directory-major, band-minor: the nearest directory wins overall, and within a
99
+ directory the overlay beats base, so the project > parents > global ladder holds.
100
+ - `FunctualizeApp.config_files(job_name=None)` reports every discovered file with
101
+ its environment slot, role, merge precedence, and own values. Inactive and
102
+ unparsable files are included on purpose, so a file that plainly exists but is
103
+ not taking effect can be explained rather than omitted.
104
+ - **Missing required config is prompted for** on an interactive surface, masked for
105
+ secret fields. Off one (a pipe, CI, MCP) it is a field-level error naming the
106
+ field and the environment variable that sets it, exit 2 — never a hang on a
107
+ prompt nothing can answer.
108
+ - Boot-time `.env` loading via `dotenv` / `dotenv_path` (or `FUNCTUALIZE_DOTENV` /
109
+ `FUNCTUALIZE_DOTENV_PATH`), loaded with `override=False` so shell values win.
110
+
111
+ ### Workflows
112
+
113
+ - `@workflow(steps=..., edges=...)` graphs with conditional edges and **gates** that
114
+ pause for human, AI, or programmatic resolution.
115
+ - Persisted scopes are inspectable and resumable from the CLI
116
+ (`func builtin workflow list | state | resume | cancel`, with `--format table|json`)
117
+ and over MCP, through one shared code path so the two surfaces cannot drift.
118
+ - A job that is both a dependency and a workflow node runs once per scope, and a
119
+ step whose `Deps` names a node the graph orders *after* it is rejected at boot as
120
+ the contradiction it is.
121
+ - A gate inside a nested workflow blocks its parent rather than failing it; the
122
+ child scope is stable across re-entry (`<parent-scope>::<step-name>`).
123
+
124
+ ### Surfaces and TUI
125
+
126
+ - A job declares where it renders directly in its signature. `tty: TTY` grants
127
+ terminal ownership for a job-owned UI and is refused pre-flight in non-terminal
128
+ contexts (piped, CI, MCP) with an actionable message. `tty: TTY | None` is a
129
+ preference, so one unmodified job renders as a full-screen app or a live view
130
+ depending on the surface. `live: Live` is an always-injected, degrading
131
+ live-display channel.
132
+ - **Inline TUI** — SmartBar command input with autocomplete and readiness colors,
133
+ config inspection and editing panels, a job browser, live execution monitoring,
134
+ and a detail view that stages edits (`i`) and removals (`d`) against any writable
135
+ source and writes them atomically (`Ctrl+S`).
136
+ - Settings are real and live in the real config files — the same layers
137
+ `resolve_cli_config` merges, so there is no parallel settings file the rest of
138
+ `func` ignores. Invalid values fall through to the next layer instead of breaking
139
+ the TUI.
140
+ - Displays co-locate with jobs and are discovered through the job cache.
141
+ `DisplayProvider.refresh()` runs on a worker with a per-provider timeout, so a
142
+ display doing I/O cannot freeze the interface.
143
+ - Selecting a `tty: TTY` job in the shell hands the terminal over and relaunches the
144
+ shell afterward.
145
+
146
+ ### Plugins and integrations
147
+
148
+ - Entry-point plugin system plus zero-packaging `.functualize/plugins/*.py`
149
+ discovery. The `[all]` extra ships 11 first-party plugins: domain SDKs (ai,
150
+ interactivity, state, tasks), implementations (ai-pydantic, inline, state-sqlite,
151
+ tasks-local), delivery adapters (http, lambda, mcp), and flow visualization.
152
+ - **MCP** — jobs are exposed as tools with structured group metadata
153
+ (`{"namespace": ["infra", "aws"], "kind": "job"}`), and plugin-declared workflows
154
+ report their real steps and edges. A `requires_tty` job is omitted rather than
155
+ offered and then failed.
156
+ - Lifecycle hooks (`HookRegistry`) and observation events (`EventBus`), strictly
157
+ non-overlapping. The event vocabulary is a documented stability contract; framework
158
+ events reach the EventBus only and are filtered out of the surface fan-out.
159
+
160
+ ### Tooling
161
+
162
+ - `func builtin scaffold init` generates projects, jobs, plugins, screens, and domains.
163
+ - `func builtin parallel <job…>` runs jobs concurrently. `--timeout N` bounds the
164
+ batch and `--output interleaved|grouped|prefixed` chooses how concurrent output is
165
+ presented (`grouped` emits GitHub Actions `::group::` / `::error::` markers). The
166
+ per-job summary goes to stderr and the verdict to the exit code, so
167
+ `func builtin parallel a b | jq` sees only what the jobs emitted.
168
+ - `func builtin history` shows recent runs newest-first across job runs and shell
169
+ commands. Arguments are stored only as a hash, never in the clear.
170
+ - `func builtin env <job>` exports a job's resolved config for tools that are not
171
+ functualize, in print form (`eval $(func builtin env deploy)`) or exec form
172
+ (`func builtin env deploy -- kubectl apply …`, propagating the exit code). Secret
173
+ fields are masked in the print form and omitted from the exec environment unless
174
+ `--include-secrets` is given.
175
+
176
+ ### Testing
177
+
178
+ - First-class test doubles in `functualize.testing`: `TestRunContext`,
179
+ `CapturingLog`, `MockInvoke`, `AutoPrompt`, `NoopPerf`. Each double subclasses
180
+ the capability it stands in for, so it satisfies the DI registry's type check
181
+ and can be injected anywhere the real capability is accepted.
182
+
183
+ ### Known limitations
184
+
185
+ - `TestRunContext.captured_logs()` does not observe `rc.log(...)`.
186
+ `RunContext.log()` writes directly to its stdlib logger and never consults the
187
+ DI registry, so messages emitted that way are not recorded and the call returns
188
+ an empty list. Assert on log output by passing the double to the job directly
189
+ (`log = CapturingLog(); my_job(config, log); assert (...) in log.calls`), which
190
+ is the style the scaffolded job template demonstrates. Routing `RunContext.log`
191
+ through the injected `Log` is deferred to a later release.
192
+
193
+ [Unreleased]: https://github.com/raicing-ai/functualize/compare/v0.1.0...HEAD
194
+ [0.1.0]: https://github.com/raicing-ai/functualize/releases/tag/v0.1.0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Mohammad Hakim Adiprasetya
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.