@arbidocs/blocks 0.4.77 → 0.4.78

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/dist/agents/index.cjs +289 -277
  2. package/dist/agents/index.js +5 -5
  3. package/dist/agents/tasks/WorkflowThreadStrip.d.ts +9 -4
  4. package/dist/agents/workflows/StepBarFrame.d.ts +75 -0
  5. package/dist/agents/workflows/WorkflowRunner.d.ts +5 -1
  6. package/dist/agents/workflows/WorkflowStepBar.d.ts +9 -11
  7. package/dist/agents/workflows/index.d.ts +2 -0
  8. package/dist/agents/workflows/stepWindow.d.ts +59 -0
  9. package/dist/chat/ChatPage.d.ts +1 -1
  10. package/dist/chat/chat-page-types.d.ts +5 -0
  11. package/dist/chat/index.cjs +124 -124
  12. package/dist/chat/index.js +2 -2
  13. package/dist/{chunk-HEVVT6IT.js → chunk-5OC5CGYX.js} +128 -124
  14. package/dist/chunk-5OC5CGYX.js.map +1 -0
  15. package/dist/chunk-CWAZNXC5.js +441 -0
  16. package/dist/chunk-CWAZNXC5.js.map +1 -0
  17. package/dist/{chunk-NIP5BOP7.js → chunk-EWSEQEPL.js} +5 -4
  18. package/dist/chunk-EWSEQEPL.js.map +1 -0
  19. package/dist/{chunk-UEU23PTW.js → chunk-ICBAFX5B.js} +3 -3
  20. package/dist/{chunk-UEU23PTW.js.map → chunk-ICBAFX5B.js.map} +1 -1
  21. package/dist/{chunk-EKIUMNCN.cjs → chunk-IF6VAYIA.cjs} +5 -5
  22. package/dist/{chunk-EKIUMNCN.cjs.map → chunk-IF6VAYIA.cjs.map} +1 -1
  23. package/dist/chunk-MLAHDAN5.cjs +450 -0
  24. package/dist/chunk-MLAHDAN5.cjs.map +1 -0
  25. package/dist/{chunk-HOD6OM7L.cjs → chunk-MP6FK43E.cjs} +5 -4
  26. package/dist/chunk-MP6FK43E.cjs.map +1 -0
  27. package/dist/{chunk-JFUN4D7D.cjs → chunk-SSDISIDW.cjs} +152 -148
  28. package/dist/chunk-SSDISIDW.cjs.map +1 -0
  29. package/dist/{chunk-3XR3IEGU.cjs → chunk-VFIZYSZB.cjs} +573 -168
  30. package/dist/chunk-VFIZYSZB.cjs.map +1 -0
  31. package/dist/{chunk-34UW6XUQ.js → chunk-WXRCMIAE.js} +567 -172
  32. package/dist/chunk-WXRCMIAE.js.map +1 -0
  33. package/dist/{chunk-GTXOV7IJ.cjs → chunk-XMBYDLZQ.cjs} +4 -4
  34. package/dist/{chunk-GTXOV7IJ.cjs.map → chunk-XMBYDLZQ.cjs.map} +1 -1
  35. package/dist/{chunk-OEM5ARVM.js → chunk-XQDM6T6C.js} +3 -3
  36. package/dist/{chunk-OEM5ARVM.js.map → chunk-XQDM6T6C.js.map} +1 -1
  37. package/dist/connect/index.cjs +209 -53
  38. package/dist/connect/index.cjs.map +1 -1
  39. package/dist/connect/index.d.ts +2 -0
  40. package/dist/connect/index.js +190 -36
  41. package/dist/connect/index.js.map +1 -1
  42. package/dist/connection/ConnectedTagMatrix.d.ts +20 -0
  43. package/dist/connection/ConnectedWorkflowRunner.d.ts +13 -1
  44. package/dist/connection/WorkflowRunThread.d.ts +21 -0
  45. package/dist/facts/index.cjs +1 -1
  46. package/dist/facts/index.js +1 -1
  47. package/dist/files/index.cjs +1 -1
  48. package/dist/files/index.js +1 -1
  49. package/dist/home/index.cjs +1 -1
  50. package/dist/home/index.js +1 -1
  51. package/dist/index.cjs +492 -447
  52. package/dist/index.cjs.map +1 -1
  53. package/dist/index.d.ts +1 -0
  54. package/dist/index.js +9 -8
  55. package/dist/index.js.map +1 -1
  56. package/dist/shell/index.cjs +1 -1
  57. package/dist/shell/index.js +1 -1
  58. package/dist/studio/index.cjs +4 -4
  59. package/dist/studio/index.js +3 -3
  60. package/dist/tags/TagMatrix.d.ts +64 -0
  61. package/dist/tags/index.d.ts +3 -0
  62. package/dist/tags/tagMatrixModel.d.ts +39 -0
  63. package/dist/workflow-canvas/index.cjs +48 -48
  64. package/dist/workflow-canvas/index.js +5 -5
  65. package/package.json +4 -4
  66. package/dist/chunk-34UW6XUQ.js.map +0 -1
  67. package/dist/chunk-3XR3IEGU.cjs.map +0 -1
  68. package/dist/chunk-HEVVT6IT.js.map +0 -1
  69. package/dist/chunk-HOD6OM7L.cjs.map +0 -1
  70. package/dist/chunk-JFUN4D7D.cjs.map +0 -1
  71. package/dist/chunk-NIP5BOP7.js.map +0 -1
@@ -1,12 +1,12 @@
1
1
  "use client";
2
- import { UploadDropzone } from './chunk-EVUEIBNU.js';
3
2
  import { FoldSection } from './chunk-XD2M6LIG.js';
3
+ import { UploadDropzone } from './chunk-EVUEIBNU.js';
4
4
  import { useElementSize } from './chunk-HOXKR26S.js';
5
5
  import { testIdOr, prefixedTestId } from './chunk-7F6CBP3Z.js';
6
- import { useState, useRef, useEffect, useCallback, useMemo, useLayoutEffect } from 'react';
7
- import { cn, Button, Textarea, Card, Label, Input, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, Switch } from '@arbidocs/react/ui';
6
+ import { useState, useRef, useEffect, useCallback, useMemo } from 'react';
7
+ import { cn, Popover, PopoverTrigger, PopoverContent, Button, Textarea, Card, Label, Input, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, Switch } from '@arbidocs/react/ui';
8
8
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
9
- import { UserRound, CornerUpLeft, ShieldCheck, MessageSquare, Check, Hourglass, Clock, PenLine, X, ExternalLink, Mail, Table2, CheckCircle2, ArrowLeft, Loader2, ArrowRight, RotateCw, GitBranch, FileText, AlertTriangle, MinusCircle } from 'lucide-react';
9
+ import { Check, Loader2, Hourglass, AlertTriangle, MinusCircle, UserRound, CornerUpLeft, ShieldCheck, MessageSquare, Clock, PenLine, X, ExternalLink, Mail, Table2, CheckCircle2, ArrowLeft, ArrowRight, RotateCw, GitBranch, ChevronLeft, ChevronRight, FileText } from 'lucide-react';
10
10
 
11
11
  // src/agents/workflows/types.ts
