@zigrivers/scaffold 3.29.0 → 3.30.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 (72) hide show
  1. package/content/guides/AUTHORING.md +143 -0
  2. package/content/guides/cli/index.html +1502 -0
  3. package/content/guides/cli/index.md +206 -0
  4. package/content/guides/concepts/index.html +1617 -0
  5. package/content/guides/concepts/index.md +347 -0
  6. package/content/guides/dashboard/index.html +1560 -0
  7. package/content/guides/dashboard/index.md +264 -0
  8. package/content/guides/index.html +1 -1
  9. package/content/guides/install/.diagrams/diagram-0.svg +1 -0
  10. package/content/guides/install/.diagrams/manifest.json +3 -0
  11. package/content/guides/install/index.html +1300 -0
  12. package/content/guides/install/index.md +186 -0
  13. package/content/guides/knowledge/.diagrams/diagram-0.svg +1 -0
  14. package/content/guides/knowledge/.diagrams/manifest.json +3 -0
  15. package/content/guides/knowledge/index.html +1412 -0
  16. package/content/guides/knowledge/index.md +209 -0
  17. package/content/guides/knowledge-freshness/.diagrams/diagram-0.svg +1 -0
  18. package/content/guides/knowledge-freshness/.diagrams/manifest.json +3 -0
  19. package/content/guides/knowledge-freshness/index.html +2442 -0
  20. package/content/guides/knowledge-freshness/index.md +893 -0
  21. package/content/guides/mmr/index.html +35 -17
  22. package/content/guides/mmr/index.md +39 -16
  23. package/content/guides/multi-agent/.diagrams/diagram-0.svg +1 -0
  24. package/content/guides/multi-agent/.diagrams/manifest.json +3 -0
  25. package/content/guides/multi-agent/index.html +1362 -0
  26. package/content/guides/multi-agent/index.md +243 -0
  27. package/content/guides/observability/.diagrams/diagram-0.svg +1 -0
  28. package/content/guides/observability/.diagrams/diagram-1.svg +1 -0
  29. package/content/guides/observability/.diagrams/diagram-2.svg +1 -0
  30. package/content/guides/observability/.diagrams/diagram-3.svg +1 -0
  31. package/content/guides/observability/.diagrams/manifest.json +6 -0
  32. package/content/guides/observability/index.html +2904 -0
  33. package/content/guides/observability/index.md +1097 -0
  34. package/content/guides/pipeline/.diagrams/diagram-0.svg +1 -0
  35. package/content/guides/pipeline/.diagrams/diagram-1.svg +1 -0
  36. package/content/guides/pipeline/.diagrams/manifest.json +4 -0
  37. package/content/guides/pipeline/index.html +1632 -0
  38. package/content/guides/pipeline/index.md +387 -0
  39. package/content/guides/review-workflow/.diagrams/diagram-0.svg +1 -0
  40. package/content/guides/review-workflow/.diagrams/diagram-1.svg +1 -0
  41. package/content/guides/review-workflow/.diagrams/manifest.json +4 -0
  42. package/content/guides/review-workflow/index.html +1437 -0
  43. package/content/guides/review-workflow/index.md +248 -0
  44. package/dist/guides/build.d.ts.map +1 -1
  45. package/dist/guides/build.js +7 -2
  46. package/dist/guides/build.js.map +1 -1
  47. package/dist/guides/build.test.js +8 -0
  48. package/dist/guides/build.test.js.map +1 -1
  49. package/dist/guides/directives-cite.test.d.ts +2 -0
  50. package/dist/guides/directives-cite.test.d.ts.map +1 -0
  51. package/dist/guides/directives-cite.test.js +26 -0
  52. package/dist/guides/directives-cite.test.js.map +1 -0
  53. package/dist/guides/directives.d.ts +1 -0
  54. package/dist/guides/directives.d.ts.map +1 -1
  55. package/dist/guides/directives.js +24 -0
  56. package/dist/guides/directives.js.map +1 -1
  57. package/dist/guides/links.d.ts +14 -0
  58. package/dist/guides/links.d.ts.map +1 -0
  59. package/dist/guides/links.js +56 -0
  60. package/dist/guides/links.js.map +1 -0
  61. package/dist/guides/links.test.d.ts +2 -0
  62. package/dist/guides/links.test.d.ts.map +1 -0
  63. package/dist/guides/links.test.js +72 -0
  64. package/dist/guides/links.test.js.map +1 -0
  65. package/dist/guides/render.d.ts +1 -0
  66. package/dist/guides/render.d.ts.map +1 -1
  67. package/dist/guides/render.js +1 -1
  68. package/dist/guides/render.js.map +1 -1
  69. package/dist/guides/sanitize.d.ts.map +1 -1
  70. package/dist/guides/sanitize.js +1 -0
  71. package/dist/guides/sanitize.js.map +1 -1
  72. package/package.json +1 -1
