@maccesar/titools 2.0.7 → 2.2.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 (132) hide show
  1. package/{AGENTS-TEMPLATE.md → AGENTS-VERCEL-RESEARCH.md} +16 -18
  2. package/README.md +250 -168
  3. package/agents/{ti-researcher.md → ti-pro.md} +10 -10
  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/lib/commands/install.js +0 -188
  126. package/skills/alloy-expert/references/anti-patterns.md +0 -133
  127. package/skills/alloy-expert/references/testing.md +0 -872
  128. package/skills/ti-guides/references/alloy-cli-advanced.md +0 -84
  129. package/skills/ti-guides/references/alloy-data-mastery.md +0 -29
  130. package/skills/ti-guides/references/alloy-widgets-and-themes.md +0 -19
  131. /package/skills/{alloy-expert → ti-expert}/assets/ControllerAutoCleanup.js +0 -0
  132. /package/skills/{alloy-expert → ti-expert}/references/contracts.md +0 -0
@@ -1,13 +1,13 @@
1
1
  ---
2
- name: alloy-expert
3
- description: "Titanium Alloy architecture and implementation expert. Use when designing, reviewing, analyzing, or examining Alloy project structure, creating controllers/views/services, choosing models vs collections, implementing communication patterns, handling memory cleanup, testing, auditing code, or migrating legacy apps. Detects Alloy vs Classic projects automatically."
2
+ name: ti-expert
3
+ description: "Titanium SDK architecture and implementation expert. Use when designing, reviewing, analyzing, or examining Titanium project structure (Alloy or Classic), creating controllers/views/services, choosing models vs collections, implementing communication patterns, handling memory cleanup, testing, auditing code, or migrating legacy apps. Automatically identifies project type."
4
4
  argument-hint: "[architecture-topic]"
5
5
  allowed-tools: Read, Grep, Glob, Edit, Write, Bash(git *), Bash(node *)
6
6
  ---
7
7
 
8
- # Titanium Alloy Expert
8
+ # Titanium Expert
9
9
 
10
- Complete architectural and implementation guidance for building scalable, maintainable Titanium Alloy applications with PurgeTSS styling.
10
+ Complete architectural and implementation guidance for building scalable, maintainable Titanium SDK applications (Alloy & Classic).
11
11
 
12
12
  ## Project Detection
13
13
 
@@ -31,28 +31,6 @@ This skill automatically detects project type when invoked and provides appropri
31
31
  - **Unknown** → Asks user to clarify project type
32
32
  :::
33
33
 
