@maccesar/titools 2.9.0 → 2.10.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.
@@ -30,6 +30,7 @@ import { formatList, isTitaniumProject } from '../utils.js';
30
30
  import { getAgentsSkillsDir } from '../config.js';
31
31
  import { existsSync } from 'fs';
32
32
  import { join, resolve } from 'path';
33
+ import os from 'os';
33
34
 
34
35
  /**
35
36
  * Check if a platform has any skill symlinks installed
@@ -105,7 +106,9 @@ export async function updateCommand(options) {
105
106
  if (!options.local) {
106
107
  const projectDir = process.cwd();
107
108
  const isProject = isTitaniumProject(projectDir);
108
- const hasLocalSkills = isProject && hasSkillsAt(projectDir);
109
+ // When cwd === home, "local" and "global" point to the same .agents/skills dir
110
+ const isHomeDir = projectDir === os.homedir();
111
+ const hasLocalSkills = !isHomeDir && isProject && hasSkillsAt(projectDir);
109
112
  const hasGlobalSkills = hasSkillsAt(undefined);
110
113
 
111
114
  // Only show prompt if BOTH local and global skills exist
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maccesar/titools",
3
- "version": "2.9.0",
3
+ "version": "2.10.1",
4
4
  "description": "Titanium SDK skills and agents for AI coding assistants (Claude Code, Gemini CLI, Codex CLI)",
5
5
  "main": "lib/index.js",
6
6
  "type": "module",
@@ -112,13 +112,35 @@ purgetss create 'MyApp' -d -v fa
112
112
  # -v: Copy icon fonts (fa, mi, ms, f7)
113
113
  ```
114
114
 
115
- ## What's New in v7.6.0
115
+ ## What's New in v7.9.0
116
116
 
117
- - `brand` command complete Titanium branding set (launcher icons, adaptive, iOS 18+ Dark/Tinted, marketplace) from logos in `./purgetss/brand/`
118
- - `images` commandmulti-density UI images (Android res-*dpi + iPhone @1x/@2x/@3x) from `./purgetss/images/`
119
- - `semantic` command Titanium semantic colors for Light/Dark mode (palette mode + single mode)
120
- - `brand:` and `images:` config sections auto-injected into older configs
121
- - Percentages as strings (`'15%'`) for self-documenting clarity in brand/images configs
117
+ - Opacity modifier on semantic colors — `bg-surface/65` syntax now works for any class mapped through `theme.extend.colors`. PurgeTSS auto-derives `<originalKey>_<alphaPercent>` entries in `semantic.colors.json` per mode (light/dark). See [Semantic Colors Opacity modifier auto-derivation](references/semantic-colors.md#opacity-modifier-auto-derivation). **Native rebuild required** — Liveview hot-reload alone does not refresh `semantic.colors.json`
118
+ - `theme.Window` / `theme.View` / `theme.ImageView` presets now use **replace mode** they no longer carry framework defaults (white background, `Ti.UI.SIZE`, iOS `hires: true`). This fixes gradient ghosting where a preset Window with `bg-gradient-*` apply was being covered by the implicit `backgroundColor: '#FFFFFF'`. Use `theme.extend.Window` / `theme.extend.View` / `theme.extend.ImageView` when you want **extend mode** (merge with defaults). See [Apply Directive → Extend mode vs replace mode](references/apply-directive.md#extend-mode-vs-replace-mode)
119
+ - Glossary path renamed: `purgetss/experimental/tailwind-classes/` `purgetss/glossary/tailwind-classes/`
120
+
121
+ ## What's New in v7.8.0
122
+
123
+ - `purgetss images --width <n>` — pin SVG output to a specific base width; PurgeTSS derives per-density assets from the multiplier scale (×1 / ×1.5 / ×2 / ×3 / ×4). Range `[1, 8192]`. CLI-only (no `images:` config equivalent — width is per-asset). See [Multi-Density Images → Pinning the output width with --width](references/multi-density-images.md#pinning-the-output-width-with---width)
124
+ - Class syntax pre-validation — the build now emits a `Class Syntax Error` block (file path + line + `Fix:` suggestion) for 5 detected patterns: inverted negative sign (`top-(-10)` → `-top-(10)`), Tailwind brackets (`top-[10px]` → `top-(10px)`), empty parens (`wh-()`), whitespace inside parens (`wh-( 200 )` → `wh-(200)`), redundant `px` unit (`top-(10px)` → `top-(10)`). See [Arbitrary Values → Class syntax pre-validation](references/arbitrary-values.md#class-syntax-pre-validation)
125
+ - Parser fix for negative values inside parentheses — `top-(-10)` is now correctly flagged as inverted-negative-sign instead of silently misparsed
126
+
127
+ ## What's New in v7.7.0
128
+
129
+ - `brand:` config restructured — flat keys replaced by purpose-based groups: `brand.logos`, `brand.padding`, `brand.android`, `brand.ios`, `brand.colors`
130
+ - Separate Android brand inputs — `logos.androidLauncher` / `--icon-logo` for Android launcher icons; `logos.androidSplash` / `--splash-logo` for Android 12+ splash artwork. Drop `logo-icon.*` and `logo-splash.*` into `purgetss/brand/`
131
+ - `--android-adaptive-padding` (default `19%`) and `--android-legacy-padding` (default `10%`) replace the single `--padding`. The shortcut `--padding` now sets both Android paddings to the same value for one run
132
+ - Legacy Android splash fallback regenerated — `app/assets/android/default.png` (Alloy) or `Resources/android/default.png` (Classic). `cleanup-legacy` no longer removes `default.png`
133
+ - New official doc: [Values and Units](references/values-and-units.md) — explains `ti.ui.defaultunit` interpretation of PurgeTSS unitless values
134
+
135
+ ## What's New in v7.6.x
136
+
137
+ - `brand` command — complete Titanium branding set (launcher icons, adaptive, iOS 18+ Dark/Tinted, marketplace) from logos in `./purgetss/brand/` (v7.6.0)
138
+ - `images` command — multi-density UI images (Android res-*dpi + iPhone @1x/@2x/@3x) from `./purgetss/images/` (v7.6.0)
139
+ - `semantic` command — Titanium semantic colors for Light/Dark mode (palette mode + single mode) (v7.6.0)
140
+ - `brand:` and `images:` config sections auto-injected into older configs (v7.6.0)
141
+ - Percentages as strings (`'15%'`) for self-documenting clarity in brand/images configs (v7.6.0)
142
+ - Confirmation prompt for destructive writes in `brand` / `images` (`y` / `N` / `a`); auto-skipped on non-TTY, with `-y`, or `PURGETSS_YES=1` (v7.6.1)
143
+ - `semantic` command works in Classic projects — writes to `Resources/semantic.colors.json` (v7.6.2)
122
144
 
123
145
  ## What's New in v7.5.3
124
146
 
@@ -401,6 +423,7 @@ purgetss create 'MyApp' -d -v fa
401
423
  > - [Installation & Setup](references/installation-setup.md) - First run, VS Code, LiveView
402
424
  > - [CLI Commands](references/cli-commands.md) - All `purgetss` commands
403
425
  > - [Migration Guide](references/migration-guide.md) - Migrating existing apps from manual TSS to PurgeTSS
426
+ > - **[Values and Units](references/values-and-units.md)** - How `ti.ui.defaultunit` in `tiapp.xml` interprets the unitless numeric values PurgeTSS writes (foundational concept for spacing, sizes, typography)
404
427
  >
405
428
  > ### Customization
406
429
  > - [Deep Customization](references/customization-deep-dive.md) - config.cjs, colors, spacing, Ti Elements
@@ -238,15 +238,6 @@ const { saveComponent } = require('purgetss.ui')
238
238
  saveComponent({ source: $.myView, directory: 'screenshots' })
239
239
  ```
240
240
 
241
- ### createAnimation(args)
242
-
243
- Factory function to create Animation objects programmatically.
244
-
245
- ```javascript
246
- const { createAnimation } = require('purgetss.ui')
247
- const anim = createAnimation({ duration: 300, curve: Ti.UI.ANIMATION_CURVE_EASE_IN_OUT })
248
- ```
249
-
250
241
  ---
251
242
 
252
243
  ## Implementation Rules
@@ -1,6 +1,6 @@
1
1
  # App Icons & Branding
2
2
 
3
- The `purgetss brand` command (shipped in PurgeTSS v7.6.0) generates the complete Titanium branding set from a single SVG or PNG logo: launcher icons across every Android density, the adaptive-icon trio (foreground + background + monochrome), iOS 18+ Dark and Tinted variants, marketplace artwork, and optional notification/splash icons. Alloy and Classic layouts are auto-detected.
3
+ The `purgetss brand` command (introduced in PurgeTSS v7.6.0, restructured in v7.7.0) generates the complete Titanium branding set from a single SVG or PNG logo — with optional Android-specific overrides when you need them: launcher icons across every Android density, the adaptive-icon trio (foreground + background + monochrome), iOS 18+ Dark and Tinted variants, marketplace artwork, and optional notification/splash icons. Alloy and Classic layouts are auto-detected.
4
4
 
5
5
  For the terse flag reference, see the [`brand` command reference](./cli-commands.md#brand-command). For sibling UI assets, see [Multi-Density Images](./multi-density-images.md).
6
6
 
@@ -41,22 +41,30 @@ PurgeTSS auto-discovers logo files under this folder, the same way `purgetss/fon
41
41
  ```text
42
42
  purgetss/brand/
43
43
  ├── logo.svg required — main logo (or logo.png)
44
+ ├── logo-icon.svg optional — square Android launcher mark
44
45
  ├── logo-mono.svg optional — monochrome layer + notifications
45
46
  ├── logo-dark.svg optional — iOS 18+ dark variant
47
+ ├── logo-splash.svg optional — Android 12+ splash icon override
46
48
  └── logo-tinted.svg optional — iOS 18+ tinted variant
47
49
  ```
48
50
 
49
- Only `logo.svg` (or `logo.png`) is required. The other three are **opt-in refinements**:
51
+ Only `logo.svg` (or `logo.png`) is required. Everything else is **opt-in refinement**:
50
52
 
51
53
  | File | Required? | What it's for | Fallback when omitted |
52
54
  | --- | --- | --- | --- |
53
55
  | `logo.svg` / `logo.png` | **Required** | Main colored logo. Feeds every density and variant. | — |
56
+ | `logo-icon.svg` / `.png` | Optional | Square Android launcher mark — use when `logo.svg` is a wide wordmark or non-square lockup. | Main logo is reused for Android launcher icons. |
54
57
  | `logo-mono.svg` / `.png` | Optional | Android adaptive monochrome layer (themed icons on Android 13+) and notification icons. | Main logo is whitened automatically. |
58
+ | `logo-splash.svg` / `.png` | Optional | Android 12+ `splash_icon.png` artwork (only used when `--splash` / `android.splash: true`). | Falls back to the launcher artwork. |
55
59
  | `logo-dark.svg` / `.png` | Optional | iOS 18+ Dark appearance variant. | Main logo on a transparent background (Apple HIG default). |
56
60
  | `logo-tinted.svg` / `.png` | Optional | iOS 18+ Tinted appearance variant. | Grayscale of the main logo on black. |
57
61
 
62
+ Provide a dedicated `logo-icon` when the main logo is a horizontal wordmark, a vertical lockup, or anything else that looks fine in a 1024×1024 branding canvas but feels cramped inside an Android launcher mask.
63
+
58
64
  Provide a dedicated `logo-mono` when the colored logo has detail that would collapse into a featureless blob under naive whitening (e.g. a painter's palette with colored dots — the monochrome variant should have cutouts instead).
59
65
 
66
+ Provide a dedicated `logo-splash` when the Android 12+ splash should use a different composition than the launcher icon. PurgeTSS generates the file, but Titanium still needs a custom Android splash theme if you want the system splash to use it instead of `ic_launcher`.
67
+
60
68
  Provide a dedicated `logo-dark` when dark-mode brand guidelines use a different lockup or color treatment; provide `logo-tinted` when you want a pre-simplified silhouette that tints better than a naive grayscale of the colored version.
61
69
 
62
70
  > **INFO**
@@ -76,40 +84,106 @@ Or in `purgetss/config.cjs`:
76
84
 
77
85
  ```javascript
78
86
  brand: {
79
- logo: './docs/snap-logo.svg',
80
- monochromeLogo: './docs/snap-logo-mono.svg'
87
+ logos: {
88
+ primary: './docs/snap-logo.svg',
89
+ androidLauncher: './docs/snap-app-icon.svg',
90
+ monochrome: './docs/snap-logo-mono.svg'
91
+ }
81
92
  }
82
93
  ```
83
94
 
84
95
  Precedence: **CLI flags win over config values, and config values win over auto-discovery.**
85
96
 
86
- ## The `brand:` config section
97
+ ## The `brand:` config section (v7.7.0 grouped structure)
87
98
 
88
- On the first run, `purgetss brand` injects a `brand:` block into your existing `purgetss/config.cjs` (between `purge:` and `theme:`) with these defaults:
99
+ On the first run, `purgetss brand` injects a `brand:` block into your existing `purgetss/config.cjs` (between `purge:` and `theme:`) with these defaults. The structure is grouped by purpose:
89
100
 
90
101
  ```javascript
91
102
  brand: {
92
- splash: false, // also generate splash_icon.png × 5
93
- padding: '15%', // Android safe-zone. Range: 12% tight (mature logos) 20% conservative. Spec floor 19.44%.
94
- iosPadding: '4%', // iOS aesthetic. Range: 2% bold — 8% conservative. No launcher mask.
95
- darkBgColor: null, // opaque dark bg for DefaultIcon-Dark.png (null = transparent per Apple HIG)
96
- bgColor: '#FFFFFF', // Android adaptive bg + iOS/marketplace flatten
97
- notification: false, // also generate ic_stat_notify.png × 5
103
+ logos: {
104
+ // Optional overrides. If omitted, PurgeTSS auto-discovers files from purgetss/brand/:
105
+ // primary: './docs/logo.svg',
106
+ // androidLauncher: './docs/app-icon.svg',
107
+ // androidSplash: './docs/splash.svg',
108
+ // monochrome: './docs/logo-mono.svg',
109
+ // iosDark: './docs/logo-dark.svg',
110
+ // iosTinted: './docs/logo-tinted.svg'
111
+ },
112
+ padding: {
113
+ ios: '4%', // iOS aesthetic padding. Range 2-8%. No launcher mask.
114
+ androidLegacy: '10%', // legacy ic_launcher.png padding %
115
+ androidAdaptive: '19%' // adaptive icon safe-zone %. Spec floor 19.44%.
116
+ },
117
+ android: {
118
+ splash: false, // also generate splash_icon.png × 5
119
+ notification: false // also generate ic_stat_notify.png × 5
120
+ },
121
+ colors: {
122
+ background: '#FFFFFF' // Android adaptive bg + iOS/marketplace flatten
123
+ },
124
+ // Optional iOS overrides:
125
+ // ios: {
126
+ // dark: false, // skip DefaultIcon-Dark.png
127
+ // tinted: false, // skip DefaultIcon-Tinted.png
128
+ // darkBackground: '#111' // opaque dark bg for DefaultIcon-Dark.png (null = transparent per Apple HIG)
129
+ // },
98
130
  confirmOverwrites: true // prompt before overwriting files (set false to skip)
99
131
  }
100
132
  ```
101
133
 
134
+ The recommended workflow is convention-first: drop files in `purgetss/brand/`, let auto-discovery pick them up, and only set `brand.logos.*` when you have a persistent override. CLI flags still win for one-off runs.
135
+
136
+ ### `brand.logos`
137
+
138
+ All `logos.*` keys are optional path overrides. If you omit them, PurgeTSS auto-discovers files from `purgetss/brand/`.
139
+
140
+ | Key | Auto-discovers | Purpose |
141
+ | --- | --- | --- |
142
+ | `logos.primary` | `purgetss/brand/logo.svg` | Main brand source. |
143
+ | `logos.androidLauncher` | `purgetss/brand/logo-icon.svg` | Square Android launcher mark — use when the main logo is a wordmark. |
144
+ | `logos.androidSplash` | `purgetss/brand/logo-splash.svg` | Android 12+ splash artwork. |
145
+ | `logos.monochrome` | `purgetss/brand/logo-mono.svg` | Android themed icons + notification icons. |
146
+ | `logos.iosDark` | `purgetss/brand/logo-dark.svg` | iOS dark variant. |
147
+ | `logos.iosTinted` | `purgetss/brand/logo-tinted.svg` | iOS tinted variant. |
148
+
149
+ ### `brand.padding`
150
+
151
+ All padding values accept either numbers or percentage strings like `'19%'`.
152
+
102
153
  | Key | Default | Purpose |
103
154
  | --- | --- | --- |
104
- | `splash` | `false` | When `true`, also emits `splash_icon.png` × 5 densities. |
105
- | `padding` | `'15%'` | Per-side safe-zone padding inside the 1024×1024 Android canvas. |
106
- | `iosPadding` | `'4%'` | Aesthetic padding for the iOS square icon. Smaller than Android because iOS has no launcher mask. |
107
- | `darkBgColor` | `null` | Opaque background baked into `DefaultIcon-Dark.png`. `null` = transparent per Apple HIG (iOS paints its own gradient). |
108
- | `bgColor` | `'#FFFFFF'` | Triple-purpose (see [Brand color](#brand-color) below). |
109
- | `notification` | `false` | When `true`, also emits `ic_stat_notify.png` × 5 densities. |
110
- | `confirmOverwrites` | `true` | When `false`, the `[y/N/a]` prompt is skipped. |
155
+ | `padding.ios` | `'4%'` | Visual inset for `DefaultIcon-ios.png`, `DefaultIcon-Dark.png`, `DefaultIcon-Tinted.png`, marketplace artwork. |
156
+ | `padding.androidLegacy` | `'10%'` | Visual inset for legacy `ic_launcher.png`. |
157
+ | `padding.androidAdaptive` | `'19%'` | Visual inset for adaptive Android foreground (`ic_launcher_foreground.png`). Adjust this first when icons look cropped inside launcher masks. |
158
+
159
+ ### `brand.android`
160
+
161
+ | Key | Default | Purpose |
162
+ | --- | --- | --- |
163
+ | `android.splash` | `false` | When `true`, also generates `drawable-*/splash_icon.png`. |
164
+ | `android.notification` | `false` | When `true`, also generates `drawable-*/ic_stat_notify.png`. |
165
+
166
+ ### `brand.ios` (optional)
111
167
 
112
- Change whatever you want to override globally; CLI flags still win for one-off runs.
168
+ If omitted, PurgeTSS behaves as if `ios.dark = true`, `ios.tinted = true`, `ios.darkBackground = null`.
169
+
170
+ | Key | Default | Purpose |
171
+ | --- | --- | --- |
172
+ | `ios.dark` | `true` | Set to `false` to skip `DefaultIcon-Dark.png`. |
173
+ | `ios.tinted` | `true` | Set to `false` to skip `DefaultIcon-Tinted.png`. |
174
+ | `ios.darkBackground` | `null` | When `null`, `DefaultIcon-Dark.png` stays transparent per Apple HIG. Set a hex to bake in an opaque dark background. |
175
+
176
+ ### `brand.colors`
177
+
178
+ | Key | Default | Purpose |
179
+ | --- | --- | --- |
180
+ | `colors.background` | `'#FFFFFF'` | Triple-purpose: Android adaptive background layer, iOS alpha flatten for `DefaultIcon-ios.png`, marketplace flatten for `iTunesConnect.png` / `MarketplaceArtwork.png` when overridden. |
181
+
182
+ ### `brand.confirmOverwrites`
183
+
184
+ | Key | Default | Purpose |
185
+ | --- | --- | --- |
186
+ | `confirmOverwrites` | `true` | When `false`, the `[y/N/a]` prompt is skipped. |
113
187
 
114
188
  ## Overwrite confirmation
115
189
 
@@ -151,14 +225,17 @@ The output is automatically routed to the right directory for your project layou
151
225
  ├── iTunesConnect.png ← 1024×1024, App Store submission
152
226
  ├── MarketplaceArtwork.png ← 512×512, Google Play submission
153
227
  └── app/
154
- └── assets/android/res/
155
- ├── mipmap-mdpi/ 108×108 foreground + background + monochrome + legacy
156
- ├── mipmap-hdpi/ ← 162×162
157
- ├── mipmap-xhdpi/ 216×216
158
- ├── mipmap-xxhdpi/ 324×324
159
- ├── mipmap-xxxhdpi/ 432×432
160
- └── mipmap-anydpi-v26/
161
- └── ic_launcher.xmladaptive-icon binder
228
+ └── assets/android/
229
+ ├── default.png legacy Titanium Android splash fallback (v7.7.0)
230
+ └── res/
231
+ ├── mipmap-mdpi/ 108×108 foreground + background + monochrome + legacy
232
+ ├── mipmap-hdpi/ 162×162
233
+ ├── mipmap-xhdpi/ 216×216
234
+ ├── mipmap-xxhdpi/ ← 324×324
235
+ ├── mipmap-xxxhdpi/432×432
236
+ ├── drawable-*/ ← optional splash_icon.png when --splash is enabled
237
+ └── mipmap-anydpi-v26/
238
+ └── ic_launcher.xml ← adaptive-icon binder
162
239
  ```
