@maccesar/titools 2.0.7 → 2.2.1

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 (133) hide show
  1. package/AGENTS-VERCEL-RESEARCH.md +172 -0
  2. package/README.md +408 -389
  3. package/agents/{ti-researcher.md → ti-pro.md} +14 -13
  4. package/bin/titools.js +16 -12
  5. package/lib/cleanup.js +95 -0
  6. package/lib/commands/agents.js +146 -70
  7. package/lib/commands/skills.js +349 -0
  8. package/lib/commands/uninstall.js +189 -154
  9. package/lib/commands/update.js +104 -21
  10. package/lib/config.js +26 -20
  11. package/lib/downloader.js +1 -1
  12. package/lib/installer.js +37 -97
  13. package/lib/platform.js +9 -5
  14. package/lib/prompts/checkboxCancel.js +264 -0
  15. package/lib/prompts/selectCancel.js +204 -0
  16. package/lib/symlink.js +19 -7
  17. package/lib/utils.js +17 -17
  18. package/package.json +10 -10
  19. package/skills/alloy-guides/SKILL.md +8 -30
  20. package/skills/alloy-guides/references/CLI_TASKS.md +14 -24
  21. package/skills/alloy-guides/references/CONCEPTS.md +5 -25
  22. package/skills/alloy-guides/references/CONTROLLERS.md +2 -19
  23. package/skills/alloy-guides/references/MODELS.md +40 -10
  24. package/skills/alloy-guides/references/PURGETSS.md +1 -11
  25. package/skills/alloy-guides/references/VIEWS_DYNAMIC.md +8 -14
  26. package/skills/alloy-guides/references/VIEWS_STYLES.md +14 -25
  27. package/skills/alloy-guides/references/VIEWS_WITHOUT_CONTROLLERS.md +2 -8
  28. package/skills/alloy-guides/references/VIEWS_XML.md +29 -40
  29. package/skills/alloy-guides/references/WIDGETS.md +1 -17
  30. package/skills/alloy-howtos/SKILL.md +1 -22
  31. package/skills/alloy-howtos/references/best_practices.md +0 -17
  32. package/skills/alloy-howtos/references/cli_reference.md +1 -23
  33. package/skills/alloy-howtos/references/config_files.md +86 -15
  34. package/skills/alloy-howtos/references/custom_tags.md +14 -13
  35. package/skills/alloy-howtos/references/debugging_troubleshooting.md +3 -22
  36. package/skills/alloy-howtos/references/samples.md +4 -14
  37. package/skills/purgetss/SKILL.md +11 -37
  38. package/skills/purgetss/references/EXAMPLES.md +106 -17
  39. package/skills/purgetss/references/animation-system.md +0 -67
  40. package/skills/purgetss/references/apply-directive.md +0 -18
  41. package/skills/purgetss/references/arbitrary-values.md +0 -25
  42. package/skills/purgetss/references/class-index.md +0 -46
  43. package/skills/purgetss/references/cli-commands.md +0 -41
  44. package/skills/purgetss/references/configurable-properties.md +0 -55
  45. package/skills/purgetss/references/custom-rules.md +0 -14
  46. package/skills/purgetss/references/customization-deep-dive.md +0 -49
  47. package/skills/purgetss/references/dynamic-component-creation.md +56 -37
  48. package/skills/purgetss/references/grid-layout.md +0 -32
  49. package/skills/purgetss/references/icon-fonts.md +0 -50
  50. package/skills/purgetss/references/installation-setup.md +61 -32
  51. package/skills/purgetss/references/migration-guide.md +127 -0
  52. package/skills/purgetss/references/opacity-modifier.md +0 -34
  53. package/skills/purgetss/references/performance-tips.md +261 -0
  54. package/skills/purgetss/references/platform-modifiers.md +0 -46
  55. package/skills/purgetss/references/smart-mappings.md +0 -12
  56. package/skills/purgetss/references/tikit-components.md +393 -0
  57. package/skills/purgetss/references/titanium-resets.md +1 -27
  58. package/skills/purgetss/references/ui-ux-design.md +467 -117
  59. package/skills/{alloy-expert → ti-expert}/SKILL.md +45 -54
  60. package/skills/ti-expert/references/alloy-builtins.md +387 -0
  61. package/skills/{alloy-expert → ti-expert}/references/alloy-structure.md +147 -40
  62. package/skills/ti-expert/references/anti-patterns.md +90 -0
  63. package/skills/ti-expert/references/cli-expert.md +109 -0
  64. package/skills/{alloy-expert → ti-expert}/references/code-conventions.md +182 -49
  65. package/skills/{alloy-expert → ti-expert}/references/controller-patterns.md +103 -93
  66. package/skills/{alloy-expert → ti-expert}/references/error-handling.md +12 -12
  67. package/skills/{alloy-expert → ti-expert}/references/examples.md +144 -85
  68. package/skills/{alloy-expert → ti-expert}/references/migration-patterns.md +38 -36
  69. package/skills/{alloy-expert → ti-expert}/references/patterns.md +8 -8
  70. package/skills/ti-expert/references/performance-listview.md +251 -0
  71. package/skills/{alloy-expert/references/performance-patterns.md → ti-expert/references/performance-optimization.md} +67 -283
  72. package/skills/{alloy-expert/references/security-patterns.md → ti-expert/references/security-device.md} +12 -295
  73. package/skills/ti-expert/references/security-fundamentals.md +284 -0
  74. package/skills/{alloy-expert → ti-expert}/references/state-management.md +10 -10
  75. package/skills/ti-expert/references/testing-e2e-ci.md +432 -0
  76. package/skills/ti-expert/references/testing-unit.md +433 -0
  77. package/skills/ti-expert/references/theming.md +394 -0
  78. package/skills/ti-guides/SKILL.md +1 -14
  79. package/skills/ti-guides/references/advanced-data-and-images.md +126 -10
  80. package/skills/ti-guides/references/app-distribution.md +48 -10
  81. package/skills/ti-guides/references/application-frameworks.md +9 -2
  82. package/skills/ti-guides/references/cli-reference.md +338 -82
  83. package/skills/ti-guides/references/coding-best-practices.md +14 -4
  84. package/skills/ti-guides/references/commonjs-advanced.md +103 -6
  85. package/skills/ti-guides/references/hello-world.md +5 -2
  86. package/skills/ti-guides/references/hyperloop-native-access.md +439 -46
  87. package/skills/ti-guides/references/javascript-primer.md +4 -3
  88. package/skills/ti-guides/references/resources.md +0 -1
  89. package/skills/ti-guides/references/style-and-conventions.md +57 -9
  90. package/skills/ti-guides/references/tiapp-config.md +48 -6
  91. package/skills/ti-howtos/SKILL.md +2 -27
  92. package/skills/ti-howtos/references/android-platform-deep-dives.md +41 -90
  93. package/skills/ti-howtos/references/automation-fastlane-appium.md +15 -14
  94. package/skills/ti-howtos/references/buffer-codec-streams.md +22 -22
  95. package/skills/ti-howtos/references/cross-platform-development.md +68 -37
  96. package/skills/ti-howtos/references/debugging-profiling.md +8 -53
  97. package/skills/ti-howtos/references/extending-titanium.md +12 -51
  98. package/skills/ti-howtos/references/google-maps-v2.md +30 -29
  99. package/skills/ti-howtos/references/ios-map-kit.md +19 -25
  100. package/skills/ti-howtos/references/ios-platform-deep-dives.md +95 -283
  101. package/skills/ti-howtos/references/local-data-sources.md +45 -37
  102. package/skills/ti-howtos/references/location-and-maps.md +47 -28
  103. package/skills/ti-howtos/references/media-apis.md +84 -27
  104. package/skills/ti-howtos/references/notification-services.md +40 -89
  105. package/skills/ti-howtos/references/remote-data-sources.md +21 -36
  106. package/skills/ti-howtos/references/tutorials.md +79 -39
  107. package/skills/ti-howtos/references/using-modules.md +4 -30
  108. package/skills/ti-howtos/references/web-content-integration.md +28 -45
  109. package/skills/ti-howtos/references/webpack-build-pipeline.md +54 -18
  110. package/skills/ti-ui/SKILL.md +1 -21
  111. package/skills/ti-ui/references/accessibility-deep-dive.md +71 -25
  112. package/skills/ti-ui/references/animation-and-matrices.md +0 -47
  113. package/skills/ti-ui/references/application-structures.md +0 -46
  114. package/skills/ti-ui/references/custom-fonts-styling.md +9 -57
  115. package/skills/ti-ui/references/event-handling.md +32 -40
  116. package/skills/ti-ui/references/gestures.md +0 -40
  117. package/skills/ti-ui/references/icons-and-splash-screens.md +21 -44
  118. package/skills/ti-ui/references/layouts-and-positioning.md +47 -39
  119. package/skills/ti-ui/references/listviews-and-performance.md +187 -73
  120. package/skills/ti-ui/references/orientation.md +57 -71
  121. package/skills/ti-ui/references/platform-ui-android.md +114 -48
  122. package/skills/ti-ui/references/platform-ui-ios.md +63 -38
  123. package/skills/ti-ui/references/scrolling-views.md +14 -23
  124. package/skills/ti-ui/references/tableviews.md +6 -56
  125. package/AGENTS-TEMPLATE.md +0 -174
  126. package/lib/commands/install.js +0 -188
  127. package/skills/alloy-expert/references/anti-patterns.md +0 -133
  128. package/skills/alloy-expert/references/testing.md +0 -872
  129. package/skills/ti-guides/references/alloy-cli-advanced.md +0 -84
  130. package/skills/ti-guides/references/alloy-data-mastery.md +0 -29
  131. package/skills/ti-guides/references/alloy-widgets-and-themes.md +0 -19
  132. /package/skills/{alloy-expert → ti-expert}/assets/ControllerAutoCleanup.js +0 -0
  133. /package/skills/{alloy-expert → ti-expert}/references/contracts.md +0 -0
