- name
- purgetss
- 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.
- allowed-tools
- Read, Grep, Glob, Edit, Write, Bash(purgetss *), Bash(node *)
# PurgeTSS Expert
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.
## Required workflow (read before responding)
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.**
### Step 1 — Detect the project type
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).
- **Alloy:** utility classes and every standalone command are available.
- **Classic:** only the supported standalone commands are available. Do not introduce `app/`, `alloy.jmk`, generated TSS, utility classes, or `$.UI.create()`.
### Step 2 — Open the relevant reference files
| Task involves | Required reading |
|---|---|
| Alloy vs. Classic support or output paths | [references/classic-projects.md](references/classic-projects.md), [references/cli-commands.md](references/cli-commands.md) |
| Setup, auto-purge, or `watch` diagnostics | [references/installation-setup.md](references/installation-setup.md), [references/cli-commands.md](references/cli-commands.md) |
| Choosing utility classes | [references/class-index.md](references/class-index.md) |
| Layout (horizontal/vertical/composite, grid) | [references/grid-layout.md](references/grid-layout.md), [references/ui-ux-design.md](references/ui-ux-design.md) |
| Dynamic components in controllers | [references/dynamic-component-creation.md](references/dynamic-component-creation.md) |
| App branding or artwork geometry | [references/app-branding.md](references/app-branding.md), [references/cli-commands.md](references/cli-commands.md) |
| SVG / multi-density image assets | [references/svg-pipeline.md](references/svg-pipeline.md), [references/multi-density-images.md](references/multi-density-images.md) |
| Custom values / arbitrary syntax | [references/arbitrary-values.md](references/arbitrary-values.md) |
| Platform-specific styles (`ios:`, `android:`) | [references/platform-modifiers.md](references/platform-modifiers.md) |
| Dark/Light mode | [references/semantic-colors.md](references/semantic-colors.md), [references/appearance-module.md](references/appearance-module.md) |
| Apply directive / class extraction | [references/apply-directive.md](references/apply-directive.md) |
| Custom or icon fonts | [references/custom-fonts.md](references/custom-fonts.md), [references/icon-fonts.md](references/icon-fonts.md) |
| Animations in Alloy | [references/animation-system.md](references/animation-system.md), [references/animation-advanced.md](references/animation-advanced.md) |
| `purgetss.ui` in Classic | [references/purgetss-ui-classic.md](references/purgetss-ui-classic.md), [references/classic-projects.md](references/classic-projects.md) |
### Step 3 — Output contract
Every utility class you suggest and every styling pattern you describe MUST be backed by a citation in the form:
`[source: references/<file>.md]`
Example: *"Use `wh-12` to set width and height to 48 [source: references/class-index.md]"*
### Step 4 — If you must answer from memory
If you write a claim without having read the reference that backs it, prepend `FROM_MEMORY (unverified):` to that claim. Do not hide it.
### Banned behaviors
- ❌ Writing utility classes "from memory" without citing any reference
- ❌ Confusing PurgeTSS classes with Tailwind — they share naming but differ
- ❌ Marking the answer complete without listing which reference files you read
- ❌ Suggesting a class without first verifying it exists in `class-index.md`
- ❌ Applying Alloy utility classes, generated TSS, `alloy.jmk`, or `$.UI.create()` to a Classic project
## Project Detection and Mode Selection
> **️ℹ️ AUTO-DETECTS PURGETSS PROJECTS**
> This skill automatically detects PurgeTSS usage when invoked and provides utility-first styling guidance.
>
> **Detection occurs automatically** - no manual command needed.
>
> **PurgeTSS indicators:**
> - `purgetss/` folder
> - `purgetss/config.cjs` configuration file
> - `purgetss/styles/utilities.tss` utility classes
> - A generated `app/styles/app.tss` whose header names PurgeTSS
> - `app/lib/purgetss.{ui,colors,fonts}.js` or `Resources/lib/purgetss.{ui,colors,fonts}.js`
>
> `app/styles/app.tss` by itself is not proof: ordinary Alloy projects can have that file.
>
> **Behavior based on detection and layout:**
> - **Alloy + PurgeTSS utility lifecycle detected** → Provides utility-class guidance and may suggest `$.UI.create()` for dynamic components
> - **Classic + PurgeTSS standalone command detected/requested** → Provides only asset, color, font, branding, or CommonJS command guidance with `Resources/` destinations
> - **Not detected** → Does NOT suggest PurgeTSS utility classes, does NOT recommend `$.UI.create()`, does NOT reference PurgeTSS-specific patterns
## Core Workflows
### Alloy utility-class workflow
1. **Setup**: `purgetss create 'name'` or `purgetss init` for an existing Alloy project.
2. **Build**: Write Alloy XML/controller classes; PurgeTSS generates `app/styles/app.tss`.
3. **Configure**: Customize utilities through `purgetss/config.cjs`.
### Classic standalone workflow
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.
## Alloy Utility Project Structure
```bash
./purgetss/
├─ fonts/ # Custom font files (.ttf, .otf)
├─ styles/
│ ├─ definitions.css # For VS Code IntelliSense
│ └─ utilities.tss # All PurgeTSS utility classes
└─ config.cjs # Theme configuration
./app/styles/
├─ app.tss # AUTO-GENERATED - DO NOT EDIT DIRECTLY
└─ _app.tss # YOUR CUSTOM STYLES (persists across runs)
```
### Understanding `app.tss` vs `_app.tss`
> **⚠️ CRITICAL: app.tss IS AUTO-GENERATED**
> **`app.tss` is ALWAYS regenerated** every time the app compiles.
>
> PurgeTSS scans ALL XMLs and Controllers for utility classes, then generates a fresh `app.tss` containing only the classes actually used.
>
> **NEVER edit `app.tss` directly** - your changes WILL be overwritten on the next build.
> **️ℹ️ THE `_app.tss` BACKUP FILE**
> On **first run**, PurgeTSS backs up your original `app.tss` to `_app.tss`.
>
> **`_app.tss` is your custom styles file** - it persists across all PurgeTSS runs.
>
> Every build, PurgeTSS:
> 1. Scans XMLs and Controllers for used classes
> 2. Regenerates `app.tss` from scratch
> 3. Copies `_app.tss` content into the generated `app.tss`
>
> Better approach: define custom classes in `config.cjs` instead of `_app.tss`.
### Checking for Unused/Unsupported Classes
> **🚨 ALWAYS CHECK `app.tss` FOR ERRORS**
> At the **end of every generated `app.tss`**, look for this section:
>
> ```tss
> // Unused or unsupported classes
> // .my-typo-class
> // .non-existent-utility
> ```
>
> **These are classes used in your XMLs or Controllers that have NO definition anywhere:**
> - Not in `utilities.tss` (generated from PurgeTSS utilities)
> - Not in `_app.tss` (your custom styles)
> - Not in any other `.tss` file in the `styles/` folder
>
> **This means:**
> 1. You have a **typo** in your class name
> 2. You're using a class that **doesn't exist** in PurgeTSS
> 3. You need to **define the class** in `_app.tss` or `config.cjs`
>
> **As part of any analysis, ALWAYS check the end of `app.tss` and report any unused/unsupported classes to the user!**
### How `utilities.tss` Works
> **️ℹ️ UTILITIES.TSS REGENERATION**
> `./purgetss/styles/utilities.tss` contains ALL available PurgeTSS utility classes.
>
> **It regenerates when `./purgetss/config.cjs` changes** - this is where you define:
> - Custom colors
> - Custom spacing scales
> - Ti Element styles
> - Any project-specific utilities
>
> 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.
## Alloy Quick Start
```bash
purgetss create 'MyApp' -d -v fa
# -d: Install dev dependencies (ESLint, Tailwind)
# -v: Copy icon fonts (fa, mi, ms, f7)
```
> **💡 NEW PROJECT: Clean Up Default app.tss**
> For new projects created with `purgetss create`, the default `app/styles/app.tss` contains a large commented template.
>
> **You can safely DELETE this file** - PurgeTSS will regenerate it on the first build with only the classes you actually use, and create a clean `_app.tss` backup.
>
> This prevents carrying around unnecessary commented code and ensures a fresh start.
## Critical Rules (Low Freedom)
### ⭐ ALLOY ONLY: Prefer `$.UI.create()` for Dynamic Components
> **💡 RECOMMENDED FOR DYNAMIC COMPONENTS**
> When creating components dynamically in Controllers, **use `$.UI.create()` instead of `Ti.UI.create()`** to get full PurgeTSS utility class support:
>
> ```javascript
> // ✅ RECOMMENDED - Full PurgeTSS support
> const view = $.UI.create('View', {
> classes: ['w-screen', 'h-auto', 'bg-white', 'rounded-lg']
> })
>
> // ❌ AVOID - No PurgeTSS classes
> const view = Ti.UI.createView({
> width: Ti.UI.FILL,
> height: Ti.UI.SIZE,
> backgroundColor: '#ffffff',
> borderRadius: 8
> })
> ```
>
> See [Dynamic Component Creation](references/dynamic-component-creation.md) for complete guide.
### 🚨 RESPECT USER FILES
**NEVER delete any existing `.tss` files** (like `index.tss`, `detail.tss`) or other project files without explicit user consent.
**How to handle migration to PurgeTSS** (full workflow and translation tables in [adopting-purgetss.md](references/adopting-purgetss.md)):
1. **ONLY** replace custom classes with PurgeTSS utility classes if the user explicitly requests it.
2. When requested:
- Analyze the definitions in the existing `.tss` files.
- Update the XML/Controller components with equivalent PurgeTSS utility classes.
- **WAIT** for user confirmation before suggesting or performing any file deletion.
3. If the user prefers keeping manual `.tss` files for specific styles, respect that choice and only use PurgeTSS for new or requested changes.
### 🚨 NO FLEXBOX - Titanium Doesn't Support It
> **🚨 FLEXBOX CLASSES DO NOT EXIST**
> The following are **NOT supported**:
> - ❌ `flex`, `flex-row`, `flex-col`
> - ❌ `justify-between`, `justify-center`, `justify-start`, `justify-end`
> - ❌ `items-center` for alignment (exists but sets `width/height: FILL`)
>
> **Use Titanium layouts instead:**
> - ✅ `horizontal` - Children left to right
> - ✅ `vertical` - Children top to bottom
> - ✅ Omit layout class - Defaults to `composite` (absolute positioning)
>
> **💡 CRITICAL: Understanding Layout Composition**
> When building complex UIs, carefully choose the layout mode for each container:
>
> **`vertical`** - Stack elements top to bottom (most common):
> ```xml
> <ScrollView class="vertical">
> <View class="mb-4">Item 1</View>
> <View class="mb-4">Item 2</View>
> <View>Item 3</View>
> </ScrollView>
> ```
>
> **`horizontal`** - Arrange elements left to right:
> ```xml
> <View class="horizontal w-screen">
> <Label text="First" />
> <Label class="ml-4" text="Second" /> <!-- ml-4 = 16 after the previous sibling -->
> </View>
> ```
>
> **`composite`** (default) - Absolute positioning with `top`, `left`, etc. (to pin one child left and another right, use a composite parent with `left-0` / `right-0`):
> ```xml
> <View class="h-screen w-screen">
> <View class="wh-12 left-0 top-0 bg-red-500" />
> <View class="wh-12 bottom-0 right-0 bg-blue-500" />
> </View>
> ```
>
> **Common Issue:** If you see elements appearing in unexpected positions (e.g., a header bar "behind" content), check if parent containers have conflicting layout modes. Each container's layout affects its direct children only.
### 🚨 PLATFORM-SPECIFIC PROPERTIES REQUIRE MODIFIERS
> **🚨 CRITICAL: Platform-Specific Properties Require Modifiers**
> Using `Ti.UI.iOS.*` or `Ti.UI.Android.*` properties WITHOUT platform modifiers causes cross-platform compilation failures.
>
> **WRONG - Adds iOS code to Android (causes failure):**
> ```tss
> // ❌ BAD - Adds Ti.UI.iOS to Android project
> "#mainWindow": {
> statusBarStyle: Ti.UI.iOS.StatusBar.LIGHT_CONTENT
> }
> ```
>
> **CORRECT - Use platform modifiers in TSS:**
> ```tss
> // ✅ GOOD - Only adds to iOS
> "#mainWindow[platform=ios]": {
> statusBarStyle: Ti.UI.iOS.StatusBar.LIGHT_CONTENT
> }
> ```
>
> **OR use PurgeTSS platform modifier classes:**
> ```xml
> <!-- ✅ GOOD - status-bar-* classes are already emitted as [platform=ios] -->
> <Window class="status-bar-light">
>
> <!-- ✅ GOOD - ios: / android: scope any other class to one platform -->
Voir sur GitHub