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.
- {python2mobile-0.1.3 → python2mobile-0.1.4}/PKG-INFO +1 -1
- {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/imagine/agent.py +236 -43
- {python2mobile-0.1.3 → python2mobile-0.1.4}/pyproject.toml +1 -1
- {python2mobile-0.1.3 → python2mobile-0.1.4}/python2mobile.egg-info/PKG-INFO +1 -1
- {python2mobile-0.1.3 → python2mobile-0.1.4}/README.md +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/examples/example_ecommerce_app.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/examples/example_todo_app.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/__init__.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/cli.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/config.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/core/__init__.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/core/api.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/core/ast_walker.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/core/database.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/core/events.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/core/render_engine.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/core/runtime.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/core/state.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/core/validator.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/devserver/__init__.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/devserver/server.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/i18n/__init__.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/i18n/translator.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/imagine/__init__.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/imagine/legacy.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/llm/__init__.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/llm/anthropic_provider.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/llm/base.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/llm/compatible_provider.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/llm/factory.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/llm/ollama_provider.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/llm/openai_provider.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/testing/__init__.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/ui/__init__.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/p2m/ui/components.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/python2mobile.egg-info/SOURCES.txt +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/python2mobile.egg-info/dependency_links.txt +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/python2mobile.egg-info/entry_points.txt +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/python2mobile.egg-info/requires.txt +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/python2mobile.egg-info/top_level.txt +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/setup.cfg +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/tests/test_basic_engine.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/tests/test_build_generation.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/tests/test_build_test_gate.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/tests/test_carousel_modal.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/tests/test_config_system.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/tests/test_i18n.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/tests/test_ifood_app_integration.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/tests/test_imagine_cli.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/tests/test_imagine_command.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/tests/test_llm_providers.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/tests/test_new_apps_integration.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/tests/test_ollama_functional.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/tests/test_real_world_apps.py +0 -0
- {python2mobile-0.1.3 → python2mobile-0.1.4}/tests/test_run_integration.py +0 -0
|
@@ -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
|
|
26
|
-
|
|
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
|
|
29
|
-
|
|
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
|
-
\"\"\"
|
|
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-
|
|
332
|
+
"bg-gray-600 hover:bg-gray-500 active:bg-gray-400 "
|
|
217
333
|
"text-white text-2xl font-semibold "
|
|
218
|
-
"rounded-
|
|
219
|
-
"flex items-center justify-center
|
|
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],
|
|
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
|
|
226
|
-
\"\"\"
|
|
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-
|
|
233
|
-
"flex items-center justify-center
|
|
364
|
+
"rounded-full aspect-square "
|
|
365
|
+
"flex items-center justify-center "
|
|
366
|
+
"transition-all duration-100"
|
|
234
367
|
),
|
|
235
|
-
on_click=
|
|
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-
|
|
373
|
+
root = Column(class_="flex flex-col min-h-screen bg-gray-900 px-3 pb-6 pt-10")
|
|
241
374
|
|
|
242
|
-
# Display —
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
display
|
|
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
|
-
#
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
382
|
+
# Row 0 — function 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
|
|
773
|
-
-
|
|
774
|
-
-
|
|
775
|
-
-
|
|
776
|
-
-
|
|
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"
|
|
861
|
-
f"
|
|
862
|
-
f"
|
|
863
|
-
f"
|
|
864
|
-
f"
|
|
865
|
-
f"
|
|
866
|
-
f"
|
|
867
|
-
f"
|
|
868
|
-
f"
|
|
869
|
-
f"
|
|
870
|
-
f"
|
|
871
|
-
f"
|
|
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
|
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|