@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,484 @@
1
+ # Error Handling & Logging Guide
2
+
3
+ ## AppError Classes
4
+
5
+ ```javascript
6
+ // lib/core/appError.js
7
+ module.exports = class AppError extends Error {
8
+ constructor(message, code, statusCode = 500) {
9
+ super(message)
10
+ this.code = code
11
+ this.statusCode = statusCode
12
+ this.name = 'AppError'
13
+ Error.captureStackTrace?.(this, this.constructor)
14
+ }
15
+ }
16
+
17
+ // Specific error types
18
+ module.exports = class NetworkError extends AppError {
19
+ constructor(message = 'Network request failed') {
20
+ super(message, 'NETWORK_ERROR', 0)
21
+ }
22
+ }
23
+
24
+ module.exports = class AuthError extends AppError {
25
+ constructor(message = 'Authentication failed') {
26
+ super(message, 'AUTH_ERROR', 401)
27
+ }
28
+ }
29
+
30
+ module.exports = class ValidationError extends AppError {
31
+ constructor(message = 'Validation failed') {
32
+ super(message, 'VALIDATION_ERROR', 400)
33
+ }
34
+ }
35
+
36
+ module.exports = class NotFoundError extends AppError {
37
+ constructor(message = 'Resource not found') {
38
+ super(message, 'NOT_FOUND', 404)
39
+ }
40
+ }
41
+
42
+ // Error codes for reference
43
+ exports.ErrorCodes = {
44
+ NETWORK_ERROR: 'NETWORK_ERROR',
45
+ AUTH_ERROR: 'AUTH_ERROR',
46
+ VALIDATION_ERROR: 'VALIDATION_ERROR',
47
+ NOT_FOUND: 'NOT_FOUND',
48
+ SERVER_ERROR: 'SERVER_ERROR'
49
+ }
50
+ ```
51
+
52
+ ## Logger Service
53
+
54
+ ```javascript
55
+ // lib/services/logger.js
56
+ const LogLevel = {
57
+ DEBUG: 0,
58
+ INFO: 1,
59
+ WARN: 2,
60
+ ERROR: 3
61
+ }
62
+
63
+ class Logger {
64
+ constructor() {
65
+ this.level = this._getLogLevel()
66
+ this.sessionId = this._generateSessionId()
67
+ }
68
+
69
+ _getLogLevel() {
70
+ const deployType = Ti.App.deployType
71
+
72
+ if (deployType === 'development') {
73
+ return LogLevel.DEBUG
74
+ } else if (deployType === 'test') {
75
+ return LogLevel.WARN
76
+ }
77
+
78
+ return LogLevel.INFO
79
+ }
80
+
81
+ _generateSessionId() {
82
+ return Date.now().toString(36) + Math.random().toString(36).substr(2)
83
+ }
84
+
85
+ _shouldLog(level) {
86
+ return level >= this.level
87
+ }
88
+
89
+ _log(level, tag, message, data = {}) {
90
+ if (!this._shouldLog(level)) {
91
+ return
92
+ }
93
+
94
+ const logData = {
95
+ sessionId: this.sessionId,
96
+ timestamp: new Date().toISOString(),
97
+ level: this._levelName(level),
98
+ tag,
99
+ message,
100
+ ...data
101
+ }
102
+
103
+ const logString = JSON.stringify(logData)
104
+
105
+ switch (level) {
106
+ case LogLevel.DEBUG:
107
+ Ti.API.debug(`[${tag}] ${message}`, logString)
108
+ break
109
+ case LogLevel.INFO:
110
+ Ti.API.info(`[${tag}] ${message}`, logString)
111
+ break
112
+ case LogLevel.WARN:
113
+ Ti.API.warn(`[${tag}] ${message}`, logString)
114
+ break
115
+ case LogLevel.ERROR:
116
+ Ti.API.error(`[${tag}] ${message}`, logString)
117
+ break
118
+ }
119
+ }
120
+
121
+ _levelName(level) {
122
+ return Object.keys(LogLevel).find(key => LogLevel[key] === level)
123
+ }
124
+
125
+ debug(tag, message, data) {
126
+ this._log(LogLevel.DEBUG, tag, message, data)
127
+ }
128
+
129
+ info(tag, message, data) {
130
+ this._log(LogLevel.INFO, tag, message, data)
131
+ }
132
+
133
+ warn(tag, message, data) {
134
+ this._log(LogLevel.WARN, tag, message, data)
135
+ }
136
+
137
+ error(tag, message, data) {
138
+ this._log(LogLevel.ERROR, tag, message, data)
139
+ }
140
+ }
141
+
142
+ module.exports = new Logger()
143
+ ```
144
+
145
+ ## Error Handler Service
146
+
147
+ ```javascript
148
+ // lib/services/errorHandler.js
149
+ const logger = require('lib/services/logger')
150
+ const { AppError } = require('lib/core/appError')
151
+
152
+ exports.handleError = function handleError(error, context = {}) {
153
+ // Log the error
154
+ logger.error('ErrorHandler', 'Error occurred', {
155
+ message: error.message,
156
+ code: error.code,
157
+ status: error.statusCode,
158
+ stack: error.stack,
159
+ ...context
160
+ })
161
+
162
+ // Report to crash service (if configured)
163
+ _reportToCrashService(error, context)
164
+
165
+ // Return user-friendly message
166
+ return _getUserMessage(error)
167
+ }
168
+
169
+ function _reportToCrashService(error, context) {
170
+ // Only in production
171
+ if (Ti.App.deployType !== 'production') {
172
+ return
173
+ }
174
+
175
+ // Example: Sentry integration
176
+ if (typeof Sentry !== 'undefined') {
177
+ Sentry.captureException(error, {
178
+ extra: context
179
+ })
180
+ }
181
+ }
182
+
183
+ function _getUserMessage(error) {
184
+ const messages = {
185
+ NETWORK_ERROR: L('error_network'),
186
+ AUTH_ERROR: L('error_auth'),
187
+ VALIDATION_ERROR: L('error_validation'),
188
+ NOT_FOUND: L('error_not_found'),
189
+ SERVER_ERROR: L('error_server')
190
+ }
191
+
192
+ if (error instanceof AppError) {
193
+ return messages[error.code] || L('error_unknown')
194
+ }
195
+
196
+ return L('error_unknown')
197
+ }
198
+ ```
199
+
200
+ ## Using the Logger
201
+
202
+ ```javascript
203
+ // lib/services/userService.js
204
+ const logger = require('lib/services/logger')
205
+ const { NetworkError, NotFoundError } = require('lib/core/appError')
206
+
207
+ exports.getUserProfile = async function getUserProfile(userId) {
208
+ logger.info('UserService', 'Fetching user profile', { userId })
209
+
210
+ try {
211
+ const response = await api.get(`/users/${userId}`)
212
+
213
+ logger.debug('UserService', 'User profile fetched', {
214
+ userId,
215
+ hasData: !!response.data
216
+ })
217
+
218
+ return response.data
219
+
220
+ } catch (error) {
221
+ logger.error('UserService', 'Failed to fetch user profile', {
222
+ userId,
223
+ error: error.message,
224
+ status: error.statusCode
225
+ })
226
+
227
+ if (error.status === 404) {
228
+ throw new NotFoundError('User not found')
229
+ }
230
+
231
+ throw new NetworkError('Failed to load profile')
232
+ }
233
+ }
234
+ ```
235
+
236
+ ## API Client Error Handling
237
+
238
+ ```javascript
239
+ // lib/api/client.js
240
+ const logger = require('lib/services/logger')
241
+ const { NetworkError, AuthError, NotFoundError, ValidationError } = require('lib/core/appError')
242
+
243
+ exports.get = async function get(endpoint, params = {}) {
244
+ return new Promise((resolve, reject) => {
245
+ const client = Ti.Network.createHTTPClient({
246
+ timeout: 10000,
247
+
248
+ onload: () => {
249
+ try {
250
+ const data = JSON.parse(client.responseText)
251
+
252
+ logger.debug('API', 'Request successful', {
253
+ endpoint,
254
+ status: client.status
255
+ })
256
+
257
+ resolve(data)
258
+
259
+ } catch (e) {
260
+ logger.error('API', 'Invalid JSON response', {
261
+ endpoint,
262
+ responseText: client.responseText
263
+ })
264
+
265
+ reject(new ValidationError('Invalid response format'))
266
+ }
267
+ },
268
+
269
+ onerror: (e) => {
270
+ logger.error('API', 'Request failed', {
271
+ endpoint,
272
+ status: client.status,
273
+ error: e.error
274
+ })
275
+
276
+ // Map HTTP status to error types
277
+ let error
278
+
279
+ switch (client.status) {
280
+ case 401:
281
+ error = new AuthError()
282
+ break
283
+ case 404:
284
+ error = new NotFoundError()
285
+ break
286
+ case 0:
287
+ error = new NetworkError('Network unavailable')
288
+ break
289
+ default:
290
+ error = new NetworkError(`Request failed: ${client.status}`)
291
+ }
292
+
293
+ reject(error)
294
+ }
295
+ })
296
+
297
+ logger.debug('API', 'Sending request', { endpoint, params })
298
+
299
+ client.open('GET', endpoint)
300
+ client.send(params)
301
+ })
302
+ }
303
+ ```
304
+
305
+ ## Controller Error Handling Pattern
306
+
307
+ ```javascript
308
+ // controllers/user/detail.js
309
+ const logger = require('lib/services/logger')
310
+ const { handleError } = require('lib/services/errorHandler')
311
+ const { getUserProfile } = require('lib/services/userService')
312
+
313
+ function init() {
314
+ logger.debug('UserDetail', 'Controller initialized', { userId: $.args.userId })
315
+
316
+ loadUserData()
317
+
318
+ // Handle retry button
319
+ $.retryButton.addEventListener('click', loadUserData)
320
+ }
321
+
322
+ async function loadUserData() {
323
+ // Show loading state
324
+ setLoading(true)
325
+
326
+ try {
327
+ const user = await getUserProfile($.args.userId)
328
+
329
+ // Update UI
330
+ updateUI(user)
331
+
332
+ logger.info('UserDetail', 'User data loaded successfully', {
333
+ userId: user.id
334
+ })
335
+
336
+ } catch (error) {
337
+ // Handle error
338
+ const userMessage = handleError(error, {
339
+ controller: 'user/detail',
340
+ userId: $.args.userId
341
+ })
342
+
343
+ showError(userMessage)
344
+
345
+ } finally {
346
+ setLoading(false)
347
+ }
348
+ }
349
+
350
+ function setLoading(isLoading) {
351
+ $.activityIndicator.visible = isLoading
352
+
353
+ if (isLoading) {
354
+ $.activityIndicator.show()
355
+ } else {
356
+ $.activityIndicator.hide()
357
+ }
358
+ }
359
+
360
+ function showError(message) {
361
+ $.errorLabel.text = message
362
+ $.errorLabel.visible = true
363
+
364
+ // Auto-hide after 3 seconds
365
+ setTimeout(() => {
366
+ $.errorLabel.visible = false
367
+ }, 3000)
368
+ }
369
+
370
+ function cleanup() {
371
+ logger.debug('UserDetail', 'Controller cleanup')
372
+ $.retryButton.removeEventListener('click', loadUserData)
373
+ $.destroy()
374
+ }
375
+
376
+ $.cleanup = cleanup
377
+ ```
378
+
379
+ ## Global Error Handler
380
+
381
+ ```javascript
382
+ // alloy.js - Setup global error catching
383
+ const { handleError } = require('lib/services/errorHandler')
384
+
385
+ // Catch unhandled errors in production
386
+ if (Ti.App.deployType === 'production') {
387
+ Ti.App.addEventListener('uncaughtException', (event) => {
388
+ handleError(event.exception, {
389
+ type: 'uncaughtException',
390
+ url: event.url
391
+ })
392
+
393
+ // Show friendly error screen
394
+ Alloy.createController('error/crash').getView().open()
395
+ })
396
+ }
397
+ ```
398
+
399
+ ## Crash Reporting Integration
400
+
401
+ ```javascript
402
+ // lib/services/crashReporting.js
403
+ exports.initSentry = function initSentry(dsn) {
404
+ if (typeof Sentry === 'undefined') return
405
+
406
+ Sentry.init({
407
+ dsn: dsn,
408
+ environment: Ti.App.deployType,
409
+ release: Ti.App.version
410
+ })
411
+
412
+ // Set user context when available
413
+ const userId = Ti.App.Properties.getString('userId')
414
+ if (userId) {
415
+ Sentry.setUser({ id: userId })
416
+ }
417
+ }
418
+
419
+ exports.reportToCrashService = function reportToCrashService(error, context = {}) {
420
+ if (typeof Sentry !== 'undefined') {
421
+ Sentry.captureException(error, {
422
+ extra: context
423
+ })
424
+ }
425
+ }
426
+ ```
427
+
428
+ ## Validation Helper
429
+
430
+ ```javascript
431
+ // lib/helpers/validator.js
432
+ const { ValidationError } = require('lib/core/appError')
433
+ const logger = require('lib/services/logger')
434
+
435
+ exports.validateEmail = function validateEmail(email) {
436
+ const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
437
+
438
+ if (!regex.test(email)) {
439
+ logger.warn('Validator', 'Invalid email', { email })
440
+
441
+ throw new ValidationError(L('error_invalid_email'))
442
+ }
443
+
444
+ return email.trim().toLowerCase()
445
+ }
446
+
447
+ exports.validatePassword = function validatePassword(password) {
448
+ if (!password || password.length < 8) {
449
+ logger.warn('Validator', 'Password too short')
450
+
451
+ throw new ValidationError(L('error_password_short'))
452
+ }
453
+
454
+ return password
455
+ }
456
+
457
+ exports.validateRequired = function validateRequired(value, fieldName) {
458
+ if (!value || (typeof value === 'string' && !value.trim())) {
459
+ logger.warn('Validator', 'Required field missing', { fieldName })
460
+
461
+ throw new ValidationError(L('error_required', { field: fieldName }))
462
+ }
463
+
464
+ return value
465
+ }
466
+ ```
467
+
468
+ ## Logging Best Practices
469
+
470
+ | Practice | Example |
471
+ | -------------------------- | ------------------------------------------------------ |
472
+ | Use appropriate log levels | `DEBUG` for diagnostics, `ERROR` for failures |
473
+ | Include context data | `logger.info('Service', 'Action', { userId, action })` |
474
+ | Don't log sensitive data | Never log passwords, tokens, credit cards |
475
+ | Use tags for filtering | `logger.error('AuthService', ...)` |
476
+ | Log at boundaries | Entry/exit of functions, API calls, user actions |
477
+
478
+ | DO | DON'T |
479
+ | ---------------------------------------------------- | ---------------------------------------- |
480
+ | Log at appropriate levels (DEBUG, INFO, WARN, ERROR) | Log everything at INFO or ERROR |
481
+ | Include structured data as second parameter | Build message strings with concatenation |
482
+ | Use DEBUG for development diagnostics | Use Ti.API.log directly |
483
+ | Log errors with stack traces in production | Log sensitive data (passwords, tokens) |
484
+ | Use context objects for correlation | Log without identifying the source |