@appsforgood/next-supabase-kit 0.1.4 → 0.1.6
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/CHANGELOG.md +12 -0
- package/DOGFOOD.md +24 -0
- package/LOOP_CODING.md +107 -0
- package/MAINTAINER_RELEASE.md +100 -0
- package/README.md +40 -4
- package/REPOSITORY_SETTINGS.md +7 -3
- package/SUPPLY_CHAIN.md +5 -5
- package/UPGRADE.md +2 -1
- package/antigravity/commands/accessibility-pass.toml +16 -0
- package/antigravity/commands/browser-qa.toml +18 -0
- package/antigravity/commands/distinctiveness-pass.toml +16 -0
- package/antigravity/commands/frontend.toml +5 -4
- package/antigravity/commands/layout-cleanup.toml +16 -0
- package/antigravity/commands/responsive-cleanup.toml +16 -0
- package/antigravity/commands/screenshot-critique.toml +16 -0
- package/antigravity/commands/ui-audit.toml +17 -0
- package/antigravity/commands/ui-polish.toml +17 -0
- package/antigravity/plugin.json +9 -0
- package/checklists/ui-acceptance-rubric.md +58 -0
- package/checklists/ui-detectors.md +75 -0
- package/dist/index.js +1090 -411
- package/dist/index.js.map +1 -1
- package/dist/studio/office/assets/office.css +188 -29
- package/dist/studio/office/assets/office.js +72 -50
- package/dist/studio/wizard/assets/wizard.css +157 -26
- package/dist/studio/wizard/assets/wizard.js +78 -70
- package/examples/next-supabase-installed/.agent-kit/agent-roster.json +7 -3
- package/examples/next-supabase-installed/.agent-kit/manifest.json +13 -11
- package/examples/next-supabase-installed/audit-output.json +22 -2
- package/examples/next-supabase-installed/tree.txt +1 -0
- package/package.json +28 -7
- package/prompts/ui-command-index.md +124 -0
- package/research/summaries/agentic-engineering-maturity-levels.md +54 -0
- package/rosters/next-supabase-default-council.json +37 -12
- package/runtime-skills/ui-improvement-harness/SKILL.md +12 -0
- package/schemas/agentic-level.schema.json +47 -0
- package/schemas/onboarding-state.schema.json +4 -1
- package/skills/ui-improvement-harness.md +96 -0
- package/templates/next-supabase/AGENT_ROSTER.md +6 -3
- package/templates/next-supabase/ASSISTANT_ADAPTERS.md +3 -1
- package/templates/next-supabase/DECISIONS.md +14 -0
- package/templates/next-supabase/DESIGN.md +3 -0
- package/templates/next-supabase/DOCS.md +7 -1
- package/templates/next-supabase/LOOP_CODING.md +98 -0
- package/templates/next-supabase/QUALITY_GATES.md +4 -2
- package/templates/next-supabase/SKILLS.md +14 -0
- package/templates/next-supabase/SPEC.md +5 -1
- package/templates/next-supabase/STYLE_GUIDE.md +3 -1
- package/templates/next-supabase/TESTING.md +14 -0
|
@@ -15,17 +15,28 @@
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
@media (prefers-reduced-motion: reduce) {
|
|
18
|
-
*,
|
|
18
|
+
*,
|
|
19
|
+
*::before,
|
|
20
|
+
*::after {
|
|
19
21
|
animation-duration: 0.01ms !important;
|
|
20
22
|
transition-duration: 0.01ms !important;
|
|
21
23
|
}
|
|
22
24
|
}
|
|
23
25
|
|
|
24
|
-
* {
|
|
26
|
+
* {
|
|
27
|
+
box-sizing: border-box;
|
|
28
|
+
}
|
|
25
29
|
|
|
26
30
|
body {
|
|
27
31
|
margin: 0;
|
|
28
|
-
font-family:
|
|
32
|
+
font-family:
|
|
33
|
+
Inter,
|
|
34
|
+
ui-sans-serif,
|
|
35
|
+
system-ui,
|
|
36
|
+
-apple-system,
|
|
37
|
+
BlinkMacSystemFont,
|
|
38
|
+
"Segoe UI",
|
|
39
|
+
sans-serif;
|
|
29
40
|
color: var(--ink);
|
|
30
41
|
background: var(--bg);
|
|
31
42
|
line-height: 1.55;
|
|
@@ -131,6 +142,58 @@ body {
|
|
|
131
142
|
color: var(--muted);
|
|
132
143
|
}
|
|
133
144
|
|
|
145
|
+
.office-promo .btn:hover {
|
|
146
|
+
filter: brightness(1.05);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.wizard-level-pill {
|
|
150
|
+
margin-top: 8px;
|
|
151
|
+
display: inline-block;
|
|
152
|
+
font-size: 12px;
|
|
153
|
+
padding: 4px 10px;
|
|
154
|
+
border-radius: 999px;
|
|
155
|
+
background: rgba(15, 118, 110, 0.25);
|
|
156
|
+
border: 1px solid rgba(153, 246, 228, 0.35);
|
|
157
|
+
color: #99f6e4;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.agentic-level-card {
|
|
161
|
+
margin: 12px 0 16px;
|
|
162
|
+
padding: 12px 14px;
|
|
163
|
+
border-radius: 10px;
|
|
164
|
+
border: 1px solid #d9e2ec;
|
|
165
|
+
background: #f8fafc;
|
|
166
|
+
font-size: 14px;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.agentic-level-card .hint-inline {
|
|
170
|
+
font-size: 12px;
|
|
171
|
+
color: #64748b;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.adapter-chip {
|
|
175
|
+
margin-top: 10px;
|
|
176
|
+
padding: 8px 10px;
|
|
177
|
+
border-radius: 8px;
|
|
178
|
+
font-size: 13px;
|
|
179
|
+
border: 1px solid #d9e2ec;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.adapter-chip.ok {
|
|
183
|
+
background: #ecfdf5;
|
|
184
|
+
border-color: #6ee7b7;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.adapter-chip.warn {
|
|
188
|
+
background: #fffbeb;
|
|
189
|
+
border-color: #fcd34d;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.adapter-chip.error {
|
|
193
|
+
background: #fef2f2;
|
|
194
|
+
border-color: #fca5a5;
|
|
195
|
+
}
|
|
196
|
+
|
|
134
197
|
.office-promo .btn {
|
|
135
198
|
display: inline-block;
|
|
136
199
|
background: var(--accent);
|
|
@@ -152,8 +215,13 @@ body {
|
|
|
152
215
|
}
|
|
153
216
|
|
|
154
217
|
@media (max-width: 860px) {
|
|
155
|
-
.shell {
|
|
156
|
-
|
|
218
|
+
.shell {
|
|
219
|
+
grid-template-columns: 1fr;
|
|
220
|
+
}
|
|
221
|
+
.rail {
|
|
222
|
+
border-right: 0;
|
|
223
|
+
border-bottom: 1px solid var(--line);
|
|
224
|
+
}
|
|
157
225
|
}
|
|
158
226
|
|
|
159
227
|
.rail {
|
|
@@ -188,7 +256,7 @@ body {
|
|
|
188
256
|
width: 56px;
|
|
189
257
|
height: 56px;
|
|
190
258
|
border-radius: 50%;
|
|
191
|
-
background: conic-gradient(var(--accent) calc(var(--pct) * 1%), rgba(255,255,255,0.12) 0);
|
|
259
|
+
background: conic-gradient(var(--accent) calc(var(--pct) * 1%), rgba(255, 255, 255, 0.12) 0);
|
|
192
260
|
display: grid;
|
|
193
261
|
place-items: center;
|
|
194
262
|
position: relative;
|
|
@@ -253,12 +321,21 @@ body {
|
|
|
253
321
|
letter-spacing: 0.04em;
|
|
254
322
|
padding: 2px 7px;
|
|
255
323
|
border-radius: 999px;
|
|
256
|
-
border: 1px solid rgba(255,255,255,0.15);
|
|
324
|
+
border: 1px solid rgba(255, 255, 255, 0.15);
|
|
257
325
|
}
|
|
258
326
|
|
|
259
|
-
.chip.done {
|
|
260
|
-
|
|
261
|
-
|
|
327
|
+
.chip.done {
|
|
328
|
+
background: rgba(22, 101, 52, 0.35);
|
|
329
|
+
color: #bbf7d0;
|
|
330
|
+
}
|
|
331
|
+
.chip.progress {
|
|
332
|
+
background: rgba(180, 83, 9, 0.35);
|
|
333
|
+
color: #fde68a;
|
|
334
|
+
}
|
|
335
|
+
.chip.optional {
|
|
336
|
+
background: rgba(100, 116, 139, 0.35);
|
|
337
|
+
color: #e2e8f0;
|
|
338
|
+
}
|
|
262
339
|
|
|
263
340
|
.main {
|
|
264
341
|
padding: clamp(20px, 4vw, 40px);
|
|
@@ -274,8 +351,18 @@ body {
|
|
|
274
351
|
font-size: 14px;
|
|
275
352
|
}
|
|
276
353
|
|
|
277
|
-
.status.ok {
|
|
278
|
-
|
|
354
|
+
.status.ok {
|
|
355
|
+
display: block;
|
|
356
|
+
background: #ecfdf5;
|
|
357
|
+
border: 1px solid #86efac;
|
|
358
|
+
color: var(--ok);
|
|
359
|
+
}
|
|
360
|
+
.status.error {
|
|
361
|
+
display: block;
|
|
362
|
+
background: #fef2f2;
|
|
363
|
+
border: 1px solid #fca5a5;
|
|
364
|
+
color: #991b1b;
|
|
365
|
+
}
|
|
279
366
|
|
|
280
367
|
.card {
|
|
281
368
|
background: var(--panel);
|
|
@@ -322,7 +409,9 @@ label span {
|
|
|
322
409
|
margin-top: 3px;
|
|
323
410
|
}
|
|
324
411
|
|
|
325
|
-
input,
|
|
412
|
+
input,
|
|
413
|
+
select,
|
|
414
|
+
textarea {
|
|
326
415
|
width: 100%;
|
|
327
416
|
border: 1px solid var(--line);
|
|
328
417
|
border-radius: 10px;
|
|
@@ -332,14 +421,23 @@ input, select, textarea {
|
|
|
332
421
|
background: #fff;
|
|
333
422
|
}
|
|
334
423
|
|
|
335
|
-
input:focus,
|
|
424
|
+
input:focus,
|
|
425
|
+
select:focus,
|
|
426
|
+
textarea:focus {
|
|
336
427
|
outline: 2px solid var(--accent-soft);
|
|
337
428
|
border-color: var(--accent);
|
|
338
429
|
}
|
|
339
430
|
|
|
340
|
-
textarea {
|
|
431
|
+
textarea {
|
|
432
|
+
min-height: 120px;
|
|
433
|
+
resize: vertical;
|
|
434
|
+
}
|
|
341
435
|
|
|
342
|
-
.grid {
|
|
436
|
+
.grid {
|
|
437
|
+
display: grid;
|
|
438
|
+
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
439
|
+
gap: 12px;
|
|
440
|
+
}
|
|
343
441
|
|
|
344
442
|
.hint {
|
|
345
443
|
background: #f0fdfa;
|
|
@@ -370,7 +468,9 @@ textarea { min-height: 120px; resize: vertical; }
|
|
|
370
468
|
display: none;
|
|
371
469
|
}
|
|
372
470
|
|
|
373
|
-
.field-error.show {
|
|
471
|
+
.field-error.show {
|
|
472
|
+
display: block;
|
|
473
|
+
}
|
|
374
474
|
|
|
375
475
|
.depth-grid {
|
|
376
476
|
display: grid;
|
|
@@ -395,8 +495,15 @@ textarea { min-height: 120px; resize: vertical; }
|
|
|
395
495
|
background: #f0fdfa;
|
|
396
496
|
}
|
|
397
497
|
|
|
398
|
-
.depth-card strong {
|
|
399
|
-
|
|
498
|
+
.depth-card strong {
|
|
499
|
+
display: block;
|
|
500
|
+
margin-bottom: 6px;
|
|
501
|
+
}
|
|
502
|
+
.depth-card p {
|
|
503
|
+
margin: 0;
|
|
504
|
+
font-size: 13px;
|
|
505
|
+
color: var(--muted);
|
|
506
|
+
}
|
|
400
507
|
|
|
401
508
|
.stack-pills {
|
|
402
509
|
display: flex;
|
|
@@ -414,9 +521,22 @@ textarea { min-height: 120px; resize: vertical; }
|
|
|
414
521
|
border: 1px solid var(--line);
|
|
415
522
|
}
|
|
416
523
|
|
|
417
|
-
.review dl {
|
|
418
|
-
|
|
419
|
-
|
|
524
|
+
.review dl {
|
|
525
|
+
margin: 0;
|
|
526
|
+
display: grid;
|
|
527
|
+
gap: 14px;
|
|
528
|
+
}
|
|
529
|
+
.review dt {
|
|
530
|
+
font-size: 11px;
|
|
531
|
+
text-transform: uppercase;
|
|
532
|
+
letter-spacing: 0.06em;
|
|
533
|
+
color: var(--muted);
|
|
534
|
+
font-weight: 700;
|
|
535
|
+
}
|
|
536
|
+
.review dd {
|
|
537
|
+
margin: 4px 0 0;
|
|
538
|
+
white-space: pre-wrap;
|
|
539
|
+
}
|
|
420
540
|
|
|
421
541
|
.preview {
|
|
422
542
|
background: #f8fafc;
|
|
@@ -455,9 +575,18 @@ button.btn {
|
|
|
455
575
|
cursor: pointer;
|
|
456
576
|
}
|
|
457
577
|
|
|
458
|
-
button.btn.primary {
|
|
459
|
-
|
|
460
|
-
|
|
578
|
+
button.btn.primary {
|
|
579
|
+
background: var(--accent);
|
|
580
|
+
color: #fff;
|
|
581
|
+
}
|
|
582
|
+
button.btn.secondary {
|
|
583
|
+
background: #edf2f7;
|
|
584
|
+
color: var(--ink);
|
|
585
|
+
}
|
|
586
|
+
button.btn:disabled {
|
|
587
|
+
opacity: 0.5;
|
|
588
|
+
cursor: not-allowed;
|
|
589
|
+
}
|
|
461
590
|
|
|
462
591
|
.complete-icon {
|
|
463
592
|
font-size: 48px;
|
|
@@ -480,7 +609,9 @@ code {
|
|
|
480
609
|
border-radius: 4px;
|
|
481
610
|
}
|
|
482
611
|
|
|
483
|
-
.hidden {
|
|
612
|
+
.hidden {
|
|
613
|
+
display: none !important;
|
|
614
|
+
}
|
|
484
615
|
|
|
485
616
|
.agent-roster {
|
|
486
617
|
list-style: none;
|
|
@@ -14,7 +14,9 @@
|
|
|
14
14
|
designDraft: null,
|
|
15
15
|
messagingDraft: null,
|
|
16
16
|
ideSurfaces: boot.ideSurfaces || [],
|
|
17
|
-
agents: boot.agents || []
|
|
17
|
+
agents: boot.agents || [],
|
|
18
|
+
agenticLevel: null,
|
|
19
|
+
lastAdapterValidation: null
|
|
18
20
|
};
|
|
19
21
|
|
|
20
22
|
const els = {
|
|
@@ -22,6 +24,7 @@
|
|
|
22
24
|
projectName: document.getElementById("project-name"),
|
|
23
25
|
ringPct: document.getElementById("ring-pct"),
|
|
24
26
|
ring: document.getElementById("progress-ring"),
|
|
27
|
+
levelPill: document.getElementById("wizard-level-pill"),
|
|
25
28
|
sectionNav: document.getElementById("section-nav"),
|
|
26
29
|
card: document.getElementById("wizard-card"),
|
|
27
30
|
footer: document.getElementById("wizard-footer"),
|
|
@@ -83,10 +86,15 @@
|
|
|
83
86
|
state.designDraft = data.designDraft;
|
|
84
87
|
state.messagingDraft = data.messagingDraft;
|
|
85
88
|
if (Array.isArray(data.agents) && data.agents.length) state.agents = data.agents;
|
|
89
|
+
state.agenticLevel = data.agenticLevel || null;
|
|
86
90
|
els.projectName.textContent = data.projectName || "your project";
|
|
87
91
|
const pct = data.progress?.percent ?? 0;
|
|
88
92
|
els.ringPct.textContent = pct + "%";
|
|
89
93
|
els.ring.style.setProperty("--pct", String(pct));
|
|
94
|
+
if (els.levelPill && state.agenticLevel) {
|
|
95
|
+
els.levelPill.textContent = "L" + state.agenticLevel.currentLevel + " → L" + state.agenticLevel.targetLevel;
|
|
96
|
+
els.levelPill.hidden = false;
|
|
97
|
+
}
|
|
90
98
|
render();
|
|
91
99
|
}
|
|
92
100
|
|
|
@@ -128,10 +136,8 @@
|
|
|
128
136
|
const sections = state.progress?.sections || [];
|
|
129
137
|
els.sectionNav.innerHTML = sections
|
|
130
138
|
.map((s) => {
|
|
131
|
-
const chipClass =
|
|
132
|
-
|
|
133
|
-
const chipLabel =
|
|
134
|
-
s.status === "done" ? "Done" : s.status === "in_progress" ? "Now" : s.status === "optional" ? "Optional" : "—";
|
|
139
|
+
const chipClass = s.status === "done" ? "done" : s.status === "in_progress" ? "progress" : s.status === "optional" ? "optional" : "";
|
|
140
|
+
const chipLabel = s.status === "done" ? "Done" : s.status === "in_progress" ? "Now" : s.status === "optional" ? "Optional" : "—";
|
|
135
141
|
return (
|
|
136
142
|
'<li><button type="button" data-section="' +
|
|
137
143
|
s.id +
|
|
@@ -162,14 +168,7 @@
|
|
|
162
168
|
|
|
163
169
|
function renderTeamIntro() {
|
|
164
170
|
const cards = state.agents
|
|
165
|
-
.map(
|
|
166
|
-
(a) =>
|
|
167
|
-
'<li class="agent-card"><strong>' +
|
|
168
|
-
escapeHtml(a.name) +
|
|
169
|
-
"</strong><p>" +
|
|
170
|
-
escapeHtml(a.roleSummary) +
|
|
171
|
-
"</p></li>"
|
|
172
|
-
)
|
|
171
|
+
.map((a) => '<li class="agent-card"><strong>' + escapeHtml(a.name) + "</strong><p>" + escapeHtml(a.roleSummary) + "</p></li>")
|
|
173
172
|
.join("");
|
|
174
173
|
return (
|
|
175
174
|
'<p class="why">Next you will brief each specialist — one step per agent. Skip any you are not ready to answer; you can return later.</p>' +
|
|
@@ -202,9 +201,7 @@
|
|
|
202
201
|
}
|
|
203
202
|
|
|
204
203
|
function renderHome() {
|
|
205
|
-
const pills = (boot.stackSignals || [])
|
|
206
|
-
.map((s) => '<span class="pill">' + escapeHtml(s) + "</span>")
|
|
207
|
-
.join("");
|
|
204
|
+
const pills = (boot.stackSignals || []).map((s) => '<span class="pill">' + escapeHtml(s) + "</span>").join("");
|
|
208
205
|
const agentCount = state.agents.length || boot.agents?.length || 0;
|
|
209
206
|
const officePromo =
|
|
210
207
|
'<div class="office-promo">' +
|
|
@@ -227,19 +224,33 @@
|
|
|
227
224
|
pills +
|
|
228
225
|
"</div>" +
|
|
229
226
|
'<p class="why" style="margin-top:20px"><strong>Choose your path</strong></p>' +
|
|
227
|
+
agenticLevelHomeBlock() +
|
|
230
228
|
'<div class="depth-grid">' +
|
|
231
229
|
depthCard("quick", "Quick (~10 min)", "IDE setup, agent briefings, and product essentials.") +
|
|
232
230
|
depthCard("standard", "Standard (~15 min)", "Quick plus visual QA tier for UI changes.") +
|
|
233
231
|
depthCard("complete", "Complete (~25 min)", "Standard plus DESIGN and MESSAGING intake drafts.") +
|
|
234
232
|
"</div>" +
|
|
235
233
|
(state.progress?.recommendedNext
|
|
236
|
-
? '<p class="why" style="margin-top:18px">Continue: <strong>' +
|
|
237
|
-
escapeHtml(state.progress.recommendedNext) +
|
|
238
|
-
"</strong></p>"
|
|
234
|
+
? '<p class="why" style="margin-top:18px">Continue: <strong>' + escapeHtml(state.progress.recommendedNext) + "</strong></p>"
|
|
239
235
|
: "")
|
|
240
236
|
);
|
|
241
237
|
}
|
|
242
238
|
|
|
239
|
+
function agenticLevelHomeBlock() {
|
|
240
|
+
const level = state.agenticLevel;
|
|
241
|
+
if (!level) return "";
|
|
242
|
+
return (
|
|
243
|
+
'<div class="agentic-level-card">' +
|
|
244
|
+
"<p><strong>Agentic level</strong> L" +
|
|
245
|
+
level.currentLevel +
|
|
246
|
+
" → target L" +
|
|
247
|
+
level.targetLevel +
|
|
248
|
+
' <span class="hint-inline">(setup progress is separate from audit readiness and visual QA tiers)</span></p>' +
|
|
249
|
+
(level.maintainerNote ? '<p class="hint">' + escapeHtml(level.maintainerNote) + "</p>" : "") +
|
|
250
|
+
"</div>"
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
|
|
243
254
|
function depthCard(id, title, desc) {
|
|
244
255
|
const sel = state.depth === id ? " selected" : "";
|
|
245
256
|
return (
|
|
@@ -259,9 +270,9 @@
|
|
|
259
270
|
const val = escapeHtml(state.form[name] || "");
|
|
260
271
|
if (type === "textarea") {
|
|
261
272
|
return (
|
|
262
|
-
|
|
273
|
+
'<label for="' +
|
|
263
274
|
name +
|
|
264
|
-
"
|
|
275
|
+
'">' +
|
|
265
276
|
escapeHtml(label) +
|
|
266
277
|
(hint ? "<span>" + escapeHtml(hint) + "</span>" : "") +
|
|
267
278
|
'</label><textarea id="' +
|
|
@@ -278,9 +289,9 @@
|
|
|
278
289
|
);
|
|
279
290
|
}
|
|
280
291
|
return (
|
|
281
|
-
|
|
292
|
+
'<label for="' +
|
|
282
293
|
name +
|
|
283
|
-
"
|
|
294
|
+
'">' +
|
|
284
295
|
escapeHtml(label) +
|
|
285
296
|
(hint ? "<span>" + escapeHtml(hint) + "</span>" : "") +
|
|
286
297
|
'</label><input id="' +
|
|
@@ -309,25 +320,11 @@
|
|
|
309
320
|
),
|
|
310
321
|
productCategory: () => {
|
|
311
322
|
const opts = (boot.categories || [])
|
|
312
|
-
.map(
|
|
313
|
-
(c) =>
|
|
314
|
-
'<option value="' +
|
|
315
|
-
c +
|
|
316
|
-
'"' +
|
|
317
|
-
(state.form.productCategory === c ? " selected" : "") +
|
|
318
|
-
">" +
|
|
319
|
-
c +
|
|
320
|
-
"</option>"
|
|
321
|
-
)
|
|
323
|
+
.map((c) => '<option value="' + c + '"' + (state.form.productCategory === c ? " selected" : "") + ">" + c + "</option>")
|
|
322
324
|
.join("");
|
|
323
|
-
return
|
|
324
|
-
'<label for="productCategory">Category</label><select id="productCategory" name="productCategory">' +
|
|
325
|
-
opts +
|
|
326
|
-
"</select>"
|
|
327
|
-
);
|
|
325
|
+
return '<label for="productCategory">Category</label><select id="productCategory" name="productCategory">' + opts + "</select>";
|
|
328
326
|
},
|
|
329
|
-
primaryAudience: () =>
|
|
330
|
-
inputField("primaryAudience", "Primary user or buyer", "", "text", "Who uses or pays for this product?"),
|
|
327
|
+
primaryAudience: () => inputField("primaryAudience", "Primary user or buyer", "", "text", "Who uses or pays for this product?"),
|
|
331
328
|
primaryWorkflows: () =>
|
|
332
329
|
inputField(
|
|
333
330
|
"primaryWorkflows",
|
|
@@ -338,16 +335,7 @@
|
|
|
338
335
|
),
|
|
339
336
|
tenantModel: () => {
|
|
340
337
|
const opts = (boot.tenantModels || [])
|
|
341
|
-
.map(
|
|
342
|
-
(c) =>
|
|
343
|
-
'<option value="' +
|
|
344
|
-
c +
|
|
345
|
-
'"' +
|
|
346
|
-
(state.form.tenantModel === c ? " selected" : "") +
|
|
347
|
-
">" +
|
|
348
|
-
c +
|
|
349
|
-
"</option>"
|
|
350
|
-
)
|
|
338
|
+
.map((c) => '<option value="' + c + '"' + (state.form.tenantModel === c ? " selected" : "") + ">" + c + "</option>")
|
|
351
339
|
.join("");
|
|
352
340
|
return '<label for="tenantModel">Who uses the system?</label><select id="tenantModel" name="tenantModel">' + opts + "</select>";
|
|
353
341
|
},
|
|
@@ -363,18 +351,17 @@
|
|
|
363
351
|
"textarea",
|
|
364
352
|
"Describe auth boundaries agents must not break."
|
|
365
353
|
),
|
|
366
|
-
uiPreferred: () =>
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
inputField("uiAvoid", "UI should avoid…", "Optional.", "textarea", "Generic SaaS heroes, card soup, fake metrics."),
|
|
370
|
-
valueProposition: () =>
|
|
371
|
-
inputField("valueProposition", "Value proposition", "", "textarea", "What outcome do users get?"),
|
|
354
|
+
uiPreferred: () => inputField("uiPreferred", "UI should feel like…", "", "textarea", "Task-first, clear hierarchy, readable typography."),
|
|
355
|
+
uiAvoid: () => inputField("uiAvoid", "UI should avoid…", "Optional.", "textarea", "Generic SaaS heroes, card soup, fake metrics."),
|
|
356
|
+
valueProposition: () => inputField("valueProposition", "Value proposition", "", "textarea", "What outcome do users get?"),
|
|
372
357
|
proof: () => inputField("proof", "Proof points", "One per line. Real evidence only.", "textarea", ""),
|
|
373
358
|
objections: () => inputField("objections", "Objections", "One per line. Optional.", "textarea", ""),
|
|
374
359
|
qualityTarget: () => {
|
|
375
360
|
const q = state.form.qualityTarget || "baseline-setup";
|
|
376
361
|
return (
|
|
377
|
-
'<label for="qualityTarget">
|
|
362
|
+
'<label for="qualityTarget">Audit readiness target</label>' +
|
|
363
|
+
'<p class="hint">This is your <strong>audit readiness</strong> goal (agent-kit audit), not Agentic L5/L6 or visual QA tier.</p>' +
|
|
364
|
+
'<select id="qualityTarget" name="qualityTarget">' +
|
|
378
365
|
optionQuality("baseline-setup", "baseline-setup — kit installed, filling evidence", q) +
|
|
379
366
|
optionQuality("needs-improvement", "needs-improvement — active delivery", q) +
|
|
380
367
|
optionQuality("best-practice-candidate", "best-practice-candidate — clean audit goal", q) +
|
|
@@ -383,22 +370,15 @@
|
|
|
383
370
|
},
|
|
384
371
|
ideSurface: () => {
|
|
385
372
|
const opts = state.ideSurfaces
|
|
386
|
-
.map(
|
|
387
|
-
(s) =>
|
|
388
|
-
'<option value="' +
|
|
389
|
-
s.id +
|
|
390
|
-
'"' +
|
|
391
|
-
(state.form.ideSurface === s.id ? " selected" : "") +
|
|
392
|
-
">" +
|
|
393
|
-
escapeHtml(s.label) +
|
|
394
|
-
"</option>"
|
|
395
|
-
)
|
|
373
|
+
.map((s) => '<option value="' + s.id + '"' + (state.form.ideSurface === s.id ? " selected" : "") + ">" + escapeHtml(s.label) + "</option>")
|
|
396
374
|
.join("");
|
|
375
|
+
const chip = renderAdapterChip(state.lastAdapterValidation);
|
|
397
376
|
return (
|
|
398
377
|
'<label for="ideSurface">Primary AI coding tool</label><select id="ideSurface" name="ideSurface" required>' +
|
|
399
378
|
'<option value="">Choose your IDE…</option>' +
|
|
400
379
|
opts +
|
|
401
|
-
'</select><p class="why">We configure instructions for this path: <code id="ide-path"></code></p>'
|
|
380
|
+
'</select><p class="why">We configure instructions for this path: <code id="ide-path"></code></p>' +
|
|
381
|
+
chip
|
|
402
382
|
);
|
|
403
383
|
},
|
|
404
384
|
visualQaTier: () => {
|
|
@@ -456,9 +436,35 @@
|
|
|
456
436
|
);
|
|
457
437
|
}
|
|
458
438
|
|
|
439
|
+
function renderAdapterChip(validation) {
|
|
440
|
+
if (!validation || !validation.target) return "";
|
|
441
|
+
const kind = validation.fail > 0 ? "error" : validation.warn > 0 ? "warn" : "ok";
|
|
442
|
+
const label =
|
|
443
|
+
validation.fail > 0
|
|
444
|
+
? "Adapter validate: " + validation.fail + " fail"
|
|
445
|
+
: validation.warn > 0
|
|
446
|
+
? "Adapter validate: pass with warnings"
|
|
447
|
+
: "Adapter validate: pass";
|
|
448
|
+
return '<p class="adapter-chip ' + kind + '" role="status">' + escapeHtml(label) + " (" + escapeHtml(validation.target) + ")</p>";
|
|
449
|
+
}
|
|
450
|
+
|
|
459
451
|
function renderComplete() {
|
|
452
|
+
const level = state.agenticLevel;
|
|
453
|
+
const climb = (level?.climbSteps || [])
|
|
454
|
+
.slice(0, 3)
|
|
455
|
+
.map((step) => "<li>" + escapeHtml(step.remediation) + "</li>")
|
|
456
|
+
.join("");
|
|
460
457
|
return (
|
|
461
|
-
'<div class="complete-icon" aria-hidden="true">✓</div><h2>Setup saved</h2
|
|
458
|
+
'<div class="complete-icon" aria-hidden="true">✓</div><h2>Setup saved</h2>' +
|
|
459
|
+
(level ? '<p class="why">Agentic level <strong>L' + level.currentLevel + "</strong> (target L" + level.targetLevel + ").</p>" : "") +
|
|
460
|
+
'<p class="why">Agents read <code>.agent-kit/project-context.md</code> and <code>.agent-kit/agent-briefs.md</code> before meaningful work.</p>' +
|
|
461
|
+
'<ol class="next-steps">' +
|
|
462
|
+
"<li>Run eval loop from <code>LOOP_CODING.md</code>: <code>npm test</code>, <code>agent-kit audit --min-readiness baseline-setup</code></li>" +
|
|
463
|
+
"<li>Validate IDE adapters: <code>agent-kit adapter validate cursor|codex|all</code></li>" +
|
|
464
|
+
"<li>Reload your IDE so it picks up council subagents and rules</li>" +
|
|
465
|
+
"<li>Return anytime with <code>agent-kit setup</code></li>" +
|
|
466
|
+
"</ol>" +
|
|
467
|
+
(climb ? '<h3>Next climb steps</h3><ol class="next-steps">' + climb + "</ol>" : "")
|
|
462
468
|
);
|
|
463
469
|
}
|
|
464
470
|
|
|
@@ -619,11 +625,13 @@
|
|
|
619
625
|
await patchState({ currentSection: step.section, currentStep: state.stepIndex });
|
|
620
626
|
}
|
|
621
627
|
if (step?.section === "ide" && fieldValue("ideSurface")) {
|
|
622
|
-
await api("/api/checklist/ide", {
|
|
628
|
+
const ideResult = await api("/api/checklist/ide", {
|
|
623
629
|
method: "POST",
|
|
624
630
|
headers: { "Content-Type": "application/json" },
|
|
625
631
|
body: JSON.stringify({ ideSurface: fieldValue("ideSurface") })
|
|
626
632
|
});
|
|
633
|
+
state.lastAdapterValidation = ideResult.adapterValidation || null;
|
|
634
|
+
state.agenticLevel = ideResult.agenticLevel || state.agenticLevel;
|
|
627
635
|
}
|
|
628
636
|
if (step?.section === "visualQa" && fieldValue("visualQaTier")) {
|
|
629
637
|
await api("/api/checklist/visual-qa", {
|
|
@@ -70,6 +70,7 @@
|
|
|
70
70
|
"frontend-distinctiveness-benchmark",
|
|
71
71
|
"frontend-product-quality-rubric",
|
|
72
72
|
"frontend-design-system",
|
|
73
|
+
"ui-improvement-harness",
|
|
73
74
|
"visual-regression-qa",
|
|
74
75
|
"accessibility-wcag"
|
|
75
76
|
],
|
|
@@ -171,7 +172,7 @@
|
|
|
171
172
|
},
|
|
172
173
|
{
|
|
173
174
|
"id": "frontend-change",
|
|
174
|
-
"triggers": ["screen", "component", "layout", "design", "responsive", "accessibility", "screenshot"],
|
|
175
|
+
"triggers": ["screen", "component", "layout", "design", "responsive", "accessibility", "screenshot", "ui audit", "ui polish", "browser qa"],
|
|
175
176
|
"sequence": ["planner", "frontend-design-lead", "marketing-copy-lead", "nextjs-engineer", "qa-engineer", "docs-maintainer"],
|
|
176
177
|
"council": ["frontend-design-lead", "marketing-copy-lead", "qa-engineer"],
|
|
177
178
|
"requiredOutputs": [
|
|
@@ -183,10 +184,13 @@
|
|
|
183
184
|
"design critique verdict",
|
|
184
185
|
"frontend product-quality scorecard",
|
|
185
186
|
"domain-specific UI rationale",
|
|
187
|
+
"UI detector findings and severity",
|
|
188
|
+
"UI command workflow applied when polishing or auditing",
|
|
186
189
|
"visual QA evidence",
|
|
187
190
|
"state coverage",
|
|
188
191
|
"accessibility checks",
|
|
189
|
-
"desktop/mobile verification"
|
|
192
|
+
"desktop/mobile verification",
|
|
193
|
+
"authenticated screen evidence when applicable"
|
|
190
194
|
]
|
|
191
195
|
},
|
|
192
196
|
{
|
|
@@ -219,7 +223,7 @@
|
|
|
219
223
|
"Meaningful multi-agent work must record council-session evidence in COUNCIL.md or a structured record that follows .agent-kit/schemas/council-session.schema.json.",
|
|
220
224
|
"Planner starts planning and ambiguous requests by default.",
|
|
221
225
|
"Lead Architect must review core changes before implementation.",
|
|
222
|
-
"Frontend Design Lead must record reference-set evidence, anti-references, a design critique verdict, a distinctiveness benchmark,
|
|
226
|
+
"Frontend Design Lead must record reference-set evidence, anti-references, a design critique verdict, a distinctiveness benchmark, a frontend product-quality scorecard, UI detector severity findings, and desktop/mobile screenshot evidence before accepting significant frontend work.",
|
|
223
227
|
"Marketing Copy Lead must ask discovery questions and record audience, pain, outcome, value proposition, proof, objections, voice/tone, and conversion goal before accepting public-facing or conversion-facing copy.",
|
|
224
228
|
"Security Reviewer must review auth, data mutation, external-call, dependency, secret, and release-risk changes.",
|
|
225
229
|
"QA Engineer must verify behavior changes before completion.",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"packageName": "@appsforgood/next-supabase-kit",
|
|
3
|
-
"packageVersion": "0.1.
|
|
3
|
+
"packageVersion": "0.1.6",
|
|
4
4
|
"stack": "next-supabase",
|
|
5
5
|
"installedAt": "2026-06-17T11:49:38.732Z",
|
|
6
6
|
"docs": [
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"STYLE_GUIDE.md",
|
|
20
20
|
"SECURITY.md",
|
|
21
21
|
"TESTING.md",
|
|
22
|
+
"LOOP_CODING.md",
|
|
22
23
|
"DEPLOYMENT.md",
|
|
23
24
|
"UPGRADE.md"
|
|
24
25
|
],
|
|
@@ -39,20 +40,21 @@
|
|
|
39
40
|
"modelRouting": ".agent-kit/model-routing.json",
|
|
40
41
|
"templateHashes": {
|
|
41
42
|
"AGENTS.md": "c7f3e7360938a1ed804d2110e9af96e6f09d50c49138063bef0db1642ddaf84f",
|
|
42
|
-
"AGENT_ROSTER.md": "
|
|
43
|
-
"ASSISTANT_ADAPTERS.md": "
|
|
43
|
+
"AGENT_ROSTER.md": "40147eecf3977bf64431204b67f24eb277a834ba5b6f894c053c79c0a9dbb8f5",
|
|
44
|
+
"ASSISTANT_ADAPTERS.md": "4d37ba6555814cf18c6ac2a302a614af07bb33b0ac0eb5f19886c3af3328cb63",
|
|
44
45
|
"COUNCIL.md": "40bec9051664c9c38b8360ee16f21b5e4716030d19c493cdec67395ab06528e1",
|
|
45
|
-
"SKILLS.md": "
|
|
46
|
-
"SPEC.md": "
|
|
47
|
-
"DECISIONS.md": "
|
|
48
|
-
"DOCS.md": "
|
|
49
|
-
"DESIGN.md": "
|
|
46
|
+
"SKILLS.md": "320b76f37e8b509d597ba01331d3b1a4dc4f1eb68b6d2294ba4125fb2ab02970",
|
|
47
|
+
"SPEC.md": "30dca40819d3d204cfcb33f016e67d0d9008d0fad0907db9c93f6d32e50e057a",
|
|
48
|
+
"DECISIONS.md": "1374d33cc40a9f3086f57c1af885c3e4defaa67df5116168cf4872d2ae8a3628",
|
|
49
|
+
"DOCS.md": "c9501b68bfa97788579ddaaa4b072ca7a7c80a5890e6ec10c05901694fcdae48",
|
|
50
|
+
"DESIGN.md": "e464ff8d9a8e542d00a04143a51417752dc98e1afcfa7e2a5549ecfbb47a479b",
|
|
50
51
|
"MESSAGING.md": "f1f7c0f11796820b60bb44e42a65749763f7167944ba6acf092a1cf7b59e50de",
|
|
51
52
|
"MODEL_ROUTING.md": "f0ca3bd12872cd5f61ff4c6bef670249c0a0188f20c049cb0d09d84219b1839c",
|
|
52
|
-
"QUALITY_GATES.md": "
|
|
53
|
-
"STYLE_GUIDE.md": "
|
|
53
|
+
"QUALITY_GATES.md": "15f260c75d6180d1e583917e367ab522030e878f1a6e93ba5f18eba17fef4bb2",
|
|
54
|
+
"STYLE_GUIDE.md": "0fcb8e04ed3d31fa560a0165588ad56efd262463ca0f3aa26633fba955daf0db",
|
|
54
55
|
"SECURITY.md": "f046e4dc794f49700ddee4cb866e2ba1983a1b71268f2e244892d615b41714f8",
|
|
55
|
-
"TESTING.md": "
|
|
56
|
+
"TESTING.md": "59a82645445c3af0c9ccc26a9ed5154c1f710b202d3d13ffa9558a0b1d8a96de",
|
|
57
|
+
"LOOP_CODING.md": "3d4719c7fc7c2e8465ee15aec27574adbbc5207d58123ecf4f88f3942c522812",
|
|
56
58
|
"DEPLOYMENT.md": "c33d949c2b1850f8ee6c38e5ec565325c3d47f4daac13b81c75e1b35655ea174",
|
|
57
59
|
"UPGRADE.md": "d4678475458744dee7c1f23b69c04e3cf82d9e896196e62455585aaae5d3a25a"
|
|
58
60
|
}
|