codeplain 0.2.1__tar.gz → 0.2.3__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 (190) hide show
  1. codeplain-0.2.3/.github/workflows/publish-install-script.yml +30 -0
  2. {codeplain-0.2.1 → codeplain-0.2.3}/.github/workflows/publish-to-pypi.yml +33 -10
  3. {codeplain-0.2.1 → codeplain-0.2.3}/PKG-INFO +1 -1
  4. codeplain-0.2.3/install.sh +136 -0
  5. {codeplain-0.2.1 → codeplain-0.2.3}/plain2code.py +21 -2
  6. {codeplain-0.2.1 → codeplain-0.2.3}/plain2code_arguments.py +0 -4
  7. {codeplain-0.2.1 → codeplain-0.2.3}/plain2code_exceptions.py +4 -0
  8. {codeplain-0.2.1 → codeplain-0.2.3}/pyproject.toml +6 -7
  9. codeplain-0.2.1/install.sh +0 -217
  10. {codeplain-0.2.1 → codeplain-0.2.3}/.flake8 +0 -0
  11. {codeplain-0.2.1 → codeplain-0.2.3}/.github/workflows/lint-and-test.yml +0 -0
  12. {codeplain-0.2.1 → codeplain-0.2.3}/.github/workflows/nofity-slack-on-main-merge.yml +0 -0
  13. {codeplain-0.2.1 → codeplain-0.2.3}/.gitignore +0 -0
  14. {codeplain-0.2.1 → codeplain-0.2.3}/.vscode/launch.json +0 -0
  15. {codeplain-0.2.1 → codeplain-0.2.3}/.vscode/settings.json +0 -0
  16. {codeplain-0.2.1 → codeplain-0.2.3}/LICENSE +0 -0
  17. {codeplain-0.2.1 → codeplain-0.2.3}/README.md +0 -0
  18. {codeplain-0.2.1 → codeplain-0.2.3}/codeplain_REST_api.py +0 -0
  19. {codeplain-0.2.1 → codeplain-0.2.3}/concept_utils.py +0 -0
  20. {codeplain-0.2.1 → codeplain-0.2.3}/config/__init__.py +0 -0
  21. {codeplain-0.2.1 → codeplain-0.2.3}/config/system_config.yaml +0 -0
  22. {codeplain-0.2.1 → codeplain-0.2.3}/diff_utils.py +0 -0
  23. {codeplain-0.2.1 → codeplain-0.2.3}/docs/generate_cli.py +0 -0
  24. {codeplain-0.2.1 → codeplain-0.2.3}/docs/plain2code_cli.md +0 -0
  25. {codeplain-0.2.1 → codeplain-0.2.3}/docs/plain_language_specification.md +0 -0
  26. {codeplain-0.2.1 → codeplain-0.2.3}/docs/starting_a_plain_project_from_scratch.md +0 -0
  27. {codeplain-0.2.1 → codeplain-0.2.3}/event_bus.py +0 -0
  28. {codeplain-0.2.1 → codeplain-0.2.3}/examples/example_hello_world_golang/config.yaml +0 -0
  29. {codeplain-0.2.1 → codeplain-0.2.3}/examples/example_hello_world_golang/harness_tests/hello_world_test.go +0 -0
  30. {codeplain-0.2.1 → codeplain-0.2.3}/examples/example_hello_world_golang/hello_world_golang.plain +0 -0
  31. {codeplain-0.2.1 → codeplain-0.2.3}/examples/example_hello_world_golang/run.sh +0 -0
  32. {codeplain-0.2.1 → codeplain-0.2.3}/examples/example_hello_world_python/config.yaml +0 -0
  33. {codeplain-0.2.1 → codeplain-0.2.3}/examples/example_hello_world_python/harness_tests/hello_world_display/test_hello_world.py +0 -0
  34. {codeplain-0.2.1 → codeplain-0.2.3}/examples/example_hello_world_python/hello_world_python.plain +0 -0
  35. {codeplain-0.2.1 → codeplain-0.2.3}/examples/example_hello_world_python/run.sh +0 -0
  36. {codeplain-0.2.1 → codeplain-0.2.3}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress/e2e/hello_world.cy.ts +0 -0
  37. {codeplain-0.2.1 → codeplain-0.2.3}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress/support/e2e.ts +0 -0
  38. {codeplain-0.2.1 → codeplain-0.2.3}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress.config.ts +0 -0
  39. {codeplain-0.2.1 → codeplain-0.2.3}/examples/example_hello_world_react/harness_tests/hello_world_display/package.json +0 -0
  40. {codeplain-0.2.1 → codeplain-0.2.3}/examples/example_hello_world_react/harness_tests/hello_world_display/tsconfig.json +0 -0
  41. {codeplain-0.2.1 → codeplain-0.2.3}/examples/example_hello_world_react/hello_world_react.plain +0 -0
  42. {codeplain-0.2.1 → codeplain-0.2.3}/examples/example_hello_world_react/run.sh +0 -0
  43. {codeplain-0.2.1 → codeplain-0.2.3}/examples/run.sh +0 -0
  44. {codeplain-0.2.1 → codeplain-0.2.3}/file_utils.py +0 -0
  45. {codeplain-0.2.1 → codeplain-0.2.3}/git_utils.py +0 -0
  46. {codeplain-0.2.1 → codeplain-0.2.3}/hash_key.py +0 -0
  47. {codeplain-0.2.1 → codeplain-0.2.3}/memory_management.py +0 -0
  48. {codeplain-0.2.1 → codeplain-0.2.3}/module_renderer.py +0 -0
  49. {codeplain-0.2.1 → codeplain-0.2.3}/plain2code_console.py +0 -0
  50. {codeplain-0.2.1 → codeplain-0.2.3}/plain2code_events.py +0 -0
  51. {codeplain-0.2.1 → codeplain-0.2.3}/plain2code_logger.py +0 -0
  52. {codeplain-0.2.1 → codeplain-0.2.3}/plain2code_nodes.py +0 -0
  53. {codeplain-0.2.1 → codeplain-0.2.3}/plain2code_read_config.py +0 -0
  54. {codeplain-0.2.1 → codeplain-0.2.3}/plain2code_state.py +0 -0
  55. {codeplain-0.2.1 → codeplain-0.2.3}/plain2code_utils.py +0 -0
  56. {codeplain-0.2.1 → codeplain-0.2.3}/plain_file.py +0 -0
  57. {codeplain-0.2.1 → codeplain-0.2.3}/plain_modules.py +0 -0
  58. {codeplain-0.2.1 → codeplain-0.2.3}/plain_spec.py +0 -0
  59. {codeplain-0.2.1 → codeplain-0.2.3}/pytest.ini +0 -0
  60. {codeplain-0.2.1 → codeplain-0.2.3}/render_machine/__init__.py +0 -0
  61. {codeplain-0.2.1 → codeplain-0.2.3}/render_machine/actions/analyze_specification_ambiguity.py +0 -0
  62. {codeplain-0.2.1 → codeplain-0.2.3}/render_machine/actions/base_action.py +0 -0
  63. {codeplain-0.2.1 → codeplain-0.2.3}/render_machine/actions/commit_conformance_tests_changes.py +0 -0
  64. {codeplain-0.2.1 → codeplain-0.2.3}/render_machine/actions/commit_implementation_code_changes.py +0 -0
  65. {codeplain-0.2.1 → codeplain-0.2.3}/render_machine/actions/create_dist.py +0 -0
  66. {codeplain-0.2.1 → codeplain-0.2.3}/render_machine/actions/exit_with_error.py +0 -0
  67. {codeplain-0.2.1 → codeplain-0.2.3}/render_machine/actions/finish_functional_requirement.py +0 -0
  68. {codeplain-0.2.1 → codeplain-0.2.3}/render_machine/actions/fix_conformance_test.py +0 -0
  69. {codeplain-0.2.1 → codeplain-0.2.3}/render_machine/actions/fix_unit_tests.py +0 -0
  70. {codeplain-0.2.1 → codeplain-0.2.3}/render_machine/actions/prepare_repositories.py +0 -0
  71. {codeplain-0.2.1 → codeplain-0.2.3}/render_machine/actions/prepare_testing_environment.py +0 -0
  72. {codeplain-0.2.1 → codeplain-0.2.3}/render_machine/actions/refactor_code.py +0 -0
  73. {codeplain-0.2.1 → codeplain-0.2.3}/render_machine/actions/render_conformance_tests.py +0 -0
  74. {codeplain-0.2.1 → codeplain-0.2.3}/render_machine/actions/render_functional_requirement.py +0 -0
  75. {codeplain-0.2.1 → codeplain-0.2.3}/render_machine/actions/run_conformance_tests.py +0 -0
  76. {codeplain-0.2.1 → codeplain-0.2.3}/render_machine/actions/run_unit_tests.py +0 -0
  77. {codeplain-0.2.1 → codeplain-0.2.3}/render_machine/actions/summarize_conformance_tests.py +0 -0
  78. {codeplain-0.2.1 → codeplain-0.2.3}/render_machine/code_renderer.py +0 -0
  79. {codeplain-0.2.1 → codeplain-0.2.3}/render_machine/conformance_test_helpers.py +0 -0
  80. {codeplain-0.2.1 → codeplain-0.2.3}/render_machine/conformance_tests.py +0 -0
  81. {codeplain-0.2.1 → codeplain-0.2.3}/render_machine/implementation_code_helpers.py +0 -0
  82. {codeplain-0.2.1 → codeplain-0.2.3}/render_machine/render_context.py +0 -0
  83. {codeplain-0.2.1 → codeplain-0.2.3}/render_machine/render_types.py +0 -0
  84. {codeplain-0.2.1 → codeplain-0.2.3}/render_machine/render_utils.py +0 -0
  85. {codeplain-0.2.1 → codeplain-0.2.3}/render_machine/state_machine_config.py +0 -0
  86. {codeplain-0.2.1 → codeplain-0.2.3}/render_machine/states.py +0 -0
  87. {codeplain-0.2.1 → codeplain-0.2.3}/render_machine/triggers.py +0 -0
  88. {codeplain-0.2.1 → codeplain-0.2.3}/requirements.txt +0 -0
  89. {codeplain-0.2.1 → codeplain-0.2.3}/resources/codeplain_overview.png +0 -0
  90. {codeplain-0.2.1 → codeplain-0.2.3}/resources/plain_example.png +0 -0
  91. {codeplain-0.2.1 → codeplain-0.2.3}/spinner.py +0 -0
  92. {codeplain-0.2.1 → codeplain-0.2.3}/standard_template_library/__init__.py +0 -0
  93. {codeplain-0.2.1 → codeplain-0.2.3}/standard_template_library/golang-console-app-template.plain +0 -0
  94. {codeplain-0.2.1 → codeplain-0.2.3}/standard_template_library/python-console-app-template.plain +0 -0
  95. {codeplain-0.2.1 → codeplain-0.2.3}/standard_template_library/typescript-react-app-boilerplate.plain +0 -0
  96. {codeplain-0.2.1 → codeplain-0.2.3}/standard_template_library/typescript-react-app-template.plain +0 -0
  97. {codeplain-0.2.1 → codeplain-0.2.3}/system_config.py +0 -0
  98. {codeplain-0.2.1 → codeplain-0.2.3}/test_scripts/run_conformance_tests_cypress.sh +0 -0
  99. {codeplain-0.2.1 → codeplain-0.2.3}/test_scripts/run_conformance_tests_golang.sh +0 -0
  100. {codeplain-0.2.1 → codeplain-0.2.3}/test_scripts/run_conformance_tests_python.sh +0 -0
  101. {codeplain-0.2.1 → codeplain-0.2.3}/test_scripts/run_unittests_golang.sh +0 -0
  102. {codeplain-0.2.1 → codeplain-0.2.3}/test_scripts/run_unittests_python.sh +0 -0
  103. {codeplain-0.2.1 → codeplain-0.2.3}/test_scripts/run_unittests_react.sh +0 -0
  104. {codeplain-0.2.1 → codeplain-0.2.3}/tests/__init__.py +0 -0
  105. {codeplain-0.2.1 → codeplain-0.2.3}/tests/conftest.py +0 -0
  106. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/imports/circular_imports_1.plain +0 -0
  107. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/imports/circular_imports_2.plain +0 -0
  108. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/imports/circular_imports_main.plain +0 -0
  109. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/imports/diamond_import_1.plain +0 -0
  110. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/imports/diamond_import_2.plain +0 -0
  111. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/imports/diamond_import_common.plain +0 -0
  112. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/imports/diamond_imports_main.plain +0 -0
  113. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/imports/non_existent_import.plain +0 -0
  114. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfile/duplicate_specification_heading.plain +0 -0
  115. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfile/invalid_specification_order.plain +0 -0
  116. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfile/missing_non_functional_requirements.plain +0 -0
  117. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfile/plain_source_with_absolute_link.plain +0 -0
  118. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfile/plain_source_with_url_link.plain +0 -0
  119. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfile/task_manager_with_reference_links.plain +0 -0
  120. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfile/without_non_functional_requirement.plain +0 -0
  121. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfileparser/concept_validation_acceptance_tests.plain +0 -0
  122. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfileparser/concept_validation_acceptance_tests_nondefined.plain +0 -0
  123. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfileparser/concept_validation_defined_nondefined.plain +0 -0
  124. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfileparser/concept_validation_defined_nondefined_2.plain +0 -0
  125. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfileparser/concept_validation_definition.plain +0 -0
  126. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfileparser/concept_validation_noconcepts.plain +0 -0
  127. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfileparser/concept_validation_nonconcept.plain +0 -0
  128. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfileparser/concept_validation_nondefined.plain +0 -0
  129. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfileparser/concept_validation_redefinition.plain +0 -0
  130. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfileparser/concept_validation_several_concepts.plain +0 -0
  131. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfileparser/concept_validation_valid.plain +0 -0
  132. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfileparser/exported_concepts.plain +0 -0
  133. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfileparser/exported_concepts_base.plain +0 -0
  134. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfileparser/exported_concepts_example.plain +0 -0
  135. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfileparser/exported_concepts_missing.plain +0 -0
  136. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfileparser/exported_concepts_missing_example.plain +0 -0
  137. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfileparser/exported_concepts_nested.plain +0 -0
  138. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfileparser/exported_concepts_nested_example.plain +0 -0
  139. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfileparser/exported_concepts_transitive_example.plain +0 -0
  140. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfileparser/exported_concepts_transitive_l1.plain +0 -0
  141. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfileparser/exported_concepts_transitive_l2.plain +0 -0
  142. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfileparser/plain_file_parser_with_comments.plain +0 -0
  143. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfileparser/plain_file_with_comments_indented.plain +0 -0
  144. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfileparser/regular_plain_source.plain +0 -0
  145. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfileparser/required_concepts.plain +0 -0
  146. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfileparser/required_concepts_defs.plain +0 -0
  147. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfileparser/required_concepts_example.plain +0 -0
  148. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfileparser/required_concepts_l1.plain +0 -0
  149. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfileparser/required_concepts_l2.plain +0 -0
  150. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfileparser/required_concepts_missing.plain +0 -0
  151. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfileparser/required_concepts_module.plain +0 -0
  152. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfileparser/required_concepts_partial.plain +0 -0
  153. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfileparser/required_concepts_partial_duplicate.plain +0 -0
  154. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfileparser/topological_sort.plain +0 -0
  155. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/plainfileparser/topological_sort_not_referenced.plain +0 -0
  156. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/requires/circular_requires_main.plain +0 -0
  157. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/requires/circular_requires_sub.plain +0 -0
  158. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/requires/diamond_requires_1.plain +0 -0
  159. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/requires/diamond_requires_2.plain +0 -0
  160. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/requires/diamond_requires_common.plain +0 -0
  161. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/requires/diamond_requires_main.plain +0 -0
  162. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/requires/independent_requires_1.plain +0 -0
  163. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/requires/independent_requires_2.plain +0 -0
  164. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/requires/independent_requires_main.plain +0 -0
  165. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/requires/non_existent_require.plain +0 -0
  166. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/requires/normal_requires_1.plain +0 -0
  167. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/requires/normal_requires_2.plain +0 -0
  168. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/requires/normal_requires_common.plain +0 -0
  169. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/requires/normal_requires_main.plain +0 -0
  170. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/simple.plain +0 -0
  171. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/templates/block_level_include.plain +0 -0
  172. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/templates/code_variables.plain +0 -0
  173. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/templates/header.plain +0 -0
  174. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/templates/implement.plain +0 -0
  175. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/templates/implement_2.plain +0 -0
  176. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/templates/template_include.plain +0 -0
  177. {codeplain-0.2.1 → codeplain-0.2.3}/tests/data/templates/test_hardest_problem.plain +0 -0
  178. {codeplain-0.2.1 → codeplain-0.2.3}/tests/test_git_utils.py +0 -0
  179. {codeplain-0.2.1 → codeplain-0.2.3}/tests/test_imports.py +0 -0
  180. {codeplain-0.2.1 → codeplain-0.2.3}/tests/test_plainfile.py +0 -0
  181. {codeplain-0.2.1 → codeplain-0.2.3}/tests/test_plainfileparser.py +0 -0
  182. {codeplain-0.2.1 → codeplain-0.2.3}/tests/test_plainspec.py +0 -0
  183. {codeplain-0.2.1 → codeplain-0.2.3}/tests/test_requires.py +0 -0
  184. {codeplain-0.2.1 → codeplain-0.2.3}/tui/__init__.py +0 -0
  185. {codeplain-0.2.1 → codeplain-0.2.3}/tui/components.py +0 -0
  186. {codeplain-0.2.1 → codeplain-0.2.3}/tui/models.py +0 -0
  187. {codeplain-0.2.1 → codeplain-0.2.3}/tui/plain2code_tui.py +0 -0
  188. {codeplain-0.2.1 → codeplain-0.2.3}/tui/state_handlers.py +0 -0
  189. {codeplain-0.2.1 → codeplain-0.2.3}/tui/styles.css +0 -0
  190. {codeplain-0.2.1 → codeplain-0.2.3}/tui/widget_helpers.py +0 -0
