qualia-framework 6.8.0 → 6.9.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.
Files changed (77) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/bin/install.js +212 -17
  3. package/bin/state.js +70 -5
  4. package/docs/EMPLOYEE-QUICKSTART.md +162 -0
  5. package/package.json +2 -1
  6. package/skills/qualia-doctor/SKILL.md +62 -0
  7. package/skills/qualia-new/REFERENCE.md +7 -0
  8. package/skills/qualia-new/SKILL.md +42 -0
  9. package/skills/qualia-report/SKILL.md +13 -0
  10. package/templates/stacks/README.md +110 -0
  11. package/templates/stacks/ai-agent/env.required.json +44 -0
  12. package/templates/stacks/ai-agent/phases.md +53 -0
  13. package/templates/stacks/ai-agent/scaffold/.env.example +12 -0
  14. package/templates/stacks/ai-agent/scaffold/README.md +31 -0
  15. package/templates/stacks/ai-agent/scaffold/app/api/chat/route.ts +33 -0
  16. package/templates/stacks/ai-agent/scaffold/app/globals.css +13 -0
  17. package/templates/stacks/ai-agent/scaffold/app/layout.tsx +19 -0
  18. package/templates/stacks/ai-agent/scaffold/app/page.tsx +12 -0
  19. package/templates/stacks/ai-agent/scaffold/evals/cases.json +23 -0
  20. package/templates/stacks/ai-agent/scaffold/lib/openrouter/client.ts +51 -0
  21. package/templates/stacks/ai-agent/scaffold/lib/prompts/system.ts +6 -0
  22. package/templates/stacks/ai-agent/scaffold/lib/supabase/client.ts +10 -0
  23. package/templates/stacks/ai-agent/scaffold/lib/supabase/server.ts +28 -0
  24. package/templates/stacks/ai-agent/scaffold/next.config.mjs +7 -0
  25. package/templates/stacks/ai-agent/scaffold/package.json +29 -0
  26. package/templates/stacks/ai-agent/scaffold/postcss.config.mjs +7 -0
  27. package/templates/stacks/ai-agent/scaffold/supabase/migrations/0001_init.sql +41 -0
  28. package/templates/stacks/ai-agent/scaffold/tsconfig.json +21 -0
  29. package/templates/stacks/ai-agent/stack.json +9 -0
  30. package/templates/stacks/ai-agent/verify-checklist.md +31 -0
  31. package/templates/stacks/full-app/env.required.json +20 -0
  32. package/templates/stacks/full-app/phases.md +45 -0
  33. package/templates/stacks/full-app/scaffold/.env.example +7 -0
  34. package/templates/stacks/full-app/scaffold/README.md +28 -0
  35. package/templates/stacks/full-app/scaffold/app/globals.css +14 -0
  36. package/templates/stacks/full-app/scaffold/app/layout.tsx +19 -0
  37. package/templates/stacks/full-app/scaffold/app/page.tsx +20 -0
  38. package/templates/stacks/full-app/scaffold/lib/supabase/client.ts +10 -0
  39. package/templates/stacks/full-app/scaffold/lib/supabase/server.ts +31 -0
  40. package/templates/stacks/full-app/scaffold/next.config.mjs +7 -0
  41. package/templates/stacks/full-app/scaffold/package.json +29 -0
  42. package/templates/stacks/full-app/scaffold/postcss.config.mjs +7 -0
  43. package/templates/stacks/full-app/scaffold/supabase/migrations/0001_init.sql +27 -0
  44. package/templates/stacks/full-app/scaffold/tsconfig.json +21 -0
  45. package/templates/stacks/full-app/stack.json +9 -0
  46. package/templates/stacks/full-app/verify-checklist.md +32 -0
  47. package/templates/stacks/internal-tool/env.required.json +20 -0
  48. package/templates/stacks/internal-tool/phases.md +45 -0
  49. package/templates/stacks/internal-tool/scaffold/.env.example +7 -0
  50. package/templates/stacks/internal-tool/scaffold/README.md +29 -0
  51. package/templates/stacks/internal-tool/scaffold/app/globals.css +13 -0
  52. package/templates/stacks/internal-tool/scaffold/app/layout.tsx +20 -0
  53. package/templates/stacks/internal-tool/scaffold/app/page.tsx +22 -0
  54. package/templates/stacks/internal-tool/scaffold/lib/supabase/client.ts +9 -0
  55. package/templates/stacks/internal-tool/scaffold/lib/supabase/server.ts +28 -0
  56. package/templates/stacks/internal-tool/scaffold/next.config.mjs +6 -0
  57. package/templates/stacks/internal-tool/scaffold/package.json +29 -0
  58. package/templates/stacks/internal-tool/scaffold/postcss.config.mjs +7 -0
  59. package/templates/stacks/internal-tool/scaffold/supabase/migrations/0001_init.sql +28 -0
  60. package/templates/stacks/internal-tool/scaffold/tsconfig.json +21 -0
  61. package/templates/stacks/internal-tool/stack.json +9 -0
  62. package/templates/stacks/internal-tool/verify-checklist.md +31 -0
  63. package/templates/stacks/landing-page/env.required.json +8 -0
  64. package/templates/stacks/landing-page/phases.md +42 -0
  65. package/templates/stacks/landing-page/scaffold/.env.example +3 -0
  66. package/templates/stacks/landing-page/scaffold/README.md +25 -0
  67. package/templates/stacks/landing-page/scaffold/app/globals.css +14 -0
  68. package/templates/stacks/landing-page/scaffold/app/layout.tsx +19 -0
  69. package/templates/stacks/landing-page/scaffold/app/page.tsx +21 -0
  70. package/templates/stacks/landing-page/scaffold/next.config.mjs +7 -0
  71. package/templates/stacks/landing-page/scaffold/package.json +26 -0
  72. package/templates/stacks/landing-page/scaffold/postcss.config.mjs +7 -0
  73. package/templates/stacks/landing-page/scaffold/tsconfig.json +21 -0
  74. package/templates/stacks/landing-page/stack.json +9 -0
  75. package/templates/stacks/landing-page/verify-checklist.md +28 -0
  76. package/tests/bin.test.sh +3 -3
  77. package/tests/state.test.sh +83 -0