163
240
 
164
241
  **Classic layout:**
@@ -166,12 +243,21 @@ The output is automatically routed to the right directory for your project layou
166
243
  ```text
167
244
  <project>/
168
245
  ├── DefaultIcon.png DefaultIcon-ios.png ... ← same root-level files as Alloy
246
+ ├── Resources/
247
+ │ └── android/default.png ← legacy Titanium Android splash fallback (v7.7.0)
169
248
  └── platform/
170
249
  └── android/res/
171
250
  ├── mipmap-*/ ← same 5 densities as Alloy
251
+ ├── drawable-*/ ← optional splash_icon.png when --splash is enabled
172
252
  └── mipmap-anydpi-v26/ic_launcher.xml
173
253
  ```
174
254
 
255
+ The Android outputs are related, but they are not interchangeable:
256
+
257
+ - `ic_launcher*` drives the app icon, and by default also feeds the Android 12+ system splash
258
+ - `splash_icon.png` is only generated when you ask for it with `--splash`
259
+ - `default.png` is the older Titanium Android splash fallback (regenerated since v7.7.0)
260
+
175
261
  ## Android dark mode
176
262
 
177
263
  > **INFO**
@@ -190,6 +276,47 @@ purgetss brand
190
276
 
191
277
  The monochrome layer is pure white (`RGB 255,255,255`) with alpha preserved. Android applies the user's tint on top at render time.
