gl-life-claude-zen 1.0.3 → 1.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/CHANGELOG.md +213 -0
- package/README.md +165 -0
- package/dist/hooks/auto-format.js +1 -1
- package/dist/hooks/complete-task.js +1 -1
- package/dist/hooks/enforce-migration-workflow.js +1 -1
- package/dist/hooks/enforce-structured-development.js +1 -1
- package/dist/hooks/enforce-test-pyramid.js +1 -1
- package/dist/hooks/init-task-tracker.js +1 -1
- package/dist/hooks/start-task.js +1 -1
- package/dist/hooks/task-status.js +1 -1
- package/dist/hooks/validate-database-changes.js +1 -1
- package/dist/hooks/validate-e2e-coverage.js +1 -1
- package/dist/hooks/validate-git-workflow.js +1 -1
- package/dist/hooks/validate-integration-site.js +2 -0
- package/dist/hooks/validate-migration-impact.js +1 -1
- package/dist/hooks/validate-task-completion.js +1 -1
- package/dist/hooks/validate-test-quality.js +1 -1
- package/dist/hooks/validate-test-results.js +1 -1
- package/dist/hooks/validate-ui-integration.js +1 -1
- package/dist/scripts/help.js +1 -1
- package/dist/scripts/plan-amend.js +1 -1
- package/dist/scripts/plan-create.js +1 -1
- package/dist/scripts/plan-help.js +1 -1
- package/dist/scripts/plan-init.js +1 -1
- package/dist/scripts/plan-manager.js +1 -1
- package/dist/scripts/setup-git-hooks.js +1 -1
- package/dist/scripts/task-done.js +1 -1
- package/dist/scripts/task-merge.js +1 -1
- package/dist/scripts/task-next.js +1 -1
- package/dist/scripts/task-start.js +1 -1
- package/dist/scripts/task-status.js +1 -1
- package/lib/init.js +9 -1
- package/package.json +6 -2
- package/templates/.claude/CLAUDE.md +196 -0
- package/templates/.claude/settings.json +40 -0
- package/templates/test-site/README.md +271 -0
- package/templates/test-site/index.html +13 -0
- package/templates/test-site/package.json +25 -0
- package/templates/test-site/server.js +125 -0
- package/templates/test-site/src/App.css +130 -0
- package/templates/test-site/src/App.jsx +78 -0
- package/templates/test-site/src/index.css +39 -0
- package/templates/test-site/src/main.jsx +10 -0
- package/templates/test-site/vite.config.js +12 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "integration-test-site",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"description": "Integration test website for stakeholder validation of UI components",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"dev": "node server.js",
|
|
9
|
+
"dev:simple": "vite",
|
|
10
|
+
"build": "vite build",
|
|
11
|
+
"preview": "vite preview",
|
|
12
|
+
"deploy": "npm run build && npx gh-pages -d dist"
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"react": "^18.2.0",
|
|
16
|
+
"react-dom": "^18.2.0"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@types/react": "^18.2.43",
|
|
20
|
+
"@types/react-dom": "^18.2.17",
|
|
21
|
+
"@vitejs/plugin-react": "^4.2.1",
|
|
22
|
+
"gh-pages": "^6.1.1",
|
|
23
|
+
"vite": "^5.0.8"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Test site development server with port management
|
|
5
|
+
*
|
|
6
|
+
* Features:
|
|
7
|
+
* - Uses PortManager for fixed port allocation (3000-3009 range)
|
|
8
|
+
* - Auto-cleanup of stale processes on restart
|
|
9
|
+
* - Port reuse for consistent URLs
|
|
10
|
+
* - Graceful shutdown handling
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { spawn } from 'child_process';
|
|
14
|
+
import { fileURLToPath } from 'url';
|
|
15
|
+
import { dirname, join } from 'path';
|
|
16
|
+
import { readFileSync, existsSync } from 'fs';
|
|
17
|
+
|
|
18
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
19
|
+
const __dirname = dirname(__filename);
|
|
20
|
+
|
|
21
|
+
// Try to load PortManager from parent project
|
|
22
|
+
let PortManager;
|
|
23
|
+
try {
|
|
24
|
+
// Check if running from installed package
|
|
25
|
+
const parentPackagePath = join(__dirname, '../../node_modules/.gl-life-claude/utils/port-manager.js');
|
|
26
|
+
if (existsSync(parentPackagePath)) {
|
|
27
|
+
const module = await import(parentPackagePath);
|
|
28
|
+
PortManager = module.PortManager;
|
|
29
|
+
} else {
|
|
30
|
+
// Fallback: Check workspace root
|
|
31
|
+
const workspacePackagePath = join(__dirname, '../../../utils/port-manager.js');
|
|
32
|
+
if (existsSync(workspacePackagePath)) {
|
|
33
|
+
const module = await import(workspacePackagePath);
|
|
34
|
+
PortManager = module.PortManager;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
} catch (err) {
|
|
38
|
+
console.warn('⚠️ Port manager not available, using default port 3000');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Start Vite dev server with port management
|
|
43
|
+
*/
|
|
44
|
+
async function startServer() {
|
|
45
|
+
let port = 3000;
|
|
46
|
+
let portManager = null;
|
|
47
|
+
|
|
48
|
+
if (PortManager) {
|
|
49
|
+
try {
|
|
50
|
+
portManager = new PortManager();
|
|
51
|
+
|
|
52
|
+
// Allocate port for test-site
|
|
53
|
+
const allocation = await portManager.allocate('test-site-dev', {
|
|
54
|
+
service: 'vite',
|
|
55
|
+
range: [3000, 3009],
|
|
56
|
+
autoCleanup: true
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
port = allocation.port;
|
|
60
|
+
console.log(`✓ Port ${port} allocated for test-site`);
|
|
61
|
+
|
|
62
|
+
} catch (err) {
|
|
63
|
+
console.warn(`⚠️ Port allocation failed: ${err.message}`);
|
|
64
|
+
console.warn(' Using default port 3000');
|
|
65
|
+
port = 3000;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Start Vite server
|
|
70
|
+
console.log(`🚀 Starting Vite dev server on port ${port}...`);
|
|
71
|
+
|
|
72
|
+
const vite = spawn('npx', ['vite', '--port', port.toString(), '--host'], {
|
|
73
|
+
stdio: 'inherit',
|
|
74
|
+
shell: true,
|
|
75
|
+
cwd: __dirname
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// Graceful shutdown
|
|
79
|
+
const cleanup = async () => {
|
|
80
|
+
console.log('\n🛑 Shutting down server...');
|
|
81
|
+
|
|
82
|
+
if (vite && !vite.killed) {
|
|
83
|
+
vite.kill('SIGTERM');
|
|
84
|
+
|
|
85
|
+
// Force kill after 5 seconds
|
|
86
|
+
setTimeout(() => {
|
|
87
|
+
if (!vite.killed) {
|
|
88
|
+
vite.kill('SIGKILL');
|
|
89
|
+
}
|
|
90
|
+
}, 5000);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (portManager) {
|
|
94
|
+
try {
|
|
95
|
+
await portManager.release('test-site-dev');
|
|
96
|
+
console.log('✓ Port released');
|
|
97
|
+
} catch (err) {
|
|
98
|
+
// Ignore release errors on shutdown
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
process.exit(0);
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
process.on('SIGINT', cleanup);
|
|
106
|
+
process.on('SIGTERM', cleanup);
|
|
107
|
+
|
|
108
|
+
vite.on('error', (err) => {
|
|
109
|
+
console.error('❌ Server error:', err.message);
|
|
110
|
+
cleanup();
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
vite.on('exit', (code) => {
|
|
114
|
+
if (code !== 0 && code !== null) {
|
|
115
|
+
console.error(`❌ Server exited with code ${code}`);
|
|
116
|
+
}
|
|
117
|
+
cleanup();
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Run server
|
|
122
|
+
startServer().catch(err => {
|
|
123
|
+
console.error('❌ Failed to start server:', err.message);
|
|
124
|
+
process.exit(1);
|
|
125
|
+
});
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
.app {
|
|
2
|
+
max-width: 1280px;
|
|
3
|
+
margin: 0 auto;
|
|
4
|
+
padding: 2rem;
|
|
5
|
+
min-height: 100vh;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.app-header {
|
|
9
|
+
margin-bottom: 3rem;
|
|
10
|
+
text-align: center;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.app-header h1 {
|
|
14
|
+
font-size: 3em;
|
|
15
|
+
line-height: 1.1;
|
|
16
|
+
margin-bottom: 0.5rem;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.app-header p {
|
|
20
|
+
font-size: 1.2em;
|
|
21
|
+
color: #888;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.app-main {
|
|
25
|
+
text-align: left;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.demo-section,
|
|
29
|
+
.instructions,
|
|
30
|
+
.component-list {
|
|
31
|
+
margin-bottom: 3rem;
|
|
32
|
+
padding: 2rem;
|
|
33
|
+
border: 1px solid #ccc;
|
|
34
|
+
border-radius: 8px;
|
|
35
|
+
background: rgba(255, 255, 255, 0.05);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.demo-section h2,
|
|
39
|
+
.instructions h2,
|
|
40
|
+
.component-list h2 {
|
|
41
|
+
margin-top: 0;
|
|
42
|
+
font-size: 1.8em;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.demo-description {
|
|
46
|
+
color: #888;
|
|
47
|
+
margin-bottom: 2rem;
|
|
48
|
+
line-height: 1.6;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.component-placeholder {
|
|
52
|
+
padding: 3rem;
|
|
53
|
+
border: 2px dashed #646cff;
|
|
54
|
+
border-radius: 8px;
|
|
55
|
+
text-align: center;
|
|
56
|
+
background: rgba(100, 108, 255, 0.05);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.component-placeholder p {
|
|
60
|
+
font-size: 1.2em;
|
|
61
|
+
margin-bottom: 1rem;
|
|
62
|
+
color: #888;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.component-placeholder code {
|
|
66
|
+
background: rgba(0, 0, 0, 0.2);
|
|
67
|
+
padding: 0.5rem 1rem;
|
|
68
|
+
border-radius: 4px;
|
|
69
|
+
display: inline-block;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.result-display {
|
|
73
|
+
margin-top: 2rem;
|
|
74
|
+
padding: 1.5rem;
|
|
75
|
+
background: rgba(100, 108, 255, 0.1);
|
|
76
|
+
border-radius: 8px;
|
|
77
|
+
border-left: 4px solid #646cff;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.result-display h3 {
|
|
81
|
+
margin: 0 0 1rem 0;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.result-display pre {
|
|
85
|
+
background: rgba(0, 0, 0, 0.2);
|
|
86
|
+
padding: 1rem;
|
|
87
|
+
border-radius: 4px;
|
|
88
|
+
overflow-x: auto;
|
|
89
|
+
font-size: 0.9em;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.instructions h3 {
|
|
93
|
+
margin-top: 2rem;
|
|
94
|
+
font-size: 1.3em;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.instructions ol {
|
|
98
|
+
line-height: 2;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.instructions code {
|
|
102
|
+
background: rgba(255, 255, 255, 0.1);
|
|
103
|
+
padding: 0.2em 0.4em;
|
|
104
|
+
border-radius: 4px;
|
|
105
|
+
font-family: 'Courier New', monospace;
|
|
106
|
+
font-size: 0.9em;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.code-example {
|
|
110
|
+
background: rgba(0, 0, 0, 0.3);
|
|
111
|
+
padding: 1.5rem;
|
|
112
|
+
border-radius: 8px;
|
|
113
|
+
overflow-x: auto;
|
|
114
|
+
font-size: 0.9em;
|
|
115
|
+
line-height: 1.6;
|
|
116
|
+
margin-top: 1rem;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.component-list ul {
|
|
120
|
+
line-height: 2;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.app-footer {
|
|
124
|
+
margin-top: 4rem;
|
|
125
|
+
padding-top: 2rem;
|
|
126
|
+
border-top: 1px solid #ccc;
|
|
127
|
+
color: #888;
|
|
128
|
+
font-size: 0.9em;
|
|
129
|
+
text-align: center;
|
|
130
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { useState } from 'react'
|
|
2
|
+
import './App.css'
|
|
3
|
+
// Import your components from Agent/src here
|
|
4
|
+
// Example: import { YourComponent } from '../../Agent/src/components/YourComponent'
|
|
5
|
+
|
|
6
|
+
function App() {
|
|
7
|
+
return (
|
|
8
|
+
<div className="app">
|
|
9
|
+
<header className="app-header">
|
|
10
|
+
<h1>Integration Test Site</h1>
|
|
11
|
+
<p>Component Preview for Stakeholder Validation</p>
|
|
12
|
+
</header>
|
|
13
|
+
|
|
14
|
+
<main className="app-main">
|
|
15
|
+
<section className="demo-section">
|
|
16
|
+
<h2>Your Components Go Here</h2>
|
|
17
|
+
<p className="demo-description">
|
|
18
|
+
Import your UI components from <code>../Agent/src/components/</code> and render them below
|
|
19
|
+
for stakeholder testing and validation.
|
|
20
|
+
</p>
|
|
21
|
+
|
|
22
|
+
<div className="component-placeholder">
|
|
23
|
+
<p>👆 Replace this section with your component</p>
|
|
24
|
+
<code>{'<YourComponent prop1="value" onEvent={handleEvent} />'}</code>
|
|
25
|
+
</div>
|
|
26
|
+
</section>
|
|
27
|
+
|
|
28
|
+
<section className="instructions">
|
|
29
|
+
<h2>How to Add Your Components</h2>
|
|
30
|
+
<ol>
|
|
31
|
+
<li>Copy your component from <code>Agent/src/components/</code> to <code>test-site/src/components/</code></li>
|
|
32
|
+
<li>Import it: <code>import { YourComponent } from './components/YourComponent'</code></li>
|
|
33
|
+
<li>OR import directly: <code>import { YourComponent } from '../../Agent/src/components/YourComponent'</code></li>
|
|
34
|
+
<li>Render it in the demo section above with realistic props</li>
|
|
35
|
+
<li>Add event handlers to demonstrate interactivity</li>
|
|
36
|
+
<li>Run <code>npm run dev</code> to test locally at http://localhost:3000</li>
|
|
37
|
+
<li>Deploy with <code>npm run deploy</code> to share with stakeholders via GitHub Pages</li>
|
|
38
|
+
</ol>
|
|
39
|
+
|
|
40
|
+
<h3>Example: GitHub Auth Login Component</h3>
|
|
41
|
+
<pre className="code-example">{`// 1. Copy your login component
|
|
42
|
+
cp ../Agent/src/components/GitHubLogin.jsx src/components/
|
|
43
|
+
|
|
44
|
+
// 2. Import and use it
|
|
45
|
+
import { GitHubLogin } from './components/GitHubLogin'
|
|
46
|
+
|
|
47
|
+
function App() {
|
|
48
|
+
const handleLogin = (user) => {
|
|
49
|
+
console.log('User logged in:', user)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return (
|
|
53
|
+
<div>
|
|
54
|
+
<GitHubLogin onLogin={handleLogin} />
|
|
55
|
+
</div>
|
|
56
|
+
)
|
|
57
|
+
}`}</pre>
|
|
58
|
+
</section>
|
|
59
|
+
|
|
60
|
+
<section className="component-list">
|
|
61
|
+
<h2>Quick Start</h2>
|
|
62
|
+
<ul>
|
|
63
|
+
<li>📦 Install dependencies: <code>npm install</code></li>
|
|
64
|
+
<li>🚀 Start dev server: <code>npm run dev</code></li>
|
|
65
|
+
<li>🌍 Deploy to GitHub Pages: <code>npm run deploy</code></li>
|
|
66
|
+
<li>📝 Edit <code>src/App.jsx</code> to add your components</li>
|
|
67
|
+
</ul>
|
|
68
|
+
</section>
|
|
69
|
+
</main>
|
|
70
|
+
|
|
71
|
+
<footer className="app-footer">
|
|
72
|
+
<p>Built with Vite + React for fast hot reload</p>
|
|
73
|
+
</footer>
|
|
74
|
+
</div>
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export default App
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
|
3
|
+
line-height: 1.5;
|
|
4
|
+
font-weight: 400;
|
|
5
|
+
|
|
6
|
+
color-scheme: light dark;
|
|
7
|
+
color: rgba(255, 255, 255, 0.87);
|
|
8
|
+
background-color: #242424;
|
|
9
|
+
|
|
10
|
+
font-synthesis: none;
|
|
11
|
+
text-rendering: optimizeLegibility;
|
|
12
|
+
-webkit-font-smoothing: antialiased;
|
|
13
|
+
-moz-osx-font-smoothing: grayscale;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
* {
|
|
17
|
+
box-sizing: border-box;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
body {
|
|
21
|
+
margin: 0;
|
|
22
|
+
display: flex;
|
|
23
|
+
place-items: center;
|
|
24
|
+
min-width: 320px;
|
|
25
|
+
min-height: 100vh;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
#root {
|
|
29
|
+
width: 100%;
|
|
30
|
+
margin: 0 auto;
|
|
31
|
+
text-align: center;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@media (prefers-color-scheme: light) {
|
|
35
|
+
:root {
|
|
36
|
+
color: #213547;
|
|
37
|
+
background-color: #ffffff;
|
|
38
|
+
}
|
|
39
|
+
}
|