@@ -0,0 +1,28 @@
1
+ # Landing Page — Definition of Done
2
+
3
+ Per-stack verify checklist. Inherits `rules/constitution.md` and the `website` archetype DoD.
4
+
5
+ ## Build & Deploy
6
+ - [ ] `npx tsc --noEmit` exits 0.
7
+ - [ ] `next build` succeeds; output is static/SSG (no accidental server-only data fetch on a marketing page).
8
+ - [ ] Deploys to Vercel; homepage returns HTTP 200.
9
+ - [ ] Custom domain wired (production).
10
+
11
+ ## Design (anti-slop)
12
+ - [ ] DESIGN.md committed; distinctive type pair (NOT Inter/Roboto/Arial/Helvetica/system-ui).
13
+ - [ ] OKLCH palette; neutrals tinted toward brand hue; no raw `#000`/`#fff`.
14
+ - [ ] 8px spacing grid + fluid `clamp()` page padding.
15
+ - [ ] Responsive at 375px and 1440px; touch targets ≥44px.
16
+
17
+ ## Content & Conversion
18
+ - [ ] Real copy — zero "lorem ipsum", zero placeholder text.
19
+ - [ ] Primary CTA present, reachable, and instrumented with an analytics event.
20
+ - [ ] Contact form (if any) validates client-side and has success + error states.
21
+
22
+ ## SEO & a11y
23
+ - [ ] Per-page title + meta description + OG tags; sitemap + favicon present.
24
+ - [ ] Alt text on every image; labels on every input; keyboard navigable.
25
+ - [ ] AA contrast verified.
26
+
27
+ ## Out of scope (by design)
28
+ - No Supabase, no auth, no `SUPABASE_SERVICE_ROLE_KEY`. If the project needs accounts or persisted data, it is a `full-app`, not a `landing-page`.
package/tests/bin.test.sh CHANGED
@@ -1466,10 +1466,10 @@ mkdir -p "$TMP/.codex"
1466
1466
  echo "OLD USER CONTENT" > "$TMP/.codex/AGENTS.md"
