@theproductguy/create-mission-control 1.0.4 ā 1.0.5
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/bin/cli.js +52 -3
- package/package.json +1 -1
- package/src/template/.env.example +28 -0
- package/src/template/.github/ISSUE_TEMPLATE/bug_report.md +40 -0
- package/src/template/.github/ISSUE_TEMPLATE/feature_request.md +30 -0
- package/src/template/.github/PULL_REQUEST_TEMPLATE.md +33 -0
- package/src/template/.github/workflows/ci.yml +83 -0
- package/src/template/.husky/commit-msg +1 -0
- package/src/template/.husky/pre-commit +1 -0
- package/src/template/.prettierrc +11 -0
- package/src/template/README.md +78 -0
- package/src/template/agent-os/commands/create-constitution/create-constitution.md +89 -0
- package/src/template/agent-os/commands/research-tech/research-tech.md +93 -0
- package/src/template/agent-os/commands/shape-spec/shape-spec.md +2 -1
- package/src/template/agent-os/docs/context7.md +20 -0
- package/src/template/commitlint.config.js +25 -0
- package/src/template/control-center/backend/index.js +58 -1
- package/src/template/control-center/frontend/src/App.tsx +161 -65
- package/src/template/design-system/.gemini/hooks/ai-slop-guard.md +80 -0
- package/src/template/design-system/.gemini/hooks/on-design-complete.md +63 -0
- package/src/template/eslint.config.js +37 -0
- package/src/template/lint-staged.config.js +6 -0
- package/src/template/package.json +25 -2
- package/src/template/src/__tests__/example.test.ts +17 -0
- package/src/template/src/__tests__/setup.ts +14 -0
- package/src/template/vitest.config.ts +25 -0
package/bin/cli.js
CHANGED
|
@@ -159,13 +159,62 @@ async function init() {
|
|
|
159
159
|
|
|
160
160
|
fs.writeFileSync(appPkgPath, JSON.stringify(appPkg, null, 2));
|
|
161
161
|
|
|
162
|
+
// 4. Copy root config files
|
|
163
|
+
console.log(cyan('\n4. Setting up quality tooling...'));
|
|
164
|
+
|
|
165
|
+
const rootConfigFiles = [
|
|
166
|
+
'.gitignore',
|
|
167
|
+
'.prettierrc',
|
|
168
|
+
'.env.example',
|
|
169
|
+
'eslint.config.js',
|
|
170
|
+
'commitlint.config.js',
|
|
171
|
+
'lint-staged.config.js',
|
|
172
|
+
'vitest.config.ts',
|
|
173
|
+
'README.md'
|
|
174
|
+
];
|
|
175
|
+
|
|
176
|
+
for (const file of rootConfigFiles) {
|
|
177
|
+
const src = path.join(templateDir, file);
|
|
178
|
+
if (fs.existsSync(src)) {
|
|
179
|
+
fs.copyFileSync(src, path.join(root, file));
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Copy directories
|
|
184
|
+
const rootDirs = ['.github', '.husky', '.vscode', 'src/__tests__'];
|
|
185
|
+
for (const dir of rootDirs) {
|
|
186
|
+
const src = path.join(templateDir, dir);
|
|
187
|
+
if (fs.existsSync(src)) {
|
|
188
|
+
fs.cpSync(src, path.join(root, dir), copyOptions);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// 5. Initialize git repository
|
|
193
|
+
console.log(cyan('\n5. Initializing git repository...'));
|
|
194
|
+
try {
|
|
195
|
+
const { execSync } = await import('node:child_process');
|
|
196
|
+
execSync('git init', { cwd: root, stdio: 'inherit' });
|
|
197
|
+
execSync('git add .', { cwd: root, stdio: 'ignore' });
|
|
198
|
+
} catch (e) {
|
|
199
|
+
console.log(' (Git initialization skipped - git may not be available)');
|
|
200
|
+
}
|
|
162
201
|
|
|
163
|
-
console.log(green(`\n\
|
|
164
|
-
console.log(
|
|
202
|
+
console.log(green(`\n\nā
Agent OS Workspace created successfully! š\n`));
|
|
203
|
+
console.log(bold('What\'s included:'));
|
|
204
|
+
console.log(' ā ESLint + Prettier + Husky pre-commit hooks');
|
|
205
|
+
console.log(' ā Vitest for testing');
|
|
206
|
+
console.log(' ā GitHub Actions CI workflow');
|
|
207
|
+
console.log(' ā Impeccable design commands');
|
|
208
|
+
console.log(' ā AI Slop Guard hook');
|
|
209
|
+
console.log(`\n${bold('Next steps:')}\n`);
|
|
165
210
|
console.log(` cd ${result.projectName}`);
|
|
166
211
|
console.log(` npm install`);
|
|
167
212
|
console.log(` npm run dev\n`);
|
|
168
|
-
console.log(
|
|
213
|
+
console.log(`${bold('Recommended workflow:')}`);
|
|
214
|
+
console.log(` 1. /plan-product ā Define your product`);
|
|
215
|
+
console.log(` 2. /create-constitution ā Set project principles`);
|
|
216
|
+
console.log(` 3. /research-tech ā Research your stack`);
|
|
217
|
+
console.log(` 4. /design-tokens ā Start designing`);
|
|
169
218
|
});
|
|
170
219
|
});
|
|
171
220
|
|
package/package.json
CHANGED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# ==============================================
|
|
2
|
+
# Environment Variables
|
|
3
|
+
# ==============================================
|
|
4
|
+
# Copy this file to .env.local and fill in your values
|
|
5
|
+
# NEVER commit .env.local to version control
|
|
6
|
+
|
|
7
|
+
# ==============================================
|
|
8
|
+
# Application
|
|
9
|
+
# ==============================================
|
|
10
|
+
# VITE_APP_NAME=My App
|
|
11
|
+
# VITE_APP_URL=http://localhost:5402
|
|
12
|
+
|
|
13
|
+
# ==============================================
|
|
14
|
+
# API Configuration
|
|
15
|
+
# ==============================================
|
|
16
|
+
# VITE_API_URL=http://localhost:5403
|
|
17
|
+
|
|
18
|
+
# ==============================================
|
|
19
|
+
# Feature Flags
|
|
20
|
+
# ==============================================
|
|
21
|
+
# VITE_ENABLE_ANALYTICS=false
|
|
22
|
+
# VITE_ENABLE_DEBUG_MODE=false
|
|
23
|
+
|
|
24
|
+
# ==============================================
|
|
25
|
+
# Third-Party Services (add as needed)
|
|
26
|
+
# ==============================================
|
|
27
|
+
# VITE_SENTRY_DSN=
|
|
28
|
+
# VITE_POSTHOG_KEY=
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug Report
|
|
3
|
+
about: Report a bug to help us improve
|
|
4
|
+
title: '[BUG] '
|
|
5
|
+
labels: bug
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Bug Description
|
|
10
|
+
|
|
11
|
+
<!-- A clear and concise description of what the bug is -->
|
|
12
|
+
|
|
13
|
+
## Steps to Reproduce
|
|
14
|
+
|
|
15
|
+
1. Go to '...'
|
|
16
|
+
2. Click on '...'
|
|
17
|
+
3. Scroll down to '...'
|
|
18
|
+
4. See error
|
|
19
|
+
|
|
20
|
+
## Expected Behavior
|
|
21
|
+
|
|
22
|
+
<!-- What you expected to happen -->
|
|
23
|
+
|
|
24
|
+
## Actual Behavior
|
|
25
|
+
|
|
26
|
+
<!-- What actually happened -->
|
|
27
|
+
|
|
28
|
+
## Screenshots
|
|
29
|
+
|
|
30
|
+
<!-- If applicable, add screenshots to help explain your problem -->
|
|
31
|
+
|
|
32
|
+
## Environment
|
|
33
|
+
|
|
34
|
+
- OS: [e.g., macOS 14.0]
|
|
35
|
+
- Browser: [e.g., Chrome 120]
|
|
36
|
+
- Node version: [e.g., 20.10.0]
|
|
37
|
+
|
|
38
|
+
## Additional Context
|
|
39
|
+
|
|
40
|
+
<!-- Add any other context about the problem here -->
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Feature Request
|
|
3
|
+
about: Suggest an idea for this project
|
|
4
|
+
title: '[FEATURE] '
|
|
5
|
+
labels: enhancement
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Problem Statement
|
|
10
|
+
|
|
11
|
+
<!-- Describe the problem you're trying to solve -->
|
|
12
|
+
|
|
13
|
+
## Proposed Solution
|
|
14
|
+
|
|
15
|
+
<!-- Describe the solution you'd like -->
|
|
16
|
+
|
|
17
|
+
## Alternatives Considered
|
|
18
|
+
|
|
19
|
+
<!-- Describe any alternative solutions or features you've considered -->
|
|
20
|
+
|
|
21
|
+
## Additional Context
|
|
22
|
+
|
|
23
|
+
<!-- Add any other context, mockups, or screenshots about the feature request here -->
|
|
24
|
+
|
|
25
|
+
## Acceptance Criteria
|
|
26
|
+
|
|
27
|
+
<!-- Define what "done" looks like for this feature -->
|
|
28
|
+
- [ ] Criterion 1
|
|
29
|
+
- [ ] Criterion 2
|
|
30
|
+
- [ ] Criterion 3
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
## Description
|
|
2
|
+
|
|
3
|
+
<!-- Describe the changes in this PR -->
|
|
4
|
+
|
|
5
|
+
## Type of Change
|
|
6
|
+
|
|
7
|
+
- [ ] š Bug fix (non-breaking change which fixes an issue)
|
|
8
|
+
- [ ] ⨠New feature (non-breaking change which adds functionality)
|
|
9
|
+
- [ ] š„ Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
|
10
|
+
- [ ] š Documentation update
|
|
11
|
+
- [ ] šØ Style/UI update
|
|
12
|
+
- [ ] ā»ļø Refactor (no functional changes)
|
|
13
|
+
- [ ] š§Ŗ Test update
|
|
14
|
+
|
|
15
|
+
## Related Issues
|
|
16
|
+
|
|
17
|
+
<!-- Link to related issues: Fixes #123 -->
|
|
18
|
+
|
|
19
|
+
## Checklist
|
|
20
|
+
|
|
21
|
+
- [ ] My code follows the project's style guidelines
|
|
22
|
+
- [ ] I have performed a self-review of my code
|
|
23
|
+
- [ ] I have added tests that prove my fix is effective or that my feature works
|
|
24
|
+
- [ ] New and existing unit tests pass locally with my changes
|
|
25
|
+
- [ ] I have run `/audit` and addressed any issues
|
|
26
|
+
|
|
27
|
+
## Screenshots (if applicable)
|
|
28
|
+
|
|
29
|
+
<!-- Add screenshots to help explain your changes -->
|
|
30
|
+
|
|
31
|
+
## Additional Context
|
|
32
|
+
|
|
33
|
+
<!-- Add any other context about the PR here -->
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, develop]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main, develop]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
lint:
|
|
11
|
+
name: Lint
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
|
|
16
|
+
- name: Setup Node.js
|
|
17
|
+
uses: actions/setup-node@v4
|
|
18
|
+
with:
|
|
19
|
+
node-version: '20'
|
|
20
|
+
cache: 'npm'
|
|
21
|
+
|
|
22
|
+
- name: Install dependencies
|
|
23
|
+
run: npm ci
|
|
24
|
+
|
|
25
|
+
- name: Run ESLint
|
|
26
|
+
run: npm run lint --if-present
|
|
27
|
+
|
|
28
|
+
- name: Check formatting
|
|
29
|
+
run: npm run format:check --if-present
|
|
30
|
+
|
|
31
|
+
build:
|
|
32
|
+
name: Build
|
|
33
|
+
runs-on: ubuntu-latest
|
|
34
|
+
steps:
|
|
35
|
+
- uses: actions/checkout@v4
|
|
36
|
+
|
|
37
|
+
- name: Setup Node.js
|
|
38
|
+
uses: actions/setup-node@v4
|
|
39
|
+
with:
|
|
40
|
+
node-version: '20'
|
|
41
|
+
cache: 'npm'
|
|
42
|
+
|
|
43
|
+
- name: Install dependencies
|
|
44
|
+
run: npm ci
|
|
45
|
+
|
|
46
|
+
- name: Build
|
|
47
|
+
run: npm run build --if-present
|
|
48
|
+
|
|
49
|
+
test:
|
|
50
|
+
name: Test
|
|
51
|
+
runs-on: ubuntu-latest
|
|
52
|
+
steps:
|
|
53
|
+
- uses: actions/checkout@v4
|
|
54
|
+
|
|
55
|
+
- name: Setup Node.js
|
|
56
|
+
uses: actions/setup-node@v4
|
|
57
|
+
with:
|
|
58
|
+
node-version: '20'
|
|
59
|
+
cache: 'npm'
|
|
60
|
+
|
|
61
|
+
- name: Install dependencies
|
|
62
|
+
run: npm ci
|
|
63
|
+
|
|
64
|
+
- name: Run tests
|
|
65
|
+
run: npm test --if-present
|
|
66
|
+
|
|
67
|
+
typecheck:
|
|
68
|
+
name: Type Check
|
|
69
|
+
runs-on: ubuntu-latest
|
|
70
|
+
steps:
|
|
71
|
+
- uses: actions/checkout@v4
|
|
72
|
+
|
|
73
|
+
- name: Setup Node.js
|
|
74
|
+
uses: actions/setup-node@v4
|
|
75
|
+
with:
|
|
76
|
+
node-version: '20'
|
|
77
|
+
cache: 'npm'
|
|
78
|
+
|
|
79
|
+
- name: Install dependencies
|
|
80
|
+
run: npm ci
|
|
81
|
+
|
|
82
|
+
- name: Type check
|
|
83
|
+
run: npm run typecheck --if-present
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
npx --no -- commitlint --edit ${1}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
npx lint-staged
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# {PROJECT_NAME}
|
|
2
|
+
|
|
3
|
+
> Built with [Agent OS](https://github.com/s1dd4rth/mission-control) ā Design-driven development
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Install dependencies
|
|
9
|
+
npm install
|
|
10
|
+
|
|
11
|
+
# Start development servers
|
|
12
|
+
npm run dev
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
This will start:
|
|
16
|
+
- **Design OS:** http://localhost:5400
|
|
17
|
+
- **Mission Control:** http://localhost:5401
|
|
18
|
+
- **Application:** http://localhost:5402
|
|
19
|
+
- **API:** http://localhost:5403
|
|
20
|
+
|
|
21
|
+
## Project Structure
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
āāā agent-os/ # Product strategy & commands
|
|
25
|
+
ā āāā product/ # Mission, roadmap, tech stack
|
|
26
|
+
ā āāā commands/ # Agent OS commands
|
|
27
|
+
ā āāā specs/ # Feature specifications
|
|
28
|
+
ā āāā constitution.md # Project principles
|
|
29
|
+
ā
|
|
30
|
+
āāā design-system/ # Design OS
|
|
31
|
+
ā āāā .gemini/ # Commands, skills, hooks
|
|
32
|
+
ā āāā product/ # Synced from agent-os
|
|
33
|
+
ā āāā src/ # Design components
|
|
34
|
+
ā
|
|
35
|
+
āāā control-center/ # Mission Control dashboard
|
|
36
|
+
ā āāā frontend/ # React dashboard
|
|
37
|
+
ā āāā backend/ # API server
|
|
38
|
+
ā
|
|
39
|
+
āāā app/ # Your application
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Available Scripts
|
|
43
|
+
|
|
44
|
+
| Script | Description |
|
|
45
|
+
|--------|-------------|
|
|
46
|
+
| `npm run dev` | Start all development servers |
|
|
47
|
+
| `npm run build` | Build for production |
|
|
48
|
+
| `npm test` | Run tests |
|
|
49
|
+
| `npm run lint` | Run ESLint |
|
|
50
|
+
| `npm run format` | Format with Prettier |
|
|
51
|
+
| `npm run typecheck` | TypeScript type checking |
|
|
52
|
+
|
|
53
|
+
## Workflow
|
|
54
|
+
|
|
55
|
+
1. **Plan** ā Define mission, roadmap, and tech stack
|
|
56
|
+
2. **Design** ā Create design tokens, shell, and sections
|
|
57
|
+
3. **Specify** ā Shape detailed feature specifications
|
|
58
|
+
4. **Implement** ā Build features with TDD approach
|
|
59
|
+
|
|
60
|
+
## Quality Commands
|
|
61
|
+
|
|
62
|
+
| Command | Purpose |
|
|
63
|
+
|---------|---------|
|
|
64
|
+
| `/create-constitution` | Establish project principles |
|
|
65
|
+
| `/research-tech` | Research tech stack best practices |
|
|
66
|
+
| `/audit` | Run accessibility & quality audit |
|
|
67
|
+
| `/polish` | Final visual refinements |
|
|
68
|
+
|
|
69
|
+
## Contributing
|
|
70
|
+
|
|
71
|
+
1. Create a feature branch from `main`
|
|
72
|
+
2. Make your changes
|
|
73
|
+
3. Run `npm run lint && npm test`
|
|
74
|
+
4. Submit a pull request
|
|
75
|
+
|
|
76
|
+
## License
|
|
77
|
+
|
|
78
|
+
MIT
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# COMMAND: Create Constitution
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
Establish the project's governing principles and development guidelines that will guide all subsequent development phases. This is a one-time setup command inspired by spec-driven development.
|
|
5
|
+
|
|
6
|
+
## When to Run
|
|
7
|
+
- **Once** at the beginning of a new project
|
|
8
|
+
- After `/plan-product` but before `/design-tokens`
|
|
9
|
+
- When you want to formalize project standards
|
|
10
|
+
|
|
11
|
+
## Instructions
|
|
12
|
+
|
|
13
|
+
### Step 1: Gather Context
|
|
14
|
+
Read the following files to understand the project:
|
|
15
|
+
- `agent-os/product/mission.md` ā Product vision and goals
|
|
16
|
+
- `agent-os/product/roadmap.md` ā Planned features
|
|
17
|
+
- `agent-os/product/tech-stack.md` ā Technology choices
|
|
18
|
+
|
|
19
|
+
### Step 2: Create Constitution Document
|
|
20
|
+
Create `agent-os/constitution.md` with the following sections:
|
|
21
|
+
|
|
22
|
+
```markdown
|
|
23
|
+
# Project Constitution
|
|
24
|
+
|
|
25
|
+
## Core Principles
|
|
26
|
+
[3-5 high-level principles that guide all decisions]
|
|
27
|
+
|
|
28
|
+
## Code Quality Standards
|
|
29
|
+
- [ ] All code must pass ESLint with no errors
|
|
30
|
+
- [ ] All code must be formatted with Prettier
|
|
31
|
+
- [ ] TypeScript strict mode is enforced
|
|
32
|
+
- [ ] No `any` types without explicit justification
|
|
33
|
+
- [ ] All public APIs must have JSDoc comments
|
|
34
|
+
|
|
35
|
+
## Testing Philosophy
|
|
36
|
+
- [ ] Unit tests for all business logic
|
|
37
|
+
- [ ] Integration tests for critical user flows
|
|
38
|
+
- [ ] Minimum 80% code coverage for new features
|
|
39
|
+
- [ ] TDD approach for complex features
|
|
40
|
+
|
|
41
|
+
## UX Consistency Rules
|
|
42
|
+
- [ ] Follow the Impeccable design principles
|
|
43
|
+
- [ ] Run `/audit` before any design handoff
|
|
44
|
+
- [ ] No AI Slop patterns (see frontend-design skill)
|
|
45
|
+
- [ ] Mobile-first responsive design
|
|
46
|
+
- [ ] WCAG 2.1 AA accessibility compliance
|
|
47
|
+
|
|
48
|
+
## Performance Budgets
|
|
49
|
+
- [ ] First Contentful Paint < 1.5s
|
|
50
|
+
- [ ] Largest Contentful Paint < 2.5s
|
|
51
|
+
- [ ] Cumulative Layout Shift < 0.1
|
|
52
|
+
- [ ] Bundle size < 200KB (gzipped)
|
|
53
|
+
|
|
54
|
+
## Security Requirements
|
|
55
|
+
- [ ] No secrets in code
|
|
56
|
+
- [ ] Input validation on all user inputs
|
|
57
|
+
- [ ] HTTPS only in production
|
|
58
|
+
- [ ] CSP headers configured
|
|
59
|
+
|
|
60
|
+
## Git Workflow
|
|
61
|
+
- [ ] Conventional commits required
|
|
62
|
+
- [ ] PR reviews required before merge
|
|
63
|
+
- [ ] Feature branches from `main`
|
|
64
|
+
- [ ] Squash merge to maintain clean history
|
|
65
|
+
|
|
66
|
+
## Definition of Done
|
|
67
|
+
A feature is considered "done" when:
|
|
68
|
+
1. [ ] Code is written and reviewed
|
|
69
|
+
2. [ ] Tests are passing (unit + integration)
|
|
70
|
+
3. [ ] Documentation is updated
|
|
71
|
+
4. [ ] Accessibility audit passes
|
|
72
|
+
5. [ ] Performance budget is met
|
|
73
|
+
6. [ ] `/audit` passes with no critical issues
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Step 3: Customize for Project
|
|
77
|
+
Based on the product mission and tech stack, customize:
|
|
78
|
+
- Add project-specific principles
|
|
79
|
+
- Adjust performance budgets if needed
|
|
80
|
+
- Add any domain-specific requirements
|
|
81
|
+
|
|
82
|
+
### Step 4: Verification
|
|
83
|
+
- Confirm `agent-os/constitution.md` exists
|
|
84
|
+
- Output message: "Constitution created! These principles will guide all subsequent development. Run `/research-tech` next to analyze your tech stack."
|
|
85
|
+
|
|
86
|
+
## Notes
|
|
87
|
+
- The constitution should be a living document
|
|
88
|
+
- Team members should review and commit to these principles
|
|
89
|
+
- Reference this document in code reviews
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# COMMAND: Research Tech Stack
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
Research and document best practices, current versions, and known gotchas for the technologies chosen in `tech-stack.md`. This ensures the implementation uses up-to-date patterns and avoids common pitfalls.
|
|
5
|
+
|
|
6
|
+
## When to Run
|
|
7
|
+
- After `/plan-product` has created `tech-stack.md`
|
|
8
|
+
- Before `/design-tokens` or implementation begins
|
|
9
|
+
- When updating to new versions of key dependencies
|
|
10
|
+
|
|
11
|
+
## Instructions
|
|
12
|
+
|
|
13
|
+
### Step 1: Read Tech Stack
|
|
14
|
+
Read `agent-os/product/tech-stack.md` to understand the chosen technologies.
|
|
15
|
+
|
|
16
|
+
### Step 2: Analyze Technologies
|
|
17
|
+
For each tech choice, answer:
|
|
18
|
+
- **Why this choice?** (Pros/Cons)
|
|
19
|
+
- **Latest Version?** (Use Context7 to check latest docs/features if possible)
|
|
20
|
+
- **Alternatives considered?**
|
|
21
|
+
|
|
22
|
+
> **Tip:** If you have Context7 configured, use it to fetch the latest documentation for accurate analysis.
|
|
23
|
+
> Prompt: "Using Context7, what are the latest best practices for [Technology]?"
|
|
24
|
+
|
|
25
|
+
For each major technology in the stack, research:
|
|
26
|
+
|
|
27
|
+
1. **Current stable version** ā What version should we pin to?
|
|
28
|
+
2. **Breaking changes** ā Any recent breaking changes to be aware of?
|
|
29
|
+
3. **Best practices** ā What are the current recommended patterns?
|
|
30
|
+
4. **Common pitfalls** ā What mistakes do developers commonly make?
|
|
31
|
+
5. **Performance tips** ā Any optimization opportunities?
|
|
32
|
+
|
|
33
|
+
### Step 3: Create Research Document
|
|
34
|
+
Create `agent-os/research.md` with the following structure:
|
|
35
|
+
|
|
36
|
+
```markdown
|
|
37
|
+
# Technology Research
|
|
38
|
+
|
|
39
|
+
**Generated:** [Date]
|
|
40
|
+
**Tech Stack:** [List from tech-stack.md]
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## [Technology Name]
|
|
45
|
+
|
|
46
|
+
### Version
|
|
47
|
+
- **Recommended:** [version]
|
|
48
|
+
- **Latest Stable:** [version]
|
|
49
|
+
- **Our Choice:** [version + justification]
|
|
50
|
+
|
|
51
|
+
### Key Features to Use
|
|
52
|
+
- [Feature 1]
|
|
53
|
+
- [Feature 2]
|
|
54
|
+
|
|
55
|
+
### Patterns to Follow
|
|
56
|
+
- [Pattern 1 with code example]
|
|
57
|
+
- [Pattern 2 with code example]
|
|
58
|
+
|
|
59
|
+
### Pitfalls to Avoid
|
|
60
|
+
- ā ļø [Pitfall 1 and how to avoid]
|
|
61
|
+
- ā ļø [Pitfall 2 and how to avoid]
|
|
62
|
+
|
|
63
|
+
### Performance Considerations
|
|
64
|
+
- [Tip 1]
|
|
65
|
+
- [Tip 2]
|
|
66
|
+
|
|
67
|
+
### Resources
|
|
68
|
+
- [Official docs link]
|
|
69
|
+
- [Helpful article link]
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
[Repeat for each technology]
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Step 4: Identify Integration Concerns
|
|
77
|
+
Document any concerns where technologies interact:
|
|
78
|
+
- State management + React patterns
|
|
79
|
+
- CSS framework + component library conflicts
|
|
80
|
+
- Build tool configuration needs
|
|
81
|
+
|
|
82
|
+
### Step 5: Create Version Lock File
|
|
83
|
+
Update `package.json` with pinned versions based on research.
|
|
84
|
+
|
|
85
|
+
### Step 6: Verification
|
|
86
|
+
- Confirm `agent-os/research.md` exists
|
|
87
|
+
- Ensure all major technologies are covered
|
|
88
|
+
- Output message: "Tech research complete! Review the findings in `agent-os/research.md`. Run `/design-tokens` next to begin designing."
|
|
89
|
+
|
|
90
|
+
## Notes
|
|
91
|
+
- Research should be done even for familiar technologies
|
|
92
|
+
- Check for security advisories on dependencies
|
|
93
|
+
- Consider LTS vs. latest tradeoffs
|
|
@@ -11,7 +11,8 @@ Create the technical specification (`spec.md`) for a specific product section.
|
|
|
11
11
|
|
|
12
12
|
### Step 1: Analyze Context
|
|
13
13
|
- Read `design-system/product/product-roadmap.md` to understand where this section fits.
|
|
14
|
-
- Read `design-system/product/product-overview.md` to understand the
|
|
14
|
+
- Read `design-system/product/product-overview.md` to understand the data model and core flows.
|
|
15
|
+
- Read `design-system/design-tokens.md` and `design-system/app-shell.md` to understand the design language and layout constraints.
|
|
15
16
|
|
|
16
17
|
### Step 2: Create Spec File
|
|
17
18
|
Create `design-system/product/sections/[section-id]/spec.md`.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Context7 Integration
|
|
2
|
+
|
|
3
|
+
Context7 (context7.com) provides up-to-date documentation and code examples for your tech stack, ensuring your agent uses the latest APIs and best practices.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
1. **Get API Key**: Go to [context7.com](https://context7.com) and get your API key.
|
|
8
|
+
2. **Configure Agent**:
|
|
9
|
+
* **Cursor/Windsurf**: Add Context7 as an MCP server.
|
|
10
|
+
* Server URL: `https://context7.com/api/mcp` (or as per their specific MCP setup instructions)
|
|
11
|
+
* Env: `CONTEXT7_API_KEY=your_key`
|
|
12
|
+
* **Manual**: Just tell the agent "Use Context7 to look up documentation for [library]" if you have the proper system prompt or tool configured.
|
|
13
|
+
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
When running `/research-tech` or implementation commands, the agent will look for Context7 tools.
|
|
17
|
+
|
|
18
|
+
### Example Prompts
|
|
19
|
+
- "Using Context7, interpret the latest docs for Next.js App Router."
|
|
20
|
+
- "Check Context7 for `shadcn/ui` installation steps."
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
extends: ['@commitlint/config-conventional'],
|
|
3
|
+
rules: {
|
|
4
|
+
'type-enum': [
|
|
5
|
+
2,
|
|
6
|
+
'always',
|
|
7
|
+
[
|
|
8
|
+
'feat', // New feature
|
|
9
|
+
'fix', // Bug fix
|
|
10
|
+
'docs', // Documentation
|
|
11
|
+
'style', // Formatting, missing semicolons, etc.
|
|
12
|
+
'refactor', // Code restructuring without changing behavior
|
|
13
|
+
'perf', // Performance improvements
|
|
14
|
+
'test', // Adding or updating tests
|
|
15
|
+
'build', // Build system or dependencies
|
|
16
|
+
'ci', // CI configuration
|
|
17
|
+
'chore', // Maintenance tasks
|
|
18
|
+
'revert', // Reverting changes
|
|
19
|
+
],
|
|
20
|
+
],
|
|
21
|
+
'subject-case': [2, 'always', 'lower-case'],
|
|
22
|
+
'subject-empty': [2, 'never'],
|
|
23
|
+
'type-empty': [2, 'never'],
|
|
24
|
+
},
|
|
25
|
+
}
|
|
@@ -136,6 +136,53 @@ app.get('/api/status', async (req, res) => {
|
|
|
136
136
|
const hasTokens = fs.existsSync(path.join(designDir, 'product/design-system/colors.json'));
|
|
137
137
|
const hasShell = fs.existsSync(path.join(designDir, 'product/shell/spec.md'));
|
|
138
138
|
|
|
139
|
+
// Implementation tracking
|
|
140
|
+
const appDir = path.join(PROJECT_ROOT, 'app');
|
|
141
|
+
const hasScaffold = fs.existsSync(path.join(APP_DIR, 'src/lib/utils.ts'));
|
|
142
|
+
|
|
143
|
+
// Check for test files
|
|
144
|
+
const testFiles = glob.sync('**/*.{test,spec}.{ts,tsx,js,jsx}', { cwd: appDir, ignore: ['node_modules/**'] });
|
|
145
|
+
const hasTests = testFiles.length > 0;
|
|
146
|
+
|
|
147
|
+
// Check for coverage report
|
|
148
|
+
const coverageDir = path.join(PROJECT_ROOT, 'coverage');
|
|
149
|
+
const coverageSummary = path.join(coverageDir, 'coverage-summary.json');
|
|
150
|
+
let coveragePercent = null;
|
|
151
|
+
if (fs.existsSync(coverageSummary)) {
|
|
152
|
+
try {
|
|
153
|
+
const coverage = JSON.parse(fs.readFileSync(coverageSummary, 'utf-8'));
|
|
154
|
+
if (coverage.total && coverage.total.lines) {
|
|
155
|
+
coveragePercent = Math.round(coverage.total.lines.pct);
|
|
156
|
+
}
|
|
157
|
+
} catch (e) {
|
|
158
|
+
// Ignore parsing errors
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Check git status
|
|
163
|
+
let gitInfo = { initialized: false, branch: null, uncommitted: 0, lastCommit: null };
|
|
164
|
+
const gitDir = path.join(PROJECT_ROOT, '.git');
|
|
165
|
+
if (fs.existsSync(gitDir)) {
|
|
166
|
+
gitInfo.initialized = true;
|
|
167
|
+
try {
|
|
168
|
+
const { execSync } = require('child_process');
|
|
169
|
+
gitInfo.branch = execSync('git rev-parse --abbrev-ref HEAD', { cwd: PROJECT_ROOT, encoding: 'utf-8' }).trim();
|
|
170
|
+
const status = execSync('git status --porcelain', { cwd: PROJECT_ROOT, encoding: 'utf-8' });
|
|
171
|
+
gitInfo.uncommitted = status.split('\n').filter(l => l.trim()).length;
|
|
172
|
+
try {
|
|
173
|
+
gitInfo.lastCommit = execSync('git log -1 --pretty=format:"%s"', { cwd: PROJECT_ROOT, encoding: 'utf-8' }).trim();
|
|
174
|
+
} catch (e) {
|
|
175
|
+
// No commits yet
|
|
176
|
+
}
|
|
177
|
+
} catch (e) {
|
|
178
|
+
// Git commands failed
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Check for linked specs
|
|
183
|
+
const specsWithTasks = specs.filter(s => s.tasks.exists && s.tasks.total > 0);
|
|
184
|
+
const specsCompleted = specs.filter(s => s.tasks.exists && s.tasks.completed === s.tasks.total && s.tasks.total > 0);
|
|
185
|
+
|
|
139
186
|
res.json({
|
|
140
187
|
product: productFiles,
|
|
141
188
|
services,
|
|
@@ -155,7 +202,17 @@ app.get('/api/status', async (req, res) => {
|
|
|
155
202
|
}
|
|
156
203
|
},
|
|
157
204
|
implementation: {
|
|
158
|
-
scaffolded:
|
|
205
|
+
scaffolded: hasScaffold,
|
|
206
|
+
tests: {
|
|
207
|
+
count: testFiles.length,
|
|
208
|
+
hasTests
|
|
209
|
+
},
|
|
210
|
+
coverage: coveragePercent,
|
|
211
|
+
specs: {
|
|
212
|
+
total: specsWithTasks.length,
|
|
213
|
+
completed: specsCompleted.length
|
|
214
|
+
},
|
|
215
|
+
git: gitInfo
|
|
159
216
|
},
|
|
160
217
|
specs,
|
|
161
218
|
projectRoot: PROJECT_ROOT
|
|
@@ -46,6 +46,21 @@ interface ProjectState {
|
|
|
46
46
|
};
|
|
47
47
|
implementation: {
|
|
48
48
|
scaffolded: boolean;
|
|
49
|
+
tests?: {
|
|
50
|
+
count: number;
|
|
51
|
+
hasTests: boolean;
|
|
52
|
+
};
|
|
53
|
+
coverage?: number | null;
|
|
54
|
+
specs?: {
|
|
55
|
+
total: number;
|
|
56
|
+
completed: number;
|
|
57
|
+
};
|
|
58
|
+
git?: {
|
|
59
|
+
initialized: boolean;
|
|
60
|
+
branch: string | null;
|
|
61
|
+
uncommitted: number;
|
|
62
|
+
lastCommit: string | null;
|
|
63
|
+
};
|
|
49
64
|
};
|
|
50
65
|
specs: Spec[];
|
|
51
66
|
services?: {
|
|
@@ -701,77 +716,14 @@ function App() {
|
|
|
701
716
|
</div>
|
|
702
717
|
</section>
|
|
703
718
|
|
|
704
|
-
{/* Phase 3:
|
|
705
|
-
<section className="bg-card border border-border rounded-xl p-5 shadow-sm h-full flex flex-col transition-all hover:shadow-md hover:border-border/80">
|
|
706
|
-
<div className="flex items-center gap-3 mb-5 pb-4 border-b border-border/50">
|
|
707
|
-
<div className="p-2 bg-sidebar-primary/10 text-sidebar-primary rounded-lg">
|
|
708
|
-
<Package size={20} />
|
|
709
|
-
</div>
|
|
710
|
-
<h2 className="text-lg font-semibold">3. Implementation</h2>
|
|
711
|
-
</div>
|
|
712
|
-
|
|
713
|
-
<div className="space-y-4 flex-1">
|
|
714
|
-
<div className="flex items-center justify-between p-3 bg-secondary/30 rounded-lg border border-border/50">
|
|
715
|
-
<span className="text-foreground font-medium text-sm flex items-center gap-2"><Layout size={16} className="text-muted-foreground" /> Scaffold</span>
|
|
716
|
-
{state?.implementation?.scaffolded ? (
|
|
717
|
-
<span className="text-emerald-600 bg-emerald-50 dark:bg-emerald-900/20 px-2 py-0.5 rounded text-xs font-medium border border-emerald-200 dark:border-emerald-800">Done</span>
|
|
718
|
-
) : (
|
|
719
|
-
<span className="text-muted-foreground bg-secondary px-2 py-0.5 rounded text-xs font-medium border border-border">Pending</span>
|
|
720
|
-
)}
|
|
721
|
-
</div>
|
|
722
|
-
</div>
|
|
723
|
-
|
|
724
|
-
<div className="mt-6">
|
|
725
|
-
{!state?.implementation?.scaffolded ? (
|
|
726
|
-
<PromptButton
|
|
727
|
-
label="Scaffold App"
|
|
728
|
-
prompt="Antigravity, scaffold the implementation. Read 'agent-os/commands/scaffold-implementation/scaffold-implementation.md'."
|
|
729
|
-
onClick={copyToClipboard}
|
|
730
|
-
/>
|
|
731
|
-
) : (
|
|
732
|
-
<div className="p-3 bg-secondary/30 rounded-lg border border-border/50 text-sm text-muted-foreground text-center italic mb-4">
|
|
733
|
-
App scaffolded. Ready for implementation.
|
|
734
|
-
</div>
|
|
735
|
-
)}
|
|
736
|
-
|
|
737
|
-
{state?.implementation?.scaffolded && state?.design?.exportPrompts?.oneShot && (
|
|
738
|
-
<div className="pt-3 border-t border-border/50">
|
|
739
|
-
<p className="text-xs text-muted-foreground mb-2 font-medium">Implementation Options:</p>
|
|
740
|
-
<div className="space-y-2">
|
|
741
|
-
<PromptButton
|
|
742
|
-
label="Option A: One-Shot (All)"
|
|
743
|
-
prompt={`Antigravity, implement the app. Read 'product-plan/prompts/one-shot-prompt.md'.`}
|
|
744
|
-
onClick={copyToClipboard}
|
|
745
|
-
small
|
|
746
|
-
primary
|
|
747
|
-
/>
|
|
748
|
-
{state?.design?.exportPrompts?.section && (
|
|
749
|
-
<div className="relative">
|
|
750
|
-
<PromptButton
|
|
751
|
-
label="Option B: Incremental (Section)"
|
|
752
|
-
prompt={`Antigravity, implement a section. Read 'product-plan/prompts/section-prompt.md'.`}
|
|
753
|
-
onClick={copyToClipboard}
|
|
754
|
-
small
|
|
755
|
-
/>
|
|
756
|
-
<p className="text-[10px] text-muted-foreground mt-1.5 text-center leading-tight">
|
|
757
|
-
Build feature-by-feature using the <strong>Feature Specs</strong> list →
|
|
758
|
-
</p>
|
|
759
|
-
</div>
|
|
760
|
-
)}
|
|
761
|
-
</div>
|
|
762
|
-
</div>
|
|
763
|
-
)}
|
|
764
|
-
</div>
|
|
765
|
-
</section>
|
|
766
|
-
|
|
767
|
-
{/* Phase 4: Specs & Implementation */}
|
|
719
|
+
{/* Phase 3: Feature Specs */}
|
|
768
720
|
<section className="bg-card border border-border rounded-xl p-5 shadow-sm col-span-1 md:col-span-2 lg:col-span-1 h-full flex flex-col transition-all hover:shadow-md hover:border-border/80">
|
|
769
721
|
<div className="flex items-center justify-between mb-5 pb-4 border-b border-border/50">
|
|
770
722
|
<div className="flex items-center gap-3">
|
|
771
723
|
<div className="p-2 bg-sidebar-primary/10 text-sidebar-primary rounded-lg">
|
|
772
724
|
<Code size={20} />
|
|
773
725
|
</div>
|
|
774
|
-
<h2 className="text-lg font-semibold">
|
|
726
|
+
<h2 className="text-lg font-semibold">3. Feature Specs</h2>
|
|
775
727
|
</div>
|
|
776
728
|
<button className="text-xs bg-secondary hover:bg-secondary/80 border border-border px-3 py-2 rounded-md flex items-center gap-1.5 font-medium transition cursor-pointer"
|
|
777
729
|
onClick={() => setCreatingSpec(true)}>
|
|
@@ -780,6 +732,24 @@ function App() {
|
|
|
780
732
|
</div>
|
|
781
733
|
|
|
782
734
|
<div className="space-y-3 flex-1 overflow-y-auto max-h-[300px] pr-1">
|
|
735
|
+
{/* Auto-generate from Roadmap after Design Export */}
|
|
736
|
+
{(state?.product?.roadmap?.items?.filter(item =>
|
|
737
|
+
!item.completed &&
|
|
738
|
+
!state?.product?.roadmap?.isBoilerplate
|
|
739
|
+
) ?? []).length > 0 && !state?.specs?.length && (
|
|
740
|
+
<div className="bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 p-4 rounded-lg mb-3">
|
|
741
|
+
<p className="text-sm text-blue-700 dark:text-blue-300 mb-2">
|
|
742
|
+
Ready to generate specs from roadmap items?
|
|
743
|
+
</p>
|
|
744
|
+
<PromptButton
|
|
745
|
+
label="Generate All Specs"
|
|
746
|
+
prompt={`Antigravity, generate feature specs from the roadmap items. For each item in 'agent-os/product/roadmap.md' that is not yet completed, create a spec folder in 'agent-os/specs/[feature-name]/' with spec.md and tasks.md files. Context: 1. Read 'product-plan/product-overview.md' for data model/flows. 2. Read 'design-system/design-tokens.md' and 'design-system/app-shell.md' for UI/UX constraints. 3. Use the shape-spec command: Read 'agent-os/commands/shape-spec/shape-spec.md'.`}
|
|
747
|
+
onClick={copyToClipboard}
|
|
748
|
+
small
|
|
749
|
+
primary
|
|
750
|
+
/>
|
|
751
|
+
</div>
|
|
752
|
+
)}
|
|
783
753
|
{state?.specs?.map(spec => (
|
|
784
754
|
<div key={spec.name} className="bg-secondary/20 p-4 rounded-lg border border-border/50 hover:border-border transition-colors group relative">
|
|
785
755
|
<button
|
|
@@ -867,6 +837,132 @@ function App() {
|
|
|
867
837
|
</div>
|
|
868
838
|
</section>
|
|
869
839
|
|
|
840
|
+
{/* Phase 4: Implementation */}
|
|
841
|
+
<section className="bg-card border border-border rounded-xl p-5 shadow-sm h-full flex flex-col transition-all hover:shadow-md hover:border-border/80">
|
|
842
|
+
<div className="flex items-center gap-3 mb-5 pb-4 border-b border-border/50">
|
|
843
|
+
<div className="p-2 bg-sidebar-primary/10 text-sidebar-primary rounded-lg">
|
|
844
|
+
<Package size={20} />
|
|
845
|
+
</div>
|
|
846
|
+
<h2 className="text-lg font-semibold">4. Implementation</h2>
|
|
847
|
+
</div>
|
|
848
|
+
|
|
849
|
+
<div className="space-y-3 flex-1">
|
|
850
|
+
{/* Scaffold Status */}
|
|
851
|
+
<div className="flex items-center justify-between p-3 bg-secondary/30 rounded-lg border border-border/50">
|
|
852
|
+
<span className="text-foreground font-medium text-sm flex items-center gap-2"><Layout size={16} className="text-muted-foreground" /> Scaffold</span>
|
|
853
|
+
{state?.implementation?.scaffolded ? (
|
|
854
|
+
<span className="text-emerald-600 bg-emerald-50 dark:bg-emerald-900/20 px-2 py-0.5 rounded text-xs font-medium border border-emerald-200 dark:border-emerald-800">Done</span>
|
|
855
|
+
) : (
|
|
856
|
+
<span className="text-muted-foreground bg-secondary px-2 py-0.5 rounded text-xs font-medium border border-border">Pending</span>
|
|
857
|
+
)}
|
|
858
|
+
</div>
|
|
859
|
+
|
|
860
|
+
{/* Git Status */}
|
|
861
|
+
{state?.implementation?.git?.initialized && (
|
|
862
|
+
<div className="flex items-center justify-between p-3 bg-secondary/30 rounded-lg border border-border/50">
|
|
863
|
+
<span className="text-foreground font-medium text-sm flex items-center gap-2">
|
|
864
|
+
<svg className="w-4 h-4 text-muted-foreground" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z" /></svg>
|
|
865
|
+
{state.implementation.git.branch || 'main'}
|
|
866
|
+
</span>
|
|
867
|
+
<div className="flex items-center gap-2">
|
|
868
|
+
{state.implementation.git.uncommitted > 0 && (
|
|
869
|
+
<span className="text-amber-600 bg-amber-50 dark:bg-amber-900/20 px-2 py-0.5 rounded text-xs font-medium border border-amber-200 dark:border-amber-800">
|
|
870
|
+
{state.implementation.git.uncommitted} uncommitted
|
|
871
|
+
</span>
|
|
872
|
+
)}
|
|
873
|
+
{state.implementation.git.uncommitted === 0 && (
|
|
874
|
+
<span className="text-emerald-600 bg-emerald-50 dark:bg-emerald-900/20 px-2 py-0.5 rounded text-xs font-medium border border-emerald-200 dark:border-emerald-800">Clean</span>
|
|
875
|
+
)}
|
|
876
|
+
</div>
|
|
877
|
+
</div>
|
|
878
|
+
)}
|
|
879
|
+
|
|
880
|
+
{/* Tests & Coverage */}
|
|
881
|
+
{state?.implementation?.scaffolded && (
|
|
882
|
+
<div className="flex items-center justify-between p-3 bg-secondary/30 rounded-lg border border-border/50">
|
|
883
|
+
<span className="text-foreground font-medium text-sm flex items-center gap-2">
|
|
884
|
+
<CheckSquare size={16} className="text-muted-foreground" /> Tests
|
|
885
|
+
</span>
|
|
886
|
+
<div className="flex items-center gap-2">
|
|
887
|
+
{state?.implementation?.tests?.hasTests ? (
|
|
888
|
+
<span className="text-emerald-600 bg-emerald-50 dark:bg-emerald-900/20 px-2 py-0.5 rounded text-xs font-medium border border-emerald-200 dark:border-emerald-800">
|
|
889
|
+
{state.implementation.tests.count} files
|
|
890
|
+
</span>
|
|
891
|
+
) : (
|
|
892
|
+
<span className="text-muted-foreground bg-secondary px-2 py-0.5 rounded text-xs font-medium border border-border">No tests</span>
|
|
893
|
+
)}
|
|
894
|
+
{state?.implementation?.coverage !== null && state?.implementation?.coverage !== undefined && (
|
|
895
|
+
<span className={`px-2 py-0.5 rounded text-xs font-medium border ${state.implementation.coverage >= 80
|
|
896
|
+
? 'text-emerald-600 bg-emerald-50 dark:bg-emerald-900/20 border-emerald-200 dark:border-emerald-800'
|
|
897
|
+
: state.implementation.coverage >= 50
|
|
898
|
+
? 'text-amber-600 bg-amber-50 dark:bg-amber-900/20 border-amber-200 dark:border-amber-800'
|
|
899
|
+
: 'text-red-600 bg-red-50 dark:bg-red-900/20 border-red-200 dark:border-red-800'
|
|
900
|
+
}`}>
|
|
901
|
+
{state.implementation.coverage}% coverage
|
|
902
|
+
</span>
|
|
903
|
+
)}
|
|
904
|
+
</div>
|
|
905
|
+
</div>
|
|
906
|
+
)}
|
|
907
|
+
|
|
908
|
+
{/* Spec Progress */}
|
|
909
|
+
{state?.implementation?.specs && state.implementation.specs.total > 0 && (
|
|
910
|
+
<div className="flex items-center justify-between p-3 bg-secondary/30 rounded-lg border border-border/50">
|
|
911
|
+
<span className="text-foreground font-medium text-sm flex items-center gap-2">
|
|
912
|
+
<FileText size={16} className="text-muted-foreground" /> Specs
|
|
913
|
+
</span>
|
|
914
|
+
<span className={`px-2 py-0.5 rounded text-xs font-medium border ${state.implementation.specs.completed === state.implementation.specs.total
|
|
915
|
+
? 'text-emerald-600 bg-emerald-50 dark:bg-emerald-900/20 border-emerald-200 dark:border-emerald-800'
|
|
916
|
+
: 'text-blue-600 bg-blue-50 dark:bg-blue-900/20 border-blue-200 dark:border-blue-800'
|
|
917
|
+
}`}>
|
|
918
|
+
{state.implementation.specs.completed}/{state.implementation.specs.total} complete
|
|
919
|
+
</span>
|
|
920
|
+
</div>
|
|
921
|
+
)}
|
|
922
|
+
</div>
|
|
923
|
+
|
|
924
|
+
<div className="mt-6">
|
|
925
|
+
{!state?.implementation?.scaffolded ? (
|
|
926
|
+
<PromptButton
|
|
927
|
+
label="Scaffold App"
|
|
928
|
+
prompt="Antigravity, scaffold the implementation. Read 'agent-os/commands/scaffold-implementation/scaffold-implementation.md'."
|
|
929
|
+
onClick={copyToClipboard}
|
|
930
|
+
/>
|
|
931
|
+
) : (
|
|
932
|
+
<div className="p-3 bg-secondary/30 rounded-lg border border-border/50 text-sm text-muted-foreground text-center italic mb-4">
|
|
933
|
+
App scaffolded. Ready for implementation.
|
|
934
|
+
</div>
|
|
935
|
+
)}
|
|
936
|
+
|
|
937
|
+
{state?.implementation?.scaffolded && state?.design?.exportPrompts?.oneShot && (
|
|
938
|
+
<div className="pt-3 border-t border-border/50">
|
|
939
|
+
<p className="text-xs text-muted-foreground mb-2 font-medium">Implementation Options:</p>
|
|
940
|
+
<div className="space-y-2">
|
|
941
|
+
<PromptButton
|
|
942
|
+
label="Option A: One-Shot (All)"
|
|
943
|
+
prompt={`Antigravity, implement the app. Read 'product-plan/prompts/one-shot-prompt.md'. If Context7 is configured, use it to verify library documentation.`}
|
|
944
|
+
onClick={copyToClipboard}
|
|
945
|
+
small
|
|
946
|
+
primary
|
|
947
|
+
/>
|
|
948
|
+
{state?.design?.exportPrompts?.section && (
|
|
949
|
+
<div className="relative">
|
|
950
|
+
<PromptButton
|
|
951
|
+
label="Option B: Incremental (Section)"
|
|
952
|
+
prompt={`Antigravity, implement a section. Read 'product-plan/prompts/section-prompt.md'. Use Context7 for latest docs if available.`}
|
|
953
|
+
onClick={copyToClipboard}
|
|
954
|
+
small
|
|
955
|
+
/>
|
|
956
|
+
<p className="text-[10px] text-muted-foreground mt-1.5 text-center leading-tight">
|
|
957
|
+
Build by spec from <strong>Feature Specs</strong> ←
|
|
958
|
+
</p>
|
|
959
|
+
</div>
|
|
960
|
+
)}
|
|
961
|
+
</div>
|
|
962
|
+
</div>
|
|
963
|
+
)}
|
|
964
|
+
</div>
|
|
965
|
+
</section>
|
|
870
966
|
|
|
871
967
|
</main>
|
|
872
968
|
</div>
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Hook: AI Slop Guard
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
Warn when code or design patterns that indicate generic AI-generated output are detected.
|
|
5
|
+
|
|
6
|
+
## Trigger
|
|
7
|
+
- PreToolUse: Before writing to CSS/TSX/HTML files
|
|
8
|
+
- PreCommit: Before committing changes
|
|
9
|
+
|
|
10
|
+
## Patterns to Watch For
|
|
11
|
+
|
|
12
|
+
### Typography Slop
|
|
13
|
+
- ā ļø `font-family: 'Inter'` ā Generic AI default font
|
|
14
|
+
- ā ļø `font-family: 'Roboto'` ā Overused AI choice
|
|
15
|
+
- ā ļø `font-family: 'Open Sans'` ā Too common
|
|
16
|
+
- ā ļø `font-family: 'Poppins'` ā AI favorite
|
|
17
|
+
|
|
18
|
+
### Color Slop
|
|
19
|
+
- ā ļø `#808080` or `gray` ā Dead gray
|
|
20
|
+
- ā ļø `#cccccc`, `#dddddd` ā Lifeless neutral
|
|
21
|
+
- ā ļø `#f5f5f5` ā The AI background color
|
|
22
|
+
- ā ļø Pure `#000000` or `#ffffff` ā No warmth
|
|
23
|
+
- ā ļø `#3b82f6` or `#2563eb` ā Everyone's blue
|
|
24
|
+
|
|
25
|
+
### Layout Slop
|
|
26
|
+
- ā ļø Cards in cards ā Nested containers
|
|
27
|
+
- ā ļø Hero with centered h1 + subtitle + CTA ā The AI template
|
|
28
|
+
- ā ļø 3-column feature grid ā Overused pattern
|
|
29
|
+
- ā ļø Centered everything ā Lazy alignment
|
|
30
|
+
|
|
31
|
+
### Effect Slop
|
|
32
|
+
- ā ļø `backdrop-filter: blur(10px)` ā Glassmorphism default
|
|
33
|
+
- ā ļø `border-radius: 12px` ā The AI corner radius
|
|
34
|
+
- ā ļø `box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1)` ā Tailwind default
|
|
35
|
+
|
|
36
|
+
### Animation Slop
|
|
37
|
+
- ā ļø `transition: all` ā Lazy animation
|
|
38
|
+
- ā ļø `animate-bounce` ā Generic micro-interaction
|
|
39
|
+
- ā ļø `animate-pulse` ā Loading skeleton overuse
|
|
40
|
+
|
|
41
|
+
### Copy Slop
|
|
42
|
+
- ā ļø "Streamline your workflow" ā Generic SaaS copy
|
|
43
|
+
- ā ļø "Unlock the power of" ā AI clichĆ©
|
|
44
|
+
- ā ļø "Seamlessly integrate" ā Meaningless buzzword
|
|
45
|
+
- ā ļø "Best-in-class" ā Tells nothing
|
|
46
|
+
|
|
47
|
+
## Response When Detected
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
ā ļø AI Slop Guard Warning
|
|
51
|
+
|
|
52
|
+
Detected potentially generic AI patterns:
|
|
53
|
+
- [Pattern name]: [File:Line]
|
|
54
|
+
|
|
55
|
+
Consider:
|
|
56
|
+
1. Running `/audit` to get specific recommendations
|
|
57
|
+
2. Consulting the frontend-design skill for alternatives
|
|
58
|
+
3. Using `/bolder` if design is too safe
|
|
59
|
+
|
|
60
|
+
Continue anyway? [y/N]
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Configuration
|
|
64
|
+
Users can customize in `.gemini/settings.json`:
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"hooks": {
|
|
68
|
+
"ai-slop-guard": {
|
|
69
|
+
"enabled": true,
|
|
70
|
+
"strictness": "medium", // low, medium, high
|
|
71
|
+
"ignore": ["Inter"] // Patterns to ignore
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Notes
|
|
78
|
+
- This is a warning, not a blocker
|
|
79
|
+
- Some patterns are acceptable in context
|
|
80
|
+
- The goal is awareness, not restriction
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Hook: On Design Complete
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
Automatically run quality checks when a design phase is completed.
|
|
5
|
+
|
|
6
|
+
## Trigger
|
|
7
|
+
After completing:
|
|
8
|
+
- `/design-tokens`
|
|
9
|
+
- `/design-shell`
|
|
10
|
+
- `/design-screen`
|
|
11
|
+
|
|
12
|
+
## Actions
|
|
13
|
+
|
|
14
|
+
### 1. Run Auto-Audit
|
|
15
|
+
Execute a mini-audit focusing on the just-completed work:
|
|
16
|
+
|
|
17
|
+
**After `/design-tokens`:**
|
|
18
|
+
- Check for AI slop fonts
|
|
19
|
+
- Verify color hierarchy exists
|
|
20
|
+
- Ensure contrast ratios meet WCAG AA
|
|
21
|
+
- Validate color format consistency
|
|
22
|
+
|
|
23
|
+
**After `/design-shell`:**
|
|
24
|
+
- Check for AI slop layout patterns
|
|
25
|
+
- Verify touch targets (44x44 minimum)
|
|
26
|
+
- Check spacing consistency
|
|
27
|
+
- Validate responsive breakpoints
|
|
28
|
+
|
|
29
|
+
**After `/design-screen`:**
|
|
30
|
+
- Full component audit
|
|
31
|
+
- Accessibility check
|
|
32
|
+
- Performance impact assessment
|
|
33
|
+
|
|
34
|
+
### 2. Generate Report
|
|
35
|
+
Save audit results to `design-system/QA/[phase]-audit.md`
|
|
36
|
+
|
|
37
|
+
### 3. Suggest Next Steps
|
|
38
|
+
Based on audit results:
|
|
39
|
+
- If issues found: Suggest specific fix commands
|
|
40
|
+
- If clean: Suggest next phase
|
|
41
|
+
|
|
42
|
+
## Output Format
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
ā
Design phase completed!
|
|
46
|
+
|
|
47
|
+
Auto-audit results:
|
|
48
|
+
āāā Accessibility: ā Pass
|
|
49
|
+
āāā Typography: ā ļø 1 warning (consider font alternatives)
|
|
50
|
+
āāā Colors: ā Pass
|
|
51
|
+
āāā Layout: ā Pass
|
|
52
|
+
|
|
53
|
+
Suggestions:
|
|
54
|
+
- Run `/critique` for UX evaluation
|
|
55
|
+
- Continue to `/design-shell` when ready
|
|
56
|
+
|
|
57
|
+
Full report: design-system/QA/tokens-audit.md
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Notes
|
|
61
|
+
- This hook runs automatically, no user action needed
|
|
62
|
+
- Reports accumulate, so you can see progress over time
|
|
63
|
+
- Hook can be disabled in settings if desired
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import js from '@eslint/js'
|
|
2
|
+
import globals from 'globals'
|
|
3
|
+
import reactHooks from 'eslint-plugin-react-hooks'
|
|
4
|
+
import reactRefresh from 'eslint-plugin-react-refresh'
|
|
5
|
+
import tseslint from 'typescript-eslint'
|
|
6
|
+
|
|
7
|
+
export default tseslint.config(
|
|
8
|
+
{ ignores: ['dist', 'node_modules', 'coverage', '.next', 'build'] },
|
|
9
|
+
{
|
|
10
|
+
extends: [js.configs.recommended, ...tseslint.configs.recommended],
|
|
11
|
+
files: ['**/*.{ts,tsx}'],
|
|
12
|
+
languageOptions: {
|
|
13
|
+
ecmaVersion: 2020,
|
|
14
|
+
globals: globals.browser,
|
|
15
|
+
},
|
|
16
|
+
plugins: {
|
|
17
|
+
'react-hooks': reactHooks,
|
|
18
|
+
'react-refresh': reactRefresh,
|
|
19
|
+
},
|
|
20
|
+
rules: {
|
|
21
|
+
...reactHooks.configs.recommended.rules,
|
|
22
|
+
'react-refresh/only-export-components': [
|
|
23
|
+
'warn',
|
|
24
|
+
{ allowConstantExport: true },
|
|
25
|
+
],
|
|
26
|
+
// Strict TypeScript rules
|
|
27
|
+
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
|
|
28
|
+
'@typescript-eslint/no-explicit-any': 'warn',
|
|
29
|
+
'@typescript-eslint/explicit-function-return-type': 'off',
|
|
30
|
+
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
|
31
|
+
// Best practices
|
|
32
|
+
'no-console': ['warn', { allow: ['warn', 'error'] }],
|
|
33
|
+
'prefer-const': 'error',
|
|
34
|
+
'no-var': 'error',
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
)
|
|
@@ -19,9 +19,32 @@
|
|
|
19
19
|
"start:control": "cd control-center/frontend && npm run dev -- --port 5401",
|
|
20
20
|
"start:app": "cd app && npm run dev -- --port 5402",
|
|
21
21
|
"build": "npm run build --workspaces",
|
|
22
|
-
"test": "
|
|
22
|
+
"test": "vitest run",
|
|
23
|
+
"test:watch": "vitest",
|
|
24
|
+
"test:coverage": "vitest run --coverage",
|
|
25
|
+
"lint": "eslint . --ext .ts,.tsx,.js,.jsx",
|
|
26
|
+
"lint:fix": "eslint . --ext .ts,.tsx,.js,.jsx --fix",
|
|
27
|
+
"format": "prettier --write .",
|
|
28
|
+
"format:check": "prettier --check .",
|
|
29
|
+
"typecheck": "tsc --noEmit",
|
|
30
|
+
"prepare": "husky"
|
|
23
31
|
},
|
|
24
32
|
"devDependencies": {
|
|
25
|
-
"
|
|
33
|
+
"@commitlint/cli": "^19.0.0",
|
|
34
|
+
"@commitlint/config-conventional": "^19.0.0",
|
|
35
|
+
"@eslint/js": "^9.0.0",
|
|
36
|
+
"@types/node": "^20.11.0",
|
|
37
|
+
"@vitest/coverage-v8": "^2.0.0",
|
|
38
|
+
"concurrently": "^8.2.2",
|
|
39
|
+
"eslint": "^9.0.0",
|
|
40
|
+
"eslint-plugin-react-hooks": "^5.0.0",
|
|
41
|
+
"eslint-plugin-react-refresh": "^0.4.0",
|
|
42
|
+
"globals": "^15.0.0",
|
|
43
|
+
"husky": "^9.0.0",
|
|
44
|
+
"lint-staged": "^15.0.0",
|
|
45
|
+
"prettier": "^3.2.0",
|
|
46
|
+
"prettier-plugin-tailwindcss": "^0.6.0",
|
|
47
|
+
"typescript-eslint": "^8.0.0",
|
|
48
|
+
"vitest": "^2.0.0"
|
|
26
49
|
}
|
|
27
50
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
|
+
|
|
3
|
+
describe('Example Test Suite', () => {
|
|
4
|
+
it('should pass a basic test', () => {
|
|
5
|
+
expect(1 + 1).toBe(2)
|
|
6
|
+
})
|
|
7
|
+
|
|
8
|
+
it('should handle strings', () => {
|
|
9
|
+
expect('hello world').toContain('world')
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
it('should handle arrays', () => {
|
|
13
|
+
const items = [1, 2, 3]
|
|
14
|
+
expect(items).toHaveLength(3)
|
|
15
|
+
expect(items).toContain(2)
|
|
16
|
+
})
|
|
17
|
+
})
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import '@testing-library/jest-dom/vitest'
|
|
2
|
+
|
|
3
|
+
// Global test setup
|
|
4
|
+
beforeAll(() => {
|
|
5
|
+
// Setup code that runs before all tests
|
|
6
|
+
})
|
|
7
|
+
|
|
8
|
+
afterEach(() => {
|
|
9
|
+
// Cleanup after each test
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
afterAll(() => {
|
|
13
|
+
// Cleanup code that runs after all tests
|
|
14
|
+
})
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { defineConfig } from 'vitest/config'
|
|
2
|
+
import react from '@vitejs/plugin-react'
|
|
3
|
+
import { resolve } from 'path'
|
|
4
|
+
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
plugins: [react()],
|
|
7
|
+
test: {
|
|
8
|
+
globals: true,
|
|
9
|
+
environment: 'jsdom',
|
|
10
|
+
setupFiles: ['./src/__tests__/setup.ts'],
|
|
11
|
+
include: ['**/*.{test,spec}.{ts,tsx}'],
|
|
12
|
+
coverage: {
|
|
13
|
+
reporter: ['text', 'json', 'html'],
|
|
14
|
+
exclude: [
|
|
15
|
+
'node_modules/',
|
|
16
|
+
'src/__tests__/setup.ts',
|
|
17
|
+
],
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
resolve: {
|
|
21
|
+
alias: {
|
|
22
|
+
'@': resolve(__dirname, './src'),
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
})
|