@@ -1,4 +1,4 @@
1
- # Alloy MVC + PurgeTSS Structure Reference
1
+ # Alloy MVC Structure Reference
2
2
 
3
3
  ## Standard Project Structure
4
4
 
@@ -10,34 +10,29 @@ app/
10
10
  │ └── list.js # Controller for list view
11
11
  ├── models/ # OPTIONAL: For persistence with migrations
12
12
  │ └── user.js # Model definition (ONLY if using SQLite)
13
- ├── views/ # XML views styled with PurgeTSS
13
+ ├── views/ # XML views
14
14
  │ ├── index.xml
15
15
  │ └── feature/
16
- ├── list.xml # View definition (Utility classes here)
16
+ └── list.xml # View definition
17
+ ├── styles/ # TSS styles (one per view + global)
18
+ │ ├── app.tss # Global application styles
19
+ │ ├── index.tss # Styles for index view
20
+ │ └── feature/
21
+ │ └── list.tss # Styles for feature/list view
17
22
  ├── lib/ # Reusable logic (no UI)
18
23
  │ ├── api/
19
24
  │ │ └── client.js # API calls
20
25
  │ ├── services/
21
26
  │ │ ├── auth.js # Business logic services
22
27
  │ │ ├── navigation.js # Navigation orchestration