@@ -0,0 +1,1300 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en" data-chrome-version="1">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title>Install, Update &amp; Adopt</title>
7
+ <!-- scaffold:chrome v1 -->
8
+ <style>/* Scaffold Dashboard Theme
9
+ * All CSS for the generated pipeline dashboard.
10
+ * Embedded into HTML by scripts/generate-dashboard.sh.
11
+ * Design system reference: docs/design-system.md
12
+ *
13
+ * Aesthetic: "Precision Industrial" — Swiss-typographic control room.
14
+ * Deep navy dark mode with indigo accents, clean cool-white light mode.
15
+ */
16
+
17
+ /* ─── Design Tokens (Light Mode) ──────────────── */
18
+ :root {
19
+ /* Surface */
20
+ --bg: #f5f6fa;
21
+ --bg-card: #ffffff;
22
+ --bg-hover: #eef0f6;
23
+ --bg-inset: #e8eaf2;
24
+
25
+ /* Text */
26
+ --text: #1a1d2e;
27
+ --text-muted: #6b7294;
28
+ --text-faint: #9ba1c0;
29
+
30
+ /* Borders & Structure */
31
+ --border: #dde0ed;
32
+ --border-light: #eceef5;
33
+ --radius: 10px;
34
+ --radius-sm: 6px;
35
+
36
+ /* Accent */
37
+ --accent: #4f46e5;
38
+ --accent-hover: #4338ca;
39
+ --accent-glow: rgba(79, 70, 229, 0.10);
40
+
41
+ /* Semantic: Status */
42
+ --green: #059669;
43
+ --green-bg: #ecfdf5;
44
+ --green-border: #a7f3d0;
45
+ --blue: #2563eb;
46
+ --blue-bg: #eff6ff;
47
+ --blue-border: #bfdbfe;
48
+ --yellow: #d97706;
49
+ --yellow-bg: #fffbeb;
50
+ --yellow-border:#fde68a;
51
+ --gray: #9ca3af;
52
+ --gray-bg: #f3f4f6;
53
+ --gray-border: #e5e7eb;
54
+
55
+ /* Semantic: Next Banner */
56
+ --next-bg: #eef2ff;
57
+ --next-border: #4f46e5;
58
+ --next-glow: rgba(79, 70, 229, 0.06);
59
+
60
+ /* Semantic: Progress */
61
+ --progress-bg: #e5e7eb;
62
+ --progress-h: 10px;
63
+
64
+ /* Depth */
65
+ --shadow-sm: 0 1px 2px rgba(30, 34, 60, 0.04);
66
+ --shadow: 0 1px 3px rgba(30, 34, 60, 0.07), 0 1px 2px rgba(30, 34, 60, 0.04);
67
+ --shadow-md: 0 4px 12px rgba(30, 34, 60, 0.08), 0 1px 3px rgba(30, 34, 60, 0.05);
68
+ --shadow-lg: 0 8px 24px rgba(30, 34, 60, 0.10), 0 2px 6px rgba(30, 34, 60, 0.04);
69
+
70
+ /* Spacing scale (4px base) */
71
+ --sp-1: 4px;
72
+ --sp-2: 8px;
73
+ --sp-3: 12px;
74
+ --sp-4: 16px;
75
+ --sp-5: 20px;
76
+ --sp-6: 24px;
77
+ --sp-8: 32px;
78
+ --sp-10: 40px;
79
+
80
+ /* Typography */
81
+ --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
82
+ --font-mono: "SF Mono", "Cascadia Code", "Fira Code", "JetBrains Mono", Menlo, Consolas, monospace;
83
+ --text-xs: 0.75rem;
84
+ --text-sm: 0.8125rem;
85
+ --text-base: 0.9375rem;
86
+ --text-lg: 1.125rem;
87
+ --text-xl: 1.375rem;
88
+ --text-2xl: 1.75rem;
89
+ --lh-tight: 1.25;
90
+ --lh-normal: 1.5;
91
+ --lh-relaxed: 1.625;
92
+ --ls-tight: -0.01em;
93
+ --ls-wide: 0.025em;
94
+ --fw-normal: 400;
95
+ --fw-medium: 500;
96
+ --fw-semi: 600;
97
+ --fw-bold: 700;
98
+
99
+ /* Layout */
100
+ --max-w: 960px;
101
+ --page-pad: 24px;
102
+ }
103
+
104
+ /* ─── Design Tokens (Dark Mode) ───────────────── */
105
+ [data-theme="dark"] {
106
+ /* Surface */
107
+ --bg: #0f1117;
108
+ --bg-card: #1a1d2e;
109
+ --bg-hover: #252940;
110
+ --bg-inset: #141724;
111
+
112
+ /* Text */
113
+ --text: #e2e5f0;
114
+ --text-muted: #7c82a8;
115
+ --text-faint: #555c80;
116
+
117
+ /* Borders & Structure */
118
+ --border: #2a2f45;
119
+ --border-light: #21253a;
120
+
121
+ /* Accent */
122
+ --accent: #818cf8;
123
+ --accent-hover: #a5b4fc;
124
+ --accent-glow: rgba(129, 140, 248, 0.12);
125
+
126
+ /* Semantic: Status */
127
+ --green: #34d399;
128
+ --green-bg: rgba(6, 78, 59, 0.25);
129
+ --green-border: rgba(52, 211, 153, 0.25);
130
+ --blue: #60a5fa;
131
+ --blue-bg: rgba(30, 58, 95, 0.30);
132
+ --blue-border: rgba(96, 165, 250, 0.25);
133
+ --yellow: #fbbf24;
134
+ --yellow-bg: rgba(120, 53, 15, 0.25);
135
+ --yellow-border:rgba(251, 191, 36, 0.20);
136
+ --gray: #6b7294;
137
+ --gray-bg: #252940;
138
+ --gray-border: #363c58;
139
+
140
+ /* Semantic: Next Banner */
141
+ --next-bg: rgba(30, 27, 75, 0.50);
142
+ --next-border: #818cf8;
143
+ --next-glow: rgba(129, 140, 248, 0.08);
144
+
145
+ /* Semantic: Progress */
146
+ --progress-bg: #1f2337;
147
+
148
+ /* Depth */
149
+ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.20);
150
+ --shadow: 0 1px 3px rgba(0, 0, 0, 0.30), 0 1px 2px rgba(0, 0, 0, 0.15);
151
+ --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.35), 0 1px 3px rgba(0, 0, 0, 0.20);
152
+ --shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.40), 0 2px 6px rgba(0, 0, 0, 0.20);
153
+ }
154
+
155
+ /* ─── Theme Toggle ───────────────────────────── */
156
+ .theme-toggle {
157
+ background: var(--bg-inset);
158
+ border: 1px solid var(--border);
159
+ border-radius: var(--radius-sm);
160
+ padding: var(--sp-1) var(--sp-2);
161
+ cursor: pointer;
162
+ font-size: var(--text-base);
163
+ line-height: 1;
164
+ color: var(--text-muted);
165
+ transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
166
+ display: flex;
167
+ align-items: center;
168
+ margin-left: auto;
169
+ }
170
+
171
+ .theme-toggle:hover {
172
+ border-color: var(--accent);
173
+ color: var(--accent);
174
+ background: var(--accent-glow);
175
+ }
176
+
177
+ /* ─── Base ────────────────────────────────────── */
178
+ *, *::before, *::after {
179
+ margin: 0;
180
+ padding: 0;
181
+ box-sizing: border-box;
182
+ }
183
+
184
+ body {
185
+ font-family: var(--font-sans);
186
+ font-size: var(--text-base);
187
+ line-height: var(--lh-normal);
188
+ color: var(--text);
189
+ background: var(--bg);
190
+ -webkit-font-smoothing: antialiased;
191
+ -moz-osx-font-smoothing: grayscale;
192
+ }
193
+
194
+ /* ─── Layout ──────────────────────────────────── */
195
+ .wrap {
196
+ max-width: var(--max-w);
197
+ margin: 0 auto;
198
+ padding: var(--sp-8) var(--page-pad);
199
+ }
200
+
201
+ /* ─── Header ──────────────────────────────────── */
202
+ .header {
203
+ display: flex;
204
+ align-items: baseline;
205
+ gap: var(--sp-3);
206
+ margin-bottom: var(--sp-2);
207
+ flex-wrap: wrap;
208
+ }
209
+
210
+ h1 {
211
+ font-size: var(--text-2xl);
212
+ font-weight: var(--fw-bold);
213
+ letter-spacing: var(--ls-tight);
214
+ line-height: var(--lh-tight);
215
+ }
216
+
217
+ h2 {
218
+ font-size: var(--text-lg);
219
+ font-weight: var(--fw-semi);
220
+ letter-spacing: var(--ls-tight);
221
+ line-height: var(--lh-tight);
222
+ margin-bottom: var(--sp-3);
223
+ }
224
+
225
+ .header-meta {
226
+ font-size: var(--text-xs);
227
+ color: var(--text-faint);
228
+ margin-bottom: var(--sp-6);
229
+ letter-spacing: var(--ls-wide);
230
+ text-transform: uppercase;
231
+ }
232
+
233
+ /* ─── Badge ───────────────────────────────────── */
234
+ .badge {
235
+ display: inline-block;
236
+ padding: 2px var(--sp-2);
237
+ border-radius: 99px;
238
+ font-size: var(--text-xs);
239
+ font-weight: var(--fw-semi);
240
+ letter-spacing: var(--ls-wide);
241
+ background: var(--accent);
242
+ color: #fff;
243
+ text-transform: uppercase;
244
+ }
245
+
246
+ .badge-optional {
247
+ background: var(--yellow-bg);
248
+ color: var(--yellow);
249
+ border: 1px solid var(--yellow-border);
250
+ }
251
+
252
+ /* ─── Progress Bar ────────────────────────────── */
253
+ .progress-bar {
254
+ width: 100%;
255
+ height: var(--progress-h);
256
+ background: var(--progress-bg);
257
+ border-radius: 99px;
258
+ overflow: hidden;
259
+ margin-bottom: var(--sp-6);
260
+ display: flex;
261
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.06);
262
+ }
263
+
264
+ .progress-bar .seg-done {
265
+ background: linear-gradient(135deg, var(--green), #10b981);
266
+ box-shadow: 0 0 8px rgba(5, 150, 105, 0.3);
267
+ }
268
+
269
+ .progress-bar .seg-likely {
270
+ background: linear-gradient(135deg, var(--blue), #3b82f6);
271
+ box-shadow: 0 0 8px rgba(37, 99, 235, 0.25);
272
+ }
273
+
274
+ .progress-bar .seg-skip {
275
+ background: var(--gray);
276
+ opacity: 0.7;
277
+ }
278
+
279
+ /* ─── Summary Cards ───────────────────────────── */
280
+ .cards {
281
+ display: grid;
282
+ grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
283
+ gap: var(--sp-3);
284
+ margin-bottom: var(--sp-6);
285
+ }
286
+
287
+ .card {
288
+ background: var(--bg-card);
289
+ border: 1px solid var(--border);
290
+ border-radius: var(--radius);
291
+ padding: var(--sp-4) var(--sp-5);
292
+ box-shadow: var(--shadow);
293
+ transition: box-shadow 0.15s ease, transform 0.15s ease;
294
+ }
295
+
296
+ .card:hover {
297
+ box-shadow: var(--shadow-md);
298
+ transform: translateY(-1px);
299
+ }
300
+
301
+ .card-num {
302
+ font-size: var(--text-2xl);
303
+ font-weight: var(--fw-bold);
304
+ font-family: var(--font-mono);
305
+ letter-spacing: var(--ls-tight);
306
+ line-height: 1;
307
+ }
308
+
309
+ .card-lbl {
310
+ font-size: var(--text-xs);
311
+ color: var(--text-muted);
312
+ margin-top: var(--sp-1);
313
+ letter-spacing: var(--ls-wide);
314
+ text-transform: uppercase;
315
+ font-weight: var(--fw-medium);
316
+ }
317
+
318
+ /* ─── What's Next Banner ──────────────────────── */
319
+ .next-banner {
320
+ background: var(--next-bg);
321
+ border: 1px solid var(--next-border);
322
+ border-left: 4px solid var(--next-border);
323
+ border-radius: var(--radius);
324
+ padding: var(--sp-5) var(--sp-6);
325
+ margin-bottom: var(--sp-6);
326
+ box-shadow: 0 0 0 1px var(--next-glow), var(--shadow);
327
+ position: relative;
328
+ overflow: hidden;
329
+ }
330
+
331
+ .next-banner::before {
332
+ content: "";
333
+ position: absolute;
334
+ top: 0;
335
+ left: 0;
336
+ width: 4px;
337
+ height: 100%;
338
+ background: var(--next-border);
339
+ animation: pulse-border 2.5s ease-in-out infinite;
340
+ }
341
+
342
+ @keyframes pulse-border {
343
+ 0%, 100% { opacity: 1; }
344
+ 50% { opacity: 0.5; }
345
+ }
346
+
347
+ .next-banner h2 {
348
+ color: var(--accent);
349
+ margin-bottom: var(--sp-1);
350
+ font-size: var(--text-base);
351
+ font-weight: var(--fw-semi);
352
+ letter-spacing: var(--ls-wide);
353
+ text-transform: uppercase;
354
+ }
355
+
356
+ .next-banner p {
357
+ color: var(--text);
358
+ font-size: var(--text-base);
359
+ }
360
+
361
+ .next-cmd {
362
+ font-family: var(--font-mono);
363
+ background: var(--bg-card);
364
+ padding: var(--sp-1) var(--sp-3);
365
+ border-radius: var(--radius-sm);
366
+ font-size: var(--text-sm);
367
+ display: inline-flex;
368
+ align-items: center;
369
+ gap: var(--sp-2);
370
+ margin-top: var(--sp-3);
371
+ border: 1px solid var(--border);
372
+ }
373
+
374
+ /* ─── Phase Headers (Collapsible) ─────────────── */
375
+ .phase {
376
+ margin-bottom: var(--sp-6);
377
+ }
378
+
379
+ .phase-hdr {
380
+ display: flex;
381
+ align-items: center;
382
+ gap: var(--sp-2);
383
+ cursor: pointer;
384
+ padding: var(--sp-2) 0;
385
+ user-select: none;
386
+ border-bottom: 2px solid var(--border);
387
+ margin-bottom: var(--sp-3);
388
+ transition: border-color 0.15s ease;
389
+ }
390
+
391
+ .phase-hdr:hover {
392
+ border-bottom-color: var(--accent);
393
+ }
394
+
395
+ .phase-hdr:hover h2 {
396
+ color: var(--accent);
397
+ }
398
+
399
+ .phase-hdr h2 {
400
+ transition: color 0.15s ease;
401
+ }
402
+
403
+ .phase-hdr .arr {
404
+ transition: transform 0.2s ease;
405
+ font-size: var(--text-xs);
406
+ color: var(--text-muted);
407
+ }
408
+
409
+ .phase-hdr.closed .arr {
410
+ transform: rotate(-90deg);
411
+ }
412
+
413
+ .phase-cnt {
414
+ font-size: var(--text-xs);
415
+ font-family: var(--font-mono);
416
+ color: var(--text-faint);
417
+ margin-left: auto;
418
+ letter-spacing: var(--ls-wide);
419
+ }
420
+
421
+ /* ─── Prompt List ─────────────────────────────── */
422
+ .plist {
423
+ display: flex;
424
+ flex-direction: column;
425
+ gap: var(--sp-2);
426
+ }
427
+
428
+ /* ─── Prompt Cards ────────────────────────────── */
429
+ .pcard {
430
+ background: var(--bg-card);
431
+ border: 1px solid var(--border);
432
+ border-radius: var(--radius);
433
+ padding: var(--sp-3) var(--sp-4);
434
+ box-shadow: var(--shadow-sm);
435
+ display: grid;
436
+ grid-template-columns: auto 1fr auto;
437
+ gap: var(--sp-2) var(--sp-3);
438
+ align-items: start;
439
+ transition: box-shadow 0.15s ease, transform 0.15s ease, border-color 0.15s ease;
440
+ }
441
+
442
+ .pcard:hover {
443
+ box-shadow: var(--shadow);
444
+ transform: translateY(-1px);
445
+ border-color: var(--accent-glow);
446
+ }
447
+
448
+ /* ─── Status Badges ──────────────────────────── */
449
+ .status-badge {
450
+ display: inline-flex;
451
+ align-items: center;
452
+ gap: var(--sp-1);
453
+ font-size: var(--text-xs);
454
+ font-weight: var(--fw-medium);
455
+ padding: 2px var(--sp-2);
456
+ border-radius: 99px;
457
+ white-space: nowrap;
458
+ flex-shrink: 0;
459
+ letter-spacing: var(--ls-wide);
460
+ line-height: var(--lh-tight);
461
+ }
462
+
463
+ .st-completed {
464
+ background: var(--green-bg);
465
+ color: var(--green);
466
+ border: 1px solid var(--green-border);
467
+ }
468
+
469
+ .st-likely-completed {
470
+ background: var(--blue-bg);
471
+ color: var(--blue);
472
+ border: 1px solid var(--blue-border);
473
+ }
474
+
475
+ .st-skipped {
476
+ background: var(--gray-bg);
477
+ color: var(--gray);
478
+ border: 1px solid var(--gray-border);
479
+ }
480
+
481
+ .st-pending {
482
+ background: var(--bg-inset);
483
+ color: var(--text-faint);
484
+ border: 1px solid var(--border);
485
+ }
486
+
487
+ /* ─── Status Legend ──────────────────────────── */
488
+ .status-legend {
489
+ display: flex;
490
+ flex-wrap: wrap;
491
+ gap: var(--sp-2);
492
+ margin-bottom: var(--sp-4);
493
+ padding: var(--sp-2) 0;
494
+ }
495
+
496
+ .status-legend .status-badge {
497
+ cursor: default;
498
+ }
499
+
500
+ /* ─── Prompt Card Inner ───────────────────────── */
501
+ .pinfo {
502
+ min-width: 0;
503
+ }
504
+
505
+ .pname {
506
+ font-weight: var(--fw-semi);
507
+ font-size: var(--text-base);
508
+ }
509
+
510
+ .pstep {
511
+ font-size: var(--text-xs);
512
+ font-family: var(--font-mono);
513
+ color: var(--text-faint);
514
+ letter-spacing: var(--ls-wide);
515
+ }
516
+
517
+ .pdesc {
518
+ font-size: var(--text-sm);
519
+ color: var(--text-muted);
520
+ margin-top: 2px;
521
+ line-height: var(--lh-relaxed);
522
+ }
523
+
524
+ .pdesc-long {
525
+ font-size: var(--text-xs);
526
+ color: var(--text-faint);
527
+ margin-top: 2px;
528
+ }
529
+
530
+ .pdeps {
531
+ font-size: var(--text-xs);
532
+ color: var(--yellow);
533
+ margin-top: var(--sp-1);
534
+ font-weight: var(--fw-medium);
535
+ }
536
+
537
+ /* ─── Copy Command Button ─────────────────────── */
538
+ .pcmd {
539
+ font-family: var(--font-mono);
540
+ font-size: var(--text-xs);
541
+ background: var(--bg-inset);
542
+ padding: 3px var(--sp-2);
543
+ border-radius: var(--radius-sm);
544
+ cursor: pointer;
545
+ border: 1px solid var(--border);
546
+ white-space: nowrap;
547
+ align-self: center;
548
+ color: var(--text-muted);
549
+ transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
550
+ letter-spacing: var(--ls-wide);
551
+ }
552
+
553
+ .pcmd:hover {
554
+ border-color: var(--accent);
555
+ color: var(--accent);
556
+ background: var(--accent-glow);
557
+ }
558
+
559
+ .pcmd.copied {
560
+ border-color: var(--green);
561
+ color: var(--green);
562
+ background: var(--green-bg);
563
+ }
564
+
565
+ /* ─── Prompt Modal ────────────────────────────── */
566
+ .modal-overlay {
567
+ position: fixed;
568
+ inset: 0;
569
+ background: rgba(0, 0, 0, 0.6);
570
+ display: flex;
571
+ align-items: center;
572
+ justify-content: center;
573
+ z-index: 1000;
574
+ padding: var(--sp-4);
575
+ }
576
+
577
+ .modal {
578
+ background: var(--bg-card);
579
+ border: 1px solid var(--border);
580
+ border-radius: var(--radius);
581
+ box-shadow: var(--shadow-lg);
582
+ max-width: 720px;
583
+ width: 100%;
584
+ max-height: 85vh;
585
+ display: flex;
586
+ flex-direction: column;
587
+ }
588
+
589
+ .modal-header {
590
+ display: flex;
591
+ align-items: center;
592
+ gap: var(--sp-3);
593
+ padding: var(--sp-4) var(--sp-5);
594
+ border-bottom: 1px solid var(--border);
595
+ flex-shrink: 0;
596
+ }
597
+
598
+ .modal-header h3 {
599
+ font-size: var(--text-lg);
600
+ font-weight: var(--fw-semi);
601
+ flex: 1;
602
+ min-width: 0;
603
+ }
604
+
605
+ .modal-close {
606
+ background: var(--bg-inset);
607
+ border: 1px solid var(--border);
608
+ border-radius: var(--radius-sm);
609
+ padding: var(--sp-1) var(--sp-2);
610
+ cursor: pointer;
611
+ font-size: var(--text-base);
612
+ color: var(--text-muted);
613
+ line-height: 1;
614
+ transition: border-color 0.15s ease, color 0.15s ease;
615
+ }
616
+
617
+ .modal-close:hover {
618
+ border-color: var(--accent);
619
+ color: var(--accent);
620
+ }
621
+
622
+ .modal-body {
623
+ padding: var(--sp-5);
624
+ overflow-y: auto;
625
+ flex: 1;
626
+ }
627
+
628
+ .modal-body pre {
629
+ font-family: var(--font-mono);
630
+ font-size: var(--text-sm);
631
+ line-height: var(--lh-relaxed);
632
+ white-space: pre-wrap;
633
+ word-break: break-word;
634
+ color: var(--text);
635
+ }
636
+
637
+ .modal-body pre .md-heading {
638
+ font-weight: var(--fw-bold);
639
+ color: var(--accent);
640
+ }
641
+
642
+ .modal-body pre .md-code {
643
+ background: var(--bg-inset);
644
+ padding: 1px 4px;
645
+ border-radius: 3px;
646
+ font-size: var(--text-xs);
647
+ }
648
+
649
+ .modal-footer {
650
+ display: flex;
651
+ gap: var(--sp-2);
652
+ padding: var(--sp-3) var(--sp-5);
653
+ border-top: 1px solid var(--border);
654
+ flex-shrink: 0;
655
+ }
656
+
657
+ .modal-copy-btn {
658
+ background: var(--accent);
659
+ color: #fff;
660
+ border: none;
661
+ border-radius: var(--radius-sm);
662
+ padding: var(--sp-2) var(--sp-4);
663
+ font-size: var(--text-sm);
664
+ font-weight: var(--fw-medium);
665
+ cursor: pointer;
666
+ transition: background 0.15s ease;
667
+ }
668
+
669
+ .modal-copy-btn:hover {
670
+ background: var(--accent-hover);
671
+ }
672
+
673
+ .modal-copy-btn.copied {
674
+ background: var(--green);
675
+ }
676
+
677
+ /* ─── Beads Task Section ─────────────────────── */
678
+ .beads-section {
679
+ margin-top: var(--sp-8);
680
+ margin-bottom: var(--sp-6);
681
+ }
682
+
683
+ .beads-filters {
684
+ display: flex;
685
+ gap: var(--sp-2);
686
+ margin-bottom: var(--sp-3);
687
+ }
688
+
689
+ .beads-filter {
690
+ background: var(--bg-inset);
691
+ border: 1px solid var(--border);
692
+ border-radius: 99px;
693
+ padding: var(--sp-1) var(--sp-3);
694
+ font-size: var(--text-xs);
695
+ font-weight: var(--fw-medium);
696
+ color: var(--text-muted);
697
+ cursor: pointer;
698
+ transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
699
+ letter-spacing: var(--ls-wide);
700
+ }
701
+
702
+ .beads-filter:hover {
703
+ border-color: var(--accent);
704
+ color: var(--accent);
705
+ }
706
+
707
+ .beads-filter.active {
708
+ background: var(--accent);
709
+ color: #fff;
710
+ border-color: var(--accent);
711
+ }
712
+
713
+ /* ─── Beads Status Badges ────────────────────── */
714
+ .st-bead-open {
715
+ background: var(--accent-glow);
716
+ color: var(--accent);
717
+ border: 1px solid var(--accent);
718
+ }
719
+
720
+ .st-bead-progress {
721
+ background: var(--blue-bg);
722
+ color: var(--blue);
723
+ border: 1px solid var(--blue-border);
724
+ }
725
+
726
+ .st-bead-blocked {
727
+ background: var(--yellow-bg);
728
+ color: var(--yellow);
729
+ border: 1px solid var(--yellow-border);
730
+ }
731
+
732
+ .st-bead-deferred {
733
+ background: var(--gray-bg);
734
+ color: var(--gray);
735
+ border: 1px solid var(--gray-border);
736
+ }
737
+
738
+ .st-bead-closed {
739
+ background: var(--green-bg);
740
+ color: var(--green);
741
+ border: 1px solid var(--green-border);
742
+ }
743
+
744
+ /* ─── Beads Filter Separator ─────────────────── */
745
+ .beads-filter-sep {
746
+ width: 1px;
747
+ background: var(--border);
748
+ align-self: stretch;
749
+ margin: 0 var(--sp-1);
750
+ }
751
+
752
+ /* ─── Beads Priority Filter ──────────────────── */
753
+ .beads-prio-filter {
754
+ background: var(--bg-inset);
755
+ border: 1px solid var(--border);
756
+ border-radius: 99px;
757
+ padding: var(--sp-1) var(--sp-3);
758
+ font-size: var(--text-xs);
759
+ font-weight: var(--fw-medium);
760
+ color: var(--text-muted);
761
+ cursor: pointer;
762
+ transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
763
+ letter-spacing: var(--ls-wide);
764
+ }
765
+
766
+ .beads-prio-filter:hover {
767
+ border-color: var(--accent);
768
+ color: var(--accent);
769
+ }
770
+
771
+ .beads-prio-filter.active {
772
+ background: var(--accent);
773
+ color: #fff;
774
+ border-color: var(--accent);
775
+ }
776
+
777
+ /* ─── Beads Task Detail Modal ────────────────── */
778
+ .bead-meta-grid {
779
+ display: grid;
780
+ grid-template-columns: 1fr 1fr;
781
+ gap: var(--sp-3);
782
+ padding: var(--sp-4) 0;
783
+ border-bottom: 1px solid var(--border-light);
784
+ }
785
+
786
+ .bead-meta-item {
787
+ display: flex;
788
+ flex-direction: column;
789
+ gap: 2px;
790
+ }
791
+
792
+ .bead-meta-label {
793
+ font-size: var(--text-xs);
794
+ color: var(--text-faint);
795
+ text-transform: uppercase;
796
+ letter-spacing: var(--ls-wide);
797
+ font-weight: var(--fw-medium);
798
+ }
799
+
800
+ .bead-meta-value {
801
+ font-size: var(--text-sm);
802
+ font-weight: var(--fw-medium);
803
+ color: var(--text);
804
+ }
805
+
806
+ .bead-description {
807
+ padding: var(--sp-4) 0;
808
+ border-bottom: 1px solid var(--border-light);
809
+ white-space: pre-wrap;
810
+ font-size: var(--text-sm);
811
+ line-height: var(--lh-relaxed);
812
+ color: var(--text-muted);
813
+ }
814
+
815
+ .bead-deps {
816
+ padding: var(--sp-4) 0;
817
+ border-bottom: 1px solid var(--border-light);
818
+ }
819
+
820
+ .bead-dep-group {
821
+ display: flex;
822
+ flex-wrap: wrap;
823
+ align-items: center;
824
+ gap: var(--sp-2);
825
+ margin-bottom: var(--sp-2);
826
+ }
827
+
828
+ .bead-dep-group:last-child {
829
+ margin-bottom: 0;
830
+ }
831
+
832
+ .bead-dep-label {
833
+ font-size: var(--text-xs);
834
+ color: var(--text-faint);
835
+ text-transform: uppercase;
836
+ letter-spacing: var(--ls-wide);
837
+ font-weight: var(--fw-medium);
838
+ min-width: 80px;
839
+ }
840
+
841
+ .bead-dep-link {
842
+ display: inline-block;
843
+ font-family: var(--font-mono);
844
+ font-size: var(--text-xs);
845
+ padding: 2px var(--sp-2);
846
+ border-radius: 99px;
847
+ background: var(--accent-glow);
848
+ color: var(--accent);
849
+ border: 1px solid var(--accent);
850
+ cursor: pointer;
851
+ transition: background 0.15s ease, color 0.15s ease;
852
+ text-decoration: none;
853
+ }
854
+
855
+ .bead-dep-link:hover {
856
+ background: var(--accent);
857
+ color: #fff;
858
+ }
859
+
860
+ .bead-timestamps {
861
+ display: flex;
862
+ flex-wrap: wrap;
863
+ gap: var(--sp-4);
864
+ padding: var(--sp-4) 0;
865
+ }
866
+
867
+ .bead-ts-item {
868
+ display: flex;
869
+ flex-direction: column;
870
+ gap: 2px;
871
+ }
872
+
873
+ .bead-ts-label {
874
+ font-size: var(--text-xs);
875
+ color: var(--text-faint);
876
+ text-transform: uppercase;
877
+ letter-spacing: var(--ls-wide);
878
+ font-weight: var(--fw-medium);
879
+ }
880
+
881
+ .bead-ts-value {
882
+ font-size: var(--text-sm);
883
+ color: var(--text-muted);
884
+ }
885
+
886
+ .bead-ts-value[title] {
887
+ border-bottom: 1px dotted var(--text-faint);
888
+ cursor: help;
889
+ }
890
+
891
+ /* ─── Standalone Commands Section ─────────────── */
892
+ .ongoing {
893
+ margin-top: var(--sp-10);
894
+ }
895
+
896
+ .ongoing h2 {
897
+ letter-spacing: var(--ls-wide);
898
+ text-transform: uppercase;
899
+ font-size: var(--text-sm);
900
+ color: var(--text-muted);
901
+ margin-bottom: var(--sp-4);
902
+ border-bottom: 2px solid var(--border);
903
+ padding-bottom: var(--sp-2);
904
+ }
905
+
906
+ /* ─── Footer ──────────────────────────────────── */
907
+ .footer {
908
+ text-align: center;
909
+ font-size: var(--text-xs);
910
+ color: var(--text-faint);
911
+ margin-top: var(--sp-10);
912
+ padding-top: var(--sp-4);
913
+ border-top: 1px solid var(--border-light);
914
+ letter-spacing: var(--ls-wide);
915
+ }
916
+
917
+ /* ─── Utilities ───────────────────────────────── */
918
+ .hidden {
919
+ display: none;
920
+ }
921
+
922
+ /* Build-observability severity + verdict tokens (Plan 4) */
923
+ :root {
924
+ --sev-p0: #dc2626; /* red 600 */
925
+ --sev-p1: #ea580c; /* orange 600 */
926
+ --sev-p2: #ca8a04; /* yellow 600 */
927
+ --sev-p3: #2563eb; /* blue 600 */
928
+ --sev-pass: #16a34a; /* green 600 */
929
+ }
930
+ [data-theme="dark"] {
931
+ --sev-p0: #f87171;
932
+ --sev-p1: #fb923c;
933
+ --sev-p2: #facc15;
934
+ --sev-p3: #60a5fa;
935
+ --sev-pass: #4ade80;
936
+ }
937
+
938
+ /* Build-observability panel layout */
939
+ .panel {
940
+ background: var(--bg-card);
941
+ border: 1px solid var(--border);
942
+ border-radius: var(--radius);
943
+ padding: var(--sp-4) var(--sp-6);
944
+ margin-bottom: var(--sp-6);
945
+ }
946
+ .panel > header {
947
+ display: flex;
948
+ align-items: center;
949
+ gap: var(--sp-3);
950
+ margin-bottom: var(--sp-4);
951
+ flex-wrap: wrap;
952
+ }
953
+ .panel > header h2 {
954
+ margin: 0;
955
+ font-size: var(--text-base);
956
+ font-weight: var(--fw-semi);
957
+ }
958
+ .panel .meta {
959
+ color: var(--text-muted);
960
+ font-size: var(--text-sm);
961
+ }
962
+ .grid { display: grid; gap: var(--sp-4); }
963
+ .grid-2 { grid-template-columns: repeat(2, 1fr); }
964
+ @media (max-width: 640px) { .grid-2 { grid-template-columns: 1fr; } }
965
+
966
+ /* Finding filters */
967
+ .finding-filters {
968
+ display: flex;
969
+ gap: var(--sp-2);
970
+ flex-wrap: wrap;
971
+ margin-bottom: var(--sp-4);
972
+ }
973
+ .finding-filters button {
974
+ padding: var(--sp-1) var(--sp-3);
975
+ border: 1px solid var(--border);
976
+ border-radius: var(--radius-sm);
977
+ background: var(--bg-inset);
978
+ color: var(--text);
979
+ font-size: var(--text-sm);
980
+ cursor: pointer;
981
+ }
982
+ .finding-filters button:hover,
983
+ .finding-filters button.active {
984
+ background: var(--accent);
985
+ border-color: var(--accent);
986
+ color: #fff;
987
+ }
988
+
989
+ /* Findings list */
990
+ .findings {
991
+ list-style: none;
992
+ padding: 0;
993
+ margin: 0;
994
+ display: flex;
995
+ flex-direction: column;
996
+ gap: var(--sp-3);
997
+ }
998
+ .finding {
999
+ background: var(--bg-inset);
1000
+ border: 1px solid var(--border-light);
1001
+ border-radius: var(--radius-sm);
1002
+ padding: var(--sp-3) var(--sp-4);
1003
+ }
1004
+ .finding header {
1005
+ display: flex;
1006
+ align-items: center;
1007
+ gap: var(--sp-2);
1008
+ flex-wrap: wrap;
1009
+ margin-bottom: var(--sp-2);
1010
+ }
1011
+ .finding-id {
1012
+ font-family: var(--font-mono, monospace);
1013
+ font-size: var(--text-xs);
1014
+ color: var(--text-muted);
1015
+ background: var(--bg-card);
1016
+ border: 1px solid var(--border);
1017
+ border-radius: 4px;
1018
+ padding: 1px var(--sp-1);
1019
+ }
1020
+ .finding .lens {
1021
+ font-size: var(--text-xs);
1022
+ color: var(--text-muted);
1023
+ }
1024
+ .finding .title {
1025
+ font-size: var(--text-sm);
1026
+ font-weight: var(--fw-semi);
1027
+ flex: 1;
1028
+ }
1029
+ .finding p { margin: 0; font-size: var(--text-sm); color: var(--text-muted); }
1030
+ .empty { color: var(--text-muted); font-size: var(--text-sm); text-align: center; padding: var(--sp-4); }
1031
+
1032
+ /* ── Mermaid diagrams ─────────────────────────────────────────────────────────
1033
+ The build renders mermaid to inline SVG via mmdc, then sanitizeSvg() +
1034
+ rehype-sanitize strip the SVG's own <script>, <foreignObject>, AND <style>
1035
+ for security. Stripping <style> means the diagram arrives unstyled (nodes
1036
+ default to a black fill). These theme-token rules restyle the SVG so nodes,
1037
+ edges, arrowheads, and labels render correctly — and follow light/dark mode.
1038
+ Authors must render with htmlLabels:false (the generator forces this) so node
1039
+ labels are native <text>/<tspan> rather than stripped <foreignObject> HTML. */
1040
+ figure.mermaid { margin: var(--sp-5) 0; text-align: center; }
1041
+ figure.mermaid svg { max-width: 100%; height: auto; }
1042
+ /* Node shapes */
1043
+ figure.mermaid svg .node rect,
1044
+ figure.mermaid svg .node circle,
1045
+ figure.mermaid svg .node ellipse,
1046
+ figure.mermaid svg .node polygon,
1047
+ figure.mermaid svg .node path {
1048
+ fill: var(--bg-inset);
1049
+ stroke: var(--border);
1050
+ stroke-width: 1px;
1051
+ }
1052
+ /* Background helper rects mermaid emits behind labels */
1053
+ figure.mermaid svg .node .label-container { fill: var(--bg-inset); stroke: var(--border); }
1054
+ figure.mermaid svg rect.background { fill: none; stroke: none; }
1055
+ /* Labels (rendered as <text>/<tspan> when htmlLabels:false) */
1056
+ figure.mermaid svg .nodeLabel,
1057
+ figure.mermaid svg .node text,
1058
+ figure.mermaid svg text.nodeLabel,
1059
+ figure.mermaid svg .label text,
1060
+ figure.mermaid svg span.nodeLabel {
1061
+ fill: var(--text);
1062
+ color: var(--text);
1063
+ font-family: var(--font-sans);
1064
+ }
1065
+ /* Edges: thin strokes, not filled blobs */
1066
+ figure.mermaid svg .edgePath path,
1067
+ figure.mermaid svg path.flowchart-link,
1068
+ figure.mermaid svg .flowchart-link {
1069
+ fill: none;
1070
+ stroke: var(--text-faint);
1071
+ stroke-width: 1.5px;
1072
+ }
1073
+ /* Arrowheads */
1074
+ figure.mermaid svg marker path,
1075
+ figure.mermaid svg .marker {
1076
+ fill: var(--text-faint);
1077
+ stroke: var(--text-faint);
1078
+ }
1079
+ figure.mermaid svg .edgeLabel,
1080
+ figure.mermaid svg .edgeLabel text { fill: var(--text-muted); color: var(--text-muted); }
1081
+ </style>
1082
+ <script>(function(){try{var t=localStorage.getItem('guide-theme');if(!t&&window.matchMedia&&matchMedia('(prefers-color-scheme: dark)').matches)t='dark';if(t)document.documentElement.setAttribute('data-theme',t);}catch(e){}})();</script>
1083
+ </head>
1084
+ <body>
1085
+ <header class="topbar">
1086
+ <button data-action="nav" class="nav-toggle" aria-label="Toggle navigation">☰</button>
1087
+ <h1>Install, Update &amp; Adopt</h1>
1088
+ <button data-action="theme" class="theme-toggle" aria-label="Toggle theme">◐</button>
1089
+ </header>
1090
+ <div class="layout">
1091
+ <aside class="rail"><nav class="toc" aria-label="Table of contents"><ul><li class="toc-2"><a href="#overview">Overview</a></li><li class="toc-2"><a href="#installing">Installing</a></li><li class="toc-2"><a href="#keeping-current">Keeping current</a></li><li class="toc-2"><a href="#starting-fresh-vs-adopting">Starting fresh vs. adopting</a></li><li class="toc-3"><a href="#scaffold-init">scaffold init</a></li><li class="toc-3"><a href="#scaffold-adopt">scaffold adopt</a></li><li class="toc-2"><a href="#troubleshooting">Troubleshooting</a></li><li class="toc-2"><a href="#see-also">See also</a></li></ul></nav></aside>
1092
+ <main class="content"><h2 id="overview">Overview</h2>
1093
+ <p>Scaffold ships as one tool with two install surfaces: the <strong><code>scaffold</code> CLI</strong>
1094
+ (distributed on npm as <code>@zigrivers/scaffold</code> and via Homebrew) and an optional
1095
+ <strong>Claude Code plugin</strong> that auto-activates the runner and pipeline-reference
1096
+ skills. The CLI is the core; the plugin only adds interactive guidance on top of
1097
+ it. The published npm package exposes the single <code>scaffold</code> binary
1098
+ (<span class="fp" data-path="package.json:37">package.json:37</span>) and bundles the compiled CLI plus the pipeline content,
1099
+ knowledge entries, and skills (<span class="fp" data-path="package.json:27">package.json:27</span>).</p>
1100
+ <p>This guide is for <strong>users</strong> installing, updating, and bootstrapping projects.
1101
+ Maintainers releasing Scaffold itself follow a separate flow in
1102
+ <code>docs/architecture/operations-runbook.md</code> <span class="cite-advisory" data-path="docs/architecture/operations-runbook.md:326">docs/architecture/operations-runbook.md:326</span>.</p>
1103
+ <div class="callout callout-note"><p><strong>Prerequisite — Node.js 18.17+.</strong> The CLI requires Node.js <code>>=18.17.0</code>
1104
+ (<span class="fp" data-path="package.json:34">package.json:34</span>). The Homebrew formula installs and manages Node as a
1105
+ dependency, so you don't install Node separately; the npm install uses your
1106
+ system Node.</p></div>
1107
+ <h2 id="installing">Installing</h2>
1108
+ <p>Pick one of the three surfaces below. The npm and Homebrew tabs install the CLI;
1109
+ the plugin tab adds the optional Claude Code skills on top.</p>
1110
+ <div class="tabs"><div class="tablist" role="tablist"><button class="tab-btn active" role="tab" data-tab="0">npm</button><button class="tab-btn" role="tab" data-tab="1">Homebrew</button><button class="tab-btn" role="tab" data-tab="2">Claude</button></div><div class="tabpane active" data-tab="0"><pre><code class="language-bash">npm install -g @zigrivers/scaffold
1111
+ </code></pre><p>Verify with <code>scaffold version</code>. This is the recommended path — it uses your
1112
+ system Node and updates with <code>npm update -g</code>.</p></div><div class="tabpane" data-tab="1"><pre><code class="language-bash">brew tap zigrivers/scaffold
1113
+ brew install scaffold
1114
+ </code></pre><p>The formula installs and manages Node as a dependency, so no separate Node
1115
+ install is needed. Verify with <code>scaffold version</code>.</p></div><div class="tabpane" data-tab="2"><p>Inside a Claude Code session:</p><pre><code class="language-text">/plugin marketplace add zigrivers/scaffold
1116
+ /plugin install scaffold@zigrivers-scaffold
1117
+ </code></pre><p>This is <strong>optional</strong> and complements the CLI — it auto-activates the Scaffold
1118
+ Runner and pipeline-reference skills for interactive guidance. Everything the
1119
+ plugin does is also reachable via <code>scaffold run &#x3C;step></code>. CLI-only users don't
1120
+ need it: <code>scaffold init</code> installs the skills automatically and later CLI
1121
+ commands keep them current.</p></div></div>
1122
+ <h2 id="keeping-current">Keeping current</h2>
1123
+ <p>Check what you have and whether a newer release exists with <code>scaffold version</code>
1124
+ (or <code>scaffold update --check-only</code>); both query the npm registry for the latest
1125
+ <code>@zigrivers/scaffold</code> (<span class="fp" data-path="src/cli/commands/version.ts:93">src/cli/commands/version.ts:93</span>). <code>scaffold update</code>
1126
+ detects how you installed and prints the right upgrade command rather than
1127
+ running the install for you — Homebrew installs map to <code>brew upgrade scaffold</code>
1128
+ (<span class="fp" data-path="src/cli/commands/update.ts:47">src/cli/commands/update.ts:47</span>), npm-global installs to
1129
+ <code>npm update -g @zigrivers/scaffold</code> (<span class="fp" data-path="src/cli/commands/update.ts:51">src/cli/commands/update.ts:51</span>), and
1130
+ anything else falls back to <code>npx @zigrivers/scaffold@latest</code>
1131
+ (<span class="fp" data-path="src/cli/commands/update.ts:55">src/cli/commands/update.ts:55</span>).</p>
1132
+ <p>The Homebrew command it prints is exactly <code>brew upgrade scaffold</code> — it does
1133
+ <strong>not</strong> include the <code>brew update</code> prefix. Homebrew users must prepend it
1134
+ themselves and run <code>brew update &#x26;&#x26; brew upgrade scaffold</code>, or the upgrade can
1135
+ silently no-op against a stale tap cache (see the danger callout below).</p>
1136
+ <p>Run the upgrade for your channel:</p>
1137
+ <div class="tabs"><div class="tablist" role="tablist"><button class="tab-btn active" role="tab" data-tab="0">npm</button><button class="tab-btn" role="tab" data-tab="1">Homebrew</button><button class="tab-btn" role="tab" data-tab="2">Claude</button></div><div class="tabpane active" data-tab="0"><pre><code class="language-bash">npm update -g @zigrivers/scaffold
1138
+ </code></pre></div><div class="tabpane" data-tab="1"><pre><code class="language-bash">brew update &#x26;&#x26; brew upgrade scaffold
1139
+ </code></pre></div><div class="tabpane" data-tab="2"><pre><code class="language-text">/plugin marketplace update zigrivers-scaffold
1140
+ </code></pre></div></div>
1141
+ <div class="callout callout-danger"><p><strong>Homebrew: run <code>brew update</code> <em>before</em> <code>brew upgrade</code>.</strong> <code>brew outdated</code> and
1142
+ <code>brew upgrade</code> both read from the local tap cache. Without a preceding
1143
+ <code>brew update</code>, the cache stays stale and a freshly-published release reports
1144
+ "already installed" / nothing-outdated even though a newer formula is live on
1145
+ GitHub. Always upgrade with <code>brew update &#x26;&#x26; brew upgrade scaffold</code>
1146
+ <span class="cite-advisory" data-path="docs/architecture/operations-runbook.md:326">docs/architecture/operations-runbook.md:326</span>.</p></div>
1147
+ <p>After upgrading the CLI, run <code>scaffold status</code> inside any existing project. The
1148
+ state manager auto-migrates old step keys, drops retired steps, and normalizes
1149
+ artifact paths — no manual editing of <code>.scaffold/state.json</code> is needed.</p>
1150
+ <h2 id="starting-fresh-vs-adopting">Starting fresh vs. adopting</h2>
1151
+ <p>Both <code>scaffold init</code> and <code>scaffold adopt</code> operate on the current project
1152
+ directory. Use <strong><code>init</code></strong> to set up a project from scratch and <strong><code>adopt</code></strong> to
1153
+ bootstrap pipeline state from documentation you already have.</p>
1154
+ <figure class="mermaid"><svg id="my-svg" width="100%" xmlns="http://www.w3.org/2000/svg" class="flowchart" style="max-width: 477.609px; background-color: transparent;" viewBox="0 0 477.609375 579.2156372070312" role="graphics-document document">#my-svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#000000;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#my-svg .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#my-svg .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#my-svg .error-icon{fill:#552222;}#my-svg .error-text{fill:#552222;stroke:#552222;}#my-svg .edge-thickness-normal{stroke-width:1px;}#my-svg .edge-thickness-thick{stroke-width:3.5px;}#my-svg .edge-pattern-solid{stroke-dasharray:0;}#my-svg .edge-thickness-invisible{stroke-width:0;fill:none;}#my-svg .edge-pattern-dashed{stroke-dasharray:3;}#my-svg .edge-pattern-dotted{stroke-dasharray:2;}#my-svg .marker{fill:#666;stroke:#666;}#my-svg .marker.cross{stroke:#666;}#my-svg svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#my-svg p{margin:0;}#my-svg .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#000000;}#my-svg .cluster-label text{fill:#333;}#my-svg .cluster-label span{color:#333;}#my-svg .cluster-label span p{background-color:transparent;}#my-svg .label text,#my-svg span{fill:#000000;color:#000000;}#my-svg .node rect,#my-svg .node circle,#my-svg .node ellipse,#my-svg .node polygon,#my-svg .node path{fill:#eee;stroke:#999;stroke-width:1px;}#my-svg .rough-node .label text,#my-svg .node .label text,#my-svg .image-shape .label,#my-svg .icon-shape .label{text-anchor:middle;}#my-svg .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#my-svg .rough-node .label,#my-svg .node .label,#my-svg .image-shape .label,#my-svg .icon-shape .label{text-align:center;}#my-svg .node.clickable{cursor:pointer;}#my-svg .root .anchor path{fill:#666!important;stroke-width:0;stroke:#666;}#my-svg .arrowheadPath{fill:#333333;}#my-svg .edgePath .path{stroke:#666;stroke-width:1px;}#my-svg .flowchart-link{stroke:#666;fill:none;}#my-svg .edgeLabel{background-color:white;text-align:center;}#my-svg .edgeLabel p{background-color:white;}#my-svg .edgeLabel rect{opacity:0.5;background-color:white;fill:white;}#my-svg .labelBkg{background-color:rgba(255, 255, 255, 0.5);}#my-svg .cluster rect{fill:hsl(0, 0%, 98.9215686275%);stroke:#707070;stroke-width:1px;}#my-svg .cluster text{fill:#333;}#my-svg .cluster span{color:#333;}#my-svg div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(-160, 0%, 93.3333333333%);border:1px solid #707070;border-radius:2px;pointer-events:none;z-index:100;}#my-svg .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#000000;}#my-svg rect.text{fill:none;stroke-width:0;}#my-svg .icon-shape,#my-svg .image-shape{background-color:white;text-align:center;}#my-svg .icon-shape p,#my-svg .image-shape p{background-color:white;padding:2px;}#my-svg .icon-shape .label rect,#my-svg .image-shape .label rect{opacity:0.5;background-color:white;fill:white;}#my-svg .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#my-svg .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#my-svg .node .neo-node{stroke:#999;}#my-svg [data-look="neo"].node rect,#my-svg [data-look="neo"].cluster rect,#my-svg [data-look="neo"].node polygon{stroke:url(#my-svg-gradient);filter:drop-shadow( 1px 2px 2px rgba(185,185,185,1));}#my-svg [data-look="neo"].node path{stroke:url(#my-svg-gradient);stroke-width:1px;}#my-svg [data-look="neo"].node .outer-path{filter:drop-shadow( 1px 2px 2px rgba(185,185,185,1));}#my-svg [data-look="neo"].node .neo-line path{stroke:#999;filter:none;}#my-svg [data-look="neo"].node circle{stroke:url(#my-svg-gradient);filter:drop-shadow( 1px 2px 2px rgba(185,185,185,1));}#my-svg [data-look="neo"].node circle .state-start{fill:#000000;}#my-svg [data-look="neo"].icon-shape .icon{fill:url(#my-svg-gradient);filter:drop-shadow( 1px 2px 2px rgba(185,185,185,1));}#my-svg [data-look="neo"].icon-shape .icon-neo path{stroke:url(#my-svg-gradient);filter:drop-shadow( 1px 2px 2px rgba(185,185,185,1));}#my-svg :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}<g><marker id="my-svg_flowchart-v2-pointEnd" class="marker flowchart-v2" viewBox="0 0 10 10" refX="5" refY="5" markerUnits="userSpaceOnUse" markerWidth="8" markerHeight="8" orient="auto"><path d="M 0 0 L 10 5 L 0 10 z" class="arrowMarkerPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker><marker id="my-svg_flowchart-v2-pointStart" class="marker flowchart-v2" viewBox="0 0 10 10" refX="4.5" refY="5" markerUnits="userSpaceOnUse" markerWidth="8" markerHeight="8" orient="auto"><path d="M 0 5 L 10 10 L 10 0 z" class="arrowMarkerPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></path></marker><marker id="my-svg_flowchart-v2-pointEnd-margin" class="marker flowchart-v2" viewBox="0 0 11.5 14" refX="11.5" refY="7" markerUnits="userSpaceOnUse" markerWidth="10.5" markerHeight="14" orient="auto"><path d="M 0 0 L 11.5 7 L 0 14 z" class="arrowMarkerPath" style="stroke-width: 0; stroke-dasharray: 1, 0;"></path></marker><marker id="my-svg_flowchart-v2-pointStart-margin" class="marker flowchart-v2" viewBox="0 0 11.5 14" refX="1" refY="7" markerUnits="userSpaceOnUse" markerWidth="11.5" markerHeight="14" orient="auto"><polygon points="0,7 11.5,14 11.5,0" class="arrowMarkerPath" style="stroke-width: 0; stroke-dasharray: 1, 0;"></polygon></marker><marker id="my-svg_flowchart-v2-circleEnd" class="marker flowchart-v2" viewBox="0 0 10 10" refX="11" refY="5" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><circle cx="5" cy="5" r="5" class="arrowMarkerPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></circle></marker><marker id="my-svg_flowchart-v2-circleStart" class="marker flowchart-v2" viewBox="0 0 10 10" refX="-1" refY="5" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><circle cx="5" cy="5" r="5" class="arrowMarkerPath" style="stroke-width: 1; stroke-dasharray: 1, 0;"></circle></marker><marker id="my-svg_flowchart-v2-circleEnd-margin" class="marker flowchart-v2" viewBox="0 0 10 10" refY="5" refX="12.25" markerUnits="userSpaceOnUse" markerWidth="14" markerHeight="14" orient="auto"><circle cx="5" cy="5" r="5" class="arrowMarkerPath" style="stroke-width: 0; stroke-dasharray: 1, 0;"></circle></marker><marker id="my-svg_flowchart-v2-circleStart-margin" class="marker flowchart-v2" viewBox="0 0 10 10" refX="-2" refY="5" markerUnits="userSpaceOnUse" markerWidth="14" markerHeight="14" orient="auto"><circle cx="5" cy="5" r="5" class="arrowMarkerPath" style="stroke-width: 0; stroke-dasharray: 1, 0;"></circle></marker><marker id="my-svg_flowchart-v2-crossEnd" class="marker cross flowchart-v2" viewBox="0 0 11 11" refX="12" refY="5.2" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><path d="M 1,1 l 9,9 M 10,1 l -9,9" class="arrowMarkerPath" style="stroke-width: 2; stroke-dasharray: 1, 0;"></path></marker><marker id="my-svg_flowchart-v2-crossStart" class="marker cross flowchart-v2" viewBox="0 0 11 11" refX="-1" refY="5.2" markerUnits="userSpaceOnUse" markerWidth="11" markerHeight="11" orient="auto"><path d="M 1,1 l 9,9 M 10,1 l -9,9" class="arrowMarkerPath" style="stroke-width: 2; stroke-dasharray: 1, 0;"></path></marker><marker id="my-svg_flowchart-v2-crossEnd-margin" class="marker cross flowchart-v2" viewBox="0 0 15 15" refX="17.7" refY="7.5" markerUnits="userSpaceOnUse" markerWidth="12" markerHeight="12" orient="auto"><path d="M 1,1 L 14,14 M 1,14 L 14,1" class="arrowMarkerPath" style="stroke-width: 2.5;"></path></marker><marker id="my-svg_flowchart-v2-crossStart-margin" class="marker cross flowchart-v2" viewBox="0 0 15 15" refX="-3.5" refY="7.5" markerUnits="userSpaceOnUse" markerWidth="12" markerHeight="12" orient="auto"><path d="M 1,1 L 14,14 M 1,14 L 14,1" class="arrowMarkerPath" style="stroke-width: 2.5; stroke-dasharray: 1, 0;"></path></marker><g class="root"><g class="clusters"></g><g class="edgePaths"><path d="M247.137,57L247.137,61.167C247.137,65.333,247.137,73.667,247.137,81.333C247.137,89,247.137,96,247.137,99.5L247.137,103" id="my-svg-L_A_B_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" marker-end="url(#my-svg_flowchart-v2-pointEnd)"></path><path d="M195.088,280.567L182.446,295.325C169.804,310.083,144.519,339.599,131.877,359.774C119.234,379.949,119.234,390.782,119.234,396.199L119.234,401.616" id="my-svg-L_B_C_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" marker-end="url(#my-svg_flowchart-v2-pointEnd)"></path><path d="M299.185,280.567L311.828,295.325C324.47,310.083,349.754,339.599,362.397,359.774C375.039,379.949,375.039,390.782,375.039,396.199L375.039,401.616" id="my-svg-L_B_D_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" marker-end="url(#my-svg_flowchart-v2-pointEnd)"></path><path d="M119.234,472.216L119.234,476.382C119.234,480.549,119.234,488.882,129.379,496.975C139.523,505.068,159.812,512.92,169.957,516.846L180.101,520.772" id="my-svg-L_C_E_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" marker-end="url(#my-svg_flowchart-v2-pointEnd)"></path><path d="M375.039,472.216L375.039,476.382C375.039,480.549,375.039,488.882,364.895,496.975C354.75,505.068,334.461,512.92,324.317,516.846L314.172,520.772" id="my-svg-L_D_E_0" class="edge-thickness-normal edge-pattern-solid edge-thickness-normal edge-pattern-solid flowchart-link" style=";" marker-end="url(#my-svg_flowchart-v2-pointEnd)"></path></g><g class="edgeLabels"><g class="edgeLabel"><g class="label" transform="translate(0, 0)"><text y="-10.1" text-anchor="middle"><tspan class="text-outer-tspan row" x="0" y="-0.1em" text-anchor="middle"></tspan></text></g></g><g><rect class="background" style="stroke: none"></rect></g><g class="edgeLabel" transform="translate(119.234375, 369.1156311035156)"><g class="label" transform="translate(0, -10.5)"><g><rect class="background" style="" x="-58.1171875" y="-1" width="116.234375" height="23"></rect><text y="-10.1" text-anchor="middle" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em" text-anchor="middle"><tspan class="text-inner-tspan">No</tspan><tspan class="text-inner-tspan"> /</tspan><tspan class="text-inner-tspan"> brand</tspan><tspan class="text-inner-tspan"> new</tspan></tspan></text></g></g></g><g class="edgeLabel" transform="translate(375.0390625, 369.1156311035156)"><g class="label" transform="translate(0, -10.5)"><g><rect class="background" style="" x="-74.15625" y="-1" width="148.3125" height="23"></rect><text y="-10.1" text-anchor="middle" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em" text-anchor="middle"><tspan class="text-inner-tspan">Yes,</tspan><tspan class="text-inner-tspan"> already</tspan><tspan class="text-inner-tspan"> written</tspan></tspan></text></g></g></g><g class="edgeLabel"><g class="label" transform="translate(0, 0)"><text y="-10.1" text-anchor="middle"><tspan class="text-outer-tspan row" x="0" y="-0.1em" text-anchor="middle"></tspan></text></g></g><g><rect class="background" style="stroke: none"></rect></g><g class="edgeLabel"><g class="label" transform="translate(0, 0)"><text y="-10.1" text-anchor="middle"><tspan class="text-outer-tspan row" x="0" y="-0.1em" text-anchor="middle"></tspan></text></g></g><g><rect class="background" style="stroke: none"></rect></g></g><g class="nodes"><g class="node default" id="my-svg-flowchart-A-0" transform="translate(247.13671875, 32.5)"><rect class="basic label-container" style="" x="-114.078125" y="-24.5" width="228.15625" height="49"></rect><g class="label" style="" transform="translate(0, -9.5)"><rect></rect><g><rect class="background" style="stroke: none"></rect><text y="-10.1" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em"><tspan class="text-inner-tspan">New</tspan><tspan class="text-inner-tspan"> or</tspan><tspan class="text-inner-tspan"> existing</tspan><tspan class="text-inner-tspan"> project</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-B-1" transform="translate(247.13671875, 219.8078155517578)"><polygon points="112.80781173706055,0 225.6156234741211,-112.80781173706055 112.80781173706055,-225.6156234741211 0,-112.80781173706055" class="label-container" transform="translate(-112.30781173706055, 112.80781173706055)"></polygon><g class="label" style="" transform="translate(0, -18.299999237060547)"><rect></rect><g><rect class="background" style="stroke: none"></rect><text y="-10.1" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em"><tspan class="text-inner-tspan">Have</tspan><tspan class="text-inner-tspan"> matching</tspan><tspan class="text-inner-tspan"> docs</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="1em"><tspan class="text-inner-tspan">PRD,</tspan><tspan class="text-inner-tspan"> tech-stack,</tspan><tspan class="text-inner-tspan"> etc.?</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-C-3" transform="translate(119.234375, 438.9156303405762)"><rect class="basic label-container" style="" x="-111.234375" y="-33.29999923706055" width="222.46875" height="66.5999984741211"></rect><g class="label" style="" transform="translate(0, -18.299999237060547)"><rect></rect><g><rect class="background" style="stroke: none"></rect><text y="-10.1" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em"><tspan class="text-inner-tspan">scaffold</tspan><tspan class="text-inner-tspan"> init</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="1em"><tspan class="text-inner-tspan">wizard</tspan><tspan class="text-inner-tspan"> +</tspan><tspan class="text-inner-tspan"> config</tspan><tspan class="text-inner-tspan"> +</tspan><tspan class="text-inner-tspan"> skills</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-D-5" transform="translate(375.0390625, 438.9156303405762)"><rect class="basic label-container" style="" x="-94.5703125" y="-33.29999923706055" width="189.140625" height="66.5999984741211"></rect><g class="label" style="" transform="translate(0, -18.299999237060547)"><rect></rect><g><rect class="background" style="stroke: none"></rect><text y="-10.1" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em"><tspan class="text-inner-tspan">scaffold</tspan><tspan class="text-inner-tspan"> init,</tspan><tspan class="text-inner-tspan"> then</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="1em"><tspan class="text-inner-tspan">scaffold</tspan><tspan class="text-inner-tspan"> adopt</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-E-7" transform="translate(247.13671875, 546.7156295776367)"><rect class="basic label-container" style="" x="-88.8359375" y="-24.5" width="177.671875" height="49"></rect><g class="label" style="" transform="translate(0, -9.5)"><rect></rect><g><rect class="background" style="stroke: none"></rect><text y="-10.1" style=""><tspan class="text-outer-tspan row" x="0" y="-0.1em"><tspan class="text-inner-tspan">Run</tspan><tspan class="text-inner-tspan"> the</tspan><tspan class="text-inner-tspan"> pipeline</tspan></tspan></text></g></g></g></g></g></g><defs></defs><defs></defs></svg></figure>
1155
+ <h3 id="scaffold-init"><code>scaffold init</code></h3>
1156
+ <p><code>scaffold init</code> initializes Scaffold for the current project
1157
+ (<span class="fp" data-path="src/cli/commands/init.ts:152">src/cli/commands/init.ts:152</span>): it runs a wizard, writes <code>.scaffold/</code>
1158
+ config and state, and installs the skills. The wizard detects whether the
1159
+ directory is brand new or already has code and suggests a methodology preset
1160
+ (<code>mvp</code>, <code>deep</code>, or <code>custom</code>) accordingly. To re-initialize a project that
1161
+ already has a <code>.scaffold/</code> directory, pass <code>--force</code> — it backs up the existing
1162
+ state before reinitializing (<span class="fp" data-path="src/cli/commands/init.ts:157">src/cli/commands/init.ts:157</span>).</p>
1163
+ <h3 id="scaffold-adopt"><code>scaffold adopt</code></h3>
1164
+ <p><code>scaffold adopt</code> adopts an existing project into Scaffold
1165
+ (<span class="fp" data-path="src/cli/commands/adopt.ts:168">src/cli/commands/adopt.ts:168</span>). It classifies the project as
1166
+ <code>greenfield</code>, <code>brownfield</code>, or <code>v1-migration</code>
1167
+ (<span class="fp" data-path="src/project/adopt.ts:72">src/project/adopt.ts:72</span>), discovers which pipeline outputs (PRD,
1168
+ tech-stack, coding-standards, etc.) you already have on disk, and marks the
1169
+ corresponding steps complete so you don't re-run work you've already done.
1170
+ Preview the changes first with <code>--dry-run</code>, which reports what it would do
1171
+ without writing anything (<span class="fp" data-path="src/cli/commands/adopt.ts:173">src/cli/commands/adopt.ts:173</span>).</p>
1172
+ <p>The usual sequence for an existing codebase: <code>scaffold init</code> (create the config
1173
+ and state), then <code>scaffold adopt</code> (backfill state from existing docs), then pick
1174
+ up the pipeline at the first incomplete step.</p>
1175
+ <h2 id="troubleshooting">Troubleshooting</h2>
1176
+ <div class="callout callout-tip"><p><strong><code>scaffold: command not found</code> after npm install.</strong> Your global npm <code>bin</code>
1177
+ directory isn't on <code>PATH</code>. Find it with <code>echo "$(npm prefix -g)/bin"</code> (the
1178
+ binaries live in the <code>bin</code> subdirectory of <code>npm prefix -g</code>) and add that
1179
+ directory to your shell <code>PATH</code>, or reinstall with a prefix that's already on
1180
+ <code>PATH</code>.</p></div>
1181
+ <ul>
1182
+ <li><strong>Homebrew says "already installed" after a release.</strong> You skipped
1183
+ <code>brew update</code>. Run <code>brew update &#x26;&#x26; brew upgrade scaffold</code> (see the danger
1184
+ callout above).</li>
1185
+ <li><strong>Wrong version reported.</strong> Run <code>scaffold version</code> to see the installed
1186
+ version, Node version, platform, and the latest registry version side by
1187
+ side. If two installs collide (e.g. both npm-global and Homebrew), remove one.</li>
1188
+ <li><strong>Node too old.</strong> The CLI needs Node 18.17+ (<span class="fp" data-path="package.json:34">package.json:34</span>). Upgrade
1189
+ Node, or use the Homebrew install, which installs and manages Node as a
1190
+ dependency.</li>
1191
+ <li><strong><code>scaffold update</code> only prints a command.</strong> That's intentional — it never
1192
+ runs installs for you. Copy the printed upgrade command for your channel and
1193
+ run it yourself.</li>
1194
+ <li><strong>Existing project behaves oddly after upgrade.</strong> Run <code>scaffold status</code> to
1195
+ trigger automatic state migration before anything else.</li>
1196
+ </ul>
1197
+ <h2 id="see-also">See also</h2>
1198
+ <ul>
1199
+ <li><a href="../pipeline/index.md">Pipeline reference</a>{mode=advisory} — what the steps are
1200
+ and the order they run in.</li>
1201
+ <li><a href="../cli/index.md">CLI reference</a>{mode=advisory} — every <code>scaffold</code> subcommand.</li>
1202
+ <li><a href="../multi-agent/index.md">Multi-agent workflow</a>{mode=advisory} — running the
1203
+ pipeline across parallel worktrees.</li>
1204
+ </ul></main>
1205
+ </div>
1206
+ <script>(function(){
1207
+ var LS_KEY = 'guide-theme';
1208
+ function applyTheme(t) {
1209
+ document.documentElement.setAttribute('data-theme', t);
1210
+ }
1211
+
1212
+ document.addEventListener('DOMContentLoaded', function() {
1213
+ // ─── Theme toggle ────────────────────────────────────────────────────────
1214
+ document.querySelectorAll('[data-action="theme"]').forEach(function(btn) {
1215
+ btn.addEventListener('click', function() {
1216
+ var current = document.documentElement.getAttribute('data-theme');
1217
+ var next = current === 'dark' ? 'light' : 'dark';
1218
+ applyTheme(next);
1219
+ try { localStorage.setItem(LS_KEY, next); } catch(e) {}
1220
+ });
1221
+ });
1222
+
1223
+ // ─── Mobile nav ──────────────────────────────────────────────────────────
1224
+ document.querySelectorAll('[data-action="nav"]').forEach(function(btn) {
1225
+ btn.addEventListener('click', function() {
1226
+ var rail = document.querySelector('.rail');
1227
+ if (rail) rail.classList.toggle('open');
1228
+ });
1229
+ });
1230
+
1231
+ // ─── Copy buttons ─────────────────────────────────────────────────────────
1232
+ document.querySelectorAll('pre').forEach(function(pre) {
1233
+ if (!pre.parentNode) return;
1234
+ var wrapper = document.createElement('div');
1235
+ wrapper.className = 'code';
1236
+ pre.parentNode.insertBefore(wrapper, pre);
1237
+ wrapper.appendChild(pre);
1238
+ var btn = document.createElement('button');
1239
+ btn.className = 'copy-btn';
1240
+ btn.textContent = 'Copy';
1241
+ btn.addEventListener('click', function() {
1242
+ var text = pre.textContent || '';
1243
+ if (navigator.clipboard && navigator.clipboard.writeText) {
1244
+ navigator.clipboard.writeText(text).then(function() {
1245
+ btn.textContent = 'Copied';
1246
+ setTimeout(function() { btn.textContent = 'Copy'; }, 1200);
1247
+ }, function() {
1248
+ btn.textContent = 'Copy';
1249
+ });
1250
+ }
1251
+ });
1252
+ wrapper.insertBefore(btn, pre);
1253
+ });
1254
+
1255
+ // ─── Tabs ─────────────────────────────────────────────────────────────────
1256
+ document.querySelectorAll('.tabs').forEach(function(group) {
1257
+ group.querySelectorAll('.tab-btn').forEach(function(btn) {
1258
+ btn.addEventListener('click', function() {
1259
+ var idx = btn.getAttribute('data-tab');
1260
+ group.querySelectorAll('.tab-btn').forEach(function(b) {
1261
+ b.classList.toggle('active', b === btn);
1262
+ });
1263
+ group.querySelectorAll('.tabpane').forEach(function(pane) {
1264
+ pane.classList.toggle('active', pane.getAttribute('data-tab') === idx);
1265
+ });
1266
+ });
1267
+ });
1268
+ });
1269
+
1270
+ // ─── Filter tables ────────────────────────────────────────────────────────
1271
+ document.querySelectorAll('.filter-input').forEach(function(input) {
1272
+ input.addEventListener('input', function() {
1273
+ var q = input.value.toLowerCase();
1274
+ var container = input.closest('.filter-table');
1275
+ if (!container) return;
1276
+ container.querySelectorAll('tbody tr').forEach(function(row) {
1277
+ var text = (row.textContent || '').toLowerCase();
1278
+ row.style.display = text.includes(q) ? '' : 'none';
1279
+ });
1280
+ });
1281
+ });
1282
+
1283
+ // ─── Scrollspy ────────────────────────────────────────────────────────────
1284
+ if (typeof IntersectionObserver === 'undefined') return;
1285
+ var headings = document.querySelectorAll('h2[id],h3[id]');
1286
+ if (!headings.length) return;
1287
+ var observer = new IntersectionObserver(function(entries) {
1288
+ entries.forEach(function(entry) {
1289
+ if (!entry.isIntersecting) return;
1290
+ var id = entry.target.getAttribute('id');
1291
+ document.querySelectorAll('.toc a').forEach(function(a) {
1292
+ a.classList.toggle('active', a.getAttribute('href') === '#' + id);
1293
+ });
1294
+ });
1295
+ }, { rootMargin: '0px 0px -70% 0px', threshold: 0 });
1296
+ headings.forEach(function(h) { observer.observe(h); });
1297
+ });
1298
+ })();</script>
1299
+ </body>
1300
+ </html>