192
278
 
279
+ ## Android 12+ splash artwork
280
+
281
+ If you pass `--splash`, PurgeTSS generates `drawable-*/splash_icon.png` across Android densities.
282
+
283
+ ```bash
284
+ purgetss brand --splash
285
+ ```
286
+
287
+ If you want that artwork to differ from the launcher icon, provide `logo-splash.svg` or set `brand.logos.androidSplash`:
288
+
289
+ ```javascript
290
+ brand: {
291
+ android: {
292
+ splash: true
293
+ },
294
+ logos: {
295
+ androidSplash: './docs/snap-splash-mark.svg'
296
+ }
297
+ }
298
+ ```
299
+
300
+ > **INFO**
301
+ >
302
+ > Generating `splash_icon.png` does not automatically switch Titanium to use it for the Android 12+ system splash. Titanium still needs a custom splash theme that points `android:windowSplashScreenAnimatedIcon` to `@drawable/splash_icon`. If you do nothing, Android keeps using `ic_launcher`.
303
+
304
+ > **WARNING**
305
+ >
306
+ > Merge splash settings into the existing Android theme
307
+ > If your app already has a custom Android theme block in `tiapp.xml`, **merge** the new splash settings (the `android:windowSplashScreenAnimatedIcon` entry and any sibling theme attributes) into that existing theme. Do **not** append a second `<application>` element or a duplicate theme block — Titanium will only honor one theme definition, and the duplicate silently shadows or overrides the original, leading to "my settings were ignored" debugging sessions. Always edit the existing `<application>` / theme block in place.
308
+
309
+ > **INFO**
310
+ >
311
+ > A brief flash on splash exit is usually the system, not your PNGs
312
+ > If you still see a brief flash or abrupt exit transition during splash dismissal even with correct assets in place, **do not assume the PNGs PurgeTSS generates are wrong**. That artifact commonly comes from Android 12+'s system splash exit transition (or from Titanium's splash theme handoff to your first window), not from the splash icon files themselves. Regenerating `splash_icon.png` will not change it — the fix lives in the splash theme animation, not in the icon assets.
313
+
314
+ ## Android legacy splash fallback
315
+
316
+ Since v7.7.0, PurgeTSS regenerates `app/assets/android/default.png` in Alloy projects and `Resources/android/default.png` in Classic projects.
317
+
318
+ That file still matters as a fallback on older Titanium Android splash paths, which is why `cleanup-legacy` no longer removes it.
319
+
193
320
  ## iOS 18+ Dark and Tinted variants