23
- │ │ ├── nativeService.js # Native module wrapper (e.g. Audio, FB, Maps)
24
- │ │ └── purgetss.animation.js # PurgeTSS Animation module
28
+ │ │ └── nativeService.js # Native module wrapper (e.g. Audio, FB, Maps)
25
29
  │ └── helpers/
26
30
  │ ├── utils.js # Pure utility functions
27
31
  │ └── i18n.js # Complex string transformations
28
32
  ├── widgets/ # Truly reusable components (used in 3+ places)
29
33
  │ └── 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
34
  ├── config.json # Alloy configuration
35
35
  └── alloy.js # Collections & Global services
36
-
37
- ./purgetss/
38
- ├── config.cjs # PurgeTSS theme configuration
39
- └── styles/
40
- └── utilities.tss # All utility classes
41
36
  ```
42
37
 
43
38
  ## lib/ Folder and Module Require Paths
@@ -145,14 +140,14 @@ api.getFrames()
145
140
  ## Controller Rules
146
141
 
147
142
  **DO:**
148
- - Use **PurgeTSS classes** in XML for 100% of the styling.
143
+ - Define styles in TSS files (per-controller + `app.tss` for global).
149
144
  - Orchestrate view and model/collection interactions.
150
145
  - Handle UI events and delegate to services.
151
146
  - Format data for display (simple cases).
152
147
  - Manage view lifecycle (including cleanup).
153
148
 
154
149
  **DON'T:**
155
- - Create per-controller `.tss` files (Use PurgeTSS utility classes).
150
+ - Use inline style attributes in XML (define in TSS files).
156
151
  - Make direct API calls (use lib/api/ or lib/services/).
157
152
  - Contain heavy business logic.
158
153
  - Call native modules directly (use a service wrapper).
@@ -197,7 +192,7 @@ See [ControllerAutoCleanup.js](../assets/ControllerAutoCleanup.js) for the compl
197
192
  - All static text must use `L('key')`.
198
193
  - All interactive elements must have `accessibilityLabel`.
199
194
  - 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.
195
+ - Use **TSS platform modifiers** (`[platform=ios]`, `[platform=android]`) for platform-specific design instead of conditional code.
201
196
 
202
197
  ## Widget Structure
203
198
 
@@ -211,7 +206,7 @@ app/widgets/
211
206
  ├── views/
212
207
  │ └── widget.xml # Main widget view
213
208
  ├── styles/
214
- │ └── widget.tss # Widget-specific styles (optional with PurgeTSS)
209
+ │ └── widget.tss # Widget-specific styles
215
210
  └── widget.json # Widget manifest
216
211
  ```
