@agentic15.com/agentic15-claude-zen 3.2.1 → 3.3.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/README.md +35 -14
- package/bin/agentic15.js +65 -57
- package/package.json +4 -2
- package/src/cli/VisualTestCommand.js +191 -0
- package/src/core/TemplateManager.js +137 -160
- package/templates/.claude/hooks/require-active-task.js +89 -89
- package/templates/.claude/settings.json +5 -91
- package/templates/package.json +31 -31
package/README.md
CHANGED
|
@@ -27,24 +27,45 @@ cd my-project
|
|
|
27
27
|
|
|
28
28
|
Start Claude Code CLI from inside the `my-project` directory. Claude Code MUST be running from inside your project directory to access the framework files.
|
|
29
29
|
|
|
30
|
-
**Step 4:
|
|
30
|
+
**Step 4: Configure Repository Settings (Recommended)**
|
|
31
31
|
```bash
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
# Prevent direct pushes to main - require PRs for all changes
|
|
33
|
+
gh api repos/OWNER/REPO/branches/main/protection -X PUT \
|
|
34
|
+
-H "Accept: application/vnd.github+json" \
|
|
35
|
+
-f required_pull_request_reviews[required_approving_review_count]=0 \
|
|
36
|
+
-f enforce_admins=false \
|
|
37
|
+
-f allow_force_pushes=false \
|
|
38
|
+
-f allow_deletions=false
|
|
39
|
+
|
|
40
|
+
# Auto-delete branches after PR merge
|
|
41
|
+
gh api repos/OWNER/REPO -X PATCH \
|
|
42
|
+
-H "Accept: application/vnd.github+json" \
|
|
43
|
+
-f delete_branch_on_merge=true
|
|
44
|
+
```
|
|
45
|
+
Replace `OWNER/REPO` with your GitHub username and repository name.
|
|
46
|
+
|
|
47
|
+
**Step 5: Use Framework Commands**
|
|
48
|
+
```bash
|
|
49
|
+
npx agentic15 auth # One-time GitHub setup
|
|
50
|
+
npx agentic15 plan # Enter interactive mode
|
|
34
51
|
# Type/paste your requirements, press Ctrl+D when done
|
|
35
|
-
|
|
36
|
-
#
|
|
37
|
-
npx agentic15
|
|
52
|
+
# Open another terminal. Make sure that you in your project directory. Launch Claude
|
|
53
|
+
# Ask Claude: "Read the requirements file and generate a task breakdown plan"
|
|
54
|
+
npx agentic15 task next # Start first task
|
|
55
|
+
# Ask Claude: "Implement this task"
|
|
56
|
+
npx agentic15 commit # Test, commit, push, PR
|
|
38
57
|
```
|
|
39
58
|
|
|
40
59
|
> **IMPORTANT**: Always launch Claude Code from inside your project directory, not from the parent directory. The framework relies on `.claude/` configuration files that must be accessible from the working directory.
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
60
|
+
|
|
61
|
+
**Step 6: Clean Up Local Branches**
|
|
62
|
+
```bash
|
|
63
|
+
# If auto-delete is enabled, only clean up local branches
|
|
64
|
+
git branch -d feature/task-001
|
|
65
|
+
|
|
66
|
+
# For repositories without auto-delete, also delete remote
|
|
67
|
+
git push origin --delete feature/task-001
|
|
68
|
+
```
|
|
48
69
|
|
|
49
70
|
**See [WORKFLOWS.md](WORKFLOWS.md) for complete workflows.**
|
|
50
71
|
|
|
@@ -56,8 +77,8 @@ npx agentic15 commit # Test, commit, push, PR
|
|
|
56
77
|
- `npx agentic15 plan` - Generate and lock plans
|
|
57
78
|
- `npx agentic15 task next` - Start next task
|
|
58
79
|
- `npx agentic15 commit` - Test + commit + push + PR
|
|
80
|
+
- `npx agentic15 visual-test <url>` - Capture screenshots & console errors
|
|
59
81
|
- `npx agentic15 status` - Check progress
|
|
60
|
-
- `npx agentic15 upgrade` - Upgrade framework files
|
|
61
82
|
- `npm test` - Run tests
|
|
62
83
|
|
|
63
84
|
**Automates:**
|
package/bin/agentic15.js
CHANGED
|
@@ -1,57 +1,65 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { Command } from 'commander';
|
|
4
|
-
import { AuthCommand } from '../src/cli/AuthCommand.js';
|
|
5
|
-
import { TaskCommand } from '../src/cli/TaskCommand.js';
|
|
6
|
-
import { CommitCommand } from '../src/cli/CommitCommand.js';
|
|
7
|
-
import { StatusCommand } from '../src/cli/StatusCommand.js';
|
|
8
|
-
import { PlanCommand } from '../src/cli/PlanCommand.js';
|
|
9
|
-
import { UpgradeCommand } from '../src/cli/UpgradeCommand.js';
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
.
|
|
16
|
-
.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
.
|
|
22
|
-
.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
.
|
|
28
|
-
.
|
|
29
|
-
.argument('
|
|
30
|
-
.
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
.
|
|
36
|
-
.
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
.
|
|
42
|
-
.
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
.
|
|
48
|
-
.
|
|
49
|
-
.
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
.
|
|
55
|
-
.
|
|
56
|
-
|
|
57
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import { AuthCommand } from '../src/cli/AuthCommand.js';
|
|
5
|
+
import { TaskCommand } from '../src/cli/TaskCommand.js';
|
|
6
|
+
import { CommitCommand } from '../src/cli/CommitCommand.js';
|
|
7
|
+
import { StatusCommand } from '../src/cli/StatusCommand.js';
|
|
8
|
+
import { PlanCommand } from '../src/cli/PlanCommand.js';
|
|
9
|
+
import { UpgradeCommand } from '../src/cli/UpgradeCommand.js';
|
|
10
|
+
import { VisualTestCommand } from '../src/cli/VisualTestCommand.js';
|
|
11
|
+
|
|
12
|
+
const program = new Command();
|
|
13
|
+
|
|
14
|
+
program
|
|
15
|
+
.name('agentic15')
|
|
16
|
+
.description('Agentic15 Claude Zen - Automated AI development workflow')
|
|
17
|
+
.version('2.0.0');
|
|
18
|
+
|
|
19
|
+
// GitHub authentication setup
|
|
20
|
+
program
|
|
21
|
+
.command('auth')
|
|
22
|
+
.description('GitHub authentication setup')
|
|
23
|
+
.action(() => AuthCommand.setup());
|
|
24
|
+
|
|
25
|
+
// Task management
|
|
26
|
+
program
|
|
27
|
+
.command('task')
|
|
28
|
+
.description('Task management')
|
|
29
|
+
.argument('<action>', 'Action: start, next, status')
|
|
30
|
+
.argument('[taskId]', 'Task ID (e.g., TASK-001) - required for "start"')
|
|
31
|
+
.action((action, taskId) => TaskCommand.handle(action, taskId));
|
|
32
|
+
|
|
33
|
+
// Auto-commit workflow
|
|
34
|
+
program
|
|
35
|
+
.command('commit')
|
|
36
|
+
.description('Run tests, commit, push, create PR')
|
|
37
|
+
.action(() => CommitCommand.execute());
|
|
38
|
+
|
|
39
|
+
// Show status
|
|
40
|
+
program
|
|
41
|
+
.command('status')
|
|
42
|
+
.description('Show current task status and progress')
|
|
43
|
+
.action(() => StatusCommand.show());
|
|
44
|
+
|
|
45
|
+
// Plan management (single command for generate + lock)
|
|
46
|
+
program
|
|
47
|
+
.command('plan')
|
|
48
|
+
.description('Generate and lock plan')
|
|
49
|
+
.argument('[description]', 'Project description (required for first run)')
|
|
50
|
+
.action((description) => PlanCommand.handle(description));
|
|
51
|
+
|
|
52
|
+
// Upgrade framework
|
|
53
|
+
program
|
|
54
|
+
.command('upgrade')
|
|
55
|
+
.description('Upgrade framework files to latest version')
|
|
56
|
+
.action(() => UpgradeCommand.execute());
|
|
57
|
+
|
|
58
|
+
// Visual testing - capture screenshots and console errors
|
|
59
|
+
program
|
|
60
|
+
.command('visual-test')
|
|
61
|
+
.description('Capture screenshots and console errors for UI debugging')
|
|
62
|
+
.argument('<url>', 'URL to test (e.g., http://localhost:3000)')
|
|
63
|
+
.action((url) => VisualTestCommand.execute(url));
|
|
64
|
+
|
|
65
|
+
program.parse();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentic15.com/agentic15-claude-zen",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.0",
|
|
4
4
|
"description": "Structured AI-assisted development framework for Claude Code with enforced quality standards",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -11,7 +11,9 @@
|
|
|
11
11
|
"scripts": {
|
|
12
12
|
"test": "node test/integration.test.js",
|
|
13
13
|
"test:e2e": "node test/e2e-verification.test.js",
|
|
14
|
-
"test:site": "node test/verify-test-site.js"
|
|
14
|
+
"test:site": "node test/verify-test-site.js",
|
|
15
|
+
"sync-readme": "node -e \"require('fs').copyFileSync('../../README.md', 'README.md')\"",
|
|
16
|
+
"prepublishOnly": "npm run sync-readme"
|
|
15
17
|
},
|
|
16
18
|
"keywords": [
|
|
17
19
|
"agentic15",
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { execSync } from 'child_process';
|
|
2
|
+
import { existsSync, writeFileSync, mkdirSync, unlinkSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* VisualTestCommand - Capture screenshots and console errors for UI debugging
|
|
7
|
+
*
|
|
8
|
+
* Uses Claude Code's built-in screenshot capabilities (no API key needed)
|
|
9
|
+
* Helps report UI issues to Claude without manual back-and-forth
|
|
10
|
+
*/
|
|
11
|
+
export class VisualTestCommand {
|
|
12
|
+
static async execute(url) {
|
|
13
|
+
console.log('\n🎯 Visual Test - Capture screenshots and console errors\n');
|
|
14
|
+
|
|
15
|
+
if (!url) {
|
|
16
|
+
console.log('❌ URL required');
|
|
17
|
+
console.log(' Usage: npx agentic15 visual-test <url>\n');
|
|
18
|
+
console.log(' Example: npx agentic15 visual-test http://localhost:3000\n');
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Check if Playwright is installed
|
|
23
|
+
const hasPlaywright = this.checkPlaywright();
|
|
24
|
+
|
|
25
|
+
if (!hasPlaywright) {
|
|
26
|
+
console.log('⚠️ Playwright not installed');
|
|
27
|
+
console.log(' Install with: npx playwright install chromium\n');
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
console.log(`📸 Capturing screenshots and logs from: ${url}\n`);
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
// Run Playwright visual test
|
|
35
|
+
this.runVisualTest(url);
|
|
36
|
+
|
|
37
|
+
console.log('\n✅ Visual test complete');
|
|
38
|
+
console.log(' Screenshots saved to: .claude/visual-test/\n');
|
|
39
|
+
console.log('💡 Next steps:');
|
|
40
|
+
console.log(' 1. Review screenshots in .claude/visual-test/');
|
|
41
|
+
console.log(' 2. Check console-errors.log for JavaScript errors');
|
|
42
|
+
console.log(' 3. Ask Claude to analyze the visual test results\n');
|
|
43
|
+
|
|
44
|
+
process.exit(0);
|
|
45
|
+
} catch (error) {
|
|
46
|
+
console.log(`\n❌ Visual test failed: ${error.message}\n`);
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
static checkPlaywright() {
|
|
52
|
+
const projectRoot = process.cwd();
|
|
53
|
+
const packageJsonPath = join(projectRoot, 'package.json');
|
|
54
|
+
|
|
55
|
+
if (!existsSync(packageJsonPath)) {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
try {
|
|
60
|
+
// Check if playwright is in devDependencies
|
|
61
|
+
execSync('npx playwright --version', { stdio: 'pipe' });
|
|
62
|
+
return true;
|
|
63
|
+
} catch {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
static runVisualTest(url) {
|
|
69
|
+
const testScript = `
|
|
70
|
+
const { chromium } = require('playwright');
|
|
71
|
+
const { writeFileSync, mkdirSync } = require('fs');
|
|
72
|
+
const { join } = require('path');
|
|
73
|
+
|
|
74
|
+
(async () => {
|
|
75
|
+
const outputDir = join(process.cwd(), '.claude', 'visual-test');
|
|
76
|
+
mkdirSync(outputDir, { recursive: true });
|
|
77
|
+
|
|
78
|
+
const consoleErrors = [];
|
|
79
|
+
const consoleWarnings = [];
|
|
80
|
+
|
|
81
|
+
const browser = await chromium.launch({ headless: true });
|
|
82
|
+
const context = await browser.newContext({
|
|
83
|
+
viewport: { width: 1920, height: 1080 }
|
|
84
|
+
});
|
|
85
|
+
const page = await context.newPage();
|
|
86
|
+
|
|
87
|
+
// Capture console errors
|
|
88
|
+
page.on('console', msg => {
|
|
89
|
+
if (msg.type() === 'error') {
|
|
90
|
+
consoleErrors.push({
|
|
91
|
+
timestamp: new Date().toISOString(),
|
|
92
|
+
message: msg.text()
|
|
93
|
+
});
|
|
94
|
+
} else if (msg.type() === 'warning') {
|
|
95
|
+
consoleWarnings.push({
|
|
96
|
+
timestamp: new Date().toISOString(),
|
|
97
|
+
message: msg.text()
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// Capture page errors
|
|
103
|
+
page.on('pageerror', error => {
|
|
104
|
+
consoleErrors.push({
|
|
105
|
+
timestamp: new Date().toISOString(),
|
|
106
|
+
message: error.message,
|
|
107
|
+
stack: error.stack
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
try {
|
|
112
|
+
// Navigate to URL
|
|
113
|
+
await page.goto('${url}', { waitUntil: 'networkidle', timeout: 30000 });
|
|
114
|
+
|
|
115
|
+
// Wait for page to stabilize
|
|
116
|
+
await page.waitForTimeout(2000);
|
|
117
|
+
|
|
118
|
+
// Capture full page screenshot
|
|
119
|
+
await page.screenshot({
|
|
120
|
+
path: join(outputDir, 'fullpage.png'),
|
|
121
|
+
fullPage: true
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
// Capture viewport screenshot
|
|
125
|
+
await page.screenshot({
|
|
126
|
+
path: join(outputDir, 'viewport.png'),
|
|
127
|
+
fullPage: false
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
// Save console errors
|
|
131
|
+
if (consoleErrors.length > 0) {
|
|
132
|
+
const errorLog = consoleErrors.map(e =>
|
|
133
|
+
\`[\${e.timestamp}] \${e.message}\${e.stack ? '\\n' + e.stack : ''}\`
|
|
134
|
+
).join('\\n\\n');
|
|
135
|
+
|
|
136
|
+
writeFileSync(join(outputDir, 'console-errors.log'), errorLog);
|
|
137
|
+
console.log(\`❌ Found \${consoleErrors.length} console errors\`);
|
|
138
|
+
} else {
|
|
139
|
+
console.log('✅ No console errors detected');
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Save console warnings
|
|
143
|
+
if (consoleWarnings.length > 0) {
|
|
144
|
+
const warningLog = consoleWarnings.map(w =>
|
|
145
|
+
\`[\${w.timestamp}] \${w.message}\`
|
|
146
|
+
).join('\\n\\n');
|
|
147
|
+
|
|
148
|
+
writeFileSync(join(outputDir, 'console-warnings.log'), warningLog);
|
|
149
|
+
console.log(\`⚠️ Found \${consoleWarnings.length} console warnings\`);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Capture page HTML for debugging
|
|
153
|
+
const html = await page.content();
|
|
154
|
+
writeFileSync(join(outputDir, 'page.html'), html);
|
|
155
|
+
|
|
156
|
+
} catch (error) {
|
|
157
|
+
console.error('Error during visual test:', error.message);
|
|
158
|
+
|
|
159
|
+
// Try to capture screenshot even on error
|
|
160
|
+
try {
|
|
161
|
+
await page.screenshot({
|
|
162
|
+
path: join(outputDir, 'error-screenshot.png')
|
|
163
|
+
});
|
|
164
|
+
} catch {}
|
|
165
|
+
|
|
166
|
+
throw error;
|
|
167
|
+
} finally {
|
|
168
|
+
await browser.close();
|
|
169
|
+
}
|
|
170
|
+
})();
|
|
171
|
+
`;
|
|
172
|
+
|
|
173
|
+
// Write test script to temp file and execute
|
|
174
|
+
const tempScriptPath = join(process.cwd(), '.claude', 'temp-visual-test.js');
|
|
175
|
+
|
|
176
|
+
mkdirSync(join(process.cwd(), '.claude'), { recursive: true });
|
|
177
|
+
writeFileSync(tempScriptPath, testScript);
|
|
178
|
+
|
|
179
|
+
try {
|
|
180
|
+
execSync(`node "${tempScriptPath}"`, {
|
|
181
|
+
stdio: 'inherit',
|
|
182
|
+
cwd: process.cwd()
|
|
183
|
+
});
|
|
184
|
+
} finally {
|
|
185
|
+
// Clean up temp script
|
|
186
|
+
try {
|
|
187
|
+
unlinkSync(tempScriptPath);
|
|
188
|
+
} catch {}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
@@ -1,160 +1,137 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright 2024-2025 agentic15.com
|
|
3
|
-
*
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
*
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
import { mkdirSync, cpSync, readFileSync, writeFileSync, existsSync } from 'fs';
|
|
18
|
-
import { join, dirname } from 'path';
|
|
19
|
-
import { fileURLToPath } from 'url';
|
|
20
|
-
|
|
21
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
22
|
-
const __dirname = dirname(__filename);
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* TemplateManager - Manages template copying and customization
|
|
26
|
-
*
|
|
27
|
-
* Single Responsibility: Copy and customize project templates
|
|
28
|
-
*/
|
|
29
|
-
export class TemplateManager {
|
|
30
|
-
constructor() {
|
|
31
|
-
// From src/core/, go up two levels to package root, then into templates
|
|
32
|
-
this.templatesDir = join(__dirname, '..', '..', 'templates');
|
|
33
|
-
this.distDir = join(__dirname, '.');
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Copy all templates to target directory
|
|
38
|
-
*
|
|
39
|
-
* @param {string} projectName - Name of the project
|
|
40
|
-
* @param {string} targetDir - Target directory path
|
|
41
|
-
*/
|
|
42
|
-
async copyTemplates(projectName, targetDir) {
|
|
43
|
-
console.log('📦 Creating project directory...');
|
|
44
|
-
mkdirSync(targetDir, { recursive: true });
|
|
45
|
-
|
|
46
|
-
console.log('📋 Copying framework templates...');
|
|
47
|
-
|
|
48
|
-
// Copy .claude directory structure
|
|
49
|
-
this.copyDirectory('.claude', targetDir);
|
|
50
|
-
|
|
51
|
-
// Copy and customize package.json
|
|
52
|
-
this.copyAndCustomize('package.json', targetDir, projectName);
|
|
53
|
-
|
|
54
|
-
// Copy and customize README.md
|
|
55
|
-
this.copyAndCustomize('README.md', targetDir, projectName);
|
|
56
|
-
|
|
57
|
-
// Copy .gitignore (npm may rename it)
|
|
58
|
-
this.copyGitignore(targetDir);
|
|
59
|
-
|
|
60
|
-
// Copy test-site
|
|
61
|
-
this.copyDirectory('test-site', targetDir);
|
|
62
|
-
|
|
63
|
-
// Copy Agent directory
|
|
64
|
-
this.copyDirectory('Agent', targetDir);
|
|
65
|
-
|
|
66
|
-
// Copy scripts directory
|
|
67
|
-
this.copyDirectory('scripts', targetDir);
|
|
68
|
-
|
|
69
|
-
// Copy Jest configuration files
|
|
70
|
-
this.copySingleFile('jest.config.js', targetDir);
|
|
71
|
-
this.copySingleFile('jest.setup.js', targetDir);
|
|
72
|
-
this.copySingleFile('.babelrc', targetDir);
|
|
73
|
-
|
|
74
|
-
// Copy __mocks__ directory
|
|
75
|
-
this.copyDirectory('__mocks__', targetDir);
|
|
76
|
-
|
|
77
|
-
console.log('✅ Framework structure created');
|
|
78
|
-
console.log('✅ Templates copied');
|
|
79
|
-
console.log('✅ Configuration files generated');
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
* @param {string}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
console.log(
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
);
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
* @param {string} targetDir - Target directory path
|
|
139
|
-
* @param {string} projectName - Project name for replacement
|
|
140
|
-
*/
|
|
141
|
-
copyAndCustomize(fileName, targetDir, projectName) {
|
|
142
|
-
console.log(` ├─ ${fileName}`);
|
|
143
|
-
const template = readFileSync(join(this.templatesDir, fileName), 'utf8');
|
|
144
|
-
const customized = template.replace(/\{\{PROJECT_NAME\}\}/g, projectName);
|
|
145
|
-
writeFileSync(join(targetDir, fileName), customized);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Copy .gitignore file (handles npm renaming issue)
|
|
150
|
-
*
|
|
151
|
-
* @param {string} targetDir - Target directory path
|
|
152
|
-
*/
|
|
153
|
-
copyGitignore(targetDir) {
|
|
154
|
-
console.log(' ├─ .gitignore');
|
|
155
|
-
const gitignoreSource = existsSync(join(this.templatesDir, '.gitignore'))
|
|
156
|
-
? join(this.templatesDir, '.gitignore')
|
|
157
|
-
: join(this.templatesDir, '.npmignore');
|
|
158
|
-
cpSync(gitignoreSource, join(targetDir, '.gitignore'));
|
|
159
|
-
}
|
|
160
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2024-2025 agentic15.com
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { mkdirSync, cpSync, readFileSync, writeFileSync, existsSync } from 'fs';
|
|
18
|
+
import { join, dirname } from 'path';
|
|
19
|
+
import { fileURLToPath } from 'url';
|
|
20
|
+
|
|
21
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
22
|
+
const __dirname = dirname(__filename);
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* TemplateManager - Manages template copying and customization
|
|
26
|
+
*
|
|
27
|
+
* Single Responsibility: Copy and customize project templates
|
|
28
|
+
*/
|
|
29
|
+
export class TemplateManager {
|
|
30
|
+
constructor() {
|
|
31
|
+
// From src/core/, go up two levels to package root, then into templates
|
|
32
|
+
this.templatesDir = join(__dirname, '..', '..', 'templates');
|
|
33
|
+
this.distDir = join(__dirname, '.');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Copy all templates to target directory
|
|
38
|
+
*
|
|
39
|
+
* @param {string} projectName - Name of the project
|
|
40
|
+
* @param {string} targetDir - Target directory path
|
|
41
|
+
*/
|
|
42
|
+
async copyTemplates(projectName, targetDir) {
|
|
43
|
+
console.log('📦 Creating project directory...');
|
|
44
|
+
mkdirSync(targetDir, { recursive: true });
|
|
45
|
+
|
|
46
|
+
console.log('📋 Copying framework templates...');
|
|
47
|
+
|
|
48
|
+
// Copy .claude directory structure
|
|
49
|
+
this.copyDirectory('.claude', targetDir);
|
|
50
|
+
|
|
51
|
+
// Copy and customize package.json
|
|
52
|
+
this.copyAndCustomize('package.json', targetDir, projectName);
|
|
53
|
+
|
|
54
|
+
// Copy and customize README.md
|
|
55
|
+
this.copyAndCustomize('README.md', targetDir, projectName);
|
|
56
|
+
|
|
57
|
+
// Copy .gitignore (npm may rename it)
|
|
58
|
+
this.copyGitignore(targetDir);
|
|
59
|
+
|
|
60
|
+
// Copy test-site
|
|
61
|
+
this.copyDirectory('test-site', targetDir);
|
|
62
|
+
|
|
63
|
+
// Copy Agent directory
|
|
64
|
+
this.copyDirectory('Agent', targetDir);
|
|
65
|
+
|
|
66
|
+
// Copy scripts directory
|
|
67
|
+
this.copyDirectory('scripts', targetDir);
|
|
68
|
+
|
|
69
|
+
// Copy Jest configuration files
|
|
70
|
+
this.copySingleFile('jest.config.js', targetDir);
|
|
71
|
+
this.copySingleFile('jest.setup.js', targetDir);
|
|
72
|
+
this.copySingleFile('.babelrc', targetDir);
|
|
73
|
+
|
|
74
|
+
// Copy __mocks__ directory
|
|
75
|
+
this.copyDirectory('__mocks__', targetDir);
|
|
76
|
+
|
|
77
|
+
console.log('✅ Framework structure created');
|
|
78
|
+
console.log('✅ Templates copied');
|
|
79
|
+
console.log('✅ Configuration files generated');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Copy a directory from templates to target
|
|
84
|
+
*
|
|
85
|
+
* @param {string} dirName - Directory name
|
|
86
|
+
* @param {string} targetDir - Target directory path
|
|
87
|
+
*/
|
|
88
|
+
copyDirectory(dirName, targetDir) {
|
|
89
|
+
console.log(` ├─ ${dirName}/`);
|
|
90
|
+
cpSync(
|
|
91
|
+
join(this.templatesDir, dirName),
|
|
92
|
+
join(targetDir, dirName),
|
|
93
|
+
{ recursive: true }
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Copy a single file from templates to target
|
|
99
|
+
*
|
|
100
|
+
* @param {string} fileName - File name
|
|
101
|
+
* @param {string} targetDir - Target directory path
|
|
102
|
+
*/
|
|
103
|
+
copySingleFile(fileName, targetDir) {
|
|
104
|
+
console.log(` ├─ ${fileName}`);
|
|
105
|
+
cpSync(
|
|
106
|
+
join(this.templatesDir, fileName),
|
|
107
|
+
join(targetDir, fileName)
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Copy and customize a file with project name replacement
|
|
113
|
+
*
|
|
114
|
+
* @param {string} fileName - File name
|
|
115
|
+
* @param {string} targetDir - Target directory path
|
|
116
|
+
* @param {string} projectName - Project name for replacement
|
|
117
|
+
*/
|
|
118
|
+
copyAndCustomize(fileName, targetDir, projectName) {
|
|
119
|
+
console.log(` ├─ ${fileName}`);
|
|
120
|
+
const template = readFileSync(join(this.templatesDir, fileName), 'utf8');
|
|
121
|
+
const customized = template.replace(/\{\{PROJECT_NAME\}\}/g, projectName);
|
|
122
|
+
writeFileSync(join(targetDir, fileName), customized);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Copy .gitignore file (handles npm renaming issue)
|
|
127
|
+
*
|
|
128
|
+
* @param {string} targetDir - Target directory path
|
|
129
|
+
*/
|
|
130
|
+
copyGitignore(targetDir) {
|
|
131
|
+
console.log(' ├─ .gitignore');
|
|
132
|
+
const gitignoreSource = existsSync(join(this.templatesDir, '.gitignore'))
|
|
133
|
+
? join(this.templatesDir, '.gitignore')
|
|
134
|
+
: join(this.templatesDir, '.npmignore');
|
|
135
|
+
cpSync(gitignoreSource, join(targetDir, '.gitignore'));
|
|
136
|
+
}
|
|
137
|
+
}
|
|
@@ -1,89 +1,89 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Require Active Task Hook
|
|
5
|
-
*
|
|
6
|
-
* BLOCKS all Edit/Write operations when no active task exists
|
|
7
|
-
*
|
|
8
|
-
* This is the enforcement mechanism that prevents workflow violations
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
const fs = require('fs');
|
|
12
|
-
const path = require('path');
|
|
13
|
-
|
|
14
|
-
// Read tool use from stdin
|
|
15
|
-
let input = '';
|
|
16
|
-
process.stdin.on('data', chunk => {
|
|
17
|
-
input += chunk;
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
process.stdin.on('end', () => {
|
|
21
|
-
try {
|
|
22
|
-
const toolUse = JSON.parse(input);
|
|
23
|
-
|
|
24
|
-
// Only check Edit and Write operations
|
|
25
|
-
if (toolUse.name !== 'Edit' && toolUse.name !== 'Write') {
|
|
26
|
-
// Allow all other tools
|
|
27
|
-
process.exit(0);
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Check if active task exists
|
|
32
|
-
const activePlanFile = '.claude/ACTIVE-PLAN';
|
|
33
|
-
|
|
34
|
-
if (!fs.existsSync(activePlanFile)) {
|
|
35
|
-
console.error('\n' + '═'.repeat(70));
|
|
36
|
-
console.error('❌ BLOCKED: No active plan exists');
|
|
37
|
-
console.error('═'.repeat(70));
|
|
38
|
-
console.error('\nYou MUST have an active plan before making code changes.');
|
|
39
|
-
console.error('\nTo create a plan:');
|
|
40
|
-
console.error(' npx agentic15 plan "Your project requirements"');
|
|
41
|
-
console.error('\n' + '═'.repeat(70) + '\n');
|
|
42
|
-
process.exit(1);
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const activePlan = fs.readFileSync(activePlanFile, 'utf8').trim();
|
|
47
|
-
const planDir = path.join('.claude/plans', activePlan);
|
|
48
|
-
const trackerPath = path.join(planDir, 'TASK-TRACKER.json');
|
|
49
|
-
|
|
50
|
-
if (!fs.existsSync(trackerPath)) {
|
|
51
|
-
console.error('\n' + '═'.repeat(70));
|
|
52
|
-
console.error('❌ BLOCKED: Task tracker not found');
|
|
53
|
-
console.error('═'.repeat(70));
|
|
54
|
-
console.error('\nPlan exists but task tracker is missing.');
|
|
55
|
-
console.error('This indicates a corrupted plan state.');
|
|
56
|
-
console.error('\n' + '═'.repeat(70) + '\n');
|
|
57
|
-
process.exit(1);
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const tracker = JSON.parse(fs.readFileSync(trackerPath, 'utf8'));
|
|
62
|
-
|
|
63
|
-
if (!tracker.activeTask) {
|
|
64
|
-
console.error('\n' + '═'.repeat(70));
|
|
65
|
-
console.error('❌ BLOCKED: No active task');
|
|
66
|
-
console.error('═'.repeat(70));
|
|
67
|
-
console.error('\nYou MUST have an active task before making code changes.');
|
|
68
|
-
console.error('\nTo start a task:');
|
|
69
|
-
console.error(' npx agentic15 task next');
|
|
70
|
-
console.error('\nThis will:');
|
|
71
|
-
console.error(' 1. Show you the next pending task');
|
|
72
|
-
console.error(' 2. Create a feature branch');
|
|
73
|
-
console.error(' 3. Create a GitHub issue');
|
|
74
|
-
console.error(' 4. Mark the task as active');
|
|
75
|
-
console.error('\nThen you can make your changes.');
|
|
76
|
-
console.error('\n' + '═'.repeat(70) + '\n');
|
|
77
|
-
process.exit(1);
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Active task exists - allow the operation
|
|
82
|
-
process.exit(0);
|
|
83
|
-
|
|
84
|
-
} catch (error) {
|
|
85
|
-
// If we can't parse or check, fail safe and allow
|
|
86
|
-
// (don't want to block legitimate work due to hook errors)
|
|
87
|
-
process.exit(0);
|
|
88
|
-
}
|
|
89
|
-
});
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Require Active Task Hook
|
|
5
|
+
*
|
|
6
|
+
* BLOCKS all Edit/Write operations when no active task exists
|
|
7
|
+
*
|
|
8
|
+
* This is the enforcement mechanism that prevents workflow violations
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const fs = require('fs');
|
|
12
|
+
const path = require('path');
|
|
13
|
+
|
|
14
|
+
// Read tool use from stdin
|
|
15
|
+
let input = '';
|
|
16
|
+
process.stdin.on('data', chunk => {
|
|
17
|
+
input += chunk;
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
process.stdin.on('end', () => {
|
|
21
|
+
try {
|
|
22
|
+
const toolUse = JSON.parse(input);
|
|
23
|
+
|
|
24
|
+
// Only check Edit and Write operations
|
|
25
|
+
if (toolUse.name !== 'Edit' && toolUse.name !== 'Write') {
|
|
26
|
+
// Allow all other tools
|
|
27
|
+
process.exit(0);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Check if active task exists
|
|
32
|
+
const activePlanFile = '.claude/ACTIVE-PLAN';
|
|
33
|
+
|
|
34
|
+
if (!fs.existsSync(activePlanFile)) {
|
|
35
|
+
console.error('\n' + '═'.repeat(70));
|
|
36
|
+
console.error('❌ BLOCKED: No active plan exists');
|
|
37
|
+
console.error('═'.repeat(70));
|
|
38
|
+
console.error('\nYou MUST have an active plan before making code changes.');
|
|
39
|
+
console.error('\nTo create a plan:');
|
|
40
|
+
console.error(' npx agentic15 plan "Your project requirements"');
|
|
41
|
+
console.error('\n' + '═'.repeat(70) + '\n');
|
|
42
|
+
process.exit(1);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const activePlan = fs.readFileSync(activePlanFile, 'utf8').trim();
|
|
47
|
+
const planDir = path.join('.claude/plans', activePlan);
|
|
48
|
+
const trackerPath = path.join(planDir, 'TASK-TRACKER.json');
|
|
49
|
+
|
|
50
|
+
if (!fs.existsSync(trackerPath)) {
|
|
51
|
+
console.error('\n' + '═'.repeat(70));
|
|
52
|
+
console.error('❌ BLOCKED: Task tracker not found');
|
|
53
|
+
console.error('═'.repeat(70));
|
|
54
|
+
console.error('\nPlan exists but task tracker is missing.');
|
|
55
|
+
console.error('This indicates a corrupted plan state.');
|
|
56
|
+
console.error('\n' + '═'.repeat(70) + '\n');
|
|
57
|
+
process.exit(1);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const tracker = JSON.parse(fs.readFileSync(trackerPath, 'utf8'));
|
|
62
|
+
|
|
63
|
+
if (!tracker.activeTask) {
|
|
64
|
+
console.error('\n' + '═'.repeat(70));
|
|
65
|
+
console.error('❌ BLOCKED: No active task');
|
|
66
|
+
console.error('═'.repeat(70));
|
|
67
|
+
console.error('\nYou MUST have an active task before making code changes.');
|
|
68
|
+
console.error('\nTo start a task:');
|
|
69
|
+
console.error(' npx agentic15 task next');
|
|
70
|
+
console.error('\nThis will:');
|
|
71
|
+
console.error(' 1. Show you the next pending task');
|
|
72
|
+
console.error(' 2. Create a feature branch');
|
|
73
|
+
console.error(' 3. Create a GitHub issue');
|
|
74
|
+
console.error(' 4. Mark the task as active');
|
|
75
|
+
console.error('\nThen you can make your changes.');
|
|
76
|
+
console.error('\n' + '═'.repeat(70) + '\n');
|
|
77
|
+
process.exit(1);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Active task exists - allow the operation
|
|
82
|
+
process.exit(0);
|
|
83
|
+
|
|
84
|
+
} catch (error) {
|
|
85
|
+
// If we can't parse or check, fail safe and allow
|
|
86
|
+
// (don't want to block legitimate work due to hook errors)
|
|
87
|
+
process.exit(0);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
@@ -34,7 +34,6 @@
|
|
|
34
34
|
"Edit(./.claude/settings.json)",
|
|
35
35
|
"Edit(./.claude/hooks/**)",
|
|
36
36
|
"Write(./.claude/hooks/**)",
|
|
37
|
-
"Edit(./.claude/CLAUDE.md)",
|
|
38
37
|
"Edit(./.claude/TASK-TRACKER.json)",
|
|
39
38
|
"Read(./.claude/POST-INSTALL.md)",
|
|
40
39
|
"Read(./docs/**)",
|
|
@@ -150,11 +149,7 @@
|
|
|
150
149
|
"hooks": [
|
|
151
150
|
{
|
|
152
151
|
"type": "command",
|
|
153
|
-
"command": "node
|
|
154
|
-
},
|
|
155
|
-
{
|
|
156
|
-
"type": "command",
|
|
157
|
-
"command": "node node_modules/.agentic15-claude-zen/hooks/detect-pending-reviews.js"
|
|
152
|
+
"command": "node .claude/hooks/session-start-context.js"
|
|
158
153
|
}
|
|
159
154
|
]
|
|
160
155
|
}
|
|
@@ -174,19 +169,7 @@
|
|
|
174
169
|
"hooks": [
|
|
175
170
|
{
|
|
176
171
|
"type": "command",
|
|
177
|
-
"command": "node
|
|
178
|
-
},
|
|
179
|
-
{
|
|
180
|
-
"type": "command",
|
|
181
|
-
"command": "node node_modules/.agentic15-claude-zen/hooks/prevent-read-bypass.js"
|
|
182
|
-
},
|
|
183
|
-
{
|
|
184
|
-
"type": "command",
|
|
185
|
-
"command": "node node_modules/.agentic15-claude-zen/hooks/enforce-structured-development.js"
|
|
186
|
-
},
|
|
187
|
-
{
|
|
188
|
-
"type": "command",
|
|
189
|
-
"command": "node node_modules/.agentic15-claude-zen/hooks/enforce-plan-template.js"
|
|
172
|
+
"command": "node .claude/hooks/enforce-plan-template.js"
|
|
190
173
|
}
|
|
191
174
|
]
|
|
192
175
|
},
|
|
@@ -195,87 +178,18 @@
|
|
|
195
178
|
"hooks": [
|
|
196
179
|
{
|
|
197
180
|
"type": "command",
|
|
198
|
-
"command": "node
|
|
199
|
-
},
|
|
200
|
-
{
|
|
201
|
-
"type": "command",
|
|
202
|
-
"command": "node node_modules/.agentic15-claude-zen/hooks/validate-task-completion.js"
|
|
181
|
+
"command": "node .claude/hooks/validate-git-workflow.js"
|
|
203
182
|
}
|
|
204
183
|
]
|
|
205
184
|
}
|
|
206
185
|
],
|
|
207
186
|
"PostToolUse": [
|
|
208
187
|
{
|
|
209
|
-
"matcher": "
|
|
188
|
+
"matcher": "Bash(git:*)",
|
|
210
189
|
"hooks": [
|
|
211
190
|
{
|
|
212
191
|
"type": "command",
|
|
213
|
-
"command": "node
|
|
214
|
-
},
|
|
215
|
-
{
|
|
216
|
-
"type": "command",
|
|
217
|
-
"command": "node node_modules/.agentic15-claude-zen/hooks/auto-format.js"
|
|
218
|
-
},
|
|
219
|
-
{
|
|
220
|
-
"type": "command",
|
|
221
|
-
"command": "node node_modules/.agentic15-claude-zen/hooks/validate-ui-syntax.js"
|
|
222
|
-
},
|
|
223
|
-
{
|
|
224
|
-
"type": "command",
|
|
225
|
-
"command": "node node_modules/.agentic15-claude-zen/hooks/validate-ui-runtime.js"
|
|
226
|
-
},
|
|
227
|
-
{
|
|
228
|
-
"type": "command",
|
|
229
|
-
"command": "node node_modules/.agentic15-claude-zen/hooks/validate-ui-visual-native.js"
|
|
230
|
-
},
|
|
231
|
-
{
|
|
232
|
-
"type": "command",
|
|
233
|
-
"command": "node node_modules/.agentic15-claude-zen/hooks/validate-component-contract.js"
|
|
234
|
-
},
|
|
235
|
-
{
|
|
236
|
-
"type": "command",
|
|
237
|
-
"command": "node node_modules/.agentic15-claude-zen/hooks/validate-test-quality.js"
|
|
238
|
-
},
|
|
239
|
-
{
|
|
240
|
-
"type": "command",
|
|
241
|
-
"command": "node node_modules/.agentic15-claude-zen/hooks/validate-ui-integration.js"
|
|
242
|
-
},
|
|
243
|
-
{
|
|
244
|
-
"type": "command",
|
|
245
|
-
"command": "node node_modules/.agentic15-claude-zen/hooks/validate-integration-site.js"
|
|
246
|
-
},
|
|
247
|
-
{
|
|
248
|
-
"type": "command",
|
|
249
|
-
"command": "node node_modules/.agentic15-claude-zen/hooks/validate-database-changes.js"
|
|
250
|
-
},
|
|
251
|
-
{
|
|
252
|
-
"type": "command",
|
|
253
|
-
"command": "node node_modules/.agentic15-claude-zen/hooks/validate-migration-impact.js"
|
|
254
|
-
},
|
|
255
|
-
{
|
|
256
|
-
"type": "command",
|
|
257
|
-
"command": "node node_modules/.agentic15-claude-zen/hooks/validate-visual-regression.js"
|
|
258
|
-
}
|
|
259
|
-
]
|
|
260
|
-
},
|
|
261
|
-
{
|
|
262
|
-
"matcher": "Bash",
|
|
263
|
-
"hooks": [
|
|
264
|
-
{
|
|
265
|
-
"type": "command",
|
|
266
|
-
"command": "node node_modules/.agentic15-claude-zen/hooks/validate-test-results.js"
|
|
267
|
-
},
|
|
268
|
-
{
|
|
269
|
-
"type": "command",
|
|
270
|
-
"command": "node node_modules/.agentic15-claude-zen/hooks/validate-e2e-coverage.js"
|
|
271
|
-
},
|
|
272
|
-
{
|
|
273
|
-
"type": "command",
|
|
274
|
-
"command": "node node_modules/.agentic15-claude-zen/hooks/enforce-test-pyramid.js"
|
|
275
|
-
},
|
|
276
|
-
{
|
|
277
|
-
"type": "command",
|
|
278
|
-
"command": "node node_modules/.agentic15-claude-zen/hooks/enforce-migration-workflow.js"
|
|
192
|
+
"command": "node .claude/hooks/post-merge.js"
|
|
279
193
|
}
|
|
280
194
|
]
|
|
281
195
|
}
|
package/templates/package.json
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "{{PROJECT_NAME}}",
|
|
3
|
-
"version": "1.0.0",
|
|
4
|
-
"description": "Project with Claude Code structured development framework",
|
|
5
|
-
"type": "commonjs",
|
|
6
|
-
"scripts": {
|
|
7
|
-
"test": "jest --passWithNoTests"
|
|
8
|
-
},
|
|
9
|
-
"keywords": [
|
|
10
|
-
"claude-code",
|
|
11
|
-
"structured-development",
|
|
12
|
-
"task-tracking"
|
|
13
|
-
],
|
|
14
|
-
"license": "MIT",
|
|
15
|
-
"dependencies": {
|
|
16
|
-
"@agentic15.com/agentic15-claude-zen": "^2.0.0"
|
|
17
|
-
},
|
|
18
|
-
"devDependencies": {
|
|
19
|
-
"jest": "^30.2.0",
|
|
20
|
-
"@testing-library/react": "^16.1.0",
|
|
21
|
-
"@testing-library/jest-dom": "^6.6.3",
|
|
22
|
-
"@testing-library/user-event": "^14.5.2",
|
|
23
|
-
"@babel/preset-env": "^7.26.0",
|
|
24
|
-
"@babel/preset-react": "^7.26.3",
|
|
25
|
-
"babel-jest": "^30.0.0",
|
|
26
|
-
"jest-environment-jsdom": "^30.0.0",
|
|
27
|
-
"prop-types": "^15.8.1",
|
|
28
|
-
"identity-obj-proxy": "^3.0.0",
|
|
29
|
-
"@playwright/test": "^1.41.0"
|
|
30
|
-
}
|
|
31
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "{{PROJECT_NAME}}",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Project with Claude Code structured development framework",
|
|
5
|
+
"type": "commonjs",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "jest --passWithNoTests"
|
|
8
|
+
},
|
|
9
|
+
"keywords": [
|
|
10
|
+
"claude-code",
|
|
11
|
+
"structured-development",
|
|
12
|
+
"task-tracking"
|
|
13
|
+
],
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"@agentic15.com/agentic15-claude-zen": "^2.0.0"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"jest": "^30.2.0",
|
|
20
|
+
"@testing-library/react": "^16.1.0",
|
|
21
|
+
"@testing-library/jest-dom": "^6.6.3",
|
|
22
|
+
"@testing-library/user-event": "^14.5.2",
|
|
23
|
+
"@babel/preset-env": "^7.26.0",
|
|
24
|
+
"@babel/preset-react": "^7.26.3",
|
|
25
|
+
"babel-jest": "^30.0.0",
|
|
26
|
+
"jest-environment-jsdom": "^30.0.0",
|
|
27
|
+
"prop-types": "^15.8.1",
|
|
28
|
+
"identity-obj-proxy": "^3.0.0",
|
|
29
|
+
"@playwright/test": "^1.41.0"
|
|
30
|
+
}
|
|
31
|
+
}
|