@@ -0,0 +1,30 @@
1
+ name: Publish Install Script to R2
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ paths:
8
+ - 'install.sh'
9
+ workflow_dispatch:
10
+
11
+ jobs:
12
+ publish:
13
+ name: Upload to Cloudflare R2
14
+ runs-on: ubuntu-latest
15
+
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+
19
+ - name: Upload install.sh to R2
20
+ env:
21
+ AWS_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
22
+ AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
23
+ R2_ENDPOINT: ${{ secrets.R2_ENDPOINT }}
24
+ R2_BUCKET: ${{ secrets.R2_BUCKET }}
25
+ run: |
26
+ aws s3 cp install.sh s3://${R2_BUCKET}/install/install.sh \
27
+ --endpoint-url "${R2_ENDPOINT}" \
28
+ --content-type "text/plain"
29
+
30
+ echo "✓ install.sh uploaded to R2"
@@ -3,6 +3,17 @@ name: Publish to PyPI
3
3
  on:
4
4
  release:
5
5
  types: [published]
6
+ workflow_dispatch:
7
+ inputs:
8
+ version:
9
+ description: "Version to build (e.g., 0.2.1)"
10
+ required: true
11
+ type: string
12
+ publish_to_pypi:
13
+ description: "Actually publish to PyPI?"
14
+ required: true
15
+ default: false
16
+ type: boolean
6
17
 