217
212
 
@@ -235,15 +230,23 @@ app/widgets/
235
230
  ### Widget View (widget.xml)
236
231
  ```xml
237
232
  <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" />
233
+ <View id="container">
234
+ <View id="box">
235
+ <ActivityIndicator id="spinner" />
236
+ <Label id="messageLabel" />
242
237
  </View>
243
238
  </View>
244
239
  </Alloy>
245
240
  ```
246
241
 
242
+ ```tss
243
+ /* styles/widget.tss */
244
+ "#container": { width: Ti.UI.FILL, height: Ti.UI.FILL, visible: false, backgroundColor: 'rgba(0,0,0,0.5)' }
245
+ "#box": { width: 128, height: 128, layout: 'vertical', borderRadius: 16, backgroundColor: '#fff' }
246
+ "#spinner": { top: 24 }
247
+ "#messageLabel": { left: 16, right: 16, top: 16, font: { fontSize: 14 }, color: '#4b5563' }
248
+ ```
249
+
247
250
  ### Widget Controller (widget.js)
248
251
  ```javascript
249
252
  // Widget controller receives args via $.args
@@ -300,22 +303,126 @@ const loadData = () => {
300
303
  }
301
304
  ```
302
305
 
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`:
306
+ :::tip Widget Styles
307
+ Widgets have their own `styles/widget.tss` file. Define all widget-specific styles there to keep them self-contained and portable.
308
+ :::
309
+
310
+ ### Widget ↔ Controller Communication
311
+
312
+ **Pattern 1: Public methods on $**
313
+
314
+ The widget exposes methods directly on `$`:
305
315
 
306
316
  ```javascript
