@maccesar/titools 2.7.2 → 2.9.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 (51) hide show
  1. package/README.md +6 -13
  2. package/lib/config.js +1 -1
  3. package/package.json +1 -1
  4. package/skills/purgetss/SKILL.md +25 -0
  5. package/skills/purgetss/references/EXAMPLES.md +86 -24
  6. package/skills/purgetss/references/app-branding.md +412 -0
  7. package/skills/purgetss/references/appearance-module.md +161 -0
  8. package/skills/purgetss/references/apply-directive.md +87 -31
  9. package/skills/purgetss/references/arbitrary-values.md +4 -0
  10. package/skills/purgetss/references/class-categories.md +10 -7
  11. package/skills/purgetss/references/class-index.md +25 -18
  12. package/skills/purgetss/references/cli-commands.md +219 -8
  13. package/skills/purgetss/references/configurable-properties.md +11 -7
  14. package/skills/purgetss/references/custom-rules.md +7 -3
  15. package/skills/purgetss/references/customization-deep-dive.md +52 -4
  16. package/skills/purgetss/references/dynamic-component-creation.md +29 -14
  17. package/skills/purgetss/references/grid-layout.md +20 -8
  18. package/skills/purgetss/references/icon-fonts.md +4 -0
  19. package/skills/purgetss/references/installation-setup.md +3 -8
  20. package/skills/purgetss/references/ios-large-titles.md +141 -0
  21. package/skills/purgetss/references/migration-guide.md +162 -25
  22. package/skills/purgetss/references/multi-density-images.md +363 -0
  23. package/skills/purgetss/references/opacity-modifier.md +4 -0
  24. package/skills/purgetss/references/performance-tips.md +5 -0
  25. package/skills/purgetss/references/platform-modifiers.md +4 -0
  26. package/skills/purgetss/references/semantic-colors.md +386 -0
  27. package/skills/purgetss/references/smart-mappings.md +50 -28
  28. package/skills/purgetss/references/tikit-components.md +3 -1
  29. package/skills/purgetss/references/titanium-resets.md +46 -15
  30. package/skills/purgetss/references/ui-ux-design.md +32 -6
  31. package/skills/ti-branding/SKILL.md +0 -230
  32. package/skills/ti-branding/assets/ic_launcher.xml +0 -6
  33. package/skills/ti-branding/references/android-adaptive-icons.md +0 -85
  34. package/skills/ti-branding/references/cleanup-legacy.md +0 -112
  35. package/skills/ti-branding/references/ios-appiconset.md +0 -62
  36. package/skills/ti-branding/references/master-input-guidelines.md +0 -84
  37. package/skills/ti-branding/references/notification-icons.md +0 -63
  38. package/skills/ti-branding/references/splash-screen-api.md +0 -81
  39. package/skills/ti-branding/references/ti-icon-paths.md +0 -84
  40. package/skills/ti-branding/references/tiapp-xml-snippets.md +0 -92
  41. package/skills/ti-branding/scripts/lib/cleanup-legacy.sh +0 -230
  42. package/skills/ti-branding/scripts/lib/deps.sh +0 -58
  43. package/skills/ti-branding/scripts/lib/gen-android-adaptive.sh +0 -64
  44. package/skills/ti-branding/scripts/lib/gen-android-legacy.sh +0 -36
  45. package/skills/ti-branding/scripts/lib/gen-ios.sh +0 -46
  46. package/skills/ti-branding/scripts/lib/gen-marketplace.sh +0 -55
  47. package/skills/ti-branding/scripts/lib/gen-notification.sh +0 -46
  48. package/skills/ti-branding/scripts/lib/gen-splash-icon.sh +0 -31
  49. package/skills/ti-branding/scripts/lib/prepare-master.sh +0 -48
  50. package/skills/ti-branding/scripts/lib/validate.sh +0 -67
  51. package/skills/ti-branding/scripts/ti-branding +0 -546
