@maccesar/titools 4.17.0 → 4.18.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.
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  </div>
8
8
 
9
- TiTools is a Titanium SDK toolkit for AI coding assistants. It ships 10 skills — 5 specialist skills (`ti-expert`, `purgetss`, `ti-ui`, `ti-game`, `ti-synthengine`) plus 5 documentation-mirror skills (`ti-api`, `ti-guides`, `ti-howtos`, `alloy-guides`, `alloy-howtos`) — a research agent, and reference files covering Titanium architecture, API reference, native how-tos, Alloy MVC, PurgeTSS styling, UI/UX patterns, 2D games, and native sound synthesis.
9
+ TiTools is a Titanium SDK toolkit for AI coding assistants. It ships 10 skills — 5 specialist skills (`ti-expert`, `purgetss`, `ti-ui`, `ti-game`, `ti-synthengine`) plus 5 documentation-mirror skills (`ti-api`, `ti-guides`, `ti-howtos`, `alloy-guides`, `alloy-howtos`) — a research agent, and reference files covering Titanium architecture, API reference, native how-tos, Alloy MVC, PurgeTSS styling and resource automation, UI/UX patterns, 2D games, and native sound synthesis.
10
10
 
11
11
  The reference files are maintained against official documentation whenever an official source exists, so the assistant can retrieve current framework behavior instead of guessing from generic training data.
12
12
 
@@ -175,7 +175,7 @@ The knowledge index is based on the latest Titanium SDK documentation. If your p
175
175
  | Skill | Purpose | Best For |
176
176
  | ------------ | ----------------------------------- | --------------------------------------- |
177
177
  | ti-expert | Architecture and implementation | Starting point for most tasks |
178
- | purgetss | Utility-first styling | UI styling and animations |
178
+ | purgetss | Alloy styling + asset automation | Utility classes; Alloy/Classic branding, images, colors, fonts and modules |
179
179
  | ti-ui | UI/UX patterns | Complex layouts, ListViews, platform UI |
180
180
  | ti-game | 2D games with the `ti.game` module | Sprites, physics, tile layers, wall jumps, pathfinding, text/performance HUDs, particles, camera |
181
181
  | ti-synthengine | Sound design with `ti.synthengine` | Tones, chords, retro/UI effects, alarms, sweeps, patterns, mixing and troubleshooting |
@@ -277,7 +277,7 @@ Skills are automatically activated based on your questions. Just ask naturally:
277
277
 
278
278
  The AI will automatically use:
279
279
  - `ti-expert` -> Architecture and controller structure
280
- - `purgetss` -> Styling classes and animations (if PurgeTSS detected)
280
+ - `purgetss` -> Alloy styling, or supported asset/CommonJS commands in Alloy and Classic (if PurgeTSS is detected or requested)
281
281
  - `ti-howtos` -> Secure token storage and native integration guidance
282
282
 
283
283
  You do not need to call skills explicitly. The AI reads skill descriptions and loads the appropriate knowledge when needed.
@@ -288,14 +288,14 @@ All skills include automatic project detection to ensure compatibility:
288
288
 
289
289
  | Skill | What It Detects | How It Works |
290
290
  | --------- | --------------------- | ------------------------------------------------------------- |
291
- | purgetss | PurgeTSS installation | Checks for `purgetss/` folder, `config.cjs`, `utilities.tss` |
291
+ | purgetss | PurgeTSS mode and project type | Checks PurgeTSS markers, then separates Alloy utilities from Classic standalone commands |
292
292
  | ti-expert | Alloy vs Classic | Checks for `app/` (Alloy) vs `Resources/` (Classic) structure |
293
293
  | ti-ui | Titanium projects | Checks for `tiapp.xml` (both Alloy and Classic) |
294
294
  | ti-game | ti.game module | Checks for `<module>ti.game</module>` in `tiapp.xml` or `require('ti.game')` |
295
295
  | ti-synthengine | ti.synthengine module | Checks for `<module>ti.synthengine</module>` in `tiapp.xml` or `require('ti.synthengine')` |
296
296
 
297
297
  Why this matters:
298
- - PurgeTSS suggestions are only provided if PurgeTSS is installed
298
+ - PurgeTSS suggestions are provided when its project markers are detected or the user explicitly requests a standalone command
299
299
  - Alloy-specific patterns are only suggested for Alloy projects
300
300
  - Classic Titanium projects will not receive inappropriate Alloy advice
301
301
 
@@ -359,7 +359,7 @@ Key features:
359
359
 
360
360
  ### purgetss
361
361
 
362
- Utility-first styling toolkit for Titanium/Alloy.
362
+ Utility-first styling for Titanium Alloy plus standalone asset and CommonJS commands for Alloy and Classic.
363
363
 
364
364
  When it activates:
365
365
  - Setting up PurgeTSS in a project
@@ -369,6 +369,7 @@ When it activates:
369
369
  - Custom color palettes
370
370
  - Platform-specific styling
371
371
  - config.cjs configuration
372
+ - Classic `Resources/` outputs for branding, density images, semantic colors, fonts, and modules
372
373
 
373
374
  Example prompts:
374
375
  ```
@@ -378,6 +379,8 @@ Example prompts:
378
379
  "How do I configure custom colors in config.cjs?"
379
380
  "How do I use Font Awesome 7 icons?"
380
381
  "Style this button differently on iOS vs Android."
382
+ "Generate image densities for this Classic Titanium app without converting it to Alloy."
383
+ "Install Font Awesome and its CommonJS module under Resources in my Classic app."
381
384
  ```
382
385
 
383
386
  Rules:
@@ -802,7 +805,7 @@ This pattern is documented across four bundled TiTools skills: `ti-ui`, `ti-expe
802
805
  | Skill | SKILL.md | References |
803
806
  | --------- | ----------------------------- | ----------------------------------------------------- |
804
807
  | ti-expert | Architecture + Implementation | 26 files (patterns, feedback surfaces, file type association, sharing, testing, security, etc.) |
805
- | purgetss | Setup + Critical Rules | 33 files (grid, animations, icons, class-index, SVG pipeline, etc.) |
808
+ | purgetss | Setup + Critical Rules | 34 files (Classic compatibility, grid, animations, icons, class-index, SVG pipeline, etc.) |
806
809
  | ti-ui | UI Rules + Platform Diffs | 14 files (layouts, lists, gestures, etc.) |
807
810
  | ti-game | Native 2D Game Workflow | 9 files (API, setup, patterns, recipes, tile maps, debugging, roadmap) |
808
811
  | ti-synthengine | Native Sound Synthesis | 8 files (API, sound design, lifecycle, engine, official examples, curated recipes, recommendations, troubleshooting) |
@@ -831,7 +834,8 @@ If the AI suggests patterns you don't use (for example, PurgeTSS when you're not
831
834
  If the purgetss skill doesn't activate for your PurgeTSS project:
832
835
  1. Verify `purgetss/` folder exists in project root
833
836
  2. Check that `purgetss/config.cjs` exists
834
- 3. Mention "PurgeTSS" explicitly in your prompt
837
+ 3. In Classic, check for generated `Resources/lib/purgetss.*.js` modules
838
+ 4. Mention "PurgeTSS" explicitly in your prompt
835
839
 
836
840
  ### Wrong advice?
837
841
 
@@ -17,7 +17,7 @@ Project-type audit:
17
17
 
18
18
  6. If the project is Alloy (`app/views/`, `app/controllers/`, `app/styles/`), invoke `alloy-guides` — check controllers, XML/TSS, models, collections, widgets, sync adapters and cleanup patterns.
19
19
  7. If the Alloy project uses `alloy.jmk`, `config.json`, `widget.json`, conditional views, custom XML tags or Alloy CLI workflows, invoke `alloy-howtos` — check configuration precedence, build hooks, generated structures and compilation/debugging conventions.
20
- 8. If the project uses PurgeTSS (`purgetss/` or `purgetss/config.cjs`), invoke `purgetss` before evaluating styling — check unsupported utility classes, padding on Views, unnecessary manual TSS, dynamic components, grids, icons and animations.
20
+ 8. If the project uses PurgeTSS (`purgetss/`, `purgetss/config.cjs`, a PurgeTSS-generated `app.tss`, or `purgetss.{ui,colors,fonts}.js`), invoke `purgetss` and detect Alloy vs. Classic before applying findings. In Alloy, audit unsupported utility classes, padding on Views, unnecessary manual TSS, dynamic components, grids, icons and animations. In Classic, audit only the supported standalone asset/CommonJS commands and their `Resources/` outputs; do not require or recommend `alloy.jmk`, generated TSS, utility classes, or `$.UI.create()`.
21
21
 
22
22
  Native-module audit:
23
23
 
@@ -100,7 +100,9 @@ export async function doctorCommand() {
100
100
  }
101
101
  }
102
102
  const expectedCommands = COMMANDS.length - pluginCommands.length;
103
- if (pluginCommands.length === COMMANDS.length) {
103
+ if (COMMANDS.length === 0) {
104
+ console.log(` ${CHECK} Slash commands: none (workflows ship as cross-agent skills)`);
105
+ } else if (pluginCommands.length === COMMANDS.length) {
104
106
  console.log(` ${CHECK} Slash commands: all ${COMMANDS.length} served by the marketplace plugin`);
105
107
  } else if (missingCommands.length === 0) {
106
108
  console.log(` ${CHECK} Slash commands: ${expectedCommands}/${expectedCommands} installed in ~/.claude/commands/`);
@@ -138,10 +140,13 @@ export async function doctorCommand() {
138
140
 
139
141
  for (const skill of SKILLS) {
140
142
  // A skill the marketplace plugin provides is *supposed* to have no mirror
141
- // here — the CLI removes it on purpose to avoid a duplicate entry. Counting
142
- // it as missing turns a healthy marketplace install into a wall of errors
143
- // telling the user to run a command that will correctly do nothing.
144
- if (platform.name === 'claude' && pluginProvidesSkill(skill, homeDir)) {
143
+ // here — the CLI removes it on purpose to avoid a duplicate entry. During
144
+ // command-to-skill migrations, a same-name command in an older enabled
145
+ // cache also suppresses the mirror until the marketplace refreshes.
146
+ if (
147
+ platform.name === 'claude' &&
148
+ (pluginProvidesSkill(skill, homeDir) || pluginProvidesCommand(skill, homeDir))
149
+ ) {
145
150
  servedByPlugin.push(skill);
146
151
  continue;
147
152
  }
package/lib/symlink.js CHANGED
@@ -83,8 +83,8 @@ async function removePath(path) {
83
83
  * @returns {Promise<boolean>} True if the plugin provides this skill
84
84
  */
85
85
  export async function isClaudePluginSkillInstalled(skillName, baseDir) {
86
- const { pluginProvidesSkill } = await import('./claude-plugin.js');
87
- return pluginProvidesSkill(skillName, baseDir);
86
+ const { pluginProvidesSkill, pluginProvidesCommand } = await import('./claude-plugin.js');
87
+ return pluginProvidesSkill(skillName, baseDir) || pluginProvidesCommand(skillName, baseDir);
88
88
  }
89
89
 
90
90
  /**
@@ -118,8 +118,9 @@ export async function createSkillSymlinks(platformSkillsDir, skills, baseDir) {
118
118
  const useRelative = !!baseDir;
119
119
 
120
120
  for (const skill of skills) {
121
- // Skip Claude when the marketplace plugin already provides this skill;
122
- // clean up any stale symlink left from a previous CLI install.
121
+ // Skip Claude when the marketplace plugin already provides this skill or
122
+ // still provides a same-name legacy command during a command-to-skill
123
+ // migration; clean up any stale symlink left from a previous CLI install.
123
124
  if (isClaudePlatform && await isClaudePluginSkillInstalled(skill, baseDir)) {
124
125
  const stalePath = join(platformSkillsDir, skill);
125
126
  if (existsSync(stalePath)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maccesar/titools",
3
- "version": "4.17.0",
3
+ "version": "4.18.0",
4
4
  "description": "Titanium SDK skills and agents for AI coding assistants, including native game and sound synthesis modules",
5
5
  "main": "lib/index.js",
6
6
  "type": "module",
@@ -1,22 +1,29 @@
1
1
  ---
2
2
  name: purgetss
3
- description: "Use when working with PurgeTSS, Titanium's utility-first styling toolkit — styling, reviewing, analyzing, or examining Titanium UI with utility classes, configuring config.cjs, creating dynamic components with $.UI.create(), building animations, grid layouts, icon fonts, or TSS styles. AUTO-DETECT: If purgetss/ folder or purgetss/config.cjs exists, invoke BEFORE writing ANY styling code. PurgeTSS classes look like Tailwind but are NOT Tailwind — verify every class exists. Never use padding on Views (use margins on children), never use flexbox classes, never write manual TSS when a utility class exists."
4
- argument-hint: "[class-name]"
3
+ description: "Use when a Titanium project uses PurgeTSS utility classes, purgetss/config.cjs, $.UI.create(), generated app.tss, or PurgeTSS asset, color, font, branding, and CommonJS commands. Detect Alloy vs. Classic first: the utility-class workflow is Alloy-only, while selected standalone commands write native Resources/ files in Classic. PurgeTSS resembles Tailwind but has a different class contract, so verify every suggested class."
5
4
  allowed-tools: Read, Grep, Glob, Edit, Write, Bash(purgetss *), Bash(node *)
6
5
  ---
7
6
 
8
7
  # PurgeTSS Expert
9
8
 
10
- Utility-first styling toolkit for Titanium/Alloy mobile apps.
9
+ PurgeTSS is a utility-first styling toolkit for Titanium Alloy and a standalone asset/CommonJS generator for Alloy and Classic projects. The project layout determines which half of the toolkit is valid.
11
10
 
12
11
  ## Required workflow (read before responding)
13
12
 
14
13
  The SKILL.md alone is an **index** of references. The detail you need to give accurate answers lives in the reference files. **Reading this SKILL.md is not enough.**
15
14
 
16
- ### Step 1 — Open the relevant reference files
15
+ ### Step 1 — Detect the project type
16
+
17
+ Before recommending a command, class, output path, `$.UI.create()`, TSS file, or build hook, determine whether the project is Alloy (`app/views/`, `app/controllers/`, `app/styles/`) or Classic (`Resources/` without the Alloy tree).
18
+
19
+ - **Alloy:** utility classes and every standalone command are available.
20
+ - **Classic:** only the supported standalone commands are available. Do not introduce `app/`, `alloy.jmk`, generated TSS, utility classes, or `$.UI.create()`.
21
+
22
+ ### Step 2 — Open the relevant reference files
17
23
 
18
24
  | Task involves | Required reading |
19
25
  |---|---|
26
+ | Alloy vs. Classic support or output paths | [references/classic-projects.md](references/classic-projects.md), [references/cli-commands.md](references/cli-commands.md) |
20
27
  | Choosing utility classes | [references/class-index.md](references/class-index.md) |
21
28
  | Layout (horizontal/vertical/composite, grid) | [references/grid-layout.md](references/grid-layout.md), [references/ui-ux-design.md](references/ui-ux-design.md) |
22
29
  | Dynamic components in controllers | [references/dynamic-component-creation.md](references/dynamic-component-creation.md) |
@@ -27,7 +34,7 @@ The SKILL.md alone is an **index** of references. The detail you need to give ac
27
34
  | Apply directive / class extraction | [references/apply-directive.md](references/apply-directive.md) |
28
35
  | Animations | [references/animation-system.md](references/animation-system.md) |
29
36
 
30
- ### Step 2 — Output contract
37
+ ### Step 3 — Output contract
31
38
 
32
39
  Every utility class you suggest and every styling pattern you describe MUST be backed by a citation in the form:
33
40
 
@@ -35,7 +42,7 @@ Every utility class you suggest and every styling pattern you describe MUST be b
35
42
 
36
43
  Example: *"Use `wh-12` to set width and height to 48px [source: references/class-index.md]"*
37
44
 
38
- ### Step 3 — If you must answer from memory
45
+ ### Step 4 — If you must answer from memory
39
46
 
40
47
  If you write a claim without having read the reference that backs it, prepend `FROM_MEMORY (unverified):` to that claim. Do not hide it.
41
48
 
@@ -45,31 +52,42 @@ If you write a claim without having read the reference that backs it, prepend `F
45
52
  - ❌ Confusing PurgeTSS classes with Tailwind — they share naming but differ
