start-vibing 2.0.2 → 2.0.4

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.
Files changed (105) hide show
  1. package/package.json +1 -1
  2. package/template/.claude/agents/01-orchestration/agent-selector.md +1 -0
  3. package/template/.claude/agents/01-orchestration/checkpoint-manager.md +2 -1
  4. package/template/.claude/agents/01-orchestration/context-manager.md +2 -1
  5. package/template/.claude/agents/01-orchestration/error-recovery.md +2 -1
  6. package/template/.claude/agents/01-orchestration/orchestrator.md +1 -1
  7. package/template/.claude/agents/01-orchestration/parallel-coordinator.md +2 -1
  8. package/template/.claude/agents/01-orchestration/task-decomposer.md +1 -1
  9. package/template/.claude/agents/01-orchestration/workflow-router.md +2 -1
  10. package/template/.claude/agents/02-typescript/bun-runtime-expert.md +2 -1
  11. package/template/.claude/agents/02-typescript/esm-resolver.md +2 -1
  12. package/template/.claude/agents/02-typescript/import-alias-enforcer.md +2 -1
  13. package/template/.claude/agents/02-typescript/ts-generics-helper.md +1 -0
  14. package/template/.claude/agents/02-typescript/ts-migration-helper.md +2 -1
  15. package/template/.claude/agents/02-typescript/ts-strict-checker.md +2 -1
  16. package/template/.claude/agents/02-typescript/ts-types-analyzer.md +2 -1
  17. package/template/.claude/agents/02-typescript/type-definition-writer.md +2 -1
  18. package/template/.claude/agents/02-typescript/zod-schema-designer.md +2 -2
  19. package/template/.claude/agents/02-typescript/zod-validator.md +2 -1
  20. package/template/.claude/agents/03-testing/playwright-assertions.md +1 -0
  21. package/template/.claude/agents/03-testing/playwright-e2e.md +2 -2
  22. package/template/.claude/agents/03-testing/playwright-fixtures.md +2 -2
  23. package/template/.claude/agents/03-testing/playwright-multi-viewport.md +2 -2
  24. package/template/.claude/agents/03-testing/playwright-page-objects.md +2 -1
  25. package/template/.claude/agents/03-testing/test-cleanup-manager.md +2 -1
  26. package/template/.claude/agents/03-testing/test-data-generator.md +2 -1
  27. package/template/.claude/agents/03-testing/tester-integration.md +1 -1
  28. package/template/.claude/agents/03-testing/tester-unit.md +1 -1
  29. package/template/.claude/agents/03-testing/vitest-config.md +2 -1
  30. package/template/.claude/agents/04-docker/container-health.md +2 -1
  31. package/template/.claude/agents/04-docker/deployment-validator.md +2 -1
  32. package/template/.claude/agents/04-docker/docker-compose-designer.md +2 -1
  33. package/template/.claude/agents/04-docker/docker-env-manager.md +2 -1
  34. package/template/.claude/agents/04-docker/docker-multi-stage.md +2 -1
  35. package/template/.claude/agents/04-docker/dockerfile-optimizer.md +2 -1
  36. package/template/.claude/agents/05-database/data-migration.md +2 -1
  37. package/template/.claude/agents/05-database/database-seeder.md +2 -1
  38. package/template/.claude/agents/05-database/mongodb-query-optimizer.md +2 -1
  39. package/template/.claude/agents/05-database/mongoose-aggregation.md +2 -1
  40. package/template/.claude/agents/05-database/mongoose-index-optimizer.md +2 -1
  41. package/template/.claude/agents/05-database/mongoose-schema-designer.md +2 -2
  42. package/template/.claude/agents/06-security/auth-session-validator.md +1 -1
  43. package/template/.claude/agents/06-security/input-sanitizer.md +2 -1
  44. package/template/.claude/agents/06-security/owasp-checker.md +1 -1
  45. package/template/.claude/agents/06-security/permission-auditor.md +2 -1
  46. package/template/.claude/agents/06-security/security-auditor.md +1 -1
  47. package/template/.claude/agents/06-security/sensitive-data-scanner.md +2 -1
  48. package/template/.claude/agents/07-documentation/api-documenter.md +2 -1
  49. package/template/.claude/agents/07-documentation/changelog-manager.md +2 -1
  50. package/template/.claude/agents/07-documentation/documenter.md +1 -1
  51. package/template/.claude/agents/07-documentation/domain-updater.md +1 -1
  52. package/template/.claude/agents/07-documentation/jsdoc-generator.md +2 -1
  53. package/template/.claude/agents/07-documentation/readme-generator.md +2 -1
  54. package/template/.claude/agents/08-git/branch-manager.md +2 -1
  55. package/template/.claude/agents/08-git/commit-manager.md +2 -2
  56. package/template/.claude/agents/08-git/pr-creator.md +2 -1
  57. package/template/.claude/agents/09-quality/code-reviewer.md +2 -1
  58. package/template/.claude/agents/09-quality/quality-checker.md +1 -1
  59. package/template/.claude/agents/10-research/best-practices-finder.md +1 -1
  60. package/template/.claude/agents/10-research/competitor-analyzer.md +1 -1
  61. package/template/.claude/agents/10-research/pattern-researcher.md +1 -1
  62. package/template/.claude/agents/10-research/research-cache-manager.md +1 -1
  63. package/template/.claude/agents/10-research/research-web.md +1 -1
  64. package/template/.claude/agents/10-research/tech-evaluator.md +1 -1
  65. package/template/.claude/agents/11-ui-ux/accessibility-auditor.md +1 -1
  66. package/template/.claude/agents/11-ui-ux/design-system-enforcer.md +2 -2
  67. package/template/.claude/agents/11-ui-ux/skeleton-generator.md +2 -2
  68. package/template/.claude/agents/11-ui-ux/ui-desktop.md +2 -2
  69. package/template/.claude/agents/11-ui-ux/ui-mobile.md +2 -2
  70. package/template/.claude/agents/11-ui-ux/ui-tablet.md +2 -2
  71. package/template/.claude/agents/12-performance/api-latency-analyzer.md +2 -1
  72. package/template/.claude/agents/12-performance/bundle-analyzer.md +2 -1
  73. package/template/.claude/agents/12-performance/memory-leak-detector.md +2 -1
  74. package/template/.claude/agents/12-performance/performance-profiler.md +2 -1
  75. package/template/.claude/agents/12-performance/query-optimizer.md +2 -2
  76. package/template/.claude/agents/12-performance/render-optimizer.md +2 -1
  77. package/template/.claude/agents/13-debugging/build-error-fixer.md +2 -1
  78. package/template/.claude/agents/13-debugging/debugger.md +2 -1
  79. package/template/.claude/agents/13-debugging/error-stack-analyzer.md +2 -1
  80. package/template/.claude/agents/13-debugging/network-debugger.md +2 -1
  81. package/template/.claude/agents/13-debugging/runtime-error-fixer.md +2 -1
  82. package/template/.claude/agents/13-debugging/type-error-resolver.md +2 -1
  83. package/template/.claude/agents/14-validation/final-validator.md +1 -1
  84. package/template/.claude/hooks/SETUP.md +85 -11
  85. package/template/.claude/hooks/run-hook.cmd +46 -0
  86. package/template/.claude/hooks/run-hook.sh +43 -0
  87. package/template/.claude/hooks/run-hook.ts +158 -0
  88. package/template/.claude/hooks/stop-validator.ts +339 -0
  89. package/template/.claude/hooks/user-prompt-submit.ts +298 -0
  90. package/template/.claude/settings.json +4 -3
  91. package/template/.claude/skills/bun-runtime/SKILL.md +430 -0
  92. package/template/.claude/skills/codebase-knowledge/domains/claude-system.md +46 -4
  93. package/template/.claude/skills/debugging-patterns/SKILL.md +484 -0
  94. package/template/.claude/skills/docker-patterns/SKILL.md +547 -0
  95. package/template/.claude/skills/git-workflow/SKILL.md +454 -0
  96. package/template/.claude/skills/mongoose-patterns/SKILL.md +512 -0
  97. package/template/.claude/skills/nextjs-app-router/SKILL.md +337 -0
  98. package/template/.claude/skills/performance-patterns/SKILL.md +549 -0
  99. package/template/.claude/skills/playwright-automation/SKILL.md +438 -0
  100. package/template/.claude/skills/react-patterns/SKILL.md +376 -0
  101. package/template/.claude/skills/shadcn-ui/SKILL.md +520 -0
  102. package/template/.claude/skills/tailwind-patterns/SKILL.md +467 -0
  103. package/template/.claude/skills/trpc-api/SKILL.md +435 -0
  104. package/template/.claude/skills/typescript-strict/SKILL.md +368 -0
  105. package/template/.claude/skills/zod-validation/SKILL.md +405 -0
