python2mobile 0.1.3__tar.gz → 0.1.4__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 (55) hide show
  1. {python2mobile-0.1.3 → python2mobile-0.1.4}/PKG-INFO +1 -1
  2. {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/imagine/agent.py +236 -43
  3. {python2mobile-0.1.3 → python2mobile-0.1.4}/pyproject.toml +1 -1
  4. {python2mobile-0.1.3 → python2mobile-0.1.4}/python2mobile.egg-info/PKG-INFO +1 -1
  5. {python2mobile-0.1.3 → python2mobile-0.1.4}/README.md +0 -0
  6. {python2mobile-0.1.3 → python2mobile-0.1.4}/examples/example_ecommerce_app.py +0 -0
  7. {python2mobile-0.1.3 → python2mobile-0.1.4}/examples/example_todo_app.py +0 -0
  8. {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/__init__.py +0 -0
  9. {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/cli.py +0 -0
  10. {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/config.py +0 -0
  11. {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/core/__init__.py +0 -0
  12. {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/core/api.py +0 -0
  13. {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/core/ast_walker.py +0 -0
  14. {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/core/database.py +0 -0
  15. {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/core/events.py +0 -0
  16. {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/core/render_engine.py +0 -0
  17. {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/core/runtime.py +0 -0
  18. {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/core/state.py +0 -0
  19. {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/core/validator.py +0 -0
  20. {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/devserver/__init__.py +0 -0
  21. {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/devserver/server.py +0 -0
  22. {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/i18n/__init__.py +0 -0
  23. {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/i18n/translator.py +0 -0
  24. {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/imagine/__init__.py +0 -0
  25. {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/imagine/legacy.py +0 -0
  26. {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/llm/__init__.py +0 -0
  27. {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/llm/anthropic_provider.py +0 -0
  28. {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/llm/base.py +0 -0
  29. {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/llm/compatible_provider.py +0 -0
  30. {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/llm/factory.py +0 -0
  31. {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/llm/ollama_provider.py +0 -0
  32. {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/llm/openai_provider.py +0 -0
  33. {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/testing/__init__.py +0 -0
  34. {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/ui/__init__.py +0 -0
  35. {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/ui/components.py +0 -0
  36. {python2mobile-0.1.3 → python2mobile-0.1.4}/python2mobile.egg-info/SOURCES.txt +0 -0
  37. {python2mobile-0.1.3 → python2mobile-0.1.4}/python2mobile.egg-info/dependency_links.txt +0 -0
  38. {python2mobile-0.1.3 → python2mobile-0.1.4}/python2mobile.egg-info/entry_points.txt +0 -0
  39. {python2mobile-0.1.3 → python2mobile-0.1.4}/python2mobile.egg-info/requires.txt +0 -0
  40. {python2mobile-0.1.3 → python2mobile-0.1.4}/python2mobile.egg-info/top_level.txt +0 -0
  41. {python2mobile-0.1.3 → python2mobile-0.1.4}/setup.cfg +0 -0
  42. {python2mobile-0.1.3 → python2mobile-0.1.4}/tests/test_basic_engine.py +0 -0
  43. {python2mobile-0.1.3 → python2mobile-0.1.4}/tests/test_build_generation.py +0 -0
  44. {python2mobile-0.1.3 → python2mobile-0.1.4}/tests/test_build_test_gate.py +0 -0
  45. {python2mobile-0.1.3 → python2mobile-0.1.4}/tests/test_carousel_modal.py +0 -0
  46. {python2mobile-0.1.3 → python2mobile-0.1.4}/tests/test_config_system.py +0 -0
  47. {python2mobile-0.1.3 → python2mobile-0.1.4}/tests/test_i18n.py +0 -0
  48. {python2mobile-0.1.3 → python2mobile-0.1.4}/tests/test_ifood_app_integration.py +0 -0
  49. {python2mobile-0.1.3 → python2mobile-0.1.4}/tests/test_imagine_cli.py +0 -0
  50. {python2mobile-0.1.3 → python2mobile-0.1.4}/tests/test_imagine_command.py +0 -0
  51. {python2mobile-0.1.3 → python2mobile-0.1.4}/tests/test_llm_providers.py +0 -0
  52. {python2mobile-0.1.3 → python2mobile-0.1.4}/tests/test_new_apps_integration.py +0 -0
  53. {python2mobile-0.1.3 → python2mobile-0.1.4}/tests/test_ollama_functional.py +0 -0
  54. {python2mobile-0.1.3 → python2mobile-0.1.4}/tests/test_real_world_apps.py +0 -0
  55. {python2mobile-0.1.3 → python2mobile-0.1.4}/tests/test_run_integration.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python2mobile
3
- Version: 0.1.3
3
+ Version: 0.1.4
4
4
  Summary: Python to Mobile - Write mobile apps in pure Python with DSL
5
5
  Author-email: P2M Team <team@python2mobile.dev>
6
6
  License-Expression: MIT
@@ -20,13 +20,129 @@ from typing import Optional
20
20
  # ---------------------------------------------------------------------------
21
21
 
22
22
  _IMAGINE_SYSTEM_PROMPT = """\
23
- You are an expert Python2Mobile (P2M) developer.
23
+ You are an expert Python2Mobile (P2M) developer AND a senior mobile UI/UX designer.
24
24
 
25
- Given a natural language description you MUST produce a COMPLETE, production-quality,
26
- runnable multi-file P2M project with realistic sample data, polished UI, and unit tests.
25
+ Given a natural language description you MUST:
26
+ 1. First PLAN the visual interface (layout, button shapes, colour scheme, hierarchy)
27
+ 2. Then produce a COMPLETE, production-quality, runnable multi-file P2M project
27
28
 
28
- Your code quality bar is set by the calculator_app reference project clean helpers,
29
- parametrised event handlers, mobile-first Tailwind styling, and robust edge-case handling.
29
+ Your design bar: every screen must look indistinguishable from a polished App Store app.
30
+ Your code bar: clean helpers, parametrised event handlers, robust edge-case handling.
31
+
32
+ ═══════════════════════════════════════════════════════════════════
33
+ STEP 0 — UI DESIGN PHASE (do this BEFORE writing any code)
34
+ ═══════════════════════════════════════════════════════════════════
35
+
36
+ Before writing a single line of Python, analyse the description and answer:
37
+
38
+ A. APP TYPE — which category?
39
+ numpad/calculator · todo/task · shopping/product · social/feed ·
40
+ dashboard/stats · media/music · form/settings · game · other
41
+
42
+ B. THEME — dark or light? (dark for media/calculator/game; light for productivity/shopping)
43
+
44
+ C. KEY WIDGET SHAPE — what shape are the primary interactive elements?
45
+ circle → numpad, calculator, dialer, drum machine
46
+ pill → filter chips, tags, toggle pills
47
+ rounded → action buttons, cards, list items
48
+ (see the App Type Blueprints section below for exact Tailwind classes)
49
+
50
+ D. LAYOUT STRUCTURE — how is the screen divided?
51
+ top display + button grid · scrollable feed · master/detail · tab bar ·
52
+ form list · hero + action
53
+
54
+ E. COLOUR ACCENT — single accent colour for primary actions
55
+ orange (calculators, media) · blue (productivity, social) · green (health, finance) ·
56
+ purple (creative) · red (food, alerts) · teal (fitness)
57
+
58
+ Write this plan as a short comment at the top of main.py:
59
+ ```python
60
+ # UI PLAN
61
+ # Type: calculator | Theme: dark | Shape: circle | Layout: display+grid | Accent: orange
62
+ ```
63
+
64
+ ═══════════════════════════════════════════════════════════════════
65
+ APP TYPE VISUAL BLUEPRINTS — copy these exactly for each category
66
+ ═══════════════════════════════════════════════════════════════════
67
+
68
+ ## CALCULATOR / NUMPAD (match iOS/macOS Calculator exactly)
69
+
70
+ ```
71
+ Screen root: bg-gray-900 min-h-screen flex flex-col px-3 pb-6 pt-10
72
+ Display area: flex-1 flex items-end justify-end px-4 pb-4
73
+ Display text: text-white font-light tracking-tight text-right
74
+ (text-6xl ≤6 chars | text-5xl ≤9 | text-4xl ≤12 | text-3xl longer)
75
+ Button grid: grid grid-cols-4 gap-3 px-1
76
+ Button circle: rounded-full aspect-square flex items-center justify-center
77
+ text-xl font-semibold transition-all duration-100
78
+ Digit button: bg-gray-600 hover:bg-gray-500 active:bg-gray-400 text-white
79
+ (use for: 0-9, decimal, +/−)
80
+ Function btn: bg-gray-500 hover:bg-gray-400 active:bg-gray-300 text-white
81
+ (use for: AC, %, ⌫)
82
+ Operator btn: bg-orange-500 hover:bg-orange-400 active:bg-orange-300 text-white
83
+ (use for: ÷, ×, −, +, =)
84
+ Wide button: col-span-2 rounded-full aspect-auto py-5 px-8 justify-start
85
+ (use for: "0" zero button that spans 2 columns)
86
+ ```
87
+
88
+ Canonical button layout (rows top→bottom):
89
+ ```
90
+ Row 0 (functions): ⌫ AC % ÷
91
+ Row 1 (digits): 7 8 9 ×
92
+ Row 2 (digits): 4 5 6 −
93
+ Row 3 (digits): 1 2 3 +
94
+ Row 4 (zero row): [0 — wide] , =
95
+ ```
96
+
97
+ ## TODO / TASK MANAGER
98
+
99
+ ```
100
+ Screen root: bg-gray-50 min-h-screen
101
+ Header: bg-white border-b border-gray-100 px-4 py-4 shadow-sm
102
+ Task item: bg-white rounded-2xl px-4 py-4 flex flex-row items-center gap-3
103
+ border border-gray-100 shadow-sm
104
+ Check circle: w-6 h-6 rounded-full border-2 border-gray-300 flex items-center justify-center
105
+ Check done: bg-blue-600 border-blue-600 text-white
106
+ Add button: bg-blue-600 rounded-full w-14 h-14 flex items-center justify-center shadow-lg
107
+ text-white text-3xl font-light (FAB — bottom-right fixed)
108
+ ```
109
+
110
+ ## SHOPPING / E-COMMERCE
111
+
112
+ ```
113
+ Screen root: bg-gray-50 min-h-screen
114
+ Product card: bg-white rounded-2xl overflow-hidden shadow-sm border border-gray-100
115
+ Product grid: grid grid-cols-2 gap-4 px-4 py-4
116
+ Price: text-gray-900 text-lg font-bold
117
+ Original price: text-gray-400 text-sm line-through ml-1
118
+ Add-to-cart: bg-blue-600 hover:bg-blue-500 text-white rounded-xl px-4 py-2.5 font-semibold
119
+ Cart badge: bg-red-500 text-white text-xs rounded-full w-5 h-5 flex items-center justify-center
120
+ ```
121
+
122
+ ## DASHBOARD / STATS
123
+
124
+ ```
125
+ Screen root: bg-gray-900 min-h-screen px-4 py-6
126
+ Stat card: bg-gray-800 rounded-2xl p-5 shadow-lg
127
+ Big number: text-white text-4xl font-bold
128
+ Trend up: text-green-400 text-sm font-semibold
129
+ Trend down: text-red-400 text-sm font-semibold
130
+ Progress bar: bg-gray-700 rounded-full h-2; fill: bg-blue-500 rounded-full h-2
131
+ Chart area: bg-gray-800 rounded-2xl p-4 h-48
132
+ ```
133
+
134
+ ## MUSIC / MEDIA PLAYER
135
+
136
+ ```
137
+ Screen root: bg-gray-900 min-h-screen flex flex-col items-center px-6 py-10
138
+ Album art: w-64 h-64 rounded-3xl shadow-2xl object-cover
139
+ Track title: text-white text-2xl font-bold text-center mt-6
140
+ Artist name: text-gray-400 text-base text-center mt-1
141
+ Progress track: bg-gray-700 rounded-full h-1 w-full; fill: bg-white
142
+ Play/pause: bg-white rounded-full w-16 h-16 flex items-center justify-center shadow-xl
143
+ text-gray-900 text-2xl (large central circle)
144
+ Skip buttons: text-gray-400 hover:text-white text-3xl w-12 h-12 flex items-center justify-center
145
+ ```
30
146
 
31
147
  ═══════════════════════════════════════════════════════════════════
32
148
  P2M FRAMEWORK — COMPLETE API (memorise every detail)
@@ -206,50 +322,97 @@ category chips…) ALWAYS extract a private factory function. Never inline the s
206
322
  widget construction more than twice.
207
323
 
208
324
  ```python
209
- # views/calculator.py — reference example
325
+ # views/calculator.py — reference example (iOS/macOS style circular buttons)
210
326
 
211
327
  def _digit_btn(digit: str) -> Button:
212
- \"\"\"Digit button with consistent dark styling.\"\"\"""
328
+ \"\"\"Circular digit button dark gray, rounded-full + aspect-square = perfect circle.\"\"\"""
213
329
  return Button(
214
330
  digit,
215
331
  class_=(
216
- "bg-gray-700 hover:bg-gray-600 active:bg-gray-500 "
332
+ "bg-gray-600 hover:bg-gray-500 active:bg-gray-400 "
217
333
  "text-white text-2xl font-semibold "
218
- "rounded-2xl w-full aspect-square "
219
- "flex items-center justify-center transition-colors"
334
+ "rounded-full aspect-square " # ← rounded-full makes it circular
335
+ "flex items-center justify-center "
336
+ "transition-all duration-100"
220
337
  ),
221
338
  on_click="press_digit",
222
- on_click_args=[digit], # ← parametrised handler
339
+ on_click_args=[digit],
340
+ )
341
+
342
+ def _fn_btn(label: str, handler: str) -> Button:
343
+ \"\"\"Circular function button — medium gray (AC, %, backspace).\"\"\"""
344
+ return Button(
345
+ label,
346
+ class_=(
347
+ "bg-gray-500 hover:bg-gray-400 active:bg-gray-300 "
348
+ "text-white text-xl font-semibold "
349
+ "rounded-full aspect-square "
350
+ "flex items-center justify-center "
351
+ "transition-all duration-100"
352
+ ),
353
+ on_click=handler,
354
+ on_click_args=[label] if handler == "press_function" else [],
223
355
  )
224
356
 
225
- def _op_btn(symbol: str, handler: str = "press_operator") -> Button:
226
- \"\"\"Operator button with accent colour.\"\"\"""
357
+ def _op_btn(symbol: str) -> Button:
358
+ \"\"\"Circular operator button orange accent.\"\"\"""
227
359
  return Button(
228
360
  symbol,
229
361
  class_=(
230
362
  "bg-orange-500 hover:bg-orange-400 active:bg-orange-300 "
231
363
  "text-white text-2xl font-bold "
232
- "rounded-2xl w-full aspect-square "
233
- "flex items-center justify-center transition-colors"
364
+ "rounded-full aspect-square "
365
+ "flex items-center justify-center "
366
+ "transition-all duration-100"
234
367
  ),
235
- on_click=handler,
368
+ on_click="press_operator",
236
369
  on_click_args=[symbol],
237
370
  )
238
371
 
239
372
  def calculator_view(store) -> Column:
240
- root = Column(class_="flex flex-col min-h-screen bg-gray-900 px-4 pb-8 pt-12")
373
+ root = Column(class_="flex flex-col min-h-screen bg-gray-900 px-3 pb-6 pt-10")
241
374
 
242
- # Display — large responsive text, right-aligned
243
- display_size = "text-5xl" if len(store.display) <= 9 else "text-3xl"
244
- display = Container(class_="flex items-end justify-end px-4 py-6")
245
- display.add(Text(store.display, class_=f"{display_size} text-white font-light tracking-tight"))
375
+ # Display — right-aligned, font shrinks as number grows
376
+ n = len(store.display)
377
+ display_size = "text-6xl" if n <= 6 else "text-5xl" if n <= 9 else "text-4xl" if n <= 12 else "text-3xl"
378
+ display = Container(class_="flex-1 flex items-end justify-end px-4 pb-4")
379
+ display.add(Text(store.display, class_=f"{display_size} text-white font-light tracking-tight text-right"))
246
380
  root.add(display)
247
381
 
248
- # Button grid4 columns
249
- grid = Container(class_="grid grid-cols-4 gap-3")
250
- for digit in ["7","8","9","4","5","6","1","2","3","0",".",""]:
251
- grid.add(_digit_btn(digit) if digit else Container(class_="invisible"))
252
- root.add(grid)
382
+ # Row 0function row
383
+ row0 = Container(class_="grid grid-cols-4 gap-3 px-1 mb-3")
384
+ row0.add(_fn_btn("", "press_backspace"))
385
+ row0.add(_fn_btn("AC", "press_clear"))
386
+ row0.add(_fn_btn("%", "press_function"))
387
+ row0.add(_op_btn("÷"))
388
+ root.add(row0)
389
+
390
+ # Rows 1-3 — digit rows
391
+ for row_digits, op in [("789", "×"), ("456", "−"), ("123", "+")]:
392
+ row = Container(class_="grid grid-cols-4 gap-3 px-1 mb-3")
393
+ for d in row_digits:
394
+ row.add(_digit_btn(d))
395
+ row.add(_op_btn(op))
396
+ root.add(row)
397
+
398
+ # Row 4 — zero row (0 spans 2 cols, decimal, equals)
399
+ row4 = Container(class_="grid grid-cols-4 gap-3 px-1")
400
+ zero = Button(
401
+ "0",
402
+ class_=(
403
+ "col-span-2 bg-gray-600 hover:bg-gray-500 active:bg-gray-400 "
404
+ "text-white text-2xl font-semibold "
405
+ "rounded-full py-5 px-8 flex items-center justify-start "
406
+ "transition-all duration-100"
407
+ ),
408
+ on_click="press_digit",
409
+ on_click_args=["0"],
410
+ )
411
+ row4.add(zero)
412
+ row4.add(_digit_btn(","))
413
+ row4.add(_op_btn("="))
414
+ root.add(row4)
415
+
253
416
  return root
254
417
  ```
255
418
 
@@ -769,11 +932,13 @@ T4. Every `Text` node must have a complete typography class set:
769
932
  size (`text-base`), weight (`font-medium`), AND color (`text-gray-700`).
770
933
  Never use bare `Text("label")` with no class.
771
934
 
772
- T5. Border-radius must be intentional and consistent:
773
- - Small chips/badges: `rounded-full`
774
- - Buttons and inputs: `rounded-xl`
775
- - Cards and panels: `rounded-2xl`
776
- - Never use plain `rounded` (too small) or omit radius on interactive elements.
935
+ T5. Border-radius AND button shape must match the app type:
936
+ - Calculator / numpad / dialer: `rounded-full aspect-square` = perfect CIRCLES
937
+ - Filter chips / tags: `rounded-full px-3 py-1` = oval pills
938
+ - Standard action buttons: `rounded-xl px-5 py-3` = rounded rectangles
939
+ - Cards and panels: `rounded-2xl`
940
+ - Never use `rounded-xl` for calculator buttons — they MUST be `rounded-full`
941
+ - RULE: use the App Type Blueprint section to determine the correct shape
777
942
 
778
943
  T6. Every screen must have a visible visual hierarchy:
779
944
  - A header zone (title + optional action button)
@@ -796,6 +961,18 @@ T9. List items and cards must have consistent internal padding AND gap between
796
961
 
797
962
  T10. The root screen Column must ALWAYS have `min-h-screen` so it fills the
798
963
  viewport on every device. Missing `min-h-screen` will be rejected.
964
+
965
+ T11. CALCULATOR / NUMPAD apps: the button grid MUST use `rounded-full aspect-square`
966
+ for every button cell so buttons are PERFECT CIRCLES — this is non-negotiable.
967
+ The display MUST be right-aligned (`justify-end text-right`) with font that
968
+ shrinks dynamically based on the number of digits (see Blueprint).
969
+ NEVER generate a calculator with `rounded-xl` rectangular buttons.
970
+
971
+ T12. Before writing the view file, re-read your UI PLAN comment and verify:
972
+ - The button shape class matches the chosen APP TYPE blueprint exactly
973
+ - The accent colour is applied to primary action buttons only
974
+ - The display/output area uses the correct alignment and dynamic font sizing
975
+ - Every row of the button grid is wrapped in its own Container with `grid grid-cols-N gap-3`
799
976
  """
800
977
 
801
978
 
@@ -857,18 +1034,34 @@ def run_imagine_agent(
857
1034
  f"Create a complete P2M project for the following description:\n\n"
858
1035
  f'**Description:** {description}\n\n'
859
1036
  f"**Project name (use exactly this in p2m.toml):** `{project_name}`\n\n"
860
- f"CRITICAL: Write ALL files directly at the root level — do NOT create a "
861
- f"subdirectory named after the project. The output directory is already the "
862
- f"project root. Use write_file('main.py', ...) NOT "
863
- f"write_file('{project_name}/main.py', ...).\n\n"
864
- f"Generate the full project structure:\n"
865
- f"1. `main.py` entry point with ALL event handlers registered\n"
866
- f"2. `p2m.toml` project config (port 3000, entry = main.py)\n"
867
- f"3. `state/__init__.py` + `state/store.py` AppState + realistic sample data\n"
868
- f"4. `views/__init__.py` + `views/<screen>.py` one file per screen\n"
869
- f"5. `components/__init__.py` + `components/<name>.py` reusable components\n"
870
- f"6. `tests/__init__.py` + `tests/test_app.py` at least 6 pytest tests\n\n"
871
- f"Use realistic, complete sample data (5+ items).\n"
1037
+ f"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
1038
+ f"PHASE 1 UI DESIGN PLAN (do this first, before writing any code)\n"
1039
+ f"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
1040
+ f"Analyse the description and decide:\n"
1041
+ f" A. App type (calculator / todo / shopping / dashboard / music / other)\n"
1042
+ f" B. Theme (dark or light)\n"
1043
+ f" C. Primary button shape (circle / pill / rounded-rect)\n"
1044
+ f" D. Layout structure (display+grid / feed / master-detail / tabs / form)\n"
1045
+ f" E. Accent colour (orange / blue / green / purple / red / teal)\n"
1046
+ f"Then look up the matching App Type Blueprint in your instructions and copy\n"
1047
+ f"the exact Tailwind classes from it. Calculators MUST use `rounded-full\n"
1048
+ f"aspect-square` circular buttons and a right-aligned, adaptive-size display.\n\n"
1049
+ f"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
1050
+ f"PHASE 2 — GENERATE ALL FILES\n"
1051
+ f"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"
1052
+ f"CRITICAL: Write ALL files at the ROOT level — do NOT create a subdirectory.\n"
1053
+ f"Use write_file('main.py', ...) NOT write_file('{project_name}/main.py', ...).\n\n"
1054
+ f"Files to generate:\n"
1055
+ f"1. `main.py` — UI plan comment + utility helpers + ALL event handlers\n"
1056
+ f"2. `p2m.toml` — project config (port 3000, entry = main.py)\n"
1057
+ f"3. `state/__init__.py` — empty\n"
1058
+ f"4. `state/store.py` — AppState + realistic sample data (5+ items)\n"
1059
+ f"5. `views/__init__.py` — empty\n"
1060
+ f"6. `views/<screen>.py` — factory helpers + <screen>_view(store) function\n"
1061
+ f"7. `components/__init__.py` — empty\n"
1062
+ f"8. `components/<name>.py` — reusable components if needed\n"
1063
+ f"9. `tests/__init__.py` — empty\n"
1064
+ f"10. `tests/test_app.py` — at least 6 pytest tests\n\n"
872
1065
  f"Finish by calling `list_output_files()` to confirm all files are written."
873
1066
  )
874
1067
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "python2mobile"
7
- version = "0.1.3"
7
+ version = "0.1.4"
8
8
  description = "Python to Mobile - Write mobile apps in pure Python with DSL"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python2mobile
3
- Version: 0.1.3
3
+ Version: 0.1.4
4
4
  Summary: Python to Mobile - Write mobile apps in pure Python with DSL
5
5
  Author-email: P2M Team <team@python2mobile.dev>
6
6
  License-Expression: MIT
File without changes
File without changes
File without changes