@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,17 +1086,290 @@ 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>Parallel Agents & Worktrees</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"
|
|
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="#why-worktrees-not-just-branches">Why worktrees, not just branches</a></li><li class="toc-2"><a href="#setup-setup-agent-worktreesh">Setup — setup-agent-worktree.sh</a></li><li class="toc-2"><a href="#which-build-phase-entry-point">Which build-phase entry point?</a></li><li class="toc-2"><a href="#working-in-parallel">Working in parallel</a></li><li class="toc-2"><a href="#teardown-harvest">Teardown & harvest</a></li><li class="toc-3"><a href="#the-branch-deletion-guards">The branch-deletion guards</a></li><li class="toc-3"><a href="#recovering-orphaned-ledgers---recover">Recovering orphaned ledgers — --recover</a></li><li class="toc-2"><a href="#resuming-after-a-break">Resuming after a break</a></li><li class="toc-2"><a href="#see-also">See also</a></li></ul></nav>
|
|
1372
|
+
</aside>
|
|
1092
1373
|
<main class="content"><h2 id="why-worktrees-not-just-branches">Why worktrees, not just branches</h2>
|
|
1093
1374
|
<p>Several agents implementing the same project at once need two things: a clean
|
|
1094
1375
|
checkout each can build and test in, and a shared history they all merge back
|
|
@@ -1147,7 +1428,7 @@ established worktree id. If you want a fresh id, delete the file first.</p></div
|
|
|
1147
1428
|
questions: <em>is the work already in the plan?</em> and <em>is one agent or several
|
|
1148
1429
|
working?</em></p>
|
|
1149
1430
|
<figure class="mermaid"><svg id="my-svg" width="100%" xmlns="http://www.w3.org/2000/svg" class="flowchart" style="max-width: 1139.59px; background-color: transparent;" viewBox="0 0 1139.589111328125 987.3843994140625" 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="M378.359,57L378.359,61.167C378.359,65.333,378.359,73.667,378.359,81.333C378.359,89,378.359,96,378.359,99.5L378.359,103" id="my-svg-L_Start_InPlan_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="M306.247,256.909L272.687,275.011C239.128,293.113,172.009,329.318,138.45,364.067C104.891,398.816,104.891,432.11,104.891,448.758L104.891,465.405" id="my-svg-L_InPlan_Quick_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="M378.359,329.022L378.359,335.105C378.359,341.189,378.359,353.355,378.359,376.086C378.359,398.816,378.359,432.11,378.359,448.758L378.359,465.405" id="my-svg-L_InPlan_Enh_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="M451.002,256.38L485.441,274.57C519.88,292.76,588.758,329.141,623.197,352.748C657.636,376.355,657.636,387.189,657.636,392.605L657.636,398.022" id="my-svg-L_InPlan_HowMany_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="M592.634,538.385L561.814,555.302C530.995,572.219,469.357,606.053,438.537,628.387C407.718,650.721,407.718,661.554,407.718,666.971L407.718,672.388" id="my-svg-L_HowMany_Single_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="M722.51,538.513L753.12,555.409C783.729,572.305,844.948,606.096,875.558,628.409C906.167,650.721,906.167,661.554,906.167,666.971L906.167,672.388" id="my-svg-L_HowMany_Multi_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="M366.035,798.102L352.462,811.132C338.889,824.163,311.743,850.224,298.17,870.137C284.597,890.051,284.597,903.818,284.597,910.701L284.597,917.584" id="my-svg-L_Single_SS_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="M449.4,798.102L462.974,811.132C476.547,824.163,503.693,850.224,517.266,870.137C530.839,890.051,530.839,903.818,530.839,910.701L530.839,917.584" id="my-svg-L_Single_SR_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="M864.256,797.873L850.49,810.942C836.724,824.01,809.192,850.147,795.425,868.633C781.659,887.118,781.659,897.951,781.659,903.368L781.659,908.784" id="my-svg-L_Multi_MS_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="M948.078,797.873L961.844,810.942C975.611,824.01,1003.143,850.147,1016.909,868.633C1030.675,887.118,1030.675,897.951,1030.675,903.368L1030.675,908.784" id="my-svg-L_Multi_MR_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(104.890625, 365.5218811035156)"><g class="label" transform="translate(0, -10.5)"><g><rect class="background" style="" x="-96.890625" y="-1" width="193.78125" 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"> one-off</tspan><tspan class="text-inner-tspan"> bug/refactor</tspan></tspan></text></g></g></g><g class="edgeLabel" transform="translate(378.359375, 365.5218811035156)"><g class="label" transform="translate(0, -10.5)"><g><rect class="background" style="" x="-96.109375" y="-1" width="192.21875" 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"> a</tspan><tspan class="text-inner-tspan"> whole</tspan><tspan class="text-inner-tspan"> new</tspan><tspan class="text-inner-tspan"> feature</tspan></tspan></text></g></g></g><g class="edgeLabel" transform="translate(657.6359405517578, 365.5218811035156)"><g class="label" transform="translate(0, -10.5)"><g><rect class="background" style="" x="-72.90625" y="-1" width="145.8125" 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"> —</tspan><tspan class="text-inner-tspan"> planned</tspan><tspan class="text-inner-tspan"> tasks</tspan></tspan></text></g></g></g><g class="edgeLabel" transform="translate(407.7179718017578, 639.8875122070312)"><g class="label" transform="translate(0, -10.5)"><g><rect class="background" style="" x="-38.6640625" y="-1" width="77.328125" 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">One</tspan><tspan class="text-inner-tspan"> agent</tspan></tspan></text></g></g></g><g class="edgeLabel" transform="translate(906.1671905517578, 639.8875122070312)"><g class="label" transform="translate(0, -10.5)"><g><rect class="background" style="" x="-53.9375" y="-1" width="107.875" 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">Several</tspan><tspan class="text-inner-tspan"> agents</tspan></tspan></text></g></g></g><g class="edgeLabel" transform="translate(284.5968780517578, 876.2843933105469)"><g class="label" transform="translate(0, -10.5)"><g><rect class="background" style="" x="-21.28125" y="-1" width="42.5625" 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">Fresh</tspan></tspan></text></g></g></g><g class="edgeLabel" transform="translate(530.8390655517578, 876.2843933105469)"><g class="label" transform="translate(0, -10.5)"><g><rect class="background" style="" x="-35.6171875" y="-1" width="71.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">Resuming</tspan></tspan></text></g></g></g><g class="edgeLabel" transform="translate(781.6593780517578, 876.2843933105469)"><g class="label" transform="translate(0, -10.5)"><g><rect class="background" style="" x="-21.28125" y="-1" width="42.5625" 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">Fresh</tspan></tspan></text></g></g></g><g class="edgeLabel" transform="translate(1030.6750030517578, 876.2843933105469)"><g class="label" transform="translate(0, -10.5)"><g><rect class="background" style="" x="-35.6171875" y="-1" width="71.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">Resuming</tspan></tspan></text></g></g></g></g><g class="nodes"><g class="node default" id="my-svg-flowchart-Start-0" transform="translate(378.359375, 32.5)"><rect class="basic label-container" style="" x="-112.4140625" y="-24.5" width="224.828125" 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">Build-phase</tspan><tspan class="text-inner-tspan"> work</tspan><tspan class="text-inner-tspan"> to</tspan><tspan class="text-inner-tspan"> do</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-InPlan-1" transform="translate(378.359375, 218.0109405517578)"><polygon points="111.01093673706055,0 222.0218734741211,-111.01093673706055 111.01093673706055,-222.0218734741211 0,-111.01093673706055" class="label-container" transform="translate(-110.51093673706055, 111.01093673706055)"></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">Already</tspan><tspan class="text-inner-tspan"> in</tspan><tspan class="text-inner-tspan"> the</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="1em"><tspan class="text-inner-tspan">implementation</tspan><tspan class="text-inner-tspan"> plan?</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-Quick-3" transform="translate(104.890625, 502.70469665527344)"><rect class="basic label-container" style="" x="-94.875" y="-33.29999923706055" width="189.75" 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">quick-task</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="1em"><tspan class="text-inner-tspan">single</tspan><tspan class="text-inner-tspan"> scoped</tspan><tspan class="text-inner-tspan"> task</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-Enh-5" transform="translate(378.359375, 502.70469665527344)"><rect class="basic label-container" style="" x="-128.59375" y="-33.29999923706055" width="257.1875" 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">new-enhancement</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="1em"><tspan class="text-inner-tspan">update</tspan><tspan class="text-inner-tspan"> PRD</tspan><tspan class="text-inner-tspan"> +</tspan><tspan class="text-inner-tspan"> stories</tspan><tspan class="text-inner-tspan"> +</tspan><tspan class="text-inner-tspan"> plan</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-HowMany-7" transform="translate(657.6359405517578, 502.70469665527344)"><polygon points="100.68281173706055,0 201.3656234741211,-100.68281173706055 100.68281173706055,-201.3656234741211 0,-100.68281173706055" class="label-container" transform="translate(-100.18281173706055, 100.68281173706055)"></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">One</tspan><tspan class="text-inner-tspan"> agent</tspan><tspan class="text-inner-tspan"> or</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="1em"><tspan class="text-inner-tspan">several</tspan><tspan class="text-inner-tspan"> in</tspan><tspan class="text-inner-tspan"> parallel?</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-Single-9" transform="translate(407.7179718017578, 758.0859527587891)"><polygon points="81.69843673706055,0 163.3968734741211,-81.69843673706055 81.69843673706055,-163.3968734741211 0,-81.69843673706055" class="label-container" transform="translate(-81.19843673706055, 81.69843673706055)"></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">Fresh</tspan><tspan class="text-inner-tspan"> start</tspan><tspan class="text-inner-tspan"> or</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="1em"><tspan class="text-inner-tspan">resuming?</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-Multi-11" transform="translate(906.1671905517578, 758.0859527587891)"><polygon points="81.69843673706055,0 163.3968734741211,-81.69843673706055 81.69843673706055,-163.3968734741211 0,-81.69843673706055" class="label-container" transform="translate(-81.19843673706055, 81.69843673706055)"></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">Fresh</tspan><tspan class="text-inner-tspan"> start</tspan><tspan class="text-inner-tspan"> or</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="1em"><tspan class="text-inner-tspan">resuming?</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-SS-13" transform="translate(284.5968780517578, 946.0843925476074)"><rect class="basic label-container" style="" x="-93.5234375" y="-24.5" width="187.046875" 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">single-agent-start</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-SR-15" transform="translate(530.8390655517578, 946.0843925476074)"><rect class="basic label-container" style="" x="-102.71875" y="-24.5" width="205.4375" 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">single-agent-resume</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-MS-17" transform="translate(781.6593780517578, 946.0843925476074)"><rect class="basic label-container" style="" x="-98.1015625" y="-33.29999923706055" width="196.203125" 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">multi-agent-start</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="1em"><tspan class="text-inner-tspan">(needs</tspan><tspan class="text-inner-tspan"> a</tspan><tspan class="text-inner-tspan"> worktree)</tspan></tspan></text></g></g></g><g class="node default" id="my-svg-flowchart-MR-19" transform="translate(1030.6750030517578, 946.0843925476074)"><rect class="basic label-container" style="" x="-100.9140625" y="-33.29999923706055" width="201.828125" 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">multi-agent-resume</tspan></tspan><tspan class="text-outer-tspan row" x="0" y="1em"><tspan class="text-inner-tspan">(in</tspan><tspan class="text-inner-tspan"> the</tspan><tspan class="text-inner-tspan"> worktree)</tspan></tspan></text></g></g></g></g></g></g><defs></defs><defs></defs></svg></figure>
|
|
1150
|
-
<div class="tabs"><div class="tablist" role="tablist"><button class="tab-btn active" role="tab" data-tab="0">Planned</button><button class="tab-btn" role="tab" data-tab="1">Unplanned</button></div><div class="tabpane active" data-tab="0"><p><strong><code>single-agent-start</code></strong> — one agent claims the next planned task, runs the
|
|
1431
|
+
<div class="tabs"><div class="tablist" role="tablist"><button id="tab-0-0" class="tab-btn active" role="tab" data-tab="0" aria-controls="tabpane-0-0" aria-selected="true" tabindex="0">Planned work</button><button id="tab-0-1" class="tab-btn" role="tab" data-tab="1" aria-controls="tabpane-0-1" aria-selected="false" tabindex="-1">Unplanned work</button></div><div id="tabpane-0-0" class="tabpane active" role="tabpanel" data-tab="0" aria-labelledby="tab-0-0" tabindex="0"><p><strong><code>single-agent-start</code></strong> — one agent claims the next planned task, runs the
|
|
1151
1432
|
red-green-refactor loop, opens a PR, repeats. The default entry point when one
|
|
1152
1433
|
agent works the plan sequentially.</p><p><strong><code>multi-agent-start <agent-name></code></strong> — establishes a <em>named</em> agent inside a git
|
|
1153
1434
|
worktree so several agents run the same loop simultaneously without file
|
|
@@ -1156,7 +1437,7 @@ worktree environment before claiming tasks.</p><p><strong><code>single-agent-res
|
|
|
1156
1437
|
after a break (context reset, paused session, next day). They recover context —
|
|
1157
1438
|
git state, in-progress work, merged PRs — and continue the loop. The
|
|
1158
1439
|
multi-agent variant additionally verifies the worktree and syncs with main
|
|
1159
|
-
before resuming.</p></div><div class="tabpane" data-tab="1"><p><strong><code>quick-task <description></code></strong> — a single, well-scoped task for a bug fix,
|
|
1440
|
+
before resuming.</p></div><div id="tabpane-0-1" class="tabpane" role="tabpanel" data-tab="1" aria-labelledby="tab-0-1" tabindex="0"><p><strong><code>quick-task <description></code></strong> — a single, well-scoped task for a bug fix,
|
|
1160
1441
|
refactor, perf tweak, or small refinement that is <em>not</em> in the plan. Produces
|
|
1161
1442
|
one task with acceptance criteria and a TDD test plan; a complexity gate
|
|
1162
1443
|
redirects to <code>new-enhancement</code> if the scope turns out to be too large.</p><p><strong><code>new-enhancement <description></code></strong> — the full-weight path for a genuinely new
|
|
@@ -1264,6 +1545,7 @@ when <code>identity.json</code> already exists — but it does no useful work.</
|
|
|
1264
1545
|
<li><code>docs/git-workflow.md</code> §7 — the canonical worktree commands and conflict
|
|
1265
1546
|
rules <span class="cite-advisory" data-path="docs/git-workflow.md:150">docs/git-workflow.md:150</span>.</li>
|
|
1266
1547
|
</ul></main>
|
|
1548
|
+
<div class="rail-backdrop" data-action="nav" aria-hidden="true"></div>
|
|
1267
1549
|
</div>
|
|
1268
1550
|
<script>(function(){
|
|
1269
1551
|
var LS_KEY = 'guide-theme';
|
|
@@ -1282,12 +1564,69 @@ rules <span class="cite-advisory" data-path="docs/git-workflow.md:150">docs/git-
|
|
|
1282
1564
|
});
|
|
1283
1565
|
});
|
|
1284
1566
|
|
|
1285
|
-
// ─── Mobile nav
|
|
1567
|
+
// ─── Mobile nav (drawer + backdrop; aria-expanded + Escape-to-close) ──────
|
|
1568
|
+
function setNav(open) {
|
|
1569
|
+
var rail = document.querySelector('.rail');
|
|
1570
|
+
if (rail) rail.classList.toggle('open', open);
|
|
1571
|
+
var toggle = document.querySelector('.nav-toggle');
|
|
1572
|
+
if (toggle) toggle.setAttribute('aria-expanded', open ? 'true' : 'false');
|
|
1573
|
+
// Modal-drawer focus containment: while open, make the page content inert
|
|
1574
|
+
// (out of tab order + a11y tree) and move focus into the drawer; on close,
|
|
1575
|
+
// restore content and return focus to the toggle.
|
|
1576
|
+
var main = document.querySelector('.content');
|
|
1577
|
+
if (main) main.inert = open;
|
|
1578
|
+
if (open) {
|
|
1579
|
+
var first = rail && rail.querySelector('a, button, [tabindex]:not([tabindex="-1"])');
|
|
1580
|
+
if (first) first.focus();
|
|
1581
|
+
else if (rail) { rail.setAttribute('tabindex', '-1'); rail.focus(); }
|
|
1582
|
+
} else if (toggle) {
|
|
1583
|
+
toggle.focus();
|
|
1584
|
+
}
|
|
1585
|
+
}
|
|
1586
|
+
// If the viewport grows past the mobile breakpoint while the drawer is open,
|
|
1587
|
+
// the rail becomes the desktop sidebar and the toggle hides — clear the open
|
|
1588
|
+
// state so .content doesn't stay inert with no way to close it.
|
|
1589
|
+
if (window.matchMedia) {
|
|
1590
|
+
var mq = window.matchMedia('(max-width: 860px)');
|
|
1591
|
+
var onMq = function() {
|
|
1592
|
+
if (mq.matches) return;
|
|
1593
|
+
var rail = document.querySelector('.rail');
|
|
1594
|
+
if (rail) rail.classList.remove('open');
|
|
1595
|
+
var toggle = document.querySelector('.nav-toggle');
|
|
1596
|
+
if (toggle) toggle.setAttribute('aria-expanded', 'false');
|
|
1597
|
+
var main = document.querySelector('.content');
|
|
1598
|
+
if (main) main.inert = false;
|
|
1599
|
+
};
|
|
1600
|
+
if (mq.addEventListener) mq.addEventListener('change', onMq);
|
|
1601
|
+
else if (mq.addListener) mq.addListener(onMq);
|
|
1602
|
+
}
|
|
1286
1603
|
document.querySelectorAll('[data-action="nav"]').forEach(function(btn) {
|
|
1287
1604
|
btn.addEventListener('click', function() {
|
|
1288
1605
|
var rail = document.querySelector('.rail');
|
|
1289
|
-
|
|
1606
|
+
setNav(!(rail && rail.classList.contains('open')));
|
|
1607
|
+
});
|
|
1608
|
+
});
|
|
1609
|
+
// Selecting a TOC link closes the drawer (so the now-active content isn't
|
|
1610
|
+
// left inert behind the panel) before the anchor navigation scrolls.
|
|
1611
|
+
var drawerRail = document.querySelector('.rail');
|
|
1612
|
+
if (drawerRail) {
|
|
1613
|
+
drawerRail.querySelectorAll('a').forEach(function(a) {
|
|
1614
|
+
a.addEventListener('click', function() {
|
|
1615
|
+
if (drawerRail.classList.contains('open')) setNav(false);
|
|
1616
|
+
});
|
|
1290
1617
|
});
|
|
1618
|
+
}
|
|
1619
|
+
document.addEventListener('keydown', function(e) {
|
|
1620
|
+
var rail = document.querySelector('.rail');
|
|
1621
|
+
if (!rail || !rail.classList.contains('open')) return;
|
|
1622
|
+
if (e.key === 'Escape') { setNav(false); return; } // setNav restores focus to the toggle
|
|
1623
|
+
// Trap Tab within the open drawer (modal pattern).
|
|
1624
|
+
if (e.key !== 'Tab') return;
|
|
1625
|
+
var f = rail.querySelectorAll('a[href], button, [tabindex]:not([tabindex="-1"])');
|
|
1626
|
+
if (!f.length) return;
|
|
1627
|
+
var first = f[0], last = f[f.length - 1];
|
|
1628
|
+
if (e.shiftKey && document.activeElement === first) { e.preventDefault(); last.focus(); }
|
|
1629
|
+
else if (!e.shiftKey && document.activeElement === last) { e.preventDefault(); first.focus(); }
|
|
1291
1630
|
});
|
|
1292
1631
|
|
|
1293
1632
|
// ─── Copy buttons ─────────────────────────────────────────────────────────
|
|
@@ -1314,17 +1653,31 @@ rules <span class="cite-advisory" data-path="docs/git-workflow.md:150">docs/git-
|
|
|
1314
1653
|
wrapper.insertBefore(btn, pre);
|
|
1315
1654
|
});
|
|
1316
1655
|
|
|
1317
|
-
// ─── Tabs
|
|
1656
|
+
// ─── Tabs (ARIA pattern: aria-selected + roving tabindex + arrow keys) ────
|
|
1657
|
+
function activateTab(group, btn, focus) {
|
|
1658
|
+
var idx = btn.getAttribute('data-tab');
|
|
1659
|
+
group.querySelectorAll('.tab-btn').forEach(function(b) {
|
|
1660
|
+
var on = b === btn;
|
|
1661
|
+
b.classList.toggle('active', on);
|
|
1662
|
+
b.setAttribute('aria-selected', on ? 'true' : 'false');
|
|
1663
|
+
b.setAttribute('tabindex', on ? '0' : '-1');
|
|
1664
|
+
});
|
|
1665
|
+
group.querySelectorAll('.tabpane').forEach(function(pane) {
|
|
1666
|
+
pane.classList.toggle('active', pane.getAttribute('data-tab') === idx);
|
|
1667
|
+
});
|
|
1668
|
+
if (focus) btn.focus();
|
|
1669
|
+
}
|
|
1318
1670
|
document.querySelectorAll('.tabs').forEach(function(group) {
|
|
1319
|
-
group.querySelectorAll('.tab-btn')
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1671
|
+
var btns = [].slice.call(group.querySelectorAll('.tab-btn'));
|
|
1672
|
+
btns.forEach(function(btn, i) {
|
|
1673
|
+
btn.addEventListener('click', function() { activateTab(group, btn, false); });
|
|
1674
|
+
btn.addEventListener('keydown', function(e) {
|
|
1675
|
+
var ni = -1;
|
|
1676
|
+
if (e.key === 'ArrowRight' || e.key === 'ArrowDown') ni = (i + 1) % btns.length;
|
|
1677
|
+
else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') ni = (i - 1 + btns.length) % btns.length;
|
|
1678
|
+
else if (e.key === 'Home') ni = 0;
|
|
1679
|
+
else if (e.key === 'End') ni = btns.length - 1;
|
|
1680
|
+
if (ni >= 0) { e.preventDefault(); activateTab(group, btns[ni], true); }
|
|
1328
1681
|
});
|
|
1329
1682
|
});
|
|
1330
1683
|
});
|
|
@@ -94,7 +94,7 @@ flowchart TD
|
|
|
94
94
|
```
|
|
95
95
|
|
|
96
96
|
::::tabs
|
|
97
|
-
:::tab{title=Planned work}
|
|
97
|
+
:::tab{title="Planned work"}
|
|
98
98
|
**`single-agent-start`** — one agent claims the next planned task, runs the
|
|
99
99
|
red-green-refactor loop, opens a PR, repeats. The default entry point when one
|
|
100
100
|
agent works the plan sequentially.
|
|
@@ -110,7 +110,7 @@ git state, in-progress work, merged PRs — and continue the loop. The
|
|
|
110
110
|
multi-agent variant additionally verifies the worktree and syncs with main
|
|
111
111
|
before resuming.
|
|
112
112
|
:::
|
|
113
|
-
:::tab{title=Unplanned work}
|
|
113
|
+
:::tab{title="Unplanned work"}
|
|
114
114
|
**`quick-task <description>`** — a single, well-scoped task for a bug fix,
|
|
115
115
|
refactor, perf tweak, or small refinement that is *not* in the plan. Produces
|
|
116
116
|
one task with acceptance criteria and a TDD test plan; a complexity gate
|