194
321
 
195
322
  iOS 18 added two appearance variants on top of the standard app icon: **Dark** (for the dark appearance of the Home Screen) and **Tinted** (for the user-accent-colored mode).
@@ -232,18 +359,32 @@ If you never pass the flag, background stays `#FFFFFF` and the marketplace artwo
232
359
 
233
360
  ## Padding guidance
234
361
 
235
- `--padding` controls how much safe-zone padding (per side, expressed as a percentage) surrounds the logo inside the Android adaptive canvas. The default `15%` matches real-world production apps like Gmail and Chrome.
362
+ Since v7.7.0, PurgeTSS treats Android adaptive and Android legacy launcher icons as two related but different cases:
363
+
364
+ - `brand.padding.androidAdaptive` or `--android-adaptive-padding` for the adaptive foreground
365
+ - `brand.padding.androidLegacy` or `--android-legacy-padding` for `ic_launcher.png`
366
+ - `--padding` is a one-shot **shortcut** that sets both Android paddings to the same value for one run
236
367
 
237
- | Padding | Logo fill | When to use |
368
+ The adaptive default is `19%`, which stays close to the Android safe-zone. The legacy default is `10%`, so the flat `ic_launcher.png` can keep a little more visual weight.
369
+
370
+ ### Adaptive icon padding
371
+
372
+ | Padding | Logo fill | When to use |
238
373
  | ------- | --------- | ------------------------------------------------------------------------------------------------------ |
