@maccesar/titools 2.2.3 → 2.2.8
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 +28 -27
- package/lib/commands/update.js +80 -101
- package/package.json +1 -1
- package/skills/alloy-guides/SKILL.md +31 -31
- package/skills/alloy-guides/references/CONCEPTS.md +3 -3
- package/skills/alloy-guides/references/CONTROLLERS.md +1 -1
- package/skills/alloy-guides/references/MODELS.md +6 -6
- package/skills/alloy-guides/references/VIEWS_WITHOUT_CONTROLLERS.md +1 -1
- package/skills/alloy-guides/references/VIEWS_XML.md +1 -1
- package/skills/alloy-guides/references/WIDGETS.md +1 -1
- package/skills/alloy-howtos/SKILL.md +27 -27
- package/skills/alloy-howtos/references/best_practices.md +9 -9
- package/skills/alloy-howtos/references/cli_reference.md +14 -14
- package/skills/alloy-howtos/references/config_files.md +16 -16
- package/skills/alloy-howtos/references/custom_tags.md +16 -16
- package/skills/alloy-howtos/references/debugging_troubleshooting.md +11 -15
- package/skills/alloy-howtos/references/samples.md +19 -19
- package/skills/purgetss/SKILL.md +11 -1
- package/skills/purgetss/references/animation-system.md +1 -1
- package/skills/purgetss/references/cli-commands.md +3 -3
- package/skills/purgetss/references/customization-deep-dive.md +1 -1
- package/skills/purgetss/references/dynamic-component-creation.md +1 -1
- package/skills/purgetss/references/icon-fonts.md +4 -0
- package/skills/purgetss/references/installation-setup.md +8 -1
- package/skills/purgetss/references/migration-guide.md +4 -0
- package/skills/purgetss/references/tikit-components.md +193 -204
- package/skills/purgetss/references/ui-ux-design.md +1 -1
- package/skills/ti-expert/SKILL.md +78 -118
- package/skills/ti-expert/references/alloy-builtins.md +18 -18
- package/skills/ti-expert/references/alloy-structure.md +21 -21
- package/skills/ti-expert/references/anti-patterns.md +15 -15
- package/skills/ti-expert/references/cli-expert.md +15 -15
- package/skills/ti-expert/references/code-conventions.md +38 -38
- package/skills/ti-expert/references/contracts.md +8 -8
- package/skills/ti-expert/references/controller-patterns.md +14 -14
- package/skills/ti-expert/references/error-handling.md +11 -11
- package/skills/ti-expert/references/examples.md +12 -12
- package/skills/ti-expert/references/migration-patterns.md +24 -24
- package/skills/ti-expert/references/patterns.md +10 -10
- package/skills/ti-expert/references/performance-listview.md +16 -16
- package/skills/ti-expert/references/performance-optimization.md +41 -41
- package/skills/ti-expert/references/security-device.md +22 -22
- package/skills/ti-expert/references/security-fundamentals.md +19 -19
- package/skills/ti-expert/references/state-management.md +33 -33
- package/skills/ti-expert/references/testing-e2e-ci.md +25 -25
- package/skills/ti-expert/references/testing-unit.md +24 -24
- package/skills/ti-expert/references/theming.md +15 -15
- package/skills/ti-guides/SKILL.md +58 -60
- package/skills/ti-guides/references/advanced-data-and-images.md +33 -33
- package/skills/ti-guides/references/android-manifest.md +15 -15
- package/skills/ti-guides/references/app-distribution.md +70 -166
- package/skills/ti-guides/references/application-frameworks.md +96 -114
- package/skills/ti-guides/references/cli-reference.md +294 -294
- package/skills/ti-guides/references/coding-best-practices.md +42 -33
- package/skills/ti-guides/references/commonjs-advanced.md +57 -51
- package/skills/ti-guides/references/hello-world.md +36 -36
- package/skills/ti-guides/references/hyperloop-native-access.md +66 -66
- package/skills/ti-guides/references/javascript-primer.md +83 -101
- package/skills/ti-guides/references/reserved-words.md +9 -9
- package/skills/ti-guides/references/resources.md +75 -83
- package/skills/ti-guides/references/style-and-conventions.md +35 -28
- package/skills/ti-guides/references/tiapp-config.md +110 -74
- package/skills/ti-howtos/SKILL.md +88 -92
- package/skills/ti-howtos/references/android-platform-deep-dives.md +104 -104
- package/skills/ti-howtos/references/automation-fastlane-appium.md +39 -39
- package/skills/ti-howtos/references/buffer-codec-streams.md +60 -60
- package/skills/ti-howtos/references/cross-platform-development.md +115 -136
- package/skills/ti-howtos/references/debugging-profiling.md +167 -181
- package/skills/ti-howtos/references/extending-titanium.md +121 -121
- package/skills/ti-howtos/references/google-maps-v2.md +84 -82
- package/skills/ti-howtos/references/ios-map-kit.md +65 -60
- package/skills/ti-howtos/references/ios-platform-deep-dives.md +123 -123
- package/skills/ti-howtos/references/local-data-sources.md +79 -78
- package/skills/ti-howtos/references/location-and-maps.md +116 -120
- package/skills/ti-howtos/references/media-apis.md +87 -86
- package/skills/ti-howtos/references/notification-services.md +250 -260
- package/skills/ti-howtos/references/remote-data-sources.md +98 -93
- package/skills/ti-howtos/references/tutorials.md +226 -216
- package/skills/ti-howtos/references/using-modules.md +73 -102
- package/skills/ti-howtos/references/web-content-integration.md +101 -103
- package/skills/ti-howtos/references/webpack-build-pipeline.md +52 -44
- package/skills/ti-ui/SKILL.md +85 -85
- package/skills/ti-ui/references/accessibility-deep-dive.md +57 -57
- package/skills/ti-ui/references/animation-and-matrices.md +79 -79
- package/skills/ti-ui/references/application-structures.md +96 -99
- package/skills/ti-ui/references/custom-fonts-styling.md +99 -99
- package/skills/ti-ui/references/event-handling.md +58 -58
- package/skills/ti-ui/references/gestures.md +62 -64
- package/skills/ti-ui/references/icons-and-splash-screens.md +88 -88
- package/skills/ti-ui/references/layouts-and-positioning.md +87 -97
- package/skills/ti-ui/references/listviews-and-performance.md +107 -107
- package/skills/ti-ui/references/orientation.md +87 -88
- package/skills/ti-ui/references/platform-ui-android.md +87 -81
- package/skills/ti-ui/references/platform-ui-ios.md +63 -61
- package/skills/ti-ui/references/scrolling-views.md +29 -29
- package/skills/ti-ui/references/tableviews.md +56 -56
package/README.md
CHANGED
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
|
|
9
9
|
</div>
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
TiTools is a CLI that installs Titanium SDK skills and a knowledge index for AI coding assistants. One command installs 7 skills, a research agent, and 100+ reference files for Titanium SDK, Alloy MVC, and PurgeTSS.
|
|
12
12
|
|
|
13
|
-
Without
|
|
13
|
+
Without TiTools, assistants rely on general training data. That data can be outdated or too generic for Titanium work. With TiTools, the assistant can look up Alloy architecture, memory cleanup patterns, PurgeTSS utility classes, and platform-specific APIs.
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Vercel's AGENTS.md evaluation reports a 100% pass rate for the knowledge index approach, compared to 53-79% using skills alone.
|
|
16
16
|
|
|
17
17
|
---
|
|
18
18
|
|
|
@@ -36,7 +36,7 @@ claude # or gemini, or codex
|
|
|
36
36
|
|
|
37
37
|
# 6) Ask away!
|
|
38
38
|
# "How should I structure a new app with login, signup, and a dashboard?"
|
|
39
|
-
# "My ListView with 500 items scrolls
|
|
39
|
+
# "My ListView with 500 items scrolls poorly on Android. How do I fix it?"
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
What gets installed:
|
|
@@ -125,15 +125,15 @@ The knowledge index is based on the latest Titanium SDK documentation. If your p
|
|
|
125
125
|
|
|
126
126
|
## Skills overview
|
|
127
127
|
|
|
128
|
-
| Skill | Purpose
|
|
129
|
-
| ------------ |
|
|
130
|
-
| alloy-guides | Alloy MVC reference
|
|
131
|
-
| alloy-howtos | Alloy CLI
|
|
132
|
-
| purgetss | Utility-first styling
|
|
133
|
-
| ti-expert | Architecture
|
|
134
|
-
| ti-guides | SDK fundamentals
|
|
135
|
-
| ti-howtos | Native feature integration
|
|
136
|
-
| ti-ui | UI/UX patterns
|
|
128
|
+
| Skill | Purpose | Best For |
|
|
129
|
+
| ------------ | ------------------------------- | --------------------------------------- |
|
|
130
|
+
| alloy-guides | Alloy MVC reference | Models, Views, Controllers, Widgets |
|
|
131
|
+
| alloy-howtos | Alloy CLI and debugging | Project setup, CLI commands, errors |
|
|
132
|
+
| purgetss | Utility-first styling | UI styling and animations |
|
|
133
|
+
| ti-expert | Architecture and implementation | Starting point for most tasks |
|
|
134
|
+
| ti-guides | SDK fundamentals | Hyperloop, distribution, configuration |
|
|
135
|
+
| ti-howtos | Native feature integration | Location, Push, Media, Platform APIs |
|
|
136
|
+
| ti-ui | UI/UX patterns | Complex layouts, ListViews, platform UI |
|
|
137
137
|
|
|
138
138
|
Note: `ti-guides`, `ti-howtos`, `ti-ui`, `alloy-guides`, and `alloy-howtos` are based on official Titanium SDK and Alloy documentation. `ti-expert` and `purgetss` are opinionated and reflect personal coding conventions (biased toward PurgeTSS).
|
|
139
139
|
|
|
@@ -206,9 +206,9 @@ All skills include automatic project detection to ensure compatibility:
|
|
|
206
206
|
| ti-expert | Alloy vs Classic | Checks for `app/` (Alloy) vs `Resources/` (Classic) structure |
|
|
207
207
|
| alloy-guides | Alloy projects | Checks for `app/views/`, `app/controllers/` |
|
|
208
208
|
| alloy-howtos | Alloy projects | Checks for `alloy.jmk`, `config.json` |
|
|
209
|
-
| ti-ui | Titanium projects | Checks for `tiapp.xml` (both Alloy
|
|
210
|
-
| ti-guides | Titanium projects | Checks for `tiapp.xml` (both Alloy
|
|
211
|
-
| ti-howtos | Titanium projects | Checks for `tiapp.xml` (both Alloy
|
|
209
|
+
| ti-ui | Titanium projects | Checks for `tiapp.xml` (both Alloy and Classic) |
|
|
210
|
+
| ti-guides | Titanium projects | Checks for `tiapp.xml` (both Alloy and Classic) |
|
|
211
|
+
| ti-howtos | Titanium projects | Checks for `tiapp.xml` (both Alloy and Classic) |
|
|
212
212
|
|
|
213
213
|
Why this matters:
|
|
214
214
|
- PurgeTSS suggestions are only provided if PurgeTSS is installed
|
|
@@ -619,13 +619,14 @@ Behavior depends on where you run it:
|
|
|
619
619
|
| Inside a Titanium project (with existing knowledge index files) | Also refreshes `AGENTS.md`/`CLAUDE.md`/`GEMINI.md` |
|
|
620
620
|
|
|
621
621
|
What it does:
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
622
|
+
1. Checks GitHub for the latest CLI version
|
|
623
|
+
2. If a newer version exists, it prompts you to update the CLI first with `npm update -g @maccesar/titools`
|
|
624
|
+
3. If the CLI is current, it syncs skills and agents from the installed package (no download needed)
|
|
625
|
+
4. Updates platform symlinks only for platforms that already have them
|
|
626
|
+
5. Cleans up legacy artifacts (`alloy-expert` skill, `ti-researcher` agent)
|
|
627
|
+
6. Auto-syncs knowledge index files if they exist in the current project
|
|
627
628
|
|
|
628
|
-
Note: This
|
|
629
|
+
Note: This command syncs knowledge packages and agents from your installed CLI. To get new features, first update the CLI with `npm update -g @maccesar/titools`, then run `titools update`.
|
|
629
630
|
|
|
630
631
|
### titools remove
|
|
631
632
|
|
|
@@ -690,13 +691,13 @@ Codex CLI:
|
|
|
690
691
|
|
|
691
692
|
| Skill | SKILL.md | References |
|
|
692
693
|
| ------------ | ----------------------------- | ----------------------------------------------------- |
|
|
693
|
-
| ti-expert | Architecture + Implementation | 19 refs + 1 asset (patterns, testing, security, etc.) |
|
|
694
|
-
| purgetss | Setup + Critical Rules | 21 files (grid, animations, icons, class-index, etc.) |
|
|
695
|
-
| ti-ui | UI Rules + Platform Diffs | 14 files (layouts, lists, gestures, etc.) |
|
|
696
|
-
| ti-howtos | Integration Workflow | 18 files (location, media, maps, automation, etc.) |
|
|
697
|
-
| ti-guides | Core Workflow | 14 files (hyperloop, distribution, etc.) |
|
|
698
694
|
| alloy-guides | MVC Quick Start | 10 files (models, views, widgets, etc.) |
|
|
699
695
|
| alloy-howtos | Best Practices | 6 files (CLI, config, debugging, etc.) |
|
|
696
|
+
| purgetss | Setup + Critical Rules | 21 files (grid, animations, icons, class-index, etc.) |
|
|
697
|
+
| ti-expert | Architecture + Implementation | 19 refs + 1 asset (patterns, testing, security, etc.) |
|
|
698
|
+
| ti-guides | Core Workflow | 14 files (hyperloop, distribution, etc.) |
|
|
699
|
+
| ti-howtos | Integration Workflow | 18 files (location, media, maps, automation, etc.) |
|
|
700
|
+
| ti-ui | UI Rules + Platform Diffs | 14 files (layouts, lists, gestures, etc.) |
|
|
700
701
|
|
|
701
702
|
---
|
|
702
703
|
|
package/lib/commands/update.js
CHANGED
|
@@ -14,7 +14,7 @@ import select from '../prompts/selectCancel.js';
|
|
|
14
14
|
import {
|
|
15
15
|
detectPlatforms,
|
|
16
16
|
} from '../platform.js';
|
|
17
|
-
import { cleanupLegacyArtifacts } from '../cleanup.js';
|
|
17
|
+
import { cleanupLegacyArtifacts, getSkillList } from '../cleanup.js';
|
|
18
18
|
import {
|
|
19
19
|
installSkills,
|
|
20
20
|
installAgents,
|
|
@@ -22,16 +22,25 @@ import {
|
|
|
22
22
|
} from '../installer.js';
|
|
23
23
|
import { agentsCommand } from './agents.js';
|
|
24
24
|
import {
|
|
25
|
-
downloadRepoArchive,
|
|
26
25
|
checkForUpdate,
|
|
26
|
+
fetchLatestVersion,
|
|
27
27
|
} from '../downloader.js';
|
|
28
28
|
import { createSkillSymlinks } from '../symlink.js';
|
|
29
29
|
import { formatList, isTitaniumProject } from '../utils.js';
|
|
30
30
|
import { getAgentsSkillsDir } from '../config.js';
|
|
31
|
-
import { mkdtemp } from 'fs/promises';
|
|
32
31
|
import { existsSync } from 'fs';
|
|
33
32
|
import { join, resolve } from 'path';
|
|
34
|
-
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Check if a platform has any skill symlinks installed
|
|
36
|
+
* @param {string} platformSkillsDir - Platform skills directory
|
|
37
|
+
* @returns {boolean} True if any skill symlink exists
|
|
38
|
+
*/
|
|
39
|
+
function hasAnySkillSymlink(platformSkillsDir) {
|
|
40
|
+
if (!platformSkillsDir || !existsSync(platformSkillsDir)) return false;
|
|
41
|
+
const skillList = getSkillList();
|
|
42
|
+
return skillList.some((skill) => existsSync(join(platformSkillsDir, skill)));
|
|
43
|
+
}
|
|
35
44
|
|
|
36
45
|
/**
|
|
37
46
|
* Update command handler
|
|
@@ -112,122 +121,92 @@ export async function updateCommand(options) {
|
|
|
112
121
|
try {
|
|
113
122
|
const hasUpdate = await checkForUpdate(PACKAGE_VERSION);
|
|
114
123
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
const aiFiles = ['AGENTS.md', 'CLAUDE.md', 'GEMINI.md'];
|
|
123
|
-
const hasAnyAiFile = aiFiles.some((file) => existsSync(join(projectDir, file)));
|
|
124
|
-
if (hasAnyAiFile) {
|
|
125
|
-
await agentsCommand(projectDir, { onlyExisting: true, force: true });
|
|
126
|
-
}
|
|
124
|
+
// If there's a newer version on GitHub, prompt user to update CLI first
|
|
125
|
+
if (hasUpdate) {
|
|
126
|
+
let latestVersion = '(newer)';
|
|
127
|
+
try {
|
|
128
|
+
latestVersion = await fetchLatestVersion();
|
|
129
|
+
} catch {
|
|
130
|
+
// Ignore error, we already know there's an update
|
|
127
131
|
}
|
|
128
|
-
console.log('');
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
132
|
|
|
132
|
-
|
|
133
|
-
console.log('');
|
|
134
|
-
console.log(chalk.gray(`Current: ${PACKAGE_VERSION}`));
|
|
135
|
-
console.log(chalk.gray(`Latest: (from GitHub)`));
|
|
136
|
-
console.log('');
|
|
137
|
-
|
|
138
|
-
// Detect installed platforms at target
|
|
139
|
-
const detectedPlatforms = detectPlatforms(baseDir);
|
|
140
|
-
|
|
141
|
-
if (detectedPlatforms.length === 0) {
|
|
142
|
-
console.log(chalk.yellow('No AI coding assistants detected.'));
|
|
143
|
-
if (baseDir) {
|
|
144
|
-
console.log('Update will install skills to ./.agents/skills/');
|
|
145
|
-
} else {
|
|
146
|
-
console.log('Update will install skills to ~/.agents/skills/');
|
|
147
|
-
}
|
|
133
|
+
spinner.warn('New version available');
|
|
148
134
|
console.log('');
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
135
|
+
console.log(chalk.yellow('A newer version is available on npm:'));
|
|
136
|
+
console.log(` Current: ${chalk.gray('v' + PACKAGE_VERSION)}`);
|
|
137
|
+
console.log(` Latest: ${chalk.green(latestVersion)}`);
|
|
138
|
+
console.log('');
|
|
139
|
+
console.log('To update, run:');
|
|
140
|
+
console.log(` ${chalk.cyan('npm update -g @maccesar/titools')}`);
|
|
153
141
|
console.log('');
|
|
142
|
+
console.log('Then run this command again:');
|
|
143
|
+
console.log(` ${chalk.cyan('titools update')}`);
|
|
144
|
+
console.log('');
|
|
145
|
+
return;
|
|
154
146
|
}
|
|
155
147
|
|
|
156
|
-
//
|
|
157
|
-
spinner.
|
|
158
|
-
|
|
159
|
-
let repoDir = getLocalRepoDir();
|
|
160
|
-
let tempDir = null;
|
|
148
|
+
// CLI is up to date, now sync skills from the installed package
|
|
149
|
+
spinner.succeed(`CLI is up to date (v${PACKAGE_VERSION})`);
|
|
161
150
|
|
|
151
|
+
// Get repository directory from the installed package
|
|
152
|
+
const repoDir = getLocalRepoDir();
|
|
162
153
|
if (!repoDir) {
|
|
163
|
-
|
|
164
|
-
|
|
154
|
+
console.log('');
|
|
155
|
+
console.log(chalk.red('Error: Could not locate skills source directory.'));
|
|
156
|
+
console.log('Try reinstalling with:');
|
|
157
|
+
console.log(` ${chalk.cyan('npm install -g titools')}`);
|
|
158
|
+
return;
|
|
165
159
|
}
|
|
166
160
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
161
|
+
// Detect platforms with existing symlinks (only update those)
|
|
162
|
+
const detectedPlatforms = detectPlatforms(baseDir);
|
|
163
|
+
const platformsWithSymlinks = detectedPlatforms.filter((p) =>
|
|
164
|
+
hasAnySkillSymlink(p.skillsDir)
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
// Install skills
|
|
168
|
+
spinner.start('Syncing skills...');
|
|
169
|
+
const skillsResult = await installSkills(repoDir, baseDir);
|
|
170
|
+
spinner.succeed(`${skillsResult.installed.length} skills updated`);
|
|
171
|
+
|
|
172
|
+
// Install agents (only if Claude Code has symlinks)
|
|
173
|
+
const claudePlatform = platformsWithSymlinks.find((p) => p.name === 'claude');
|
|
174
|
+
if (claudePlatform) {
|
|
175
|
+
spinner.start('Syncing agents...');
|
|
179
176
|
const agentsResult = await installAgents(repoDir, baseDir);
|
|
180
177
|
if (agentsResult.installed.length > 0) {
|
|
181
|
-
spinner.succeed(
|
|
182
|
-
`Agents: ${formatList(agentsResult.installed)}`
|
|
183
|
-
);
|
|
178
|
+
spinner.succeed('Platform agents updated');
|
|
184
179
|
} else {
|
|
185
|
-
spinner.info('No agents to
|
|
180
|
+
spinner.info('No agents to sync');
|
|
186
181
|
}
|
|
182
|
+
}
|
|
187
183
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
// Update symlinks for detected platforms
|
|
191
|
-
for (const platform of detectedPlatforms) {
|
|
192
|
-
spinner.start(`Updating ${platform.displayName} symlinks...`);
|
|
193
|
-
const symlinkResult = await createSkillSymlinks(
|
|
194
|
-
platform.skillsDir,
|
|
195
|
-
SKILLS,
|
|
196
|
-
baseDir
|
|
197
|
-
);
|
|
198
|
-
if (symlinkResult.linked.length === SKILLS.length) {
|
|
199
|
-
spinner.succeed(`${platform.displayName} linked`);
|
|
200
|
-
} else {
|
|
201
|
-
spinner.warn(
|
|
202
|
-
`${platform.displayName}: ${symlinkResult.linked.length}/${SKILLS.length} linked`
|
|
203
|
-
);
|
|
204
|
-
}
|
|
205
|
-
}
|
|
184
|
+
cleanupLegacyArtifacts(baseDir);
|
|
206
185
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
if (hasAnyAiFile) {
|
|
216
|
-
await agentsCommand(projectDir, { onlyExisting: true, force: true });
|
|
217
|
-
} else {
|
|
218
|
-
console.log(chalk.bold('▸'), 'Run in the Titanium project:', chalk.cyan('titools sync'));
|
|
219
|
-
}
|
|
220
|
-
} else {
|
|
221
|
-
console.log(chalk.bold('▸'), 'Run in the Titanium project:', chalk.cyan('titools sync'));
|
|
222
|
-
}
|
|
223
|
-
console.log('');
|
|
186
|
+
// Update symlinks silently for platforms that already had them
|
|
187
|
+
for (const platform of platformsWithSymlinks) {
|
|
188
|
+
await createSkillSymlinks(
|
|
189
|
+
platform.skillsDir,
|
|
190
|
+
SKILLS,
|
|
191
|
+
baseDir
|
|
192
|
+
);
|
|
193
|
+
}
|
|
224
194
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
195
|
+
// Summary
|
|
196
|
+
console.log('');
|
|
197
|
+
console.log(chalk.green('✓ Update complete!'));
|
|
198
|
+
|
|
199
|
+
// Update knowledge index in MD files if in a Titanium project
|
|
200
|
+
const projectDir = resolve(process.cwd());
|
|
201
|
+
if (isTitaniumProject(projectDir)) {
|
|
202
|
+
const aiFiles = ['AGENTS.md', 'CLAUDE.md', 'GEMINI.md'];
|
|
203
|
+
const hasAnyAiFile = aiFiles.some((file) => existsSync(join(projectDir, file)));
|
|
204
|
+
if (hasAnyAiFile) {
|
|
205
|
+
console.log('');
|
|
206
|
+
await agentsCommand(projectDir, { onlyExisting: true, force: true });
|
|
229
207
|
}
|
|
230
208
|
}
|
|
209
|
+
console.log('');
|
|
231
210
|
|
|
232
211
|
} catch (error) {
|
|
233
212
|
spinner.fail('Update failed');
|
package/package.json
CHANGED
|
@@ -5,11 +5,11 @@ argument-hint: "[concept]"
|
|
|
5
5
|
allowed-tools: Read, Grep, Glob, Edit, Write, Bash(node *)
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
# Alloy MVC
|
|
8
|
+
# Alloy MVC framework guide
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Reference for building Titanium mobile applications with the Alloy MVC framework and Backbone.js.
|
|
11
11
|
|
|
12
|
-
## Project
|
|
12
|
+
## Project detection
|
|
13
13
|
|
|
14
14
|
:::info AUTO-DETECTS ALLOY PROJECTS
|
|
15
15
|
This skill automatically detects Alloy projects when invoked and provides framework-specific guidance.
|
|
@@ -26,7 +26,7 @@ This skill automatically detects Alloy projects when invoked and provides framew
|
|
|
26
26
|
- **Not detected** → Indicates this skill is for Alloy projects only, does not suggest Alloy-specific features
|
|
27
27
|
:::
|
|
28
28
|
|
|
29
|
-
## Quick
|
|
29
|
+
## Quick reference
|
|
30
30
|
|
|
31
31
|
| Topic | Reference File |
|
|
32
32
|
| ------------------------------------------------ | ----------------------------------------------------------------------- |
|
|
@@ -41,7 +41,7 @@ This skill automatically detects Alloy projects when invoked and provides framew
|
|
|
41
41
|
| CLI commands, code generation | [CLI_TASKS.md](references/CLI_TASKS.md) |
|
|
42
42
|
| PurgeTSS integration (optional addon) | [PURGETSS.md](references/PURGETSS.md) |
|
|
43
43
|
|
|
44
|
-
## Project
|
|
44
|
+
## Project structure
|
|
45
45
|
|
|
46
46
|
Standard Alloy project structure:
|
|
47
47
|
|
|
@@ -64,7 +64,7 @@ app/
|
|
|
64
64
|
└── widgets/ # Widget components
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
-
## MVC
|
|
67
|
+
## MVC quick start
|
|
68
68
|
|
|
69
69
|
**Controller** (`app/controllers/index.js`):
|
|
70
70
|
```javascript
|
|
@@ -89,7 +89,7 @@ $.index.open();
|
|
|
89
89
|
"Label": { color: "#000" }
|
|
90
90
|
```
|
|
91
91
|
|
|
92
|
-
## Key
|
|
92
|
+
## Key concepts
|
|
93
93
|
|
|
94
94
|
- **Models/Collections**: Backbone.js objects with sync adapters (sql, properties)
|
|
95
95
|
- **Views**: XML markup with TSS styling
|
|
@@ -98,29 +98,29 @@ $.index.open();
|
|
|
98
98
|
- **Widgets**: Reusable components with MVC structure
|
|
99
99
|
- **Conventions**: File naming and placement drive code generation
|
|
100
100
|
|
|
101
|
-
## Critical
|
|
101
|
+
## Critical rules
|
|
102
102
|
|
|
103
|
-
### Platform-
|
|
103
|
+
### Platform-specific properties in TSS
|
|
104
104
|
|
|
105
|
-
:::danger CRITICAL: Platform-
|
|
106
|
-
Using `Ti.UI.iOS.*` or `Ti.UI.Android.*` properties in TSS
|
|
105
|
+
:::danger CRITICAL: Platform-specific properties require modifiers
|
|
106
|
+
Using `Ti.UI.iOS.*` or `Ti.UI.Android.*` properties in TSS without platform modifiers causes cross-platform compilation failures.
|
|
107
107
|
|
|
108
|
-
|
|
108
|
+
Example of the failure:
|
|
109
109
|
```tss
|
|
110
|
-
//
|
|
110
|
+
// WRONG - Adds Ti.UI.iOS to Android project
|
|
111
111
|
"#mainWindow": {
|
|
112
112
|
statusBarStyle: Ti.UI.iOS.StatusBar.LIGHT_CONTENT // FAILS on Android!
|
|
113
113
|
}
|
|
114
114
|
```
|
|
115
115
|
|
|
116
|
-
|
|
116
|
+
Correct approach - use platform modifiers:
|
|
117
117
|
```tss
|
|
118
|
-
//
|
|
118
|
+
// CORRECT - Only adds to iOS
|
|
119
119
|
"#mainWindow[platform=ios]": {
|
|
120
120
|
statusBarStyle: Ti.UI.iOS.StatusBar.LIGHT_CONTENT
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
-
//
|
|
123
|
+
// CORRECT - Only adds to Android
|
|
124
124
|
"#mainWindow[platform=android]": {
|
|
125
125
|
actionBar: {
|
|
126
126
|
displayHomeAsUp: true
|
|
@@ -128,23 +128,23 @@ Using `Ti.UI.iOS.*` or `Ti.UI.Android.*` properties in TSS WITHOUT platform modi
|
|
|
128
128
|
}
|
|
129
129
|
```
|
|
130
130
|
|
|
131
|
-
|
|
131
|
+
Properties that always require platform modifiers:
|
|
132
132
|
- iOS: `statusBarStyle`, `modalStyle`, `modalTransitionStyle`, any `Ti.UI.iOS.*`
|
|
133
133
|
- Android: `actionBar` config, any `Ti.UI.Android.*` constant
|
|
134
134
|
|
|
135
135
|
**Available modifiers:** `[platform=ios]`, `[platform=android]`, `[formFactor=handheld]`, `[formFactor=tablet]`, `[if=Alloy.Globals.customVar]`
|
|
136
136
|
|
|
137
|
-
|
|
137
|
+
For more platform-specific patterns, see [Code conventions (ti-expert)](skills/ti-expert/references/code-conventions.md#platform--device-modifiers) or [Platform UI guides (ti-ui)](skills/ti-ui/references/platform-ui-ios.md).
|
|
138
138
|
:::
|
|
139
139
|
|
|
140
|
-
## Common
|
|
140
|
+
## Common patterns
|
|
141
141
|
|
|
142
|
-
### Creating a
|
|
142
|
+
### Creating a model
|
|
143
143
|
```bash
|
|
144
144
|
alloy generate model book sql title:string author:string
|
|
145
145
|
```
|
|
146
146
|
|
|
147
|
-
### Data
|
|
147
|
+
### Data binding
|
|
148
148
|
```xml
|
|
149
149
|
<Collection src="book" />
|
|
150
150
|
<TableView dataCollection="book">
|
|
@@ -152,7 +152,7 @@ alloy generate model book sql title:string author:string
|
|
|
152
152
|
</TableView>
|
|
153
153
|
```
|
|
154
154
|
|
|
155
|
-
### Platform-
|
|
155
|
+
### Platform-specific code
|
|
156
156
|
```javascript
|
|
157
157
|
if (OS_IOS) {
|
|
158
158
|
// iOS-only code
|
|
@@ -162,25 +162,25 @@ if (OS_ANDROID) {
|
|
|
162
162
|
}
|
|
163
163
|
```
|
|
164
164
|
|
|
165
|
-
### Widget
|
|
165
|
+
### Widget usage
|
|
166
166
|
```xml
|
|
167
167
|
<Widget src="mywidget" id="foo" />
|
|
168
168
|
```
|
|
169
169
|
|
|
170
|
-
## Compilation
|
|
170
|
+
## Compilation process
|
|
171
171
|
|
|
172
|
-
1.
|
|
173
|
-
2.
|
|
174
|
-
3.
|
|
175
|
-
4.
|
|
176
|
-
5.
|
|
177
|
-
6.
|
|
172
|
+
1. Cleanup: Resources folder cleaned
|
|
173
|
+
2. Build Config: alloy.jmk loaded (pre:load task)
|
|
174
|
+
3. Framework Files: Backbone.js, Underscore.js, sync adapters copied
|
|
175
|
+
4. MVC Generation: Models, widgets, views, controllers compiled to JS
|
|
176
|
+
5. Main App: app.js generated from template
|
|
177
|
+
6. Optimization: UglifyJS optimization, platform-specific code removal
|
|
178
178
|
|
|
179
179
|
## References
|
|
180
180
|
|
|
181
181
|
Read detailed documentation from the reference files listed above based on your specific task.
|
|
182
182
|
|
|
183
|
-
## Related
|
|
183
|
+
## Related skills
|
|
184
184
|
|
|
185
185
|
For tasks beyond Alloy MVC basics, use these complementary skills:
|
|
186
186
|
|
|
@@ -6,7 +6,7 @@ This guide covers the important concepts related to the Alloy framework, includi
|
|
|
6
6
|
|
|
7
7
|
## Model-View-Controller
|
|
8
8
|
|
|
9
|
-
Alloy
|
|
9
|
+
Alloy uses the model-view-controller (MVC) pattern, which separates the application into three different components:
|
|
10
10
|
|
|
11
11
|
* **Models** provide the business logic, containing the rules, data and state of the application
|
|
12
12
|
|
|
@@ -26,7 +26,7 @@ Alloy views are built from Titanium UI components. You define views using XML ma
|
|
|
26
26
|
|
|
27
27
|
Alloy controllers generally have a one-to-one relationship with Alloy views. Controllers directly use the Titanium SDK API without an abstraction layer. The controller has access to all of the view components.
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
Also, Alloy provides built-in support for Underscore.js, which provides a set of utility functions, such as array and iterative helpers.
|
|
30
30
|
|
|
31
31
|
## Alloy and the Titanium SDK
|
|
32
32
|
|
|
@@ -103,7 +103,7 @@ app/
|
|
|
103
103
|
|
|
104
104
|
Alternatively, you can use special conditional code and attributes inside the controllers, views and styles to apply platform-specific code and components.
|
|
105
105
|
|
|
106
|
-
|
|
106
|
+
Also, the `assets` folder is laid out the same way as the `Resources` folder in a Titanium project for platform-specific files and density-specific images.
|
|
107
107
|
|
|
108
108
|
## Widgets
|
|
109
109
|
|
|
@@ -137,7 +137,7 @@ if (OS_IOS) {
|
|
|
137
137
|
|
|
138
138
|
### Passing Arguments
|
|
139
139
|
|
|
140
|
-
When initializing an external controller, you can pass arguments to customize it, for instance, `const controller = Alloy.createController('controller', {args1: 'foo'})`. In the external controller, the special variable `$.args` is used to receive the arguments.
|
|
140
|
+
When initializing an external controller, you can pass arguments to customize it, for instance, `const controller = Alloy.createController('controller', {args1: 'foo'})`. In the external controller, the special variable `$.args` is used to receive the arguments. Before Alloy 1.6, you needed to use `arguments[0]`. For example, suppose you want to add multiple TableViewRow objects to a TableView object.
|
|
141
141
|
|
|
142
142
|
For the TableViewRow object, called 'row', the view contains only the object, and the controller contains only a few lines of code to parse the arguments:
|
|
143
143
|
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
Alloy uses Backbone.js to provide support for its models and collections. Alloy also borrows the concepts of migrations and adapters from Rails for storage integration.
|
|
13
13
|
|
|
14
|
-
For models, collections and sync adapters, these guides only provides information on how Alloy
|
|
14
|
+
For models, collections and sync adapters, these guides only provides information on how Alloy uses the Backbone.js functionality and some simple examples of using it.
|
|
15
15
|
|
|
16
16
|
## Alloy Collection and Model Objects
|
|
17
17
|
|
|
@@ -214,7 +214,7 @@ exports.definition = {
|
|
|
214
214
|
|
|
215
215
|
#### Underscore.js Functionality
|
|
216
216
|
|
|
217
|
-
|
|
217
|
+
Also, the Backbone.Collection class inherits some functionality from [Underscore.js](https://underscorejs.org/), which can help simplify iterative functions. For example, to add the title of each book object in the library collection to a table, you could use the `map` function to set the table:
|
|
218
218
|
|
|
219
219
|
**Iterating over a collection with underscore**
|
|
220
220
|
|
|
@@ -281,7 +281,7 @@ You can bind both a collection of models or an individual model. To bind a model
|
|
|
281
281
|
|
|
282
282
|
### Global Singleton vs Local Instance
|
|
283
283
|
|
|
284
|
-
In the above code snippet, the model and collection are global singletons under `Alloy.Models.currentCategory` and `Alloy.Collections.book`. You can also use local instances for the current controller by adding `instance="true"` as attribute. You also need to assign them an ID
|
|
284
|
+
In the above code snippet, the model and collection are global singletons under `Alloy.Models.currentCategory` and `Alloy.Collections.book`. You can also use local instances for the current controller by adding `instance="true"` as attribute. You also need to assign them an ID to reference them in the XML and controller.
|
|
285
285
|
|
|
286
286
|
```xml
|
|
287
287
|
<Alloy>
|
|
@@ -360,7 +360,7 @@ You can bind deep object properties:
|
|
|
360
360
|
|
|
361
361
|
Before, you needed to use a transformer to create a reference like `authorName`.
|
|
362
362
|
|
|
363
|
-
|
|
363
|
+
Before CLI 7.1.0, the only way to set object properties (e.g. `font.fontFamily` for a Label) was to use TSS. You can use dot notation in XML:
|
|
364
364
|
|
|
365
365
|
```xml
|
|
366
366
|
<Alloy>
|
|
@@ -760,7 +760,7 @@ The sync adapter exports three functions:
|
|
|
760
760
|
|
|
761
761
|
### Migrations
|
|
762
762
|
|
|
763
|
-
A migration is a description of incremental changes to a database, which takes your database from version 1 to version X, with a migration file for each step in the evolution of your database schema. This is helpful to keep different versions of a database in sync. For example, when version 7 of your application is deployed, migrations
|
|
763
|
+
A migration is a description of incremental changes to a database, which takes your database from version 1 to version X, with a migration file for each step in the evolution of your database schema. This is helpful to keep different versions of a database in sync. For example, when version 7 of your application is deployed, migrations can successfully update the database from versions 1 through 6. Currently, migrations are only used with the `sql` sync adapter.
|
|
764
764
|
|
|
765
765
|
The `migration.up` function upgrades the database from the previous version, while the `migration.down` function rolls back the changes to the previous version.
|
|
766
766
|
|
|
@@ -1014,7 +1014,7 @@ To use Backbone 1.1.2 to support Alloy Model and Collections objects, open the p
|
|
|
1014
1014
|
|
|
1015
1015
|
#### Model APIs
|
|
1016
1016
|
|
|
1017
|
-
**Validation**: Model validation is now only enforced with the `save()` method. Previously, models were also validated with the `set()` method. To force validation when the `set()` method is called, pass `{validate: true}` to the method or extend the Model class.
|
|
1017
|
+
**Validation**: Model validation is now only enforced with the `save()` method. Previously, models were also validated with the `set()` method. To force validation when the `set()` method is called, pass `{validate: true}` to the method or extend the Model class. Also, validation now occurs even during 'silent' changes (passing `{silent: true}` to methods). Previously, it would not. Failed validations return the `invalid` event. Previously, a failed model validation would return the `error` event.
|
|
1018
1018
|
|
|
1019
1019
|
**Parse Method**: All `parse` methods now run after a `fetch`. You cannot change the `id` of a model during `parse`. The `parse` method receives `options` as a second parameter.
|
|
1020
1020
|
|
|
@@ -84,7 +84,7 @@ $.index.add(profile.getView());
|
|
|
84
84
|
$.index.open();
|
|
85
85
|
```
|
|
86
86
|
|
|
87
|
-
**
|
|
87
|
+
**Before Alloy 1.4.0**, to dynamically generate a view:
|
|
88
88
|
|
|
89
89
|
1. Create a new instance of the controller using `Alloy.createController()`.
|
|
90
90
|
2. Modify the properties directly.
|
|
@@ -354,7 +354,7 @@ For UI objects that belong to a specific platform, use the `platform` attribute:
|
|
|
354
354
|
<SplitWindow platform="ios"/>
|
|
355
355
|
```
|
|
356
356
|
|
|
357
|
-
|
|
357
|
+
Also, use the alias `Ti` for `Titanium` when specifying namespaces.
|
|
358
358
|
|
|
359
359
|
Many of the Titanium view proxies not part of the `Titanium.UI` namespace do not require that the `ns` attribute be explicitly set. The following elements are implicitly mapped to a namespace:
|
|
360
360
|
|
|
@@ -10,7 +10,7 @@ See [Importing Widgets](./VIEWS_XML.md#importing-widgets) for more information o
|
|
|
10
10
|
|
|
11
11
|
## Creating Widgets
|
|
12
12
|
|
|
13
|
-
Widgets should be built in their own directory in the Alloy project's `app/widgets/` directory. Widgets have their own views, controllers, models, styles and assets and are laid out the same as the `app` directory in the Alloy project.
|
|
13
|
+
Widgets should be built in their own directory in the Alloy project's `app/widgets/` directory. Widgets have their own views, controllers, models, styles and assets and are laid out the same as the `app` directory in the Alloy project. Also, since widgets are self-contained, they should not reference any code or assets not within its path, except for internationalization and localization files, which are located in the `i18n` folder.
|
|
14
14
|
|
|
15
15
|
## Assets and Libs
|
|
16
16
|
|