codeplain 0.3.0__tar.gz → 0.3.2__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 (234) hide show
  1. codeplain-0.3.2/.claude/settings.json +32 -0
  2. codeplain-0.3.2/.github/workflows/e2e.yml +62 -0
  3. codeplain-0.3.2/.zed/settings.json +46 -0
  4. codeplain-0.3.2/CLAUDE.md +238 -0
  5. {codeplain-0.3.0 → codeplain-0.3.2}/PKG-INFO +45 -24
  6. {codeplain-0.3.0 → codeplain-0.3.2}/README.md +40 -19
  7. codeplain-0.3.2/_version.py +1 -0
  8. codeplain-0.3.2/cli_output/__init__.py +7 -0
  9. codeplain-0.3.0/plain2code_utils.py → codeplain-0.3.2/cli_output/dry_run.py +3 -24
  10. codeplain-0.3.2/cli_output/render_summary.py +32 -0
  11. codeplain-0.3.2/cli_output/status.py +160 -0
  12. {codeplain-0.3.0 → codeplain-0.3.2}/codeplain_REST_api.py +9 -1
  13. {codeplain-0.3.0 → codeplain-0.3.2}/concept_utils.py +0 -1
  14. {codeplain-0.3.0 → codeplain-0.3.2}/examples/example_hello_world_python/hello_world_python.plain +3 -3
  15. codeplain-0.3.2/examples/example_hello_world_python/text.txt +1 -0
  16. {codeplain-0.3.0 → codeplain-0.3.2}/file_utils.py +18 -62
  17. {codeplain-0.3.0 → codeplain-0.3.2}/install/bash/install.sh +68 -37
  18. {codeplain-0.3.0 → codeplain-0.3.2}/install/powershell/install.ps1 +58 -34
  19. {codeplain-0.3.0 → codeplain-0.3.2}/memory_management.py +2 -2
  20. {codeplain-0.3.0 → codeplain-0.3.2}/module_renderer.py +2 -5
  21. {codeplain-0.3.0 → codeplain-0.3.2}/partial_rendering.py +10 -6
  22. {codeplain-0.3.0 → codeplain-0.3.2}/plain2code.py +63 -44
  23. {codeplain-0.3.0 → codeplain-0.3.2}/plain2code_arguments.py +32 -2
  24. {codeplain-0.3.0 → codeplain-0.3.2}/plain2code_console.py +2 -0
  25. {codeplain-0.3.0 → codeplain-0.3.2}/plain2code_exceptions.py +6 -0
  26. {codeplain-0.3.0 → codeplain-0.3.2}/plain2code_logger.py +37 -3
  27. {codeplain-0.3.0 → codeplain-0.3.2}/plain2code_state.py +4 -7
  28. codeplain-0.3.2/plain2code_utils.py +22 -0
  29. {codeplain-0.3.0 → codeplain-0.3.2}/plain_file.py +6 -0
  30. {codeplain-0.3.0 → codeplain-0.3.2}/plain_modules.py +11 -8
  31. {codeplain-0.3.0 → codeplain-0.3.2}/pyproject.toml +5 -5
  32. {codeplain-0.3.0 → codeplain-0.3.2}/pytest.ini +3 -2
  33. {codeplain-0.3.0 → codeplain-0.3.2}/render_machine/actions/fix_conformance_test.py +27 -29
  34. {codeplain-0.3.0 → codeplain-0.3.2}/render_machine/actions/fix_unit_tests.py +2 -6
  35. {codeplain-0.3.0 → codeplain-0.3.2}/render_machine/actions/prepare_repositories.py +3 -6
  36. {codeplain-0.3.0 → codeplain-0.3.2}/render_machine/actions/prepare_testing_environment.py +3 -5
  37. {codeplain-0.3.0 → codeplain-0.3.2}/render_machine/actions/refactor_code.py +11 -15
  38. {codeplain-0.3.0 → codeplain-0.3.2}/render_machine/actions/render_conformance_tests.py +34 -39
  39. {codeplain-0.3.0 → codeplain-0.3.2}/render_machine/actions/render_functional_requirement.py +15 -20
  40. {codeplain-0.3.0 → codeplain-0.3.2}/render_machine/actions/run_conformance_tests.py +11 -11
  41. {codeplain-0.3.0 → codeplain-0.3.2}/render_machine/actions/run_unit_tests.py +5 -7
  42. {codeplain-0.3.0 → codeplain-0.3.2}/render_machine/code_renderer.py +1 -1
  43. {codeplain-0.3.0 → codeplain-0.3.2}/render_machine/conformance_tests.py +9 -13
  44. {codeplain-0.3.0 → codeplain-0.3.2}/render_machine/render_context.py +12 -15
  45. {codeplain-0.3.0 → codeplain-0.3.2}/render_machine/render_types.py +0 -10
  46. {codeplain-0.3.0 → codeplain-0.3.2}/render_machine/render_utils.py +42 -47
  47. {codeplain-0.3.0 → codeplain-0.3.2}/render_machine/state_machine_config.py +39 -33
  48. {codeplain-0.3.0 → codeplain-0.3.2}/requirements.txt +3 -3
  49. {codeplain-0.3.0 → codeplain-0.3.2}/system_config.py +0 -6
  50. codeplain-0.3.2/tests/data/plainfile/add_new_task_modal_specification.yaml +1 -0
  51. codeplain-0.3.2/tests/data/plainfile/task_list_ui_specification.yaml +1 -0
  52. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfile/task_manager_with_reference_links.plain +3 -3
  53. codeplain-0.3.2/tests/e2e/Dockerfile +31 -0
  54. codeplain-0.3.2/tests/e2e/conftest.py +145 -0
  55. codeplain-0.3.2/tests/e2e/test_hello_world_python.py +37 -0
  56. codeplain-0.3.2/tests/e2e/test_hello_world_python_windows.py +64 -0
  57. codeplain-0.3.2/tests/test_cli_output.py +407 -0
  58. {codeplain-0.3.0 → codeplain-0.3.2}/tests/test_plainfileparser.py +4 -4
  59. {codeplain-0.3.0 → codeplain-0.3.2}/tui/components.py +0 -6
  60. {codeplain-0.3.0 → codeplain-0.3.2}/tui/plain2code_tui.py +15 -0
  61. {codeplain-0.3.0 → codeplain-0.3.2}/tui/plain_module_render_choice_tui.py +36 -9
  62. {codeplain-0.3.0 → codeplain-0.3.2}/tui/styles.css +1 -1
  63. {codeplain-0.3.0 → codeplain-0.3.2}/tui/widget_helpers.py +0 -18
  64. codeplain-0.3.0/.claude/docs/PLAIN_REFERENCE.md +0 -325
  65. codeplain-0.3.0/.zed/settings.json +0 -61
  66. codeplain-0.3.0/CLAUDE.md +0 -113
  67. codeplain-0.3.0/_version.py +0 -1
  68. codeplain-0.3.0/hash_key.py +0 -29
  69. codeplain-0.3.0/render_machine/conformance_test_helpers.py +0 -68
  70. {codeplain-0.3.0 → codeplain-0.3.2}/.claude/settings.local.json +0 -0
  71. {codeplain-0.3.0 → codeplain-0.3.2}/.flake8 +0 -0
  72. {codeplain-0.3.0 → codeplain-0.3.2}/.github/dependabot.yml +0 -0
  73. {codeplain-0.3.0 → codeplain-0.3.2}/.github/workflows/lint-and-test.yml +0 -0
  74. {codeplain-0.3.0 → codeplain-0.3.2}/.github/workflows/nofity-slack-on-main-merge.yml +0 -0
  75. {codeplain-0.3.0 → codeplain-0.3.2}/.github/workflows/publish-install-script.yml +0 -0
  76. {codeplain-0.3.0 → codeplain-0.3.2}/.github/workflows/publish-to-pypi.yml +0 -0
  77. {codeplain-0.3.0 → codeplain-0.3.2}/.gitignore +0 -0
  78. {codeplain-0.3.0 → codeplain-0.3.2}/.vscode/launch.json +0 -0
  79. {codeplain-0.3.0 → codeplain-0.3.2}/.vscode/settings.json +0 -0
  80. {codeplain-0.3.0 → codeplain-0.3.2}/LICENSE +0 -0
  81. {codeplain-0.3.0 → codeplain-0.3.2}/config/__init__.py +0 -0
  82. {codeplain-0.3.0 → codeplain-0.3.2}/config/system_config.yaml +0 -0
  83. {codeplain-0.3.0 → codeplain-0.3.2}/diff_utils.py +0 -0
  84. {codeplain-0.3.0 → codeplain-0.3.2}/docs/generate_cli.py +0 -0
  85. {codeplain-0.3.0 → codeplain-0.3.2}/docs/plain2code_cli.md +0 -0
  86. {codeplain-0.3.0 → codeplain-0.3.2}/docs/starting_a_plain_project_from_scratch.md +0 -0
  87. {codeplain-0.3.0 → codeplain-0.3.2}/event_bus.py +0 -0
  88. {codeplain-0.3.0 → codeplain-0.3.2}/examples/example_hello_world_golang/config.yaml +0 -0
  89. {codeplain-0.3.0 → codeplain-0.3.2}/examples/example_hello_world_golang/harness_tests/hello_world_test.go +0 -0
  90. {codeplain-0.3.0 → codeplain-0.3.2}/examples/example_hello_world_golang/hello_world_golang.plain +0 -0
  91. {codeplain-0.3.0 → codeplain-0.3.2}/examples/example_hello_world_golang/run.sh +0 -0
  92. {codeplain-0.3.0 → codeplain-0.3.2}/examples/example_hello_world_python/config.yaml +0 -0
  93. {codeplain-0.3.0 → codeplain-0.3.2}/examples/example_hello_world_python/harness_tests/hello_world_display/test_hello_world.py +0 -0
  94. {codeplain-0.3.0 → codeplain-0.3.2}/examples/example_hello_world_python/run.sh +0 -0
  95. {codeplain-0.3.0 → codeplain-0.3.2}/examples/example_hello_world_react/config.yaml +0 -0
  96. {codeplain-0.3.0 → codeplain-0.3.2}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress/e2e/hello_world.cy.ts +0 -0
  97. {codeplain-0.3.0 → codeplain-0.3.2}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress/support/e2e.ts +0 -0
  98. {codeplain-0.3.0 → codeplain-0.3.2}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress.config.ts +0 -0
  99. {codeplain-0.3.0 → codeplain-0.3.2}/examples/example_hello_world_react/harness_tests/hello_world_display/package.json +0 -0
  100. {codeplain-0.3.0 → codeplain-0.3.2}/examples/example_hello_world_react/harness_tests/hello_world_display/tsconfig.json +0 -0
  101. {codeplain-0.3.0 → codeplain-0.3.2}/examples/example_hello_world_react/hello_world_react.plain +0 -0
  102. {codeplain-0.3.0 → codeplain-0.3.2}/examples/example_hello_world_react/run.sh +0 -0
  103. {codeplain-0.3.0 → codeplain-0.3.2}/examples/run.sh +0 -0
  104. {codeplain-0.3.0 → codeplain-0.3.2}/git_utils.py +0 -0
  105. {codeplain-0.3.0 → codeplain-0.3.2}/install/bash/examples.sh +0 -0
  106. {codeplain-0.3.0 → codeplain-0.3.2}/install/bash/walkthrough.sh +0 -0
  107. {codeplain-0.3.0 → codeplain-0.3.2}/install/powershell/examples.ps1 +0 -0
  108. {codeplain-0.3.0 → codeplain-0.3.2}/install/powershell/walkthrough.ps1 +0 -0
  109. {codeplain-0.3.0 → codeplain-0.3.2}/plain2code_events.py +0 -0
  110. {codeplain-0.3.0 → codeplain-0.3.2}/plain2code_nodes.py +0 -0
  111. {codeplain-0.3.0 → codeplain-0.3.2}/plain2code_read_config.py +0 -0
  112. {codeplain-0.3.0 → codeplain-0.3.2}/plain_spec.py +0 -0
  113. {codeplain-0.3.0 → codeplain-0.3.2}/render_machine/__init__.py +0 -0
  114. {codeplain-0.3.0 → codeplain-0.3.2}/render_machine/actions/analyze_specification_ambiguity.py +0 -0
  115. {codeplain-0.3.0 → codeplain-0.3.2}/render_machine/actions/base_action.py +0 -0
  116. {codeplain-0.3.0 → codeplain-0.3.2}/render_machine/actions/commit_conformance_tests_changes.py +0 -0
  117. {codeplain-0.3.0 → codeplain-0.3.2}/render_machine/actions/commit_implementation_code_changes.py +0 -0
  118. {codeplain-0.3.0 → codeplain-0.3.2}/render_machine/actions/create_dist.py +0 -0
  119. {codeplain-0.3.0 → codeplain-0.3.2}/render_machine/actions/exit_with_error.py +0 -0
  120. {codeplain-0.3.0 → codeplain-0.3.2}/render_machine/actions/finish_functional_requirement.py +0 -0
  121. {codeplain-0.3.0 → codeplain-0.3.2}/render_machine/actions/summarize_conformance_tests.py +0 -0
  122. {codeplain-0.3.0 → codeplain-0.3.2}/render_machine/implementation_code_helpers.py +0 -0
  123. {codeplain-0.3.0 → codeplain-0.3.2}/render_machine/states.py +0 -0
  124. {codeplain-0.3.0 → codeplain-0.3.2}/render_machine/triggers.py +0 -0
  125. {codeplain-0.3.0 → codeplain-0.3.2}/resources/codeplain_overview.png +0 -0
  126. {codeplain-0.3.0 → codeplain-0.3.2}/resources/plain_example.png +0 -0
  127. {codeplain-0.3.0 → codeplain-0.3.2}/standard_template_library/__init__.py +0 -0
  128. {codeplain-0.3.0 → codeplain-0.3.2}/standard_template_library/golang-console-app-template.plain +0 -0
  129. {codeplain-0.3.0 → codeplain-0.3.2}/standard_template_library/python-console-app-template.plain +0 -0
  130. {codeplain-0.3.0 → codeplain-0.3.2}/standard_template_library/typescript-react-app-boilerplate.plain +0 -0
  131. {codeplain-0.3.0 → codeplain-0.3.2}/standard_template_library/typescript-react-app-template.plain +0 -0
  132. {codeplain-0.3.0 → codeplain-0.3.2}/test_scripts/run_conformance_tests_cypress.ps1 +0 -0
  133. {codeplain-0.3.0 → codeplain-0.3.2}/test_scripts/run_conformance_tests_cypress.sh +0 -0
  134. {codeplain-0.3.0 → codeplain-0.3.2}/test_scripts/run_conformance_tests_golang.ps1 +0 -0
  135. {codeplain-0.3.0 → codeplain-0.3.2}/test_scripts/run_conformance_tests_golang.sh +0 -0
  136. {codeplain-0.3.0 → codeplain-0.3.2}/test_scripts/run_conformance_tests_python.ps1 +0 -0
  137. {codeplain-0.3.0 → codeplain-0.3.2}/test_scripts/run_conformance_tests_python.sh +0 -0
  138. {codeplain-0.3.0 → codeplain-0.3.2}/test_scripts/run_unittests_flutter.ps1 +0 -0
  139. {codeplain-0.3.0 → codeplain-0.3.2}/test_scripts/run_unittests_golang.ps1 +0 -0
  140. {codeplain-0.3.0 → codeplain-0.3.2}/test_scripts/run_unittests_golang.sh +0 -0
  141. {codeplain-0.3.0 → codeplain-0.3.2}/test_scripts/run_unittests_python.ps1 +0 -0
  142. {codeplain-0.3.0 → codeplain-0.3.2}/test_scripts/run_unittests_python.sh +0 -0
  143. {codeplain-0.3.0 → codeplain-0.3.2}/test_scripts/run_unittests_react.ps1 +0 -0
  144. {codeplain-0.3.0 → codeplain-0.3.2}/test_scripts/run_unittests_react.sh +0 -0
  145. {codeplain-0.3.0 → codeplain-0.3.2}/tests/__init__.py +0 -0
  146. {codeplain-0.3.0 → codeplain-0.3.2}/tests/conftest.py +0 -0
  147. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/imports/circular_imports_1.plain +0 -0
  148. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/imports/circular_imports_2.plain +0 -0
  149. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/imports/circular_imports_main.plain +0 -0
  150. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/imports/diamond_import_1.plain +0 -0
  151. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/imports/diamond_import_2.plain +0 -0
  152. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/imports/diamond_import_common.plain +0 -0
  153. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/imports/diamond_imports_main.plain +0 -0
  154. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/imports/non_existent_import.plain +0 -0
  155. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/partial_rendering/pr_leaf.plain +0 -0
  156. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/partial_rendering/pr_middle.plain +0 -0
  157. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/partial_rendering/pr_root.plain +0 -0
  158. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/partial_rendering/pr_solo.plain +0 -0
  159. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfile/duplicate_specification_heading.plain +0 -0
  160. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfile/invalid_specification_order.plain +0 -0
  161. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfile/missing_non_functional_requirements.plain +0 -0
  162. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfile/plain_source_with_absolute_link.plain +0 -0
  163. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfile/plain_source_with_url_link.plain +0 -0
  164. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfile/without_non_functional_requirement.plain +0 -0
  165. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfileparser/concept_validation_acceptance_tests.plain +0 -0
  166. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfileparser/concept_validation_acceptance_tests_nondefined.plain +0 -0
  167. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfileparser/concept_validation_defined_nondefined.plain +0 -0
  168. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfileparser/concept_validation_defined_nondefined_2.plain +0 -0
  169. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfileparser/concept_validation_definition.plain +0 -0
  170. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfileparser/concept_validation_noconcepts.plain +0 -0
  171. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfileparser/concept_validation_nonconcept.plain +0 -0
  172. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfileparser/concept_validation_nondefined.plain +0 -0
  173. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfileparser/concept_validation_redefinition.plain +0 -0
  174. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfileparser/concept_validation_several_concepts.plain +0 -0
  175. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfileparser/concept_validation_valid.plain +0 -0
  176. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfileparser/exported_concepts.plain +0 -0
  177. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfileparser/exported_concepts_base.plain +0 -0
  178. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfileparser/exported_concepts_example.plain +0 -0
  179. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfileparser/exported_concepts_missing.plain +0 -0
  180. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfileparser/exported_concepts_missing_example.plain +0 -0
  181. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfileparser/exported_concepts_nested.plain +0 -0
  182. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfileparser/exported_concepts_nested_example.plain +0 -0
  183. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfileparser/exported_concepts_transitive_example.plain +0 -0
  184. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfileparser/exported_concepts_transitive_l1.plain +0 -0
  185. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfileparser/exported_concepts_transitive_l2.plain +0 -0
  186. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfileparser/plain_file_parser_with_comments.plain +0 -0
  187. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfileparser/plain_file_with_comments_indented.plain +0 -0
  188. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfileparser/regular_plain_source.plain +0 -0
  189. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfileparser/required_concepts.plain +0 -0
  190. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfileparser/required_concepts_defs.plain +0 -0
  191. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfileparser/required_concepts_example.plain +0 -0
  192. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfileparser/required_concepts_l1.plain +0 -0
  193. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfileparser/required_concepts_l2.plain +0 -0
  194. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfileparser/required_concepts_missing.plain +0 -0
  195. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfileparser/required_concepts_module.plain +0 -0
  196. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfileparser/required_concepts_partial.plain +0 -0
  197. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfileparser/required_concepts_partial_duplicate.plain +0 -0
  198. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfileparser/topological_sort.plain +0 -0
  199. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/plainfileparser/topological_sort_not_referenced.plain +0 -0
  200. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/requires/circular_requires_main.plain +0 -0
  201. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/requires/circular_requires_sub.plain +0 -0
  202. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/requires/diamond_requires_1.plain +0 -0
  203. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/requires/diamond_requires_2.plain +0 -0
  204. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/requires/diamond_requires_common.plain +0 -0
  205. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/requires/diamond_requires_main.plain +0 -0
  206. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/requires/independent_requires_1.plain +0 -0
  207. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/requires/independent_requires_2.plain +0 -0
  208. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/requires/independent_requires_main.plain +0 -0
  209. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/requires/non_existent_require.plain +0 -0
  210. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/requires/normal_requires_1.plain +0 -0
  211. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/requires/normal_requires_2.plain +0 -0
  212. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/requires/normal_requires_common.plain +0 -0
  213. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/requires/normal_requires_main.plain +0 -0
  214. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/simple.plain +0 -0
  215. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/templates/block_level_include.plain +0 -0
  216. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/templates/code_variables.plain +0 -0
  217. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/templates/header.plain +0 -0
  218. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/templates/implement.plain +0 -0
  219. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/templates/implement_2.plain +0 -0
  220. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/templates/template_include.plain +0 -0
  221. {codeplain-0.3.0 → codeplain-0.3.2}/tests/data/templates/test_hardest_problem.plain +0 -0
  222. {codeplain-0.3.0 → codeplain-0.3.2}/tests/test_file_utils.py +0 -0
  223. {codeplain-0.3.0 → codeplain-0.3.2}/tests/test_git_utils.py +0 -0
  224. {codeplain-0.3.0 → codeplain-0.3.2}/tests/test_imports.py +0 -0
  225. {codeplain-0.3.0 → codeplain-0.3.2}/tests/test_partial_rendering.py +0 -0
  226. {codeplain-0.3.0 → codeplain-0.3.2}/tests/test_plain_modules.py +0 -0
  227. {codeplain-0.3.0 → codeplain-0.3.2}/tests/test_plainfile.py +0 -0
  228. {codeplain-0.3.0 → codeplain-0.3.2}/tests/test_plainspec.py +0 -0
  229. {codeplain-0.3.0 → codeplain-0.3.2}/tests/test_requires.py +0 -0
  230. {codeplain-0.3.0 → codeplain-0.3.2}/tests/test_resolve_config_file.py +0 -0
  231. {codeplain-0.3.0 → codeplain-0.3.2}/tui/__init__.py +0 -0
  232. {codeplain-0.3.0 → codeplain-0.3.2}/tui/models.py +0 -0
  233. {codeplain-0.3.0 → codeplain-0.3.2}/tui/spinner.py +0 -0
  234. {codeplain-0.3.0 → codeplain-0.3.2}/tui/state_handlers.py +0 -0