1467
1467
  printf 'QS-FAWZI-11\n2\n' | HOME="$TMP" $NODE "$INSTALL_JS" > "$TMP/log.txt" 2>&1
1468
1468
  EXIT=$?
1469
- BAK_COUNT=$(ls "$TMP/.codex/"AGENTS.md.bak.* 2>/dev/null | wc -l)
1469
+ BAK_COUNT=$(ls "$TMP/.codex/backups/"AGENTS.md.bak.* 2>/dev/null | wc -l)
1470
1470
  if [ "$EXIT" -eq 0 ] \
1471
1471
  && [ "$BAK_COUNT" -ge 1 ] \
1472
- && grep -q "OLD USER CONTENT" "$TMP/.codex/"AGENTS.md.bak.* \
1472
+ && grep -q "OLD USER CONTENT" "$TMP/.codex/backups/"AGENTS.md.bak.* \
1473
1473
  && ! grep -q "OLD USER CONTENT" "$TMP/.codex/AGENTS.md"; then
1474
1474
  pass "Codex AGENTS.md backup-before-overwrite preserves prior content"
1475
1475
  else
@@ -1482,7 +1482,7 @@ TMP=$(mktmp)
1482
1482
  printf 'QS-FAWZI-11\n2\n' | HOME="$TMP" $NODE "$INSTALL_JS" > "$TMP/log.txt" 2>&1
1483
1483
  # Re-run with same input — content should be identical, no new backup.
1484
1484
  printf 'QS-FAWZI-11\n2\n' | HOME="$TMP" $NODE "$INSTALL_JS" > "$TMP/log2.txt" 2>&1
1485
- BAK_COUNT=$(ls "$TMP/.codex/"AGENTS.md.bak.* 2>/dev/null | wc -l)
1485
+ BAK_COUNT=$(ls "$TMP/.codex/backups/"AGENTS.md.bak.* 2>/dev/null | wc -l)
1486
1486
  if [ "$BAK_COUNT" -eq 0 ]; then
1487
1487
  pass "Codex re-install with identical content → no redundant .bak"
1488
1488
  else
@@ -1011,6 +1011,89 @@ else
1011
1011
  fail_case "close-milestone + init" "got=$RESULT expected=2,4,1,1,1,0"
1012
1012
  fi
1013
1013
 