307
- // ./purgetss/config.cjs
308
- module.exports = {
309
- purge: {
310
- options: {
311
- widgets: true // Enable PurgeTSS class processing for widgets
312
- }
317
+ // widgets/loadingOverlay/controllers/widget.js
318
+ $.show = (msg) => { /* ... */ }
319
+ $.hide = () => { /* ... */ }
320
+
321
+ // Parent controller
322
+ $.loader.show(L('loading'))
323
+ $.loader.hide()
324
+ ```
325
+
326
+ **Pattern 2: Callbacks via $.args**
327
+
328
+ Pass functions as arguments for child → parent communication:
329
+
330
+ ```xml
331
+ <!-- Parent view -->
332
+ <Widget id="picker" src="datePicker" />
333
+ ```
334
+
335
+ ```javascript
336
+ // Parent controller - pass callback after creation
337
+ $.picker.onDateSelected = (date) => {
338
+ $.dateLabel.text = formatDate(date)
339
+ }
340
+
341
+ // Widget controller
342
+ function handleSelection(e) {
343
+ if ($.args.onDateSelected) {
344
+ $.args.onDateSelected(e.value)
345
+ }
346
+ // Or if set as property:
347
+ if ($._onDateSelected) {
348
+ $._onDateSelected(e.value)
313
349
  }
314
350
  }
315
351
  ```
316
352
 
317
- Without this setting, PurgeTSS will NOT process classes in widget files.
318
- :::
353
+ **Pattern 3: Backbone Events (for complex communication)**
354
+
355
+ ```javascript
356
+ // Widget controller (emits events)
357
+ $.trigger('item:selected', { item: selectedItem })
358
+ $.trigger('search:changed', { query: text })
359
+
360
+ // Parent controller (listens)
361
+ $.searchWidget.on('search:changed', (data) => {
362
+ filterResults(data.query)
363
+ })
364
+
365
+ // Cleanup in parent
366
+ function cleanup() {
367
+ $.searchWidget.off('search:changed')
368
+ $.destroy()
369
+ }
370
+ ```
371
+
372
+ ### Widget with Internal State
373
+
374
+ ```javascript
375
+ // widgets/counter/controllers/widget.js
376
+ let count = parseInt($.args.initial || '0', 10)
377
+
378
+ function render() {
379
+ $.countLabel.text = String(count)
380
+ $.decrementBtn.enabled = count > 0
381
+ }
382
+
383
+ $.increment = () => {
384
+ count++
385
+ render()
386
+ $.trigger('change', { value: count })
387
+ }
388
+
389
+ $.decrement = () => {
390
+ if (count > 0) {
391
+ count--
392
+ render()
393
+ $.trigger('change', { value: count })
394
+ }
395
+ }
396
+
397
+ $.getValue = () => count
398
+
399
+ $.setValue = (val) => {
400
+ count = val
401
+ render()
402
+ }
403
+
404
+ // Expose for click handlers in XML
405
+ $.incrementBtn.addEventListener('click', $.increment)
406
+ $.decrementBtn.addEventListener('click', $.decrement)
407
+
408
+ $.cleanup = () => {
409
+ $.incrementBtn.removeEventListener('click', $.increment)
410
+ $.decrementBtn.removeEventListener('click', $.decrement)
411
+ $.destroy()
412
+ }
413
+
414
+ render()
415
+ ```
416
+
417
+ ### When to Use Widget vs Require
418
+
419
+ | Use `<Widget>` when | Use `<Require>` when |
420
+ | ------------------------------------- | ------------------------------- |
421
+ | Component is used in 3+ places | Component is used in 1-2 places |
422
+ | Needs its own self-contained styles | Shares styles with parent |
423
+ | Has public API (show/hide/setValue) | Just renders, no API needed |
424
+ | Could be extracted to another project | Specific to this app |
425
+ | Needs its own `widget.json` manifest | Lightweight, no manifest needed |
319
426
 
320
427
  ## config.json Reference
321
428
 
@@ -371,11 +478,11 @@ if (Alloy.CFG.debug) {
371
478
 
372
479
  ### Key Configuration Options
373
480
 
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 |
481
+ | Property | Description |
482
+ | -------------- | ----------------------------------------- |
483
+ | `theme` | Theme folder to use from `app/themes/` |
484
+ | `autoStyle` | Auto-apply TSS styles by element ID/class |
485
+ | `backbone` | Backbone.js version to use |
486
+ | `sourcemap` | Generate source maps for debugging |
487
+ | `dependencies` | Widget dependencies and versions |
488
+ | `adaptersPath` | Custom path for sync adapters |
@@ -0,0 +1,90 @@
1
+ # Titanium Alloy Anti-Patterns
2
+
3
+ ## 1. Inline Styling Instead of TSS
4
+ **Symptom:** Using inline attributes like `backgroundColor="#fff"` directly in XML views.
5
+ **Problem:** Inline attributes make theme changes impossible and scatter visual definitions across views.
6
+ **Solution:** Define styles in TSS files using IDs or class selectors.
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()` for simple animations.
26
+ **Solution:** Use `Ti.UI.createAnimation()` for opacity, transform, and duration-based animations. Reserve 2D Matrix for complex multi-property transforms.
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 in TSS files.
35
+
36
+ ---
37
+
38
+ ## Titanium Layout Anti-Patterns
39
+
40
+ ## 9. Padding on Container Views
41
+ **Symptom:** Setting `padding` on View, Window, ScrollView, or TableView.
42
+ **Problem:** Base container elements don't support padding in Titanium.
43
+ **Solution:** Use margins on children instead:
44
+ ```tss
45
+ /* WRONG */
46
+ "#container": { padding: 16 }
47
+
48
+ /* CORRECT - margin on children */
49
+ "#childLabel": { left: 16, top: 16, right: 16 }
50
+ ```
51
+
52
+ ## 10. Redundant Composite Layout
53
+ **Symptom:** Adding `layout: 'composite'` to Views.
54
+ **Problem:** Composite (absolute positioning) is the DEFAULT layout. Setting it is redundant.
55
+ **Solution:** Omit `layout` for composite, only specify `layout: 'horizontal'` or `layout: 'vertical'` when needed.
56
+
57
+ ## 11. Using `lib/` Prefix in Require Statements
58
+ **Symptom:** `const service = require('lib/services/picsum')`
59
+ **Problem:** Alloy flattens the `lib/` folder during build. Files in `app/lib/services/` become `Resources/iphone/services/`.
60
+ **Solution:** Omit the `lib/` prefix: `const service = require('services/picsum')`
61
+
62
+ ## 12. Wrong Window ID in Controller
63
+ **Symptom:** Using `$.index.open()` when the Window has `id="mainWindow"`.
64
+ **Problem:** Alloy generates `$` references from XML IDs. If Window is `id="mainWindow"`, `$.index` doesn't exist.
65
+ **Solution:** Match the ID: `$.mainWindow.open()`
66
+
67
+ ## 13. Using `Ti.UI.createNotification`
68
+ **Symptom:** `Ti.UI.createNotification({ message: 'Hi' }).show()`
69
+ **Problem:** This API doesn't exist in Titanium. Causes "invalid method" error.
70
+ **Solution:** Use `Ti.UI.createAlertDialog` for simple messages, or create custom toast views.
71
+
72
+ ## 14. Using Nonexistent iOS Share APIs
73
+ **Symptom:** `Ti.UI.iOS.createActivityPopover` or `alloy/social` with wrong methods.
74
+ **Problem:** These APIs either don't exist or have changed. Causes runtime errors.
75
+ **Solution:**
76
+ - iOS: Use `Ti.UI.iOS.createDocumentViewer` for files, or simple `Ti.UI.createOptionDialog` + `Ti.UI.Clipboard` for links
77
+ - Android: Use `Ti.Android.createIntent` with ACTION_SEND
78
+
79
+ ---
80
+
81
+ ## Quick Reference Table
82
+
83
+ | Anti-Pattern | Why It Fails | Correct Approach |
84
+ | ----------------------- | ------------------------ | --------------------- |
85
+ | `padding` on View | No padding on containers | Margins on children |
86
+ | `layout: 'composite'` | Already default | Omit it |
87
+ | Inline style attributes | Scattered styling | Define in TSS files |
88
+ | `lib/` prefix | lib/ is flattened | Use path without lib/ |
89
+ | `$.index.open()` | Wrong ID reference | Use actual Window ID |
90
+ | `createNotification` | API doesn't exist | `createAlertDialog` |
@@ -0,0 +1,109 @@
1
+ # CLI Expert Strategies & TiNy
2
+
3
+ Mastering the command line is essential for a Titanium expert. This guide covers advanced workflows, optimization techniques, and the use of **TiNy (`tn`)** for efficient development.
4
+
5
+ ## The Expert Workflow
6
+
7
+ An expert doesn't just run `ti build`. They optimize for speed, reliability, and automation.
8
+
9
+ ### 1. The "Inner Loop" Optimization
10
+ Reduce the time between writing code and seeing it on the device.
11
+
12
+ - **LiveView**: Use `--liveview` for near-instant UI updates without full recompilation.
13
+ ```bash
14
+ ti build -p ios --liveview
15
+ ```
16
+ - **Build Only**: Use `-b` to verify Alloy compilation and JavaScript syntax without launching the simulator.
17
+ ```bash
18
+ ti build -p ios -b
19
+ ```
20
+ - **Skip Minification**: In development, always skip minification to speed up the build process.
21
+ ```bash
22
+ ti build -p ios --skip-js-minify
23
+ ```
24
+
25
+ ### 2. Precise Cleaning
26
+ Don't use `ti clean` as a first resort (it's slow).
27
+ - **Targeted Clean**: If Alloy isn't reflecting changes, try deleting `Resources/` and `build/` manually or use `ti clean -p <platform>`.
28
+ - **Pre-Production**: Always run a full `ti clean` before a production/App Store build to ensure no stale assets are included.
29
+
30
+ ### 3. Advanced Debugging
31
+ - **Trace Logging**: Use `--log-level trace` when a build fails for mysterious reasons (e.g., a broken hook or native module issue).
32
+ - **Build Logs**: Check `build/build.log` for the full output of the last build process.
33
+
34
+ ---
35
+
36
+ ## TiNy (`tn`): The Expert's Power Tool
37
+
38
+ **TiNy** is a modern CLI wrapper for Titanium SDK that drastically reduces keystrokes and manages complex build configurations through "recipes".
39
+
40
+ ### Why Experts Use TiNy
41
+ - **Speed**: `tn ios` vs `ti build -p ios -T simulator`.
42
+ - **Consistency**: Recipes ensure every team member builds with the same flags.
43
+ - **Device Management**: Easily target specific simulators/emulators by name.
44
+
45
+ ### Quick Start
46
+ 1. **Install**: `npm install -g tn`
47
+ 2. **Repo**: https://github.com/jasonkneen/tn
48
+ 3. **Generate Recipes**: Detect all connected devices/simulators.
49
+ ```bash
50
+ tn generate
51
+ ```
52
+ 4. **Build**:
53
+ ```bash
54
+ tn iphone-16-pro
55
+ tn pixel-8-pro-api-34
56
+ ```
57
+
58
+ ### Expert Recipes
59
+ Recipes can be flags or options. Multiple recipes can be combined.
60
+
61
+ | Command | Expansion |
62
+ | -------------- | ----------------------------------- |
63
+ | `tn ios` | `--platform ios` |
64
+ | `tn android` | `--platform android` |
65
+ | `tn appstore` | `--ios --target dist-appstore` |
66
+ | `tn playstore` | `--android --target dist-playstore` |
67
+ | `tn watch` | `--ios --launch-watch-app` |
68
+
69
+ ### Customizing Your Workflow
70
+ - **Save Global Recipe**:
71
+ ```bash
72
+ tn save my-debug --ios --simulator --log-level trace --skip-js-minify
73
+ ```
74
+ - **Project-Specific Recipes**: Save a `tn.json` in your project root for team-wide recipes (e.g., specific provisioning profiles).
75
+ ```bash
76
+ tn project save release --playstore --keystore ./android/release.keystore
77
+ ```
78
+
79
+ ### Composition & Placeholders
80
+ You can use `%s` as a placeholder in recipes for values:
81
+ ```bash
82
+ tn save ci -b --pp-uuid <UUID> --distribution-name "<NAME>" --ah --installr --installr-release-notes %s
83
+
84
+ # Usage:
85
+ tn ci "Fixed login bug"
86
+ ```
87
+
88
+ ---
89
+
90
+ ## Automation Integration
91
+
92
+ Experts automate their builds using `package.json` scripts, often combining `ti` or `tn` with other tools.
93
+
94
+ ```json
95
+ "scripts": {
96
+ "start": "tn ios --liveview",
97
+ "build:android": "tn android",
98
+ "clean": "ti clean",
99
+ "prod:ios": "tn appstore --distribution-name 'My Company'",
100
+ "lint": "eslint app/"
101
+ }
102
+ ```
103
+
104
+ ---
105
+
106
+ ## Pro-Tips
107
+ - **SDK Switching**: Use `-s <version>` to test your app against a specific SDK version without changing your global default.
108
+ - **Sim Focus**: Use `--no-sim-focus` if you want to keep your editor in focus while the simulator launches in the background.
109
+ - **Concurrent Builds**: You can often build for iOS and Android simultaneously in different terminal tabs if your machine has the resources.