46
53
  - ❌ Marking the answer complete without listing which reference files you read
47
54
  - ❌ Suggesting a class without first verifying it exists in `class-index.md`
55
+ - ❌ Applying Alloy utility classes, generated TSS, `alloy.jmk`, or `$.UI.create()` to a Classic project
48
56
 
49
- ## Project Detection
57
+ ## Project Detection and Mode Selection
50
58
 
51
59
  > **️ℹ️ AUTO-DETECTS PURGETSS PROJECTS**
52
60
  > This skill automatically detects PurgeTSS usage when invoked and provides utility-first styling guidance.
53
61
  >
54
62
  > **Detection occurs automatically** - no manual command needed.
55
63
  >
56
- > **PurgeTSS project indicators:**
64
+ > **PurgeTSS indicators:**
57
65
  > - `purgetss/` folder
58
66
  > - `purgetss/config.cjs` configuration file
59
67
  > - `purgetss/styles/utilities.tss` utility classes
60
- > - `app/styles/app.tss` (auto-generated)
68
+ > - A generated `app/styles/app.tss` whose header names PurgeTSS
69
+ > - `app/lib/purgetss.{ui,colors,fonts}.js` or `Resources/lib/purgetss.{ui,colors,fonts}.js`
70
+ >
71
+ > `app/styles/app.tss` by itself is not proof: ordinary Alloy projects can have that file.
61
72
  >
62
- > **Behavior based on detection:**
63
- > - **PurgeTSS detected** → Provides PurgeTSS-specific guidance, recommends utility classes, suggests `$.UI.create()` for dynamic components
73
+ > **Behavior based on detection and layout:**
74
+ > - **Alloy + PurgeTSS utility lifecycle detected** → Provides utility-class guidance and may suggest `$.UI.create()` for dynamic components
75
+ > - **Classic + PurgeTSS standalone command detected/requested** → Provides only asset, color, font, branding, or CommonJS command guidance with `Resources/` destinations
64
76
  > - **Not detected** → Does NOT suggest PurgeTSS utility classes, does NOT recommend `$.UI.create()`, does NOT reference PurgeTSS-specific patterns
65
77
 
66
- ## Core Workflow
78
+ ## Core Workflows
79
+
80
+ ### Alloy utility-class workflow
81
+
82
+ 1. **Setup**: `purgetss create 'name'` or `purgetss init` for an existing Alloy project.
83
+ 2. **Build**: Write Alloy XML/controller classes; PurgeTSS generates `app/styles/app.tss`.
84
+ 3. **Configure**: Customize utilities through `purgetss/config.cjs`.
85
+
86
+ ### Classic standalone workflow
67
87
 
68
- 1. **Setup**: `purgetss create 'name'` or `purgetss init` for existing projects
69
- 2. **Build**: Write XML with utility classes → PurgeTSS auto-generates `app.tss`
70
- 3. **Configure**: Customize via `purgetss/config.cjs`
88
+ Run only a command marked Classic-compatible in [Classic Project Support](references/classic-projects.md). Generated files are ordinary Titanium resources under `Resources/`; the app does not need a PurgeTSS hook or runtime dependency.
71
89
 
72
- ## Project Structure
90
+ ## Alloy Utility Project Structure
73
91
 
74
92
  ```bash
75
93
  ./purgetss/
@@ -141,7 +159,7 @@ If you write a claim without having read the reference that backs it, prepend `F
141
159
  >
142
160
  > If a class appears in "Unused or unsupported classes" in `app.tss`, it means it's truly not defined anywhere - not even in your `config.cjs` customizations.
143
161
 
144
- ## Quick Start
162
+ ## Alloy Quick Start
145
163
 
146
164
  ```bash
147
165
  purgetss create 'MyApp' -d -v fa
@@ -158,7 +176,7 @@ purgetss create 'MyApp' -d -v fa
158
176
 
159
177
  ## Critical Rules (Low Freedom)
160
178
 
161
- ### ⭐ PREFER `$.UI.create()` for Dynamic Components
179
+ ### ⭐ ALLOY ONLY: Prefer `$.UI.create()` for Dynamic Components
162
180
 
163
181
  > **💡 RECOMMENDED FOR DYNAMIC COMPONENTS**
164
182
  > When creating components dynamically in Controllers, **use `$.UI.create()` instead of `Ti.UI.create()`** to get full PurgeTSS utility class support:
@@ -1,8 +1,8 @@
1
1
  # App Icons & Branding
2
2
 
3
- The `purgetss brand` command (introduced in v7.6.0, grouped config in v7.7.0, restructured into per-piece blocks in v7.13.0) regenerates **every image the Titanium template ships**, from one main SVG or PNG logo: launcher icons, adaptive icons, iOS 18+ Dark/Tinted variants, marketplace artwork, and both the iOS and Android splash sets. Per-piece overrides are there when you need them. Alloy and Classic layouts are auto-detected.
3
+ The `purgetss brand` command generates the complete Titanium branding set from one main SVG or PNG logo: launcher icons, adaptive icons, iOS 18+ Dark/Tinted variants, marketplace artwork, and both splash sets. Per-piece overrides are available when needed. Alloy and Classic layouts are auto-detected, and since v7.14.0 a normal run follows the platforms enabled in `tiapp.xml`.
4
4
 
5
- The rule is simple: **if the template ships the file, `brand` updates it.** You should never have to know which API still reads which file to avoid shipping an app with the grey Alloy logo somewhere in it.
5
+ The command also creates Titanium-consumed Classic paths that a fresh Classic template does not seed, including the 11 Android `Resources/android/images/res-*` splash variants. An explicit `--only` is an intentional override that can prepare assets for a disabled deployment target.
6
6
 
7
7
  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).
8
8
 
@@ -51,9 +51,10 @@ purgetss brand
51
51
 
52
52
  On a first run the command:
53
53
 
54
- 1. Creates the `brand:` section in `purgetss/config.cjs` with sensible defaults (if missing).
55
- 2. Generates every branding file directly into the project (in-place).
56
- 3. Prints a compact summary of what was written.
54
+ 1. Creates `purgetss/config.cjs` from the canonical template if the file is missing, including in standalone Classic projects.
55
+ 2. Creates or updates the `brand:` section with current defaults.
56
+ 3. Generates branding files for the enabled deployment targets directly into the project.
57
+ 4. Prints a compact summary of what was written.
57
58
 
58
59
  Pass `--dry-run` to preview without writing any files:
59
60
 
@@ -61,6 +62,8 @@ Pass `--dry-run` to preview without writing any files:
61
62
  purgetss brand --dry-run
62
63
  ```
