@agimon-ai/po-workflow 0.0.0-alpha.22 → 0.0.0-alpha.23

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,11 +1,12 @@
1
1
  import { createApiClient, defineActivityGroup, defineChannelFile, defineFill, defineNativePlugin, defineSessionStore, nativeApiTransport, sessionApiAddress } from "@agimon-ai/po-core/native";
2
- import { Badge, Button, CodeBlock, Dot, Input, ListRow, Markdown, Sheet, SheetBody, SheetContent, SheetHeader, SheetTitle, Textarea, WorkflowIcon } from "@agimon-ai/po-native-components";
2
+ import { ArrowRightIcon, Badge, Button, CodeBlock, Dot, Input, ListRow, Markdown, Sheet, SheetBody, SheetContent, SheetHeader, SheetTitle, Textarea, WorkflowIcon, fontOf } from "@agimon-ai/po-native-components";
3
3
  import { createElement, 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";
6
6
  import { ScrollView } from "react-native-unistyles/components/native/ScrollView";
7
7
  import { StyleSheet } from "react-native-unistyles";
8
8
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
9
+ import { Pressable } from "react-native-unistyles/components/native/Pressable";
9
10
  //#region src/extensions/workspaces/(frontend)/fill/Workflows.home.native.ts
10
11
  var Workflows_home_native_default = defineFill({ data: {
11
12
  version: 1,
@@ -808,7 +809,7 @@ function WorkflowLauncher(props) {
808
809
  setSelected(void 0);
809
810
  }
810
811
  }, workflow.path) : /* @__PURE__ */ jsxs(View, {
811
- style: styles.body,
812
+ style: styles$1.body,
812
813
  children: [
813
814
  /* @__PURE__ */ jsx(Input, {
814
815
  accessibilityLabel: "Find a workflow",
@@ -817,7 +818,7 @@ function WorkflowLauncher(props) {
817
818
  placeholder: "Find a workflow"
818
819
  }),
819
820
  state.warning ? /* @__PURE__ */ jsx(Text, {
820
- style: styles.error,
821
+ style: styles$1.error,
821
822
  children: state.warning
822
823
  }) : null,
823
824
  filterCatalog(state.workflows, filter).map((item) => /* @__PURE__ */ jsx(ListRow, {
@@ -829,7 +830,7 @@ function WorkflowLauncher(props) {
829
830
  description: `${item.description}\n${item.tags.join(", ")} · ${item.jobs.map((job) => job.name).join(", ")}`
830
831
  }, item.path)),
831
832
  state.workflows.length === 0 ? /* @__PURE__ */ jsx(Text, {
832
- style: styles.meta,
833
+ style: styles$1.meta,
833
834
  children: "No workflows reported yet."
834
835
  }) : null
835
836
  ]
@@ -838,7 +839,7 @@ function WorkflowLauncher(props) {
838
839
  }
839
840
  function Choice({ label, options, value, onChange }) {
840
841
  return /* @__PURE__ */ jsxs(View, { children: [/* @__PURE__ */ jsx(Text, {
841
- style: styles.meta,
842
+ style: styles$1.meta,
842
843
  children: label
843
844
  }), options.map((option) => /* @__PURE__ */ jsx(Button, {
844
845
  variant: "outline",
@@ -865,10 +866,10 @@ function WorkflowLaunch({ sessionId, workflow, initialPrompt, sendSessionFrame,
865
866
  const problems = launchProblems(workflow, request);
866
867
  const line = workflowLaunchLine(request);
867
868
  return /* @__PURE__ */ jsxs(View, {
868
- style: styles.body,
869
+ style: styles$1.body,
869
870
  children: [
870
871
  /* @__PURE__ */ jsx(Text, {
871
- style: styles.meta,
872
+ style: styles$1.meta,
872
873
  children: workflow.description
873
874
  }),
874
875
  /* @__PURE__ */ jsx(Textarea, {
@@ -880,7 +881,7 @@ function WorkflowLaunch({ sessionId, workflow, initialPrompt, sendSessionFrame,
880
881
  workflow.inputs.map((input) => {
881
882
  const options = input.options ?? (input.type === "boolean" ? ["true", "false"] : void 0);
882
883
  return /* @__PURE__ */ jsxs(View, { children: [/* @__PURE__ */ jsxs(Text, {
883
- style: styles.meta,
884
+ style: styles$1.meta,
884
885
  children: [
885
886
  input.name,
886
887
  input.required ? " (required)" : "",
@@ -924,11 +925,11 @@ function WorkflowLaunch({ sessionId, workflow, initialPrompt, sendSessionFrame,
924
925
  }) : null,
925
926
  /* @__PURE__ */ jsx(CodeBlock, { text: line }),
926
927
  problems.map((problem) => /* @__PURE__ */ jsx(Text, {
927
- style: styles.meta,
928
+ style: styles$1.meta,
928
929
  children: problem
929
930
  }, problem)),
930
931
  error ? /* @__PURE__ */ jsx(Text, {
931
- style: styles.error,
932
+ style: styles$1.error,
932
933
  children: error
933
934
  }) : null,
934
935
  /* @__PURE__ */ jsx(Button, {
@@ -966,19 +967,19 @@ function WorkflowPanel(props) {
966
967
  }
967
968
  };
968
969
  if (!run) return /* @__PURE__ */ jsx(Text, {
969
- style: styles.meta,
970
+ style: styles$1.meta,
970
971
  children: "This run is no longer listed."
971
972
  });
972
973
  return /* @__PURE__ */ jsxs(ScrollView, {
973
- contentContainerStyle: styles.body,
974
+ contentContainerStyle: styles$1.body,
974
975
  children: [
975
976
  /* @__PURE__ */ jsx(Text, {
976
- style: styles.title,
977
+ style: styles$1.title,
977
978
  children: run.displayName
978
979
  }),
979
980
  /* @__PURE__ */ jsx(Badge, { children: run.executionState ?? run.outcome ?? run.stage }),
980
981
  /* @__PURE__ */ jsx(Text, {
981
- style: styles.meta,
982
+ style: styles$1.meta,
982
983
  children: run.errorMessage ?? `${run.position?.job ?? ""} ${run.position?.step ?? ""}`
983
984
  }),
984
985
  state.runs.length > 1 ? state.runs.map((item) => /* @__PURE__ */ jsx(Button, {
@@ -990,7 +991,7 @@ function WorkflowPanel(props) {
990
991
  children: item.displayName
991
992
  }, workflowRunIdentity(item))) : null,
992
993
  run.executionState === "paused" || run.executionState === "pause_requested" ? /* @__PURE__ */ jsx(Text, {
993
- style: styles.meta,
994
+ style: styles$1.meta,
994
995
  children: "Waiting to be resumed. Ask the agent in this conversation to resume it."
995
996
  }) : null,
996
997
  run.jobs.map((job) => /* @__PURE__ */ jsxs(View, { children: [/* @__PURE__ */ jsxs(Button, {
@@ -1010,7 +1011,7 @@ function WorkflowPanel(props) {
1010
1011
  description: step.status
1011
1012
  }, step.name))] }, job.name)),
1012
1013
  /* @__PURE__ */ jsx(Text, {
1013
- style: styles.title,
1014
+ style: styles$1.title,
1014
1015
  children: "Artifacts"
1015
1016
  }),
1016
1017
  /* @__PURE__ */ jsx(WorkflowArtifacts, {
@@ -1018,7 +1019,7 @@ function WorkflowPanel(props) {
1018
1019
  run
1019
1020
  }),
1020
1021
  error ? /* @__PURE__ */ jsx(Text, {
1021
- style: styles.error,
1022
+ style: styles$1.error,
1022
1023
  children: error
1023
1024
  }) : null,
1024
1025
  run.stage === "running" ? /* @__PURE__ */ jsx(Button, {
@@ -1039,7 +1040,7 @@ function WorkflowPanel(props) {
1039
1040
  open: confirmDelete,
1040
1041
  onOpenChange: setConfirmDelete,
1041
1042
  children: /* @__PURE__ */ jsxs(SheetContent, { children: [/* @__PURE__ */ jsx(SheetHeader, { children: /* @__PURE__ */ jsx(SheetTitle, { children: "Delete this run?" }) }), /* @__PURE__ */ jsxs(SheetBody, { children: [/* @__PURE__ */ jsx(Text, {
1042
- style: styles.meta,
1043
+ style: styles$1.meta,
1043
1044
  children: "This permanently removes the settled run and its directory."
1044
1045
  }), /* @__PURE__ */ jsx(Button, {
1045
1046
  variant: "danger-outline",
@@ -1082,10 +1083,10 @@ function WorkflowStep({ sessionId, workspace, runKey, job, step, renderSessionTr
1082
1083
  const ref = target?.ref;
1083
1084
  const session = ref?.kind === "session" ? ref.id : void 0;
1084
1085
  return /* @__PURE__ */ jsxs(View, {
1085
- style: styles.screen,
1086
+ style: styles$1.screen,
1086
1087
  children: [
1087
1088
  /* @__PURE__ */ jsxs(Text, {
1088
- style: styles.title,
1089
+ style: styles$1.title,
1089
1090
  children: [
1090
1091
  job,
1091
1092
  step === void 0 ? "" : ` › ${step}`,
@@ -1101,7 +1102,7 @@ function WorkflowStep({ sessionId, workspace, runKey, job, step, renderSessionTr
1101
1102
  renderRunnerTerminal
1102
1103
  }, `${sessionId}:${workspace}:${runKey}:${ref?.id ?? ""}`),
1103
1104
  session && run?.stage === "running" && target?.status === "running" ? /* @__PURE__ */ jsxs(View, {
1104
- style: styles.body,
1105
+ style: styles$1.body,
1105
1106
  children: [/* @__PURE__ */ jsx(Textarea, {
1106
1107
  accessibilityLabel: "Step guidance",
1107
1108
  value: message,
@@ -1122,7 +1123,7 @@ function WorkflowStep({ sessionId, workspace, runKey, job, step, renderSessionTr
1122
1123
  })]
1123
1124
  }) : null,
1124
1125
  error ? /* @__PURE__ */ jsx(Text, {
1125
- style: styles.error,
1126
+ style: styles$1.error,
1126
1127
  children: error
1127
1128
  }) : null
1128
1129
  ]
@@ -1194,7 +1195,7 @@ function WorkflowTerminal({ sessionId, workspace, runKey, pane, renderRunnerTerm
1194
1195
  }
1195
1196
  };
1196
1197
  return /* @__PURE__ */ jsxs(View, {
1197
- style: styles.transcript,
1198
+ style: styles$1.transcript,
1198
1199
  children: [
1199
1200
  /* @__PURE__ */ jsx(Badge, { children: token ? "keyboard yours" : "watching" }),
1200
1201
  capabilities?.writable ? /* @__PURE__ */ jsx(Button, {
@@ -1207,11 +1208,11 @@ function WorkflowTerminal({ sessionId, workspace, runKey, pane, renderRunnerTerm
1207
1208
  children: token ? "Release keyboard" : "Take control"
1208
1209
  }) : null,
1209
1210
  /* @__PURE__ */ jsx(View, {
1210
- style: styles.transcript,
1211
+ style: styles$1.transcript,
1211
1212
  children: renderRunnerTerminal?.(request)
1212
1213
  }),
1213
1214
  capabilities?.reason ? /* @__PURE__ */ jsx(Text, {
1214
- style: styles.meta,
1215
+ style: styles$1.meta,
1215
1216
  children: capabilities.reason
1216
1217
  }) : null,
1217
1218
  token && capabilities?.resizable ? /* @__PURE__ */ jsxs(View, { children: [
@@ -1239,7 +1240,7 @@ function WorkflowTerminal({ sessionId, workspace, runKey, pane, renderRunnerTerm
1239
1240
  })
1240
1241
  ] }) : null,
1241
1242
  notice ? /* @__PURE__ */ jsx(Text, {
1242
- style: styles.meta,
1243
+ style: styles$1.meta,
1243
1244
  children: notice
1244
1245
  }) : null
1245
1246
  ]
@@ -1276,7 +1277,7 @@ function WorkflowArtifacts(props) {
1276
1277
  ]);
1277
1278
  return /* @__PURE__ */ jsxs(View, { children: [
1278
1279
  error ? /* @__PURE__ */ jsx(Text, {
1279
- style: styles.error,
1280
+ style: styles$1.error,
1280
1281
  children: error
1281
1282
  }) : null,
1282
1283
  directory ? /* @__PURE__ */ jsx(Button, {
@@ -1359,10 +1360,10 @@ function ArtifactPreview({ sessionId, workspace, runKey, path, renderFilePreview
1359
1360
  }
1360
1361
  };
1361
1362
  return /* @__PURE__ */ jsxs(ScrollView, {
1362
- contentContainerStyle: styles.body,
1363
+ contentContainerStyle: styles$1.body,
1363
1364
  children: [
1364
1365
  /* @__PURE__ */ jsx(Text, {
1365
- style: styles.title,
1366
+ style: styles$1.title,
1366
1367
  children: path
1367
1368
  }),
1368
1369
  /* @__PURE__ */ jsx(Button, {
@@ -1377,11 +1378,11 @@ function ArtifactPreview({ sessionId, workspace, runKey, path, renderFilePreview
1377
1378
  children: "Cancel download"
1378
1379
  }) : null,
1379
1380
  saveNote ? /* @__PURE__ */ jsx(Text, {
1380
- style: styles.meta,
1381
+ style: styles$1.meta,
1381
1382
  children: saveNote
1382
1383
  }) : null,
1383
1384
  error ? /* @__PURE__ */ jsx(Text, {
1384
- style: styles.error,
1385
+ style: styles$1.error,
1385
1386
  children: error
1386
1387
  }) : null,
1387
1388
  content?.text !== void 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -1399,7 +1400,7 @@ function ArtifactPreview({ sessionId, workspace, runKey, path, renderFilePreview
1399
1400
  delimiter: /\.csv$/i.test(path) ? "," : " "
1400
1401
  }) : /* @__PURE__ */ jsx(CodeBlock, { text: !raw && /\.json$/i.test(path) ? prettyJson(content.text) : content.text }),
1401
1402
  content.truncated ? /* @__PURE__ */ jsx(Text, {
1402
- style: styles.meta,
1403
+ style: styles$1.meta,
1403
1404
  children: "This preview was truncated."
1404
1405
  }) : null
1405
1406
  ] }) : content ? /* @__PURE__ */ jsx(BinaryArtifactPreview, {
@@ -1409,7 +1410,7 @@ function ArtifactPreview({ sessionId, workspace, runKey, path, renderFilePreview
1409
1410
  path,
1410
1411
  renderMediaPreview
1411
1412
  }) : /* @__PURE__ */ jsx(Text, {
1412
- style: styles.meta,
1413
+ style: styles$1.meta,
1413
1414
  children: "Loading preview…"
1414
1415
  })
1415
1416
  ]
@@ -1452,7 +1453,7 @@ function BinaryArtifactPreview({ sessionId, workspace, runKey, path, renderMedia
1452
1453
  title: path,
1453
1454
  path
1454
1455
  }) : /* @__PURE__ */ jsx(Text, {
1455
- style: styles.meta,
1456
+ style: styles$1.meta,
1456
1457
  children: error ?? "Loading preview…"
1457
1458
  });
1458
1459
  }
@@ -1490,15 +1491,15 @@ function DelimitedArtifact({ text, delimiter }) {
1490
1491
  return /* @__PURE__ */ jsx(ScrollView, {
1491
1492
  horizontal: true,
1492
1493
  children: /* @__PURE__ */ jsx(View, { children: rows.map((cells, index) => /* @__PURE__ */ jsx(View, {
1493
- style: styles.tableRow,
1494
+ style: styles$1.tableRow,
1494
1495
  children: cells.map((value, column) => /* @__PURE__ */ jsx(Text, {
1495
- style: styles.tableCell,
1496
+ style: styles$1.tableCell,
1496
1497
  children: value
1497
1498
  }, column))
1498
1499
  }, index)) })
1499
1500
  });
1500
1501
  }
1501
- const styles = StyleSheet.create((theme) => ({
1502
+ const styles$1 = StyleSheet.create((theme) => ({
1502
1503
  screen: {
1503
1504
  flex: 1,
1504
1505
  backgroundColor: theme.colors.bg,
@@ -1584,16 +1585,61 @@ function WorkflowsActivitySection({ sessionId, openSession, openTransientTab })
1584
1585
  }),
1585
1586
  description: `${row.detail} · ${row.elapsed}`
1586
1587
  }, row.identity)) : null] }, group.name);
1587
- }), groups.length === 0 ? /* @__PURE__ */ jsx(Button, {
1588
- variant: "ghost",
1589
- testID: "activity-workflow-launch",
1590
- disabled: sessionId === null,
1591
- onPress: () => {
1592
- if (sessionId !== null) openCatalog(sessionId);
1593
- },
1594
- children: "Launch a workflow"
1588
+ }), groups.length === 0 ? /* @__PURE__ */ jsxs(View, {
1589
+ style: styles.idle,
1590
+ children: [/* @__PURE__ */ jsx(Text, {
1591
+ style: styles.status,
1592
+ children: "Idle"
1593
+ }), /* @__PURE__ */ jsxs(Pressable, {
1594
+ accessibilityRole: "button",
1595
+ accessibilityState: { disabled: sessionId === null },
1596
+ testID: "activity-workflow-launch",
1597
+ disabled: sessionId === null,
1598
+ hitSlop: 10,
1599
+ onPress: () => {
1600
+ if (sessionId !== null) openCatalog(sessionId);
1601
+ },
1602
+ style: styles.action,
1603
+ children: [/* @__PURE__ */ jsx(Text, {
1604
+ style: styles.actionText(sessionId === null),
1605
+ children: "Launch a workflow"
1606
+ }), /* @__PURE__ */ jsx(ArrowRightIcon, {
1607
+ size: 14,
1608
+ color: sessionId === null ? "dim" : "green"
1609
+ })]
1610
+ })]
1595
1611
  }) : null] });
1596
1612
  }
1613
+ const styles = StyleSheet.create((theme) => ({
1614
+ idle: {
1615
+ flexDirection: "row",
1616
+ alignItems: "center",
1617
+ flexWrap: "wrap",
1618
+ gap: theme.spacing(4),
1619
+ uni__dependencies: [0]
1620
+ },
1621
+ status: {
1622
+ fontFamily: fontOf(theme.fontFamily.sans),
1623
+ fontSize: theme.fontSize.sm,
1624
+ lineHeight: theme.lineHeight.sm,
1625
+ color: theme.colors.dim,
1626
+ uni__dependencies: [0]
1627
+ },
1628
+ action: {
1629
+ flexDirection: "row",
1630
+ alignItems: "center",
1631
+ gap: theme.spacing(1),
1632
+ uni__dependencies: [0]
1633
+ },
1634
+ actionText: (disabled) => ({
1635
+ fontFamily: fontOf(theme.fontFamily.sans),
1636
+ fontSize: theme.fontSize.base,
1637
+ lineHeight: theme.lineHeight.base,
1638
+ fontWeight: theme.fontWeight.medium,
1639
+ color: disabled ? theme.colors.dim : theme.colors.green,
1640
+ uni__dependencies: [0]
1641
+ })
1642
+ }));
1597
1643
  //#endregion
1598
1644
  //#region src/extensions/workspaces/sessions/(frontend)/fill/Workflows.activity.workflows.native.tsx
1599
1645
  var Workflows_activity_workflows_native_default = defineFill({ component: WorkflowsActivitySection });
@@ -1 +1 @@
1
- {"version":3,"file":"native.mjs","names":["isRecord","isRecord","WebPluginSlotProps","Badge","Button","CodeBlock","Input","ListRow","Markdown","Sheet","SheetBody","SheetContent","SheetHeader","SheetTitle","Textarea","useCallback","useEffect","useMemo","useRef","useState","useSyncExternalStore","StyleSheet","WorkflowCatalogEntryView","WorkflowRunView","WorkflowArtifactContentResponse","WorkflowArtifactsResponse","WorkflowTerminalCapabilitiesView","catalog","closeCatalog","filterCatalog","initialChoice","initialCommand","initialInputs","initialRunner","launchProblems","workflowLaunchLine","deleteWorkflowRun","fetchArtifact","fetchArtifactMedia","prepareArtifactSave","finiteScreenReader","fetchArtifacts","readScreen","releaseControl","resizeRun","sendKeys","takeControl","steerStep","stopWorkflowRun","workflowRunIdentity","focusRun","removeRun","requestLaunch","workflows","useWorkflows","sessionId","subscribe","listener","sub","store","unsubscribe","select","state","workflowTab","run","Parameters","identity","id","workspace","routeKey","runKey","replace","label","displayName","retainComposer","panel","props","WorkflowLauncher","filter","setFilter","selected","setSelected","open","workflow","find","item","path","undefined","name","prompt","styles","body","warning","error","map","relativePath","description","tags","join","jobs","job","length","meta","Choice","options","value","onChange","option","WorkflowLaunch","initialPrompt","sendSessionFrame","onClose","setPrompt","inputs","setInputs","runner","setRunner","command","setCommand","choice","setChoice","setError","request","trim","problems","line","input","type","required","current","runners","commands","choices","problem","cause","Error","message","String","WorkflowPanel","runs","confirmDelete","setConfirmDelete","busy","setBusy","act","action","Promise","title","executionState","outcome","stage","errorMessage","position","step","openTransientTab","stepTab","status","steps","result","closeTransientTab","WorkflowStep","renderSessionTranscript","renderRunnerTerminal","target","at","setMessage","ref","session","kind","screen","then","catch","finally","WorkflowTerminal","pane","Pick","capabilities","setCapabilities","token","setToken","notice","setNotice","columns","setColumns","rows","setRows","lifetime","AbortController","abort","key","read","signal","frame","aborted","write","text","arm","grant","held","reason","transcript","writable","resizable","Number","isInteger","WorkflowArtifacts","directory","setDirectory","listing","setListing","active","artifacts","includes","slice","lastIndexOf","panelProps","ArtifactPreview","renderFilePreview","renderMediaPreview","nativeSaveFile","content","setContent","raw","setRaw","artifact","downloadController","saving","setSaving","saveNote","setSaveNote","download","controller","test","html","prettyJson","truncated","BinaryArtifactPreview","requestKey","JSON","stringify","loaded","setLoaded","media","data","mimeType","parse","DelimitedArtifact","delimiter","row","cell","quoted","index","character","push","cells","tableRow","column","tableCell","create","theme","flex","backgroundColor","colors","bg","padding","spacing","uni__dependencies","flexDirection","color","fontSize","sm","width","borderWidth","borderColor","border","gap","hi","base","fontWeight","dim","red","WebPluginSlotProps","Button","Dot","ListRow","useEffect","useState","useWorkflows","workflowTab","openCatalog","workflowActivityGroups","workflowActivityRows","WorkflowActivityGroupName","focusRun","WorkflowsActivitySection","sessionId","openSession","openTransientTab","state","now","setNow","Date","folded","setFolded","Partial","Record","timer","setInterval","clearInterval","groups","runs","map","group","open","name","openByDefault","expanded","current","rows","length","row","identity","tone","runKey","ownerSessionId","run","find","item","workspace","routeKey","detail","elapsed","fillWorkflows","activityGroupWorkflows","channelWorkflowCatalog","channelWorkflowRuns","fillWorkflowLauncher","fillWorkflows2"],"sources":["../../src/extensions/workspaces/(frontend)/fill/Workflows.home.native.ts","../../src/types/webWorkflows.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/runDuration.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/workflowActivity.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/workflowsStore.native.ts","../../src/extensions/workspaces/sessions/(frontend)/activity-group/workflows.native.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/catalogStore.native.ts","../../src/extensions/workspaces/sessions/(frontend)/channel/workflow-catalog.native.ts","../../src/extensions/workspaces/sessions/(frontend)/channel/workflow-runs.native.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/launchLine.ts","../../src/types/apiRoutes.ts","../../generated/client.native.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/terminalApi.native.ts","../../src/extensions/workspaces/sessions/(frontend)/_components/WorkflowPanel.native.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/WorkflowLauncher.overlay.native.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/_components/WorkflowsActivitySection.native.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/Workflows.activity.workflows.native.tsx","../../generated/native.ts"],"sourcesContent":["import { defineFill } from '@agimon-ai/po-core/native';\n\nexport default defineFill({\n data: { version: 1, label: 'Workflows', source: 'workflow_runs', destination: 'workflows' },\n});\n","/**\n * Workflow run view types shared by this package's hub channel and its web\n * plugin. The shapes mirror what the embedded workflow-mcp engine records;\n * the cockpit renders them as 'workflow_runs' channel payloads.\n */\n\n/** workflow-mcp's own stage vocabulary; the registry bucket a run record sits in. */\nexport type WorkflowStage = 'running' | 'completed' | 'error';\n\n/** workflow-mcp's terminal outcome for a finished run. */\nexport type WorkflowOutcome = 'success' | 'skipped' | 'failed' | 'interrupted';\n\n/** Recorded job/step states, plus pending entries from the workflow definition. */\nexport type WorkflowProgressState =\n | 'pending'\n | 'running'\n | 'completed'\n | 'skipped'\n | 'failed'\n | 'pause_requested'\n | 'paused'\n | 'resumed';\n\n/** A customRun step ran as this child session. */\nexport const STEP_SESSION_REF_KIND = 'session';\n/** A command step ran in this terminal pane. */\nexport const STEP_PANE_REF_KIND = 'pane';\n\n/** Where a host executor ran a step: `session` for a customRun agent, `pane` for a command. */\nexport interface WorkflowStepRefView {\n kind: string;\n id: string;\n label?: string;\n}\n\nexport interface WorkflowStepView {\n name: string;\n status: WorkflowProgressState;\n /** Kept after the step ends, so a finished agent step still opens its conversation. */\n ref?: WorkflowStepRefView;\n /** Why the step is in its state, when the engine recorded one (e.g. a skip condition). */\n reason?: string;\n /** The parallel group the step ran in, beside the group's other steps. */\n group?: string;\n /** ISO 8601 of the step's first running event. */\n startedAt?: string;\n /** ISO 8601 of the step's terminal event. */\n endedAt?: string;\n}\n\n/** 'pre' and 'post' are the engine's pseudo-jobs for its pre:/post: blocks. */\nexport type WorkflowJobPhase = 'pre' | 'job' | 'post';\n\nexport interface WorkflowJobView {\n name: string;\n phase: WorkflowJobPhase;\n status: WorkflowProgressState;\n reason?: string;\n /** Position among the run's jobs, when the engine recorded one. */\n index?: number;\n total?: number;\n startedAt?: string;\n endedAt?: string;\n steps: WorkflowStepView[];\n}\n\n/** The job and step a run is on right now; drives the NOW breadcrumb. */\nexport interface WorkflowPosition {\n job: string;\n step?: string;\n index?: number;\n total?: number;\n}\n\n/**\n * One workflow run of a session, read from workflow-mcp's registry: the\n * run.json record plus the folded progress.ndjson job tree.\n */\nexport interface WorkflowRunView {\n /** Opaque owner-qualified API/cache key. The displayed engine runKey stays unchanged. */\n routeKey?: string;\n /** Engine generation identity, distinct from a reused run key. */\n runId?: string;\n /** Registry identity within its workspace; unique per workspace+stage. */\n runKey: string;\n workspace: string;\n displayName: string;\n workflowName?: string;\n workflowPath: string;\n stage: WorkflowStage;\n outcome?: WorkflowOutcome;\n /** Present while the engine is pausing or paused; absent for plain running. */\n executionState?: 'running' | 'pause_requested' | 'paused' | 'resume_requested';\n /** The prompt the run was launched with, when one was recorded. */\n prompt?: string;\n /** ISO 8601, from the run record. */\n startedAt: string;\n finishedAt?: string;\n /** Failure cause with ANSI escapes stripped, present when the run errored. */\n errorMessage?: string;\n /** The job the engine blamed for the failure, when it recorded one. */\n failedJob?: string;\n /** True when reconciliation decided the recorded pid is no longer alive. */\n stale?: boolean;\n staleReason?: string;\n worktreeBranch?: string;\n /** The session that owns the run (its PI_SESSION_ID); absent on records that carry none. */\n ownerSessionId?: string;\n /** The session that launched the run into its own workflow session, when it was handed off. */\n launcherSessionId?: string;\n position?: WorkflowPosition;\n jobs: WorkflowJobView[];\n}\n\n/** What the workflow runs channel publishes for one session. */\nexport interface WorkflowRunsPayload {\n runs: WorkflowRunView[];\n}\n\nexport const WORKFLOW_RUNS_TYPE = 'workflow_runs';\n\n/**\n * One workflow the session's directory can launch, as the catalog drawer\n * lists it: the engine's own catalog entry plus the parsed detail the drawer\n * unfolds and the launch dialog turns into fields.\n */\nexport interface WorkflowCatalogEntryView {\n /** Absolute path, the row's stable identity. */\n path: string;\n relativePath: string;\n name: string;\n description: string;\n tags: string[];\n /** The trigger names the file declares, such as workflow_dispatch. */\n triggers: string[];\n inputs: WorkflowCatalogInputView[];\n jobs: WorkflowCatalogJobView[];\n artifacts: WorkflowCatalogArtifactView[];\n /** Absent when the workflow names no runner map, which means any runner will do. */\n runners?: string[];\n /** Commands every templated step offers; absent when no step is templated. */\n commands?: string[];\n /** Declared model choices; `default` is used when a launch names none. */\n choices?: string[];\n /** Set when the file could not be parsed; the row shows this instead of guessing. */\n error?: string;\n}\n\nexport interface WorkflowCatalogInputView {\n name: string;\n description?: string;\n required?: boolean;\n default?: string;\n type?: string;\n options?: string[];\n}\n\nexport interface WorkflowCatalogJobView {\n name: string;\n steps: string[];\n}\n\nexport interface WorkflowCatalogArtifactView {\n path: string;\n kind: 'file' | 'directory';\n description: string;\n producedBy: string[];\n}\n\n/** What the catalog channel publishes for one session. */\nexport interface WorkflowCatalogPayload {\n /** The directory the catalog was read from, which is the session's own. */\n cwd: string;\n workflows: WorkflowCatalogEntryView[];\n /** Present when the directory could not be read at all. */\n warning?: string;\n}\n\nexport const WORKFLOW_CATALOG_TYPE = 'workflow_catalog';\n\nexport interface WorkflowInputSummary {\n name: string;\n description?: string;\n required?: boolean;\n default?: string;\n options?: readonly string[];\n}\n\nexport interface WorkflowJobSummary {\n name: string;\n steps: readonly string[];\n}\n\n/**\n * What the detail pane shows for one workflow. `runners` is undefined when the\n * workflow names no runner map at all, which is not the same as naming an empty\n * one - see `compatibleRunners`.\n */\nexport interface WorkflowCatalogDetail {\n triggers: readonly string[];\n inputs: readonly WorkflowInputSummary[];\n jobs: readonly WorkflowJobSummary[];\n runners?: readonly string[];\n /** Commands every templated step offers; absent when no step is templated. */\n commands?: readonly string[];\n /** Declared model choices. */\n choices?: readonly string[];\n /** Set when the file could not be parsed; the pane shows this instead of guessing. */\n error?: string;\n}\n","/**\n * Local copy of the host's formatRunDuration (src/web/lib/sessionSummary.ts):\n * this plugin keeps zero host-lib imports so its later move into the owning\n * package is a file relocation.\n */\nconst MINUTE_MS = 60 * 1000;\nconst HOUR_MS = 60 * MINUTE_MS;\n\nexport function formatRunDuration(elapsedMs: number): string {\n if (elapsedMs < MINUTE_MS) return '<1m';\n if (elapsedMs < HOUR_MS) return `${Math.floor(elapsedMs / MINUTE_MS)}m`;\n const hours = Math.floor(elapsedMs / HOUR_MS);\n const minutes = Math.floor((elapsedMs % HOUR_MS) / MINUTE_MS);\n return `${hours}h ${String(minutes).padStart(2, '0')}m`;\n}\n","import type { WorkflowRunView } from '../../../../../types/webWorkflows';\nimport { formatRunDuration } from './runDuration';\n\nexport type WorkflowActivityTone = 'running' | 'paused' | 'failed' | 'done' | 'skipped';\n\n/** One run as the activity dock lists it: identity, a tone, and a one-liner. */\nexport interface WorkflowActivityRow {\n /** Registry identity: workspace/runKey, unique across the session's runs. */\n identity: string;\n runKey: string;\n name: string;\n tone: WorkflowActivityTone;\n elapsed: string;\n /** Where the run is right now, or how it ended. */\n detail: string;\n /** The workflow session that owns the run, when it is not the session listing it. */\n ownerSessionId?: string;\n}\n\nconst PAUSED_STATES: ReadonlySet<NonNullable<WorkflowRunView['executionState']>> = new Set([\n 'paused',\n 'pause_requested',\n]);\n\nexport function workflowRunIdentity(run: Pick<WorkflowRunView, 'workspace' | 'runKey' | 'routeKey'>): string {\n return `${run.workspace}/${run.routeKey ?? run.runKey}`;\n}\n\n/** Whether the session runs this workflow itself; a record from an older hub names no owner and means the viewer. */\nexport function ownsRun(run: Pick<WorkflowRunView, 'ownerSessionId'>, sessionId: string | null): boolean {\n return sessionId !== null && (run.ownerSessionId ?? sessionId) === sessionId;\n}\n\nfunction toneOf(run: WorkflowRunView): WorkflowActivityTone {\n if (run.stage === 'running') {\n return run.executionState !== undefined && PAUSED_STATES.has(run.executionState) ? 'paused' : 'running';\n }\n if (run.stage === 'error') return 'failed';\n if (run.outcome !== undefined && run.outcome !== 'success') return run.outcome === 'failed' ? 'failed' : 'skipped';\n return 'done';\n}\n\nfunction detailOf(run: WorkflowRunView, tone: WorkflowActivityTone): string {\n if (tone === 'paused') return 'paused; resume it from the owning session';\n if (tone === 'failed')\n return run.errorMessage ?? (run.failedJob === undefined ? 'failed' : `job '${run.failedJob}' failed`);\n if (tone === 'running') {\n if (run.position === undefined) return 'starting';\n return run.position.step === undefined ? run.position.job : `${run.position.job} · ${run.position.step}`;\n }\n return run.outcome ?? 'done';\n}\n\nfunction elapsedOf(run: WorkflowRunView, now: number): string {\n const start = Date.parse(run.startedAt);\n if (!Number.isFinite(start)) return '';\n const end = run.finishedAt === undefined ? now : Date.parse(run.finishedAt);\n return formatRunDuration(Math.max(0, (Number.isFinite(end) ? end : now) - start));\n}\n\n/** The hub's presented order is kept: it already puts live runs first. */\nexport function workflowActivityRows(\n runs: readonly WorkflowRunView[],\n now: number,\n sessionId: string | null = null,\n): WorkflowActivityRow[] {\n return runs.map((run) => {\n const tone = toneOf(run);\n return {\n identity: workflowRunIdentity(run),\n runKey: run.runKey,\n name: run.displayName,\n tone,\n elapsed: elapsedOf(run, now),\n detail: detailOf(run, tone),\n ...(run.ownerSessionId === undefined || run.ownerSessionId === sessionId\n ? {}\n : { ownerSessionId: run.ownerSessionId }),\n };\n });\n}\n\n/** The three answers a reader wants from the dock: what is live, what broke, what is done. */\nexport type WorkflowActivityGroupName = 'running' | 'failed' | 'successful';\n\nexport interface WorkflowActivityGroup {\n name: WorkflowActivityGroupName;\n rows: WorkflowActivityRow[];\n /**\n * Whether the group is open when the dock first draws it.\n *\n * Failures open because they are the only ones that need an answer, and a\n * folded failure is one nobody sees. Everything else stays folded so a\n * session's whole history does not push the other groups off the dock.\n */\n openByDefault: boolean;\n}\n\nconst GROUP_OF: Readonly<Record<WorkflowActivityTone, WorkflowActivityGroupName>> = {\n running: 'running',\n paused: 'running',\n failed: 'failed',\n done: 'successful',\n skipped: 'successful',\n};\n\nconst GROUP_ORDER: readonly WorkflowActivityGroupName[] = ['running', 'failed', 'successful'];\n\n/** Rows split by outcome, in the order the dock shows them; empty groups are dropped. */\nexport function workflowActivityGroups(rows: readonly WorkflowActivityRow[]): WorkflowActivityGroup[] {\n return GROUP_ORDER.map((name) => ({\n name,\n rows: rows.filter((row) => GROUP_OF[row.tone] === name),\n openByDefault: name !== 'successful',\n })).filter((group) => group.rows.length > 0);\n}\n","import type { SessionFrameSender } from '@agimon-ai/po-core/native';\nimport { defineSessionStore } from '@agimon-ai/po-core/native';\n\nimport { WORKFLOW_RUNS_TYPE, type WorkflowRunView } from '../../../../../types/webWorkflows';\nimport { workflowRunIdentity } from './workflowActivity';\n\n/** One session's record: the hub's last report plus the run this page is looking at. */\nexport interface WorkflowsSession {\n /** The workflow runs the hub last reported; presented order preserved. */\n runs: WorkflowRunView[];\n /** The run (workspace/runKey) the workflows tab shows; the first run until someone picks. */\n focusedRun: string | undefined;\n /**\n * A launch that was sent and has not shown up yet.\n *\n * The line goes to the session, the run appears on the registry channel some\n * seconds later, and nothing connects the two but timing: the first run this\n * session did not already have is the one that was just asked for.\n */\n pendingLaunch: { workflowPath: string; knownRuns: string[] } | undefined;\n}\n\nexport const workflows = defineSessionStore<WorkflowsSession>({\n runs: [],\n focusedRun: undefined,\n pendingLaunch: undefined,\n});\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** Points the workflows tab at one run; the activity dock uses this before opening the tab. */\nexport function focusRun(sessionId: string, identity: string | undefined): void {\n workflows.update(sessionId, (current) => ({ ...current, focusedRun: identity }));\n}\n\n/** Removes a deleted run immediately while the registry channel catches up. */\nexport function removeRun(sessionId: string, identity: string): void {\n workflows.update(sessionId, (current) => {\n const runs = current.runs.filter((run) => workflowRunIdentity(run) !== identity);\n return {\n ...current,\n runs,\n focusedRun:\n current.focusedRun === identity\n ? runs[0] === undefined\n ? undefined\n : workflowRunIdentity(runs[0])\n : current.focusedRun,\n };\n });\n}\n\n/**\n * Sends a launch line to the session and remembers what was already running.\n *\n * The cockpit's only channel to a session is a prompt frame, so a launch is\n * the verb the extension registers for exactly this; see web/launchLine.ts.\n */\nexport function requestLaunch(send: SessionFrameSender, sessionId: string, line: string, workflowPath: string): void {\n send(sessionId, { type: 'prompt', message: line });\n workflows.update(sessionId, (current) => ({\n ...current,\n pendingLaunch: { workflowPath, knownRuns: current.runs.map(workflowRunIdentity) },\n }));\n}\n\nexport interface WorkflowRunsPayload {\n runs: WorkflowRunView[];\n}\n\n/** The plugin's session data channel: 'workflow_runs' payloads into the store. */\nexport const workflowRunsChannel = workflows.channel<WorkflowRunsPayload>({\n channel: WORKFLOW_RUNS_TYPE,\n parse(input) {\n if (!isRecord(input) || !Array.isArray(input.runs)) return null;\n return { runs: input.runs.filter(isRecord) as unknown as WorkflowRunView[] };\n },\n reduce: (current, { runs }) => {\n const pending = current.pendingLaunch;\n if (pending === undefined) return { ...current, runs };\n const known = new Set(pending.knownRuns);\n const arrived = runs.find((run) => !known.has(workflowRunIdentity(run)));\n // Until one arrives the launch stays pending: a workflow can take a while\n // to reach the registry, and forgetting it would leave the board wherever\n // the reader last was.\n if (arrived === undefined) return { ...current, runs };\n return { ...current, runs, focusedRun: workflowRunIdentity(arrived), pendingLaunch: undefined };\n },\n});\n","import { defineActivityGroup } from '@agimon-ai/po-core/native';\nimport { WorkflowIcon } from '@agimon-ai/po-native-components';\nimport { createElement } from 'react';\n\nimport { workflows } from '../_lib/workflowsStore.native';\nexport default defineActivityGroup({\n keys: 'w r',\n icon: () => createElement(WorkflowIcon),\n widgetKeys: ['workflow-mcp-progress', 'workflow-mcp-follow'],\n order: 30,\n activeSource: {\n subscribe(listener) {\n const subscription = workflows.store.subscribe(listener);\n return () => subscription.unsubscribe();\n },\n isActive(sessionId) {\n return workflows.select(workflows.store.state, sessionId).runs.some((run) => run.stage === 'running');\n },\n },\n});\n","import { defineSessionStore } from '@agimon-ai/po-core/native';\n\nimport {\n WORKFLOW_CATALOG_TYPE,\n type WorkflowCatalogEntryView,\n type WorkflowCatalogPayload,\n} from '../../../../../types/webWorkflows';\n\n/** One session's catalog: what the hub last reported plus what the drawer is doing with it. */\nexport interface CatalogSession {\n cwd: string;\n workflows: WorkflowCatalogEntryView[];\n warning: string | undefined;\n /** True while the catalog drawer is shown in the workflows tab. */\n open: boolean;\n filter: string;\n /** Prompt carried from the surface that opened the catalog. */\n prompt: string;\n /** The highlighted row, by workflow path. */\n selected: string | undefined;\n /** The row whose parsed detail is unfolded. */\n inspected: string | undefined;\n /** The workflow the launch dialog is open for. */\n launch: string | undefined;\n}\n\nexport const catalog = defineSessionStore<CatalogSession>({\n cwd: '',\n workflows: [],\n warning: undefined,\n open: false,\n filter: '',\n prompt: '',\n selected: undefined,\n inspected: undefined,\n launch: undefined,\n});\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport function openCatalog(sessionId: string, prompt = ''): void {\n catalog.update(sessionId, (current) => ({ ...current, open: true, prompt }));\n}\n\nexport function closeCatalog(sessionId: string): void {\n catalog.update(sessionId, (current) => ({ ...current, open: false, prompt: '', launch: undefined }));\n}\n\nexport function setCatalogFilter(sessionId: string, filter: string): void {\n catalog.update(sessionId, (current) => ({ ...current, filter }));\n}\n\nexport function selectWorkflow(sessionId: string, path: string | undefined): void {\n catalog.update(sessionId, (current) => ({ ...current, selected: path }));\n}\n\nexport function toggleInspect(sessionId: string, path: string): void {\n catalog.update(sessionId, (current) => ({ ...current, inspected: current.inspected === path ? undefined : path }));\n}\n\nexport function openLaunch(sessionId: string, path: string): void {\n catalog.update(sessionId, (current) => ({ ...current, selected: path, launch: path }));\n}\n\nexport function closeLaunch(sessionId: string): void {\n catalog.update(sessionId, (current) => ({ ...current, launch: undefined }));\n}\n\n/** Rows whose name, path, tag or job matches the filter, case-insensitively. */\nexport function filterCatalog(\n workflows: readonly WorkflowCatalogEntryView[],\n filter: string,\n): WorkflowCatalogEntryView[] {\n const needle = filter.trim().toLowerCase();\n if (needle === '') return [...workflows];\n return workflows.filter((workflow) =>\n [\n workflow.name,\n workflow.relativePath,\n workflow.description,\n ...workflow.tags,\n ...workflow.jobs.map((job) => job.name),\n ]\n .join('\\n')\n .toLowerCase()\n .includes(needle),\n );\n}\n\n/** The plugin's catalog channel: 'workflow_catalog' payloads into the store. */\nexport const workflowCatalogChannel = catalog.channel<WorkflowCatalogPayload>({\n channel: WORKFLOW_CATALOG_TYPE,\n parse(input) {\n if (!isRecord(input) || typeof input.cwd !== 'string' || !Array.isArray(input.workflows)) return null;\n return {\n cwd: input.cwd,\n workflows: input.workflows.filter(isRecord) as unknown as WorkflowCatalogEntryView[],\n ...(typeof input.warning === 'string' ? { warning: input.warning } : {}),\n };\n },\n reduce(current, payload) {\n const paths = new Set(payload.workflows.map((workflow) => workflow.path));\n return {\n ...current,\n cwd: payload.cwd,\n workflows: payload.workflows,\n warning: payload.warning,\n // A row that is gone cannot stay selected, inspected, or half-launched.\n selected: current.selected !== undefined && paths.has(current.selected) ? current.selected : undefined,\n inspected: current.inspected !== undefined && paths.has(current.inspected) ? current.inspected : undefined,\n launch: current.launch !== undefined && paths.has(current.launch) ? current.launch : undefined,\n };\n },\n});\n","import { defineChannelFile } from '@agimon-ai/po-core/native';\n\nimport { workflowCatalogChannel } from '../_lib/catalogStore.native';\nexport default defineChannelFile(workflowCatalogChannel);\n","import { defineChannelFile } from '@agimon-ai/po-core/native';\n\nimport { workflowRunsChannel } from '../_lib/workflowsStore.native';\nexport default defineChannelFile(workflowRunsChannel);\n","import type { WorkflowCatalogEntryView } from '../../../../../types/webWorkflows';\n\n/**\n * The `/workflow-launch` line the dialog sends.\n *\n * WHY THE BUILDER LIVES HERE AND THE PARSER DOES NOT:\n * Cockpit code is compiled into the host bundle and may import only this\n * package's own web and type modules, so it cannot share the session's parser.\n * The two are pinned together by a test that parses what this writes, which is\n * the only guarantee that matters: the line has to survive the trip.\n */\n\nexport const WORKFLOW_LAUNCH_VERB = '/workflow-launch';\n/** Reserved keys; every other pair is one of the workflow's own inputs. */\nexport const RUNNER_KEY = 'runner';\nexport const COMMAND_KEY = 'command';\nexport const CHOICE_KEY = 'choice';\n\nexport interface WorkflowLaunchRequest {\n workflow: string;\n runner?: string;\n command?: string;\n choice?: string;\n inputs: Record<string, string>;\n prompt?: string;\n}\n\n/** Quotes a value that carries whitespace, which is how a value survives tokenizing. */\nfunction quote(value: string): string {\n return /\\s/.test(value) ? `\"${value}\"` : value;\n}\n\nfunction reservedPair(key: string, value: string | undefined): string[] {\n return value === undefined || value === '' ? [] : [`${key}=${quote(value)}`];\n}\n\nexport function workflowLaunchLine(request: WorkflowLaunchRequest): string {\n const pairs = [\n ...reservedPair(RUNNER_KEY, request.runner),\n ...reservedPair(COMMAND_KEY, request.command),\n ...reservedPair(CHOICE_KEY, request.choice),\n ...Object.entries(request.inputs)\n .filter(([, value]) => value !== '')\n .map(([key, value]) => `${key}=${quote(value)}`),\n ];\n const prompt = request.prompt?.trim();\n return [WORKFLOW_LAUNCH_VERB, quote(request.workflow), ...pairs, ...(prompt ? [prompt] : [])].join(' ');\n}\n\n/** The trigger that makes a prompt mandatory. */\nconst USER_PROMPT_TRIGGER = 'user_prompt';\n\n/** What the dialog will not let a reader send, worded the way the session would answer. */\nexport function launchProblems(workflow: WorkflowCatalogEntryView, request: WorkflowLaunchRequest): string[] {\n const problems: string[] = [];\n if (workflow.triggers.includes(USER_PROMPT_TRIGGER) && (request.prompt ?? '').trim() === '') {\n problems.push('This workflow is triggered by a prompt, so it needs one.');\n }\n const missing = workflow.inputs\n .filter((input) => input.required === true && (request.inputs[input.name] ?? '') === '')\n .map((input) => input.name);\n if (missing.length > 0) {\n problems.push(`Missing required input${missing.length > 1 ? 's' : ''}: ${missing.join(', ')}.`);\n }\n return problems;\n}\n\n/** The default a field starts with: what the workflow declared, or empty. */\nexport function initialInputs(workflow: WorkflowCatalogEntryView): Record<string, string> {\n return Object.fromEntries(workflow.inputs.map((input) => [input.name, input.default ?? '']));\n}\n\n/** The runner a launch starts on: the workflow's first declared one, when it declares any. */\nexport function initialRunner(workflow: WorkflowCatalogEntryView): string | undefined {\n return workflow.runners?.[0];\n}\n\n/** The command templated steps start on: the one their steps list first. */\nexport function initialCommand(workflow: WorkflowCatalogEntryView): string | undefined {\n return workflow.commands?.[0];\n}\n\n/** The choice a launch starts on: `default` when declared, else the first. */\nexport function initialChoice(workflow: WorkflowCatalogEntryView): string | undefined {\n const choices = workflow.choices ?? [];\n return choices.includes('default') ? 'default' : choices[0];\n}\n","import type { ApiResponseOf, ApiRoutes } from '@agimon-ai/po-core/web';\n\nimport type {\n WorkflowArtifactContentResponse,\n WorkflowArtifactsResponse,\n WorkflowControlResponse,\n WorkflowDeleteResponse,\n WorkflowLaunchResponse,\n WorkflowOpenRunDirectoryResponse,\n WorkflowSteerResponse,\n WorkflowStopResponse,\n WorkflowScreenEvent,\n} from './webWorkflowTerminal';\n\n/**\n * This package's routes, as data.\n *\n * No scope and no base path. The build reads both off\n * `src/extensions/(backend)/api/workflow/`, so the mount is stated once, by the\n * folder that creates it. The same API answers at all three scopes, because a\n * global contribution cascades into workspace and session; the folder under\n * `workspaces/sessions/` only re-mounts it for a session's own server.\n *\n * This is the one file the routes, the Hono app and the browser all read, so a\n * path cannot move on one side alone. The page used to build the hub's own\n * absolute URL and then rewrite its plugin prefix with String.replace to reach\n * a session, which is exactly the kind of copy that can move by one character\n * without anything noticing.\n *\n * `:workspace` and `:runKey` are Hono's own parameter syntax, because the app\n * registers `path` verbatim.\n */\n\n/** One run, which every route below addresses. */\nconst RUN = '/runs/:workspace/:runKey';\n\n/**\n * The artifact route's parameter, as Hono spells a multi-segment match.\n *\n * An artifact is named by its path inside the run directory, so `reports/a.md`\n * is one parameter across two segments. The client's `params` substitution\n * fills a single segment and percent-encodes the slash with it, so the page\n * substitutes this one itself; see the page's `_lib/terminalApi.ts`.\n */\nexport const ARTIFACT_NAME_PARAM = ':name{.+}';\n\n/**\n * The step whose pane a terminal route reads: a step ref's id. Absent, the\n * route follows the run's current step, which is one of a parallel group's.\n */\nexport const STEP_TARGET_PARAM = 'step';\n\n/** Query parameters the artifact route reads, spelled once for both halves. */\nexport const ARTIFACT_RAW_PARAM = 'raw';\nexport const ARTIFACT_DOWNLOAD_PARAM = 'download';\n\nconst routes = {\n /**\n * The terminal, as server-sent events.\n *\n * `stream: true` gets a URL and no call method: the consumer is the browser's\n * own `EventSource`, and a relayed call would buffer a stream that never ends.\n */\n snapshot: {\n method: 'GET',\n path: `${RUN}/screen`,\n query: [STEP_TARGET_PARAM],\n response: undefined as unknown as ApiResponseOf<WorkflowScreenEvent>,\n },\n screen: {\n method: 'GET',\n path: `${RUN}/screen/stream`,\n query: [STEP_TARGET_PARAM],\n stream: true,\n },\n control: {\n method: 'POST',\n path: `${RUN}/control`,\n response: undefined as unknown as ApiResponseOf<WorkflowControlResponse>,\n },\n keys: {\n method: 'POST',\n path: `${RUN}/keys`,\n },\n resize: {\n method: 'POST',\n path: `${RUN}/resize`,\n response: undefined as unknown as ApiResponseOf<{ resized: boolean }>,\n },\n remove: {\n method: 'DELETE',\n path: RUN,\n response: undefined as unknown as ApiResponseOf<WorkflowDeleteResponse>,\n },\n stop: {\n method: 'POST',\n path: `${RUN}/stop`,\n response: undefined as unknown as ApiResponseOf<WorkflowStopResponse>,\n },\n /** Guidance for the agent session the running step is in, like steering a Team sub-agent. */\n steer: {\n method: 'POST',\n path: `${RUN}/steer`,\n response: undefined as unknown as ApiResponseOf<WorkflowSteerResponse>,\n },\n /**\n * Launch a workflow into the mounting session's own runtime, which then owns\n * the run. A dispatcher session reaches its root's session mount through this.\n */\n launch: {\n method: 'POST',\n path: '/launch',\n response: undefined as unknown as ApiResponseOf<WorkflowLaunchResponse>,\n },\n openRunDirectory: {\n method: 'POST',\n path: `${RUN}/open-directory`,\n response: undefined as unknown as ApiResponseOf<WorkflowOpenRunDirectoryResponse>,\n },\n artifacts: {\n method: 'GET',\n path: `${RUN}/artifacts`,\n query: ['directory'],\n response: undefined as unknown as ApiResponseOf<WorkflowArtifactsResponse>,\n },\n /** One artifact: its metadata and text, or its raw bytes under `raw=1`. */\n artifact: {\n method: 'GET',\n path: `${RUN}/artifacts/${ARTIFACT_NAME_PARAM}`,\n query: [ARTIFACT_RAW_PARAM, ARTIFACT_DOWNLOAD_PARAM],\n response: undefined as unknown as ApiResponseOf<WorkflowArtifactContentResponse>,\n },\n} as const satisfies ApiRoutes;\n\nexport default routes;\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { createApiClient, nativeApiTransport, sessionApiAddress } from '@agimon-ai/po-core/native';\n\nimport routes from '../src/types/apiRoutes';\n\n/** Scopes the tree mounts 'workflow' at. */\nexport const apiScopes = ['global', 'workspace', 'session'] as const;\n\nexport const api = createApiClient(routes, {\n scopes: apiScopes,\n basePath: 'workflow',\n transport: nativeApiTransport,\n sessionAddress: sessionApiAddress,\n});\n","import type { WebPluginSlotProps } from '@agimon-ai/po-core/native';\nimport { nativeApiTransport } from '@agimon-ai/po-core/native';\n\nimport { api } from '../../../../../../generated/client.native';\nimport {\n ARTIFACT_DOWNLOAD_PARAM,\n ARTIFACT_NAME_PARAM,\n ARTIFACT_RAW_PARAM,\n STEP_TARGET_PARAM,\n} from '../../../../../types/apiRoutes';\nimport {\n type WorkflowArtifactContentResponse,\n type WorkflowArtifactsResponse,\n type WorkflowControlResponse,\n type WorkflowDeleteResponse,\n type WorkflowScreenEvent,\n type WorkflowSteerResponse,\n type WorkflowStopResponse,\n} from '../../../../../types/webWorkflowTerminal';\n\n/**\n * The page's half of this package's hub API: one run's terminal and the files\n * its run directory holds.\n *\n * These are adapters now, not a transport. The generated client owns the URL\n * and the sealed transport with it, so nothing here spells a mount. What stays\n * is this package's own vocabulary: which refusals the reader is shown, and the\n * shapes the terminal expects back.\n *\n * A run belongs to its multiplexer rather than to a session, so the same API\n * answers at the hub and inside a session's own server. Passing a session id\n * addresses that session's copy and passing none addresses the hub. The deleted\n * builder made that branch the other way round: it always built the hub's\n * absolute URL, then rewrote the plugin prefix into the session's with\n * String.replace, so a session's URL was a hub URL with its head swapped.\n */\n\nconst UNREACHABLE = 'The cockpit hub is unreachable.';\n\n/** One of the scopes this API mounts at; every route is the same on all of them. */\ntype WorkflowScope = typeof api.global;\n\n/** The hub, or one session's own copy of it; a null session id is the hub. */\nfunction scoped(sessionId?: string | null): WorkflowScope {\n return sessionId == null ? api.global : api.session(sessionId);\n}\n\n/** The run every route addresses, as the route table's two path parameters. */\nfunction runParams(workspace: string, runKey: string): { workspace: string; runKey: string } {\n return { workspace, runKey };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * The message a reader is shown: the route's own words, or why there were none.\n *\n * `error` is optional because an answered call that simply carried the wrong\n * shape reaches here too, and that result has no error field at all.\n */\nfunction messageOf(result: { status: number; error?: string }, fallback: string): string {\n if (result.status === 0) return UNREACHABLE;\n return result.error === undefined || result.error === '' ? fallback : result.error;\n}\n\n/**\n * One artifact's URL, with its path filled in.\n *\n * An artifact is named by its path inside the run directory, which Hono matches\n * as the one multi-segment parameter `:name{.+}`. The client's own `params`\n * substitution fills a single segment and percent-encodes the separating slash\n * with it, which would move every nested artifact's URL, so that one segment is\n * substituted here instead: each segment encoded, the slashes between them\n * kept. Everything left of it still comes from the client.\n */\nfunction artifactUrl(\n scope: WorkflowScope,\n workspace: string,\n runKey: string,\n artifactPath: string,\n query?: Record<string, number>,\n): string {\n return scope.artifact\n .url({ params: runParams(workspace, runKey), ...(query === undefined ? {} : { query }) })\n .replace(ARTIFACT_NAME_PARAM, artifactPath.split('/').map(encodeURIComponent).join('/'));\n}\n\n/** The pane a terminal call names, when it reads one step's rather than the run's current one. */\nfunction stepBody(step: string | undefined): { step?: string } {\n return step === undefined ? {} : { step };\n}\n\n/** One finite screen read over the session-bound sealed transport. */\nexport async function readScreen(\n workspace: string,\n runKey: string,\n sessionId: string | null,\n step: string | undefined,\n signal: AbortSignal,\n): Promise<WorkflowScreenEvent> {\n const response = await nativeApiTransport(\n scoped(sessionId).snapshot.url({\n params: runParams(workspace, runKey),\n query: { [STEP_TARGET_PARAM]: step },\n }),\n { signal },\n );\n const body: unknown = await response.json();\n if (!response.ok)\n throw new Error(isRecord(body) && typeof body.error === 'string' ? body.error : 'The screen could not be read.');\n if (\n !isRecord(body) ||\n !Array.isArray(body.lines) ||\n body.lines.length > 48 ||\n !body.lines.every((line) => typeof line === 'string' && line.length <= 4096) ||\n !isRecord(body.capabilities) ||\n typeof body.capabilities.readable !== 'boolean' ||\n typeof body.capabilities.writable !== 'boolean' ||\n typeof body.capabilities.resizable !== 'boolean'\n ) {\n throw new Error('The workflow hub returned an invalid screen.');\n }\n return body as unknown as WorkflowScreenEvent;\n}\n\n/** Takes the keyboard for one run, renewing when this page already holds it. */\nexport async function takeControl(\n workspace: string,\n runKey: string,\n token?: string,\n sessionId?: string | null,\n step?: string,\n): Promise<WorkflowControlResponse> {\n const result = await scoped(sessionId).control({\n params: runParams(workspace, runKey),\n body: { token, ...stepBody(step) },\n });\n if (result.status === 0) return { held: false, reason: UNREACHABLE };\n // A refusal carries the same shape as a grant, so the body is read before the\n // status: a 409 says who holds the keyboard and why, which is the answer.\n if (isRecord(result.data) && typeof result.data.held === 'boolean') {\n return result.data as unknown as WorkflowControlResponse;\n }\n return { held: false, reason: messageOf(result, 'The run refused the keyboard.') };\n}\n\nexport async function releaseControl(\n workspace: string,\n runKey: string,\n token: string,\n sessionId?: string | null,\n step?: string,\n): Promise<void> {\n await scoped(sessionId).control({\n params: runParams(workspace, runKey),\n body: { token, release: true, ...stepBody(step) },\n });\n}\n\n/** Sends literal keystrokes; the reason comes back when the lease has moved on. */\nexport async function sendKeys(\n workspace: string,\n runKey: string,\n token: string,\n data: string,\n sessionId?: string | null,\n step?: string,\n): Promise<{ error?: string }> {\n const result = await scoped(sessionId).keys({\n params: runParams(workspace, runKey),\n body: { token, data, ...stepBody(step) },\n });\n if (result.ok) return {};\n return { error: messageOf(result, 'The run would not take those keys.') };\n}\n\n/** Matches the run's terminal to the viewport of whoever holds the keyboard. */\nexport async function resizeRun(\n workspace: string,\n runKey: string,\n token: string,\n columns: number,\n rows: number,\n sessionId?: string | null,\n step?: string,\n): Promise<void> {\n await scoped(sessionId).resize({\n params: runParams(workspace, runKey),\n body: { token, columns, rows, ...stepBody(step) },\n });\n}\n\nexport type DeleteWorkflowResult = { result: WorkflowDeleteResponse } | { error: string };\n\n/** Permanently removes one settled run and its run directory. */\nexport async function deleteWorkflowRun(\n workspace: string,\n runKey: string,\n sessionId?: string | null,\n): Promise<DeleteWorkflowResult> {\n const result = await scoped(sessionId).remove({ params: runParams(workspace, runKey) });\n if (!result.ok) return { error: messageOf(result, 'The workflow could not be deleted.') };\n if (result.data.deleted === true) return { result: { deleted: true } };\n return { error: 'The workflow hub returned an invalid deletion response.' };\n}\n\nexport type StopWorkflowResult = { result: WorkflowStopResponse } | { error: string };\n\n/** Asks the engine running a workflow to stop it; the run settles on its own shortly after. */\nexport async function stopWorkflowRun(\n workspace: string,\n runKey: string,\n sessionId?: string | null,\n): Promise<StopWorkflowResult> {\n const result = await scoped(sessionId).stop({ params: runParams(workspace, runKey) });\n if (!result.ok) return { error: messageOf(result, 'The workflow could not be stopped.') };\n if (result.data.requested === true) return { result: { requested: true } };\n return { error: 'The workflow hub returned an invalid stop response.' };\n}\n\nexport type SteerStepResult = { result: WorkflowSteerResponse } | { error: string };\n\n/**\n * Sends guidance to the agent session a running step is in: the run's current\n * step, or `step`, the session of one step of a parallel group.\n */\nexport async function steerStep(\n workspace: string,\n runKey: string,\n message: string,\n sessionId?: string | null,\n step?: string,\n): Promise<SteerStepResult> {\n const result = await scoped(sessionId).steer({\n params: runParams(workspace, runKey),\n body: step === undefined ? { message } : { message, step },\n });\n if (!result.ok) return { error: messageOf(result, 'The step would not take that guidance.') };\n if (result.data.delivered === true) return { result: { delivered: true } };\n return { error: 'The workflow hub returned an invalid steer response.' };\n}\n\n/** Opens the current registry folder, never a browser-supplied path. */\nexport async function openRunDirectory(\n workspace: string,\n runKey: string,\n sessionId?: string | null,\n): Promise<{ error?: string }> {\n const result = await scoped(sessionId).openRunDirectory({ params: runParams(workspace, runKey) });\n if (!result.ok) return { error: messageOf(result, 'The run folder could not be opened in Finder.') };\n return result.data.opened === true ? {} : { error: 'The workflow hub returned an invalid folder response.' };\n}\n\nexport type ArtifactsResult = { artifacts: WorkflowArtifactsResponse } | { error: string };\n\nexport async function fetchArtifacts(\n workspace: string,\n runKey: string,\n sessionId?: string | null,\n directory?: string,\n): Promise<ArtifactsResult> {\n const result = await scoped(sessionId).artifacts({ params: runParams(workspace, runKey), query: { directory } });\n if (!result.ok) return { error: messageOf(result, 'This run has no directory to read.') };\n return { artifacts: result.data };\n}\n\nexport type ArtifactResult = { artifact: WorkflowArtifactContentResponse } | { error: string };\n\n/** Trusted same-origin URL for browser-native media previews and downloads. */\nexport function artifactContentUrl(\n workspace: string,\n runKey: string,\n path: string,\n download = false,\n sessionId?: string | null,\n): string {\n return artifactUrl(scoped(sessionId), workspace, runKey, path, {\n [ARTIFACT_RAW_PARAM]: 1,\n ...(download ? { [ARTIFACT_DOWNLOAD_PARAM]: 1 } : {}),\n });\n}\n\n/**\n * One artifact's metadata and text.\n *\n * The only route here that addresses itself rather than being called: its path\n * parameter spans segments, so the URL comes from `artifactUrl` and the request\n * goes over the same sealed transport the client is built on.\n */\nexport async function fetchArtifact(\n workspace: string,\n runKey: string,\n path: string,\n sessionId?: string | null,\n): Promise<ArtifactResult> {\n try {\n const response = await nativeApiTransport(artifactUrl(scoped(sessionId), workspace, runKey, path));\n const body = (await response.json()) as unknown;\n if (!response.ok) {\n const error = isRecord(body) && typeof body.error === 'string' && body.error !== '' ? body.error : '';\n return { error: error === '' ? 'That file has not been written.' : error };\n }\n return { artifact: body as WorkflowArtifactContentResponse };\n } catch {\n return { error: UNREACHABLE };\n }\n}\n\nconst MAX_MEDIA_BYTES = 5 * 1024 * 1024;\nconst MAX_FRAME_BYTES = 64 * 1024;\n\n/** Drain each UTF-8 snapshot before asking the server for another screen. */\nexport function finiteScreenReader(load: (signal: AbortSignal) => Promise<WorkflowScreenEvent>) {\n let bytes: Uint8Array = new Uint8Array(0);\n let cursor = 0;\n let generation = 0;\n let frame: WorkflowScreenEvent | undefined;\n return async (from: number, previous: string | undefined, signal: AbortSignal) => {\n if (signal.aborted) throw new Error('Preview cancelled.');\n let reset = previous !== String(generation) || from !== cursor;\n if (!frame || cursor >= bytes.length || reset) {\n const next = await load(signal);\n if (signal.aborted) throw new Error('Preview cancelled.');\n frame = next;\n bytes = utf8(next.lines.join('\\r\\n'));\n cursor = 0;\n generation += 1;\n reset = true;\n }\n const chunk = bytes.subarray(cursor, cursor + MAX_FRAME_BYTES);\n cursor += chunk.length;\n return {\n chunk: base64(chunk),\n offset: cursor,\n reset,\n generation: String(generation),\n exists: frame.capabilities.readable,\n hasMore: cursor < bytes.length,\n ended: frame.ended === true,\n };\n };\n}\n\n/** Raw media uses the same scoped sealed route as artifact metadata. */\nexport async function fetchArtifactMedia(\n workspace: string,\n runKey: string,\n path: string,\n sessionId: string | null,\n signal: AbortSignal,\n): Promise<{ data: string; mimeType: string }> {\n if (signal.aborted) throw new Error('Preview cancelled.');\n const response = await nativeApiTransport(artifactContentUrl(workspace, runKey, path, false, sessionId), { signal });\n if (signal.aborted) throw new Error('Preview cancelled.');\n if (!response.ok) throw new Error('That artifact could not be read.');\n const mimeType = (response.headers.get('content-type') ?? '').split(';')[0]!.trim().toLowerCase();\n if (\n !/^(application\\/pdf|image\\/(png|jpeg|gif|webp|bmp)|audio\\/(mpeg|mp4|wav|x-wav|ogg|webm|aac|flac)|video\\/(mp4|webm|quicktime|ogg))$/.test(\n mimeType,\n )\n )\n throw new Error('This artifact type cannot be previewed.');\n if (Number(response.headers.get('content-length')) > MAX_MEDIA_BYTES)\n throw new Error('This artifact exceeds the 5 MiB preview limit.');\n const bytes = await response.arrayBuffer();\n if (signal.aborted) throw new Error('Preview cancelled.');\n if (bytes.byteLength > MAX_MEDIA_BYTES) throw new Error('This artifact exceeds the 5 MiB preview limit.');\n return { data: base64(new Uint8Array(bytes)), mimeType };\n}\n\nfunction base64(bytes: Uint8Array): string {\n const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n const parts: string[] = [];\n let chunk = '';\n for (let offset = 0; offset < bytes.length; offset += 3) {\n const first = bytes[offset]!;\n const second = bytes[offset + 1];\n const third = bytes[offset + 2];\n chunk +=\n alphabet[first >> 2]! +\n alphabet[((first & 3) << 4) | ((second ?? 0) >> 4)]! +\n (second === undefined ? '=' : alphabet[((second & 15) << 2) | ((third ?? 0) >> 6)]!) +\n (third === undefined ? '=' : alphabet[third & 63]!);\n if (chunk.length >= 8192) {\n parts.push(chunk);\n chunk = '';\n }\n }\n parts.push(chunk);\n return parts.join('');\n}\n\nfunction utf8(text: string): Uint8Array {\n const bytes: number[] = [];\n for (const character of text) {\n let code = character.codePointAt(0)!;\n if (code >= 0xd800 && code <= 0xdfff) code = 0xfffd;\n if (code < 0x80) bytes.push(code);\n else if (code < 0x800) bytes.push(0xc0 | (code >> 6), 0x80 | (code & 63));\n else if (code < 0x10000) bytes.push(0xe0 | (code >> 12), 0x80 | ((code >> 6) & 63), 0x80 | (code & 63));\n else bytes.push(0xf0 | (code >> 18), 0x80 | ((code >> 12) & 63), 0x80 | ((code >> 6) & 63), 0x80 | (code & 63));\n }\n return Uint8Array.from(bytes);\n}\n\n/** Binds a save to this package's guarded sealed route and one file version. */\nexport async function prepareArtifactSave(\n workspace: string,\n runKey: string,\n path: string,\n sessionId: string | null,\n signal: AbortSignal,\n): Promise<Parameters<NonNullable<WebPluginSlotProps['nativeSaveFile']>>[0]> {\n const load = async (headers: Record<string, string>, signal: AbortSignal): Promise<Response> => {\n if (signal.aborted) throw new Error('Download cancelled.');\n return nativeApiTransport(artifactContentUrl(workspace, runKey, path, true, sessionId), { headers, signal });\n };\n const probe = await load({ Range: 'bytes=0-0' }, signal);\n if (signal.aborted) throw new Error('Download cancelled.');\n const range = /^bytes 0-0\\/(\\d+)$/u.exec(probe.headers.get('content-range') ?? '');\n const empty =\n (probe.status === 416 && probe.headers.get('content-range') === 'bytes */0') ||\n (probe.status === 200 && probe.headers.get('content-length') === '0');\n if (!empty && (probe.status !== 206 || !range)) throw new Error('The file does not support bounded downloads.');\n const size = empty ? 0 : Number(range![1]);\n if (!Number.isSafeInteger(size) || size < 0) throw new Error('Invalid file size.');\n const probeBytes = await probe.arrayBuffer();\n if (probeBytes.byteLength !== (empty ? 0 : 1)) throw new Error('Invalid file response.');\n const version = probe.headers.get('etag');\n if (!version) throw new Error('The file has no version validator.');\n return {\n name: path.split(/[\\\\/]/u).at(-1) ?? '',\n mimeType: probe.headers.get('content-type')?.split(';')[0]?.trim() || 'application/octet-stream',\n size,\n signal,\n read: async (offset, count, signal) => {\n if (\n !Number.isSafeInteger(offset) ||\n !Number.isSafeInteger(count) ||\n offset < 0 ||\n count < 1 ||\n count > 1024 * 1024 ||\n offset + count > size\n )\n throw new Error('Invalid download range.');\n const end = offset + count - 1;\n const response = await load({ Range: `bytes=${offset}-${end}`, 'If-Match': version }, signal);\n if (signal.aborted) throw new Error('Download cancelled.');\n if (\n response.status !== 206 ||\n response.headers.get('etag') !== version ||\n response.headers.get('content-range') !== `bytes ${offset}-${end}/${size}`\n )\n throw new Error('The file changed or its range response is invalid.');\n const bytes = new Uint8Array(await response.arrayBuffer());\n if (signal.aborted) throw new Error('Download cancelled.');\n if (bytes.byteLength !== count) throw new Error('The file response is incomplete.');\n return bytes;\n },\n };\n}\n","import type { WebPluginSlotProps } from '@agimon-ai/po-core/native';\nimport {\n Badge,\n Button,\n CodeBlock,\n Input,\n ListRow,\n Markdown,\n Sheet,\n SheetBody,\n SheetContent,\n SheetHeader,\n SheetTitle,\n Textarea,\n} from '@agimon-ai/po-native-components';\nimport { useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react';\nimport { ScrollView, Text, View } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport type { WorkflowCatalogEntryView, WorkflowRunView } from '../../../../../types/webWorkflows';\nimport type {\n WorkflowArtifactContentResponse,\n WorkflowArtifactsResponse,\n WorkflowTerminalCapabilitiesView,\n} from '../../../../../types/webWorkflowTerminal';\nimport { catalog, closeCatalog, filterCatalog } from '../_lib/catalogStore.native';\nimport {\n initialChoice,\n initialCommand,\n initialInputs,\n initialRunner,\n launchProblems,\n workflowLaunchLine,\n} from '../_lib/launchLine';\nimport {\n deleteWorkflowRun,\n fetchArtifact,\n fetchArtifactMedia,\n prepareArtifactSave,\n finiteScreenReader,\n fetchArtifacts,\n readScreen,\n releaseControl,\n resizeRun,\n sendKeys,\n takeControl,\n steerStep,\n stopWorkflowRun,\n} from '../_lib/terminalApi.native';\nimport { workflowRunIdentity } from '../_lib/workflowActivity';\nimport { focusRun, removeRun, requestLaunch, workflows } from '../_lib/workflowsStore.native';\n\nexport function useWorkflows(sessionId: string | null) {\n const subscribe = useCallback((listener: () => void) => {\n const sub = workflows.store.subscribe(listener);\n return () => sub.unsubscribe();\n }, []);\n return useSyncExternalStore(subscribe, () => workflows.select(workflows.store.state, sessionId));\n}\nexport function workflowTab(run: WorkflowRunView): Parameters<WebPluginSlotProps['openTransientTab']>[0] {\n const identity = workflowRunIdentity(run);\n return {\n id: `workflows-run-${run.workspace}-${run.routeKey ?? run.runKey}`.replace(/[^\\w-]+/g, '-'),\n label: run.displayName,\n retainComposer: true,\n panel: (props) => <WorkflowPanel {...props} identity={identity} />,\n };\n}\nexport function WorkflowLauncher(props: WebPluginSlotProps) {\n const subscribe = useCallback((listener: () => void) => {\n const sub = catalog.store.subscribe(listener);\n return () => sub.unsubscribe();\n }, []);\n const state = useSyncExternalStore(subscribe, () => catalog.select(catalog.store.state, props.sessionId));\n const [filter, setFilter] = useState('');\n const [selected, setSelected] = useState<string>();\n if (props.sessionId === null || !state.open) return null;\n const workflow = state.workflows.find((item) => item.path === selected);\n return (\n <Sheet\n open\n onOpenChange={(open) => {\n if (!open) {\n closeCatalog(props.sessionId!);\n setSelected(undefined);\n }\n }}\n >\n <SheetContent>\n <SheetHeader>\n <SheetTitle>{workflow ? `Launch ${workflow.name}` : 'Launch a workflow'}</SheetTitle>\n </SheetHeader>\n <SheetBody>\n {workflow ? (\n <WorkflowLaunch\n key={workflow.path}\n {...props}\n sessionId={props.sessionId}\n workflow={workflow}\n initialPrompt={state.prompt}\n onClose={() => {\n closeCatalog(props.sessionId!);\n setSelected(undefined);\n }}\n />\n ) : (\n <View style={styles.body}>\n <Input\n accessibilityLabel=\"Find a workflow\"\n value={filter}\n onChangeText={setFilter}\n placeholder=\"Find a workflow\"\n />\n {state.warning ? <Text style={styles.error}>{state.warning}</Text> : null}\n {filterCatalog(state.workflows, filter).map((item) => (\n <ListRow\n key={item.path}\n title={\n <Button variant=\"ghost\" onPress={() => setSelected(item.path)}>\n {item.name || item.relativePath}\n </Button>\n }\n description={`${item.description}\\n${item.tags.join(', ')} · ${item.jobs.map((job) => job.name).join(', ')}`}\n />\n ))}\n {state.workflows.length === 0 ? <Text style={styles.meta}>No workflows reported yet.</Text> : null}\n </View>\n )}\n </SheetBody>\n </SheetContent>\n </Sheet>\n );\n}\nfunction Choice({\n label,\n options,\n value,\n onChange,\n}: {\n label: string;\n options: readonly string[];\n value: string | undefined;\n onChange: (value: string) => void;\n}) {\n return (\n <View>\n <Text style={styles.meta}>{label}</Text>\n {options.map((option) => (\n <Button\n key={option}\n variant=\"outline\"\n accessibilityState={{ selected: value === option }}\n onPress={() => onChange(option)}\n >\n {option}\n </Button>\n ))}\n </View>\n );\n}\nfunction WorkflowLaunch({\n sessionId,\n workflow,\n initialPrompt,\n sendSessionFrame,\n onClose,\n}: WebPluginSlotProps & {\n sessionId: string;\n workflow: WorkflowCatalogEntryView;\n initialPrompt: string;\n onClose: () => void;\n}) {\n const [prompt, setPrompt] = useState(initialPrompt);\n const [inputs, setInputs] = useState(() => initialInputs(workflow));\n const [runner, setRunner] = useState(() => initialRunner(workflow));\n const [command, setCommand] = useState(() => initialCommand(workflow));\n const [choice, setChoice] = useState(() => initialChoice(workflow));\n const [error, setError] = useState<string>();\n const request = {\n workflow: workflow.name || workflow.relativePath,\n inputs,\n runner,\n command,\n choice,\n ...(prompt.trim() === '' ? {} : { prompt: prompt.trim() }),\n };\n const problems = launchProblems(workflow, request);\n const line = workflowLaunchLine(request);\n return (\n <View style={styles.body}>\n <Text style={styles.meta}>{workflow.description}</Text>\n <Textarea\n accessibilityLabel=\"Workflow prompt\"\n placeholder=\"What should this workflow do?\"\n value={prompt}\n onChangeText={setPrompt}\n />\n {workflow.inputs.map((input) => {\n const options = input.options ?? (input.type === 'boolean' ? ['true', 'false'] : undefined);\n return (\n <View key={input.name}>\n <Text style={styles.meta}>\n {input.name}\n {input.required ? ' (required)' : ''} · {input.description}\n </Text>\n {options ? (\n <Choice\n label={input.name}\n options={options}\n value={inputs[input.name]}\n onChange={(value) => setInputs((current) => ({ ...current, [input.name]: value }))}\n />\n ) : (\n <Input\n accessibilityLabel={input.name}\n value={inputs[input.name] ?? ''}\n onChangeText={(value) => setInputs((current) => ({ ...current, [input.name]: value }))}\n />\n )}\n </View>\n );\n })}\n {workflow.runners?.length ? (\n <Choice label=\"Runner\" options={workflow.runners} value={runner} onChange={setRunner} />\n ) : null}\n {workflow.commands?.length ? (\n <Choice label=\"Command\" options={workflow.commands} value={command} onChange={setCommand} />\n ) : null}\n {workflow.choices?.length ? (\n <Choice label=\"Choice\" options={workflow.choices} value={choice} onChange={setChoice} />\n ) : null}\n <CodeBlock text={line} />\n {problems.map((problem) => (\n <Text key={problem} style={styles.meta}>\n {problem}\n </Text>\n ))}\n {error ? <Text style={styles.error}>{error}</Text> : null}\n <Button\n testID=\"launch-workflow-submit\"\n disabled={problems.length > 0}\n onPress={() => {\n try {\n requestLaunch(sendSessionFrame, sessionId, line, workflow.path);\n onClose();\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : String(cause));\n }\n }}\n >\n Launch\n </Button>\n </View>\n );\n}\n\nexport function WorkflowPanel(props: WebPluginSlotProps & { identity: string }) {\n const state = useWorkflows(props.sessionId);\n const run = state.runs.find((item) => workflowRunIdentity(item) === props.identity);\n const [confirmDelete, setConfirmDelete] = useState(false);\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<string>();\n const act = async (action: () => Promise<void>) => {\n if (busy) return;\n setBusy(true);\n setError(undefined);\n try {\n await action();\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : String(cause));\n } finally {\n setBusy(false);\n }\n };\n if (!run) return <Text style={styles.meta}>This run is no longer listed.</Text>;\n return (\n <ScrollView contentContainerStyle={styles.body}>\n <Text style={styles.title}>{run.displayName}</Text>\n <Badge>{run.executionState ?? run.outcome ?? run.stage}</Badge>\n <Text style={styles.meta}>{run.errorMessage ?? `${run.position?.job ?? ''} ${run.position?.step ?? ''}`}</Text>\n {state.runs.length > 1\n ? state.runs.map((item) => (\n <Button\n key={workflowRunIdentity(item)}\n variant=\"ghost\"\n onPress={() => {\n if (props.sessionId !== null) focusRun(props.sessionId, workflowRunIdentity(item));\n props.openTransientTab(workflowTab(item));\n }}\n >\n {item.displayName}\n </Button>\n ))\n : null}\n {run.executionState === 'paused' || run.executionState === 'pause_requested' ? (\n <Text style={styles.meta}>Waiting to be resumed. Ask the agent in this conversation to resume it.</Text>\n ) : null}\n {run.jobs.map((job) => (\n <View key={job.name}>\n <Button variant=\"ghost\" onPress={() => props.openTransientTab(stepTab(run, job.name))}>\n {job.name} · {job.status}\n </Button>\n {job.steps.map((step) => (\n <ListRow\n key={step.name}\n title={\n <Button variant=\"ghost\" onPress={() => props.openTransientTab(stepTab(run, job.name, step.name))}>\n {step.name}\n </Button>\n }\n description={step.status}\n />\n ))}\n </View>\n ))}\n <Text style={styles.title}>Artifacts</Text>\n <WorkflowArtifacts {...props} run={run} />\n {error ? <Text style={styles.error}>{error}</Text> : null}\n {run.stage === 'running' ? (\n <Button\n variant=\"danger-outline\"\n disabled={busy || props.sessionId === null}\n onPress={() =>\n void act(async () => {\n const result = await stopWorkflowRun(run.workspace, run.routeKey ?? run.runKey, props.sessionId);\n if ('error' in result) throw new Error(result.error);\n })\n }\n >\n Stop workflow\n </Button>\n ) : (\n <Button variant=\"danger-outline\" disabled={props.sessionId === null} onPress={() => setConfirmDelete(true)}>\n Delete run…\n </Button>\n )}\n <Sheet open={confirmDelete} onOpenChange={setConfirmDelete}>\n <SheetContent>\n <SheetHeader>\n <SheetTitle>Delete this run?</SheetTitle>\n </SheetHeader>\n <SheetBody>\n <Text style={styles.meta}>This permanently removes the settled run and its directory.</Text>\n <Button\n variant=\"danger-outline\"\n disabled={busy}\n onPress={() =>\n void act(async () => {\n const result = await deleteWorkflowRun(run.workspace, run.routeKey ?? run.runKey, props.sessionId);\n if ('error' in result) throw new Error(result.error);\n if (props.sessionId !== null) removeRun(props.sessionId, props.identity);\n setConfirmDelete(false);\n props.closeTransientTab(\n `workflows-run-${run.workspace}-${run.routeKey ?? run.runKey}`.replace(/[^\\w-]+/g, '-'),\n );\n })\n }\n >\n Delete\n </Button>\n </SheetBody>\n </SheetContent>\n </Sheet>\n </ScrollView>\n );\n}\nfunction stepTab(\n run: WorkflowRunView,\n job: string,\n step?: string,\n): Parameters<WebPluginSlotProps['openTransientTab']>[0] {\n const workspace = run.workspace;\n const runKey = run.routeKey ?? run.runKey;\n return {\n id: `workflows-step-${workspace}-${runKey}-${job}${step === undefined ? '' : `-${step}`}`.replace(/[^\\w-]+/g, '-'),\n label: `${run.displayName} › ${step ?? job}`,\n panel: (props) => <WorkflowStep {...props} workspace={workspace} runKey={runKey} job={job} step={step} />,\n };\n}\nfunction WorkflowStep({\n sessionId,\n workspace,\n runKey,\n job,\n step,\n renderSessionTranscript,\n renderRunnerTerminal,\n}: WebPluginSlotProps & { workspace: string; runKey: string; job: string; step?: string }) {\n const state = useWorkflows(sessionId);\n const run = state.runs.find((item) => item.workspace === workspace && (item.routeKey ?? item.runKey) === runKey);\n const steps = run?.jobs.find((item) => item.name === job)?.steps;\n const target = step === undefined ? steps?.at(-1) : steps?.find((item) => item.name === step);\n const [message, setMessage] = useState('');\n const [error, setError] = useState<string>();\n const [busy, setBusy] = useState(false);\n const ref = target?.ref;\n const session = ref?.kind === 'session' ? ref.id : undefined;\n return (\n <View style={styles.screen}>\n <Text style={styles.title}>\n {job}\n {step === undefined ? '' : ` › ${step}`} · {target?.status}\n </Text>\n {session ? (\n renderSessionTranscript?.(session)\n ) : (\n <WorkflowTerminal\n key={`${sessionId}:${workspace}:${runKey}:${ref?.id ?? ''}`}\n sessionId={sessionId}\n workspace={workspace}\n runKey={runKey}\n pane={ref?.kind === 'pane' ? ref.id : undefined}\n renderRunnerTerminal={renderRunnerTerminal}\n />\n )}\n {session && run?.stage === 'running' && target?.status === 'running' ? (\n <View style={styles.body}>\n <Textarea accessibilityLabel=\"Step guidance\" value={message} onChangeText={setMessage} />\n <Button\n disabled={busy || message.trim() === ''}\n onPress={() => {\n setBusy(true);\n void steerStep(workspace, runKey, message.trim(), sessionId, session)\n .then((result) => {\n if ('error' in result) setError(result.error);\n else {\n setMessage('');\n setError(undefined);\n }\n })\n .catch((cause: unknown) => setError(cause instanceof Error ? cause.message : String(cause)))\n .finally(() => setBusy(false));\n }}\n >\n Send guidance\n </Button>\n </View>\n ) : null}\n {error ? <Text style={styles.error}>{error}</Text> : null}\n </View>\n );\n}\nfunction WorkflowTerminal({\n sessionId,\n workspace,\n runKey,\n pane,\n renderRunnerTerminal,\n}: Pick<WebPluginSlotProps, 'sessionId' | 'renderRunnerTerminal'> & {\n workspace: string;\n runKey: string;\n pane?: string;\n}) {\n const [capabilities, setCapabilities] = useState<WorkflowTerminalCapabilitiesView>();\n const [token, setToken] = useState<string>();\n const [notice, setNotice] = useState<string>();\n const [columns, setColumns] = useState('80');\n const [rows, setRows] = useState('24');\n const [busy, setBusy] = useState(false);\n const [lifetime] = useState(() => new AbortController());\n useEffect(() => () => lifetime.abort(), [lifetime]);\n useEffect(() => {\n if (token === undefined) return;\n return () => {\n void releaseControl(workspace, runKey, token, sessionId, pane).catch(() => {});\n };\n }, [workspace, runKey, token, sessionId, pane]);\n const request = useMemo(\n () => ({\n key: `${sessionId}:${workspace}:${runKey}:${pane ?? ''}`,\n read: finiteScreenReader(async (signal) => {\n const frame = await readScreen(workspace, runKey, sessionId, pane, signal);\n if (!signal.aborted && !lifetime.signal.aborted) setCapabilities(frame.capabilities);\n return frame;\n }),\n write: async (text: string) => {\n if (token === undefined) throw new Error('Take control before typing into this run.');\n const result = await sendKeys(workspace, runKey, token, text, sessionId, pane);\n if (result.error) {\n if (!lifetime.signal.aborted) {\n setNotice(result.error);\n setToken(undefined);\n }\n throw new Error(result.error);\n }\n },\n }),\n [sessionId, workspace, runKey, pane, token, lifetime],\n );\n const arm = async () => {\n setBusy(true);\n try {\n const grant = await takeControl(workspace, runKey, undefined, sessionId, pane);\n if (lifetime.signal.aborted) {\n if (grant.held && grant.token) await releaseControl(workspace, runKey, grant.token, sessionId, pane);\n return;\n }\n if (grant.held && grant.token) {\n setToken(grant.token);\n setNotice(undefined);\n } else setNotice(grant.reason ?? 'The keyboard is not available for this run.');\n } catch (cause) {\n if (!lifetime.signal.aborted) setNotice(cause instanceof Error ? cause.message : String(cause));\n } finally {\n if (!lifetime.signal.aborted) setBusy(false);\n }\n };\n return (\n <View style={styles.transcript}>\n <Badge>{token ? 'keyboard yours' : 'watching'}</Badge>\n {capabilities?.writable ? (\n <Button\n variant=\"outline\"\n disabled={busy}\n onPress={() => {\n if (token) setToken(undefined);\n else void arm();\n }}\n >\n {token ? 'Release keyboard' : 'Take control'}\n </Button>\n ) : null}\n <View style={styles.transcript}>{renderRunnerTerminal?.(request)}</View>\n {capabilities?.reason ? <Text style={styles.meta}>{capabilities.reason}</Text> : null}\n {token && capabilities?.resizable ? (\n <View>\n <Input\n accessibilityLabel=\"Terminal columns\"\n keyboardType=\"number-pad\"\n value={columns}\n onChangeText={setColumns}\n />\n <Input accessibilityLabel=\"Terminal rows\" keyboardType=\"number-pad\" value={rows} onChangeText={setRows} />\n <Button\n variant=\"outline\"\n disabled={\n !Number.isInteger(Number(columns)) ||\n !Number.isInteger(Number(rows)) ||\n Number(columns) < 1 ||\n Number(rows) < 1\n }\n onPress={() => {\n void resizeRun(workspace, runKey, token, Number(columns), Number(rows), sessionId, pane).catch(\n (cause: unknown) => {\n if (!lifetime.signal.aborted) setNotice(cause instanceof Error ? cause.message : String(cause));\n },\n );\n }}\n >\n Resize terminal\n </Button>\n </View>\n ) : null}\n {notice ? <Text style={styles.meta}>{notice}</Text> : null}\n </View>\n );\n}\nfunction WorkflowArtifacts(props: WebPluginSlotProps & { run: WorkflowRunView }) {\n const { run, sessionId, openTransientTab } = props;\n const [directory, setDirectory] = useState<string>();\n const [listing, setListing] = useState<WorkflowArtifactsResponse>();\n const [error, setError] = useState<string>();\n useEffect(() => {\n let active = true;\n void fetchArtifacts(run.workspace, run.routeKey ?? run.runKey, sessionId, directory)\n .then((result) => {\n if (active) {\n if ('error' in result) setError(result.error);\n else {\n setListing(result.artifacts);\n setError(undefined);\n }\n }\n })\n .catch((cause: unknown) => {\n if (active) setError(cause instanceof Error ? cause.message : String(cause));\n });\n return () => {\n active = false;\n };\n }, [run.workspace, run.runKey, run.routeKey, sessionId, directory, run.stage]);\n return (\n <View>\n {error ? <Text style={styles.error}>{error}</Text> : null}\n {directory ? (\n <Button\n variant=\"ghost\"\n onPress={() =>\n setDirectory(directory.includes('/') ? directory.slice(0, directory.lastIndexOf('/')) : undefined)\n }\n >\n Parent directory\n </Button>\n ) : null}\n {listing?.artifacts.map((item) => (\n <ListRow\n key={item.path}\n title={\n <Button\n variant=\"ghost\"\n disabled={item.kind !== 'directory' && item.state !== 'written' && item.state !== 'empty'}\n onPress={() => {\n if (item.kind === 'directory') setDirectory(item.path);\n else {\n const workspace = run.workspace;\n const runKey = run.routeKey ?? run.runKey;\n const path = item.path;\n openTransientTab({\n id: `workflows-artifact-${workspace}-${runKey}-${path}`.replace(/[^\\w-]+/g, '-'),\n label: path,\n panel: (panelProps) => (\n <ArtifactPreview {...panelProps} workspace={workspace} runKey={runKey} path={path} />\n ),\n });\n }\n }}\n >\n {item.path}\n </Button>\n }\n description={`${item.state} · ${item.description}`}\n />\n ))}\n </View>\n );\n}\nfunction ArtifactPreview({\n sessionId,\n workspace,\n runKey,\n path,\n renderFilePreview,\n renderMediaPreview,\n nativeSaveFile,\n}: WebPluginSlotProps & { workspace: string; runKey: string; path: string }) {\n const [content, setContent] = useState<WorkflowArtifactContentResponse>();\n const [error, setError] = useState<string>();\n const [raw, setRaw] = useState(false);\n useEffect(() => {\n let active = true;\n void fetchArtifact(workspace, runKey, path, sessionId)\n .then((result) => {\n if (active) {\n if ('error' in result) setError(result.error);\n else setContent(result.artifact);\n }\n })\n .catch((cause: unknown) => {\n if (active) setError(cause instanceof Error ? cause.message : String(cause));\n });\n return () => {\n active = false;\n };\n }, [workspace, runKey, path, sessionId]);\n const downloadController = useRef<AbortController | undefined>(undefined);\n const [saving, setSaving] = useState(false);\n const [saveNote, setSaveNote] = useState<string>();\n useEffect(() => () => downloadController.current?.abort(), [workspace, runKey, path, sessionId]);\n const download = async () => {\n if (!nativeSaveFile || saving) return;\n const controller = new AbortController();\n downloadController.current = controller;\n setSaving(true);\n try {\n await nativeSaveFile(await prepareArtifactSave(workspace, runKey, path, sessionId, controller.signal));\n if (!controller.signal.aborted) setSaveNote('Saved.');\n } catch (error) {\n if (!controller.signal.aborted) setSaveNote(error instanceof Error ? error.message : String(error));\n } finally {\n setSaving(false);\n }\n };\n return (\n <ScrollView contentContainerStyle={styles.body}>\n <Text style={styles.title}>{path}</Text>\n <Button variant=\"outline\" disabled={!nativeSaveFile || saving} onPress={() => void download()}>\n Download\n </Button>\n {saving ? (\n <Button variant=\"ghost\" onPress={() => downloadController.current?.abort()}>\n Cancel download\n </Button>\n ) : null}\n {saveNote ? <Text style={styles.meta}>{saveNote}</Text> : null}\n {error ? <Text style={styles.error}>{error}</Text> : null}\n {content?.text !== undefined ? (\n <>\n <Button variant=\"outline\" onPress={() => setRaw((value) => !value)}>\n {raw ? 'Preview' : 'Raw source'}\n </Button>\n {!raw && /\\.(md|markdown)$/i.test(path) ? (\n <Markdown text={content.text} />\n ) : !raw && /\\.(html|htm)$/i.test(path) ? (\n renderFilePreview?.({ key: `${sessionId}:${workspace}:${runKey}:${path}`, html: content.text, title: path })\n ) : !raw && /\\.(csv|tsv)$/i.test(path) ? (\n <DelimitedArtifact text={content.text} delimiter={/\\.csv$/i.test(path) ? ',' : '\\t'} />\n ) : (\n <CodeBlock text={!raw && /\\.json$/i.test(path) ? prettyJson(content.text) : content.text} />\n )}\n {content.truncated ? <Text style={styles.meta}>This preview was truncated.</Text> : null}\n </>\n ) : content ? (\n <BinaryArtifactPreview\n sessionId={sessionId}\n workspace={workspace}\n runKey={runKey}\n path={path}\n renderMediaPreview={renderMediaPreview}\n />\n ) : (\n <Text style={styles.meta}>Loading preview…</Text>\n )}\n </ScrollView>\n );\n}\nfunction BinaryArtifactPreview({\n sessionId,\n workspace,\n runKey,\n path,\n renderMediaPreview,\n}: Pick<WebPluginSlotProps, 'sessionId' | 'renderMediaPreview'> & { workspace: string; runKey: string; path: string }) {\n const requestKey = JSON.stringify([sessionId, workspace, runKey, path]);\n const [loaded, setLoaded] = useState<{ key: string; media?: { data: string; mimeType: string }; error?: string }>();\n const media = loaded?.key === requestKey ? loaded.media : undefined;\n const error = loaded?.key === requestKey ? loaded.error : undefined;\n useEffect(() => {\n const controller = new AbortController();\n void fetchArtifactMedia(workspace, runKey, path, sessionId, controller.signal)\n .then((value) => {\n if (!controller.signal.aborted) setLoaded({ key: requestKey, media: value });\n })\n .catch((cause: unknown) => {\n if (!controller.signal.aborted)\n setLoaded({ key: requestKey, error: cause instanceof Error ? cause.message : String(cause) });\n });\n return () => controller.abort();\n }, [workspace, runKey, path, sessionId, requestKey]);\n return media ? (\n renderMediaPreview?.({ key: `${sessionId}:${workspace}:${runKey}:${path}`, ...media, title: path, path })\n ) : (\n <Text style={styles.meta}>{error ?? 'Loading preview…'}</Text>\n );\n}\nfunction prettyJson(text: string): string {\n try {\n return JSON.stringify(JSON.parse(text) as unknown, null, 2);\n } catch {\n return text;\n }\n}\nfunction DelimitedArtifact({ text, delimiter }: { text: string; delimiter: ',' | '\\t' }) {\n const rows: string[][] = [];\n let row: string[] = [];\n let cell = '';\n let quoted = false;\n for (let index = 0; index <= text.length && rows.length < 500; index += 1) {\n const character = text[index] ?? '\\n';\n if (quoted) {\n if (character === '\"' && text[index + 1] === '\"') {\n cell += '\"';\n index += 1;\n } else if (character === '\"') quoted = false;\n else cell += character;\n } else if (character === '\"' && cell === '') quoted = true;\n else if (character === delimiter) {\n row.push(cell);\n cell = '';\n } else if (character === '\\n') {\n row.push(cell.replace(/\\r$/, ''));\n rows.push(row);\n row = [];\n cell = '';\n } else cell += character;\n }\n return (\n <ScrollView horizontal>\n <View>\n {rows.map((cells, index) => (\n <View key={index} style={styles.tableRow}>\n {cells.map((value, column) => (\n <Text key={column} style={styles.tableCell}>\n {value}\n </Text>\n ))}\n </View>\n ))}\n </View>\n </ScrollView>\n );\n}\nconst styles = StyleSheet.create((theme) => ({\n screen: { flex: 1, backgroundColor: theme.colors.bg, padding: theme.spacing(3) },\n transcript: { flex: 1 },\n tableRow: { flexDirection: 'row' },\n tableCell: {\n color: theme.colors.text,\n fontSize: theme.fontSize.sm,\n padding: theme.spacing(2),\n width: theme.spacing(30),\n borderWidth: 1,\n borderColor: theme.colors.border,\n },\n body: { padding: theme.spacing(3), gap: theme.spacing(2) },\n title: { color: theme.colors.hi, fontSize: theme.fontSize.base, fontWeight: '600' },\n meta: { color: theme.colors.dim, fontSize: theme.fontSize.sm },\n error: { color: theme.colors.red, fontSize: theme.fontSize.sm },\n}));\n","import { defineFill } from '@agimon-ai/po-core/native';\n\nimport { WorkflowLauncher } from '../_components/WorkflowPanel.native';\nexport default defineFill({ component: WorkflowLauncher });\n","import type { WebPluginSlotProps } from '@agimon-ai/po-core/native';\nimport { Button, Dot, ListRow } from '@agimon-ai/po-native-components';\nimport { useEffect, useState } from 'react';\nimport { View } from 'react-native';\n\nimport { useWorkflows, workflowTab } from '../../_components/WorkflowPanel.native';\nimport { openCatalog } from '../../_lib/catalogStore.native';\nimport {\n workflowActivityGroups,\n workflowActivityRows,\n type WorkflowActivityGroupName,\n} from '../../_lib/workflowActivity';\nimport { focusRun } from '../../_lib/workflowsStore.native';\n\nexport function WorkflowsActivitySection({ sessionId, openSession, openTransientTab }: WebPluginSlotProps) {\n const state = useWorkflows(sessionId);\n const [now, setNow] = useState(() => Date.now());\n const [folded, setFolded] = useState<Partial<Record<WorkflowActivityGroupName, boolean>>>({});\n useEffect(() => {\n const timer = setInterval(() => setNow(Date.now()), 10_000);\n return () => clearInterval(timer);\n }, []);\n const groups = workflowActivityGroups(workflowActivityRows(state.runs, now, sessionId));\n return (\n <View>\n {groups.map((group) => {\n const open = folded[group.name] ?? group.openByDefault;\n return (\n <View key={group.name}>\n <Button\n variant=\"ghost\"\n accessibilityState={{ expanded: open }}\n onPress={() => setFolded((current) => ({ ...current, [group.name]: !open }))}\n >\n {group.name} · {group.rows.length}\n </Button>\n {open\n ? group.rows.map((row) => (\n <ListRow\n key={row.identity}\n leading={\n <Dot\n tone={\n row.tone === 'failed'\n ? 'red'\n : row.tone === 'running' || row.tone === 'paused'\n ? 'yellow'\n : row.tone === 'done'\n ? 'green'\n : 'muted'\n }\n />\n }\n title={\n <Button\n variant=\"ghost\"\n testID={`activity-workflow-${row.runKey}`}\n onPress={() => {\n if (row.ownerSessionId && openSession) {\n openSession(row.ownerSessionId);\n return;\n }\n const run = state.runs.find(\n (item) => `${item.workspace}/${item.routeKey ?? item.runKey}` === row.identity,\n );\n if (sessionId !== null) focusRun(sessionId, row.identity);\n if (run) openTransientTab(workflowTab(run));\n }}\n >\n {row.name}\n </Button>\n }\n description={`${row.detail} · ${row.elapsed}`}\n />\n ))\n : null}\n </View>\n );\n })}\n {groups.length === 0 ? (\n <Button\n variant=\"ghost\"\n testID=\"activity-workflow-launch\"\n disabled={sessionId === null}\n onPress={() => {\n if (sessionId !== null) openCatalog(sessionId);\n }}\n >\n Launch a workflow\n </Button>\n ) : null}\n </View>\n );\n}\n","import { defineFill } from '@agimon-ai/po-core/native';\n\nimport { WorkflowsActivitySection } from './_components/WorkflowsActivitySection.native';\nexport default defineFill({ component: WorkflowsActivitySection });\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineNativePlugin, type WebPluginContributions } from '@agimon-ai/po-core/native';\n\nimport fillWorkflows from '../src/extensions/workspaces/(frontend)/fill/Workflows.home.native';\nimport activityGroupWorkflows from '../src/extensions/workspaces/sessions/(frontend)/activity-group/workflows.native';\nimport channelWorkflowCatalog from '../src/extensions/workspaces/sessions/(frontend)/channel/workflow-catalog.native';\nimport channelWorkflowRuns from '../src/extensions/workspaces/sessions/(frontend)/channel/workflow-runs.native';\nimport fillWorkflowLauncher from '../src/extensions/workspaces/sessions/(frontend)/fill/WorkflowLauncher.overlay.native';\nimport fillWorkflows2 from '../src/extensions/workspaces/sessions/(frontend)/fill/Workflows.activity.workflows.native';\n\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const nativePlugin = defineNativePlugin({\n id: 'workflows',\n workspace: {\n get fills(): WebPluginContributions['fills'] { return [via({ slot: 'home', id: 'workflows' }, fillWorkflows)]; },\n },\n session: {\n get activityGroups(): WebPluginContributions['activityGroups'] { return [via({ name: 'workflows' }, activityGroupWorkflows)]; },\n get channels(): WebPluginContributions['channels'] { return [via({ channel: 'workflow_catalog' }, channelWorkflowCatalog), via({ channel: 'workflow_runs' }, channelWorkflowRuns)]; },\n get fills(): WebPluginContributions['fills'] { return [via({ slot: 'overlay', id: 'workflow-launcher' }, fillWorkflowLauncher), via({ slot: 'activity.workflows', id: 'workflows' }, fillWorkflows2)]; },\n },\n});\n"],"mappings":";;;;;;;;;AAEA,IAAA,gCAAe,WAAW,EACxB,MAAM;CAAE,SAAS;CAAG,OAAO;CAAa,QAAQ;CAAiB,aAAa;AAAY,EAC5F,CAAC;;;ACmHD,MAAa,qBAAqB;AA2DlC,MAAa,wBAAwB;;;;;;;;AC7KrC,MAAM,YAAY;AAClB,MAAM,UAAU,KAAK;AAErB,SAAgB,kBAAkB,WAA2B;CAC3D,IAAI,YAAY,WAAW,OAAO;CAClC,IAAI,YAAY,SAAS,OAAO,GAAG,KAAK,MAAM,YAAY,SAAS,EAAE;CACrE,MAAM,QAAQ,KAAK,MAAM,YAAY,OAAO;CAC5C,MAAM,UAAU,KAAK,MAAO,YAAY,UAAW,SAAS;CAC5D,OAAO,GAAG,MAAM,IAAI,OAAO,OAAO,CAAC,CAAC,SAAS,GAAG,GAAG,EAAE;AACvD;;;ACKA,MAAM,gCAA6E,IAAI,IAAI,CACzF,UACA,iBACF,CAAC;AAED,SAAgB,oBAAoB,KAAyE;CAC3G,OAAO,GAAG,IAAI,UAAU,GAAG,IAAI,YAAY,IAAI;AACjD;AAOA,SAAS,OAAO,KAA4C;CAC1D,IAAI,IAAI,UAAU,WAChB,OAAO,IAAI,mBAAmB,KAAA,KAAa,cAAc,IAAI,IAAI,cAAc,IAAI,WAAW;CAEhG,IAAI,IAAI,UAAU,SAAS,OAAO;CAClC,IAAI,IAAI,YAAY,KAAA,KAAa,IAAI,YAAY,WAAW,OAAO,IAAI,YAAY,WAAW,WAAW;CACzG,OAAO;AACT;AAEA,SAAS,SAAS,KAAsB,MAAoC;CAC1E,IAAI,SAAS,UAAU,OAAO;CAC9B,IAAI,SAAS,UACX,OAAO,IAAI,iBAAiB,IAAI,cAAc,KAAA,IAAY,WAAW,QAAQ,IAAI,UAAU;CAC7F,IAAI,SAAS,WAAW;EACtB,IAAI,IAAI,aAAa,KAAA,GAAW,OAAO;EACvC,OAAO,IAAI,SAAS,SAAS,KAAA,IAAY,IAAI,SAAS,MAAM,GAAG,IAAI,SAAS,IAAI,KAAK,IAAI,SAAS;CACpG;CACA,OAAO,IAAI,WAAW;AACxB;AAEA,SAAS,UAAU,KAAsB,KAAqB;CAC5D,MAAM,QAAQ,KAAK,MAAM,IAAI,SAAS;CACtC,IAAI,CAAC,OAAO,SAAS,KAAK,GAAG,OAAO;CACpC,MAAM,MAAM,IAAI,eAAe,KAAA,IAAY,MAAM,KAAK,MAAM,IAAI,UAAU;CAC1E,OAAO,kBAAkB,KAAK,IAAI,IAAI,OAAO,SAAS,GAAG,IAAI,MAAM,OAAO,KAAK,CAAC;AAClF;;AAGA,SAAgB,qBACd,MACA,KACA,YAA2B,MACJ;CACvB,OAAO,KAAK,KAAK,QAAQ;EACvB,MAAM,OAAO,OAAO,GAAG;EACvB,OAAO;GACL,UAAU,oBAAoB,GAAG;GACjC,QAAQ,IAAI;GACZ,MAAM,IAAI;GACV;GACA,SAAS,UAAU,KAAK,GAAG;GAC3B,QAAQ,SAAS,KAAK,IAAI;GAC1B,GAAI,IAAI,mBAAmB,KAAA,KAAa,IAAI,mBAAmB,YAC3D,CAAC,IACD,EAAE,gBAAgB,IAAI,eAAe;EAC3C;CACF,CAAC;AACH;AAkBA,MAAM,WAA8E;CAClF,SAAS;CACT,QAAQ;CACR,QAAQ;CACR,MAAM;CACN,SAAS;AACX;AAEA,MAAM,cAAoD;CAAC;CAAW;CAAU;AAAY;;AAG5F,SAAgB,uBAAuB,MAA+D;CACpG,OAAO,YAAY,KAAK,UAAU;EAChC;EACA,MAAM,KAAK,QAAQ,QAAQ,SAAS,IAAI,UAAU,IAAI;EACtD,eAAe,SAAS;CAC1B,EAAE,CAAC,CAAC,QAAQ,UAAU,MAAM,KAAK,SAAS,CAAC;AAC7C;;;AC7FA,MAAa,YAAY,mBAAqC;CAC5D,MAAM,CAAC;CACP,YAAY,KAAA;CACZ,eAAe,KAAA;AACjB,CAAC;AAED,SAASA,WAAS,OAAkD;CAClE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;;AAGA,SAAgB,SAAS,WAAmB,UAAoC;CAC9E,UAAU,OAAO,YAAY,aAAa;EAAE,GAAG;EAAS,YAAY;CAAS,EAAE;AACjF;;AAGA,SAAgB,UAAU,WAAmB,UAAwB;CACnE,UAAU,OAAO,YAAY,YAAY;EACvC,MAAM,OAAO,QAAQ,KAAK,QAAQ,QAAQ,oBAAoB,GAAG,MAAM,QAAQ;EAC/E,OAAO;GACL,GAAG;GACH;GACA,YACE,QAAQ,eAAe,WACnB,KAAK,OAAO,KAAA,IACV,KAAA,IACA,oBAAoB,KAAK,EAAE,IAC7B,QAAQ;EAChB;CACF,CAAC;AACH;;;;;;;AAQA,SAAgB,cAAc,MAA0B,WAAmB,MAAc,cAA4B;CACnH,KAAK,WAAW;EAAE,MAAM;EAAU,SAAS;CAAK,CAAC;CACjD,UAAU,OAAO,YAAY,aAAa;EACxC,GAAG;EACH,eAAe;GAAE;GAAc,WAAW,QAAQ,KAAK,IAAI,mBAAmB;EAAE;CAClF,EAAE;AACJ;;AAOA,MAAa,sBAAsB,UAAU,QAA6B;CACxE,SAAS;CACT,MAAM,OAAO;EACX,IAAI,CAACA,WAAS,KAAK,KAAK,CAAC,MAAM,QAAQ,MAAM,IAAI,GAAG,OAAO;EAC3D,OAAO,EAAE,MAAM,MAAM,KAAK,OAAOA,UAAQ,EAAkC;CAC7E;CACA,SAAS,SAAS,EAAE,WAAW;EAC7B,MAAM,UAAU,QAAQ;EACxB,IAAI,YAAY,KAAA,GAAW,OAAO;GAAE,GAAG;GAAS;EAAK;EACrD,MAAM,QAAQ,IAAI,IAAI,QAAQ,SAAS;EACvC,MAAM,UAAU,KAAK,MAAM,QAAQ,CAAC,MAAM,IAAI,oBAAoB,GAAG,CAAC,CAAC;EAIvE,IAAI,YAAY,KAAA,GAAW,OAAO;GAAE,GAAG;GAAS;EAAK;EACrD,OAAO;GAAE,GAAG;GAAS;GAAM,YAAY,oBAAoB,OAAO;GAAG,eAAe,KAAA;EAAU;CAChG;AACF,CAAC;;;ACrFD,IAAA,2BAAe,oBAAoB;CACjC,MAAM;CACN,YAAY,cAAc,YAAY;CACtC,YAAY,CAAC,yBAAyB,qBAAqB;CAC3D,OAAO;CACP,cAAc;EACZ,UAAU,UAAU;GAClB,MAAM,eAAe,UAAU,MAAM,UAAU,QAAQ;GACvD,aAAa,aAAa,YAAY;EACxC;EACA,SAAS,WAAW;GAClB,OAAO,UAAU,OAAO,UAAU,MAAM,OAAO,SAAS,CAAC,CAAC,KAAK,MAAM,QAAQ,IAAI,UAAU,SAAS;EACtG;CACF;AACF,CAAC;;;ACOD,MAAa,UAAU,mBAAmC;CACxD,KAAK;CACL,WAAW,CAAC;CACZ,SAAS,KAAA;CACT,MAAM;CACN,QAAQ;CACR,QAAQ;CACR,UAAU,KAAA;CACV,WAAW,KAAA;CACX,QAAQ,KAAA;AACV,CAAC;AAED,SAASC,WAAS,OAAkD;CAClE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAgB,YAAY,WAAmB,SAAS,IAAU;CAChE,QAAQ,OAAO,YAAY,aAAa;EAAE,GAAG;EAAS,MAAM;EAAM;CAAO,EAAE;AAC7E;AAEA,SAAgB,aAAa,WAAyB;CACpD,QAAQ,OAAO,YAAY,aAAa;EAAE,GAAG;EAAS,MAAM;EAAO,QAAQ;EAAI,QAAQ,KAAA;CAAU,EAAE;AACrG;;AAuBA,SAAgB,cACd,WACA,QAC4B;CAC5B,MAAM,SAAS,OAAO,KAAK,CAAC,CAAC,YAAY;CACzC,IAAI,WAAW,IAAI,OAAO,CAAC,GAAG,SAAS;CACvC,OAAO,UAAU,QAAQ,aACvB;EACE,SAAS;EACT,SAAS;EACT,SAAS;EACT,GAAG,SAAS;EACZ,GAAG,SAAS,KAAK,KAAK,QAAQ,IAAI,IAAI;CACxC,CAAC,CACE,KAAK,IAAI,CAAC,CACV,YAAY,CAAC,CACb,SAAS,MAAM,CACpB;AACF;;AAGA,MAAa,yBAAyB,QAAQ,QAAgC;CAC5E,SAAS;CACT,MAAM,OAAO;EACX,IAAI,CAACA,WAAS,KAAK,KAAK,OAAO,MAAM,QAAQ,YAAY,CAAC,MAAM,QAAQ,MAAM,SAAS,GAAG,OAAO;EACjG,OAAO;GACL,KAAK,MAAM;GACX,WAAW,MAAM,UAAU,OAAOA,UAAQ;GAC1C,GAAI,OAAO,MAAM,YAAY,WAAW,EAAE,SAAS,MAAM,QAAQ,IAAI,CAAC;EACxE;CACF;CACA,OAAO,SAAS,SAAS;EACvB,MAAM,QAAQ,IAAI,IAAI,QAAQ,UAAU,KAAK,aAAa,SAAS,IAAI,CAAC;EACxE,OAAO;GACL,GAAG;GACH,KAAK,QAAQ;GACb,WAAW,QAAQ;GACnB,SAAS,QAAQ;GAEjB,UAAU,QAAQ,aAAa,KAAA,KAAa,MAAM,IAAI,QAAQ,QAAQ,IAAI,QAAQ,WAAW,KAAA;GAC7F,WAAW,QAAQ,cAAc,KAAA,KAAa,MAAM,IAAI,QAAQ,SAAS,IAAI,QAAQ,YAAY,KAAA;GACjG,QAAQ,QAAQ,WAAW,KAAA,KAAa,MAAM,IAAI,QAAQ,MAAM,IAAI,QAAQ,SAAS,KAAA;EACvF;CACF;AACF,CAAC;;;AChHD,IAAA,kCAAe,kBAAkB,sBAAsB;;;ACAvD,IAAA,+BAAe,kBAAkB,mBAAmB;;;;;;;;;;;;ACSpD,MAAa,uBAAuB;;AAEpC,MAAa,aAAa;AAC1B,MAAa,cAAc;AAC3B,MAAa,aAAa;;AAY1B,SAAS,MAAM,OAAuB;CACpC,OAAO,KAAK,KAAK,KAAK,IAAI,IAAI,MAAM,KAAK;AAC3C;AAEA,SAAS,aAAa,KAAa,OAAqC;CACtE,OAAO,UAAU,KAAA,KAAa,UAAU,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,MAAM,KAAK,GAAG;AAC7E;AAEA,SAAgB,mBAAmB,SAAwC;CACzE,MAAM,QAAQ;EACZ,GAAG,aAAa,YAAY,QAAQ,MAAM;EAC1C,GAAG,aAAa,aAAa,QAAQ,OAAO;EAC5C,GAAG,aAAa,YAAY,QAAQ,MAAM;EAC1C,GAAG,OAAO,QAAQ,QAAQ,MAAM,CAAC,CAC9B,QAAQ,GAAG,WAAW,UAAU,EAAE,CAAC,CACnC,KAAK,CAAC,KAAK,WAAW,GAAG,IAAI,GAAG,MAAM,KAAK,GAAG;CACnD;CACA,MAAM,SAAS,QAAQ,QAAQ,KAAK;CACpC,OAAO;EAAC;EAAsB,MAAM,QAAQ,QAAQ;EAAG,GAAG;EAAO,GAAI,SAAS,CAAC,MAAM,IAAI,CAAC;CAAE,CAAC,CAAC,KAAK,GAAG;AACxG;;AAGA,MAAM,sBAAsB;;AAG5B,SAAgB,eAAe,UAAoC,SAA0C;CAC3G,MAAM,WAAqB,CAAC;CAC5B,IAAI,SAAS,SAAS,SAAS,mBAAmB,MAAM,QAAQ,UAAU,GAAA,CAAI,KAAK,MAAM,IACvF,SAAS,KAAK,0DAA0D;CAE1E,MAAM,UAAU,SAAS,OACtB,QAAQ,UAAU,MAAM,aAAa,SAAS,QAAQ,OAAO,MAAM,SAAS,QAAQ,EAAE,CAAC,CACvF,KAAK,UAAU,MAAM,IAAI;CAC5B,IAAI,QAAQ,SAAS,GACnB,SAAS,KAAK,yBAAyB,QAAQ,SAAS,IAAI,MAAM,GAAG,IAAI,QAAQ,KAAK,IAAI,EAAE,EAAE;CAEhG,OAAO;AACT;;AAGA,SAAgB,cAAc,UAA4D;CACxF,OAAO,OAAO,YAAY,SAAS,OAAO,KAAK,UAAU,CAAC,MAAM,MAAM,MAAM,WAAW,EAAE,CAAC,CAAC;AAC7F;;AAGA,SAAgB,cAAc,UAAwD;CACpF,OAAO,SAAS,UAAU;AAC5B;;AAGA,SAAgB,eAAe,UAAwD;CACrF,OAAO,SAAS,WAAW;AAC7B;;AAGA,SAAgB,cAAc,UAAwD;CACpF,MAAM,UAAU,SAAS,WAAW,CAAC;CACrC,OAAO,QAAQ,SAAS,SAAS,IAAI,YAAY,QAAQ;AAC3D;;;;;;;;;;;;;;;;;;;;;;ACpDA,MAAM,MAAM;;;;;;;;;AAUZ,MAAa,sBAAsB;;;;;AAMnC,MAAa,oBAAoB;AAIjC,MAAa,0BAA0B;AC9CvC,MAAa,MAAM,gBAAgB;;;;;;;CDuDjC,UAAU;EACR,QAAQ;EACR,MAAM,GAAG,IAAI;EACb,OAAO,CAAC,iBAAiB;EACzB,UAAU,KAAA;CACZ;CACA,QAAQ;EACN,QAAQ;EACR,MAAM,GAAG,IAAI;EACb,OAAO,CAAC,iBAAiB;EACzB,QAAQ;CACV;CACA,SAAS;EACP,QAAQ;EACR,MAAM,GAAG,IAAI;EACb,UAAU,KAAA;CACZ;CACA,MAAM;EACJ,QAAQ;EACR,MAAM,GAAG,IAAI;CACf;CACA,QAAQ;EACN,QAAQ;EACR,MAAM,GAAG,IAAI;EACb,UAAU,KAAA;CACZ;CACA,QAAQ;EACN,QAAQ;EACR,MAAM;EACN,UAAU,KAAA;CACZ;CACA,MAAM;EACJ,QAAQ;EACR,MAAM,GAAG,IAAI;EACb,UAAU,KAAA;CACZ;;CAEA,OAAO;EACL,QAAQ;EACR,MAAM,GAAG,IAAI;EACb,UAAU,KAAA;CACZ;;;;;CAKA,QAAQ;EACN,QAAQ;EACR,MAAM;EACN,UAAU,KAAA;CACZ;CACA,kBAAkB;EAChB,QAAQ;EACR,MAAM,GAAG,IAAI;EACb,UAAU,KAAA;CACZ;CACA,WAAW;EACT,QAAQ;EACR,MAAM,GAAG,IAAI;EACb,OAAO,CAAC,WAAW;EACnB,UAAU,KAAA;CACZ;;CAEA,UAAU;EACR,QAAQ;EACR,MAAM,GAAG,IAAI,aAAa;EAC1B,OAAO,CAAA,OAAqB,uBAAuB;EACnD,UAAU,KAAA;CACZ;AC3HiC,GAAQ;CACzC,QAAQ;EAHgB;EAAU;EAAa;CAGvC;CACR,UAAU;CACV,WAAW;CACX,gBAAgB;AAClB,CAAC;;;;;;;;;;;;;;;;;;;ACwBD,MAAM,cAAc;;AAMpB,SAAS,OAAO,WAA0C;CACxD,OAAO,aAAa,OAAO,IAAI,SAAS,IAAI,QAAQ,SAAS;AAC/D;;AAGA,SAAS,UAAU,WAAmB,QAAuD;CAC3F,OAAO;EAAE;EAAW;CAAO;AAC7B;AAEA,SAAS,SAAS,OAAkD;CAClE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;;;;;;;AAQA,SAAS,UAAU,QAA4C,UAA0B;CACvF,IAAI,OAAO,WAAW,GAAG,OAAO;CAChC,OAAO,OAAO,UAAU,KAAA,KAAa,OAAO,UAAU,KAAK,WAAW,OAAO;AAC/E;;;;;;;;;;;AAYA,SAAS,YACP,OACA,WACA,QACA,cACA,OACQ;CACR,OAAO,MAAM,SACV,IAAI;EAAE,QAAQ,UAAU,WAAW,MAAM;EAAG,GAAI,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM;CAAG,CAAC,CAAC,CACxF,QAAQ,qBAAqB,aAAa,MAAM,GAAG,CAAC,CAAC,IAAI,kBAAkB,CAAC,CAAC,KAAK,GAAG,CAAC;AAC3F;;AAGA,SAAS,SAAS,MAA6C;CAC7D,OAAO,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,KAAK;AAC1C;;AAGA,eAAsB,WACpB,WACA,QACA,WACA,MACA,QAC8B;CAC9B,MAAM,WAAW,MAAM,mBACrB,OAAO,SAAS,CAAC,CAAC,SAAS,IAAI;EAC7B,QAAQ,UAAU,WAAW,MAAM;EACnC,OAAO,GAAG,oBAAoB,KAAK;CACrC,CAAC,GACD,EAAE,OAAO,CACX;CACA,MAAM,OAAgB,MAAM,SAAS,KAAK;CAC1C,IAAI,CAAC,SAAS,IACZ,MAAM,IAAI,MAAM,SAAS,IAAI,KAAK,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ,+BAA+B;CACjH,IACE,CAAC,SAAS,IAAI,KACd,CAAC,MAAM,QAAQ,KAAK,KAAK,KACzB,KAAK,MAAM,SAAS,MACpB,CAAC,KAAK,MAAM,OAAO,SAAS,OAAO,SAAS,YAAY,KAAK,UAAU,IAAI,KAC3E,CAAC,SAAS,KAAK,YAAY,KAC3B,OAAO,KAAK,aAAa,aAAa,aACtC,OAAO,KAAK,aAAa,aAAa,aACtC,OAAO,KAAK,aAAa,cAAc,WAEvC,MAAM,IAAI,MAAM,8CAA8C;CAEhE,OAAO;AACT;;AAGA,eAAsB,YACpB,WACA,QACA,OACA,WACA,MACkC;CAClC,MAAM,SAAS,MAAM,OAAO,SAAS,CAAC,CAAC,QAAQ;EAC7C,QAAQ,UAAU,WAAW,MAAM;EACnC,MAAM;GAAE;GAAO,GAAG,SAAS,IAAI;EAAE;CACnC,CAAC;CACD,IAAI,OAAO,WAAW,GAAG,OAAO;EAAE,MAAM;EAAO,QAAQ;CAAY;CAGnE,IAAI,SAAS,OAAO,IAAI,KAAK,OAAO,OAAO,KAAK,SAAS,WACvD,OAAO,OAAO;CAEhB,OAAO;EAAE,MAAM;EAAO,QAAQ,UAAU,QAAQ,+BAA+B;CAAE;AACnF;AAEA,eAAsB,eACpB,WACA,QACA,OACA,WACA,MACe;CACf,MAAM,OAAO,SAAS,CAAC,CAAC,QAAQ;EAC9B,QAAQ,UAAU,WAAW,MAAM;EACnC,MAAM;GAAE;GAAO,SAAS;GAAM,GAAG,SAAS,IAAI;EAAE;CAClD,CAAC;AACH;;AAGA,eAAsB,SACpB,WACA,QACA,OACA,MACA,WACA,MAC6B;CAC7B,MAAM,SAAS,MAAM,OAAO,SAAS,CAAC,CAAC,KAAK;EAC1C,QAAQ,UAAU,WAAW,MAAM;EACnC,MAAM;GAAE;GAAO;GAAM,GAAG,SAAS,IAAI;EAAE;CACzC,CAAC;CACD,IAAI,OAAO,IAAI,OAAO,CAAC;CACvB,OAAO,EAAE,OAAO,UAAU,QAAQ,oCAAoC,EAAE;AAC1E;;AAGA,eAAsB,UACpB,WACA,QACA,OACA,SACA,MACA,WACA,MACe;CACf,MAAM,OAAO,SAAS,CAAC,CAAC,OAAO;EAC7B,QAAQ,UAAU,WAAW,MAAM;EACnC,MAAM;GAAE;GAAO;GAAS;GAAM,GAAG,SAAS,IAAI;EAAE;CAClD,CAAC;AACH;;AAKA,eAAsB,kBACpB,WACA,QACA,WAC+B;CAC/B,MAAM,SAAS,MAAM,OAAO,SAAS,CAAC,CAAC,OAAO,EAAE,QAAQ,UAAU,WAAW,MAAM,EAAE,CAAC;CACtF,IAAI,CAAC,OAAO,IAAI,OAAO,EAAE,OAAO,UAAU,QAAQ,oCAAoC,EAAE;CACxF,IAAI,OAAO,KAAK,YAAY,MAAM,OAAO,EAAE,QAAQ,EAAE,SAAS,KAAK,EAAE;CACrE,OAAO,EAAE,OAAO,0DAA0D;AAC5E;;AAKA,eAAsB,gBACpB,WACA,QACA,WAC6B;CAC7B,MAAM,SAAS,MAAM,OAAO,SAAS,CAAC,CAAC,KAAK,EAAE,QAAQ,UAAU,WAAW,MAAM,EAAE,CAAC;CACpF,IAAI,CAAC,OAAO,IAAI,OAAO,EAAE,OAAO,UAAU,QAAQ,oCAAoC,EAAE;CACxF,IAAI,OAAO,KAAK,cAAc,MAAM,OAAO,EAAE,QAAQ,EAAE,WAAW,KAAK,EAAE;CACzE,OAAO,EAAE,OAAO,sDAAsD;AACxE;;;;;AAQA,eAAsB,UACpB,WACA,QACA,SACA,WACA,MAC0B;CAC1B,MAAM,SAAS,MAAM,OAAO,SAAS,CAAC,CAAC,MAAM;EAC3C,QAAQ,UAAU,WAAW,MAAM;EACnC,MAAM,SAAS,KAAA,IAAY,EAAE,QAAQ,IAAI;GAAE;GAAS;EAAK;CAC3D,CAAC;CACD,IAAI,CAAC,OAAO,IAAI,OAAO,EAAE,OAAO,UAAU,QAAQ,wCAAwC,EAAE;CAC5F,IAAI,OAAO,KAAK,cAAc,MAAM,OAAO,EAAE,QAAQ,EAAE,WAAW,KAAK,EAAE;CACzE,OAAO,EAAE,OAAO,uDAAuD;AACzE;AAeA,eAAsB,eACpB,WACA,QACA,WACA,WAC0B;CAC1B,MAAM,SAAS,MAAM,OAAO,SAAS,CAAC,CAAC,UAAU;EAAE,QAAQ,UAAU,WAAW,MAAM;EAAG,OAAO,EAAE,UAAU;CAAE,CAAC;CAC/G,IAAI,CAAC,OAAO,IAAI,OAAO,EAAE,OAAO,UAAU,QAAQ,oCAAoC,EAAE;CACxF,OAAO,EAAE,WAAW,OAAO,KAAK;AAClC;;AAKA,SAAgB,mBACd,WACA,QACA,MACA,WAAW,OACX,WACQ;CACR,OAAO,YAAY,OAAO,SAAS,GAAG,WAAW,QAAQ,MAAM;GACvC,QAAA;EACtB,GAAI,WAAW,GAAG,0BAA0B,EAAE,IAAI,CAAC;CACrD,CAAC;AACH;;;;;;;;AASA,eAAsB,cACpB,WACA,QACA,MACA,WACyB;CACzB,IAAI;EACF,MAAM,WAAW,MAAM,mBAAmB,YAAY,OAAO,SAAS,GAAG,WAAW,QAAQ,IAAI,CAAC;EACjG,MAAM,OAAQ,MAAM,SAAS,KAAK;EAClC,IAAI,CAAC,SAAS,IAAI;GAChB,MAAM,QAAQ,SAAS,IAAI,KAAK,OAAO,KAAK,UAAU,YAAY,KAAK,UAAU,KAAK,KAAK,QAAQ;GACnG,OAAO,EAAE,OAAO,UAAU,KAAK,oCAAoC,MAAM;EAC3E;EACA,OAAO,EAAE,UAAU,KAAwC;CAC7D,QAAQ;EACN,OAAO,EAAE,OAAO,YAAY;CAC9B;AACF;AAEA,MAAM,kBAAkB;AACxB,MAAM,kBAAkB;;AAGxB,SAAgB,mBAAmB,MAA6D;CAC9F,IAAI,wBAAoB,IAAI,WAAW,CAAC;CACxC,IAAI,SAAS;CACb,IAAI,aAAa;CACjB,IAAI;CACJ,OAAO,OAAO,MAAc,UAA8B,WAAwB;EAChF,IAAI,OAAO,SAAS,MAAM,IAAI,MAAM,oBAAoB;EACxD,IAAI,QAAQ,aAAa,OAAO,UAAU,KAAK,SAAS;EACxD,IAAI,CAAC,SAAS,UAAU,MAAM,UAAU,OAAO;GAC7C,MAAM,OAAO,MAAM,KAAK,MAAM;GAC9B,IAAI,OAAO,SAAS,MAAM,IAAI,MAAM,oBAAoB;GACxD,QAAQ;GACR,QAAQ,KAAK,KAAK,MAAM,KAAK,MAAM,CAAC;GACpC,SAAS;GACT,cAAc;GACd,QAAQ;EACV;EACA,MAAM,QAAQ,MAAM,SAAS,QAAQ,SAAS,eAAe;EAC7D,UAAU,MAAM;EAChB,OAAO;GACL,OAAO,OAAO,KAAK;GACnB,QAAQ;GACR;GACA,YAAY,OAAO,UAAU;GAC7B,QAAQ,MAAM,aAAa;GAC3B,SAAS,SAAS,MAAM;GACxB,OAAO,MAAM,UAAU;EACzB;CACF;AACF;;AAGA,eAAsB,mBACpB,WACA,QACA,MACA,WACA,QAC6C;CAC7C,IAAI,OAAO,SAAS,MAAM,IAAI,MAAM,oBAAoB;CACxD,MAAM,WAAW,MAAM,mBAAmB,mBAAmB,WAAW,QAAQ,MAAM,OAAO,SAAS,GAAG,EAAE,OAAO,CAAC;CACnH,IAAI,OAAO,SAAS,MAAM,IAAI,MAAM,oBAAoB;CACxD,IAAI,CAAC,SAAS,IAAI,MAAM,IAAI,MAAM,kCAAkC;CACpE,MAAM,YAAY,SAAS,QAAQ,IAAI,cAAc,KAAK,GAAA,CAAI,MAAM,GAAG,CAAC,CAAC,EAAE,CAAE,KAAK,CAAC,CAAC,YAAY;CAChG,IACE,CAAC,oIAAoI,KACnI,QACF,GAEA,MAAM,IAAI,MAAM,yCAAyC;CAC3D,IAAI,OAAO,SAAS,QAAQ,IAAI,gBAAgB,CAAC,IAAI,iBACnD,MAAM,IAAI,MAAM,gDAAgD;CAClE,MAAM,QAAQ,MAAM,SAAS,YAAY;CACzC,IAAI,OAAO,SAAS,MAAM,IAAI,MAAM,oBAAoB;CACxD,IAAI,MAAM,aAAa,iBAAiB,MAAM,IAAI,MAAM,gDAAgD;CACxG,OAAO;EAAE,MAAM,OAAO,IAAI,WAAW,KAAK,CAAC;EAAG;CAAS;AACzD;AAEA,SAAS,OAAO,OAA2B;CACzC,MAAM,WAAW;CACjB,MAAM,QAAkB,CAAC;CACzB,IAAI,QAAQ;CACZ,KAAK,IAAI,SAAS,GAAG,SAAS,MAAM,QAAQ,UAAU,GAAG;EACvD,MAAM,QAAQ,MAAM;EACpB,MAAM,SAAS,MAAM,SAAS;EAC9B,MAAM,QAAQ,MAAM,SAAS;EAC7B,SACE,SAAS,SAAS,KAClB,UAAW,QAAQ,MAAM,KAAO,UAAU,MAAM,MAC/C,WAAW,KAAA,IAAY,MAAM,UAAW,SAAS,OAAO,KAAO,SAAS,MAAM,OAC9E,UAAU,KAAA,IAAY,MAAM,SAAS,QAAQ;EAChD,IAAI,MAAM,UAAU,MAAM;GACxB,MAAM,KAAK,KAAK;GAChB,QAAQ;EACV;CACF;CACA,MAAM,KAAK,KAAK;CAChB,OAAO,MAAM,KAAK,EAAE;AACtB;AAEA,SAAS,KAAK,MAA0B;CACtC,MAAM,QAAkB,CAAC;CACzB,KAAK,MAAM,aAAa,MAAM;EAC5B,IAAI,OAAO,UAAU,YAAY,CAAC;EAClC,IAAI,QAAQ,SAAU,QAAQ,OAAQ,OAAO;EAC7C,IAAI,OAAO,KAAM,MAAM,KAAK,IAAI;OAC3B,IAAI,OAAO,MAAO,MAAM,KAAK,MAAQ,QAAQ,GAAI,MAAQ,OAAO,EAAG;OACnE,IAAI,OAAO,OAAS,MAAM,KAAK,MAAQ,QAAQ,IAAK,MAAS,QAAQ,IAAK,IAAK,MAAQ,OAAO,EAAG;OACjG,MAAM,KAAK,MAAQ,QAAQ,IAAK,MAAS,QAAQ,KAAM,IAAK,MAAS,QAAQ,IAAK,IAAK,MAAQ,OAAO,EAAG;CAChH;CACA,OAAO,WAAW,KAAK,KAAK;AAC9B;;AAGA,eAAsB,oBACpB,WACA,QACA,MACA,WACA,QAC2E;CAC3E,MAAM,OAAO,OAAO,SAAiC,WAA2C;EAC9F,IAAI,OAAO,SAAS,MAAM,IAAI,MAAM,qBAAqB;EACzD,OAAO,mBAAmB,mBAAmB,WAAW,QAAQ,MAAM,MAAM,SAAS,GAAG;GAAE;GAAS;EAAO,CAAC;CAC7G;CACA,MAAM,QAAQ,MAAM,KAAK,EAAE,OAAO,YAAY,GAAG,MAAM;CACvD,IAAI,OAAO,SAAS,MAAM,IAAI,MAAM,qBAAqB;CACzD,MAAM,QAAQ,sBAAsB,KAAK,MAAM,QAAQ,IAAI,eAAe,KAAK,EAAE;CACjF,MAAM,QACH,MAAM,WAAW,OAAO,MAAM,QAAQ,IAAI,eAAe,MAAM,eAC/D,MAAM,WAAW,OAAO,MAAM,QAAQ,IAAI,gBAAgB,MAAM;CACnE,IAAI,CAAC,UAAU,MAAM,WAAW,OAAO,CAAC,QAAQ,MAAM,IAAI,MAAM,8CAA8C;CAC9G,MAAM,OAAO,QAAQ,IAAI,OAAO,MAAO,EAAE;CACzC,IAAI,CAAC,OAAO,cAAc,IAAI,KAAK,OAAO,GAAG,MAAM,IAAI,MAAM,oBAAoB;CAEjF,KAAI,MADqB,MAAM,YAAY,EAAA,CAC5B,gBAAgB,QAAQ,IAAI,IAAI,MAAM,IAAI,MAAM,wBAAwB;CACvF,MAAM,UAAU,MAAM,QAAQ,IAAI,MAAM;CACxC,IAAI,CAAC,SAAS,MAAM,IAAI,MAAM,oCAAoC;CAClE,OAAO;EACL,MAAM,KAAK,MAAM,QAAQ,CAAC,CAAC,GAAG,EAAE,KAAK;EACrC,UAAU,MAAM,QAAQ,IAAI,cAAc,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,EAAE,EAAE,KAAK,KAAK;EACtE;EACA;EACA,MAAM,OAAO,QAAQ,OAAO,WAAW;GACrC,IACE,CAAC,OAAO,cAAc,MAAM,KAC5B,CAAC,OAAO,cAAc,KAAK,KAC3B,SAAS,KACT,QAAQ,KACR,QAAQ,WACR,SAAS,QAAQ,MAEjB,MAAM,IAAI,MAAM,yBAAyB;GAC3C,MAAM,MAAM,SAAS,QAAQ;GAC7B,MAAM,WAAW,MAAM,KAAK;IAAE,OAAO,SAAS,OAAO,GAAG;IAAO,YAAY;GAAQ,GAAG,MAAM;GAC5F,IAAI,OAAO,SAAS,MAAM,IAAI,MAAM,qBAAqB;GACzD,IACE,SAAS,WAAW,OACpB,SAAS,QAAQ,IAAI,MAAM,MAAM,WACjC,SAAS,QAAQ,IAAI,eAAe,MAAM,SAAS,OAAO,GAAG,IAAI,GAAG,QAEpE,MAAM,IAAI,MAAM,oDAAoD;GACtE,MAAM,QAAQ,IAAI,WAAW,MAAM,SAAS,YAAY,CAAC;GACzD,IAAI,OAAO,SAAS,MAAM,IAAI,MAAM,qBAAqB;GACzD,IAAI,MAAM,eAAe,OAAO,MAAM,IAAI,MAAM,kCAAkC;GAClF,OAAO;EACT;CACF;AACF;;;AC1ZA,SAAgBqD,aAAaC,WAA0B;CACrD,MAAMC,YAAYzC,aAAa0C,aAAyB;EACtD,MAAMC,MAAML,UAAUM,MAAMH,UAAUC,QAAQ;EAC9C,aAAaC,IAAIE,YAAY;CAC/B,GAAG,CAAA,CAAE;CACL,OAAOxC,qBAAqBoC,iBAAiBH,UAAUQ,OAAOR,UAAUM,MAAMG,OAAOP,SAAS,CAAC;AACjG;AACA,SAAgBQ,YAAYC,KAA6E;CACvG,MAAME,WAAWjB,oBAAoBe,GAAG;CACxC,OAAO;EACLG,IAAI,iBAAiBH,IAAII,UAAS,GAAIJ,IAAIK,YAAYL,IAAIM,SAASC,QAAQ,YAAY,GAAG;EAC1FC,OAAOR,IAAIS;EACXC,gBAAgB;EAChBC,QAAQC,UAAU,oBAAC,eAAD;GAAe,GAAIA;GAAiBV;EAAS,CAAA;CACjE;AACF;AACA,SAAgBW,iBAAiBD,OAA2B;CAC1D,MAAMpB,YAAYzC,aAAa0C,aAAyB;EACtD,MAAMC,MAAM/B,QAAQgC,MAAMH,UAAUC,QAAQ;EAC5C,aAAaC,IAAIE,YAAY;CAC/B,GAAG,CAAA,CAAE;CACL,MAAME,QAAQ1C,qBAAqBoC,iBAAiB7B,QAAQkC,OAAOlC,QAAQgC,MAAMG,OAAOc,MAAMrB,SAAS,CAAC;CACxG,MAAM,CAACuB,QAAQC,aAAa5D,SAAS,EAAE;CACvC,MAAM,CAAC6D,UAAUC,eAAe9D,SAAiB;CACjD,IAAIyD,MAAMrB,cAAc,QAAQ,CAACO,MAAMoB,MAAM,OAAO;CACpD,MAAMC,WAAWrB,MAAMT,UAAU+B,MAAMC,SAASA,KAAKC,SAASN,QAAQ;CACtE,OACE,oBAAC,OAAD;EACE,MAAA;EACA,eAAeE,SAAS;GACtB,IAAI,CAACA,MAAM;IACTtD,aAAagD,MAAMrB,SAAU;IAC7B0B,YAAYM,KAAAA,CAAS;GACvB;EACF;EAEA,UAAA,qBAAC,cAAD,EAAA,UAAA,CACE,oBAAC,aAAD,EAAA,UACE,oBAAC,YAAD,EAAA,UAAaJ,WAAW,UAAUA,SAASK,SAAS,oBAAgC,CAAA,EACzE,CAAA,GACb,oBAAC,WAAD,EAAA,UACGL,WACC,oBAAC,gBAAD;GAEE,GAAIP;GACJ,WAAWA,MAAMrB;GACP4B;GACV,eAAerB,MAAM2B;GACrB,eAAe;IACb7D,aAAagD,MAAMrB,SAAU;IAC7B0B,YAAYM,KAAAA,CAAS;GACvB;EAAE,GARGJ,SAASG,IAQZ,IAGJ,qBAAC,MAAD;GAAM,OAAOI,OAAOC;GAApB,UAAA;IACE,oBAAC,OAAD;KACE,oBAAmB;KACnB,OAAOb;KACP,cAAcC;KACd,aAAY;IAAiB,CAAA;IAE9BjB,MAAM8B,UAAU,oBAAC,MAAD;KAAM,OAAOF,OAAOG;KAAQ/B,UAAAA,MAAM8B;IAAc,CAAA,IAAI;IACpE/D,cAAciC,MAAMT,WAAWyB,MAAM,CAAC,CAACgB,KAAKT,SAC3C,oBAAC,SAAD;KAEE,OACE,oBAAC,QAAD;MAAQ,SAAQ;MAAQ,eAAeJ,YAAYI,KAAKC,IAAI;MACzDD,UAAAA,KAAKG,QAAQH,KAAKU;KACb,CAAA;KAEV,aAAa,GAAGV,KAAKW,YAAW,IAAKX,KAAKY,KAAKC,KAAK,IAAI,EAAC,KAAMb,KAAKc,KAAKL,KAAKM,QAAQA,IAAIZ,IAAI,CAAC,CAACU,KAAK,IAAI;IAAI,GANxGb,KAAKC,IAMmG,CAEhH;IACAxB,MAAMT,UAAUgD,WAAW,IAAI,oBAAC,MAAD;KAAM,OAAOX,OAAOY;KAAM,UAAA;IAAgC,CAAA,IAAI;GAC1F;EAEC,CAAA,EAAA,CAAA,CACC,EAAA,CAAA;CACT,CAAA;AAEX;AACA,SAASC,OAAO,EACd/B,OACAgC,SACAC,OACAC,YAMC;CACD,OACE,qBAAC,MAAD,EAAA,UAAA,CACE,oBAAC,MAAD;EAAM,OAAOhB,OAAOY;EAAO9B,UAAAA;CAAY,CAAA,GACtCgC,QAAQV,KAAKa,WACZ,oBAAC,QAAD;EAEE,SAAQ;EACR,oBAAoB,EAAE3B,UAAUyB,UAAUE,OAAO;EACjD,eAAeD,SAASC,MAAM;EAE7BA,UAAAA;CACK,GANDA,MAMC,CACT,CACG,EAAA,CAAA;AAEV;AACA,SAASC,eAAe,EACtBrD,WACA4B,UACA0B,eACAC,kBACAC,WAMC;CACD,MAAM,CAACtB,QAAQuB,aAAa7F,SAAS0F,aAAa;CAClD,MAAM,CAACI,QAAQC,aAAa/F,eAAea,cAAcmD,QAAQ,CAAC;CAClE,MAAM,CAACgC,QAAQC,aAAajG,eAAec,cAAckD,QAAQ,CAAC;CAClE,MAAM,CAACkC,SAASC,cAAcnG,eAAeY,eAAeoD,QAAQ,CAAC;CACrE,MAAM,CAACoC,QAAQC,aAAarG,eAAeW,cAAcqD,QAAQ,CAAC;CAClE,MAAM,CAACU,OAAO4B,YAAYtG,SAAiB;CAC3C,MAAMuG,UAAU;EACdvC,UAAUA,SAASK,QAAQL,SAASY;EACpCkB;EACAE;EACAE;EACAE;EACA,GAAI9B,OAAOkC,KAAK,MAAM,KAAK,CAAC,IAAI,EAAElC,QAAQA,OAAOkC,KAAK,EAAE;CAC1D;CACA,MAAMC,WAAW1F,eAAeiD,UAAUuC,OAAO;CACjD,MAAMG,OAAO1F,mBAAmBuF,OAAO;CACvC,OACE,qBAAC,MAAD;EAAM,OAAOhC,OAAOC;EAApB,UAAA;GACE,oBAAC,MAAD;IAAM,OAAOD,OAAOY;IAAOnB,UAAAA,SAASa;GAAkB,CAAA;GACtD,oBAAC,UAAD;IACE,oBAAmB;IACnB,aAAY;IACZ,OAAOP;IACP,cAAcuB;GAAU,CAAA;GAEzB7B,SAAS8B,OAAOnB,KAAKgC,UAAU;IAC9B,MAAMtB,UAAUsB,MAAMtB,YAAYsB,MAAMC,SAAS,YAAY,CAAC,QAAQ,OAAO,IAAIxC,KAAAA;IACjF,OACE,qBAAC,MAAD,EAAA,UAAA,CACE,qBAAC,MAAD;KAAM,OAAOG,OAAOY;KAApB,UAAA;MACGwB,MAAMtC;MACNsC,MAAME,WAAW,gBAAgB;MAAG;MAAIF,MAAM9B;KAC3C;IACLQ,CAAAA,GAAAA,UACC,oBAAC,QAAD;KACE,OAAOsB,MAAMtC;KACJgB;KACT,OAAOS,OAAOa,MAAMtC;KACpB,WAAWiB,UAAUS,WAAWe,aAAa;MAAE,GAAGA;OAAUH,MAAMtC,OAAOiB;KAAM,EAAE;IAAE,CAAA,IAGrF,oBAAC,OAAD;KACE,oBAAoBqB,MAAMtC;KAC1B,OAAOyB,OAAOa,MAAMtC,SAAS;KAC7B,eAAeiB,UAAUS,WAAWe,aAAa;MAAE,GAAGA;OAAUH,MAAMtC,OAAOiB;KAAM,EAAE;IAAE,CAAA,CAGvF,EAAA,GAnBKqB,MAAMtC,IAmBX;GAEV,CAAC;GACAL,SAAS+C,SAAS7B,SACjB,oBAAC,QAAD;IAAQ,OAAM;IAAS,SAASlB,SAAS+C;IAAS,OAAOf;IAAQ,UAAUC;GAAU,CAAA,IACnF;GACHjC,SAASgD,UAAU9B,SAClB,oBAAC,QAAD;IAAQ,OAAM;IAAU,SAASlB,SAASgD;IAAU,OAAOd;IAAS,UAAUC;GAAW,CAAA,IACvF;GACHnC,SAASiD,SAAS/B,SACjB,oBAAC,QAAD;IAAQ,OAAM;IAAS,SAASlB,SAASiD;IAAS,OAAOb;IAAQ,UAAUC;GAAU,CAAA,IACnF;GACJ,oBAAC,WAAD,EAAW,MAAMK,KAAK,CAAA;GACrBD,SAAS9B,KAAKuC,YACb,oBAAC,MAAD;IAAoB,OAAO3C,OAAOY;IAC/B+B,UAAAA;GACG,GAFKA,OAEL,CACP;GACAxC,QAAQ,oBAAC,MAAD;IAAM,OAAOH,OAAOG;IAAQA,UAAAA;GAAY,CAAA,IAAI;GACrD,oBAAC,QAAD;IACE,QAAO;IACP,UAAU+B,SAASvB,SAAS;IAC5B,eAAe;KACb,IAAI;MACFjD,cAAc0D,kBAAkBvD,WAAWsE,MAAM1C,SAASG,IAAI;MAC9DyB,QAAQ;KACV,SAASuB,OAAO;MACdb,SAASa,iBAAiBC,QAAQD,MAAME,UAAUC,OAAOH,KAAK,CAAC;KACjE;IACF;IAAE,UAAA;GAGI,CAAA;EACJ;;AAEV;AAEA,SAAgBI,cAAc9D,OAAkD;CAC9E,MAAMd,QAAQR,aAAasB,MAAMrB,SAAS;CAC1C,MAAMS,MAAMF,MAAM6E,KAAKvD,MAAMC,SAASpC,oBAAoBoC,IAAI,MAAMT,MAAMV,QAAQ;CAClF,MAAM,CAAC0E,eAAeC,oBAAoB1H,SAAS,KAAK;CACxD,MAAM,CAAC2H,MAAMC,WAAW5H,SAAS,KAAK;CACtC,MAAM,CAAC0E,OAAO4B,YAAYtG,SAAiB;CAC3C,MAAM6H,MAAM,OAAOC,WAAgC;EACjD,IAAIH,MAAM;EACVC,QAAQ,IAAI;EACZtB,SAASlC,KAAAA,CAAS;EAClB,IAAI;GACF,MAAM0D,OAAO;EACf,SAASX,OAAO;GACdb,SAASa,iBAAiBC,QAAQD,MAAME,UAAUC,OAAOH,KAAK,CAAC;EACjE,UAAU;GACRS,QAAQ,KAAK;EACf;CACF;CACA,IAAI,CAAC/E,KAAK,OAAO,oBAAC,MAAD;EAAM,OAAO0B,OAAOY;EAAM,UAAA;CAAmC,CAAA;CAC9E,OACE,qBAAC,YAAD;EAAY,uBAAuBZ,OAAOC;EAA1C,UAAA;GACE,oBAAC,MAAD;IAAM,OAAOD,OAAOyD;IAAQnF,UAAAA,IAAIS;GAAkB,CAAA;GAClD,oBAAC,OAAD,EAAA,UAAQT,IAAIoF,kBAAkBpF,IAAIqF,WAAWrF,IAAIsF,MAAa,CAAA;GAC9D,oBAAC,MAAD;IAAM,OAAO5D,OAAOY;IAAOtC,UAAAA,IAAIuF,gBAAgB,GAAGvF,IAAIwF,UAAUpD,OAAO,GAAE,GAAIpC,IAAIwF,UAAUC,QAAQ;GAAW,CAAA;GAC7G3F,MAAM6E,KAAKtC,SAAS,IACjBvC,MAAM6E,KAAK7C,KAAKT,SACd,oBAAC,QAAD;IAEE,SAAQ;IACR,eAAe;KACb,IAAIT,MAAMrB,cAAc,MAAML,SAAS0B,MAAMrB,WAAWN,oBAAoBoC,IAAI,CAAC;KACjFT,MAAM8E,iBAAiB3F,YAAYsB,IAAI,CAAC;IAC1C;IAECA,UAAAA,KAAKZ;GACA,GARDxB,oBAAoBoC,IAAI,CAQvB,CACT,IACD;GACHrB,IAAIoF,mBAAmB,YAAYpF,IAAIoF,mBAAmB,oBACzD,oBAAC,MAAD;IAAM,OAAO1D,OAAOY;IAAM,UAAA;GAA6E,CAAA,IACrG;GACHtC,IAAImC,KAAKL,KAAKM,QACb,qBAAC,MAAD,EAAA,UAAA,CACE,qBAAC,QAAD;IAAQ,SAAQ;IAAQ,eAAexB,MAAM8E,iBAAiBC,QAAQ3F,KAAKoC,IAAIZ,IAAI,CAAC;IAApF,UAAA;KACGY,IAAIZ;KAAK;KAAIY,IAAIwD;IACZ;GACPxD,CAAAA,GAAAA,IAAIyD,MAAM/D,KAAK2D,SACd,oBAAC,SAAD;IAEE,OACE,oBAAC,QAAD;KAAQ,SAAQ;KAAQ,eAAe7E,MAAM8E,iBAAiBC,QAAQ3F,KAAKoC,IAAIZ,MAAMiE,KAAKjE,IAAI,CAAC;KAC5FiE,UAAAA,KAAKjE;IACA,CAAA;IAEV,aAAaiE,KAAKG;GAAO,GANpBH,KAAKjE,IAMe,CAE5B,CACG,EAAA,GAfKY,IAAIZ,IAeT,CACP;GACD,oBAAC,MAAD;IAAM,OAAOE,OAAOyD;IAAO,UAAA;GAAe,CAAA;GAC1C,oBAAC,mBAAD;IAAmB,GAAIvE;IAAYZ;GAAI,CAAA;GACtC6B,QAAQ,oBAAC,MAAD;IAAM,OAAOH,OAAOG;IAAQA,UAAAA;GAAY,CAAA,IAAI;GACpD7B,IAAIsF,UAAU,YACb,oBAAC,QAAD;IACE,SAAQ;IACR,UAAUR,QAAQlE,MAAMrB,cAAc;IACtC,eACE,KAAKyF,IAAI,YAAY;KACnB,MAAMc,SAAS,MAAM9G,gBAAgBgB,IAAII,WAAWJ,IAAIK,YAAYL,IAAIM,QAAQM,MAAMrB,SAAS;KAC/F,IAAI,WAAWuG,QAAQ,MAAM,IAAIvB,MAAMuB,OAAOjE,KAAK;IACrD,CAAC;IACF,UAAA;GAGK,CAAA,IAER,oBAAC,QAAD;IAAQ,SAAQ;IAAiB,UAAUjB,MAAMrB,cAAc;IAAM,eAAesF,iBAAiB,IAAI;IAAE,UAAA;GAEnG,CAAA;GAEV,oBAAC,OAAD;IAAO,MAAMD;IAAe,cAAcC;IACxC,UAAA,qBAAC,cAAD,EAAA,UAAA,CACE,oBAAC,aAAD,EAAA,UACE,oBAAC,YAAD,EAAA,UAAY,mBAA4B,CAAA,EAC7B,CAAA,GACb,qBAAC,WAAD,EAAA,UAAA,CACE,oBAAC,MAAD;KAAM,OAAOnD,OAAOY;KAAM,UAAA;IAAiE,CAAA,GAC3F,oBAAC,QAAD;KACE,SAAQ;KACR,UAAUwC;KACV,eACE,KAAKE,IAAI,YAAY;MACnB,MAAMc,SAAS,MAAM1H,kBAAkB4B,IAAII,WAAWJ,IAAIK,YAAYL,IAAIM,QAAQM,MAAMrB,SAAS;MACjG,IAAI,WAAWuG,QAAQ,MAAM,IAAIvB,MAAMuB,OAAOjE,KAAK;MACnD,IAAIjB,MAAMrB,cAAc,MAAMJ,UAAUyB,MAAMrB,WAAWqB,MAAMV,QAAQ;MACvE2E,iBAAiB,KAAK;MACtBjE,MAAMmF,kBACJ,iBAAiB/F,IAAII,UAAS,GAAIJ,IAAIK,YAAYL,IAAIM,SAASC,QAAQ,YAAY,GAAG,CACxF;KACF,CAAC;KACF,UAAA;IAGK,CAAA,CACC,EAAA,CAAA,CACC,EAAA,CAAA;GACT,CAAA;EACG;;AAEhB;AACA,SAASoF,QACP3F,KACAoC,KACAqD,MACuD;CACvD,MAAMrF,YAAYJ,IAAII;CACtB,MAAME,SAASN,IAAIK,YAAYL,IAAIM;CACnC,OAAO;EACLH,IAAI,kBAAkBC,UAAS,GAAIE,OAAM,GAAI8B,MAAMqD,SAASlE,KAAAA,IAAY,KAAK,IAAIkE,SAASlF,QAAQ,YAAY,GAAG;EACjHC,OAAO,GAAGR,IAAIS,YAAW,KAAMgF,QAAQrD;EACvCzB,QAAQC,UAAU,oBAAC,cAAD;GAAc,GAAIA;GAAkBR;GAAmBE;GAAa8B;GAAWqD;EAAK,CAAA;CACxG;AACF;AACA,SAASO,aAAa,EACpBzG,WACAa,WACAE,QACA8B,KACAqD,MACAQ,yBACAC,wBACyF;CAEzF,MAAMlG,MADQV,aAAaC,SACfO,CAAK,CAAC6E,KAAKvD,MAAMC,SAASA,KAAKjB,cAAcA,cAAciB,KAAKhB,YAAYgB,KAAKf,YAAYA,MAAM;CAC/G,MAAMuF,QAAQ7F,KAAKmC,KAAKf,MAAMC,SAASA,KAAKG,SAASY,GAAG,CAAC,EAAEyD;CAC3D,MAAMM,SAASV,SAASlE,KAAAA,IAAYsE,OAAOO,GAAG,EAAE,IAAIP,OAAOzE,MAAMC,SAASA,KAAKG,SAASiE,IAAI;CAC5F,MAAM,CAACjB,SAAS6B,cAAclJ,SAAS,EAAE;CACzC,MAAM,CAAC0E,OAAO4B,YAAYtG,SAAiB;CAC3C,MAAM,CAAC2H,MAAMC,WAAW5H,SAAS,KAAK;CACtC,MAAMmJ,MAAMH,QAAQG;CACpB,MAAMC,UAAUD,KAAKE,SAAS,YAAYF,IAAInG,KAAKoB,KAAAA;CACnD,OACE,qBAAC,MAAD;EAAM,OAAOG,OAAO+E;EAApB,UAAA;GACE,qBAAC,MAAD;IAAM,OAAO/E,OAAOyD;IAApB,UAAA;KACG/C;KACAqD,SAASlE,KAAAA,IAAY,KAAK,MAAMkE;KAAO;KAAIU,QAAQP;IAChD;;GACLW,UACCN,0BAA0BM,OAAO,IAEjC,oBAAC,kBAAD;IAEahH;IACAa;IACHE;IACR,MAAMgG,KAAKE,SAAS,SAASF,IAAInG,KAAKoB,KAAAA;IAChB2E;GAAqB,GALtC,GAAG3G,UAAS,GAAIa,UAAS,GAAIE,OAAM,GAAIgG,KAAKnG,MAAM,IAKZ;GAG9CoG,WAAWvG,KAAKsF,UAAU,aAAaa,QAAQP,WAAW,YACzD,qBAAC,MAAD;IAAM,OAAOlE,OAAOC;IAApB,UAAA,CACE,oBAAC,UAAD;KAAU,oBAAmB;KAAgB,OAAO6C;KAAS,cAAc6B;IAAW,CAAA,GACtF,oBAAC,QAAD;KACE,UAAUvB,QAAQN,QAAQb,KAAK,MAAM;KACrC,eAAe;MACboB,QAAQ,IAAI;MACZ,UAAe3E,WAAWE,QAAQkE,QAAQb,KAAK,GAAGpE,WAAWgH,OAAO,CAAC,CAClEG,MAAMZ,WAAW;OAChB,IAAI,WAAWA,QAAQrC,SAASqC,OAAOjE,KAAK;YACvC;QACHwE,WAAW,EAAE;QACb5C,SAASlC,KAAAA,CAAS;OACpB;MACF,CAAC,CAAC,CACDoF,OAAOrC,UAAmBb,SAASa,iBAAiBC,QAAQD,MAAME,UAAUC,OAAOH,KAAK,CAAC,CAAC,CAAC,CAC3FsC,cAAc7B,QAAQ,KAAK,CAAC;KACjC;KAAE,UAAA;IAGI,CAAA,CACJ;GACJ,CAAA,IAAA;GACHlD,QAAQ,oBAAC,MAAD;IAAM,OAAOH,OAAOG;IAAQA,UAAAA;GAAY,CAAA,IAAI;EACjD;;AAEV;AACA,SAASgF,iBAAiB,EACxBtH,WACAa,WACAE,QACAwG,MACAZ,wBAKC;CACD,MAAM,CAACc,cAAcC,mBAAmB9J,SAA2C;CACnF,MAAM,CAAC+J,OAAOC,YAAYhK,SAAiB;CAC3C,MAAM,CAACiK,QAAQC,aAAalK,SAAiB;CAC7C,MAAM,CAACmK,SAASC,cAAcpK,SAAS,IAAI;CAC3C,MAAM,CAACqK,MAAMC,WAAWtK,SAAS,IAAI;CACrC,MAAM,CAAC2H,MAAMC,WAAW5H,SAAS,KAAK;CACtC,MAAM,CAACuK,YAAYvK,eAAe,IAAIwK,gBAAgB,CAAC;CACvD3K,sBAAsB0K,SAASE,MAAM,GAAG,CAACF,QAAQ,CAAC;CAClD1K,gBAAgB;EACd,IAAIkK,UAAU3F,KAAAA,GAAW;EACzB,aAAa;GACX,eAAoBnB,WAAWE,QAAQ4G,OAAO3H,WAAWuH,IAAI,CAAC,CAACH,YAAY,CAAC,CAAC;EAC/E;CACF,GAAG;EAACvG;EAAWE;EAAQ4G;EAAO3H;EAAWuH;CAAI,CAAC;CAC9C,MAAMpD,UAAUzG,eACP;EACL4K,KAAK,GAAGtI,UAAS,GAAIa,UAAS,GAAIE,OAAM,GAAIwG,QAAQ;EACpDgB,MAAMtJ,mBAAmB,OAAOuJ,WAAW;GACzC,MAAMC,QAAQ,MAAMtJ,WAAW0B,WAAWE,QAAQf,WAAWuH,MAAMiB,MAAM;GACzE,IAAI,CAACA,OAAOE,WAAW,CAACP,SAASK,OAAOE,SAAShB,gBAAgBe,MAAMhB,YAAY;GACnF,OAAOgB;EACT,CAAC;EACDE,OAAO,OAAOC,SAAiB;GAC7B,IAAIjB,UAAU3F,KAAAA,GAAW,MAAM,IAAIgD,MAAM,2CAA2C;GACpF,MAAMuB,SAAS,MAAMjH,SAASuB,WAAWE,QAAQ4G,OAAOiB,MAAM5I,WAAWuH,IAAI;GAC7E,IAAIhB,OAAOjE,OAAO;IAChB,IAAI,CAAC6F,SAASK,OAAOE,SAAS;KAC5BZ,UAAUvB,OAAOjE,KAAK;KACtBsF,SAAS5F,KAAAA,CAAS;IACpB;IACA,MAAM,IAAIgD,MAAMuB,OAAOjE,KAAK;GAC9B;EACF;CACF,IACA;EAACtC;EAAWa;EAAWE;EAAQwG;EAAMI;EAAOQ;CAAQ,CACtD;CACA,MAAMU,MAAM,YAAY;EACtBrD,QAAQ,IAAI;EACZ,IAAI;GACF,MAAMsD,QAAQ,MAAMvJ,YAAYsB,WAAWE,QAAQiB,KAAAA,GAAWhC,WAAWuH,IAAI;GAC7E,IAAIY,SAASK,OAAOE,SAAS;IAC3B,IAAII,MAAMC,QAAQD,MAAMnB,OAAO,MAAMvI,eAAeyB,WAAWE,QAAQ+H,MAAMnB,OAAO3H,WAAWuH,IAAI;IACnG;GACF;GACA,IAAIuB,MAAMC,QAAQD,MAAMnB,OAAO;IAC7BC,SAASkB,MAAMnB,KAAK;IACpBG,UAAU9F,KAAAA,CAAS;GACrB,OAAO8F,UAAUgB,MAAME,UAAU,6CAA6C;EAChF,SAASjE,OAAO;GACd,IAAI,CAACoD,SAASK,OAAOE,SAASZ,UAAU/C,iBAAiBC,QAAQD,MAAME,UAAUC,OAAOH,KAAK,CAAC;EAChG,UAAU;GACR,IAAI,CAACoD,SAASK,OAAOE,SAASlD,QAAQ,KAAK;EAC7C;CACF;CACA,OACE,qBAAC,MAAD;EAAM,OAAOrD,OAAO8G;EAApB,UAAA;GACE,oBAAC,OAAD,EAAA,UAAQtB,QAAQ,mBAAmB,WAAkB,CAAA;GACpDF,cAAcyB,WACb,oBAAC,QAAD;IACE,SAAQ;IACR,UAAU3D;IACV,eAAe;KACb,IAAIoC,OAAOC,SAAS5F,KAAAA,CAAS;UACxB,IAAS;IAChB;IAEC2F,UAAAA,QAAQ,qBAAqB;GACxB,CAAA,IACN;GACJ,oBAAC,MAAD;IAAM,OAAOxF,OAAO8G;IAAatC,UAAAA,uBAAuBxC,OAAO;GAAQ,CAAA;GACtEsD,cAAcuB,SAAS,oBAAC,MAAD;IAAM,OAAO7G,OAAOY;IAAO0E,UAAAA,aAAauB;GAAa,CAAA,IAAI;GAChFrB,SAASF,cAAc0B,YACtB,qBAAC,MAAD,EAAA,UAAA;IACE,oBAAC,OAAD;KACE,oBAAmB;KACnB,cAAa;KACb,OAAOpB;KACP,cAAcC;IAAW,CAAA;IAE3B,oBAAC,OAAD;KAAO,oBAAmB;KAAgB,cAAa;KAAa,OAAOC;KAAM,cAAcC;IAAQ,CAAA;IACvG,oBAAC,QAAD;KACE,SAAQ;KACR,UACE,CAACkB,OAAOC,UAAUD,OAAOrB,OAAO,CAAC,KACjC,CAACqB,OAAOC,UAAUD,OAAOnB,IAAI,CAAC,KAC9BmB,OAAOrB,OAAO,IAAI,KAClBqB,OAAOnB,IAAI,IAAI;KAEjB,eAAe;MACb,UAAepH,WAAWE,QAAQ4G,OAAOyB,OAAOrB,OAAO,GAAGqB,OAAOnB,IAAI,GAAGjI,WAAWuH,IAAI,CAAC,CAACH,OACtFrC,UAAmB;OAClB,IAAI,CAACoD,SAASK,OAAOE,SAASZ,UAAU/C,iBAAiBC,QAAQD,MAAME,UAAUC,OAAOH,KAAK,CAAC;MAChG,CACF;KACF;KAAE,UAAA;IAGI,CAAA;GACJ,EAAA,CAAA,IACJ;GACH8C,SAAS,oBAAC,MAAD;IAAM,OAAO1F,OAAOY;IAAO8E,UAAAA;GAAa,CAAA,IAAI;EAClD;;AAEV;AACA,SAASyB,kBAAkBjI,OAAsD;CAC/E,MAAM,EAAEZ,KAAKT,WAAWmG,qBAAqB9E;CAC7C,MAAM,CAACkI,WAAWC,gBAAgB5L,SAAiB;CACnD,MAAM,CAAC6L,SAASC,cAAc9L,SAAoC;CAClE,MAAM,CAAC0E,OAAO4B,YAAYtG,SAAiB;CAC3CH,gBAAgB;EACd,IAAIkM,SAAS;EACb,eAAoBlJ,IAAII,WAAWJ,IAAIK,YAAYL,IAAIM,QAAQf,WAAWuJ,SAAS,CAAC,CACjFpC,MAAMZ,WAAW;GAChB,IAAIoD,QAAQ;IACV,IAAI,WAAWpD,QAAQrC,SAASqC,OAAOjE,KAAK;SACvC;KACHoH,WAAWnD,OAAOqD,SAAS;KAC3B1F,SAASlC,KAAAA,CAAS;IACpB;GACF;EACF,CAAC,CAAC,CACDoF,OAAOrC,UAAmB;GACzB,IAAI4E,QAAQzF,SAASa,iBAAiBC,QAAQD,MAAME,UAAUC,OAAOH,KAAK,CAAC;EAC7E,CAAC;EACH,aAAa;GACX4E,SAAS;EACX;CACF,GAAG;EAAClJ,IAAII;EAAWJ,IAAIM;EAAQN,IAAIK;EAAUd;EAAWuJ;EAAW9I,IAAIsF;CAAK,CAAC;CAC7E,OACE,qBAAC,MAAD,EAAA,UAAA;EACGzD,QAAQ,oBAAC,MAAD;GAAM,OAAOH,OAAOG;GAAQA,UAAAA;EAAY,CAAA,IAAI;EACpDiH,YACC,oBAAC,QAAD;GACE,SAAQ;GACR,eACEC,aAAaD,UAAUM,SAAS,GAAG,IAAIN,UAAUO,MAAM,GAAGP,UAAUQ,YAAY,GAAG,CAAC,IAAI/H,KAAAA,CAAS;GAClG,UAAA;EAGK,CAAA,IACN;EACHyH,SAASG,UAAUrH,KAAKT,SACvB,oBAAC,SAAD;GAEE,OACE,oBAAC,QAAD;IACE,SAAQ;IACR,UAAUA,KAAKmF,SAAS,eAAenF,KAAKvB,UAAU,aAAauB,KAAKvB,UAAU;IAClF,eAAe;KACb,IAAIuB,KAAKmF,SAAS,aAAauC,aAAa1H,KAAKC,IAAI;UAChD;MACH,MAAMlB,YAAYJ,IAAII;MACtB,MAAME,SAASN,IAAIK,YAAYL,IAAIM;MACnC,MAAMgB,OAAOD,KAAKC;MAClBoE,iBAAiB;OACfvF,IAAI,sBAAsBC,UAAS,GAAIE,OAAM,GAAIgB,OAAOf,QAAQ,YAAY,GAAG;OAC/EC,OAAOc;OACPX,QAAQ4I,eACN,oBAAC,iBAAD;QAAiB,GAAIA;QAAuBnJ;QAAmBE;QAAcgB;OAAK,CAAA;MAEtF,CAAC;KACH;IACF;IAECD,UAAAA,KAAKC;GACA,CAAA;GAEV,aAAa,GAAGD,KAAKvB,MAAK,KAAMuB,KAAKW;EAAc,GAxB9CX,KAAKC,IAwByC,CAEtD;CACG,EAAA,CAAA;AAEV;AACA,SAASkI,gBAAgB,EACvBjK,WACAa,WACAE,QACAgB,MACAmI,mBACAC,oBACAC,kBAC2E;CAC3E,MAAM,CAACC,SAASC,cAAc1M,SAA0C;CACxE,MAAM,CAAC0E,OAAO4B,YAAYtG,SAAiB;CAC3C,MAAM,CAAC2M,KAAKC,UAAU5M,SAAS,KAAK;CACpCH,gBAAgB;EACd,IAAIkM,SAAS;EACb,cAAmB9I,WAAWE,QAAQgB,MAAM/B,SAAS,CAAC,CACnDmH,MAAMZ,WAAW;GAChB,IAAIoD,QAAQ;IACV,IAAI,WAAWpD,QAAQrC,SAASqC,OAAOjE,KAAK;SACvCgI,WAAW/D,OAAOkE,QAAQ;GACjC;EACF,CAAC,CAAC,CACDrD,OAAOrC,UAAmB;GACzB,IAAI4E,QAAQzF,SAASa,iBAAiBC,QAAQD,MAAME,UAAUC,OAAOH,KAAK,CAAC;EAC7E,CAAC;EACH,aAAa;GACX4E,SAAS;EACX;CACF,GAAG;EAAC9I;EAAWE;EAAQgB;EAAM/B;CAAS,CAAC;CACvC,MAAM0K,qBAAqB/M,OAAoCqE,KAAAA,CAAS;CACxE,MAAM,CAAC2I,QAAQC,aAAahN,SAAS,KAAK;CAC1C,MAAM,CAACiN,UAAUC,eAAelN,SAAiB;CACjDH,sBAAsBiN,mBAAmBhG,SAAS2D,MAAM,GAAG;EAACxH;EAAWE;EAAQgB;EAAM/B;CAAS,CAAC;CAC/F,MAAM+K,WAAW,YAAY;EAC3B,IAAI,CAACX,kBAAkBO,QAAQ;EAC/B,MAAMK,aAAa,IAAI5C,gBAAgB;EACvCsC,mBAAmBhG,UAAUsG;EAC7BJ,UAAU,IAAI;EACd,IAAI;GACF,MAAMR,eAAe,MAAMpL,oBAAoB6B,WAAWE,QAAQgB,MAAM/B,WAAWgL,WAAWxC,MAAM,CAAC;GACrG,IAAI,CAACwC,WAAWxC,OAAOE,SAASoC,YAAY,QAAQ;EACtD,SAASxI,OAAO;GACd,IAAI,CAAC0I,WAAWxC,OAAOE,SAASoC,YAAYxI,iBAAiB0C,QAAQ1C,MAAM2C,UAAUC,OAAO5C,KAAK,CAAC;EACpG,UAAU;GACRsI,UAAU,KAAK;EACjB;CACF;CACA,OACE,qBAAC,YAAD;EAAY,uBAAuBzI,OAAOC;EAA1C,UAAA;GACE,oBAAC,MAAD;IAAM,OAAOD,OAAOyD;IAAQ7D,UAAAA;GAAW,CAAA;GACvC,oBAAC,QAAD;IAAQ,SAAQ;IAAU,UAAU,CAACqI,kBAAkBO;IAAQ,eAAe,KAAKI,SAAS;IAAE,UAAA;GAEtF,CAAA;GACPJ,SACC,oBAAC,QAAD;IAAQ,SAAQ;IAAQ,eAAeD,mBAAmBhG,SAAS2D,MAAM;IAAE,UAAA;GAEnE,CAAA,IACN;GACHwC,WAAW,oBAAC,MAAD;IAAM,OAAO1I,OAAOY;IAAO8H,UAAAA;GAAe,CAAA,IAAI;GACzDvI,QAAQ,oBAAC,MAAD;IAAM,OAAOH,OAAOG;IAAQA,UAAAA;GAAY,CAAA,IAAI;GACpD+H,SAASzB,SAAS5G,KAAAA,IACjB,qBAAA,UAAA,EAAA,UAAA;IACE,oBAAC,QAAD;KAAQ,SAAQ;KAAU,eAAewI,QAAQtH,UAAU,CAACA,KAAK;KAC9DqH,UAAAA,MAAM,YAAY;IACb,CAAA;IACP,CAACA,OAAO,oBAAoBU,KAAKlJ,IAAI,IACpC,oBAAC,UAAD,EAAU,MAAMsI,QAAQzB,KAAK,CAAA,IAC3B,CAAC2B,OAAO,iBAAiBU,KAAKlJ,IAAI,IACpCmI,oBAAoB;KAAE5B,KAAK,GAAGtI,UAAS,GAAIa,UAAS,GAAIE,OAAM,GAAIgB;KAAQmJ,MAAMb,QAAQzB;KAAMhD,OAAO7D;IAAK,CAAC,IACzG,CAACwI,OAAO,gBAAgBU,KAAKlJ,IAAI,IACnC,oBAAC,mBAAD;KAAmB,MAAMsI,QAAQzB;KAAM,WAAW,UAAUqC,KAAKlJ,IAAI,IAAI,MAAM;IAAK,CAAA,IAEpF,oBAAC,WAAD,EAAW,MAAM,CAACwI,OAAO,WAAWU,KAAKlJ,IAAI,IAAIoJ,WAAWd,QAAQzB,IAAI,IAAIyB,QAAQzB,KAAK,CAAA;IAE1FyB,QAAQe,YAAY,oBAAC,MAAD;KAAM,OAAOjJ,OAAOY;KAAM,UAAA;IAAiC,CAAA,IAAI;GACtF,EAAA,CAAA,IACEsH,UACF,oBAAC,uBAAD;IACarK;IACAa;IACHE;IACFgB;IACcoI;GAAmB,CAAA,IAGzC,oBAAC,MAAD;IAAM,OAAOhI,OAAOY;IAAM,UAAA;GAAsB,CAAA;EAExC;;AAEhB;AACA,SAASsI,sBAAsB,EAC7BrL,WACAa,WACAE,QACAgB,MACAoI,sBACqH;CACrH,MAAMmB,aAAaC,KAAKC,UAAU;EAACxL;EAAWa;EAAWE;EAAQgB;CAAI,CAAC;CACtE,MAAM,CAAC0J,QAAQC,aAAa9N,SAAsF;CAClH,MAAM+N,QAAQF,QAAQnD,QAAQgD,aAAaG,OAAOE,QAAQ3J,KAAAA;CAC1D,MAAMM,QAAQmJ,QAAQnD,QAAQgD,aAAaG,OAAOnJ,QAAQN,KAAAA;CAC1DvE,gBAAgB;EACd,MAAMuN,aAAa,IAAI5C,gBAAgB;EACvC,mBAAwBvH,WAAWE,QAAQgB,MAAM/B,WAAWgL,WAAWxC,MAAM,CAAC,CAC3ErB,MAAMjE,UAAU;GACf,IAAI,CAAC8H,WAAWxC,OAAOE,SAASgD,UAAU;IAAEpD,KAAKgD;IAAYK,OAAOzI;GAAM,CAAC;EAC7E,CAAC,CAAC,CACDkE,OAAOrC,UAAmB;GACzB,IAAI,CAACiG,WAAWxC,OAAOE,SACrBgD,UAAU;IAAEpD,KAAKgD;IAAYhJ,OAAOyC,iBAAiBC,QAAQD,MAAME,UAAUC,OAAOH,KAAK;GAAE,CAAC;EAChG,CAAC;EACH,aAAaiG,WAAW3C,MAAM;CAChC,GAAG;EAACxH;EAAWE;EAAQgB;EAAM/B;EAAWsL;CAAU,CAAC;CACnD,OAAOK,QACLxB,qBAAqB;EAAE7B,KAAK,GAAGtI,UAAS,GAAIa,UAAS,GAAIE,OAAM,GAAIgB;EAAQ,GAAG4J;EAAO/F,OAAO7D;EAAMA;CAAK,CAAC,IAExG,oBAAC,MAAD;EAAM,OAAOI,OAAOY;EAAOT,UAAAA,SAAS;CAAyB,CAAA;AAEjE;AACA,SAAS6I,WAAWvC,MAAsB;CACxC,IAAI;EACF,OAAO2C,KAAKC,UAAUD,KAAKO,MAAMlD,IAAI,GAAc,MAAM,CAAC;CAC5D,QAAQ;EACN,OAAOA;CACT;AACF;AACA,SAASmD,kBAAkB,EAAEnD,MAAMoD,aAAsD;CACvF,MAAM/D,OAAmB,CAAA;CACzB,IAAIgE,MAAgB,CAAA;CACpB,IAAIC,OAAO;CACX,IAAIC,SAAS;CACb,KAAK,IAAIC,QAAQ,GAAGA,SAASxD,KAAK9F,UAAUmF,KAAKnF,SAAS,KAAKsJ,SAAS,GAAG;EACzE,MAAMC,YAAYzD,KAAKwD,UAAU;EACjC,IAAID,QAAQ;GACV,IAAIE,cAAc,QAAOzD,KAAKwD,QAAQ,OAAO,MAAK;IAChDF,QAAQ;IACRE,SAAS;GACX,OAAO,IAAIC,cAAc,MAAKF,SAAS;QAClCD,QAAQG;EACf,OAAO,IAAIA,cAAc,QAAOH,SAAS,IAAIC,SAAS;OACjD,IAAIE,cAAcL,WAAW;GAChCC,IAAIK,KAAKJ,IAAI;GACbA,OAAO;EACT,OAAO,IAAIG,cAAc,MAAM;GAC7BJ,IAAIK,KAAKJ,KAAKlL,QAAQ,OAAO,EAAE,CAAC;GAChCiH,KAAKqE,KAAKL,GAAG;GACbA,MAAM,CAAA;GACNC,OAAO;EACT,OAAOA,QAAQG;CACjB;CACA,OACE,oBAAC,YAAD;EAAY,YAAA;EACV,UAAA,oBAAC,MAAD,EAAA,UACGpE,KAAK1F,KAAKgK,OAAOH,UAChB,oBAAC,MAAD;GAAkB,OAAOjK,OAAOqK;GAC7BD,UAAAA,MAAMhK,KAAKW,OAAOuJ,WACjB,oBAAC,MAAD;IAAmB,OAAOtK,OAAOuK;IAC9BxJ,UAAAA;GACG,GAFKuJ,MAEL,CACP;EACG,GANKL,KAML,CACP,EACG,CAAA;CACI,CAAA;AAEhB;AACA,MAAMjK,SAASrE,WAAW6O,QAAQC,WAAW;CAC3C1F,QAAQ;EAAE2F,MAAM;EAAGC,iBAAiBF,MAAMG,OAAOC;EAAIC,SAASL,MAAMM,QAAQ,CAAC;EAACC,mBAAA,CAAA,CAAA;CAAC;CAC/ElE,YAAY,EAAE4D,MAAM,EAAE;CACtBL,UAAU,EAAEY,eAAe,MAAM;CACjCV,WAAW;EACTW,OAAOT,MAAMG,OAAOnE;EACpB0E,UAAUV,MAAMU,SAASC;EACzBN,SAASL,MAAMM,QAAQ,CAAC;EACxBM,OAAOZ,MAAMM,QAAQ,EAAE;EACvBO,aAAa;EACbC,aAAad,MAAMG,OAAOY;EAAMR,mBAAA,CAAA,CAAA;CAClC;CACA/K,MAAM;EAAE6K,SAASL,MAAMM,QAAQ,CAAC;EAAGU,KAAKhB,MAAMM,QAAQ,CAAC;EAACC,mBAAA,CAAA,CAAA;CAAC;CACzDvH,OAAO;EAAEyH,OAAOT,MAAMG,OAAOc;EAAIP,UAAUV,MAAMU,SAASQ;EAAMC,YAAY;EAAKZ,mBAAA,CAAA,CAAA;CAAC;CAClFpK,MAAM;EAAEsK,OAAOT,MAAMG,OAAOiB;EAAKV,UAAUV,MAAMU,SAASC;EAAEJ,mBAAA,CAAA,CAAA;CAAC;CAC7D7K,OAAO;EAAE+K,OAAOT,MAAMG,OAAOkB;EAAKX,UAAUV,MAAMU,SAASC;EAAEJ,mBAAA,CAAA,CAAA;CAAC;AAChE,EAAE;;;ACpyBF,IAAA,0CAAe,WAAW,EAAE,WAAW,iBAAiB,CAAC;;;ACWzD,SAAgB4B,yBAAyB,EAAEC,WAAWC,aAAaC,oBAAwC;CACzG,MAAMC,QAAQX,aAAaQ,SAAS;CACpC,MAAM,CAACI,KAAKC,UAAUd,eAAee,KAAKF,IAAI,CAAC;CAC/C,MAAM,CAACG,QAAQC,aAAajB,SAA8D,CAAC,CAAC;CAC5FD,gBAAgB;EACd,MAAMqB,QAAQC,kBAAkBP,OAAOC,KAAKF,IAAI,CAAC,GAAG,GAAM;EAC1D,aAAaS,cAAcF,KAAK;CAClC,GAAG,CAAA,CAAE;CACL,MAAMG,SAASnB,uBAAuBC,qBAAqBO,MAAMY,MAAMX,KAAKJ,SAAS,CAAC;CACtF,OACE,qBAAC,MAAD,EAAA,UAAA,CACGc,OAAOE,KAAKC,UAAU;EACrB,MAAMC,OAAOX,OAAOU,MAAME,SAASF,MAAMG;EACzC,OACE,qBAAC,MAAD,EAAA,UAAA,CACE,qBAAC,QAAD;GACE,SAAQ;GACR,oBAAoB,EAAEC,UAAUH,KAAK;GACrC,eAAeV,WAAWc,aAAa;IAAE,GAAGA;KAAUL,MAAME,OAAO,CAACD;GAAK,EAAE;GAH7E,UAAA;IAKGD,MAAME;IAAK;IAAIF,MAAMM,KAAKC;GACrB;EACPN,CAAAA,GAAAA,OACGD,MAAMM,KAAKP,KAAKS,QACd,oBAAC,SAAD;GAEE,SACE,oBAAC,KAAD,EACE,MACEA,IAAIE,SAAS,WACT,QACAF,IAAIE,SAAS,aAAaF,IAAIE,SAAS,WACrC,WACAF,IAAIE,SAAS,SACX,UACA,QACT,CAAA;GAGL,OACE,oBAAC,QAAD;IACE,SAAQ;IACR,QAAQ,qBAAqBF,IAAIG;IACjC,eAAe;KACb,IAAIH,IAAII,kBAAkB5B,aAAa;MACrCA,YAAYwB,IAAII,cAAc;MAC9B;KACF;KACA,MAAMC,MAAM3B,MAAMY,KAAKgB,MACpBC,SAAS,GAAGA,KAAKC,UAAS,GAAID,KAAKE,YAAYF,KAAKJ,aAAaH,IAAIC,QACxE;KACA,IAAI1B,cAAc,MAAMF,SAASE,WAAWyB,IAAIC,QAAQ;KACxD,IAAII,KAAK5B,iBAAiBT,YAAYqC,GAAG,CAAC;IAC5C;IAECL,UAAAA,IAAIN;GACC,CAAA;GAEV,aAAa,GAAGM,IAAIU,OAAM,KAAMV,IAAIW;EAAU,GAjCzCX,IAAIC,QAiCqC,CAEjD,IACD,IACA,EAAA,GAhDKT,MAAME,IAgDX;CAEV,CAAC,GACAL,OAAOU,WAAW,IACjB,oBAAC,QAAD;EACE,SAAQ;EACR,QAAO;EACP,UAAUxB,cAAc;EACxB,eAAe;GACb,IAAIA,cAAc,MAAMN,YAAYM,SAAS;EAC/C;EAAE,UAAA;CAGI,CAAA,IACN,IACA,EAAA,CAAA;AAEV;;;AC1FA,IAAA,8CAAe,WAAW,EAAE,WAAW,yBAAyB,CAAC;;;ACOjE,MAAM,OAAU,UAAmC,UAChD,UAAU,KAAA,IAAY,KAAA,IAAY;CAAE,GAAG;CAAU,GAAI;AAAiB;AAEzE,MAAa,eAAe,mBAAmB;CAC7C,IAAI;CACJ,WAAW,EACT,IAAI,QAAyC;EAAE,OAAO,CAAC,IAAI;GAAE,MAAM;GAAQ,IAAI;EAAY,GAAGqC,6BAAa,CAAC;CAAG,EACjH;CACA,SAAS;EACP,IAAI,iBAA2D;GAAE,OAAO,CAAC,IAAI,EAAE,MAAM,YAAY,GAAGC,wBAAsB,CAAC;EAAG;EAC9H,IAAI,WAA+C;GAAE,OAAO,CAAC,IAAI,EAAE,SAAS,mBAAmB,GAAGC,+BAAsB,GAAG,IAAI,EAAE,SAAS,gBAAgB,GAAGC,4BAAmB,CAAC;EAAG;EACpL,IAAI,QAAyC;GAAE,OAAO,CAAC,IAAI;IAAE,MAAM;IAAW,IAAI;GAAoB,GAAGC,uCAAoB,GAAG,IAAI;IAAE,MAAM;IAAsB,IAAI;GAAY,GAAGC,2CAAc,CAAC;EAAG;CACzM;AACF,CAAC"}
1
+ {"version":3,"file":"native.mjs","names":["isRecord","isRecord","WebPluginSlotProps","Badge","Button","CodeBlock","Input","ListRow","Markdown","Sheet","SheetBody","SheetContent","SheetHeader","SheetTitle","Textarea","useCallback","useEffect","useMemo","useRef","useState","useSyncExternalStore","StyleSheet","WorkflowCatalogEntryView","WorkflowRunView","WorkflowArtifactContentResponse","WorkflowArtifactsResponse","WorkflowTerminalCapabilitiesView","catalog","closeCatalog","filterCatalog","initialChoice","initialCommand","initialInputs","initialRunner","launchProblems","workflowLaunchLine","deleteWorkflowRun","fetchArtifact","fetchArtifactMedia","prepareArtifactSave","finiteScreenReader","fetchArtifacts","readScreen","releaseControl","resizeRun","sendKeys","takeControl","steerStep","stopWorkflowRun","workflowRunIdentity","focusRun","removeRun","requestLaunch","workflows","useWorkflows","sessionId","subscribe","listener","sub","store","unsubscribe","select","state","workflowTab","run","Parameters","identity","id","workspace","routeKey","runKey","replace","label","displayName","retainComposer","panel","props","WorkflowLauncher","filter","setFilter","selected","setSelected","open","workflow","find","item","path","undefined","name","prompt","styles","body","warning","error","map","relativePath","description","tags","join","jobs","job","length","meta","Choice","options","value","onChange","option","WorkflowLaunch","initialPrompt","sendSessionFrame","onClose","setPrompt","inputs","setInputs","runner","setRunner","command","setCommand","choice","setChoice","setError","request","trim","problems","line","input","type","required","current","runners","commands","choices","problem","cause","Error","message","String","WorkflowPanel","runs","confirmDelete","setConfirmDelete","busy","setBusy","act","action","Promise","title","executionState","outcome","stage","errorMessage","position","step","openTransientTab","stepTab","status","steps","result","closeTransientTab","WorkflowStep","renderSessionTranscript","renderRunnerTerminal","target","at","setMessage","ref","session","kind","screen","then","catch","finally","WorkflowTerminal","pane","Pick","capabilities","setCapabilities","token","setToken","notice","setNotice","columns","setColumns","rows","setRows","lifetime","AbortController","abort","key","read","signal","frame","aborted","write","text","arm","grant","held","reason","transcript","writable","resizable","Number","isInteger","WorkflowArtifacts","directory","setDirectory","listing","setListing","active","artifacts","includes","slice","lastIndexOf","panelProps","ArtifactPreview","renderFilePreview","renderMediaPreview","nativeSaveFile","content","setContent","raw","setRaw","artifact","downloadController","saving","setSaving","saveNote","setSaveNote","download","controller","test","html","prettyJson","truncated","BinaryArtifactPreview","requestKey","JSON","stringify","loaded","setLoaded","media","data","mimeType","parse","DelimitedArtifact","delimiter","row","cell","quoted","index","character","push","cells","tableRow","column","tableCell","create","theme","flex","backgroundColor","colors","bg","padding","spacing","uni__dependencies","flexDirection","color","fontSize","sm","width","borderWidth","borderColor","border","gap","hi","base","fontWeight","dim","red","styles","WebPluginSlotProps","ArrowRightIcon","Button","Dot","fontOf","ListRow","PoNativeTheme","useEffect","useState","StyleSheet","useWorkflows","workflowTab","openCatalog","workflowActivityGroups","workflowActivityRows","WorkflowActivityGroupName","focusRun","WorkflowsActivitySection","sessionId","openSession","openTransientTab","state","now","setNow","Date","folded","setFolded","Partial","Record","timer","setInterval","clearInterval","groups","runs","map","group","open","name","openByDefault","expanded","current","rows","length","row","identity","tone","runKey","ownerSessionId","run","find","item","workspace","routeKey","detail","elapsed","styles","idle","status","disabled","action","actionText","create","theme","flexDirection","alignItems","flexWrap","gap","spacing","uni__dependencies","fontFamily","sans","fontSize","sm","lineHeight","color","colors","dim","base","fontWeight","medium","green","fillWorkflows","activityGroupWorkflows","channelWorkflowCatalog","channelWorkflowRuns","fillWorkflowLauncher","fillWorkflows2"],"sources":["../../src/extensions/workspaces/(frontend)/fill/Workflows.home.native.ts","../../src/types/webWorkflows.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/runDuration.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/workflowActivity.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/workflowsStore.native.ts","../../src/extensions/workspaces/sessions/(frontend)/activity-group/workflows.native.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/catalogStore.native.ts","../../src/extensions/workspaces/sessions/(frontend)/channel/workflow-catalog.native.ts","../../src/extensions/workspaces/sessions/(frontend)/channel/workflow-runs.native.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/launchLine.ts","../../src/types/apiRoutes.ts","../../generated/client.native.ts","../../src/extensions/workspaces/sessions/(frontend)/_lib/terminalApi.native.ts","../../src/extensions/workspaces/sessions/(frontend)/_components/WorkflowPanel.native.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/WorkflowLauncher.overlay.native.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/_components/WorkflowsActivitySection.native.tsx","../../src/extensions/workspaces/sessions/(frontend)/fill/Workflows.activity.workflows.native.tsx","../../generated/native.ts"],"sourcesContent":["import { defineFill } from '@agimon-ai/po-core/native';\n\nexport default defineFill({\n data: { version: 1, label: 'Workflows', source: 'workflow_runs', destination: 'workflows' },\n});\n","/**\n * Workflow run view types shared by this package's hub channel and its web\n * plugin. The shapes mirror what the embedded workflow-mcp engine records;\n * the cockpit renders them as 'workflow_runs' channel payloads.\n */\n\n/** workflow-mcp's own stage vocabulary; the registry bucket a run record sits in. */\nexport type WorkflowStage = 'running' | 'completed' | 'error';\n\n/** workflow-mcp's terminal outcome for a finished run. */\nexport type WorkflowOutcome = 'success' | 'skipped' | 'failed' | 'interrupted';\n\n/** Recorded job/step states, plus pending entries from the workflow definition. */\nexport type WorkflowProgressState =\n | 'pending'\n | 'running'\n | 'completed'\n | 'skipped'\n | 'failed'\n | 'pause_requested'\n | 'paused'\n | 'resumed';\n\n/** A customRun step ran as this child session. */\nexport const STEP_SESSION_REF_KIND = 'session';\n/** A command step ran in this terminal pane. */\nexport const STEP_PANE_REF_KIND = 'pane';\n\n/** Where a host executor ran a step: `session` for a customRun agent, `pane` for a command. */\nexport interface WorkflowStepRefView {\n kind: string;\n id: string;\n label?: string;\n}\n\nexport interface WorkflowStepView {\n name: string;\n status: WorkflowProgressState;\n /** Kept after the step ends, so a finished agent step still opens its conversation. */\n ref?: WorkflowStepRefView;\n /** Why the step is in its state, when the engine recorded one (e.g. a skip condition). */\n reason?: string;\n /** The parallel group the step ran in, beside the group's other steps. */\n group?: string;\n /** ISO 8601 of the step's first running event. */\n startedAt?: string;\n /** ISO 8601 of the step's terminal event. */\n endedAt?: string;\n}\n\n/** 'pre' and 'post' are the engine's pseudo-jobs for its pre:/post: blocks. */\nexport type WorkflowJobPhase = 'pre' | 'job' | 'post';\n\nexport interface WorkflowJobView {\n name: string;\n phase: WorkflowJobPhase;\n status: WorkflowProgressState;\n reason?: string;\n /** Position among the run's jobs, when the engine recorded one. */\n index?: number;\n total?: number;\n startedAt?: string;\n endedAt?: string;\n steps: WorkflowStepView[];\n}\n\n/** The job and step a run is on right now; drives the NOW breadcrumb. */\nexport interface WorkflowPosition {\n job: string;\n step?: string;\n index?: number;\n total?: number;\n}\n\n/**\n * One workflow run of a session, read from workflow-mcp's registry: the\n * run.json record plus the folded progress.ndjson job tree.\n */\nexport interface WorkflowRunView {\n /** Opaque owner-qualified API/cache key. The displayed engine runKey stays unchanged. */\n routeKey?: string;\n /** Engine generation identity, distinct from a reused run key. */\n runId?: string;\n /** Registry identity within its workspace; unique per workspace+stage. */\n runKey: string;\n workspace: string;\n displayName: string;\n workflowName?: string;\n workflowPath: string;\n stage: WorkflowStage;\n outcome?: WorkflowOutcome;\n /** Present while the engine is pausing or paused; absent for plain running. */\n executionState?: 'running' | 'pause_requested' | 'paused' | 'resume_requested';\n /** The prompt the run was launched with, when one was recorded. */\n prompt?: string;\n /** ISO 8601, from the run record. */\n startedAt: string;\n finishedAt?: string;\n /** Failure cause with ANSI escapes stripped, present when the run errored. */\n errorMessage?: string;\n /** The job the engine blamed for the failure, when it recorded one. */\n failedJob?: string;\n /** True when reconciliation decided the recorded pid is no longer alive. */\n stale?: boolean;\n staleReason?: string;\n worktreeBranch?: string;\n /** The session that owns the run (its PI_SESSION_ID); absent on records that carry none. */\n ownerSessionId?: string;\n /** The session that launched the run into its own workflow session, when it was handed off. */\n launcherSessionId?: string;\n position?: WorkflowPosition;\n jobs: WorkflowJobView[];\n}\n\n/** What the workflow runs channel publishes for one session. */\nexport interface WorkflowRunsPayload {\n runs: WorkflowRunView[];\n}\n\nexport const WORKFLOW_RUNS_TYPE = 'workflow_runs';\n\n/**\n * One workflow the session's directory can launch, as the catalog drawer\n * lists it: the engine's own catalog entry plus the parsed detail the drawer\n * unfolds and the launch dialog turns into fields.\n */\nexport interface WorkflowCatalogEntryView {\n /** Absolute path, the row's stable identity. */\n path: string;\n relativePath: string;\n name: string;\n description: string;\n tags: string[];\n /** The trigger names the file declares, such as workflow_dispatch. */\n triggers: string[];\n inputs: WorkflowCatalogInputView[];\n jobs: WorkflowCatalogJobView[];\n artifacts: WorkflowCatalogArtifactView[];\n /** Absent when the workflow names no runner map, which means any runner will do. */\n runners?: string[];\n /** Commands every templated step offers; absent when no step is templated. */\n commands?: string[];\n /** Declared model choices; `default` is used when a launch names none. */\n choices?: string[];\n /** Set when the file could not be parsed; the row shows this instead of guessing. */\n error?: string;\n}\n\nexport interface WorkflowCatalogInputView {\n name: string;\n description?: string;\n required?: boolean;\n default?: string;\n type?: string;\n options?: string[];\n}\n\nexport interface WorkflowCatalogJobView {\n name: string;\n steps: string[];\n}\n\nexport interface WorkflowCatalogArtifactView {\n path: string;\n kind: 'file' | 'directory';\n description: string;\n producedBy: string[];\n}\n\n/** What the catalog channel publishes for one session. */\nexport interface WorkflowCatalogPayload {\n /** The directory the catalog was read from, which is the session's own. */\n cwd: string;\n workflows: WorkflowCatalogEntryView[];\n /** Present when the directory could not be read at all. */\n warning?: string;\n}\n\nexport const WORKFLOW_CATALOG_TYPE = 'workflow_catalog';\n\nexport interface WorkflowInputSummary {\n name: string;\n description?: string;\n required?: boolean;\n default?: string;\n options?: readonly string[];\n}\n\nexport interface WorkflowJobSummary {\n name: string;\n steps: readonly string[];\n}\n\n/**\n * What the detail pane shows for one workflow. `runners` is undefined when the\n * workflow names no runner map at all, which is not the same as naming an empty\n * one - see `compatibleRunners`.\n */\nexport interface WorkflowCatalogDetail {\n triggers: readonly string[];\n inputs: readonly WorkflowInputSummary[];\n jobs: readonly WorkflowJobSummary[];\n runners?: readonly string[];\n /** Commands every templated step offers; absent when no step is templated. */\n commands?: readonly string[];\n /** Declared model choices. */\n choices?: readonly string[];\n /** Set when the file could not be parsed; the pane shows this instead of guessing. */\n error?: string;\n}\n","/**\n * Local copy of the host's formatRunDuration (src/web/lib/sessionSummary.ts):\n * this plugin keeps zero host-lib imports so its later move into the owning\n * package is a file relocation.\n */\nconst MINUTE_MS = 60 * 1000;\nconst HOUR_MS = 60 * MINUTE_MS;\n\nexport function formatRunDuration(elapsedMs: number): string {\n if (elapsedMs < MINUTE_MS) return '<1m';\n if (elapsedMs < HOUR_MS) return `${Math.floor(elapsedMs / MINUTE_MS)}m`;\n const hours = Math.floor(elapsedMs / HOUR_MS);\n const minutes = Math.floor((elapsedMs % HOUR_MS) / MINUTE_MS);\n return `${hours}h ${String(minutes).padStart(2, '0')}m`;\n}\n","import type { WorkflowRunView } from '../../../../../types/webWorkflows';\nimport { formatRunDuration } from './runDuration';\n\nexport type WorkflowActivityTone = 'running' | 'paused' | 'failed' | 'done' | 'skipped';\n\n/** One run as the activity dock lists it: identity, a tone, and a one-liner. */\nexport interface WorkflowActivityRow {\n /** Registry identity: workspace/runKey, unique across the session's runs. */\n identity: string;\n runKey: string;\n name: string;\n tone: WorkflowActivityTone;\n elapsed: string;\n /** Where the run is right now, or how it ended. */\n detail: string;\n /** The workflow session that owns the run, when it is not the session listing it. */\n ownerSessionId?: string;\n}\n\nconst PAUSED_STATES: ReadonlySet<NonNullable<WorkflowRunView['executionState']>> = new Set([\n 'paused',\n 'pause_requested',\n]);\n\nexport function workflowRunIdentity(run: Pick<WorkflowRunView, 'workspace' | 'runKey' | 'routeKey'>): string {\n return `${run.workspace}/${run.routeKey ?? run.runKey}`;\n}\n\n/** Whether the session runs this workflow itself; a record from an older hub names no owner and means the viewer. */\nexport function ownsRun(run: Pick<WorkflowRunView, 'ownerSessionId'>, sessionId: string | null): boolean {\n return sessionId !== null && (run.ownerSessionId ?? sessionId) === sessionId;\n}\n\nfunction toneOf(run: WorkflowRunView): WorkflowActivityTone {\n if (run.stage === 'running') {\n return run.executionState !== undefined && PAUSED_STATES.has(run.executionState) ? 'paused' : 'running';\n }\n if (run.stage === 'error') return 'failed';\n if (run.outcome !== undefined && run.outcome !== 'success') return run.outcome === 'failed' ? 'failed' : 'skipped';\n return 'done';\n}\n\nfunction detailOf(run: WorkflowRunView, tone: WorkflowActivityTone): string {\n if (tone === 'paused') return 'paused; resume it from the owning session';\n if (tone === 'failed')\n return run.errorMessage ?? (run.failedJob === undefined ? 'failed' : `job '${run.failedJob}' failed`);\n if (tone === 'running') {\n if (run.position === undefined) return 'starting';\n return run.position.step === undefined ? run.position.job : `${run.position.job} · ${run.position.step}`;\n }\n return run.outcome ?? 'done';\n}\n\nfunction elapsedOf(run: WorkflowRunView, now: number): string {\n const start = Date.parse(run.startedAt);\n if (!Number.isFinite(start)) return '';\n const end = run.finishedAt === undefined ? now : Date.parse(run.finishedAt);\n return formatRunDuration(Math.max(0, (Number.isFinite(end) ? end : now) - start));\n}\n\n/** The hub's presented order is kept: it already puts live runs first. */\nexport function workflowActivityRows(\n runs: readonly WorkflowRunView[],\n now: number,\n sessionId: string | null = null,\n): WorkflowActivityRow[] {\n return runs.map((run) => {\n const tone = toneOf(run);\n return {\n identity: workflowRunIdentity(run),\n runKey: run.runKey,\n name: run.displayName,\n tone,\n elapsed: elapsedOf(run, now),\n detail: detailOf(run, tone),\n ...(run.ownerSessionId === undefined || run.ownerSessionId === sessionId\n ? {}\n : { ownerSessionId: run.ownerSessionId }),\n };\n });\n}\n\n/** The three answers a reader wants from the dock: what is live, what broke, what is done. */\nexport type WorkflowActivityGroupName = 'running' | 'failed' | 'successful';\n\nexport interface WorkflowActivityGroup {\n name: WorkflowActivityGroupName;\n rows: WorkflowActivityRow[];\n /**\n * Whether the group is open when the dock first draws it.\n *\n * Failures open because they are the only ones that need an answer, and a\n * folded failure is one nobody sees. Everything else stays folded so a\n * session's whole history does not push the other groups off the dock.\n */\n openByDefault: boolean;\n}\n\nconst GROUP_OF: Readonly<Record<WorkflowActivityTone, WorkflowActivityGroupName>> = {\n running: 'running',\n paused: 'running',\n failed: 'failed',\n done: 'successful',\n skipped: 'successful',\n};\n\nconst GROUP_ORDER: readonly WorkflowActivityGroupName[] = ['running', 'failed', 'successful'];\n\n/** Rows split by outcome, in the order the dock shows them; empty groups are dropped. */\nexport function workflowActivityGroups(rows: readonly WorkflowActivityRow[]): WorkflowActivityGroup[] {\n return GROUP_ORDER.map((name) => ({\n name,\n rows: rows.filter((row) => GROUP_OF[row.tone] === name),\n openByDefault: name !== 'successful',\n })).filter((group) => group.rows.length > 0);\n}\n","import type { SessionFrameSender } from '@agimon-ai/po-core/native';\nimport { defineSessionStore } from '@agimon-ai/po-core/native';\n\nimport { WORKFLOW_RUNS_TYPE, type WorkflowRunView } from '../../../../../types/webWorkflows';\nimport { workflowRunIdentity } from './workflowActivity';\n\n/** One session's record: the hub's last report plus the run this page is looking at. */\nexport interface WorkflowsSession {\n /** The workflow runs the hub last reported; presented order preserved. */\n runs: WorkflowRunView[];\n /** The run (workspace/runKey) the workflows tab shows; the first run until someone picks. */\n focusedRun: string | undefined;\n /**\n * A launch that was sent and has not shown up yet.\n *\n * The line goes to the session, the run appears on the registry channel some\n * seconds later, and nothing connects the two but timing: the first run this\n * session did not already have is the one that was just asked for.\n */\n pendingLaunch: { workflowPath: string; knownRuns: string[] } | undefined;\n}\n\nexport const workflows = defineSessionStore<WorkflowsSession>({\n runs: [],\n focusedRun: undefined,\n pendingLaunch: undefined,\n});\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** Points the workflows tab at one run; the activity dock uses this before opening the tab. */\nexport function focusRun(sessionId: string, identity: string | undefined): void {\n workflows.update(sessionId, (current) => ({ ...current, focusedRun: identity }));\n}\n\n/** Removes a deleted run immediately while the registry channel catches up. */\nexport function removeRun(sessionId: string, identity: string): void {\n workflows.update(sessionId, (current) => {\n const runs = current.runs.filter((run) => workflowRunIdentity(run) !== identity);\n return {\n ...current,\n runs,\n focusedRun:\n current.focusedRun === identity\n ? runs[0] === undefined\n ? undefined\n : workflowRunIdentity(runs[0])\n : current.focusedRun,\n };\n });\n}\n\n/**\n * Sends a launch line to the session and remembers what was already running.\n *\n * The cockpit's only channel to a session is a prompt frame, so a launch is\n * the verb the extension registers for exactly this; see web/launchLine.ts.\n */\nexport function requestLaunch(send: SessionFrameSender, sessionId: string, line: string, workflowPath: string): void {\n send(sessionId, { type: 'prompt', message: line });\n workflows.update(sessionId, (current) => ({\n ...current,\n pendingLaunch: { workflowPath, knownRuns: current.runs.map(workflowRunIdentity) },\n }));\n}\n\nexport interface WorkflowRunsPayload {\n runs: WorkflowRunView[];\n}\n\n/** The plugin's session data channel: 'workflow_runs' payloads into the store. */\nexport const workflowRunsChannel = workflows.channel<WorkflowRunsPayload>({\n channel: WORKFLOW_RUNS_TYPE,\n parse(input) {\n if (!isRecord(input) || !Array.isArray(input.runs)) return null;\n return { runs: input.runs.filter(isRecord) as unknown as WorkflowRunView[] };\n },\n reduce: (current, { runs }) => {\n const pending = current.pendingLaunch;\n if (pending === undefined) return { ...current, runs };\n const known = new Set(pending.knownRuns);\n const arrived = runs.find((run) => !known.has(workflowRunIdentity(run)));\n // Until one arrives the launch stays pending: a workflow can take a while\n // to reach the registry, and forgetting it would leave the board wherever\n // the reader last was.\n if (arrived === undefined) return { ...current, runs };\n return { ...current, runs, focusedRun: workflowRunIdentity(arrived), pendingLaunch: undefined };\n },\n});\n","import { defineActivityGroup } from '@agimon-ai/po-core/native';\nimport { WorkflowIcon } from '@agimon-ai/po-native-components';\nimport { createElement } from 'react';\n\nimport { workflows } from '../_lib/workflowsStore.native';\nexport default defineActivityGroup({\n keys: 'w r',\n icon: () => createElement(WorkflowIcon),\n widgetKeys: ['workflow-mcp-progress', 'workflow-mcp-follow'],\n order: 30,\n activeSource: {\n subscribe(listener) {\n const subscription = workflows.store.subscribe(listener);\n return () => subscription.unsubscribe();\n },\n isActive(sessionId) {\n return workflows.select(workflows.store.state, sessionId).runs.some((run) => run.stage === 'running');\n },\n },\n});\n","import { defineSessionStore } from '@agimon-ai/po-core/native';\n\nimport {\n WORKFLOW_CATALOG_TYPE,\n type WorkflowCatalogEntryView,\n type WorkflowCatalogPayload,\n} from '../../../../../types/webWorkflows';\n\n/** One session's catalog: what the hub last reported plus what the drawer is doing with it. */\nexport interface CatalogSession {\n cwd: string;\n workflows: WorkflowCatalogEntryView[];\n warning: string | undefined;\n /** True while the catalog drawer is shown in the workflows tab. */\n open: boolean;\n filter: string;\n /** Prompt carried from the surface that opened the catalog. */\n prompt: string;\n /** The highlighted row, by workflow path. */\n selected: string | undefined;\n /** The row whose parsed detail is unfolded. */\n inspected: string | undefined;\n /** The workflow the launch dialog is open for. */\n launch: string | undefined;\n}\n\nexport const catalog = defineSessionStore<CatalogSession>({\n cwd: '',\n workflows: [],\n warning: undefined,\n open: false,\n filter: '',\n prompt: '',\n selected: undefined,\n inspected: undefined,\n launch: undefined,\n});\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport function openCatalog(sessionId: string, prompt = ''): void {\n catalog.update(sessionId, (current) => ({ ...current, open: true, prompt }));\n}\n\nexport function closeCatalog(sessionId: string): void {\n catalog.update(sessionId, (current) => ({ ...current, open: false, prompt: '', launch: undefined }));\n}\n\nexport function setCatalogFilter(sessionId: string, filter: string): void {\n catalog.update(sessionId, (current) => ({ ...current, filter }));\n}\n\nexport function selectWorkflow(sessionId: string, path: string | undefined): void {\n catalog.update(sessionId, (current) => ({ ...current, selected: path }));\n}\n\nexport function toggleInspect(sessionId: string, path: string): void {\n catalog.update(sessionId, (current) => ({ ...current, inspected: current.inspected === path ? undefined : path }));\n}\n\nexport function openLaunch(sessionId: string, path: string): void {\n catalog.update(sessionId, (current) => ({ ...current, selected: path, launch: path }));\n}\n\nexport function closeLaunch(sessionId: string): void {\n catalog.update(sessionId, (current) => ({ ...current, launch: undefined }));\n}\n\n/** Rows whose name, path, tag or job matches the filter, case-insensitively. */\nexport function filterCatalog(\n workflows: readonly WorkflowCatalogEntryView[],\n filter: string,\n): WorkflowCatalogEntryView[] {\n const needle = filter.trim().toLowerCase();\n if (needle === '') return [...workflows];\n return workflows.filter((workflow) =>\n [\n workflow.name,\n workflow.relativePath,\n workflow.description,\n ...workflow.tags,\n ...workflow.jobs.map((job) => job.name),\n ]\n .join('\\n')\n .toLowerCase()\n .includes(needle),\n );\n}\n\n/** The plugin's catalog channel: 'workflow_catalog' payloads into the store. */\nexport const workflowCatalogChannel = catalog.channel<WorkflowCatalogPayload>({\n channel: WORKFLOW_CATALOG_TYPE,\n parse(input) {\n if (!isRecord(input) || typeof input.cwd !== 'string' || !Array.isArray(input.workflows)) return null;\n return {\n cwd: input.cwd,\n workflows: input.workflows.filter(isRecord) as unknown as WorkflowCatalogEntryView[],\n ...(typeof input.warning === 'string' ? { warning: input.warning } : {}),\n };\n },\n reduce(current, payload) {\n const paths = new Set(payload.workflows.map((workflow) => workflow.path));\n return {\n ...current,\n cwd: payload.cwd,\n workflows: payload.workflows,\n warning: payload.warning,\n // A row that is gone cannot stay selected, inspected, or half-launched.\n selected: current.selected !== undefined && paths.has(current.selected) ? current.selected : undefined,\n inspected: current.inspected !== undefined && paths.has(current.inspected) ? current.inspected : undefined,\n launch: current.launch !== undefined && paths.has(current.launch) ? current.launch : undefined,\n };\n },\n});\n","import { defineChannelFile } from '@agimon-ai/po-core/native';\n\nimport { workflowCatalogChannel } from '../_lib/catalogStore.native';\nexport default defineChannelFile(workflowCatalogChannel);\n","import { defineChannelFile } from '@agimon-ai/po-core/native';\n\nimport { workflowRunsChannel } from '../_lib/workflowsStore.native';\nexport default defineChannelFile(workflowRunsChannel);\n","import type { WorkflowCatalogEntryView } from '../../../../../types/webWorkflows';\n\n/**\n * The `/workflow-launch` line the dialog sends.\n *\n * WHY THE BUILDER LIVES HERE AND THE PARSER DOES NOT:\n * Cockpit code is compiled into the host bundle and may import only this\n * package's own web and type modules, so it cannot share the session's parser.\n * The two are pinned together by a test that parses what this writes, which is\n * the only guarantee that matters: the line has to survive the trip.\n */\n\nexport const WORKFLOW_LAUNCH_VERB = '/workflow-launch';\n/** Reserved keys; every other pair is one of the workflow's own inputs. */\nexport const RUNNER_KEY = 'runner';\nexport const COMMAND_KEY = 'command';\nexport const CHOICE_KEY = 'choice';\n\nexport interface WorkflowLaunchRequest {\n workflow: string;\n runner?: string;\n command?: string;\n choice?: string;\n inputs: Record<string, string>;\n prompt?: string;\n}\n\n/** Quotes a value that carries whitespace, which is how a value survives tokenizing. */\nfunction quote(value: string): string {\n return /\\s/.test(value) ? `\"${value}\"` : value;\n}\n\nfunction reservedPair(key: string, value: string | undefined): string[] {\n return value === undefined || value === '' ? [] : [`${key}=${quote(value)}`];\n}\n\nexport function workflowLaunchLine(request: WorkflowLaunchRequest): string {\n const pairs = [\n ...reservedPair(RUNNER_KEY, request.runner),\n ...reservedPair(COMMAND_KEY, request.command),\n ...reservedPair(CHOICE_KEY, request.choice),\n ...Object.entries(request.inputs)\n .filter(([, value]) => value !== '')\n .map(([key, value]) => `${key}=${quote(value)}`),\n ];\n const prompt = request.prompt?.trim();\n return [WORKFLOW_LAUNCH_VERB, quote(request.workflow), ...pairs, ...(prompt ? [prompt] : [])].join(' ');\n}\n\n/** The trigger that makes a prompt mandatory. */\nconst USER_PROMPT_TRIGGER = 'user_prompt';\n\n/** What the dialog will not let a reader send, worded the way the session would answer. */\nexport function launchProblems(workflow: WorkflowCatalogEntryView, request: WorkflowLaunchRequest): string[] {\n const problems: string[] = [];\n if (workflow.triggers.includes(USER_PROMPT_TRIGGER) && (request.prompt ?? '').trim() === '') {\n problems.push('This workflow is triggered by a prompt, so it needs one.');\n }\n const missing = workflow.inputs\n .filter((input) => input.required === true && (request.inputs[input.name] ?? '') === '')\n .map((input) => input.name);\n if (missing.length > 0) {\n problems.push(`Missing required input${missing.length > 1 ? 's' : ''}: ${missing.join(', ')}.`);\n }\n return problems;\n}\n\n/** The default a field starts with: what the workflow declared, or empty. */\nexport function initialInputs(workflow: WorkflowCatalogEntryView): Record<string, string> {\n return Object.fromEntries(workflow.inputs.map((input) => [input.name, input.default ?? '']));\n}\n\n/** The runner a launch starts on: the workflow's first declared one, when it declares any. */\nexport function initialRunner(workflow: WorkflowCatalogEntryView): string | undefined {\n return workflow.runners?.[0];\n}\n\n/** The command templated steps start on: the one their steps list first. */\nexport function initialCommand(workflow: WorkflowCatalogEntryView): string | undefined {\n return workflow.commands?.[0];\n}\n\n/** The choice a launch starts on: `default` when declared, else the first. */\nexport function initialChoice(workflow: WorkflowCatalogEntryView): string | undefined {\n const choices = workflow.choices ?? [];\n return choices.includes('default') ? 'default' : choices[0];\n}\n","import type { ApiResponseOf, ApiRoutes } from '@agimon-ai/po-core/web';\n\nimport type {\n WorkflowArtifactContentResponse,\n WorkflowArtifactsResponse,\n WorkflowControlResponse,\n WorkflowDeleteResponse,\n WorkflowLaunchResponse,\n WorkflowOpenRunDirectoryResponse,\n WorkflowSteerResponse,\n WorkflowStopResponse,\n WorkflowScreenEvent,\n} from './webWorkflowTerminal';\n\n/**\n * This package's routes, as data.\n *\n * No scope and no base path. The build reads both off\n * `src/extensions/(backend)/api/workflow/`, so the mount is stated once, by the\n * folder that creates it. The same API answers at all three scopes, because a\n * global contribution cascades into workspace and session; the folder under\n * `workspaces/sessions/` only re-mounts it for a session's own server.\n *\n * This is the one file the routes, the Hono app and the browser all read, so a\n * path cannot move on one side alone. The page used to build the hub's own\n * absolute URL and then rewrite its plugin prefix with String.replace to reach\n * a session, which is exactly the kind of copy that can move by one character\n * without anything noticing.\n *\n * `:workspace` and `:runKey` are Hono's own parameter syntax, because the app\n * registers `path` verbatim.\n */\n\n/** One run, which every route below addresses. */\nconst RUN = '/runs/:workspace/:runKey';\n\n/**\n * The artifact route's parameter, as Hono spells a multi-segment match.\n *\n * An artifact is named by its path inside the run directory, so `reports/a.md`\n * is one parameter across two segments. The client's `params` substitution\n * fills a single segment and percent-encodes the slash with it, so the page\n * substitutes this one itself; see the page's `_lib/terminalApi.ts`.\n */\nexport const ARTIFACT_NAME_PARAM = ':name{.+}';\n\n/**\n * The step whose pane a terminal route reads: a step ref's id. Absent, the\n * route follows the run's current step, which is one of a parallel group's.\n */\nexport const STEP_TARGET_PARAM = 'step';\n\n/** Query parameters the artifact route reads, spelled once for both halves. */\nexport const ARTIFACT_RAW_PARAM = 'raw';\nexport const ARTIFACT_DOWNLOAD_PARAM = 'download';\n\nconst routes = {\n /**\n * The terminal, as server-sent events.\n *\n * `stream: true` gets a URL and no call method: the consumer is the browser's\n * own `EventSource`, and a relayed call would buffer a stream that never ends.\n */\n snapshot: {\n method: 'GET',\n path: `${RUN}/screen`,\n query: [STEP_TARGET_PARAM],\n response: undefined as unknown as ApiResponseOf<WorkflowScreenEvent>,\n },\n screen: {\n method: 'GET',\n path: `${RUN}/screen/stream`,\n query: [STEP_TARGET_PARAM],\n stream: true,\n },\n control: {\n method: 'POST',\n path: `${RUN}/control`,\n response: undefined as unknown as ApiResponseOf<WorkflowControlResponse>,\n },\n keys: {\n method: 'POST',\n path: `${RUN}/keys`,\n },\n resize: {\n method: 'POST',\n path: `${RUN}/resize`,\n response: undefined as unknown as ApiResponseOf<{ resized: boolean }>,\n },\n remove: {\n method: 'DELETE',\n path: RUN,\n response: undefined as unknown as ApiResponseOf<WorkflowDeleteResponse>,\n },\n stop: {\n method: 'POST',\n path: `${RUN}/stop`,\n response: undefined as unknown as ApiResponseOf<WorkflowStopResponse>,\n },\n /** Guidance for the agent session the running step is in, like steering a Team sub-agent. */\n steer: {\n method: 'POST',\n path: `${RUN}/steer`,\n response: undefined as unknown as ApiResponseOf<WorkflowSteerResponse>,\n },\n /**\n * Launch a workflow into the mounting session's own runtime, which then owns\n * the run. A dispatcher session reaches its root's session mount through this.\n */\n launch: {\n method: 'POST',\n path: '/launch',\n response: undefined as unknown as ApiResponseOf<WorkflowLaunchResponse>,\n },\n openRunDirectory: {\n method: 'POST',\n path: `${RUN}/open-directory`,\n response: undefined as unknown as ApiResponseOf<WorkflowOpenRunDirectoryResponse>,\n },\n artifacts: {\n method: 'GET',\n path: `${RUN}/artifacts`,\n query: ['directory'],\n response: undefined as unknown as ApiResponseOf<WorkflowArtifactsResponse>,\n },\n /** One artifact: its metadata and text, or its raw bytes under `raw=1`. */\n artifact: {\n method: 'GET',\n path: `${RUN}/artifacts/${ARTIFACT_NAME_PARAM}`,\n query: [ARTIFACT_RAW_PARAM, ARTIFACT_DOWNLOAD_PARAM],\n response: undefined as unknown as ApiResponseOf<WorkflowArtifactContentResponse>,\n },\n} as const satisfies ApiRoutes;\n\nexport default routes;\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { createApiClient, nativeApiTransport, sessionApiAddress } from '@agimon-ai/po-core/native';\n\nimport routes from '../src/types/apiRoutes';\n\n/** Scopes the tree mounts 'workflow' at. */\nexport const apiScopes = ['global', 'workspace', 'session'] as const;\n\nexport const api = createApiClient(routes, {\n scopes: apiScopes,\n basePath: 'workflow',\n transport: nativeApiTransport,\n sessionAddress: sessionApiAddress,\n});\n","import type { WebPluginSlotProps } from '@agimon-ai/po-core/native';\nimport { nativeApiTransport } from '@agimon-ai/po-core/native';\n\nimport { api } from '../../../../../../generated/client.native';\nimport {\n ARTIFACT_DOWNLOAD_PARAM,\n ARTIFACT_NAME_PARAM,\n ARTIFACT_RAW_PARAM,\n STEP_TARGET_PARAM,\n} from '../../../../../types/apiRoutes';\nimport {\n type WorkflowArtifactContentResponse,\n type WorkflowArtifactsResponse,\n type WorkflowControlResponse,\n type WorkflowDeleteResponse,\n type WorkflowScreenEvent,\n type WorkflowSteerResponse,\n type WorkflowStopResponse,\n} from '../../../../../types/webWorkflowTerminal';\n\n/**\n * The page's half of this package's hub API: one run's terminal and the files\n * its run directory holds.\n *\n * These are adapters now, not a transport. The generated client owns the URL\n * and the sealed transport with it, so nothing here spells a mount. What stays\n * is this package's own vocabulary: which refusals the reader is shown, and the\n * shapes the terminal expects back.\n *\n * A run belongs to its multiplexer rather than to a session, so the same API\n * answers at the hub and inside a session's own server. Passing a session id\n * addresses that session's copy and passing none addresses the hub. The deleted\n * builder made that branch the other way round: it always built the hub's\n * absolute URL, then rewrote the plugin prefix into the session's with\n * String.replace, so a session's URL was a hub URL with its head swapped.\n */\n\nconst UNREACHABLE = 'The cockpit hub is unreachable.';\n\n/** One of the scopes this API mounts at; every route is the same on all of them. */\ntype WorkflowScope = typeof api.global;\n\n/** The hub, or one session's own copy of it; a null session id is the hub. */\nfunction scoped(sessionId?: string | null): WorkflowScope {\n return sessionId == null ? api.global : api.session(sessionId);\n}\n\n/** The run every route addresses, as the route table's two path parameters. */\nfunction runParams(workspace: string, runKey: string): { workspace: string; runKey: string } {\n return { workspace, runKey };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * The message a reader is shown: the route's own words, or why there were none.\n *\n * `error` is optional because an answered call that simply carried the wrong\n * shape reaches here too, and that result has no error field at all.\n */\nfunction messageOf(result: { status: number; error?: string }, fallback: string): string {\n if (result.status === 0) return UNREACHABLE;\n return result.error === undefined || result.error === '' ? fallback : result.error;\n}\n\n/**\n * One artifact's URL, with its path filled in.\n *\n * An artifact is named by its path inside the run directory, which Hono matches\n * as the one multi-segment parameter `:name{.+}`. The client's own `params`\n * substitution fills a single segment and percent-encodes the separating slash\n * with it, which would move every nested artifact's URL, so that one segment is\n * substituted here instead: each segment encoded, the slashes between them\n * kept. Everything left of it still comes from the client.\n */\nfunction artifactUrl(\n scope: WorkflowScope,\n workspace: string,\n runKey: string,\n artifactPath: string,\n query?: Record<string, number>,\n): string {\n return scope.artifact\n .url({ params: runParams(workspace, runKey), ...(query === undefined ? {} : { query }) })\n .replace(ARTIFACT_NAME_PARAM, artifactPath.split('/').map(encodeURIComponent).join('/'));\n}\n\n/** The pane a terminal call names, when it reads one step's rather than the run's current one. */\nfunction stepBody(step: string | undefined): { step?: string } {\n return step === undefined ? {} : { step };\n}\n\n/** One finite screen read over the session-bound sealed transport. */\nexport async function readScreen(\n workspace: string,\n runKey: string,\n sessionId: string | null,\n step: string | undefined,\n signal: AbortSignal,\n): Promise<WorkflowScreenEvent> {\n const response = await nativeApiTransport(\n scoped(sessionId).snapshot.url({\n params: runParams(workspace, runKey),\n query: { [STEP_TARGET_PARAM]: step },\n }),\n { signal },\n );\n const body: unknown = await response.json();\n if (!response.ok)\n throw new Error(isRecord(body) && typeof body.error === 'string' ? body.error : 'The screen could not be read.');\n if (\n !isRecord(body) ||\n !Array.isArray(body.lines) ||\n body.lines.length > 48 ||\n !body.lines.every((line) => typeof line === 'string' && line.length <= 4096) ||\n !isRecord(body.capabilities) ||\n typeof body.capabilities.readable !== 'boolean' ||\n typeof body.capabilities.writable !== 'boolean' ||\n typeof body.capabilities.resizable !== 'boolean'\n ) {\n throw new Error('The workflow hub returned an invalid screen.');\n }\n return body as unknown as WorkflowScreenEvent;\n}\n\n/** Takes the keyboard for one run, renewing when this page already holds it. */\nexport async function takeControl(\n workspace: string,\n runKey: string,\n token?: string,\n sessionId?: string | null,\n step?: string,\n): Promise<WorkflowControlResponse> {\n const result = await scoped(sessionId).control({\n params: runParams(workspace, runKey),\n body: { token, ...stepBody(step) },\n });\n if (result.status === 0) return { held: false, reason: UNREACHABLE };\n // A refusal carries the same shape as a grant, so the body is read before the\n // status: a 409 says who holds the keyboard and why, which is the answer.\n if (isRecord(result.data) && typeof result.data.held === 'boolean') {\n return result.data as unknown as WorkflowControlResponse;\n }\n return { held: false, reason: messageOf(result, 'The run refused the keyboard.') };\n}\n\nexport async function releaseControl(\n workspace: string,\n runKey: string,\n token: string,\n sessionId?: string | null,\n step?: string,\n): Promise<void> {\n await scoped(sessionId).control({\n params: runParams(workspace, runKey),\n body: { token, release: true, ...stepBody(step) },\n });\n}\n\n/** Sends literal keystrokes; the reason comes back when the lease has moved on. */\nexport async function sendKeys(\n workspace: string,\n runKey: string,\n token: string,\n data: string,\n sessionId?: string | null,\n step?: string,\n): Promise<{ error?: string }> {\n const result = await scoped(sessionId).keys({\n params: runParams(workspace, runKey),\n body: { token, data, ...stepBody(step) },\n });\n if (result.ok) return {};\n return { error: messageOf(result, 'The run would not take those keys.') };\n}\n\n/** Matches the run's terminal to the viewport of whoever holds the keyboard. */\nexport async function resizeRun(\n workspace: string,\n runKey: string,\n token: string,\n columns: number,\n rows: number,\n sessionId?: string | null,\n step?: string,\n): Promise<void> {\n await scoped(sessionId).resize({\n params: runParams(workspace, runKey),\n body: { token, columns, rows, ...stepBody(step) },\n });\n}\n\nexport type DeleteWorkflowResult = { result: WorkflowDeleteResponse } | { error: string };\n\n/** Permanently removes one settled run and its run directory. */\nexport async function deleteWorkflowRun(\n workspace: string,\n runKey: string,\n sessionId?: string | null,\n): Promise<DeleteWorkflowResult> {\n const result = await scoped(sessionId).remove({ params: runParams(workspace, runKey) });\n if (!result.ok) return { error: messageOf(result, 'The workflow could not be deleted.') };\n if (result.data.deleted === true) return { result: { deleted: true } };\n return { error: 'The workflow hub returned an invalid deletion response.' };\n}\n\nexport type StopWorkflowResult = { result: WorkflowStopResponse } | { error: string };\n\n/** Asks the engine running a workflow to stop it; the run settles on its own shortly after. */\nexport async function stopWorkflowRun(\n workspace: string,\n runKey: string,\n sessionId?: string | null,\n): Promise<StopWorkflowResult> {\n const result = await scoped(sessionId).stop({ params: runParams(workspace, runKey) });\n if (!result.ok) return { error: messageOf(result, 'The workflow could not be stopped.') };\n if (result.data.requested === true) return { result: { requested: true } };\n return { error: 'The workflow hub returned an invalid stop response.' };\n}\n\nexport type SteerStepResult = { result: WorkflowSteerResponse } | { error: string };\n\n/**\n * Sends guidance to the agent session a running step is in: the run's current\n * step, or `step`, the session of one step of a parallel group.\n */\nexport async function steerStep(\n workspace: string,\n runKey: string,\n message: string,\n sessionId?: string | null,\n step?: string,\n): Promise<SteerStepResult> {\n const result = await scoped(sessionId).steer({\n params: runParams(workspace, runKey),\n body: step === undefined ? { message } : { message, step },\n });\n if (!result.ok) return { error: messageOf(result, 'The step would not take that guidance.') };\n if (result.data.delivered === true) return { result: { delivered: true } };\n return { error: 'The workflow hub returned an invalid steer response.' };\n}\n\n/** Opens the current registry folder, never a browser-supplied path. */\nexport async function openRunDirectory(\n workspace: string,\n runKey: string,\n sessionId?: string | null,\n): Promise<{ error?: string }> {\n const result = await scoped(sessionId).openRunDirectory({ params: runParams(workspace, runKey) });\n if (!result.ok) return { error: messageOf(result, 'The run folder could not be opened in Finder.') };\n return result.data.opened === true ? {} : { error: 'The workflow hub returned an invalid folder response.' };\n}\n\nexport type ArtifactsResult = { artifacts: WorkflowArtifactsResponse } | { error: string };\n\nexport async function fetchArtifacts(\n workspace: string,\n runKey: string,\n sessionId?: string | null,\n directory?: string,\n): Promise<ArtifactsResult> {\n const result = await scoped(sessionId).artifacts({ params: runParams(workspace, runKey), query: { directory } });\n if (!result.ok) return { error: messageOf(result, 'This run has no directory to read.') };\n return { artifacts: result.data };\n}\n\nexport type ArtifactResult = { artifact: WorkflowArtifactContentResponse } | { error: string };\n\n/** Trusted same-origin URL for browser-native media previews and downloads. */\nexport function artifactContentUrl(\n workspace: string,\n runKey: string,\n path: string,\n download = false,\n sessionId?: string | null,\n): string {\n return artifactUrl(scoped(sessionId), workspace, runKey, path, {\n [ARTIFACT_RAW_PARAM]: 1,\n ...(download ? { [ARTIFACT_DOWNLOAD_PARAM]: 1 } : {}),\n });\n}\n\n/**\n * One artifact's metadata and text.\n *\n * The only route here that addresses itself rather than being called: its path\n * parameter spans segments, so the URL comes from `artifactUrl` and the request\n * goes over the same sealed transport the client is built on.\n */\nexport async function fetchArtifact(\n workspace: string,\n runKey: string,\n path: string,\n sessionId?: string | null,\n): Promise<ArtifactResult> {\n try {\n const response = await nativeApiTransport(artifactUrl(scoped(sessionId), workspace, runKey, path));\n const body = (await response.json()) as unknown;\n if (!response.ok) {\n const error = isRecord(body) && typeof body.error === 'string' && body.error !== '' ? body.error : '';\n return { error: error === '' ? 'That file has not been written.' : error };\n }\n return { artifact: body as WorkflowArtifactContentResponse };\n } catch {\n return { error: UNREACHABLE };\n }\n}\n\nconst MAX_MEDIA_BYTES = 5 * 1024 * 1024;\nconst MAX_FRAME_BYTES = 64 * 1024;\n\n/** Drain each UTF-8 snapshot before asking the server for another screen. */\nexport function finiteScreenReader(load: (signal: AbortSignal) => Promise<WorkflowScreenEvent>) {\n let bytes: Uint8Array = new Uint8Array(0);\n let cursor = 0;\n let generation = 0;\n let frame: WorkflowScreenEvent | undefined;\n return async (from: number, previous: string | undefined, signal: AbortSignal) => {\n if (signal.aborted) throw new Error('Preview cancelled.');\n let reset = previous !== String(generation) || from !== cursor;\n if (!frame || cursor >= bytes.length || reset) {\n const next = await load(signal);\n if (signal.aborted) throw new Error('Preview cancelled.');\n frame = next;\n bytes = utf8(next.lines.join('\\r\\n'));\n cursor = 0;\n generation += 1;\n reset = true;\n }\n const chunk = bytes.subarray(cursor, cursor + MAX_FRAME_BYTES);\n cursor += chunk.length;\n return {\n chunk: base64(chunk),\n offset: cursor,\n reset,\n generation: String(generation),\n exists: frame.capabilities.readable,\n hasMore: cursor < bytes.length,\n ended: frame.ended === true,\n };\n };\n}\n\n/** Raw media uses the same scoped sealed route as artifact metadata. */\nexport async function fetchArtifactMedia(\n workspace: string,\n runKey: string,\n path: string,\n sessionId: string | null,\n signal: AbortSignal,\n): Promise<{ data: string; mimeType: string }> {\n if (signal.aborted) throw new Error('Preview cancelled.');\n const response = await nativeApiTransport(artifactContentUrl(workspace, runKey, path, false, sessionId), { signal });\n if (signal.aborted) throw new Error('Preview cancelled.');\n if (!response.ok) throw new Error('That artifact could not be read.');\n const mimeType = (response.headers.get('content-type') ?? '').split(';')[0]!.trim().toLowerCase();\n if (\n !/^(application\\/pdf|image\\/(png|jpeg|gif|webp|bmp)|audio\\/(mpeg|mp4|wav|x-wav|ogg|webm|aac|flac)|video\\/(mp4|webm|quicktime|ogg))$/.test(\n mimeType,\n )\n )\n throw new Error('This artifact type cannot be previewed.');\n if (Number(response.headers.get('content-length')) > MAX_MEDIA_BYTES)\n throw new Error('This artifact exceeds the 5 MiB preview limit.');\n const bytes = await response.arrayBuffer();\n if (signal.aborted) throw new Error('Preview cancelled.');\n if (bytes.byteLength > MAX_MEDIA_BYTES) throw new Error('This artifact exceeds the 5 MiB preview limit.');\n return { data: base64(new Uint8Array(bytes)), mimeType };\n}\n\nfunction base64(bytes: Uint8Array): string {\n const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n const parts: string[] = [];\n let chunk = '';\n for (let offset = 0; offset < bytes.length; offset += 3) {\n const first = bytes[offset]!;\n const second = bytes[offset + 1];\n const third = bytes[offset + 2];\n chunk +=\n alphabet[first >> 2]! +\n alphabet[((first & 3) << 4) | ((second ?? 0) >> 4)]! +\n (second === undefined ? '=' : alphabet[((second & 15) << 2) | ((third ?? 0) >> 6)]!) +\n (third === undefined ? '=' : alphabet[third & 63]!);\n if (chunk.length >= 8192) {\n parts.push(chunk);\n chunk = '';\n }\n }\n parts.push(chunk);\n return parts.join('');\n}\n\nfunction utf8(text: string): Uint8Array {\n const bytes: number[] = [];\n for (const character of text) {\n let code = character.codePointAt(0)!;\n if (code >= 0xd800 && code <= 0xdfff) code = 0xfffd;\n if (code < 0x80) bytes.push(code);\n else if (code < 0x800) bytes.push(0xc0 | (code >> 6), 0x80 | (code & 63));\n else if (code < 0x10000) bytes.push(0xe0 | (code >> 12), 0x80 | ((code >> 6) & 63), 0x80 | (code & 63));\n else bytes.push(0xf0 | (code >> 18), 0x80 | ((code >> 12) & 63), 0x80 | ((code >> 6) & 63), 0x80 | (code & 63));\n }\n return Uint8Array.from(bytes);\n}\n\n/** Binds a save to this package's guarded sealed route and one file version. */\nexport async function prepareArtifactSave(\n workspace: string,\n runKey: string,\n path: string,\n sessionId: string | null,\n signal: AbortSignal,\n): Promise<Parameters<NonNullable<WebPluginSlotProps['nativeSaveFile']>>[0]> {\n const load = async (headers: Record<string, string>, signal: AbortSignal): Promise<Response> => {\n if (signal.aborted) throw new Error('Download cancelled.');\n return nativeApiTransport(artifactContentUrl(workspace, runKey, path, true, sessionId), { headers, signal });\n };\n const probe = await load({ Range: 'bytes=0-0' }, signal);\n if (signal.aborted) throw new Error('Download cancelled.');\n const range = /^bytes 0-0\\/(\\d+)$/u.exec(probe.headers.get('content-range') ?? '');\n const empty =\n (probe.status === 416 && probe.headers.get('content-range') === 'bytes */0') ||\n (probe.status === 200 && probe.headers.get('content-length') === '0');\n if (!empty && (probe.status !== 206 || !range)) throw new Error('The file does not support bounded downloads.');\n const size = empty ? 0 : Number(range![1]);\n if (!Number.isSafeInteger(size) || size < 0) throw new Error('Invalid file size.');\n const probeBytes = await probe.arrayBuffer();\n if (probeBytes.byteLength !== (empty ? 0 : 1)) throw new Error('Invalid file response.');\n const version = probe.headers.get('etag');\n if (!version) throw new Error('The file has no version validator.');\n return {\n name: path.split(/[\\\\/]/u).at(-1) ?? '',\n mimeType: probe.headers.get('content-type')?.split(';')[0]?.trim() || 'application/octet-stream',\n size,\n signal,\n read: async (offset, count, signal) => {\n if (\n !Number.isSafeInteger(offset) ||\n !Number.isSafeInteger(count) ||\n offset < 0 ||\n count < 1 ||\n count > 1024 * 1024 ||\n offset + count > size\n )\n throw new Error('Invalid download range.');\n const end = offset + count - 1;\n const response = await load({ Range: `bytes=${offset}-${end}`, 'If-Match': version }, signal);\n if (signal.aborted) throw new Error('Download cancelled.');\n if (\n response.status !== 206 ||\n response.headers.get('etag') !== version ||\n response.headers.get('content-range') !== `bytes ${offset}-${end}/${size}`\n )\n throw new Error('The file changed or its range response is invalid.');\n const bytes = new Uint8Array(await response.arrayBuffer());\n if (signal.aborted) throw new Error('Download cancelled.');\n if (bytes.byteLength !== count) throw new Error('The file response is incomplete.');\n return bytes;\n },\n };\n}\n","import type { WebPluginSlotProps } from '@agimon-ai/po-core/native';\nimport {\n Badge,\n Button,\n CodeBlock,\n Input,\n ListRow,\n Markdown,\n Sheet,\n SheetBody,\n SheetContent,\n SheetHeader,\n SheetTitle,\n Textarea,\n} from '@agimon-ai/po-native-components';\nimport { useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react';\nimport { ScrollView, Text, View } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport type { WorkflowCatalogEntryView, WorkflowRunView } from '../../../../../types/webWorkflows';\nimport type {\n WorkflowArtifactContentResponse,\n WorkflowArtifactsResponse,\n WorkflowTerminalCapabilitiesView,\n} from '../../../../../types/webWorkflowTerminal';\nimport { catalog, closeCatalog, filterCatalog } from '../_lib/catalogStore.native';\nimport {\n initialChoice,\n initialCommand,\n initialInputs,\n initialRunner,\n launchProblems,\n workflowLaunchLine,\n} from '../_lib/launchLine';\nimport {\n deleteWorkflowRun,\n fetchArtifact,\n fetchArtifactMedia,\n prepareArtifactSave,\n finiteScreenReader,\n fetchArtifacts,\n readScreen,\n releaseControl,\n resizeRun,\n sendKeys,\n takeControl,\n steerStep,\n stopWorkflowRun,\n} from '../_lib/terminalApi.native';\nimport { workflowRunIdentity } from '../_lib/workflowActivity';\nimport { focusRun, removeRun, requestLaunch, workflows } from '../_lib/workflowsStore.native';\n\nexport function useWorkflows(sessionId: string | null) {\n const subscribe = useCallback((listener: () => void) => {\n const sub = workflows.store.subscribe(listener);\n return () => sub.unsubscribe();\n }, []);\n return useSyncExternalStore(subscribe, () => workflows.select(workflows.store.state, sessionId));\n}\nexport function workflowTab(run: WorkflowRunView): Parameters<WebPluginSlotProps['openTransientTab']>[0] {\n const identity = workflowRunIdentity(run);\n return {\n id: `workflows-run-${run.workspace}-${run.routeKey ?? run.runKey}`.replace(/[^\\w-]+/g, '-'),\n label: run.displayName,\n retainComposer: true,\n panel: (props) => <WorkflowPanel {...props} identity={identity} />,\n };\n}\nexport function WorkflowLauncher(props: WebPluginSlotProps) {\n const subscribe = useCallback((listener: () => void) => {\n const sub = catalog.store.subscribe(listener);\n return () => sub.unsubscribe();\n }, []);\n const state = useSyncExternalStore(subscribe, () => catalog.select(catalog.store.state, props.sessionId));\n const [filter, setFilter] = useState('');\n const [selected, setSelected] = useState<string>();\n if (props.sessionId === null || !state.open) return null;\n const workflow = state.workflows.find((item) => item.path === selected);\n return (\n <Sheet\n open\n onOpenChange={(open) => {\n if (!open) {\n closeCatalog(props.sessionId!);\n setSelected(undefined);\n }\n }}\n >\n <SheetContent>\n <SheetHeader>\n <SheetTitle>{workflow ? `Launch ${workflow.name}` : 'Launch a workflow'}</SheetTitle>\n </SheetHeader>\n <SheetBody>\n {workflow ? (\n <WorkflowLaunch\n key={workflow.path}\n {...props}\n sessionId={props.sessionId}\n workflow={workflow}\n initialPrompt={state.prompt}\n onClose={() => {\n closeCatalog(props.sessionId!);\n setSelected(undefined);\n }}\n />\n ) : (\n <View style={styles.body}>\n <Input\n accessibilityLabel=\"Find a workflow\"\n value={filter}\n onChangeText={setFilter}\n placeholder=\"Find a workflow\"\n />\n {state.warning ? <Text style={styles.error}>{state.warning}</Text> : null}\n {filterCatalog(state.workflows, filter).map((item) => (\n <ListRow\n key={item.path}\n title={\n <Button variant=\"ghost\" onPress={() => setSelected(item.path)}>\n {item.name || item.relativePath}\n </Button>\n }\n description={`${item.description}\\n${item.tags.join(', ')} · ${item.jobs.map((job) => job.name).join(', ')}`}\n />\n ))}\n {state.workflows.length === 0 ? <Text style={styles.meta}>No workflows reported yet.</Text> : null}\n </View>\n )}\n </SheetBody>\n </SheetContent>\n </Sheet>\n );\n}\nfunction Choice({\n label,\n options,\n value,\n onChange,\n}: {\n label: string;\n options: readonly string[];\n value: string | undefined;\n onChange: (value: string) => void;\n}) {\n return (\n <View>\n <Text style={styles.meta}>{label}</Text>\n {options.map((option) => (\n <Button\n key={option}\n variant=\"outline\"\n accessibilityState={{ selected: value === option }}\n onPress={() => onChange(option)}\n >\n {option}\n </Button>\n ))}\n </View>\n );\n}\nfunction WorkflowLaunch({\n sessionId,\n workflow,\n initialPrompt,\n sendSessionFrame,\n onClose,\n}: WebPluginSlotProps & {\n sessionId: string;\n workflow: WorkflowCatalogEntryView;\n initialPrompt: string;\n onClose: () => void;\n}) {\n const [prompt, setPrompt] = useState(initialPrompt);\n const [inputs, setInputs] = useState(() => initialInputs(workflow));\n const [runner, setRunner] = useState(() => initialRunner(workflow));\n const [command, setCommand] = useState(() => initialCommand(workflow));\n const [choice, setChoice] = useState(() => initialChoice(workflow));\n const [error, setError] = useState<string>();\n const request = {\n workflow: workflow.name || workflow.relativePath,\n inputs,\n runner,\n command,\n choice,\n ...(prompt.trim() === '' ? {} : { prompt: prompt.trim() }),\n };\n const problems = launchProblems(workflow, request);\n const line = workflowLaunchLine(request);\n return (\n <View style={styles.body}>\n <Text style={styles.meta}>{workflow.description}</Text>\n <Textarea\n accessibilityLabel=\"Workflow prompt\"\n placeholder=\"What should this workflow do?\"\n value={prompt}\n onChangeText={setPrompt}\n />\n {workflow.inputs.map((input) => {\n const options = input.options ?? (input.type === 'boolean' ? ['true', 'false'] : undefined);\n return (\n <View key={input.name}>\n <Text style={styles.meta}>\n {input.name}\n {input.required ? ' (required)' : ''} · {input.description}\n </Text>\n {options ? (\n <Choice\n label={input.name}\n options={options}\n value={inputs[input.name]}\n onChange={(value) => setInputs((current) => ({ ...current, [input.name]: value }))}\n />\n ) : (\n <Input\n accessibilityLabel={input.name}\n value={inputs[input.name] ?? ''}\n onChangeText={(value) => setInputs((current) => ({ ...current, [input.name]: value }))}\n />\n )}\n </View>\n );\n })}\n {workflow.runners?.length ? (\n <Choice label=\"Runner\" options={workflow.runners} value={runner} onChange={setRunner} />\n ) : null}\n {workflow.commands?.length ? (\n <Choice label=\"Command\" options={workflow.commands} value={command} onChange={setCommand} />\n ) : null}\n {workflow.choices?.length ? (\n <Choice label=\"Choice\" options={workflow.choices} value={choice} onChange={setChoice} />\n ) : null}\n <CodeBlock text={line} />\n {problems.map((problem) => (\n <Text key={problem} style={styles.meta}>\n {problem}\n </Text>\n ))}\n {error ? <Text style={styles.error}>{error}</Text> : null}\n <Button\n testID=\"launch-workflow-submit\"\n disabled={problems.length > 0}\n onPress={() => {\n try {\n requestLaunch(sendSessionFrame, sessionId, line, workflow.path);\n onClose();\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : String(cause));\n }\n }}\n >\n Launch\n </Button>\n </View>\n );\n}\n\nexport function WorkflowPanel(props: WebPluginSlotProps & { identity: string }) {\n const state = useWorkflows(props.sessionId);\n const run = state.runs.find((item) => workflowRunIdentity(item) === props.identity);\n const [confirmDelete, setConfirmDelete] = useState(false);\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<string>();\n const act = async (action: () => Promise<void>) => {\n if (busy) return;\n setBusy(true);\n setError(undefined);\n try {\n await action();\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : String(cause));\n } finally {\n setBusy(false);\n }\n };\n if (!run) return <Text style={styles.meta}>This run is no longer listed.</Text>;\n return (\n <ScrollView contentContainerStyle={styles.body}>\n <Text style={styles.title}>{run.displayName}</Text>\n <Badge>{run.executionState ?? run.outcome ?? run.stage}</Badge>\n <Text style={styles.meta}>{run.errorMessage ?? `${run.position?.job ?? ''} ${run.position?.step ?? ''}`}</Text>\n {state.runs.length > 1\n ? state.runs.map((item) => (\n <Button\n key={workflowRunIdentity(item)}\n variant=\"ghost\"\n onPress={() => {\n if (props.sessionId !== null) focusRun(props.sessionId, workflowRunIdentity(item));\n props.openTransientTab(workflowTab(item));\n }}\n >\n {item.displayName}\n </Button>\n ))\n : null}\n {run.executionState === 'paused' || run.executionState === 'pause_requested' ? (\n <Text style={styles.meta}>Waiting to be resumed. Ask the agent in this conversation to resume it.</Text>\n ) : null}\n {run.jobs.map((job) => (\n <View key={job.name}>\n <Button variant=\"ghost\" onPress={() => props.openTransientTab(stepTab(run, job.name))}>\n {job.name} · {job.status}\n </Button>\n {job.steps.map((step) => (\n <ListRow\n key={step.name}\n title={\n <Button variant=\"ghost\" onPress={() => props.openTransientTab(stepTab(run, job.name, step.name))}>\n {step.name}\n </Button>\n }\n description={step.status}\n />\n ))}\n </View>\n ))}\n <Text style={styles.title}>Artifacts</Text>\n <WorkflowArtifacts {...props} run={run} />\n {error ? <Text style={styles.error}>{error}</Text> : null}\n {run.stage === 'running' ? (\n <Button\n variant=\"danger-outline\"\n disabled={busy || props.sessionId === null}\n onPress={() =>\n void act(async () => {\n const result = await stopWorkflowRun(run.workspace, run.routeKey ?? run.runKey, props.sessionId);\n if ('error' in result) throw new Error(result.error);\n })\n }\n >\n Stop workflow\n </Button>\n ) : (\n <Button variant=\"danger-outline\" disabled={props.sessionId === null} onPress={() => setConfirmDelete(true)}>\n Delete run…\n </Button>\n )}\n <Sheet open={confirmDelete} onOpenChange={setConfirmDelete}>\n <SheetContent>\n <SheetHeader>\n <SheetTitle>Delete this run?</SheetTitle>\n </SheetHeader>\n <SheetBody>\n <Text style={styles.meta}>This permanently removes the settled run and its directory.</Text>\n <Button\n variant=\"danger-outline\"\n disabled={busy}\n onPress={() =>\n void act(async () => {\n const result = await deleteWorkflowRun(run.workspace, run.routeKey ?? run.runKey, props.sessionId);\n if ('error' in result) throw new Error(result.error);\n if (props.sessionId !== null) removeRun(props.sessionId, props.identity);\n setConfirmDelete(false);\n props.closeTransientTab(\n `workflows-run-${run.workspace}-${run.routeKey ?? run.runKey}`.replace(/[^\\w-]+/g, '-'),\n );\n })\n }\n >\n Delete\n </Button>\n </SheetBody>\n </SheetContent>\n </Sheet>\n </ScrollView>\n );\n}\nfunction stepTab(\n run: WorkflowRunView,\n job: string,\n step?: string,\n): Parameters<WebPluginSlotProps['openTransientTab']>[0] {\n const workspace = run.workspace;\n const runKey = run.routeKey ?? run.runKey;\n return {\n id: `workflows-step-${workspace}-${runKey}-${job}${step === undefined ? '' : `-${step}`}`.replace(/[^\\w-]+/g, '-'),\n label: `${run.displayName} › ${step ?? job}`,\n panel: (props) => <WorkflowStep {...props} workspace={workspace} runKey={runKey} job={job} step={step} />,\n };\n}\nfunction WorkflowStep({\n sessionId,\n workspace,\n runKey,\n job,\n step,\n renderSessionTranscript,\n renderRunnerTerminal,\n}: WebPluginSlotProps & { workspace: string; runKey: string; job: string; step?: string }) {\n const state = useWorkflows(sessionId);\n const run = state.runs.find((item) => item.workspace === workspace && (item.routeKey ?? item.runKey) === runKey);\n const steps = run?.jobs.find((item) => item.name === job)?.steps;\n const target = step === undefined ? steps?.at(-1) : steps?.find((item) => item.name === step);\n const [message, setMessage] = useState('');\n const [error, setError] = useState<string>();\n const [busy, setBusy] = useState(false);\n const ref = target?.ref;\n const session = ref?.kind === 'session' ? ref.id : undefined;\n return (\n <View style={styles.screen}>\n <Text style={styles.title}>\n {job}\n {step === undefined ? '' : ` › ${step}`} · {target?.status}\n </Text>\n {session ? (\n renderSessionTranscript?.(session)\n ) : (\n <WorkflowTerminal\n key={`${sessionId}:${workspace}:${runKey}:${ref?.id ?? ''}`}\n sessionId={sessionId}\n workspace={workspace}\n runKey={runKey}\n pane={ref?.kind === 'pane' ? ref.id : undefined}\n renderRunnerTerminal={renderRunnerTerminal}\n />\n )}\n {session && run?.stage === 'running' && target?.status === 'running' ? (\n <View style={styles.body}>\n <Textarea accessibilityLabel=\"Step guidance\" value={message} onChangeText={setMessage} />\n <Button\n disabled={busy || message.trim() === ''}\n onPress={() => {\n setBusy(true);\n void steerStep(workspace, runKey, message.trim(), sessionId, session)\n .then((result) => {\n if ('error' in result) setError(result.error);\n else {\n setMessage('');\n setError(undefined);\n }\n })\n .catch((cause: unknown) => setError(cause instanceof Error ? cause.message : String(cause)))\n .finally(() => setBusy(false));\n }}\n >\n Send guidance\n </Button>\n </View>\n ) : null}\n {error ? <Text style={styles.error}>{error}</Text> : null}\n </View>\n );\n}\nfunction WorkflowTerminal({\n sessionId,\n workspace,\n runKey,\n pane,\n renderRunnerTerminal,\n}: Pick<WebPluginSlotProps, 'sessionId' | 'renderRunnerTerminal'> & {\n workspace: string;\n runKey: string;\n pane?: string;\n}) {\n const [capabilities, setCapabilities] = useState<WorkflowTerminalCapabilitiesView>();\n const [token, setToken] = useState<string>();\n const [notice, setNotice] = useState<string>();\n const [columns, setColumns] = useState('80');\n const [rows, setRows] = useState('24');\n const [busy, setBusy] = useState(false);\n const [lifetime] = useState(() => new AbortController());\n useEffect(() => () => lifetime.abort(), [lifetime]);\n useEffect(() => {\n if (token === undefined) return;\n return () => {\n void releaseControl(workspace, runKey, token, sessionId, pane).catch(() => {});\n };\n }, [workspace, runKey, token, sessionId, pane]);\n const request = useMemo(\n () => ({\n key: `${sessionId}:${workspace}:${runKey}:${pane ?? ''}`,\n read: finiteScreenReader(async (signal) => {\n const frame = await readScreen(workspace, runKey, sessionId, pane, signal);\n if (!signal.aborted && !lifetime.signal.aborted) setCapabilities(frame.capabilities);\n return frame;\n }),\n write: async (text: string) => {\n if (token === undefined) throw new Error('Take control before typing into this run.');\n const result = await sendKeys(workspace, runKey, token, text, sessionId, pane);\n if (result.error) {\n if (!lifetime.signal.aborted) {\n setNotice(result.error);\n setToken(undefined);\n }\n throw new Error(result.error);\n }\n },\n }),\n [sessionId, workspace, runKey, pane, token, lifetime],\n );\n const arm = async () => {\n setBusy(true);\n try {\n const grant = await takeControl(workspace, runKey, undefined, sessionId, pane);\n if (lifetime.signal.aborted) {\n if (grant.held && grant.token) await releaseControl(workspace, runKey, grant.token, sessionId, pane);\n return;\n }\n if (grant.held && grant.token) {\n setToken(grant.token);\n setNotice(undefined);\n } else setNotice(grant.reason ?? 'The keyboard is not available for this run.');\n } catch (cause) {\n if (!lifetime.signal.aborted) setNotice(cause instanceof Error ? cause.message : String(cause));\n } finally {\n if (!lifetime.signal.aborted) setBusy(false);\n }\n };\n return (\n <View style={styles.transcript}>\n <Badge>{token ? 'keyboard yours' : 'watching'}</Badge>\n {capabilities?.writable ? (\n <Button\n variant=\"outline\"\n disabled={busy}\n onPress={() => {\n if (token) setToken(undefined);\n else void arm();\n }}\n >\n {token ? 'Release keyboard' : 'Take control'}\n </Button>\n ) : null}\n <View style={styles.transcript}>{renderRunnerTerminal?.(request)}</View>\n {capabilities?.reason ? <Text style={styles.meta}>{capabilities.reason}</Text> : null}\n {token && capabilities?.resizable ? (\n <View>\n <Input\n accessibilityLabel=\"Terminal columns\"\n keyboardType=\"number-pad\"\n value={columns}\n onChangeText={setColumns}\n />\n <Input accessibilityLabel=\"Terminal rows\" keyboardType=\"number-pad\" value={rows} onChangeText={setRows} />\n <Button\n variant=\"outline\"\n disabled={\n !Number.isInteger(Number(columns)) ||\n !Number.isInteger(Number(rows)) ||\n Number(columns) < 1 ||\n Number(rows) < 1\n }\n onPress={() => {\n void resizeRun(workspace, runKey, token, Number(columns), Number(rows), sessionId, pane).catch(\n (cause: unknown) => {\n if (!lifetime.signal.aborted) setNotice(cause instanceof Error ? cause.message : String(cause));\n },\n );\n }}\n >\n Resize terminal\n </Button>\n </View>\n ) : null}\n {notice ? <Text style={styles.meta}>{notice}</Text> : null}\n </View>\n );\n}\nfunction WorkflowArtifacts(props: WebPluginSlotProps & { run: WorkflowRunView }) {\n const { run, sessionId, openTransientTab } = props;\n const [directory, setDirectory] = useState<string>();\n const [listing, setListing] = useState<WorkflowArtifactsResponse>();\n const [error, setError] = useState<string>();\n useEffect(() => {\n let active = true;\n void fetchArtifacts(run.workspace, run.routeKey ?? run.runKey, sessionId, directory)\n .then((result) => {\n if (active) {\n if ('error' in result) setError(result.error);\n else {\n setListing(result.artifacts);\n setError(undefined);\n }\n }\n })\n .catch((cause: unknown) => {\n if (active) setError(cause instanceof Error ? cause.message : String(cause));\n });\n return () => {\n active = false;\n };\n }, [run.workspace, run.runKey, run.routeKey, sessionId, directory, run.stage]);\n return (\n <View>\n {error ? <Text style={styles.error}>{error}</Text> : null}\n {directory ? (\n <Button\n variant=\"ghost\"\n onPress={() =>\n setDirectory(directory.includes('/') ? directory.slice(0, directory.lastIndexOf('/')) : undefined)\n }\n >\n Parent directory\n </Button>\n ) : null}\n {listing?.artifacts.map((item) => (\n <ListRow\n key={item.path}\n title={\n <Button\n variant=\"ghost\"\n disabled={item.kind !== 'directory' && item.state !== 'written' && item.state !== 'empty'}\n onPress={() => {\n if (item.kind === 'directory') setDirectory(item.path);\n else {\n const workspace = run.workspace;\n const runKey = run.routeKey ?? run.runKey;\n const path = item.path;\n openTransientTab({\n id: `workflows-artifact-${workspace}-${runKey}-${path}`.replace(/[^\\w-]+/g, '-'),\n label: path,\n panel: (panelProps) => (\n <ArtifactPreview {...panelProps} workspace={workspace} runKey={runKey} path={path} />\n ),\n });\n }\n }}\n >\n {item.path}\n </Button>\n }\n description={`${item.state} · ${item.description}`}\n />\n ))}\n </View>\n );\n}\nfunction ArtifactPreview({\n sessionId,\n workspace,\n runKey,\n path,\n renderFilePreview,\n renderMediaPreview,\n nativeSaveFile,\n}: WebPluginSlotProps & { workspace: string; runKey: string; path: string }) {\n const [content, setContent] = useState<WorkflowArtifactContentResponse>();\n const [error, setError] = useState<string>();\n const [raw, setRaw] = useState(false);\n useEffect(() => {\n let active = true;\n void fetchArtifact(workspace, runKey, path, sessionId)\n .then((result) => {\n if (active) {\n if ('error' in result) setError(result.error);\n else setContent(result.artifact);\n }\n })\n .catch((cause: unknown) => {\n if (active) setError(cause instanceof Error ? cause.message : String(cause));\n });\n return () => {\n active = false;\n };\n }, [workspace, runKey, path, sessionId]);\n const downloadController = useRef<AbortController | undefined>(undefined);\n const [saving, setSaving] = useState(false);\n const [saveNote, setSaveNote] = useState<string>();\n useEffect(() => () => downloadController.current?.abort(), [workspace, runKey, path, sessionId]);\n const download = async () => {\n if (!nativeSaveFile || saving) return;\n const controller = new AbortController();\n downloadController.current = controller;\n setSaving(true);\n try {\n await nativeSaveFile(await prepareArtifactSave(workspace, runKey, path, sessionId, controller.signal));\n if (!controller.signal.aborted) setSaveNote('Saved.');\n } catch (error) {\n if (!controller.signal.aborted) setSaveNote(error instanceof Error ? error.message : String(error));\n } finally {\n setSaving(false);\n }\n };\n return (\n <ScrollView contentContainerStyle={styles.body}>\n <Text style={styles.title}>{path}</Text>\n <Button variant=\"outline\" disabled={!nativeSaveFile || saving} onPress={() => void download()}>\n Download\n </Button>\n {saving ? (\n <Button variant=\"ghost\" onPress={() => downloadController.current?.abort()}>\n Cancel download\n </Button>\n ) : null}\n {saveNote ? <Text style={styles.meta}>{saveNote}</Text> : null}\n {error ? <Text style={styles.error}>{error}</Text> : null}\n {content?.text !== undefined ? (\n <>\n <Button variant=\"outline\" onPress={() => setRaw((value) => !value)}>\n {raw ? 'Preview' : 'Raw source'}\n </Button>\n {!raw && /\\.(md|markdown)$/i.test(path) ? (\n <Markdown text={content.text} />\n ) : !raw && /\\.(html|htm)$/i.test(path) ? (\n renderFilePreview?.({ key: `${sessionId}:${workspace}:${runKey}:${path}`, html: content.text, title: path })\n ) : !raw && /\\.(csv|tsv)$/i.test(path) ? (\n <DelimitedArtifact text={content.text} delimiter={/\\.csv$/i.test(path) ? ',' : '\\t'} />\n ) : (\n <CodeBlock text={!raw && /\\.json$/i.test(path) ? prettyJson(content.text) : content.text} />\n )}\n {content.truncated ? <Text style={styles.meta}>This preview was truncated.</Text> : null}\n </>\n ) : content ? (\n <BinaryArtifactPreview\n sessionId={sessionId}\n workspace={workspace}\n runKey={runKey}\n path={path}\n renderMediaPreview={renderMediaPreview}\n />\n ) : (\n <Text style={styles.meta}>Loading preview…</Text>\n )}\n </ScrollView>\n );\n}\nfunction BinaryArtifactPreview({\n sessionId,\n workspace,\n runKey,\n path,\n renderMediaPreview,\n}: Pick<WebPluginSlotProps, 'sessionId' | 'renderMediaPreview'> & { workspace: string; runKey: string; path: string }) {\n const requestKey = JSON.stringify([sessionId, workspace, runKey, path]);\n const [loaded, setLoaded] = useState<{ key: string; media?: { data: string; mimeType: string }; error?: string }>();\n const media = loaded?.key === requestKey ? loaded.media : undefined;\n const error = loaded?.key === requestKey ? loaded.error : undefined;\n useEffect(() => {\n const controller = new AbortController();\n void fetchArtifactMedia(workspace, runKey, path, sessionId, controller.signal)\n .then((value) => {\n if (!controller.signal.aborted) setLoaded({ key: requestKey, media: value });\n })\n .catch((cause: unknown) => {\n if (!controller.signal.aborted)\n setLoaded({ key: requestKey, error: cause instanceof Error ? cause.message : String(cause) });\n });\n return () => controller.abort();\n }, [workspace, runKey, path, sessionId, requestKey]);\n return media ? (\n renderMediaPreview?.({ key: `${sessionId}:${workspace}:${runKey}:${path}`, ...media, title: path, path })\n ) : (\n <Text style={styles.meta}>{error ?? 'Loading preview…'}</Text>\n );\n}\nfunction prettyJson(text: string): string {\n try {\n return JSON.stringify(JSON.parse(text) as unknown, null, 2);\n } catch {\n return text;\n }\n}\nfunction DelimitedArtifact({ text, delimiter }: { text: string; delimiter: ',' | '\\t' }) {\n const rows: string[][] = [];\n let row: string[] = [];\n let cell = '';\n let quoted = false;\n for (let index = 0; index <= text.length && rows.length < 500; index += 1) {\n const character = text[index] ?? '\\n';\n if (quoted) {\n if (character === '\"' && text[index + 1] === '\"') {\n cell += '\"';\n index += 1;\n } else if (character === '\"') quoted = false;\n else cell += character;\n } else if (character === '\"' && cell === '') quoted = true;\n else if (character === delimiter) {\n row.push(cell);\n cell = '';\n } else if (character === '\\n') {\n row.push(cell.replace(/\\r$/, ''));\n rows.push(row);\n row = [];\n cell = '';\n } else cell += character;\n }\n return (\n <ScrollView horizontal>\n <View>\n {rows.map((cells, index) => (\n <View key={index} style={styles.tableRow}>\n {cells.map((value, column) => (\n <Text key={column} style={styles.tableCell}>\n {value}\n </Text>\n ))}\n </View>\n ))}\n </View>\n </ScrollView>\n );\n}\nconst styles = StyleSheet.create((theme) => ({\n screen: { flex: 1, backgroundColor: theme.colors.bg, padding: theme.spacing(3) },\n transcript: { flex: 1 },\n tableRow: { flexDirection: 'row' },\n tableCell: {\n color: theme.colors.text,\n fontSize: theme.fontSize.sm,\n padding: theme.spacing(2),\n width: theme.spacing(30),\n borderWidth: 1,\n borderColor: theme.colors.border,\n },\n body: { padding: theme.spacing(3), gap: theme.spacing(2) },\n title: { color: theme.colors.hi, fontSize: theme.fontSize.base, fontWeight: '600' },\n meta: { color: theme.colors.dim, fontSize: theme.fontSize.sm },\n error: { color: theme.colors.red, fontSize: theme.fontSize.sm },\n}));\n","import { defineFill } from '@agimon-ai/po-core/native';\n\nimport { WorkflowLauncher } from '../_components/WorkflowPanel.native';\nexport default defineFill({ component: WorkflowLauncher });\n","import type { WebPluginSlotProps } from '@agimon-ai/po-core/native';\nimport { ArrowRightIcon, Button, Dot, fontOf, ListRow } from '@agimon-ai/po-native-components';\nimport type { PoNativeTheme } from '@agimon-ai/po-web-components/nativeTheme';\nimport { useEffect, useState } from 'react';\nimport { Pressable, Text, View } from 'react-native';\nimport { StyleSheet } from 'react-native-unistyles';\n\nimport { useWorkflows, workflowTab } from '../../_components/WorkflowPanel.native';\nimport { openCatalog } from '../../_lib/catalogStore.native';\nimport {\n workflowActivityGroups,\n workflowActivityRows,\n type WorkflowActivityGroupName,\n} from '../../_lib/workflowActivity';\nimport { focusRun } from '../../_lib/workflowsStore.native';\n\nexport function WorkflowsActivitySection({ sessionId, openSession, openTransientTab }: WebPluginSlotProps) {\n const state = useWorkflows(sessionId);\n const [now, setNow] = useState(() => Date.now());\n const [folded, setFolded] = useState<Partial<Record<WorkflowActivityGroupName, boolean>>>({});\n useEffect(() => {\n const timer = setInterval(() => setNow(Date.now()), 10_000);\n return () => clearInterval(timer);\n }, []);\n const groups = workflowActivityGroups(workflowActivityRows(state.runs, now, sessionId));\n return (\n <View>\n {groups.map((group) => {\n const open = folded[group.name] ?? group.openByDefault;\n return (\n <View key={group.name}>\n <Button\n variant=\"ghost\"\n accessibilityState={{ expanded: open }}\n onPress={() => setFolded((current) => ({ ...current, [group.name]: !open }))}\n >\n {group.name} · {group.rows.length}\n </Button>\n {open\n ? group.rows.map((row) => (\n <ListRow\n key={row.identity}\n leading={\n <Dot\n tone={\n row.tone === 'failed'\n ? 'red'\n : row.tone === 'running' || row.tone === 'paused'\n ? 'yellow'\n : row.tone === 'done'\n ? 'green'\n : 'muted'\n }\n />\n }\n title={\n <Button\n variant=\"ghost\"\n testID={`activity-workflow-${row.runKey}`}\n onPress={() => {\n if (row.ownerSessionId && openSession) {\n openSession(row.ownerSessionId);\n return;\n }\n const run = state.runs.find(\n (item) => `${item.workspace}/${item.routeKey ?? item.runKey}` === row.identity,\n );\n if (sessionId !== null) focusRun(sessionId, row.identity);\n if (run) openTransientTab(workflowTab(run));\n }}\n >\n {row.name}\n </Button>\n }\n description={`${row.detail} · ${row.elapsed}`}\n />\n ))\n : null}\n </View>\n );\n })}\n {groups.length === 0 ? (\n // The cockpit's idle line: the status, then the one jade action beside it.\n <View style={styles.idle}>\n <Text style={styles.status}>Idle</Text>\n <Pressable\n accessibilityRole=\"button\"\n accessibilityState={{ disabled: sessionId === null }}\n testID=\"activity-workflow-launch\"\n disabled={sessionId === null}\n hitSlop={10}\n onPress={() => {\n if (sessionId !== null) openCatalog(sessionId);\n }}\n style={styles.action}\n >\n <Text style={styles.actionText(sessionId === null)}>Launch a workflow</Text>\n <ArrowRightIcon size={14} color={sessionId === null ? 'dim' : 'green'} />\n </Pressable>\n </View>\n ) : null}\n </View>\n );\n}\n\nconst styles = StyleSheet.create((theme: PoNativeTheme) => ({\n idle: { flexDirection: 'row', alignItems: 'center', flexWrap: 'wrap', gap: theme.spacing(4) },\n status: {\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.sm,\n lineHeight: theme.lineHeight.sm,\n color: theme.colors.dim,\n },\n action: { flexDirection: 'row', alignItems: 'center', gap: theme.spacing(1) },\n actionText: (disabled: boolean) => ({\n fontFamily: fontOf(theme.fontFamily.sans),\n fontSize: theme.fontSize.base,\n lineHeight: theme.lineHeight.base,\n fontWeight: theme.fontWeight.medium,\n color: disabled ? theme.colors.dim : theme.colors.green,\n }),\n}));\n","import { defineFill } from '@agimon-ai/po-core/native';\n\nimport { WorkflowsActivitySection } from './_components/WorkflowsActivitySection.native';\nexport default defineFill({ component: WorkflowsActivitySection });\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineNativePlugin, type WebPluginContributions } from '@agimon-ai/po-core/native';\n\nimport fillWorkflows from '../src/extensions/workspaces/(frontend)/fill/Workflows.home.native';\nimport activityGroupWorkflows from '../src/extensions/workspaces/sessions/(frontend)/activity-group/workflows.native';\nimport channelWorkflowCatalog from '../src/extensions/workspaces/sessions/(frontend)/channel/workflow-catalog.native';\nimport channelWorkflowRuns from '../src/extensions/workspaces/sessions/(frontend)/channel/workflow-runs.native';\nimport fillWorkflowLauncher from '../src/extensions/workspaces/sessions/(frontend)/fill/WorkflowLauncher.overlay.native';\nimport fillWorkflows2 from '../src/extensions/workspaces/sessions/(frontend)/fill/Workflows.activity.workflows.native';\n\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const nativePlugin = defineNativePlugin({\n id: 'workflows',\n workspace: {\n get fills(): WebPluginContributions['fills'] { return [via({ slot: 'home', id: 'workflows' }, fillWorkflows)]; },\n },\n session: {\n get activityGroups(): WebPluginContributions['activityGroups'] { return [via({ name: 'workflows' }, activityGroupWorkflows)]; },\n get channels(): WebPluginContributions['channels'] { return [via({ channel: 'workflow_catalog' }, channelWorkflowCatalog), via({ channel: 'workflow_runs' }, channelWorkflowRuns)]; },\n get fills(): WebPluginContributions['fills'] { return [via({ slot: 'overlay', id: 'workflow-launcher' }, fillWorkflowLauncher), via({ slot: 'activity.workflows', id: 'workflows' }, fillWorkflows2)]; },\n },\n});\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agimon-ai/po-workflow",
3
- "version": "0.0.0-alpha.22",
3
+ "version": "0.0.0-alpha.23",
4
4
  "description": "GitHub Actions-style workflow graphs, artifacts, recovery, and asynchronous runs for Po.",
5
5
  "keywords": [
6
6
  "ai",
@@ -63,12 +63,12 @@
63
63
  "access": "public"
64
64
  },
65
65
  "dependencies": {
66
- "@agimon-ai/po-core": "0.0.0-alpha.22",
67
- "@agimon-ai/po-minor-mode": "0.0.0-alpha.22",
68
- "@agimon-ai/po-telemetry": "0.0.0-alpha.22",
69
- "@agimon-ai/po-ui": "0.0.0-alpha.22",
70
- "@agimon-ai/po-web-components": "0.0.0-alpha.22",
71
- "@agimon-ai/po-web-security": "0.0.0-alpha.22",
66
+ "@agimon-ai/po-core": "0.0.0-alpha.23",
67
+ "@agimon-ai/po-minor-mode": "0.0.0-alpha.23",
68
+ "@agimon-ai/po-telemetry": "0.0.0-alpha.23",
69
+ "@agimon-ai/po-ui": "0.0.0-alpha.23",
70
+ "@agimon-ai/po-web-components": "0.0.0-alpha.23",
71
+ "@agimon-ai/po-web-security": "0.0.0-alpha.23",
72
72
  "@agimon-ai/workflow-mcp": "0.24.13",
73
73
  "@deepseek-ai/cordis": "4.0.5",
74
74
  "@modelcontextprotocol/server": "2.3.1",
@@ -77,8 +77,8 @@
77
77
  "zod": "4.6.7"
78
78
  },
79
79
  "devDependencies": {
80
- "@agimon-ai/po-build": "0.0.0-alpha.22",
81
- "@agimon-ai/po-native-components": "0.0.0-alpha.22",
80
+ "@agimon-ai/po-build": "0.0.0-alpha.23",
81
+ "@agimon-ai/po-native-components": "0.0.0-alpha.23",
82
82
  "@babel/core": "7.29.7",
83
83
  "@earendil-works/pi-coding-agent": "1.3.0",
84
84
  "@tanstack/react-store": "0.11.2",