@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
|
@@ -13,13 +13,17 @@
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
@media (prefers-reduced-motion: reduce) {
|
|
16
|
-
*,
|
|
16
|
+
*,
|
|
17
|
+
*::before,
|
|
18
|
+
*::after {
|
|
17
19
|
animation-duration: 0.01ms !important;
|
|
18
20
|
transition-duration: 0.01ms !important;
|
|
19
21
|
}
|
|
20
22
|
}
|
|
21
23
|
|
|
22
|
-
* {
|
|
24
|
+
* {
|
|
25
|
+
box-sizing: border-box;
|
|
26
|
+
}
|
|
23
27
|
|
|
24
28
|
body {
|
|
25
29
|
margin: 0;
|
|
@@ -79,16 +83,101 @@ body {
|
|
|
79
83
|
border: 1px solid rgba(255, 255, 255, 0.12);
|
|
80
84
|
}
|
|
81
85
|
|
|
86
|
+
.level-pill {
|
|
87
|
+
font-size: 12px;
|
|
88
|
+
padding: 6px 12px;
|
|
89
|
+
border-radius: 999px;
|
|
90
|
+
background: rgba(15, 118, 110, 0.35);
|
|
91
|
+
border: 1px solid rgba(153, 246, 228, 0.35);
|
|
92
|
+
font-variant-numeric: tabular-nums;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.iceberg-strip {
|
|
96
|
+
display: grid;
|
|
97
|
+
grid-template-columns: repeat(6, 1fr);
|
|
98
|
+
gap: 4px;
|
|
99
|
+
padding: 8px 20px 10px;
|
|
100
|
+
background: #0a1620;
|
|
101
|
+
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.iceberg-seg {
|
|
105
|
+
text-align: center;
|
|
106
|
+
font-size: 10px;
|
|
107
|
+
padding: 6px 4px;
|
|
108
|
+
border-radius: 6px;
|
|
109
|
+
border: 1px solid rgba(255, 255, 255, 0.12);
|
|
110
|
+
color: #94a3b8;
|
|
111
|
+
opacity: 0.55;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.iceberg-seg.current {
|
|
115
|
+
opacity: 1;
|
|
116
|
+
color: #ecfdf5;
|
|
117
|
+
border-color: rgba(153, 246, 228, 0.55);
|
|
118
|
+
background: rgba(15, 118, 110, 0.35);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.iceberg-seg.target {
|
|
122
|
+
opacity: 0.85;
|
|
123
|
+
border-style: dashed;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.iceberg-seg.deferred {
|
|
127
|
+
opacity: 0.35;
|
|
128
|
+
border-style: dotted;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.climb-panel {
|
|
132
|
+
margin: 0 0 12px;
|
|
133
|
+
padding: 10px;
|
|
134
|
+
border-radius: 8px;
|
|
135
|
+
background: rgba(255, 255, 255, 0.04);
|
|
136
|
+
border: 1px solid var(--line);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.climb-panel h3 {
|
|
140
|
+
margin: 0 0 8px;
|
|
141
|
+
font-size: 12px;
|
|
142
|
+
text-transform: uppercase;
|
|
143
|
+
letter-spacing: 0.04em;
|
|
144
|
+
color: var(--muted);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.climb-panel ol {
|
|
148
|
+
margin: 0 0 10px;
|
|
149
|
+
padding-left: 18px;
|
|
150
|
+
font-size: 12px;
|
|
151
|
+
color: var(--ink);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.climb-panel li {
|
|
155
|
+
margin-bottom: 6px;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.climb-refresh {
|
|
159
|
+
width: 100%;
|
|
160
|
+
font-size: 12px;
|
|
161
|
+
padding: 6px 8px;
|
|
162
|
+
}
|
|
163
|
+
|
|
82
164
|
.office-main {
|
|
83
165
|
display: grid;
|
|
84
166
|
grid-template-columns: 220px minmax(0, 1fr);
|
|
85
167
|
gap: 0;
|
|
86
|
-
min-height: calc(100vh -
|
|
168
|
+
min-height: calc(100vh - 96px);
|
|
87
169
|
}
|
|
88
170
|
|
|
89
171
|
@media (max-width: 900px) {
|
|
90
|
-
.office-main {
|
|
91
|
-
|
|
172
|
+
.office-main {
|
|
173
|
+
grid-template-columns: 1fr;
|
|
174
|
+
}
|
|
175
|
+
.station-list {
|
|
176
|
+
border-right: 0;
|
|
177
|
+
border-bottom: 1px solid var(--line);
|
|
178
|
+
max-height: 180px;
|
|
179
|
+
overflow: auto;
|
|
180
|
+
}
|
|
92
181
|
}
|
|
93
182
|
|
|
94
183
|
.station-list {
|
|
@@ -130,8 +219,12 @@ body {
|
|
|
130
219
|
cursor: pointer;
|
|
131
220
|
}
|
|
132
221
|
|
|
133
|
-
.station-list button:hover {
|
|
134
|
-
|
|
222
|
+
.station-list button:hover {
|
|
223
|
+
background: rgba(255, 255, 255, 0.1);
|
|
224
|
+
}
|
|
225
|
+
.station-list button.done {
|
|
226
|
+
border-color: rgba(74, 222, 128, 0.4);
|
|
227
|
+
}
|
|
135
228
|
.station-list button .chip {
|
|
136
229
|
float: right;
|
|
137
230
|
font-size: 10px;
|
|
@@ -224,8 +317,14 @@ body {
|
|
|
224
317
|
max-width: 90vw;
|
|
225
318
|
}
|
|
226
319
|
|
|
227
|
-
.status.ok {
|
|
228
|
-
|
|
320
|
+
.status.ok {
|
|
321
|
+
background: #dcfce7;
|
|
322
|
+
color: #166534;
|
|
323
|
+
}
|
|
324
|
+
.status.error {
|
|
325
|
+
background: #fee2e2;
|
|
326
|
+
color: #991b1b;
|
|
327
|
+
}
|
|
229
328
|
|
|
230
329
|
.btn {
|
|
231
330
|
display: inline-flex;
|
|
@@ -240,9 +339,18 @@ body {
|
|
|
240
339
|
text-decoration: none;
|
|
241
340
|
}
|
|
242
341
|
|
|
243
|
-
.btn.primary {
|
|
244
|
-
|
|
245
|
-
|
|
342
|
+
.btn.primary {
|
|
343
|
+
background: var(--accent);
|
|
344
|
+
color: #fff;
|
|
345
|
+
}
|
|
346
|
+
.btn.secondary {
|
|
347
|
+
background: #334155;
|
|
348
|
+
color: #f8fafc;
|
|
349
|
+
}
|
|
350
|
+
.btn:disabled {
|
|
351
|
+
opacity: 0.5;
|
|
352
|
+
cursor: not-allowed;
|
|
353
|
+
}
|
|
246
354
|
|
|
247
355
|
.panel {
|
|
248
356
|
position: fixed;
|
|
@@ -257,7 +365,9 @@ body {
|
|
|
257
365
|
flex-direction: column;
|
|
258
366
|
}
|
|
259
367
|
|
|
260
|
-
.panel.hidden {
|
|
368
|
+
.panel.hidden {
|
|
369
|
+
display: none;
|
|
370
|
+
}
|
|
261
371
|
|
|
262
372
|
.panel-head {
|
|
263
373
|
display: flex;
|
|
@@ -267,7 +377,10 @@ body {
|
|
|
267
377
|
border-bottom: 1px solid var(--line);
|
|
268
378
|
}
|
|
269
379
|
|
|
270
|
-
.panel-head h2 {
|
|
380
|
+
.panel-head h2 {
|
|
381
|
+
margin: 0;
|
|
382
|
+
font-size: 18px;
|
|
383
|
+
}
|
|
271
384
|
|
|
272
385
|
.panel-close {
|
|
273
386
|
background: none;
|
|
@@ -317,7 +430,10 @@ body {
|
|
|
317
430
|
padding: 10px;
|
|
318
431
|
}
|
|
319
432
|
|
|
320
|
-
.panel textarea {
|
|
433
|
+
.panel textarea {
|
|
434
|
+
min-height: 90px;
|
|
435
|
+
resize: vertical;
|
|
436
|
+
}
|
|
321
437
|
|
|
322
438
|
.panel .agent-role {
|
|
323
439
|
font-size: 13px;
|
|
@@ -363,7 +479,9 @@ body {
|
|
|
363
479
|
}
|
|
364
480
|
|
|
365
481
|
.modal[hidden],
|
|
366
|
-
.modal.hidden {
|
|
482
|
+
.modal.hidden {
|
|
483
|
+
display: none;
|
|
484
|
+
}
|
|
367
485
|
|
|
368
486
|
.modal-card {
|
|
369
487
|
background: var(--panel);
|
|
@@ -374,11 +492,19 @@ body {
|
|
|
374
492
|
box-shadow: 0 20px 50px rgba(0, 0, 0, 0.35);
|
|
375
493
|
}
|
|
376
494
|
|
|
377
|
-
.modal-wide {
|
|
495
|
+
.modal-wide {
|
|
496
|
+
max-width: 640px;
|
|
497
|
+
}
|
|
378
498
|
|
|
379
|
-
.modal-card h2 {
|
|
499
|
+
.modal-card h2 {
|
|
500
|
+
margin: 0 0 8px;
|
|
501
|
+
}
|
|
380
502
|
|
|
381
|
-
.why {
|
|
503
|
+
.why {
|
|
504
|
+
color: var(--muted);
|
|
505
|
+
font-size: 14px;
|
|
506
|
+
margin: 0 0 16px;
|
|
507
|
+
}
|
|
382
508
|
|
|
383
509
|
.depth-grid {
|
|
384
510
|
display: grid;
|
|
@@ -395,14 +521,39 @@ body {
|
|
|
395
521
|
font: inherit;
|
|
396
522
|
}
|
|
397
523
|
|
|
398
|
-
.depth-card:hover {
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
.depth-card
|
|
524
|
+
.depth-card:hover {
|
|
525
|
+
border-color: var(--accent);
|
|
526
|
+
}
|
|
527
|
+
.depth-card.selected {
|
|
528
|
+
border-color: var(--accent);
|
|
529
|
+
background: var(--accent-soft);
|
|
530
|
+
}
|
|
531
|
+
.depth-card strong {
|
|
532
|
+
display: block;
|
|
533
|
+
margin-bottom: 4px;
|
|
534
|
+
}
|
|
535
|
+
.depth-card p {
|
|
536
|
+
margin: 0;
|
|
537
|
+
font-size: 13px;
|
|
538
|
+
color: var(--muted);
|
|
539
|
+
}
|
|
402
540
|
|
|
403
|
-
.review {
|
|
404
|
-
|
|
405
|
-
|
|
541
|
+
.review {
|
|
542
|
+
margin: 0;
|
|
543
|
+
display: grid;
|
|
544
|
+
gap: 12px;
|
|
545
|
+
}
|
|
546
|
+
.review dt {
|
|
547
|
+
font-size: 11px;
|
|
548
|
+
text-transform: uppercase;
|
|
549
|
+
letter-spacing: 0.06em;
|
|
550
|
+
color: var(--muted);
|
|
551
|
+
font-weight: 700;
|
|
552
|
+
}
|
|
553
|
+
.review dd {
|
|
554
|
+
margin: 4px 0 0;
|
|
555
|
+
white-space: pre-wrap;
|
|
556
|
+
}
|
|
406
557
|
|
|
407
558
|
.modal-actions {
|
|
408
559
|
display: flex;
|
|
@@ -411,7 +562,9 @@ body {
|
|
|
411
562
|
margin-top: 20px;
|
|
412
563
|
}
|
|
413
564
|
|
|
414
|
-
.hidden {
|
|
565
|
+
.hidden {
|
|
566
|
+
display: none !important;
|
|
567
|
+
}
|
|
415
568
|
|
|
416
569
|
code {
|
|
417
570
|
font-family: ui-monospace, Menlo, Consolas, monospace;
|
|
@@ -507,8 +660,14 @@ code {
|
|
|
507
660
|
}
|
|
508
661
|
|
|
509
662
|
@media (max-width: 900px) {
|
|
510
|
-
.office-main.studio-layout {
|
|
511
|
-
|
|
663
|
+
.office-main.studio-layout {
|
|
664
|
+
grid-template-columns: 1fr;
|
|
665
|
+
}
|
|
666
|
+
.transcript-panel {
|
|
667
|
+
max-height: 200px;
|
|
668
|
+
border-left: 0;
|
|
669
|
+
border-top: 1px solid rgba(255, 255, 255, 0.08);
|
|
670
|
+
}
|
|
512
671
|
}
|
|
513
672
|
|
|
514
673
|
.studio-main .transcript-list {
|
|
@@ -35,7 +35,8 @@
|
|
|
35
35
|
handoffPulse: null,
|
|
36
36
|
studioSessionId: boot.activeSessionId || "",
|
|
37
37
|
studioEvents: [],
|
|
38
|
-
speechBubbles: []
|
|
38
|
+
speechBubbles: [],
|
|
39
|
+
agenticLevel: null
|
|
39
40
|
};
|
|
40
41
|
|
|
41
42
|
const agentRuntime = {};
|
|
@@ -44,6 +45,11 @@
|
|
|
44
45
|
canvas: document.getElementById("office-floor"),
|
|
45
46
|
projectName: document.getElementById("project-name"),
|
|
46
47
|
progressPill: document.getElementById("progress-pill"),
|
|
48
|
+
levelPill: document.getElementById("level-pill"),
|
|
49
|
+
icebergStrip: document.getElementById("iceberg-strip"),
|
|
50
|
+
climbPanel: document.getElementById("climb-panel"),
|
|
51
|
+
climbList: document.getElementById("climb-list"),
|
|
52
|
+
climbRefresh: document.getElementById("climb-refresh"),
|
|
47
53
|
sessionPill: document.getElementById("session-pill"),
|
|
48
54
|
stationList: document.getElementById("station-list"),
|
|
49
55
|
status: document.getElementById("status"),
|
|
@@ -188,9 +194,11 @@
|
|
|
188
194
|
state.progress = data.progress || {};
|
|
189
195
|
state.onboarding = data.onboarding || {};
|
|
190
196
|
state.depth = data.onboarding?.depth || "undecided";
|
|
197
|
+
state.agenticLevel = data.agenticLevel || null;
|
|
191
198
|
if (Array.isArray(data.agents) && data.agents.length) state.agents = data.agents;
|
|
192
199
|
els.projectName.textContent = data.projectName || "your project";
|
|
193
200
|
updateProgressUi();
|
|
201
|
+
updateAgenticLevelUi();
|
|
194
202
|
renderStationList();
|
|
195
203
|
if (state.depth === "undecided") showDepthModal();
|
|
196
204
|
else {
|
|
@@ -260,7 +268,7 @@
|
|
|
260
268
|
(ev) =>
|
|
261
269
|
'<li><span class="tx-time">' +
|
|
262
270
|
escapeHtml((ev.createdAt || "").slice(11, 19)) +
|
|
263
|
-
|
|
271
|
+
"</span> <strong>" +
|
|
264
272
|
escapeHtml(ev.agentId || ev.fromAgentId || "session") +
|
|
265
273
|
"</strong> " +
|
|
266
274
|
escapeHtml(eventLabel(ev)) +
|
|
@@ -316,15 +324,7 @@
|
|
|
316
324
|
.map((b) => {
|
|
317
325
|
const left = offsetLeft + b.x * scaleX;
|
|
318
326
|
const top = offsetTop + b.y * scaleY - 28;
|
|
319
|
-
return (
|
|
320
|
-
'<span class="speech-bubble" style="left:' +
|
|
321
|
-
left +
|
|
322
|
-
"px;top:" +
|
|
323
|
-
top +
|
|
324
|
-
'px">' +
|
|
325
|
-
escapeHtml(b.text) +
|
|
326
|
-
"</span>"
|
|
327
|
-
);
|
|
327
|
+
return '<span class="speech-bubble" style="left:' + left + "px;top:" + top + 'px">' + escapeHtml(b.text) + "</span>";
|
|
328
328
|
})
|
|
329
329
|
.join("");
|
|
330
330
|
}
|
|
@@ -334,6 +334,57 @@
|
|
|
334
334
|
if (els.progressPill) els.progressPill.textContent = pct + "% ready";
|
|
335
335
|
}
|
|
336
336
|
|
|
337
|
+
function updateAgenticLevelUi() {
|
|
338
|
+
const level = state.agenticLevel;
|
|
339
|
+
if (!level || isStudio) return;
|
|
340
|
+
const current = level.currentLevel ?? 3;
|
|
341
|
+
const target = level.targetLevel ?? 5;
|
|
342
|
+
if (els.levelPill) {
|
|
343
|
+
els.levelPill.textContent = "L" + current + " → L" + target;
|
|
344
|
+
els.levelPill.setAttribute("aria-label", "Agentic engineering level " + current + ", target level " + target);
|
|
345
|
+
}
|
|
346
|
+
if (els.icebergStrip) {
|
|
347
|
+
els.icebergStrip.innerHTML = [3, 4, 5, 6, 7, 8]
|
|
348
|
+
.map((n) => {
|
|
349
|
+
let cls = "iceberg-seg";
|
|
350
|
+
if (n === current) cls += " current";
|
|
351
|
+
if (n === target && n !== current) cls += " target";
|
|
352
|
+
if (n >= 7) cls += " deferred";
|
|
353
|
+
return '<span class="' + cls + '">L' + n + "</span>";
|
|
354
|
+
})
|
|
355
|
+
.join("");
|
|
356
|
+
}
|
|
357
|
+
const steps = level.climbSteps || [];
|
|
358
|
+
if (els.climbPanel && els.climbList) {
|
|
359
|
+
if (current >= target || steps.length === 0) {
|
|
360
|
+
els.climbPanel.hidden = true;
|
|
361
|
+
} else {
|
|
362
|
+
els.climbPanel.hidden = false;
|
|
363
|
+
els.climbList.innerHTML = steps
|
|
364
|
+
.slice(0, 3)
|
|
365
|
+
.map((step) => "<li><strong>L" + step.level + "</strong> " + escapeHtml(step.label) + " — " + escapeHtml(step.remediation) + "</li>")
|
|
366
|
+
.join("");
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
if (level.maintainerNote && els.status && !els.status.textContent) {
|
|
370
|
+
setStatus("ok", level.maintainerNote);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
if (els.climbRefresh) {
|
|
375
|
+
els.climbRefresh.addEventListener("click", async () => {
|
|
376
|
+
try {
|
|
377
|
+
const data = await api("/api/agentic-level/refresh", { method: "POST" });
|
|
378
|
+
state.agenticLevel = data.agenticLevel;
|
|
379
|
+
state.progress = data.progress;
|
|
380
|
+
updateAgenticLevelUi();
|
|
381
|
+
setStatus("ok", "Agentic level refreshed.");
|
|
382
|
+
} catch (error) {
|
|
383
|
+
setStatus("error", error.message);
|
|
384
|
+
}
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
|
|
337
388
|
function spawnConfetti(x, y) {
|
|
338
389
|
if (state.reducedMotion) return;
|
|
339
390
|
for (let i = 0; i < 12; i += 1) {
|
|
@@ -395,17 +446,7 @@
|
|
|
395
446
|
const cx = offsetLeft + (station.x + station.w / 2) * TILE * scaleX;
|
|
396
447
|
const cy = offsetTop + station.y * TILE * scaleY - 4;
|
|
397
448
|
const st = stationStatus(station);
|
|
398
|
-
return (
|
|
399
|
-
'<span class="nameplate ' +
|
|
400
|
-
st +
|
|
401
|
-
'" style="left:' +
|
|
402
|
-
cx +
|
|
403
|
-
"px;top:" +
|
|
404
|
-
cy +
|
|
405
|
-
'px">' +
|
|
406
|
-
escapeHtml(station.label) +
|
|
407
|
-
"</span>"
|
|
408
|
-
);
|
|
449
|
+
return '<span class="nameplate ' + st + '" style="left:' + cx + "px;top:" + cy + 'px">' + escapeHtml(station.label) + "</span>";
|
|
409
450
|
})
|
|
410
451
|
.join("");
|
|
411
452
|
}
|
|
@@ -420,13 +461,7 @@
|
|
|
420
461
|
]
|
|
421
462
|
.map(
|
|
422
463
|
([id, title, desc]) =>
|
|
423
|
-
'<button type="button" class="depth-card" data-depth="' +
|
|
424
|
-
id +
|
|
425
|
-
'"><strong>' +
|
|
426
|
-
escapeHtml(title) +
|
|
427
|
-
"</strong><p>" +
|
|
428
|
-
escapeHtml(desc) +
|
|
429
|
-
"</p></button>"
|
|
464
|
+
'<button type="button" class="depth-card" data-depth="' + id + '"><strong>' + escapeHtml(title) + "</strong><p>" + escapeHtml(desc) + "</p></button>"
|
|
430
465
|
)
|
|
431
466
|
.join("");
|
|
432
467
|
els.depthGrid.querySelectorAll("[data-depth]").forEach((btn) => {
|
|
@@ -757,9 +792,9 @@
|
|
|
757
792
|
const req = optional ? "" : " required";
|
|
758
793
|
if (type === "textarea") {
|
|
759
794
|
return (
|
|
760
|
-
|
|
795
|
+
'<label for="p-' +
|
|
761
796
|
name +
|
|
762
|
-
"
|
|
797
|
+
'">' +
|
|
763
798
|
escapeHtml(label) +
|
|
764
799
|
(hint ? "<span>" + escapeHtml(hint) + "</span>" : "") +
|
|
765
800
|
'</label><textarea id="p-' +
|
|
@@ -776,9 +811,9 @@
|
|
|
776
811
|
);
|
|
777
812
|
}
|
|
778
813
|
return (
|
|
779
|
-
|
|
814
|
+
'<label for="p-' +
|
|
780
815
|
name +
|
|
781
|
-
"
|
|
816
|
+
'">' +
|
|
782
817
|
escapeHtml(label) +
|
|
783
818
|
(hint ? "<span>" + escapeHtml(hint) + "</span>" : "") +
|
|
784
819
|
'</label><input id="p-' +
|
|
@@ -806,7 +841,7 @@
|
|
|
806
841
|
field +
|
|
807
842
|
'">Project briefing<span>Optional — what is unique about this project for ' +
|
|
808
843
|
escapeHtml(station.label) +
|
|
809
|
-
|
|
844
|
+
'?</span></label><textarea id="p-' +
|
|
810
845
|
field +
|
|
811
846
|
'" name="' +
|
|
812
847
|
field +
|
|
@@ -819,16 +854,7 @@
|
|
|
819
854
|
const maps = {
|
|
820
855
|
ide: () => {
|
|
821
856
|
const opts = (boot.ideSurfaces || [])
|
|
822
|
-
.map(
|
|
823
|
-
(s) =>
|
|
824
|
-
'<option value="' +
|
|
825
|
-
s.id +
|
|
826
|
-
'"' +
|
|
827
|
-
(state.form.ideSurface === s.id ? " selected" : "") +
|
|
828
|
-
">" +
|
|
829
|
-
escapeHtml(s.label) +
|
|
830
|
-
"</option>"
|
|
831
|
-
)
|
|
857
|
+
.map((s) => '<option value="' + s.id + '"' + (state.form.ideSurface === s.id ? " selected" : "") + ">" + escapeHtml(s.label) + "</option>")
|
|
832
858
|
.join("");
|
|
833
859
|
return (
|
|
834
860
|
'<label for="p-ideSurface">Primary AI coding tool</label><select id="p-ideSurface" name="ideSurface" required><option value="">Choose…</option>' +
|
|
@@ -847,14 +873,10 @@
|
|
|
847
873
|
inputField("primaryWorkflows", "Top workflows", "One per line.", "textarea", "Workflow one", false),
|
|
848
874
|
access: () =>
|
|
849
875
|
'<label for="p-tenantModel">Who uses the system?</label><select id="p-tenantModel" name="tenantModel">' +
|
|
850
|
-
(boot.tenantModels || [])
|
|
851
|
-
.map((c) => '<option value="' + c + '"' + (state.form.tenantModel === c ? " selected" : "") + ">" + c + "</option>")
|
|
852
|
-
.join("") +
|
|
876
|
+
(boot.tenantModels || []).map((c) => '<option value="' + c + '"' + (state.form.tenantModel === c ? " selected" : "") + ">" + c + "</option>").join("") +
|
|
853
877
|
"</select>" +
|
|
854
878
|
inputField("owner", "Project owner", "Optional.", "text", "", true) +
|
|
855
|
-
(boot.hasSupabase
|
|
856
|
-
? '<div class="hint-box">Supabase detected.<button type="button" id="apply-supabase-auth">Insert auth baseline</button></div>'
|
|
857
|
-
: "") +
|
|
879
|
+
(boot.hasSupabase ? '<div class="hint-box">Supabase detected.<button type="button" id="apply-supabase-auth">Insert auth baseline</button></div>' : "") +
|
|
858
880
|
inputField("authModel", "Authentication model", "Rules agents must preserve.", "textarea", "Describe auth boundaries.", false),
|
|
859
881
|
ui: () =>
|
|
860
882
|
inputField("uiPreferred", "UI should feel like…", "", "textarea", "Clear, readable, task-first.", false) +
|