12
12
  var EMPTY_WORKFLOW_SCOPE = { folders: [], labels: [] };
@@ -1269,6 +1269,431 @@ function useWorkflowView(options) {
1269
1269
  }
1270
1270
  };
1271
1271
  }
1272
+
1273
+ // src/agents/workflows/stepWindow.ts
1274
+ var ATTENTION = ["waiting", "failed", "ready"];
1275
+ function activeStepId(levels, phaseOf) {
1276
+ const all = levels.flat();
1277
+ for (const phase of ["running", ...ATTENTION]) {
1278
+ const hit = all.find((s) => phaseOf(s.id) === phase);
1279
+ if (hit) return hit.id;
1280
+ }
1281
+ return all[all.length - 1]?.id;
1282
+ }
1283
+ function primaryOf(steps, phaseOf, current) {
1284
+ return steps.find((s) => phaseOf(s.id) === "running") ?? steps.find((s) => s.id === current) ?? ATTENTION.map((p) => steps.find((s) => phaseOf(s.id) === p)).find(Boolean) ?? steps[0];
1285
+ }
1286
+ function stepWindow({
1287
+ levels: raw,
1288
+ phaseOf,
1289
+ current,
1290
+ start: requested,
1291
+ span = 3
1292
+ }) {
1293
+ const levelsIn = raw.filter((l) => l.length > 0);
1294
+ const known = current && levelsIn.some((l) => l.some((s) => s.id === current));
1295
+ const at = known ? current : activeStepId(levelsIn, phaseOf);
1296
+ const currentLevel = Math.max(
1297
+ 0,
1298
+ levelsIn.findIndex((l) => l.some((s) => s.id === at))
1299
+ );
1300
+ const n = levelsIn.length;
1301
+ const size = Math.max(1, Math.min(span, n));
1302
+ const maxStart = Math.max(0, n - size);
1303
+ const auto = currentLevel - (size >= 3 ? 1 : 0);
1304
+ const start = Math.min(maxStart, Math.max(0, requested ?? auto));
1305
+ const end = start + size;
1306
+ const levels = levelsIn.map((steps, index) => {
1307
+ const primary = primaryOf(steps, phaseOf, at);
1308
+ return {
1309
+ index,
1310
+ steps,
1311
+ primary,
1312
+ others: steps.filter((s) => s !== primary),
1313
+ role: index === currentLevel ? "current" : index === currentLevel - 1 ? "previous" : index === currentLevel + 1 ? "next" : "other"
1314
+ };
1315
+ });
1316
+ const visible = levels.slice(start, end);
1317
+ const count = (ls) => ls.reduce((sum, l) => sum + l.steps.length, 0);
1318
+ const shown = new Set(visible.map((l) => l.primary.id));
1319
+ const all = levelsIn.flat();
1320
+ return {
1321
+ levels,
1322
+ visible,
1323
+ start,
1324
+ end,
1325
+ currentLevel,
1326
+ hiddenBefore: count(levels.slice(0, start)),
1327
+ hiddenAfter: count(levels.slice(end)),
1328
+ canBack: start > 0,
1329
+ canForward: end < n,
1330
+ runningHidden: all.filter((s) => phaseOf(s.id) === "running" && !shown.has(s.id)),
1331
+ position: Math.max(1, all.findIndex((s) => s.id === at) + 1),
1332
+ total: all.length
1333
+ };
1334
+ }
1335
+ function PhaseMark({ phase, icon }) {
1336
+ if (phase === "done") return /* @__PURE__ */ jsx(Check, { className: "size-3.5 shrink-0" });
1337
+ if (phase === "running") return /* @__PURE__ */ jsx(Loader2, { className: "size-3.5 shrink-0 animate-spin" });
1338
+ if (phase === "waiting") return /* @__PURE__ */ jsx(Hourglass, { className: "size-3.5 shrink-0" });
1339
+ if (phase === "failed") return /* @__PURE__ */ jsx(AlertTriangle, { className: "size-3.5 shrink-0" });
1340
+ if (phase === "skipped") return /* @__PURE__ */ jsx(MinusCircle, { className: "size-3.5 shrink-0" });
1341
+ return icon ? /* @__PURE__ */ jsx("span", { className: "flex size-3.5 shrink-0 items-center justify-center [&_svg]:size-3.5", children: icon }) : /* @__PURE__ */ jsx("span", { className: "mx-1 size-1.5 shrink-0 rounded-full bg-current opacity-60" });
1342
+ }
1343
+ var DEFAULT_STEP_BAR_LABELS = {
1344
+ nav: "Workflow steps",
1345
+ back: "Earlier steps",
1346
+ forward: "Later steps",
1347
+ hiddenBefore: "{count} earlier steps: show all steps",
1348
+ hiddenAfter: "{count} later steps: show all steps",
1349
+ position: "Step {position} of {total}",
1350
+ parallel: "{count} more in parallel",
1351
+ inParallel: "In parallel",
1352
+ working: "Working: {title}",
1353
+ moreWorking: "+{count} working",
1354
+ waitingFor: "Waiting for {name}",
1355
+ phases: {
1356
+ blocked: "Not started",
1357
+ ready: "To do",
1358
+ running: "Working",
1359
+ waiting: "Waiting",
1360
+ done: "Done",
1361
+ skipped: "Skipped",
1362
+ failed: "Failed"
1363
+ }
1364
+ };
1365
+ function stepPillTone(phase, current) {
1366
+ if (current) return "border-primary bg-primary/10 text-primary font-semibold shadow-sm";
1367
+ switch (phase) {
1368
+ case "done":
1369
+ return "border-emerald-600/30 text-emerald-700 dark:border-emerald-400/30 dark:text-emerald-400";
1370
+ case "running":
1371
+ return "border-primary/40 bg-primary/5 text-primary";
1372
+ case "waiting":
1373
+ return "border-amber-500/40 text-amber-700 dark:text-amber-300";
1374
+ case "failed":
1375
+ return "border-destructive/40 text-destructive";
1376
+ case "skipped":
1377
+ return "border-border text-muted-foreground line-through decoration-1";
1378
+ case "ready":
1379
+ return "border-border text-foreground";
1380
+ default:
1381
+ return "border-dashed border-border text-muted-foreground";
1382
+ }
1383
+ }
1384
+ var PHASE_TEXT = {
1385
+ done: "text-emerald-700 dark:text-emerald-400",
1386
+ running: "text-primary",
1387
+ waiting: "text-amber-700 dark:text-amber-300",
1388
+ failed: "text-destructive",
1389
+ skipped: "text-muted-foreground",
1390
+ ready: "text-foreground",
1391
+ blocked: "text-muted-foreground"
1392
+ };
1393
+ var STEP_PILL = "flex min-w-0 items-center gap-1.5 whitespace-nowrap rounded-full border px-2.5 py-1 text-xs font-medium transition-colors";
1394
+ var STEP_LABEL = "min-w-[2.5rem] truncate";
1395
+ var STEP_EXTRA = "min-w-0 shrink-[6] truncate font-normal opacity-80";
1396
+ var fill = (template, values) => Object.entries(values).reduce((s, [k, v]) => s.replace(`{${k}}`, String(v)), template);
1397
+ var NARROW_PX = 560;
1398
+ var FULL_LEVEL_PX = 190;
1399
+ function StepBarFrame({
1400
+ levels,
1401
+ phaseOf,
1402
+ current,
1403
+ onSelect,
1404
+ renderStep,
1405
+ noteOf,
1406
+ renderAfter,
1407
+ leading,
1408
+ trailing,
1409
+ isSelectable = () => true,
1410
+ icon,
1411
+ disabled,
1412
+ labels,
1413
+ tid,
1414
+ className
1415
+ }) {
1416
+ const l = { ...DEFAULT_STEP_BAR_LABELS, ...labels };
1417
+ const box = useRef(null);
1418
+ const { width } = useElementSize(box);
1419
+ const narrow = width > 0 && width < NARROW_PX;
1420
+ const [start, setStart] = useState(null);
1421
+ useEffect(() => setStart(null), [current]);
1422
+ const span = narrow ? 2 : width >= levels.length * FULL_LEVEL_PX ? levels.length : 3;
1423
+ const win = stepWindow({ levels, phaseOf, current, start, span });
1424
+ const [listOpen, setListOpen] = useState(null);
1425
+ const move = (to) => setStart(Math.max(0, Math.min(win.levels.length - 1, to)));
1426
+ const select = (id) => {
1427
+ setListOpen(null);
1428
+ setStart(null);
1429
+ onSelect(id);
1430
+ };
1431
+ const onKeyDown = (e) => {
1432
+ if (!box.current?.contains(e.target)) return;
1433
+ const to = e.key === "ArrowLeft" ? win.start - 1 : e.key === "ArrowRight" ? win.start + 1 : e.key === "Home" ? 0 : e.key === "End" ? win.levels.length : null;
1434
+ if (to === null) return;
1435
+ e.preventDefault();
1436
+ move(to);
1437
+ };
1438
+ const row = (s, isCurrent) => {
1439
+ const phase = phaseOf(s.id);
1440
+ const selectable = isSelectable(s.id);
1441
+ return /* @__PURE__ */ jsxs(
1442
+ "button",
1443
+ {
1444
+ type: "button",
1445
+ disabled: !selectable || disabled,
1446
+ onClick: () => select(s.id),
1447
+ "aria-current": isCurrent ? "step" : void 0,
1448
+ className: cn(
1449
+ "flex w-full min-w-0 items-center gap-2 rounded-md px-2 py-1 text-left text-xs hover:bg-accent disabled:cursor-default disabled:hover:bg-transparent",
1450
+ isCurrent && "bg-primary/10 font-semibold text-primary"
1451
+ ),
1452
+ "data-phase": phase,
1453
+ "data-testid": tid(`list-step-${s.id}`),
1454
+ children: [
1455
+ /* @__PURE__ */ jsx("span", { className: cn("flex shrink-0", !isCurrent && PHASE_TEXT[phase]), children: /* @__PURE__ */ jsx(PhaseMark, { phase, icon: icon?.(s) }) }),
1456
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", title: s.title, children: s.title }),
1457
+ /* @__PURE__ */ jsx("span", { className: "shrink-0 text-[10px] font-normal text-muted-foreground", children: l.phases[phase] })
1458
+ ]
1459
+ },
1460
+ s.id
1461
+ );
1462
+ };
1463
+ const at = win.levels[win.currentLevel];
1464
+ const atId = at && (at.steps.find((s) => s.id === current) ?? at.primary).id;
1465
+ const focusCurrent = (e) => {
1466
+ const el = e.currentTarget?.querySelector(
1467
+ '[aria-current="step"]'
1468
+ );
1469
+ if (!el) return;
1470
+ e.preventDefault();
1471
+ el.focus();
1472
+ el.scrollIntoView?.({ block: "nearest" });
1473
+ };
1474
+ const allSteps = /* @__PURE__ */ jsxs(Fragment, { children: [
1475
+ /* @__PURE__ */ jsx("p", { className: "px-2 py-1 text-[11px] font-medium text-muted-foreground", children: fill(l.position, { position: win.position, total: win.total }) }),
1476
+ /* @__PURE__ */ jsx("ol", { children: win.levels.map((level) => /* @__PURE__ */ jsxs(
1477
+ "li",
1478
+ {
1479
+ className: cn(level.steps.length > 1 && "my-0.5 border-l-2 border-primary/30 pl-1"),
1480
+ children: [
1481
+ level.steps.length > 1 && /* @__PURE__ */ jsx("p", { className: "px-2 text-[10px] uppercase tracking-wide text-muted-foreground", children: l.inParallel }),
1482
+ level.steps.map((s) => row(s, s.id === atId))
1483
+ ]
1484
+ },
1485
+ level.index
1486
+ )) })
1487
+ ] });
1488
+ const overflow = (side, count) => narrow && side === "before" ? null : narrow && side === "after" ? win.hiddenBefore + win.hiddenAfter > 0 ? /* @__PURE__ */ jsxs(Popover, { open: listOpen === side, onOpenChange: (o) => setListOpen(o ? side : null), children: [
1489
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
1490
+ "button",
1491
+ {
1492
+ type: "button",
1493
+ className: "flex shrink-0 items-center rounded-full px-1.5 py-1 text-[11px] tabular-nums text-muted-foreground hover:bg-accent hover:text-foreground",
1494
+ "aria-label": fill(l.position, { position: win.position, total: win.total }),
1495
+ title: fill(l.position, { position: win.position, total: win.total }),
1496
+ "data-testid": tid("steps-count"),
1497
+ children: [
1498
+ win.position,
1499
+ "/",
1500
+ win.total
1501
+ ]
1502
+ }
1503
+ ) }),
1504
+ /* @__PURE__ */ jsx(
1505
+ PopoverContent,
1506
+ {
1507
+ align: "end",
1508
+ className: "max-h-[min(24rem,70vh)] w-72 overflow-y-auto p-1",
1509
+ onOpenAutoFocus: focusCurrent,
1510
+ "data-testid": tid("all-steps"),
1511
+ children: allSteps
1512
+ }
1513
+ )
1514
+ ] }) : null : count > 0 ? /* @__PURE__ */ jsxs(Popover, { open: listOpen === side, onOpenChange: (o) => setListOpen(o ? side : null), children: [
1515
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
1516
+ "button",
1517
+ {
1518
+ type: "button",
1519
+ className: "flex shrink-0 items-center gap-0.5 rounded-full px-1.5 py-1 text-xs text-muted-foreground hover:bg-accent hover:text-foreground",
1520
+ "aria-label": fill(side === "before" ? l.hiddenBefore : l.hiddenAfter, { count }),
1521
+ title: fill(side === "before" ? l.hiddenBefore : l.hiddenAfter, { count }),
1522
+ "data-testid": tid(`hidden-${side}`),
1523
+ children: [
1524
+ /* @__PURE__ */ jsx("span", { "aria-hidden": true, children: "\u2026" }),
1525
+ /* @__PURE__ */ jsx("span", { className: "tabular-nums", children: count })
1526
+ ]
1527
+ }
1528
+ ) }),
1529
+ /* @__PURE__ */ jsx(
1530
+ PopoverContent,
1531
+ {
1532
+ align: side === "before" ? "start" : "end",
1533
+ className: "max-h-[min(24rem,70vh)] w-80 overflow-y-auto p-1",
1534
+ onOpenAutoFocus: focusCurrent,
1535
+ "data-testid": tid("all-steps"),
1536
+ children: allSteps
1537
+ }
1538
+ )
1539
+ ] }) : null;
1540
+ const arrow = (dir) => {
1541
+ const can = dir === "back" ? win.canBack : win.canForward;
1542
+ const Icon = dir === "back" ? ChevronLeft : ChevronRight;
1543
+ return /* @__PURE__ */ jsx(
1544
+ "button",
1545
+ {
1546
+ type: "button",
1547
+ onClick: () => move(win.start + (dir === "back" ? -1 : 1)),
1548
+ disabled: !can,
1549
+ "aria-label": dir === "back" ? l.back : l.forward,
1550
+ title: dir === "back" ? l.back : l.forward,
1551
+ className: "flex size-6 shrink-0 items-center justify-center rounded-full text-muted-foreground hover:bg-accent hover:text-foreground disabled:pointer-events-none disabled:opacity-30",
1552
+ "data-testid": tid(`steps-${dir}`),
1553
+ children: /* @__PURE__ */ jsx(Icon, { className: "size-4" })
1554
+ }
1555
+ );
1556
+ };
1557
+ const running = win.runningHidden;
1558
+ const workingPill = (s) => /* @__PURE__ */ jsxs(
1559
+ "button",
1560
+ {
1561
+ type: "button",
1562
+ onClick: () => select(s.id),
1563
+ className: "flex min-w-0 max-w-[14rem] shrink items-center gap-1.5 rounded-full border border-primary/40 bg-primary/5 px-2 py-1 text-xs text-primary hover:bg-primary/10",
1564
+ title: fill(l.working, { title: s.title }),
1565
+ "data-testid": tid(`working-${s.id}`),
1566
+ children: [
1567
+ /* @__PURE__ */ jsx(Loader2, { className: "size-3.5 shrink-0 animate-spin" }),
1568
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: fill(l.working, { title: s.title }) })
1569
+ ]
1570
+ },
1571
+ s.id
1572
+ );
1573
+ return /* @__PURE__ */ jsxs(
1574
+ "nav",
1575
+ {
1576
+ ref: box,
1577
+ "aria-label": l.nav,
1578
+ onKeyDown,
1579
+ className: cn("flex min-w-0 items-center gap-1", narrow && "flex-wrap", className),
1580
+ "data-testid": tid("steps"),
1581
+ "data-narrow": narrow || void 0,
1582
+ children: [
1583
+ arrow("back"),
1584
+ win.start === 0 && leading,
1585
+ overflow("before", win.hiddenBefore),
1586
+ /* @__PURE__ */ jsx("ol", { className: "flex min-w-0 flex-1 items-center gap-1", children: win.visible.map((level, i) => /* @__PURE__ */ jsxs(
1587
+ "li",
1588
+ {
1589
+ className: cn(
1590
+ "flex min-w-[5.5rem] items-center gap-1",
1591
+ i === win.visible.length - 1 ? "flex-[0_1_auto]" : "flex-[1_1_auto]"
1592
+ ),
1593
+ "data-role": level.role,
1594
+ children: [
1595
+ renderStep(level.primary, level, win, narrow),
1596
+ level.others.length > 0 && /* @__PURE__ */ jsx(
1597
+ GroupChip,
1598
+ {
1599
+ level,
1600
+ label: fill(l.parallel, { count: level.others.length }),
1601
+ heading: l.inParallel,
1602
+ row: (s) => row(s, s.id === atId),
1603
+ tid
1604
+ }
1605
+ ),
1606
+ renderAfter?.(level),
1607
+ i < win.visible.length - 1 && !narrow && /* @__PURE__ */ jsx(
1608
+ "span",
1609
+ {
1610
+ "aria-hidden": true,
1611
+ className: cn(
1612
+ "h-px min-w-3 flex-1",
1613
+ level.steps.every((s) => ["done", "skipped"].includes(phaseOf(s.id))) ? "bg-emerald-600/40" : "bg-border"
1614
+ )
1615
+ }
1616
+ )
1617
+ ]
1618
+ },
1619
+ level.steps.map((s) => s.id).join("+")
1620
+ )) }),
1621
+ overflow("after", win.hiddenAfter),
1622
+ !win.canForward && trailing,
1623
+ arrow("forward"),
1624
+ narrow && atId && noteOf?.(atId) && /* @__PURE__ */ jsx(
1625
+ "p",
1626
+ {
1627
+ className: "min-w-0 basis-full truncate px-1 text-[11px] text-muted-foreground",
1628
+ "data-testid": tid("note"),
1629
+ children: noteOf(atId)
1630
+ }
1631
+ ),
1632
+ running.length > 0 && /* @__PURE__ */ jsxs(
1633
+ "div",
1634
+ {
1635
+ className: cn("flex min-w-0 shrink items-center gap-1", narrow && "basis-full"),
1636
+ "data-testid": tid("working"),
1637
+ children: [
1638
+ (running.length > 2 ? running.slice(0, 1) : running).map(workingPill),
1639
+ running.length > 2 && /* @__PURE__ */ jsxs(Popover, { children: [
1640
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
1641
+ "button",
1642
+ {
1643
+ type: "button",
1644
+ className: "flex shrink-0 items-center gap-1 rounded-full border border-primary/40 bg-primary/5 px-2 py-1 text-xs text-primary hover:bg-primary/10",
1645
+ "data-testid": tid("working-more"),
1646
+ children: [
1647
+ /* @__PURE__ */ jsx(Loader2, { className: "size-3.5 animate-spin" }),
1648
+ fill(l.moreWorking, { count: running.length - 1 })
1649
+ ]
1650
+ }
1651
+ ) }),
1652
+ /* @__PURE__ */ jsx(PopoverContent, { align: "end", className: "w-72 p-1", children: running.slice(1).map((s) => row(s, false)) })
1653
+ ] })
1654
+ ]
1655
+ }
1656
+ )
1657
+ ]
1658
+ }
1659
+ );
1660
+ }
1661
+ function GroupChip({
1662
+ level,
1663
+ label,
1664
+ heading,
1665
+ row,
1666
+ tid
1667
+ }) {
1668
+ return /* @__PURE__ */ jsxs(Popover, { children: [
1669
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
1670
+ "button",
1671
+ {
1672
+ type: "button",
1673
+ className: "shrink-0 rounded-full border border-border bg-muted px-1.5 py-0.5 text-[11px] font-medium tabular-nums text-muted-foreground hover:border-primary/40 hover:text-primary",
1674
+ "aria-label": label,
1675
+ title: label,
1676
+ "data-testid": tid(`group-${level.steps[0].id}`),
1677
+ children: [
1678
+ "+",
1679
+ level.others.length
1680
+ ]
1681
+ }
1682
+ ) }),
1683
+ /* @__PURE__ */ jsxs(
1684
+ PopoverContent,
1685
+ {
1686
+ align: "start",
1687
+ className: "w-72 p-1",
1688
+ "data-testid": tid(`group-${level.steps[0].id}-list`),
1689
+ children: [
1690
+ /* @__PURE__ */ jsx("p", { className: "px-2 py-1 text-[11px] font-medium text-muted-foreground", children: heading }),
1691
+ level.steps.map(row)
1692
+ ]
1693
+ }
1694
+ )
1695
+ ] });
1696
+ }
1272
1697
  var DEFAULT_WORKFLOW_STEP_PARTS_LABELS = {
1273
1698
  waitingFor: "Waiting for {name}",
1274
1699
  sendBack: "Send back",
@@ -1748,152 +2173,102 @@ function ActionStepBody({
1748
2173
  phase === "failed" && !state?.declinedBy && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", "data-testid": `${testId}-failed`, children: state?.error || "" })
1749
2174
  ] });