239
- | `12%` | 76% | Logos with built-in breathing room (circular wordmarks, letterforms inside a shape). Tight, bold look. |
240
- | `15%` | 70% | **Default**. Balanced, safe on Pixel, Oppo, Samsung, OneUI, and Nova. |
241
- | `18%` | 64% | Defensive: for intricate logos, fine serifs, multi-element designs. |
242
- | `20%` | 60% | Conservative, spec-compliant. Safe on every launcher, including legacy aggressive masks. |
374
+ | `15%` | 70% | Aggressive. Better for square symbols with lots of built-in breathing room. |
375
+ | `18%` | 64% | Defensive: for intricate logos, fine serifs, multi-element designs. |
376
+ | `19%` | 62% | **Default**. Close to the Android safe-zone and safer for adaptive masks. |
377
+ | `20%` | 60% | Conservative, spec-compliant. Safe on every launcher, including aggressive masks. |
243
378
 
244
379
  A useful visual check is the "corners" heuristic: imagine a circle inscribed in your 1024×1024 canvas with the given padding. If your logo's outermost corners fit inside that circle, you're safe on circular launchers (Pixel default, Oppo Android 15). If they poke out, they'll be clipped.
245
380
 
246
- The official Android spec floor is `19.44%` (108dp canvas, 66dp inscribed safe-zone circle). Modern launchers are more permissive: Gmail and Chrome ship at 10–14%, which is why `15%` is the default. The 19.44% floor is the theoretical worst-case for aggressive masks; if you're worried about legacy Samsung teardrop masks or similar, bump to `--padding 20` to stay inside the spec.
381
+ The official Android spec floor is `19.44%` (108dp canvas, 66dp inscribed safe-zone circle). That is the theoretical worst-case for aggressive adaptive masks, which is why the adaptive default now sits close to it.
382
+
383
+ ### Legacy icon padding
384
+
385
+ Legacy `ic_launcher.png` does not go through the same adaptive mask, so it can usually run tighter. That is why the default for `brand.padding.androidLegacy` is `10%`.
386
+
387
+ ### iOS padding
247
388
 
