autoworkflow 1.2.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/install.js DELETED
@@ -1,745 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * autoworkflow - Auto-Install Script
4
- *
5
- * This runs automatically when the package is installed.
6
- * Sets up Git hooks and creates default config.
7
- */
8
-
9
- const fs = require('fs');
10
- const path = require('path');
11
- const { execSync } = require('child_process');
12
-
13
- // Colors for output
14
- const c = {
15
- reset: '\x1b[0m',
16
- green: '\x1b[32m',
17
- yellow: '\x1b[33m',
18
- blue: '\x1b[34m',
19
- red: '\x1b[31m',
20
- };
21
-
22
- function log(color, message) {
23
- console.log(`${color}${message}${c.reset}`);
24
- }
25
-
26
- function findProjectRoot() {
27
- // Start from where npm install was run (not node_modules)
28
- let dir = process.env.INIT_CWD || process.cwd();
29
-
30
- // Walk up to find package.json (project root)
31
- while (dir !== path.dirname(dir)) {
32
- if (fs.existsSync(path.join(dir, 'package.json'))) {
33
- // Make sure it's not our own package.json
34
- const pkg = JSON.parse(fs.readFileSync(path.join(dir, 'package.json'), 'utf-8'));
35
- if (pkg.name !== 'autoworkflow') {
36
- return dir;
37
- }
38
- }
39
- dir = path.dirname(dir);
40
- }
41
-
42
- return process.env.INIT_CWD || process.cwd();
43
- }
44
-
45
- function isGitRepo(dir) {
46
- return fs.existsSync(path.join(dir, '.git'));
47
- }
48
-
49
- function ensureHuskyDir(projectRoot) {
50
- const huskyDir = path.join(projectRoot, '.husky');
51
- if (!fs.existsSync(huskyDir)) {
52
- fs.mkdirSync(huskyDir, { recursive: true });
53
- }
54
-
55
- // Create husky internal dir
56
- const huskyInternalDir = path.join(huskyDir, '_');
57
- if (!fs.existsSync(huskyInternalDir)) {
58
- fs.mkdirSync(huskyInternalDir, { recursive: true });
59
- }
60
-
61
- return huskyDir;
62
- }
63
-
64
- function createPreCommitHook(huskyDir, projectRoot) {
65
- const hookPath = path.join(huskyDir, 'pre-commit');
66
-
67
- // Check if hook already exists
68
- if (fs.existsSync(hookPath)) {
69
- log(c.yellow, ' ⚠ Pre-commit hook already exists, skipping...');
70
- return;
71
- }
72
-
73
- const hookContent = `#!/bin/bash
74
- # ============================================
75
- # autoworkflow - Pre-Commit Hook
76
- # ============================================
77
- # Auto-generated. Modify enforce.config.json to customize.
78
- # ============================================
79
-
80
- npx autoworkflow run
81
- `;
82
-
83
- fs.writeFileSync(hookPath, hookContent);
84
- fs.chmodSync(hookPath, '755');
85
- log(c.green, ' ✓ Created pre-commit hook');
86
- }
87
-
88
- function createCommitMsgHook(huskyDir) {
89
- const hookPath = path.join(huskyDir, 'commit-msg');
90
-
91
- if (fs.existsSync(hookPath)) {
92
- log(c.yellow, ' ⚠ Commit-msg hook already exists, skipping...');
93
- return;
94
- }
95
-
96
- const hookContent = `#!/bin/bash
97
- # ============================================
98
- # autoworkflow - Commit Message Hook
99
- # ============================================
100
-
101
- npx autoworkflow commit-msg "$1"
102
- `;
103
-
104
- fs.writeFileSync(hookPath, hookContent);
105
- fs.chmodSync(hookPath, '755');
106
- log(c.green, ' ✓ Created commit-msg hook');
107
- }
108
-
109
- function createDefaultConfig(projectRoot) {
110
- const configPath = path.join(projectRoot, 'enforce.config.json');
111
-
112
- if (fs.existsSync(configPath)) {
113
- log(c.yellow, ' ⚠ Config file already exists, skipping...');
114
- return;
115
- }
116
-
117
- const defaultConfig = {
118
- version: '1.0.0',
119
- rules: {
120
- 'no-todo-comments': {
121
- enabled: true,
122
- blocking: true,
123
- patterns: ['TODO', 'FIXME', 'XXX', 'HACK']
124
- },
125
- 'no-console-logs': {
126
- enabled: true,
127
- blocking: true,
128
- allow: ['warn', 'error']
129
- },
130
- 'typescript': {
131
- enabled: true,
132
- blocking: true,
133
- command: 'npx tsc --noEmit'
134
- },
135
- 'eslint': {
136
- enabled: true,
137
- blocking: true,
138
- autoFix: true,
139
- command: 'npx eslint . --max-warnings 0',
140
- fixCommand: 'npx eslint . --fix'
141
- },
142
- 'circular-deps': {
143
- enabled: true,
144
- blocking: true,
145
- paths: ['src/']
146
- }
147
- },
148
- fixLoop: {
149
- enabled: true,
150
- maxAttempts: 5,
151
- autoFixRules: ['eslint']
152
- },
153
- commitMessage: {
154
- enabled: true,
155
- pattern: '^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\\(.+\\))?: .{1,72}$'
156
- }
157
- };
158
-
159
- fs.writeFileSync(configPath, JSON.stringify(defaultConfig, null, 2));
160
- log(c.green, ' ✓ Created enforce.config.json');
161
- }
162
-
163
- function initializeHusky(projectRoot) {
164
- try {
165
- // Initialize husky
166
- execSync('npx husky', { cwd: projectRoot, stdio: 'ignore' });
167
- log(c.green, ' ✓ Initialized husky');
168
- } catch (error) {
169
- // Husky might already be initialized, that's okay
170
- }
171
- }
172
-
173
- function updatePackageJson(projectRoot) {
174
- const pkgPath = path.join(projectRoot, 'package.json');
175
-
176
- if (!fs.existsSync(pkgPath)) {
177
- log(c.yellow, ' ⚠ No package.json found');
178
- return;
179
- }
180
-
181
- const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
182
-
183
- // Add prepare script for husky if not exists
184
- if (!pkg.scripts) {
185
- pkg.scripts = {};
186
- }
187
-
188
- if (!pkg.scripts.prepare) {
189
- pkg.scripts.prepare = 'husky';
190
- fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
191
- log(c.green, ' ✓ Added prepare script to package.json');
192
- }
193
- }
194
-
195
- function createClaudeMd(projectRoot) {
196
- const claudePath = path.join(projectRoot, 'CLAUDE.md');
197
-
198
- if (fs.existsSync(claudePath)) {
199
- log(c.yellow, ' ⚠ CLAUDE.md already exists, skipping...');
200
- return;
201
- }
202
-
203
- const claudeContent = `# CLAUDE.md - Agentic Workflow
204
-
205
- > **MANDATORY**: Follow this workflow for ALL coding tasks. No exceptions.
206
-
207
- ## Workflow (REQUIRED)
208
-
209
- \`\`\`
210
- ┌─────────────────────────────────────────────────────────────────┐
211
- │ AGENTIC WORKFLOW │
212
- ├─────────────────────────────────────────────────────────────────┤
213
- │ │
214
- │ 1. ANALYZE ──► Read relevant files first │
215
- │ │ │
216
- │ ▼ │
217
- │ 2. PLAN ──► Show plan + suggestions (3-tier) │
218
- │ │ │
219
- │ ▼ │
220
- │ 3. CONFIRM ──► "Should I proceed?" (WAIT for approval) │
221
- │ │ │
222
- │ ▼ │
223
- │ 4. IMPLEMENT ──► Make changes (after approval only) │
224
- │ │ │
225
- │ ▼ │
226
- │ 5. VERIFY ──► npm run typecheck 2>&1 || true │
227
- │ │ │
228
- │ ├──► PASS ──► Continue to step 6 │
229
- │ │ │
230
- │ └──► FAIL ──► Fix errors → Re-verify (max 5 attempts) │
231
- │ │
232
- │ ▼ │
233
- │ 6. COMMIT ──► git commit -m "type: description" │
234
- │ (autoworkflow runs all checks automatically) │
235
- │ │
236
- └─────────────────────────────────────────────────────────────────┘
237
- \`\`\`
238
-
239
- ---
240
-
241
- ## Blocking Rules (Enforced by autoworkflow)
242
-
243
- These rules are **automatically enforced** on every commit:
244
-
245
- | Rule | Blocking | Auto-Fix |
246
- |------|----------|----------|
247
- | No TODO/FIXME comments | ⛔ YES | NO |
248
- | No console.log statements | ⛔ YES | NO |
249
- | TypeScript errors | ⛔ YES | NO |
250
- | ESLint errors | ⛔ YES | YES (auto-fix loop) |
251
- | Circular dependencies | ⛔ YES | NO |
252
- | Conventional commits | ⛔ YES | NO |
253
-
254
- ---
255
-
256
- ## Suggestions System (3-Tier)
257
-
258
- For EVERY new feature or significant change, include a **Suggestions** section after your plan:
259
-
260
- \`\`\`
261
- 💡 **Suggestions for Feature Completeness:**
262
-
263
- 🔴 **Required** (must implement):
264
- - [ ] Error handling for [specific case]
265
- - [ ] Loading state for [async operation]
266
- - [ ] Input validation for [field]
267
-
268
- 🟡 **Recommended** (improves quality):
269
- - [ ] Handle edge case: [scenario]
270
- - [ ] Add accessibility: [aria labels, keyboard nav]
271
- - [ ] Empty state handling
272
-
273
- 🟢 **Optional** (nice to have):
274
- - [ ] Add tests for [component/function]
275
- - [ ] Performance optimization: [specific]
276
- - [ ] Add analytics tracking
277
-
278
- **Which suggestions should I include?** (all/required/none/1,2,4)
279
- \`\`\`
280
-
281
- ### When to Show Suggestions
282
-
283
- | Task Type | Show Suggestions? |
284
- |-----------|-------------------|
285
- | New feature | ✅ Always |
286
- | New component | ✅ Always |
287
- | New page/route | ✅ Always |
288
- | Bug fix | ⚠️ Only if reveals missing handling |
289
- | Refactor | ⚠️ Only if scope expands |
290
- | Style changes | ❌ Skip |
291
- | Config changes | ❌ Skip |
292
-
293
- ### Suggestion Checklist Reference
294
-
295
- **Functionality:**
296
- - [ ] Error states (API failures, network errors)
297
- - [ ] Loading states (spinners, skeletons)
298
- - [ ] Empty states (no data)
299
- - [ ] Success feedback (toasts, confirmations)
300
-
301
- **Edge Cases:**
302
- - [ ] Null/undefined data
303
- - [ ] Empty arrays/strings
304
- - [ ] Maximum limits (text length, file size)
305
- - [ ] Concurrent actions (double-click, race conditions)
306
-
307
- **User Experience:**
308
- - [ ] Form validation (client + server)
309
- - [ ] Keyboard navigation
310
- - [ ] Mobile responsiveness
311
- - [ ] Disabled states
312
-
313
- ---
314
-
315
- ## Confirmation Checkpoints
316
-
317
- ### Checkpoint 1: Plan + Suggestions (BEFORE implementing)
318
-
319
- \`\`\`
320
- ## Task: [description]
321
-
322
- ### 1. Analysis
323
- [findings from codebase]
324
-
325
- ### 2. Plan
326
- 📋 **Proposed changes:**
327
- 1. [Change 1]
328
- 2. [Change 2]
329
-
330
- 💡 **Suggestions for Feature Completeness:**
331
-
332
- 🔴 **Required:**
333
- - [ ] Add error handling for API failure
334
- - [ ] Add loading state while fetching
335
-
336
- 🟡 **Recommended:**
337
- - [ ] Add empty state when no results
338
- - [ ] Add keyboard shortcut
339
-
340
- 🟢 **Optional:**
341
- - [ ] Add unit tests
342
-
343
- **Should I proceed?**
344
- **Which suggestions to include?** (all/required/none/1,2,4)
345
- \`\`\`
346
-
347
- ### Checkpoint 2: Before Destructive Actions
348
-
349
- \`\`\`
350
- ⚠️ **Warning:** This will [describe impact].
351
- Files affected: [list]
352
- **Should I proceed?**
353
- \`\`\`
354
-
355
- ### Checkpoint 3: Before Commit
356
-
357
- \`\`\`
358
- ✅ Verification passed.
359
- **Should I commit with message: "[message]"?**
360
- \`\`\`
361
-
362
- ---
363
-
364
- ## Verification Protocol
365
-
366
- ### After EVERY Change
367
-
368
- \`\`\`bash
369
- npm run typecheck 2>&1 || true
370
- \`\`\`
371
-
372
- ### Error Resolution (Max 5 Attempts)
373
-
374
- \`\`\`
375
- ┌─────────────────────────────────────────────────────────────────┐
376
- │ VERIFICATION FAILED - Attempt [X/5] │
377
- ├─────────────────────────────────────────────────────────────────┤
378
- │ Error: [error message] │
379
- │ File: [file path] │
380
- │ Line: [line number] │
381
- ├─────────────────────────────────────────────────────────────────┤
382
- │ Fix Applied: [what was changed] │
383
- │ Re-running verification... │
384
- └─────────────────────────────────────────────────────────────────┘
385
- \`\`\`
386
-
387
- ### If 5 Attempts Fail
388
-
389
- \`\`\`
390
- ❌ VERIFICATION FAILED after 5 attempts.
391
- Remaining errors:
392
- 1. [error 1]
393
- 2. [error 2]
394
-
395
- **Need guidance on:** [specific question about the error]
396
- \`\`\`
397
-
398
- ---
399
-
400
- ## Commit Message Format
401
-
402
- Must follow conventional commits:
403
-
404
- \`\`\`bash
405
- # Valid formats
406
- feat: add user authentication
407
- fix(api): resolve timeout issue
408
- docs: update installation guide
409
-
410
- # Types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert
411
- \`\`\`
412
-
413
- ---
414
-
415
- ## Anti-Patterns (NEVER DO)
416
-
417
- | ❌ Don't | ✅ Do Instead |
418
- |----------|---------------|
419
- | Implement without plan | Show plan + suggestions first |
420
- | Leave TODO comments | Complete the work or create issue |
421
- | Use console.log | Remove or use proper logging |
422
- | Skip verification | Always run \`npm run typecheck\` |
423
- | Batch multiple features | Complete one feature fully first |
424
- | Commit with errors | Fix all errors before commit |
425
- | Guess at solutions | Ask for clarification |
426
-
427
- ---
428
-
429
- ## Quick Reference
430
-
431
- **For new features:**
432
- \`\`\`
433
- Analyze → Plan + Suggestions → Confirm → Implement → Verify → Commit
434
- \`\`\`
435
-
436
- **For bug fixes:**
437
- \`\`\`
438
- Analyze → Plan → Confirm → Implement → Verify → Commit
439
- \`\`\`
440
-
441
- **Commands:**
442
- \`\`\`bash
443
- npm run typecheck # Verify (REQUIRED after changes)
444
- npx autoworkflow run # Run all enforcement checks
445
- npx autoworkflow list # Show rule status
446
- \`\`\`
447
-
448
- ---
449
-
450
- **VERIFY ALWAYS. SUGGEST COMPLETENESS. ASK BEFORE ACTIONS.**
451
- `;
452
-
453
- fs.writeFileSync(claudePath, claudeContent);
454
- log(c.green, ' ✓ Created CLAUDE.md');
455
- }
456
-
457
- function createVSCodeSettings(projectRoot) {
458
- const vscodeDir = path.join(projectRoot, '.vscode');
459
- const settingsPath = path.join(vscodeDir, 'settings.json');
460
-
461
- // Create .vscode directory if it doesn't exist
462
- if (!fs.existsSync(vscodeDir)) {
463
- fs.mkdirSync(vscodeDir, { recursive: true });
464
- }
465
-
466
- if (fs.existsSync(settingsPath)) {
467
- log(c.yellow, ' ⚠ .vscode/settings.json already exists, skipping...');
468
- return;
469
- }
470
-
471
- const settings = {
472
- // Editor - Format & Fix on Save
473
- "editor.formatOnSave": true,
474
- "editor.formatOnPaste": true,
475
- "editor.codeActionsOnSave": {
476
- "source.fixAll.eslint": "explicit",
477
- "source.organizeImports": "explicit",
478
- "source.removeUnusedImports": "explicit"
479
- },
480
- "editor.defaultFormatter": "esbenp.prettier-vscode",
481
- "editor.tabSize": 2,
482
- "editor.insertSpaces": true,
483
- "editor.detectIndentation": false,
484
- "editor.bracketPairColorization.enabled": true,
485
- "editor.guides.bracketPairs": true,
486
- "editor.linkedEditing": true,
487
- "editor.suggest.preview": true,
488
- "editor.inlineSuggest.enabled": true,
489
-
490
- // TypeScript - Use workspace version, strict checking
491
- "typescript.tsdk": "node_modules/typescript/lib",
492
- "typescript.enablePromptUseWorkspaceTsdk": true,
493
- "typescript.validate.enable": true,
494
- "typescript.suggestionActions.enabled": true,
495
- "typescript.preferences.importModuleSpecifier": "relative",
496
- "typescript.updateImportsOnFileMove.enabled": "always",
497
- "typescript.suggest.completeFunctionCalls": true,
498
-
499
- // JavaScript
500
- "javascript.updateImportsOnFileMove.enabled": "always",
501
- "javascript.suggest.completeFunctionCalls": true,
502
-
503
- // ESLint
504
- "eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact"],
505
- "eslint.codeActionsOnSave.mode": "all",
506
- "eslint.run": "onType",
507
-
508
- // Prettier
509
- "[typescript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
510
- "[typescriptreact]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
511
- "[javascript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
512
- "[javascriptreact]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
513
- "[json]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
514
- "[jsonc]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
515
- "[markdown]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
516
- "[css]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
517
- "[scss]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
518
- "[html]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
519
-
520
- // Files
521
- "files.autoSave": "onFocusChange",
522
- "files.trimTrailingWhitespace": true,
523
- "files.insertFinalNewline": true,
524
- "files.trimFinalNewlines": true,
525
- "files.associations": {
526
- "*.css": "tailwindcss"
527
- },
528
- "files.exclude": {
529
- "**/node_modules": true,
530
- "**/.git": true,
531
- "**/dist": true,
532
- "**/.next": true,
533
- "**/coverage": true
534
- },
535
-
536
- // Search
537
- "search.exclude": {
538
- "**/node_modules": true,
539
- "**/dist": true,
540
- "**/coverage": true,
541
- "**/.next": true,
542
- "**/package-lock.json": true
543
- },
544
-
545
- // Tailwind CSS
546
- "tailwindCSS.experimental.classRegex": [
547
- ["clsx\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"],
548
- ["cn\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"],
549
- ["cva\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"]
550
- ],
551
- "tailwindCSS.includeLanguages": {
552
- "typescript": "javascript",
553
- "typescriptreact": "javascript"
554
- },
555
-
556
- // Terminal
557
- "terminal.integrated.defaultProfile.osx": "zsh",
558
- "terminal.integrated.scrollback": 10000,
559
-
560
- // Git
561
- "git.enableSmartCommit": true,
562
- "git.confirmSync": false,
563
- "git.autofetch": true,
564
-
565
- // Explorer
566
- "explorer.confirmDelete": false,
567
- "explorer.confirmDragAndDrop": false,
568
- "explorer.compactFolders": false
569
- };
570
-
571
- fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
572
- log(c.green, ' ✓ Created .vscode/settings.json');
573
- }
574
-
575
- function createVSCodeTasks(projectRoot) {
576
- const vscodeDir = path.join(projectRoot, '.vscode');
577
- const tasksPath = path.join(vscodeDir, 'tasks.json');
578
-
579
- // Create .vscode directory if it doesn't exist
580
- if (!fs.existsSync(vscodeDir)) {
581
- fs.mkdirSync(vscodeDir, { recursive: true });
582
- }
583
-
584
- if (fs.existsSync(tasksPath)) {
585
- log(c.yellow, ' ⚠ .vscode/tasks.json already exists, skipping...');
586
- return;
587
- }
588
-
589
- const tasks = {
590
- "version": "2.0.0",
591
- "tasks": [
592
- {
593
- "label": "Autoworkflow: Run Checks",
594
- "type": "shell",
595
- "command": "npx autoworkflow run",
596
- "group": {
597
- "kind": "build",
598
- "isDefault": true
599
- },
600
- "presentation": {
601
- "reveal": "always",
602
- "panel": "shared",
603
- "clear": true
604
- },
605
- "problemMatcher": ["$tsc", "$eslint-stylish"]
606
- },
607
- {
608
- "label": "Autoworkflow: TypeScript Check",
609
- "type": "shell",
610
- "command": "npx tsc --noEmit",
611
- "group": "build",
612
- "presentation": {
613
- "reveal": "always",
614
- "panel": "shared"
615
- },
616
- "problemMatcher": "$tsc"
617
- },
618
- {
619
- "label": "Autoworkflow: ESLint Fix",
620
- "type": "shell",
621
- "command": "npx eslint . --fix",
622
- "group": "build",
623
- "presentation": {
624
- "reveal": "always",
625
- "panel": "shared"
626
- },
627
- "problemMatcher": "$eslint-stylish"
628
- },
629
- {
630
- "label": "Autoworkflow: List Rules",
631
- "type": "shell",
632
- "command": "npx autoworkflow list",
633
- "group": "build",
634
- "presentation": {
635
- "reveal": "always",
636
- "panel": "shared"
637
- },
638
- "problemMatcher": []
639
- },
640
- {
641
- "label": "Dev Server",
642
- "type": "shell",
643
- "command": "npm run dev",
644
- "group": "build",
645
- "isBackground": true,
646
- "presentation": {
647
- "reveal": "always",
648
- "panel": "dedicated"
649
- },
650
- "problemMatcher": []
651
- },
652
- {
653
- "label": "Quick Commit",
654
- "type": "shell",
655
- "command": "git add -A && git commit -m '${input:commitMessage}'",
656
- "group": "build",
657
- "presentation": {
658
- "reveal": "always",
659
- "panel": "shared"
660
- },
661
- "problemMatcher": []
662
- }
663
- ],
664
- "inputs": [
665
- {
666
- "id": "commitMessage",
667
- "type": "promptString",
668
- "description": "Commit message (e.g., 'feat: add dark mode')"
669
- }
670
- ]
671
- };
672
-
673
- fs.writeFileSync(tasksPath, JSON.stringify(tasks, null, 2));
674
- log(c.green, ' ✓ Created .vscode/tasks.json');
675
- }
676
-
677
- function main() {
678
- console.log('');
679
- log(c.blue, '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
680
- log(c.blue, '🔧 autoworkflow - Setting up...');
681
- log(c.blue, '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
682
- console.log('');
683
-
684
- const projectRoot = findProjectRoot();
685
-
686
- // Skip if we're in the package itself
687
- if (projectRoot.includes('node_modules')) {
688
- return;
689
- }
690
-
691
- log(c.blue, `Project root: ${projectRoot}`);
692
- console.log('');
693
-
694
- // Check if it's a git repo
695
- if (!isGitRepo(projectRoot)) {
696
- log(c.yellow, '⚠ Not a git repository. Initialize git first:');
697
- log(c.yellow, ' git init');
698
- console.log('');
699
- return;
700
- }
701
-
702
- // Setup husky
703
- const huskyDir = ensureHuskyDir(projectRoot);
704
- initializeHusky(projectRoot);
705
-
706
- // Create hooks
707
- createPreCommitHook(huskyDir, projectRoot);
708
- createCommitMsgHook(huskyDir);
709
-
710
- // Create config
711
- createDefaultConfig(projectRoot);
712
-
713
- // Update package.json
714
- updatePackageJson(projectRoot);
715
-
716
- // Create CLAUDE.md for AI workflow
717
- createClaudeMd(projectRoot);
718
-
719
- // Create VSCode settings and tasks
720
- createVSCodeSettings(projectRoot);
721
- createVSCodeTasks(projectRoot);
722
-
723
- console.log('');
724
- log(c.green, '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
725
- log(c.green, '✅ Setup complete!');
726
- log(c.green, '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
727
- console.log('');
728
- log(c.blue, 'Enforcement is now active. Just commit as usual:');
729
- console.log(' git add .');
730
- console.log(' git commit -m "feat: your feature"');
731
- console.log('');
732
- log(c.blue, 'Files created:');
733
- console.log(' • enforce.config.json - Rule configuration');
734
- console.log(' • CLAUDE.md - AI workflow instructions');
735
- console.log(' • .vscode/settings.json - Editor settings');
736
- console.log(' • .vscode/tasks.json - Quick tasks (Cmd+Shift+B)');
737
- console.log('');
738
- log(c.blue, 'CLI commands: npx autoworkflow --help');
739
- console.log('');
740
- }
741
-
742
- // Only run if this is the actual install (not during npm pack)
743
- if (!process.env.npm_config_ignore_scripts) {
744
- main();
745
- }