@@ -0,0 +1,363 @@
1
+ # Multi-Density Images
2
+
3
+ The `purgetss images` command (shipped in PurgeTSS v7.6.0) generates every Titanium density variant of your UI images — buttons, illustrations, screen graphics, inline icons, logos — from a single high-resolution source per image. Alloy and Classic layouts are auto-detected.
4
+
5
+ - **Android**: `res-mdpi`, `res-hdpi`, `res-xhdpi`, `res-xxhdpi`, `res-xxxhdpi` (5 densities)
6
+ - **iPhone**: `@1x`, `@2x`, `@3x` (3 scales via filename suffix)
7
+
8
+ For the terse flag reference, see the [`images` command reference](./cli-commands.md#images-command). For launcher icons and branding, see [App Icons & Branding](./app-branding.md).
9
+
10
+ > **INFO**
11
+ >
12
+ > The `images` command at a glance
13
+ > One source per image in `purgetss/images/`, run `purgetss images`, and every density lands in the right place under `app/assets/android/images/res-*/` and `app/assets/iphone/images/`. Works on both Alloy and Classic projects.
14
+
15
+ ## Why multi-density?
16
+
17
+ Android's UI toolkit resolves images by **density**: a Pixel 7 (xxhdpi ≈ 3×) picks files from `res-xxhdpi/`, a low-end Moto (hdpi ≈ 1.5×) picks from `res-hdpi/`. If the right density isn't available, Android upscales the closest one, which looks noticeably blurry on high-DPI screens.
18
+
19
+ iOS uses the same idea with filename suffixes: `icon.png`, `icon@2x.png`, `icon@3x.png`. iPhone 15 Pro picks `@3x`, older iPads pick `@2x`.
20
+
21
+ Shipping every variant keeps your UI sharp on every device. `purgetss images` does it in one pass from a single source per image.
22
+
23
+ ## Quick start
24
+
25
+ Drop source images into `purgetss/images/`, then run the command:
26
+
27
+ ```bash
28
+ cp my-hero-illustration.png purgetss/images/
29
+ cp my-button.svg purgetss/images/buttons/primary.svg
30
+
31
+ purgetss images
32
+ ```
33
+
34
+ Output in an Alloy project:
35
+
36
+ ```text
37
+ app/assets/
38
+ ├── android/images/
39
+ │ ├── res-mdpi/
40
+ │ │ ├── my-hero-illustration.png
41
+ │ │ └── buttons/primary.svg
42
+ │ ├── res-hdpi/…
43
+ │ ├── res-xhdpi/…
44
+ │ ├── res-xxhdpi/…
45
+ │ └── res-xxxhdpi/…
46
+ └── iphone/images/
47
+ ├── my-hero-illustration.png (@1x)
48
+ ├── my-hero-illustration@2x.png
49
+ ├── my-hero-illustration@3x.png
50
+ └── buttons/
51
+ ├── primary.svg (@1x)
52
+ ├── primary@2x.svg
53
+ └── primary@3x.svg
54
+ ```
55
+
56
+ Classic projects output to `assets/android/images/res-*/` and `assets/iphone/images/` under the project root instead of under `app/assets/` — the command auto-detects the layout.
57
+
58
+ ## The `purgetss/images/` convention
59
+
60
+ `init` creates `purgetss/images/` (alongside `fonts/` and `brand/`), so the folder is already there the first time you look for it, even before you've dropped any sources.
61
+
62
+ ```text
63
+ purgetss/images/
64
+ ├── logo-screen.svg
65
+ ├── hero.png
66
+ ├── buttons/
67
+ │ ├── primary.png
68
+ │ └── secondary.png
69
+ └── icons/
70
+ └── home.svg
71
+ ```
72
+
73
+ Supported input formats: `.svg`, `.png`, `.jpg`, `.jpeg`, `.webp`, `.gif`.
74
+
75
+ **Subdirectories are preserved in the output.** A file at `purgetss/images/buttons/primary.png` ends up at `app/assets/android/images/res-*/buttons/primary.png` and `app/assets/iphone/images/buttons/primary.png`. Organize however makes sense for your project.
76
+
77
+ > **INFO**
78
+ >
79
+ > Use SVG whenever you can
80
+ > SVG scales losslessly to every density. A single `icon.svg` rasterizes perfectly to every `res-*dpi` folder without pixel loss. PNG/JPG sources must be downscaled and lose a bit of sharpness at smaller densities.
81
+
82
+ ## Source sizes — the 4× master convention
83
+
84
+ PurgeTSS (and Titanium Alloy generally) treats every source image as a **4× master** (`res-xxxhdpi` / `@xxxhdpi` on Android, equivalent to `@4x` on iPhone if iOS supported it). All smaller densities are **downscaled** from that source.
85
+
86
+ That means:
87
+
88
+ | Source size (logical) | Use for |
89
+ | --- | --- |
90
+ | 1920×1080 or larger | Full-screen illustration / hero image |
91
+ | 800×800 | Card, list item, large icon |
92
+ | 200×200 | Button, inline icon |
93
+ | 96×96 | Small inline icon |
94
+
95
+ If your source is smaller than 4×, the tool still runs but the larger density outputs are essentially upscaled — quality drops on high-DPI devices.
96
+
97
+ Recommended sizes for common UI elements (in source pixels, assumed 4×):
98
+
99
+ - **Full-screen illustration**: at least `1920×1080`
100
+ - **Tab bar icon**: at least `192×192` (source for 48px at xxxhdpi)
101
+ - **List-row thumbnail**: at least `320×320`
102
+ - **Button background**: match the intended display size × 4
103
+
104
+ ## The `images:` config section
105
+
106
+ On the first run, `purgetss images` injects an `images:` block into your existing `purgetss/config.cjs` (between `brand:` and `theme:`) with these defaults:
107
+
108
+ ```javascript
109
+ images: {
110
+ quality: 85, // JPEG/WebP/AVIF quality (0-100)
111
+ format: null, // null = keep original; 'webp' | 'jpeg' | 'png' to convert every image
112
+ confirmOverwrites: true // prompt before overwriting files (set false to skip)
113
+ }
114
+ ```
115
+
116
+ | Key | Default | Purpose |
117
+ | --- | --- | --- |
118
+ | `quality` | `85` | Quality for lossy formats (JPEG, WebP, AVIF). Range `0–100`. |
119
+ | `format` | `null` | `null` keeps each source's original format. Set `'webp'`, `'jpeg'`, or `'png'` to convert every output. |
120
+ | `confirmOverwrites` | `true` | When `false`, the `[y/N/a]` prompt is skipped. |
121
+
122
+ Change whatever you want to override globally; CLI flags still win for one-off runs.
123
+
124
+ ## Output layouts
125
+
126
+ **Alloy layout** (auto-detected when `app/assets/` exists):
127
+
128
+ ```text
129
+ <project>/
130
+ └── app/assets/
131
+ ├── android/images/
132
+ │ ├── res-mdpi/
133
+ │ ├── res-hdpi/
134
+ │ ├── res-xhdpi/
135
+ │ ├── res-xxhdpi/
136
+ │ └── res-xxxhdpi/
137
+ └── iphone/images/
138
+ ├── <name>.<ext> (@1x)
139
+ ├── <name>@2x.<ext>
140
+ └── <name>@3x.<ext>
141
+ ```
142
+
143
+ **Classic layout** (auto-detected otherwise):
144
+
145
+ ```text
146
+ <project>/
147
+ └── assets/
148
+ ├── android/images/res-*/
149
+ └── iphone/images/
150
+ ```
151
+
152
+ Subdirectory structure inside `purgetss/images/` is preserved in both layouts.
153
+
154
+ ## Overwrite confirmation
155
+
156
+ `images` writes directly into the project, so it asks before overwriting anything:
157
+
158
+ ```text
159
+ Continue? [y/N/a]
160
+ ```
161
+
162
+ - `y` / `yes` — write this time
163
+ - `N` / `no` / `Enter` — abort (nothing is written)
164
+ - `a` / `always` — write, then add `confirmOverwrites: false` to the `images:` section of `config.cjs` so the prompt stays quiet on future runs
165
+
166
+ The prompt is skipped automatically when:
167
+
168
+ - `stdin` is not a TTY (the `alloy.jmk` hook, CI, a pipe)
169
+ - you pass `-y` / `--yes` — one-shot bypass
170
+ - `PURGETSS_YES=1` is set in the environment — lasts the whole shell session
171
+ - `confirmOverwrites: false` is already in the `images:` config
172
+
173
+ ```bash
174
+ purgetss images -y # skip prompt once
175
+ PURGETSS_YES=1 purgetss images # skip for the whole session
176
+ ```
177
+
178
+ ## Re-processing a single file or subfolder
179
+
180
+ Common workflow: you tweaked one image in Affinity or Figma and only want to regenerate that one, not the whole folder.
181
+
182
+ Pass its path directly:
183
+
184
+ ```bash
185
+ purgetss images buttons/primary.png
186
+ ```
187
+
188
+ Short paths auto-resolve against `purgetss/images/`, so you don't need to type `purgetss/images/buttons/primary.png`. The command tries two interpretations in order:
189
+
190
+ 1. `purgetss/images/buttons/primary.png` (matches the convention folder).
191
+ 2. `./buttons/primary.png` (fallback, relative to the project root).
192
+
193
+ Subdirectory structure is preserved in the output whenever the source lives inside `purgetss/images/`, whether you pass the full folder, a subfolder, or a single file. Re-processing one file produces the same output path it had in a full run.
194
+
195
+ ### Re-process a whole subfolder
196
+
197
+ ```bash
198
+ purgetss images buttons/
199
+ ```
200
+
201
+ Walks `purgetss/images/buttons/` recursively and regenerates every image inside. Everything outside stays untouched.
202
+
203
+ ### Pointing to sources outside the convention
204
+
205
+ If your source images live elsewhere (e.g. next to your design files in `docs/screenshots/`), pass an absolute or cwd-relative path:
206
+
207
+ ```bash
208
+ purgetss images ./docs/screenshots/home-hero.png
209
+ purgetss images /Users/cesar/Design/banner.svg
210
+ ```
211
+
212
+ When the source is outside `purgetss/images/`, subdirectory preservation uses the directory of the source file as the root instead.
213
+
214
+ ## Platform filter
215
+
216
+ By default, every run generates both Android densities and iPhone scales. Scope to one platform for targeted runs:
217
+
218
+ ```bash
219
+ purgetss images --android # Android only (skip iPhone)
220
+ purgetss images --ios # iPhone only (skip Android)
221
+ ```
222
+
223
+ Useful when:
224
+
225
+ - You're iterating on an iOS-only screen and don't need to regenerate Android assets every time.
226
+ - You want to tune JPEG quality differently for the two platforms (run the command twice with different flags).
227
+
228
+ The two flags are mutually exclusive. Pass neither to get both.
229
+
230
+ ## Format conversion
231
+
232
+ The default preserves each source's format: drop in `.png`, get out `.png`; drop in `.jpg`, get out `.jpg`. Add `--format <ext>` to convert every output to a single target format:
233
+
234
+ ```bash
235
+ purgetss images --format webp # convert every output to WebP
236
+ purgetss images --format jpeg --quality 90
237
+ ```
238
+
239
+ Valid targets: `webp`, `jpeg`, `png`, `avif`, `gif`, `tiff`.
240
+
241
+ ### Why WebP?
242
+
243
+ WebP produces ~25–35% smaller files than JPEG at similar visual quality, and Titanium supports it natively on both platforms. For a large UI asset library, switching to WebP can shave several MB off your APK/IPA.
244
+
245
+ ```bash
246
+ purgetss images --format webp --quality 85
247
+ ```
248
+
249
+ Keep the default `format: null` when you need to stay in the same format as the source — for example PNG with alpha that shouldn't be flattened.
250
+
251
+ ## Full pipeline alongside `build`
252
+
253
+ The typical sequence when iterating on an app:
254
+
255
+ ```bash
256
+ # 1. Edit your source images in Affinity/Figma, drop into purgetss/images/
257
+ # 2. Regenerate the variants
258
+ purgetss images
259
+
260
+ # 3. Run purgetss build to regenerate utilities.tss if you changed classes
261
+ purgetss build
262
+
263
+ # 4. Build the app
264
+ ti build -p android -T emulator
265
+ ```
266
+
267
+ If you only tweaked CSS classes (no image changes), you don't need to re-run `purgetss images`. It's safe to skip.
268
+
269
+ ## Cleaning up
270
+
271
+ `purgetss images` never deletes files. It only creates them. If you remove an image from `purgetss/images/`, the previously-generated copies in `app/assets/android/images/res-*/` and `app/assets/iphone/images/` stay in place. Remove them manually (or via git) when you clean up.
272
+
273
+ ## Full flag reference
274
+
275
+ **Source selection**
276
+
277
+ | Argument | Purpose |
278
+ | --- | --- |
279
+ | `[source]` (positional) | Optional path to override auto-discovery. Resolves first against `purgetss/images/` (short paths like `buttons/btn.png`), then against cwd. |
280
+
281
+ **Platform filter**
282
+
283
+ | Flag | Purpose |
284
+ | --- | --- |
285
+ | `--android` | Only Android density variants. Mutually exclusive with `--ios`. |
286
+ | `--ios` | Only iPhone scale variants. Mutually exclusive with `--android`. |
287
+
288
+ **Output format**
289
+
290
+ | Flag | Purpose |
291
+ | --- | --- |
292
+ | `--format <ext>` | Convert all outputs to: `webp`, `jpeg`, `png`, `avif`, `gif`, `tiff`. Default: keep source format. |
293
+ | `--quality <n>` | Quality `0–100` for lossy formats. Default `85`. |
294
+
295
+ **Project & output**
296
+
297
+ | Flag | Purpose |
298
+ | --- | --- |
299
+ | `--dry-run` | Preview without writing any files. |
300
+ | `--project <path>` | Project root (defaults to cwd). |
301
+ | `-y`, `--yes` | Skip the overwrite confirmation prompt for this invocation. |
302
+
303
+ **Diagnostics**
304
+
305
+ | Flag | Purpose |
306
+ | --- | --- |
307
+ | `--debug` | Print extra diagnostics. |
308
+
309
+ ### Examples
310
+
311
+ ```bash
312
+ purgetss images # uses purgetss/images/ + config
313
+ purgetss images background/pink-texture.png # re-process one file (short path)
314
+ purgetss images background/ # re-process one subfolder
315
+ purgetss images --android # only Android densities
316
+ purgetss images --format webp --quality 90 # convert all outputs to WebP
317
+ purgetss images --dry-run # preview
318
+ ```
319
+
320
+ ## Troubleshooting
321
+
322
+ ### The output is blurry on high-DPI devices
323
+
324
+ Your source is likely smaller than the 4× master convention. A larger source means sharper output across all densities. Aim for at least 4× the intended display size, or use SVG sources when possible.
325
+
326
+ ### JPG output has a white background instead of transparency
327
+
328
+ JPEG doesn't support alpha channels. If your source is PNG with transparency and you convert to JPEG (via `--format jpeg`), the alpha gets flattened on white. To preserve transparency, keep the format as PNG or WebP:
329
+
330
+ ```bash
331
+ purgetss images --format webp # supports alpha
332
+ purgetss images --format png # keeps alpha
333
+ ```
334
+
335
+ ### My subdirectories aren't preserved in the output
336
+
337
+ Verify your source path is inside `purgetss/images/`. When passing sources from outside the convention (e.g. `./docs/screenshots`), the directory of the source file is used as the root, so a file at `./docs/screenshots/hero.png` outputs to `images/hero.png` (flat), not `images/screenshots/hero.png`.
338
+
339
+ Move the file into `purgetss/images/screenshots/` if you want subdirectory preservation.
340
+
341
+ ### I want to preview what would happen before writing files
342
+
343
+ ```bash
344
+ purgetss images --dry-run
345
+ ```
346
+
347
+ Shows every file that would be written, no side effects.
348
+
349
+ ### Can I use this for app icons?
350
+
351
+ **No.** App icons need a different pipeline: adaptive icons with foreground + background + monochrome layers, mask safe-zones, marketplace flattening, iOS 18+ Dark/Tinted variants. Use [`purgetss brand`](./app-branding.md) for the launcher icon.
352
+
353
+ `purgetss images` is for the UI assets *inside* your screens: buttons, backgrounds, illustrations, inline icons.
354
+
355
+ ## Community-Discovered Patterns
356
+
357
+ - **4× master convention predates PurgeTSS.** Treating the source as a 4× master (`xxxhdpi` on Android, `@4x` equivalent on iOS) is the same convention Titanium Alloy has always used internally when resolving density-qualified image paths. `purgetss images` formalizes the workflow but doesn't invent a new rule — any Alloy project already ships with the same assumption.
358
+ - **Short-path fallback order matters for monorepos.** When you pass `buttons/primary.png`, the command tries `purgetss/images/buttons/primary.png` first, then `./buttons/primary.png` relative to cwd. In a monorepo where a design folder might shadow the convention, the convention wins. To force the cwd-relative interpretation, pass `./buttons/primary.png` with the explicit `./` prefix or an absolute path.
359
+
360
+ ## See also
361
+
362
+ - [`images` command reference](./cli-commands.md#images-command) — terse flag list.
363
+ - [App Icons & Branding](./app-branding.md) — sibling `brand` command for launcher icons and marketplace artwork.
@@ -56,5 +56,9 @@ module.exports = {
56
56
  > **CAUTION -- Semantic Colors**
57
57
  > Semantic colors cannot be modified with the opacity modifier because they are defined as an object with light and dark values.
58
58
 
59
+ ## Community-Discovered Patterns
60
+
61
+ The following note reflects community observations about how the opacity modifier interacts with gradient utilities.
62
+
59
63
  > **Gradients**
60
64
  > The same modifier logic applies to color-based gradient utilities such as `from-*` and `to-*`. When you define custom `backgroundGradient.colors` arrays of `{ color, offset }` objects in `config.cjs`, PurgeTSS v7.4.0 correctly serializes those nested objects in `utilities.tss`.
@@ -1,5 +1,10 @@
1
1
  # Performance Tips with PurgeTSS
2
2
 
3
+ > **DISCLAIMER**
4
+ > This entire document is curated community-verified guidance for optimizing Titanium apps that use PurgeTSS. It is **not** a mirror of the official PurgeTSS documentation. Tips are compiled from real-world project experience, Titanium bridge/memory observations, and commonly applied patterns in the Titanium community. Official PurgeTSS docs focus on utility classes and configuration, not app performance.
5
+
6
+ ## Community-Discovered Patterns
7
+
3
8
  Best practices for optimizing performance in Titanium apps using PurgeTSS utility classes.
4
9
 
5
10
  ## PurgeTSS Classes vs Inline Styles
@@ -43,5 +43,9 @@ You can set different background colors and font sizes per platform and device,
43
43
  '.tablet:bg-green-500[formFactor=tablet]': { backgroundColor: '#22c55e' }
44
44
  ```
45
45
 
46
+ ## Community-Discovered Patterns
47
+
48
+ The following guidance comes from community experience combining platform modifiers with platform-specific Titanium constants.
49
+
46
50
  > **Platform-Specific Properties**
47
51
  > If a style relies on `Ti.UI.iOS.*` or `Ti.UI.Android.*` constants, scope it with the matching `ios:` or `android:` modifier, or with the equivalent platform block in `config.cjs`.