248
389
  `--ios-padding` is a separate lever — iOS has no launcher mask, so the range is different:
249
390
 
@@ -280,28 +421,42 @@ purgetss brand --cleanup-legacy --aggressive
280
421
  > Commit first
281
422
  > `--cleanup-legacy` deletes files permanently. Commit your project to git before running without `--dry-run` so `git restore` is available as a rollback.
282
423
 
424
+ > **INFO**
425
+ >
426
+ > Files kept on purpose
427
+ > `--cleanup-legacy` intentionally does **not** remove the following files, even when modern adaptive launcher icons and splash assets are already in place:
428
+ >
429
+ > - `app/assets/android/default.png` (Alloy projects)
430
+ > - `Resources/android/default.png` (Classic projects)
431
+ >
432
+ > These remain because they are still required by Titanium framework defaults — older Android splash code paths fall back to `default.png`, and removing it can cause build warnings or a missing-asset error on certain Titanium SDK versions even when modern splash assets exist. Treat them as part of the baseline asset set, not as legacy clutter.
433
+
283
434
  ## Troubleshooting
284
435
 
285
436
  ### The icon looks cropped or cramped on my phone
286
437
 
287
- Your logo is probably landing too close to the launcher mask. Increase `--padding`:
438
+ Your adaptive foreground is probably landing too close to the launcher mask. Increase `--android-adaptive-padding`:
288
439
 