@@ -0,0 +1,158 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * Universal Hook Runner
4
+ *
5
+ * Runs hooks with multiple runtime fallbacks:
6
+ * 1. python3 (primary - user's preferred)
7
+ * 2. python (fallback)
8
+ * 3. Bun TypeScript (fallback if Python not available)
9
+ * 4. npx tsx (final fallback)
10
+ *
11
+ * Usage: bun run-hook.ts <hook-name>
12
+ * The hook-name should be without extension (e.g., "stop-validator")
13
+ */
14
+
15
+ import { spawnSync } from 'child_process';
16
+ import { existsSync } from 'fs';
17
+ import { join, dirname } from 'path';
18
+ import { fileURLToPath } from 'url';
19
+
20
+ // Get hooks directory - handle both ESM and CJS contexts
21
+ const getHooksDir = (): string => {
22
+ try {
23
+ if (typeof import.meta.url !== 'undefined') {
24
+ return dirname(fileURLToPath(import.meta.url));
25
+ }
26
+ } catch {
27
+ // Fallback for environments where import.meta is not available
28
+ }
29
+ return process.cwd();
30
+ };
31
+
32
+ const HOOKS_DIR = getHooksDir();
33
+
34
+ function checkRuntime(cmd: string): boolean {
35
+ try {
36
+ const result = spawnSync(cmd, ['--version'], {
37
+ stdio: 'pipe',
38
+ shell: true,
39
+ timeout: 5000,
40
+ windowsHide: true
41
+ });
42
+ return result.status === 0;
43
+ } catch {
44
+ return false;
45
+ }
46
+ }
47
+
48
+ function runWithRuntime(cmd: string, args: string[], input: string): { success: boolean; output: string; error?: string } {
49
+ try {
50
+ const result = spawnSync(cmd, args, {
51
+ input,
52
+ shell: true,
53
+ stdio: ['pipe', 'pipe', 'pipe'],
54
+ timeout: 30000,
55
+ windowsHide: true,
56
+ encoding: 'utf8'
57
+ });
58
+
59
+ return {
60
+ success: result.status === 0,
61
+ output: result.stdout?.toString() || '',
62
+ error: result.stderr?.toString() || undefined
63
+ };
64
+ } catch (err) {
65
+ return {
66
+ success: false,
67
+ output: '',
68
+ error: err instanceof Error ? err.message : 'Unknown error'
69
+ };
70
+ }
71
+ }
72
+
73
+ async function runHook(hookName: string, stdinData: string): Promise<void> {
74
+ const tsPath = join(HOOKS_DIR, `${hookName}.ts`);
75
+ const pyPath = join(HOOKS_DIR, `${hookName}.py`);
76
+
77
+ // Runtime detection order - Python FIRST, then fallbacks
78
+ const runtimes: Array<{ name: string; cmd: string; ext: string }> = [
79
+ { name: 'python3', cmd: 'python3', ext: '.py' },
80
+ { name: 'python', cmd: 'python', ext: '.py' },
81
+ { name: 'bun-ts', cmd: 'bun', ext: '.ts' },
82
+ { name: 'npx-tsx', cmd: 'npx tsx', ext: '.ts' }
83
+ ];
84
+
85
+ for (const runtime of runtimes) {
86
+ const hookPath = runtime.ext === '.ts' ? tsPath : pyPath;
87
+
88
+ if (!existsSync(hookPath)) {
89
+ continue;
90
+ }
91
+
92
+ if (!checkRuntime(runtime.cmd.split(' ')[0])) {
93
+ continue;
94
+ }
95
+
96
+ const result = runWithRuntime(runtime.cmd, [hookPath], stdinData);
97
+
98
+ if (result.success || !result.error?.includes('not found')) {
99
+ // Runtime worked (success or runtime-specific failure)
100
+ process.stdout.write(result.output);
101
+ if (result.error && !result.success) {
102
+ process.stderr.write(result.error);
103
+ }
104
+ process.exit(result.success ? 0 : 1);
105
+ }
106
+ // Runtime not available, try next
107
+ }
108
+
109
+ // No runtime available - return safe default
110
+ console.error(`[run-hook] No runtime available to run hook: ${hookName}`);
111
+ console.error('[run-hook] Please install one of: python3, python, bun, or Node.js');
112
+ const safeDefault = JSON.stringify({
113
+ decision: 'approve',
114
+ continue: true,
115
+ reason: 'Hook runtime not available, allowing by default'
116
+ });
117
+ process.stdout.write(safeDefault);
118
+ process.exit(0);
119
+ }
120
+
121
+ async function readStdinWithTimeout(timeoutMs: number): Promise<string> {
122
+ return new Promise((resolve) => {
123
+ const timeout = setTimeout(() => resolve('{}'), timeoutMs);
124
+
125
+ Bun.stdin.text().then((text) => {
126
+ clearTimeout(timeout);
127
+ resolve(text || '{}');
128
+ }).catch(() => {
129
+ clearTimeout(timeout);
130
+ resolve('{}');
131
+ });
132
+ });
133
+ }
134
+
135
+ // Main
136
+ async function main(): Promise<void> {
137
+ const hookName = process.argv[2];
138
+ if (!hookName) {
139
+ console.error('Usage: bun run-hook.ts <hook-name>');
140
+ process.exit(1);
141
+ }
142
+
143
+ // Read stdin with timeout to avoid hanging
144
+ const stdinData = await readStdinWithTimeout(2000);
145
+ await runHook(hookName, stdinData);
146
+ }
147
+
148
+ main().catch((err) => {
149
+ console.error('[run-hook] Fatal error:', err);
150
+ // Return safe default on error
151
+ const safeDefault = JSON.stringify({
152
+ decision: 'approve',
153
+ continue: true,
154
+ reason: 'Hook runner error, allowing by default'
155
+ });
156
+ process.stdout.write(safeDefault);
157
+ process.exit(0);
158
+ });
@@ -0,0 +1,339 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * Stop Validator Hook - TypeScript version (fallback when Python not available)
4
+ *
5
+ * VALIDATES:
6
+ * 1. NOT on main branch (unless no source changes)
7
+ * 2. All modified files are documented
8
+ * 3. Documenter agent was executed for source changes
9
+ *
10
+ * BLOCKS completion if validations fail.
11
+ */
12
+
13
+ import { execSync } from 'child_process';
14
+ import { existsSync, readdirSync, readFileSync, statSync } from 'fs';
15
+ import { join, basename, extname } from 'path';
16
+
17
+ const IGNORE_DIRS = new Set([
18
+ '.next', 'node_modules', 'dist', 'build', 'coverage',
19
+ '.git', '__pycache__', '.turbo', '.cache', '.husky',
20
+ 'packages'
21
+ ]);
22
+
23
+ const IGNORE_PATTERNS = [
24
+ '.lock', '.log', '.map', '.min.js', '.min.css',
25
+ 'package-lock.json', 'bun.lockb', '.DS_Store', 'Thumbs.db'
26
+ ];
27
+
28
+ const DOC_EXTENSIONS = new Set(['.md', '.mdx', '.txt', '.rst']);
29
+
30
+ const SOURCE_EXTENSIONS = new Set([
31
+ '.ts', '.tsx', '.js', '.jsx', '.py', '.go', '.rs',
32
+ '.java', '.kt', '.swift', '.vue', '.svelte'
33
+ ]);
34
+
35
+ const SYSTEM_CONFIG_PATTERNS = [
36
+ 'CLAUDE.md',
37
+ '.claude/',
38
+ 'PROJECT.md',
39
+ '.env.example',
40
+ ];
41
+
42
+ function shouldIgnoreFile(filePath: string): boolean {
43
+ const parts = filePath.split(/[/\\]/);
44
+
45
+ for (const part of parts) {
46
+ if (IGNORE_DIRS.has(part)) return true;
47
+ }
48
+
49
+ for (const pattern of IGNORE_PATTERNS) {
50
+ if (filePath.includes(pattern)) return true;
51
+ }
52
+
53
+ return false;
54
+ }
55
+
56
+ function isSourceFile(filePath: string): boolean {
57
+ const ext = extname(filePath);
58
+ return SOURCE_EXTENSIONS.has(ext) && !shouldIgnoreFile(filePath);
59
+ }
60
+
61
+ function isSystemConfigFile(filePath: string): boolean {
62
+ return SYSTEM_CONFIG_PATTERNS.some(pattern => filePath.includes(pattern));
63
+ }
64
+
65
+ function getCurrentBranch(projectDir: string): string {
66
+ try {
67
+ const result = execSync('git rev-parse --abbrev-ref HEAD', {
68
+ cwd: projectDir,
69
+ encoding: 'utf8',
70
+ stdio: ['pipe', 'pipe', 'pipe']
71
+ });
72
+ return result.trim();
73
+ } catch {
74
+ return 'unknown';
75
+ }
76
+ }
77
+
78
+ function getModifiedFiles(projectDir: string): string[] {
79
+ try {
80
+ const staged = execSync('git diff --name-only --cached', {
81
+ cwd: projectDir,
82
+ encoding: 'utf8',
83
+ stdio: ['pipe', 'pipe', 'pipe']
84
+ }).trim().split('\n').filter(Boolean);
85
+
86
+ const unstaged = execSync('git diff --name-only', {
87
+ cwd: projectDir,
88
+ encoding: 'utf8',
89
+ stdio: ['pipe', 'pipe', 'pipe']
90
+ }).trim().split('\n').filter(Boolean);
91
+
92
+ const untracked = execSync('git ls-files --others --exclude-standard', {
93
+ cwd: projectDir,
94
+ encoding: 'utf8',
95
+ stdio: ['pipe', 'pipe', 'pipe']
96
+ }).trim().split('\n').filter(Boolean);
97
+
98
+ return [...new Set([...staged, ...unstaged, ...untracked])].filter(Boolean);
99
+ } catch {
100
+ return [];
101
+ }
102
+ }
103
+
104
+ function* walkDir(dir: string): Generator<string> {
105
+ if (!existsSync(dir)) return;
106
+
107
+ const entries = readdirSync(dir);
108
+ for (const entry of entries) {
109
+ const fullPath = join(dir, entry);
110
+ try {
111
+ const stat = statSync(fullPath);
112
+ if (stat.isDirectory()) {
113
+ yield* walkDir(fullPath);
114
+ } else if (stat.isFile()) {
115
+ yield fullPath;
116
+ }
117
+ } catch {
118
+ continue;
119
+ }
120
+ }
121
+ }
122
+
123
+ function searchInDocs(projectDir: string, filePath: string): boolean {
124
+ const fileName = basename(filePath);
125
+ const fileStem = basename(filePath, extname(filePath));
126
+
127
+ const docDirs = [
128
+ join(projectDir, 'docs'),
129
+ join(projectDir, '.claude', 'skills', 'codebase-knowledge', 'domains'),
130
+ ];
131
+
132
+ for (const docDir of docDirs) {
133
+ if (!existsSync(docDir)) continue;
134
+
135
+ for (const docFile of walkDir(docDir)) {
136
+ const ext = extname(docFile);
137
+ if (!DOC_EXTENSIONS.has(ext)) continue;
138
+
139
+ try {
140
+ const content = readFileSync(docFile, 'utf8');
141
+ if (content.includes(fileName) || content.includes(fileStem) || content.includes(filePath)) {
142
+ return true;
143
+ }
144
+ } catch {
145
+ continue;
146
+ }
147
+ }
148
+ }
149
+
150
+ return false;
151
+ }
152
+
153
+ function validateDocumentation(projectDir: string, modifiedFiles: string[]): { undocumented: string[], documented: string[] } {
154
+ const undocumented: string[] = [];
155
+ const documented: string[] = [];
156
+
157
+ for (const filePath of modifiedFiles) {
158
+ if (!isSourceFile(filePath)) continue;
159
+
160
+ if (searchInDocs(projectDir, filePath)) {
161
+ documented.push(filePath);
162
+ } else {
163
+ undocumented.push(filePath);
164
+ }
165
+ }
166
+
167
+ return { undocumented, documented };
168
+ }
169
+
170
+ interface HookInput {
171
+ stop_hook_active?: boolean;
172
+ }
173
+
174
+ interface HookResult {
175
+ decision: 'approve' | 'block';
176
+ reason: string;
177
+ }
178
+
179
+ async function readStdinWithTimeout(timeoutMs: number): Promise<string> {
180
+ return new Promise((resolve) => {
181
+ const timeout = setTimeout(() => resolve('{}'), timeoutMs);
182
+
183
+ Bun.stdin.text().then((text) => {
184
+ clearTimeout(timeout);
185
+ resolve(text || '{}');
186
+ }).catch(() => {
187
+ clearTimeout(timeout);
188
+ resolve('{}');
189
+ });
190
+ });
191
+ }
192
+
193
+ async function main(): Promise<void> {
194
+ const projectDir = process.env['CLAUDE_PROJECT_DIR'] || process.cwd();
195
+
196
+ let hookInput: HookInput = {};
197
+ try {
198
+ const stdin = await readStdinWithTimeout(1000);
199
+ if (stdin && stdin.trim()) {
200
+ hookInput = JSON.parse(stdin);
201
+ }
202
+ } catch {
203
+ hookInput = {};
204
+ }
205
+
206
+ // Prevent infinite loops
207
+ if (hookInput.stop_hook_active) {
208
+ const result: HookResult = { decision: 'approve', reason: 'Stop hook cycle detected, allowing exit' };
209
+ console.log(JSON.stringify(result));
210
+ process.exit(0);
211
+ }
212
+
213
+ const currentBranch = getCurrentBranch(projectDir);
214
+ const modifiedFiles = getModifiedFiles(projectDir);
215
+ const sourceFiles = modifiedFiles.filter(isSourceFile);
216
+ const systemConfigFiles = modifiedFiles.filter(isSystemConfigFile);
217
+
218
+ const errors: Array<{ type: string; message: string }> = [];
219
+
220
+ // Check 1: ANY changes on main branch are FORBIDDEN
221
+ if ((currentBranch === 'main' || currentBranch === 'master') && modifiedFiles.length > 0) {
222
+ const fileList = modifiedFiles.slice(0, 15).map(f => ` - ${f}`).join('\n');
223
+ const more = modifiedFiles.length > 15 ? '\n ... and more' : '';
224
+
225
+ errors.push({
226
+ type: 'DIRECT_MAIN_COMMIT',
227
+ message: `
228
+ BLOCKED: Attempting to work directly on '${currentBranch}' branch!
229
+
230
+ You have ${modifiedFiles.length} modified file(s):
231
+ ${fileList}${more}
232
+
233
+ REQUIRED ACTION:
234
+ 1. Create a feature branch: git checkout -b feature/[name]
235
+ 2. Or fix/chore branch: git checkout -b fix/[name] or git checkout -b chore/[name]
236
+ 3. Continue your work on the new branch
237
+ 4. Create PR to merge back to main
238
+
239
+ NEVER make ANY changes directly on main. ALL work must be done on branches.
240
+ `
241
+ });
242
+ }
243
+
244
+ // Check 2: Documentation for source files
245
+ if (sourceFiles.length > 0) {
246
+ const { undocumented } = validateDocumentation(projectDir, sourceFiles);
247
+
248
+ if (undocumented.length > 0) {
249
+ const fileList = undocumented.slice(0, 15).map(f => ` - ${f}`).join('\n');
250
+ const more = undocumented.length > 15 ? '\n ... and more' : '';
251
+
252
+ errors.push({
253
+ type: 'MISSING_DOCUMENTATION',
254
+ message: `
255
+ BLOCKED: ${undocumented.length} source file(s) are NOT documented!
256
+
257
+ Undocumented files:
258
+ ${fileList}${more}
259
+
260
+ REQUIRED ACTION:
261
+ Run the documenter agent to update documentation:
262
+
263
+ Task(subagent_type="documenter", prompt="Update documentation for all modified files")
264
+
265
+ The documenter will:
266
+ 1. Detect changed files via git diff
267
+ 2. Update domain files in .claude/skills/codebase-knowledge/domains/
268
+ 3. Update docs/CHANGELOG.md
269
+ 4. Ensure all modified files are mentioned in documentation
270
+
271
+ DOCUMENTATION IS MANDATORY before task completion.
272
+ `
273
+ });
274
+ }
275
+ }
276
+
277
+ if (errors.length > 0) {
278
+ let errorOutput = `
279
+ ================================================================================
280
+ STOP VALIDATOR - BLOCKING TASK COMPLETION
281
+ ================================================================================
282
+ `;
283
+ for (const err of errors) {
284
+ errorOutput += `
285
+ --- ${err.type} ---
286
+ ${err.message}
287
+ `;
288
+ }
289
+
290
+ errorOutput += `
291
+ ================================================================================
292
+ FIX THE ABOVE ISSUES BEFORE COMPLETING THE TASK
293
+ ================================================================================
294
+ `;
295
+
296
+ const result: HookResult = { decision: 'block', reason: errorOutput.trim() };
297
+ console.log(JSON.stringify(result));
298
+ process.exit(0);
299
+ }
300
+
301
+ // All validations passed
302
+ let nextStepMessage: string;
303
+ if (modifiedFiles.length > 0) {
304
+ nextStepMessage = `
305
+ ================================================================================
306
+ ✓ ALL VALIDATIONS PASSED
307
+ ================================================================================
308
+
309
+ Branch: ${currentBranch}
310
+ Modified files: ${modifiedFiles.length} (source: ${sourceFiles.length}, config: ${systemConfigFiles.length})
311
+
312
+ MANDATORY NEXT STEP:
313
+ You MUST now commit, push, and create a PR:
314
+
315
+ 1. git add -A
316
+ 2. git commit with conventional commit message
317
+ 3. git push -u origin ${currentBranch}
318
+ 4. gh pr create to main branch
319
+
320
+ DO NOT ask the user - just execute the commit-manager flow.
321
+
322
+ ================================================================================
323
+ `;
324
+ } else {
325
+ nextStepMessage = `All validations passed. Branch: ${currentBranch}, no files modified.`;
326
+ }
327
+
328
+ const result: HookResult = { decision: 'approve', reason: nextStepMessage.trim() };
329
+ console.log(JSON.stringify(result));
330
+ process.exit(0);
331
+ }
332
+
333
+ main().catch((err) => {
334
+ console.error('Hook error:', err);
335
+ // On error, allow to continue to not block user
336
+ const result: HookResult = { decision: 'approve', reason: 'Hook error, allowing by default' };
337
+ console.log(JSON.stringify(result));
338
+ process.exit(0);
339
+ });