@shaykec/app-agent 1.0.10 → 1.0.11

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.
@@ -0,0 +1,310 @@
1
+ # Web Analyzer Skill
2
+
3
+ Analyze the web crawl report and website screenshots to produce a structured app specification (web-to-app manifest) that drives the rest of the build pipeline.
4
+
5
+ ## Inputs
6
+
7
+ - **Web crawl report**: `output/{app-name}/reports/02-web-crawl-report.md`
8
+ - **Website screenshots**: `output/{app-name}/web-crawl/screenshots/*.png` (passed as image attachments)
9
+ - **Focus directive** (optional): User's description of what to prioritize
10
+ - **Platform**: ios, android, or react-native
11
+
12
+ ## Process
13
+
14
+ ### 1. Read the Crawl Report
15
+
16
+ Read `reports/02-web-crawl-report.md` to understand:
17
+ - Site map (all pages discovered)
18
+ - Navigation structure
19
+ - Brand palette (colors, typography, layout patterns)
20
+ - Content model (entities, fields, categories)
21
+ - Functionality inventory (search, forms, filters, auth, CRUD)
22
+
23
+ ### 2. View the Screenshots
24
+
25
+ Examine all saved screenshots to visually verify and refine:
26
+ - Color accuracy (screenshots show the actual rendered colors)
27
+ - Layout patterns (card grids, list styles, hero sections, spacing)
28
+ - Visual hierarchy (what's prominent, what's secondary)
29
+ - Overall brand "feel" (modern, classic, playful, corporate, etc.)
30
+ - Typography style (even if exact fonts can't be extracted)
31
+
32
+ ### 3. Map Pages to Mobile Screens
33
+
34
+ Apply these mapping rules:
35
+
36
+ | Web Pattern | Mobile Pattern |
37
+ |-------------|---------------|
38
+ | Home/landing page | Home tab (main tab) |
39
+ | List/catalog page (products, articles) | List screen (scrollable, searchable) |
40
+ | Detail page (product detail, article) | Detail screen (push navigation) |
41
+ | Search page / search results | Search/Explore tab or search overlay |
42
+ | Category/filter page | Filter sheet or Explore tab |
43
+ | User profile / account | Profile tab |
44
+ | Favorites / wishlist / saved | Favorites tab |
45
+ | Contact / about / info | Info section in Profile or separate screen |
46
+ | Form (create, submit) | Create/Compose screen (modal or push) |
47
+ | Cart / checkout | Cart tab or sheet (if e-commerce) |
48
+ | Settings / preferences | Settings screen (in Profile tab) |
49
+
50
+ **Tab Bar Strategy** (max 4-5 tabs):
51
+ 1. **Home** — always the first tab (mirrors home page)
52
+ 2. **Explore/Search** — if the site has search, catalog, or browse functionality
53
+ 3. **Favorites** — if the site has save/wishlist/bookmark functionality
54
+ 4. **Profile** — if the site has user accounts, settings, or contact info
55
+ 5. **Extra tab** — only if the site has a major section that doesn't fit above (e.g., Cart for e-commerce)
56
+
57
+ ### 4. Map Navigation
58
+
59
+ | Web Navigation | Mobile Navigation |
60
+ |----------------|-------------------|
61
+ | Top nav bar links | Tab bar items |
62
+ | Sub-menu / dropdown | Navigation stack (push screens) |
63
+ | Breadcrumbs | Back button (automatic in nav stack) |
64
+ | Pagination | Infinite scroll or load-more |
65
+ | Modal / popup | Sheet or modal presentation |
66
+ | Sidebar / drawer | Not recommended — flatten into tabs |
67
+
68
+ ### 5. Extract Brand Tokens
69
+
70
+ From the crawl report and screenshots, produce exact brand tokens:
71
+
72
+ ```
73
+ Primary Color: #XXXXXX (main CTA / button color)
74
+ Secondary Color: #XXXXXX (accent / highlight color)
75
+ Background: #XXXXXX (page background)
76
+ Surface: #XXXXXX (card / section background)
77
+ Text Primary: #XXXXXX (headings, main text)
78
+ Text Secondary: #XXXXXX (captions, secondary text)
79
+ Error: #FF3B30 (default if not visible on site)
80
+ Success: #34C759 (default if not visible on site)
81
+
82
+ Corner Radius: {small/medium/large} → {4/8/12}pt
83
+ Shadow Style: {none/subtle/prominent}
84
+ Spacing Scale: {tight/medium/generous}
85
+
86
+ Typography Style: {sans-serif/serif/rounded} → map to system fonts
87
+ ```
88
+
89
+ ### 6. Define Data Model
90
+
91
+ From the content model in the crawl report:
92
+ - Map each entity to a Swift struct / Kotlin data class / TypeScript interface
93
+ - Define fields with types (String, Int, Double, URL, Date, Bool)
94
+ - Identify primary entity (the main "item" the app displays)
95
+ - Identify relationships (entity A has many entity B)
96
+
97
+ ### 7. Generate Content Brief
98
+
99
+ Adapt website copy for mobile:
100
+ - App display name (from website name/logo)
101
+ - Tab labels (short, 1-2 words)
102
+ - Screen titles
103
+ - Empty state messages
104
+ - Search placeholder text
105
+ - CTA button labels
106
+ - Onboarding text (if the site has a value proposition)
107
+ - Category names
108
+
109
+ ### 8. Decide: Template or Scratch
110
+
111
+ Compare the web-to-app mapping against available templates in CATALOG.md:
112
+ - If a template matches 70%+ of the required screens/features → use template mode
113
+ - If no template is a good fit → recommend scratch mode
114
+ - Always prefer template mode for reliability
115
+
116
+ ### 9. Generate Parallel Batches
117
+
118
+ Divide screens into 2-3 batches for parallel customization and testing:
119
+ - **Batch 1**: Home + Explore/Search screens
120
+ - **Batch 2**: Detail + Create/Form screens
121
+ - **Batch 3**: Profile + Settings + Favorites screens
122
+
123
+ ## Output
124
+
125
+ Write `output/{app-name}/reports/03-web-to-app-manifest.md` with this structure:
126
+
127
+ ```markdown
128
+ # Web-to-App Manifest
129
+
130
+ ## Source
131
+ - **URL**: {url}
132
+ - **App Name**: {derived from website name}
133
+ - **Bundle ID**: com.appship.{appname}
134
+ - **Platform**: {platform}
135
+ - **Build Mode**: {template/scratch}
136
+ - **Selected Template**: {template name or "N/A for scratch mode"}
137
+
138
+ ## Screen Mapping
139
+
140
+ | # | Web Page | Mobile Screen | Tab | Navigation |
141
+ |---|----------|--------------|-----|------------|
142
+ | 1 | Home | HomeView | Home | Root |
143
+ | 2 | Products | ProductListView | Explore | Root |
144
+ | 3 | Product Detail | ProductDetailView | — | Push from ProductList |
145
+ | 4 | Search Results | SearchView | Explore | Overlay |
146
+ | 5 | Cart | CartView | Cart | Root |
147
+ | 6 | Profile | ProfileView | Profile | Root |
148
+
149
+ ## Tab Bar
150
+
151
+ | # | Tab | Label | Icon (SF Symbol / Material) | Root Screen |
152
+ |---|-----|-------|---------------------------|-------------|
153
+ | 1 | Home | Home | house.fill / home | HomeView |
154
+ | 2 | Explore | Explore | magnifyingglass / search | ProductListView |
155
+ | 3 | Favorites | Saved | heart.fill / favorite | FavoritesView |
156
+ | 4 | Profile | Profile | person.fill / person | ProfileView |
157
+
158
+ ## Brand Tokens
159
+
160
+ ### Colors (Light Mode)
161
+ - primary: #{hex}
162
+ - secondary: #{hex}
163
+ - background: #{hex}
164
+ - surface: #{hex}
165
+ - textPrimary: #{hex}
166
+ - textSecondary: #{hex}
167
+ - error: #{hex}
168
+ - success: #{hex}
169
+
170
+ ### Colors (Dark Mode)
171
+ - primary: #{hex} (lightened for dark bg)
172
+ - secondary: #{hex}
173
+ - background: #1C1C1E
174
+ - surface: #2C2C2E
175
+ - textPrimary: #FFFFFF
176
+ - textSecondary: #8E8E93
177
+
178
+ ### Layout
179
+ - cornerRadius: {value}
180
+ - shadowStyle: {none/subtle/prominent}
181
+ - spacingScale: {tight/medium/generous}
182
+
183
+ ### Typography
184
+ - fontStyle: {sans-serif/serif/rounded}
185
+ - iOS: {system font recommendation}
186
+ - Android: {font recommendation}
187
+
188
+ ## Data Model
189
+
190
+ ### {PrimaryEntity} (e.g., Product)
191
+ ```
192
+ id: String (UUID)
193
+ name: String
194
+ description: String
195
+ imageUrl: URL
196
+ price: Double (optional)
197
+ category: String
198
+ rating: Double (optional)
199
+ isFavorite: Bool
200
+ createdAt: Date
201
+ ```
202
+
203
+ ### Categories
204
+ - {Category 1}
205
+ - {Category 2}
206
+ - ...
207
+
208
+ ## Content Brief
209
+
210
+ ### App Name & Branding
211
+ - **Display Name**: {name}
212
+ - **Tagline**: {from website}
213
+
214
+ ### Tab Labels
215
+ - Home, Explore, Saved, Profile
216
+
217
+ ### Screen Titles
218
+ - Home: "{title}"
219
+ - Explore: "{title}"
220
+ - ...
221
+
222
+ ### Empty States
223
+ - No items: "{message}"
224
+ - No favorites: "{message}"
225
+ - No search results: "{message}"
226
+
227
+ ### CTAs
228
+ - Primary CTA: "{label}"
229
+ - Secondary CTA: "{label}"
230
+
231
+ ## Mock Data Spec
232
+
233
+ ### {PrimaryEntity} (generate 12-15 items)
234
+ Use realistic content observed on the website:
235
+ - Item 1: {name}, {category}, {description snippet}
236
+ - Item 2: ...
237
+ (list 5-6 examples, agent generates the rest)
238
+
239
+ ### Categories (4-6)
240
+ - {name}: {description}
241
+
242
+ ## AppConfig Values
243
+
244
+ Map to CUSTOMIZE markers in the template:
245
+ - `appName`: "{value}"
246
+ - `primaryColor`: "#{hex}"
247
+ - `accentColor`: "#{hex}"
248
+ - `tabTitles`: ["{tab1}", "{tab2}", "{tab3}", "{tab4}"]
249
+ - `categories`: ["{cat1}", "{cat2}", ...]
250
+ - `entityName`: "{name}"
251
+ - `entityNamePlural`: "{names}"
252
+ (continue for all CUSTOMIZE markers)
253
+
254
+ ## Screen Changes
255
+
256
+ ### HomeView
257
+ - Replace hero section with: {description from website}
258
+ - Cards should display: {entity fields}
259
+ - Style: {layout pattern from website}
260
+ - Reference screenshot: page-home.png
261
+
262
+ ### {ScreenName}
263
+ - Changes: {description}
264
+ - Reference screenshot: page-{slug}.png
265
+
266
+ (repeat for each screen)
267
+
268
+ ## Parallel Batches
269
+
270
+ ### Screen Customization Batches
271
+ - **Batch 1** (Simulator 1): HomeView, ExploreView, SearchView
272
+ - **Batch 2** (Simulator 2): DetailView, CreateView, FavoritesView
273
+ - **Batch 3** (Simulator 3): ProfileView, SettingsView
274
+
275
+ ### UI Testing Batches
276
+ - **Batch 1** (Simulator 1): Home tab, Explore tab
277
+ - **Batch 2** (Simulator 2): Detail screen, Create flow, Favorites tab
278
+ - **Batch 3** (Simulator 3): Profile tab, Settings
279
+
280
+ ### Maestro Test Batches
281
+ - **Batch 1**: launch.yaml, home-tab.yaml, explore-tab.yaml
282
+ - **Batch 2**: detail-screen.yaml, create-flow.yaml, search-flow.yaml
283
+ - **Batch 3**: profile-tab.yaml, favorites-tab.yaml, e2e-navigation.yaml
284
+ ```
285
+
286
+ ## Template Selection Heuristics
287
+
288
+ When deciding which template to use, consider:
289
+
290
+ | Website Type | Best Template Match |
291
+ |-------------|-------------------|
292
+ | E-commerce / Shop | ShopTemplate |
293
+ | Blog / News / Content | SocialTemplate |
294
+ | Booking / Appointments | BookTemplate |
295
+ | Fitness / Health tracking | TrackTemplate |
296
+ | Finance / Banking | FinanceTemplate |
297
+ | Social / Community | SocialTemplate |
298
+ | Chat / Messaging | ChatTemplate |
299
+ | General / Mixed | Skeleton (or scratch) |
300
+
301
+ If the web-to-app manifest matches a template at 70%+ screen overlap, use it. Otherwise, recommend scratch mode or the Skeleton template.
302
+
303
+ ## Key Principles
304
+
305
+ 1. **Mobile-first thinking**: websites have infinite scroll space; mobile apps need concise, focused screens
306
+ 2. **Tab bar is the backbone**: map the site's main sections to 4-5 tabs maximum
307
+ 3. **Progressive disclosure**: detail pages are push-navigated from list pages, not shown inline
308
+ 4. **Brand fidelity**: match the website's colors, typography feel, and card/layout patterns as closely as the native platform allows
309
+ 5. **Content fidelity**: use actual content from the website (entity names, categories, descriptions) not generic placeholders
310
+ 6. **Platform conventions**: respect iOS HIG and Material Design guidelines even while matching the web brand
@@ -0,0 +1,252 @@
1
+ # Web Crawler Skill
2
+
3
+ Systematically crawl a website using ai-tester MCP tools to capture its structure, brand, content, and functionality. Produce a structured crawl report that feeds into the web-analyzer skill.
4
+
5
+ ## Inputs
6
+
7
+ - **URL**: The website URL to crawl
8
+ - **Focus directive** (optional): Which sections to prioritize
9
+
10
+ ## Tools
11
+
12
+ Use ONLY ai-tester MCP tools for all web interaction:
13
+ - `inspect({ platform: "web", url: "...", saveBaseline: "...", label: "..." })` — load page, get screenshot + element tree
14
+ - `navigate({ url: "..." })` — navigate to a page
15
+ - `act({ action: "tap", selector: "..." })` — click elements (menus, dropdowns, modals)
16
+ - `act({ action: "swipe", direction: "down" })` — scroll the page
17
+ - `wait({ for: "duration", duration: 2000 })` — wait for content to load
18
+
19
+ ## Crawl Strategy
20
+
21
+ ### Phase 1: Home Page Analysis
22
+
23
+ 1. Load the home page:
24
+ ```
25
+ inspect({ platform: "web", url: "{url}", saveBaseline: "page-home", label: "Home" })
26
+ ```
27
+ 2. Save the screenshot path: `output/{app-name}/web-crawl/screenshots/page-home.png`
28
+ 3. Analyze the element tree for:
29
+ - **Navigation elements**: `<nav>`, header links, hamburger menus, footer links
30
+ - **Hero/banner sections**: main call-to-action areas
31
+ - **Content sections**: cards, lists, grids
32
+ - **Brand signals**: logo, primary colors in buttons/headers, font styles
33
+
34
+ ### Phase 2: Navigation Discovery
35
+
36
+ From the home page element tree, identify all major navigation links:
37
+ - Primary navigation (top nav bar, main menu)
38
+ - Secondary navigation (sidebar, sub-menus)
39
+ - Footer navigation (about, contact, legal)
40
+ - Call-to-action links (sign up, get started, shop now)
41
+
42
+ Build a **page queue** of URLs to visit. Prioritize:
43
+ 1. Primary nav links (always visit)
44
+ 2. Pages mentioned in the focus directive (if provided)
45
+ 3. Secondary nav links (visit if under 10 pages total)
46
+ 4. Skip: external links, auth/login pages, legal/privacy pages
47
+
48
+ ### Phase 3: Page-by-Page Crawl
49
+
50
+ For each page in the queue (max 10 pages, depth 2 from home):
51
+
52
+ 1. Navigate to the page:
53
+ ```
54
+ navigate({ url: "{pageUrl}" })
55
+ ```
56
+ 2. Wait for content to load:
57
+ ```
58
+ wait({ for: "duration", duration: 2000 })
59
+ ```
60
+ 3. Capture screenshot + element tree:
61
+ ```
62
+ inspect({ saveBaseline: "page-{slug}", label: "{Page Title}" })
63
+ ```
64
+ 4. Scroll down to capture below-fold content:
65
+ ```
66
+ act({ action: "swipe", direction: "down" })
67
+ wait({ for: "duration", duration: 1000 })
68
+ inspect({ saveBaseline: "page-{slug}-scroll", label: "{Page Title} (scrolled)" })
69
+ ```
70
+ 5. Check for interactive elements:
71
+ - **Forms**: identify input fields, textareas, submit buttons
72
+ - **Dropdowns/modals**: tap to open, capture expanded state
73
+ - **Tabs/accordions**: click to reveal hidden content
74
+ - **Search**: identify search inputs and their behavior
75
+
76
+ Record for each page:
77
+ - URL
78
+ - Page title
79
+ - Screenshot file paths (above-fold + scrolled)
80
+ - Element tree summary (interactive elements count, content sections)
81
+ - Content type (list page, detail page, form page, informational page)
82
+ - Key entities displayed (products, articles, users, events, etc.)
83
+
84
+ ### Phase 4: Brand Extraction
85
+
86
+ From the collected screenshots and element trees, extract:
87
+
88
+ **Colors**:
89
+ - Primary color: dominant color in buttons, headers, and CTAs
90
+ - Secondary color: accent color used for highlights, links, hover states
91
+ - Background: main page background color
92
+ - Surface: card/section background color
93
+ - Text colors: heading color, body text color
94
+ - Error/success colors if visible in any forms
95
+
96
+ **Typography**:
97
+ - Heading font style (serif, sans-serif, monospace)
98
+ - Body text font style
99
+ - Relative sizes (large headings, medium subheads, regular body)
100
+
101
+ **Layout Patterns**:
102
+ - Card style (rounded corners, shadows, borders)
103
+ - Grid layout (2-column, 3-column, masonry)
104
+ - List layout (compact, spacious, with thumbnails)
105
+ - Spacing rhythm (tight, medium, generous)
106
+
107
+ **Logo & Imagery**:
108
+ - Logo description (text-based, icon, combination mark)
109
+ - Image style (photos, illustrations, icons)
110
+ - Hero section pattern (full-width image, gradient, video)
111
+
112
+ ### Phase 5: Functionality Inventory
113
+
114
+ Catalog all interactive functionality discovered:
115
+
116
+ - **Search**: search bar location, search behavior (instant, page-based)
117
+ - **Forms**: sign up, contact, create/edit forms — list all fields
118
+ - **Filters**: category filters, sort options, tag filters
119
+ - **Navigation patterns**: pagination, infinite scroll, back/forward
120
+ - **Authentication**: login/signup forms (note: do NOT attempt to log in)
121
+ - **CRUD indicators**: create buttons, edit icons, delete actions
122
+ - **E-commerce**: cart, checkout, product selection
123
+ - **Social**: comments, likes, sharing, user profiles
124
+
125
+ ## Output
126
+
127
+ Write `output/{app-name}/reports/02-web-crawl-report.md` with this structure:
128
+
129
+ ```markdown
130
+ # Web Crawl Report
131
+
132
+ ## Source
133
+ - **URL**: {url}
134
+ - **Crawl date**: {date}
135
+ - **Pages crawled**: {count}
136
+ - **Focus directive**: {description or "none"}
137
+
138
+ ## Site Map
139
+
140
+ | # | Page | URL | Type | Screenshot |
141
+ |---|------|-----|------|------------|
142
+ | 1 | Home | {url} | Landing | page-home.png |
143
+ | 2 | Products | {url}/products | List | page-products.png |
144
+ | ... | | | | |
145
+
146
+ ## Navigation Structure
147
+
148
+ ### Primary Navigation
149
+ - Home
150
+ - Products → /products
151
+ - About → /about
152
+ - Contact → /contact
153
+
154
+ ### Secondary Navigation
155
+ (sub-menus, sidebar links)
156
+
157
+ ### Footer Navigation
158
+ (footer links)
159
+
160
+ ## Brand Palette
161
+
162
+ ### Colors
163
+ - **Primary**: #{hex} (from: buttons, headers)
164
+ - **Secondary**: #{hex} (from: links, accents)
165
+ - **Background**: #{hex}
166
+ - **Surface**: #{hex} (cards, sections)
167
+ - **Text Primary**: #{hex}
168
+ - **Text Secondary**: #{hex}
169
+
170
+ ### Typography
171
+ - **Headings**: {font style description}
172
+ - **Body**: {font style description}
173
+ - **Size scale**: {relative sizes}
174
+
175
+ ### Layout Patterns
176
+ - **Cards**: {description — rounded corners, shadow, border}
177
+ - **Grid**: {column count, gap}
178
+ - **Spacing**: {tight/medium/generous}
179
+
180
+ ### Logo & Imagery
181
+ - **Logo**: {description}
182
+ - **Image style**: {photos/illustrations/icons}
183
+
184
+ ## Content Model
185
+
186
+ ### Entities
187
+ 1. **{Entity Name}** (e.g., Product)
188
+ - Fields: name, price, image, description, category, rating
189
+ - Seen on: /products, /products/{id}
190
+ - Count: ~{n} items visible
191
+
192
+ 2. **{Entity Name}** (e.g., Blog Post)
193
+ - Fields: title, author, date, excerpt, image
194
+ - Seen on: /blog, /blog/{slug}
195
+
196
+ ### Categories
197
+ - {Category 1}: {description}
198
+ - {Category 2}: {description}
199
+
200
+ ## Functionality Inventory
201
+
202
+ ### Search
203
+ - Location: {header/page}
204
+ - Type: {instant/page-based}
205
+
206
+ ### Forms
207
+ 1. **{Form Name}** (e.g., Contact Form)
208
+ - Fields: name, email, message
209
+ - Location: /contact
210
+
211
+ ### Filters & Sorting
212
+ - {description of filter/sort options}
213
+
214
+ ### Authentication
215
+ - Login: {yes/no, location}
216
+ - Sign up: {yes/no, location}
217
+
218
+ ### Other Features
219
+ - {feature}: {description}
220
+
221
+ ## Page Details
222
+
223
+ ### Page: {Page Name}
224
+ - **URL**: {url}
225
+ - **Type**: {list/detail/form/landing}
226
+ - **Screenshot**: page-{slug}.png
227
+ - **Key elements**: {description}
228
+ - **Interactive elements**: {count} buttons, {count} links, {count} inputs
229
+ - **Content**: {summary of what's displayed}
230
+
231
+ (repeat for each page)
232
+ ```
233
+
234
+ ## Limits & Safety
235
+
236
+ - **Max pages**: 10 (prioritize primary nav and focus directive pages)
237
+ - **Max depth**: 2 levels from home page
238
+ - **Timeout**: 5 seconds per page load — skip pages that don't load
239
+ - **No authentication**: do NOT attempt to log in or create accounts
240
+ - **No form submission**: inspect forms but do NOT submit them
241
+ - **No payments**: do NOT interact with payment flows
242
+ - **External links**: skip links to other domains
243
+ - **Rate limiting**: wait 1-2 seconds between page navigations
244
+
245
+ ## Focus Directive Handling
246
+
247
+ If a focus directive is provided:
248
+ 1. Still crawl the home page first (for brand extraction)
249
+ 2. Prioritize pages related to the directive
250
+ 3. Explore those sections more deeply (depth 2)
251
+ 4. Other sections: capture at depth 1 only (screenshot + basic element tree)
252
+ 5. In the crawl report, mark which pages are "primary" (from directive) vs "secondary"
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAA2B,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAIrF,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AAE9B,mDAAmD;AACnD,MAAM,WAAW,QAAQ;IACvB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,SAAS,CAAC;IACjB,KAAK,EAAE,QAAQ,CAAC;CACjB;AAED,qIAAqI;AACrI,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,WAAW,GAAG,KAAK,GAAG,SAAS,GAAG,YAAY,GAAG,WAAW,CAAC;IAChG,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,iFAAiF;AACjF,MAAM,MAAM,iBAAiB,GACzB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,iBAAiB,CAAA;CAAE,CAAC;AAEvD;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,iBAAiB,GAAG,IAAI,CAqKjE;AAED;;;GAGG;AACH,wBAAgB,YAAY,IAAI,cAAc,GAAG,IAAI,CAyGpD;AAED;;;GAGG;AACH,wBAAsB,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,CA4D/C;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAoNnE;AAoHD,uEAAuE;AACvE,wBAAsB,YAAY,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAkDrE"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAA2B,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAIrF,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AAE9B,mDAAmD;AACnD,MAAM,WAAW,QAAQ;IACvB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,SAAS,CAAC;IACjB,KAAK,EAAE,QAAQ,CAAC;CACjB;AAED,qIAAqI;AACrI,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,WAAW,GAAG,KAAK,GAAG,SAAS,GAAG,YAAY,GAAG,WAAW,CAAC;IAChG,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,iFAAiF;AACjF,MAAM,MAAM,iBAAiB,GACzB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,iBAAiB,CAAA;CAAE,CAAC;AAEvD;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,iBAAiB,GAAG,IAAI,CAqKjE;AAED;;;GAGG;AACH,wBAAgB,YAAY,IAAI,cAAc,GAAG,IAAI,CAuHpD;AAED;;;GAGG;AACH,wBAAsB,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,CA4D/C;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAoNnE;AAoHD,uEAAuE;AACvE,wBAAsB,YAAY,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAwDrE"}
package/dist/cli.js CHANGED
@@ -184,6 +184,7 @@ export function parseCliArgs() {
184
184
  let quick = false;
185
185
  let update = false;
186
186
  let updateTarget;
187
+ let url;
187
188
  let noPreview = false;
188
189
  let keysFile;
189
190
  let keepSimulator = true;
@@ -224,6 +225,10 @@ export function parseCliArgs() {
224
225
  update = true;
225
226
  updateTarget = args[++i];
226
227
  break;
228
+ case "--url":
229
+ case "--web":
230
+ url = args[++i];
231
+ break;
227
232
  case "--no-preview":
228
233
  noPreview = true;
229
234
  break;
@@ -241,8 +246,12 @@ export function parseCliArgs() {
241
246
  break;
242
247
  }
243
248
  }
244
- // Non-interactive mode: description is required; platform defaults to ios if not provided
245
- if (description && (PLATFORM_INPUTS.includes(platform) || update)) {
249
+ // Web clone mode: --url triggers non-interactive mode even without --description
250
+ if (url && !description) {
251
+ description = ""; // description is optional in web-clone mode
252
+ }
253
+ // Non-interactive mode: description (or url) is required; platform defaults to ios if not provided
254
+ if ((description != null || url) && (PLATFORM_INPUTS.includes(platform) || update)) {
246
255
  if (!PLATFORM_INPUTS.includes(platform)) {
247
256
  console.error(`Invalid platform: ${platform}. Available: ${PLATFORM_INPUTS.join(", ")}`);
248
257
  process.exit(1);
@@ -263,11 +272,15 @@ export function parseCliArgs() {
263
272
  console.error("--update requires a GitHub URL, local path, or app name.");
264
273
  process.exit(1);
265
274
  }
275
+ if (url && !description) {
276
+ // Ensure description is non-empty for downstream code that expects it
277
+ description = `Clone website: ${url}`;
278
+ }
266
279
  if (!platformSet && !update) {
267
280
  console.log(`Using default platform: ${platform}`);
268
281
  }
269
282
  return {
270
- input: { description, platform, model, engine, scratch, quick, update, updateTarget, keysFile, keepSimulator },
283
+ input: { description: description, platform, model, engine, scratch, quick, update, updateTarget, url, keysFile, keepSimulator },
271
284
  flags: { push, repoName, engine, noPreview },
272
285
  };
273
286
  }
@@ -648,13 +661,22 @@ export async function confirmInput(input) {
648
661
  }
649
662
  const platLabel = input.platform === "both" ? "Both (iOS + Android)"
650
663
  : platformLabel(input.platform);
651
- p.note([
652
- `App: ${input.description}`,
653
- `Platform: ${platLabel}`,
654
- `Engine: ${input.engine === "claude" ? "Claude Code" : "Cursor CLI"}`,
655
- `Model: ${input.model}`,
656
- `Mode: ${input.quick ? "Quick" : input.scratch ? "From scratch" : "Template"}`,
657
- ].join("\n"), "Build Summary");
664
+ const modeLabel = input.url ? "Web Clone" : input.quick ? "Quick" : input.scratch ? "From scratch" : "Template";
665
+ const summaryLines = [];
666
+ if (input.url) {
667
+ summaryLines.push(`URL: ${input.url}`);
668
+ if (input.description && !input.description.startsWith("Clone website:")) {
669
+ summaryLines.push(`Focus: ${input.description}`);
670
+ }
671
+ }
672
+ else {
673
+ summaryLines.push(`App: ${input.description}`);
674
+ }
675
+ summaryLines.push(`Platform: ${platLabel}`);
676
+ summaryLines.push(`Engine: ${input.engine === "claude" ? "Claude Code" : "Cursor CLI"}`);
677
+ summaryLines.push(`Model: ${input.model}`);
678
+ summaryLines.push(`Mode: ${modeLabel}`);
679
+ p.note(summaryLines.join("\n"), "Build Summary");
658
680
  const confirmed = await p.confirm({
659
681
  message: "Proceed with building this app?",
660
682
  });