qualia-framework 5.5.0 → 5.8.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 +17 -13
- package/agents/research-synthesizer.md +4 -1
- package/agents/researcher.md +6 -1
- package/agents/visual-evaluator.md +1 -1
- package/bin/install.js +6 -6
- package/bin/slop-detect.mjs +1 -1
- package/docs/onboarding.html +623 -0
- package/guide.md +5 -6
- package/hooks/session-start.js +1 -1
- package/package.json +1 -1
- package/skills/qualia-discuss/SKILL.md +106 -6
- package/skills/qualia-feature/SKILL.md +216 -0
- package/skills/qualia-milestone/SKILL.md +73 -1
- package/skills/qualia-new/SKILL.md +52 -25
- package/skills/qualia-optimize/SKILL.md +1 -1
- package/skills/{qualia-polish-loop → qualia-polish}/REFERENCE.md +5 -5
- package/skills/qualia-polish/SKILL.md +13 -4
- package/skills/{qualia-polish-loop → qualia-polish}/scripts/loop.mjs +2 -2
- package/skills/{qualia-polish-loop → qualia-polish}/scripts/playwright-capture.mjs +1 -1
- package/skills/qualia-road/SKILL.md +10 -11
- package/templates/project-discovery.md +83 -0
- package/templates/project.md +7 -0
- package/tests/bin.test.sh +74 -62
- package/tests/slop-detect.test.sh +2 -2
- package/skills/qualia-polish-loop/SKILL.md +0 -201
- package/skills/qualia-prd/SKILL.md +0 -199
- package/skills/qualia-quick/SKILL.md +0 -44
- package/skills/qualia-task/SKILL.md +0 -98
- /package/skills/{qualia-polish-loop → qualia-polish}/fixtures/broken.html +0 -0
- /package/skills/{qualia-polish-loop → qualia-polish}/fixtures/clean.html +0 -0
- /package/skills/{qualia-polish-loop → qualia-polish}/scripts/score.mjs +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: qualia-polish
|
|
3
|
-
description: "Scope-adaptive design pass
|
|
3
|
+
description: "Scope-adaptive design pass. Works on a single component, a route, the whole app, a ground-up redesign, or an autonomous visual loop. Trigger on 'polish', 'design pass', 'fix the design', 'redesign', 'critique', 'audit design', 'looks ugly', 'make it look better', 'polish loop', 'visual loop', 'fix what I see', 'iterate on the design until it's correct'. Replaces /qualia-polish-loop (now /qualia-polish --loop) and /qualia-design from earlier versions."
|
|
4
4
|
allowed-tools:
|
|
5
5
|
- Bash
|
|
6
6
|
- Read
|
|
@@ -9,12 +9,12 @@ allowed-tools:
|
|
|
9
9
|
- Grep
|
|
10
10
|
- Glob
|
|
11
11
|
- Agent
|
|
12
|
-
argument-hint: "[file|route|--redesign|--critique|--quick] [--register=brand|product]"
|
|
12
|
+
argument-hint: "[file|route|--redesign|--critique|--quick|--loop] [--register=brand|product] [--brief PATH] [--max 8] [--viewports 375,768,1440]"
|
|
13
13
|
---
|
|
14
14
|
|
|
15
15
|
# /qualia-polish — Scope-Adaptive Design Pass
|
|
16
16
|
|
|
17
|
-
One command.
|
|
17
|
+
One command. Seven scopes. Use it whenever you need design work, from a 30-second component touch-up to a 30-minute ground-up redesign to a fully autonomous see-fix-verify loop.
|
|
18
18
|
|
|
19
19
|
## Scopes
|
|
20
20
|
|
|
@@ -28,8 +28,17 @@ The first argument selects the scope. Stage selection follows from scope.
|
|
|
28
28
|
| `/qualia-polish --redesign` | **Redesign** | ~30m | all + Stage 1 mandatory + 2 vision iterations |
|
|
29
29
|
| `/qualia-polish --critique` | **Critique** | read-only | 0, 4, 5 (no edits) |
|
|
30
30
|
| `/qualia-polish --quick` | **Quick** | ~1m | 0, 2, 7 (gates only, no vision loop) |
|
|
31
|
+
| `/qualia-polish --loop {url}` | **Loop** | ~5-15m | autonomous see/fix/verify, max 8 iterations |
|
|
31
32
|
|
|
32
|
-
Other flags: `--register=brand|product`
|
|
33
|
+
Other flags: `--register=brand|product` overrides register inference. Loop-specific flags: `--brief PATH`, `--max N`, `--viewports 375,768,1440`, `--ref PATH`, `--budget 100000`.
|
|
34
|
+
|
|
35
|
+
## --loop mode (autonomous visual loop)
|
|
36
|
+
|
|
37
|
+
When `--loop` is the first flag, the polish run is fully autonomous: screenshot a live URL at three viewports, score 8 design dimensions of `qualia-design/design-rubric.md` against the brief using vision, fix top issues in the codebase, re-screenshot, repeat until every dimension scores ≥ 3 or the kill-switch fires (regression, budget cap, max iterations).
|
|
38
|
+
|
|
39
|
+
This is the surface formerly known as `/qualia-polish-loop` (consolidated into a flag in v5.8.0). The scripts ship at `skills/qualia-polish/scripts/{loop,playwright-capture,score}.mjs`; vision evaluator is `agents/visual-evaluator.md`; full loop spec lives in this skill's `REFERENCE.md`.
|
|
40
|
+
|
|
41
|
+
When `--loop` is detected on entry, route to the loop process documented in `REFERENCE.md` and stop executing the standard stages below. The two paths share Stage 0 substrate gates and the rubric, but diverge from Stage 1 onward.
|
|
33
42
|
|
|
34
43
|
## Setup gates (non-optional, every scope)
|
|
35
44
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* loop.mjs — orchestrator state-machine for /qualia-polish
|
|
3
|
+
* loop.mjs — orchestrator state-machine for /qualia-polish --loop.
|
|
4
4
|
*
|
|
5
5
|
* Claude (the parent session) drives the loop by issuing CLI commands. This
|
|
6
6
|
* script keeps the deterministic state — iteration counter, regression
|
|
@@ -294,7 +294,7 @@ switch (cmd) {
|
|
|
294
294
|
case "--help":
|
|
295
295
|
case "-h":
|
|
296
296
|
case undefined:
|
|
297
|
-
console.log(`loop.mjs — orchestrator for /qualia-polish
|
|
297
|
+
console.log(`loop.mjs — orchestrator for /qualia-polish --loop
|
|
298
298
|
|
|
299
299
|
Commands:
|
|
300
300
|
init --state PATH (--url URL | --routes URL1,URL2,...) [--brief PATH] [--ref PATH] [--max 8] [--budget 100000] [--reduced-motion]
|
|
@@ -36,7 +36,7 @@ function parseArgs() {
|
|
|
36
36
|
} else if (a === "--wait" && argv[i + 1]) args.wait = parseInt(argv[++i], 10);
|
|
37
37
|
else if (a === "--reduced-motion") args.reducedMotion = true;
|
|
38
38
|
else if (a === "--help" || a === "-h") {
|
|
39
|
-
console.log(`playwright-capture.mjs — Screenshot capture for /qualia-polish
|
|
39
|
+
console.log(`playwright-capture.mjs — Screenshot capture for /qualia-polish --loop
|
|
40
40
|
|
|
41
41
|
Usage:
|
|
42
42
|
node playwright-capture.mjs --url <url> --out <dir> [--viewports 375,768,1440] [--wait 1500] [--reduced-motion]
|
|
@@ -45,23 +45,22 @@ Every road agent loads `PRODUCT.md + DESIGN.md + design-laws.md` substrate. Buil
|
|
|
45
45
|
/qualia-polish --quick ~1m gates only
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
-
## /qualia-polish
|
|
48
|
+
## /qualia-polish --loop -- autonomous visual QA (v5.1+, consolidated into /qualia-polish in v5.8)
|
|
49
49
|
```
|
|
50
|
-
/qualia-polish
|
|
51
|
-
/qualia-polish
|
|
52
|
-
/qualia-polish
|
|
53
|
-
/qualia-polish
|
|
54
|
-
/qualia-polish
|
|
50
|
+
/qualia-polish --loop http://localhost:3000 screenshot + eval + fix loop
|
|
51
|
+
/qualia-polish --loop {url} --max 4 cap iterations
|
|
52
|
+
/qualia-polish --loop {url} --ref design.png anchor to reference image
|
|
53
|
+
/qualia-polish --loop {url} --reduced-motion force prefers-reduced-motion
|
|
54
|
+
/qualia-polish --loop --routes /a,/b,/c multi-route sweep
|
|
55
55
|
```
|
|
56
56
|
Screenshots at 3 viewports (375/768/1440), scores 8 design dimensions using vision, fixes issues, re-screenshots, loops until all dims >= 3 or kill-switch triggers. Per-iteration git commits for clean revert.
|
|
57
57
|
|
|
58
|
-
## v5.3+ skills
|
|
58
|
+
## v5.3+ skills
|
|
59
59
|
```
|
|
60
|
-
/qualia-prd synthesize current conversation → .planning/PRD-{slug}.md (durable feature spec)
|
|
61
60
|
/qualia-hook-gen convert a CLAUDE.md/rules instruction into a deterministic pre-tool-use hook
|
|
62
|
-
/qualia-optimize --deepen
|
|
61
|
+
/qualia-optimize --deepen spawns 3 parallel interface-design variants per candidate (Step 5b)
|
|
63
62
|
```
|
|
64
|
-
`/qualia-
|
|
63
|
+
`/qualia-hook-gen` reduces lifetime token cost (each migrated rule frees ~50-200 tokens per request). `/qualia-optimize --deepen` produces dramatically better refactor RFCs because 3 radically-different interfaces are surfaced and the human picks/hybridizes.
|
|
65
64
|
|
|
66
65
|
## Alignment substrate (v5.0+)
|
|
67
66
|
Before high-stakes phases, run alignment skills against `.planning/CONTEXT.md` (domain glossary) and `.planning/decisions/` (ADRs):
|
|
@@ -80,7 +79,7 @@ Before high-stakes phases, run alignment skills against `.planning/CONTEXT.md` (
|
|
|
80
79
|
```
|
|
81
80
|
Lost? → /qualia (state router — tells you the next command)
|
|
82
81
|
Stuck/weird? → /qualia-idk (diagnostic — spawns plan-view + code-view agents in parallel)
|
|
83
|
-
|
|
82
|
+
Single feature? → /qualia-feature (auto-scoped: inline for trivia, fresh spawn for 1-5 files)
|
|
84
83
|
Paused? → /qualia-resume (restore from .continue-here.md or STATE.md)
|
|
85
84
|
End of day? → /qualia-report (mandatory before clock-out; writes ERP payload)
|
|
86
85
|
Debug bug? → /qualia-debug (feedback-loop-first investigation)
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
---
|
|
2
|
+
project_type: {demo or full}
|
|
3
|
+
discovered_at: {YYYY-MM-DD}
|
|
4
|
+
discovery_mode: project
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Project Discovery, {Project Name}
|
|
8
|
+
|
|
9
|
+
The non-technical kickoff interview output. `/qualia-discuss` writes this in PROJECT MODE before `/qualia-new` generates JOURNEY.md. Captures intent, audience, brand, and constraints in the user's own words.
|
|
10
|
+
|
|
11
|
+
Demo path: 8 questions. Full-project path: 14 questions.
|
|
12
|
+
|
|
13
|
+
## 1. The one-line pitch
|
|
14
|
+
|
|
15
|
+
> {What is this thing, in one sentence a stranger would understand?}
|
|
16
|
+
|
|
17
|
+
## 2. Who is it for
|
|
18
|
+
|
|
19
|
+
> {Name three real humans who will use this. Not personas, real names plus their scenario.}
|
|
20
|
+
|
|
21
|
+
## 3. The "remember 24 hours later" sentence
|
|
22
|
+
|
|
23
|
+
> {What does someone remember 24 hours after first using this?}
|
|
24
|
+
|
|
25
|
+
## 4. Three anti-references
|
|
26
|
+
|
|
27
|
+
> {Three sites or apps this should NOT look like, with one-line reasons each.}
|
|
28
|
+
|
|
29
|
+
## 5. Brand voice
|
|
30
|
+
|
|
31
|
+
> {Three adjectives, then one paragraph of voice in motion — an error message, a confirmation, an empty state.}
|
|
32
|
+
|
|
33
|
+
## 6. Success criterion
|
|
34
|
+
|
|
35
|
+
> {How does the client know this worked? One observable outcome.}
|
|
36
|
+
|
|
37
|
+
## 7. Hard constraints
|
|
38
|
+
|
|
39
|
+
> {Anything that is non-negotiable: stack, deadline, compliance, integrations, budget.}
|
|
40
|
+
|
|
41
|
+
## 8. Out of scope
|
|
42
|
+
|
|
43
|
+
> {What is intentionally NOT in this project, even if it would be obvious to add.}
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
The remaining six questions only run for `project_type: full`. Demo mode stops here.
|
|
48
|
+
|
|
49
|
+
## 9. Milestone arc, in the client's words
|
|
50
|
+
|
|
51
|
+
> {After the demo, what's the next chapter? After that, what's the chapter after? Stop at three to five chapters total. The last chapter is always Handoff.}
|
|
52
|
+
|
|
53
|
+
## 10. Compliance and legal
|
|
54
|
+
|
|
55
|
+
> {Anything regulated: payments, medical, legal, finance, accessibility commitments, data residency.}
|
|
56
|
+
|
|
57
|
+
## 11. Integrations
|
|
58
|
+
|
|
59
|
+
> {Third-party systems this must talk to, in priority order.}
|
|
60
|
+
|
|
61
|
+
## 12. Content and copy
|
|
62
|
+
|
|
63
|
+
> {Who writes the copy and where does it live, today and after handoff?}
|
|
64
|
+
|
|
65
|
+
## 13. Team and roles after handoff
|
|
66
|
+
|
|
67
|
+
> {Who maintains this after we ship? What can they do, what can't they do?}
|
|
68
|
+
|
|
69
|
+
## 14. Budget and timeline shape
|
|
70
|
+
|
|
71
|
+
> {Fixed deadline, fixed scope, or fixed budget? Pick one — the other two flex.}
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## How this feeds `/qualia-new`
|
|
76
|
+
|
|
77
|
+
- §1-§5 seed PROJECT.md (one-line pitch, what we're building) and PRODUCT.md (users, register, voice, anti-references).
|
|
78
|
+
- §6 becomes the first row of the success-criteria table in ROADMAP.md.
|
|
79
|
+
- §7-§8 populate PROJECT.md's "Out of Scope" and the constraints section.
|
|
80
|
+
- §9 (full only) seeds JOURNEY.md milestone names + "why now" lines.
|
|
81
|
+
- §10-§14 (full only) feed research scoping and the Handoff milestone checklist.
|
|
82
|
+
|
|
83
|
+
Demo projects skip §9-§14 because they ARE one milestone — the journey is just that milestone plus an implicit "client signs, we extend" branch handled by `/qualia-milestone`.
|
package/templates/project.md
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
project_type: full
|
|
3
|
+
---
|
|
4
|
+
|
|
1
5
|
# {Project Name}
|
|
2
6
|
|
|
3
7
|
## Client
|
|
4
8
|
{client name}
|
|
5
9
|
|
|
10
|
+
## Project Type
|
|
11
|
+
{demo or full — demo is a single shippable milestone for a sales conversation; full is the multi-milestone arc to Handoff}
|
|
12
|
+
|
|
6
13
|
## What We're Building
|
|
7
14
|
{description}
|
|
8
15
|
|
package/tests/bin.test.sh
CHANGED
|
@@ -1131,52 +1131,59 @@ fi
|
|
|
1131
1131
|
echo ""
|
|
1132
1132
|
echo "--- v5.0.0 (visual-polish loop addendum) ---"
|
|
1133
1133
|
|
|
1134
|
-
# 99. qualia-polish
|
|
1134
|
+
# 99. qualia-polish SKILL.md installs (v5.8: polish-loop consolidated into --loop flag)
|
|
1135
1135
|
TMP=$(mktmp)
|
|
1136
1136
|
echo "QS-FAWZI-01" | HOME="$TMP" $NODE "$INSTALL_JS" >/dev/null 2>&1
|
|
1137
|
-
if [ -f "$TMP/.claude/skills/qualia-polish
|
|
1138
|
-
pass "qualia-polish
|
|
1137
|
+
if [ -f "$TMP/.claude/skills/qualia-polish/SKILL.md" ]; then
|
|
1138
|
+
pass "qualia-polish SKILL.md installs"
|
|
1139
1139
|
else
|
|
1140
|
-
fail_case "qualia-polish
|
|
1140
|
+
fail_case "qualia-polish SKILL.md missing after install"
|
|
1141
1141
|
fi
|
|
1142
1142
|
|
|
1143
|
-
# 100. qualia-polish
|
|
1144
|
-
if [ -f "$TMP/.claude/skills/qualia-polish
|
|
1145
|
-
pass "qualia-polish
|
|
1143
|
+
# 100. qualia-polish REFERENCE.md installs (carries the loop spec)
|
|
1144
|
+
if [ -f "$TMP/.claude/skills/qualia-polish/REFERENCE.md" ]; then
|
|
1145
|
+
pass "qualia-polish REFERENCE.md installs"
|
|
1146
1146
|
else
|
|
1147
|
-
fail_case "qualia-polish
|
|
1147
|
+
fail_case "qualia-polish REFERENCE.md missing after install"
|
|
1148
1148
|
fi
|
|
1149
1149
|
|
|
1150
|
-
# 101. qualia-polish
|
|
1151
|
-
if grep -q "design-rubric.md" "$TMP/.claude/skills/qualia-polish
|
|
1152
|
-
pass "qualia-polish
|
|
1150
|
+
# 101. qualia-polish SKILL.md references the design rubric
|
|
1151
|
+
if grep -q "design-rubric.md" "$TMP/.claude/skills/qualia-polish/SKILL.md"; then
|
|
1152
|
+
pass "qualia-polish references design-rubric.md"
|
|
1153
1153
|
else
|
|
1154
|
-
fail_case "qualia-polish
|
|
1154
|
+
fail_case "qualia-polish missing rubric reference"
|
|
1155
1155
|
fi
|
|
1156
1156
|
|
|
1157
|
-
# 102. qualia-polish
|
|
1158
|
-
if grep -q "DEFAULT TO 3" "$TMP/.claude/skills/qualia-polish
|
|
1159
|
-
pass "qualia-polish
|
|
1157
|
+
# 102. qualia-polish REFERENCE.md has the anchored vision eval prompt
|
|
1158
|
+
if grep -q "DEFAULT TO 3" "$TMP/.claude/skills/qualia-polish/REFERENCE.md"; then
|
|
1159
|
+
pass "qualia-polish REFERENCE.md has anchored rubric prompt"
|
|
1160
1160
|
else
|
|
1161
|
-
fail_case "qualia-polish
|
|
1161
|
+
fail_case "qualia-polish REFERENCE.md missing anchored rubric"
|
|
1162
1162
|
fi
|
|
1163
1163
|
|
|
1164
|
-
# 103. qualia-polish
|
|
1165
|
-
if grep -q "LOOP_REGRESSION_DETECTED" "$TMP/.claude/skills/qualia-polish
|
|
1166
|
-
pass "qualia-polish
|
|
1164
|
+
# 103. qualia-polish REFERENCE.md has regression detection (LOOP_REGRESSION_DETECTED)
|
|
1165
|
+
if grep -q "LOOP_REGRESSION_DETECTED" "$TMP/.claude/skills/qualia-polish/REFERENCE.md"; then
|
|
1166
|
+
pass "qualia-polish has regression kill-switch"
|
|
1167
1167
|
else
|
|
1168
|
-
fail_case "qualia-polish
|
|
1168
|
+
fail_case "qualia-polish missing regression kill-switch"
|
|
1169
|
+
fi
|
|
1170
|
+
|
|
1171
|
+
# 103b. qualia-polish SKILL.md documents the --loop flag
|
|
1172
|
+
if grep -q -- "--loop" "$TMP/.claude/skills/qualia-polish/SKILL.md"; then
|
|
1173
|
+
pass "qualia-polish SKILL.md documents --loop flag"
|
|
1174
|
+
else
|
|
1175
|
+
fail_case "qualia-polish SKILL.md missing --loop documentation"
|
|
1169
1176
|
fi
|
|
1170
1177
|
|
|
1171
1178
|
# 104. score.mjs exists in the framework skill scripts
|
|
1172
|
-
if [ -f "$FRAMEWORK_DIR/skills/qualia-polish
|
|
1179
|
+
if [ -f "$FRAMEWORK_DIR/skills/qualia-polish/scripts/score.mjs" ]; then
|
|
1173
1180
|
pass "score.mjs exists in skill scripts"
|
|
1174
1181
|
else
|
|
1175
1182
|
fail_case "score.mjs missing from skill scripts"
|
|
1176
1183
|
fi
|
|
1177
1184
|
|
|
1178
1185
|
# 105. score.mjs computes pass correctly (all dims >= 3)
|
|
1179
|
-
SCORE_OUT=$(echo '{"typography":3,"color":3,"spatial":3,"layout":3,"shadow":3,"motion":3,"microcopy":3,"container":3}' | $NODE "$FRAMEWORK_DIR/skills/qualia-polish
|
|
1186
|
+
SCORE_OUT=$(echo '{"typography":3,"color":3,"spatial":3,"layout":3,"shadow":3,"motion":3,"microcopy":3,"container":3}' | $NODE "$FRAMEWORK_DIR/skills/qualia-polish/scripts/score.mjs" 2>&1)
|
|
1180
1187
|
EXIT=$?
|
|
1181
1188
|
if [ "$EXIT" -eq 0 ] && echo "$SCORE_OUT" | grep -q '"pass": true'; then
|
|
1182
1189
|
pass "score.mjs pass on all-3 scores"
|
|
@@ -1185,7 +1192,7 @@ else
|
|
|
1185
1192
|
fi
|
|
1186
1193
|
|
|
1187
1194
|
# 106. score.mjs computes fail correctly (one dim < 3)
|
|
1188
|
-
SCORE_OUT=$(echo '{"typography":2,"color":3,"spatial":3,"layout":3,"shadow":3,"motion":3,"microcopy":3,"container":3}' | $NODE "$FRAMEWORK_DIR/skills/qualia-polish
|
|
1195
|
+
SCORE_OUT=$(echo '{"typography":2,"color":3,"spatial":3,"layout":3,"shadow":3,"motion":3,"microcopy":3,"container":3}' | $NODE "$FRAMEWORK_DIR/skills/qualia-polish/scripts/score.mjs" 2>&1)
|
|
1189
1196
|
EXIT=$?
|
|
1190
1197
|
if [ "$EXIT" -eq 1 ] && echo "$SCORE_OUT" | grep -q '"pass": false'; then
|
|
1191
1198
|
pass "score.mjs fail on dim < 3"
|
|
@@ -1193,38 +1200,38 @@ else
|
|
|
1193
1200
|
fail_case "score.mjs fail computation" "exit=$EXIT"
|
|
1194
1201
|
fi
|
|
1195
1202
|
|
|
1196
|
-
# 107. qualia-road references
|
|
1197
|
-
if grep -
|
|
1198
|
-
pass "qualia-road references qualia-polish
|
|
1203
|
+
# 107. qualia-road references the polish loop (now via --loop flag)
|
|
1204
|
+
if grep -qE "qualia-polish --loop|/qualia-polish --loop" "$TMP/.claude/skills/qualia-road/SKILL.md"; then
|
|
1205
|
+
pass "qualia-road references /qualia-polish --loop"
|
|
1199
1206
|
else
|
|
1200
|
-
fail_case "qualia-road missing qualia-polish
|
|
1207
|
+
fail_case "qualia-road missing /qualia-polish --loop reference"
|
|
1201
1208
|
fi
|
|
1202
1209
|
|
|
1203
1210
|
# 108. package.json version is 5.x (5.1+ accepted; v5.1 / v5.2 share the v5 line)
|
|
1204
|
-
if grep -qE '"5\.[
|
|
1211
|
+
if grep -qE '"5\.([1-9]|[1-9][0-9])\.' "$FRAMEWORK_DIR/package.json"; then
|
|
1205
1212
|
pass "package.json version is 5.x"
|
|
1206
1213
|
else
|
|
1207
1214
|
fail_case "package.json version not 5.x"
|
|
1208
1215
|
fi
|
|
1209
1216
|
|
|
1210
1217
|
# 109. loop.mjs installs (orchestrator)
|
|
1211
|
-
if [ -f "$TMP/.claude/skills/qualia-polish
|
|
1212
|
-
pass "qualia-polish
|
|
1218
|
+
if [ -f "$TMP/.claude/skills/qualia-polish/scripts/loop.mjs" ]; then
|
|
1219
|
+
pass "qualia-polish scripts/loop.mjs installs"
|
|
1213
1220
|
else
|
|
1214
1221
|
fail_case "scripts/loop.mjs missing — install.js scripts/ subfolder copy broken"
|
|
1215
1222
|
fi
|
|
1216
1223
|
|
|
1217
1224
|
# 110. playwright-capture.mjs installs (capture helper)
|
|
1218
|
-
if [ -f "$TMP/.claude/skills/qualia-polish
|
|
1219
|
-
pass "qualia-polish
|
|
1225
|
+
if [ -f "$TMP/.claude/skills/qualia-polish/scripts/playwright-capture.mjs" ]; then
|
|
1226
|
+
pass "qualia-polish scripts/playwright-capture.mjs installs"
|
|
1220
1227
|
else
|
|
1221
1228
|
fail_case "scripts/playwright-capture.mjs missing"
|
|
1222
1229
|
fi
|
|
1223
1230
|
|
|
1224
1231
|
# 111. fixtures/ subfolder installs (self-test pages)
|
|
1225
|
-
if [ -f "$TMP/.claude/skills/qualia-polish
|
|
1226
|
-
[ -f "$TMP/.claude/skills/qualia-polish
|
|
1227
|
-
pass "qualia-polish
|
|
1232
|
+
if [ -f "$TMP/.claude/skills/qualia-polish/fixtures/clean.html" ] && \
|
|
1233
|
+
[ -f "$TMP/.claude/skills/qualia-polish/fixtures/broken.html" ]; then
|
|
1234
|
+
pass "qualia-polish fixtures/ installs (clean.html + broken.html)"
|
|
1228
1235
|
else
|
|
1229
1236
|
fail_case "fixtures/ subfolder not copied by install.js"
|
|
1230
1237
|
fi
|
|
@@ -1237,7 +1244,7 @@ else
|
|
|
1237
1244
|
fi
|
|
1238
1245
|
|
|
1239
1246
|
# 113. loop.mjs parses as valid Node ESM
|
|
1240
|
-
EXIT=0; $NODE --check "$FRAMEWORK_DIR/skills/qualia-polish
|
|
1247
|
+
EXIT=0; $NODE --check "$FRAMEWORK_DIR/skills/qualia-polish/scripts/loop.mjs" 2>/dev/null || EXIT=$?
|
|
1241
1248
|
if [ "$EXIT" -eq 0 ]; then
|
|
1242
1249
|
pass "loop.mjs parses as valid Node ESM"
|
|
1243
1250
|
else
|
|
@@ -1245,7 +1252,7 @@ else
|
|
|
1245
1252
|
fi
|
|
1246
1253
|
|
|
1247
1254
|
# 114. playwright-capture.mjs parses as valid Node ESM
|
|
1248
|
-
EXIT=0; $NODE --check "$FRAMEWORK_DIR/skills/qualia-polish
|
|
1255
|
+
EXIT=0; $NODE --check "$FRAMEWORK_DIR/skills/qualia-polish/scripts/playwright-capture.mjs" 2>/dev/null || EXIT=$?
|
|
1249
1256
|
if [ "$EXIT" -eq 0 ]; then
|
|
1250
1257
|
pass "playwright-capture.mjs parses as valid Node ESM"
|
|
1251
1258
|
else
|
|
@@ -1255,7 +1262,7 @@ fi
|
|
|
1255
1262
|
# 115. loop.mjs init creates a valid state file
|
|
1256
1263
|
TMP_STATE=$(mktmp)/qpl-state.json
|
|
1257
1264
|
mkdir -p "$(dirname "$TMP_STATE")"
|
|
1258
|
-
EXIT=0; $NODE "$FRAMEWORK_DIR/skills/qualia-polish
|
|
1265
|
+
EXIT=0; $NODE "$FRAMEWORK_DIR/skills/qualia-polish/scripts/loop.mjs" init \
|
|
1259
1266
|
--state "$TMP_STATE" --url "http://localhost:3000" --max 4 --budget 50000 >/dev/null 2>&1 || EXIT=$?
|
|
1260
1267
|
if [ "$EXIT" -eq 0 ] && [ -f "$TMP_STATE" ] && grep -q '"verdict": "pending"' "$TMP_STATE"; then
|
|
1261
1268
|
pass "loop.mjs init creates valid state.json"
|
|
@@ -1267,7 +1274,7 @@ fi
|
|
|
1267
1274
|
TMP_STATE2=$(mktmp)/qpl-kill.json
|
|
1268
1275
|
TMP_EVAL=$(mktmp)/qpl-eval.json
|
|
1269
1276
|
mkdir -p "$(dirname "$TMP_STATE2")" "$(dirname "$TMP_EVAL")"
|
|
1270
|
-
$NODE "$FRAMEWORK_DIR/skills/qualia-polish
|
|
1277
|
+
$NODE "$FRAMEWORK_DIR/skills/qualia-polish/scripts/loop.mjs" init \
|
|
1271
1278
|
--state "$TMP_STATE2" --url "http://localhost:3000" --max 8 >/dev/null 2>&1
|
|
1272
1279
|
# write 3 identical evals
|
|
1273
1280
|
KILL_OK=true
|
|
@@ -1282,7 +1289,7 @@ for ITER in 1 2 3; do
|
|
|
1282
1289
|
"pass": false
|
|
1283
1290
|
}
|
|
1284
1291
|
EOF
|
|
1285
|
-
EXIT=0; $NODE "$FRAMEWORK_DIR/skills/qualia-polish
|
|
1292
|
+
EXIT=0; $NODE "$FRAMEWORK_DIR/skills/qualia-polish/scripts/loop.mjs" record \
|
|
1286
1293
|
--state "$TMP_STATE2" --eval "$TMP_EVAL" >/dev/null 2>&1 || EXIT=$?
|
|
1287
1294
|
if [ "$ITER" -lt 3 ] && [ "$EXIT" -ne 1 ]; then KILL_OK=false; fi
|
|
1288
1295
|
if [ "$ITER" -eq 3 ] && [ "$EXIT" -ne 3 ]; then KILL_OK=false; fi
|
|
@@ -1430,7 +1437,7 @@ fi
|
|
|
1430
1437
|
|
|
1431
1438
|
# 128. package.json bumped to 5.x (5.1+ accepted; 5.2 is the v5.2 release)
|
|
1432
1439
|
PKG_V=$($NODE -e 'console.log(require("'"$FRAMEWORK_DIR"'/package.json").version)')
|
|
1433
|
-
if echo "$PKG_V" | grep -qE "^5\.[
|
|
1440
|
+
if echo "$PKG_V" | grep -qE "^5\.([1-9]|[1-9][0-9])\."; then
|
|
1434
1441
|
pass "package.json version bumped to 5.x ($PKG_V)"
|
|
1435
1442
|
else
|
|
1436
1443
|
fail_case "package.json version not 5.x" "got=$PKG_V"
|
|
@@ -1442,7 +1449,7 @@ echo "--- v5.2.0 (polish-loop reliability) ---"
|
|
|
1442
1449
|
# 129. loop.mjs init accepts --routes and stores the URL list
|
|
1443
1450
|
TMP_S=$(mktmp)/qpl-routes.json
|
|
1444
1451
|
mkdir -p "$(dirname "$TMP_S")"
|
|
1445
|
-
EXIT=0; $NODE "$FRAMEWORK_DIR/skills/qualia-polish
|
|
1452
|
+
EXIT=0; $NODE "$FRAMEWORK_DIR/skills/qualia-polish/scripts/loop.mjs" init \
|
|
1446
1453
|
--state "$TMP_S" \
|
|
1447
1454
|
--routes "http://x.test/a,http://x.test/b,http://x.test/c" \
|
|
1448
1455
|
--max 4 >/dev/null 2>&1 || EXIT=$?
|
|
@@ -1466,7 +1473,7 @@ fi
|
|
|
1466
1473
|
# 131. loop.mjs init accepts --reduced-motion and records it in state
|
|
1467
1474
|
TMP_S2=$(mktmp)/qpl-rm.json
|
|
1468
1475
|
mkdir -p "$(dirname "$TMP_S2")"
|
|
1469
|
-
EXIT=0; $NODE "$FRAMEWORK_DIR/skills/qualia-polish
|
|
1476
|
+
EXIT=0; $NODE "$FRAMEWORK_DIR/skills/qualia-polish/scripts/loop.mjs" init \
|
|
1470
1477
|
--state "$TMP_S2" --url "http://x.test/" --reduced-motion >/dev/null 2>&1 || EXIT=$?
|
|
1471
1478
|
if [ "$EXIT" -eq 0 ] && grep -q '"reduced_motion": true' "$TMP_S2"; then
|
|
1472
1479
|
pass "loop.mjs init --reduced-motion records state.reduced_motion=true"
|
|
@@ -1475,7 +1482,7 @@ else
|
|
|
1475
1482
|
fi
|
|
1476
1483
|
|
|
1477
1484
|
# 132. playwright-capture.mjs accepts --reduced-motion (parses without error)
|
|
1478
|
-
EXIT=0; OUT=$($NODE "$FRAMEWORK_DIR/skills/qualia-polish
|
|
1485
|
+
EXIT=0; OUT=$($NODE "$FRAMEWORK_DIR/skills/qualia-polish/scripts/playwright-capture.mjs" --help 2>&1) || EXIT=$?
|
|
1479
1486
|
if [ "$EXIT" -eq 0 ] && echo "$OUT" | grep -q -- "--reduced-motion"; then
|
|
1480
1487
|
pass "playwright-capture.mjs --help documents --reduced-motion"
|
|
1481
1488
|
else
|
|
@@ -1485,7 +1492,7 @@ fi
|
|
|
1485
1492
|
# 133. loop.mjs init rejects when neither --url nor --routes given
|
|
1486
1493
|
TMP_S3=$(mktmp)/qpl-nourl.json
|
|
1487
1494
|
mkdir -p "$(dirname "$TMP_S3")"
|
|
1488
|
-
EXIT=0; $NODE "$FRAMEWORK_DIR/skills/qualia-polish
|
|
1495
|
+
EXIT=0; $NODE "$FRAMEWORK_DIR/skills/qualia-polish/scripts/loop.mjs" init \
|
|
1489
1496
|
--state "$TMP_S3" --max 4 >/dev/null 2>&1 || EXIT=$?
|
|
1490
1497
|
if [ "$EXIT" -eq 2 ]; then
|
|
1491
1498
|
pass "loop.mjs init rejects missing --url/--routes (exit 2)"
|
|
@@ -1496,9 +1503,9 @@ fi
|
|
|
1496
1503
|
# 134. loop.mjs report mentions multi-route when state.urls > 1
|
|
1497
1504
|
TMP_S4=$(mktmp)/qpl-rep.json
|
|
1498
1505
|
mkdir -p "$(dirname "$TMP_S4")"
|
|
1499
|
-
$NODE "$FRAMEWORK_DIR/skills/qualia-polish
|
|
1506
|
+
$NODE "$FRAMEWORK_DIR/skills/qualia-polish/scripts/loop.mjs" init \
|
|
1500
1507
|
--state "$TMP_S4" --routes "http://a/,http://b/" >/dev/null 2>&1
|
|
1501
|
-
REP=$($NODE "$FRAMEWORK_DIR/skills/qualia-polish
|
|
1508
|
+
REP=$($NODE "$FRAMEWORK_DIR/skills/qualia-polish/scripts/loop.mjs" report --state "$TMP_S4" 2>&1)
|
|
1502
1509
|
if echo "$REP" | grep -q "URLs (2)"; then
|
|
1503
1510
|
pass "loop.mjs report renders multi-route header"
|
|
1504
1511
|
else
|
|
@@ -1512,27 +1519,32 @@ echo "--- v5.3.0 (Matt Pocock gaps: prd, hook-gen, parallel-interface) ---"
|
|
|
1512
1519
|
TMP=$(mktmp)
|
|
1513
1520
|
echo "QS-FAWZI-01" | HOME="$TMP" $NODE "$INSTALL_JS" >/dev/null 2>&1
|
|
1514
1521
|
|
|
1515
|
-
# 135. qualia-prd
|
|
1516
|
-
|
|
1517
|
-
|
|
1522
|
+
# 135-137. /qualia-prd removed in v5.8.0 (was deprecated, overlapped /qualia-discuss).
|
|
1523
|
+
# Assert non-existence so the framework cannot accidentally re-ship it.
|
|
1524
|
+
if [ ! -f "$TMP/.claude/skills/qualia-prd/SKILL.md" ]; then
|
|
1525
|
+
pass "qualia-prd removed (v5.8.0 cleanup)"
|
|
1526
|
+
else
|
|
1527
|
+
fail_case "qualia-prd unexpectedly present after v5.8.0 removal"
|
|
1528
|
+
fi
|
|
1529
|
+
|
|
1530
|
+
# v5.8.0: assert /qualia-quick + /qualia-task also removed (were deprecated in v5.7).
|
|
1531
|
+
if [ ! -f "$TMP/.claude/skills/qualia-quick/SKILL.md" ]; then
|
|
1532
|
+
pass "qualia-quick removed (v5.8.0 cleanup)"
|
|
1518
1533
|
else
|
|
1519
|
-
fail_case "qualia-
|
|
1534
|
+
fail_case "qualia-quick unexpectedly present after v5.8.0 removal"
|
|
1520
1535
|
fi
|
|
1521
1536
|
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
&& grep -q "/qualia-issues" "$TMP/.claude/skills/qualia-prd/SKILL.md"; then
|
|
1525
|
-
pass "qualia-prd describes synthesis flow + pairs with /qualia-issues"
|
|
1537
|
+
if [ ! -f "$TMP/.claude/skills/qualia-task/SKILL.md" ]; then
|
|
1538
|
+
pass "qualia-task removed (v5.8.0 cleanup)"
|
|
1526
1539
|
else
|
|
1527
|
-
fail_case "qualia-
|
|
1540
|
+
fail_case "qualia-task unexpectedly present after v5.8.0 removal"
|
|
1528
1541
|
fi
|
|
1529
1542
|
|
|
1530
|
-
#
|
|
1531
|
-
if
|
|
1532
|
-
|
|
1533
|
-
pass "qualia-prd documents fork-based synthesis (token discipline)"
|
|
1543
|
+
# v5.8.0: assert /qualia-feature is the canonical single-feature surface.
|
|
1544
|
+
if [ -f "$TMP/.claude/skills/qualia-feature/SKILL.md" ]; then
|
|
1545
|
+
pass "qualia-feature installed (canonical single-feature surface)"
|
|
1534
1546
|
else
|
|
1535
|
-
fail_case "qualia-
|
|
1547
|
+
fail_case "qualia-feature missing after install"
|
|
1536
1548
|
fi
|
|
1537
1549
|
|
|
1538
1550
|
# 138. qualia-hook-gen skill installs
|
|
@@ -1577,7 +1589,7 @@ fi
|
|
|
1577
1589
|
|
|
1578
1590
|
# 143. package.json version is 5.x (5.1+ accepted; v5.3 is the v5.3 release)
|
|
1579
1591
|
PKG_V=$($NODE -e 'console.log(require("'"$FRAMEWORK_DIR"'/package.json").version)')
|
|
1580
|
-
if echo "$PKG_V" | grep -qE "^5\.[
|
|
1592
|
+
if echo "$PKG_V" | grep -qE "^5\.([1-9]|[1-9][0-9])\."; then
|
|
1581
1593
|
pass "package.json version is 5.x ($PKG_V) — v5.3 accepted"
|
|
1582
1594
|
else
|
|
1583
1595
|
fail_case "package.json version not 5.x" "got=$PKG_V"
|
|
@@ -121,8 +121,8 @@ else
|
|
|
121
121
|
fail_case "gradient detection" "expected exit 1, got $EXIT_CODE"
|
|
122
122
|
fi
|
|
123
123
|
|
|
124
|
-
# ── Existing fixture: skills/qualia-polish
|
|
125
|
-
FIXTURE="$(cd "$(dirname "$0")/.." && pwd)/skills/qualia-polish
|
|
124
|
+
# ── Existing fixture: skills/qualia-polish/fixtures/broken.html ──
|
|
125
|
+
FIXTURE="$(cd "$(dirname "$0")/.." && pwd)/skills/qualia-polish/fixtures/broken.html"
|
|
126
126
|
if [ -f "$FIXTURE" ]; then
|
|
127
127
|
EXIT_CODE=0
|
|
128
128
|
$NODE "$SLOP_DETECT" "$FIXTURE" >/dev/null 2>&1 || EXIT_CODE=$?
|