@@ -0,0 +1,32 @@
1
+ {
2
+ "includeCoAuthoredBy": false,
3
+ "attribution": { "commit": "", "pr": "" },
4
+ "permissions": {
5
+ "allow": [
6
+ "Read",
7
+ "Bash(pytest *)",
8
+ "Bash(black *)",
9
+ "Bash(isort *)",
10
+ "Bash(flake8 *)",
11
+ "Bash(mypy *)",
12
+ "Bash(coverage *)",
13
+ "Bash(git status*)",
14
+ "Bash(git diff*)",
15
+ "Bash(git log*)",
16
+ "Bash(gh issue *)",
17
+ "Bash(gh pr *)",
18
+ "Bash(gh api *)",
19
+ "Bash(gh repo *)",
20
+ "Bash(gh run *)",
21
+ "Bash(ls *)",
22
+ "Bash(cat *)",
23
+ "Bash(grep *)",
24
+ "Bash(find *)",
25
+ "Bash(head *)",
26
+ "Bash(tail *)",
27
+ "Bash(conda *)",
28
+ "Bash(.venv/bin/python *)",
29
+ "Bash(python plain2code.py *)"
30
+ ]
31
+ }
32
+ }
@@ -0,0 +1,62 @@
1
+ # .github/workflows/e2e.yml
2
+ name: E2E
3
+
4
+ on:
5
+ schedule:
6
+ - cron: '0 5 * * 1-5' # weekday nights to catch API drift
7
+ workflow_dispatch:
8
+
9
+ jobs:
10
+ e2e-linux:
11
+ runs-on: ubuntu-latest
12
+ timeout-minutes: 15
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - uses: actions/setup-python@v5
17
+ with:
18
+ python-version: '3.12'
19
+
20
+ - run: pip install pytest
21
+
22
+ - name: Set up Docker Buildx
23
+ uses: docker/setup-buildx-action@v3
24
+
25
+ - name: Build E2E image (cached)
26
+ uses: docker/build-push-action@v5
27
+ with:
28
+ context: .
29
+ file: tests/e2e/Dockerfile
30
+ tags: codeplain-e2e:latest
31
+ load: true
32
+ cache-from: type=gha
33
+ cache-to: type=gha,mode=max
34
+
35
+ - name: Run E2E tests
36
+ env:
37
+ CODEPLAIN_API_KEY: ${{ secrets.CODEPLAIN_API_KEY }}
38
+ run: pytest tests/e2e/ -v --tb=short
39
+
40
+ - name: Upload generated outputs on failure
41
+ if: failure()
42
+ uses: actions/upload-artifact@v4
43
+ with:
44
+ name: e2e-outputs-linux
45
+ path: /tmp/pytest-of-runner/**/container_work*/**
46
+
47
+ e2e-windows:
48
+ runs-on: windows-latest
49
+ timeout-minutes: 15
50
+ steps:
51
+ - uses: actions/checkout@v4
52
+
53
+ - uses: actions/setup-python@v5
54
+ with:
55
+ python-version: '3.12'
56
+
57
+ - run: pip install pytest
58
+
59
+ - name: Run E2E tests
60
+ env:
61
+ CODEPLAIN_API_KEY: ${{ secrets.CODEPLAIN_API_KEY }}
62
+ run: pytest tests/e2e/ -v --tb=short
@@ -0,0 +1,46 @@
1
+ // Zed project-local settings, converted from .vscode/settings.json.
2
+ // Docs: https://zed.dev/docs/configuring-zed
3
+ {
4
+ "format_on_save": "on",
5
+ "languages": {
6
+ "Python": {
7
+ "tab_size": 4,
8
+ "hard_tabs": false,
9
+ "preferred_line_length": 120,
10
+ "wrap_guides": [120],
11
+ "format_on_save": "on",
12
+ // Run isort first (organize imports), then black (format).
13
+ // Matches `source.organizeImports: explicit` + black-formatter from VS Code.
14
+ "formatter": [
15
+ {
16
+ "external": {
17
+ "command": "isort",
18
+ "arguments": ["--profile", "black", "--filename", "{buffer_path}", "-"]
19
+ }
20
+ },
21
+ {
22
+ "external": {
23
+ "command": "black",
24
+ "arguments": ["--quiet", "--stdin-filename", "{buffer_path}", "-"]
25
+ }
26
+ }
27
+ ]
28
+ }
29
+ },
30
+ // Treat fixture files under tests/data as plain text (matches files.associations).
31
+ "file_types": {
32
+ "Plain Text": ["tests/data/**"]
33
+ },
34
+ // python.analysis.extraPaths -> Pyright (Zed's default Python LSP).
35
+ "lsp": {
36
+ "pyright": {
37
+ "settings": {
38
+ "python": {
39
+ "analysis": {
40
+ "extraPaths": ["."]
41
+ }
42
+ }
43
+ }
44
+ }
45
+ }
46
+ }
@@ -0,0 +1,238 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Overview
6
+
7
+ This is **codeplain**, a Python CLI tool that renders code from `***plain` specification files using the Codeplain API. The tool acts as a client that:
8
+ 1. Parses `***plain` spec files (a domain-specific language for software specifications)
9
+ 2. Sends specs to the Codeplain API (LLM-based code generation service)
10
+ 3. Manages an iterative state-machine-driven render process with testing and refactoring cycles
11
+ 4. Outputs generated code to a build folder
12
+
13
+ The codebase serves two audiences:
14
+ - **End users**: developers who write `***plain` specs and run `plain2code.py` to generate code
15
+ - **Internal devs**: maintaining the renderer itself (this codebase)
16
+
17
+ ### Related Repository: plain2code_rest_api
18
+
19
+ This repository has a sibling repository **`plain2code_rest_api`** which contains the backend API service that this client communicates with. The two repositories are typically cloned as siblings:
20
+
21
+ ```
22
+ parent-directory/
23
+ ├── codeplain/ # This repository (client)
24
+ └── plain2code_rest_api/ # Backend API service
25
+ ```
26
+
27
+ **When to work across both repositories:**
28
+ - API contract changes (request/response formats)
29
+ - Adding new endpoints or modifying existing ones
30
+ - Debugging communication issues between client and server
31
+ - End-to-end feature development that requires both client and server changes
32
+
33
+ When working on features that span both repositories, coordinate changes carefully to maintain backward compatibility or plan coordinated deployments.
34
+
35
+ ## Development Setup
36
+
37
+ ### Prerequisites
38
+ - Python 3.11+
39
+ - `CODEPLAIN_API_KEY` environment variable set
40
+
41
+ ### Installation
42
+ ```bash
43
+ python -m venv .venv
44
+ source .venv/bin/activate # On Windows: .venv\Scripts\activate
45
+ pip install -r requirements.txt
46
+ ```
47
+
48
+ ### Git Hooks
49
+ A pre-push hook runs automatically on `git push` and executes:
50
+ - Black formatting check
51
+ - isort import sorting check
52
+ - Flake8 linting
53
+ - Mypy type checking
54
+ - Full test suite with coverage
55
+
56
+ Hook is located at `.git/hooks/pre-push`.
57
+
58
+ ## Common Commands
59
+
60
+ ### Running the Tool
61
+ ```bash
62
+ # Basic usage - render a .plain file
63
+ python plain2code.py path/to/file.plain
64
+
65
+ # Display account status (user info, credits, API key label)
66
+ python plain2code.py --status
67
+
68
+ # Dry run (parse and validate .plain files without rendering code)
69
+ # This parses the spec files, resolves imports/requires, but doesn't generate code
70
+ python plain2code.py path/to/file.plain --dry-run
71
+
72
+ # Enable file logging (writes to codeplain.log in same dir as .plain file)
73
+ python plain2code.py path/to/file.plain --log-to-file
74
+
75
+ # Headless mode (no TUI, logs to file only)
76
+ python plain2code.py path/to/file.plain --headless
77
+
78
+ # Render specific functionality range
79
+ python plain2code.py file.plain --render-range 1,3 # Render functionalities 1-3
80
+ python plain2code.py file.plain --render-from 2 # Resume from functionality 2
81
+
82
+ # Run with examples
83
+ cd examples/example_hello_world_python
84
+ python ../../plain2code.py hello_world_python.plain
85
+ cd build && python hello_world.py
86
+ ```
87
+
88
+ ### Testing
89
+ ```bash
90
+ # Run all tests
91
+ pytest tests/ -v
92
+
93
+ # Run specific test file
94
+ pytest tests/test_plain_modules.py -v
95
+
96
+ # Run specific test
97
+ pytest tests/test_plain_modules.py::test_get_next_frid_within_same_module -v
98
+
99
+ # Run with coverage
100
+ coverage run -m pytest tests/ -v
101
+ coverage report
102
+ coverage html # Generates htmlcov/index.html
103
+ ```
104
+
105
+ ### Code Quality
106
+ ```bash
107
+ # Format code
108
+ black .
109
+
110
+ # Sort imports
111
+ isort .
112
+
113
+ # Lint
114
+ flake8 .
115
+
116
+ # Type check
117
+ mypy . --check-untyped-defs
118
+
119
+ # Run all checks (same as pre-push hook)
120
+ black . --check && isort . --check-only && flake8 . && mypy . --check-untyped-defs && coverage run -m pytest tests/ -v && coverage report
121
+ ```
122
+
123
+ ## Architecture
124
+
125
+ ### High-Level Flow
126
+ 1. **Entry Point** (`plain2code.py`): CLI argument parsing, logging setup, TUI initialization
127
+ 2. **Module Loading** (`plain_modules.py`, `plain_file.py`): Parse `.plain` files into `PlainModule` objects with dependency trees
128
+ 3. **Rendering Orchestration** (`module_renderer.py`): Coordinates render process across modules
129
+ 4. **State Machine** (`render_machine/`): Hierarchical state machine drives the render lifecycle
130
+ 5. **API Communication** (`codeplain_REST_api.py`): HTTP client for Codeplain API
131
+ 6. **Code Generation** (`render_machine/code_renderer.py`): Main code renderer class that orchestrates the code generation workflow using a hierarchical state machine
132
+ 7. **TUI** (`tui/`): Textual-based terminal UI showing render progress
133
+ 8. **CLI Output** (`cli_output/`): Non-interactive terminal output formatting for status, dry-run, and render summaries
134
+
135
+ ### Key Concepts
136
+
137
+ **Plain Modules**: A `.plain` file can `import` other `.plain` files, creating a module dependency tree. The renderer processes required modules first (depth-first), then the top module.
138
+
139
+ **Functionalities (FRIDs)**: Each functional requirement in a `.plain` file has a unique ID (FRID). The renderer processes them sequentially. State is checkpointed after each FRID.
140
+
141
+ **Render State Machine** (`render_machine/states.py`): Hierarchical FSM with states like:
142
+ - `IMPLEMENTING_FRID` → `PROCESSING_UNIT_TESTS` → `REFACTORING_CODE` → `PROCESSING_CONFORMANCE_TESTS`
143
+ - Transitions handled by triggers in `render_machine/triggers.py`
144
+ - Config in `render_machine/state_machine_config.py`
145
+
146
+ **Memory Management** (`memory_management.py`): Tracks previously rendered code to provide context to the LLM for incremental changes. Uses git commits to persist checkpoints.
147
+
148
+ **Partial Rendering** (`partial_rendering.py`): Detects when specs or code changed and determines the optimal starting point to resume rendering (avoids full re-renders).
149
+
150
+ **Event Bus** (`event_bus.py`): Pub/sub for UI updates. Events defined in `plain2code_events.py` (e.g., `LogMessageEmitted`, `RenderCompleted`).
151
+
152
+ ### Directory Structure
153
+
154
+ - `plain2code.py` - Main CLI entry point
155
+ - `plain2code_arguments.py` - CLI argument parsing and validation
156
+ - `plain2code_utils.py` - Pure utility functions (duration formatting, ambiguity messages)
157
+ - `plain_modules.py` - Module dependency resolution
158
+ - `plain_file.py` - `.plain` file parser
159
+ - `plain_spec.py` - Spec extraction and FRID utilities
160
+ - `module_renderer.py` - Orchestrates render for a module
161
+ - `render_machine/` - State machine implementation
162
+ - `code_renderer.py` - Generates code via templates
163
+ - `states.py` - State name constants
164
+ - `triggers.py` - State transition logic
165
+ - `render_context.py` - Shared context across states
166
+ - `conformance_tests.py` - Test generation and execution
167
+ - `tui/` - Interactive terminal UI (Textual framework)
168
+ - `plain2code_tui.py` - Main TUI app
169
+ - `components.py` - Custom UI widgets
170
+ - `cli_output/` - Non-interactive CLI output formatting
171
+ - `status.py` - Status display (`--status` flag)
172
+ - `dry_run.py` - Dry run output (`--dry-run` flag)
173
+ - `render_summary.py` - Render completion summary
174
+ - `codeplain_REST_api.py` - API client
175
+ - `memory_management.py` - Context tracking
176
+ - `git_utils.py` - Git operations for checkpointing
177
+ - `file_utils.py` - File I/O utilities
178
+ - `concept_utils.py` - Concept validation (***plain language feature)
179
+ - `plain2code_logger.py` - Custom logging with elapsed time timestamps
180
+ - `plain2code_console.py` - Rich console wrapper with custom styles
181
+ - `plain2code_state.py` - Runtime state (render ID, counters, timing)
182
+ - `standard_template_library/` - Built-in code templates
183
+ - `examples/` - Sample `.plain` projects
184
+
185
+ ### Testing Architecture
186
+
187
+ Tests are in `tests/` and cover:
188
+ - `test_plain_modules.py` - Module loading, dependency resolution, metadata
189
+ - `test_plainfileparser.py` - `.plain` syntax parsing
190
+ - `test_partial_rendering.py` - Render resumption logic
191
+ - `test_git_utils.py` - Git checkpoint/restore operations
192
+ - `test_imports.py`, `test_requires.py` - Module dependency resolution
193
+
194
+ No integration tests hit the actual Codeplain API (would require API key + network). Testing focuses on parser, state management, and file operations.
195
+
196
+ ### Logging
197
+
198
+ Two logging modes:
199
+ 1. **Console (TUI)**: Logs displayed in TUI with relative timestamps `[HH:MM:SS]` (elapsed since render start, accounts for pauses)
200
+ 2. **File**: Same format as TUI, written to `codeplain.log` in the `.plain` file's directory
201
+
202
+ `ElapsedTimeFormatter` (in `plain2code_logger.py`) uses `RunState` to calculate elapsed time. Format: `[HH:MM:SS] LEVEL logger_name: message`
203
+
204
+ ## Important Notes
205
+
206
+ ### Plain Specification Language
207
+ - `***plain` is a Markdown-like DSL for software specs
208
+ - Docs at https://www.plainlang.org/docs/
209
+ - Parser handles sections: definitions, functional specs, implementation reqs, test reqs, acceptance tests
210
+ - Concepts (domain terms) validated across modules via `concept_utils.py`
211
+
212
+ ### Code Generation Process
213
+ - Templates in `standard_template_library/` use Liquid2 syntax
214
+ - Template search order: (1) `.plain` file dir, (2) `--template-dir`, (3) built-in standard lib
215
+ - Generated code written to `build/` (configurable via `--build-folder`)
216
+ - Each FRID render produces a git commit in build folder for rollback capability
217
+
218
+ ### Configuration
219
+ - `config.yaml` can be placed in `.plain` file dir or CWD
220
+ - Specifies test scripts, template dirs, build paths
221
+ - CLI args override config file values
222
+
223
+ ### Running Plain2Code from Another Directory
224
+ The tool can be run from any directory by providing an absolute or relative path to the `.plain` file. All paths (build folder, log file, templates) are resolved relative to the `.plain` file's directory, not the current working directory, unless explicitly overridden via CLI arguments.
225
+
226
+ ### Windows Support
227
+ Windows users must use WSL (Windows Subsystem for Linux). The codebase has some platform-specific script handling (`.ps1` for Windows, `.sh` for Unix).
228
+
229
+ ### CRITICAL: No User-Specific Paths in Version Control
230
+ **Never commit files containing user-specific absolute paths** (e.g., `/Users/username/...`, `/home/username/...`, `C:\Users\...`) to version-controlled files like:
231
+ - `.claude/settings.json` - Use relative paths (`.venv/bin/python`) instead of absolute paths
232
+ - `config.yaml` or any config files
233
+ - Any documentation or scripts
234
+
235
+ User-specific paths should only exist in:
236
+ - `.claude/settings.local.json` (gitignored)
237
+ - Personal `.env` files (gitignored)
238
+ - User's global `~/.claude/settings.json`
@@ -1,27 +1,27 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codeplain
3
- Version: 0.3.0
3
+ Version: 0.3.2
4
4
  Summary: Transform plain language specifications into working code
5
5
  License-File: LICENSE
6
6
  Classifier: Environment :: Console
7
7
  Classifier: Intended Audience :: Developers
8
8
  Classifier: Operating System :: OS Independent
9
9
  Classifier: Topic :: Software Development :: Code Generators
10
- Requires-Python: ==3.11
10
+ Requires-Python: >=3.11
11
11
  Requires-Dist: gitpython==3.1.50
12
12
  Requires-Dist: mistletoe==1.3.0
13
13
  Requires-Dist: networkx==3.6.1
14
- Requires-Dist: python-frontmatter==1.1.0
14
+ Requires-Dist: python-frontmatter==1.3.0
15
15
  Requires-Dist: python-liquid2==0.3.0
16
16
  Requires-Dist: pyyaml==6.0.3
17
17
  Requires-Dist: requests==2.34.0
18
- Requires-Dist: rich==14.2.0
18
+ Requires-Dist: rich==15.0.0
19
19
  Requires-Dist: textual>=7.5.0
20
20
  Requires-Dist: tiktoken==0.12.0
21
21
  Requires-Dist: transitions==0.9.3
22
22
  Provides-Extra: dev
23
23
  Requires-Dist: black==26.3.1; extra == 'dev'
24
- Requires-Dist: flake8==7.0.0; extra == 'dev'
24
+ Requires-Dist: flake8==7.3.0; extra == 'dev'
25
25
  Requires-Dist: isort==5.13.2; extra == 'dev'
26
26
  Requires-Dist: mypy==1.11.2; extra == 'dev'
27
27
  Requires-Dist: pytest==8.3.5; extra == 'dev'
@@ -29,31 +29,28 @@ Description-Content-Type: text/markdown
29
29
 
30
30
  # Codeplain plain2code renderer
31
31
 
32
- Render ***plain source to software code using the Codeplain API.
32
+ Render \*\*\*plain source to software code using the Codeplain API.
33
33
 
34
34
  ## Codeplain.ai - Code Generation as a Service
35
35
 
36
- Codeplain is a platform that generates software code using large language models based on requirements you specify in ***plain specification language.
36
+ Codeplain is a platform that generates software code using large language models based on requirements you specify in \*\*\*plain specification language.
37
37
 
38
38
  Schematic overview of the Codeplain's code generation service
39
39
 
40
40
  <img src="https://raw.githubusercontent.com/Codeplain-ai/plain2code_client/main/resources/codeplain_overview.png">
41
41
 
42
- ### Abstracting Away Code Generation Complexity with ***plain
42
+ ### Abstracting Away Code Generation Complexity with \*\*\*plain
43
43
 
44
+ \*\*\*plain is a novel specification language that helps abstracting away complexity of using large language models for code generation.
44
45
 
45
- ***plain is a novel specification language that helps abstracting away complexity of using large language models for code generation.
46
-
47
- An example application in ***plain
46
+ An example application in \*\*\*plain
48
47
 
49
48
  <img src="resources/plain_example.png" width="70%" height="70%">
50
49
 
51
-
52
50
  ## Getting started
53
51
 
54
52
  ### Prerequisites
55
53
 
56
-
57
54
  #### System requirements
58
55
 
59
56
  To run the plain2code client, you need Python 3.11 or a later version.
@@ -92,31 +89,55 @@ export CODEPLAIN_API_KEY="your_actual_api_key_here"
92
89
  After completing the installation steps above, you can immediately test the system with a simple "Hello World" example:
93
90
 
94
91
  - Change to the example folder and run the example:
95
- ```
96
- cd examples/example_hello_world_python
97
- python ../../plain2code.py hello_world_python.plain
98
- ```
99
92
 
100
- *Note: Rendering will take a few minutes to complete.*
93
+ ```
94
+ cd examples/example_hello_world_python
95
+ python ../../plain2code.py hello_world_python.plain
96
+ ```
97
+
98
+ _Note: Rendering will take a few minutes to complete._
101
99
 
102
100
  - The system will generate a Python application in the `build` directory. You can run it with:
101
+ ```
102
+ cd build
103
+ python hello_world.py
104
+ ```
105
+
106
+ ## Releasing
107
+
108
+ Releases are built and published with [uv](https://docs.astral.sh/uv/). The version is read from `_version.py`.
109
+
110
+ 1. Bump the version in `_version.py` and commit/tag (`git tag v<version>`).
111
+ 2. Build the distributions:
112
+ ```bash
113
+ uv build --python 3.11
114
+ ```
115
+ This produces `dist/codeplain-<version>-py3-none-any.whl` and `dist/codeplain-<version>.tar.gz`.
116
+ 3. (Optional) Smoke-test the wheel:
117
+ ```bash
118
+ uv run --with dist/codeplain-<version>-py3-none-any.whl --no-project -- codeplain --status
119
+ ```
120
+ 4. (Optional) Publish to TestPyPI first:
121
+ ```bash
122
+ uv publish --publish-url https://test.pypi.org/legacy/ dist/codeplain-<version>*
103
123
  ```
104
- cd build
105
- python hello_world.py
124
+ 5. Publish to PyPI:
125
+ ```bash
126
+ uv publish dist/codeplain-<version>*
106
127
  ```
128
+ Authenticate with `UV_PUBLISH_TOKEN=pypi-...` (recommended), `--token pypi-...`, or `--username __token__ --password pypi-...`.
129
+ 6. Push the tag: `git push origin v<version>`.
107
130
 
108
131
  ## Additional Resources
109
132
 
110
133
  ### Examples and Sample Projects
111
134
 
112
135
  - See the [examples](examples) folder for sample projects in Golang, Python, and React.
113
- - For example application how to implement task manager in ***plain see [example-task-manager](https://github.com/Codeplain-ai/example-task-manager) repository.
114
- - For example application how to implement SaaS connectors in ***plain see [example-saas-connectors](https://github.com/Codeplain-ai/example-saas-connectors) repository.
136
+ - For example application how to implement task manager in \*\*\*plain see [example-task-manager](https://github.com/Codeplain-ai/example-task-manager) repository.
137
+ - For example application how to implement SaaS connectors in \*\*\*plain see [example-saas-connectors](https://github.com/Codeplain-ai/example-saas-connectors) repository.
115
138
 
116
139
  ### Documentation
117
140
 
118
141
  - For more details on the ***plain format, see the [***plain language specification](https://www.plainlang.org/docs/).
119
142
  - For step-by-step instructions for creating your first ***plain project see the [Kickstart your ***plain project](docs/starting_a_plain_project_from_scratch.md).
120
143
  - For complete CLI documentation and usage examples, see [plain2code CLI documentation](docs/plain2code_cli.md).
121
-
122
-
@@ -1,30 +1,27 @@
1
1
  # Codeplain plain2code renderer
2
2
 
3
- Render ***plain source to software code using the Codeplain API.
3
+ Render \*\*\*plain source to software code using the Codeplain API.
4
4
 
5
5
  ## Codeplain.ai - Code Generation as a Service
6
6
 
7
- Codeplain is a platform that generates software code using large language models based on requirements you specify in ***plain specification language.
7
+ Codeplain is a platform that generates software code using large language models based on requirements you specify in \*\*\*plain specification language.
8
8
 
9
9
  Schematic overview of the Codeplain's code generation service
10
10
 
11
11
  <img src="https://raw.githubusercontent.com/Codeplain-ai/plain2code_client/main/resources/codeplain_overview.png">
12
12
 
13
- ### Abstracting Away Code Generation Complexity with ***plain
13
+ ### Abstracting Away Code Generation Complexity with \*\*\*plain
14
14
 
15
+ \*\*\*plain is a novel specification language that helps abstracting away complexity of using large language models for code generation.
15
16
 
16
- ***plain is a novel specification language that helps abstracting away complexity of using large language models for code generation.
17
-
18
- An example application in ***plain
17
+ An example application in \*\*\*plain
19
18
 
20
19
  <img src="resources/plain_example.png" width="70%" height="70%">
21
20
 
22
-
23
21
  ## Getting started
24
22
 
25
23
  ### Prerequisites
26
24
 
27
-
28
25
  #### System requirements
29
26
 
30
27
  To run the plain2code client, you need Python 3.11 or a later version.
@@ -63,31 +60,55 @@ export CODEPLAIN_API_KEY="your_actual_api_key_here"
63
60
  After completing the installation steps above, you can immediately test the system with a simple "Hello World" example:
64
61
 
65
62
  - Change to the example folder and run the example:
66
- ```
67
- cd examples/example_hello_world_python
68
- python ../../plain2code.py hello_world_python.plain
69
- ```
70
63
 
71
- *Note: Rendering will take a few minutes to complete.*
64
+ ```
65
+ cd examples/example_hello_world_python
66
+ python ../../plain2code.py hello_world_python.plain
67
+ ```
68
+
69
+ _Note: Rendering will take a few minutes to complete._
72
70
 
73
71
  - The system will generate a Python application in the `build` directory. You can run it with:
72
+ ```
73
+ cd build
74
+ python hello_world.py
75
+ ```
76
+
77
+ ## Releasing
78
+
79
+ Releases are built and published with [uv](https://docs.astral.sh/uv/). The version is read from `_version.py`.
80
+
81
+ 1. Bump the version in `_version.py` and commit/tag (`git tag v<version>`).
82
+ 2. Build the distributions:
83
+ ```bash
84
+ uv build --python 3.11
85
+ ```
86
+ This produces `dist/codeplain-<version>-py3-none-any.whl` and `dist/codeplain-<version>.tar.gz`.
87
+ 3. (Optional) Smoke-test the wheel:
88
+ ```bash
89
+ uv run --with dist/codeplain-<version>-py3-none-any.whl --no-project -- codeplain --status
90
+ ```
91
+ 4. (Optional) Publish to TestPyPI first:
92
+ ```bash
93
+ uv publish --publish-url https://test.pypi.org/legacy/ dist/codeplain-<version>*
74
94
  ```
75
- cd build
76
- python hello_world.py
95
+ 5. Publish to PyPI:
96
+ ```bash
97
+ uv publish dist/codeplain-<version>*
77
98
  ```
99
+ Authenticate with `UV_PUBLISH_TOKEN=pypi-...` (recommended), `--token pypi-...`, or `--username __token__ --password pypi-...`.
100
+ 6. Push the tag: `git push origin v<version>`.
78
101
 
79
102
  ## Additional Resources
80
103
 
81
104
  ### Examples and Sample Projects
82
105
 
83
106
  - See the [examples](examples) folder for sample projects in Golang, Python, and React.
84
- - For example application how to implement task manager in ***plain see [example-task-manager](https://github.com/Codeplain-ai/example-task-manager) repository.
85
- - For example application how to implement SaaS connectors in ***plain see [example-saas-connectors](https://github.com/Codeplain-ai/example-saas-connectors) repository.
107
+ - For example application how to implement task manager in \*\*\*plain see [example-task-manager](https://github.com/Codeplain-ai/example-task-manager) repository.
108
+ - For example application how to implement SaaS connectors in \*\*\*plain see [example-saas-connectors](https://github.com/Codeplain-ai/example-saas-connectors) repository.
86
109
 
87
110
  ### Documentation
88
111
 
89
112
  - For more details on the ***plain format, see the [***plain language specification](https://www.plainlang.org/docs/).
90
113
  - For step-by-step instructions for creating your first ***plain project see the [Kickstart your ***plain project](docs/starting_a_plain_project_from_scratch.md).
91
114
  - For complete CLI documentation and usage examples, see [plain2code CLI documentation](docs/plain2code_cli.md).
92
-
93
-
@@ -0,0 +1 @@
1
+ __version__ = "0.3.2"
@@ -0,0 +1,7 @@
1
+ """CLI output formatting for non-interactive display."""
2
+
3
+ from cli_output.dry_run import print_dry_run_output
4
+ from cli_output.render_summary import print_exit_summary
5
+ from cli_output.status import print_status
6
+
7
+ __all__ = ["print_dry_run_output", "print_exit_summary", "print_status"]
@@ -1,34 +1,13 @@
1
+ """Dry run output display for --dry-run flag."""
2
+
1
3
  from typing import Optional
2
4
 
3
5
  import plain_spec
4
6
  from plain2code_console import console
5
7
 
6
8
 
7
- def format_duration_hms(total_seconds: int) -> str:
8
- """Format a duration in seconds as hours, minutes, and seconds (e.g. ``1h 2m 3.45s``, ``45.67s``)."""
9
- if total_seconds < 0:
10
- total_seconds = 0
11
- h = int(total_seconds // 3600)
12
- m = int((total_seconds % 3600) // 60)
13
- s = total_seconds % 60
14
- if h:
15
- return f"{h}h {m}m {s}s"
16
- if m:
17
- return f"{m}m {s}s"
18
- text = f"{s}".rstrip("0").rstrip(".")
19
- return f"{text}s" if text else "0s"
20
-
21
-
22
- AMBIGUITY_CAUSES = {
23
- "reference_resource_ambiguity": "Ambiguity is in the reference resources",
24
- "definition_ambiguity": "Ambiguity is in the definitions",
25
- "non_functional_requirement_ambiguity": "Ambiguity is in the implementation reqs",
26
- "functional_requirement_ambiguity": "Ambiguity is in the functionality",
27
- "other": "Ambiguity in the other parts of the specification",
28
- }
29
-
30
-
31
9
  def print_dry_run_output(plain_source_tree: dict, render_range: Optional[list[str]]):
10
+ """Print dry run output showing what would be rendered."""
32
11
  frid = plain_spec.get_first_frid(plain_source_tree)
33
12
 
34
13
  while frid is not None: