@maccesar/titools 2.0.0

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 (120) hide show
  1. package/AGENTS-TEMPLATE.md +173 -0
  2. package/README.md +867 -0
  3. package/agents/ti-researcher.md +108 -0
  4. package/bin/titools.js +53 -0
  5. package/lib/commands/agents.js +126 -0
  6. package/lib/commands/install.js +188 -0
  7. package/lib/commands/uninstall.js +215 -0
  8. package/lib/commands/update.js +159 -0
  9. package/lib/config.js +119 -0
  10. package/lib/downloader.js +153 -0
  11. package/lib/installer.js +253 -0
  12. package/lib/platform.js +108 -0
  13. package/lib/symlink.js +142 -0
  14. package/lib/utils.js +270 -0
  15. package/package.json +67 -0
  16. package/skills/alloy-expert/SKILL.md +247 -0
  17. package/skills/alloy-expert/assets/ControllerAutoCleanup.js +182 -0
  18. package/skills/alloy-expert/references/alloy-structure.md +381 -0
  19. package/skills/alloy-expert/references/anti-patterns.md +133 -0
  20. package/skills/alloy-expert/references/code-conventions.md +469 -0
  21. package/skills/alloy-expert/references/contracts.md +280 -0
  22. package/skills/alloy-expert/references/controller-patterns.md +520 -0
  23. package/skills/alloy-expert/references/error-handling.md +484 -0
  24. package/skills/alloy-expert/references/examples.md +735 -0
  25. package/skills/alloy-expert/references/migration-patterns.md +298 -0
  26. package/skills/alloy-expert/references/patterns.md +448 -0
  27. package/skills/alloy-expert/references/performance-patterns.md +855 -0
  28. package/skills/alloy-expert/references/security-patterns.md +847 -0
  29. package/skills/alloy-expert/references/state-management.md +779 -0
  30. package/skills/alloy-expert/references/testing.md +872 -0
  31. package/skills/alloy-guides/SKILL.md +214 -0
  32. package/skills/alloy-guides/references/CLI_TASKS.md +243 -0
  33. package/skills/alloy-guides/references/CONCEPTS.md +191 -0
  34. package/skills/alloy-guides/references/CONTROLLERS.md +298 -0
  35. package/skills/alloy-guides/references/MODELS.md +1028 -0
  36. package/skills/alloy-guides/references/PURGETSS.md +56 -0
  37. package/skills/alloy-guides/references/VIEWS_DYNAMIC.md +242 -0
  38. package/skills/alloy-guides/references/VIEWS_STYLES.md +388 -0
  39. package/skills/alloy-guides/references/VIEWS_WITHOUT_CONTROLLERS.md +109 -0
  40. package/skills/alloy-guides/references/VIEWS_XML.md +558 -0
  41. package/skills/alloy-guides/references/WIDGETS.md +176 -0
  42. package/skills/alloy-howtos/SKILL.md +203 -0
  43. package/skills/alloy-howtos/references/best_practices.md +138 -0
  44. package/skills/alloy-howtos/references/cli_reference.md +253 -0
  45. package/skills/alloy-howtos/references/config_files.md +87 -0
  46. package/skills/alloy-howtos/references/custom_tags.md +147 -0
  47. package/skills/alloy-howtos/references/debugging_troubleshooting.md +101 -0
  48. package/skills/alloy-howtos/references/samples.md +167 -0
  49. package/skills/purgetss/SKILL.md +442 -0
  50. package/skills/purgetss/assets/purgetss.config.cjs +17 -0
  51. package/skills/purgetss/references/EXAMPLES.md +247 -0
  52. package/skills/purgetss/references/animation-system.md +1294 -0
  53. package/skills/purgetss/references/apply-directive.md +375 -0
  54. package/skills/purgetss/references/arbitrary-values.md +612 -0
  55. package/skills/purgetss/references/class-index.md +1350 -0
  56. package/skills/purgetss/references/cli-commands.md +948 -0
  57. package/skills/purgetss/references/configurable-properties.md +654 -0
  58. package/skills/purgetss/references/custom-rules.md +161 -0
  59. package/skills/purgetss/references/customization-deep-dive.md +722 -0
  60. package/skills/purgetss/references/dynamic-component-creation.md +489 -0
  61. package/skills/purgetss/references/grid-layout.md +455 -0
  62. package/skills/purgetss/references/icon-fonts.md +609 -0
  63. package/skills/purgetss/references/installation-setup.md +366 -0
  64. package/skills/purgetss/references/opacity-modifier.md +291 -0
  65. package/skills/purgetss/references/platform-modifiers.md +479 -0
  66. package/skills/purgetss/references/smart-mappings.md +42 -0
  67. package/skills/purgetss/references/titanium-resets.md +359 -0
  68. package/skills/purgetss/references/ui-ux-design.md +1526 -0
  69. package/skills/ti-guides/SKILL.md +94 -0
  70. package/skills/ti-guides/references/advanced-data-and-images.md +19 -0
  71. package/skills/ti-guides/references/alloy-cli-advanced.md +84 -0
  72. package/skills/ti-guides/references/alloy-data-mastery.md +29 -0
  73. package/skills/ti-guides/references/alloy-widgets-and-themes.md +19 -0
  74. package/skills/ti-guides/references/android-manifest.md +97 -0
  75. package/skills/ti-guides/references/app-distribution.md +258 -0
  76. package/skills/ti-guides/references/application-frameworks.md +377 -0
  77. package/skills/ti-guides/references/cli-reference.md +402 -0
  78. package/skills/ti-guides/references/coding-best-practices.md +102 -0
  79. package/skills/ti-guides/references/commonjs-advanced.md +134 -0
  80. package/skills/ti-guides/references/hello-world.md +100 -0
  81. package/skills/ti-guides/references/hyperloop-native-access.md +62 -0
  82. package/skills/ti-guides/references/javascript-primer.md +411 -0
  83. package/skills/ti-guides/references/reserved-words.md +36 -0
  84. package/skills/ti-guides/references/resources.md +183 -0
  85. package/skills/ti-guides/references/style-and-conventions.md +48 -0
  86. package/skills/ti-guides/references/tiapp-config.md +609 -0
  87. package/skills/ti-howtos/SKILL.md +174 -0
  88. package/skills/ti-howtos/references/android-platform-deep-dives.md +658 -0
  89. package/skills/ti-howtos/references/automation-fastlane-appium.md +95 -0
  90. package/skills/ti-howtos/references/buffer-codec-streams.md +140 -0
  91. package/skills/ti-howtos/references/cross-platform-development.md +348 -0
  92. package/skills/ti-howtos/references/debugging-profiling.md +543 -0
  93. package/skills/ti-howtos/references/extending-titanium.md +723 -0
  94. package/skills/ti-howtos/references/google-maps-v2.md +169 -0
  95. package/skills/ti-howtos/references/ios-map-kit.md +143 -0
  96. package/skills/ti-howtos/references/ios-platform-deep-dives.md +783 -0
  97. package/skills/ti-howtos/references/local-data-sources.md +301 -0
  98. package/skills/ti-howtos/references/location-and-maps.md +252 -0
  99. package/skills/ti-howtos/references/media-apis.md +210 -0
  100. package/skills/ti-howtos/references/notification-services.md +599 -0
  101. package/skills/ti-howtos/references/remote-data-sources.md +349 -0
  102. package/skills/ti-howtos/references/tutorials.md +502 -0
  103. package/skills/ti-howtos/references/using-modules.md +237 -0
  104. package/skills/ti-howtos/references/web-content-integration.md +307 -0
  105. package/skills/ti-howtos/references/webpack-build-pipeline.md +78 -0
  106. package/skills/ti-ui/SKILL.md +179 -0
  107. package/skills/ti-ui/references/accessibility-deep-dive.md +242 -0
  108. package/skills/ti-ui/references/animation-and-matrices.md +599 -0
  109. package/skills/ti-ui/references/application-structures.md +655 -0
  110. package/skills/ti-ui/references/custom-fonts-styling.md +579 -0
  111. package/skills/ti-ui/references/event-handling.md +393 -0
  112. package/skills/ti-ui/references/gestures.md +473 -0
  113. package/skills/ti-ui/references/icons-and-splash-screens.md +409 -0
  114. package/skills/ti-ui/references/layouts-and-positioning.md +462 -0
  115. package/skills/ti-ui/references/listviews-and-performance.md +619 -0
  116. package/skills/ti-ui/references/orientation.md +362 -0
  117. package/skills/ti-ui/references/platform-ui-android.md +635 -0
  118. package/skills/ti-ui/references/platform-ui-ios.md +469 -0
  119. package/skills/ti-ui/references/scrolling-views.md +252 -0
  120. package/skills/ti-ui/references/tableviews.md +568 -0
@@ -0,0 +1,381 @@
1
+ # Alloy MVC + PurgeTSS Structure Reference
2
+
3
+ ## Standard Project Structure
4
+
5
+ ```
6
+ app/
7
+ ├── controllers/ # View orchestrators
8
+ │ ├── index.js # Bootstrap only (no business logic)
9
+ │ └── feature/
10
+ │ └── list.js # Controller for list view
11
+ ├── models/ # OPTIONAL: For persistence with migrations
12
+ │ └── user.js # Model definition (ONLY if using SQLite)
13
+ ├── views/ # XML views styled with PurgeTSS
14
+ │ ├── index.xml
15
+ │ └── feature/
16
+ │ ├── list.xml # View definition (Utility classes here)
17
+ ├── lib/ # Reusable logic (no UI)
18
+ │ ├── api/
19
+ │ │ └── client.js # API calls
20
+ │ ├── services/
21
+ │ │ ├── auth.js # Business logic services
22
+ │ │ ├── navigation.js # Navigation orchestration
23
+ │ │ ├── nativeService.js # Native module wrapper (e.g. Audio, FB, Maps)
24
+ │ │ └── purgetss.animation.js # PurgeTSS Animation module
25
+ │ └── helpers/
26
+ │ ├── utils.js # Pure utility functions
27
+ │ └── i18n.js # Complex string transformations
28
+ ├── widgets/ # Truly reusable components (used in 3+ places)
29
+ │ └── customButton/
30
+ ├── styles/ # Global styles
31
+ │ ├── app.tss # GENERATED by PurgeTSS (Do not edit)
32
+ │ ├── _app.tss # YOUR custom styles (persists across runs)
33
+ │ └── fonts.tss # GENERATED by PurgeTSS build-fonts
34
+ ├── config.json # Alloy configuration
35
+ └── alloy.js # Collections & Global services
36
+
37
+ ./purgetss/
38
+ ├── config.cjs # PurgeTSS theme configuration
39
+ └── styles/
40
+ └── utilities.tss # All utility classes
41
+ ```
42
+
43
+ ## lib/ Folder and Module Require Paths
44
+
45
+ :::danger CRITICAL: lib/ Folder is FLATTENED During Build
46
+ When Alloy compiles, the **entire `lib/` folder is flattened to the root of Resources**. This means:
47
+ - `app/lib/services/picsum.js` → `Resources/iphone/services/picsum.js`
48
+ - `app/lib/api/client.js` → `Resources/iphone/api/client.js`
49
+
50
+ **Therefore, require statements should NOT include `lib/` prefix:**
51
+ ```javascript
52
+ // ❌ WRONG - Will fail at runtime
53
+ const client = require('lib/api/client')
54
+
55
+ // ✅ CORRECT - Path relative to flattened lib/
56
+ const client = require('api/client')
57
+ const picsum = require('services/picsum')
58
+ ```
59
+
60
+ **This applies to:**
61
+ - All files in `app/lib/` (services, api, helpers, etc.)
62
+ - Cross-references within lib/ files
63
+ - Controller requires of lib/ files
64
+
65
+ **Example project structure:**
66
+ ```
67
+ app/
68
+ ├── lib/
69
+ │ ├── services/
70
+ │ │ ├── picsum.js # require('services/logger')
71
+ │ │ ├── navigation.js # require('services/logger')
72
+ │ │ └── logger.js
73
+ │ └── api/
74
+ │ └── client.js # require('services/logger')
75
+ ├── controllers/
76
+ │ └── index.js # require('services/picsum')
77
+ ```
78
+ :::
79
+
80
+ ## Data Layer: Two Approaches
81
+
82
+ ### Approach A: Alloy Models (app/models/) - For Persistence
83
+
84
+ **Use when:**
85
+ - You need SQLite persistence
86
+ - You need schema migrations between app versions
87
+ - You need offline-first functionality
88
+
89
+ ```javascript
90
+ // app/models/User.js
91
+ exports.definition = {
92
+ config: {
93
+ columns: {
94
+ id: 'INTEGER PRIMARY KEY',
95
+ name: 'TEXT',
96
+ email: 'TEXT'
97
+ },
98
+ adapter: {
99
+ type: 'sql',
100
+ collection_name: 'users'
101
+ }
102
+ }
103
+ }
104
+
105
+ // Usage
106
+ const users = Alloy.createCollection('User')
107
+ users.fetch()
108
+ ```
109
+
110
+ ---
111
+
112
+ ### Approach B: Backbone Collections Direct (alloy.js) - For API Data
113
+
114
+ **Use when:**
115
+ - Data comes from APIs
116
+ - No local persistence needed
117
+ - You want simplicity and flexibility
118
+
119
+ ```javascript
120
+ // alloy.js - Define collections globally
121
+ Alloy.Collections.frames = new Backbone.Collection()
122
+ Alloy.Collections.mockups = new Backbone.Collection()
123
+ ```
124
+
125
+ **In views - bind with dataCollection:**
126
+ ```xml
127
+ <ListSection id="section" dataCollection="frames">
128
+ <ListItem title:text="{title}" />
129
+ </ListSection>
130
+ ```
131
+
132
+ **In controllers - manipulate directly:**
133
+ ```javascript
134
+ // Reset collection
135
+ Alloy.Collections.frames.reset()
136
+
137
+ // Add items
138
+ Alloy.Collections.frames.add(newItem)
139
+
140
+ // Fetch from API
141
+ api.getFrames()
142
+ .then(frames => Alloy.Collections.frames.reset(frames))
143
+ ```
144
+
145
+ ## Controller Rules
146
+
147
+ **DO:**
148
+ - Use **PurgeTSS classes** in XML for 100% of the styling.
149
+ - Orchestrate view and model/collection interactions.
150
+ - Handle UI events and delegate to services.
151
+ - Format data for display (simple cases).
152
+ - Manage view lifecycle (including cleanup).
153
+
154
+ **DON'T:**
155
+ - Create per-controller `.tss` files (Use PurgeTSS utility classes).
156
+ - Make direct API calls (use lib/api/ or lib/services/).
157
+ - Contain heavy business logic.
158
+ - Call native modules directly (use a service wrapper).
159
+
160
+ ## Navigation & Cleanup Pattern
161
+
162
+ ### Automatic Cleanup with ControllerAutoCleanup
163
+
164
+ For automatic controller cleanup without code changes, use the ControllerAutoCleanup utility.
165
+
166
+ **Installation:**
167
+
168
+ 1. Copy `ControllerAutoCleanup.js` to `app/lib/`
169
+ 2. Add as first line in `alloy.js`:
170
+
171
+ ```javascript
172
+ // alloy.js
173
+ require('ControllerAutoCleanup')
174
+
175
+ // Rest of your alloy.js initialization...
176
+ Alloy.Collections.frames = new Backbone.Collection()
177
+ ```
178
+
179
+ **How it works:**
180
+
181
+ - Monkey-patches `Alloy.createController` to add automatic cleanup
182
+ - Listens for `close` events and recursively cleans up controllers
183
+ - No code changes needed - existing `Alloy.createController().getView().open()` calls get cleanup automatically
184
+
185
+ **Benefits:**
186
+
187
+ | Without ControllerAutoCleanup | With ControllerAutoCleanup |
188
+ | ------------------------------------------ | -------------------------- |
189
+ | Must remember manual cleanup | Cleanup automatic |
190
+ | Easy to forget, causes memory leaks | Memory leaks prevented |
191
+ | Repetitive code in each navigation service | One-line install |
192
+
193
+ See [ControllerAutoCleanup.js](../assets/ControllerAutoCleanup.js) for the complete source code.
194
+
195
+ ## i18n and Accessibility Rules
196
+
197
+ - All static text must use `L('key')`.
198
+ - All interactive elements must have `accessibilityLabel`.
199
+ - Use `lib/helpers/i18n.js` for strings that require logic (e.g., "You have 5 messages").
200
+ - Use **PurgeTSS modifiers** for platform-specific design instead of conditional code.
201
+
202
+ ## Widget Structure
203
+
204
+ Widgets are self-contained, reusable components used in 3+ places across the app.
205
+
206
+ ```
207
+ app/widgets/
208
+ └── loadingOverlay/
209
+ ├── controllers/
210
+ │ └── widget.js # Main widget controller
211
+ ├── views/
212
+ │ └── widget.xml # Main widget view
213
+ ├── styles/
214
+ │ └── widget.tss # Widget-specific styles (optional with PurgeTSS)
215
+ └── widget.json # Widget manifest
216
+ ```
217
+
218
+ ### widget.json Configuration
219
+ ```json
220
+ {
221
+ "id": "com.app.loadingOverlay",
222
+ "name": "Loading Overlay",
223
+ "description": "Full-screen loading indicator with optional message",
224
+ "author": "Your Name",
225
+ "version": "1.0.0",
226
+ "copyright": "Copyright (c) 2024",
227
+ "license": "MIT",
228
+ "min-alloy-version": "1.0.0",
229
+ "min-titanium-version": "9.0.0",
230
+ "tags": "ui, loading",
231
+ "platforms": "android,ios"
232
+ }
233
+ ```
234
+
235
+ ### Widget View (widget.xml)
236
+ ```xml
237
+ <Alloy>
238
+ <View id="container" class="wh-screen hidden bg-black/50">
239
+ <View class="wh-32 vertical rounded-2xl bg-white">
240
+ <ActivityIndicator id="spinner" class="mt-6" />
241
+ <Label id="messageLabel" class="mx-4 mt-4 text-sm text-gray-600" />
242
+ </View>
243
+ </View>
244
+ </Alloy>
245
+ ```
246
+
247
+ ### Widget Controller (widget.js)
248
+ ```javascript
249
+ // Widget controller receives args via $.args
250
+ const args = $.args || {}
251
+
252
+ // Initialize with defaults
253
+ let message = args.message || L('loading')
254
+
255
+ // Public API
256
+ $.show = (msg) => {
257
+ if (msg) message = msg
258
+ $.messageLabel.text = message
259
+ $.spinner.show()
260
+ $.container.visible = true
261
+ }
262
+
263
+ $.hide = () => {
264
+ $.spinner.hide()
265
+ $.container.visible = false
266
+ }
267
+
268
+ $.setMessage = (msg) => {
269
+ $.messageLabel.text = msg
270
+ }
271
+
272
+ // Cleanup
273
+ $.cleanup = () => {
274
+ $.spinner.hide()
275
+ $.destroy()
276
+ }
277
+ ```
278
+
279
+ ### Using Widgets
280
+ ```xml
281
+ <!-- In any view -->
282
+ <Alloy>
283
+ <Window>
284
+ <!-- Your content -->
285
+
286
+ <!-- Add widget -->
287
+ <Widget id="loader" src="loadingOverlay" message="L('please_wait')" />
288
+ </Window>
289
+ </Alloy>
290
+ ```
291
+
292
+ ```javascript
293
+ // In controller
294
+ const loadData = () => {
295
+ $.loader.show(L('loading_data'))
296
+
297
+ api.fetchData()
298
+ .then(renderData)
299
+ .finally(() => $.loader.hide())
300
+ }
301
+ ```
302
+
303
+ :::tip PurgeTSS with Widgets
304
+ If your widget uses PurgeTSS utility classes (as shown in the example above), you must enable widget processing in `./purgetss/config.cjs`:
305
+
306
+ ```javascript
307
+ // ./purgetss/config.cjs
308
+ module.exports = {
309
+ purge: {
310
+ options: {
311
+ widgets: true // Enable PurgeTSS class processing for widgets
312
+ }
313
+ }
314
+ }
315
+ ```
316
+
317
+ Without this setting, PurgeTSS will NOT process classes in widget files.
318
+ :::
319
+
320
+ ## config.json Reference
321
+
322
+ The `app/config.json` file configures Alloy compilation and runtime behavior.
323
+
324
+ ```json
325
+ {
326
+ "global": {
327
+ "theme": "default"
328
+ },
329
+ "env:development": {
330
+ "apiUrl": "https://dev-api.example.com",
331
+ "debug": true,
332
+ "logLevel": "debug"
333
+ },
334
+ "env:test": {
335
+ "apiUrl": "https://staging-api.example.com",
336
+ "debug": true,
337
+ "logLevel": "info"
338
+ },
339
+ "env:production": {
340
+ "apiUrl": "https://api.example.com",
341
+ "debug": false,
342
+ "logLevel": "error"
343
+ },
344
+ "os:android": {
345
+ "androidSpecificSetting": true
346
+ },
347
+ "os:ios": {
348
+ "iosSpecificSetting": true
349
+ },
350
+ "dependencies": {
351
+ "com.app.loadingOverlay": "1.0"
352
+ },
353
+ "autoStyle": false,
354
+ "backbone": "1.4.0",
355
+ "sourcemap": true
356
+ }
357
+ ```
358
+
359
+ ### Accessing Config Values
360
+ ```javascript
361
+ // In any controller or lib file
362
+ const apiUrl = Alloy.CFG.apiUrl
363
+ const isDebug = Alloy.CFG.debug
364
+ const logLevel = Alloy.CFG.logLevel
365
+
366
+ // Environment check
367
+ if (Alloy.CFG.debug) {
368
+ console.log('Debug mode enabled')
369
+ }
370
+ ```
371
+
372
+ ### Key Configuration Options
373
+
374
+ | Property | Description |
375
+ | -------------- | ------------------------------------------------- |
376
+ | `theme` | Theme folder to use from `app/themes/` |
377
+ | `autoStyle` | Auto-apply TSS styles (set `false` with PurgeTSS) |
378
+ | `backbone` | Backbone.js version to use |
379
+ | `sourcemap` | Generate source maps for debugging |
380
+ | `dependencies` | Widget dependencies and versions |
381
+ | `adaptersPath` | Custom path for sync adapters |
@@ -0,0 +1,133 @@
1
+ # Titanium Alloy + PurgeTSS Anti-Patterns
2
+
3
+ ## 1. Manual Styling (Legacy & Overwrite Risk)
4
+ **Symptom:** Editing `app.tss` manually or using inline attributes like `backgroundColor="#fff"`.
5
+ **Problem:** PurgeTSS will overwrite manual changes in `app.tss`. Inline attributes make theme changes impossible.
6
+ **Solution:** Use **PurgeTSS classes** in XML.
7
+
8
+ ## 2. Fat Controllers
9
+ **Symptom:** Controllers with 100+ lines handling logic, API, and UI.
10
+ **Solution:** Delegate business logic to `lib/services/` and API calls to `lib/api/`.
11
+
12
+ ## 3. Memory Leaks (Missing Cleanup)
13
+ **Symptom:** Adding `Ti.App` or `Alloy.Collections` listeners without a `cleanup()` function.
14
+ **Solution:** Always implement `$.cleanup = cleanup` and remove listeners there.
15
+
16
+ ## 4. Direct Native Module Calls
17
+ **Symptom:** Calling `require('ti.module')` directly in a controller.
18
+ **Solution:** Wrap it in a service in `lib/services/` (e.g., `audioService.js`).
19
+
20
+ ## 5. Direct Controller Navigation
21
+ **Symptom:** `Alloy.createController('name').getView().open()`.
22
+ **Solution:** Use a Navigation Service to centralize `open/close` and trigger the `cleanup()` function automatically.
23
+
24
+ ## 6. Complex Matrix Animations
25
+ **Symptom:** Manual use of `Ti.UI.create2DMatrix()`.
26
+ **Solution:** Use the **PurgeTSS Animation Module** with state modifiers (`class="close:opacity-0 open:opacity-100"`).
27
+
28
+ ## 7. Hardcoded Strings & Missing a11y
29
+ **Symptom:** `text="Login"` instead of `text="L('login')"`, or missing `accessibilityLabel`.
30
+ **Solution:** Always use i18n and accessibility properties.
31
+
32
+ ## 8. Logic in TSS
33
+ **Symptom:** Using conditionals or calculations inside TSS.
34
+ **Solution:** Keep styling declarative through PurgeTSS classes.
35
+
36
+ ---
37
+
38
+ ## PurgeTSS-Specific Anti-Patterns
39
+
40
+ ## 9. Flexbox Classes (Don't Exist)
41
+ **Symptom:** Using `flex-row`, `flex-col`, `justify-between`, `justify-center`, `items-center`.
42
+ **Problem:** Titanium does NOT support CSS Flexbox. These classes don't exist in PurgeTSS.
43
+ **Solution:** Use Titanium layout modes:
44
+ ```xml
45
+ <!-- WRONG -->
46
+ <View class="flex-row justify-between">
47
+
48
+ <!-- CORRECT -->
49
+ <View class="horizontal">
50
+ ```
51
+
52
+ ## 10. Padding on Container Views
53
+ **Symptom:** Using `p-4`, `px-2`, `py-3` on View, Window, ScrollView, or TableView.
54
+ **Problem:** Base container elements don't support padding in Titanium.
55
+ **Solution:** Use margins on children instead:
56
+ ```xml
57
+ <!-- WRONG -->
58
+ <View class="p-4">
59
+ <Label text="Hello" />
60
+ </View>
61
+
62
+ <!-- CORRECT -->
63
+ <View>
64
+ <Label class="m-4" text="Hello" />
65
+ </View>
66
+ ```
67
+
68
+ ## 11. Confusing `w-full` with `w-screen`
69
+ **Symptom:** Using `w-full` when `w-screen` is needed.
70
+ **Difference:** `w-full` sets `width: '100%'` (100% of parent), while `w-screen` sets `width: Ti.UI.FILL` (fills available space).
71
+ **Solution:** Use `w-screen` for full-width elements that should fill space. `w-full` is useful when you need percentage-based sizing.
72
+
73
+ ## 12. Using `rounded-full` Without Size
74
+ **Symptom:** Using `rounded-full` expecting a circle.
75
+ **Problem:** `rounded-full` (without number) doesn't exist. You need `rounded-full-XX` where XX × 4 = element size.
76
+ **Note:** `rounded-full-XX` already includes width and height. Don't add `w-XX h-XX` with it.
77
+ **Solution:** For a 48×48 circle, use `rounded-full-12` (includes size). For percentage-based, use `w-12 h-12 rounded-full`.
78
+
79
+ ## 13. Adding `composite` Class Explicitly
80
+ **Symptom:** Adding `class="composite"` to Views.
81
+ **Problem:** Composite (absolute positioning) is the DEFAULT layout. Adding it is redundant.
82
+ **Solution:** Omit layout class for composite, only use `horizontal` or `vertical` when needed.
83
+
84
+ ## 14. Square Brackets for Arbitrary Values
85
+ **Symptom:** Using `w-[100px]` or `bg-[#ff0000]` with square brackets.
86
+ **Problem:** PurgeTSS uses parentheses, not square brackets.
87
+ **Solution:** Use parentheses: `w-(100px)`, `bg-(#ff0000)`.
88
+
89
+ ## 15. Creating Manual .tss Files Per Controller
90
+ **Symptom:** Creating `app/styles/login.tss`, `app/styles/profile.tss`, etc.
91
+ **Problem:** Defeats the purpose of PurgeTSS which auto-generates a single optimized `app.tss`.
92
+ **Solution:** Use ONLY utility classes in XML. Delete all manual `.tss` files except `_app.tss`.
93
+
94
+ ## 16. Using `lib/` Prefix in Require Statements
95
+ **Symptom:** `const service = require('lib/services/picsum')`
96
+ **Problem:** Alloy flattens the `lib/` folder during build. Files in `app/lib/services/` become `Resources/iphone/services/`.
97
+ **Solution:** Omit the `lib/` prefix: `const service = require('services/picsum')`
98
+
99
+ ## 17. Wrong Window ID in Controller
100
+ **Symptom:** Using `$.index.open()` when the Window has `id="mainWindow"`.
101
+ **Problem:** Alloy generates `$` references from XML IDs. If Window is `id="mainWindow"`, `$.index` doesn't exist.
102
+ **Solution:** Match the ID: `$.mainWindow.open()`
103
+
104
+ ## 18. Using `Ti.UI.createNotification`
105
+ **Symptom:** `Ti.UI.createNotification({ message: 'Hi' }).show()`
106
+ **Problem:** This API doesn't exist in Titanium. Causes "invalid method" error.
107
+ **Solution:** Use `Ti.UI.createAlertDialog` for simple messages, or create custom toast views.
108
+
109
+ ## 19. Using Nonexistent iOS Share APIs
110
+ **Symptom:** `Ti.UI.iOS.createActivityPopover` or `alloy/social` with wrong methods.
111
+ **Problem:** These APIs either don't exist or have changed. Causes runtime errors.
112
+ **Solution:**
113
+ - iOS: Use `Ti.UI.iOS.createDocumentViewer` for files, or simple `Ti.UI.createOptionDialog` + `Ti.UI.Clipboard` for links
114
+ - Android: Use `Ti.Android.createIntent` with ACTION_SEND
115
+
116
+ ---
117
+
118
+ ## Quick Reference Table
119
+
120
+ | Anti-Pattern | Why It Fails | Correct Approach |
121
+ | -------------------- | ------------------------ | ----------------------- |
122
+ | `flex-row` | Flexbox not supported | `horizontal` |
123
+ | `flex-col` | Flexbox not supported | `vertical` |
124
+ | `justify-*` | Flexbox not supported | Use margins/positioning |
125
+ | `p-4` on View | No padding on containers | `m-4` on children |
126
+ | `w-full` | Doesn't exist | `w-screen` |
127
+ | `rounded-full` | Needs size suffix | `rounded-full-12` |
128
+ | `composite` class | Already default | Omit it |
129
+ | `w-[100px]` | Wrong syntax | `w-(100px)` |
130
+ | Manual `.tss` | Overwritten by PurgeTSS | Use utility classes |
131
+ | `lib/` prefix | lib/ is flattened | Use path without lib/ |
132
+ | `$.index.open()` | Wrong ID reference | Use actual Window ID |
133
+ | `createNotification` | API doesn't exist | `createAlertDialog` |