1750
2175
  }
1751
- function PhaseMark({ phase, icon }) {
1752
- if (phase === "done") return /* @__PURE__ */ jsx(Check, { className: "size-3.5 shrink-0" });
1753
- if (phase === "running") return /* @__PURE__ */ jsx(Loader2, { className: "size-3.5 shrink-0 animate-spin" });
1754
- if (phase === "waiting") return /* @__PURE__ */ jsx(Hourglass, { className: "size-3.5 shrink-0" });
1755
- if (phase === "failed") return /* @__PURE__ */ jsx(AlertTriangle, { className: "size-3.5 shrink-0" });
1756
- if (phase === "skipped") return /* @__PURE__ */ jsx(MinusCircle, { className: "size-3.5 shrink-0" });
1757
- return icon ? /* @__PURE__ */ jsx("span", { className: "flex size-3.5 shrink-0 items-center justify-center [&_svg]:size-3.5", children: icon }) : null;
1758
- }
1759
- var PILL = "flex min-w-0 max-w-full shrink-0 items-center gap-2 whitespace-nowrap rounded-full border px-2.5 py-1.5 text-xs font-medium";
1760
- var LABEL = "min-w-0 max-w-[12rem] truncate";
2176
+ var DONE = "__done";
1761
2177
  function WorkflowStepBar({
1762
2178
  run,
1763
2179
  levels,
1764
2180
  doneTitle,
1765
2181
  doneIcon,
1766
2182
  icon,
1767
- tid
2183
+ tid,
2184
+ labels
1768
2185
  }) {
1769
- const box = useRef(null);
1770
- const measure = useRef(null);
1771
- const row = useRef(null);
1772
- const { width } = useElementSize(box);
1773
- const [compact3, setCompact] = useState(false);
1774
- const titles = levels.map((l) => l.map((s) => s.title).join("\0")).join("") + doneTitle;
1775
- useLayoutEffect(() => {
1776
- const needed = measure.current?.scrollWidth ?? 0;
1777
- setCompact(width > 0 && needed > width);
1778
- }, [width, titles]);
1779
- useLayoutEffect(() => {
1780
- if (!compact3) return;
1781
- const el = row.current?.querySelector('[aria-current="step"]');
1782
- el?.scrollIntoView?.({ block: "nearest", inline: "nearest" });
1783
- }, [compact3, run.current]);
1784
- const pill = (s) => {
1785
- const phase = run.phaseOf(s.id);
1786
- const current = s.id === run.current;
2186
+ const l = { ...DEFAULT_STEP_BAR_LABELS, ...labels };
2187
+ const done = { id: DONE, title: doneTitle };
2188
+ const phaseOf = (id) => id === DONE ? run.isComplete ? "done" : "blocked" : run.phaseOf(id);
2189
+ const current = run.isComplete ? DONE : run.current;
2190
+ const waitingOf = (id) => {
2191
+ if (id === DONE || !["ready", "waiting"].includes(phaseOf(id))) return void 0;
2192
+ const assignee = run.assigneeOf(id);
2193
+ return assignee ? l.waitingFor.replace("{name}", assignee) : void 0;
2194
+ };
2195
+ const pill = (s, narrow = false) => {
2196
+ const phase = phaseOf(s.id);
2197
+ const isCurrent = s.id === current;
1787
2198
  const assignee = ["ready", "waiting"].includes(phase) ? run.assigneeOf(s.id) : void 0;
1788
- const title = assignee ? `${s.title} \xB7 ${assignee}` : s.title;
2199
+ const waiting = assignee ? l.waitingFor.replace("{name}", assignee) : void 0;
2200
+ const title = waiting ? `${s.title} \xB7 ${waiting}` : s.title;
2201
+ const name = `${title} (${l.phases[phase]})`;
2202
+ if (s.id === DONE)
2203
+ return /* @__PURE__ */ jsxs(
2204
+ "span",
2205
+ {
2206
+ className: cn(STEP_PILL, stepPillTone(phase, isCurrent)),
2207
+ "aria-current": isCurrent ? "step" : void 0,
2208
+ "aria-label": name,
2209
+ title: doneTitle,
2210
+ "data-phase": phase,
2211
+ "data-testid": tid("step-done"),
2212
+ children: [
2213
+ /* @__PURE__ */ jsx(PhaseMark, { phase: run.isComplete ? "done" : "ready", icon: doneIcon }),
2214
+ /* @__PURE__ */ jsx("span", { className: cn(STEP_LABEL, "max-w-[12rem]"), children: doneTitle })
2215
+ ]
2216
+ }
2217
+ );
1789
2218
  return /* @__PURE__ */ jsxs(
1790
2219
  "button",
1791
2220
  {
1792
2221
  type: "button",
1793
2222
  onClick: () => run.goTo(s.id),
1794
2223
  disabled: run.busy,
1795
- className: cn(
1796
- PILL,
1797
- "transition-colors disabled:cursor-default",
1798
- current ? "border-primary bg-primary/10 text-primary" : phase === "failed" ? "border-destructive/40 text-destructive" : phase === "done" || phase === "skipped" || phase === "running" || phase === "waiting" ? "border-primary/30 bg-primary/5 text-primary" : "border-border text-muted-foreground"
1799
- ),
1800
- "aria-current": current ? "step" : void 0,
1801
- "aria-label": title,
2224
+ className: cn(STEP_PILL, stepPillTone(phase, isCurrent), "disabled:cursor-default"),
2225
+ "aria-current": isCurrent ? "step" : void 0,
2226
+ "aria-label": name,
1802
2227
  title,
1803
2228
  "data-phase": phase,
1804
2229
  "data-testid": tid(`step-${s.id}`),
1805
2230
  children: [
1806
2231
  /* @__PURE__ */ jsx(PhaseMark, { phase, icon: icon(s.icon) }),
1807
- (current || !compact3) && /* @__PURE__ */ jsx("span", { className: LABEL, "data-testid": tid(`step-${s.id}-label`), children: s.title }),
1808
- assignee && !compact3 && /* @__PURE__ */ jsxs(
2232
+ /* @__PURE__ */ jsx(
1809
2233
  "span",
1810
2234
  {
1811
- className: "min-w-0 max-w-[8rem] truncate font-normal opacity-75",
2235
+ className: cn(STEP_LABEL, isCurrent ? "max-w-[18rem]" : "max-w-[12rem]"),
2236
+ "data-testid": tid(`step-${s.id}-label`),
2237
+ children: s.title
2238
+ }
2239
+ ),
2240
+ assignee && isCurrent && !narrow && /* @__PURE__ */ jsxs(
2241
+ "span",
2242
+ {
2243
+ className: cn(STEP_EXTRA, "max-w-[12rem]"),
1812
2244
  "data-testid": tid(`step-${s.id}-assignee`),
1813
2245
  children: [
1814
2246
  "\xB7 ",
1815
- assignee
2247
+ waiting
1816
2248
  ]
1817
2249
  }
1818
2250
  )
1819
2251
  ]
1820
- },
1821
- s.id
2252
+ }
1822
2253
  );
1823
2254
  };
1824
- const done = run.isComplete;
1825
- return /* @__PURE__ */ jsxs("div", { ref: box, className: "relative min-w-0", children: [
1826
- /* @__PURE__ */ jsx(
1827
- "div",
1828
- {
1829
- ref: measure,
1830
- "aria-hidden": true,
1831
- className: "pointer-events-none invisible absolute left-0 top-0 flex w-max items-center gap-1.5",
1832
- children: [...levels, [{ id: "__done", title: doneTitle }]].map((level, i) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
1833
- /* @__PURE__ */ jsx("div", { className: "flex flex-col items-start gap-1", children: level.map((s) => /* @__PURE__ */ jsxs("div", { className: PILL, children: [
1834
- /* @__PURE__ */ jsx("span", { className: "size-3.5 shrink-0" }),
1835
- /* @__PURE__ */ jsx(
1836
- "span",
1837
- {
1838
- className: cn(LABEL, "before:content-[attr(data-label)]"),
1839
- "data-label": s.title
1840
- }
1841
- )
1842
- ] }, s.id)) }),
1843
- i < levels.length && /* @__PURE__ */ jsx("div", { className: "w-2" })
1844
- ] }, i))
1845
- }
1846
- ),
1847
- /* @__PURE__ */ jsx(
1848
- "ol",
1849
- {
1850
- ref: row,
1851
- className: cn("flex w-full items-center gap-1.5", compact3 && "overflow-x-auto pb-1"),
1852
- "data-compact": compact3 || void 0,
1853
- "data-testid": tid("steps"),
1854
- children: [...levels, null].map((level, i) => /* @__PURE__ */ jsxs(
1855
- "li",
1856
- {
1857
- className: cn(
1858
- "flex min-w-0 items-center gap-1.5",
1859
- i < levels.length && !compact3 && "flex-1",
1860
- compact3 && "flex-none"
1861
- ),
1862
- children: [
1863
- level ? /* @__PURE__ */ jsx("div", { className: "flex min-w-0 flex-col items-start gap-1", children: level.map(pill) }) : /* @__PURE__ */ jsxs(
1864
- "div",
1865
- {
1866
- className: cn(
1867
- PILL,
1868
- done ? "border-primary bg-primary/10 text-primary" : "border-border text-muted-foreground"
1869
- ),
1870
- "aria-current": done ? "step" : void 0,
1871
- "aria-label": doneTitle,
1872
- title: doneTitle,
1873
- "data-testid": tid("step-done"),
1874
- children: [
1875
- /* @__PURE__ */ jsx(PhaseMark, { phase: "ready", icon: doneIcon }),
1876
- (done || !compact3) && /* @__PURE__ */ jsx("span", { className: LABEL, children: doneTitle })
1877
- ]
1878
- }
1879
- ),
1880
- i < levels.length && /* @__PURE__ */ jsx(
1881
- "div",
1882
- {
1883
- className: cn(
1884
- "h-px",
1885
- compact3 ? "w-3 flex-none" : "min-w-2 flex-1",
1886
- level?.every((s) => ["done", "skipped"].includes(run.phaseOf(s.id))) ? "bg-primary/40" : "bg-border"
1887
- )
1888
- }
1889
- )
1890
- ]
1891
- },
1892
- level ? level.map((s) => s.id).join("+") : "done"
1893
- ))
1894
- }
1895
- )
1896
- ] });
2255
+ return /* @__PURE__ */ jsx(
2256
+ StepBarFrame,
2257
+ {
2258
+ levels: [...levels, [done]],
2259
+ phaseOf,
2260
+ current,
2261
+ onSelect: (id) => id !== DONE && run.goTo(id),
2262
+ isSelectable: (id) => id !== DONE,
2263
+ renderStep: (s, _level, _win, narrow) => pill(s, narrow),
2264
+ noteOf: waitingOf,
2265
+ icon: (s) => s.id === DONE ? doneIcon : icon(s.icon),
2266
+ disabled: run.busy,
2267
+ labels,
2268
+ tid,
2269
+ className: "w-full"
2270
+ }
2271
+ );
1897
2272
  }