7
18
  jobs:
8
19
  build:
@@ -19,11 +30,16 @@ jobs:
19
30
  with:
20
31
  python-version: "3.11"
21
32
 
22
- - name: Extract version from tag
33
+ - name: Extract version
23
34
  id: get_version
24
35
  run: |
25
- # Strip 'v' prefix from tag (v0.2.1 -> 0.2.1)
26
- VERSION=${GITHUB_REF_NAME#v}
36
+ if [ "${{ github.event_name }}" = "release" ]; then
37
+ # Strip 'v' prefix from tag (v0.2.1 -> 0.2.1)
38
+ VERSION=${GITHUB_REF_NAME#v}
39
+ else
40
+ # Use manual input
41
+ VERSION="${{ github.event.inputs.version }}"
42
+ fi
27
43
  echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
28
44
  echo "Extracted version: $VERSION"
29
45
 
@@ -34,6 +50,7 @@ jobs:
34
50
  grep "^version" pyproject.toml
35
51
 
36
52
  - name: Commit version update to repo
53
+ if: github.event_name == 'release'
37
54
  run: |
38
55
  git config user.name "github-actions[bot]"
39
56
  git config user.email "github-actions[bot]@users.noreply.github.com"
@@ -41,13 +58,14 @@ jobs:
41
58
  git commit -m "Bump version to ${{ steps.get_version.outputs.VERSION }}"
42
59
  git push origin HEAD:main
43
60
 
44
- - name: Install build dependencies
61
+ - name: Install uv
45
62
  run: |
46
- python -m pip install --upgrade pip
47
- pip install build
63
+ curl -LsSf https://astral.sh/uv/install.sh | sh
64
+ echo "$HOME/.local/bin" >> $GITHUB_PATH
48
65
 
49
66
  - name: Build package
50
- run: python -m build
67
+ run: |
68
+ uv build
51
69
 
52
70
  - name: Store the distribution packages
53
71
  uses: actions/upload-artifact@v4
@@ -56,6 +74,7 @@ jobs:
56
74
  path: dist/
57
75
 
58
76
  - name: Upload assets to GitHub Release
77
+ if: github.event_name == 'release'
59
78
  env:
60
79
  GH_TOKEN: ${{ github.token }}
61
80
  run: |
@@ -64,6 +83,7 @@ jobs:
64
83
  publish-to-pypi:
65
84
  name: Publish to PyPI
66
85
  needs: build
86
+ if: github.event_name == 'release' || github.event.inputs.publish_to_pypi == 'true'
67
87
  runs-on: ubuntu-latest
68
88
  environment:
69
89
  name: pypi
@@ -76,11 +96,14 @@ jobs:
76
96
  name: python-package-distributions
77
97
  path: dist/
78
98
 
79
- - name: Install twine
80
- run: pip install twine
99
+ - name: Install uv
100
+ run: |
101
+ curl -LsSf https://astral.sh/uv/install.sh | sh
102
+ echo "$HOME/.local/bin" >> $GITHUB_PATH
81
103
 
82
104
  - name: Publish to PyPI
83
105
  env:
84
106
  TWINE_USERNAME: __token__
85
107
  TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
86
- run: twine upload dist/*
108
+ run: |
109
+ uv tool run twine upload dist/*
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codeplain
3
- Version: 0.2.1
3
+ Version: 0.2.3
4
4
  Summary: Transform plain language specifications into working code
5
5
  License-File: LICENSE
6
6
  Classifier: Environment :: Console
@@ -0,0 +1,136 @@
1
+ #!/bin/bash
2
+
3
+ set -euo pipefail
4
+
5
+ # Brand Colors (True Color / 24-bit)
6
+ YELLOW='\033[38;2;224;255;110m' # #E0FF6E
7
+ GREEN='\033[38;2;121;252;150m' # #79FC96
8
+ GREEN_LIGHT='\033[38;2;197;220;217m' # #C5DCD9
9
+ GREEN_DARK='\033[38;2;34;57;54m' # #223936
10
+ BLUE='\033[38;2;10;31;212m' # #0A1FD4
11
+ BLACK='\033[38;2;26;26;26m' # #1A1A1A
12
+ WHITE='\033[38;2;255;255;255m' # #FFFFFF
13
+ RED='\033[38;2;239;68;68m' # #EF4444
14
+ GRAY='\033[38;2;128;128;128m' # #808080
15
+ GRAY_LIGHT='\033[38;2;211;211;211m' # #D3D3D3
16
+ BOLD='\033[1m'
17
+ NC='\033[0m' # No Color / Reset
18
+
19
+ echo -e "started ${YELLOW}${BOLD}*codeplain CLI${NC} installation..."
20
+
21
+ # Install uv if not present
22
+ install_uv() {
23
+ echo -e "installing uv package manager..."
24
+ curl -LsSf https://astral.sh/uv/install.sh | sh
25
+ # Add uv to PATH for this session
26
+ export PATH="$HOME/.local/bin:$PATH"
27
+ }
28
+
29
+ # Check if uv is installed
30
+ if ! command -v uv &> /dev/null; then
31
+ echo -e "${GRAY}uv is not installed.${NC}"
32
+ install_uv
33
+ echo -e "${GREEN}✓${NC} uv installed successfully"
34
+ echo -e ""
35
+ fi
36
+
37
+ echo -e "${GREEN}✓${NC} uv detected"
38
+ echo -e ""
39
+
40
+ # Install or upgrade codeplain using uv tool
41
+ if uv tool list 2>/dev/null | grep -q "^codeplain"; then
42
+ CURRENT_VERSION=$(uv tool list 2>/dev/null | grep "^codeplain" | sed 's/codeplain v//')
43
+ echo -e "${GRAY}codeplain ${CURRENT_VERSION} is already installed.${NC}"
44
+ echo -e "upgrading to latest version..."
45
+ echo -e ""
46
+ uv tool upgrade codeplain &> /dev/null
47
+ NEW_VERSION=$(uv tool list 2>/dev/null | grep "^codeplain" | sed 's/codeplain v//')
48
+ if [ "$CURRENT_VERSION" = "$NEW_VERSION" ]; then
49
+ echo -e "${GREEN}✓${NC} codeplain is already up to date (${NEW_VERSION})"
50
+ else
51
+ echo -e "${GREEN}✓${NC} codeplain upgraded from ${CURRENT_VERSION} to ${NEW_VERSION}!"
52
+ fi
53
+ else
54
+ echo -e "installing codeplain...${NC}"
55
+ echo -e ""
56
+ uv tool install codeplain
57
+ echo -e "${GREEN}✓ codeplain installed successfully!${NC}"
58
+ fi
59
+
60
+ echo -e "${GREEN}✓${NC} the latest version of *codeplain CLI is now installed."
61
+ echo ""
62
+ echo -e "go to ${YELLOW}https://platform.codeplain.ai${NC} and sign up to get your API key."
63
+ echo ""
64
+ read -p "paste your API key here: " API_KEY
65
+ echo ""
66
+
67
+ if [ -z "$API_KEY" ]; then
68
+ echo -e "${GRAY}no API key provided. you can set it later with:${NC}"
69
+ echo -e " export CODEPLAIN_API_KEY=\"your_api_key\""
70
+ else
71
+ # Export for current session
72
+ export CODEPLAIN_API_KEY="$API_KEY"
73
+
74
+ # Detect user's default shell from $SHELL (works even when script runs in different shell)
75
+ case "$SHELL" in
76
+ */zsh)
77
+ SHELL_RC="$HOME/.zprofile"
78
+ ;;
79
+ */bash)
80
+ if [[ "$OSTYPE" == "darwin"* ]]; then
81
+ # macOS uses .bash_profile for login shells
82
+ SHELL_RC="$HOME/.bash_profile"
83
+ else
84
+ SHELL_RC="$HOME/.bashrc"
85
+ fi
86
+ ;;
87
+ *)
88
+ SHELL_RC="$HOME/.profile"
89
+ ;;
90
+ esac
91
+
92
+ # Create the file if it doesn't exist
93
+ touch "$SHELL_RC"
94
+
95
+ # Add to shell config if not already present
96
+ if ! grep -q "CODEPLAIN_API_KEY" "$SHELL_RC" 2>/dev/null; then
97
+ echo "" >> "$SHELL_RC"
98
+ echo "# codeplain API Key" >> "$SHELL_RC"
99
+ echo "export CODEPLAIN_API_KEY=\"$API_KEY\"" >> "$SHELL_RC"
100
+ echo -e "${GREEN}✓ API key saved to ${SHELL_RC}${NC}"
101
+ else
102
+ # Update existing key (different sed syntax for macOS vs Linux)
103
+ if [[ "$OSTYPE" == "darwin"* ]]; then
104
+ sed -i '' "s|export CODEPLAIN_API_KEY=.*|export CODEPLAIN_API_KEY=\"$API_KEY\"|" "$SHELL_RC"
105
+ else
106
+ sed -i "s|export CODEPLAIN_API_KEY=.*|export CODEPLAIN_API_KEY=\"$API_KEY\"|" "$SHELL_RC"
107
+ fi
108
+ echo -e "${GREEN}✓${NC} API key added to ${SHELL_RC}"
109
+ fi
110
+
111
+ fi
112
+
113
+ # ASCII Art Welcome
114
+ echo ""
115
+ echo -e "${NC}"
116
+ echo -e "${GRAY}────────────────────────────────────────────${NC}"
117
+ echo -e ""
118
+ cat << 'EOF'
119
+ _ _ _
120
+ ___ ___ __| | ___ _ __ | | __ _(_)_ __
121
+ / __/ _ \ / _` |/ _ \ '_ \| |/ _` | | '_ \
122
+ | (_| (_) | (_| | __/ |_) | | (_| | | | | |
123
+ \___\___/ \__,_|\___| .__/|_|\__,_|_|_| |_|
124
+ |_|
125
+ EOF
126
+ echo ""
127
+ echo -e " ${YELLOW}welcome to *codeplain!${NC}"
128
+ echo ""
129
+ echo -e " spec-driven, production-ready code generation"
130
+ echo ""
131
+ echo ""
132
+ echo -e "${GRAY}────────────────────────────────────────────${NC}"
133
+ echo ""
134
+ echo -e " thank you for using *codeplain!"
135
+ echo ""
136
+ echo -e " run '${YELLOW}${BOLD}codeplain <path_to_plain_file>${NC}' to get started."
@@ -17,7 +17,7 @@ from event_bus import EventBus
17
17
  from module_renderer import ModuleRenderer
18
18
  from plain2code_arguments import parse_arguments
19
19
  from plain2code_console import console
20
- from plain2code_exceptions import PlainSyntaxError
20
+ from plain2code_exceptions import MissingAPIKey, PlainSyntaxError
21
21
  from plain2code_logger import (
22
22
  CrashLogHandler,
23
23
  IndentedFormatter,
@@ -161,6 +161,17 @@ def render(args, run_state: RunState, codeplain_api, event_bus: EventBus): # no
161
161
 
162
162
  console.info(f"Rendering {args.filename} to target code.")
163
163
 
164
+ # Compute render range from either --render-range or --render-from
165
+ render_range = None
166
+ if args.render_range or args.render_from:
167
+ # Parse the plain file to get the plain_source for FRID extraction
168
+ _, plain_source, _ = plain_file.plain_file_parser(args.filename, template_dirs)
169
+
170
+ if args.render_range:
171
+ render_range = get_render_range(args.render_range, plain_source)
172
+ elif args.render_from:
173
+ render_range = get_render_range_from(args.render_from, plain_source)
174
+
164
175
  codeplainAPI = codeplain_api.CodeplainAPI(args.api_key, console)
165
176
  codeplainAPI.verbose = args.verbose
166
177
  assert args.api is not None and args.api != "", "API URL is required"
@@ -169,7 +180,7 @@ def render(args, run_state: RunState, codeplain_api, event_bus: EventBus): # no
169
180
  module_renderer = ModuleRenderer(
170
181
  codeplainAPI,
171
182
  args.filename,
172
- args.render_range,
183
+ render_range,
173
184
  template_dirs,
174
185
  args,
175
186
  run_state,
@@ -208,6 +219,12 @@ def main():
208
219
  run_state = RunState(spec_filename=args.filename, replay_with=args.replay_with)
209
220
 
210
221
  try:
222
+ # Validate API key is present
223
+ if not args.api_key:
224
+ raise MissingAPIKey(
225
+ "API key is required. Please set the CODEPLAIN_API_KEY environment variable or provide it with the --api-key argument."
226
+ )
227
+
211
228
  render(args, run_state, codeplain_api, event_bus)
212
229
  except InvalidFridArgument as e:
213
230
  console.error(f"Error rendering plain code: {str(e)}.\n")
@@ -237,6 +254,8 @@ def main():
237
254
  console.error(f"Error rendering plain code: {str(e)}\n")
238
255
  console.debug(f"Render ID: {run_state.render_id}")
239
256
  dump_crash_logs(args)
257
+ except MissingAPIKey as e:
258
+ console.error(f"Missing API key: {str(e)}\n")
240
259
  except Exception as e:
241
260
  console.error(f"Error rendering plain code: {str(e)}\n")
242
261
  console.debug(f"Render ID: {run_state.render_id}")
@@ -5,10 +5,6 @@ import re
5
5
  from plain2code_read_config import get_args_from_config
6
6
 
7
7
  CODEPLAIN_API_KEY = os.getenv("CODEPLAIN_API_KEY")
8
- if not CODEPLAIN_API_KEY:
9
- CLAUDE_API_KEY = os.getenv("CLAUDE_API_KEY")
10
- if not CLAUDE_API_KEY:
11
- raise ValueError("CODEPLAIN_API_KEY or CLAUDE_API_KEY environment variable is not set")
12
8
 
13
9
 
14
10
  DEFAULT_BUILD_FOLDER = "plain_modules"
@@ -43,3 +43,7 @@ class MultipleRendersFound(Exception):
43
43
 
44
44
  class UnexpectedState(Exception):
45
45
  pass
46
+
47
+
48
+ class MissingAPIKey(Exception):
49
+ pass
@@ -4,20 +4,20 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "codeplain"
7
- version = "0.2.1"
7
+ version = "0.2.3"
8
8
  description = "Transform plain language specifications into working code"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
11
- classifiers = [
11
+ classifiers = [
12
12
  "Environment :: Console",
13
- "Intended Audience :: Developers",
14
- "Operating System :: OS Independent",
13
+ "Intended Audience :: Developers",
14
+ "Operating System :: OS Independent",
15
15
  "Topic :: Software Development :: Code Generators",
16
16
  ]
17
17
  dependencies = [
18
18
  "python-liquid2==0.3.0",
19
19
  "mistletoe==1.3.0",
20
- "requests==2.32.3",
20
+ "requests==2.32.3",
21
21
  "tiktoken==0.12.0",
22
22
  "PyYAML==6.0.2",
23
23
  "gitpython==3.1.42",
@@ -41,11 +41,10 @@ dev = [
41
41
  codeplain = "plain2code:main"
42
42
 
43
43
  [tool.hatch.build.targets.wheel]
44
- # Include all Python files from the root directory
45
44
  include = [
46
45
  "*.py",
47
46
  "config/**/*",
48
- "render_machine/**/*",
47
+ "render_machine/**/*",
49
48
  "standard_template_library/**/*",
50
49
  "tui/**/*"
51
50
  ]
@@ -1,217 +0,0 @@
1
- #!/bin/bash
2
-
3
- set -e
4
-
5
- # Brand Colors (True Color / 24-bit)
6
- YELLOW='\033[38;2;224;255;110m' # #E0FF6E
7
- GREEN='\033[38;2;121;252;150m' # #79FC96
8
- GREEN_LIGHT='\033[38;2;197;220;217m' # #C5DCD9
9
- GREEN_DARK='\033[38;2;34;57;54m' # #223936
10
- BLUE='\033[38;2;10;31;212m' # #0A1FD4
11
- BLACK='\033[38;2;26;26;26m' # #1A1A1A
12
- WHITE='\033[38;2;255;255;255m' # #FFFFFF
13
- RED='\033[38;2;239;68;68m' # #EF4444
14
- GRAY='\033[38;2;128;128;128m' # #808080
15
- GRAY_LIGHT='\033[38;2;211;211;211m' # #D3D3D3
16
- BOLD='\033[1m'
17
- NC='\033[0m' # No Color / Reset
18
-
19
- # Required Python version
20
- REQUIRED_MAJOR=3
21
- REQUIRED_MINOR=11
22
-
23
- # Detect OS
24
- detect_os() {
25
- if [[ "$OSTYPE" == "darwin"* ]]; then
26
- echo "macos"
27
- elif [[ -f /etc/debian_version ]]; then
28
- echo "debian"
29
- elif [[ -f /etc/redhat-release ]]; then
30
- echo "redhat"
31
- else
32
- echo "unknown"
33
- fi
34
- }
35
-
36
- echo -e "started ${YELLOW}${BOLD}*codeplain CLI${NC} installation..."
37
-
38
- # Install Python based on OS
39
- install_python() {
40
- local os=$(detect_os)
41
-
42
- case $os in
43
- macos)
44
- if command -v brew &> /dev/null; then
45
- echo -e "installing Python ${REQUIRED_MAJOR}.${REQUIRED_MINOR} via Homebrew..."
46
- brew install python@${REQUIRED_MAJOR}.${REQUIRED_MINOR}
47
- else
48
- echo -e "${RED}Error: Homebrew is not installed.${NC}"
49
- echo "please install Homebrew first: https://brew.sh"
50
- echo "or install Python manually from: https://www.python.org/downloads/"
51
- exit 1
52
- fi
53
- ;;
54
- debian)
55
- echo -e "installing Python ${REQUIRED_MAJOR}.${REQUIRED_MINOR} via apt..."
56
- sudo apt update
57
- sudo apt install -y python${REQUIRED_MAJOR}.${REQUIRED_MINOR} python${REQUIRED_MAJOR}.${REQUIRED_MINOR}-venv python3-pip
58
- ;;
59
- redhat)
60
- echo -e "installing Python ${REQUIRED_MAJOR}.${REQUIRED_MINOR} via dnf..."
61
- sudo dnf install -y python${REQUIRED_MAJOR}.${REQUIRED_MINOR}
62
- ;;
63
- *)
64
- echo -e "${RED}Error: Automatic installation not supported for your OS.${NC}"
65
- echo "please install Python ${REQUIRED_MAJOR}.${REQUIRED_MINOR} manually from:"
66
- echo " https://www.python.org/downloads/"
67
- exit 1
68
- ;;
69
- esac
70
- }
71
-
72
- # Prompt user to install Python
73
- prompt_install_python() {
74
- echo ""
75
- read -p "$(echo -e ${YELLOW}would you like to install Python ${REQUIRED_MAJOR}.${REQUIRED_MINOR}? \(Y/n\): ${NC})" response
76
- case "$response" in
77
- [yY][eE][sS]|[yY]|"")
78
- install_python
79
- echo ""
80
- echo -e "${GREEN}✓ python installed.${NC} please restart your terminal and run this script again."
81
- exit 0
82
- ;;
83
- *)
84
- echo -e "${YELLOW}installation cancelled.${NC}"
85
- exit 1
86
- ;;
87
- esac
88
- }
89
-
90
- # Check if python3 or python is installed
91
- if command -v python3.11 &> /dev/null; then
92
- PYTHON_CMD="python3.11"
93
- elif command -v python3 &> /dev/null; then
94
- PYTHON_CMD="python3"
95
- elif command -v python &> /dev/null; then
96
- PYTHON_CMD="python"
97
- else
98
- echo -e "${RED}error: Python 3 is not installed.${NC}"
99
- prompt_install_python
100
- fi
101
-
102
- # Get Python version
103
- PYTHON_VERSION=$($PYTHON_CMD -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')
104
- PYTHON_MAJOR=$(echo "$PYTHON_VERSION" | cut -d. -f1)
105
- PYTHON_MINOR=$(echo "$PYTHON_VERSION" | cut -d. -f2)
106
-
107
- # Check version
108
- if [ "$PYTHON_MAJOR" -lt "$REQUIRED_MAJOR" ] || \
109
- ([ "$PYTHON_MAJOR" -eq "$REQUIRED_MAJOR" ] && [ "$PYTHON_MINOR" -lt "$REQUIRED_MINOR" ]); then
110
- echo -e "${RED}error: Python ${REQUIRED_MAJOR}.${REQUIRED_MINOR} or greater is required.${NC}"
111
- echo -e "found: python ${YELLOW}${PYTHON_VERSION}${NC}"
112
- prompt_install_python
113
- fi
114
-
115
- echo -e ""
116
- echo -e "${GREEN}✓${NC} python ${BOLD}${PYTHON_VERSION}${NC} detected"
117
- echo -e ""
118
- # Use python -m pip for reliability
119
- PIP_CMD="$PYTHON_CMD -m pip"
120
-
121
- # Install or upgrade codeplain
122
- if $PIP_CMD show codeplain &> /dev/null; then
123
- CURRENT_VERSION=$($PIP_CMD show codeplain | grep "^Version:" | cut -d' ' -f2)
124
- echo -e "${GRAY}codeplain ${CURRENT_VERSION} is already installed.${NC}"
125
- echo -e "upgrading to latest version..."
126
- echo -e ""
127
- $PIP_CMD install --upgrade codeplain &> /dev/null
128
- NEW_VERSION=$($PIP_CMD show codeplain | grep "^Version:" | cut -d' ' -f2)
129
- if [ "$CURRENT_VERSION" = "$NEW_VERSION" ]; then
130
- echo -e "${GREEN}✓${NC} codeplain is already up to date (${NEW_VERSION})"
131
- else
132
- echo -e "${GREEN}✓${NC} codeplain upgraded from ${CURRENT_VERSION} to ${NEW_VERSION}!"
133
- fi
134
- else
135
- echo -e "installing codeplain...${NC}"
136
- echo -e ""
137
- $PIP_CMD install codeplain &> /dev/null
138
- echo -e "${GREEN}✓ codeplain installed successfully!${NC}"
139
- fi
140
-
141
- echo -e "${GREEN}✓${NC} the latest version of *codeplain CLI is now installed."
142
- echo ""
143
- echo -e "go to ${YELLOW}https://platform.codeplain.ai${NC} and sign up to get your API key."
144
- echo ""
145
- read -p "paste your API key here: " API_KEY
146
- echo ""
147
-
148
- if [ -z "$API_KEY" ]; then
149
- echo -e "${GRAY}no API key provided. you can set it later with:${NC}"
150
- echo -e " export CODEPLAIN_API_KEY=\"your_api_key\""
151
- else
152
- # Export for current session
153
- export CODEPLAIN_API_KEY="$API_KEY"
154
-
155
- # Detect user's default shell from $SHELL (works even when script runs in different shell)
156
- case "$SHELL" in
157
- */zsh)
158
- SHELL_RC="$HOME/.zprofile"
159
- ;;
160
- */bash)
161
- if [[ "$OSTYPE" == "darwin"* ]]; then
162
- # macOS uses .bash_profile for login shells
163
- SHELL_RC="$HOME/.bash_profile"
164
- else
165
- SHELL_RC="$HOME/.bashrc"
166
- fi
167
- ;;
168
- *)
169
- SHELL_RC="$HOME/.profile"
170
- ;;
171
- esac
172
-
173
- # Create the file if it doesn't exist
174
- touch "$SHELL_RC"
175
-
176
- # Add to shell config if not already present
177
- if ! grep -q "CODEPLAIN_API_KEY" "$SHELL_RC" 2>/dev/null; then
178
- echo "" >> "$SHELL_RC"
179
- echo "# codeplain API Key" >> "$SHELL_RC"
180
- echo "export CODEPLAIN_API_KEY=\"$API_KEY\"" >> "$SHELL_RC"
181
- echo -e "${GREEN}✓ API key saved to ${SHELL_RC}${NC}"
182
- else
183
- # Update existing key (different sed syntax for macOS vs Linux)
184
- if [[ "$OSTYPE" == "darwin"* ]]; then
185
- sed -i '' "s|export CODEPLAIN_API_KEY=.*|export CODEPLAIN_API_KEY=\"$API_KEY\"|" "$SHELL_RC"
186
- else
187
- sed -i "s|export CODEPLAIN_API_KEY=.*|export CODEPLAIN_API_KEY=\"$API_KEY\"|" "$SHELL_RC"
188
- fi
189
- echo -e "${GREEN}✓${NC} API key added to ${SHELL_RC}"
190
- fi
191
-
192
- fi
193
-
194
- # ASCII Art Welcome
195
- echo ""
196
- echo -e "${NC}"
197
- echo -e "${GRAY}────────────────────────────────────────────${NC}"
198
- echo -e ""
199
- cat << 'EOF'
200
- _ _ _
201
- ___ ___ __| | ___ _ __ | | __ _(_)_ __
202
- / __/ _ \ / _` |/ _ \ '_ \| |/ _` | | '_ \
203
- | (_| (_) | (_| | __/ |_) | | (_| | | | | |
204
- \___\___/ \__,_|\___| .__/|_|\__,_|_|_| |_|
205
- |_|
206
- EOF
207
- echo ""
208
- echo -e " ${YELLOW}welcome to *codeplain!${NC}"
209
- echo ""
210
- echo -e " spec-driven, production-ready code generation"
211
- echo ""
212
- echo ""
213
- echo -e "${GRAY}────────────────────────────────────────────${NC}"
214
- echo ""
215
- echo -e " thank you for using *codeplain!"
216
- echo ""
217
- echo -e " run '${YELLOW}${BOLD}codeplain <path_to_plain_file>${NC}' to get started."
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes