@worca/ui 0.22.0 → 0.24.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/app/main.bundle.js +7298 -4688
- package/app/main.bundle.js.map +4 -4
- package/app/protocol.js +5 -1
- package/app/styles.css +1315 -23
- package/app/utils/state-actions.js +33 -4
- package/app/utils/status-constants.js +11 -0
- package/bin/worca-ui.js +2 -2
- package/package.json +2 -1
- package/scripts/build-frontend.js +48 -1
- package/server/app.js +159 -1
- package/server/fleet-routes.js +1149 -0
- package/server/index.js +4 -3
- package/server/integrations/commands/fleet.js +266 -0
- package/server/integrations/commands/global.js +18 -0
- package/server/integrations/commands/parser.js +4 -1
- package/server/integrations/commands/workspace.js +295 -0
- package/server/integrations/index.js +9 -0
- package/server/integrations/renderers.js +386 -0
- package/server/integrations/rest_client.js +7 -0
- package/server/paths.js +78 -0
- package/server/project-routes.js +68 -5
- package/server/workspace-routes.js +1554 -0
- package/server/worktree-ops.js +12 -1
- package/server/worktrees-routes.js +34 -0
- package/server/ws-fleet-manifest-watcher.js +131 -0
- package/server/ws-message-router.js +20 -0
- package/server/ws-modular.js +18 -1
- package/server/ws-workspace-manifest-watcher.js +136 -0
package/app/styles.css
CHANGED
|
@@ -535,14 +535,13 @@ h1, h2, h3, h4, h5, h6 {
|
|
|
535
535
|
gap: 6px;
|
|
536
536
|
}
|
|
537
537
|
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
.run-template {
|
|
538
|
+
/* Project / Branch / Pipeline-Template / Worktree rows inside
|
|
539
|
+
`.run-info-section` all share the same label-value typography so the
|
|
540
|
+
block reads as a uniform stack. Mirror .run-group below it. */
|
|
541
|
+
.run-project,
|
|
542
|
+
.run-branch,
|
|
543
|
+
.run-template,
|
|
544
|
+
.run-worktree {
|
|
546
545
|
display: flex;
|
|
547
546
|
align-items: center;
|
|
548
547
|
gap: 6px;
|
|
@@ -1150,6 +1149,34 @@ sl-input [slot="prefix"] {
|
|
|
1150
1149
|
color: var(--status-cancelled);
|
|
1151
1150
|
}
|
|
1152
1151
|
|
|
1152
|
+
.status-halted {
|
|
1153
|
+
color: var(--status-paused);
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
.status-setup-failed {
|
|
1157
|
+
color: var(--status-failed);
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
.status-unrecoverable {
|
|
1161
|
+
color: var(--status-failed);
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
.status-planning {
|
|
1165
|
+
color: var(--status-running);
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
.status-integration-testing {
|
|
1169
|
+
color: var(--status-running);
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
.status-integration-failed {
|
|
1173
|
+
color: var(--status-failed);
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
.status-blocked {
|
|
1177
|
+
color: var(--status-paused);
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1153
1180
|
/* --- 18b. Control Buttons --- */
|
|
1154
1181
|
.action-btn--amber {
|
|
1155
1182
|
border-color: var(--status-paused);
|
|
@@ -1171,6 +1198,19 @@ sl-input [slot="prefix"] {
|
|
|
1171
1198
|
color: #ffffff;
|
|
1172
1199
|
}
|
|
1173
1200
|
|
|
1201
|
+
.action-btn--teal {
|
|
1202
|
+
/* "Re-run" / "iterate again" actions — distinct from primary blue
|
|
1203
|
+
(resume) and status palette colors so it reads as a separate
|
|
1204
|
+
intent: launch a fresh attempt from this one. */
|
|
1205
|
+
border-color: #0891b2;
|
|
1206
|
+
color: #0891b2;
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
.action-btn--teal:hover {
|
|
1210
|
+
background: #0891b2;
|
|
1211
|
+
color: #ffffff;
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1174
1214
|
.action-btn--red {
|
|
1175
1215
|
border-color: var(--status-failed);
|
|
1176
1216
|
color: var(--status-failed);
|
|
@@ -1302,11 +1342,146 @@ sl-input [slot="prefix"] {
|
|
|
1302
1342
|
|
|
1303
1343
|
/* Status-colored left border accent on run cards */
|
|
1304
1344
|
.run-card.status-running { border-left: 3px solid var(--status-running); }
|
|
1345
|
+
.run-card.status-resuming { border-left: 3px solid var(--status-running); }
|
|
1305
1346
|
.run-card.status-paused { border-left: 3px solid var(--status-paused); }
|
|
1347
|
+
.run-card.status-interrupted { border-left: 3px solid var(--status-interrupted); }
|
|
1306
1348
|
.run-card.status-completed { border-left: 3px solid var(--status-completed); }
|
|
1307
1349
|
.run-card.status-failed { border-left: 3px solid var(--status-failed); }
|
|
1350
|
+
.run-card.status-error { border-left: 3px solid var(--status-error); }
|
|
1308
1351
|
.run-card.status-pending { border-left: 3px solid var(--status-pending); }
|
|
1352
|
+
.run-card.status-skipped { border-left: 3px solid var(--status-pending); }
|
|
1309
1353
|
.run-card.status-cancelled { border-left: 3px solid var(--status-cancelled); }
|
|
1354
|
+
.run-card.status-halted { border-left: 3px solid var(--status-paused); }
|
|
1355
|
+
.run-card.status-setup-failed { border-left: 3px solid var(--status-failed); }
|
|
1356
|
+
.run-card.status-unrecoverable { border-left: 3px solid var(--status-failed); }
|
|
1357
|
+
.run-card.status-planning { border-left: 3px solid var(--status-running); }
|
|
1358
|
+
.run-card.status-integration-testing { border-left: 3px solid var(--status-running); }
|
|
1359
|
+
.run-card.status-integration-failed { border-left: 3px solid var(--status-failed); }
|
|
1360
|
+
.run-card.status-blocked { border-left: 3px solid var(--status-paused); }
|
|
1361
|
+
|
|
1362
|
+
/* ── Fleet card (shared component for Dashboard + Fleet list) ───────────
|
|
1363
|
+
The fleet card reuses the `.run-card` base class and its shared
|
|
1364
|
+
structural sub-elements (`.run-card-top`, `.run-card-status`,
|
|
1365
|
+
`.run-card-title`, `.run-card-meta`, `.run-card-meta-item`,
|
|
1366
|
+
`.run-card-actions`) — exactly like `.worktree-card` does. The
|
|
1367
|
+
`.fleet-card` / `.fleet-card-*` rules below are only the bits that are
|
|
1368
|
+
genuinely fleet-specific:
|
|
1369
|
+
- a layered "stack of cards" silhouette (::before / ::after layers)
|
|
1370
|
+
- the "Projects:" name-badge row
|
|
1371
|
+
- the failed-count pill + exception pills
|
|
1372
|
+
The box, hover, and status-accent styling all come from `.run-card`. */
|
|
1373
|
+
|
|
1374
|
+
/* Stack-of-cards illusion: two thin layers above-right behind the main card,
|
|
1375
|
+
each progressively offset and dimmed. Pure decoration — pointer-events
|
|
1376
|
+
off so they never steal clicks. */
|
|
1377
|
+
.fleet-card-stack {
|
|
1378
|
+
position: relative;
|
|
1379
|
+
isolation: isolate;
|
|
1380
|
+
}
|
|
1381
|
+
.fleet-card-stack::before,
|
|
1382
|
+
.fleet-card-stack::after {
|
|
1383
|
+
content: '';
|
|
1384
|
+
position: absolute;
|
|
1385
|
+
inset: 0;
|
|
1386
|
+
border: 1px solid var(--border-subtle);
|
|
1387
|
+
border-radius: var(--radius-lg);
|
|
1388
|
+
background: var(--surface);
|
|
1389
|
+
pointer-events: none;
|
|
1390
|
+
z-index: -1;
|
|
1391
|
+
}
|
|
1392
|
+
.fleet-card-stack::before {
|
|
1393
|
+
transform: translate(4px, -4px);
|
|
1394
|
+
opacity: 0.55;
|
|
1395
|
+
}
|
|
1396
|
+
.fleet-card-stack::after {
|
|
1397
|
+
transform: translate(8px, -8px);
|
|
1398
|
+
opacity: 0.3;
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1401
|
+
/* The status-coloured left edge comes from `.run-card.status-*` (the
|
|
1402
|
+
fleet card carries the `run-card` base class). The one fleet-specific
|
|
1403
|
+
override: a user-initiated halt reads as informational grey, matching
|
|
1404
|
+
its `neutral` status-badge variant — per the badge-color-language
|
|
1405
|
+
guide §CSS Variables. Circuit-breaker / targets-not-ready halts keep
|
|
1406
|
+
the inherited orange. */
|
|
1407
|
+
.fleet-card.status-halted[data-halt-reason="user"] {
|
|
1408
|
+
border-left-color: var(--status-pending);
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1411
|
+
/* Project name badges — the value of the "Projects:" meta label. Neutral
|
|
1412
|
+
(no status color), each clamped to ~20ch with an ellipsis; the JS also
|
|
1413
|
+
pre-truncates so the title attr carries the full name. Up to 3 render
|
|
1414
|
+
inline, the rest collapse into `.fleet-card-project-more`. */
|
|
1415
|
+
.fleet-card-project-badge {
|
|
1416
|
+
display: inline-block;
|
|
1417
|
+
max-width: 20ch;
|
|
1418
|
+
overflow: hidden;
|
|
1419
|
+
text-overflow: ellipsis;
|
|
1420
|
+
white-space: nowrap;
|
|
1421
|
+
vertical-align: bottom;
|
|
1422
|
+
padding: 1px 8px;
|
|
1423
|
+
font-size: 11px;
|
|
1424
|
+
color: var(--fg);
|
|
1425
|
+
background: var(--bg-tertiary);
|
|
1426
|
+
border: 1px solid var(--border-subtle);
|
|
1427
|
+
border-radius: 999px;
|
|
1428
|
+
flex-shrink: 0;
|
|
1429
|
+
}
|
|
1430
|
+
.fleet-card-project-more {
|
|
1431
|
+
font-size: 11px;
|
|
1432
|
+
color: var(--muted);
|
|
1433
|
+
flex-shrink: 0;
|
|
1434
|
+
}
|
|
1435
|
+
/* Failed-project count — rides the "Projects:" row after the name badges
|
|
1436
|
+
as a solid red badge (e.g. "1 failed"). Only rendered when at least one
|
|
1437
|
+
project failed; callers guard with `failedCount > 0`. */
|
|
1438
|
+
.fleet-card-failed-count {
|
|
1439
|
+
display: inline-block;
|
|
1440
|
+
flex-shrink: 0;
|
|
1441
|
+
padding: 1px 8px;
|
|
1442
|
+
font-size: 11px;
|
|
1443
|
+
font-weight: 500;
|
|
1444
|
+
color: #ffffff;
|
|
1445
|
+
background: var(--status-error);
|
|
1446
|
+
border-radius: 999px;
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1449
|
+
/* Exception counter pills — surface non-zero failure / halted / paused
|
|
1450
|
+
buckets when they don't already match the fleet's overall status badge.
|
|
1451
|
+
Variants follow the badge-color-language guide: `danger` for failures,
|
|
1452
|
+
`warning` for halts/pauses. Replaces the prior right-edge accent stripe
|
|
1453
|
+
(which was too subtle to be actionable). */
|
|
1454
|
+
.fleet-card-exception-pill {
|
|
1455
|
+
flex-shrink: 0;
|
|
1456
|
+
}
|
|
1457
|
+
|
|
1458
|
+
.fleet-card-mono {
|
|
1459
|
+
font-family: var(--font-mono, ui-monospace, monospace);
|
|
1460
|
+
font-size: 11px;
|
|
1461
|
+
color: var(--fg);
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1464
|
+
.fleet-card-children-label {
|
|
1465
|
+
align-self: center;
|
|
1466
|
+
flex-shrink: 0;
|
|
1467
|
+
font-size: 12px;
|
|
1468
|
+
/* Color/weight inherited from `.meta-label` so this row matches the
|
|
1469
|
+
Plan/Base/Started/Duration label vocabulary on the rows below. */
|
|
1470
|
+
}
|
|
1471
|
+
.fleet-card-children-empty {
|
|
1472
|
+
font-size: 12px;
|
|
1473
|
+
color: var(--muted);
|
|
1474
|
+
font-style: italic;
|
|
1475
|
+
}
|
|
1476
|
+
|
|
1477
|
+
/* "Projects:" label + name-badge list row. */
|
|
1478
|
+
.fleet-card-progress {
|
|
1479
|
+
display: flex;
|
|
1480
|
+
align-items: center;
|
|
1481
|
+
flex-wrap: wrap;
|
|
1482
|
+
gap: 6px;
|
|
1483
|
+
padding-left: 26px;
|
|
1484
|
+
}
|
|
1310
1485
|
|
|
1311
1486
|
/* --- 21. Dashboard --- */
|
|
1312
1487
|
.dashboard {
|
|
@@ -2340,7 +2515,39 @@ sl-details.live-output-panel::part(content) {
|
|
|
2340
2515
|
.new-run-advanced {
|
|
2341
2516
|
display: flex;
|
|
2342
2517
|
flex-direction: column;
|
|
2343
|
-
gap:
|
|
2518
|
+
gap: 24px;
|
|
2519
|
+
}
|
|
2520
|
+
|
|
2521
|
+
/* Advanced Options is dense — give each field a touch more breathing room
|
|
2522
|
+
between label / control / hint than the default 4px so multi-line
|
|
2523
|
+
sub-controls (head-template preview, plan-mode radio + warning) don't
|
|
2524
|
+
feel stacked. Scoped to .new-run-advanced so the rest of Settings
|
|
2525
|
+
keeps its tighter rhythm. */
|
|
2526
|
+
.new-run-advanced .settings-field {
|
|
2527
|
+
gap: 8px;
|
|
2528
|
+
}
|
|
2529
|
+
.new-run-advanced .settings-field-hint {
|
|
2530
|
+
margin-top: 4px;
|
|
2531
|
+
line-height: 1.5;
|
|
2532
|
+
}
|
|
2533
|
+
|
|
2534
|
+
/* Visual subgroup inside Advanced Options — small caps title + subtle
|
|
2535
|
+
underline divider. Keeps the section card's outer border doing the
|
|
2536
|
+
heavy lifting; the subgroup title is just a quiet "BRANCHES" /
|
|
2537
|
+
"PLANNING" / "CONCURRENCY" label for scanability. */
|
|
2538
|
+
.advanced-subgroup {
|
|
2539
|
+
display: flex;
|
|
2540
|
+
flex-direction: column;
|
|
2541
|
+
gap: 14px;
|
|
2542
|
+
}
|
|
2543
|
+
.advanced-subgroup-title {
|
|
2544
|
+
font-size: 11px;
|
|
2545
|
+
font-weight: 600;
|
|
2546
|
+
color: var(--muted);
|
|
2547
|
+
text-transform: uppercase;
|
|
2548
|
+
letter-spacing: 0.06em;
|
|
2549
|
+
padding-bottom: 6px;
|
|
2550
|
+
border-bottom: 1px dashed var(--border-subtle);
|
|
2344
2551
|
}
|
|
2345
2552
|
|
|
2346
2553
|
.new-run-grid {
|
|
@@ -2484,39 +2691,106 @@ sl-option.template-grouped:focus::part(suffix) {
|
|
|
2484
2691
|
background: var(--bg-tertiary);
|
|
2485
2692
|
}
|
|
2486
2693
|
|
|
2487
|
-
/* Sidebar new run button
|
|
2694
|
+
/* Sidebar new run button (split button pattern: primary + chevron).
|
|
2695
|
+
The split button is the W-040 UX choice — primary "New Pipeline"
|
|
2696
|
+
handles the common case; the chevron drops down to a menu of
|
|
2697
|
+
multi-project alternatives (Fleet, plus Workspace when W-047 ships). */
|
|
2488
2698
|
.sidebar-new-run {
|
|
2489
2699
|
padding: 8px 8px 4px;
|
|
2490
2700
|
}
|
|
2491
2701
|
|
|
2492
|
-
.sidebar-new-run-
|
|
2702
|
+
.sidebar-new-run-split {
|
|
2493
2703
|
display: flex;
|
|
2494
|
-
align-items:
|
|
2495
|
-
justify-content: center;
|
|
2496
|
-
gap: 8px;
|
|
2704
|
+
align-items: stretch;
|
|
2497
2705
|
width: 100%;
|
|
2498
|
-
|
|
2706
|
+
min-height: 36px;
|
|
2499
2707
|
border: 2px dashed var(--accent);
|
|
2500
2708
|
border-radius: var(--radius);
|
|
2709
|
+
overflow: hidden;
|
|
2710
|
+
background: transparent;
|
|
2711
|
+
transition: background var(--transition-fast), border-color var(--transition-fast);
|
|
2712
|
+
}
|
|
2713
|
+
|
|
2714
|
+
.sidebar-new-run-btn-primary {
|
|
2715
|
+
flex: 1 1 auto;
|
|
2716
|
+
display: flex;
|
|
2717
|
+
align-items: center;
|
|
2718
|
+
justify-content: center;
|
|
2719
|
+
gap: 8px;
|
|
2720
|
+
min-width: 0;
|
|
2721
|
+
padding: 6px 12px;
|
|
2722
|
+
border: 0;
|
|
2723
|
+
border-right: 2px dashed var(--accent);
|
|
2501
2724
|
background: transparent;
|
|
2502
2725
|
color: var(--accent);
|
|
2503
2726
|
font-size: 13px;
|
|
2504
2727
|
font-weight: 600;
|
|
2505
2728
|
font-family: inherit;
|
|
2506
2729
|
cursor: pointer;
|
|
2730
|
+
transition: background var(--transition-fast), color var(--transition-fast),
|
|
2731
|
+
border-color var(--transition-fast);
|
|
2732
|
+
}
|
|
2733
|
+
|
|
2734
|
+
.sidebar-new-run-btn-primary:hover:not(:disabled) {
|
|
2735
|
+
background: var(--accent);
|
|
2736
|
+
color: #ffffff;
|
|
2737
|
+
}
|
|
2738
|
+
|
|
2739
|
+
/* Disabled state: muted (not ghosted) so it reads as "waiting on something"
|
|
2740
|
+
rather than a broken control. Pairs with the title tooltip explaining
|
|
2741
|
+
why it's inactive (e.g., "Select a project first…"). */
|
|
2742
|
+
.sidebar-new-run-btn-primary:disabled {
|
|
2743
|
+
cursor: not-allowed;
|
|
2744
|
+
color: var(--muted);
|
|
2745
|
+
border-right-color: var(--muted);
|
|
2746
|
+
}
|
|
2747
|
+
|
|
2748
|
+
/* sl-dropdown defaults to inline-block; force it to fill the cross-axis
|
|
2749
|
+
so the slotted chevron button can stretch to the full split height. */
|
|
2750
|
+
.sidebar-new-run-chevron-dropdown {
|
|
2751
|
+
display: flex;
|
|
2752
|
+
flex: 0 0 auto;
|
|
2753
|
+
align-self: stretch;
|
|
2754
|
+
}
|
|
2755
|
+
|
|
2756
|
+
.sidebar-new-run-btn-chevron {
|
|
2757
|
+
display: flex;
|
|
2758
|
+
align-items: center;
|
|
2759
|
+
justify-content: center;
|
|
2760
|
+
align-self: stretch;
|
|
2761
|
+
height: 100%;
|
|
2762
|
+
min-height: 32px;
|
|
2763
|
+
padding: 0 12px;
|
|
2764
|
+
border: 0;
|
|
2765
|
+
background: transparent;
|
|
2766
|
+
color: var(--accent);
|
|
2767
|
+
cursor: pointer;
|
|
2507
2768
|
transition: background var(--transition-fast), color var(--transition-fast);
|
|
2508
2769
|
}
|
|
2509
2770
|
|
|
2510
|
-
.sidebar-new-run-btn:hover {
|
|
2771
|
+
.sidebar-new-run-btn-chevron:hover:not(:disabled) {
|
|
2511
2772
|
background: var(--accent);
|
|
2512
2773
|
color: #ffffff;
|
|
2513
2774
|
}
|
|
2514
2775
|
|
|
2515
|
-
.sidebar
|
|
2776
|
+
.sidebar-new-run-btn-chevron:disabled {
|
|
2777
|
+
cursor: not-allowed;
|
|
2778
|
+
color: var(--muted);
|
|
2779
|
+
}
|
|
2780
|
+
|
|
2781
|
+
/* Menu items: icon + label, slight indent under their icon */
|
|
2782
|
+
.sidebar-new-run-chevron-dropdown sl-menu-item::part(base) {
|
|
2783
|
+
display: flex;
|
|
2784
|
+
align-items: center;
|
|
2785
|
+
gap: 8px;
|
|
2786
|
+
font-size: 13px;
|
|
2787
|
+
}
|
|
2788
|
+
|
|
2789
|
+
.sidebar.collapsed .sidebar-new-run-btn-primary span {
|
|
2516
2790
|
display: none;
|
|
2517
2791
|
}
|
|
2518
2792
|
|
|
2519
|
-
.sidebar.collapsed .sidebar-new-run-btn {
|
|
2793
|
+
.sidebar.collapsed .sidebar-new-run-btn-primary {
|
|
2520
2794
|
padding: 8px;
|
|
2521
2795
|
}
|
|
2522
2796
|
|
|
@@ -2906,6 +3180,16 @@ sl-details.run-beads-panel::part(content) {
|
|
|
2906
3180
|
border: 1px solid var(--border-subtle);
|
|
2907
3181
|
}
|
|
2908
3182
|
|
|
3183
|
+
/* Default badge layout: when a badge contains an icon + text (e.g. the
|
|
3184
|
+
pipeline-page header status badge "<icon> Completed"), the children
|
|
3185
|
+
sit flush against each other. Give them a small gap. Single-child
|
|
3186
|
+
badges are unaffected because flex+gap only manifests between siblings. */
|
|
3187
|
+
sl-badge::part(base) {
|
|
3188
|
+
display: inline-flex;
|
|
3189
|
+
align-items: center;
|
|
3190
|
+
gap: 4px;
|
|
3191
|
+
}
|
|
3192
|
+
|
|
2909
3193
|
.run-bead-row sl-badge::part(base) {
|
|
2910
3194
|
font-size: 0.68rem;
|
|
2911
3195
|
padding: 0 5px;
|
|
@@ -3960,6 +4244,9 @@ sl-details.learnings-panel::part(content) {
|
|
|
3960
4244
|
.filter-chip-failed.active { background: var(--status-failed); border-color: var(--status-failed); }
|
|
3961
4245
|
.filter-chip-paused.active { background: var(--status-paused); border-color: var(--status-paused); }
|
|
3962
4246
|
.filter-chip-error.active { background: var(--status-failed); border-color: var(--status-failed); }
|
|
4247
|
+
.filter-chip-halted.active { background: var(--status-paused); border-color: var(--status-paused); }
|
|
4248
|
+
.filter-chip-integration-failed.active,
|
|
4249
|
+
.filter-chip-integration_failed.active { background: var(--status-failed); border-color: var(--status-failed); }
|
|
3963
4250
|
.filter-chip .chip-count {
|
|
3964
4251
|
font-size: 0.68rem;
|
|
3965
4252
|
opacity: 0.7;
|
|
@@ -3970,6 +4257,7 @@ sl-details.learnings-panel::part(content) {
|
|
|
3970
4257
|
display: flex;
|
|
3971
4258
|
align-items: center;
|
|
3972
4259
|
justify-content: flex-end;
|
|
4260
|
+
flex-wrap: wrap;
|
|
3973
4261
|
gap: 8px;
|
|
3974
4262
|
padding-left: 26px;
|
|
3975
4263
|
}
|
|
@@ -4036,11 +4324,8 @@ sl-details.learnings-panel::part(content) {
|
|
|
4036
4324
|
.project-status-paused { background: var(--status-paused, #eab308); }
|
|
4037
4325
|
|
|
4038
4326
|
/* --- Dashboard Project Cards --- */
|
|
4039
|
-
.project-cards
|
|
4040
|
-
|
|
4041
|
-
.project-card:hover { border-color: var(--accent); box-shadow: var(--shadow-sm); }
|
|
4042
|
-
.project-card-name { font-weight: 600; margin-bottom: 4px; }
|
|
4043
|
-
.project-card-stats { font-size: 0.85rem; color: var(--text-secondary); }
|
|
4327
|
+
/* .project-cards / .project-card-* removed — see app/views/dashboard.js
|
|
4328
|
+
for the rationale (sidebar dropdown replaces them). */
|
|
4044
4329
|
|
|
4045
4330
|
/* --- Settings Projects List --- */
|
|
4046
4331
|
.projects-list-item { display: flex; justify-content: space-between; align-items: center; padding: 8px 0; border-bottom: 1px solid var(--border); }
|
|
@@ -4077,6 +4362,10 @@ sl-details.learnings-panel::part(content) {
|
|
|
4077
4362
|
.pipeline-failed { border-left-color: var(--status-failed); }
|
|
4078
4363
|
.pipeline-paused { border-left-color: var(--status-paused); }
|
|
4079
4364
|
.pipeline-cancelled { border-left-color: var(--status-cancelled); }
|
|
4365
|
+
.pipeline-planning { border-left-color: var(--status-running); }
|
|
4366
|
+
.pipeline-integration-testing { border-left-color: var(--status-running); }
|
|
4367
|
+
.pipeline-integration-failed { border-left-color: var(--status-failed); }
|
|
4368
|
+
.pipeline-blocked { border-left-color: var(--status-paused); }
|
|
4080
4369
|
.pipeline-unknown { border-left-color: var(--muted); }
|
|
4081
4370
|
|
|
4082
4371
|
.pipeline-card-header {
|
|
@@ -4639,6 +4928,23 @@ sl-tooltip.bead-tooltip::part(body) {
|
|
|
4639
4928
|
flex: 1;
|
|
4640
4929
|
min-width: 240px;
|
|
4641
4930
|
}
|
|
4931
|
+
|
|
4932
|
+
/* Shared text-filter row — the line under the filter chips on the
|
|
4933
|
+
History and Fleets list pages. Mirrors `.worktrees-toolbar` so the
|
|
4934
|
+
three list pages present an identical filter affordance. The
|
|
4935
|
+
worktrees page keeps its own toolbar (it carries the extra
|
|
4936
|
+
"Cleanup all completed" button alongside the text input). */
|
|
4937
|
+
.list-filter-row {
|
|
4938
|
+
display: flex;
|
|
4939
|
+
align-items: center;
|
|
4940
|
+
gap: 12px;
|
|
4941
|
+
flex-wrap: wrap;
|
|
4942
|
+
margin-bottom: 12px;
|
|
4943
|
+
}
|
|
4944
|
+
.list-filter-row .list-text-filter {
|
|
4945
|
+
flex: 1;
|
|
4946
|
+
min-width: 240px;
|
|
4947
|
+
}
|
|
4642
4948
|
.worktree-card-path {
|
|
4643
4949
|
align-items: baseline;
|
|
4644
4950
|
}
|
|
@@ -4854,3 +5160,989 @@ sl-tooltip.bead-tooltip::part(body) {
|
|
|
4854
5160
|
line-height: 1.2;
|
|
4855
5161
|
flex: 0 0 auto;
|
|
4856
5162
|
}
|
|
5163
|
+
|
|
5164
|
+
/* ─── Fleet group (W-040 §13.2) ────────────────────────────────────────────── */
|
|
5165
|
+
.fleet-group {
|
|
5166
|
+
margin-bottom: 8px;
|
|
5167
|
+
border: 1px solid var(--border-subtle);
|
|
5168
|
+
border-radius: 8px;
|
|
5169
|
+
overflow: hidden;
|
|
5170
|
+
}
|
|
5171
|
+
|
|
5172
|
+
.fleet-header {
|
|
5173
|
+
display: flex;
|
|
5174
|
+
align-items: center;
|
|
5175
|
+
gap: 10px;
|
|
5176
|
+
padding: 10px 14px;
|
|
5177
|
+
background: var(--bg-secondary);
|
|
5178
|
+
cursor: pointer;
|
|
5179
|
+
user-select: none;
|
|
5180
|
+
}
|
|
5181
|
+
|
|
5182
|
+
.fleet-header:hover {
|
|
5183
|
+
background: var(--bg-tertiary);
|
|
5184
|
+
}
|
|
5185
|
+
|
|
5186
|
+
.fleet-toggle {
|
|
5187
|
+
flex-shrink: 0;
|
|
5188
|
+
color: var(--fg-muted);
|
|
5189
|
+
font-size: 14px;
|
|
5190
|
+
}
|
|
5191
|
+
|
|
5192
|
+
.fleet-title {
|
|
5193
|
+
flex: 0 1 auto;
|
|
5194
|
+
font-size: 13px;
|
|
5195
|
+
font-weight: 600;
|
|
5196
|
+
color: var(--fg);
|
|
5197
|
+
overflow: hidden;
|
|
5198
|
+
text-overflow: ellipsis;
|
|
5199
|
+
white-space: nowrap;
|
|
5200
|
+
}
|
|
5201
|
+
|
|
5202
|
+
.fleet-status-badge {
|
|
5203
|
+
flex-shrink: 0;
|
|
5204
|
+
}
|
|
5205
|
+
|
|
5206
|
+
.fleet-progress {
|
|
5207
|
+
flex-shrink: 0;
|
|
5208
|
+
font-size: 12px;
|
|
5209
|
+
color: var(--fg-muted);
|
|
5210
|
+
}
|
|
5211
|
+
|
|
5212
|
+
.fleet-progress-bar {
|
|
5213
|
+
flex: 1 1 80px;
|
|
5214
|
+
min-width: 60px;
|
|
5215
|
+
max-width: 160px;
|
|
5216
|
+
}
|
|
5217
|
+
|
|
5218
|
+
.fleet-cost {
|
|
5219
|
+
flex-shrink: 0;
|
|
5220
|
+
font-size: 12px;
|
|
5221
|
+
color: var(--fg-muted);
|
|
5222
|
+
}
|
|
5223
|
+
|
|
5224
|
+
.fleet-detail-btn {
|
|
5225
|
+
flex-shrink: 0;
|
|
5226
|
+
margin-left: auto;
|
|
5227
|
+
}
|
|
5228
|
+
|
|
5229
|
+
.fleet-children {
|
|
5230
|
+
padding: 8px;
|
|
5231
|
+
display: flex;
|
|
5232
|
+
flex-direction: column;
|
|
5233
|
+
gap: 8px;
|
|
5234
|
+
background: var(--bg-primary);
|
|
5235
|
+
}
|
|
5236
|
+
|
|
5237
|
+
/* ── Fleet launcher (page) ─────────────────────────────────────────────── */
|
|
5238
|
+
|
|
5239
|
+
.fleet-launcher-page,
|
|
5240
|
+
.fleet-detail-page {
|
|
5241
|
+
max-width: 760px;
|
|
5242
|
+
}
|
|
5243
|
+
|
|
5244
|
+
.fleet-launcher-projects-controls {
|
|
5245
|
+
display: flex;
|
|
5246
|
+
gap: 8px;
|
|
5247
|
+
align-items: center;
|
|
5248
|
+
margin-bottom: 4px;
|
|
5249
|
+
}
|
|
5250
|
+
|
|
5251
|
+
.fleet-launcher-projects-controls .input-project-filter {
|
|
5252
|
+
flex: 1 1 auto;
|
|
5253
|
+
}
|
|
5254
|
+
|
|
5255
|
+
/* Head-template preview rows — render below the input as a small inset
|
|
5256
|
+
panel so the per-project resolved branches feel attached to (not just
|
|
5257
|
+
stacked under) the template field. */
|
|
5258
|
+
.head-template-input {
|
|
5259
|
+
display: flex;
|
|
5260
|
+
flex-direction: column;
|
|
5261
|
+
gap: 8px;
|
|
5262
|
+
}
|
|
5263
|
+
.head-template-preview {
|
|
5264
|
+
display: flex;
|
|
5265
|
+
flex-direction: column;
|
|
5266
|
+
gap: 4px;
|
|
5267
|
+
padding: 8px 12px;
|
|
5268
|
+
background: var(--bg-primary);
|
|
5269
|
+
border: 1px solid var(--border-subtle);
|
|
5270
|
+
border-radius: var(--radius);
|
|
5271
|
+
font-size: 12px;
|
|
5272
|
+
}
|
|
5273
|
+
.head-template-preview-row {
|
|
5274
|
+
display: flex;
|
|
5275
|
+
align-items: center;
|
|
5276
|
+
gap: 8px;
|
|
5277
|
+
font-family: var(--font-mono, ui-monospace, monospace);
|
|
5278
|
+
}
|
|
5279
|
+
.head-template-preview-row .preview-arrow {
|
|
5280
|
+
color: var(--muted);
|
|
5281
|
+
}
|
|
5282
|
+
.head-template-preview-row .preview-branch {
|
|
5283
|
+
color: var(--text);
|
|
5284
|
+
}
|
|
5285
|
+
.head-template-preview-row.collision .preview-branch {
|
|
5286
|
+
color: var(--status-error);
|
|
5287
|
+
}
|
|
5288
|
+
.head-template-preview-row .collision-flag {
|
|
5289
|
+
margin-left: auto;
|
|
5290
|
+
font-size: 11px;
|
|
5291
|
+
color: var(--status-error);
|
|
5292
|
+
text-transform: uppercase;
|
|
5293
|
+
letter-spacing: 0.04em;
|
|
5294
|
+
}
|
|
5295
|
+
|
|
5296
|
+
/* Plan-mode radio container: stack the radios with breathing room and
|
|
5297
|
+
keep the divergence-warning alert visually attached to the chosen
|
|
5298
|
+
option without crowding it. */
|
|
5299
|
+
.plan-mode-radio {
|
|
5300
|
+
display: flex;
|
|
5301
|
+
flex-direction: column;
|
|
5302
|
+
gap: 10px;
|
|
5303
|
+
}
|
|
5304
|
+
.plan-mode-radio sl-radio-group::part(form-control) {
|
|
5305
|
+
display: flex;
|
|
5306
|
+
flex-direction: column;
|
|
5307
|
+
gap: 4px;
|
|
5308
|
+
}
|
|
5309
|
+
|
|
5310
|
+
/* Base-branch validation states */
|
|
5311
|
+
.base-branch-validating {
|
|
5312
|
+
display: flex;
|
|
5313
|
+
align-items: center;
|
|
5314
|
+
gap: 8px;
|
|
5315
|
+
font-size: 12px;
|
|
5316
|
+
color: var(--muted);
|
|
5317
|
+
padding: 4px 0;
|
|
5318
|
+
}
|
|
5319
|
+
.base-branch-error {
|
|
5320
|
+
font-size: 12px;
|
|
5321
|
+
color: var(--status-error);
|
|
5322
|
+
padding: 8px 12px;
|
|
5323
|
+
background: var(--bg-primary);
|
|
5324
|
+
border: 1px solid var(--status-error);
|
|
5325
|
+
border-radius: var(--radius);
|
|
5326
|
+
}
|
|
5327
|
+
.base-branch-missing-list {
|
|
5328
|
+
margin: 4px 0 0;
|
|
5329
|
+
padding-left: 20px;
|
|
5330
|
+
}
|
|
5331
|
+
|
|
5332
|
+
/* ── Fleet detail (page) ────────────────────────────────────────────────── */
|
|
5333
|
+
|
|
5334
|
+
/* The page top mirrors `runDetailView`'s overview: a clickable projects
|
|
5335
|
+
strip (analogue of the stage-timeline pills) sits above a single
|
|
5336
|
+
`.run-info-section` panel that holds the status badge + id chip + flat
|
|
5337
|
+
meta rows. No hero card — the per-project run-cards below carry the
|
|
5338
|
+
"card" affordance now. */
|
|
5339
|
+
.fleet-detail-overview {
|
|
5340
|
+
display: flex;
|
|
5341
|
+
flex-direction: column;
|
|
5342
|
+
gap: 8px;
|
|
5343
|
+
}
|
|
5344
|
+
|
|
5345
|
+
.fleet-projects-strip {
|
|
5346
|
+
display: flex;
|
|
5347
|
+
gap: 6px;
|
|
5348
|
+
width: 100%;
|
|
5349
|
+
}
|
|
5350
|
+
.fleet-projects-strip-segment {
|
|
5351
|
+
flex: 1 1 0;
|
|
5352
|
+
min-width: 0;
|
|
5353
|
+
display: inline-flex;
|
|
5354
|
+
align-items: center;
|
|
5355
|
+
justify-content: center;
|
|
5356
|
+
gap: 6px;
|
|
5357
|
+
padding: 8px 10px;
|
|
5358
|
+
border: 1px solid var(--border-subtle);
|
|
5359
|
+
border-left-width: 3px;
|
|
5360
|
+
border-radius: var(--radius-md);
|
|
5361
|
+
background: var(--bg-secondary);
|
|
5362
|
+
color: var(--fg);
|
|
5363
|
+
font-size: 12px;
|
|
5364
|
+
font-weight: 500;
|
|
5365
|
+
cursor: pointer;
|
|
5366
|
+
transition: background 120ms ease, transform 120ms ease;
|
|
5367
|
+
overflow: hidden;
|
|
5368
|
+
}
|
|
5369
|
+
.fleet-projects-strip-segment:hover {
|
|
5370
|
+
background: var(--bg-hover);
|
|
5371
|
+
}
|
|
5372
|
+
.fleet-projects-strip-segment:disabled {
|
|
5373
|
+
cursor: default;
|
|
5374
|
+
opacity: 0.75;
|
|
5375
|
+
}
|
|
5376
|
+
.fleet-projects-strip-segment.status-running { border-left-color: var(--status-running); }
|
|
5377
|
+
.fleet-projects-strip-segment.status-resuming { border-left-color: var(--status-running); }
|
|
5378
|
+
.fleet-projects-strip-segment.status-paused { border-left-color: var(--status-paused); }
|
|
5379
|
+
.fleet-projects-strip-segment.status-interrupted { border-left-color: var(--status-interrupted); }
|
|
5380
|
+
.fleet-projects-strip-segment.status-completed { border-left-color: var(--status-completed); }
|
|
5381
|
+
.fleet-projects-strip-segment.status-failed,
|
|
5382
|
+
.fleet-projects-strip-segment.status-setup-failed,
|
|
5383
|
+
.fleet-projects-strip-segment.status-unrecoverable { border-left-color: var(--status-failed); }
|
|
5384
|
+
.fleet-projects-strip-segment.status-error { border-left-color: var(--status-error); }
|
|
5385
|
+
.fleet-projects-strip-segment.status-halted { border-left-color: var(--status-paused); }
|
|
5386
|
+
.fleet-projects-strip-segment.status-pending,
|
|
5387
|
+
.fleet-projects-strip-segment.status-skipped,
|
|
5388
|
+
.fleet-projects-strip-segment.status-cancelled { border-left-color: var(--status-pending); }
|
|
5389
|
+
.fleet-projects-strip-icon {
|
|
5390
|
+
display: inline-flex;
|
|
5391
|
+
align-items: center;
|
|
5392
|
+
flex-shrink: 0;
|
|
5393
|
+
}
|
|
5394
|
+
.fleet-projects-strip-label {
|
|
5395
|
+
overflow: hidden;
|
|
5396
|
+
text-overflow: ellipsis;
|
|
5397
|
+
white-space: nowrap;
|
|
5398
|
+
min-width: 0;
|
|
5399
|
+
}
|
|
5400
|
+
|
|
5401
|
+
.fleet-info-section {
|
|
5402
|
+
/* Inherits .run-info-section padding/background — adds a couple of fleet
|
|
5403
|
+
-specific layout rules for the status row. */
|
|
5404
|
+
}
|
|
5405
|
+
.fleet-overview-status-row {
|
|
5406
|
+
display: flex;
|
|
5407
|
+
align-items: center;
|
|
5408
|
+
gap: 10px;
|
|
5409
|
+
flex-wrap: wrap;
|
|
5410
|
+
/* Match `.fleet-meta-line` so the "Fleet ID:" label renders in the
|
|
5411
|
+
same vocabulary as the Projects / Base / Started / Cost labels. */
|
|
5412
|
+
font-size: 13px;
|
|
5413
|
+
color: var(--fg);
|
|
5414
|
+
}
|
|
5415
|
+
.fleet-meta-line {
|
|
5416
|
+
display: flex;
|
|
5417
|
+
flex-wrap: wrap;
|
|
5418
|
+
gap: 4px 20px;
|
|
5419
|
+
font-size: 13px;
|
|
5420
|
+
color: var(--fg);
|
|
5421
|
+
}
|
|
5422
|
+
.fleet-meta-item {
|
|
5423
|
+
display: inline-flex;
|
|
5424
|
+
align-items: center;
|
|
5425
|
+
gap: 6px;
|
|
5426
|
+
}
|
|
5427
|
+
/* Projects row in the hero — label + name badges, same vocabulary as the
|
|
5428
|
+
fleet card's "Projects:" row. Tighter gap than the default meta line so
|
|
5429
|
+
the badges read as a contiguous list. */
|
|
5430
|
+
.fleet-meta-line-projects {
|
|
5431
|
+
align-items: center;
|
|
5432
|
+
gap: 6px;
|
|
5433
|
+
}
|
|
5434
|
+
.fleet-cost-strip {
|
|
5435
|
+
/* Reuses .pipeline-cost-strip — no overrides needed but keep the class
|
|
5436
|
+
so future tweaks can target fleet-specific copy. */
|
|
5437
|
+
}
|
|
5438
|
+
|
|
5439
|
+
/* Anchor wrapper around each project run-card so the projects strip can
|
|
5440
|
+
scroll to a specific card on click. */
|
|
5441
|
+
.fleet-project-anchor {
|
|
5442
|
+
scroll-margin-top: 80px;
|
|
5443
|
+
}
|
|
5444
|
+
|
|
5445
|
+
.fleet-detail-status-row {
|
|
5446
|
+
display: flex;
|
|
5447
|
+
align-items: center;
|
|
5448
|
+
gap: 12px;
|
|
5449
|
+
padding: 12px 16px;
|
|
5450
|
+
border: 1px solid var(--border-subtle);
|
|
5451
|
+
border-radius: var(--radius-lg);
|
|
5452
|
+
background: var(--bg-secondary);
|
|
5453
|
+
}
|
|
5454
|
+
|
|
5455
|
+
.fleet-detail-status-row .fleet-status-badge::part(base) {
|
|
5456
|
+
font-size: 12px;
|
|
5457
|
+
padding: 4px 10px;
|
|
5458
|
+
}
|
|
5459
|
+
|
|
5460
|
+
.fleet-id-chip {
|
|
5461
|
+
font-family: var(--sl-font-mono);
|
|
5462
|
+
font-size: 12px;
|
|
5463
|
+
color: var(--muted);
|
|
5464
|
+
padding: 2px 8px;
|
|
5465
|
+
background: var(--bg-tertiary);
|
|
5466
|
+
border-radius: 4px;
|
|
5467
|
+
border: 1px solid var(--border-subtle);
|
|
5468
|
+
}
|
|
5469
|
+
|
|
5470
|
+
.fleet-detail-body {
|
|
5471
|
+
margin-top: 4px;
|
|
5472
|
+
}
|
|
5473
|
+
|
|
5474
|
+
.fleet-manifest-grid {
|
|
5475
|
+
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
|
|
5476
|
+
}
|
|
5477
|
+
|
|
5478
|
+
.fleet-meta-mono {
|
|
5479
|
+
font-family: var(--sl-font-mono);
|
|
5480
|
+
font-size: 12.5px;
|
|
5481
|
+
color: var(--fg);
|
|
5482
|
+
background: var(--bg-tertiary);
|
|
5483
|
+
padding: 2px 6px;
|
|
5484
|
+
border-radius: 4px;
|
|
5485
|
+
display: inline-block;
|
|
5486
|
+
word-break: break-all;
|
|
5487
|
+
}
|
|
5488
|
+
|
|
5489
|
+
.fleet-meta-value {
|
|
5490
|
+
font-size: 13px;
|
|
5491
|
+
color: var(--fg);
|
|
5492
|
+
font-weight: 500;
|
|
5493
|
+
}
|
|
5494
|
+
|
|
5495
|
+
.fleet-wr-title {
|
|
5496
|
+
font-size: 16px;
|
|
5497
|
+
font-weight: 600;
|
|
5498
|
+
color: var(--fg);
|
|
5499
|
+
}
|
|
5500
|
+
|
|
5501
|
+
.fleet-wr-description {
|
|
5502
|
+
margin: 0;
|
|
5503
|
+
font-size: 13px;
|
|
5504
|
+
line-height: 1.55;
|
|
5505
|
+
color: var(--fg);
|
|
5506
|
+
white-space: pre-wrap;
|
|
5507
|
+
}
|
|
5508
|
+
|
|
5509
|
+
.fleet-guide-files {
|
|
5510
|
+
display: flex;
|
|
5511
|
+
flex-wrap: wrap;
|
|
5512
|
+
gap: 6px;
|
|
5513
|
+
margin-bottom: 4px;
|
|
5514
|
+
}
|
|
5515
|
+
|
|
5516
|
+
.fleet-guide-tag::part(base) {
|
|
5517
|
+
font-family: var(--sl-font-mono);
|
|
5518
|
+
}
|
|
5519
|
+
|
|
5520
|
+
.fleet-guide-actions {
|
|
5521
|
+
border-top: none;
|
|
5522
|
+
padding-top: 4px;
|
|
5523
|
+
}
|
|
5524
|
+
|
|
5525
|
+
.fleet-children-header {
|
|
5526
|
+
display: flex;
|
|
5527
|
+
align-items: baseline;
|
|
5528
|
+
justify-content: space-between;
|
|
5529
|
+
gap: 12px;
|
|
5530
|
+
}
|
|
5531
|
+
|
|
5532
|
+
.fleet-children-list {
|
|
5533
|
+
margin-top: 4px;
|
|
5534
|
+
}
|
|
5535
|
+
|
|
5536
|
+
.fleet-child-card {
|
|
5537
|
+
border-left-width: 3px;
|
|
5538
|
+
}
|
|
5539
|
+
|
|
5540
|
+
.fleet-child-card .run-card-meta code.fleet-meta-mono {
|
|
5541
|
+
background: transparent;
|
|
5542
|
+
padding: 0;
|
|
5543
|
+
font-size: 12px;
|
|
5544
|
+
}
|
|
5545
|
+
|
|
5546
|
+
.fleet-aggregate-cost-section .fleet-total-cost {
|
|
5547
|
+
font-size: 22px;
|
|
5548
|
+
font-weight: 600;
|
|
5549
|
+
color: var(--fg);
|
|
5550
|
+
font-variant-numeric: tabular-nums;
|
|
5551
|
+
}
|
|
5552
|
+
|
|
5553
|
+
.fleet-circuit-breaker-alert,
|
|
5554
|
+
.fleet-user-halt-alert {
|
|
5555
|
+
display: block;
|
|
5556
|
+
}
|
|
5557
|
+
|
|
5558
|
+
.fleet-circuit-breaker-alert .cb-trip-reason,
|
|
5559
|
+
.fleet-circuit-breaker-alert .cb-unstarted-count {
|
|
5560
|
+
display: block;
|
|
5561
|
+
margin-top: 4px;
|
|
5562
|
+
font-size: 12.5px;
|
|
5563
|
+
color: var(--fg);
|
|
5564
|
+
opacity: 0.85;
|
|
5565
|
+
}
|
|
5566
|
+
|
|
5567
|
+
.fleet-actions {
|
|
5568
|
+
display: flex;
|
|
5569
|
+
flex-wrap: wrap;
|
|
5570
|
+
gap: 10px;
|
|
5571
|
+
align-items: center;
|
|
5572
|
+
}
|
|
5573
|
+
|
|
5574
|
+
/* Run-detail "Fleet:" / "Workspace:" group line above the Branch row.
|
|
5575
|
+
Mirrors .run-branch exactly: same font-size, gap, and value weight.
|
|
5576
|
+
The only visual difference is the accent-colored anchor + underline-
|
|
5577
|
+
on-hover affordance signalling it's clickable. */
|
|
5578
|
+
.run-group {
|
|
5579
|
+
display: flex;
|
|
5580
|
+
align-items: center;
|
|
5581
|
+
gap: 6px;
|
|
5582
|
+
font-size: 13px;
|
|
5583
|
+
}
|
|
5584
|
+
|
|
5585
|
+
.run-group-link {
|
|
5586
|
+
/* Inherits font-family + font-size from .run-group → matches the plain
|
|
5587
|
+
<span class="meta-value"> on the Branch line, just colored and
|
|
5588
|
+
underlined-on-hover to read as a link. */
|
|
5589
|
+
color: var(--accent);
|
|
5590
|
+
font-weight: 600;
|
|
5591
|
+
text-decoration: none;
|
|
5592
|
+
word-break: break-all;
|
|
5593
|
+
}
|
|
5594
|
+
|
|
5595
|
+
.run-group-link:hover {
|
|
5596
|
+
text-decoration: underline;
|
|
5597
|
+
}
|
|
5598
|
+
|
|
5599
|
+
/* Run-card "Fleet:" / "Workspace:" meta-item — sized by parent
|
|
5600
|
+
.run-card-meta (12px). Same coloring as .run-group-link but no
|
|
5601
|
+
monospace. */
|
|
5602
|
+
.run-card-group-link {
|
|
5603
|
+
color: var(--accent);
|
|
5604
|
+
font-weight: 600;
|
|
5605
|
+
text-decoration: none;
|
|
5606
|
+
word-break: break-all;
|
|
5607
|
+
}
|
|
5608
|
+
|
|
5609
|
+
.run-card-group-link:hover {
|
|
5610
|
+
text-decoration: underline;
|
|
5611
|
+
}
|
|
5612
|
+
|
|
5613
|
+
/* Sidebar fleet-header clickable feedback */
|
|
5614
|
+
.fleet-header-clickable {
|
|
5615
|
+
transition: background-color var(--transition-fast);
|
|
5616
|
+
}
|
|
5617
|
+
|
|
5618
|
+
.fleet-header-clickable:hover {
|
|
5619
|
+
background-color: color-mix(in srgb, var(--accent) 6%, transparent);
|
|
5620
|
+
}
|
|
5621
|
+
|
|
5622
|
+
/* Fleet list view (route: /#/fleet-runs) — one `fleet-card` per fleet.
|
|
5623
|
+
No wrapping border / shared background; each card carries its own
|
|
5624
|
+
chrome plus the layered stack-of-cards shadow. Gap matches the
|
|
5625
|
+
gap between pipeline cards in run-list for visual consistency. */
|
|
5626
|
+
.fleet-list {
|
|
5627
|
+
display: flex;
|
|
5628
|
+
flex-direction: column;
|
|
5629
|
+
gap: 16px;
|
|
5630
|
+
}
|
|
5631
|
+
|
|
5632
|
+
.fleet-list-row {
|
|
5633
|
+
display: flex;
|
|
5634
|
+
align-items: center;
|
|
5635
|
+
gap: 12px;
|
|
5636
|
+
padding: 12px 16px;
|
|
5637
|
+
border-bottom: 1px solid var(--border-subtle);
|
|
5638
|
+
cursor: pointer;
|
|
5639
|
+
transition: background-color var(--transition-fast);
|
|
5640
|
+
}
|
|
5641
|
+
|
|
5642
|
+
.fleet-list-row:last-child {
|
|
5643
|
+
border-bottom: none;
|
|
5644
|
+
}
|
|
5645
|
+
|
|
5646
|
+
.fleet-list-row:hover {
|
|
5647
|
+
background-color: color-mix(in srgb, var(--accent) 6%, transparent);
|
|
5648
|
+
}
|
|
5649
|
+
|
|
5650
|
+
.fleet-list-row-title {
|
|
5651
|
+
font-size: 14px;
|
|
5652
|
+
font-weight: 600;
|
|
5653
|
+
color: var(--fg);
|
|
5654
|
+
flex: 1 1 auto;
|
|
5655
|
+
min-width: 0;
|
|
5656
|
+
overflow: hidden;
|
|
5657
|
+
text-overflow: ellipsis;
|
|
5658
|
+
white-space: nowrap;
|
|
5659
|
+
}
|
|
5660
|
+
|
|
5661
|
+
.fleet-list-row-badge {
|
|
5662
|
+
flex-shrink: 0;
|
|
5663
|
+
}
|
|
5664
|
+
|
|
5665
|
+
.fleet-list-row-meta {
|
|
5666
|
+
font-size: 12px;
|
|
5667
|
+
color: var(--muted);
|
|
5668
|
+
flex-shrink: 0;
|
|
5669
|
+
}
|
|
5670
|
+
|
|
5671
|
+
.fleet-list-row-id {
|
|
5672
|
+
font-family: var(--sl-font-mono);
|
|
5673
|
+
font-size: 11.5px;
|
|
5674
|
+
color: var(--muted);
|
|
5675
|
+
background: var(--bg-tertiary);
|
|
5676
|
+
padding: 2px 8px;
|
|
5677
|
+
border-radius: 4px;
|
|
5678
|
+
flex-shrink: 0;
|
|
5679
|
+
}
|
|
5680
|
+
|
|
5681
|
+
.fleet-list-loading,
|
|
5682
|
+
.fleet-list-empty {
|
|
5683
|
+
padding: 24px;
|
|
5684
|
+
text-align: center;
|
|
5685
|
+
color: var(--muted);
|
|
5686
|
+
display: flex;
|
|
5687
|
+
flex-direction: column;
|
|
5688
|
+
align-items: center;
|
|
5689
|
+
gap: 12px;
|
|
5690
|
+
}
|
|
5691
|
+
|
|
5692
|
+
.fleet-detail-empty {
|
|
5693
|
+
padding: 64px 24px;
|
|
5694
|
+
text-align: center;
|
|
5695
|
+
color: var(--muted);
|
|
5696
|
+
display: flex;
|
|
5697
|
+
flex-direction: column;
|
|
5698
|
+
align-items: center;
|
|
5699
|
+
gap: 12px;
|
|
5700
|
+
max-width: 540px;
|
|
5701
|
+
margin: 0 auto;
|
|
5702
|
+
}
|
|
5703
|
+
|
|
5704
|
+
.fleet-detail-empty sl-icon {
|
|
5705
|
+
font-size: 48px;
|
|
5706
|
+
color: var(--muted);
|
|
5707
|
+
opacity: 0.6;
|
|
5708
|
+
}
|
|
5709
|
+
|
|
5710
|
+
.fleet-detail-empty h2 {
|
|
5711
|
+
margin: 8px 0 0 0;
|
|
5712
|
+
font-size: 18px;
|
|
5713
|
+
color: var(--fg);
|
|
5714
|
+
}
|
|
5715
|
+
|
|
5716
|
+
.fleet-detail-empty p {
|
|
5717
|
+
margin: 0;
|
|
5718
|
+
line-height: 1.5;
|
|
5719
|
+
}
|
|
5720
|
+
|
|
5721
|
+
.fleet-detail-empty code {
|
|
5722
|
+
font-size: 12px;
|
|
5723
|
+
background: var(--bg-2, var(--border));
|
|
5724
|
+
padding: 1px 6px;
|
|
5725
|
+
border-radius: 4px;
|
|
5726
|
+
}
|
|
5727
|
+
|
|
5728
|
+
.fleet-detail-empty-hint {
|
|
5729
|
+
font-size: 13px;
|
|
5730
|
+
opacity: 0.85;
|
|
5731
|
+
}
|
|
5732
|
+
|
|
5733
|
+
.fleet-detail-empty-hint a {
|
|
5734
|
+
color: var(--accent, var(--fg));
|
|
5735
|
+
}
|
|
5736
|
+
|
|
5737
|
+
/* --- Workspace: tier styling --- */
|
|
5738
|
+
|
|
5739
|
+
.workspace-card-tiers {
|
|
5740
|
+
display: flex;
|
|
5741
|
+
flex-direction: column;
|
|
5742
|
+
gap: 6px;
|
|
5743
|
+
margin-top: 8px;
|
|
5744
|
+
}
|
|
5745
|
+
|
|
5746
|
+
.workspace-tier-row {
|
|
5747
|
+
display: flex;
|
|
5748
|
+
align-items: center;
|
|
5749
|
+
gap: 8px;
|
|
5750
|
+
}
|
|
5751
|
+
|
|
5752
|
+
.tier-label {
|
|
5753
|
+
font-size: 11px;
|
|
5754
|
+
font-weight: 600;
|
|
5755
|
+
color: var(--muted);
|
|
5756
|
+
text-transform: uppercase;
|
|
5757
|
+
letter-spacing: 0.05em;
|
|
5758
|
+
min-width: 60px;
|
|
5759
|
+
flex-shrink: 0;
|
|
5760
|
+
}
|
|
5761
|
+
|
|
5762
|
+
.tier-status {
|
|
5763
|
+
display: inline-flex;
|
|
5764
|
+
align-items: center;
|
|
5765
|
+
flex-shrink: 0;
|
|
5766
|
+
}
|
|
5767
|
+
|
|
5768
|
+
.tier-children {
|
|
5769
|
+
display: flex;
|
|
5770
|
+
flex-wrap: wrap;
|
|
5771
|
+
gap: 4px;
|
|
5772
|
+
}
|
|
5773
|
+
|
|
5774
|
+
.tier-child {
|
|
5775
|
+
font-size: 12px;
|
|
5776
|
+
padding: 2px 8px;
|
|
5777
|
+
border-radius: 4px;
|
|
5778
|
+
background: var(--bg-tertiary);
|
|
5779
|
+
border: 1px solid var(--border);
|
|
5780
|
+
}
|
|
5781
|
+
|
|
5782
|
+
/* --- Workspace: DAG graph --- */
|
|
5783
|
+
|
|
5784
|
+
.dag-preview {
|
|
5785
|
+
overflow-x: auto;
|
|
5786
|
+
border: 1px solid var(--border);
|
|
5787
|
+
border-radius: var(--radius);
|
|
5788
|
+
background: var(--bg-secondary);
|
|
5789
|
+
padding: 16px;
|
|
5790
|
+
}
|
|
5791
|
+
|
|
5792
|
+
.dag-preview svg {
|
|
5793
|
+
display: block;
|
|
5794
|
+
}
|
|
5795
|
+
|
|
5796
|
+
.workspace-dag-panel {
|
|
5797
|
+
display: flex;
|
|
5798
|
+
flex-direction: column;
|
|
5799
|
+
gap: 8px;
|
|
5800
|
+
}
|
|
5801
|
+
|
|
5802
|
+
|
|
5803
|
+
|
|
5804
|
+
.workspace-dag-svg {
|
|
5805
|
+
overflow-x: auto;
|
|
5806
|
+
}
|
|
5807
|
+
|
|
5808
|
+
/* --- Workspace run card --- */
|
|
5809
|
+
|
|
5810
|
+
/* --- Plan stage artifact strip (run-detail) --- */
|
|
5811
|
+
|
|
5812
|
+
.plan-artifact-strip {
|
|
5813
|
+
display: flex;
|
|
5814
|
+
align-items: center;
|
|
5815
|
+
flex-wrap: wrap;
|
|
5816
|
+
gap: 8px;
|
|
5817
|
+
margin: 10px 0 4px;
|
|
5818
|
+
}
|
|
5819
|
+
.plan-artifact-strip .plan-file-chip {
|
|
5820
|
+
font-family: var(--font-mono);
|
|
5821
|
+
font-size: 12px;
|
|
5822
|
+
color: var(--fg-muted);
|
|
5823
|
+
background: var(--bg-secondary);
|
|
5824
|
+
padding: 2px 6px;
|
|
5825
|
+
border-radius: 4px;
|
|
5826
|
+
max-width: 360px;
|
|
5827
|
+
overflow: hidden;
|
|
5828
|
+
text-overflow: ellipsis;
|
|
5829
|
+
white-space: nowrap;
|
|
5830
|
+
}
|
|
5831
|
+
.plan-loading,
|
|
5832
|
+
.plan-error {
|
|
5833
|
+
display: flex;
|
|
5834
|
+
align-items: center;
|
|
5835
|
+
gap: 8px;
|
|
5836
|
+
padding: 20px;
|
|
5837
|
+
color: var(--fg-muted);
|
|
5838
|
+
}
|
|
5839
|
+
|
|
5840
|
+
/* --- sl-dialog: wider markdown-body dialogs (plan, guide) --- */
|
|
5841
|
+
|
|
5842
|
+
sl-dialog.markdown-dialog::part(panel) {
|
|
5843
|
+
/* Default sl-dialog is ~31rem wide — too narrow for prose with code
|
|
5844
|
+
blocks. Cap at 90vw so it stays comfortable on small viewports. */
|
|
5845
|
+
width: min(960px, 90vw);
|
|
5846
|
+
max-width: min(960px, 90vw);
|
|
5847
|
+
}
|
|
5848
|
+
sl-dialog.markdown-dialog::part(body) {
|
|
5849
|
+
/* Give the body breathing room and let it scroll vertically instead
|
|
5850
|
+
of the whole dialog growing without bound. */
|
|
5851
|
+
max-height: 70vh;
|
|
5852
|
+
overflow: auto;
|
|
5853
|
+
}
|
|
5854
|
+
|
|
5855
|
+
/* --- Markdown body styling (used by guide-content + workspace-plan-content) --- */
|
|
5856
|
+
|
|
5857
|
+
.markdown-body {
|
|
5858
|
+
font-family: var(--sl-font-sans, system-ui, sans-serif);
|
|
5859
|
+
font-size: 14px;
|
|
5860
|
+
line-height: 1.55;
|
|
5861
|
+
color: var(--fg);
|
|
5862
|
+
}
|
|
5863
|
+
.markdown-body h1,
|
|
5864
|
+
.markdown-body h2,
|
|
5865
|
+
.markdown-body h3,
|
|
5866
|
+
.markdown-body h4 {
|
|
5867
|
+
margin: 1.2em 0 0.5em;
|
|
5868
|
+
line-height: 1.25;
|
|
5869
|
+
font-weight: 600;
|
|
5870
|
+
}
|
|
5871
|
+
.markdown-body h1 { font-size: 1.5em; }
|
|
5872
|
+
.markdown-body h2 { font-size: 1.25em; border-bottom: 1px solid var(--border-subtle); padding-bottom: 4px; }
|
|
5873
|
+
.markdown-body h3 { font-size: 1.1em; }
|
|
5874
|
+
.markdown-body p { margin: 0.6em 0; }
|
|
5875
|
+
.markdown-body ul,
|
|
5876
|
+
.markdown-body ol { margin: 0.6em 0; padding-left: 1.5em; }
|
|
5877
|
+
.markdown-body li { margin: 0.25em 0; }
|
|
5878
|
+
.markdown-body code {
|
|
5879
|
+
font-family: var(--font-mono);
|
|
5880
|
+
font-size: 0.9em;
|
|
5881
|
+
background: var(--bg-secondary);
|
|
5882
|
+
padding: 1px 5px;
|
|
5883
|
+
border-radius: 3px;
|
|
5884
|
+
}
|
|
5885
|
+
.markdown-body pre {
|
|
5886
|
+
background: var(--bg-secondary);
|
|
5887
|
+
border: 1px solid var(--border-subtle);
|
|
5888
|
+
border-radius: 6px;
|
|
5889
|
+
padding: 10px 12px;
|
|
5890
|
+
overflow-x: auto;
|
|
5891
|
+
font-size: 12.5px;
|
|
5892
|
+
}
|
|
5893
|
+
.markdown-body pre code {
|
|
5894
|
+
background: transparent;
|
|
5895
|
+
padding: 0;
|
|
5896
|
+
border-radius: 0;
|
|
5897
|
+
}
|
|
5898
|
+
.markdown-body blockquote {
|
|
5899
|
+
border-left: 3px solid var(--border);
|
|
5900
|
+
padding: 4px 12px;
|
|
5901
|
+
margin: 0.6em 0;
|
|
5902
|
+
color: var(--fg-muted);
|
|
5903
|
+
}
|
|
5904
|
+
.markdown-body a { color: var(--accent); }
|
|
5905
|
+
.markdown-body table {
|
|
5906
|
+
border-collapse: collapse;
|
|
5907
|
+
margin: 0.8em 0;
|
|
5908
|
+
}
|
|
5909
|
+
.markdown-body th,
|
|
5910
|
+
.markdown-body td {
|
|
5911
|
+
border: 1px solid var(--border-subtle);
|
|
5912
|
+
padding: 4px 8px;
|
|
5913
|
+
text-align: left;
|
|
5914
|
+
}
|
|
5915
|
+
|
|
5916
|
+
.workspace-run-card .workspace-card-root,
|
|
5917
|
+
.workspace-run-card .workspace-card-name {
|
|
5918
|
+
font-family: var(--font-mono);
|
|
5919
|
+
font-size: 12px;
|
|
5920
|
+
color: var(--fg-muted);
|
|
5921
|
+
}
|
|
5922
|
+
|
|
5923
|
+
/* --- Workspace forms: external-repo picker --- */
|
|
5924
|
+
|
|
5925
|
+
.repo-checklist-actions {
|
|
5926
|
+
display: flex;
|
|
5927
|
+
align-items: center;
|
|
5928
|
+
gap: 12px;
|
|
5929
|
+
margin-top: 12px;
|
|
5930
|
+
flex-wrap: wrap;
|
|
5931
|
+
}
|
|
5932
|
+
.ws-external-tag {
|
|
5933
|
+
margin-left: 8px;
|
|
5934
|
+
}
|
|
5935
|
+
|
|
5936
|
+
/* --- Workspace forms: Dependency Graph label --- */
|
|
5937
|
+
|
|
5938
|
+
.dag-preview-block {
|
|
5939
|
+
margin-top: 16px;
|
|
5940
|
+
}
|
|
5941
|
+
.dag-preview-label {
|
|
5942
|
+
display: block;
|
|
5943
|
+
margin-bottom: 8px;
|
|
5944
|
+
}
|
|
5945
|
+
|
|
5946
|
+
/* --- Workspace edit: scan-for-additions status + Available tag --- */
|
|
5947
|
+
|
|
5948
|
+
.ws-edit-scan-status {
|
|
5949
|
+
display: flex;
|
|
5950
|
+
align-items: center;
|
|
5951
|
+
gap: 8px;
|
|
5952
|
+
font-size: 13px;
|
|
5953
|
+
color: var(--fg-muted);
|
|
5954
|
+
margin-bottom: 12px;
|
|
5955
|
+
}
|
|
5956
|
+
.ws-edit-scan-error {
|
|
5957
|
+
margin-bottom: 12px;
|
|
5958
|
+
}
|
|
5959
|
+
.ws-edit-new-tag {
|
|
5960
|
+
margin-left: 8px;
|
|
5961
|
+
}
|
|
5962
|
+
|
|
5963
|
+
/* --- Workspace create: Parent Directory row --- */
|
|
5964
|
+
|
|
5965
|
+
.parent-dir-row {
|
|
5966
|
+
display: flex;
|
|
5967
|
+
gap: 8px;
|
|
5968
|
+
align-items: stretch;
|
|
5969
|
+
}
|
|
5970
|
+
.parent-dir-row .input-parent-dir {
|
|
5971
|
+
flex: 1;
|
|
5972
|
+
}
|
|
5973
|
+
.parent-dir-suggestions {
|
|
5974
|
+
margin-top: 8px;
|
|
5975
|
+
border: 1px solid var(--border);
|
|
5976
|
+
border-radius: 6px;
|
|
5977
|
+
background: var(--bg);
|
|
5978
|
+
overflow: hidden;
|
|
5979
|
+
}
|
|
5980
|
+
.parent-dir-suggestions-label {
|
|
5981
|
+
padding: 6px 12px;
|
|
5982
|
+
font-size: 11px;
|
|
5983
|
+
text-transform: uppercase;
|
|
5984
|
+
letter-spacing: 0.04em;
|
|
5985
|
+
color: var(--fg-muted);
|
|
5986
|
+
background: var(--bg-secondary);
|
|
5987
|
+
border-bottom: 1px solid var(--border-subtle);
|
|
5988
|
+
}
|
|
5989
|
+
.parent-dir-suggestion-item {
|
|
5990
|
+
display: flex;
|
|
5991
|
+
align-items: center;
|
|
5992
|
+
gap: 8px;
|
|
5993
|
+
width: 100%;
|
|
5994
|
+
padding: 8px 12px;
|
|
5995
|
+
background: transparent;
|
|
5996
|
+
border: none;
|
|
5997
|
+
border-bottom: 1px solid var(--border-subtle);
|
|
5998
|
+
cursor: pointer;
|
|
5999
|
+
font-family: var(--font-mono);
|
|
6000
|
+
font-size: 13px;
|
|
6001
|
+
color: var(--fg);
|
|
6002
|
+
text-align: left;
|
|
6003
|
+
}
|
|
6004
|
+
.parent-dir-suggestion-item:last-child {
|
|
6005
|
+
border-bottom: none;
|
|
6006
|
+
}
|
|
6007
|
+
.parent-dir-suggestion-item:hover {
|
|
6008
|
+
background: var(--bg-hover);
|
|
6009
|
+
}
|
|
6010
|
+
.parent-dir-suggestion-item svg {
|
|
6011
|
+
flex-shrink: 0;
|
|
6012
|
+
color: var(--fg-muted);
|
|
6013
|
+
}
|
|
6014
|
+
|
|
6015
|
+
/* --- Configuration → Workspaces list --- */
|
|
6016
|
+
|
|
6017
|
+
.workspaces-config-empty {
|
|
6018
|
+
display: flex;
|
|
6019
|
+
flex-direction: column;
|
|
6020
|
+
align-items: center;
|
|
6021
|
+
justify-content: center;
|
|
6022
|
+
text-align: center;
|
|
6023
|
+
padding: 64px 24px;
|
|
6024
|
+
gap: 12px;
|
|
6025
|
+
color: var(--fg-muted);
|
|
6026
|
+
}
|
|
6027
|
+
.workspaces-config-empty .empty-icon {
|
|
6028
|
+
color: var(--fg-muted);
|
|
6029
|
+
opacity: 0.5;
|
|
6030
|
+
margin-bottom: 8px;
|
|
6031
|
+
}
|
|
6032
|
+
.workspaces-config-empty h3 {
|
|
6033
|
+
margin: 0;
|
|
6034
|
+
color: var(--fg);
|
|
6035
|
+
}
|
|
6036
|
+
.workspaces-config-empty p {
|
|
6037
|
+
max-width: 480px;
|
|
6038
|
+
margin: 0 0 12px;
|
|
6039
|
+
line-height: 1.5;
|
|
6040
|
+
}
|
|
6041
|
+
|
|
6042
|
+
.workspaces-config-table {
|
|
6043
|
+
padding: 16px;
|
|
6044
|
+
overflow-x: auto;
|
|
6045
|
+
}
|
|
6046
|
+
.workspaces-config-table table {
|
|
6047
|
+
width: 100%;
|
|
6048
|
+
border-collapse: collapse;
|
|
6049
|
+
font-size: 14px;
|
|
6050
|
+
}
|
|
6051
|
+
.workspaces-config-table thead th {
|
|
6052
|
+
text-align: left;
|
|
6053
|
+
font-weight: 600;
|
|
6054
|
+
padding: 8px 12px;
|
|
6055
|
+
border-bottom: 1px solid var(--border);
|
|
6056
|
+
color: var(--fg-muted);
|
|
6057
|
+
text-transform: uppercase;
|
|
6058
|
+
font-size: 11px;
|
|
6059
|
+
letter-spacing: 0.04em;
|
|
6060
|
+
}
|
|
6061
|
+
.workspaces-config-table tbody td {
|
|
6062
|
+
padding: 12px;
|
|
6063
|
+
border-bottom: 1px solid var(--border);
|
|
6064
|
+
vertical-align: middle;
|
|
6065
|
+
}
|
|
6066
|
+
.workspaces-config-table tbody tr:hover {
|
|
6067
|
+
background: var(--bg-hover);
|
|
6068
|
+
}
|
|
6069
|
+
.workspaces-config-table .ws-name strong {
|
|
6070
|
+
font-weight: 600;
|
|
6071
|
+
}
|
|
6072
|
+
.workspaces-config-table .ws-path code,
|
|
6073
|
+
.workspaces-config-table .ws-umbrella {
|
|
6074
|
+
font-family: var(--font-mono);
|
|
6075
|
+
font-size: 12px;
|
|
6076
|
+
color: var(--fg-muted);
|
|
6077
|
+
}
|
|
6078
|
+
.workspaces-config-table .ws-tiers {
|
|
6079
|
+
color: var(--fg-muted);
|
|
6080
|
+
font-size: 12px;
|
|
6081
|
+
margin-left: 4px;
|
|
6082
|
+
}
|
|
6083
|
+
.workspaces-config-table .ws-dash {
|
|
6084
|
+
color: var(--fg-muted);
|
|
6085
|
+
opacity: 0.5;
|
|
6086
|
+
}
|
|
6087
|
+
.workspaces-config-table .actions-col {
|
|
6088
|
+
text-align: right;
|
|
6089
|
+
}
|
|
6090
|
+
.workspaces-config-table .ws-actions {
|
|
6091
|
+
display: flex;
|
|
6092
|
+
gap: 4px;
|
|
6093
|
+
justify-content: flex-end;
|
|
6094
|
+
}
|
|
6095
|
+
.ws-action-btn {
|
|
6096
|
+
background: transparent;
|
|
6097
|
+
border: 1px solid var(--border);
|
|
6098
|
+
border-radius: 4px;
|
|
6099
|
+
padding: 4px 6px;
|
|
6100
|
+
cursor: pointer;
|
|
6101
|
+
color: var(--fg);
|
|
6102
|
+
display: inline-flex;
|
|
6103
|
+
align-items: center;
|
|
6104
|
+
justify-content: center;
|
|
6105
|
+
}
|
|
6106
|
+
.ws-action-btn:hover {
|
|
6107
|
+
background: var(--bg-hover);
|
|
6108
|
+
}
|
|
6109
|
+
.ws-action-btn--danger:hover {
|
|
6110
|
+
background: rgba(220, 38, 38, 0.1);
|
|
6111
|
+
color: rgb(220, 38, 38);
|
|
6112
|
+
border-color: rgba(220, 38, 38, 0.4);
|
|
6113
|
+
}
|
|
6114
|
+
|
|
6115
|
+
.dag-graph-node rect {
|
|
6116
|
+
rx: 6;
|
|
6117
|
+
fill: var(--bg);
|
|
6118
|
+
stroke: var(--border);
|
|
6119
|
+
stroke-width: 1.5;
|
|
6120
|
+
}
|
|
6121
|
+
|
|
6122
|
+
.dag-graph-node text {
|
|
6123
|
+
font-size: 12px;
|
|
6124
|
+
font-family: var(--sl-font-sans);
|
|
6125
|
+
fill: var(--fg);
|
|
6126
|
+
}
|
|
6127
|
+
|
|
6128
|
+
.dag-graph-edge {
|
|
6129
|
+
fill: none;
|
|
6130
|
+
stroke: var(--border);
|
|
6131
|
+
stroke-width: 2;
|
|
6132
|
+
}
|
|
6133
|
+
|
|
6134
|
+
.dag-graph-node--status-pending rect { stroke: var(--status-pending); }
|
|
6135
|
+
.dag-graph-node--status-running rect { stroke: var(--status-running); }
|
|
6136
|
+
.dag-graph-node--status-completed rect { stroke: var(--status-completed); }
|
|
6137
|
+
.dag-graph-node--status-failed rect { stroke: var(--status-failed); }
|
|
6138
|
+
.dag-graph-node--status-paused rect { stroke: var(--status-paused); }
|
|
6139
|
+
.dag-graph-node--status-blocked rect { stroke: var(--status-blocked); }
|
|
6140
|
+
.dag-graph-node--status-planning rect { stroke: var(--status-running); }
|
|
6141
|
+
.dag-graph-node--status-integration-testing rect { stroke: var(--status-running); }
|
|
6142
|
+
.dag-graph-node--status-integration-failed rect { stroke: var(--status-failed); }
|
|
6143
|
+
|
|
6144
|
+
/* --- Workspace: conflict icon --- */
|
|
6145
|
+
|
|
6146
|
+
.conflict-icon {
|
|
6147
|
+
color: var(--status-blocked);
|
|
6148
|
+
}
|