@agimon-ai/po-team 0.0.0-alpha.35 → 0.0.0-alpha.37

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.
@@ -4,8 +4,9 @@ import { createElement, useCallback, useEffect, useState, useSyncExternalStore }
4
4
  import { View } from "react-native-unistyles/components/native/View";
5
5
  import { Text } from "react-native-unistyles/components/native/Text";
6
6
  import { ScrollView } from "react-native-unistyles/components/native/ScrollView";
7
- import { Pressable } from "react-native-unistyles/components/native/Pressable";
8
7
  import { StyleSheet } from "react-native-unistyles";
8
+ import { Pressable } from "react-native-unistyles/components/native/Pressable";
9
+ import { FlatList } from "react-native-unistyles/components/native/FlatList";
9
10
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
10
11
  //#region src/extensions/workspaces/(frontend)/fill/Team.home.native.ts
11
12
  var Team_home_native_default = defineFill({ data: {
@@ -389,329 +390,488 @@ const subagentRunsChannel = subagents.channel({
389
390
  }
390
391
  });
391
392
  //#endregion
392
- //#region src/extensions/workspaces/sessions/(frontend)/_components/SubagentsPanel.native.tsx
393
- const TICK_MS$1 = 1e4;
394
- /** How much of a run's own conversation a card carries; the whole thread is one press away. */
395
- const CARD_THREAD_ENTRIES = 8;
396
- /** One run state, in the host's shared outcome vocabulary. */
397
- const RUN_BADGE = {
393
+ //#region src/extensions/workspaces/sessions/(frontend)/_components/CompactAgents.native.tsx
394
+ const BADGES = {
398
395
  queued: {
399
- label: "QUEUED",
396
+ label: "Queued",
400
397
  tone: "neutral"
401
398
  },
402
399
  running: {
403
- label: "RUNNING",
400
+ label: "Running",
404
401
  tone: "running"
405
402
  },
406
403
  done: {
407
- label: "DONE",
404
+ label: "Done",
408
405
  tone: "ok"
409
406
  },
410
407
  failed: {
411
- label: "FAILED",
408
+ label: "Failed",
412
409
  tone: "error"
413
410
  },
414
411
  stopped: {
415
- label: "STOPPED",
412
+ label: "Stopped",
416
413
  tone: "neutral"
417
414
  }
418
415
  };
419
- const NOT_REPORTED = "Not reported";
420
- const END_NOTE = {
421
- done: "This run has finished. Start a new run from Agents.",
422
- failed: "This run failed. Start a new run from Agents.",
423
- stopped: "This run was stopped. Start a new run from Agents."
424
- };
425
- function useSubagents(sessionId) {
426
- const subscribe = useCallback((listener) => {
427
- const sub = subagents.store.subscribe(listener);
428
- return () => sub.unsubscribe();
429
- }, []);
430
- return useSyncExternalStore(subscribe, () => subagents.select(subagents.store.state, sessionId));
416
+ function terminal(item) {
417
+ return item.state === "done" || item.state === "failed" || item.state === "stopped";
431
418
  }
432
- function useNow() {
433
- const [now, setNow] = useState(() => Date.now());
434
- useEffect(() => {
435
- const timer = setInterval(() => setNow(Date.now()), TICK_MS$1);
436
- return () => clearInterval(timer);
437
- }, []);
438
- return now;
419
+ function elapsedRun(item, now) {
420
+ return formatRunDuration(Math.max(0, (item.endedAt ?? (terminal(item) ? item.lastUpdate : now)) - item.startedAt));
439
421
  }
440
- /** How long the run has been going, or took; the clock only matters while it is active. */
441
- function elapsedRun(run, now) {
442
- const end = run.endedAt ?? (run.state === "running" || run.state === "queued" ? now : run.lastUpdate);
443
- return formatRunDuration(Math.max(0, end - run.startedAt));
422
+ function firstLine(text) {
423
+ return text.split("\n").find((line) => line.trim() !== "") ?? "";
444
424
  }
445
- function subagentsTab() {
446
- return {
447
- id: "subagents",
448
- label: "Agents",
449
- panel: SubagentsPanel
450
- };
451
- }
452
- function agentThreadTab(run) {
453
- const runId = run.runId;
454
- return {
455
- id: `subagents-run-${runId}`,
456
- label: agentRunLabel(run),
457
- panel: (props) => /* @__PURE__ */ jsx(AgentThreadPanel, {
458
- ...props,
459
- runId
460
- }, `${props.sessionId}:${runId}`)
461
- };
425
+ /** Only the elapsed leaf ticks, and only for an active, still-listed run. */
426
+ function RunElapsed({ item, now, active = true }) {
427
+ const [time, setTime] = useState(() => Date.now());
428
+ const ticking = now === void 0 && active && !terminal(item);
429
+ useEffect(() => {
430
+ if (!ticking) return void 0;
431
+ const timer = setInterval(() => setTime(Date.now()), 1e4);
432
+ return () => clearInterval(timer);
433
+ }, [ticking]);
434
+ return /* @__PURE__ */ jsx(Fragment, { children: elapsedRun(item, now ?? time) });
462
435
  }
463
- /** The card's work line: a task binding wins; otherwise the delegation prompt. */
464
- function WorkLine({ run }) {
465
- const firstLine = run.task.split("\n").find((line) => line.trim() !== "") ?? "";
466
- return /* @__PURE__ */ jsxs(View, {
467
- style: styles$1.work,
468
- children: [run.taskRef ? /* @__PURE__ */ jsxs(Badge, {
469
- tone: "violet",
470
- size: "xs",
471
- children: ["TASK ", run.taskRef]
472
- }) : /* @__PURE__ */ jsx(Text, {
473
- style: styles$1.workLabel,
474
- children: "Prompt"
475
- }), /* @__PURE__ */ jsx(Text, {
476
- testID: "run-work",
477
- numberOfLines: 1,
478
- style: run.taskRef ? styles$1.workHi : styles$1.workDim,
479
- children: firstLine
480
- })]
436
+ function RunActions({ item, stopping, initiallyOpen, onAction }) {
437
+ return /* @__PURE__ */ jsxs(DropdownMenu, {
438
+ defaultOpen: initiallyOpen,
439
+ children: [/* @__PURE__ */ jsx(DropdownMenuTrigger, {
440
+ variant: "ghost",
441
+ size: "icon",
442
+ style: styles$2.menu,
443
+ testID: `compact-run-menu-${item.runId}`,
444
+ accessibilityLabel: `Actions for ${agentRunLabel(item)}`,
445
+ children: /* @__PURE__ */ jsx(KebabIcon, { size: 14 })
446
+ }), /* @__PURE__ */ jsxs(DropdownMenuContent, { children: [
447
+ /* @__PURE__ */ jsx(DropdownMenuItem, {
448
+ onSelect: () => onAction("thread", item),
449
+ children: "Open thread"
450
+ }),
451
+ /* @__PURE__ */ jsx(DropdownMenuItem, {
452
+ onSelect: () => onAction("details", item),
453
+ children: "Details"
454
+ }),
455
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
456
+ terminal(item) ? /* @__PURE__ */ jsx(DropdownMenuItem, {
457
+ onSelect: () => onAction("clear", item),
458
+ children: "Clear from the list"
459
+ }) : /* @__PURE__ */ jsx(DropdownMenuItem, {
460
+ variant: "destructive",
461
+ disabled: stopping,
462
+ onSelect: () => onAction("stop", item),
463
+ children: stopping ? "Stopping…" : "Stop"
464
+ })
465
+ ] })]
481
466
  });
482
467
  }
483
- /** Everything a card can do, behind one control. */
484
- function RunMenu({ sessionId, run, stopping, onOpenThread, onOpenDetail }) {
485
- const [error, setError] = useState();
486
- const stop = () => {
487
- setError(void 0);
488
- requestRunStop(sessionId, run.runId).catch((cause) => setError(cause instanceof Error ? cause.message : String(cause)));
489
- };
490
- return /* @__PURE__ */ jsxs(Fragment, { children: [error ? /* @__PURE__ */ jsx(Text, {
491
- accessibilityRole: "alert",
492
- testID: `run-menu-stop-error-${run.runId}`,
493
- numberOfLines: 1,
494
- style: styles$1.error,
495
- children: error
496
- }) : null, /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsx(DropdownMenuTrigger, {
497
- variant: "ghost",
498
- size: "icon",
499
- testID: `run-menu-${run.runId}`,
500
- accessibilityLabel: "run actions",
501
- children: /* @__PURE__ */ jsx(KebabIcon, { size: 12 })
502
- }), /* @__PURE__ */ jsxs(DropdownMenuContent, { children: [
503
- /* @__PURE__ */ jsx(DropdownMenuItem, {
504
- onSelect: onOpenThread,
505
- children: "open thread"
506
- }),
507
- /* @__PURE__ */ jsx(DropdownMenuItem, {
508
- onSelect: onOpenDetail,
509
- children: "details"
510
- }),
511
- /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
512
- isTerminalRun(run) ? /* @__PURE__ */ jsx(DropdownMenuItem, {
513
- onSelect: () => dismissRun(sessionId, run.runId),
514
- children: "clear from the grid"
515
- }) : /* @__PURE__ */ jsx(DropdownMenuItem, {
516
- variant: "destructive",
517
- disabled: stopping,
518
- onSelect: stop,
519
- children: stopping ? "stopping…" : "stop"
520
- })
521
- ] })] })] });
522
- }
523
- /** One run in the fleet: its live conversation under a header; the whole card is the way into the run's tab. */
524
- function RunCard({ sessionId, run, now, stopping, renderThread, onOpenThread, onOpenDetail }) {
525
- const badge = RUN_BADGE[run.state];
526
- const who = agentDisplay(run);
468
+ function CompactRun({ now, item, stopping, menuRunId, stopError, onAction }) {
469
+ const who = agentDisplay(item);
470
+ const badge = BADGES[item.state];
471
+ const summary = item.promptWithheld ? "Prompt withheld: this task was marked sensitive." : firstLine(item.error ?? item.summary ?? item.task) || "No prompt recorded";
527
472
  return /* @__PURE__ */ jsxs(Panel, {
528
- testID: `run-card-${run.runId}`,
529
- style: styles$1.card(STATUS_EDGE[badge.tone]),
473
+ testID: `compact-run-${item.runId}`,
474
+ style: styles$2.card(STATUS_EDGE[badge.tone]),
530
475
  children: [/* @__PURE__ */ jsxs(Pressable, {
531
476
  accessibilityRole: "button",
532
477
  accessibilityLabel: `Open ${who.name}'s conversation`,
533
- testID: `run-open-card-${run.runId}`,
534
- onPress: onOpenThread,
535
- style: styles$1.cardOpen,
478
+ testID: `compact-run-open-${item.runId}`,
479
+ onPress: () => onAction("thread", item),
480
+ style: styles$2.open,
536
481
  children: [
537
482
  /* @__PURE__ */ jsxs(View, {
538
- style: styles$1.cardHead,
483
+ style: styles$2.rowHead,
539
484
  children: [
540
485
  /* @__PURE__ */ jsx(AgentAvatar, {
541
486
  name: who.name,
542
487
  seed: who.seed,
543
488
  size: "sm"
544
489
  }),
545
- /* @__PURE__ */ jsx(Text, {
546
- testID: "run-agent",
547
- numberOfLines: 1,
548
- style: styles$1.name,
549
- children: who.name
550
- }),
551
- who.role ? /* @__PURE__ */ jsx(Text, {
552
- numberOfLines: 1,
553
- style: styles$1.dim,
554
- children: who.role
555
- }) : null,
556
- /* @__PURE__ */ jsx(View, { style: styles$1.spacer }),
557
- /* @__PURE__ */ jsx(Text, {
558
- style: styles$1.dim,
559
- children: elapsedRun(run, now)
490
+ /* @__PURE__ */ jsxs(View, {
491
+ style: styles$2.nameBlock,
492
+ children: [/* @__PURE__ */ jsx(Text, {
493
+ numberOfLines: 2,
494
+ style: styles$2.name,
495
+ children: who.name
496
+ }), who.role ? /* @__PURE__ */ jsxs(Text, {
497
+ numberOfLines: 1,
498
+ style: styles$2.dim,
499
+ children: [
500
+ who.role,
501
+ " · ",
502
+ /* @__PURE__ */ jsx(RunElapsed, {
503
+ item,
504
+ now
505
+ })
506
+ ]
507
+ }) : null]
560
508
  }),
561
509
  /* @__PURE__ */ jsx(StatusBadge, {
562
510
  tone: badge.tone,
563
- testID: "run-state",
564
- children: badge.label
511
+ children: stopping ? "Stopping…" : badge.label
565
512
  })
566
513
  ]
567
514
  }),
568
- /* @__PURE__ */ jsx(WorkLine, { run }),
569
- /* @__PURE__ */ jsx(View, {
570
- testID: "run-stream",
571
- pointerEvents: "none",
572
- style: styles$1.stream,
573
- children: renderThread(run.runId, {
574
- limit: CARD_THREAD_ENTRIES,
575
- compact: true
576
- })
515
+ /* @__PURE__ */ jsx(Text, {
516
+ numberOfLines: 2,
517
+ style: item.error ? styles$2.error : styles$2.workText,
518
+ children: summary
577
519
  }),
578
- run.state === "failed" && run.error ? /* @__PURE__ */ jsx(Text, {
579
- testID: "run-error",
580
- numberOfLines: 1,
581
- style: [styles$1.error, styles$1.cardError],
582
- children: run.error
520
+ stopError ? /* @__PURE__ */ jsx(Text, {
521
+ accessibilityRole: "alert",
522
+ style: styles$2.error,
523
+ children: stopError
583
524
  }) : null
584
525
  ]
585
- }), /* @__PURE__ */ jsxs(View, {
586
- style: styles$1.cardFoot,
587
- children: [
588
- /* @__PURE__ */ jsxs(Text, {
589
- numberOfLines: 1,
590
- style: styles$1.dim,
591
- children: [
592
- run.toolCount !== void 0 ? `${run.toolCount} tools` : "—",
593
- run.tokens !== void 0 ? ` · ${run.tokens.toLocaleString()} tk` : "",
594
- run.model ? ` · ${run.model.split("/").pop() ?? run.model}` : ""
595
- ]
596
- }),
597
- /* @__PURE__ */ jsx(View, { style: styles$1.spacer }),
598
- /* @__PURE__ */ jsx(RunMenu, {
599
- sessionId,
600
- run,
601
- stopping,
602
- onOpenThread,
603
- onOpenDetail
604
- })
605
- ]
526
+ }), /* @__PURE__ */ jsx(RunActions, {
527
+ item,
528
+ stopping,
529
+ initiallyOpen: menuRunId === item.runId,
530
+ onAction
606
531
  })]
607
532
  });
608
533
  }
609
- function SheetRow({ label, value, violet }) {
610
- return /* @__PURE__ */ jsxs(View, {
611
- style: styles$1.sheetRow,
612
- children: [/* @__PURE__ */ jsx(Text, {
613
- style: [styles$1.dim, styles$1.sheetRowLabel],
614
- children: label
615
- }), /* @__PURE__ */ jsx(Text, {
616
- style: violet ? styles$1.violet : styles$1.bodyDim,
617
- children: value
618
- })]
619
- });
620
- }
621
- function SheetBlock({ label, text, testId, failure }) {
622
- return /* @__PURE__ */ jsxs(View, {
623
- style: styles$1.sheetBlock,
624
- children: [/* @__PURE__ */ jsx(Text, {
625
- style: styles$1.sheetBlockLabel,
626
- children: label
627
- }), /* @__PURE__ */ jsx(Text, {
628
- testID: testId,
629
- style: failure ? styles$1.bodyRed : styles$1.bodyText,
630
- children: text
631
- })]
632
- });
633
- }
634
- /** What the run was asked to do and what it was given to do it with, over the fleet. */
635
- function RunDetailSheet({ sessionId, run, now, stopping, renderSlot, onClose }) {
636
- const badge = RUN_BADGE[run.state];
534
+ /** Same prompt/report/failure and control contract as the current RunDetailSheet. */
535
+ function CompactRunDetails({ now, actions, stopError, item, stopping, onClose, onAction }) {
536
+ const badge = BADGES[item.state];
537
+ const facts = [
538
+ ["Run", item.runId],
539
+ ...item.taskRef ? [["Task", item.taskRef]] : [],
540
+ ["Model", item.model ?? "The runtime default"],
541
+ ["Folder", abbreviateCwd(item.cwd)],
542
+ ...item.currentTool ? [["Current action", item.currentTool]] : [],
543
+ ["Work", [item.toolCount === void 0 ? "No tools reported" : `${item.toolCount} tools`, item.tokens === void 0 ? void 0 : `${item.tokens.toLocaleString("en-US")} tk`].filter(Boolean).join(" · ")]
544
+ ];
637
545
  return /* @__PURE__ */ jsx(Sheet, {
638
546
  open: true,
639
547
  onOpenChange: (open) => {
640
548
  if (!open) onClose();
641
549
  },
642
- children: /* @__PURE__ */ jsxs(SheetContent, { children: [/* @__PURE__ */ jsxs(SheetHeader, { children: [
643
- /* @__PURE__ */ jsx(SheetTitle, {
644
- testID: "sheet-agent",
645
- children: agentRunLabel(run)
646
- }),
647
- /* @__PURE__ */ jsx(StatusBadge, {
648
- tone: badge.tone,
649
- children: badge.label
650
- }),
651
- /* @__PURE__ */ jsx(View, { style: styles$1.spacer }),
550
+ children: /* @__PURE__ */ jsxs(SheetContent, { children: [/* @__PURE__ */ jsxs(SheetHeader, { children: [/* @__PURE__ */ jsx(SheetTitle, { children: agentRunLabel(item) }), /* @__PURE__ */ jsx(StatusBadge, {
551
+ tone: badge.tone,
552
+ children: badge.label
553
+ })] }), /* @__PURE__ */ jsxs(SheetBody, { children: [
554
+ actions,
555
+ stopError ? /* @__PURE__ */ jsx(Text, {
556
+ accessibilityRole: "alert",
557
+ style: styles$2.error,
558
+ children: stopError
559
+ }) : null,
652
560
  /* @__PURE__ */ jsx(Text, {
653
- style: styles$1.dim,
654
- children: elapsedRun(run, now)
561
+ style: styles$2.dim,
562
+ children: /* @__PURE__ */ jsx(RunElapsed, {
563
+ item,
564
+ now
565
+ })
655
566
  }),
656
- renderSlot(RUN_ACTIONS_SLOT.slot),
657
- /* @__PURE__ */ jsx(RunControl, {
658
- sessionId,
659
- run,
660
- stopping
661
- })
662
- ] }), /* @__PURE__ */ jsxs(SheetBody, { children: [
567
+ facts.map(([label, value]) => /* @__PURE__ */ jsxs(View, {
568
+ style: styles$2.fact,
569
+ children: [/* @__PURE__ */ jsx(Text, {
570
+ style: styles$2.factLabel,
571
+ children: label
572
+ }), /* @__PURE__ */ jsx(Text, {
573
+ selectable: true,
574
+ style: styles$2.factValue,
575
+ children: value
576
+ })]
577
+ }, label)),
663
578
  /* @__PURE__ */ jsxs(View, {
664
- style: styles$1.sheetRows,
665
- children: [
666
- /* @__PURE__ */ jsx(SheetRow, {
667
- label: "run",
668
- value: run.runId
669
- }),
670
- run.taskRef ? /* @__PURE__ */ jsx(SheetRow, {
671
- label: "task",
672
- value: run.taskRef,
673
- violet: true
674
- }) : null,
675
- /* @__PURE__ */ jsx(SheetRow, {
676
- label: "model",
677
- value: run.model ?? "the runtime default"
678
- }),
679
- /* @__PURE__ */ jsx(SheetRow, {
680
- label: "cwd",
681
- value: abbreviateCwd(run.cwd)
682
- }),
683
- /* @__PURE__ */ jsx(SheetRow, {
684
- label: "work",
685
- value: `${run.toolCount === void 0 ? "no" : String(run.toolCount)} tools${run.tokens === void 0 ? "" : ` · ${run.tokens.toLocaleString()} tk`}`
686
- })
687
- ]
688
- }),
689
- /* @__PURE__ */ jsx(SheetBlock, {
690
- label: "PROMPT FROM THE MAIN AGENT",
691
- testId: "sheet-task",
692
- text: run.task || "(no prompt recorded)"
579
+ style: styles$2.detailBlock,
580
+ children: [/* @__PURE__ */ jsx(Text, {
581
+ style: styles$2.name,
582
+ children: "Prompt from the main agent"
583
+ }), /* @__PURE__ */ jsx(Text, {
584
+ selectable: true,
585
+ style: styles$2.body,
586
+ children: item.promptWithheld ? "Withheld: this task was marked sensitive." : item.task || "(no prompt recorded)"
587
+ })]
693
588
  }),
694
- run.summary ? /* @__PURE__ */ jsx(SheetBlock, {
695
- label: "REPORT",
696
- testId: "sheet-summary",
697
- text: run.summary
589
+ item.summary ? /* @__PURE__ */ jsxs(View, {
590
+ style: styles$2.detailBlock,
591
+ children: [/* @__PURE__ */ jsx(Text, {
592
+ style: styles$2.name,
593
+ children: "Report"
594
+ }), /* @__PURE__ */ jsx(Text, {
595
+ selectable: true,
596
+ style: styles$2.body,
597
+ children: item.summary
598
+ })]
698
599
  }) : null,
699
- run.error ? /* @__PURE__ */ jsx(SheetBlock, {
700
- label: "FAILURE",
701
- testId: "sheet-error",
702
- text: run.error,
703
- failure: true
704
- }) : null
600
+ item.error ? /* @__PURE__ */ jsxs(View, {
601
+ style: styles$2.detailBlock,
602
+ children: [/* @__PURE__ */ jsx(Text, {
603
+ style: styles$2.name,
604
+ children: "Failure"
605
+ }), /* @__PURE__ */ jsx(Text, {
606
+ selectable: true,
607
+ style: styles$2.error,
608
+ children: item.error
609
+ })]
610
+ }) : null,
611
+ /* @__PURE__ */ jsx(Button, {
612
+ variant: terminal(item) || stopping ? "outline" : "danger-outline",
613
+ disabled: stopping,
614
+ onPress: () => onAction(terminal(item) ? "clear" : "stop", item),
615
+ children: terminal(item) ? "Clear from the list" : stopping ? "Stopping…" : "Stop"
616
+ })
705
617
  ] })] })
706
618
  });
707
619
  }
620
+ function CompactAgents({ now, items, stoppingRunId, stoppingRunIds = [], menuRunId, stopError, stopErrorRunId, onAction }) {
621
+ const tally = Object.keys(BADGES).map((state) => `${items.filter((item) => item.state === state).length} ${state}`).join(" · ");
622
+ return /* @__PURE__ */ jsx(View, {
623
+ style: styles$2.screen,
624
+ children: /* @__PURE__ */ jsx(FlatList, {
625
+ accessibilityLabel: "Agent runs",
626
+ data: items,
627
+ keyExtractor: (item) => item.runId,
628
+ style: styles$2.list,
629
+ contentContainerStyle: styles$2.listContent,
630
+ initialNumToRender: 8,
631
+ maxToRenderPerBatch: 8,
632
+ windowSize: 5,
633
+ ListHeaderComponent: /* @__PURE__ */ jsxs(View, {
634
+ style: styles$2.headingBlock,
635
+ children: [/* @__PURE__ */ jsxs(View, {
636
+ style: styles$2.headingRow,
637
+ children: [/* @__PURE__ */ jsx(Text, {
638
+ accessibilityRole: "header",
639
+ style: styles$2.heading,
640
+ children: "Agents · this session"
641
+ }), /* @__PURE__ */ jsx(Button, {
642
+ variant: "primary",
643
+ testID: "compact-agent-launch",
644
+ onPress: () => onAction("launch"),
645
+ children: "New agent run"
646
+ })]
647
+ }), /* @__PURE__ */ jsx(Text, {
648
+ testID: "compact-agent-tally",
649
+ style: styles$2.dim,
650
+ children: items.length === 0 ? "No runs yet" : tally
651
+ })]
652
+ }),
653
+ ListEmptyComponent: /* @__PURE__ */ jsxs(View, {
654
+ style: styles$2.empty,
655
+ children: [/* @__PURE__ */ jsx(Text, {
656
+ style: styles$2.body,
657
+ children: "No runs yet"
658
+ }), /* @__PURE__ */ jsx(Text, {
659
+ style: styles$2.dim,
660
+ children: "Start an agent run to get help with your work."
661
+ })]
662
+ }),
663
+ renderItem: ({ item }) => /* @__PURE__ */ jsx(CompactRun, {
664
+ item,
665
+ now,
666
+ stopping: stoppingRunId === item.runId || stoppingRunIds.includes(item.runId),
667
+ menuRunId,
668
+ stopError: item.runId === (stopErrorRunId ?? items[0]?.runId) ? stopError : void 0,
669
+ onAction
670
+ }),
671
+ ListFooterComponent: items.length === 0 ? void 0 : /* @__PURE__ */ jsx(Text, {
672
+ style: styles$2.dim,
673
+ children: "Tap a run to open its thread. Run actions holds details, stop and clear. Finished runs leave the list after 10m."
674
+ })
675
+ })
676
+ });
677
+ }
678
+ const styles$2 = StyleSheet.create((theme) => {
679
+ const sans = fontOf(theme.fontFamily.sans);
680
+ const small = {
681
+ fontFamily: sans,
682
+ fontSize: theme.fontSize.sm,
683
+ lineHeight: theme.lineHeight.sm
684
+ };
685
+ const base = {
686
+ fontFamily: sans,
687
+ fontSize: theme.fontSize.base,
688
+ lineHeight: theme.lineHeight.base
689
+ };
690
+ return {
691
+ list: { flex: 1 },
692
+ listContent: {
693
+ padding: theme.spacing(3),
694
+ uni__dependencies: [0]
695
+ },
696
+ screen: {
697
+ flex: 1,
698
+ backgroundColor: theme.colors.bg,
699
+ uni__dependencies: [0]
700
+ },
701
+ headingBlock: {
702
+ gap: theme.spacing(2),
703
+ paddingBottom: theme.spacing(3),
704
+ uni__dependencies: [0]
705
+ },
706
+ headingRow: {
707
+ flexDirection: "row",
708
+ flexWrap: "wrap",
709
+ alignItems: "center",
710
+ justifyContent: "space-between",
711
+ gap: theme.spacing(2),
712
+ uni__dependencies: [0]
713
+ },
714
+ heading: {
715
+ fontFamily: sans,
716
+ fontSize: theme.fontSize.lg,
717
+ lineHeight: theme.lineHeight.lg,
718
+ fontWeight: theme.fontWeight.semibold,
719
+ color: theme.colors.hi,
720
+ uni__dependencies: [0]
721
+ },
722
+ card: (edge) => ({
723
+ flexDirection: "row",
724
+ marginBottom: theme.spacing(3),
725
+ borderColor: theme.colors[edge],
726
+ uni__dependencies: [0]
727
+ }),
728
+ open: {
729
+ flex: 1,
730
+ minWidth: 0,
731
+ minHeight: 44,
732
+ padding: theme.spacing(3),
733
+ gap: theme.spacing(1.5),
734
+ uni__dependencies: [0]
735
+ },
736
+ rowHead: {
737
+ flexDirection: "row",
738
+ alignItems: "center",
739
+ gap: theme.spacing(2),
740
+ uni__dependencies: [0]
741
+ },
742
+ nameBlock: {
743
+ flex: 1,
744
+ minWidth: 0
745
+ },
746
+ name: {
747
+ ...base,
748
+ fontWeight: theme.fontWeight.semibold,
749
+ color: theme.colors.hi,
750
+ uni__dependencies: [0]
751
+ },
752
+ dim: {
753
+ ...small,
754
+ color: theme.colors.dim,
755
+ uni__dependencies: [0]
756
+ },
757
+ error: {
758
+ ...small,
759
+ color: theme.colors.red,
760
+ uni__dependencies: [0]
761
+ },
762
+ body: {
763
+ ...base,
764
+ color: theme.colors.text,
765
+ uni__dependencies: [0]
766
+ },
767
+ workText: {
768
+ ...base,
769
+ minWidth: 0,
770
+ color: theme.colors.text,
771
+ uni__dependencies: [0]
772
+ },
773
+ menu: {
774
+ width: 44,
775
+ minWidth: 44,
776
+ minHeight: 44,
777
+ alignSelf: "flex-start"
778
+ },
779
+ empty: {
780
+ gap: theme.spacing(2),
781
+ paddingVertical: theme.spacing(3),
782
+ uni__dependencies: [0]
783
+ },
784
+ fact: {
785
+ flexDirection: "row",
786
+ gap: theme.spacing(3),
787
+ uni__dependencies: [0]
788
+ },
789
+ factLabel: {
790
+ ...small,
791
+ width: 44,
792
+ color: theme.colors.dim,
793
+ uni__dependencies: [0]
794
+ },
795
+ factValue: {
796
+ ...base,
797
+ flex: 1,
798
+ minWidth: 0,
799
+ color: theme.colors.text,
800
+ uni__dependencies: [0]
801
+ },
802
+ detailBlock: {
803
+ gap: theme.spacing(1),
804
+ borderWidth: 1,
805
+ borderColor: theme.colors.border,
806
+ borderRadius: theme.borderRadius.md,
807
+ backgroundColor: theme.colors.deep,
808
+ padding: theme.spacing(3),
809
+ uni__dependencies: [0]
810
+ }
811
+ };
812
+ });
813
+ //#endregion
814
+ //#region src/extensions/workspaces/sessions/(frontend)/_components/SubagentsPanel.native.tsx
815
+ /** One run state, in the host's shared outcome vocabulary. */
816
+ const RUN_BADGE = {
817
+ queued: {
818
+ label: "QUEUED",
819
+ tone: "neutral"
820
+ },
821
+ running: {
822
+ label: "RUNNING",
823
+ tone: "running"
824
+ },
825
+ done: {
826
+ label: "DONE",
827
+ tone: "ok"
828
+ },
829
+ failed: {
830
+ label: "FAILED",
831
+ tone: "error"
832
+ },
833
+ stopped: {
834
+ label: "STOPPED",
835
+ tone: "neutral"
836
+ }
837
+ };
838
+ const NOT_REPORTED = "Not reported";
839
+ const END_NOTE = {
840
+ done: "This run has finished. Start a new run from Agents.",
841
+ failed: "This run failed. Start a new run from Agents.",
842
+ stopped: "This run was stopped. Start a new run from Agents."
843
+ };
844
+ function useSubagents(sessionId) {
845
+ const subscribe = useCallback((listener) => {
846
+ const sub = subagents.store.subscribe(listener);
847
+ return () => sub.unsubscribe();
848
+ }, []);
849
+ return useSyncExternalStore(subscribe, () => subagents.select(subagents.store.state, sessionId));
850
+ }
851
+ function subagentsTab() {
852
+ return {
853
+ id: "subagents",
854
+ label: "Agents",
855
+ panel: SubagentsPanel
856
+ };
857
+ }
858
+ function agentThreadTab(run) {
859
+ const runId = run.runId;
860
+ return {
861
+ id: `subagents-run-${runId}`,
862
+ label: agentRunLabel(run),
863
+ panel: (props) => /* @__PURE__ */ jsx(AgentThreadPanel, {
864
+ ...props,
865
+ runId
866
+ }, `${props.sessionId}:${runId}`)
867
+ };
868
+ }
708
869
  /** The subagents tab: the focused session's fleet, one card per run. */
709
870
  function SubagentsPanel(props) {
710
- const { sessionId, renderSlot, renderThread, openTransientTab } = props;
871
+ const { sessionId, renderSlot, openTransientTab } = props;
711
872
  const state = useSubagents(sessionId);
712
873
  const runs = visibleRuns(state);
713
874
  const { openRunId, stopRequested, autoOpenRunId } = state;
714
- const now = useNow();
715
875
  useEffect(() => {
716
876
  if (autoOpenRunId === void 0 || sessionId === null) return;
717
877
  const run = runs.find((candidate) => candidate.runId === autoOpenRunId);
@@ -725,86 +885,48 @@ function SubagentsPanel(props) {
725
885
  ]);
726
886
  const shownRun = openRunId === void 0 ? void 0 : runs.find((run) => run.runId === openRunId);
727
887
  const stopping = (run) => stopRequested.includes(run.runId);
728
- const runningTally = runs.filter((run) => run.state === "running" || run.state === "queued").length;
729
- const doneTally = runs.filter((run) => run.state === "done").length;
730
- const failedTally = runs.filter((run) => run.state === "failed" || run.state === "stopped").length;
888
+ const [stopError, setStopError] = useState();
889
+ const onAction = (action, run) => {
890
+ if (sessionId === null) return;
891
+ if (action === "launch") {
892
+ openRun(sessionId, void 0);
893
+ openCatalog(sessionId);
894
+ } else if (run) {
895
+ if (action === "thread") {
896
+ closeCatalog(sessionId);
897
+ openTransientTab(agentThreadTab(run));
898
+ } else if (action === "details") {
899
+ closeCatalog(sessionId);
900
+ openRun(sessionId, run.runId);
901
+ } else if (action === "clear") dismissRun(sessionId, run.runId);
902
+ else if (action === "stop") {
903
+ setStopError(void 0);
904
+ requestRunStop(sessionId, run.runId).catch((cause) => setStopError({
905
+ runId: run.runId,
906
+ message: cause instanceof Error ? cause.message : String(cause)
907
+ }));
908
+ }
909
+ }
910
+ };
731
911
  return /* @__PURE__ */ jsxs(View, {
732
912
  testID: "subagents-panel",
733
913
  style: styles$1.screen,
734
914
  children: [
735
- /* @__PURE__ */ jsxs(ScrollView, {
736
- contentContainerStyle: styles$1.fleet,
737
- children: [/* @__PURE__ */ jsxs(View, {
738
- style: styles$1.fleetHead,
739
- children: [
740
- /* @__PURE__ */ jsx(Text, {
741
- style: styles$1.heading,
742
- children: "Agents · this session"
743
- }),
744
- /* @__PURE__ */ jsx(Button, {
745
- variant: "primary",
746
- testID: "subagents-launch",
747
- style: styles$1.launch,
748
- onPress: () => {
749
- if (sessionId === null) return;
750
- openRun(sessionId, void 0);
751
- openCatalog(sessionId);
752
- },
753
- children: "New agent run"
754
- }),
755
- /* @__PURE__ */ jsx(Text, {
756
- testID: "subagents-tally",
757
- style: [styles$1.dim, styles$1.tally],
758
- children: runs.length === 0 ? "no runs yet" : `${runningTally} running · ${doneTally} done · ${failedTally} failed`
759
- })
760
- ]
761
- }), runs.length === 0 ? /* @__PURE__ */ jsxs(View, {
762
- testID: "subagents-empty",
763
- children: [
764
- /* @__PURE__ */ jsx(Text, {
765
- style: styles$1.bodyDim,
766
- children: "No runs yet"
767
- }),
768
- /* @__PURE__ */ jsx(Text, {
769
- style: styles$1.bodyDim,
770
- children: "Start an agent run to get help with your work."
771
- }),
772
- /* @__PURE__ */ jsx(Text, {
773
- style: [styles$1.dim, styles$1.emptyHint],
774
- children: "Agent runs will appear here once you start one."
775
- })
776
- ]
777
- }) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(View, {
778
- testID: "subagents-grid",
779
- style: styles$1.grid,
780
- children: sessionId === null ? null : runs.map((run) => /* @__PURE__ */ jsx(RunCard, {
781
- sessionId,
782
- run,
783
- now,
784
- stopping: stopping(run),
785
- renderThread,
786
- onOpenThread: () => {
787
- closeCatalog(sessionId);
788
- openTransientTab(agentThreadTab(run));
789
- },
790
- onOpenDetail: () => {
791
- closeCatalog(sessionId);
792
- openRun(sessionId, run.runId);
793
- }
794
- }, run.runId))
795
- }), /* @__PURE__ */ jsx(Text, {
796
- style: styles$1.dim,
797
- children: "tap a card to open the run's thread · the card menu holds details, stop and clear · finished runs leave the grid after 10m"
798
- })] })]
915
+ /* @__PURE__ */ jsx(CompactAgents, {
916
+ items: runs,
917
+ stoppingRunIds: stopRequested,
918
+ stopError: stopError?.message,
919
+ stopErrorRunId: stopError?.runId,
920
+ onAction
799
921
  }),
800
922
  /* @__PURE__ */ jsx(AgentCatalog, { ...props }),
801
- shownRun && sessionId !== null ? /* @__PURE__ */ jsx(RunDetailSheet, {
802
- sessionId,
803
- run: shownRun,
804
- now,
923
+ shownRun && sessionId !== null ? /* @__PURE__ */ jsx(CompactRunDetails, {
924
+ item: shownRun,
805
925
  stopping: stopping(shownRun),
806
- renderSlot,
807
- onClose: () => openRun(sessionId, void 0)
926
+ actions: renderSlot(RUN_ACTIONS_SLOT.slot),
927
+ stopError: stopError?.runId === shownRun.runId ? stopError.message : void 0,
928
+ onClose: () => openRun(sessionId, void 0),
929
+ onAction
808
930
  }) : null
809
931
  ]
810
932
  });
@@ -1094,7 +1216,6 @@ function AgentThreadPanel({ sessionId, runId, renderThread }) {
1094
1216
  if (listed !== void 0 && listed !== seen) setSeen(listed);
1095
1217
  const run = listed ?? seen;
1096
1218
  const gone = listed === void 0;
1097
- const now = useNow();
1098
1219
  const [guidance, setGuidance] = useState("");
1099
1220
  const [sending, setSending] = useState(false);
1100
1221
  const [error, setError] = useState();
@@ -1125,10 +1246,6 @@ function AgentThreadPanel({ sessionId, runId, renderThread }) {
1125
1246
  };
1126
1247
  const who = run ? agentDisplay(run) : void 0;
1127
1248
  const badge = run ? RUN_BADGE[run.state] : void 0;
1128
- const elapsed = run ? elapsedRun(gone ? {
1129
- ...run,
1130
- endedAt: run.endedAt ?? run.lastUpdate
1131
- } : run, now) : void 0;
1132
1249
  const endNote = run && isTerminalRun(run) ? END_NOTE[run.state] : run?.canSteer === false && !gone ? "This runtime does not take guidance while it runs." : "Guidance is unavailable for this run.";
1133
1250
  const toggleInfo = () => setInfoOpen((current) => !current);
1134
1251
  return /* @__PURE__ */ jsxs(View, {
@@ -1163,7 +1280,13 @@ function AgentThreadPanel({ sessionId, runId, renderThread }) {
1163
1280
  /* @__PURE__ */ jsx(Text, {
1164
1281
  numberOfLines: 1,
1165
1282
  style: [styles$1.dim, styles$1.grow],
1166
- children: elapsed
1283
+ children: run ? /* @__PURE__ */ jsx(RunElapsed, {
1284
+ item: gone ? {
1285
+ ...run,
1286
+ endedAt: run.endedAt ?? run.lastUpdate
1287
+ } : run,
1288
+ active: !gone
1289
+ }) : null
1167
1290
  }),
1168
1291
  live ? /* @__PURE__ */ jsx(RunControl, {
1169
1292
  sessionId,
@@ -1364,138 +1487,6 @@ const styles$1 = StyleSheet.create((theme) => {
1364
1487
  uni__dependencies: [0]
1365
1488
  },
1366
1489
  capitalize: { textTransform: "capitalize" },
1367
- fleet: {
1368
- padding: theme.spacing(3),
1369
- gap: theme.spacing(3),
1370
- uni__dependencies: [0]
1371
- },
1372
- fleetHead: {
1373
- flexDirection: "row",
1374
- flexWrap: "wrap",
1375
- alignItems: "center",
1376
- columnGap: theme.spacing(3),
1377
- rowGap: theme.spacing(2),
1378
- uni__dependencies: [0]
1379
- },
1380
- heading: {
1381
- fontFamily: sans,
1382
- fontSize: theme.fontSize.lg,
1383
- lineHeight: theme.lineHeight.lg,
1384
- fontWeight: theme.fontWeight.semibold,
1385
- color: theme.colors.hi,
1386
- uni__dependencies: [0]
1387
- },
1388
- launch: { marginLeft: "auto" },
1389
- tally: { width: "100%" },
1390
- emptyHint: {
1391
- paddingVertical: theme.spacing(32),
1392
- textAlign: "center",
1393
- uni__dependencies: [0]
1394
- },
1395
- grid: {
1396
- gap: theme.spacing(4),
1397
- uni__dependencies: [0]
1398
- },
1399
- card: (edge) => ({
1400
- height: 280,
1401
- overflow: "hidden",
1402
- borderColor: theme.colors[edge],
1403
- uni__dependencies: [0]
1404
- }),
1405
- cardOpen: {
1406
- flex: 1,
1407
- minHeight: 0
1408
- },
1409
- cardHead: {
1410
- flexDirection: "row",
1411
- alignItems: "center",
1412
- gap: theme.spacing(2),
1413
- paddingHorizontal: theme.spacing(3),
1414
- paddingTop: theme.spacing(2.5),
1415
- paddingBottom: theme.spacing(1.5),
1416
- uni__dependencies: [0]
1417
- },
1418
- work: {
1419
- flexDirection: "row",
1420
- alignItems: "center",
1421
- gap: theme.spacing(2),
1422
- paddingHorizontal: theme.spacing(3),
1423
- paddingBottom: theme.spacing(2.5),
1424
- uni__dependencies: [0]
1425
- },
1426
- workLabel: {
1427
- ...base,
1428
- fontWeight: theme.fontWeight.medium,
1429
- color: theme.colors.dim,
1430
- uni__dependencies: [0]
1431
- },
1432
- workHi: {
1433
- ...base,
1434
- color: theme.colors.hi,
1435
- flexShrink: 1,
1436
- uni__dependencies: [0]
1437
- },
1438
- workDim: {
1439
- ...base,
1440
- color: theme.colors.dim,
1441
- flexShrink: 1,
1442
- uni__dependencies: [0]
1443
- },
1444
- stream: {
1445
- flex: 1,
1446
- minHeight: 0,
1447
- overflow: "hidden",
1448
- borderTopWidth: 1,
1449
- borderTopColor: theme.colors["border-soft"],
1450
- backgroundColor: theme.colors.deep,
1451
- uni__dependencies: [0]
1452
- },
1453
- cardError: {
1454
- borderTopWidth: 1,
1455
- borderTopColor: theme.colors["border-soft"],
1456
- paddingHorizontal: theme.spacing(3),
1457
- paddingVertical: theme.spacing(1.5),
1458
- uni__dependencies: [0]
1459
- },
1460
- cardFoot: {
1461
- flexDirection: "row",
1462
- alignItems: "center",
1463
- gap: theme.spacing(3),
1464
- borderTopWidth: 1,
1465
- borderTopColor: theme.colors["border-soft"],
1466
- paddingHorizontal: theme.spacing(3),
1467
- paddingVertical: theme.spacing(1.5),
1468
- uni__dependencies: [0]
1469
- },
1470
- sheetRows: {
1471
- gap: theme.spacing(1.5),
1472
- uni__dependencies: [0]
1473
- },
1474
- sheetRow: {
1475
- flexDirection: "row",
1476
- gap: theme.spacing(2.5),
1477
- uni__dependencies: [0]
1478
- },
1479
- sheetRowLabel: {
1480
- width: 44,
1481
- flexShrink: 0
1482
- },
1483
- sheetBlock: {
1484
- gap: theme.spacing(1),
1485
- borderRadius: theme.borderRadius.md,
1486
- borderWidth: 1,
1487
- borderColor: theme.colors.border,
1488
- backgroundColor: theme.colors.deep,
1489
- paddingHorizontal: theme.spacing(3),
1490
- paddingVertical: theme.spacing(2.5),
1491
- uni__dependencies: [0]
1492
- },
1493
- sheetBlockLabel: {
1494
- ...base,
1495
- fontWeight: theme.fontWeight.medium,
1496
- color: theme.colors.dim,
1497
- uni__dependencies: [0]
1498
- },
1499
1490
  threadHead: {
1500
1491
  flexDirection: "row",
1501
1492
  alignItems: "center",