@agimon-ai/po-workflow 0.0.0-alpha.73 → 0.0.0-alpha.74

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.
@@ -1,5 +1,5 @@
1
- import { createApiClient, defineActivityGroup, defineChannelFile, defineDockFace, defineFill, defineNativePlugin, defineSessionChannel, defineSessionStore, encodeBase64, nativeApiTransport, sessionApiAddress } from "@agimon-ai/po-core/native";
2
- import { ArrowRightIcon, Badge, Button, ChevronDownIcon, ChevronRightIcon, CodeBlock, Dot, EmptyState, FileIcon, FolderIcon, Input, ListRow, LiveDuration, Markdown, Sheet, SheetBody, SheetContent, SheetHeader, SheetList, SheetTitle, StatusBadge, Textarea, WorkflowIcon, fontOf } from "@agimon-ai/po-native-components";
1
+ import { createApiClient, defineActivityGroup, defineChannelFile, defineDockFace, defineFill, defineNativePlugin, defineSessionChannel, defineSessionStore, defineToolRenderer, encodeBase64, nativeApiTransport, sessionApiAddress } from "@agimon-ai/po-core/native";
2
+ import { ArrowRightIcon, Badge, Button, ChevronDownIcon, ChevronRightIcon, CodeBlock, Dot, EmptyState, FileIcon, FolderIcon, Input, ListRow, LiveDuration, Markdown, MessageItem, MessageItemBody, MessageItemHeader, MessageItemStatus, Sheet, SheetBody, SheetContent, SheetHeader, SheetList, SheetTitle, StatusBadge, Textarea, WorkflowIcon, fontOf, toolTone } from "@agimon-ai/po-native-components";
3
3
  import { createElement, memo, useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
4
4
  import { View } from "react-native-unistyles/components/native/View";
5
5
  import { Text } from "react-native-unistyles/components/native/Text";
@@ -966,10 +966,10 @@ function WorkflowDuration({ startedAt, endedAt, now, seconds = false, running =
966
966
  //#region src/extensions/workspaces/sessions/(frontend)/_components/DynamicWorkflowView.native.tsx
967
967
  function DynamicWorkflowActivity({ runs, connected = true, onOpen }) {
968
968
  return /* @__PURE__ */ jsxs(View, {
969
- style: styles$5.run,
969
+ style: styles$8.run,
970
970
  children: [
971
971
  /* @__PURE__ */ jsx(Text, {
972
- style: styles$5.dim,
972
+ style: styles$8.dim,
973
973
  children: connected ? activitySummary(runs) : "Connection paused. Showing last update."
974
974
  }),
975
975
  !runs.length && /* @__PURE__ */ jsxs(Button, {
@@ -979,15 +979,15 @@ function DynamicWorkflowActivity({ runs, connected = true, onOpen }) {
979
979
  accessibilityLabel: "Open dynamic workflows",
980
980
  children: [
981
981
  /* @__PURE__ */ jsx(Text, {
982
- style: styles$5.itemTitle,
982
+ style: styles$8.itemTitle,
983
983
  children: "No workflows yet"
984
984
  }),
985
985
  /* @__PURE__ */ jsx(Text, {
986
- style: styles$5.dim,
986
+ style: styles$8.dim,
987
987
  children: "Idle"
988
988
  }),
989
989
  /* @__PURE__ */ jsx(Text, {
990
- style: styles$5.link,
990
+ style: styles$8.link,
991
991
  children: "View workflows →"
992
992
  })
993
993
  ]
@@ -998,27 +998,27 @@ function DynamicWorkflowActivity({ runs, connected = true, onOpen }) {
998
998
  onPress: onOpen,
999
999
  accessibilityRole: "button",
1000
1000
  accessibilityLabel: `Open ${run.label}`,
1001
- style: styles$5.activityRow,
1001
+ style: styles$8.activityRow,
1002
1002
  children: [/* @__PURE__ */ jsxs(View, {
1003
- style: styles$5.inline,
1003
+ style: styles$8.inline,
1004
1004
  children: [
1005
1005
  /* @__PURE__ */ jsx(Dot, {
1006
1006
  tone: statusDot(run.status),
1007
1007
  size: "md"
1008
1008
  }),
1009
1009
  /* @__PURE__ */ jsx(Text, {
1010
- style: styles$5.itemTitle,
1010
+ style: styles$8.itemTitle,
1011
1011
  children: run.label
1012
1012
  }),
1013
1013
  /* @__PURE__ */ jsxs(Text, {
1014
- style: styles$5.dim,
1014
+ style: styles$8.dim,
1015
1015
  children: [WORKFLOW_STATUS[run.status].label, " ›"]
1016
1016
  })
1017
1017
  ]
1018
1018
  }), counts.total > 0 && /* @__PURE__ */ jsxs(View, {
1019
- style: styles$5.activityDetail,
1019
+ style: styles$8.activityDetail,
1020
1020
  children: [/* @__PURE__ */ jsxs(Text, {
1021
- style: styles$5.dim,
1021
+ style: styles$8.dim,
1022
1022
  children: [
1023
1023
  run.status === "running" ? `${counts.running} of ${counts.total} running` : `${counts.total} items`,
1024
1024
  " ",
@@ -1026,7 +1026,7 @@ function DynamicWorkflowActivity({ runs, connected = true, onOpen }) {
1026
1026
  counts.done,
1027
1027
  " done",
1028
1028
  counts.failed > 0 && /* @__PURE__ */ jsxs(Text, {
1029
- style: styles$5.error,
1029
+ style: styles$8.error,
1030
1030
  children: [
1031
1031
  " · ",
1032
1032
  counts.failed,
@@ -1035,9 +1035,9 @@ function DynamicWorkflowActivity({ runs, connected = true, onOpen }) {
1035
1035
  })
1036
1036
  ]
1037
1037
  }), /* @__PURE__ */ jsxs(View, {
1038
- style: styles$5.progress,
1038
+ style: styles$8.progress,
1039
1039
  accessibilityLabel: `${counts.done} done, ${counts.running} running, ${counts.total} total`,
1040
- children: [/* @__PURE__ */ jsx(View, { style: [styles$5.progressDone, { width: `${counts.done / counts.total * 100}%` }] }), /* @__PURE__ */ jsx(View, { style: [styles$5.progressRunning, { width: `${counts.running / counts.total * 100}%` }] })]
1040
+ children: [/* @__PURE__ */ jsx(View, { style: [styles$8.progressDone, { width: `${counts.done / counts.total * 100}%` }] }), /* @__PURE__ */ jsx(View, { style: [styles$8.progressRunning, { width: `${counts.running / counts.total * 100}%` }] })]
1041
1041
  })]
1042
1042
  })]
1043
1043
  }, run.key);
@@ -1049,7 +1049,7 @@ function PhaseTrack({ shape, phases }) {
1049
1049
  if (shape.kind === "step") {
1050
1050
  const phase = phases.find((entry) => entry.key === shape.key);
1051
1051
  return phase ? /* @__PURE__ */ jsx(View, {
1052
- style: styles$5.phase,
1052
+ style: styles$8.phase,
1053
1053
  children: /* @__PURE__ */ jsxs(StatusBadge, {
1054
1054
  tone: WORKFLOW_STATUS[phase.status].tone,
1055
1055
  children: [
@@ -1064,9 +1064,9 @@ function PhaseTrack({ shape, phases }) {
1064
1064
  if (!leaves(shape)) return null;
1065
1065
  const grouped = shape.kind === "parallel" || shape.kind === "branch";
1066
1066
  return /* @__PURE__ */ jsxs(View, {
1067
- style: grouped ? styles$5.phaseGroup : styles$5.phaseSequence,
1067
+ style: grouped ? styles$8.phaseGroup : styles$8.phaseSequence,
1068
1068
  children: [grouped && /* @__PURE__ */ jsx(Text, {
1069
- style: styles$5.dim,
1069
+ style: styles$8.dim,
1070
1070
  children: shape.kind === "parallel" ? "Parallel" : "Branch"
1071
1071
  }), shape.children.map((child) => /* @__PURE__ */ jsx(PhaseTrack, {
1072
1072
  shape: child,
@@ -1077,21 +1077,21 @@ function PhaseTrack({ shape, phases }) {
1077
1077
  function ItemRow({ item, run, now, defaultExpanded, onOpenAgent }) {
1078
1078
  const [expanded, setExpanded] = useState(defaultExpanded);
1079
1079
  return /* @__PURE__ */ jsxs(View, {
1080
- style: styles$5.item,
1080
+ style: styles$8.item,
1081
1081
  children: [
1082
1082
  /* @__PURE__ */ jsxs(Pressable, {
1083
1083
  onPress: () => setExpanded(!expanded),
1084
1084
  accessibilityRole: "button",
1085
1085
  accessibilityLabel: `${item.label}, ${WORKFLOW_STATUS[item.status].label}`,
1086
1086
  accessibilityState: { expanded },
1087
- style: styles$5.toggle,
1087
+ style: styles$8.toggle,
1088
1088
  children: [
1089
1089
  /* @__PURE__ */ jsx(Text, {
1090
- style: styles$5.dim,
1090
+ style: styles$8.dim,
1091
1091
  children: expanded ? "▾" : "▸"
1092
1092
  }),
1093
1093
  /* @__PURE__ */ jsx(Text, {
1094
- style: styles$5.itemTitle,
1094
+ style: styles$8.itemTitle,
1095
1095
  children: item.label
1096
1096
  }),
1097
1097
  /* @__PURE__ */ jsx(StatusBadge, {
@@ -1101,25 +1101,25 @@ function ItemRow({ item, run, now, defaultExpanded, onOpenAgent }) {
1101
1101
  ]
1102
1102
  }),
1103
1103
  /* @__PURE__ */ jsx(View, {
1104
- style: styles$5.track,
1104
+ style: styles$8.track,
1105
1105
  children: /* @__PURE__ */ jsx(PhaseTrack, {
1106
1106
  shape: run.shape,
1107
1107
  phases: item.phases
1108
1108
  })
1109
1109
  }),
1110
1110
  expanded && /* @__PURE__ */ jsx(View, {
1111
- style: styles$5.details,
1111
+ style: styles$8.details,
1112
1112
  children: item.phases.map((phase) => /* @__PURE__ */ jsxs(View, {
1113
- style: styles$5.detail,
1113
+ style: styles$8.detail,
1114
1114
  children: [
1115
1115
  /* @__PURE__ */ jsxs(View, {
1116
- style: styles$5.inline,
1116
+ style: styles$8.inline,
1117
1117
  children: [/* @__PURE__ */ jsx(Text, {
1118
- style: styles$5.title,
1118
+ style: styles$8.title,
1119
1119
  children: phase.label
1120
1120
  }), /* @__PURE__ */ jsx(WorkflowDuration, {
1121
1121
  seconds: true,
1122
- style: styles$5.dim,
1122
+ style: styles$8.dim,
1123
1123
  startedAt: phase.startedAt,
1124
1124
  endedAt: phase.finishedAt,
1125
1125
  running: phase.status === "running",
@@ -1127,16 +1127,16 @@ function ItemRow({ item, run, now, defaultExpanded, onOpenAgent }) {
1127
1127
  })]
1128
1128
  }),
1129
1129
  phase.executionStatus !== phase.status && /* @__PURE__ */ jsxs(Text, {
1130
- style: styles$5.dim,
1130
+ style: styles$8.dim,
1131
1131
  children: ["Step: ", WORKFLOW_STATUS[phase.executionStatus].label]
1132
1132
  }),
1133
1133
  phase.error && /* @__PURE__ */ jsx(Text, {
1134
1134
  accessibilityRole: phase.status === "failed" ? "alert" : void 0,
1135
- style: phase.status === "failed" ? styles$5.error : styles$5.dim,
1135
+ style: phase.status === "failed" ? styles$8.error : styles$8.dim,
1136
1136
  children: phase.error
1137
1137
  }),
1138
1138
  phase.agents.map((agent, index) => /* @__PURE__ */ jsxs(View, {
1139
- style: styles$5.inline,
1139
+ style: styles$8.inline,
1140
1140
  children: [/* @__PURE__ */ jsxs(Button, {
1141
1141
  variant: "link",
1142
1142
  size: "sm",
@@ -1153,7 +1153,7 @@ function ItemRow({ item, run, now, defaultExpanded, onOpenAgent }) {
1153
1153
  })]
1154
1154
  }, agent.runId)),
1155
1155
  !phase.agents.length && /* @__PURE__ */ jsx(Text, {
1156
- style: styles$5.dim,
1156
+ style: styles$8.dim,
1157
1157
  children: "No agent transcript"
1158
1158
  })
1159
1159
  ]
@@ -1164,34 +1164,34 @@ function ItemRow({ item, run, now, defaultExpanded, onOpenAgent }) {
1164
1164
  }
1165
1165
  function DynamicWorkflowView({ runs, now, connected = true, defaultExpandedKeys = [], onOpenAgent }) {
1166
1166
  return /* @__PURE__ */ jsxs(ScrollView, {
1167
- style: styles$5.screen,
1168
- contentContainerStyle: styles$5.content,
1167
+ style: styles$8.screen,
1168
+ contentContainerStyle: styles$8.content,
1169
1169
  accessibilityLabel: "Dynamic workflows",
1170
1170
  children: [
1171
1171
  !connected && /* @__PURE__ */ jsx(Text, {
1172
1172
  accessibilityRole: "alert",
1173
- style: styles$5.notice,
1173
+ style: styles$8.notice,
1174
1174
  children: "Connection paused. These are the last reported workflow states."
1175
1175
  }),
1176
1176
  !runs.length && /* @__PURE__ */ jsxs(View, {
1177
- style: styles$5.empty,
1177
+ style: styles$8.empty,
1178
1178
  children: [/* @__PURE__ */ jsx(Text, {
1179
1179
  accessibilityRole: "header",
1180
- style: styles$5.heading,
1180
+ style: styles$8.heading,
1181
1181
  children: "No workflows yet"
1182
1182
  }), /* @__PURE__ */ jsx(Text, {
1183
- style: styles$5.body,
1183
+ style: styles$8.body,
1184
1184
  children: "Workflows appear here when Po starts them. You can carry on with your conversation."
1185
1185
  })]
1186
1186
  }),
1187
1187
  runs.map((run) => /* @__PURE__ */ jsxs(View, {
1188
- style: styles$5.run,
1188
+ style: styles$8.run,
1189
1189
  children: [
1190
1190
  /* @__PURE__ */ jsxs(View, {
1191
- style: styles$5.inline,
1191
+ style: styles$8.inline,
1192
1192
  children: [/* @__PURE__ */ jsx(Text, {
1193
1193
  accessibilityRole: "header",
1194
- style: styles$5.runTitle,
1194
+ style: styles$8.runTitle,
1195
1195
  children: run.label
1196
1196
  }), /* @__PURE__ */ jsx(StatusBadge, {
1197
1197
  tone: WORKFLOW_STATUS[run.status].tone,
@@ -1199,34 +1199,34 @@ function DynamicWorkflowView({ runs, now, connected = true, defaultExpandedKeys
1199
1199
  })]
1200
1200
  }),
1201
1201
  /* @__PURE__ */ jsxs(View, {
1202
- style: styles$5.inline,
1202
+ style: styles$8.inline,
1203
1203
  children: [/* @__PURE__ */ jsx(WorkflowDuration, {
1204
1204
  seconds: true,
1205
- style: styles$5.dim,
1205
+ style: styles$8.dim,
1206
1206
  startedAt: run.startedAt,
1207
1207
  endedAt: run.finishedAt,
1208
1208
  running: run.status === "running",
1209
1209
  now
1210
1210
  }), /* @__PURE__ */ jsx(Text, {
1211
- style: styles$5.dim,
1211
+ style: styles$8.dim,
1212
1212
  children: run.executionStatus !== run.status ? ` · Workflow execution: ${WORKFLOW_STATUS[run.executionStatus].label}` : ""
1213
1213
  })]
1214
1214
  }),
1215
1215
  run.error && /* @__PURE__ */ jsx(Text, {
1216
1216
  accessibilityRole: run.status === "failed" ? "alert" : void 0,
1217
- style: run.status === "failed" ? styles$5.error : styles$5.dim,
1217
+ style: run.status === "failed" ? styles$8.error : styles$8.dim,
1218
1218
  children: run.error
1219
1219
  }),
1220
1220
  run.groups.map((group) => /* @__PURE__ */ jsxs(View, {
1221
- style: styles$5.group,
1221
+ style: styles$8.group,
1222
1222
  children: [
1223
1223
  /* @__PURE__ */ jsx(Text, {
1224
1224
  accessibilityRole: "header",
1225
- style: styles$5.title,
1225
+ style: styles$8.title,
1226
1226
  children: group.label
1227
1227
  }),
1228
1228
  /* @__PURE__ */ jsxs(Text, {
1229
- style: styles$5.dim,
1229
+ style: styles$8.dim,
1230
1230
  children: [groupSummary(group), group.concurrency ? ` · Up to ${group.concurrency} at once` : ""]
1231
1231
  }),
1232
1232
  group.items.map((item) => /* @__PURE__ */ jsx(ItemRow, {
@@ -1237,7 +1237,7 @@ function DynamicWorkflowView({ runs, now, connected = true, defaultExpandedKeys
1237
1237
  onOpenAgent
1238
1238
  }, item.key)),
1239
1239
  group.truncated && /* @__PURE__ */ jsxs(Text, {
1240
- style: styles$5.dim,
1240
+ style: styles$8.dim,
1241
1241
  children: [
1242
1242
  "Showing ",
1243
1243
  group.items.length,
@@ -1253,7 +1253,7 @@ function DynamicWorkflowView({ runs, now, connected = true, defaultExpandedKeys
1253
1253
  ]
1254
1254
  });
1255
1255
  }
1256
- const styles$5 = StyleSheet.create((theme) => ({
1256
+ const styles$8 = StyleSheet.create((theme) => ({
1257
1257
  activityRow: {
1258
1258
  minHeight: 44,
1259
1259
  padding: theme.spacing(3),
@@ -1475,9 +1475,9 @@ function StepDynamicRunsNote({ stepSessionId }) {
1475
1475
  const summary = stepRunsSummary(runs);
1476
1476
  return /* @__PURE__ */ jsxs(Text, {
1477
1477
  testID: `step-dynamic-note-${stepSessionId}`,
1478
- style: styles$4.summary,
1478
+ style: styles$7.summary,
1479
1479
  children: [summary.text, summary.failed > 0 ? /* @__PURE__ */ jsxs(Text, {
1480
- style: styles$4.failed,
1480
+ style: styles$7.failed,
1481
1481
  children: [
1482
1482
  " · ",
1483
1483
  summary.failed,
@@ -1497,13 +1497,13 @@ function StepDynamicRuns({ stepSessionId, openSession }) {
1497
1497
  const summary = stepRunsSummary(runs);
1498
1498
  return /* @__PURE__ */ jsxs(View, {
1499
1499
  testID: "step-dynamic-runs",
1500
- style: styles$4.section(open),
1500
+ style: styles$7.section(open),
1501
1501
  children: [/* @__PURE__ */ jsxs(Pressable, {
1502
1502
  accessibilityRole: "button",
1503
1503
  accessibilityState: { expanded: open },
1504
1504
  testID: "step-dynamic-runs-toggle",
1505
1505
  onPress: () => setOpen(!open),
1506
- style: styles$4.toggle,
1506
+ style: styles$7.toggle,
1507
1507
  children: [
1508
1508
  open ? /* @__PURE__ */ jsx(ChevronDownIcon, {
1509
1509
  size: 12,
@@ -1513,14 +1513,14 @@ function StepDynamicRuns({ stepSessionId, openSession }) {
1513
1513
  color: "faint"
1514
1514
  }),
1515
1515
  /* @__PURE__ */ jsx(Text, {
1516
- style: styles$4.title,
1516
+ style: styles$7.title,
1517
1517
  children: "Dynamic workflows"
1518
1518
  }),
1519
1519
  /* @__PURE__ */ jsxs(Text, {
1520
1520
  numberOfLines: 1,
1521
- style: styles$4.summary,
1521
+ style: styles$7.summary,
1522
1522
  children: [summary.text, summary.failed > 0 ? /* @__PURE__ */ jsxs(Text, {
1523
- style: styles$4.failed,
1523
+ style: styles$7.failed,
1524
1524
  children: [
1525
1525
  " · ",
1526
1526
  summary.failed,
@@ -1530,7 +1530,7 @@ function StepDynamicRuns({ stepSessionId, openSession }) {
1530
1530
  })
1531
1531
  ]
1532
1532
  }), open ? /* @__PURE__ */ jsx(ScrollView, {
1533
- style: styles$4.runs,
1533
+ style: styles$7.runs,
1534
1534
  children: /* @__PURE__ */ jsx(DynamicWorkflowView, {
1535
1535
  runs,
1536
1536
  onOpenAgent: () => openSession?.(stepSessionId)
@@ -1538,7 +1538,7 @@ function StepDynamicRuns({ stepSessionId, openSession }) {
1538
1538
  }) : null]
1539
1539
  });
1540
1540
  }
1541
- const styles$4 = StyleSheet.create((theme) => ({
1541
+ const styles$7 = StyleSheet.create((theme) => ({
1542
1542
  section: (open) => ({
1543
1543
  flex: open ? 2 : 0,
1544
1544
  flexShrink: open ? 1 : 0,
@@ -1592,13 +1592,13 @@ function Status({ state }) {
1592
1592
  }
1593
1593
  function Heading({ title, count }) {
1594
1594
  return /* @__PURE__ */ jsxs(View, {
1595
- style: styles$3.section,
1595
+ style: styles$6.section,
1596
1596
  children: [/* @__PURE__ */ jsx(Text, {
1597
1597
  accessibilityRole: "header",
1598
- style: styles$3.heading,
1598
+ style: styles$6.heading,
1599
1599
  children: title
1600
1600
  }), /* @__PURE__ */ jsx(Text, {
1601
- style: styles$3.meta,
1601
+ style: styles$6.meta,
1602
1602
  children: count
1603
1603
  })]
1604
1604
  });
@@ -1607,9 +1607,9 @@ function Duration({ start, end, now }) {
1607
1607
  return now === void 0 ? /* @__PURE__ */ jsx(WorkflowDuration, {
1608
1608
  startedAt: start,
1609
1609
  endedAt: end,
1610
- style: styles$3.meta
1610
+ style: styles$6.meta
1611
1611
  }) : /* @__PURE__ */ jsx(Text, {
1612
- style: styles$3.meta,
1612
+ style: styles$6.meta,
1613
1613
  children: start === void 0 ? "" : formatRunDuration(Math.max(0, (end === void 0 ? now : Date.parse(end)) - Date.parse(start)))
1614
1614
  });
1615
1615
  }
@@ -1622,7 +1622,7 @@ function Job({ job, now, onOpen }) {
1622
1622
  accessibilityLabel: `${job.name}, ${job.status}`,
1623
1623
  accessibilityState: { expanded: open },
1624
1624
  onPress: () => setOpen(!open),
1625
- style: styles$3.job,
1625
+ style: styles$6.job,
1626
1626
  children: [
1627
1627
  open ? /* @__PURE__ */ jsx(ChevronDownIcon, {
1628
1628
  size: 16,
@@ -1632,11 +1632,11 @@ function Job({ job, now, onOpen }) {
1632
1632
  color: "dim"
1633
1633
  }),
1634
1634
  /* @__PURE__ */ jsx(Text, {
1635
- style: styles$3.name,
1635
+ style: styles$6.name,
1636
1636
  children: job.name
1637
1637
  }),
1638
1638
  /* @__PURE__ */ jsxs(Text, {
1639
- style: styles$3.meta,
1639
+ style: styles$6.meta,
1640
1640
  children: [
1641
1641
  done,
1642
1642
  "/",
@@ -1652,15 +1652,15 @@ function Job({ job, now, onOpen }) {
1652
1652
  ]
1653
1653
  }),
1654
1654
  job.reason ? /* @__PURE__ */ jsx(Text, {
1655
- style: styles$3.reason,
1655
+ style: styles$6.reason,
1656
1656
  children: job.reason
1657
1657
  }) : null,
1658
1658
  open ? job.steps.map((step) => /* @__PURE__ */ jsx(ListRow, {
1659
- style: styles$3.step,
1659
+ style: styles$6.step,
1660
1660
  title: step.name,
1661
1661
  leading: /* @__PURE__ */ jsx(Dot, { tone: step.status === "failed" ? "red" : step.status === "running" || step.status === "resumed" ? "yellow" : step.status === "completed" ? "green" : "muted" }),
1662
1662
  description: /* @__PURE__ */ jsxs(View, { children: [/* @__PURE__ */ jsx(Text, {
1663
- style: styles$3.meta,
1663
+ style: styles$6.meta,
1664
1664
  children: [
1665
1665
  step.status,
1666
1666
  step.group ? `∥ ${step.group}` : void 0,
@@ -1681,7 +1681,7 @@ function Job({ job, now, onOpen }) {
1681
1681
  function WorkflowArtifactList({ listing, error, loading = false, onOpen, onParent }) {
1682
1682
  const artifacts = listing?.artifacts ?? [];
1683
1683
  return /* @__PURE__ */ jsxs(View, {
1684
- style: styles$3.artifacts,
1684
+ style: styles$6.artifacts,
1685
1685
  children: [
1686
1686
  /* @__PURE__ */ jsx(Heading, {
1687
1687
  title: "Artifacts",
@@ -1694,11 +1694,11 @@ function WorkflowArtifactList({ listing, error, loading = false, onOpen, onParen
1694
1694
  }) : null,
1695
1695
  error ? /* @__PURE__ */ jsx(Text, {
1696
1696
  accessibilityRole: "alert",
1697
- style: styles$3.error,
1697
+ style: styles$6.error,
1698
1698
  children: error
1699
1699
  }) : null,
1700
1700
  loading ? /* @__PURE__ */ jsx(Text, {
1701
- style: styles$3.reason,
1701
+ style: styles$6.reason,
1702
1702
  children: "Loading artifacts…"
1703
1703
  }) : null,
1704
1704
  artifacts.map((artifact) => /* @__PURE__ */ jsx(ListRow, {
@@ -1715,7 +1715,7 @@ function WorkflowArtifactList({ listing, error, loading = false, onOpen, onParen
1715
1715
  onPress: artifact.state === "pending" || artifact.state === "unreadable" ? void 0 : () => onOpen(artifact)
1716
1716
  }, artifact.path)),
1717
1717
  !artifacts.length && !loading && !error ? /* @__PURE__ */ jsx(Text, {
1718
- style: styles$3.reason,
1718
+ style: styles$6.reason,
1719
1719
  children: "No artifacts yet."
1720
1720
  }) : null
1721
1721
  ]
@@ -1734,20 +1734,20 @@ function WorkflowDockView({ run, runs, now, sheet = false, dockHeader, artifacts
1734
1734
  const header = /* @__PURE__ */ jsxs(Fragment, { children: [
1735
1735
  dockHeader,
1736
1736
  run ? /* @__PURE__ */ jsxs(View, {
1737
- style: styles$3.header,
1737
+ style: styles$6.header,
1738
1738
  children: [
1739
1739
  /* @__PURE__ */ jsxs(View, {
1740
- style: styles$3.row,
1740
+ style: styles$6.row,
1741
1741
  children: [/* @__PURE__ */ jsx(Text, {
1742
1742
  accessibilityRole: "header",
1743
- style: styles$3.title,
1743
+ style: styles$6.title,
1744
1744
  children: run.displayName
1745
1745
  }), /* @__PURE__ */ jsx(Status, { state: runState(run) })]
1746
1746
  }),
1747
1747
  /* @__PURE__ */ jsxs(View, {
1748
- style: styles$3.row,
1748
+ style: styles$6.row,
1749
1749
  children: [/* @__PURE__ */ jsx(Text, {
1750
- style: styles$3.flexMeta,
1750
+ style: styles$6.flexMeta,
1751
1751
  children: [run.position?.job, run.position?.step].filter(Boolean).join(" › ") || (run.stage === "running" ? "Starting" : run.workflowPath)
1752
1752
  }), /* @__PURE__ */ jsx(Duration, {
1753
1753
  start: run.startedAt,
@@ -1763,18 +1763,18 @@ function WorkflowDockView({ run, runs, now, sheet = false, dockHeader, artifacts
1763
1763
  ]
1764
1764
  }) : null,
1765
1765
  attention ? /* @__PURE__ */ jsxs(View, {
1766
- style: [styles$3.attention, attention.kind === "paused" ? styles$3.ask : styles$3.failure],
1766
+ style: [styles$6.attention, attention.kind === "paused" ? styles$6.ask : styles$6.failure],
1767
1767
  children: [
1768
1768
  /* @__PURE__ */ jsx(Text, {
1769
- style: styles$3.heading,
1769
+ style: styles$6.heading,
1770
1770
  children: attention.kind === "error" ? "Run failed" : attention.kind === "stale" ? "Progress stopped" : "Paused"
1771
1771
  }),
1772
1772
  /* @__PURE__ */ jsx(Text, {
1773
- style: styles$3.body,
1773
+ style: styles$6.body,
1774
1774
  children: attentionText
1775
1775
  }),
1776
1776
  /* @__PURE__ */ jsx(Text, {
1777
- style: styles$3.meta,
1777
+ style: styles$6.meta,
1778
1778
  children: attention.kind === "paused" ? "Ask the agent in this conversation to resume it." : "Ask the agent in this conversation to diagnose or recover it."
1779
1779
  })
1780
1780
  ]
@@ -1799,13 +1799,13 @@ function WorkflowDockView({ run, runs, now, sheet = false, dockHeader, artifacts
1799
1799
  }) : null
1800
1800
  ] });
1801
1801
  const details = mode === "picker" ? /* @__PURE__ */ jsxs(View, {
1802
- style: styles$3.picker,
1802
+ style: styles$6.picker,
1803
1803
  children: [
1804
1804
  /* @__PURE__ */ jsxs(View, {
1805
- style: styles$3.row,
1805
+ style: styles$6.row,
1806
1806
  children: [/* @__PURE__ */ jsx(Text, {
1807
1807
  accessibilityRole: "header",
1808
- style: styles$3.title,
1808
+ style: styles$6.title,
1809
1809
  children: "Switch run"
1810
1810
  }), /* @__PURE__ */ jsx(Button, {
1811
1811
  variant: "ghost",
@@ -1820,7 +1820,7 @@ function WorkflowDockView({ run, runs, now, sheet = false, dockHeader, artifacts
1820
1820
  onChangeText: setSearch
1821
1821
  }),
1822
1822
  /* @__PURE__ */ jsx(View, {
1823
- style: styles$3.filters,
1823
+ style: styles$6.filters,
1824
1824
  children: Object.values(FILTER).map((value) => /* @__PURE__ */ jsx(Button, {
1825
1825
  variant: filter === value ? "secondary" : "ghost",
1826
1826
  accessibilityState: { selected: filter === value },
@@ -1844,24 +1844,24 @@ function WorkflowDockView({ run, runs, now, sheet = false, dockHeader, artifacts
1844
1844
  }, `${item.workspace}/${item.routeKey ?? item.runKey}`))
1845
1845
  ]
1846
1846
  }) : mode === "delete" ? /* @__PURE__ */ jsxs(View, {
1847
- style: styles$3.picker,
1847
+ style: styles$6.picker,
1848
1848
  children: [
1849
1849
  /* @__PURE__ */ jsx(Text, {
1850
1850
  accessibilityRole: "header",
1851
- style: styles$3.title,
1851
+ style: styles$6.title,
1852
1852
  children: "Delete this run?"
1853
1853
  }),
1854
1854
  /* @__PURE__ */ jsx(Text, {
1855
- style: styles$3.body,
1855
+ style: styles$6.body,
1856
1856
  children: "This permanently removes the settled run and its directory, including logs and artifacts."
1857
1857
  }),
1858
1858
  /* @__PURE__ */ jsx(Text, {
1859
- style: styles$3.meta,
1859
+ style: styles$6.meta,
1860
1860
  children: run?.displayName
1861
1861
  }),
1862
1862
  error ? /* @__PURE__ */ jsx(Text, {
1863
1863
  accessibilityRole: "alert",
1864
- style: styles$3.error,
1864
+ style: styles$6.error,
1865
1865
  children: error
1866
1866
  }) : null,
1867
1867
  /* @__PURE__ */ jsx(Button, {
@@ -1879,7 +1879,7 @@ function WorkflowDockView({ run, runs, now, sheet = false, dockHeader, artifacts
1879
1879
  ]
1880
1880
  }) : null;
1881
1881
  return /* @__PURE__ */ jsx(View, {
1882
- style: styles$3.frame,
1882
+ style: styles$6.frame,
1883
1883
  children: details ? sheet ? /* @__PURE__ */ jsx(SheetList, {
1884
1884
  embedded: true,
1885
1885
  data: [],
@@ -1891,7 +1891,7 @@ function WorkflowDockView({ run, runs, now, sheet = false, dockHeader, artifacts
1891
1891
  children: details
1892
1892
  }) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(List, {
1893
1893
  ...sheet ? { embedded: true } : {},
1894
- style: styles$3.list,
1894
+ style: styles$6.list,
1895
1895
  data: run?.jobs ?? [],
1896
1896
  keyExtractor: (job) => job.name,
1897
1897
  keyboardShouldPersistTaps: "handled",
@@ -1913,10 +1913,10 @@ function WorkflowDockView({ run, runs, now, sheet = false, dockHeader, artifacts
1913
1913
  })
1914
1914
  }) : void 0
1915
1915
  }), run ? /* @__PURE__ */ jsxs(View, {
1916
- style: styles$3.actions,
1916
+ style: styles$6.actions,
1917
1917
  children: [error ? /* @__PURE__ */ jsx(Text, {
1918
1918
  accessibilityRole: "alert",
1919
- style: styles$3.error,
1919
+ style: styles$6.error,
1920
1920
  children: error
1921
1921
  }) : null, /* @__PURE__ */ jsx(Button, {
1922
1922
  variant: "danger-outline",
@@ -1927,7 +1927,7 @@ function WorkflowDockView({ run, runs, now, sheet = false, dockHeader, artifacts
1927
1927
  }) : null] })
1928
1928
  });
1929
1929
  }
1930
- const styles$3 = StyleSheet.create((theme) => {
1930
+ const styles$6 = StyleSheet.create((theme) => {
1931
1931
  const text = {
1932
1932
  fontFamily: fontOf(theme.fontFamily.sans),
1933
1933
  fontSize: theme.fontSize.base,
@@ -2165,10 +2165,10 @@ const DelimitedArtifact = memo(function DelimitedArtifact({ text, delimiter, ini
2165
2165
  columns
2166
2166
  ]);
2167
2167
  return /* @__PURE__ */ jsxs(View, {
2168
- style: styles$2.body,
2168
+ style: styles$5.body,
2169
2169
  children: [
2170
2170
  /* @__PURE__ */ jsxs(Text, {
2171
- style: styles$2.meta,
2171
+ style: styles$5.meta,
2172
2172
  accessibilityLiveRegion: "polite",
2173
2173
  children: [
2174
2174
  "Rows ",
@@ -2186,26 +2186,26 @@ const DelimitedArtifact = memo(function DelimitedArtifact({ text, delimiter, ini
2186
2186
  ]
2187
2187
  }),
2188
2188
  /* @__PURE__ */ jsx(Text, {
2189
- style: styles$2.copy,
2189
+ style: styles$5.copy,
2190
2190
  children: "Scroll within the preview. Load more rows or columns when you need them."
2191
2191
  }),
2192
2192
  /* @__PURE__ */ jsx(ScrollView, {
2193
- style: styles$2.preview,
2193
+ style: styles$5.preview,
2194
2194
  nestedScrollEnabled: true,
2195
2195
  children: /* @__PURE__ */ jsx(ScrollView, {
2196
2196
  horizontal: true,
2197
2197
  children: /* @__PURE__ */ jsxs(View, { children: [/* @__PURE__ */ jsx(View, {
2198
- style: styles$2.tableRow,
2198
+ style: styles$5.tableRow,
2199
2199
  children: Array.from({ length: columns }, (_, column) => /* @__PURE__ */ jsxs(Text, {
2200
2200
  selectable: true,
2201
- style: styles$2.cell,
2201
+ style: styles$5.cell,
2202
2202
  children: ["Column ", column + 1]
2203
2203
  }, column))
2204
2204
  }), cells.map((values, row) => /* @__PURE__ */ jsx(View, {
2205
- style: styles$2.tableRow,
2205
+ style: styles$5.tableRow,
2206
2206
  children: Array.from({ length: columns }, (_, column) => /* @__PURE__ */ jsx(Text, {
2207
2207
  selectable: true,
2208
- style: styles$2.cell,
2208
+ style: styles$5.cell,
2209
2209
  children: values[column] ?? ""
2210
2210
  }, column))
2211
2211
  }, row))] })
@@ -2234,7 +2234,7 @@ const DelimitedArtifact = memo(function DelimitedArtifact({ text, delimiter, ini
2234
2234
  ]
2235
2235
  });
2236
2236
  });
2237
- const styles$2 = StyleSheet.create((theme) => ({
2237
+ const styles$5 = StyleSheet.create((theme) => ({
2238
2238
  body: {
2239
2239
  flex: 1,
2240
2240
  padding: theme.spacing(4),
@@ -2333,7 +2333,7 @@ function WorkflowLauncher(props) {
2333
2333
  setSelected(void 0);
2334
2334
  }
2335
2335
  }, workflow.path) : /* @__PURE__ */ jsxs(View, {
2336
- style: styles$1.body,
2336
+ style: styles$4.body,
2337
2337
  children: [
2338
2338
  /* @__PURE__ */ jsx(Input, {
2339
2339
  accessibilityLabel: "Find a workflow",
@@ -2342,13 +2342,13 @@ function WorkflowLauncher(props) {
2342
2342
  placeholder: "Find a workflow"
2343
2343
  }),
2344
2344
  state.warning ? /* @__PURE__ */ jsx(Text, {
2345
- style: styles$1.error,
2345
+ style: styles$4.error,
2346
2346
  children: state.warning
2347
2347
  }) : null,
2348
2348
  filterCatalog(state.workflows, filter).map((item) => /* @__PURE__ */ jsx(ListRow, {
2349
2349
  title: item.name || item.relativePath,
2350
2350
  description: item.error !== void 0 ? /* @__PURE__ */ jsx(Text, {
2351
- style: styles$1.error,
2351
+ style: styles$4.error,
2352
2352
  children: item.error
2353
2353
  }) : item.description || item.jobs.map((job) => job.name).join(", "),
2354
2354
  disabled: item.error !== void 0,
@@ -2357,7 +2357,7 @@ function WorkflowLauncher(props) {
2357
2357
  }
2358
2358
  }, item.path)),
2359
2359
  state.workflows.length === 0 ? /* @__PURE__ */ jsx(Text, {
2360
- style: styles$1.meta,
2360
+ style: styles$4.meta,
2361
2361
  children: "No workflows reported yet."
2362
2362
  }) : null
2363
2363
  ]
@@ -2366,7 +2366,7 @@ function WorkflowLauncher(props) {
2366
2366
  }
2367
2367
  function Choice({ label, options, value, onChange }) {
2368
2368
  return /* @__PURE__ */ jsxs(View, { children: [/* @__PURE__ */ jsx(Text, {
2369
- style: styles$1.meta,
2369
+ style: styles$4.meta,
2370
2370
  children: label
2371
2371
  }), options.map((option) => /* @__PURE__ */ jsx(Button, {
2372
2372
  variant: "outline",
@@ -2393,10 +2393,10 @@ function WorkflowLaunch({ sessionId, workflow, initialPrompt, sendSessionFrame,
2393
2393
  const problems = [...launchProblems(workflow, request), ...workflow.error === void 0 ? [] : [workflow.error]];
2394
2394
  const line = workflowLaunchLine(request);
2395
2395
  return /* @__PURE__ */ jsxs(View, {
2396
- style: styles$1.body,
2396
+ style: styles$4.body,
2397
2397
  children: [
2398
2398
  /* @__PURE__ */ jsx(Text, {
2399
- style: styles$1.meta,
2399
+ style: styles$4.meta,
2400
2400
  children: workflow.description
2401
2401
  }),
2402
2402
  /* @__PURE__ */ jsx(Textarea, {
@@ -2408,7 +2408,7 @@ function WorkflowLaunch({ sessionId, workflow, initialPrompt, sendSessionFrame,
2408
2408
  workflow.inputs.map((input) => {
2409
2409
  const options = input.options ?? (input.type === "boolean" ? ["true", "false"] : void 0);
2410
2410
  return /* @__PURE__ */ jsxs(View, { children: [/* @__PURE__ */ jsxs(Text, {
2411
- style: styles$1.meta,
2411
+ style: styles$4.meta,
2412
2412
  children: [
2413
2413
  input.name,
2414
2414
  input.required ? " (required)" : "",
@@ -2452,11 +2452,11 @@ function WorkflowLaunch({ sessionId, workflow, initialPrompt, sendSessionFrame,
2452
2452
  }) : null,
2453
2453
  /* @__PURE__ */ jsx(CodeBlock, { text: line }),
2454
2454
  problems.map((problem) => /* @__PURE__ */ jsx(Text, {
2455
- style: styles$1.meta,
2455
+ style: styles$4.meta,
2456
2456
  children: problem
2457
2457
  }, problem)),
2458
2458
  error ? /* @__PURE__ */ jsx(Text, {
2459
- style: styles$1.error,
2459
+ style: styles$4.error,
2460
2460
  children: error
2461
2461
  }) : null,
2462
2462
  /* @__PURE__ */ jsx(Button, {
@@ -2481,7 +2481,7 @@ function WorkflowPanel(props) {
2481
2481
  const identity = props.identity ?? state.focusedRun;
2482
2482
  const run = state.runs.find((item) => workflowRunIdentity(item) === identity) ?? (props.identity === void 0 ? state.runs[0] : void 0);
2483
2483
  if (props.identity !== void 0 && !run) return /* @__PURE__ */ jsx(Text, {
2484
- style: styles$1.meta,
2484
+ style: styles$4.meta,
2485
2485
  children: "This run is no longer listed."
2486
2486
  });
2487
2487
  return /* @__PURE__ */ jsx(WorkflowRunPanel, {
@@ -2614,9 +2614,9 @@ function WorkflowStep({ sessionId, workspace, runKey, job, step, renderSessionTr
2614
2614
  session
2615
2615
  ]);
2616
2616
  return /* @__PURE__ */ jsxs(View, {
2617
- style: styles$1.screen,
2617
+ style: styles$4.screen,
2618
2618
  children: [/* @__PURE__ */ jsxs(Text, {
2619
- style: styles$1.title,
2619
+ style: styles$4.title,
2620
2620
  children: [
2621
2621
  job,
2622
2622
  step === void 0 ? "" : ` › ${step}`,
@@ -2701,7 +2701,7 @@ function WorkflowTerminal({ sessionId, workspace, runKey, pane, renderRunnerTerm
2701
2701
  }
2702
2702
  };
2703
2703
  return /* @__PURE__ */ jsxs(View, {
2704
- style: styles$1.transcript,
2704
+ style: styles$4.transcript,
2705
2705
  children: [
2706
2706
  /* @__PURE__ */ jsx(Badge, { children: token ? "keyboard yours" : "watching" }),
2707
2707
  capabilities?.writable ? /* @__PURE__ */ jsx(Button, {
@@ -2714,11 +2714,11 @@ function WorkflowTerminal({ sessionId, workspace, runKey, pane, renderRunnerTerm
2714
2714
  children: token ? "Release keyboard" : "Take control"
2715
2715
  }) : null,
2716
2716
  /* @__PURE__ */ jsx(View, {
2717
- style: styles$1.transcript,
2717
+ style: styles$4.transcript,
2718
2718
  children: renderRunnerTerminal?.(request)
2719
2719
  }),
2720
2720
  capabilities?.reason ? /* @__PURE__ */ jsx(Text, {
2721
- style: styles$1.meta,
2721
+ style: styles$4.meta,
2722
2722
  children: capabilities.reason
2723
2723
  }) : null,
2724
2724
  token && capabilities?.resizable ? /* @__PURE__ */ jsxs(View, { children: [
@@ -2746,7 +2746,7 @@ function WorkflowTerminal({ sessionId, workspace, runKey, pane, renderRunnerTerm
2746
2746
  })
2747
2747
  ] }) : null,
2748
2748
  notice ? /* @__PURE__ */ jsx(Text, {
2749
- style: styles$1.meta,
2749
+ style: styles$4.meta,
2750
2750
  children: notice
2751
2751
  }) : null
2752
2752
  ]
@@ -2869,7 +2869,7 @@ function ArtifactPreview({ sessionId, workspace, runKey, path, renderFilePreview
2869
2869
  const delimited = !raw && content?.text !== void 0 && /\.(csv|tsv)$/i.test(path);
2870
2870
  const preview = /* @__PURE__ */ jsxs(Fragment, { children: [
2871
2871
  /* @__PURE__ */ jsx(Text, {
2872
- style: styles$1.title,
2872
+ style: styles$4.title,
2873
2873
  children: path
2874
2874
  }),
2875
2875
  /* @__PURE__ */ jsx(Button, {
@@ -2884,11 +2884,11 @@ function ArtifactPreview({ sessionId, workspace, runKey, path, renderFilePreview
2884
2884
  children: "Cancel download"
2885
2885
  }) : null,
2886
2886
  saveNote ? /* @__PURE__ */ jsx(Text, {
2887
- style: styles$1.meta,
2887
+ style: styles$4.meta,
2888
2888
  children: saveNote
2889
2889
  }) : null,
2890
2890
  error ? /* @__PURE__ */ jsx(Text, {
2891
- style: styles$1.error,
2891
+ style: styles$4.error,
2892
2892
  children: error
2893
2893
  }) : null,
2894
2894
  content?.text !== void 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -2906,7 +2906,7 @@ function ArtifactPreview({ sessionId, workspace, runKey, path, renderFilePreview
2906
2906
  delimiter: /\.csv$/i.test(path) ? "," : " "
2907
2907
  }) : /* @__PURE__ */ jsx(CodeBlock, { text: !raw && /\.json$/i.test(path) ? prettyJson(content.text) : content.text }),
2908
2908
  content.truncated ? /* @__PURE__ */ jsx(Text, {
2909
- style: styles$1.meta,
2909
+ style: styles$4.meta,
2910
2910
  children: "This preview was truncated."
2911
2911
  }) : null
2912
2912
  ] }) : content ? /* @__PURE__ */ jsx(BinaryArtifactPreview, {
@@ -2916,15 +2916,15 @@ function ArtifactPreview({ sessionId, workspace, runKey, path, renderFilePreview
2916
2916
  path,
2917
2917
  renderMediaPreview
2918
2918
  }) : /* @__PURE__ */ jsx(Text, {
2919
- style: styles$1.meta,
2919
+ style: styles$4.meta,
2920
2920
  children: "Loading preview…"
2921
2921
  })
2922
2922
  ] });
2923
2923
  return delimited ? /* @__PURE__ */ jsx(View, {
2924
- style: [styles$1.body, styles$1.transcript],
2924
+ style: [styles$4.body, styles$4.transcript],
2925
2925
  children: preview
2926
2926
  }) : /* @__PURE__ */ jsx(ScrollView, {
2927
- contentContainerStyle: styles$1.body,
2927
+ contentContainerStyle: styles$4.body,
2928
2928
  children: preview
2929
2929
  });
2930
2930
  }
@@ -2965,7 +2965,7 @@ function BinaryArtifactPreview({ sessionId, workspace, runKey, path, renderMedia
2965
2965
  title: path,
2966
2966
  path
2967
2967
  }) : /* @__PURE__ */ jsx(Text, {
2968
- style: styles$1.meta,
2968
+ style: styles$4.meta,
2969
2969
  children: error ?? "Loading preview…"
2970
2970
  });
2971
2971
  }
@@ -2976,7 +2976,7 @@ function prettyJson(text) {
2976
2976
  return text;
2977
2977
  }
2978
2978
  }
2979
- const styles$1 = StyleSheet.create((theme) => ({
2979
+ const styles$4 = StyleSheet.create((theme) => ({
2980
2980
  screen: {
2981
2981
  flex: 1,
2982
2982
  backgroundColor: theme.colors.bg,
@@ -3055,7 +3055,7 @@ function WorkflowDockPanel(props) {
3055
3055
  }
3056
3056
  //#endregion
3057
3057
  //#region src/extensions/workspaces/sessions/(frontend)/dock/workflow.native.tsx
3058
- var workflow_native_default = defineDockFace({
3058
+ var workflow_native_default$1 = defineDockFace({
3059
3059
  id: "workflow",
3060
3060
  label: "Workflow",
3061
3061
  order: 20,
@@ -3154,12 +3154,12 @@ function WorkflowsActivitySection({ sessionId, openSession, openTransientTab })
3154
3154
  alignItems: "center"
3155
3155
  },
3156
3156
  children: [/* @__PURE__ */ jsxs(Text, {
3157
- style: styles.status,
3157
+ style: styles$3.status,
3158
3158
  children: [row.detail, " · "]
3159
3159
  }), /* @__PURE__ */ jsx(WorkflowDuration, {
3160
3160
  startedAt: row.startedAt,
3161
3161
  endedAt: row.finishedAt,
3162
- style: styles.status
3162
+ style: styles$3.status
3163
3163
  })]
3164
3164
  })
3165
3165
  }, row.identity)) : null] }, group.name);
@@ -3167,7 +3167,7 @@ function WorkflowsActivitySection({ sessionId, openSession, openTransientTab })
3167
3167
  dynamicRuns.length > 0 ? /* @__PURE__ */ jsxs(View, {
3168
3168
  testID: "activity-dynamic-workflows",
3169
3169
  children: [/* @__PURE__ */ jsx(Text, {
3170
- style: styles.heading,
3170
+ style: styles$3.heading,
3171
3171
  children: "Dynamic"
3172
3172
  }), /* @__PURE__ */ jsx(DynamicWorkflowActivity, {
3173
3173
  runs: dynamicRuns,
@@ -3175,9 +3175,9 @@ function WorkflowsActivitySection({ sessionId, openSession, openTransientTab })
3175
3175
  })]
3176
3176
  }) : null,
3177
3177
  /* @__PURE__ */ jsxs(View, {
3178
- style: styles.idle,
3178
+ style: styles$3.idle,
3179
3179
  children: [groups.length === 0 && dynamicRuns.length === 0 ? /* @__PURE__ */ jsx(Text, {
3180
- style: styles.status,
3180
+ style: styles$3.status,
3181
3181
  children: "Idle"
3182
3182
  }) : null, /* @__PURE__ */ jsxs(Pressable, {
3183
3183
  accessibilityRole: "button",
@@ -3188,9 +3188,9 @@ function WorkflowsActivitySection({ sessionId, openSession, openTransientTab })
3188
3188
  onPress: () => {
3189
3189
  if (sessionId !== null) openCatalog(sessionId);
3190
3190
  },
3191
- style: styles.action,
3191
+ style: styles$3.action,
3192
3192
  children: [/* @__PURE__ */ jsx(Text, {
3193
- style: styles.actionText(sessionId === null),
3193
+ style: styles$3.actionText(sessionId === null),
3194
3194
  children: "Launch a workflow"
3195
3195
  }), /* @__PURE__ */ jsx(ArrowRightIcon, {
3196
3196
  size: 14,
@@ -3200,7 +3200,7 @@ function WorkflowsActivitySection({ sessionId, openSession, openTransientTab })
3200
3200
  })
3201
3201
  ] });
3202
3202
  }
3203
- const styles = StyleSheet.create((theme) => ({
3203
+ const styles$3 = StyleSheet.create((theme) => ({
3204
3204
  idle: {
3205
3205
  flexDirection: "row",
3206
3206
  alignItems: "center",
@@ -3243,6 +3243,1406 @@ const styles = StyleSheet.create((theme) => ({
3243
3243
  //#region src/extensions/workspaces/sessions/(frontend)/fill/Workflows.activity.workflows.native.tsx
3244
3244
  var Workflows_activity_workflows_native_default = defineFill({ component: WorkflowsActivitySection });
3245
3245
  //#endregion
3246
+ //#region src/extensions/workspaces/sessions/(frontend)/tool/_lib/workflowToolRender.ts
3247
+ const COLLAPSED_CATALOG_ROWS = 6;
3248
+ const COLLAPSED_DETAIL_LINES = 8;
3249
+ const WORKFLOW_TOOL_NAMES = [
3250
+ "list_workflows",
3251
+ "launch_workflow",
3252
+ "workflow_run",
3253
+ "workflow_tools",
3254
+ "scaffold_workflow"
3255
+ ];
3256
+ /** The card's tool, with any other name read as workflow_run, as the web card always has. */
3257
+ function workflowToolName(name) {
3258
+ return WORKFLOW_TOOL_NAMES.includes(name) ? name : "workflow_run";
3259
+ }
3260
+ function asRecord$1(value) {
3261
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
3262
+ return value;
3263
+ }
3264
+ function inlineText(value) {
3265
+ let normalized = "";
3266
+ for (const character of value) {
3267
+ const code = character.codePointAt(0) ?? 0;
3268
+ normalized += code <= 31 || code === 127 ? " " : character;
3269
+ }
3270
+ return normalized.replace(/\s+/gu, " ").trim();
3271
+ }
3272
+ function readString$1(record, key) {
3273
+ const value = record?.[key];
3274
+ if (typeof value !== "string") return void 0;
3275
+ return inlineText(value) || void 0;
3276
+ }
3277
+ function readNumber$1(record, key) {
3278
+ const value = record?.[key];
3279
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
3280
+ }
3281
+ function readBoolean(record, key) {
3282
+ const value = record?.[key];
3283
+ return typeof value === "boolean" ? value : void 0;
3284
+ }
3285
+ function readStringArray(record, key) {
3286
+ const value = record?.[key];
3287
+ if (!Array.isArray(value)) return [];
3288
+ return value.filter((item) => typeof item === "string");
3289
+ }
3290
+ function parseJsonRecord(text) {
3291
+ if (!text) return void 0;
3292
+ try {
3293
+ return asRecord$1(JSON.parse(text));
3294
+ } catch {
3295
+ return;
3296
+ }
3297
+ }
3298
+ function textBlocks(result) {
3299
+ if (!result) return [];
3300
+ return result.content.flatMap((item) => {
3301
+ const record = asRecord$1(item);
3302
+ return record?.type === "text" && typeof record.text === "string" ? [record.text] : [];
3303
+ });
3304
+ }
3305
+ function detailLines(result) {
3306
+ return textBlocks(result).flatMap((block) => block.split("\n")).map((entry) => entry.trimEnd()).filter((entry) => entry.length > 0);
3307
+ }
3308
+ function firstPayload(result) {
3309
+ return parseJsonRecord(textBlocks(result)[0]);
3310
+ }
3311
+ function plural$1(count, singular, pluralForm = `${singular}s`) {
3312
+ return count === 1 ? singular : pluralForm;
3313
+ }
3314
+ function line(text, tone, extra = {}) {
3315
+ return {
3316
+ text,
3317
+ tone,
3318
+ ...extra
3319
+ };
3320
+ }
3321
+ function labelValue(label, value) {
3322
+ return line(`${label} ${value}`, "text");
3323
+ }
3324
+ function hiddenLine(hidden) {
3325
+ return line(`… ${hidden} more`, "dim");
3326
+ }
3327
+ function targetScope(args) {
3328
+ const runKey = readString$1(args, "runKey");
3329
+ if (!runKey) return void 0;
3330
+ const workspace = readString$1(args, "workspace");
3331
+ return workspace ? `${workspace}/${runKey}` : runKey;
3332
+ }
3333
+ function toolAction(toolName, args) {
3334
+ if (toolName === "list_workflows") return "list";
3335
+ if (toolName === "launch_workflow") return "launch";
3336
+ if (toolName === "scaffold_workflow") return "scaffold";
3337
+ return readString$1(args, "action") ?? "run";
3338
+ }
3339
+ function toolTarget(toolName, args) {
3340
+ if (toolName === "list_workflows") return readString$1(args, "directory");
3341
+ if (toolName === "launch_workflow") return readString$1(args, "workflowPath");
3342
+ if (toolName === "scaffold_workflow") return readString$1(args, "path");
3343
+ return targetScope(args);
3344
+ }
3345
+ function statusTimestamp(value) {
3346
+ return value.replace("T", " ").replace(/\.\d{3}Z$/, "Z");
3347
+ }
3348
+ function workflowNameFromPath(path) {
3349
+ if (!path) return "workflow";
3350
+ const filename = path.split("/").at(-1) ?? path;
3351
+ return filename.replace(/\.workflow\.ya?ml$/u, "") || filename;
3352
+ }
3353
+ function callMetadata(toolName, args) {
3354
+ const values = [];
3355
+ if (toolName === "list_workflows") {
3356
+ const page = readNumber$1(args, "page");
3357
+ const pageSize = readNumber$1(args, "pageSize");
3358
+ if (page !== void 0) values.push(`page ${page}`);
3359
+ if (pageSize !== void 0) values.push(`${pageSize}/page`);
3360
+ if (readString$1(args, "filter")) values.push("filtered");
3361
+ const tags = readStringArray(args, "tags");
3362
+ if (tags.length > 0) values.push(`${tags.length} ${plural$1(tags.length, "tag")}`);
3363
+ } else if (toolName === "launch_workflow") {
3364
+ const job = readString$1(args, "job");
3365
+ const runner = readString$1(args, "runner");
3366
+ const workspace = readString$1(args, "workspace");
3367
+ const inputCount = Object.keys(asRecord$1(args.inputs) ?? {}).length;
3368
+ const environmentCount = Object.keys(asRecord$1(args.env) ?? {}).length;
3369
+ if (workspace) values.push(`workspace ${workspace}`);
3370
+ if (job) values.push(`job ${job}`);
3371
+ if (runner) values.push(`runner ${runner}`);
3372
+ if (readBoolean(args, "dryRun")) values.push("dry run");
3373
+ if (readString$1(args, "prompt")) values.push("with prompt");
3374
+ if (inputCount > 0) values.push(`${inputCount} ${plural$1(inputCount, "input")}`);
3375
+ if (environmentCount > 0) values.push(`${environmentCount} env`);
3376
+ } else if (toolName === "scaffold_workflow") {
3377
+ if (readBoolean(args, "force")) values.push("overwrite allowed");
3378
+ } else {
3379
+ if (readString$1(args, "expectedRunId")) values.push("generation checked");
3380
+ if (readString$1(args, "reason")) values.push("with reason");
3381
+ if (readBoolean(args, "dryRun")) values.push("dry run");
3382
+ if (readString$1(args, "job")) values.push("job override");
3383
+ if (readString$1(args, "runner")) values.push("runner override");
3384
+ }
3385
+ return values;
3386
+ }
3387
+ /** The header beside the tool name: action, target, and the call's flags. */
3388
+ function workflowCallSummary(toolName, args) {
3389
+ const target = toolTarget(toolName, args);
3390
+ return {
3391
+ action: toolAction(toolName, args),
3392
+ ...target === void 0 ? {} : { target },
3393
+ metadata: callMetadata(toolName, args)
3394
+ };
3395
+ }
3396
+ function parseCatalog(payload) {
3397
+ if (!Array.isArray(payload?.workflows)) return void 0;
3398
+ const workflows = payload.workflows.flatMap((value) => {
3399
+ const record = asRecord$1(value);
3400
+ const path = readString$1(record, "path");
3401
+ if (!record || !path) return [];
3402
+ return [{
3403
+ description: readString$1(record, "description") ?? "",
3404
+ name: readString$1(record, "name") ?? "",
3405
+ path,
3406
+ tags: readStringArray(record, "tags")
3407
+ }];
3408
+ });
3409
+ const tags = Array.isArray(payload.tags) ? payload.tags.flatMap((value) => {
3410
+ const record = asRecord$1(value);
3411
+ const tag = readString$1(record, "tag");
3412
+ const count = readNumber$1(record, "count");
3413
+ return tag && count !== void 0 ? [{
3414
+ count,
3415
+ tag
3416
+ }] : [];
3417
+ }) : [];
3418
+ const directory = readString$1(payload, "directory");
3419
+ return {
3420
+ ...directory === void 0 ? {} : { directory },
3421
+ page: readNumber$1(payload, "page") ?? 1,
3422
+ pageSize: readNumber$1(payload, "pageSize") ?? workflows.length,
3423
+ tags,
3424
+ total: readNumber$1(payload, "total") ?? workflows.length,
3425
+ totalPages: readNumber$1(payload, "totalPages") ?? (workflows.length > 0 ? 1 : 0),
3426
+ workflows
3427
+ };
3428
+ }
3429
+ function catalogItemLines(item, expanded) {
3430
+ const lines = [line(`› ${item.name || workflowNameFromPath(item.path)} · ${item.path}`, "text")];
3431
+ if (!expanded) return lines;
3432
+ if (item.description) lines.push(line(item.description, "muted", { indent: true }));
3433
+ if (item.tags.length > 0) lines.push(line(`tags ${item.tags.join(", ")}`, "dim", { indent: true }));
3434
+ return lines;
3435
+ }
3436
+ function catalogLines(result, options) {
3437
+ const catalog = parseCatalog(firstPayload(result));
3438
+ if (!catalog) return void 0;
3439
+ const pageLabel = `page ${catalog.page}/${catalog.totalPages}`;
3440
+ const summary = line(`${catalog.total > 0 ? "✓" : "○"} ${catalog.total} ${plural$1(catalog.total, "workflow")} · ${pageLabel}`, "hi", { bold: true });
3441
+ const shown = options.expanded ? catalog.workflows : catalog.workflows.slice(0, COLLAPSED_CATALOG_ROWS);
3442
+ const lines = [summary, ...shown.flatMap((item) => catalogItemLines(item, options.expanded))];
3443
+ const hidden = catalog.workflows.length - shown.length;
3444
+ if (hidden > 0) lines.push(hiddenLine(hidden));
3445
+ if (options.expanded) {
3446
+ if (catalog.tags.length > 0) {
3447
+ const tags = catalog.tags.map(({ count, tag }) => `${tag} (${count})`).join(", ");
3448
+ lines.push(labelValue("available tags", tags));
3449
+ }
3450
+ if (catalog.directory) lines.push(labelValue("directory", catalog.directory));
3451
+ lines.push(labelValue("page size", String(catalog.pageSize)));
3452
+ }
3453
+ return lines;
3454
+ }
3455
+ function readWorkflowState(record) {
3456
+ const stage = readString$1(record, "effectiveStage") ?? readString$1(record, "stage") ?? "unknown";
3457
+ const outcome = readString$1(record, "effectiveOutcome") ?? readString$1(record, "outcome");
3458
+ const executionState = readString$1(record, "executionState");
3459
+ if (outcome === "interrupted") return {
3460
+ tone: "warning",
3461
+ glyph: "!",
3462
+ label: "interrupted"
3463
+ };
3464
+ if (stage === "error" || outcome === "failed") return {
3465
+ tone: "error",
3466
+ glyph: "✗",
3467
+ label: "failed"
3468
+ };
3469
+ if (stage === "completed" && outcome === "skipped") return {
3470
+ tone: "muted",
3471
+ glyph: "○",
3472
+ label: "skipped"
3473
+ };
3474
+ if (stage === "completed") return {
3475
+ tone: "success",
3476
+ glyph: "✓",
3477
+ label: "completed"
3478
+ };
3479
+ if (executionState === "paused") return {
3480
+ tone: "warning",
3481
+ glyph: "Ⅱ",
3482
+ label: "paused"
3483
+ };
3484
+ if (executionState === "pause_requested") return {
3485
+ tone: "warning",
3486
+ glyph: "◐",
3487
+ label: "pause requested"
3488
+ };
3489
+ if (executionState === "resume_requested") return {
3490
+ tone: "warning",
3491
+ glyph: "◐",
3492
+ label: "resume requested"
3493
+ };
3494
+ if (stage === "running") return {
3495
+ tone: "accent",
3496
+ glyph: "◐",
3497
+ label: "running"
3498
+ };
3499
+ return {
3500
+ tone: "muted",
3501
+ glyph: "○",
3502
+ label: stage
3503
+ };
3504
+ }
3505
+ function currentActivity(record) {
3506
+ const position = asRecord$1(record.position);
3507
+ const cursor = asRecord$1(record.executionCursor);
3508
+ const job = readString$1(position, "job") ?? readString$1(cursor, "job") ?? readString$1(record, "job");
3509
+ const step = readString$1(position, "step") ?? readString$1(cursor, "stepName");
3510
+ const phase = readString$1(cursor, "phase");
3511
+ if (!job && !step && !phase) return void 0;
3512
+ return line(`[${job ?? phase ?? "workflow"}] ${step ?? phase ?? "current job"}`, "text", { indent: true });
3513
+ }
3514
+ function launcherLabel(record) {
3515
+ const launcher = asRecord$1(record.launcher);
3516
+ const type = readString$1(launcher, "type");
3517
+ if (!type) return void 0;
3518
+ const identity = readString$1(launcher, "sessionName") ?? readString$1(launcher, "workspaceId");
3519
+ return identity ? `${type} ${identity}` : type;
3520
+ }
3521
+ function workflowRecordLines(record, expanded) {
3522
+ const runKey = readString$1(record, "runKey");
3523
+ const stage = readString$1(record, "stage");
3524
+ if (!runKey || !stage) return void 0;
3525
+ const state = readWorkflowState(record);
3526
+ const lines = [
3527
+ line(`Status retrieved · ${readString$1(record, "displayName") ?? runKey} · workflow: ${state.label}`, state.tone, { bold: true }),
3528
+ labelValue("workspace", readString$1(record, "workspace") ?? "unknown"),
3529
+ labelValue("runKey", runKey)
3530
+ ];
3531
+ const activity = currentActivity(record);
3532
+ if (activity) lines.push(activity);
3533
+ const failure = readString$1(record, "errorMessage") ?? readString$1(record, "failureReason");
3534
+ if (failure) lines.push(line(`error ${failure}`, "error"));
3535
+ const staleReason = readString$1(record, "staleReason");
3536
+ if (staleReason) lines.push(line(`stale ${staleReason}`, "warning"));
3537
+ const startedAt = readString$1(record, "startedAt");
3538
+ const exitCode = readNumber$1(record, "exitCode");
3539
+ const conciseMetadata = [
3540
+ readString$1(record, "runner") ? `runner ${readString$1(record, "runner")}` : void 0,
3541
+ readBoolean(record, "dryRun") ? "dry run" : void 0,
3542
+ exitCode !== void 0 ? `exit ${exitCode}` : void 0,
3543
+ startedAt ? `started ${statusTimestamp(startedAt)}` : void 0
3544
+ ].filter((value) => !!value);
3545
+ if (conciseMetadata.length > 0) lines.push(line(conciseMetadata.join(" · "), "dim"));
3546
+ if (!expanded) return lines;
3547
+ const finishedAt = readString$1(record, "finishedAt");
3548
+ const repairId = readString$1(record, "activeRepairId");
3549
+ const detailedValues = [
3550
+ ["workflow", readString$1(record, "workflowPath")],
3551
+ ["workflow id", readString$1(record, "workflowId")],
3552
+ ["run id", readString$1(record, "runId")],
3553
+ ["launcher", launcherLabel(record)],
3554
+ ["job", readString$1(record, "job")],
3555
+ ["outcome", readString$1(record, "effectiveOutcome") ?? readString$1(record, "outcome")],
3556
+ ["finished", finishedAt ? statusTimestamp(finishedAt) : void 0],
3557
+ ["pid", readNumber$1(record, "pid")?.toString()],
3558
+ ["repair", repairId ? `#${repairId}` : void 0],
3559
+ ["worktree", readString$1(record, "worktreeBranch") ?? readString$1(record, "worktreePath")]
3560
+ ];
3561
+ for (const [label, value] of detailedValues) if (value) lines.push(labelValue(label, value));
3562
+ const jobs = record.jobs;
3563
+ if (Array.isArray(jobs)) for (const value of jobs) {
3564
+ const job = asRecord$1(value);
3565
+ const name = readString$1(job, "name");
3566
+ const status = readString$1(job, "status");
3567
+ if (!name || !status) continue;
3568
+ lines.push(labelValue("job", `${name} · ${status}`));
3569
+ if (!Array.isArray(job?.steps)) continue;
3570
+ for (const value of job.steps) {
3571
+ const step = asRecord$1(value);
3572
+ const stepName = readString$1(step, "name");
3573
+ const stepStatus = readString$1(step, "status");
3574
+ if (stepName && stepStatus) lines.push(line(`step ${stepName} · ${stepStatus}`, "text", { indent: true }));
3575
+ }
3576
+ }
3577
+ return lines;
3578
+ }
3579
+ function statusLines(result, options) {
3580
+ const payload = firstPayload(result);
3581
+ if (!payload) return void 0;
3582
+ return workflowRecordLines(payload, options.expanded);
3583
+ }
3584
+ function nestedRequestedAt(payload) {
3585
+ return readString$1(asRecord$1(payload?.request), "requestedAt") ?? readString$1(payload, "requestedAt");
3586
+ }
3587
+ function controlLines(action, args, result, options) {
3588
+ const payload = firstPayload(result);
3589
+ const scope = targetScope(args) ?? readString$1(payload, "runKey") ?? "workflow";
3590
+ const payloadWorkspace = readString$1(payload, "workspace");
3591
+ const lines = [line(`◐ ${action} requested · ${payloadWorkspace && !scope.includes("/") ? `${payloadWorkspace}/${scope}` : scope}`, "warning", { bold: true })];
3592
+ const requestedAt = nestedRequestedAt(payload);
3593
+ if (requestedAt) lines.push(labelValue("requested", statusTimestamp(requestedAt)));
3594
+ if (options.expanded) lines.push(line("verify the transition with workflow_run status", "dim"));
3595
+ return lines;
3596
+ }
3597
+ function matchLine(text, pattern) {
3598
+ return text.match(pattern)?.[1]?.trim();
3599
+ }
3600
+ function launchSummary(text, args) {
3601
+ const startedName = matchLine(text, /^Started (.+) in workspace .+\.$/mu);
3602
+ const workspace = matchLine(text, /^Started .+ in workspace (.+)\.$/mu) ?? readString$1(args, "workspace");
3603
+ const runKey = matchLine(text, /^Run key:\s*(.+)$/mu);
3604
+ const path = readString$1(args, "workflowPath");
3605
+ const name = startedName ?? workflowNameFromPath(path);
3606
+ const scope = runKey ? workspace ? `${workspace}/${runKey}` : runKey : workspace ?? path ?? "workflow";
3607
+ if (/Workflow completed successfully/iu.test(text)) return {
3608
+ name,
3609
+ scope,
3610
+ state: {
3611
+ tone: "success",
3612
+ glyph: "✓",
3613
+ label: "completed"
3614
+ }
3615
+ };
3616
+ if (/Workflow skipped/iu.test(text)) return {
3617
+ name,
3618
+ scope,
3619
+ state: {
3620
+ tone: "muted",
3621
+ glyph: "○",
3622
+ label: "skipped"
3623
+ }
3624
+ };
3625
+ if (/no run was registered/iu.test(text)) return {
3626
+ name,
3627
+ scope,
3628
+ state: {
3629
+ tone: "warning",
3630
+ glyph: "◐",
3631
+ label: "starting · run key pending"
3632
+ }
3633
+ };
3634
+ return {
3635
+ name,
3636
+ scope,
3637
+ state: {
3638
+ tone: "accent",
3639
+ glyph: "◐",
3640
+ label: runKey ? "started" : "launch accepted"
3641
+ }
3642
+ };
3643
+ }
3644
+ function launchLines(args, result, options) {
3645
+ const summary = launchSummary(textBlocks(result).join("\n"), args);
3646
+ const lines = [line(`${summary.state.glyph} ${summary.name} · ${summary.scope} · ${summary.state.label}`, summary.state.tone, { bold: true })];
3647
+ const metadata = [
3648
+ readString$1(args, "job") ? `job ${readString$1(args, "job")}` : void 0,
3649
+ readString$1(args, "runner") ? `runner ${readString$1(args, "runner")}` : void 0,
3650
+ readBoolean(args, "dryRun") ? "dry run" : void 0
3651
+ ].filter((value) => !!value);
3652
+ if (metadata.length > 0) lines.push(line(metadata.join(" · "), "dim"));
3653
+ if (options.expanded) {
3654
+ const details = detailLines(result).filter((entry) => !entry.startsWith("Next steps for the agent:"));
3655
+ lines.push(...details.map((entry) => line(entry, "text")));
3656
+ }
3657
+ return lines;
3658
+ }
3659
+ function splitEvidence(text) {
3660
+ const sections = [];
3661
+ let current;
3662
+ for (const entry of text.split("\n")) {
3663
+ const match = entry.match(/^--- (.+) ---$/u);
3664
+ if (match?.[1]) {
3665
+ current = {
3666
+ body: [],
3667
+ name: match[1]
3668
+ };
3669
+ sections.push(current);
3670
+ continue;
3671
+ }
3672
+ current?.body.push(entry);
3673
+ }
3674
+ return sections;
3675
+ }
3676
+ function recoveryEvidenceLines(args, result, options) {
3677
+ const sections = splitEvidence(textBlocks(result).join("\n"));
3678
+ const record = parseJsonRecord(sections.find((section) => section.name === "run.json")?.body.join("\n"));
3679
+ const recordLines = record ? workflowRecordLines(record, options.expanded) : void 0;
3680
+ const evidenceSections = sections.filter((section) => section.name !== "run.json");
3681
+ const scope = targetScope(args) ?? "workflow";
3682
+ const lines = recordLines ?? [line(`✓ recovery evidence · ${scope}`, "success", { bold: true })];
3683
+ const names = evidenceSections.map((section) => section.name);
3684
+ lines.push(names.length > 0 ? labelValue("evidence", names.join(", ")) : line("no durable evidence files recorded", "muted"));
3685
+ if (options.expanded) for (const section of evidenceSections) {
3686
+ lines.push(line(section.name, "hi", { bold: true }));
3687
+ lines.push(...section.body.filter((entry) => entry.length > 0).map((entry) => line(entry, "text")));
3688
+ }
3689
+ return lines;
3690
+ }
3691
+ function simpleActionLines(action, args, result, options) {
3692
+ const scope = targetScope(args) ?? "workflow";
3693
+ const actionLabel = {
3694
+ follow: "following output",
3695
+ open: "launcher opened",
3696
+ recover: readBoolean(args, "dryRun") ? "recovery dry run finished" : "recovery accepted",
3697
+ tail: "launcher output checked"
3698
+ };
3699
+ const state = action === "recover" ? {
3700
+ tone: "accent",
3701
+ glyph: "◐",
3702
+ label: actionLabel[action] ?? action
3703
+ } : {
3704
+ tone: "success",
3705
+ glyph: "✓",
3706
+ label: actionLabel[action] ?? action
3707
+ };
3708
+ const lines = [line(`${state.glyph} ${state.label} · ${scope}`, state.tone, { bold: true })];
3709
+ const details = detailLines(result);
3710
+ if (action === "tail") {
3711
+ const workflowLine = details.find((entry) => entry.startsWith("Workflow:"));
3712
+ const stageLine = details.find((entry) => entry.startsWith("Stage:"));
3713
+ if (workflowLine) lines.push(line(workflowLine, "text"));
3714
+ if (stageLine) lines.push(line(stageLine, "text"));
3715
+ }
3716
+ if (options.expanded) lines.push(...details.map((entry) => line(entry, "text")));
3717
+ return lines;
3718
+ }
3719
+ function failureLines(toolName, args, result, options) {
3720
+ const action = toolAction(toolName, args);
3721
+ const target = toolTarget(toolName, args);
3722
+ const details = detailLines(result);
3723
+ const shown = options.expanded ? details : details.slice(0, COLLAPSED_DETAIL_LINES);
3724
+ const lines = [line(toolName === "workflow_run" && action === "status" ? `✗ Status lookup failed${target ? ` · ${target}` : ""}` : `✗ ${action} failed${target ? ` · ${target}` : ""}`, "error", { bold: true }), ...shown.length > 0 ? shown.map((entry) => line(entry, "text")) : [line("Unknown workflow error", "error")]];
3725
+ const hidden = details.length - shown.length;
3726
+ if (hidden > 0) lines.push(hiddenLine(hidden));
3727
+ return lines;
3728
+ }
3729
+ function partialLines(toolName, args, result) {
3730
+ const details = detailLines(result);
3731
+ const shown = details.slice(-4);
3732
+ const action = toolAction(toolName, args);
3733
+ const target = toolTarget(toolName, args);
3734
+ const hidden = details.length - shown.length;
3735
+ const lines = [line(`◐ ${action}${target ? ` · ${target}` : ""}`, "accent", { bold: true })];
3736
+ if (hidden > 0) lines.push(line(`… ${hidden} earlier`, "dim"));
3737
+ lines.push(...shown.map((entry) => line(entry, "text")));
3738
+ return lines;
3739
+ }
3740
+ function fallbackLines(result, options) {
3741
+ const details = detailLines(result);
3742
+ if (details.length === 0) return [line("No workflow output.", "muted")];
3743
+ const shown = options.expanded ? details : details.slice(0, COLLAPSED_DETAIL_LINES);
3744
+ const lines = shown.map((entry) => line(entry, "text"));
3745
+ const hidden = details.length - shown.length;
3746
+ if (hidden > 0) lines.push(hiddenLine(hidden));
3747
+ return lines;
3748
+ }
3749
+ /** The body of a workflow tool card, chosen by tool, action, and result shape. */
3750
+ function workflowResultLines(toolName, args, result, options) {
3751
+ if (options.isPartial) return partialLines(toolName, args, result);
3752
+ if (options.isError) return failureLines(toolName, args, result, options);
3753
+ if (toolName === "list_workflows") return catalogLines(result, options) ?? fallbackLines(result, options);
3754
+ if (toolName === "launch_workflow") return launchLines(args, result, options);
3755
+ const action = readString$1(args, "action");
3756
+ if (action === "status") return statusLines(result, options) ?? fallbackLines(result, options);
3757
+ if (action === "pause" || action === "resume" || action === "stop") return controlLines(action, args, result, options);
3758
+ if (action === "recovery-evidence") return recoveryEvidenceLines(args, result, options);
3759
+ if (action === "follow" || action === "open" || action === "recover" || action === "tail") return simpleActionLines(action, args, result, options);
3760
+ return fallbackLines(result, options);
3761
+ }
3762
+ /**
3763
+ * The reason a failed call gives, for a card that shows only the reason: the
3764
+ * `{ error }` payload the runtime answers a failed operation with, or the plain
3765
+ * text a launch failure carries.
3766
+ */
3767
+ function workflowFailureReason(result, output = "") {
3768
+ const text = (textBlocks(result).join("\n") || output).trim();
3769
+ const error = readString$1(parseJsonRecord(text), "error");
3770
+ if (error) return error;
3771
+ return text || "Unknown workflow error";
3772
+ }
3773
+ function parseJsonValue(text) {
3774
+ try {
3775
+ return JSON.parse(text);
3776
+ } catch {
3777
+ return;
3778
+ }
3779
+ }
3780
+ function failedRunsView(payload) {
3781
+ if (!Array.isArray(payload)) return void 0;
3782
+ const rows = payload.flatMap((value) => {
3783
+ const record = asRecord$1(value);
3784
+ const runKey = readString$1(record, "runKey");
3785
+ if (!runKey) return [];
3786
+ const workspace = readString$1(record, "workspace");
3787
+ const failedJob = readString$1(record, "failedJob");
3788
+ const updatedAt = readString$1(record, "updatedAt");
3789
+ const outcome = readString$1(record, "outcome") ?? "failed";
3790
+ const detail = [
3791
+ workspace ? `${workspace}/${runKey}` : runKey,
3792
+ failedJob ? `job ${failedJob}` : void 0,
3793
+ updatedAt ? statusTimestamp(updatedAt) : void 0
3794
+ ].filter((entry) => !!entry);
3795
+ return [{
3796
+ key: `${workspace ?? ""}/${runKey}`,
3797
+ title: readString$1(record, "displayName") ?? runKey,
3798
+ detail: detail.join(" · "),
3799
+ chip: {
3800
+ label: outcome,
3801
+ tone: outcome === "interrupted" ? "yellow" : "red"
3802
+ }
3803
+ }];
3804
+ });
3805
+ if (rows.length !== payload.length) return void 0;
3806
+ return {
3807
+ headline: rows.length === 0 ? "No failed runs" : `${rows.length} failed ${plural$1(rows.length, "run")}`,
3808
+ facts: [],
3809
+ rows,
3810
+ ...rows.length > 0 ? { note: "Read recovery-evidence before recover." } : {}
3811
+ };
3812
+ }
3813
+ function scalarText(value) {
3814
+ if (typeof value === "string") return inlineText(value) || void 0;
3815
+ if (typeof value === "number" && Number.isFinite(value)) return String(value);
3816
+ if (typeof value === "boolean") return value ? "yes" : "no";
3817
+ }
3818
+ /** Any JSON result as its scalar figures and list counts, or a list of rows for an array. */
3819
+ function workflowGenericView(payload) {
3820
+ if (Array.isArray(payload)) {
3821
+ const rows = payload.map((value, index) => {
3822
+ const record = asRecord$1(value);
3823
+ const scalars = Object.values(record ?? {}).flatMap((entry) => scalarText(entry) ?? []);
3824
+ const title = scalarText(value) ?? scalars[0] ?? `item ${index + 1}`;
3825
+ const rest = scalars.slice(1).join(" · ");
3826
+ return {
3827
+ key: String(index),
3828
+ title,
3829
+ ...rest ? { detail: rest } : {}
3830
+ };
3831
+ });
3832
+ return {
3833
+ headline: `${rows.length} ${plural$1(rows.length, "item")}`,
3834
+ facts: [],
3835
+ rows
3836
+ };
3837
+ }
3838
+ const record = asRecord$1(payload) ?? {};
3839
+ const facts = Object.entries(record).flatMap(([label, value]) => {
3840
+ const scalar = scalarText(value);
3841
+ if (scalar !== void 0) return [{
3842
+ label,
3843
+ value: scalar
3844
+ }];
3845
+ if (Array.isArray(value)) return [{
3846
+ label,
3847
+ value: `${value.length} ${plural$1(value.length, "item")}`
3848
+ }];
3849
+ const nested = asRecord$1(value);
3850
+ if (nested) {
3851
+ const count = Object.keys(nested).length;
3852
+ return [{
3853
+ label,
3854
+ value: `${count} ${plural$1(count, "field")}`
3855
+ }];
3856
+ }
3857
+ return [];
3858
+ });
3859
+ return {
3860
+ headline: facts.length === 0 ? "No details returned" : "Result",
3861
+ facts,
3862
+ rows: []
3863
+ };
3864
+ }
3865
+ /**
3866
+ * The laid-out form of a JSON result the toned lines would otherwise print
3867
+ * as raw text, or undefined when the lines already parse it (the catalog, a
3868
+ * run record, a control request) or the result is plain text.
3869
+ */
3870
+ function workflowStructuredView(toolName, args, result) {
3871
+ const text = textBlocks(result).join("\n").trim();
3872
+ if (!text.startsWith("{") && !text.startsWith("[")) return void 0;
3873
+ const payload = parseJsonValue(text);
3874
+ if (payload === void 0) return void 0;
3875
+ const action = readString$1(args, "action");
3876
+ if (toolName === "workflow_tools" && action === "list-failed") return failedRunsView(payload) ?? workflowGenericView(payload);
3877
+ const record = asRecord$1(payload);
3878
+ if (toolName === "list_workflows" && parseCatalog(record)) return void 0;
3879
+ if (toolName === "launch_workflow") return void 0;
3880
+ if (action === "status" && record && workflowRecordLines(record, false)) return void 0;
3881
+ if (action === "pause" || action === "resume" || action === "stop") return void 0;
3882
+ return workflowGenericView(payload);
3883
+ }
3884
+ //#endregion
3885
+ //#region src/extensions/workspaces/sessions/(frontend)/tool/_lib/workflowChildToolView.ts
3886
+ /**
3887
+ * The view model of the workflow child tools, the lead's spawnChild,
3888
+ * childStatus and children and the child's reportCriteria and
3889
+ * reviewArtifacts, registered under the names in
3890
+ * src/services/workflowNamespace (CHILD_TOOL_NAMES). The runtime picks which
3891
+ * of them a session gets by its role, so the renderers claim them by name
3892
+ * through `matches`. Results arrive as JSON text; they are parsed and
3893
+ * validated here into figures, chips, and compact lists, and only text that
3894
+ * does not parse falls back to plain lines. As the namespace's call cards do,
3895
+ * the view leaves out the assignment prompt, input values, criteria
3896
+ * feedback, and reviewed artifact bodies.
3897
+ */
3898
+ const WORKFLOW_CHILD_TOOL_NAMES = [
3899
+ "workflow_spawn_child",
3900
+ "workflow_child_status",
3901
+ "workflow_children",
3902
+ "workflow_report_criteria",
3903
+ "workflow_review_artifacts"
3904
+ ];
3905
+ function matchesWorkflowChildTool(toolName) {
3906
+ return WORKFLOW_CHILD_TOOL_NAMES.includes(toolName);
3907
+ }
3908
+ function asRecord(value) {
3909
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
3910
+ return value;
3911
+ }
3912
+ function readString(record, key) {
3913
+ const value = record?.[key];
3914
+ if (typeof value !== "string") return void 0;
3915
+ return value.replace(/\s+/gu, " ").trim() || void 0;
3916
+ }
3917
+ function readNumber(record, key) {
3918
+ const value = record?.[key];
3919
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
3920
+ }
3921
+ function plural(count, singular, pluralForm = `${singular}s`) {
3922
+ return count === 1 ? singular : pluralForm;
3923
+ }
3924
+ function timestamp(value) {
3925
+ return value.replace("T", " ").replace(/\.\d{3}Z$/u, "Z");
3926
+ }
3927
+ function resultText(result) {
3928
+ if (!result) return "";
3929
+ return result.content.flatMap((item) => {
3930
+ const record = asRecord(item);
3931
+ return record?.type === "text" && typeof record.text === "string" ? [record.text] : [];
3932
+ }).join("\n").trim();
3933
+ }
3934
+ function parseResult(result) {
3935
+ const text = resultText(result);
3936
+ if (text) try {
3937
+ return {
3938
+ ok: true,
3939
+ value: JSON.parse(text)
3940
+ };
3941
+ } catch {
3942
+ return { ok: false };
3943
+ }
3944
+ return result && result.details !== void 0 ? {
3945
+ ok: true,
3946
+ value: result.details
3947
+ } : { ok: false };
3948
+ }
3949
+ function criteriaResults(args) {
3950
+ const results = asRecord(args.results);
3951
+ if (!results) return [];
3952
+ return Object.entries(results).flatMap(([key, value]) => {
3953
+ const status = readString(asRecord(value), "status");
3954
+ return status ? [{
3955
+ key,
3956
+ status
3957
+ }] : [];
3958
+ });
3959
+ }
3960
+ function workflowChildSummary(toolName, args) {
3961
+ if (toolName === "workflow_spawn_child") {
3962
+ const inputs = Object.keys(asRecord(args.inputs) ?? {}).length;
3963
+ const job = readString(args, "job");
3964
+ return {
3965
+ ...job === void 0 ? {} : { primary: job },
3966
+ detail: inputs > 0 ? [`${inputs} ${plural(inputs, "input")}`] : []
3967
+ };
3968
+ }
3969
+ if (toolName === "workflow_child_status") {
3970
+ const id = readString(args, "invocationId");
3971
+ return {
3972
+ ...id === void 0 ? {} : { primary: id },
3973
+ detail: []
3974
+ };
3975
+ }
3976
+ if (toolName === "workflow_report_criteria") {
3977
+ const results = criteriaResults(args);
3978
+ if (results.length === 0) return { detail: [] };
3979
+ const notMet = results.filter((entry) => entry.status === "not-met").length;
3980
+ return {
3981
+ primary: `${results.length} ${plural(results.length, "criterion", "criteria")}`,
3982
+ detail: notMet > 0 ? [`${notMet} not met`] : []
3983
+ };
3984
+ }
3985
+ return { detail: [] };
3986
+ }
3987
+ /** What the card says while the call runs. */
3988
+ function workflowChildRunningLabel(toolName) {
3989
+ if (toolName === "workflow_spawn_child") return "Starting the child";
3990
+ if (toolName === "workflow_child_status") return "Reading the child";
3991
+ if (toolName === "workflow_children") return "Reading the children";
3992
+ if (toolName === "workflow_report_criteria") return "Reporting criteria";
3993
+ if (toolName === "workflow_review_artifacts") return "Reading the artifacts";
3994
+ return "Running";
3995
+ }
3996
+ const INVOCATION_CHIPS = {
3997
+ running: {
3998
+ label: "running",
3999
+ tone: "blue"
4000
+ },
4001
+ completed: {
4002
+ label: "completed",
4003
+ tone: "green"
4004
+ },
4005
+ failed: {
4006
+ label: "failed",
4007
+ tone: "red"
4008
+ },
4009
+ interrupted: {
4010
+ label: "interrupted",
4011
+ tone: "yellow"
4012
+ }
4013
+ };
4014
+ const CRITERION_CHIPS = {
4015
+ checked: {
4016
+ label: "checked",
4017
+ tone: "green"
4018
+ },
4019
+ "not-met": {
4020
+ label: "not met",
4021
+ tone: "yellow"
4022
+ },
4023
+ unchecked: {
4024
+ label: "unchecked",
4025
+ tone: "neutral"
4026
+ }
4027
+ };
4028
+ function invocationChip(state) {
4029
+ return INVOCATION_CHIPS[state] ?? {
4030
+ label: state,
4031
+ tone: "neutral"
4032
+ };
4033
+ }
4034
+ function invocationView(value) {
4035
+ const record = asRecord(value);
4036
+ const invocationId = readString(record, "invocationId");
4037
+ const job = readString(record, "job");
4038
+ const state = readString(record, "state");
4039
+ if (!record || !invocationId || !job || !state) return void 0;
4040
+ const sessions = Array.isArray(record.sessionIds) ? record.sessionIds.filter((id) => typeof id === "string") : [];
4041
+ const startedAt = readString(record, "startedAt");
4042
+ const endedAt = readString(record, "endedAt");
4043
+ const facts = [{
4044
+ label: "invocation",
4045
+ value: invocationId
4046
+ }];
4047
+ if (startedAt) facts.push({
4048
+ label: "started",
4049
+ value: timestamp(startedAt)
4050
+ });
4051
+ if (endedAt) facts.push({
4052
+ label: "ended",
4053
+ value: timestamp(endedAt)
4054
+ });
4055
+ if (sessions.length > 0) facts.push({
4056
+ label: "sessions",
4057
+ value: String(sessions.length)
4058
+ });
4059
+ const error = readString(record, "error");
4060
+ return {
4061
+ headline: job,
4062
+ chip: invocationChip(state),
4063
+ facts,
4064
+ sections: [],
4065
+ ...error === void 0 ? {} : { error },
4066
+ ...state === "running" ? { note: "Check back with childStatus; a started child is not a finished one." } : {}
4067
+ };
4068
+ }
4069
+ function criterionRow(value) {
4070
+ const record = asRecord(value);
4071
+ const key = readString(record, "key");
4072
+ const status = readString(record, "status");
4073
+ if (!key || !status) return void 0;
4074
+ const verifiedBy = readString(record, "verifiedBy");
4075
+ return {
4076
+ key,
4077
+ title: key,
4078
+ ...verifiedBy === void 0 ? {} : { detail: `verified by ${verifiedBy}` },
4079
+ chip: CRITERION_CHIPS[status] ?? {
4080
+ label: status,
4081
+ tone: "neutral"
4082
+ }
4083
+ };
4084
+ }
4085
+ function invocationRow(value) {
4086
+ const record = asRecord(value);
4087
+ const id = readString(record, "invocationId");
4088
+ const job = readString(record, "job");
4089
+ const state = readString(record, "state");
4090
+ if (!id || !job || !state) return void 0;
4091
+ return {
4092
+ key: id,
4093
+ title: job,
4094
+ detail: id,
4095
+ chip: invocationChip(state)
4096
+ };
4097
+ }
4098
+ function childrenView(value) {
4099
+ const record = asRecord(value);
4100
+ const lead = readString(record, "lead");
4101
+ if (!record || !lead || !Array.isArray(record.criteria) || !Array.isArray(record.invocations)) return void 0;
4102
+ const criteria = record.criteria.flatMap((entry) => criterionRow(entry) ?? []);
4103
+ const invocations = record.invocations.flatMap((entry) => invocationRow(entry) ?? []);
4104
+ const checked = criteria.filter((row) => row.chip?.label === "checked").length;
4105
+ const continuations = readNumber(record, "continuations");
4106
+ const maxContinuations = readNumber(record, "maxContinuations");
4107
+ const facts = [{
4108
+ label: "lead",
4109
+ value: lead
4110
+ }];
4111
+ if (continuations !== void 0 && maxContinuations !== void 0) facts.push({
4112
+ label: "continuations",
4113
+ value: `${continuations}/${maxContinuations}`
4114
+ });
4115
+ const sections = [];
4116
+ if (criteria.length > 0) sections.push({
4117
+ title: "Criteria",
4118
+ rows: criteria
4119
+ });
4120
+ if (invocations.length > 0) sections.push({
4121
+ title: "Children",
4122
+ rows: invocations
4123
+ });
4124
+ return {
4125
+ headline: criteria.length > 0 ? `${checked}/${criteria.length} ${plural(criteria.length, "criterion", "criteria")} checked` : `${invocations.length} ${plural(invocations.length, "child", "children")}`,
4126
+ facts,
4127
+ sections,
4128
+ ...sections.length === 0 ? { note: "No children spawned yet." } : {}
4129
+ };
4130
+ }
4131
+ function reportView(args) {
4132
+ const rows = criteriaResults(args).map((entry) => ({
4133
+ key: entry.key,
4134
+ title: entry.key,
4135
+ chip: CRITERION_CHIPS[entry.status] ?? {
4136
+ label: entry.status,
4137
+ tone: "neutral"
4138
+ }
4139
+ }));
4140
+ return {
4141
+ headline: `${rows.length} ${plural(rows.length, "criterion", "criteria")} reported`,
4142
+ facts: [],
4143
+ sections: rows.length > 0 ? [{
4144
+ title: "Criteria",
4145
+ rows
4146
+ }] : [],
4147
+ note: "The lead reads these on its next look at the children."
4148
+ };
4149
+ }
4150
+ function artifactsView(value) {
4151
+ const record = asRecord(value);
4152
+ const revision = readString(record, "revision");
4153
+ const artifacts = asRecord(record?.artifacts);
4154
+ if (!revision || !artifacts) return void 0;
4155
+ const rows = Object.entries(artifacts).map(([name, body]) => {
4156
+ const lines = typeof body === "string" && body.length > 0 ? body.split("\n").length : 0;
4157
+ return {
4158
+ key: name,
4159
+ title: name,
4160
+ detail: `${lines} ${plural(lines, "line")}`
4161
+ };
4162
+ });
4163
+ return {
4164
+ headline: `${rows.length} ${plural(rows.length, "artifact")}`,
4165
+ facts: [{
4166
+ label: "revision",
4167
+ value: revision
4168
+ }],
4169
+ sections: rows.length > 0 ? [{
4170
+ title: "Artifacts",
4171
+ rows
4172
+ }] : [],
4173
+ ...rows.length === 0 ? { note: "No artifacts recorded for review." } : {}
4174
+ };
4175
+ }
4176
+ function textView(result) {
4177
+ const lines = resultText(result).split("\n").map((entry) => entry.trimEnd()).filter((entry) => entry.length > 0);
4178
+ return {
4179
+ headline: "",
4180
+ facts: [],
4181
+ sections: [],
4182
+ text: lines.length > 0 ? lines : ["No output."]
4183
+ };
4184
+ }
4185
+ /** The settled result of a child tool, parsed by tool; raw text only when it does not parse. */
4186
+ function workflowChildView(toolName, args, result) {
4187
+ if (toolName === "workflow_report_criteria") return reportView(args);
4188
+ const parsed = parseResult(result);
4189
+ if (!parsed.ok) return textView(result);
4190
+ const view = toolName === "workflow_spawn_child" || toolName === "workflow_child_status" ? invocationView(parsed.value) : toolName === "workflow_children" ? childrenView(parsed.value) : toolName === "workflow_review_artifacts" ? artifactsView(parsed.value) : void 0;
4191
+ if (view) return view;
4192
+ const generic = workflowGenericView(parsed.value);
4193
+ return {
4194
+ headline: generic.headline,
4195
+ facts: generic.facts,
4196
+ sections: generic.rows.length > 0 ? [{
4197
+ title: "Items",
4198
+ rows: generic.rows
4199
+ }] : []
4200
+ };
4201
+ }
4202
+ //#endregion
4203
+ //#region src/extensions/workspaces/sessions/(frontend)/tool/_components/WorkflowResultParts.native.tsx
4204
+ function WorkflowLines({ lines }) {
4205
+ return /* @__PURE__ */ jsx(View, {
4206
+ style: styles$2.lines,
4207
+ children: lines.map((entry, index) => /* @__PURE__ */ jsx(Text, {
4208
+ selectable: true,
4209
+ style: [
4210
+ styles$2.sans,
4211
+ TONE_STYLE[entry.tone],
4212
+ entry.bold === true ? styles$2.bold : null,
4213
+ entry.indent === true ? styles$2.indent : null
4214
+ ],
4215
+ children: entry.text
4216
+ }, `${String(index)}-${entry.text}`))
4217
+ });
4218
+ }
4219
+ /** The key figure of a result, with its status chip beside it when it has one. */
4220
+ function WorkflowHeadline({ text, chip }) {
4221
+ return /* @__PURE__ */ jsxs(View, {
4222
+ style: styles$2.headline,
4223
+ children: [text.length > 0 ? /* @__PURE__ */ jsx(Text, {
4224
+ numberOfLines: 1,
4225
+ style: [
4226
+ styles$2.sans,
4227
+ styles$2.bold,
4228
+ styles$2.hi,
4229
+ styles$2.headlineText
4230
+ ],
4231
+ children: text
4232
+ }) : null, chip !== void 0 ? /* @__PURE__ */ jsx(Badge, {
4233
+ tone: chip.tone,
4234
+ size: "xs",
4235
+ children: chip.label
4236
+ }) : null]
4237
+ });
4238
+ }
4239
+ /** Labelled figures, each label over its value, wrapping across the row. */
4240
+ function WorkflowFacts({ facts }) {
4241
+ if (facts.length === 0) return null;
4242
+ return /* @__PURE__ */ jsx(View, {
4243
+ style: styles$2.facts,
4244
+ children: facts.map((fact) => /* @__PURE__ */ jsxs(View, {
4245
+ style: styles$2.fact,
4246
+ children: [/* @__PURE__ */ jsx(Text, {
4247
+ style: styles$2.label,
4248
+ children: fact.label
4249
+ }), /* @__PURE__ */ jsx(Text, {
4250
+ selectable: true,
4251
+ numberOfLines: 1,
4252
+ ellipsizeMode: "middle",
4253
+ style: [styles$2.mono, styles$2.text],
4254
+ children: fact.value
4255
+ })]
4256
+ }, fact.label))
4257
+ });
4258
+ }
4259
+ /** A titled compact list: one row per item, the title and chip on a line, the detail quiet below. */
4260
+ function WorkflowRows({ title, rows }) {
4261
+ if (rows.length === 0) return null;
4262
+ return /* @__PURE__ */ jsxs(View, {
4263
+ style: styles$2.section,
4264
+ children: [title !== void 0 ? /* @__PURE__ */ jsx(Text, {
4265
+ style: styles$2.label,
4266
+ children: title
4267
+ }) : null, rows.map((row) => /* @__PURE__ */ jsxs(View, {
4268
+ style: styles$2.row,
4269
+ children: [/* @__PURE__ */ jsxs(View, {
4270
+ style: styles$2.rowLine,
4271
+ children: [/* @__PURE__ */ jsx(Text, {
4272
+ numberOfLines: 1,
4273
+ style: [
4274
+ styles$2.sans,
4275
+ styles$2.text,
4276
+ styles$2.rowTitle
4277
+ ],
4278
+ children: row.title
4279
+ }), row.chip !== void 0 ? /* @__PURE__ */ jsx(Badge, {
4280
+ tone: row.chip.tone,
4281
+ size: "xs",
4282
+ children: row.chip.label
4283
+ }) : null]
4284
+ }), row.detail !== void 0 ? /* @__PURE__ */ jsx(Text, {
4285
+ numberOfLines: 1,
4286
+ ellipsizeMode: "middle",
4287
+ style: [styles$2.small, styles$2.faint],
4288
+ children: row.detail
4289
+ }) : null]
4290
+ }, row.key))]
4291
+ });
4292
+ }
4293
+ function WorkflowNote({ children }) {
4294
+ return /* @__PURE__ */ jsx(Text, {
4295
+ style: [styles$2.small, styles$2.faint],
4296
+ children
4297
+ });
4298
+ }
4299
+ /** A failure reason, alone in red: the card's edge and icon already say it failed. */
4300
+ function WorkflowReason({ children }) {
4301
+ return /* @__PURE__ */ jsx(Text, {
4302
+ selectable: true,
4303
+ style: [styles$2.sans, styles$2.error],
4304
+ children
4305
+ });
4306
+ }
4307
+ const styles$2 = StyleSheet.create((theme) => ({
4308
+ sans: {
4309
+ fontFamily: fontOf(theme.fontFamily.sans),
4310
+ fontSize: theme.fontSize.base,
4311
+ lineHeight: theme.lineHeight.base,
4312
+ uni__dependencies: [0]
4313
+ },
4314
+ small: {
4315
+ fontFamily: fontOf(theme.fontFamily.sans),
4316
+ fontSize: theme.fontSize.sm,
4317
+ lineHeight: theme.lineHeight.sm,
4318
+ uni__dependencies: [0]
4319
+ },
4320
+ mono: {
4321
+ fontFamily: fontOf(theme.fontFamily.mono),
4322
+ fontSize: theme.fontSize.sm,
4323
+ lineHeight: theme.lineHeight.sm,
4324
+ uni__dependencies: [0]
4325
+ },
4326
+ lines: {
4327
+ gap: theme.spacing(.5),
4328
+ uni__dependencies: [0]
4329
+ },
4330
+ headline: {
4331
+ flexDirection: "row",
4332
+ alignItems: "center",
4333
+ gap: theme.spacing(2),
4334
+ minWidth: 0,
4335
+ uni__dependencies: [0]
4336
+ },
4337
+ headlineText: { flexShrink: 1 },
4338
+ facts: {
4339
+ flexDirection: "row",
4340
+ flexWrap: "wrap",
4341
+ columnGap: theme.spacing(5),
4342
+ rowGap: theme.spacing(2),
4343
+ uni__dependencies: [0]
4344
+ },
4345
+ fact: {
4346
+ gap: theme.spacing(.5),
4347
+ maxWidth: "100%",
4348
+ uni__dependencies: [0]
4349
+ },
4350
+ section: {
4351
+ gap: theme.spacing(2),
4352
+ uni__dependencies: [0]
4353
+ },
4354
+ row: {
4355
+ gap: theme.spacing(.5),
4356
+ uni__dependencies: [0]
4357
+ },
4358
+ rowLine: {
4359
+ flexDirection: "row",
4360
+ alignItems: "center",
4361
+ gap: theme.spacing(2),
4362
+ minWidth: 0,
4363
+ uni__dependencies: [0]
4364
+ },
4365
+ rowTitle: { flexShrink: 1 },
4366
+ label: {
4367
+ fontFamily: fontOf(theme.fontFamily.sans),
4368
+ fontSize: theme.fontSize.xs,
4369
+ lineHeight: theme.lineHeight.xs,
4370
+ fontWeight: theme.fontWeight.semibold,
4371
+ textTransform: "uppercase",
4372
+ color: theme.colors.dim,
4373
+ uni__dependencies: [0]
4374
+ },
4375
+ bold: {
4376
+ fontWeight: theme.fontWeight.semibold,
4377
+ uni__dependencies: [0]
4378
+ },
4379
+ indent: {
4380
+ paddingLeft: theme.spacing(4),
4381
+ uni__dependencies: [0]
4382
+ },
4383
+ error: {
4384
+ color: theme.colors.red,
4385
+ uni__dependencies: [0]
4386
+ },
4387
+ hi: {
4388
+ color: theme.colors.hi,
4389
+ uni__dependencies: [0]
4390
+ },
4391
+ text: {
4392
+ color: theme.colors.text,
4393
+ uni__dependencies: [0]
4394
+ },
4395
+ dim: {
4396
+ color: theme.colors.dim,
4397
+ uni__dependencies: [0]
4398
+ },
4399
+ faint: {
4400
+ color: theme.colors.faint,
4401
+ uni__dependencies: [0]
4402
+ },
4403
+ success: {
4404
+ color: theme.colors.green,
4405
+ uni__dependencies: [0]
4406
+ },
4407
+ warning: {
4408
+ color: theme.colors.yellow,
4409
+ uni__dependencies: [0]
4410
+ },
4411
+ accent: {
4412
+ color: theme.colors.blue,
4413
+ uni__dependencies: [0]
4414
+ }
4415
+ }));
4416
+ /** The line tones of the web's MessageLines, drawn with the same theme tokens. */
4417
+ const TONE_STYLE = {
4418
+ hi: styles$2.hi,
4419
+ text: styles$2.text,
4420
+ dim: styles$2.dim,
4421
+ muted: styles$2.faint,
4422
+ success: styles$2.success,
4423
+ error: styles$2.error,
4424
+ warning: styles$2.warning,
4425
+ accent: styles$2.accent
4426
+ };
4427
+ //#endregion
4428
+ //#region src/extensions/workspaces/sessions/(frontend)/tool/_components/WorkflowChildToolMessage.native.tsx
4429
+ /**
4430
+ * The workflow child tools' timeline item on native, as the web's: the job,
4431
+ * invocation or criteria count whole beside the tool name, the key figure
4432
+ * and its chip as the collapsed preview, and the facts and compact lists
4433
+ * once expanded. A failure shows only its reason.
4434
+ */
4435
+ function WorkflowChildToolMessage({ toolName, args, result, output, running, isError }) {
4436
+ const summary = workflowChildSummary(toolName, args);
4437
+ const view = running || isError ? void 0 : workflowChildView(toolName, args, result);
4438
+ const expandable = view !== void 0 && (view.facts.length > 0 || view.sections.length > 0 || view.error !== void 0 || view.note !== void 0 || (view.text?.length ?? 0) > 1);
4439
+ return /* @__PURE__ */ jsx(MessageItem, {
4440
+ tone: toolTone({
4441
+ running,
4442
+ isError
4443
+ }),
4444
+ expandable,
4445
+ children: ({ expanded }) => /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(MessageItemHeader, {
4446
+ title: toolName,
4447
+ children: /* @__PURE__ */ jsxs(View, {
4448
+ testID: `tool-call-${toolName}`,
4449
+ style: styles$1.summary,
4450
+ children: [summary.primary !== void 0 ? /* @__PURE__ */ jsx(Text, {
4451
+ numberOfLines: 1,
4452
+ style: [styles$1.sans, styles$1.primary],
4453
+ children: summary.primary
4454
+ }) : null, summary.primary === void 0 && summary.detail.length > 0 ? /* @__PURE__ */ jsx(Text, {
4455
+ numberOfLines: 1,
4456
+ style: [styles$1.sans, styles$1.detail],
4457
+ children: summary.detail.join(" · ")
4458
+ }) : null]
4459
+ })
4460
+ }), isError ? /* @__PURE__ */ jsx(MessageItemBody, {
4461
+ testID: `tool-result-${toolName}`,
4462
+ children: /* @__PURE__ */ jsx(WorkflowReason, { children: workflowFailureReason(result, output) })
4463
+ }) : running ? /* @__PURE__ */ jsx(MessageItemBody, {
4464
+ testID: `tool-result-${toolName}`,
4465
+ children: /* @__PURE__ */ jsx(MessageItemStatus, {
4466
+ tone: "running",
4467
+ children: workflowChildRunningLabel(toolName)
4468
+ })
4469
+ }) : view === void 0 ? null : view.text !== void 0 ? /* @__PURE__ */ jsx(MessageItemBody, {
4470
+ testID: `tool-result-${toolName}`,
4471
+ children: /* @__PURE__ */ jsx(WorkflowLines, { lines: (expanded ? view.text : view.text.slice(0, 1)).map((text) => ({
4472
+ text,
4473
+ tone: "text"
4474
+ })) })
4475
+ }) : /* @__PURE__ */ jsx(MessageItemBody, {
4476
+ testID: `tool-result-${toolName}`,
4477
+ children: /* @__PURE__ */ jsxs(View, {
4478
+ style: styles$1.stack,
4479
+ children: [/* @__PURE__ */ jsx(WorkflowHeadline, {
4480
+ text: view.headline,
4481
+ ...view.chip === void 0 ? {} : { chip: view.chip }
4482
+ }), expanded ? /* @__PURE__ */ jsxs(Fragment, { children: [
4483
+ view.error !== void 0 ? /* @__PURE__ */ jsx(WorkflowReason, { children: view.error }) : null,
4484
+ /* @__PURE__ */ jsx(WorkflowFacts, { facts: view.facts }),
4485
+ view.sections.map((section) => /* @__PURE__ */ jsx(WorkflowRows, {
4486
+ title: section.title,
4487
+ rows: section.rows
4488
+ }, section.title)),
4489
+ view.note !== void 0 ? /* @__PURE__ */ jsx(WorkflowNote, { children: view.note }) : null
4490
+ ] }) : null]
4491
+ })
4492
+ })] })
4493
+ });
4494
+ }
4495
+ const styles$1 = StyleSheet.create((theme) => ({
4496
+ summary: {
4497
+ flex: 1,
4498
+ flexDirection: "row",
4499
+ alignItems: "center",
4500
+ gap: theme.spacing(2),
4501
+ minWidth: 0,
4502
+ uni__dependencies: [0]
4503
+ },
4504
+ sans: {
4505
+ fontFamily: fontOf(theme.fontFamily.sans),
4506
+ fontSize: theme.fontSize.base,
4507
+ lineHeight: theme.lineHeight.base,
4508
+ uni__dependencies: [0]
4509
+ },
4510
+ primary: {
4511
+ flexShrink: 1,
4512
+ fontWeight: theme.fontWeight.semibold,
4513
+ color: theme.colors.hi,
4514
+ uni__dependencies: [0]
4515
+ },
4516
+ detail: {
4517
+ flexShrink: 1,
4518
+ color: theme.colors.faint,
4519
+ uni__dependencies: [0]
4520
+ },
4521
+ stack: {
4522
+ gap: theme.spacing(3),
4523
+ uni__dependencies: [0]
4524
+ }
4525
+ }));
4526
+ //#endregion
4527
+ //#region src/extensions/workspaces/sessions/(frontend)/tool/workflow-child.native.tsx
4528
+ /** The runtime registers only the child tools a session's role allows, so the names are matched, not just listed. */
4529
+ var workflow_child_native_default = defineToolRenderer({
4530
+ tools: [...WORKFLOW_CHILD_TOOL_NAMES],
4531
+ matches: matchesWorkflowChildTool,
4532
+ message: WorkflowChildToolMessage
4533
+ });
4534
+ //#endregion
4535
+ //#region src/extensions/workspaces/sessions/(frontend)/tool/_components/WorkflowToolMessage.native.tsx
4536
+ /**
4537
+ * The workflow tools' timeline item on native, as the web's: the action
4538
+ * whole beside the tool name with the target and flags truncating after it,
4539
+ * and the shape-specific summary lines in the body (a preview collapsed, as
4540
+ * the web shows). A JSON result the lines have no shape for, such as
4541
+ * list-failed, is laid out as figures and rows rather than printed. A failure
4542
+ * shows only its reason; the edge and icon say it failed.
4543
+ */
4544
+ function WorkflowToolMessage({ toolName, args, result, output, running, isError }) {
4545
+ const name = workflowToolName(toolName);
4546
+ const summary = workflowCallSummary(name, args);
4547
+ const detail = [summary.target, ...summary.metadata].filter((value) => value !== void 0);
4548
+ const structured = running || isError ? void 0 : workflowStructuredView(name, args, result);
4549
+ const collapsed = workflowResultLines(name, args, result, {
4550
+ expanded: false,
4551
+ isError,
4552
+ isPartial: running
4553
+ });
4554
+ const full = workflowResultLines(name, args, result, {
4555
+ expanded: true,
4556
+ isError,
4557
+ isPartial: running
4558
+ });
4559
+ const expandable = !isError && (structured !== void 0 ? structured.facts.length + structured.rows.length > 0 || structured.note !== void 0 : full.length > collapsed.length);
4560
+ return /* @__PURE__ */ jsx(MessageItem, {
4561
+ tone: toolTone({
4562
+ running,
4563
+ isError
4564
+ }),
4565
+ expandable,
4566
+ children: ({ expanded }) => /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(MessageItemHeader, {
4567
+ title: toolName,
4568
+ children: /* @__PURE__ */ jsxs(View, {
4569
+ testID: `tool-call-${toolName}`,
4570
+ style: styles.summary,
4571
+ children: [/* @__PURE__ */ jsx(Text, {
4572
+ numberOfLines: 1,
4573
+ style: [styles.sans, styles.primary],
4574
+ children: summary.action
4575
+ }), detail.length > 0 ? /* @__PURE__ */ jsxs(Text, {
4576
+ numberOfLines: 1,
4577
+ ellipsizeMode: "middle",
4578
+ style: [styles.sans, styles.detail],
4579
+ children: ["· ", detail.join(" · ")]
4580
+ }) : null]
4581
+ })
4582
+ }), isError ? /* @__PURE__ */ jsx(MessageItemBody, {
4583
+ testID: `tool-result-${toolName}`,
4584
+ children: /* @__PURE__ */ jsx(WorkflowReason, { children: workflowFailureReason(result, output) })
4585
+ }) : structured !== void 0 ? /* @__PURE__ */ jsx(MessageItemBody, {
4586
+ testID: `tool-result-${toolName}`,
4587
+ children: /* @__PURE__ */ jsxs(View, {
4588
+ style: styles.stack,
4589
+ children: [/* @__PURE__ */ jsx(WorkflowHeadline, { text: structured.headline }), expanded ? /* @__PURE__ */ jsxs(Fragment, { children: [
4590
+ /* @__PURE__ */ jsx(WorkflowFacts, { facts: structured.facts }),
4591
+ /* @__PURE__ */ jsx(WorkflowRows, { rows: structured.rows }),
4592
+ structured.note !== void 0 ? /* @__PURE__ */ jsx(WorkflowNote, { children: structured.note }) : null
4593
+ ] }) : null]
4594
+ })
4595
+ }) : (expanded ? full : collapsed).length > 0 ? /* @__PURE__ */ jsx(MessageItemBody, {
4596
+ testID: `tool-result-${toolName}`,
4597
+ children: /* @__PURE__ */ jsx(WorkflowLines, { lines: expanded ? full : collapsed })
4598
+ }) : null] })
4599
+ });
4600
+ }
4601
+ const styles = StyleSheet.create((theme) => ({
4602
+ summary: {
4603
+ flex: 1,
4604
+ flexDirection: "row",
4605
+ alignItems: "center",
4606
+ gap: theme.spacing(2),
4607
+ minWidth: 0,
4608
+ uni__dependencies: [0]
4609
+ },
4610
+ sans: {
4611
+ fontFamily: fontOf(theme.fontFamily.sans),
4612
+ fontSize: theme.fontSize.base,
4613
+ lineHeight: theme.lineHeight.base,
4614
+ uni__dependencies: [0]
4615
+ },
4616
+ primary: {
4617
+ flexShrink: 0,
4618
+ maxWidth: "50%",
4619
+ fontWeight: theme.fontWeight.semibold,
4620
+ color: theme.colors.hi,
4621
+ uni__dependencies: [0]
4622
+ },
4623
+ detail: {
4624
+ flexShrink: 1,
4625
+ color: theme.colors.faint,
4626
+ uni__dependencies: [0]
4627
+ },
4628
+ stack: {
4629
+ gap: theme.spacing(3),
4630
+ uni__dependencies: [0]
4631
+ }
4632
+ }));
4633
+ //#endregion
4634
+ //#region src/extensions/workspaces/sessions/(frontend)/tool/workflow.native.tsx
4635
+ var workflow_native_default = defineToolRenderer({
4636
+ tools: [
4637
+ "list_workflows",
4638
+ "launch_workflow",
4639
+ "workflow_run",
4640
+ "workflow_tools",
4641
+ "scaffold_workflow"
4642
+ ],
4643
+ message: WorkflowToolMessage
4644
+ });
4645
+ //#endregion
3246
4646
  //#region generated/native.ts
3247
4647
  const via = (identity, value) => value === void 0 ? void 0 : {
3248
4648
  ...identity,
@@ -3268,7 +4668,7 @@ const nativePlugin = defineNativePlugin({
3268
4668
  ];
3269
4669
  },
3270
4670
  get dockFaces() {
3271
- return [via({ id: "workflow" }, workflow_native_default)];
4671
+ return [via({ id: "workflow" }, workflow_native_default$1)];
3272
4672
  },
3273
4673
  get fills() {
3274
4674
  return [via({
@@ -3278,6 +4678,9 @@ const nativePlugin = defineNativePlugin({
3278
4678
  slot: "activity.workflows",
3279
4679
  id: "workflows"
3280
4680
  }, Workflows_activity_workflows_native_default)];
4681
+ },
4682
+ get toolRenderers() {
4683
+ return [via({ tools: ["workflow_child"] }, workflow_child_native_default), via({ tools: ["workflow"] }, workflow_native_default)];
3281
4684
  }
3282
4685
  }
3283
4686
  });