@zigrivers/scaffold 3.30.0 → 3.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/content/guides/AUTHORING.md +8 -5
- package/content/guides/cli/index.html +367 -14
- package/content/guides/concepts/index.html +367 -14
- package/content/guides/dashboard/index.html +367 -14
- package/content/guides/index.html +368 -15
- package/content/guides/install/index.html +373 -20
- package/content/guides/install/index.md +6 -6
- package/content/guides/knowledge/index.html +367 -14
- package/content/guides/knowledge-freshness/index.html +369 -16
- package/content/guides/knowledge-freshness/index.md +2 -2
- package/content/guides/mmr/index.html +373 -20
- package/content/guides/multi-agent/index.html +369 -16
- package/content/guides/multi-agent/index.md +2 -2
- package/content/guides/observability/index.html +367 -14
- package/content/guides/pipeline/index.html +378 -37
- package/content/guides/pipeline/index.md +8 -8
- package/content/guides/review-workflow/index.html +367 -14
- package/dist/guides/build.d.ts +1 -1
- package/dist/guides/build.d.ts.map +1 -1
- package/dist/guides/build.js +14 -7
- package/dist/guides/build.js.map +1 -1
- package/dist/guides/build.test.js +39 -0
- package/dist/guides/build.test.js.map +1 -1
- package/dist/guides/chrome.d.ts.map +1 -1
- package/dist/guides/chrome.js +83 -12
- package/dist/guides/chrome.js.map +1 -1
- package/dist/guides/dashboard-theme.css +8 -0
- package/dist/guides/directives-tabs.test.js +47 -0
- package/dist/guides/directives-tabs.test.js.map +1 -1
- package/dist/guides/directives.d.ts.map +1 -1
- package/dist/guides/directives.js +14 -0
- package/dist/guides/directives.js.map +1 -1
- package/dist/guides/guides.css +268 -0
- package/dist/guides/index-page.d.ts.map +1 -1
- package/dist/guides/index-page.js +41 -8
- package/dist/guides/index-page.js.map +1 -1
- package/dist/guides/sanitize.d.ts.map +1 -1
- package/dist/guides/sanitize.js +4 -0
- package/dist/guides/sanitize.js.map +1 -1
- package/dist/guides/template.d.ts.map +1 -1
- package/dist/guides/template.js +7 -2
- package/dist/guides/template.js.map +1 -1
- package/package.json +2 -2
|
@@ -48,9 +48,13 @@
|
|
|
48
48
|
--yellow: #d97706;
|
|
49
49
|
--yellow-bg: #fffbeb;
|
|
50
50
|
--yellow-border:#fde68a;
|
|
51
|
+
--red: #dc2626;
|
|
52
|
+
--red-bg: #fef2f2;
|
|
53
|
+
--red-border: #fecaca;
|
|
51
54
|
--gray: #9ca3af;
|
|
52
55
|
--gray-bg: #f3f4f6;
|
|
53
56
|
--gray-border: #e5e7eb;
|
|
57
|
+
--scrim: rgba(15, 17, 23, 0.45);
|
|
54
58
|
|
|
55
59
|
/* Semantic: Next Banner */
|
|
56
60
|
--next-bg: #eef2ff;
|
|
@@ -133,9 +137,13 @@
|
|
|
133
137
|
--yellow: #fbbf24;
|
|
134
138
|
--yellow-bg: rgba(120, 53, 15, 0.25);
|
|
135
139
|
--yellow-border:rgba(251, 191, 36, 0.20);
|
|
140
|
+
--red: #f87171;
|
|
141
|
+
--red-bg: rgba(127, 29, 29, 0.25);
|
|
142
|
+
--red-border: rgba(248, 113, 113, 0.22);
|
|
136
143
|
--gray: #6b7294;
|
|
137
144
|
--gray-bg: #252940;
|
|
138
145
|
--gray-border: #363c58;
|
|
146
|
+
--scrim: rgba(0, 0, 0, 0.6);
|
|
139
147
|
|
|
140
148
|
/* Semantic: Next Banner */
|
|
141
149
|
--next-bg: rgba(30, 27, 75, 0.50);
|
|
@@ -1078,18 +1086,292 @@ figure.mermaid svg .marker {
|
|
|
1078
1086
|
}
|
|
1079
1087
|
figure.mermaid svg .edgeLabel,
|
|
1080
1088
|
figure.mermaid svg .edgeLabel text { fill: var(--text-muted); color: var(--text-muted); }
|
|
1089
|
+
|
|
1090
|
+
/* ============================================================================
|
|
1091
|
+
* guides.css — component + layout styles for `scaffold guides` reference pages.
|
|
1092
|
+
*
|
|
1093
|
+
* Pairs with lib/dashboard-theme.css (the token source) and src/guides/chrome.ts
|
|
1094
|
+
* (the behavior). Styles the guide CHROME (.topbar, .layout, .rail, nav.toc,
|
|
1095
|
+
* .content) and the markdown DIRECTIVES (callouts, sev chips, filter-tables,
|
|
1096
|
+
* charts, tabs, citations) plus base prose typography.
|
|
1097
|
+
*
|
|
1098
|
+
* DESIGN SYSTEM: all COLORS come from dashboard-theme.css tokens, and spacing
|
|
1099
|
+
* uses the --sp-* scale wherever it maps. The few structural layout constants
|
|
1100
|
+
* (topbar height, rail/drawer width, chart label column, card min) are declared
|
|
1101
|
+
* as local custom properties below; a handful of sub-scale UI values (chip/bar
|
|
1102
|
+
* sizing, em-based inline-code padding) and the responsive breakpoint are
|
|
1103
|
+
* literal because no token expresses them. Both themes are covered because every
|
|
1104
|
+
* color is a token.
|
|
1105
|
+
* ==========================================================================*/
|
|
1106
|
+
|
|
1107
|
+
:root {
|
|
1108
|
+
--topbar-h: 52px; /* sticky topbar height; rail sticky offset keys off it */
|
|
1109
|
+
--rail-w: 260px; /* desktop TOC sidebar column */
|
|
1110
|
+
--drawer-w: 280px; /* mobile off-canvas TOC drawer */
|
|
1111
|
+
--card-min: 260px; /* index card min track width */
|
|
1112
|
+
--chart-label-w: 90px; /* chart row label column min */
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1115
|
+
/* ── Base / reset on top of the token base in dashboard-theme.css ─────────── */
|
|
1116
|
+
.content a { color: var(--accent); text-decoration: none; }
|
|
1117
|
+
.content a:hover { text-decoration: underline; }
|
|
1118
|
+
.content strong { font-weight: var(--fw-semi); }
|
|
1119
|
+
.content hr { border: 0; border-top: 1px solid var(--border-light); margin: var(--sp-6) 0; }
|
|
1120
|
+
|
|
1121
|
+
/* Consistent keyboard focus for every interactive control (a11y). */
|
|
1122
|
+
.topbar button:focus-visible,
|
|
1123
|
+
.copy-btn:focus-visible,
|
|
1124
|
+
.tab-btn:focus-visible,
|
|
1125
|
+
.filter-input:focus-visible,
|
|
1126
|
+
nav.toc a:focus-visible,
|
|
1127
|
+
.guide-card:focus-visible,
|
|
1128
|
+
.content a:focus-visible {
|
|
1129
|
+
outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--radius-sm);
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
/* ── Topbar ────────────────────────────────────────────────────────────────*/
|
|
1133
|
+
.topbar {
|
|
1134
|
+
position: sticky; top: 0; z-index: 60; height: var(--topbar-h);
|
|
1135
|
+
display: flex; align-items: center; gap: var(--sp-3);
|
|
1136
|
+
padding: 0 var(--page-pad);
|
|
1137
|
+
background: var(--bg-card); border-bottom: 1px solid var(--border);
|
|
1138
|
+
}
|
|
1139
|
+
.topbar h1 {
|
|
1140
|
+
flex: 1; min-width: 0; margin: 0;
|
|
1141
|
+
font-size: var(--text-lg); font-weight: var(--fw-bold);
|
|
1142
|
+
letter-spacing: var(--ls-tight);
|
|
1143
|
+
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
|
1144
|
+
}
|
|
1145
|
+
.topbar button {
|
|
1146
|
+
background: var(--bg-card); border: 1px solid var(--border); color: var(--text);
|
|
1147
|
+
border-radius: var(--radius-sm); padding: var(--sp-1) var(--sp-3); font-size: var(--text-base);
|
|
1148
|
+
line-height: 1; cursor: pointer; font-family: inherit;
|
|
1149
|
+
}
|
|
1150
|
+
.topbar button:hover { background: var(--bg-hover); border-color: var(--accent); }
|
|
1151
|
+
.nav-toggle { display: none; }
|
|
1152
|
+
|
|
1153
|
+
/* ── Layout: sticky sidebar TOC + reading-width content ──────────────────── */
|
|
1154
|
+
.layout {
|
|
1155
|
+
max-width: var(--max-w); margin: 0 auto;
|
|
1156
|
+
display: grid; grid-template-columns: var(--rail-w) minmax(0, 1fr);
|
|
1157
|
+
gap: var(--sp-8); padding: 0 var(--page-pad);
|
|
1158
|
+
}
|
|
1159
|
+
.rail {
|
|
1160
|
+
position: sticky; top: var(--topbar-h); align-self: start;
|
|
1161
|
+
height: calc(100vh - var(--topbar-h)); overflow-y: auto;
|
|
1162
|
+
padding: var(--sp-5) 0; border-right: 1px solid var(--border-light);
|
|
1163
|
+
}
|
|
1164
|
+
.content { min-width: 0; padding: var(--sp-6) 0 var(--sp-10); }
|
|
1165
|
+
|
|
1166
|
+
/* Backdrop behind the mobile drawer (toggled with the rail via chrome.ts). */
|
|
1167
|
+
.rail-backdrop { display: none; }
|
|
1168
|
+
/* In-drawer close button — hidden on desktop (the rail is a static sidebar). */
|
|
1169
|
+
.rail-close { display: none; }
|
|
1170
|
+
|
|
1171
|
+
/* ── Table of contents (scrollspy marks a.active) ────────────────────────── */
|
|
1172
|
+
nav.toc ul { list-style: none; margin: 0; padding: 0; }
|
|
1173
|
+
nav.toc li { margin: 0; }
|
|
1174
|
+
nav.toc a {
|
|
1175
|
+
display: block; padding: var(--sp-1) var(--sp-3); line-height: 1.35;
|
|
1176
|
+
color: var(--text-muted); font-size: var(--text-sm);
|
|
1177
|
+
text-decoration: none; border-left: 2px solid transparent;
|
|
1178
|
+
border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
|
|
1179
|
+
}
|
|
1180
|
+
nav.toc a:hover { color: var(--text); background: var(--bg-hover); }
|
|
1181
|
+
nav.toc a.active {
|
|
1182
|
+
color: var(--accent); border-left-color: var(--accent);
|
|
1183
|
+
background: var(--accent-glow); font-weight: var(--fw-medium);
|
|
1184
|
+
}
|
|
1185
|
+
nav.toc li.toc-3 a { padding-left: var(--sp-6); font-size: var(--text-xs); }
|
|
1186
|
+
|
|
1187
|
+
/* ── Prose typography ──────────────────────────────────────────────────────*/
|
|
1188
|
+
.content h2 {
|
|
1189
|
+
font-size: var(--text-xl); letter-spacing: var(--ls-tight);
|
|
1190
|
+
margin: var(--sp-8) 0 var(--sp-3); padding-bottom: var(--sp-2);
|
|
1191
|
+
border-bottom: 1px solid var(--border-light); scroll-margin-top: calc(var(--topbar-h) + var(--sp-3));
|
|
1192
|
+
}
|
|
1193
|
+
.content h3 {
|
|
1194
|
+
font-size: var(--text-lg); margin: var(--sp-5) 0 var(--sp-2);
|
|
1195
|
+
scroll-margin-top: calc(var(--topbar-h) + var(--sp-3));
|
|
1196
|
+
}
|
|
1197
|
+
.content p { margin: var(--sp-3) 0; line-height: var(--lh-relaxed); }
|
|
1198
|
+
.content ul, .content ol { margin: var(--sp-3) 0; padding-left: var(--sp-6); }
|
|
1199
|
+
.content li { margin: var(--sp-1) 0; line-height: var(--lh-relaxed); }
|
|
1200
|
+
.content blockquote {
|
|
1201
|
+
margin: var(--sp-3) 0; padding: var(--sp-1) var(--sp-4);
|
|
1202
|
+
border-left: 3px solid var(--border); color: var(--text-muted);
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
/* ── Inline code + code blocks (chrome.ts wraps <pre> in .code + .copy-btn) ──*/
|
|
1206
|
+
.content code {
|
|
1207
|
+
font-family: var(--font-mono); font-size: 0.85em;
|
|
1208
|
+
background: var(--bg-inset); padding: 0.12em 0.4em; border-radius: var(--radius-sm);
|
|
1209
|
+
}
|
|
1210
|
+
.content .code { position: relative; margin: var(--sp-3) 0; }
|
|
1211
|
+
.content .code pre {
|
|
1212
|
+
margin: 0; padding: var(--sp-3) var(--sp-4); overflow-x: auto;
|
|
1213
|
+
background: var(--bg-inset); border: 1px solid var(--border-light);
|
|
1214
|
+
border-radius: var(--radius-sm); font-family: var(--font-mono);
|
|
1215
|
+
font-size: var(--text-sm); line-height: var(--lh-relaxed);
|
|
1216
|
+
}
|
|
1217
|
+
.content .code pre code { background: none; padding: 0; font-size: inherit; }
|
|
1218
|
+
.copy-btn {
|
|
1219
|
+
position: absolute; top: var(--sp-1); right: var(--sp-1);
|
|
1220
|
+
background: var(--bg-card); border: 1px solid var(--border); color: var(--text-muted);
|
|
1221
|
+
border-radius: var(--radius-sm); font-size: var(--text-xs); padding: var(--sp-1) var(--sp-2);
|
|
1222
|
+
cursor: pointer; opacity: 0.85; font-family: inherit;
|
|
1223
|
+
}
|
|
1224
|
+
.copy-btn:hover { color: var(--accent); border-color: var(--accent); opacity: 1; }
|
|
1225
|
+
|
|
1226
|
+
/* ── Callouts ─ (border-color BEFORE border-left-color so the accent wins) ── */
|
|
1227
|
+
.callout {
|
|
1228
|
+
margin: var(--sp-4) 0; padding: var(--sp-3) var(--sp-4);
|
|
1229
|
+
border: 1px solid var(--border); border-left-width: 3px;
|
|
1230
|
+
border-radius: var(--radius-sm); background: var(--bg-card);
|
|
1231
|
+
}
|
|
1232
|
+
.callout > :first-child { margin-top: 0; }
|
|
1233
|
+
.callout > :last-child { margin-bottom: 0; }
|
|
1234
|
+
.callout-note, .callout-info { background: var(--blue-bg); border-color: var(--blue-border); border-left-color: var(--blue); }
|
|
1235
|
+
.callout-tip { background: var(--green-bg); border-color: var(--green-border); border-left-color: var(--green); }
|
|
1236
|
+
.callout-warning { background: var(--yellow-bg); border-color: var(--yellow-border); border-left-color: var(--yellow); }
|
|
1237
|
+
.callout-danger { background: var(--red-bg); border-color: var(--red-border); border-left-color: var(--red); }
|
|
1238
|
+
|
|
1239
|
+
/* ── Severity chips (:sev) — tight pill, sub-scale vertical padding ───────── */
|
|
1240
|
+
.sev {
|
|
1241
|
+
display: inline-block; font-size: var(--text-xs); font-weight: var(--fw-semi);
|
|
1242
|
+
padding: 1px var(--sp-2); border-radius: 999px; line-height: 1.5;
|
|
1243
|
+
border: 1px solid var(--border); background: var(--bg-inset); color: var(--text-muted);
|
|
1244
|
+
white-space: nowrap;
|
|
1245
|
+
}
|
|
1246
|
+
.sev-p0 { color: var(--sev-p0); border-color: var(--sev-p0); }
|
|
1247
|
+
.sev-p1 { color: var(--sev-p1); border-color: var(--sev-p1); }
|
|
1248
|
+
.sev-p2 { color: var(--sev-p2); border-color: var(--sev-p2); }
|
|
1249
|
+
.sev-p3 { color: var(--sev-p3); border-color: var(--sev-p3); }
|
|
1250
|
+
.sev-pass { color: var(--sev-pass); border-color: var(--sev-pass); }
|
|
1251
|
+
|
|
1252
|
+
/* ── Citations (:cite) — inline provenance refs ──────────────────────────── */
|
|
1253
|
+
.fp, .cite-advisory {
|
|
1254
|
+
font-family: var(--font-mono); font-size: 0.82em;
|
|
1255
|
+
padding: 0.05em 0.35em; border-radius: var(--radius-sm);
|
|
1256
|
+
background: var(--bg-inset); border: 1px solid var(--border-light);
|
|
1257
|
+
}
|
|
1258
|
+
.fp { color: var(--accent); }
|
|
1259
|
+
.cite-advisory { color: var(--text-faint); border-style: dashed; }
|
|
1260
|
+
|
|
1261
|
+
/* ── Tables + filter-tables ──────────────────────────────────────────────── */
|
|
1262
|
+
.content table { width: 100%; border-collapse: collapse; margin: var(--sp-3) 0; font-size: var(--text-sm); }
|
|
1263
|
+
.content th, .content td { text-align: left; padding: var(--sp-2) var(--sp-3); border-bottom: 1px solid var(--border-light); vertical-align: top; }
|
|
1264
|
+
.content th {
|
|
1265
|
+
color: var(--text-muted); font-weight: var(--fw-semi); font-size: var(--text-xs);
|
|
1266
|
+
text-transform: uppercase; letter-spacing: var(--ls-wide); border-bottom-color: var(--border);
|
|
1267
|
+
}
|
|
1268
|
+
.content tbody tr:hover { background: var(--bg-hover); }
|
|
1269
|
+
.content td code { white-space: nowrap; }
|
|
1270
|
+
.filter-table { margin: var(--sp-4) 0; }
|
|
1271
|
+
.filter-input {
|
|
1272
|
+
width: 100%; max-width: 320px; margin-bottom: var(--sp-2);
|
|
1273
|
+
padding: var(--sp-2) var(--sp-3); font-family: inherit; font-size: var(--text-sm);
|
|
1274
|
+
color: var(--text); background: var(--bg-card);
|
|
1275
|
+
border: 1px solid var(--border); border-radius: var(--radius-sm);
|
|
1276
|
+
}
|
|
1277
|
+
.filter-input:focus { border-color: var(--accent); }
|
|
1278
|
+
|
|
1279
|
+
/* ── Charts (:::chart) — label + proportional bar (fill carries inline width%) */
|
|
1280
|
+
.chart-block { margin: var(--sp-4) 0; }
|
|
1281
|
+
.chart-row {
|
|
1282
|
+
display: grid; grid-template-columns: minmax(var(--chart-label-w), 24%) 1fr;
|
|
1283
|
+
align-items: center; gap: var(--sp-3); margin: var(--sp-1) 0;
|
|
1284
|
+
}
|
|
1285
|
+
.chart-label {
|
|
1286
|
+
font-size: var(--text-sm); color: var(--text-muted); text-align: right;
|
|
1287
|
+
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
|
1288
|
+
}
|
|
1289
|
+
.chart-row .chart-bar {
|
|
1290
|
+
height: 0.9em; min-width: 2px; background: var(--accent);
|
|
1291
|
+
border-radius: var(--radius-sm);
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
/* ── Tabs (::::tabs / :::tab) ─────────────────────────────────────────────── */
|
|
1295
|
+
.tabs { margin: var(--sp-4) 0; }
|
|
1296
|
+
.tablist { display: flex; flex-wrap: wrap; gap: var(--sp-1); border-bottom: 1px solid var(--border); margin-bottom: var(--sp-3); }
|
|
1297
|
+
.tab-btn {
|
|
1298
|
+
background: none; border: none; border-bottom: 2px solid transparent; margin-bottom: -1px;
|
|
1299
|
+
padding: var(--sp-2) var(--sp-3); color: var(--text-muted);
|
|
1300
|
+
font-family: inherit; font-size: var(--text-sm); font-weight: var(--fw-medium); cursor: pointer;
|
|
1301
|
+
}
|
|
1302
|
+
.tab-btn:hover { color: var(--text); }
|
|
1303
|
+
.tab-btn.active { color: var(--accent); border-bottom-color: var(--accent); }
|
|
1304
|
+
.tabpane { display: none; }
|
|
1305
|
+
.tabpane.active { display: block; }
|
|
1306
|
+
|
|
1307
|
+
/* ── Mermaid diagrams ────────────────────────────────────────────────────── */
|
|
1308
|
+
.content figure { margin: var(--sp-4) 0; text-align: center; }
|
|
1309
|
+
.content figure svg, .content > svg, .content .mermaid svg { max-width: 100%; height: auto; }
|
|
1310
|
+
|
|
1311
|
+
/* ── Index page: category card grid ──────────────────────────────────────── */
|
|
1312
|
+
.content .lead { color: var(--text-muted); font-size: var(--text-base); max-width: 60ch; margin-top: var(--sp-2); }
|
|
1313
|
+
.guide-cards {
|
|
1314
|
+
display: grid; grid-template-columns: repeat(auto-fill, minmax(min(var(--card-min), 100%), 1fr));
|
|
1315
|
+
gap: var(--sp-4); margin: var(--sp-4) 0 var(--sp-6);
|
|
1316
|
+
}
|
|
1317
|
+
.guide-card {
|
|
1318
|
+
display: flex; flex-direction: column; gap: var(--sp-2);
|
|
1319
|
+
padding: var(--sp-4); background: var(--bg-card);
|
|
1320
|
+
border: 1px solid var(--border); border-radius: var(--radius);
|
|
1321
|
+
color: inherit; text-decoration: none;
|
|
1322
|
+
transition: border-color 0.15s ease, box-shadow 0.15s ease;
|
|
1323
|
+
}
|
|
1324
|
+
.guide-card:hover { border-color: var(--accent); box-shadow: var(--shadow-md); text-decoration: none; }
|
|
1325
|
+
.guide-card-title { font-weight: var(--fw-semi); color: var(--accent); font-size: var(--text-base); }
|
|
1326
|
+
.guide-card-desc { color: var(--text-muted); font-size: var(--text-sm); line-height: var(--lh-normal); }
|
|
1327
|
+
|
|
1328
|
+
/* ── Responsive: TOC becomes an off-canvas drawer (chrome.ts toggles .open) ──*/
|
|
1329
|
+
/* 860px is literal — media queries cannot read custom properties. Revisit it if
|
|
1330
|
+
--topbar-h / --rail-w / --drawer-w change (the drawer sticky offsets key off them). */
|
|
1331
|
+
@media (max-width: 860px) {
|
|
1332
|
+
.nav-toggle { display: inline-flex; align-items: center; }
|
|
1333
|
+
.layout { grid-template-columns: 1fr; gap: 0; }
|
|
1334
|
+
.rail {
|
|
1335
|
+
position: fixed; top: var(--topbar-h); left: 0; bottom: 0; width: var(--drawer-w); z-index: 50;
|
|
1336
|
+
height: auto; background: var(--bg-card); border-right: 1px solid var(--border);
|
|
1337
|
+
padding: var(--sp-4); box-shadow: var(--shadow-lg);
|
|
1338
|
+
transform: translateX(-100%); transition: transform 0.2s ease, visibility 0.2s ease;
|
|
1339
|
+
/* Closed drawer is off-screen AND removed from tab order / pointer events. */
|
|
1340
|
+
visibility: hidden; pointer-events: none;
|
|
1341
|
+
}
|
|
1342
|
+
.rail.open { transform: translateX(0); visibility: visible; pointer-events: auto; }
|
|
1343
|
+
.rail-close {
|
|
1344
|
+
display: block; margin-left: auto; margin-bottom: var(--sp-2);
|
|
1345
|
+
background: var(--bg-card); border: 1px solid var(--border); color: var(--text);
|
|
1346
|
+
border-radius: var(--radius-sm); padding: var(--sp-1) var(--sp-3); font-size: var(--text-base);
|
|
1347
|
+
line-height: 1; cursor: pointer; font-family: inherit;
|
|
1348
|
+
}
|
|
1349
|
+
.rail-close:hover { background: var(--bg-hover); border-color: var(--accent); }
|
|
1350
|
+
.rail-close:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
|
|
1351
|
+
.rail-backdrop {
|
|
1352
|
+
display: block; position: fixed; inset: var(--topbar-h) 0 0 0;
|
|
1353
|
+
background: var(--scrim); z-index: 49;
|
|
1354
|
+
opacity: 0; pointer-events: none; transition: opacity 0.2s ease;
|
|
1355
|
+
}
|
|
1356
|
+
.rail.open ~ .rail-backdrop { opacity: 1; pointer-events: auto; }
|
|
1357
|
+
}
|
|
1081
1358
|
</style>
|
|
1082
1359
|
<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
1360
|
</head>
|
|
1084
1361
|
<body>
|
|
1085
1362
|
<header class="topbar">
|
|
1086
|
-
<button data-action="nav" class="nav-toggle" aria-label="Toggle navigation"
|
|
1363
|
+
<button data-action="nav" class="nav-toggle" aria-label="Toggle navigation"
|
|
1364
|
+
aria-expanded="false" aria-controls="guide-toc">☰</button>
|
|
1087
1365
|
<h1>Scaffold Guides</h1>
|
|
1088
1366
|
<button data-action="theme" class="theme-toggle" aria-label="Toggle theme">◐</button>
|
|
1089
1367
|
</header>
|
|
1090
1368
|
<div class="layout">
|
|
1091
|
-
<aside class="rail"
|
|
1092
|
-
|
|
1369
|
+
<aside class="rail" id="guide-toc">
|
|
1370
|
+
<button class="rail-close" data-action="nav" aria-label="Close navigation">✕</button>
|
|
1371
|
+
<nav class="toc" aria-label="Table of contents"><ul><li class="toc-2"><a href="#cat-concepts">Concepts</a></li><li class="toc-2"><a href="#cat-reference">Reference</a></li><li class="toc-2"><a href="#cat-workflows">Workflows</a></li><li class="toc-2"><a href="#cat-tools">Tools</a></li></ul></nav>
|
|
1372
|
+
</aside>
|
|
1373
|
+
<main class="content"><p class="lead">Reference guides for Scaffold — human- and agent-readable. Open a guide to read it in your browser; agents read the markdown source with <code>scaffold guides <topic> --markdown</code>.</p><h2 id="cat-concepts">Concepts</h2><div class="guide-cards"><a class="guide-card" href="concepts/index.html"><span class="guide-card-title">Concepts & Glossary</span><span class="guide-card-desc">The shared vocabulary — worktrees, phases, lenses, verdicts, and the rest — that the other guides assume</span></a><a class="guide-card" href="pipeline/index.html"><span class="guide-card-title">The Scaffold Pipeline</span><span class="guide-card-desc">The 16-phase meta-prompt pipeline — phases, dependencies, conditional steps, methodology depth, and how to navigate it</span></a></div><h2 id="cat-reference">Reference</h2><div class="guide-cards"><a class="guide-card" href="cli/index.html"><span class="guide-card-title">Scaffold CLI Reference</span><span class="guide-card-desc">Every scaffold command grouped by purpose — setup, navigation, observability, knowledge, validation, version</span></a><a class="guide-card" href="install/index.html"><span class="guide-card-title">Install, Update & Adopt</span><span class="guide-card-desc">Installing via npm/Homebrew/plugin, keeping current, and adopting scaffold into a new or existing project</span></a><a class="guide-card" href="knowledge/index.html"><span class="guide-card-title">Knowledge Base</span><span class="guide-card-desc">What the knowledge base is, how entries are injected during assembly, and how to author or override them</span></a></div><h2 id="cat-workflows">Workflows</h2><div class="guide-cards"><a class="guide-card" href="review-workflow/index.html"><span class="guide-card-title">The Code-Review Workflow</span><span class="guide-card-desc">When and how to run multi-model review — entry points, input modes, verdicts, the round limit, and degraded mode</span></a><a class="guide-card" href="multi-agent/index.html"><span class="guide-card-title">Parallel Agents & Worktrees</span><span class="guide-card-desc">Running agents in parallel — worktree setup/teardown, the ledger-harvest coupling, and the build-phase entry points</span></a></div><h2 id="cat-tools">Tools</h2><div class="guide-cards"><a class="guide-card" href="mmr/index.html"><span class="guide-card-title">MMR Reference</span><span class="guide-card-desc">Multi-Model Review — independent AI reviewers, reconciliation, and verdict gating</span></a><a class="guide-card" href="observability/index.html"><span class="guide-card-title">Build Observability</span><span class="guide-card-desc">A durable ledger of build decisions, fused with git/GitHub/MMR/state and audited against the planning docs by nine lenses</span></a><a class="guide-card" href="knowledge-freshness/index.html"><span class="guide-card-title">Knowledge Freshness</span><span class="guide-card-desc">How knowledge entries stay current, how coverage gaps surface as Lens-I findings, and how the daily cron, five PR gates, and source allowlist keep the KB grounded</span></a><a class="guide-card" href="dashboard/index.html"><span class="guide-card-title">Dashboard & Design System</span><span class="guide-card-desc">The pipeline dashboard, its panels, the design-token system, and how to customize it safely</span></a></div></main>
|
|
1374
|
+
<div class="rail-backdrop" data-action="nav" aria-hidden="true"></div>
|
|
1093
1375
|
</div>
|
|
1094
1376
|
<script>(function(){
|
|
1095
1377
|
var LS_KEY = 'guide-theme';
|
|
@@ -1108,12 +1390,69 @@ figure.mermaid svg .edgeLabel text { fill: var(--text-muted); color: var(--text-
|
|
|
1108
1390
|
});
|
|
1109
1391
|
});
|
|
1110
1392
|
|
|
1111
|
-
// ─── Mobile nav
|
|
1393
|
+
// ─── Mobile nav (drawer + backdrop; aria-expanded + Escape-to-close) ──────
|
|
1394
|
+
function setNav(open) {
|
|
1395
|
+
var rail = document.querySelector('.rail');
|
|
1396
|
+
if (rail) rail.classList.toggle('open', open);
|
|
1397
|
+
var toggle = document.querySelector('.nav-toggle');
|
|
1398
|
+
if (toggle) toggle.setAttribute('aria-expanded', open ? 'true' : 'false');
|
|
1399
|
+
// Modal-drawer focus containment: while open, make the page content inert
|
|
1400
|
+
// (out of tab order + a11y tree) and move focus into the drawer; on close,
|
|
1401
|
+
// restore content and return focus to the toggle.
|
|
1402
|
+
var main = document.querySelector('.content');
|
|
1403
|
+
if (main) main.inert = open;
|
|
1404
|
+
if (open) {
|
|
1405
|
+
var first = rail && rail.querySelector('a, button, [tabindex]:not([tabindex="-1"])');
|
|
1406
|
+
if (first) first.focus();
|
|
1407
|
+
else if (rail) { rail.setAttribute('tabindex', '-1'); rail.focus(); }
|
|
1408
|
+
} else if (toggle) {
|
|
1409
|
+
toggle.focus();
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
// If the viewport grows past the mobile breakpoint while the drawer is open,
|
|
1413
|
+
// the rail becomes the desktop sidebar and the toggle hides — clear the open
|
|
1414
|
+
// state so .content doesn't stay inert with no way to close it.
|
|
1415
|
+
if (window.matchMedia) {
|
|
1416
|
+
var mq = window.matchMedia('(max-width: 860px)');
|
|
1417
|
+
var onMq = function() {
|
|
1418
|
+
if (mq.matches) return;
|
|
1419
|
+
var rail = document.querySelector('.rail');
|
|
1420
|
+
if (rail) rail.classList.remove('open');
|
|
1421
|
+
var toggle = document.querySelector('.nav-toggle');
|
|
1422
|
+
if (toggle) toggle.setAttribute('aria-expanded', 'false');
|
|
1423
|
+
var main = document.querySelector('.content');
|
|
1424
|
+
if (main) main.inert = false;
|
|
1425
|
+
};
|
|
1426
|
+
if (mq.addEventListener) mq.addEventListener('change', onMq);
|
|
1427
|
+
else if (mq.addListener) mq.addListener(onMq);
|
|
1428
|
+
}
|
|
1112
1429
|
document.querySelectorAll('[data-action="nav"]').forEach(function(btn) {
|
|
1113
1430
|
btn.addEventListener('click', function() {
|
|
1114
1431
|
var rail = document.querySelector('.rail');
|
|
1115
|
-
|
|
1432
|
+
setNav(!(rail && rail.classList.contains('open')));
|
|
1433
|
+
});
|
|
1434
|
+
});
|
|
1435
|
+
// Selecting a TOC link closes the drawer (so the now-active content isn't
|
|
1436
|
+
// left inert behind the panel) before the anchor navigation scrolls.
|
|
1437
|
+
var drawerRail = document.querySelector('.rail');
|
|
1438
|
+
if (drawerRail) {
|
|
1439
|
+
drawerRail.querySelectorAll('a').forEach(function(a) {
|
|
1440
|
+
a.addEventListener('click', function() {
|
|
1441
|
+
if (drawerRail.classList.contains('open')) setNav(false);
|
|
1442
|
+
});
|
|
1116
1443
|
});
|
|
1444
|
+
}
|
|
1445
|
+
document.addEventListener('keydown', function(e) {
|
|
1446
|
+
var rail = document.querySelector('.rail');
|
|
1447
|
+
if (!rail || !rail.classList.contains('open')) return;
|
|
1448
|
+
if (e.key === 'Escape') { setNav(false); return; } // setNav restores focus to the toggle
|
|
1449
|
+
// Trap Tab within the open drawer (modal pattern).
|
|
1450
|
+
if (e.key !== 'Tab') return;
|
|
1451
|
+
var f = rail.querySelectorAll('a[href], button, [tabindex]:not([tabindex="-1"])');
|
|
1452
|
+
if (!f.length) return;
|
|
1453
|
+
var first = f[0], last = f[f.length - 1];
|
|
1454
|
+
if (e.shiftKey && document.activeElement === first) { e.preventDefault(); last.focus(); }
|
|
1455
|
+
else if (!e.shiftKey && document.activeElement === last) { e.preventDefault(); first.focus(); }
|
|
1117
1456
|
});
|
|
1118
1457
|
|
|
1119
1458
|
// ─── Copy buttons ─────────────────────────────────────────────────────────
|
|
@@ -1140,17 +1479,31 @@ figure.mermaid svg .edgeLabel text { fill: var(--text-muted); color: var(--text-
|
|
|
1140
1479
|
wrapper.insertBefore(btn, pre);
|
|
1141
1480
|
});
|
|
1142
1481
|
|
|
1143
|
-
// ─── Tabs
|
|
1482
|
+
// ─── Tabs (ARIA pattern: aria-selected + roving tabindex + arrow keys) ────
|
|
1483
|
+
function activateTab(group, btn, focus) {
|
|
1484
|
+
var idx = btn.getAttribute('data-tab');
|
|
1485
|
+
group.querySelectorAll('.tab-btn').forEach(function(b) {
|
|
1486
|
+
var on = b === btn;
|
|
1487
|
+
b.classList.toggle('active', on);
|
|
1488
|
+
b.setAttribute('aria-selected', on ? 'true' : 'false');
|
|
1489
|
+
b.setAttribute('tabindex', on ? '0' : '-1');
|
|
1490
|
+
});
|
|
1491
|
+
group.querySelectorAll('.tabpane').forEach(function(pane) {
|
|
1492
|
+
pane.classList.toggle('active', pane.getAttribute('data-tab') === idx);
|
|
1493
|
+
});
|
|
1494
|
+
if (focus) btn.focus();
|
|
1495
|
+
}
|
|
1144
1496
|
document.querySelectorAll('.tabs').forEach(function(group) {
|
|
1145
|
-
group.querySelectorAll('.tab-btn')
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1497
|
+
var btns = [].slice.call(group.querySelectorAll('.tab-btn'));
|
|
1498
|
+
btns.forEach(function(btn, i) {
|
|
1499
|
+
btn.addEventListener('click', function() { activateTab(group, btn, false); });
|
|
1500
|
+
btn.addEventListener('keydown', function(e) {
|
|
1501
|
+
var ni = -1;
|
|
1502
|
+
if (e.key === 'ArrowRight' || e.key === 'ArrowDown') ni = (i + 1) % btns.length;
|
|
1503
|
+
else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') ni = (i - 1 + btns.length) % btns.length;
|
|
1504
|
+
else if (e.key === 'Home') ni = 0;
|
|
1505
|
+
else if (e.key === 'End') ni = btns.length - 1;
|
|
1506
|
+
if (ni >= 0) { e.preventDefault(); activateTab(group, btns[ni], true); }
|
|
1154
1507
|
});
|
|
1155
1508
|
});
|
|
1156
1509
|
});
|