34
- ## Table of Contents
35
-
36
- - [Titanium Alloy Expert](#titanium-alloy-expert)
37
- - [Project Detection](#project-detection)
38
- - [Table of Contents](#table-of-contents)
39
- - [Workflow](#workflow)
40
- - [Quick Start Example](#quick-start-example)
41
- - [Code Standards (Low Freedom)](#code-standards-low-freedom)
42
- - [PurgeTSS Rules (Low Freedom)](#purgetss-rules-low-freedom)
43
- - [Quick Decision Matrix](#quick-decision-matrix)
44
- - [Reference Guides (Progressive Disclosure)](#reference-guides-progressive-disclosure)
45
- - [Architecture](#architecture)
46
- - [Implementation](#implementation)
47
- - [Quality \& Reliability](#quality--reliability)
48
- - [Performance \& Security](#performance--security)
49
- - [Migration](#migration)
50
- - [Specialized Titanium Skills](#specialized-titanium-skills)
51
- - [Guiding Principles](#guiding-principles)
52
- - [Response Format](#response-format)
53
-
54
- ---
55
-
56
34
  ## Workflow
57
35
 
58
36
  1. **Architecture**: Define structure (`lib/api`, `lib/services`, `lib/helpers`)
@@ -69,12 +47,12 @@ Minimal example following all conventions:
69
47
  **View (views/user/card.xml)**
70
48
  ```xml
71
49
  <Alloy>
72
- <View class="m-2 rounded-xl bg-white shadow-md">
73
- <View class="horizontal m-3 w-screen">
74
- <Label class="fa-solid fa-user text-2xl text-blue-500" />
75
- <Label id="name" class="ml-3 text-lg font-bold" />
50
+ <View id="cardContainer">
51
+ <View id="headerRow">
52
+ <ImageView id="userIcon" image="/images/user.png" />
53
+ <Label id="name" />
76
54
  </View>
77
- <Button class="mx-3 mb-3 h-10 w-screen rounded-md bg-blue-600 text-white"
55
+ <Button id="viewProfileBtn"
78
56
  title="L('view_profile')"
79
57
  onClick="onViewProfile"
80
58
  />
@@ -82,9 +60,18 @@ Minimal example following all conventions:
82
60
  </Alloy>
83
61
  ```
84
62
 
63
+ **Styles (styles/user/card.tss)**
64
+ ```tss
65
+ "#cardContainer": { left: 8, right: 8, top: 8, height: Ti.UI.SIZE, borderRadius: 12, backgroundColor: '#fff' }
66
+ "#headerRow": { layout: 'horizontal', left: 12, right: 12, top: 12, height: Ti.UI.SIZE, width: Ti.UI.FILL }
67
+ "#userIcon": { width: 32, height: 32 }
68
+ "#name": { left: 12, font: { fontSize: 18, fontWeight: 'bold' } }
69
+ "#viewProfileBtn": { left: 12, right: 12, bottom: 12, height: 40, width: Ti.UI.FILL, borderRadius: 6, backgroundColor: '#2563eb', color: '#fff' }
70
+ ```
71
+
85
72
  **Controller (controllers/user/card.js)**
86
73
  ```javascript
87
- const { Navigation } = require('lib/services/navigation')
74
+ const { Navigation } = require('services/navigation')
88
75
 
89
76
  function init() {
90
77
  const user = $.args.user
@@ -128,7 +115,7 @@ exports.Navigation = {
128
115
  - **ERROR HANDLING**: Use AppError classes, log with context, never swallow errors
129
116
  - **TESTABLE**: Inject dependencies, avoid hard coupling
130
117
 
131
- ## PurgeTSS Rules (Low Freedom)
118
+ ## Titanium Style Sheets Rules (Low Freedom)
132
119
 
133
120
  :::danger CRITICAL: Platform-Specific Properties Require Modifiers
134
121
  Using `Ti.UI.iOS.*` or `Ti.UI.Android.*` properties WITHOUT platform modifiers causes cross-platform compilation failures.
@@ -155,58 +142,63 @@ Using `Ti.UI.iOS.*` or `Ti.UI.Android.*` properties WITHOUT platform modifiers c
155
142
 
156
143
  **Available modifiers:** `[platform=ios]`, `[platform=android]`, `[formFactor=handheld]`, `[formFactor=tablet]`, `[if=Alloy.Globals.customVar]`
157
144
 
158
- **For more platform-specific patterns, see** [Platform Modifiers (purgetss)](skills/purgetss/references/platform-modifiers.md) or [Platform UI guides (ti-ui)](skills/ti-ui/references/platform-ui-ios.md).
145
+ **For more platform-specific patterns, see the `ti-ui` skill.**
159
146
  :::
160
147
 
161
- | WRONG | CORRECT | Why |
162
- | ------------------------------ | ------------------- | ----------------------------- |
163
- | `flex-row` | `horizontal` | Flexbox not supported |
164
- | `flex-col` | `vertical` | Flexbox not supported |
165
- | `p-4` on View | `m-4` on children | No padding on containers |
166
- | `justify-*` | margins/positioning | Flexbox not supported |
167
- | `items-center` (for centering) | layout + sizing | Different meaning in Titanium |
168
- | `rounded-full` (for circle) | `rounded-full-12` | Need size suffix (12×4=48px) |
169
- | `border-[1px]` | `border-(1)` | Parentheses, not brackets |
148
+ **Titanium layout system:**
149
+ - Three layout modes: `layout: 'horizontal'`, `layout: 'vertical'`, and composite (default — no `layout` needed)
150
+ - No padding on container Views — use margins on children instead
151
+ - `width: Ti.UI.FILL` fills available space (preferred), `width: '100%'` = 100% of parent
152
+ - `height: Ti.UI.SIZE` wraps content, `height: Ti.UI.FILL` fills available space
153
+
154
+ ## Alloy Builtins Quick Reference
155
+
156
+ Key builtins: `OS_IOS`/`OS_ANDROID` (compile-time), `Alloy.CFG` (config.json), `Alloy.Globals` (shared state), `$.args` (controller params), `$.destroy()` (cleanup bindings), `platform="ios"` / `formFactor="tablet"` (XML conditionals).
170
157
 
171
- **Note on `w-full` vs `w-screen`:**
172
- - `w-full` → `width: '100%'` (100% of parent container) - exists and valid
173
- - `w-screen` → `width: Ti.UI.FILL` (fills all available space) - use for full-width elements
158
+ For the complete reference with examples, see **[Alloy Builtins & Globals](references/alloy-builtins.md)**.
174
159
 
175
160
  ## Quick Decision Matrix
176
161
 
177
162
  | Question | Answer |
178
163
  | ---------------------------------- | -------------------------------------------------------------- |
179
164
  | How to create a new Alloy project? | **`ti create -t app --alloy`** (not `--classic` + `alloy new`) |
165
+ | Fastest way to build? | **`tn <recipe>`** (using TiNy CLI wrapper) |
180
166
  | Where does API call go? | `lib/api/` |
181
167
  | Where does business logic go? | `lib/services/` |
182
168
  | Where do I store auth tokens? | Keychain (iOS) / KeyStore (Android) via service |
183
169
  | Models or Collections? | Collections for API data, Models for SQLite persistence |
184
170
  | Ti.App.fireEvent or EventBus? | **Always EventBus** (Backbone.Events) |
185
171
  | Direct navigation or service? | **Always Navigation service** (auto cleanup) |
186
- | Manual TSS or PurgeTSS? | **Always PurgeTSS utility classes** |
172
+ | Inline styles or TSS files? | **Always TSS files** (per-controller + `app.tss` for global) |
187
173
  | Controller 100+ lines? | Extract logic to services |
188
174
 
189
175
  ## Reference Guides (Progressive Disclosure)
190
176
 
191
177
  ### Architecture
192
- - **[Structure & Organization](references/alloy-structure.md)**: Models vs Collections, folder maps, styling strategies, automatic cleanup
178
+ - **[CLI Expert & TiNy](references/cli-expert.md)**: Advanced build workflows, LiveView, and TiNy (`tn`) recipes
179
+ - **[Structure & Organization](references/alloy-structure.md)**: Models vs Collections, folder maps, widget patterns, automatic cleanup
180
+ - **[Alloy Builtins & Globals](references/alloy-builtins.md)**: OS_IOS/OS_ANDROID, Alloy.CFG, Alloy.Globals, $.args, compiler directives
193
181
  - **[ControllerAutoCleanup.js](assets/ControllerAutoCleanup.js)**: Drop-in utility for automatic controller cleanup (prevents memory leaks)
194
182
  - **[Architectural Patterns](references/patterns.md)**: Repository, Service Layer, Event Bus, Factory, Singleton
195
183
  - **[Contracts & Communication](references/contracts.md)**: Layer interaction examples and JSDoc specs
196
- - **[Anti-Patterns](references/anti-patterns.md)**: Fat controllers, flexbox classes, memory leaks, direct API calls
184
+ - **[Anti-Patterns](references/anti-patterns.md)**: Fat controllers, memory leaks, inline styling, direct API calls
197
185
 
198
186
  ### Implementation
199
- - **[Code Conventions](references/code-conventions.md)**: ES6 features, PurgeTSS usage, accessibility
187
+ - **[Code Conventions](references/code-conventions.md)**: ES6 features, TSS design system, accessibility
188
+ - **[Theming & Dark Mode](references/theming.md)**: Theme system, Alloy.Globals palette, runtime switching, design tokens
200
189
  - **[Controller Patterns](references/controller-patterns.md)**: Templates, animation, dynamic styling
201
190
  - **[Examples](references/examples.md)**: API clients, SQL models, full screen examples
202
191
 
203
192
  ### Quality & Reliability
204
- - **[Testing](references/testing.md)**: Unit testing, mocking patterns, controller testing, test helpers
193
+ - **[Unit & Integration Testing](references/testing-unit.md)**: Unit testing, mocking patterns, controller testing, test helpers
194
+ - **[E2E Testing & CI/CD](references/testing-e2e-ci.md)**: Appium, WebdriverIO, GitHub Actions, Fastlane
205
195
  - **[Error Handling & Logging](references/error-handling.md)**: AppError classes, Logger service, validation
206
196
 
207
197
  ### Performance & Security
208
- - **[Performance Patterns](references/performance-patterns.md)**: ListView, bridge optimization, memory management, lazy loading
209
- - **[Security Patterns](references/security-patterns.md)**: Token storage, certificate pinning, encryption, OWASP
198
+ - **[ListView & ScrollView Performance](references/performance-listview.md)**: ListView templates, data binding, image caching, ScrollView optimization
199
+ - **[Performance Optimization](references/performance-optimization.md)**: Bridge crossings, memory management, animations, debounce/throttle, database
200
+ - **[Security Fundamentals](references/security-fundamentals.md)**: Token storage, certificate pinning, encryption, HTTPS, OWASP
201
+ - **[Device Security](references/security-device.md)**: Biometric auth, deep link validation, jailbreak/root detection
210
202
  - **[State Management](references/state-management.md)**: Centralized store, reactive patterns, synchronization
211
203
 
212
204
  ### Migration
@@ -218,7 +210,6 @@ For specific feature implementations, defer to these specialized skills:
218
210
 
219
211
  | Task | Use This Skill |
220
212
  | ----------------------------------------------------- | -------------- |
221
- | PurgeTSS setup, advanced styling, animations | `purgetss` |
222
213
  | Location, Maps, Push Notifications, Media APIs | `ti-howtos` |
223
214
  | UI layouts, ListViews, gestures, platform-specific UI | `ti-ui` |
224
215
  | Alloy CLI, configuration files, debugging | `alloy-howtos` |
@@ -0,0 +1,387 @@
1
+ # Alloy Builtins & Globals
2
+
3
+ ## Compiler Directives
4
+
5
+ Alloy provides compile-time constants that are replaced with `true`/`false` during build. Use them for platform-specific code without runtime cost.
6
+
7
+ ### OS_IOS / OS_ANDROID
8
+
9
+ ```javascript
10
+ // These are compile-time constants — dead code is removed at build
11
+ if (OS_IOS) {
12
+ $.window.applyProperties({
13
+ largeTitleEnabled: true,
14
+ largeTitleDisplayMode: Ti.UI.iOS.LARGE_TITLE_DISPLAY_MODE_ALWAYS
15
+ })
16
+ }
17
+
18
+ if (OS_ANDROID) {
19
+ $.window.activity.onCreateOptionsMenu = (e) => {
20
+ const menu = e.menu
21
+ menu.add({ title: L('settings'), showAsAction: Ti.Android.SHOW_AS_ACTION_NEVER })
22
+ }
23
+ }
24
+ ```
25
+
26
+ :::warning These are NOT runtime checks
27
+ `OS_IOS` and `OS_ANDROID` are replaced by the Alloy compiler with literal `true`/`false`. The opposite platform's code is completely removed from the build output. This is different from `Ti.Platform.osname === 'iphone'` which remains in the code.
28
+
29
+ **Use for:** Platform-specific APIs, platform-specific UI configuration
30
+ **Do NOT use for:** Logic that should be testable on both platforms
31
+ :::
32
+
33
+ ### ENV_DEV / ENV_TEST / ENV_PRODUCTION
34
+
35
+ ```javascript
36
+ if (ENV_DEV) {
37
+ Ti.API.info('Debug mode: API URL = ' + Alloy.CFG.apiUrl)
38
+ }
39
+
40
+ if (ENV_PRODUCTION) {
41
+ // Enable crash reporting
42
+ crashReporter.init()
43
+ }
44
+ ```
45
+
46
+ Set environment during build:
47
+ ```bash
48
+ ti build -p ios -T simulator -D development
49
+ ti build -p ios -T dist-appstore -D production
50
+ ```
51
+
52
+ ---
53
+
54
+ ## Alloy.Globals
55
+
56
+ Shared state and utilities accessible from any controller or lib file. Set in `alloy.js`, available everywhere.
57
+
58
+ ### Common Patterns
59
+
60
+ ```javascript
61
+ // alloy.js
62
+ const Backbone = require('alloy/backbone')
63
+
64
+ // --- Theme / Design Tokens ---
65
+ Alloy.Globals.theme = {
66
+ primary: '#2563eb',
67
+ bg: '#ffffff',
68
+ text: '#111827'
69
+ }
70
+
71
+ // --- Device Info (cached once) ---
72
+ Alloy.Globals.isTablet = Alloy.isTablet
73
+ Alloy.Globals.screenWidth = Ti.Platform.displayCaps.platformWidth
74
+ Alloy.Globals.screenHeight = Ti.Platform.displayCaps.platformHeight
75
+ Alloy.Globals.density = Ti.Platform.displayCaps.dpi
76
+
77
+ // --- App State Flags ---
78
+ Alloy.Globals.isLoggedIn = false
79
+ Alloy.Globals.currentUserId = null
80
+
81
+ // --- Collections ---
82
+ Alloy.Collections.products = new Backbone.Collection()
83
+ Alloy.Collections.notifications = new Backbone.Collection()
84
+ ```
85
+
86
+ ### Access from Anywhere
87
+
88
+ ```javascript
89
+ // In any controller
90
+ const theme = Alloy.Globals.theme
91
+ $.label.color = theme.primary
92
+
93
+ // In TSS (evaluated at compile time for controller creation)
94
+ "#header": {
95
+ backgroundColor: Alloy.Globals.theme.primary
96
+ }
97
+
98
+ // In XML with conditional binding
99
+ // <View if="Alloy.Globals.isLoggedIn">
100
+ ```
101
+
102
+ ### Globals vs Services
103
+
104
+ | Use `Alloy.Globals` for | Use a Service for |
105
+ | ---------------------------------- | ----------------------------- |
106
+ | Static config (theme, device info) | Business logic |
107
+ | Simple flags (isLoggedIn) | Complex state with listeners |
108
+ | Values set once in `alloy.js` | Values that change frequently |
109
+ | Read-only data | Data with side effects |
110
+
111
+ ---
112
+
113
+ ## Alloy.CFG
114
+
115
+ Values from `app/config.json`, automatically resolved by environment and platform.
116
+
117
+ ```javascript
118
+ // config.json
119
+ {
120
+ "global": { "appName": "MyApp" },
121
+ "env:development": { "apiUrl": "https://dev.api.com", "debug": true },
122
+ "env:production": { "apiUrl": "https://api.com", "debug": false },
123
+ "os:ios": { "statusBarStyle": "light" },
124
+ "os:android": { "exitOnBack": true }
125
+ }
126
+ ```
127
+
128
+ ```javascript
129
+ // Access anywhere
130
+ const url = Alloy.CFG.apiUrl // Resolved by environment
131
+ const debug = Alloy.CFG.debug // true in dev, false in prod
132
+ const appName = Alloy.CFG.appName // From global
133
+ ```
134
+
135
+ :::tip CFG is read-only
136
+ `Alloy.CFG` values are set at build time and cannot be modified at runtime. For runtime configuration, use `Alloy.Globals` or `Ti.App.Properties`.
137
+ :::
138
+
139
+ ---
140
+
141
+ ## Alloy.isTablet / Alloy.isHandheld
142
+
143
+ Detect device form factor at runtime.
144
+
145
+ ```javascript
146
+ if (Alloy.isTablet) {
147
+ // Show split-view layout
148
+ Navigation.open('tablet/splitView')
149
+ } else {
150
+ // Show phone layout
151
+ Navigation.open('phone/list')
152
+ }
153
+ ```
154
+
155
+ ### In TSS
156
+
157
+ ```tss
158
+ "#sidebar[formFactor=tablet]": {
159
+ width: 320,
160
+ visible: true
161
+ }
162
+
163
+ "#sidebar[formFactor=handheld]": {
164
+ width: 0,
165
+ visible: false
166
+ }
167
+ ```
168
+
169
+ ### In XML
170
+
171
+ ```xml
172
+ <Alloy>
173
+ <!-- Only rendered on tablet -->
174
+ <View formFactor="tablet" id="sidebar">
175
+ <Require src="sidebar/menu" />
176
+ </View>
177
+
178
+ <!-- Only rendered on phone -->
179
+ <View formFactor="handheld" id="content">
180
+ <Require src="phone/content" />
181
+ </View>
182
+ </Alloy>
183
+ ```
184
+
185
+ ---
186
+
187
+ ## $.args — Controller Arguments
188
+
189
+ Every controller receives arguments via `$.args`. This is the standard way to pass data between controllers.
190
+
191
+ ### Basic Usage
192
+
193
+ ```javascript
194
+ // Opening controller with args
195
+ const ctrl = Alloy.createController('user/profile', {
196
+ userId: 123,
197
+ mode: 'edit',
198
+ onSave: handleSave
199
+ })
200
+
201
+ // Receiving in target controller
202
+ // controllers/user/profile.js
203
+ const { userId, mode, onSave } = $.args
204
+ ```
205
+
206
+ ### Common Patterns
207
+
208
+ ```javascript
209
+ // Pattern 1: Default values with destructuring
210
+ const {
211
+ userId,
212
+ mode = 'view',
213
+ showHeader = true,
214
+ onComplete = () => {}
215
+ } = $.args
216
+
217
+ // Pattern 2: Validation
218
+ function init() {
219
+ if (!$.args.userId) {
220
+ Ti.API.error('user/profile requires userId')
221
+ $.getView().close()
222
+ return
223
+ }
224
+
225
+ loadUser($.args.userId)
226
+ }
227
+
228
+ // Pattern 3: Passing callbacks for communication
229
+ // Parent controller
230
+ const editor = Alloy.createController('editor', {
231
+ item: selectedItem,
232
+ onSave: (updatedItem) => {
233
+ refreshList()
234
+ }
235
+ })
236
+
237
+ // Child controller (editor.js)
238
+ function save() {
239
+ const data = collectFormData()
240
+ $.args.onSave(data)
241
+ $.getView().close()
242
+ }
243
+ ```
244
+
245
+ ### $.args in Widgets
246
+
247
+ Widgets also receive args, but through the `<Widget>` tag attributes:
248
+
249
+ ```xml
250
+ <Widget id="header" src="appHeader" title="L('home')" showBack="false" />
251
+ ```
252
+
253
+ ```javascript
254
+ // widgets/appHeader/controllers/widget.js
255
+ const title = $.args.title || ''
256
+ const showBack = $.args.showBack !== 'false' // XML passes strings
257
+ ```
258
+
259
+ :::warning XML attributes are always strings
260
+ When passing values through XML attributes, they arrive as strings in `$.args`. Numbers and booleans need to be parsed:
261
+ ```javascript
262
+ const count = parseInt($.args.count, 10) // "5" → 5
263
+ const visible = $.args.visible !== 'false' // "false" → false
264
+ ```
265
+ For complex data, pass via `Alloy.createController()` in the parent controller instead.
266
+ :::
267
+
268
+ ---
269
+
270
+ ## Alloy.createController / Alloy.createWidget
271
+
272
+ ### Controller Creation
273
+
274
+ ```javascript
275
+ // Create and open
276
+ const ctrl = Alloy.createController('user/profile', { userId: 123 })
277
+ ctrl.getView().open()
278
+
279
+ // Create and embed
280
+ const card = Alloy.createController('components/userCard', { user: userData })
281
+ $.container.add(card.getView())
282
+
283
+ // Access controller methods
284
+ ctrl.refresh()
285
+ ctrl.setData(newData)
286
+ ```
287
+
288
+ ### Widget Creation
289
+
290
+ ```javascript
291
+ // Create widget programmatically (alternative to XML <Widget>)
292
+ const loader = Alloy.createWidget('loadingOverlay')
293
+ $.window.add(loader.getView())
294
+
295
+ loader.show(L('loading'))
296
+ // ... later
297
+ loader.hide()
298
+ ```
299
+
300
+ ---
301
+
302
+ ## Alloy.createModel / Alloy.createCollection
303
+
304
+ ```javascript
305
+ // Create a model instance
306
+ const user = Alloy.createModel('User', {
307
+ name: 'John',
308
+ email: 'john@example.com'
309
+ })
310
+ user.save()
311
+
312
+ // Create a collection (fetches from adapter)
313
+ const users = Alloy.createCollection('User')
314
+ users.fetch()
315
+
316
+ // Collection with query (SQL adapter)
317
+ users.fetch({
318
+ query: 'SELECT * FROM users WHERE active = 1 ORDER BY name'
319
+ })
320
+ ```
321
+
322
+ ---
323
+
324
+ ## Conditional Code in XML
325
+
326
+ ### Platform Conditional
327
+
328
+ ```xml
329
+ <Alloy>
330
+ <Window>
331
+ <!-- iOS only -->
332
+ <NavigationWindow platform="ios" id="navWin">
333
+ <Require src="home" />
334
+ </NavigationWindow>
335
+
336
+ <!-- Android only -->
337
+ <Require platform="android" src="home" />
338
+ </Window>
339
+ </Alloy>
340
+ ```
341
+
342
+ ### Form Factor Conditional
343
+
344
+ ```xml
345
+ <Alloy>
346
+ <View formFactor="tablet" id="splitView">
347
+ <!-- Tablet layout -->
348
+ </View>
349
+ <View formFactor="handheld" id="phoneView">
350
+ <!-- Phone layout -->
351
+ </View>
352
+ </Alloy>
353
+ ```
354
+
355
+ ### Custom Conditional (if attribute)
356
+
357
+ ```xml
358
+ <!-- Only render if condition is true at creation time -->
359
+ <View if="Alloy.Globals.isLoggedIn" id="userMenu">
360
+ <Label text="L('welcome_back')" />
361
+ </View>
362
+
363
+ <View if="Alloy.Globals.featureFlags.newDashboard" id="newDashboard">
364
+ <Require src="dashboard/v2" />
365
+ </View>
366
+ ```
367
+
368
+ :::warning `if` is evaluated once at controller creation
369
+ The `if` attribute is checked when the controller is created. It does NOT react to later changes in the condition. For dynamic visibility, use the `visible` property in the controller.
370
+ :::
371
+
372
+ ---
373
+
374
+ ## Quick Reference
375
+
376
+ | Builtin | Type | Where Set | Mutable |
377
+ | ------------------- | ----------------- | ----------------- | ------- |
378
+ | `OS_IOS` | Compiler constant | Build time | No |
379
+ | `OS_ANDROID` | Compiler constant | Build time | No |
380
+ | `ENV_DEV` | Compiler constant | Build flag | No |
381
+ | `ENV_PRODUCTION` | Compiler constant | Build flag | No |
382
+ | `Alloy.CFG` | Object | `config.json` | No |
383
+ | `Alloy.Globals` | Object | `alloy.js` | Yes |
384
+ | `Alloy.isTablet` | Boolean | Runtime | No |
385
+ | `Alloy.isHandheld` | Boolean | Runtime | No |
386
+ | `Alloy.Collections` | Object | `alloy.js` | Yes |
387
+ | `$.args` | Object | Parent controller | No |