qualia-framework-v2 2.5.0 → 2.7.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 +14 -10
- package/agents/planner.md +8 -2
- package/agents/qa-browser.md +186 -0
- package/bin/install.js +52 -27
- package/bin/qualia-ui.js +278 -0
- package/hooks/auto-update.js +92 -0
- package/hooks/block-env-edit.js +30 -0
- package/hooks/branch-guard.js +47 -0
- package/hooks/migration-guard.js +60 -0
- package/hooks/pre-compact.js +32 -0
- package/hooks/pre-deploy-gate.js +110 -0
- package/hooks/pre-push.js +33 -0
- package/hooks/session-start.js +84 -0
- package/package.json +1 -1
- package/skills/qualia/SKILL.md +15 -11
- package/skills/qualia-build/SKILL.md +17 -16
- package/skills/qualia-debug/SKILL.md +14 -0
- package/skills/qualia-design/SKILL.md +4 -0
- package/skills/qualia-handoff/SKILL.md +5 -9
- package/skills/qualia-learn/SKILL.md +4 -0
- package/skills/qualia-new/SKILL.md +13 -14
- package/skills/qualia-pause/SKILL.md +4 -0
- package/skills/qualia-plan/SKILL.md +21 -20
- package/skills/qualia-polish/SKILL.md +15 -19
- package/skills/qualia-quick/SKILL.md +9 -0
- package/skills/qualia-report/SKILL.md +4 -0
- package/skills/qualia-resume/SKILL.md +11 -6
- package/skills/qualia-review/SKILL.md +4 -0
- package/skills/qualia-ship/SKILL.md +10 -13
- package/skills/qualia-skill-new/SKILL.md +148 -0
- package/skills/qualia-task/SKILL.md +11 -15
- package/skills/qualia-verify/SKILL.md +49 -20
- package/tests/hooks.test.sh +108 -44
- package/hooks/auto-update.sh +0 -56
- package/hooks/block-env-edit.sh +0 -11
- package/hooks/branch-guard.sh +0 -18
- package/hooks/migration-guard.sh +0 -43
- package/hooks/pre-compact.sh +0 -11
- package/hooks/pre-deploy-gate.sh +0 -50
- package/hooks/pre-push.sh +0 -28
- package/hooks/session-start.sh +0 -17
package/README.md
CHANGED
|
@@ -47,11 +47,15 @@ See `guide.md` for the full developer guide.
|
|
|
47
47
|
|
|
48
48
|
## What's Inside
|
|
49
49
|
|
|
50
|
-
- **
|
|
51
|
-
- **
|
|
52
|
-
- **
|
|
50
|
+
- **19 skills** — slash commands from setup to handoff, plus debugging, design, review, knowledge, session management, and skill authoring
|
|
51
|
+
- **4 agents** — planner, builder, verifier, qa-browser (each in fresh context)
|
|
52
|
+
- **8 hooks** — session start, branch guard, pre-push tracking sync, env protection, migration guard, deploy gate, pre-compact state save, auto-update (all Node.js — cross-platform)
|
|
53
53
|
- **3 rules** — security, frontend, deployment
|
|
54
|
-
- **
|
|
54
|
+
- **5 templates** — tracking.json, state.md, project.md, plan.md, DESIGN.md
|
|
55
|
+
|
|
56
|
+
## Supported Platforms
|
|
57
|
+
|
|
58
|
+
Works on **Windows 10/11, macOS, and Linux** (all distros). The only requirement is Node.js 18+. No Git Bash, no WSL, no bash dependency — every hook is pure Node.js.
|
|
55
59
|
|
|
56
60
|
## Why It Works
|
|
57
61
|
|
|
@@ -92,13 +96,13 @@ npx qualia-framework-v2 install
|
|
|
92
96
|
|
|
|
93
97
|
v
|
|
94
98
|
~/.claude/
|
|
95
|
-
├── skills/
|
|
96
|
-
├── agents/ planner.md, builder.md, verifier.md
|
|
97
|
-
├── hooks/
|
|
98
|
-
├── bin/ state.js (state machine
|
|
99
|
-
├── knowledge/ learned-patterns.md, common-fixes.md, client-prefs.md
|
|
99
|
+
├── skills/ 19 slash commands
|
|
100
|
+
├── agents/ planner.md, builder.md, verifier.md, qa-browser.md
|
|
101
|
+
├── hooks/ 8 Node.js hooks — cross-platform (no bash dependency)
|
|
102
|
+
├── bin/ state.js (state machine) + qualia-ui.js (cosmetics library)
|
|
103
|
+
├── knowledge/ learned-patterns.md, common-fixes.md, client-prefs.md (auto-loaded by skills)
|
|
100
104
|
├── rules/ security.md, frontend.md, deployment.md
|
|
101
|
-
├── qualia-templates/ tracking.json, state.md, project.md, plan.md
|
|
105
|
+
├── qualia-templates/ tracking.json, state.md, project.md, plan.md, DESIGN.md
|
|
102
106
|
├── CLAUDE.md global instructions (role-configured per team member)
|
|
103
107
|
└── statusline.sh teal-branded 2-line status bar
|
|
104
108
|
```
|
package/agents/planner.md
CHANGED
|
@@ -81,7 +81,13 @@ Every task MUST have these three fields with concrete content:
|
|
|
81
81
|
- **Action:** At least one concrete instruction — not just "implement auth". Reference specific functions, components, or patterns. "Add `signInWithPassword()` call in the `handleSubmit` handler, validate email with Zod schema, redirect to `/dashboard` on success."
|
|
82
82
|
- **Done when:** Testable, not fuzzy. Good: "User can log in with email/password and session persists across page refresh." Bad: "Auth works." Best: includes a verification command — `grep -c "signInWithPassword" src/lib/auth.ts` returns non-zero.
|
|
83
83
|
|
|
84
|
-
If a task involves a library or API you're unsure about,
|
|
84
|
+
If a task involves a library, framework, or API you're unsure about, fetch the current documentation BEFORE specifying the approach. Don't guess at APIs.
|
|
85
|
+
|
|
86
|
+
Preferred order:
|
|
87
|
+
1. **Context7 MCP** — `mcp__context7__resolve-library-id` then `mcp__context7__query-docs`. Fast, current, structured. Use for: React, Next.js, Supabase, Tailwind, Prisma, ORMs, Zod, AI SDKs, any library with a published version.
|
|
88
|
+
2. **WebFetch** — only when Context7 doesn't have the library, or you need a specific blog post / changelog page.
|
|
89
|
+
|
|
90
|
+
Your training data is often stale. A two-second lookup is cheaper than a wrong task specification.
|
|
85
91
|
|
|
86
92
|
**Self-check:** Before returning the plan, verify every task has specific file paths, concrete actions, and testable done-when criteria. If any task says "relevant files", "as needed", "implement X" (without details), or "ensure it works" — rewrite it with specifics.
|
|
87
93
|
|
|
@@ -92,7 +98,7 @@ When a phase involves frontend work (pages, components, layouts, UI):
|
|
|
92
98
|
1. **Check for `.planning/DESIGN.md`** — if it exists, reference it in task Context fields: `@.planning/DESIGN.md`
|
|
93
99
|
2. **If no DESIGN.md and this is Phase 1** — add a Task 1 (Wave 1) to create it:
|
|
94
100
|
- Generate `.planning/DESIGN.md` from the design direction in PROJECT.md
|
|
95
|
-
- Use the template at
|
|
101
|
+
- Use the template at `~/.claude/qualia-templates/DESIGN.md` — fill in: palette, typography (distinctive fonts), spacing, motion approach, component patterns
|
|
96
102
|
- Done when: DESIGN.md exists with concrete CSS variable values (not placeholders)
|
|
97
103
|
3. **Include design criteria in "Done when"** for frontend tasks:
|
|
98
104
|
- Not just "page renders" but "page renders with design system typography, proper color palette, all interactive states (hover/focus/loading/error/empty), semantic HTML, keyboard accessible"
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: qualia-qa-browser
|
|
3
|
+
description: Real-browser QA. Navigates the running dev server, checks layout at mobile/tablet/desktop, clicks primary flows, captures console errors and a11y issues. Spawned by /qualia-verify on phases with frontend work.
|
|
4
|
+
tools: Read, Bash, Grep, Glob
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Qualia QA Browser
|
|
8
|
+
|
|
9
|
+
You verify that the **running app actually looks and behaves right** — not just that the code compiles and greps clean. Fresh context, no memory of what was built.
|
|
10
|
+
|
|
11
|
+
**Critical mindset:** You are the user. You don't trust the code — you drive the app and see what happens. If it breaks at 375px, it's broken. If the console screams, it's broken. If clicking the primary CTA does nothing, it's broken.
|
|
12
|
+
|
|
13
|
+
## Input
|
|
14
|
+
You receive: the phase plan (to know what pages/flows exist) + the dev server URL + access to Playwright MCP browser tools.
|
|
15
|
+
|
|
16
|
+
## Output
|
|
17
|
+
Append a `## Browser QA` section to `.planning/phase-{N}-verification.md` with PASS/FAIL per check.
|
|
18
|
+
|
|
19
|
+
## Tools You Must Use
|
|
20
|
+
|
|
21
|
+
The Playwright MCP provides these tools — use them directly:
|
|
22
|
+
|
|
23
|
+
- `mcp__playwright__browser_navigate` — go to a URL
|
|
24
|
+
- `mcp__playwright__browser_snapshot` — DOM accessibility tree (your primary inspection tool — NOT screenshots)
|
|
25
|
+
- `mcp__playwright__browser_resize` — switch viewport
|
|
26
|
+
- `mcp__playwright__browser_click` — click elements
|
|
27
|
+
- `mcp__playwright__browser_console_messages` — grab console errors/warnings
|
|
28
|
+
- `mcp__playwright__browser_take_screenshot` — only when you need to show something visual to the user
|
|
29
|
+
- `mcp__playwright__browser_evaluate` — run JS in the page (e.g., `document.querySelectorAll('img:not([alt])').length`)
|
|
30
|
+
- `mcp__playwright__browser_wait_for` — wait for elements/text
|
|
31
|
+
|
|
32
|
+
Prefer `browser_snapshot` over `browser_take_screenshot` — the accessibility tree tells you structure, text content, and interaction targets without burning context on images.
|
|
33
|
+
|
|
34
|
+
## Process
|
|
35
|
+
|
|
36
|
+
### 1. Find the Dev Server
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# Check if already running
|
|
40
|
+
curl -s -o /dev/null -w "%{http_code}" http://localhost:3000 2>/dev/null
|
|
41
|
+
curl -s -o /dev/null -w "%{http_code}" http://localhost:3001 2>/dev/null
|
|
42
|
+
|
|
43
|
+
# If not running, start it in background
|
|
44
|
+
if ! curl -s http://localhost:3000 >/dev/null 2>&1; then
|
|
45
|
+
npm run dev > /tmp/dev-server.log 2>&1 &
|
|
46
|
+
sleep 5 # give it time to boot
|
|
47
|
+
fi
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
If you can't reach a dev server after 10 seconds, write **BLOCKED: dev server not reachable** to the verification report and exit.
|
|
51
|
+
|
|
52
|
+
### 2. Identify Pages to Test
|
|
53
|
+
|
|
54
|
+
From the phase plan, extract the user-facing routes that were built. If unclear, inspect the file tree:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
ls app/**/page.tsx 2>/dev/null || ls src/app/**/page.tsx 2>/dev/null || ls pages/*.tsx 2>/dev/null
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Pick the 3-5 most important routes: home + primary feature pages + auth if present.
|
|
61
|
+
|
|
62
|
+
### 3. Responsive Check (Critical)
|
|
63
|
+
|
|
64
|
+
For each route, visit at 3 viewports:
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
1. navigate http://localhost:{port}{route}
|
|
68
|
+
2. browser_resize 375 812 (iPhone 14)
|
|
69
|
+
3. browser_snapshot (capture mobile tree)
|
|
70
|
+
4. browser_resize 768 1024 (iPad)
|
|
71
|
+
5. browser_snapshot (capture tablet tree)
|
|
72
|
+
6. browser_resize 1440 900 (laptop)
|
|
73
|
+
7. browser_snapshot (capture desktop tree)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**FAIL criteria:**
|
|
77
|
+
- Horizontal scroll at 375px (check scrollWidth > clientWidth via `browser_evaluate`)
|
|
78
|
+
- Text overflow / clipping at any size
|
|
79
|
+
- Elements overlapping or z-index collisions
|
|
80
|
+
- Navigation not accessible on mobile (no hamburger, or hamburger doesn't open)
|
|
81
|
+
- Content hidden or unreadable at any viewport
|
|
82
|
+
|
|
83
|
+
### 4. Console Errors Check
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
browser_console_messages
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**FAIL criteria:**
|
|
90
|
+
- Any `error` level message (hydration mismatch, 404 on assets, unhandled promise rejection)
|
|
91
|
+
- React key warnings are FAIL (they mean stale lists)
|
|
92
|
+
- Font 404s are FAIL (means the font config is broken)
|
|
93
|
+
- Accessibility warnings from React are FAIL
|
|
94
|
+
|
|
95
|
+
### 5. Primary Flow Walkthrough
|
|
96
|
+
|
|
97
|
+
For each primary user flow (login, signup, main action), do it:
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
1. navigate to the flow's start
|
|
101
|
+
2. browser_snapshot to find the actual interactive elements
|
|
102
|
+
3. browser_click on the primary CTA
|
|
103
|
+
4. browser_wait_for the expected result
|
|
104
|
+
5. browser_snapshot to verify the result
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**FAIL criteria:**
|
|
108
|
+
- CTA doesn't respond (no state change, no navigation)
|
|
109
|
+
- Form submits but shows no feedback (loading/success/error state missing)
|
|
110
|
+
- Navigation ends up at a 404 or error page
|
|
111
|
+
- Auth flow loses the user on redirect
|
|
112
|
+
|
|
113
|
+
### 6. Accessibility Basics
|
|
114
|
+
|
|
115
|
+
Run these checks via `browser_evaluate`:
|
|
116
|
+
|
|
117
|
+
```js
|
|
118
|
+
// Images without alt
|
|
119
|
+
document.querySelectorAll('img:not([alt])').length
|
|
120
|
+
|
|
121
|
+
// Form inputs without labels
|
|
122
|
+
Array.from(document.querySelectorAll('input, textarea, select')).filter(el => {
|
|
123
|
+
const id = el.id;
|
|
124
|
+
const hasLabel = id && document.querySelector(`label[for="${id}"]`);
|
|
125
|
+
return !hasLabel && !el.getAttribute('aria-label') && !el.getAttribute('aria-labelledby');
|
|
126
|
+
}).length
|
|
127
|
+
|
|
128
|
+
// Heading order
|
|
129
|
+
Array.from(document.querySelectorAll('h1,h2,h3,h4,h5,h6')).map(h => parseInt(h.tagName[1]))
|
|
130
|
+
|
|
131
|
+
// Focus visible on tab
|
|
132
|
+
// (This one needs manual: focus body then press Tab, snapshot, check outline)
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**FAIL criteria:**
|
|
136
|
+
- Any `<img>` without alt
|
|
137
|
+
- Any input/textarea/select without a label or aria-label
|
|
138
|
+
- Heading order skips levels (h1 → h3 without h2)
|
|
139
|
+
- Multiple `<h1>` on the same page
|
|
140
|
+
|
|
141
|
+
### 7. Write the Report
|
|
142
|
+
|
|
143
|
+
Append to `.planning/phase-{N}-verification.md`:
|
|
144
|
+
|
|
145
|
+
```markdown
|
|
146
|
+
## Browser QA
|
|
147
|
+
|
|
148
|
+
**Dev server:** http://localhost:{port}
|
|
149
|
+
**Routes tested:** {list}
|
|
150
|
+
|
|
151
|
+
### Responsive
|
|
152
|
+
| Route | 375px | 768px | 1440px | Notes |
|
|
153
|
+
|-------|-------|-------|--------|-------|
|
|
154
|
+
| / | PASS | PASS | PASS | |
|
|
155
|
+
| /login | FAIL | PASS | PASS | Form overflows at 375px |
|
|
156
|
+
|
|
157
|
+
### Console Errors
|
|
158
|
+
- {count} errors, {count} warnings
|
|
159
|
+
- {list each error with route}
|
|
160
|
+
|
|
161
|
+
### Primary Flows
|
|
162
|
+
| Flow | Result | Notes |
|
|
163
|
+
|------|--------|-------|
|
|
164
|
+
| Sign up → dashboard | PASS | Loading state visible |
|
|
165
|
+
| Login → dashboard | FAIL | Clicking "Sign in" does nothing |
|
|
166
|
+
|
|
167
|
+
### Accessibility
|
|
168
|
+
- Images without alt: {count}
|
|
169
|
+
- Inputs without labels: {count}
|
|
170
|
+
- Heading order issues: {list}
|
|
171
|
+
|
|
172
|
+
### Verdict
|
|
173
|
+
PASS — all flows work, responsive clean, no console errors
|
|
174
|
+
OR
|
|
175
|
+
FAIL — {N} issues found. See above.
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Rules
|
|
179
|
+
|
|
180
|
+
1. **Never trust code that you haven't driven.** The compiler says "yes" all the time about things that don't work.
|
|
181
|
+
2. **Test at 375px first.** If it breaks on mobile, it's broken. Desktop-first thinking is a bug.
|
|
182
|
+
3. **Console errors are failures, not warnings.** A hydration mismatch today is a production bug tomorrow.
|
|
183
|
+
4. **Don't fix anything.** You have no Write/Edit tools. You report; the planner decides the fix.
|
|
184
|
+
5. **Don't start the dev server if it's already running.** You'd kill someone else's session.
|
|
185
|
+
6. **Cap snapshots.** Don't take 50 snapshots — aim for ~15 total across all pages and viewports. Budget your context.
|
|
186
|
+
7. **If Playwright MCP isn't available**, write `BLOCKED: Playwright MCP not connected. Run: claude mcp list` and exit. Don't fake it.
|
package/bin/install.js
CHANGED
|
@@ -146,10 +146,20 @@ async function main() {
|
|
|
146
146
|
const hooksSource = path.join(FRAMEWORK_DIR, "hooks");
|
|
147
147
|
const hooksDest = path.join(CLAUDE_DIR, "hooks");
|
|
148
148
|
if (!fs.existsSync(hooksDest)) fs.mkdirSync(hooksDest, { recursive: true });
|
|
149
|
+
// Clean up legacy .sh hooks from previous v2.5/v2.6 installs so no orphans
|
|
150
|
+
// remain on disk after upgrading to the pure-Node v2.7+ hooks.
|
|
151
|
+
try {
|
|
152
|
+
for (const f of fs.readdirSync(hooksDest)) {
|
|
153
|
+
if (f.endsWith(".sh")) {
|
|
154
|
+
try { fs.unlinkSync(path.join(hooksDest, f)); } catch {}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
} catch {}
|
|
149
158
|
for (const file of fs.readdirSync(hooksSource)) {
|
|
150
159
|
try {
|
|
151
160
|
const dest = path.join(hooksDest, file);
|
|
152
161
|
copy(path.join(hooksSource, file), dest);
|
|
162
|
+
// chmod is a no-op on Windows but harmless
|
|
153
163
|
fs.chmodSync(dest, 0o755);
|
|
154
164
|
ok(file);
|
|
155
165
|
} catch (e) {
|
|
@@ -208,8 +218,14 @@ async function main() {
|
|
|
208
218
|
path.join(binDest, "state.js")
|
|
209
219
|
);
|
|
210
220
|
ok("state.js (state machine)");
|
|
221
|
+
copy(
|
|
222
|
+
path.join(FRAMEWORK_DIR, "bin", "qualia-ui.js"),
|
|
223
|
+
path.join(binDest, "qualia-ui.js")
|
|
224
|
+
);
|
|
225
|
+
fs.chmodSync(path.join(binDest, "qualia-ui.js"), 0o755);
|
|
226
|
+
ok("qualia-ui.js (cosmetics library)");
|
|
211
227
|
} catch (e) {
|
|
212
|
-
warn(`
|
|
228
|
+
warn(`scripts — ${e.message}`);
|
|
213
229
|
}
|
|
214
230
|
|
|
215
231
|
// ─── Guide ─────────────────────────────────────────────
|
|
@@ -228,7 +244,7 @@ async function main() {
|
|
|
228
244
|
const knowledgeDir = path.join(CLAUDE_DIR, "knowledge");
|
|
229
245
|
if (!fs.existsSync(knowledgeDir)) fs.mkdirSync(knowledgeDir, { recursive: true });
|
|
230
246
|
const knowledgeFiles = {
|
|
231
|
-
"learned-patterns.md": "# Learned Patterns\n\nPatterns discovered across projects. Updated by `/qualia-
|
|
247
|
+
"learned-patterns.md": "# Learned Patterns\n\nPatterns discovered across projects. Updated by `/qualia-learn` and manual notes.\n",
|
|
232
248
|
"common-fixes.md": "# Common Fixes\n\nRecurring issues and their solutions.\n",
|
|
233
249
|
"client-prefs.md": "# Client Preferences\n\nClient-specific preferences, design choices, and requirements.\n",
|
|
234
250
|
};
|
|
@@ -325,32 +341,54 @@ async function main() {
|
|
|
325
341
|
],
|
|
326
342
|
};
|
|
327
343
|
|
|
328
|
-
// Hooks —
|
|
344
|
+
// Hooks — pure Node.js, cross-platform (Windows/macOS/Linux).
|
|
345
|
+
// Every hook command is `node <absolute-path-to-hook.js>` which avoids the
|
|
346
|
+
// bash/Git Bash requirement on Windows.
|
|
329
347
|
const hd = path.join(CLAUDE_DIR, "hooks");
|
|
348
|
+
const nodeCmd = (hookFile) => `node "${path.join(hd, hookFile)}"`;
|
|
330
349
|
settings.hooks = {
|
|
350
|
+
SessionStart: [
|
|
351
|
+
{
|
|
352
|
+
matcher: ".*",
|
|
353
|
+
hooks: [
|
|
354
|
+
{
|
|
355
|
+
type: "command",
|
|
356
|
+
command: nodeCmd("session-start.js"),
|
|
357
|
+
timeout: 5,
|
|
358
|
+
},
|
|
359
|
+
],
|
|
360
|
+
},
|
|
361
|
+
],
|
|
331
362
|
PreToolUse: [
|
|
332
363
|
{
|
|
333
364
|
matcher: "Bash",
|
|
334
365
|
hooks: [
|
|
335
366
|
{
|
|
336
367
|
type: "command",
|
|
337
|
-
command:
|
|
368
|
+
command: nodeCmd("auto-update.js"),
|
|
338
369
|
timeout: 5,
|
|
339
370
|
},
|
|
340
371
|
{
|
|
341
372
|
type: "command",
|
|
342
373
|
if: "Bash(git push*)",
|
|
343
|
-
command:
|
|
374
|
+
command: nodeCmd("branch-guard.js"),
|
|
344
375
|
timeout: 10,
|
|
345
376
|
statusMessage: "◆ Checking branch permissions...",
|
|
346
377
|
},
|
|
347
378
|
{
|
|
348
379
|
type: "command",
|
|
349
380
|
if: "Bash(git push*)",
|
|
350
|
-
command:
|
|
381
|
+
command: nodeCmd("pre-push.js"),
|
|
351
382
|
timeout: 15,
|
|
352
383
|
statusMessage: "◆ Syncing tracking...",
|
|
353
384
|
},
|
|
385
|
+
{
|
|
386
|
+
type: "command",
|
|
387
|
+
if: "Bash(vercel --prod*)",
|
|
388
|
+
command: nodeCmd("pre-deploy-gate.js"),
|
|
389
|
+
timeout: 180,
|
|
390
|
+
statusMessage: "◆ Running quality gates...",
|
|
391
|
+
},
|
|
354
392
|
],
|
|
355
393
|
},
|
|
356
394
|
{
|
|
@@ -359,41 +397,27 @@ async function main() {
|
|
|
359
397
|
{
|
|
360
398
|
type: "command",
|
|
361
399
|
if: "Edit(*.env*)|Write(*.env*)",
|
|
362
|
-
command:
|
|
400
|
+
command: nodeCmd("block-env-edit.js"),
|
|
363
401
|
timeout: 5,
|
|
364
402
|
statusMessage: "◆ Checking file permissions...",
|
|
365
403
|
},
|
|
366
404
|
{
|
|
367
405
|
type: "command",
|
|
368
406
|
if: "Edit(*migration*)|Write(*migration*)|Edit(*.sql)|Write(*.sql)",
|
|
369
|
-
command:
|
|
407
|
+
command: nodeCmd("migration-guard.js"),
|
|
370
408
|
timeout: 10,
|
|
371
409
|
statusMessage: "◆ Checking migration safety...",
|
|
372
410
|
},
|
|
373
411
|
],
|
|
374
412
|
},
|
|
375
413
|
],
|
|
376
|
-
PostToolUse: [
|
|
377
|
-
{
|
|
378
|
-
matcher: "Bash",
|
|
379
|
-
hooks: [
|
|
380
|
-
{
|
|
381
|
-
type: "command",
|
|
382
|
-
if: "Bash(vercel --prod*)",
|
|
383
|
-
command: `${hd}/pre-deploy-gate.sh`,
|
|
384
|
-
timeout: 120,
|
|
385
|
-
statusMessage: "◆ Running quality gates...",
|
|
386
|
-
},
|
|
387
|
-
],
|
|
388
|
-
},
|
|
389
|
-
],
|
|
390
414
|
PreCompact: [
|
|
391
415
|
{
|
|
392
416
|
matcher: "compact",
|
|
393
417
|
hooks: [
|
|
394
418
|
{
|
|
395
419
|
type: "command",
|
|
396
|
-
command:
|
|
420
|
+
command: nodeCmd("pre-compact.js"),
|
|
397
421
|
timeout: 15,
|
|
398
422
|
statusMessage: "◆ Saving state...",
|
|
399
423
|
},
|
|
@@ -429,7 +453,7 @@ async function main() {
|
|
|
429
453
|
|
|
430
454
|
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
431
455
|
|
|
432
|
-
ok("Hooks: auto-update, branch-guard, pre-push, env-block, migration-guard, deploy-gate, pre-compact");
|
|
456
|
+
ok("Hooks: session-start, auto-update, branch-guard, pre-push, env-block, migration-guard, deploy-gate, pre-compact");
|
|
433
457
|
ok("Status line + spinner configured");
|
|
434
458
|
ok("Environment variables + permissions");
|
|
435
459
|
|
|
@@ -439,10 +463,11 @@ async function main() {
|
|
|
439
463
|
console.log(`${DIM} ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}`);
|
|
440
464
|
console.log(` ${WHITE}${member.name}${RESET} ${DIM}(${member.role})${RESET}`);
|
|
441
465
|
console.log(` Skills: ${WHITE}${skills.length}${RESET}`);
|
|
442
|
-
|
|
443
|
-
console.log(`
|
|
466
|
+
const agentCount = fs.readdirSync(agentsDir).filter(f => f.endsWith('.md')).length;
|
|
467
|
+
console.log(` Agents: ${WHITE}${agentCount}${RESET} ${DIM}(planner, builder, verifier, qa-browser)${RESET}`);
|
|
468
|
+
console.log(` Hooks: ${WHITE}8${RESET} ${DIM}(session-start, auto-update, branch-guard, pre-push, env-block, migration-guard, deploy-gate, pre-compact)${RESET}`);
|
|
444
469
|
console.log(` Rules: ${WHITE}${fs.readdirSync(rulesDir).length}${RESET} ${DIM}(security, frontend, design-reference, deployment)${RESET}`);
|
|
445
|
-
console.log(` Scripts: ${WHITE}
|
|
470
|
+
console.log(` Scripts: ${WHITE}2${RESET} ${DIM}(state.js, qualia-ui.js)${RESET}`);
|
|
446
471
|
console.log(` Knowledge: ${WHITE}3${RESET} ${DIM}(patterns, fixes, client prefs)${RESET}`);
|
|
447
472
|
console.log(` Templates: ${WHITE}${fs.readdirSync(tmplDir).length}${RESET}`);
|
|
448
473
|
console.log(` Status line: ${GREEN}✓${RESET}`);
|