codeplain 0.3.11.dev14__py3-none-any.whl → 0.3.11.dev16__py3-none-any.whl

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.
cli_output/status.py CHANGED
@@ -6,6 +6,8 @@ from typing import Optional
6
6
  import codeplain_REST_api as codeplain_api
7
7
  from plain2code_console import console
8
8
 
9
+ PLANS_URL = "https://platform.codeplain.ai/plans"
10
+
9
11
 
10
12
  def _create_progress_bar(remaining: int, total: int, width: int = 30) -> str:
11
13
  """Create a Unicode progress bar."""
@@ -42,12 +44,12 @@ def _display_credit_line(plan_credits: dict) -> None:
42
44
  bar = _create_progress_bar(remaining, total, width=30)
43
45
 
44
46
  # Format plan type label
45
- plan_label = "Free trial" if plan_type == "free" else plan_type.upper() + " plan"
47
+ plan_label = "Free credits" if plan_type == "free" else plan_type.upper() + " plan"
46
48
 
47
49
  if is_expired:
48
- console.print(f" {plan_label:10} {bar} expired {formatted_date}")
50
+ console.print(f" {plan_label:12} {bar} expired {formatted_date}")
49
51
  else:
50
- console.print(f" {plan_label:10} {bar} {remaining:2} of {total} remaining expires {formatted_date}")
52
+ console.print(f" {plan_label:12} {bar} {remaining:2} of {total} remaining expires {formatted_date}")
51
53
 
52
54
 
53
55
  def _display_bucket_credit_line(bucket: dict, label: str) -> None:
@@ -71,9 +73,9 @@ def _display_bucket_credit_line(bucket: dict, label: str) -> None:
71
73
  bar = _create_progress_bar(remaining, total, width=30)
72
74
 
73
75
  if is_expired:
74
- console.print(f" {label:10} {bar} expired {formatted_date}")
76
+ console.print(f" {label:12} {bar} expired {formatted_date}")
75
77
  else:
76
- console.print(f" {label:10} {bar} {remaining:2} of {total} remaining expires {formatted_date}")
78
+ console.print(f" {label:12} {bar} {remaining:2} of {total} remaining expires {formatted_date}")
77
79
 
78
80
 
79
81
  def _display_status_message(plan_credits: Optional[dict], purchased_credits: list, promo_credits: list) -> None:
@@ -107,7 +109,11 @@ def _display_status_message(plan_credits: Optional[dict], purchased_credits: lis
107
109
  break
108
110
 
109
111
  if not has_remaining:
110
- console.print("\nNo rendering credits remaining. Upgrade to continue rendering.")
112
+ console.print(
113
+ f"\nNo rendering credits remaining. Upgrade to the PRO plan at {PLANS_URL} to continue rendering."
114
+ )
115
+ else:
116
+ console.print(f"\nTo manage your plan navigate to {PLANS_URL}")
111
117
 
112
118
 
113
119
  def print_status(api_key: str, api_url: str, client_version: str) -> None:
@@ -148,7 +154,7 @@ def print_status(api_key: str, api_url: str, client_version: str) -> None:
148
154
  # Display rendering credits section
149
155
  console.print("Rendering credits:")
150
156
 
151
- # Display plan credits (free trial or subscription)
157
+ # Display plan credits (free credits or subscription)
152
158
  if plan_credits:
153
159
  _display_credit_line(plan_credits)
154
160
 
@@ -162,4 +168,3 @@ def print_status(api_key: str, api_url: str, client_version: str) -> None:
162
168
 
163
169
  # Display status messages and management link
164
170
  _display_status_message(plan_credits, purchased_credits, promo_credits)
165
- console.print("\nTo manage your plan navigate to https://platform.codeplain.ai/plans")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: codeplain
3
- Version: 0.3.11.dev14
3
+ Version: 0.3.11.dev16
4
4
  Summary: Transform plain language specifications into working code
5
5
  License-File: LICENSE
6
6
  Classifier: Environment :: Console
@@ -23,7 +23,7 @@ plain2code_read_config.py,sha256=D5CxnmTRjddupecWvstcUm0kIJWWzq5-Zmk6sU0wbIg,223
23
23
  plain2code_state.py,sha256=uePQlC29Pbhm1yXfdCFebONYdy6jo13gTTmXSwC11cQ,3168
24
24
  plain2code_telemetry.py,sha256=e4UCAoFklJMDWGQsL50i7nTLiOBy8gs86A0XO4WLgPo,4597
25
25
  plain2code_utils.py,sha256=unOxuqSQRpwG8YF6uoQhnZ3ZSTJRIUCPLdJ-1lRZR5M,1534
26
- plain_file.py,sha256=c7VFzJUXLM3oBFrA9JePDwdxXTR1T8hxWeyGZg4O4wA,36968
26
+ plain_file.py,sha256=5UkjZNePMGmUhGqduwbm6R6DnT_rDX7q3gd8IzIDAF8,37092
27
27
  plain_modules.py,sha256=nXlmw0J2rKkuU1Y3A68LVtZ1Ffdc-D5iMjxaXSaSHTQ,25963
28
28
  plain_spec.py,sha256=7nb5lLJKHZ3uu9THkSXyJ5brIKkbGW0ooVfRclLdlzA,16062
29
29
  system_config.py,sha256=sA8wiPmBMtRsLwSQ40U5pVdLazAafbV-1Z19Yp0HiSQ,5314
@@ -31,7 +31,7 @@ usage_summary.py,sha256=MA4WcVaAwz6IWCN4k_rgxVcwO4I157wN7BZlFi3h0R4,1282
31
31
  cli_output/__init__.py,sha256=MBKl0YbVpWE-tBa3V5_aVbB7vbaqlIK2NsHTjRUZqis,284
32
32
  cli_output/dry_run.py,sha256=6NKhNWPtD0CBK_QHSsSqIKLTzibTwxS9d8ltP9d1bgU,1473
33
33
  cli_output/render_summary.py,sha256=-yRoI7ZZTS9IHyp1vd-sFleGXTVbxlrCkvuM5TX0Mp4,1168
34
- cli_output/status.py,sha256=MvdocFXL1aA73NMp92gQb0Nd-f7-iw66XVUiHK33sEM,6194
34
+ cli_output/status.py,sha256=TrRo-BYUJmzjVzPlMUDpE76FUSpSsN_JdsKigKMrdmg,6294
35
35
  config/__init__.py,sha256=beYSsJWmBNHDP5rYmVDouqgEeP3t1lkkepbXJ-oq0F8,37
36
36
  config/system_config.yaml,sha256=of5R9vukSohU9AlkGJOcAVQA1UJgxYmDy6islU6iFuE,508
37
37
  docs/generate_cli.py,sha256=0FHVhICbM8g7ahdInTNih3hNKpty1wbV5rdGECMJj48,656
@@ -72,7 +72,7 @@ tests/__init__.py,sha256=Wk73Io62J15BtlLVIzxmASDWaaJkQLevS4BLK5LDAQg,16
72
72
  tests/conftest.py,sha256=QZcp08htUlJGgmHDlRWFgsWXZ8o8IBWTD5QqJaUMlU8,790
73
73
  tests/test_arg_provenance.py,sha256=d_J7aCeHMXBpctBWTt60WU-I8pEKN7XRXRTJZZGCdo0,3441
74
74
  tests/test_change_detection.py,sha256=jH8SEhndX400DNqIKmcYLzxHqq9WFdgmuvY3XPq-ZFc,13534
75
- tests/test_cli_output.py,sha256=ZV2F1NNW4EiZvMNkhF9XUZH6bFJbddfkZof5qAFxe3Y,18885
75
+ tests/test_cli_output.py,sha256=aRgq9d06aXZMAx1Qyi68LPX0-VDoZ29pYsncat5rs8Q,18947
76
76
  tests/test_conformance_fix_journal.py,sha256=olTeAuxXgFwQ8LSQyt0FqtBy9_XY_gK-Ei_pUuJ0C3M,10389
77
77
  tests/test_console_log_styles.py,sha256=sxlhynMAP-kmqhBn1-pKvZXdCnlKSyCGJqwYKrh6sQ0,6468
78
78
  tests/test_distill_conformance_test_memory.py,sha256=Tftw9l-gLVwIU6QttY03h2VedvuFxpIsCmZIzvWfxMA,5481
@@ -93,7 +93,7 @@ tests/test_plain2code_state.py,sha256=cowPZS9oRbv9J49CE4P3Rc47Q5oQOby4bTf2OlnRlB
93
93
  tests/test_plain2code_utils.py,sha256=-W8a7FquMJQ_pTdBoBF1XprzNL2G555QhdtXCy6BDyQ,1237
94
94
  tests/test_plain_modules.py,sha256=Fn3FeH-M4exnyFJDZzc9YWaLEfBmiqPH5TpiBT9jgAs,33033
95
95
  tests/test_plainfile.py,sha256=wZ_PN4GULPWIpl_AK_r_6jkgtX0Ch8EHmN5IhX7huOE,11027
96
- tests/test_plainfileparser.py,sha256=lFUnOEOOBOTvmB6b-VQgRRDiM2Ojein7lUzGdsT9pdk,24874
96
+ tests/test_plainfileparser.py,sha256=M-7VDs0N79yqJOZRv55K12Kaz73oFz7Lqh3L_dqcpX4,25199
97
97
  tests/test_plainspec.py,sha256=ng55E8ajrH2-gPC1p_QDIe_zXplPvoqHJ-d57UWKFTw,3577
98
98
  tests/test_prepare_repositories_layout.py,sha256=PhJQLnHfjfjo6CTWoicyEKgL0_GtjwB2OKYAWSBVHtk,14638
99
99
  tests/test_requires.py,sha256=6tnHYaKudxN-RiQjSFoi9nHe_x0ze3QF-f-j67zAE74,1250
@@ -116,8 +116,8 @@ tui/spinner.py,sha256=Ro6Gd9Przf-whuHqPRY6HwI0T57yJjyNPbhDbigZKZE,2471
116
116
  tui/state_handlers.py,sha256=zbUS_D9eU8qIwVpaxPEp9zL9bpg8gXsWNoUaqg9TLrQ,16664
117
117
  tui/styles.css,sha256=kiC7Og_2G1E7owoiZgV95-3_dSeQnsNj3qzaY04xkDg,6727
118
118
  tui/widget_helpers.py,sha256=jitm2WHiKj-NVFL-hULxWzckPreRbUTl9OIZLN31-ek,6997
119
- codeplain-0.3.11.dev14.dist-info/METADATA,sha256=cDHh3AdeuhUTdXAIyBUSa8uztsFrV-9kUrKEt-08SqA,7257
120
- codeplain-0.3.11.dev14.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
121
- codeplain-0.3.11.dev14.dist-info/entry_points.txt,sha256=oDZkBqu9WhtZApb_K6ia8-fn9aojwmAsgnKELceX5T4,46
122
- codeplain-0.3.11.dev14.dist-info/licenses/LICENSE,sha256=pCeKgQ1mXE5OmNUuKOfOZh1T1vqkeCUxghE7N8qgnzc,11345
123
- codeplain-0.3.11.dev14.dist-info/RECORD,,
119
+ codeplain-0.3.11.dev16.dist-info/METADATA,sha256=78SIF_oAZUEh8P1xmxcWNAVvgW58_nmpg3uk_alzOZk,7257
120
+ codeplain-0.3.11.dev16.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
121
+ codeplain-0.3.11.dev16.dist-info/entry_points.txt,sha256=oDZkBqu9WhtZApb_K6ia8-fn9aojwmAsgnKELceX5T4,46
122
+ codeplain-0.3.11.dev16.dist-info/licenses/LICENSE,sha256=pCeKgQ1mXE5OmNUuKOfOZh1T1vqkeCUxghE7N8qgnzc,11345
123
+ codeplain-0.3.11.dev16.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.32.0
2
+ Generator: hatchling 1.32.4
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
plain_file.py CHANGED
@@ -759,6 +759,9 @@ def process_exported_definitions(plain_source: dict, exported_definitions: list[
759
759
  if len(exported_definitions) == 0:
760
760
  return
761
761
 
762
+ if plain_source[plain_spec.DEFINITIONS] is None:
763
+ plain_source[plain_spec.DEFINITIONS] = mistletoe.Document("")
764
+
762
765
  with PlainRenderer() as renderer:
763
766
  for exported_definition in exported_definitions:
764
767
  add_defintion = True
tests/test_cli_output.py CHANGED
@@ -67,7 +67,7 @@ class TestDisplayCreditLine:
67
67
 
68
68
  @patch("cli_output.status.console")
69
69
  def test_display_active_free_trial(self, mock_console):
70
- """Test displaying active free trial credits."""
70
+ """Test displaying active free credits."""
71
71
  plan_credits = {
72
72
  "type": "free",
73
73
  "total": 50,
@@ -78,7 +78,7 @@ class TestDisplayCreditLine:
78
78
 
79
79
  mock_console.print.assert_called_once()
80
80
  call_args = mock_console.print.call_args[0][0]
81
- assert "Free trial" in call_args
81
+ assert "Free credits" in call_args
82
82
  assert "4 of 50 remaining" in call_args
83
83
  assert "expires Dec 1, 2028" in call_args
84
84
 
@@ -259,6 +259,7 @@ class TestDisplayStatusMessage:
259
259
  mock_console.print.assert_called_once()
260
260
  call_args = mock_console.print.call_args[0][0]
261
261
  assert "No rendering credits remaining" in call_args
262
+ assert "https://platform.codeplain.ai/plans" in call_args
262
263
 
263
264
  @patch("cli_output.status.console")
264
265
  def test_expired_plan_credits(self, mock_console):
@@ -698,6 +698,14 @@ def test_exported_concepts_invalid(get_test_data_path, fixture, expected_word):
698
698
  plain_file.plain_file_parser(fixture, [get_test_data_path("data/plainfileparser")])
699
699
 
700
700
 
701
+ def test_requires_without_definitions(get_test_data_path):
702
+ _, plain_source, _ = plain_file.plain_file_parser(
703
+ "requires_without_definitions_example.plain",
704
+ [get_test_data_path("data/plainfileparser")],
705
+ )
706
+ assert plain_source[plain_spec.DEFINITIONS] == [{"markdown": "- :Concept: is a concept."}]
707
+
708
+
701
709
  def test_topological_sort(get_test_data_path):
702
710
  _, plain_source, _ = plain_file.plain_file_parser(
703
711
  "topological_sort.plain", [get_test_data_path("data/plainfileparser")]