289
440
  ```bash
290
- purgetss brand --padding 20
441
+ purgetss brand --android-adaptive-padding 20
291
442
  ```
292
443
 
293
444
  Or set it in the config:
294
445
 
295
446
  ```javascript
296
- brand: { padding: '20%' }
447
+ brand: {
448
+ padding: {
449
+ androidAdaptive: '20%'
450
+ }
451
+ }
297
452
  ```
298
453
 
299
454
  ### The icon looks tiny / lost in the middle
300
455
 
301
- Padding is too generous. Lower it:
456
+ Adaptive padding is probably too generous. Lower it:
302
457
 
303
458
  ```bash
304
- purgetss brand --padding 12
459
+ purgetss brand --android-adaptive-padding 17
305
460
  ```
306
461
 
307
462
  ### The monochrome version looks like a white blob
@@ -355,7 +510,9 @@ All 5 Android densities, marketplace artwork, and iOS variants regenerate in one
355
510
  | Flag | Purpose |
356
511
  | --- | --- |
357
512
  | `--bg-color <hex>` | Background color for Android adaptive + iOS/marketplace flatten. |
358
- | `--padding <n>` | Android safe-zone % (range `12–20`, default `15`). |
513
+ | `--padding <n>` | Shortcut: sets BOTH Android paddings to the same value for one run. |
514
+ | `--android-adaptive-padding <n>` | Adaptive icon safe-zone % (default `19`). |
515
+ | `--android-legacy-padding <n>` | Legacy `ic_launcher.png` padding % (default `10`). |
359
516
  | `--ios-padding <n>` | iOS aesthetic padding % (range `2–8`, default `4`). |
360
517
 
361
518
  **Optional asset types**
@@ -369,9 +526,11 @@ All 5 Android densities, marketplace artwork, and iOS variants regenerate in one
369
526
 
370
527
  | Flag | Purpose |
371
528
  | --- | --- |
