qualia-framework 3.2.0 → 3.2.1
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/CLAUDE.md +3 -4
- package/README.md +10 -5
- package/agents/planner.md +52 -0
- package/agents/verifier.md +180 -32
- package/bin/cli.js +403 -9
- package/bin/install.js +118 -65
- package/bin/qualia-ui.js +11 -11
- package/bin/state.js +200 -6
- package/bin/statusline.js +4 -4
- package/docs/erp-contract.md +161 -0
- package/hooks/branch-guard.js +23 -2
- package/hooks/migration-guard.js +23 -0
- package/hooks/pre-compact.js +20 -0
- package/hooks/pre-deploy-gate.js +39 -0
- package/hooks/pre-push.js +20 -0
- package/hooks/session-start.js +16 -43
- package/package.json +5 -4
- package/rules/infrastructure.md +87 -0
- package/skills/qualia/SKILL.md +1 -0
- package/skills/qualia-build/SKILL.md +18 -0
- package/skills/qualia-design/SKILL.md +14 -8
- package/skills/qualia-help/SKILL.md +60 -0
- package/skills/qualia-learn/SKILL.md +27 -4
- package/skills/qualia-polish/SKILL.md +167 -117
- package/skills/qualia-report/SKILL.md +17 -8
- package/skills/qualia-review/SKILL.md +126 -41
- package/skills/qualia-test/SKILL.md +134 -0
- package/skills/qualia-verify/SKILL.md +1 -1
- package/templates/DESIGN.md +440 -102
- package/templates/help.html +476 -0
- package/templates/plan.md +14 -0
- package/tests/bin.test.sh +20 -6
- package/tests/hooks.test.sh +76 -7
- package/tests/runner.js +1915 -0
- package/tests/state.test.sh +189 -11
|
@@ -0,0 +1,476 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Qualia Framework — Reference</title>
|
|
7
|
+
<style>
|
|
8
|
+
:root {
|
|
9
|
+
--teal: #00ced1;
|
|
10
|
+
--teal-glow: #00aab0;
|
|
11
|
+
--teal-dim: #008285;
|
|
12
|
+
--bg: #0b1415;
|
|
13
|
+
--bg-subtle: #0f1c1e;
|
|
14
|
+
--bg-card: #121f21;
|
|
15
|
+
--text: #dce1e6;
|
|
16
|
+
--text-muted: #6b7a85;
|
|
17
|
+
--text-subtle: #4a5560;
|
|
18
|
+
--border: #1a2e30;
|
|
19
|
+
--green: #34d399;
|
|
20
|
+
--yellow: #eab308;
|
|
21
|
+
--red: #ef4444;
|
|
22
|
+
--blue: #60a5fa;
|
|
23
|
+
--font-display: 'Outfit', system-ui, sans-serif;
|
|
24
|
+
--font-body: 'Inter', system-ui, sans-serif;
|
|
25
|
+
--font-mono: 'JetBrains Mono', 'Fira Code', monospace;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@import url('https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700&family=Inter:wght@400;500&family=JetBrains+Mono:wght@400;500&display=swap');
|
|
29
|
+
|
|
30
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
31
|
+
|
|
32
|
+
body {
|
|
33
|
+
font-family: var(--font-body);
|
|
34
|
+
background: var(--bg);
|
|
35
|
+
color: var(--text);
|
|
36
|
+
line-height: 1.6;
|
|
37
|
+
-webkit-font-smoothing: antialiased;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/* ─── Header ─────────────────────────────── */
|
|
41
|
+
.header {
|
|
42
|
+
padding: clamp(2rem, 6vw, 4rem) clamp(1.5rem, 5vw, 4rem);
|
|
43
|
+
border-bottom: 1px solid var(--border);
|
|
44
|
+
background: linear-gradient(160deg, var(--bg-subtle), var(--bg));
|
|
45
|
+
position: relative;
|
|
46
|
+
overflow: hidden;
|
|
47
|
+
}
|
|
48
|
+
.header::before {
|
|
49
|
+
content: '';
|
|
50
|
+
position: absolute;
|
|
51
|
+
top: -40%;
|
|
52
|
+
right: -10%;
|
|
53
|
+
width: 400px;
|
|
54
|
+
height: 400px;
|
|
55
|
+
background: radial-gradient(circle, rgba(0,206,209,0.08), transparent 70%);
|
|
56
|
+
pointer-events: none;
|
|
57
|
+
}
|
|
58
|
+
.header-content { position: relative; max-width: 900px; margin: 0 auto; }
|
|
59
|
+
.header h1 {
|
|
60
|
+
font-family: var(--font-display);
|
|
61
|
+
font-weight: 300;
|
|
62
|
+
font-size: clamp(2rem, 1rem + 3vw, 3rem);
|
|
63
|
+
letter-spacing: -0.02em;
|
|
64
|
+
color: var(--text);
|
|
65
|
+
}
|
|
66
|
+
.header h1 span { color: var(--teal); font-weight: 600; }
|
|
67
|
+
.header p {
|
|
68
|
+
color: var(--text-muted);
|
|
69
|
+
font-size: 1rem;
|
|
70
|
+
margin-top: 0.75rem;
|
|
71
|
+
max-width: 50ch;
|
|
72
|
+
}
|
|
73
|
+
.version {
|
|
74
|
+
display: inline-block;
|
|
75
|
+
margin-top: 1rem;
|
|
76
|
+
padding: 0.25rem 0.75rem;
|
|
77
|
+
border: 1px solid var(--border);
|
|
78
|
+
border-radius: 999px;
|
|
79
|
+
font-family: var(--font-mono);
|
|
80
|
+
font-size: 0.75rem;
|
|
81
|
+
color: var(--teal-dim);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/* ─── Layout ─────────────────────────────── */
|
|
85
|
+
.content {
|
|
86
|
+
max-width: 900px;
|
|
87
|
+
margin: 0 auto;
|
|
88
|
+
padding: clamp(2rem, 5vw, 4rem) clamp(1.5rem, 5vw, 4rem);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/* ─── Sections ───────────────────────────── */
|
|
92
|
+
section { margin-bottom: 3.5rem; }
|
|
93
|
+
section h2 {
|
|
94
|
+
font-family: var(--font-display);
|
|
95
|
+
font-weight: 500;
|
|
96
|
+
font-size: 1.35rem;
|
|
97
|
+
letter-spacing: -0.01em;
|
|
98
|
+
color: var(--teal);
|
|
99
|
+
margin-bottom: 1.25rem;
|
|
100
|
+
padding-bottom: 0.5rem;
|
|
101
|
+
border-bottom: 1px solid var(--border);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/* ─── The Road ───────────────────────────── */
|
|
105
|
+
.road {
|
|
106
|
+
display: flex;
|
|
107
|
+
flex-wrap: wrap;
|
|
108
|
+
gap: 0.5rem;
|
|
109
|
+
align-items: center;
|
|
110
|
+
margin: 1.5rem 0;
|
|
111
|
+
}
|
|
112
|
+
.road-step {
|
|
113
|
+
padding: 0.5rem 1rem;
|
|
114
|
+
background: var(--bg-card);
|
|
115
|
+
border: 1px solid var(--border);
|
|
116
|
+
border-radius: 8px;
|
|
117
|
+
font-family: var(--font-mono);
|
|
118
|
+
font-size: 0.8rem;
|
|
119
|
+
color: var(--text);
|
|
120
|
+
transition: border-color 0.15s ease-out;
|
|
121
|
+
}
|
|
122
|
+
.road-step:hover { border-color: var(--teal-dim); }
|
|
123
|
+
.road-arrow { color: var(--text-subtle); font-size: 0.9rem; }
|
|
124
|
+
|
|
125
|
+
/* ─── Command Cards ──────────────────────── */
|
|
126
|
+
.commands { display: grid; gap: 0.75rem; }
|
|
127
|
+
.cmd-group { margin-bottom: 1.5rem; }
|
|
128
|
+
.cmd-group h3 {
|
|
129
|
+
font-family: var(--font-display);
|
|
130
|
+
font-weight: 500;
|
|
131
|
+
font-size: 0.85rem;
|
|
132
|
+
text-transform: uppercase;
|
|
133
|
+
letter-spacing: 0.08em;
|
|
134
|
+
color: var(--text-subtle);
|
|
135
|
+
margin-bottom: 0.75rem;
|
|
136
|
+
}
|
|
137
|
+
.cmd {
|
|
138
|
+
display: flex;
|
|
139
|
+
gap: 1rem;
|
|
140
|
+
align-items: baseline;
|
|
141
|
+
padding: 0.625rem 1rem;
|
|
142
|
+
background: var(--bg-card);
|
|
143
|
+
border: 1px solid var(--border);
|
|
144
|
+
border-radius: 8px;
|
|
145
|
+
transition: border-color 0.15s ease-out;
|
|
146
|
+
}
|
|
147
|
+
.cmd:hover { border-color: var(--teal-dim); }
|
|
148
|
+
.cmd-name {
|
|
149
|
+
font-family: var(--font-mono);
|
|
150
|
+
font-size: 0.85rem;
|
|
151
|
+
color: var(--teal);
|
|
152
|
+
white-space: nowrap;
|
|
153
|
+
min-width: 160px;
|
|
154
|
+
}
|
|
155
|
+
.cmd-desc {
|
|
156
|
+
font-size: 0.85rem;
|
|
157
|
+
color: var(--text-muted);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/* ─── Rules ──────────────────────────────── */
|
|
161
|
+
.rules { list-style: none; }
|
|
162
|
+
.rules li {
|
|
163
|
+
padding: 0.625rem 0;
|
|
164
|
+
border-bottom: 1px solid var(--border);
|
|
165
|
+
font-size: 0.9rem;
|
|
166
|
+
display: flex;
|
|
167
|
+
gap: 0.75rem;
|
|
168
|
+
align-items: baseline;
|
|
169
|
+
}
|
|
170
|
+
.rules li:last-child { border-bottom: none; }
|
|
171
|
+
.rule-icon { color: var(--teal); font-size: 0.85rem; flex-shrink: 0; }
|
|
172
|
+
|
|
173
|
+
/* ─── Services ───────────────────────────── */
|
|
174
|
+
.services {
|
|
175
|
+
display: grid;
|
|
176
|
+
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
|
177
|
+
gap: 0.75rem;
|
|
178
|
+
}
|
|
179
|
+
.service {
|
|
180
|
+
padding: 1rem 1.25rem;
|
|
181
|
+
background: var(--bg-card);
|
|
182
|
+
border: 1px solid var(--border);
|
|
183
|
+
border-radius: 10px;
|
|
184
|
+
transition: border-color 0.15s ease-out;
|
|
185
|
+
}
|
|
186
|
+
.service:hover { border-color: var(--teal-dim); }
|
|
187
|
+
.service-name {
|
|
188
|
+
font-family: var(--font-display);
|
|
189
|
+
font-weight: 500;
|
|
190
|
+
font-size: 0.95rem;
|
|
191
|
+
color: var(--text);
|
|
192
|
+
margin-bottom: 0.25rem;
|
|
193
|
+
}
|
|
194
|
+
.service-desc { font-size: 0.8rem; color: var(--text-muted); }
|
|
195
|
+
.service-key {
|
|
196
|
+
font-family: var(--font-mono);
|
|
197
|
+
font-size: 0.7rem;
|
|
198
|
+
color: var(--teal-dim);
|
|
199
|
+
margin-top: 0.5rem;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/* ─── Scoring ────────────────────────────── */
|
|
203
|
+
.scoring {
|
|
204
|
+
display: grid;
|
|
205
|
+
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
|
206
|
+
gap: 0.75rem;
|
|
207
|
+
}
|
|
208
|
+
.score-dim {
|
|
209
|
+
padding: 1rem;
|
|
210
|
+
background: var(--bg-card);
|
|
211
|
+
border: 1px solid var(--border);
|
|
212
|
+
border-radius: 10px;
|
|
213
|
+
text-align: center;
|
|
214
|
+
}
|
|
215
|
+
.score-dim h4 {
|
|
216
|
+
font-family: var(--font-display);
|
|
217
|
+
font-weight: 500;
|
|
218
|
+
color: var(--teal);
|
|
219
|
+
font-size: 0.95rem;
|
|
220
|
+
margin-bottom: 0.25rem;
|
|
221
|
+
}
|
|
222
|
+
.score-dim p { font-size: 0.78rem; color: var(--text-muted); }
|
|
223
|
+
.score-bar {
|
|
224
|
+
display: flex;
|
|
225
|
+
gap: 3px;
|
|
226
|
+
justify-content: center;
|
|
227
|
+
margin-top: 0.5rem;
|
|
228
|
+
}
|
|
229
|
+
.score-bar span {
|
|
230
|
+
width: 18px;
|
|
231
|
+
height: 6px;
|
|
232
|
+
border-radius: 3px;
|
|
233
|
+
background: var(--border);
|
|
234
|
+
}
|
|
235
|
+
.score-bar span.filled { background: var(--teal); }
|
|
236
|
+
.score-bar span.threshold { background: var(--yellow); }
|
|
237
|
+
|
|
238
|
+
/* ─── Footer ─────────────────────────────── */
|
|
239
|
+
.footer {
|
|
240
|
+
padding: 2rem clamp(1.5rem, 5vw, 4rem);
|
|
241
|
+
border-top: 1px solid var(--border);
|
|
242
|
+
text-align: center;
|
|
243
|
+
font-size: 0.8rem;
|
|
244
|
+
color: var(--text-subtle);
|
|
245
|
+
}
|
|
246
|
+
.footer strong { color: var(--teal); font-weight: 500; }
|
|
247
|
+
|
|
248
|
+
/* ─── Responsive ─────────────────────────── */
|
|
249
|
+
@media (max-width: 640px) {
|
|
250
|
+
.cmd { flex-direction: column; gap: 0.25rem; }
|
|
251
|
+
.cmd-name { min-width: unset; }
|
|
252
|
+
.road { flex-direction: column; align-items: flex-start; }
|
|
253
|
+
.road-arrow { display: none; }
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
@media (prefers-reduced-motion: reduce) {
|
|
257
|
+
* { transition-duration: 0.01ms !important; }
|
|
258
|
+
}
|
|
259
|
+
</style>
|
|
260
|
+
</head>
|
|
261
|
+
<body>
|
|
262
|
+
|
|
263
|
+
<div class="header">
|
|
264
|
+
<div class="header-content">
|
|
265
|
+
<h1><span>Qualia</span> Framework</h1>
|
|
266
|
+
<p>Plan, build, verify, ship. The AI-powered workflow for Qualia Solutions.</p>
|
|
267
|
+
<div class="version">v{{VERSION}}</div>
|
|
268
|
+
</div>
|
|
269
|
+
</div>
|
|
270
|
+
|
|
271
|
+
<div class="content">
|
|
272
|
+
|
|
273
|
+
<!-- The Road -->
|
|
274
|
+
<section>
|
|
275
|
+
<h2>The Road</h2>
|
|
276
|
+
<p style="color: var(--text-muted); margin-bottom: 1rem;">Every project follows this path. No exceptions.</p>
|
|
277
|
+
<div class="road">
|
|
278
|
+
<div class="road-step">/qualia-new</div>
|
|
279
|
+
<span class="road-arrow">→</span>
|
|
280
|
+
<div class="road-step">/qualia-plan</div>
|
|
281
|
+
<span class="road-arrow">→</span>
|
|
282
|
+
<div class="road-step">/qualia-build</div>
|
|
283
|
+
<span class="road-arrow">→</span>
|
|
284
|
+
<div class="road-step">/qualia-verify</div>
|
|
285
|
+
<span class="road-arrow">→</span>
|
|
286
|
+
<div class="road-step">/qualia-polish</div>
|
|
287
|
+
<span class="road-arrow">→</span>
|
|
288
|
+
<div class="road-step">/qualia-ship</div>
|
|
289
|
+
<span class="road-arrow">→</span>
|
|
290
|
+
<div class="road-step">/qualia-handoff</div>
|
|
291
|
+
<span class="road-arrow">→</span>
|
|
292
|
+
<div class="road-step">/qualia-report</div>
|
|
293
|
+
</div>
|
|
294
|
+
</section>
|
|
295
|
+
|
|
296
|
+
<!-- Commands -->
|
|
297
|
+
<section>
|
|
298
|
+
<h2>Commands</h2>
|
|
299
|
+
|
|
300
|
+
<div class="cmd-group">
|
|
301
|
+
<h3>Navigation</h3>
|
|
302
|
+
<div class="commands">
|
|
303
|
+
<div class="cmd"><span class="cmd-name">/qualia</span><span class="cmd-desc">What should I do next? Reads project state, tells you the exact command.</span></div>
|
|
304
|
+
<div class="cmd"><span class="cmd-name">/qualia-idk</span><span class="cmd-desc">Same as /qualia. For when you're stuck.</span></div>
|
|
305
|
+
<div class="cmd"><span class="cmd-name">/qualia-resume</span><span class="cmd-desc">Pick up where you left off from a previous session.</span></div>
|
|
306
|
+
<div class="cmd"><span class="cmd-name">/qualia-pause</span><span class="cmd-desc">Save progress. Creates .continue-here.md for next session.</span></div>
|
|
307
|
+
</div>
|
|
308
|
+
</div>
|
|
309
|
+
|
|
310
|
+
<div class="cmd-group">
|
|
311
|
+
<h3>Project Setup</h3>
|
|
312
|
+
<div class="commands">
|
|
313
|
+
<div class="cmd"><span class="cmd-name">/qualia-new</span><span class="cmd-desc">Interactive wizard. Asks about client, scope, design, stack. Creates everything.</span></div>
|
|
314
|
+
</div>
|
|
315
|
+
</div>
|
|
316
|
+
|
|
317
|
+
<div class="cmd-group">
|
|
318
|
+
<h3>Build Loop</h3>
|
|
319
|
+
<div class="commands">
|
|
320
|
+
<div class="cmd"><span class="cmd-name">/qualia-plan</span><span class="cmd-desc">Plan the current phase. AI generates tasks with success criteria.</span></div>
|
|
321
|
+
<div class="cmd"><span class="cmd-name">/qualia-build</span><span class="cmd-desc">Build it. Fresh AI agent per task, parallel waves.</span></div>
|
|
322
|
+
<div class="cmd"><span class="cmd-name">/qualia-verify</span><span class="cmd-desc">Verify it actually works. Greps code, scores on 4 dimensions.</span></div>
|
|
323
|
+
</div>
|
|
324
|
+
</div>
|
|
325
|
+
|
|
326
|
+
<div class="cmd-group">
|
|
327
|
+
<h3>Quick Work</h3>
|
|
328
|
+
<div class="commands">
|
|
329
|
+
<div class="cmd"><span class="cmd-name">/qualia-quick</span><span class="cmd-desc">Skip planning. For bug fixes, tweaks, hot fixes under 1 hour.</span></div>
|
|
330
|
+
<div class="cmd"><span class="cmd-name">/qualia-task</span><span class="cmd-desc">One focused task. More structured than quick, lighter than build.</span></div>
|
|
331
|
+
</div>
|
|
332
|
+
</div>
|
|
333
|
+
|
|
334
|
+
<div class="cmd-group">
|
|
335
|
+
<h3>Design & Quality</h3>
|
|
336
|
+
<div class="commands">
|
|
337
|
+
<div class="cmd"><span class="cmd-name">/qualia-design</span><span class="cmd-desc">One-shot design fix. Reads DESIGN.md, kills AI slop, makes it professional.</span></div>
|
|
338
|
+
<div class="cmd"><span class="cmd-name">/qualia-polish</span><span class="cmd-desc">Full design pass. Typography, color, states, motion, a11y, responsive, hardening.</span></div>
|
|
339
|
+
<div class="cmd"><span class="cmd-name">/qualia-review</span><span class="cmd-desc">Production audit. Security, performance, reliability. Scored diagnostics.</span></div>
|
|
340
|
+
</div>
|
|
341
|
+
</div>
|
|
342
|
+
|
|
343
|
+
<div class="cmd-group">
|
|
344
|
+
<h3>Ship & Deliver</h3>
|
|
345
|
+
<div class="commands">
|
|
346
|
+
<div class="cmd"><span class="cmd-name">/qualia-ship</span><span class="cmd-desc">Quality gates, commit, push, deploy to Vercel, post-deploy verification.</span></div>
|
|
347
|
+
<div class="cmd"><span class="cmd-name">/qualia-handoff</span><span class="cmd-desc">Client delivery. Credentials, docs, handover package.</span></div>
|
|
348
|
+
<div class="cmd"><span class="cmd-name">/qualia-report</span><span class="cmd-desc">Log your session. Mandatory before clock-out. Uploads to ERP.</span></div>
|
|
349
|
+
</div>
|
|
350
|
+
</div>
|
|
351
|
+
|
|
352
|
+
<div class="cmd-group">
|
|
353
|
+
<h3>Debugging & Learning</h3>
|
|
354
|
+
<div class="commands">
|
|
355
|
+
<div class="cmd"><span class="cmd-name">/qualia-debug</span><span class="cmd-desc">Structured debugging. Symptom → diagnosis → root cause → fix.</span></div>
|
|
356
|
+
<div class="cmd"><span class="cmd-name">/qualia-learn</span><span class="cmd-desc">Save a pattern, fix, or client preference to the knowledge base.</span></div>
|
|
357
|
+
<div class="cmd"><span class="cmd-name">/qualia-test</span><span class="cmd-desc">Generate or run tests. Auto-detects framework.</span></div>
|
|
358
|
+
</div>
|
|
359
|
+
</div>
|
|
360
|
+
|
|
361
|
+
<div class="cmd-group">
|
|
362
|
+
<h3>CLI (Terminal)</h3>
|
|
363
|
+
<div class="commands">
|
|
364
|
+
<div class="cmd"><span class="cmd-name">qualia-framework install</span><span class="cmd-desc">Install or reinstall the framework.</span></div>
|
|
365
|
+
<div class="cmd"><span class="cmd-name">qualia-framework update</span><span class="cmd-desc">Update to the latest version.</span></div>
|
|
366
|
+
<div class="cmd"><span class="cmd-name">qualia-framework version</span><span class="cmd-desc">Show installed version + check for updates.</span></div>
|
|
367
|
+
<div class="cmd"><span class="cmd-name">qualia-framework migrate</span><span class="cmd-desc">Upgrade v2 settings to v3.</span></div>
|
|
368
|
+
<div class="cmd"><span class="cmd-name">qualia-framework analytics</span><span class="cmd-desc">Hook telemetry, verification pass rates, gap cycles.</span></div>
|
|
369
|
+
<div class="cmd"><span class="cmd-name">qualia-framework team</span><span class="cmd-desc">List, add, or remove team members.</span></div>
|
|
370
|
+
<div class="cmd"><span class="cmd-name">qualia-framework traces</span><span class="cmd-desc">View recent hook activity.</span></div>
|
|
371
|
+
</div>
|
|
372
|
+
</div>
|
|
373
|
+
</section>
|
|
374
|
+
|
|
375
|
+
<!-- Verification Scoring -->
|
|
376
|
+
<section>
|
|
377
|
+
<h2>Verification Scoring</h2>
|
|
378
|
+
<p style="color: var(--text-muted); margin-bottom: 1rem;">Every phase is scored on 4 dimensions. Any score below 3 = automatic FAIL.</p>
|
|
379
|
+
<div class="scoring">
|
|
380
|
+
<div class="score-dim">
|
|
381
|
+
<h4>Correctness</h4>
|
|
382
|
+
<p>Does it work as expected?</p>
|
|
383
|
+
<div class="score-bar"><span class="filled"></span><span class="filled"></span><span class="threshold"></span><span></span><span></span></div>
|
|
384
|
+
</div>
|
|
385
|
+
<div class="score-dim">
|
|
386
|
+
<h4>Completeness</h4>
|
|
387
|
+
<p>Are all requirements met?</p>
|
|
388
|
+
<div class="score-bar"><span class="filled"></span><span class="filled"></span><span class="threshold"></span><span></span><span></span></div>
|
|
389
|
+
</div>
|
|
390
|
+
<div class="score-dim">
|
|
391
|
+
<h4>Wiring</h4>
|
|
392
|
+
<p>Is everything connected end-to-end?</p>
|
|
393
|
+
<div class="score-bar"><span class="filled"></span><span class="filled"></span><span class="threshold"></span><span></span><span></span></div>
|
|
394
|
+
</div>
|
|
395
|
+
<div class="score-dim">
|
|
396
|
+
<h4>Quality</h4>
|
|
397
|
+
<p>Code quality, security, a11y?</p>
|
|
398
|
+
<div class="score-bar"><span class="filled"></span><span class="filled"></span><span class="threshold"></span><span></span><span></span></div>
|
|
399
|
+
</div>
|
|
400
|
+
</div>
|
|
401
|
+
</section>
|
|
402
|
+
|
|
403
|
+
<!-- Rules -->
|
|
404
|
+
<section>
|
|
405
|
+
<h2>Rules</h2>
|
|
406
|
+
<ul class="rules">
|
|
407
|
+
<li><span class="rule-icon">1</span> Feature branches only — never push to main</li>
|
|
408
|
+
<li><span class="rule-icon">2</span> Read before write — understand files before editing</li>
|
|
409
|
+
<li><span class="rule-icon">3</span> MVP first — build what's asked, nothing extra</li>
|
|
410
|
+
<li><span class="rule-icon">4</span> /qualia-report before clock-out — mandatory, enforced by ERP</li>
|
|
411
|
+
<li><span class="rule-icon">5</span> No .env edits — ask Fawzi for secrets</li>
|
|
412
|
+
<li><span class="rule-icon">6</span> Stuck 30+ minutes? Ask Fawzi</li>
|
|
413
|
+
</ul>
|
|
414
|
+
</section>
|
|
415
|
+
|
|
416
|
+
<!-- Services -->
|
|
417
|
+
<section>
|
|
418
|
+
<h2>Our Stack</h2>
|
|
419
|
+
<div class="services">
|
|
420
|
+
<div class="service">
|
|
421
|
+
<div class="service-name">Supabase</div>
|
|
422
|
+
<div class="service-desc">Database, auth, storage. Every project. MCP + CLI available.</div>
|
|
423
|
+
<div class="service-key">Always enable RLS</div>
|
|
424
|
+
</div>
|
|
425
|
+
<div class="service">
|
|
426
|
+
<div class="service-name">Vercel</div>
|
|
427
|
+
<div class="service-desc">Hosting. 3 teams. No auto-deploy — CLI only via /qualia-ship.</div>
|
|
428
|
+
<div class="service-key">vercel --prod</div>
|
|
429
|
+
</div>
|
|
430
|
+
<div class="service">
|
|
431
|
+
<div class="service-name">Railway</div>
|
|
432
|
+
<div class="service-desc">Long-running agents, background jobs. MCP + CLI available.</div>
|
|
433
|
+
<div class="service-key">railway deploy</div>
|
|
434
|
+
</div>
|
|
435
|
+
<div class="service">
|
|
436
|
+
<div class="service-name">OpenRouter</div>
|
|
437
|
+
<div class="service-desc">AI model routing. One API key for all models.</div>
|
|
438
|
+
<div class="service-key">Ask Fawzi for a key</div>
|
|
439
|
+
</div>
|
|
440
|
+
<div class="service">
|
|
441
|
+
<div class="service-name">Retell AI</div>
|
|
442
|
+
<div class="service-desc">Voice agents. Primary voice platform.</div>
|
|
443
|
+
<div class="service-key">RETELL_API_KEY</div>
|
|
444
|
+
</div>
|
|
445
|
+
<div class="service">
|
|
446
|
+
<div class="service-name">ElevenLabs</div>
|
|
447
|
+
<div class="service-desc">Voice synthesis, cloning, streaming.</div>
|
|
448
|
+
<div class="service-key">ELEVENLABS_API_KEY</div>
|
|
449
|
+
</div>
|
|
450
|
+
</div>
|
|
451
|
+
</section>
|
|
452
|
+
|
|
453
|
+
<!-- GitHub -->
|
|
454
|
+
<section>
|
|
455
|
+
<h2>GitHub Organizations</h2>
|
|
456
|
+
<div class="services" style="grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));">
|
|
457
|
+
<div class="service">
|
|
458
|
+
<div class="service-name">QualiasolutionsCY</div>
|
|
459
|
+
<div class="service-desc">Primary org. All Qualia Solutions projects.</div>
|
|
460
|
+
</div>
|
|
461
|
+
<div class="service">
|
|
462
|
+
<div class="service-name">SakaniQualia</div>
|
|
463
|
+
<div class="service-desc">Sakani real estate platform.</div>
|
|
464
|
+
</div>
|
|
465
|
+
</div>
|
|
466
|
+
</section>
|
|
467
|
+
|
|
468
|
+
</div>
|
|
469
|
+
|
|
470
|
+
<div class="footer">
|
|
471
|
+
<strong>Welcome to the future with Qualia.</strong><br>
|
|
472
|
+
Qualia Solutions — Nicosia, Cyprus
|
|
473
|
+
</div>
|
|
474
|
+
|
|
475
|
+
</body>
|
|
476
|
+
</html>
|
package/templates/plan.md
CHANGED
|
@@ -26,3 +26,17 @@ Goal: {what must be true when done}
|
|
|
26
26
|
- [ ] {truth 1 — what the user can do}
|
|
27
27
|
- [ ] {truth 2}
|
|
28
28
|
- [ ] {truth 3}
|
|
29
|
+
|
|
30
|
+
## Verification Contract
|
|
31
|
+
|
|
32
|
+
### Contract for Task 1 — {title}
|
|
33
|
+
**Check type:** {file-exists | grep-match | command-exit | behavioral}
|
|
34
|
+
**Command:** `{exact command the verifier will run}`
|
|
35
|
+
**Expected:** {what the output should be}
|
|
36
|
+
**Fail if:** {what constitutes failure}
|
|
37
|
+
|
|
38
|
+
### Contract for Task 2 — {title}
|
|
39
|
+
**Check type:** {file-exists | grep-match | command-exit | behavioral}
|
|
40
|
+
**Command:** `{exact command}`
|
|
41
|
+
**Expected:** {expected output}
|
|
42
|
+
**Fail if:** {failure condition}
|
package/tests/bin.test.sh
CHANGED
|
@@ -139,7 +139,7 @@ cat > "$TMP/.claude/.qualia-config.json" <<'EOF'
|
|
|
139
139
|
"code": "QS-FAWZI-01",
|
|
140
140
|
"installed_by": "Fawzi Goussous",
|
|
141
141
|
"role": "OWNER",
|
|
142
|
-
"version": "
|
|
142
|
+
"version": "2.8.1",
|
|
143
143
|
"installed_at": "2026-04-10"
|
|
144
144
|
}
|
|
145
145
|
EOF
|
|
@@ -423,7 +423,7 @@ cat > "$TMP/.claude/.qualia-config.json" <<'EOF'
|
|
|
423
423
|
"code": "QS-FAWZI-01",
|
|
424
424
|
"installed_by": "Fawzi Goussous",
|
|
425
425
|
"role": "OWNER",
|
|
426
|
-
"version": "
|
|
426
|
+
"version": "2.8.1",
|
|
427
427
|
"installed_at": "2026-04-10"
|
|
428
428
|
}
|
|
429
429
|
EOF
|
|
@@ -476,10 +476,10 @@ else
|
|
|
476
476
|
fail_case "CLAUDE.md role substitution"
|
|
477
477
|
fi
|
|
478
478
|
|
|
479
|
-
# 31. All
|
|
479
|
+
# 31. All 8 hooks installed
|
|
480
480
|
HOOK_COUNT=$(ls "$TMP/.claude/hooks/"*.js 2>/dev/null | wc -l)
|
|
481
|
-
if [ "$HOOK_COUNT" -eq
|
|
482
|
-
pass "
|
|
481
|
+
if [ "$HOOK_COUNT" -eq 8 ]; then
|
|
482
|
+
pass "8 hooks installed in hooks/"
|
|
483
483
|
else
|
|
484
484
|
fail_case "hook count" "got $HOOK_COUNT"
|
|
485
485
|
fi
|
|
@@ -494,7 +494,21 @@ else
|
|
|
494
494
|
fail_case "settings.json contents"
|
|
495
495
|
fi
|
|
496
496
|
|
|
497
|
-
# 33.
|
|
497
|
+
# 33. settings.json contains all 8 hooks wired correctly
|
|
498
|
+
if grep -q 'block-env-edit.js' "$TMP/.claude/settings.json" \
|
|
499
|
+
&& grep -q 'branch-guard.js' "$TMP/.claude/settings.json" \
|
|
500
|
+
&& grep -q 'migration-guard.js' "$TMP/.claude/settings.json" \
|
|
501
|
+
&& grep -q 'pre-push.js' "$TMP/.claude/settings.json" \
|
|
502
|
+
&& grep -q 'pre-deploy-gate.js' "$TMP/.claude/settings.json" \
|
|
503
|
+
&& grep -q 'auto-update.js' "$TMP/.claude/settings.json" \
|
|
504
|
+
&& grep -q 'session-start.js' "$TMP/.claude/settings.json" \
|
|
505
|
+
&& grep -q 'pre-compact.js' "$TMP/.claude/settings.json"; then
|
|
506
|
+
pass "settings.json has all 8 hooks wired"
|
|
507
|
+
else
|
|
508
|
+
fail_case "settings.json missing hooks"
|
|
509
|
+
fi
|
|
510
|
+
|
|
511
|
+
# 34. Lowercase code works (resolveTeamCode normalizes)
|
|
498
512
|
TMP=$(mktmp)
|
|
499
513
|
echo "qs-fawzi-01" | HOME="$TMP" $NODE "$INSTALL_JS" > "$TMP/out.log" 2>&1
|
|
500
514
|
EXIT=$?
|