1014
+ # 46b. close-milestone resolves the REAL milestone name from JOURNEY.md
1015
+ # instead of emitting a "Milestone N" placeholder when tracking.json has
1016
+ # no (or a placeholder) milestone_name.
1017
+ TMP=$(make_project)
1018
+ cat > "$TMP/.planning/JOURNEY.md" <<'JOURNEY'
1019
+ # Journey
1020
+
1021
+ ## Milestone 1 · Foundation Arc
1022
+
1023
+ Some prose.
1024
+
1025
+ ## Milestone 2 · Core Features
1026
+ JOURNEY
1027
+ $NODE -e "
1028
+ const fs = require('fs');
1029
+ const t = JSON.parse(fs.readFileSync('$TMP/.planning/tracking.json','utf8'));
1030
+ t.milestone_name = 'Milestone 1'; // placeholder — must lose to JOURNEY.md
1031
+ fs.writeFileSync('$TMP/.planning/tracking.json', JSON.stringify(t, null, 2));
1032
+ "
1033
+ (cd "$TMP" && $NODE "$STATE_JS" close-milestone --force >/dev/null 2>&1)
1034
+ RESULT=$($NODE -e "
1035
+ const t = JSON.parse(require('fs').readFileSync('$TMP/.planning/tracking.json','utf8'));
1036
+ console.log(t.milestones[0].name + '|' + t.milestone_name);
1037
+ ")
1038
+ if [ "$RESULT" = "Foundation Arc|Core Features" ]; then
1039
+ pass "close-milestone resolves real name from JOURNEY.md (no placeholder)"
1040
+ else
1041
+ fail_case "close-milestone JOURNEY name resolution" "got=$RESULT expected='Foundation Arc|Core Features'"
1042
+ fi
1043
+
1044
+ # 46c. close-milestone dedupes: same real name already logged under a
1045
+ # different (legacy string) num updates that entry instead of pushing a
1046
+ # duplicate.
1047
+ TMP=$(make_project)
1048
+ cat > "$TMP/.planning/JOURNEY.md" <<'JOURNEY'
1049
+ ## Milestone 1 · Foundation Arc
1050
+ JOURNEY
1051
+ $NODE -e "
1052
+ const fs = require('fs');
1053
+ const t = JSON.parse(fs.readFileSync('$TMP/.planning/tracking.json','utf8'));
1054
+ t.milestone_name = '';
1055
+ t.milestones = [{ num: '9', name: 'Foundation Arc', total_phases: 2, phases_completed: 2, tasks_completed: 0, shipped_url: '', closed_at: '' }];
1056
+ fs.writeFileSync('$TMP/.planning/tracking.json', JSON.stringify(t, null, 2));
1057
+ "
1058
+ (cd "$TMP" && $NODE "$STATE_JS" close-milestone --force >/dev/null 2>&1)
1059
+ RESULT=$($NODE -e "
1060
+ const t = JSON.parse(require('fs').readFileSync('$TMP/.planning/tracking.json','utf8'));
1061
+ console.log(t.milestones.length + '|' + t.milestones[0].num + '|' + t.milestones[0].name);
1062
+ ")
1063
+ if [ "$RESULT" = "1|1|Foundation Arc" ]; then
1064
+ pass "close-milestone dedupes same-name entry under different num"
1065
+ else
1066
+ fail_case "close-milestone name dedupe" "got=$RESULT expected='1|1|Foundation Arc'"
1067
+ fi
1068
+
1069
+ # 46d. backfill-milestones repairs a placeholder-named real-close entry in
1070
+ # place (fixes the name, keeps the richer close data like tasks_completed).
1071
+ TMP=$(make_project)
1072
+ cat > "$TMP/.planning/JOURNEY.md" <<'JOURNEY'
1073
+ # Journey
1074
+
1075
+ | # | Milestone | Status | Phases | Closed |
1076
+ |---|-----------|--------|--------|--------|
1077
+ | 1 | Foundation Arc | CLOSED | 1–2 | 2026-01-01 |
1078
+ | 2 | Core Features | OPEN | rolling | — |
1079
+ JOURNEY
1080
+ $NODE -e "
1081
+ const fs = require('fs');
1082
+ const t = JSON.parse(fs.readFileSync('$TMP/.planning/tracking.json','utf8'));
1083
+ t.milestones = [{ num: '1', name: 'Milestone 1', total_phases: 2, phases_completed: 2, tasks_completed: 7, shipped_url: 'https://x.test', closed_at: '2026-01-01T00:00:00.000Z' }];
1084
+ fs.writeFileSync('$TMP/.planning/tracking.json', JSON.stringify(t, null, 2));
1085
+ "
1086
+ (cd "$TMP" && $NODE "$STATE_JS" backfill-milestones >/dev/null 2>&1)
1087
+ RESULT=$($NODE -e "
1088
+ const t = JSON.parse(require('fs').readFileSync('$TMP/.planning/tracking.json','utf8'));
1089
+ console.log(t.milestones.length + '|' + t.milestones[0].name + '|' + t.milestones[0].tasks_completed + '|' + t.milestone_name);
1090
+ ")
1091
+ if [ "$RESULT" = "1|Foundation Arc|7|Core Features" ]; then
1092
+ pass "backfill-milestones repairs placeholder name, keeps real close data"
1093
+ else
1094
+ fail_case "backfill-milestones placeholder repair" "got=$RESULT expected='1|Foundation Arc|7|Core Features'"
1095
+ fi
1096
+
1014
1097
  # ─── Backward compatibility ──────────────────────────────
1015
1098
  echo ""
1016
1099
  echo "backward compatibility:"