529
+ | `--icon-logo <path>` | Override `purgetss/brand/logo-icon.{svg,png}` for Android launcher icons. |
372
530
  | `--monochrome-logo <path>` | Override `purgetss/brand/logo-mono.{svg,png}`. |
373
531
  | `--dark-logo <path>` | Override `purgetss/brand/logo-dark.{svg,png}`. |
374
532
  | `--dark-bg-color <hex>` | Opaque dark bg for `DefaultIcon-Dark.png` (default: transparent per Apple HIG). |
533
+ | `--splash-logo <path>` | Override `purgetss/brand/logo-splash.{svg,png}` for Android 12+ splash artwork. |
375
534
  | `--tinted-logo <path>` | Override `purgetss/brand/logo-tinted.{svg,png}`. |
376
535
  | `--no-dark` | Skip `DefaultIcon-Dark.png`. |
377
536
  | `--no-tinted` | Skip `DefaultIcon-Tinted.png`. |
@@ -380,7 +539,7 @@ All 5 Android densities, marketplace artwork, and iOS variants regenerate in one
380
539
 
381
540
  | Flag | Purpose |
382
541
  | --- | --- |
383
- | `--cleanup-legacy` | Remove obsolete branding artifacts (reads `tiapp.xml` for safety rules). |
542
+ | `--cleanup-legacy` | Remove obsolete branding artifacts (reads `tiapp.xml` for safety rules). Keeps `default.png` on purpose. |
384
543
  | `--aggressive` | With `--cleanup-legacy`, also remove `ldpi` density folders. |
385
544
 
386
545
  **Diagnostics**
@@ -393,18 +552,21 @@ All 5 Android densities, marketplace artwork, and iOS variants regenerate in one
393
552
  ### Examples
394
553
 
395
554
  ```bash
396
- purgetss brand # uses purgetss/brand/logo.svg + config
397
- purgetss brand --bg-color "#0B1326" # override bg color
398
- purgetss brand --notification --splash # add notification + splash
399
- purgetss brand --no-tinted # skip iOS 18+ tinted variant
400
- purgetss brand --dry-run # preview without writing
401
- purgetss brand --cleanup-legacy --dry-run # preview legacy cleanup
555
+ purgetss brand # uses purgetss/brand/logo.svg + config
556
+ purgetss brand --bg-color "#0B1326" # override bg color
557
+ purgetss brand --icon-logo ./docs/app-icon.svg # dedicated square Android launcher mark
558
+ purgetss brand --splash --splash-logo ./docs/splash.svg # custom Android 12+ splash artwork
559
+ purgetss brand --notification --splash # add notification + splash
560
+ purgetss brand --no-tinted # skip iOS 18+ tinted variant
561
+ purgetss brand --dry-run # preview without writing
562
+ purgetss brand --cleanup-legacy --dry-run # preview legacy cleanup
402
563
  ```
403
564
 
404
565
  ## Community-Discovered Patterns
405
566
 
406
567
  - **Titanium SDK wiring lag for iOS 18+ variants.** Titanium SDK currently wires `DefaultIcon-ios.png` into the generated appiconset automatically, but `DefaultIcon-Dark.png` and `DefaultIcon-Tinted.png` are not picked up yet. Until [tidev/titanium-sdk#14122](https://github.com/tidev/titanium-sdk/issues/14122) merges, the practical workaround is: run `ti build -p ios` once, then open `build/iphone/Assets.xcassets/AppIcon.appiconset/` in Xcode and drag the two PNGs into the "Appearance" column of the asset catalog editor. The generated PNGs are already named and sized correctly — no resizing needed.
407
- - **Modern launchers ship tighter than the spec.** The Android adaptive-icon spec floor is `19.44%` padding, but shipped apps like Gmail and Chrome use `10–14%`. PurgeTSS's `15%` default sits in that real-world range rather than the conservative spec floor, which is why icons look tight-but-balanced out of the box.
568
+ - **Wordmark logos need a separate launcher mark.** When `logo.svg` is a wide wordmark or vertical lockup, it tends to look cramped inside Android launcher masks. Drop a square `logo-icon.svg` (or set `brand.logos.androidLauncher`) and the launcher icons get the dedicated mark while the rest of the brand set still uses the main logo. Same idea applies to Android 12+ splash with `logo-splash.svg`.
569
+ - **Three Android assets, three different jobs.** `ic_launcher*` drives the app icon and the default Android 12+ splash; `splash_icon.png` is generated only when you pass `--splash` and Titanium needs an explicit splash theme to actually use it; `default.png` is the older Titanium Android splash fallback (regenerated since v7.7.0, intentionally kept by `cleanup-legacy`). Knowing which file does what saves a lot of "but the icon didn't change" debugging.
408
570
 
409
571
  ## See also
410
572