1898
2273
  var DEFAULT_WORKFLOW_RUNNER_LABELS = {
1899
2274
  back: "Back",
@@ -1940,6 +2315,8 @@ function WorkflowRunner({
1940
2315
  people,
1941
2316
  actions,
1942
2317
  nameOfDoc,
2318
+ hideStepBar,
2319
+ compact: compact3,
1943
2320
  labels,
1944
2321
  partsLabels,
1945
2322
  testIdPrefix = "workflow-run",
@@ -1947,6 +2324,7 @@ function WorkflowRunner({
1947
2324
  }) {
1948
2325
  const l = { ...DEFAULT_WORKFLOW_RUNNER_LABELS, ...labels };
1949
2326
  const pl = { ...DEFAULT_WORKFLOW_STEP_PARTS_LABELS, ...partsLabels };
2327
+ const box = compact3 ? "p-4" : "max-w-2xl p-6";
1950
2328
  const { steps, step, isComplete, action } = run;
1951
2329
  const completion = workflow.run.kind === "steps" ? workflow.run.completion : void 0;
1952
2330
  const tid = (suffix) => `${testIdPrefix}-${suffix}`;
@@ -1956,8 +2334,8 @@ function WorkflowRunner({
1956
2334
  const unread = added.filter((f) => f.status === "processing").length;
1957
2335
  const reading = action === "complete" && unread > 0;
1958
2336
  const nextLabel = reading ? l.readingFiles.replace("{current}", String(Math.min(added.length - unread + 1, added.length))).replace("{count}", String(added.length)) : action === "skip" ? l.skip : action === "finish" ? l.finish : action === "complete" && step?.kind === "review" ? l.approve : action === "complete" && step?.kind === "action" ? l.markSent : action === "wait" && (run.isRunning || run.busy) ? l.working : (step && !run.isLocked(step.id) ? step.nextLabel : void 0) ?? l.next;
1959
- return /* @__PURE__ */ jsxs("div", { className: cn("space-y-6", className), "data-testid": testIdPrefix, children: [
1960
- /* @__PURE__ */ jsx(
2337
+ return /* @__PURE__ */ jsxs("div", { className: cn(compact3 ? "space-y-3" : "space-y-6", className), "data-testid": testIdPrefix, children: [
2338
+ !hideStepBar && /* @__PURE__ */ jsx(
1961
2339
  WorkflowStepBar,
1962
2340
  {
1963
2341
  run,
@@ -1982,10 +2360,10 @@ function WorkflowRunner({
1982
2360
  children: l.restart
1983
2361
  }
1984
2362
  )
1985
- ] }) : step ? /* @__PURE__ */ jsx("div", { className: "space-y-3", children: run.phaseOf(step.id) === "blocked" ? /* @__PURE__ */ jsx(Card, { className: "max-w-2xl p-6", "data-testid": tid(step.id), children: /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", "data-testid": tid(`${step.id}-blocked`), children: l.blocked.replace(
2363
+ ] }) : step ? /* @__PURE__ */ jsx("div", { className: "space-y-3", children: run.phaseOf(step.id) === "blocked" ? /* @__PURE__ */ jsx(Card, { className: cn(box, "p-6"), "data-testid": tid(step.id), children: /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", "data-testid": tid(`${step.id}-blocked`), children: l.blocked.replace(
1986
2364
  "{steps}",
1987
2365
  stepDependencies(steps, step.id).map((d) => steps.find((s) => s.id === d)?.title ?? d).join(", ")
1988
- ) }) }) : step.kind === "form" ? /* @__PURE__ */ jsxs(Card, { className: "max-w-2xl space-y-4 p-6", "data-testid": tid(step.id), children: [
2366
+ ) }) }) : step.kind === "form" ? /* @__PURE__ */ jsxs(Card, { className: cn(box, "space-y-4"), "data-testid": tid(step.id), children: [
1989
2367
  /* @__PURE__ */ jsx(StepHeading, { step, icon: icon(step.icon), testId: tid(`${step.id}-title`) }),
1990
2368
  /* @__PURE__ */ jsx(SentBackNote, { state: run.stateOf(step.id), l: pl, testId: tid(step.id) }),
1991
2369
  /* @__PURE__ */ jsx(AssigneeLine, { run, stepId: step.id, l: pl, testId: tid(step.id) }),
@@ -2006,7 +2384,7 @@ function WorkflowRunner({
2006
2384
  ) }),
2007
2385
  run.actionError && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", "data-testid": tid("action-error"), children: run.actionError }),
2008
2386
  renderStepNote?.(step, run)
2009
- ] }) : step.kind === "upload" ? /* @__PURE__ */ jsxs(Card, { className: "max-w-2xl space-y-4 p-6", "data-testid": tid(step.id), children: [
2387
+ ] }) : step.kind === "upload" ? /* @__PURE__ */ jsxs(Card, { className: cn(box, "space-y-4"), "data-testid": tid(step.id), children: [
2010
2388
  /* @__PURE__ */ jsx(SentBackNote, { state: run.stateOf(step.id), l: pl, testId: tid(step.id) }),
2011
2389
  /* @__PURE__ */ jsx(AssigneeLine, { run, stepId: step.id, l: pl, testId: tid(step.id) }),
2012
2390
  renderUpload?.(step) ?? /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -2035,7 +2413,7 @@ function WorkflowRunner({
2035
2413
  ] }),
2036
2414
  run.actionError && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: run.actionError }),
2037
2415
  renderStepNote?.(step, run)
2038
- ] }) : step.kind === "review" ? /* @__PURE__ */ jsxs(Card, { className: "max-w-2xl space-y-4 p-6", "data-testid": tid(step.id), children: [
2416
+ ] }) : step.kind === "review" ? /* @__PURE__ */ jsxs(Card, { className: cn(box, "space-y-4"), "data-testid": tid(step.id), children: [
2039
2417
  /* @__PURE__ */ jsx(StepHeading, { step, icon: icon(step.icon) }),
2040
2418
  /* @__PURE__ */ jsx(SentBackNote, { state: run.stateOf(step.id), l: pl, testId: tid(step.id) }),
2041
2419
  /* @__PURE__ */ jsx("p", { className: "whitespace-pre-line text-sm text-muted-foreground", children: reviewInstructions(step, run.inputs) }),
@@ -2070,7 +2448,7 @@ function WorkflowRunner({
2070
2448
  /* @__PURE__ */ jsx(SendBackControl, { run, step, l: pl, testId: tid(step.id) }),
2071
2449
  run.actionError && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: run.actionError }),
2072
2450
  renderStepNote?.(step, run)
2073
- ] }) : step.kind === "action" ? /* @__PURE__ */ jsxs(Card, { className: "max-w-2xl space-y-4 p-6", "data-testid": tid(step.id), children: [
2451
+ ] }) : step.kind === "action" ? /* @__PURE__ */ jsxs(Card, { className: cn(box, "space-y-4"), "data-testid": tid(step.id), children: [
2074
2452
  /* @__PURE__ */ jsx(
2075
2453
  ActionStepBody,
2076
2454
  {
@@ -2093,6 +2471,7 @@ function WorkflowRunner({
2093
2471
  renderAgentOutput,
2094
2472
  icon: icon(step.icon),
2095
2473
  renderStepNote,
2474
+ compact: compact3,
2096
2475
  extra: /* @__PURE__ */ jsxs(Fragment, { children: [
2097
2476
  /* @__PURE__ */ jsx(SentBackNote, { state: run.stateOf(step.id), l: pl, testId: tid(step.id) }),
2098
2477
  /* @__PURE__ */ jsx(
@@ -2110,47 +2489,62 @@ function WorkflowRunner({
2110
2489
  tid
2111
2490
  }
2112
2491
  ) }, step.id) : null,
2113
- !isComplete && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between border-t border-border pt-4", children: [
2114
- /* @__PURE__ */ jsxs(
2115
- Button,
2116
- {
2117
- variant: "ghost",
2118
- onClick: run.back,
2119
- disabled: !run.canBack,
2120
- "data-testid": tid("back"),
2121
- children: [
2122
- /* @__PURE__ */ jsx(ArrowLeft, { className: "size-4" }),
2123
- " ",
2124
- l.back
2125
- ]
2126
- }
2127
- ),
2128
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
2129
- step && action !== "skip" && // A step that commits (creates the matter, starts the thread) is what the run stands on.
2130
- !step.commit && ["ready", "blocked", "failed"].includes(run.phaseOf(step.id)) && /* @__PURE__ */ jsx(
2131
- Button,
2132
- {
2133
- variant: "ghost",
2134
- onClick: () => void run.skip(step.id),
2135
- disabled: run.busy,
2136
- "data-testid": tid("skip-step"),
2137
- children: l.skipStep
2138
- }
2492
+ !isComplete && /* @__PURE__ */ jsxs(
2493
+ "div",
2494
+ {
2495
+ className: cn(
2496
+ "flex items-center justify-between border-t border-border pt-4",
2497
+ compact3 && "flex-wrap gap-2 pt-3"
2139
2498
  ),
2140
- /* @__PURE__ */ jsxs(
2141
- Button,
2142
- {
2143
- onClick: () => void run.next(),
2144
- disabled: action === "wait" || reading,
2145
- "data-testid": tid("next"),
2146
- children: [
2147
- nextLabel,
2148
- reading || action === "wait" && (run.isRunning || run.busy) ? /* @__PURE__ */ jsx(Loader2, { className: "size-4 animate-spin" }) : /* @__PURE__ */ jsx(ArrowRight, { className: "size-4" })
2149
- ]
2150
- }
2151
- )
2152
- ] })
2153
- ] })
2499
+ children: [
2500
+ /* @__PURE__ */ jsxs(
2501
+ Button,
2502
+ {
2503
+ variant: "ghost",
2504
+ onClick: run.back,
2505
+ disabled: !run.canBack,
2506
+ "data-testid": tid("back"),
2507
+ children: [
2508
+ /* @__PURE__ */ jsx(ArrowLeft, { className: "size-4" }),
2509
+ " ",
2510
+ l.back
2511
+ ]
2512
+ }
2513
+ ),
2514
+ /* @__PURE__ */ jsxs(
2515
+ "div",
2516
+ {
2517
+ className: cn("flex items-center gap-2", compact3 && "ml-auto flex-wrap justify-end"),
2518
+ children: [
2519
+ step && action !== "skip" && // A step that commits (creates the matter, starts the thread) is what the run stands on.
2520
+ !step.commit && ["ready", "blocked", "failed"].includes(run.phaseOf(step.id)) && /* @__PURE__ */ jsx(
2521
+ Button,
2522
+ {
2523
+ variant: "ghost",
2524
+ onClick: () => void run.skip(step.id),
2525
+ disabled: run.busy,
2526
+ "data-testid": tid("skip-step"),
2527
+ children: l.skipStep
2528
+ }
2529
+ ),
2530
+ /* @__PURE__ */ jsxs(
2531
+ Button,
2532
+ {
2533
+ onClick: () => void run.next(),
2534
+ disabled: action === "wait" || reading,
2535
+ "data-testid": tid("next"),
2536
+ children: [
2537
+ nextLabel,
2538
+ reading || action === "wait" && (run.isRunning || run.busy) ? /* @__PURE__ */ jsx(Loader2, { className: "size-4 animate-spin" }) : /* @__PURE__ */ jsx(ArrowRight, { className: "size-4" })
2539
+ ]
2540
+ }
2541
+ )
2542
+ ]
2543
+ }
2544
+ )
2545
+ ]
2546
+ }
2547
+ )
2154
2548
  ] });
2155
2549
  }
2156
2550
  function UploadFiles({
@@ -2237,6 +2631,7 @@ function AgentStepBody({
2237
2631
  icon,
2238
2632
  renderStepNote,
2239
2633
  extra,
2634
+ compact: compact3,
2240
2635
  l,
2241
2636
  tid
2242
2637
  }) {
@@ -2282,7 +2677,7 @@ function AgentStepBody({
2282
2677
  phase === "skipped" && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: l.skipped }),
2283
2678
  extra
2284
2679
  ] });
2285
- if (step.output === "artifact") {
2680
+ if (step.output === "artifact" && !compact3) {
2286
2681
  return /* @__PURE__ */ jsxs(
2287
2682
  "div",
2288
2683
  {
@@ -2299,7 +2694,7 @@ function AgentStepBody({
2299
2694
  }
2300
2695
  );
2301
2696
  }
2302
- return /* @__PURE__ */ jsxs(Card, { className: "space-y-3 p-6", "data-testid": tid(step.id), children: [
2697
+ return /* @__PURE__ */ jsxs(Card, { className: cn("space-y-3", compact3 ? "p-4" : "p-6"), "data-testid": tid(step.id), children: [
2303
2698
  header,
2304
2699
  status,
2305
2700
  renderAgentOutput(step, state),
@@ -2307,6 +2702,6 @@ function AgentStepBody({
2307
2702
  ] });
2308
2703
  }
2309
2704
 
2310
- export { ActionStepBody, ApprovalEvidence, AssigneeLine, DEFAULT_ASSIGNEE_WORDING, DEFAULT_SCHEMA_FORM_LABELS, DEFAULT_WORKFLOW_RUNNER_LABELS, DEFAULT_WORKFLOW_STEP_PARTS_LABELS, EMPTY_WORKFLOW_SCOPE, SKILL_PROMPT_FALLBACK_PLACEHOLDER, SKILL_PROMPT_LABEL, SchemaForm, SendBackControl, WorkflowRunner, assigneeName, buildLaunch, canAssign, composeStepPrompt, composeWorkflowPrompt, defaultInputs, dependsOn, fieldToFrontmatter, fillRunText, fillStepInputs, fromPlanAssignee, fromPlanDocumentRef, fromPlanSteps, initialRunInputs, inputsFromContext, isEmptyWorkflowScope, isIncompleteSignal, isPersonAction, isPersonStep, isRunFinished, isSteppedWorkflow, isWorkflowScope, layoutFromPlanSteps, nextAction, orderSteps, promptFieldName, reviewInstructions, runFields, runFieldsOf, runThreadTitle, sendBackTargets, skillToWorkflow, splitDocRef, stepConfigProblems, stepDependencies, stepFields, stepLevels, stepPhase, stepStatesFromActivity, toPlanAssignee, toPlanDocumentRef, toPlanSteps, upstreamSteps, useWorkflowView, validateInputs, validateStep, validateWorkflowGraph, workflowAccepts, workflowFromFrontmatter, workflowSteps, workflowsAccepting, workflowsForHost };
2311
- //# sourceMappingURL=chunk-34UW6XUQ.js.map
2312
- //# sourceMappingURL=chunk-34UW6XUQ.js.map
2705
+ export { ActionStepBody, ApprovalEvidence, AssigneeLine, DEFAULT_ASSIGNEE_WORDING, DEFAULT_SCHEMA_FORM_LABELS, DEFAULT_STEP_BAR_LABELS, DEFAULT_WORKFLOW_RUNNER_LABELS, DEFAULT_WORKFLOW_STEP_PARTS_LABELS, EMPTY_WORKFLOW_SCOPE, PhaseMark, SKILL_PROMPT_FALLBACK_PLACEHOLDER, SKILL_PROMPT_LABEL, STEP_EXTRA, STEP_LABEL, STEP_PILL, SchemaForm, SendBackControl, StepBarFrame, WorkflowRunner, WorkflowStepBar, activeStepId, assigneeName, buildLaunch, canAssign, composeStepPrompt, composeWorkflowPrompt, defaultInputs, dependsOn, fieldToFrontmatter, fillRunText, fillStepInputs, fromPlanAssignee, fromPlanDocumentRef, fromPlanSteps, initialRunInputs, inputsFromContext, isEmptyWorkflowScope, isIncompleteSignal, isPersonAction, isPersonStep, isRunFinished, isSteppedWorkflow, isWorkflowScope, layoutFromPlanSteps, nextAction, orderSteps, promptFieldName, reviewInstructions, runFields, runFieldsOf, runThreadTitle, sendBackTargets, skillToWorkflow, splitDocRef, stepConfigProblems, stepDependencies, stepFields, stepLevels, stepPhase, stepPillTone, stepStatesFromActivity, stepWindow, toPlanAssignee, toPlanDocumentRef, toPlanSteps, upstreamSteps, useWorkflowView, validateInputs, validateStep, validateWorkflowGraph, workflowAccepts, workflowFromFrontmatter, workflowSteps, workflowsAccepting, workflowsForHost };
2706
+ //# sourceMappingURL=chunk-WXRCMIAE.js.map
2707
+ //# sourceMappingURL=chunk-WXRCMIAE.js.map