63
64
 
65
+ You may also pass a source directly. When a standalone Classic project has no canonical `purgetss/brand/logo.{svg,png}`, the confirmed run moves that positional source into the convention and reports the destination. An existing canonical logo is never replaced silently.
66
+
64
67
  ## The `purgetss/brand/` convention
65
68
 
66
69
  `init` creates `purgetss/brand/` (alongside `fonts/` and `images/`) so the folder is already there the first time you look for it, even before you've dropped in a logo.
@@ -146,7 +149,7 @@ brand: {
146
149
 
147
150
  // One block per piece. Artwork comes from purgetss/brand/logo-<piece>.{svg,png};
148
151
  // these keys are for numbers, colors and activation. Padding is never inherited.
149
- icon: { padding: '4%' }, // DefaultIcon.png + DefaultIcon-ios.png
152
+ icon: { padding: '0%' }, // DefaultIcon.png + DefaultIcon-ios.png
150
153
  dark: { background: null }, // DefaultIcon-Dark.png
151
154
  tinted: {}, // DefaultIcon-Tinted.png
152
155
  iosSplash: { padding: '26%' }, // assets/iphone/Default*.png × 16
@@ -234,12 +237,12 @@ And these live at the top level:
234
237
 
235
238
  | Piece | Config key | Generates | Default padding | On by default |
236
239
  | --- | --- | --- | --- | --- |
237
- | `icon` | `icon` | `DefaultIcon.png` + `DefaultIcon-ios.png` | `4%` | yes |
238
- | `dark` | `dark` | `DefaultIcon-Dark.png` | `4%` | yes |
239
- | `tinted` | `tinted` | `DefaultIcon-Tinted.png` | `4%` | yes |
240
+ | `icon` | `icon` | `DefaultIcon.png` + `DefaultIcon-ios.png` | `0%` | yes |
241
+ | `dark` | `dark` | `DefaultIcon-Dark.png` | `0%` | yes |
242
+ | `tinted` | `tinted` | `DefaultIcon-Tinted.png` | `0%` | yes |
240
243
  | `ios-splash` | `iosSplash` | `assets/iphone/Default*.png` × 16 | `26%` | yes |
241
244
  | `launch-logo` | `launchLogo` | `LaunchLogo.png` (1024×1024) | `12%` | when `logo-launch.*` exists |
242
- | `marketplace` | `marketplace` | `iTunesConnect.png` + `MarketplaceArtwork.png` | `4%` | yes |
245
+ | `marketplace` | `marketplace` | `iTunesConnect.png` + `MarketplaceArtwork.png` | `0%` | yes |
243
246
  | `feature-graphic` | `featureGraphic` | `MarketplaceArtworkFeature.png` (1024×500) | `12%` | yes |
244
247
  | `adaptive` | `adaptive` | `ic_launcher_{foreground,background,monochrome}.png` × 5 + `ic_launcher.xml` | `18%` | yes |
245
248
  | `legacy-icon` | `legacyIcon` | `ic_launcher.png` × 5 | `10%` | yes |
@@ -255,7 +258,7 @@ Only three pieces are opt-in, and for one reason: they produce nothing useful un
255
258
 
256
259
  ### `background` is inherited, `padding` is not
257
260
 
258
- Set `brand.background` once and every piece picks it up. Padding works the other way on purpose: the defaults answer to different constraints. The adaptive `18%` answers to the Android launcher mask, while the iOS `4%` is an aesthetic choice with no mask behind it. A single inherited number would let `8%` quietly break the launcher mask, so padding is set per piece or not at all.
261
+ Set `brand.background` once and every piece picks it up. Padding works the other way on purpose: the adaptive `18%` answers to the Android launcher mask, while finished iOS/store artwork defaults to full-bleed `0%`. A single inherited number could quietly break the launcher mask or frame finished square artwork, so padding is set per piece or not at all.
259
262
 
260
263
  ## Overwrite confirmation
261
264
 
@@ -290,7 +293,7 @@ The output is automatically routed to the right directory for your project layou
290
293
 
291
294
  ```text
292
295
  <project>/
293
- ├── DefaultIcon.png ← 1024×1024, universal fallback (Android-safe padding)
296
+ ├── DefaultIcon.png ← 1024×1024, universal fallback (brand.icon.padding)
294
297
  ├── DefaultIcon-ios.png ← 1024×1024, iOS flattened on brand.background
295
298
  ├── DefaultIcon-Dark.png ← 1024×1024, iOS 18+ dark (transparent per Apple HIG)
296
299
  ├── DefaultIcon-Tinted.png ← 1024×1024, iOS 18+ tinted (grayscale on black)
@@ -326,7 +329,8 @@ The output is automatically routed to the right directory for your project layou
326
329
  │ ├── iphone/Default*.png ← the launch images the template ships
327
330
  │ └── android/
328
331
  │ ├── appicon.png ← 128×128
329
- │ └── default.png ← Android <12 splash
332
+ │ ├── default.png ← Android <12 splash
333
+ │ └── images/res-*/default.png ← 11 Titanium qualifier splashes
330
334
  └── platform/
331
335
  └── android/res/
332
336
  ├── mipmap-*/ ← same 5 densities as Alloy
@@ -334,7 +338,7 @@ The output is automatically routed to the right directory for your project layou
334
338
  └── mipmap-anydpi-v26/ic_launcher.xml
335
339
  ```
336
340
 
337
- A Classic project has no `images/res-*` folders, so the per-qualifier splashes are simply skipped there.
341
+ A fresh Classic project may not contain `images/res-*`, but `brand` creates all 11 `Resources/android/images/res-*` variants because Titanium consumes those qualifier paths.
338
342
 
339
343
  The Android outputs are related, but they are not interchangeable:
340
344
 
@@ -475,7 +479,7 @@ Below Android 12 there is no system splash: the launch screen comes from the ima
475
479
  `brand` regenerates the whole set on every run. It is the `android-splash` piece, on by default:
476
480
 
477
481
  - `app/assets/android/default.png` (`Resources/android/default.png` in Classic)
478
- - `app/assets/android/images/res-*/default.png` — the 11 per-qualifier images the Alloy template ships
482
+ - `app/assets/android/images/res-*/default.png` (`Resources/android/images/res-*/default.png` in Classic) — the 11 per-qualifier images Titanium consumes
479
483
 
480
484
  Earlier versions regenerated only the first file and hid the other 11 behind a `--legacy-splash` flag, which is why a freshly branded project could still flash the grey Alloy logo on an older phone. That flag is gone: its output is part of `android-splash` and always generated.
481
485
 
@@ -509,7 +513,7 @@ The output keeps its alpha, so the storyboard's `<default-background-color>` sho
509
513
 
510
514
  ## iPhone launch images
511
515
 
512
- The Alloy and Classic templates ship 16 `Default*.png` launch images under `assets/iphone/`, from the 320×480 original iPhone size up to 2688×1242. `brand` regenerates all of them, scaling the logo against the **shorter side** of each canvas so portrait and landscape carry the same visual weight.
516
+ The Alloy and Classic templates ship 16 `Default*.png` launch images under `app/assets/iphone/` or `Resources/iphone/`, from the 320×480 original iPhone size up to 2688×1242. `brand` regenerates all of them, scaling the logo against the **shorter side** of each canvas so portrait and landscape carry the same visual weight.
513
517
 
514
518
  With `<enable-launch-screen-storyboard>` enabled (the default), iOS never reads these files. They are regenerated because they are in your project, they ship with the Alloy logo, and no one should have to audit their `tiapp.xml` to know whether that matters. If you are sure your project doesn't need them, [`--cleanup-legacy`](#cleanup-legacy-branding-artifacts) deletes them instead.
515
519
 
@@ -572,7 +576,7 @@ Padding belongs to the piece, not to the project. Each piece has its own key and
572
576
  | --- | --- | --- | --- |
573
577
  | `adaptive` | `brand.adaptive.padding` | `--android-adaptive-padding` | `18%` |
574
578
  | `legacy-icon` | `brand.legacyIcon.padding` | `--android-legacy-padding` | `10%` |
575
- | `icon` | `brand.icon.padding` | `--ios-padding` | `4%` |
579
+ | `icon` | `brand.icon.padding` | `--ios-padding` | `0%` |
576
580
  | `feature-graphic` | `brand.featureGraphic.padding` | `--feature-graphic-padding` | `12%` |
577
581
  | `launch-logo` | `brand.launchLogo.padding` | `--launch-logo-padding` | `12%` |
578
582
  | `android-splash` | `brand.androidSplash.padding` | `--android-splash-padding` | `26%` |
@@ -580,7 +584,7 @@ Padding belongs to the piece, not to the project. Each piece has its own key and
580
584
 
581
585
  `--padding` is a shortcut for the two Android launcher paddings in a single run, and `--splash-padding` for the two splash paddings. `--ios-padding` moves the four square iOS/marketplace pieces together (`icon`, `dark`, `tinted`, `marketplace`); in config each of them has its own key.
582
586
 
583
- There is deliberately **no global padding value that cascades down**. The defaults answer to different constraints: `18%` answers to the Android launcher mask, while `4%` is an aesthetic choice for a canvas with no mask behind it. One inherited number would let a reasonable-looking `8%` silently break the launcher mask. `background`, which has no such trap, is inherited from `brand.background`.
587
+ There is deliberately **no global padding value that cascades down**. The defaults answer to different constraints: `18%` answers to the Android launcher mask, while finished square iOS/store artwork stays full-bleed at `0%`. One inherited number could silently break the launcher mask or add an unwanted frame to finished artwork. `background`, which has no such trap, is inherited from `brand.background`.
584
588
 
585
589
  ### How the source is read, and how sharp the output is
586
590
 
@@ -0,0 +1,96 @@
1
+ # Classic Project Support
2
+
3
+ PurgeTSS 7.15 keeps its utility-class lifecycle Alloy-only while allowing independent asset and CommonJS commands to run in Titanium Classic projects. Detect the project layout before choosing a command or output path.
4
+
5
+ Official source: <https://purgetss.com/docs/commands#alloy-and-classic-compatibility>
6
+
7
+ ## Compatibility Matrix
8
+
9
+ | Command | Alloy | Classic | Classic behavior |
10
+ | --- | :---: | :---: | --- |
11
+ | `brand` | yes | yes | Writes branding assets to Classic paths and follows enabled `tiapp.xml` deployment targets; explicit `--only` overrides that filter. |
12
+ | `images` | yes | yes | Writes density variants under `Resources/android/images/res-*/` and `Resources/iphone/images/`; follows deployment targets unless `--android` or `--ios` is explicit. |
13
+ | `semantic` | yes | yes | Writes only `Resources/semantic.colors.json`; it does not create `purgetss/`, `config.cjs`, TSS, `app/`, or a hook. |
14
+ | `shades` | yes | yes | Output-only modes work anywhere. Saving creates or updates `purgetss/config.cjs` as a development-time color source. |
15
+ | `color-module` | yes | yes | Writes `app/lib/purgetss.colors.js` or `Resources/lib/purgetss.colors.js`. |
16
+ | `module` | yes | yes | Writes `app/lib/purgetss.ui.js` or `Resources/lib/purgetss.ui.js`. |
17
+ | `icon-library` | yes | yes | Copies fonts to `Resources/fonts/` and optional modules to `Resources/lib/`; `--styles` is skipped in Classic. |
18
+ | `build-fonts` | yes | yes | Copies fonts to `Resources/fonts/` and optionally writes `Resources/lib/purgetss.fonts.js`; it does not generate TSS in Classic. |
19
+ | Root `purgetss`, `--all`, `init`, `create`, `install-dependencies`, `build`, `watch` | yes | no | These commands own the Alloy utility-class lifecycle. |
20
+ | `update`, `sudo-update` | yes | yes | Global CLI maintenance; no project layout is required. |
21
+
22
+ ## The Hard Boundary
23
+
24
+ A Classic project does not receive or need:
25
+
26
+ - `app/`
27
+ - `app/styles/app.tss`
28
+ - `purgetss/styles/utilities.tss`
29
+ - `purgetss/styles/fonts.tss`
30
+ - `alloy.jmk`
31
+ - utility classes in views or controllers
32
+ - `$.UI.create()`
33
+ - PurgeTSS during application compilation or at runtime
34
+
35
+ Files generated under `Resources/` are native Titanium resources. Compile the Classic app normally with `ti build`.
36
+
37
+ Do not interpret the presence of `purgetss/config.cjs` in a Classic project as permission to use utilities. Commands such as `brand`, `images`, `shades`, and `color-module` may use that file as development-time input without installing the Alloy lifecycle.
38
+
39
+ ## Layout and Output Routing
40
+
41
+ | Artifact | Alloy | Classic |
42
+ | --- | --- | --- |
43
+ | Semantic colors | `app/assets/semantic.colors.json` | `Resources/semantic.colors.json` |
44
+ | Android UI densities | `app/assets/android/images/res-*/` | `Resources/android/images/res-*/` |
45
+ | iPhone UI scales | `app/assets/iphone/images/` | `Resources/iphone/images/` |
46
+ | Font files | `app/assets/fonts/` | `Resources/fonts/` |
47
+ | Color module | `app/lib/purgetss.colors.js` | `Resources/lib/purgetss.colors.js` |
48
+ | UI module | `app/lib/purgetss.ui.js` | `Resources/lib/purgetss.ui.js` |
49
+ | Custom-font module | `app/lib/purgetss.fonts.js` | `Resources/lib/purgetss.fonts.js` |
50
+
51
+ ## Deployment Targets
52
+
53
+ `brand` and `images` read `<deployment-targets>` from `tiapp.xml` independently of whether the layout is Alloy or Classic.
54
+
55
+ - A normal run generates only enabled platform families.
56
+ - `images --android` and `images --ios` are explicit overrides.
57
+ - `brand --only <piece-or-group>` is an explicit override and may prepare assets for a platform before that target is enabled.
58
+
59
+ Do not assume that Classic means Android-only or that an Alloy project targets both platforms.
60
+
61
+ ## Standalone First-Run Behavior
62
+
63
+ ### `brand`
64
+
65
+ In a Classic project without `purgetss/config.cjs`, `brand` creates the canonical config before resolving settings. If a positional PNG/SVG is supplied and no canonical `purgetss/brand/logo.{png,svg}` exists, the command moves the source into that convention after overwrite confirmation and reports the destination. It never replaces an existing canonical logo silently.
66
+
67
+ Classic Android receives the 11 `Resources/android/images/res-*` splash variants even when a fresh `ti create` template did not seed those folders. Titanium consumes those qualifier paths.
68
+
69
+ ### `images`
70
+
71
+ Running `images` without a positional source establishes the `purgetss/images/` convention. Passing an existing external file or directory does not create an empty `purgetss/images/` folder or a config file merely to process that source.
72
+
73
+ ### `semantic`
74
+
75
+ Classic `semantic` is deliberately output-only: it writes the native JSON and does not bootstrap any other PurgeTSS artifact. Classic code uses semantic keys directly in Titanium color properties rather than through utility classes.
76
+
77
+ ## Audit Checklist
78
+
79
+ When auditing a Classic project that uses PurgeTSS:
80
+
81
+ 1. Confirm every invoked command is marked Classic-compatible in the matrix.
82
+ 2. Confirm outputs use `Resources/`, never Alloy's `app/assets/` or `app/lib/`.
83
+ 3. Reject any added `alloy.jmk`, generated TSS, utility classes, or `$.UI.create()`.
84
+ 4. For `brand` and `images`, compare generated platform families with `tiapp.xml` deployment targets and any explicit override flags.
85
+ 5. Confirm `semantic` did not create unrelated PurgeTSS setup files.
86
+ 6. For `icon-library --styles`, expect Classic to skip TSS output.
87
+ 7. For `build-fonts`, expect font files and optional CommonJS output only; no `fonts.tss`.
88
+
89
+ ## Related References
90
+
91
+ - [CLI Commands](./cli-commands.md)
92
+ - [App Icons & Branding](./app-branding.md)
93
+ - [Multi-Density Images](./multi-density-images.md)
94
+ - [Semantic Colors](./semantic-colors.md)
95
+ - [Icon Font Libraries](./icon-fonts.md)
96
+ - [Custom Fonts](./custom-fonts.md)
@@ -5,11 +5,7 @@ This page lists the commands available in PurgeTSS. For release-by-release featu
5
5
  <!-- TOC-START -->
6
6
  ## Contents
7
7
 
8
- - [Setup Commands](#setup-commands)
9
- - [Development Commands](#development-commands)
10
- - [Asset Commands](#asset-commands)
11
- - [Utility Commands](#utility-commands)
12
- - [Maintenance Commands](#maintenance-commands)
8
+ - [Alloy and Classic Compatibility](#alloy-and-classic-compatibility)
13
9
  - [`init` Command](#init-command)
14
10
  - [`create` Command](#create-command)
15
11
  - [`brand` Command](#brand-command)
@@ -29,34 +25,21 @@ This page lists the commands available in PurgeTSS. For release-by-release featu
29
25
 
30
26
  <!-- TOC-END -->
31
27
 
32
- ## Setup Commands
28
+ ## Alloy and Classic Compatibility
33
29
 
34
- - `init`: Initializes PurgeTSS on an existing Alloy project.
35
- - `create`: Creates a new Alloy project with PurgeTSS already set up.
36
- - `brand`: Generates the Titanium branding set from a single logo. See [`brand` Command](#brand-command).
37
- - `images`: Generates multi-density UI images from sources in `./purgetss/images/`. See [`images` Command](#images-command).
30
+ The utility-class lifecycle remains Alloy-only. Classic projects can use independent asset and CommonJS commands without installing an `alloy.jmk` hook or adding PurgeTSS to their compilation flow.
38
31
 
39
- ## Development Commands
32
+ | Command | Alloy | Classic | Classic behavior |
33
+ | --- | :---: | :---: | --- |
34
+ | `brand` | yes | yes | Uses Classic asset paths and follows `tiapp.xml` deployment targets; `--only` is an explicit override. |
35
+ | `images` | yes | yes | Writes under `Resources/` and follows deployment targets unless `--android` or `--ios` is explicit. |
36
+ | `semantic` | yes | yes | Writes only `Resources/semantic.colors.json`; no utility setup is created. |
37
+ | `shades` | yes | yes | Console modes work anywhere; saving creates or updates development-time `purgetss/config.cjs`. |
38
+ | `color-module`, `module` | yes | yes | Writes CommonJS modules to `app/lib/` or `Resources/lib/`. |
39
+ | `icon-library`, `build-fonts` | yes | yes | Writes fonts to `Resources/fonts/` and optional modules to `Resources/lib/`; Classic receives no TSS. |
40
+ | Root `purgetss`, `--all`, `init`, `create`, `install-dependencies`, `build`, `watch` | yes | no | Alloy utility-class lifecycle only. |
40
41
 
41
- - `build`: Generates `utilities.tss` from `config.cjs`.
42
- - `watch`: Runs `purgetss` automatically on each project compile (defaults to `--on`).
43
-
44
- ## Asset Commands
45
-
46
- - `icon-library`: Copies the official icon fonts into `./app/assets/fonts`.
47
- - `build-fonts`: Generates `./purgetss/styles/fonts.tss` with class definitions and `fontFamily` selectors for custom fonts.
48
-
49
- ## Utility Commands
50
-
51
- - `shades`: Generates shades and tints for a color and writes the palette to `config.cjs`.
52
- - `semantic`: Generates Titanium semantic colors (Light/Dark) into `app/assets/semantic.colors.json`. See [`semantic` Command](#semantic-command).
53
- - `color-module`: Creates `./app/lib/purgetss.colors.js` with the colors defined in `config.cjs`.
54
- - `module`: Installs `purgetss.ui.js` in the `lib` folder.
55
-
56
- ## Maintenance Commands
57
-
58
- - `update`: Updates PurgeTSS to the latest version.
59
- - `sudo-update`: Updates PurgeTSS using `sudo` to install npm modules if needed.
42
+ See [Classic Project Support](./classic-projects.md) for the complete boundary and audit checklist.
60
43
 
61
44
  ## `init` Command
62
45
 
@@ -92,7 +75,7 @@ module.exports = {
92
75
  optimize: false, // true = quantize the generated PNGs to a palette (lossy)
93
76
 
94
77
  // One block per piece — see the `brand` Command section for the full list.
95
- icon: { padding: '4%' }, dark: { background: null }, tinted: {},
78
+ icon: { padding: '0%' }, dark: { background: null }, tinted: {},
96
79
  iosSplash: { padding: '26%' }, launchLogo: { padding: '12%' },
97
80
  marketplace: {}, featureGraphic: { padding: '12%' },
98
81
  adaptive: { padding: '18%' }, legacyIcon: { padding: '10%' },
@@ -191,7 +174,7 @@ Recommended VSCode extensions:
191
174
 
192
175
  ## `brand` Command
193
176
 
194
- Introduced in v7.6.0, grouped config in v7.7.0, restructured into per-piece blocks in v7.13.0. Regenerates **every image the Titanium template ships**, from one main logo: launcher icons, adaptive icons, iOS 18+ Dark/Tinted variants, marketplace artwork, and both the iOS and Android splash sets. The rule is *if the template ships the file, `brand` updates it*. Each piece can take its own artwork, and `--only` narrows a run to the pieces you name. Alloy and Classic projects are auto-detected.
177
+ Introduced in v7.6.0 and fully standalone in Classic since v7.14.0. Generates the complete Titanium branding set from one main logo: launcher icons, adaptive icons, iOS 18+ Dark/Tinted variants, marketplace artwork, and both splash sets. Alloy and Classic projects are auto-detected. A normal run follows `<deployment-targets>` in `tiapp.xml`; explicit `--only` intentionally overrides that filter.
195
178
 
196
179
  > **Tip**
197
180
  > This is a quick reference. See [app-branding.md](./app-branding.md) for the complete guide — workflow, padding guidance, Android dark mode, iOS 18+ variants, the launch-background setup, and troubleshooting. It also carries the full `brand:` config reference.
@@ -228,7 +211,7 @@ The 14 pieces, their config keys and what each one writes are tabulated in [app-
228
211
  | `--padding <n>` | Shortcut: sets both Android launcher paddings to the same value for one run. |
229
212
  | `--android-adaptive-padding <n>` | Adaptive icon safe-zone % (default `18`). |
230
213
  | `--android-legacy-padding <n>` | Legacy `ic_launcher.png` padding % (default `10`). |
231
- | `--ios-padding <n>` | Padding % for the four square iOS/marketplace pieces — `icon`, `dark`, `tinted`, `marketplace` (range `2-8`, default `4`). |
214
+ | `--ios-padding <n>` | Padding % for the four square iOS/marketplace pieces — `icon`, `dark`, `tinted`, `marketplace` (default `0`, full-bleed). |
232
215
  | `--feature-graphic-padding <n>` | Vertical padding % for `MarketplaceArtworkFeature.png` (range `0-40`, default `12`). |
233
216
  | `--launch-logo-padding <n>` | Padding % for `LaunchLogo.png` (default `12`). |
234
217
  | `--splash-padding <n>` | Shortcut: sets both splash paddings to the same value for one run. |
@@ -284,16 +267,14 @@ Every piece has a `--<piece>-logo <path>` flag — with no exceptions since v7.1
284
267
 
285
268
  > **Warning**
286
269
  > Breaking renames in v7.13.0: `--splash` → `--splash-icon`, `--notification` → `--notification-icon`, `--splash-logo` → `--splash-icon-logo`, `--feature-logo` → `--feature-graphic-logo`. `--icon-logo` now feeds the `icon` piece; the Android launcher source is `--adaptive-logo`. `--legacy-splash` is gone. **No aliases were kept.**
287
- >
288
- > Also note `purgetss brand --help` still prints `default: 19` for `--android-adaptive-padding` and `default: 20` for the two splash paddings. Those help strings are stale — the pipeline applies `18`, `26` and `26`.
289
270
 
290
271
  ### Positional argument
291
272
 
292
- - `[logo-path]` (optional) — overrides auto-discovery of `purgetss/brand/logo.{svg,png}`. It is the main logo, source for every piece that has no override.
273
+ - `[logo-path]` (optional) — main source for every piece without an override. In a standalone Classic first run, when no canonical logo exists, PurgeTSS moves this source to `purgetss/brand/logo.{svg,png}` after confirmation and reports the destination.
293
274
 
294
275
  ### Config block (v7.13.0 per-piece structure)
295
276
 
296
- Defaults live under `brand:` in `purgetss/config.cjs` and are injected automatically. The block has **one entry per piece**; each accepts the same four keys where they apply: `logo`, `padding` (never inherited), `background` (inherited from `brand.background`), `enabled`. Top-level: `background`, `confirmOverwrites`, `optimize`, `logo`, `monochromeLogo`.
277
+ Defaults live under `brand:` in `purgetss/config.cjs`. Since v7.14.0, a standalone Classic run creates the canonical config when it is missing. The block has **one entry per piece**; each accepts the same four keys where they apply: `logo`, `padding` (never inherited), `background` (inherited from `brand.background`), `enabled`. Top-level: `background`, `confirmOverwrites`, `optimize`, `logo`, `monochromeLogo`.
297
278
 
298
279
  An unknown key aborts the run before a single file is written. A `brand:` block written for an older PurgeTSS is **rewritten on disk** on the next run, carrying over every customized value.
299
280
 
@@ -328,7 +309,7 @@ purgetss brand --cleanup-legacy --dry-run # preview legacy clean
328
309
 
329
310
  ## `images` Command
330
311
 
331
- Introduced in v7.6.0. Generates multi-density variants of your UI images (buttons, illustrations, logos, screen graphics) from a single high-resolution source per image. Alloy and Classic projects are auto-detected.
312
+ Introduced in v7.6.0 and standalone in Classic since v7.15.0. Generates multi-density variants of UI images from one high-resolution source. Alloy and Classic projects are auto-detected. With neither platform flag, the command follows `<deployment-targets>` in `tiapp.xml`; `--android` and `--ios` are explicit overrides.
332
313
 
333
314
  > **Tip**
334
315
  > This is a quick reference. See [multi-density-images.md](./multi-density-images.md) for the complete guide — 4× source convention, re-processing single files, format conversion, subdirectory preservation, and troubleshooting.
@@ -360,6 +341,8 @@ purgetss images background/ # re-process one subfolder
360
341
 
361
342
  - `[source]` (optional) — path to override auto-discovery. Resolves first against `purgetss/images/` (short paths like `buttons/btn.png`), then against cwd.
362
343
 
344
+ Alloy outputs go under `app/assets/{android,iphone}/images/`; Classic outputs go under `Resources/{android,iphone}/images/`. Passing an existing external source in Classic does not bootstrap an empty `purgetss/images/` folder or config file.
345
+
363
346
  ### When to use `--width`
364
347
 
365
348
  Use `--width <n>` for SVG sources from vector editors with disproportionate viewBoxes — common in Affinity, Illustrator, and other design tools where the viewBox does not match the intended display size. Without the flag, every scale derives from the source's natural pixel size as a 4× master, which can produce unexpected output sizes.
@@ -409,14 +392,14 @@ purgetss images --dry-run # preview
409
392
 
410
393
  ## `semantic` Command
411
394
 
412
- Introduced in v7.6.0. Generates Titanium semantic colors (Light/Dark mode aware) into `app/assets/semantic.colors.json`. The command dispatches between two distinct modes based on whether `--single` is passed.
395
+ Introduced in v7.6.0. Generates Titanium semantic colors with Light/Dark support. Alloy writes `app/assets/semantic.colors.json` and utility mappings; Classic writes only `Resources/semantic.colors.json` and does not create `purgetss/`, `config.cjs`, TSS, `app/`, or a hook. The command dispatches between two modes based on `--single`.
413
396
 
414
397
  > **Tip**
415
398
  > This is a quick reference. See [semantic-colors.md](./semantic-colors.md) for the complete guide — mirror inversion math, Titanium semantic color spec, class mapping conventions, and strategies for purpose-based design systems.
416
399
 
417
400
  ### Palette mode (no `--single`)
418
401
 
419
- One base hex, 11-shade tonal palette with mirror-by-index Light/Dark inversion anchored at shade `500`. Writes both files in one step: the JSON gets 11 entries, and `config.cjs` gets the family mapped to those semantic keys.
402
+ One base hex, 11-shade tonal palette with mirror-by-index Light/Dark inversion anchored at shade `500`. Alloy writes the JSON plus the utility mapping in `config.cjs`; Classic writes only the native JSON entries.
420
403
 
421
404
  ```bash
422
405
  purgetss semantic <hex> <name>
@@ -427,7 +410,7 @@ Usage produces classes like `bg-amazon-50`, `text-amazon-500`, `border-amazon-95
427
410
 
428
411
  ### Single mode (`--single`)
429
412
 
430
- Explicit per-mode hex values for purpose-based semantic colors (`surfaceColor`, `textColor`, `borderColor`, `overlayColor`, etc.). Writes the JSON entry AND auto-maps it to a class in `config.cjs` by stripping the conventional `Color` suffix (e.g. `surfaceColor` → class `surface`).
413
+ Explicit per-mode hex values for purpose-based semantic colors (`surfaceColor`, `textColor`, `borderColor`, `overlayColor`, etc.). Alloy writes the JSON entry and maps it to a utility class in `config.cjs`; Classic writes only the native JSON entry and uses its key directly in Titanium color properties.
431
414
 
432
415
  ```bash
433
416
  purgetss semantic --single <hex> <name> [--dark <hex>] [--alpha <0-100>]
@@ -479,13 +462,13 @@ Re-running on the same palette family fully replaces it: PurgeTSS strips prior k
479
462
  | `-a, --alpha <0-100>` | With `--single`, wraps both modes in `{ color, alpha }` per the Titanium spec. |
480
463
  | `-n, --name <name>` | Specify the name (alternative to the positional argument). |
481
464
  | `-r, --random` | Palette mode — use a random base color. |
482
- | `-o, --override` | Place the mapping in `theme.colors` instead of `theme.extend.colors`. |
483
- | `-q, --quotes` | Keep double quotes in `config.cjs`. |
465
+ | `-o, --override` | Alloy only: place the mapping in `theme.colors` instead of `theme.extend.colors`. Ignored in Classic. |
466
+ | `-q, --quotes` | Alloy only: keep double quotes in `config.cjs`. Ignored in Classic. |
484
467
  | `-l, --log` | Preview the JSON without writing any files. |
485
468
 
486
469
  ## `install-dependencies` Command
487
470
 
488
- This command installs dev dependencies and configuration files in existing PurgeTSS projects, and sets up Visual Studio Code support.
471
+ This Alloy-only command installs dev dependencies and configuration files for the utility-class workflow and sets up Visual Studio Code support. Do not run it in Classic.
489
472
 
490
473
  ```bash
491
474
  purgetss install-dependencies
@@ -499,7 +482,7 @@ purgetss id
499
482
 
500
483
  ## `icon-library` Command
501
484
 
502
- Copies the bundled free font files (Font Awesome 7, Material Icons, Material Symbols, Framework7 Icons) into `./app/assets/fonts/`. Once the fonts are in place, every official icon class (`fa-home`, `ms-home`, `mi-home`, `f7-house`, etc.) works out of the box — PurgeTSS resolves them at compile time from its own bundled `dist/` files.
485
+ Copies the bundled free font files (Font Awesome 7, Material Icons, Material Symbols, Framework7 Icons) to `app/assets/fonts/` in Alloy or `Resources/fonts/` in Classic. Alloy resolves the official utility classes at compile time; Classic uses the installed `fontFamily` plus Unicode directly or through the optional CommonJS module.
503
486
 
504
487
  ```bash
505
488
  purgetss icon-library [--vendor=fa,mi,ms,f7] [--module] [--styles]
@@ -513,17 +496,19 @@ purgetss il [-v=fa,mi,ms,f7] [-m] [-s]
513
496
  | Flag | Purpose |
514
497
  | --- | --- |
515
498
  | `-v, --vendor [fa,mi,ms,f7]` | Copy specific font vendors only (default copies all four). |
516
- | `-m, --module` | Copy the matching CommonJS module into `./app/lib/` so you can reference icons by name from controllers (`icons.fa.home`). |
517
- | `-s, --styles` | Copy the official `.tss` source files into `./purgetss/styles/` for reference only — not needed for the classes to work. |
499
+ | `-m, --module` | Copy the matching CommonJS module into `app/lib/` (Alloy) or `Resources/lib/` (Classic). |
500
+ | `-s, --styles` | Alloy only: copy official `.tss` sources into `purgetss/styles/` for reference. Classic skips this output. |
518
501
 
519
502
  Vendor aliases: `fa`/`fontawesome`, `mi`/`materialicons`, `ms`/`materialsymbol`, `f7`/`framework7`.
520
503
 
504
+ Every installed module exposes `families.default`. Direct variant aliases are `solid`/`regular`/`brands` for Font Awesome; `regular`/`outlined`/`round`/`sharp`/`twoTone` for Material Icons; `outlined`/`rounded`/`sharp` for Material Symbols; and `fontFamily` for Framework7.
505
+
521
506
  > **Tip**
522
507
  > This is a quick reference. See [Icon Fonts](./icon-fonts.md) for the complete guide — variant tables (`.ms`/`.mso`/`.msr`/`.mss`, `.fa`/`.fas`/`.far`/`.fab`), XML usage patterns, the side-by-side four-family example, Font Awesome Pro / Beta workflow, and instructions for recreating removed libraries.
523
508
 
524
509
  ## `build-fonts` Command
525
510
 
526
- Generates `./purgetss/styles/fonts.tss` with class definitions and `fontFamily` selectors for any user-defined fonts dropped into `./purgetss/fonts/` (Google Fonts, brand typefaces, community icon libraries with `.ttf` + `.css` pairs).
511
+ Installs user-defined fonts dropped into `purgetss/fonts/`. Alloy also generates `purgetss/styles/fonts.tss`; Classic copies only native fonts to `Resources/fonts/` and generates no TSS or utility definitions.
527
512
 
528
513
  ```bash
529
514
  purgetss build-fonts [-m] [-f]
@@ -536,13 +521,13 @@ purgetss bf [-m] [-f]
536
521
 
537
522
  | Flag | Purpose |
538
523
  | --- | --- |
539
- | `-m, --module` | Also generates a CommonJS module in `./app/lib/purgetss.fonts.js` exposing `exports.icons` and `exports.families` for use from controllers. |
524
+ | `-m, --module` | Also generates `app/lib/purgetss.fonts.js` (Alloy) or `Resources/lib/purgetss.fonts.js` (Classic), exposing `exports.icons` and `exports.families`. |
540
525
  | `-f, --font-class-from-filename` | Uses the font filename as the class name and icon prefix instead of the font family. Replaces the old `-p` flag. |
541
526
 
542
527
  ### What it does
543
528
 
544
- 1. Creates `./purgetss/styles/fonts.tss` with one `fontFamily` class per file.
545
- 2. Copies the font files into `./app/assets/fonts/`, renamed to their PostScript names so they work on both iOS and Android.
529
+ 1. Copies font files to `app/assets/fonts/` (Alloy) or `Resources/fonts/` (Classic), renamed to their PostScript names.
530
+ 2. In Alloy only, creates `purgetss/styles/fonts.tss` with the TSS class definitions.
546
531
 
547
532
  > **Tip**
548
533
  > This is a quick reference. See [Custom Fonts](./custom-fonts.md) for the complete guide — folder organization, class renaming, adding icon libraries, the `--module` output structure, and `--font-class-from-filename` workflow.
@@ -554,6 +539,8 @@ purgetss bf [-m] [-f]
554
539
 
555
540
  The `shades` command generates shades and tints for a given color and writes the palette to `config.cjs`.
556
541
 
542
+ Saving works in Alloy and Classic. In Classic, `config.cjs` is only a development-time color source for commands such as `color-module`; it does not install the PurgeTSS utility lifecycle. `--log`, `--json`, and `--tailwind` write nothing and work outside a project.
543
+
557
544
  ```bash
558
545
  purgetss shades [hexcode] [name]
559
546
 
@@ -654,7 +641,7 @@ purgetss s '#65e92c' -j
654
641
 
655
642
  ## `color-module` Command
656
643
 
657
- This command creates `purgetss.colors.js` in the `lib` folder with all colors defined in `config.cjs`.
644
+ This command creates `purgetss.colors.js` with all colors defined in `config.cjs`: `app/lib/` in Alloy or `Resources/lib/` in Classic. A missing config is created as the color source, but Classic receives no Alloy hook or TSS.
658
645
 
659
646
  ```bash
660
647
  purgetss color-module
@@ -687,7 +674,7 @@ This is handy for using colors in code without hardcoding values in multiple pla
687
674
 
688
675
  ## `build` Command
689
676
 
690
- The `build` command generates `utilities.tss` from `config.cjs`. Run it after you change `config.cjs`.
677
+ The Alloy-only `build` command generates `utilities.tss` from `config.cjs`. It is not part of a Classic standalone workflow.
691
678
 
692
679
  ```bash
693
680
  purgetss build
@@ -704,7 +691,7 @@ When `purgetss` runs (manually or via `watch`), it checks for changes in `config
704
691
 
705
692
  ## `watch` Command
706
693
 
707
- The `watch` command runs PurgeTSS on each project compile. You do not need to run `build` manually after each change.
694
+ The Alloy-only `watch` command runs PurgeTSS on each Alloy project compile. Classic projects do not install this hook.
708
695
 
709
696
  ```bash
710
697
  purgetss watch
@@ -746,7 +733,7 @@ purgetss w -d
746
733
 
747
734
  ## `module` Command
748
735
 
749
- The `module` command installs `purgetss.ui.js` in the `lib` folder.
736
+ The `module` command installs the self-contained `purgetss.ui.js` in `app/lib/` (Alloy) or `Resources/lib/` (Classic). A Classic app does not need PurgeTSS during compilation or at runtime.
750
737
 
751
738
  ```bash
752
739
  purgetss module
@@ -757,7 +744,7 @@ purgetss m
757
744
 
758
745
  The PurgeTSS module includes:
759
746
 
760
- - Animation: Methods for playing or applying basic animations and transformations to Alloy objects.
747
+ - Animation: methods for playing or applying basic animations and transformations to Titanium views.
761
748
 
762
749
  See [Animation System](./animation-system.md) for details.
763
750
 
@@ -1,9 +1,29 @@
1
1
  # Custom Fonts
2
2
 
3
- Use the `purgetss/fonts/` folder and the `build-fonts` command to register any font in your Titanium app: brand typefaces, custom icon fonts, or community icon libraries that PurgeTSS no longer bundles.
3
+ Use the `purgetss/fonts/` folder and the `build-fonts` command to register any font in Alloy or Classic: brand typefaces, custom icon fonts, or community icon libraries that PurgeTSS no longer bundles.
4
+
5
+ | Output | Alloy | Classic |
6
+ | --- | --- | --- |
7
+ | Font files | `app/assets/fonts/` | `Resources/fonts/` |
8
+ | Generated TSS classes | `purgetss/styles/fonts.tss` | Not generated |
9
+ | `--module` output | `app/lib/purgetss.fonts.js` | `Resources/lib/purgetss.fonts.js` |
10
+
11
+ Classic receives only native Titanium resources and optional CommonJS output. It does not receive `app/`, TSS, or an Alloy build hook.
4
12
 
5
13
  For the 4 official icon families that ship with PurgeTSS (Font Awesome 7, Material Icons, Material Symbols, Framework7), see [Icon Fonts](./icon-fonts.md) — they use the `icon-library` command and do **not** require `build-fonts`.
6
14
 
15
+ <!-- TOC-START -->
16
+ ## Contents
17
+
18
+ - [The `fonts` folder](#the-fonts-folder)
19
+ - [The `build-fonts` command](#the-build-fonts-command)
20
+ - [Adding icon fonts](#adding-icon-fonts)
21
+ - [Options](#options)
22
+ - [Custom proprietary icon fonts](#custom-proprietary-icon-fonts)
23
+ - [Community-Discovered Patterns](#community-discovered-patterns)
24
+
25
+ <!-- TOC-END -->
26
+
7
27
  ## The `fonts` folder
8
28
 
9
29
  Place `.ttf` or `.otf` files in `./purgetss/fonts/`. For icon fonts, also include the `.css` file that ships with the library. PurgeTSS reads it to extract the Unicode characters for each icon class.
@@ -49,13 +69,15 @@ $ purgetss build-fonts [-m] [-f]
49
69
  $ purgetss bf [-m] [-f]
50
70
  ```
51
71
 
52
- What it does:
72
+ In Alloy it:
53
73
 
54
74
  1. Creates `./purgetss/styles/fonts.tss` with one `fontFamily` class per file.
55
75
  2. Copies the font files into `./app/assets/fonts/`, renamed to their PostScript names so they work on both iOS and Android.
56
76
 
77
+ In Classic it copies the renamed font files into `Resources/fonts/` and deliberately skips TSS and utility definitions. Use each PostScript name directly through Titanium's `fontFamily` property.
78
+
57
79
  > ℹ️ **INFO — How this differs from the official icon fonts**
58
- > Unlike the [official icon fonts](./icon-fonts.md), which PurgeTSS resolves automatically from its own bundled files and need no `.tss` in your project, custom fonts **do** generate `./purgetss/styles/fonts.tss`. That file is then folded into the generated `app/styles/app.tss` when you run `purgetss` (or compile your app) — that is where the final classes used by Alloy live.
80
+ > In Alloy, unlike the [official icon fonts](./icon-fonts.md), custom fonts generate `purgetss/styles/fonts.tss`, which is folded into generated `app/styles/app.tss`. Classic skips this class-generation step.
59
81
 
60
82
  After running `purgetss build-fonts` with the Bevan and Dancing Script example above:
61
83
 
@@ -156,7 +178,7 @@ After `purgetss build-fonts`, the generated `fonts.tss` includes the family clas
156
178
 
157
179
  Two optional flags adjust what `build-fonts` generates:
158
180
 
159
- - `-m, --module`: generates a CommonJS module in `./app/lib/purgetss.fonts.js` that exposes each icon's Unicode string to JavaScript. Handy when you set `label.text` from a controller.
181
+ - `-m, --module`: generates a CommonJS module in `app/lib/purgetss.fonts.js` (Alloy) or `Resources/lib/purgetss.fonts.js` (Classic) that exposes each icon's Unicode string to JavaScript.
160
182
  - `-f, --font-class-from-filename`: uses the font's filename as the font class name and icon prefix instead of the font family name. Useful when you want shorter prefixes. Replaces the old `-p` flag.
161
183
 
162
184
  ### Using `--module`
@@ -170,7 +192,7 @@ $ purgetss bf -m
170
192
 
171
193
  To avoid prefix conflicts between libraries, each icon keeps its prefix as a nested object. Both `icons` and `families` are exported:
172
194
 
173
- `./app/lib/purgetss.fonts.js`
195
+ `app/lib/purgetss.fonts.js` (Alloy) or `Resources/lib/purgetss.fonts.js` (Classic)
174
196
  ```javascript
175
197
  const icons = {
176
198
  // map-icons/map-icons.css
@@ -240,7 +262,7 @@ purgetss
240
262
  /* ... */
241
263
  ```
242
264
 
243
- `./app/lib/purgetss.fonts.js`
265
+ `app/lib/purgetss.fonts.js` (Alloy) or `Resources/lib/purgetss.fonts.js` (Classic)
244
266
  ```javascript
245
267
  const icons = {
246
268
  // map-icons/mp.css
@@ -283,7 +305,7 @@ If your design system ships its own icon font, treat it like any other icon libr
283
305
  The following notes reflect community experience with `build-fonts` against real-world Titanium projects.
284
306
 
285
307
  > **💡 PostScript renaming**
286
- > `build-fonts` copies `.ttf`/`.otf` files into `./app/assets/fonts/` renamed to their **PostScript names**. iOS reads PostScript names while Android tolerates filenames; by renaming both platforms work from the same `fontFamily` value.
308
+ > `build-fonts` copies `.ttf`/`.otf` files into `app/assets/fonts/` (Alloy) or `Resources/fonts/` (Classic), renamed to their **PostScript names**. iOS reads PostScript names while Android tolerates filenames; by renaming both platforms work from the same `fontFamily` value.
287
309
 
288
310
  > **🛑 Font Awesome Duotone**
289
311
  > Titanium cannot render Font Awesome duotone icons because each icon uses two glyphs. If you work with Font Awesome Pro, avoid documenting duotone as supported.
@@ -56,7 +56,7 @@ module.exports = {
56
56
 
57
57
  // One block per piece. Artwork comes from purgetss/brand/logo-<piece>.{svg,png};
58
58
  // these keys are for numbers, colors and activation. Padding is never inherited.
59
- icon: { padding: '4%' }, // DefaultIcon.png + DefaultIcon-ios.png
59
+ icon: { padding: '0%' }, // DefaultIcon.png + DefaultIcon-ios.png
60
60
  dark: { background: null }, // DefaultIcon-Dark.png
61
61
  tinted: {}, // DefaultIcon-Tinted.png
62
62
  iosSplash: { padding: '26%' }, // assets/iphone/Default*.png × 16
@@ -1,6 +1,6 @@
1
1
  # Icon Font Libraries
2
2
 
3
- PurgeTSS ships with four official icon font families, each preconfigured with the TSS classes and `fontFamily` mappings you need to drop icons into Buttons, Labels, and TextFields.
3
+ PurgeTSS ships with four official icon font families. Alloy projects can use their preconfigured TSS classes; Classic projects can install the same fonts and use `fontFamily` plus Unicode directly or through the optional CommonJS modules.
4
4
 
5
5
  For user-defined fonts (Google Fonts, brand typefaces, community icon libraries like map-icons or microns), see [Custom Fonts](./custom-fonts.md) — those use `build-fonts`, not `icon-library`.
6
6
 
@@ -43,7 +43,7 @@ The complete class definitions live in the PurgeTSS `dist/` folder:
43
43
 
44
44
  ## Installing the icon fonts
45
45
 
46
- Run `icon-library` to copy the `.ttf` files into `./app/assets/fonts/`. That is the only step you need. Once the fonts are in place, the icon classes from the table above work out of the box.
46
+ Run `icon-library` to copy the font files to `app/assets/fonts/` (Alloy) or `Resources/fonts/` (Classic). Alloy can then use the icon classes from the table; Classic does not run class resolution.
47
47
 
48
48
  ```bash
49
49
  # All four families
@@ -56,14 +56,14 @@ $ purgetss il -v=fa,mi,ms,f7
56
56
  > ℹ️ **INFO — You do not need the `.tss` files in `./purgetss/styles/`**
57
57
  > PurgeTSS already knows every official icon class and resolves them at compile time from its own bundled `dist/` files. You do not need `fontawesome.tss`, `materialsymbols.tss`, `materialicons.tss`, or `framework7icons.tss` inside `./purgetss/styles/` for `class="fas fa-home"` (or any other icon class) to work in your XML and controllers. Install the `.ttf` files with `icon-library` and the classes are ready.
58
58
  >
59
- > The resolved classes are written to the generated `app/styles/app.tss`, not to `purgetss/styles/utilities.tss`. If you go looking for a class like `.ms-home`, check `app.tss`.
59
+ > The resolved Alloy classes are written to generated `app/styles/app.tss`, not `purgetss/styles/utilities.tss`. Classic receives only native fonts and any requested JavaScript module.
60
60
 
61
61
  ### Optional flags
62
62
 
63
63
  Two optional flags adjust what `icon-library` copies into your project:
64
64
 
65
- - `-s, --styles`: copies the official `.tss` source files into `./purgetss/styles/` for reference only. Useful if you want to grep the full class list, see how a class is defined, or override a specific class in your own project.
66
- - `-m, --module`: copies the matching CommonJS module into `./app/lib/`, which exposes each icon's Unicode string to JavaScript. Handy when you set `label.text` from a controller and prefer a friendly name like `icons.fa.home` over a raw ``.
65
+ - `-s, --styles`: Alloy only. Copies the official `.tss` sources into `purgetss/styles/` for reference. Classic skips this output.
66
+ - `-m, --module`: copies the matching CommonJS module into `app/lib/` (Alloy) or `Resources/lib/` (Classic), exposing Unicode strings and stable font-family aliases.
67
67
 
68
68
  ```bash
69
69
  # Add either flag when you want them
@@ -81,7 +81,32 @@ $ purgetss il -m -s
81
81
  - `ms`, `materialsymbol` = Material Symbols
82
82
  - `f7`, `framework7` = Framework7 Icons
83
83
 
84
- ## Using icons in XML
84
+ ### CommonJS modules in Classic
85
+
86
+ Each module exposes its existing icon lookup API plus a `families` object with `families.default`. Direct aliases are also available:
87
+
88
+ | Module | Direct aliases |
89
+ | --- | --- |
90
+ | `fontawesome` | `solid`, `regular`, `brands` |
91
+ | `materialicons` | `regular`, `outlined`, `round`, `sharp`, `twoTone` |
92
+ | `materialsymbols` | `outlined`, `rounded`, `sharp` |
93
+ | `framework7icons` | `fontFamily` |
94
+
95
+ ```javascript
96
+ const fontAwesome = require('fontawesome')
97
+
98
+ const home = Ti.UI.createLabel({
99
+ text: fontAwesome.icons.home,
100
+ font: {
101
+ fontFamily: fontAwesome.solid,
102
+ fontSize: 24
103
+ }
104
+ })
105
+ ```
106
+
107
+ The direct alias and `families` values agree, for example `fontAwesome.solid === fontAwesome.families.solid`; `families.default` provides the library's default variant.
108
+
109
+ ## Using icons in Alloy XML
85
110
 
86
111
  The variant class sets the `fontFamily`. The icon class sets the glyph (`text` / `title`). Apply both together:
87
112
 
@@ -12,6 +12,12 @@ Install PurgeTSS globally on your machine using [NPM](https://www.npmjs.com/).
12
12
  > Node.js 20+ required.
13
13
  > PurgeTSS requires Node 20.0.0 or higher.
14
14
 
15
+ ## Alloy vs. Classic Setup
16
+
17
+ The root `purgetss` command, `init`, `create`, `install-dependencies`, `build`, and `watch` belong to the Alloy utility-class lifecycle described below. Do not run them to “set up PurgeTSS” in a Classic project.
18
+
19
+ Classic projects can run compatible standalone commands directly: `brand`, `images`, `semantic`, `shades`, `color-module`, `module`, `icon-library`, and `build-fonts`. Their native outputs go under `Resources/`, and the application does not need an `alloy.jmk` hook or PurgeTSS at compile/runtime. See [Classic Project Support](./classic-projects.md).
20
+
15
21
  ## XML Validation
16
22
 
17
23
  Before purging, PurgeTSS pre-checks every XML file in your project. One case worth calling out: double dashes (`--`) are not allowed inside XML comments. That restriction comes from the XML spec itself, not from PurgeTSS, but many people only run into it once a tool actually parses the file.
@@ -44,7 +50,7 @@ Pick whichever of these reads best:
44
50
 
45
51
  Any of those approaches keeps the comment readable and produces a document that every XML parser will accept.
46
52
 
47
- ## Run PurgeTSS the First Time
53
+ ## Run PurgeTSS the First Time (Alloy Only)
48
54
 
49
55
  > **INFO**
50
56
  > Run `purgetss` once in your project to generate the required files and folders.
@@ -1,6 +1,6 @@
1
1
  # Multi-Density Images
2
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.
3
+ The `purgetss images` command generates every Titanium density variant of your UI images from one high-resolution source. Alloy and Classic layouts are auto-detected. Since v7.15.0, a normal run follows the enabled platforms in `tiapp.xml`; `--android` and `--ios` are explicit overrides.
4
4
 
5
5
  - **Android**: `res-mdpi`, `res-hdpi`, `res-xhdpi`, `res-xxhdpi`, `res-xxxhdpi` (5 densities)
6
6
  - **iPhone**: `@1x`, `@2x`, `@3x` (3 scales via filename suffix)
@@ -10,7 +10,7 @@ For the terse flag reference, see the [`images` command reference](./cli-command
10
10
  > **INFO**
11
11
  >
12
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.
13
+ > One source per image in `purgetss/images/`, run `purgetss images`, and every density lands under `app/assets/` (Alloy) or `Resources/` (Classic).
14
14
 
15
15
  <!-- TOC-START -->
16
16
  ## Contents
@@ -80,11 +80,11 @@ app/assets/
80
80
  └── primary@3x.svg
81
81
  ```
82
82
 
83
- 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.
83
+ Classic projects output to `Resources/android/images/res-*/` and `Resources/iphone/images/` — the command auto-detects the layout.
84
84
 
85
85
  ## The `purgetss/images/` convention
86
86
 
87
- `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.
87
+ Alloy `init` creates `purgetss/images/` alongside `fonts/` and `brand/`. In standalone Classic, running `purgetss images` without a positional source establishes the convention folder. Passing an existing external source does not create an empty `purgetss/images/` folder or config file.
88
88
 
89
89
  ```text
90
90
  purgetss/images/
@@ -99,7 +99,7 @@ purgetss/images/
99
99
 
100
100
  Supported input formats: `.svg`, `.png`, `.jpg`, `.jpeg`, `.webp`, `.gif`.
101
101
 
102
- **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.
102
+ **Subdirectories are preserved in the output.** A file at `purgetss/images/buttons/primary.png` ends up under the matching `app/assets/` or `Resources/` platform roots. Organize however makes sense for your project.
103
103
 
104
104
  > **INFO**
105
105
  >
@@ -264,7 +264,7 @@ Raster entries you add by hand survive subsequent runs untouched. For SVGs detec
264
264
 
265
265
  ```text
266
266
  <project>/
267
- └── assets/
267
+ └── Resources/
268
268
  ├── android/images/res-*/
269
269
  └── iphone/images/
270
270
  ```
@@ -329,11 +329,11 @@ purgetss images ./docs/screenshots/home-hero.png
329
329
  purgetss images /Users/cesar/Design/banner.svg
330
330
  ```
331
331
 
332
- When the source is outside `purgetss/images/`, subdirectory preservation uses the directory of the source file as the root instead.
332
+ When the source is outside `purgetss/images/`, subdirectory preservation uses the directory of the source file as the root instead. Processing that external source in Classic does not bootstrap unrelated PurgeTSS folders or config.
333
333
 
334
334
  ## Platform filter
335
335
 
336
- By default, every run generates both Android densities and iPhone scales. Scope to one platform for targeted runs:
336
+ By default, the command follows `<deployment-targets>` in `tiapp.xml`. Pass a platform flag to override that selection for a targeted run:
337
337
 
338
338
  ```bash
339
339
  purgetss images --android # Android only (skip iPhone)
@@ -345,7 +345,7 @@ Useful when:
345
345
  - You're iterating on an iOS-only screen and don't need to regenerate Android assets every time.
346
346
  - You want to tune JPEG quality differently for the two platforms (run the command twice with different flags).
347
347
 
348
- The two flags are mutually exclusive. Pass neither to get both.
348
+ The two flags are mutually exclusive. Passing neither means “use the project's enabled targets,” not “always generate both.”
349
349
 
350
350
  ## Format conversion
351
351
 
@@ -462,7 +462,7 @@ If you only tweaked CSS classes (no image changes), you don't need to re-run `pu
462
462
 
463
463
  ## Cleaning up
464
464
 
465
- `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.
465
+ `purgetss images` never deletes files. It only creates them. If you remove a source, generated copies under `app/assets/` (Alloy) or `Resources/` (Classic) stay in place. Remove them manually or with git when you clean up.
466
466
 
467
467
  ## Full flag reference
468
468
 
@@ -8,7 +8,7 @@ For the mode-switching runtime that drives all of this (`Appearance.init()`, `Ap
8
8
 
9
9
  > **INFO**
10
10
  >
11
- > Semantic color resolution is a **Titanium** feature, not PurgeTSS magic. Titanium natively reads `semantic.colors.json` (at `app/assets/` on Alloy, `Resources/` on Classic) and resolves any color-accepting property whose value matches a key in that file. PurgeTSS only generates the utility classes that point *at* those keys — the switching behavior is 100% native.
11
+ > Semantic color resolution is a **Titanium** feature, not PurgeTSS magic. Titanium natively reads `semantic.colors.json` (at `app/assets/` on Alloy, `Resources/` on Classic) and resolves any color-accepting property whose value matches a key in that file. In Alloy, PurgeTSS also generates utility mappings that point at those keys; Classic uses the keys directly. The switching behavior is native in both layouts.
12
12
 
13
13
  <!-- TOC-START -->
14
14
  ## Contents
@@ -17,7 +17,7 @@ For the mode-switching runtime that drives all of this (`Appearance.init()`, `Ap
17
17
  - [Registering in `config.cjs`](#registering-in-configcjs)
18
18
  - [Numeric 11-step tonal-inversion palette](#numeric-11-step-tonal-inversion-palette)
19
19
  - [The `semantic` CLI command](#the-semantic-cli-command)
20
- - [Using semantic classes in views](#using-semantic-classes-in-views)
20
+ - [Using semantic classes in Alloy views](#using-semantic-classes-in-alloy-views)
21
21
  - [Using semantic colors in controllers](#using-semantic-colors-in-controllers)
22
22
  - [Recommended starter palette](#recommended-starter-palette)
23
23
  - [Related](#related)
@@ -235,13 +235,15 @@ One base hex plus a family name produces 11 JSON entries with mirror inversion,
235
235
  purgetss semantic '#15803d' amazon
236
236
  ```
237
237
 
238
- This:
238
+ In Alloy, this:
239
239
 
240
240
  1. Generates `amazon50` through `amazon950` using the same algorithm as the `shades` command.
241
- 2. Writes `semantic.colors.json` at the project's canonical location (`app/assets/` on Alloy, `Resources/` on Classic) with mirror-by-index values — 50 ↔ 950, 100 ↔ 900, …, 500 as the identical anchor.
241
+ 2. Writes `semantic.colors.json` under `app/assets/` with mirror-by-index values — 50 ↔ 950, 100 ↔ 900, …, 500 as the identical anchor.
242
242
  3. Writes the `{ 50: 'amazon50', 100: 'amazon100', ... }` mapping into `config.cjs`.
243
243
  4. Strips any prior keys for the `amazon` family before writing — re-runs cleanly replace, never duplicate.
244
244
 
245
+ In Classic, the same command writes only the native `Resources/semantic.colors.json` entries. It does not create `purgetss/`, `config.cjs`, utility mappings, TSS, `app/`, or an Alloy hook. Use keys such as `amazon50` directly in Titanium color properties.
246
+
245
247
  Useful flags:
246
248
 
247
249
  - `--log` (`-l`) — preview the JSON on the console without writing anything.
@@ -270,7 +272,7 @@ purgetss semantic --single '#000000' overlayColor --alpha 50
270
272
 
271
273
  The name is preserved verbatim as the JSON key (camelCase is respected). When `--dark` is omitted, it defaults to the light hex — useful for overlays where alpha is the only variation between modes.
272
274
 
273
- Single mode writes **both files** in one shot. The class name is auto-derived from the semantic key by stripping the conventional `Color` suffix and kebab-casing the rest, so `surfaceHighColor` becomes the `surface-high` class:
275
+ In Alloy, single mode writes **both files** in one shot. The class name is auto-derived from the semantic key by stripping the conventional `Color` suffix and kebab-casing the rest, so `surfaceHighColor` becomes the `surface-high` class. In Classic, it writes only the native JSON entry and code uses the semantic key directly:
274
276
 
275
277
  `./purgetss/config.cjs` (auto-generated)
276
278
  ```js
@@ -301,7 +303,7 @@ After the batch above you can use `bg-surface`, `bg-surface-high`, `text-text`,
301
303
 
302
304
  Alpha follows the Titanium spec exactly: range `0.0-100.0`, stored as a **string**, wrapped per-mode as `{ color, alpha }`. Without `--alpha`, values stay as bare hex strings. Out-of-range values are rejected before any file is written.
303
305
 
304
- ## Using semantic classes in views
306
+ ## Using semantic classes in Alloy views
305
307
 
306
308
  Once the JSON and the `config.cjs` mapping are in place, you use the semantic classes like any other PurgeTSS utility:
307
309
 
@@ -315,6 +317,14 @@ Once the JSON and the `config.cjs` mapping are in place, you use the semantic cl
315
317
  </Window>
316
318
  ```
317
319
 
320
+ Classic has no utility mapping. Use the native semantic key directly:
321
+
322
+ ```javascript
323
+ const window = Ti.UI.createWindow({
324
+ backgroundColor: 'surfaceColor'
325
+ })
326
+ ```
327
+
318
328
  When the appearance changes — whether from `Appearance.set(...)` or a system-level toggle — Titanium resolves each semantic color name to its `light` or `dark` value automatically. No event listeners, no manual repaint.
319
329
 
320
330
  ### Opacity modifier auto-derivation
@@ -440,5 +450,5 @@ Start with these 6-7 colors and add more only when the design requires it. Fewer
440
450
  ## Community-Discovered Patterns
441
451
 
442
452
  - **The `[object Object]` crash is always a missing `DEFAULT`.** Any time a view renders with a mysterious fallback color and the class was something like `bg-surface`, check `config.cjs` first: if `surface` is a nested object without a `DEFAULT` key, PurgeTSS serializes the whole object and emits `[object Object]` as the color value. The fix is either to add `DEFAULT: 'surfaceColor'` inside the nested object or flatten the structure.
443
- - **Semantic resolution is Titanium-native, not PurgeTSS.** This matters when debugging: if a semantic name doesn't resolve, the problem is usually the `semantic.colors.json` file (wrong filename, wrong key, malformed JSON, or file in the wrong location — Alloy expects `app/assets/`, Classic expects `Resources/`), not PurgeTSS. PurgeTSS's job ends at generating the class that points at the name.
453
+ - **Semantic resolution is Titanium-native, not PurgeTSS.** This matters when debugging: if a semantic name doesn't resolve, the problem is usually the `semantic.colors.json` file (wrong filename, wrong key, malformed JSON, or wrong location — Alloy expects `app/assets/`, Classic expects `Resources/`). PurgeTSS generates the file in both layouts and an additional utility mapping only in Alloy.
444
454
  - **Re-running `purgetss semantic` on the same family is safe.** The CLI strips prior keys for that family from both the JSON and `config.cjs` before writing, so switching between palette and single forms — or changing the base hex — does not leave orphans. Other palettes and manually-defined entries are untouched.
@@ -8,6 +8,22 @@ When in doubt about whether a class, flag, or config key exists in the user's in
8
8
 
9
9
  ---
10
10
 
11
+ ## v7.15.0
12
+ - Standalone `images`, `semantic`, `shades`, `color-module`, `module`, `icon-library`, and `build-fonts` now support Classic without installing the Alloy hook or utility-class lifecycle. Outputs route to native `Resources/` paths where appropriate. See [classic-projects.md](classic-projects.md).
13
+ - `images` follows `<deployment-targets>` from `tiapp.xml` by default; explicit `--android` / `--ios` override that selection.
14
+ - Classic `semantic` writes only `Resources/semantic.colors.json`; external Classic `images` runs no longer create unrelated empty `purgetss/` or config artifacts.
15
+ - Official icon-font CommonJS modules expose stable `families.default` plus variant aliases. Existing icon lookup APIs remain intact. See [icon-fonts.md](icon-fonts.md).
16
+
17
+ ## v7.14.0
18
+ - `brand` became self-contained in standalone Classic projects: it creates the canonical config when missing and adopts a positional logo into `purgetss/brand/logo.{png,svg}` after confirmation when no canonical source exists.
19
+ - Normal `brand` runs follow `tiapp.xml` deployment targets; explicit `--only` remains an intentional override.
20
+ - Classic Android now receives the 11 `Resources/android/images/res-*` splash variants Titanium consumes, even when `ti create` did not seed the directories.
21
+ - Square iOS/store artwork defaults to full-bleed `0%` padding. Android adaptive (`18%`), legacy (`10%`), and splash (`26%`) defaults remain platform-specific.
22
+ - Fixes align `DefaultIcon.png` and `DefaultIcon-ios.png` with `brand.icon.padding` and make the documented legacy padding the actual per-side inset.
23
+
24
+ ## v7.13.2
25
+ - `brand --help` padding defaults now come from the same piece table as the pipeline. The help output correctly reports adaptive `18%` and splash `26%`; do not preserve the older “stale help strings” warning.
26
+
11
27
  ## v7.13.1
12
28
  - Four vulnerable transitive dependencies patched (`postcss`, `nanoid`, `brace-expansion`, `uuid`). Lockfile only; no API or class changes.
13
29