create-ng-tailwind 3.0.0 ā 3.1.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/CHANGELOG.md +17 -0
- package/README.md +1 -1
- package/lib/templates/starter/index.js +10 -41
- package/lib/utils/ai-config.js +16 -20
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,23 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [3.1.0] - 2025-11-30
|
|
9
|
+
|
|
10
|
+
### ⨠New Features
|
|
11
|
+
|
|
12
|
+
- **simple-git-hooks**: Added lightweight pre-commit hooks (~1KB vs Husky's ~40KB)
|
|
13
|
+
- Runs `npm run lint` before each commit
|
|
14
|
+
- Auto-setup via `prepare` script on `npm install`
|
|
15
|
+
- Config stored in package.json (no separate folder)
|
|
16
|
+
- Zero dependencies, much simpler than Husky
|
|
17
|
+
|
|
18
|
+
### šļø Removed
|
|
19
|
+
|
|
20
|
+
- **Husky**: Replaced Husky and lint-staged with simple-git-hooks
|
|
21
|
+
- Removed `husky` and `lint-staged` dev dependencies
|
|
22
|
+
- Removed `setupHusky()` method
|
|
23
|
+
- Lighter alternative with same functionality
|
|
24
|
+
|
|
8
25
|
## [3.0.0] - 2025-11-30
|
|
9
26
|
|
|
10
27
|
### š„ Breaking Changes
|
package/README.md
CHANGED
|
@@ -154,7 +154,7 @@ The **Starter Template** includes 25+ production-ready features:
|
|
|
154
154
|
- **Authentication Pages** - Login, Register, Forgot Password
|
|
155
155
|
- **Example Pages** - Home, About, Contact with reactive forms
|
|
156
156
|
- **PWA Support** - Service worker configuration
|
|
157
|
-
- **Linting & Formatting** - ESLint + Prettier +
|
|
157
|
+
- **Linting & Formatting** - ESLint + Prettier + simple-git-hooks (pre-commit linting)
|
|
158
158
|
- **Modern Stack** - Tailwind v4, TypeScript, Signals
|
|
159
159
|
|
|
160
160
|
## šØ Tailwind CSS v4
|
|
@@ -64,7 +64,7 @@ const starter = {
|
|
|
64
64
|
'API, Auth, Storage, Loading, Cache, SEO services',
|
|
65
65
|
'TypeScript interfaces and models',
|
|
66
66
|
'Responsive Tailwind design system',
|
|
67
|
-
'ESLint + Prettier +
|
|
67
|
+
'ESLint + Prettier + simple-git-hooks (pre-commit)',
|
|
68
68
|
'PWA-ready with service worker configuration',
|
|
69
69
|
'Icons library (@ng-icons/heroicons)',
|
|
70
70
|
],
|
|
@@ -129,7 +129,7 @@ const starter = {
|
|
|
129
129
|
completeStep('Utility pipes & directives');
|
|
130
130
|
completeStep('Authentication pages & guards');
|
|
131
131
|
completeStep('PWA support configured');
|
|
132
|
-
completeStep('ESLint + Prettier +
|
|
132
|
+
completeStep('ESLint + Prettier + simple-git-hooks');
|
|
133
133
|
console.log('');
|
|
134
134
|
},
|
|
135
135
|
|
|
@@ -3171,7 +3171,7 @@ export class HomeComponent implements OnInit {
|
|
|
3171
3171
|
<span class="text-gray-500">{{ 'home.preConfigured.formatting' | translate }}</span>
|
|
3172
3172
|
</div>
|
|
3173
3173
|
<div class="flex justify-between items-center p-2 bg-gray-50 rounded">
|
|
3174
|
-
<span class="font-mono text-gray-700">
|
|
3174
|
+
<span class="font-mono text-gray-700">simple-git-hooks</span>
|
|
3175
3175
|
<span class="text-gray-500">{{ 'home.preConfigured.gitHooks' | translate }}</span>
|
|
3176
3176
|
</div>
|
|
3177
3177
|
<div class="flex justify-between items-center p-2 bg-gray-50 rounded">
|
|
@@ -3727,8 +3727,7 @@ export class AboutComponent implements OnInit {
|
|
|
3727
3727
|
prettier: '^3.5.3',
|
|
3728
3728
|
'eslint-config-prettier': '^10.1.2',
|
|
3729
3729
|
'prettier-plugin-tailwindcss': '^0.6.11',
|
|
3730
|
-
|
|
3731
|
-
'lint-staged': '^15.2.0',
|
|
3730
|
+
'simple-git-hooks': '^2.11.1',
|
|
3732
3731
|
};
|
|
3733
3732
|
|
|
3734
3733
|
// Add enhanced scripts
|
|
@@ -3740,7 +3739,7 @@ export class AboutComponent implements OnInit {
|
|
|
3740
3739
|
'format:ts': 'prettier --write "**/*.ts"',
|
|
3741
3740
|
'code:check': 'npm run format:check && npm run lint',
|
|
3742
3741
|
'code:fix': 'npm run format && npm run lint:fix',
|
|
3743
|
-
prepare: '
|
|
3742
|
+
prepare: 'simple-git-hooks',
|
|
3744
3743
|
};
|
|
3745
3744
|
|
|
3746
3745
|
// Add prettier configuration
|
|
@@ -3763,10 +3762,9 @@ export class AboutComponent implements OnInit {
|
|
|
3763
3762
|
],
|
|
3764
3763
|
};
|
|
3765
3764
|
|
|
3766
|
-
//
|
|
3767
|
-
const
|
|
3768
|
-
'
|
|
3769
|
-
'*.css': ['prettier --write'],
|
|
3765
|
+
// simple-git-hooks configuration (lightweight pre-commit hooks)
|
|
3766
|
+
const simpleGitHooksConfig = {
|
|
3767
|
+
'pre-commit': 'npm run lint',
|
|
3770
3768
|
};
|
|
3771
3769
|
|
|
3772
3770
|
// Update package.json
|
|
@@ -3776,7 +3774,7 @@ export class AboutComponent implements OnInit {
|
|
|
3776
3774
|
};
|
|
3777
3775
|
packageJson.scripts = { ...packageJson.scripts, ...enhancedScripts };
|
|
3778
3776
|
packageJson.prettier = prettierConfig;
|
|
3779
|
-
packageJson['
|
|
3777
|
+
packageJson['simple-git-hooks'] = simpleGitHooksConfig;
|
|
3780
3778
|
|
|
3781
3779
|
// Write updated package.json
|
|
3782
3780
|
await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
@@ -3926,7 +3924,6 @@ node_modules/
|
|
|
3926
3924
|
// Install linting packages if not skipping install
|
|
3927
3925
|
if (!config.skipInstall) {
|
|
3928
3926
|
await this.installLintingPackages(config);
|
|
3929
|
-
await this.setupHusky(config);
|
|
3930
3927
|
}
|
|
3931
3928
|
},
|
|
3932
3929
|
|
|
@@ -3959,8 +3956,7 @@ node_modules/
|
|
|
3959
3956
|
'prettier@^3.5.3',
|
|
3960
3957
|
'eslint-config-prettier@^10.1.2',
|
|
3961
3958
|
'prettier-plugin-tailwindcss@^0.6.11',
|
|
3962
|
-
'
|
|
3963
|
-
'lint-staged@^15.2.0',
|
|
3959
|
+
'simple-git-hooks@^2.11.1',
|
|
3964
3960
|
];
|
|
3965
3961
|
|
|
3966
3962
|
await execa.command(`npm install ${packages.join(' ')} --save-dev`, {
|
|
@@ -3991,33 +3987,6 @@ node_modules/
|
|
|
3991
3987
|
}
|
|
3992
3988
|
},
|
|
3993
3989
|
|
|
3994
|
-
async setupHusky(config) {
|
|
3995
|
-
const execa = require('execa');
|
|
3996
|
-
|
|
3997
|
-
try {
|
|
3998
|
-
// Initialize husky
|
|
3999
|
-
await execa.command('npx husky install', {
|
|
4000
|
-
cwd: config.fullPath,
|
|
4001
|
-
stdio: 'pipe',
|
|
4002
|
-
});
|
|
4003
|
-
|
|
4004
|
-
// Create pre-commit hook
|
|
4005
|
-
const preCommitHook = `#!/usr/bin/env sh
|
|
4006
|
-
. "$(dirname -- "$0")/_/husky.sh"
|
|
4007
|
-
|
|
4008
|
-
npx lint-staged
|
|
4009
|
-
`;
|
|
4010
|
-
|
|
4011
|
-
await fs.ensureDir(path.join(config.fullPath, '.husky'));
|
|
4012
|
-
await fs.writeFile(path.join(config.fullPath, '.husky/pre-commit'), preCommitHook, {
|
|
4013
|
-
mode: 0o755,
|
|
4014
|
-
});
|
|
4015
|
-
} catch (error) {
|
|
4016
|
-
// If husky setup fails, it's not critical
|
|
4017
|
-
// Silent failure - user can run "npm run prepare" later
|
|
4018
|
-
}
|
|
4019
|
-
},
|
|
4020
|
-
|
|
4021
3990
|
async setupPWA(config) {
|
|
4022
3991
|
// Create manifest.json
|
|
4023
3992
|
const manifest = {
|
package/lib/utils/ai-config.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const fs = require(
|
|
2
|
-
const path = require(
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* AI Configuration Generator
|
|
@@ -50,7 +50,7 @@ src/app/
|
|
|
50
50
|
- **Forms:** Reactive Forms with validation
|
|
51
51
|
- **Routing:** Angular Router with lazy loading
|
|
52
52
|
- **Icons:** @ng-icons/heroicons
|
|
53
|
-
- **Linting:** ESLint + Prettier +
|
|
53
|
+
- **Linting:** ESLint + Prettier + simple-git-hooks
|
|
54
54
|
|
|
55
55
|
## šÆ Path Aliases (Use These!)
|
|
56
56
|
|
|
@@ -432,11 +432,11 @@ describe('ExampleComponent', () => {
|
|
|
432
432
|
`;
|
|
433
433
|
|
|
434
434
|
// Create .claude directory if it doesn't exist
|
|
435
|
-
const claudeDir = path.join(projectPath,
|
|
435
|
+
const claudeDir = path.join(projectPath, '.claude');
|
|
436
436
|
await fs.ensureDir(claudeDir);
|
|
437
437
|
|
|
438
438
|
// Write CLAUDE.md inside .claude folder (uppercase to match Angular CLI convention)
|
|
439
|
-
await fs.writeFile(path.join(claudeDir,
|
|
439
|
+
await fs.writeFile(path.join(claudeDir, 'CLAUDE.md'), claudeMd);
|
|
440
440
|
}
|
|
441
441
|
|
|
442
442
|
// ==================== CURSOR-SPECIFIC CONFIG ====================
|
|
@@ -518,7 +518,7 @@ Add keys to \`public/assets/i18n/en.json\` and \`ar.json\`
|
|
|
518
518
|
- No HttpClient directly (use ApiService)
|
|
519
519
|
`;
|
|
520
520
|
|
|
521
|
-
await fs.writeFile(path.join(projectPath,
|
|
521
|
+
await fs.writeFile(path.join(projectPath, '.cursorrules'), cursorRules);
|
|
522
522
|
}
|
|
523
523
|
|
|
524
524
|
// ==================== WINDSURF-SPECIFIC CONFIG ====================
|
|
@@ -596,7 +596,7 @@ public/assets/i18n/en.json + ar.json
|
|
|
596
596
|
No NgModule, No constructors, No custom CSS, No 'any', No src/assets
|
|
597
597
|
`;
|
|
598
598
|
|
|
599
|
-
await fs.writeFile(path.join(projectPath,
|
|
599
|
+
await fs.writeFile(path.join(projectPath, '.windsurfrules'), windsurfRules);
|
|
600
600
|
}
|
|
601
601
|
|
|
602
602
|
// ==================== MAIN EXPORT ====================
|
|
@@ -611,33 +611,29 @@ No NgModule, No constructors, No custom CSS, No 'any', No src/assets
|
|
|
611
611
|
*/
|
|
612
612
|
async function createAIConfigs(projectPath, projectName, aiTools) {
|
|
613
613
|
// Skip if user selected "none"
|
|
614
|
-
if (
|
|
615
|
-
!aiTools ||
|
|
616
|
-
aiTools.length === 0 ||
|
|
617
|
-
(aiTools.length === 1 && aiTools[0] === "none")
|
|
618
|
-
) {
|
|
614
|
+
if (!aiTools || aiTools.length === 0 || (aiTools.length === 1 && aiTools[0] === 'none')) {
|
|
619
615
|
return;
|
|
620
616
|
}
|
|
621
617
|
|
|
622
|
-
console.log(
|
|
618
|
+
console.log('\nš¤ Configuring AI tools...');
|
|
623
619
|
|
|
624
620
|
// Create tool-specific configs only if selected
|
|
625
|
-
if (aiTools.includes(
|
|
621
|
+
if (aiTools.includes('claude')) {
|
|
626
622
|
await createClaudeConfig(projectPath, projectName);
|
|
627
|
-
console.log(
|
|
623
|
+
console.log(' ā .claude/CLAUDE.md created');
|
|
628
624
|
}
|
|
629
625
|
|
|
630
|
-
if (aiTools.includes(
|
|
626
|
+
if (aiTools.includes('cursor')) {
|
|
631
627
|
await createCursorConfig(projectPath, projectName);
|
|
632
|
-
console.log(
|
|
628
|
+
console.log(' ā .cursorrules created');
|
|
633
629
|
}
|
|
634
630
|
|
|
635
|
-
if (aiTools.includes(
|
|
631
|
+
if (aiTools.includes('windsurf')) {
|
|
636
632
|
await createWindsurfConfig(projectPath, projectName);
|
|
637
|
-
console.log(
|
|
633
|
+
console.log(' ā .windsurfrules created');
|
|
638
634
|
}
|
|
639
635
|
|
|
640
|
-
console.log(
|
|
636
|
+
console.log('⨠AI configuration complete!\n');
|
|
641
637
|
}
|
|
642
638
|
|
|
643
639
|
module.exports = {
|