create-expert 0.0.29 → 0.0.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin/cli.js CHANGED
@@ -33528,7 +33528,26 @@ var getInstance = (stdout, createInstance, concurrent) => {
33528
33528
  };
33529
33529
 
33530
33530
  // ../../node_modules/.pnpm/ink@6.7.0_@types+react@19.2.14_react@19.2.4/node_modules/ink/build/components/Static.js
33531
- __toESM(require_react(), 1);
33531
+ var import_react16 = __toESM(require_react(), 1);
33532
+ function Static(props) {
33533
+ const { items, children: render2, style: customStyle } = props;
33534
+ const [index, setIndex] = (0, import_react16.useState)(0);
33535
+ const itemsToRender = (0, import_react16.useMemo)(() => {
33536
+ return items.slice(index);
33537
+ }, [items, index]);
33538
+ (0, import_react16.useLayoutEffect)(() => {
33539
+ setIndex(items.length);
33540
+ }, [items.length]);
33541
+ const children = itemsToRender.map((item, itemIndex) => {
33542
+ return render2(item, index + itemIndex);
33543
+ });
33544
+ const style = (0, import_react16.useMemo)(() => ({
33545
+ position: "absolute",
33546
+ flexDirection: "column",
33547
+ ...customStyle
33548
+ }), [customStyle]);
33549
+ return import_react16.default.createElement("ink-box", { internal_static: true, style }, children);
33550
+ }
33532
33551
 
33533
33552
  // ../../node_modules/.pnpm/ink@6.7.0_@types+react@19.2.14_react@19.2.4/node_modules/ink/build/components/Transform.js
33534
33553
  __toESM(require_react(), 1);
@@ -34123,46 +34142,8 @@ var EventQueue = class _EventQueue {
34123
34142
  }
34124
34143
  };
34125
34144
 
34126
- // ../../packages/tui-components/src/components/browser-router.tsx
34127
- var import_react41 = __toESM(require_react(), 1);
34128
-
34129
- // ../../packages/tui-components/src/context/input-area-context.tsx
34130
- var import_react29 = __toESM(require_react(), 1);
34131
- var InputAreaContext = (0, import_react29.createContext)(null);
34132
- var InputAreaProvider = InputAreaContext.Provider;
34133
- var useInputAreaContext = () => {
34134
- const context = (0, import_react29.useContext)(InputAreaContext);
34135
- if (!context) {
34136
- throw new Error("useInputAreaContext must be used within InputAreaProvider");
34137
- }
34138
- return context;
34139
- };
34140
-
34141
- // ../../packages/tui-components/src/helpers.ts
34142
- var truncateText = (text, maxLength) => {
34143
- if (text.length <= maxLength) return text;
34144
- return `${text.slice(0, maxLength)}...`;
34145
- };
34146
- var assertNever = (x) => {
34147
- throw new Error(`Unexpected value: ${x}`);
34148
- };
34149
- var formatTimestamp = (timestamp) => new Date(timestamp).toLocaleString();
34150
- var shortenPath = (fullPath, maxLength = 60) => {
34151
- if (fullPath.length <= maxLength) return fullPath;
34152
- const parts = fullPath.split("/");
34153
- if (parts.length <= 2) return fullPath;
34154
- const filename = parts[parts.length - 1] ?? "";
34155
- const parentDir = parts[parts.length - 2] ?? "";
34156
- const shortened = `.../${parentDir}/${filename}`;
34157
- if (shortened.length <= maxLength) return shortened;
34158
- return `.../${filename}`;
34159
- };
34160
- var summarizeOutput = (lines, maxLines) => {
34161
- const filtered = lines.filter((l) => l.trim());
34162
- const visible = filtered.slice(0, maxLines);
34163
- const remaining = filtered.length - visible.length;
34164
- return { visible, remaining };
34165
- };
34145
+ // ../../packages/tui-components/src/execution/app.tsx
34146
+ var import_react46 = __toESM(require_react(), 1);
34166
34147
 
34167
34148
  // ../../packages/tui-components/src/constants.ts
34168
34149
  var UI_CONSTANTS = {
@@ -34174,7 +34155,6 @@ var RENDER_CONSTANTS = {
34174
34155
  NEW_TODO_MAX_PREVIEW: 3};
34175
34156
  var INDICATOR = {
34176
34157
  BULLET: "\u25CF",
34177
- TREE: "\u2514",
34178
34158
  ELLIPSIS: "..."
34179
34159
  };
34180
34160
  var STOP_EVENT_TYPES = [
@@ -34194,6 +34174,8 @@ var KEY_BINDINGS = {
34194
34174
  CHECKPOINTS: "c",
34195
34175
  EVENTS: "e",
34196
34176
  RESUME: "Enter"};
34177
+ var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
34178
+ var USAGE_INDICATORS = { LOW: "\u25D4", MEDIUM: "\u25D1", HIGH: "\u25D5", FULL: "\u25CF" };
34197
34179
  var KEY_HINTS = {
34198
34180
  NAVIGATE: `${KEY_BINDINGS.NAVIGATE_UP}${KEY_BINDINGS.NAVIGATE_DOWN}:Navigate`,
34199
34181
  SELECT: `${KEY_BINDINGS.SELECT}:Select`,
@@ -34206,6 +34188,66 @@ var KEY_HINTS = {
34206
34188
  CHECKPOINTS: `${KEY_BINDINGS.CHECKPOINTS}:Checkpoints`,
34207
34189
  EVENTS: `${KEY_BINDINGS.EVENTS}:Events`};
34208
34190
 
34191
+ // ../../packages/tui-components/src/components/action-row.tsx
34192
+ var import_jsx_runtime = __toESM(require_jsx_runtime(), 1);
34193
+ var ActionRowSimple = ({
34194
+ indicatorColor,
34195
+ text,
34196
+ textDimColor = false
34197
+ }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box_default, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { flexDirection: "row", gap: 1, children: [
34198
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: indicatorColor, children: INDICATOR.BULLET }),
34199
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "white", dimColor: textDimColor, children: text })
34200
+ ] }) });
34201
+ var ActionRow = ({ indicatorColor, label, summary, children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { flexDirection: "column", marginBottom: 1, children: [
34202
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { flexDirection: "row", gap: 1, children: [
34203
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: indicatorColor, children: INDICATOR.BULLET }),
34204
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "white", children: label }),
34205
+ summary && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "white", dimColor: true, children: summary })
34206
+ ] }),
34207
+ children
34208
+ ] });
34209
+
34210
+ // ../../packages/tui-components/src/components/browser-router.tsx
34211
+ var import_react41 = __toESM(require_react(), 1);
34212
+
34213
+ // ../../packages/tui-components/src/context/input-area-context.tsx
34214
+ var import_react29 = __toESM(require_react(), 1);
34215
+ var InputAreaContext = (0, import_react29.createContext)(null);
34216
+ var InputAreaProvider = InputAreaContext.Provider;
34217
+ var useInputAreaContext = () => {
34218
+ const context = (0, import_react29.useContext)(InputAreaContext);
34219
+ if (!context) {
34220
+ throw new Error("useInputAreaContext must be used within InputAreaProvider");
34221
+ }
34222
+ return context;
34223
+ };
34224
+
34225
+ // ../../packages/tui-components/src/helpers.ts
34226
+ var truncateText = (text, maxLength) => {
34227
+ if (text.length <= maxLength) return text;
34228
+ return `${text.slice(0, maxLength)}...`;
34229
+ };
34230
+ var assertNever = (x) => {
34231
+ throw new Error(`Unexpected value: ${x}`);
34232
+ };
34233
+ var formatTimestamp = (timestamp) => new Date(timestamp).toLocaleString();
34234
+ var shortenPath = (fullPath, maxLength = 60) => {
34235
+ if (fullPath.length <= maxLength) return fullPath;
34236
+ const parts = fullPath.split("/");
34237
+ if (parts.length <= 2) return fullPath;
34238
+ const filename = parts[parts.length - 1] ?? "";
34239
+ const parentDir = parts[parts.length - 2] ?? "";
34240
+ const shortened = `.../${parentDir}/${filename}`;
34241
+ if (shortened.length <= maxLength) return shortened;
34242
+ return `.../${filename}`;
34243
+ };
34244
+ var summarizeOutput = (lines, maxLines) => {
34245
+ const filtered = lines.filter((l) => l.trim());
34246
+ const visible = filtered.slice(0, maxLines);
34247
+ const remaining = filtered.length - visible.length;
34248
+ return { visible, remaining };
34249
+ };
34250
+
34209
34251
  // ../../packages/tui-components/src/components/list-browser.tsx
34210
34252
  var import_react31 = __toESM(require_react(), 1);
34211
34253
 
@@ -34245,7 +34287,7 @@ var useListNavigation = (options) => {
34245
34287
  };
34246
34288
 
34247
34289
  // ../../packages/tui-components/src/components/list-browser.tsx
34248
- var import_jsx_runtime = __toESM(require_jsx_runtime(), 1);
34290
+ var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1);
34249
34291
  var ListBrowser = ({
34250
34292
  title,
34251
34293
  items,
@@ -34274,10 +34316,10 @@ var ListBrowser = ({
34274
34316
  }, [items, selectedIndex, maxItems]);
34275
34317
  const hasMoreAbove = scrollOffset > 0;
34276
34318
  const hasMoreBelow = scrollOffset + maxItems < items.length;
34277
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { flexDirection: "column", children: [
34278
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { children: [
34279
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "cyan", children: title }),
34280
- items.length > maxItems && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { color: "gray", children: [
34319
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { flexDirection: "column", children: [
34320
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Box_default, { children: [
34321
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: "cyan", children: title }),
34322
+ items.length > maxItems && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { color: "gray", children: [
34281
34323
  " ",
34282
34324
  "(",
34283
34325
  selectedIndex + 1,
@@ -34286,17 +34328,17 @@ var ListBrowser = ({
34286
34328
  ")"
34287
34329
  ] })
34288
34330
  ] }),
34289
- hasMoreAbove && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "gray", children: INDICATOR.ELLIPSIS }),
34290
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box_default, { flexDirection: "column", children: displayItems.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "gray", children: emptyMessage }) : displayItems.map((item, index) => {
34331
+ hasMoreAbove && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: "gray", children: INDICATOR.ELLIPSIS }),
34332
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Box_default, { flexDirection: "column", children: displayItems.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: "gray", children: emptyMessage }) : displayItems.map((item, index) => {
34291
34333
  const actualIndex = scrollOffset + index;
34292
34334
  return renderItem(item, actualIndex === selectedIndex, actualIndex);
34293
34335
  }) }),
34294
- hasMoreBelow && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "gray", children: INDICATOR.ELLIPSIS })
34336
+ hasMoreBelow && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Text, { color: "gray", children: INDICATOR.ELLIPSIS })
34295
34337
  ] });
34296
34338
  };
34297
34339
 
34298
34340
  // ../../packages/tui-components/src/components/input-areas/browsing-checkpoints.tsx
34299
- var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1);
34341
+ var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1);
34300
34342
  var BrowsingCheckpointsInput = ({
34301
34343
  job,
34302
34344
  checkpoints,
@@ -34304,7 +34346,7 @@ var BrowsingCheckpointsInput = ({
34304
34346
  onCheckpointResume,
34305
34347
  onBack,
34306
34348
  showEventsHint = true
34307
- }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
34349
+ }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
34308
34350
  ListBrowser,
34309
34351
  {
34310
34352
  title: `Checkpoints for ${job.expertKey} ${KEY_HINTS.NAVIGATE} ${KEY_HINTS.RESUME} ${showEventsHint ? KEY_HINTS.EVENTS : ""} ${KEY_HINTS.BACK}`.trim(),
@@ -34319,7 +34361,7 @@ var BrowsingCheckpointsInput = ({
34319
34361
  }
34320
34362
  return false;
34321
34363
  },
34322
- renderItem: (cp, isSelected) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Text, { color: isSelected ? "cyan" : "gray", children: [
34364
+ renderItem: (cp, isSelected) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { color: isSelected ? "cyan" : "gray", children: [
34323
34365
  isSelected ? ">" : " ",
34324
34366
  " Step ",
34325
34367
  cp.stepNumber,
@@ -34331,54 +34373,54 @@ var BrowsingCheckpointsInput = ({
34331
34373
  );
34332
34374
 
34333
34375
  // ../../packages/tui-components/src/components/input-areas/browsing-event-detail.tsx
34334
- var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1);
34376
+ var import_jsx_runtime4 = __toESM(require_jsx_runtime(), 1);
34335
34377
  var BrowsingEventDetailInput = ({ event, onBack }) => {
34336
34378
  use_input_default((input, key) => {
34337
34379
  if (input === "b" || key.escape) {
34338
34380
  onBack();
34339
34381
  }
34340
34382
  });
34341
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Box_default, { flexDirection: "column", paddingX: 1, children: [
34342
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Box_default, { marginBottom: 1, children: [
34343
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { bold: true, children: "Event Detail" }),
34344
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { dimColor: true, children: [
34383
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Box_default, { flexDirection: "column", paddingX: 1, children: [
34384
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Box_default, { marginBottom: 1, children: [
34385
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { bold: true, children: "Event Detail" }),
34386
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { dimColor: true, children: [
34345
34387
  " ",
34346
34388
  KEY_HINTS.BACK
34347
34389
  ] })
34348
34390
  ] }),
34349
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Box_default, { flexDirection: "column", marginLeft: 2, children: [
34350
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { children: [
34351
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: "gray", children: "Type: " }),
34352
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: "cyan", children: event.type })
34391
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Box_default, { flexDirection: "column", marginLeft: 2, children: [
34392
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { children: [
34393
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: "gray", children: "Type: " }),
34394
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: "cyan", children: event.type })
34353
34395
  ] }),
34354
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { children: [
34355
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: "gray", children: "Step: " }),
34356
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { children: event.stepNumber })
34396
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { children: [
34397
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: "gray", children: "Step: " }),
34398
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { children: event.stepNumber })
34357
34399
  ] }),
34358
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { children: [
34359
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: "gray", children: "Timestamp: " }),
34360
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { children: formatTimestamp(event.timestamp) })
34400
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { children: [
34401
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: "gray", children: "Timestamp: " }),
34402
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { children: formatTimestamp(event.timestamp) })
34361
34403
  ] }),
34362
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { children: [
34363
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: "gray", children: "ID: " }),
34364
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { dimColor: true, children: event.id })
34404
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { children: [
34405
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: "gray", children: "ID: " }),
34406
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { dimColor: true, children: event.id })
34365
34407
  ] }),
34366
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { children: [
34367
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: "gray", children: "Run ID: " }),
34368
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { dimColor: true, children: event.runId })
34408
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { children: [
34409
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: "gray", children: "Run ID: " }),
34410
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { dimColor: true, children: event.runId })
34369
34411
  ] })
34370
34412
  ] })
34371
34413
  ] });
34372
34414
  };
34373
34415
 
34374
34416
  // ../../packages/tui-components/src/components/input-areas/browsing-events.tsx
34375
- var import_jsx_runtime4 = __toESM(require_jsx_runtime(), 1);
34417
+ var import_jsx_runtime5 = __toESM(require_jsx_runtime(), 1);
34376
34418
  var BrowsingEventsInput = ({
34377
34419
  checkpoint,
34378
34420
  events,
34379
34421
  onEventSelect,
34380
34422
  onBack
34381
- }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
34423
+ }) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
34382
34424
  ListBrowser,
34383
34425
  {
34384
34426
  title: `Events for Step ${checkpoint.stepNumber} ${KEY_HINTS.NAVIGATE} ${KEY_HINTS.SELECT} ${KEY_HINTS.BACK}`,
@@ -34386,7 +34428,7 @@ var BrowsingEventsInput = ({
34386
34428
  onSelect: onEventSelect,
34387
34429
  onBack,
34388
34430
  emptyMessage: "No events found",
34389
- renderItem: (ev, isSelected) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { color: isSelected ? "cyan" : "gray", children: [
34431
+ renderItem: (ev, isSelected) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: isSelected ? "cyan" : "gray", children: [
34390
34432
  isSelected ? ">" : " ",
34391
34433
  " [",
34392
34434
  ev.type,
@@ -35023,6 +35065,7 @@ var useTextInput = (options) => {
35023
35065
  const inputRef = useLatestRef(input);
35024
35066
  const onSubmitRef = useLatestRef(options.onSubmit);
35025
35067
  const onCancelRef = useLatestRef(options.onCancel);
35068
+ const canSubmitRef = useLatestRef(options.canSubmit ?? true);
35026
35069
  const handleInput = (0, import_react38.useCallback)(
35027
35070
  (inputChar, key) => {
35028
35071
  if (key.escape) {
@@ -35030,7 +35073,7 @@ var useTextInput = (options) => {
35030
35073
  onCancelRef.current?.();
35031
35074
  return;
35032
35075
  }
35033
- if (key.return && inputRef.current.trim()) {
35076
+ if (key.return && inputRef.current.trim() && canSubmitRef.current) {
35034
35077
  onSubmitRef.current(inputRef.current.trim());
35035
35078
  setInput("");
35036
35079
  return;
@@ -35043,7 +35086,7 @@ var useTextInput = (options) => {
35043
35086
  setInput((prev) => prev + inputChar);
35044
35087
  }
35045
35088
  },
35046
- [inputRef, onSubmitRef, onCancelRef]
35089
+ [inputRef, onSubmitRef, onCancelRef, canSubmitRef]
35047
35090
  );
35048
35091
  const reset = (0, import_react38.useCallback)(() => {
35049
35092
  setInput("");
@@ -35090,7 +35133,7 @@ var useExpertSelector = (options) => {
35090
35133
  };
35091
35134
 
35092
35135
  // ../../packages/tui-components/src/components/expert-list.tsx
35093
- var import_jsx_runtime5 = __toESM(require_jsx_runtime(), 1);
35136
+ var import_jsx_runtime6 = __toESM(require_jsx_runtime(), 1);
35094
35137
  var ExpertList = ({
35095
35138
  experts,
35096
35139
  selectedIndex,
@@ -35100,15 +35143,15 @@ var ExpertList = ({
35100
35143
  }) => {
35101
35144
  const displayExperts = maxItems ? experts.slice(0, maxItems) : experts;
35102
35145
  if (displayExperts.length === 0) {
35103
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "gray", children: "No experts found." });
35146
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "gray", children: "No experts found." });
35104
35147
  }
35105
- const items = displayExperts.map((expert, index) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: index === selectedIndex ? "cyan" : "gray", children: [
35148
+ const items = displayExperts.map((expert, index) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { color: index === selectedIndex ? "cyan" : "gray", children: [
35106
35149
  index === selectedIndex ? ">" : " ",
35107
35150
  " ",
35108
35151
  showSource ? expert.key : expert.name,
35109
- showSource && expert.source && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
35152
+ showSource && expert.source && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
35110
35153
  " ",
35111
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: expert.source === "configured" ? "green" : "yellow", children: [
35154
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Text, { color: expert.source === "configured" ? "green" : "yellow", children: [
35112
35155
  "[",
35113
35156
  expert.source === "configured" ? "config" : "recent",
35114
35157
  "]"
@@ -35116,11 +35159,11 @@ var ExpertList = ({
35116
35159
  ] }),
35117
35160
  inline ? " " : ""
35118
35161
  ] }, expert.key));
35119
- return inline ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Box_default, { children: items }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Box_default, { flexDirection: "column", children: items });
35162
+ return inline ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Box_default, { children: items }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Box_default, { flexDirection: "column", children: items });
35120
35163
  };
35121
35164
 
35122
35165
  // ../../packages/tui-components/src/components/expert-selector-base.tsx
35123
- var import_jsx_runtime6 = __toESM(require_jsx_runtime(), 1);
35166
+ var import_jsx_runtime7 = __toESM(require_jsx_runtime(), 1);
35124
35167
  var ExpertSelectorBase = ({
35125
35168
  experts,
35126
35169
  hint,
@@ -35136,10 +35179,10 @@ var ExpertSelectorBase = ({
35136
35179
  extraKeyHandler
35137
35180
  });
35138
35181
  use_input_default(handleKeyInput);
35139
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Box_default, { flexDirection: inline ? "row" : "column", children: [
35140
- !inputMode && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Box_default, { flexDirection: "column", children: [
35141
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "cyan", children: hint }) }),
35142
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
35182
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Box_default, { flexDirection: inline ? "row" : "column", children: [
35183
+ !inputMode && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Box_default, { flexDirection: "column", children: [
35184
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: "cyan", children: hint }) }),
35185
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
35143
35186
  ExpertList,
35144
35187
  {
35145
35188
  experts,
@@ -35150,16 +35193,16 @@ var ExpertSelectorBase = ({
35150
35193
  }
35151
35194
  )
35152
35195
  ] }),
35153
- inputMode && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Box_default, { children: [
35154
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "gray", children: "Expert: " }),
35155
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "white", children: input }),
35156
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Text, { color: "cyan", children: "_" })
35196
+ inputMode && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Box_default, { children: [
35197
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: "gray", children: "Expert: " }),
35198
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: "white", children: input }),
35199
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { color: "cyan", children: "_" })
35157
35200
  ] })
35158
35201
  ] });
35159
35202
  };
35160
35203
 
35161
35204
  // ../../packages/tui-components/src/components/input-areas/browsing-experts.tsx
35162
- var import_jsx_runtime7 = __toESM(require_jsx_runtime(), 1);
35205
+ var import_jsx_runtime8 = __toESM(require_jsx_runtime(), 1);
35163
35206
  var BrowsingExpertsInput = ({
35164
35207
  experts,
35165
35208
  onExpertSelect,
@@ -35176,7 +35219,7 @@ var BrowsingExpertsInput = ({
35176
35219
  [onSwitchToHistory]
35177
35220
  );
35178
35221
  const hint = `Experts ${KEY_HINTS.NAVIGATE} ${KEY_HINTS.SELECT} ${KEY_HINTS.INPUT} ${KEY_HINTS.HISTORY} ${KEY_HINTS.CANCEL}`;
35179
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
35222
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
35180
35223
  ExpertSelectorBase,
35181
35224
  {
35182
35225
  experts,
@@ -35190,13 +35233,13 @@ var BrowsingExpertsInput = ({
35190
35233
  };
35191
35234
 
35192
35235
  // ../../packages/tui-components/src/components/input-areas/browsing-history.tsx
35193
- var import_jsx_runtime8 = __toESM(require_jsx_runtime(), 1);
35236
+ var import_jsx_runtime9 = __toESM(require_jsx_runtime(), 1);
35194
35237
  var BrowsingHistoryInput = ({
35195
35238
  jobs,
35196
35239
  onJobSelect,
35197
35240
  onJobResume,
35198
35241
  onSwitchToExperts
35199
- }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
35242
+ }) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
35200
35243
  ListBrowser,
35201
35244
  {
35202
35245
  title: `Job History ${KEY_HINTS.NAVIGATE} ${KEY_HINTS.RESUME} ${KEY_HINTS.CHECKPOINTS} ${KEY_HINTS.NEW}`,
@@ -35214,7 +35257,7 @@ var BrowsingHistoryInput = ({
35214
35257
  }
35215
35258
  return false;
35216
35259
  },
35217
- renderItem: (job, isSelected) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Text, { color: isSelected ? "cyan" : "gray", children: [
35260
+ renderItem: (job, isSelected) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { color: isSelected ? "cyan" : "gray", children: [
35218
35261
  isSelected ? ">" : " ",
35219
35262
  " ",
35220
35263
  job.expertKey,
@@ -35230,7 +35273,7 @@ var BrowsingHistoryInput = ({
35230
35273
  );
35231
35274
 
35232
35275
  // ../../packages/tui-components/src/components/browser-router.tsx
35233
- var import_jsx_runtime9 = __toESM(require_jsx_runtime(), 1);
35276
+ var import_jsx_runtime10 = __toESM(require_jsx_runtime(), 1);
35234
35277
  var BrowserRouter = ({ inputState, showEventsHint = true }) => {
35235
35278
  const ctx = useInputAreaContext();
35236
35279
  const handleEventSelect = (0, import_react41.useCallback)(
@@ -35243,7 +35286,7 @@ var BrowserRouter = ({ inputState, showEventsHint = true }) => {
35243
35286
  );
35244
35287
  switch (inputState.type) {
35245
35288
  case "browsingHistory":
35246
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
35289
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
35247
35290
  BrowsingHistoryInput,
35248
35291
  {
35249
35292
  jobs: inputState.jobs,
@@ -35253,7 +35296,7 @@ var BrowserRouter = ({ inputState, showEventsHint = true }) => {
35253
35296
  }
35254
35297
  );
35255
35298
  case "browsingExperts":
35256
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
35299
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
35257
35300
  BrowsingExpertsInput,
35258
35301
  {
35259
35302
  experts: inputState.experts,
@@ -35262,7 +35305,7 @@ var BrowserRouter = ({ inputState, showEventsHint = true }) => {
35262
35305
  }
35263
35306
  );
35264
35307
  case "browsingCheckpoints":
35265
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
35308
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
35266
35309
  BrowsingCheckpointsInput,
35267
35310
  {
35268
35311
  job: inputState.job,
@@ -35274,7 +35317,7 @@ var BrowserRouter = ({ inputState, showEventsHint = true }) => {
35274
35317
  }
35275
35318
  );
35276
35319
  case "browsingEvents":
35277
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
35320
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
35278
35321
  BrowsingEventsInput,
35279
35322
  {
35280
35323
  checkpoint: inputState.checkpoint,
@@ -35284,34 +35327,12 @@ var BrowserRouter = ({ inputState, showEventsHint = true }) => {
35284
35327
  }
35285
35328
  );
35286
35329
  case "browsingEventDetail":
35287
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(BrowsingEventDetailInput, { event: inputState.selectedEvent, onBack: ctx.onBack });
35330
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(BrowsingEventDetailInput, { event: inputState.selectedEvent, onBack: ctx.onBack });
35288
35331
  default:
35289
35332
  return assertNever(inputState);
35290
35333
  }
35291
35334
  };
35292
35335
 
35293
- // ../../packages/tui-components/src/components/action-row.tsx
35294
- var import_jsx_runtime10 = __toESM(require_jsx_runtime(), 1);
35295
- var ActionRowSimple = ({
35296
- indicatorColor,
35297
- text,
35298
- textDimColor = false
35299
- }) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Box_default, { flexDirection: "column", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Box_default, { flexDirection: "row", children: [
35300
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Box_default, { paddingRight: 1, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text, { color: indicatorColor, children: INDICATOR.BULLET }) }),
35301
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text, { color: "white", dimColor: textDimColor, children: text })
35302
- ] }) });
35303
- var ActionRow = ({ indicatorColor, label, summary, children }) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Box_default, { flexDirection: "column", children: [
35304
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Box_default, { flexDirection: "row", gap: 1, children: [
35305
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text, { color: indicatorColor, children: INDICATOR.BULLET }),
35306
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text, { color: "white", children: label }),
35307
- summary && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text, { color: "white", dimColor: true, children: summary })
35308
- ] }),
35309
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Box_default, { flexDirection: "row", children: [
35310
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Box_default, { paddingRight: 1, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text, { dimColor: true, children: INDICATOR.TREE }) }),
35311
- children
35312
- ] })
35313
- ] });
35314
-
35315
35336
  // ../../packages/tui-components/src/components/checkpoint-action-row.tsx
35316
35337
  var import_jsx_runtime11 = __toESM(require_jsx_runtime(), 1);
35317
35338
  var CheckpointActionRow = ({ action }) => {
@@ -35511,25 +35532,116 @@ function renderQuery(text, runId) {
35511
35532
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ActionRow, { indicatorColor: "cyan", label: "Query", summary: `(${shortRunId})`, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box_default, { flexDirection: "column", children: lines.map((line, idx) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { dimColor: true, wrap: "wrap", children: line }, `query-${idx}`)) }) });
35512
35533
  }
35513
35534
 
35514
- // ../../packages/tui-components/src/components/run-setting.tsx
35535
+ // ../../packages/tui-components/src/execution/components/activity-log-panel.tsx
35515
35536
  var import_jsx_runtime12 = __toESM(require_jsx_runtime(), 1);
35516
- var RunSetting = ({
35517
- info,
35518
- eventCount,
35519
- isEditing,
35520
- expertName,
35521
- onQuerySubmit
35537
+ function getActivityProps(activityOrGroup) {
35538
+ if (activityOrGroup.type === "parallelGroup") {
35539
+ const group = activityOrGroup;
35540
+ const firstActivity = group.activities[0];
35541
+ return {
35542
+ runId: group.runId,
35543
+ expertKey: group.expertKey,
35544
+ delegatedBy: firstActivity?.delegatedBy
35545
+ };
35546
+ }
35547
+ return activityOrGroup;
35548
+ }
35549
+ var ActivityLogItem = ({ activity }) => {
35550
+ const { delegatedBy, expertKey } = getActivityProps(activity);
35551
+ if (delegatedBy) {
35552
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Box_default, { marginLeft: 1, flexDirection: "column", children: [
35553
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { dimColor: true, bold: true, children: [
35554
+ "[",
35555
+ expertKey,
35556
+ "]"
35557
+ ] }),
35558
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(CheckpointActionRow, { action: activity })
35559
+ ] });
35560
+ }
35561
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(CheckpointActionRow, { action: activity });
35562
+ };
35563
+
35564
+ // ../../packages/tui-components/src/execution/hooks/use-spinner.ts
35565
+ var import_react42 = __toESM(require_react(), 1);
35566
+ var useSpinner = ({ isActive }) => {
35567
+ const [index, setIndex] = (0, import_react42.useState)(0);
35568
+ const intervalRef = (0, import_react42.useRef)(null);
35569
+ (0, import_react42.useEffect)(() => {
35570
+ if (isActive) {
35571
+ intervalRef.current = setInterval(() => {
35572
+ setIndex((prev) => (prev + 1) % SPINNER_FRAMES.length);
35573
+ }, 80);
35574
+ } else {
35575
+ if (intervalRef.current) {
35576
+ clearInterval(intervalRef.current);
35577
+ intervalRef.current = null;
35578
+ }
35579
+ setIndex(0);
35580
+ }
35581
+ return () => {
35582
+ if (intervalRef.current) {
35583
+ clearInterval(intervalRef.current);
35584
+ intervalRef.current = null;
35585
+ }
35586
+ };
35587
+ }, [isActive]);
35588
+ if (!isActive) return "";
35589
+ return SPINNER_FRAMES[index];
35590
+ };
35591
+
35592
+ // ../../packages/tui-components/src/execution/hooks/use-streaming-phase.ts
35593
+ var import_react43 = __toESM(require_react(), 1);
35594
+ function deriveStreamingPhase(streaming) {
35595
+ for (const run of Object.values(streaming.runs)) {
35596
+ if (run.isReasoningActive) return "reasoning";
35597
+ if (run.isRunResultActive) return "generating";
35598
+ }
35599
+ return "idle";
35600
+ }
35601
+ var useStreamingPhase = (streaming) => {
35602
+ return (0, import_react43.useMemo)(() => deriveStreamingPhase(streaming), [streaming]);
35603
+ };
35604
+
35605
+ // ../../packages/tui-components/src/execution/components/interface-panel.tsx
35606
+ var import_jsx_runtime13 = __toESM(require_jsx_runtime(), 1);
35607
+ function getUsageIcon(percent) {
35608
+ if (percent <= 25) return USAGE_INDICATORS.LOW;
35609
+ if (percent <= 50) return USAGE_INDICATORS.MEDIUM;
35610
+ if (percent <= 75) return USAGE_INDICATORS.HIGH;
35611
+ return USAGE_INDICATORS.FULL;
35612
+ }
35613
+ var InterfacePanel = ({
35614
+ runtimeInfo,
35615
+ runStatus,
35616
+ streaming,
35617
+ onSubmit
35522
35618
  }) => {
35619
+ const streamingPhase = useStreamingPhase(streaming);
35620
+ const isSpinnerActive = runStatus === "running";
35621
+ const spinner = useSpinner({ isActive: isSpinnerActive });
35523
35622
  const { input, handleInput } = useTextInput({
35524
- onSubmit: onQuerySubmit ?? (() => {
35525
- })
35623
+ onSubmit,
35624
+ canSubmit: runStatus !== "running"
35526
35625
  });
35527
- use_input_default(handleInput, { isActive: isEditing });
35528
- const displayExpertName = expertName ?? info.expertName;
35529
- const skills = info.activeSkills.length > 0 ? info.activeSkills.join(", ") : "";
35530
- const step = info.currentStep !== void 0 ? String(info.currentStep) : "";
35531
- const usagePercent = (info.contextWindowUsage * 100).toFixed(1);
35532
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
35626
+ use_input_default(handleInput);
35627
+ let statusLabel;
35628
+ if (runStatus === "waiting") {
35629
+ statusLabel = /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { color: "cyan", children: "Waiting for query..." });
35630
+ } else if (runStatus === "completed") {
35631
+ statusLabel = /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { color: "green", children: "Completed" });
35632
+ } else if (runStatus === "stopped") {
35633
+ statusLabel = /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { color: "yellow", children: "Stopped" });
35634
+ } else if (streamingPhase === "reasoning") {
35635
+ statusLabel = /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { children: "Streaming Reasoning..." });
35636
+ } else if (streamingPhase === "generating") {
35637
+ statusLabel = /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { children: "Streaming Generation..." });
35638
+ } else {
35639
+ statusLabel = /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { children: "Running..." });
35640
+ }
35641
+ const step = runtimeInfo.currentStep !== void 0 ? String(runtimeInfo.currentStep) : "\u2013";
35642
+ const usagePercent = (runtimeInfo.contextWindowUsage * 100).toFixed(1);
35643
+ const usageIcon = getUsageIcon(runtimeInfo.contextWindowUsage * 100);
35644
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
35533
35645
  Box_default,
35534
35646
  {
35535
35647
  flexDirection: "column",
@@ -35540,308 +35652,189 @@ var RunSetting = ({
35540
35652
  borderLeft: false,
35541
35653
  borderRight: false,
35542
35654
  children: [
35543
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { children: [
35544
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { bold: true, color: "cyan", children: "Perstack" }),
35545
- info.runtimeVersion && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { color: "gray", children: [
35546
- " (v",
35547
- info.runtimeVersion,
35548
- ")"
35549
- ] })
35550
- ] }),
35551
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { children: [
35552
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { color: "gray", children: "Expert: " }),
35553
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { color: "white", children: displayExpertName }),
35554
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { color: "gray", children: " / Skills: " }),
35555
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { color: "green", children: skills })
35556
- ] }),
35557
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { children: [
35558
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { color: "gray", children: "Status: " }),
35559
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
35560
- Text,
35561
- {
35562
- color: info.status === "running" ? "green" : info.status === "completed" ? "cyan" : "yellow",
35563
- children: info.status
35564
- }
35565
- ),
35566
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { color: "gray", children: " / Step: " }),
35567
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { color: "white", children: step }),
35568
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { color: "gray", children: " / Events: " }),
35569
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { color: "white", children: eventCount }),
35570
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { color: "gray", children: " / Usage: " }),
35571
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { color: "white", children: [
35655
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Text, { children: [
35656
+ spinner ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Text, { color: "cyan", children: [
35657
+ spinner,
35658
+ " "
35659
+ ] }) : null,
35660
+ statusLabel,
35661
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { dimColor: true, children: " \u2503 " }),
35662
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { dimColor: true, children: "\u21BB " }),
35663
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { children: step }),
35664
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { dimColor: true, children: " \u2503 " }),
35665
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Text, { children: [
35666
+ usageIcon,
35667
+ " "
35668
+ ] }),
35669
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Text, { children: [
35572
35670
  usagePercent,
35573
35671
  "%"
35574
35672
  ] })
35575
35673
  ] }),
35576
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { children: [
35577
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { color: "gray", children: "Model: " }),
35578
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { color: "white", children: info.model })
35579
- ] }),
35580
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Box_default, { children: [
35581
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { color: "gray", children: "Query: " }),
35582
- isEditing ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
35583
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { color: "white", children: input }),
35584
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { color: "cyan", children: "_" })
35585
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { color: "white", children: info.query })
35674
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Text, { children: [
35675
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { color: "gray", children: "> " }),
35676
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { children: input }),
35677
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { color: "cyan", children: "_" })
35586
35678
  ] })
35587
35679
  ]
35588
35680
  }
35589
35681
  );
35590
35682
  };
35591
35683
 
35592
- // ../../packages/tui-components/src/components/streaming-display.tsx
35593
- var import_jsx_runtime13 = __toESM(require_jsx_runtime(), 1);
35594
- var StreamingDisplay = ({ streaming }) => {
35595
- const activeRuns = Object.entries(streaming.runs).filter(
35596
- ([, run]) => run.isReasoningActive || run.isRunResultActive
35597
- );
35598
- if (activeRuns.length === 0) return null;
35599
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Box_default, { flexDirection: "column", marginY: 1, children: activeRuns.map(([runId, run]) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(StreamingRunSection, { run }, runId)) });
35600
- };
35601
- function StreamingRunSection({ run }) {
35602
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Box_default, { flexDirection: "column", children: [
35603
- run.isReasoningActive && run.reasoning !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(StreamingReasoning, { expertKey: run.expertKey, text: run.reasoning }),
35604
- run.isRunResultActive && run.runResult !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(StreamingRunResult, { expertKey: run.expertKey, text: run.runResult })
35605
- ] });
35606
- }
35607
- function StreamingReasoning({
35608
- expertKey,
35609
- text
35610
- }) {
35611
- const lines = text.split("\n");
35612
- const label = `[${formatExpertKey(expertKey)}] Reasoning...`;
35613
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ActionRow, { indicatorColor: "cyan", label, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Box_default, { flexDirection: "column", children: lines.map((line, idx) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { dimColor: true, wrap: "wrap", children: line }, `streaming-reasoning-${idx}`)) }) });
35614
- }
35615
- function StreamingRunResult({
35616
- expertKey,
35617
- text
35618
- }) {
35619
- const lines = text.split("\n");
35620
- const label = `[${formatExpertKey(expertKey)}] Generating...`;
35621
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ActionRow, { indicatorColor: "green", label, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Box_default, { flexDirection: "column", children: lines.map((line, idx) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Text, { wrap: "wrap", children: line }, `streaming-run-result-${idx}`)) }) });
35622
- }
35623
- function formatExpertKey(expertKey) {
35624
- const atIndex = expertKey.lastIndexOf("@");
35625
- if (atIndex > 0) {
35626
- return expertKey.substring(0, atIndex);
35627
- }
35628
- return expertKey;
35629
- }
35630
-
35631
- // ../../packages/tui-components/src/execution/components/activity-log-panel.tsx
35632
- var import_react42 = __toESM(require_react(), 1);
35633
- var import_jsx_runtime14 = __toESM(require_jsx_runtime(), 1);
35634
- function getActivityKey(activityOrGroup, index) {
35635
- return activityOrGroup.id || `activity-${index}`;
35684
+ // ../../packages/tui-components/src/execution/hooks/use-execution-state.ts
35685
+ var import_react45 = __toESM(require_react(), 1);
35686
+ var logEntryCounter = 0;
35687
+ function createLogEntry(label, color, detail) {
35688
+ logEntryCounter++;
35689
+ return { id: `log-${logEntryCounter}`, type: "logEntry", label, color, detail };
35636
35690
  }
35637
- var RunBox = ({ node, isRoot }) => {
35638
- if (isRoot) {
35639
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(Box_default, { flexDirection: "column", children: [
35640
- node.activities.map((activity, index) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(CheckpointActionRow, { action: activity }, getActivityKey(activity, index))),
35641
- node.children.map((child) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(RunBox, { node: child, isRoot: false }, child.runId))
35642
- ] });
35643
- }
35644
- const shortRunId = node.runId.slice(0, 8);
35645
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(Box_default, { flexDirection: "column", borderStyle: "round", borderColor: "gray", marginLeft: 1, children: [
35646
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(Text, { dimColor: true, bold: true, children: [
35647
- "[",
35648
- node.expertKey,
35649
- "] ",
35650
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(Text, { dimColor: true, children: [
35651
- "(",
35652
- shortRunId,
35653
- ")"
35654
- ] })
35655
- ] }),
35656
- node.activities.map((activity, index) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(CheckpointActionRow, { action: activity }, getActivityKey(activity, index))),
35657
- node.children.map((child) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(RunBox, { node: child, isRoot: false }, child.runId))
35658
- ] });
35659
- };
35660
- function getActivityProps(activityOrGroup) {
35661
- if (activityOrGroup.type === "parallelGroup") {
35662
- const group = activityOrGroup;
35663
- const firstActivity = group.activities[0];
35664
- return {
35665
- runId: group.runId,
35666
- expertKey: group.expertKey,
35667
- delegatedBy: firstActivity?.delegatedBy
35668
- };
35691
+ function extractLogEntriesFromEvent(event) {
35692
+ const entries = [];
35693
+ if (event.type === "initializeRuntime") {
35694
+ entries.push(
35695
+ createLogEntry(
35696
+ "Initialize Runtime",
35697
+ "green",
35698
+ `Perstack v${event.runtimeVersion} \xB7 ${event.expertName} \xB7 ${event.model}`
35699
+ )
35700
+ );
35701
+ } else if (event.type === "skillConnected") {
35702
+ entries.push(createLogEntry(`Skill Connected: ${event.skillName}`, "green"));
35703
+ } else if (event.type === "skillDisconnected") {
35704
+ entries.push(createLogEntry(`Skill Disconnected: ${event.skillName}`, "yellow"));
35669
35705
  }
35670
- return activityOrGroup;
35706
+ return entries;
35671
35707
  }
35672
- var ActivityLogPanel = ({ activities }) => {
35673
- const rootNodes = (0, import_react42.useMemo)(() => {
35674
- const nodeMap = /* @__PURE__ */ new Map();
35675
- const roots = [];
35676
- const orphanChildren = /* @__PURE__ */ new Map();
35677
- for (const activityOrGroup of activities) {
35678
- const { runId, expertKey, delegatedBy } = getActivityProps(activityOrGroup);
35679
- let node = nodeMap.get(runId);
35680
- if (!node) {
35681
- node = {
35682
- runId,
35683
- expertKey,
35684
- activities: [],
35685
- children: []
35686
- };
35687
- nodeMap.set(runId, node);
35688
- const waitingChildren = orphanChildren.get(runId);
35689
- if (waitingChildren) {
35690
- for (const child of waitingChildren) {
35691
- node.children.push(child);
35692
- const rootIndex = roots.indexOf(child);
35693
- if (rootIndex !== -1) {
35694
- roots.splice(rootIndex, 1);
35695
- }
35696
- }
35697
- orphanChildren.delete(runId);
35698
- }
35699
- if (delegatedBy) {
35700
- const parentNode = nodeMap.get(delegatedBy.runId);
35701
- if (parentNode) {
35702
- parentNode.children.push(node);
35703
- } else {
35704
- const orphans = orphanChildren.get(delegatedBy.runId) ?? [];
35705
- orphans.push(node);
35706
- orphanChildren.set(delegatedBy.runId, orphans);
35707
- roots.push(node);
35708
- }
35709
- } else {
35710
- roots.push(node);
35711
- }
35712
- }
35713
- node.activities.push(activityOrGroup);
35714
- }
35715
- return roots;
35716
- }, [activities]);
35717
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Box_default, { flexDirection: "column", children: rootNodes.map((node) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(RunBox, { node, isRoot: true }, node.runId)) });
35718
- };
35719
-
35720
- // ../../packages/tui-components/src/execution/components/continue-input-panel.tsx
35721
- var import_jsx_runtime15 = __toESM(require_jsx_runtime(), 1);
35722
- var ContinueInputPanel = ({
35723
- isActive,
35724
- runStatus,
35725
- onSubmit
35726
- }) => {
35727
- const { input, handleInput } = useTextInput({
35728
- onSubmit: (newQuery) => {
35729
- if (isActive && newQuery.trim()) {
35730
- onSubmit(newQuery.trim());
35731
- }
35732
- }
35733
- });
35734
- use_input_default(handleInput, { isActive });
35735
- if (runStatus === "running") {
35736
- return null;
35737
- }
35738
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Box_default, { flexDirection: "column", borderStyle: "single", borderColor: "gray", children: [
35739
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Text, { children: [
35740
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Text, { color: runStatus === "completed" ? "green" : "yellow", bold: true, children: runStatus === "completed" ? "Completed" : "Stopped" }),
35741
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Text, { color: "gray", children: " - Enter a follow-up query or wait to exit" })
35742
- ] }),
35743
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Box_default, { children: [
35744
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Text, { color: "gray", children: "Continue: " }),
35745
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Text, { children: input }),
35746
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Text, { color: "cyan", children: "_" })
35747
- ] })
35748
- ] });
35749
- };
35750
-
35751
- // ../../packages/tui-components/src/execution/components/status-panel.tsx
35752
- var import_jsx_runtime16 = __toESM(require_jsx_runtime(), 1);
35753
- var StatusPanel = ({
35754
- runtimeInfo,
35755
- eventCount,
35756
- runStatus
35757
- }) => {
35758
- if (runStatus !== "running") {
35759
- return null;
35760
- }
35761
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(RunSetting, { info: runtimeInfo, eventCount, isEditing: false });
35762
- };
35763
-
35764
- // ../../packages/tui-components/src/execution/hooks/use-execution-state.ts
35765
- var import_react44 = __toESM(require_react(), 1);
35766
35708
  var useExecutionState = (options) => {
35767
- const { expertKey, query, config, continueTimeoutMs, historicalEvents, onReady, onComplete } = options;
35768
- const { exit } = use_app_default();
35709
+ const {
35710
+ expertKey,
35711
+ query,
35712
+ config,
35713
+ continueTimeoutMs,
35714
+ historicalEvents,
35715
+ onReady,
35716
+ onComplete,
35717
+ onQueryReady
35718
+ } = options;
35769
35719
  const runState = useRun();
35770
35720
  const { runtimeInfo, handleEvent, setQuery } = useRuntimeInfo({
35771
35721
  initialExpertName: expertKey,
35772
35722
  initialConfig: config
35773
35723
  });
35774
- const [runStatus, setRunStatus] = (0, import_react44.useState)("running");
35775
- const [isAcceptingContinue, setIsAcceptingContinue] = (0, import_react44.useState)(false);
35776
- const timeoutRef = (0, import_react44.useRef)(null);
35777
- const clearTimeoutIfExists = (0, import_react44.useCallback)(() => {
35724
+ const [runStatus, setRunStatus] = (0, import_react45.useState)(query ? "running" : "waiting");
35725
+ const [staticItems, setStaticItems] = (0, import_react45.useState)([]);
35726
+ const timeoutRef = (0, import_react45.useRef)(null);
35727
+ const lastSyncedCountRef = (0, import_react45.useRef)(0);
35728
+ const clearTimeoutIfExists = (0, import_react45.useCallback)(() => {
35778
35729
  if (timeoutRef.current) {
35779
35730
  clearTimeout(timeoutRef.current);
35780
35731
  timeoutRef.current = null;
35781
35732
  }
35782
35733
  }, []);
35783
- const startExitTimeout = (0, import_react44.useCallback)(() => {
35734
+ const startExitTimeout = (0, import_react45.useCallback)(() => {
35784
35735
  clearTimeoutIfExists();
35785
35736
  timeoutRef.current = setTimeout(() => {
35786
35737
  onComplete({ nextQuery: null });
35787
- exit();
35788
35738
  }, continueTimeoutMs);
35789
- }, [clearTimeoutIfExists, continueTimeoutMs, onComplete, exit]);
35790
- (0, import_react44.useEffect)(() => {
35791
- setQuery(query);
35739
+ }, [clearTimeoutIfExists, continueTimeoutMs, onComplete]);
35740
+ (0, import_react45.useEffect)(() => {
35741
+ if (query) {
35742
+ setQuery(query);
35743
+ }
35792
35744
  }, [query, setQuery]);
35793
- (0, import_react44.useEffect)(() => {
35745
+ (0, import_react45.useEffect)(() => {
35794
35746
  if (historicalEvents && historicalEvents.length > 0) {
35795
35747
  runState.appendHistoricalEvents(historicalEvents);
35748
+ const logEntries = [];
35749
+ for (const event of historicalEvents) {
35750
+ logEntries.push(...extractLogEntriesFromEvent(event));
35751
+ }
35752
+ if (logEntries.length > 0) {
35753
+ setStaticItems((prev) => [...prev, ...logEntries]);
35754
+ }
35796
35755
  }
35797
35756
  }, [historicalEvents, runState.appendHistoricalEvents]);
35798
- (0, import_react44.useEffect)(() => {
35757
+ (0, import_react45.useEffect)(() => {
35758
+ const currentActivities = runState.activities;
35759
+ if (currentActivities.length > lastSyncedCountRef.current) {
35760
+ const newItems = currentActivities.slice(lastSyncedCountRef.current);
35761
+ lastSyncedCountRef.current = currentActivities.length;
35762
+ setStaticItems((prev) => [...prev, ...newItems]);
35763
+ }
35764
+ }, [runState.activities]);
35765
+ (0, import_react45.useEffect)(() => {
35799
35766
  onReady((event) => {
35800
35767
  runState.addEvent(event);
35801
35768
  const result = handleEvent(event);
35769
+ const logEntries = extractLogEntriesFromEvent(event);
35770
+ if (logEntries.length > 0) {
35771
+ setStaticItems((prev) => [...prev, ...logEntries]);
35772
+ }
35802
35773
  if (result?.completed) {
35803
35774
  setRunStatus("completed");
35804
- setIsAcceptingContinue(true);
35805
35775
  startExitTimeout();
35806
35776
  } else if (result?.stopped) {
35807
35777
  setRunStatus("stopped");
35808
- setIsAcceptingContinue(true);
35809
35778
  startExitTimeout();
35810
35779
  }
35811
35780
  });
35812
35781
  }, [onReady, runState.addEvent, handleEvent, startExitTimeout]);
35813
- (0, import_react44.useEffect)(() => {
35782
+ (0, import_react45.useEffect)(() => {
35814
35783
  return () => {
35815
35784
  clearTimeoutIfExists();
35816
35785
  };
35817
35786
  }, [clearTimeoutIfExists]);
35818
- const handleContinueSubmit = (0, import_react44.useCallback)(
35787
+ const handleSubmit = (0, import_react45.useCallback)(
35819
35788
  (newQuery) => {
35820
- if (isAcceptingContinue && newQuery.trim()) {
35789
+ if (!newQuery.trim()) return;
35790
+ if (runStatus === "waiting") {
35791
+ const trimmed = newQuery.trim();
35792
+ setQuery(trimmed);
35793
+ setRunStatus("running");
35794
+ onQueryReady?.(trimmed);
35795
+ return;
35796
+ }
35797
+ if (runStatus !== "running") {
35821
35798
  clearTimeoutIfExists();
35822
35799
  onComplete({ nextQuery: newQuery.trim() });
35823
- exit();
35824
35800
  }
35825
35801
  },
35826
- [isAcceptingContinue, clearTimeoutIfExists, onComplete, exit]
35802
+ [runStatus, clearTimeoutIfExists, onComplete, setQuery, onQueryReady]
35827
35803
  );
35828
35804
  return {
35829
- activities: runState.activities,
35805
+ staticItems,
35830
35806
  streaming: runState.streaming,
35831
- eventCount: runState.eventCount,
35832
35807
  runtimeInfo,
35833
35808
  runStatus,
35834
- isAcceptingContinue,
35835
- handleContinueSubmit,
35809
+ handleSubmit,
35836
35810
  clearTimeout: clearTimeoutIfExists
35837
35811
  };
35838
35812
  };
35839
35813
 
35840
35814
  // ../../packages/tui-components/src/execution/app.tsx
35841
- var import_jsx_runtime17 = __toESM(require_jsx_runtime(), 1);
35815
+ var import_jsx_runtime14 = __toESM(require_jsx_runtime(), 1);
35842
35816
  var ExecutionApp = (props) => {
35843
- const { expertKey, query, config, continueTimeoutMs, historicalEvents, onReady, onComplete } = props;
35817
+ const {
35818
+ expertKey,
35819
+ query,
35820
+ config,
35821
+ continueTimeoutMs,
35822
+ historicalEvents,
35823
+ onReady,
35824
+ onComplete,
35825
+ onQueryReady
35826
+ } = props;
35844
35827
  const { exit } = use_app_default();
35828
+ const [exitResult, setExitResult] = (0, import_react46.useState)(null);
35829
+ const handleComplete = (0, import_react46.useCallback)((result) => {
35830
+ setExitResult(result);
35831
+ }, []);
35832
+ (0, import_react46.useEffect)(() => {
35833
+ if (exitResult) {
35834
+ onComplete(exitResult);
35835
+ exit();
35836
+ }
35837
+ }, [exitResult, onComplete, exit]);
35845
35838
  const state = useExecutionState({
35846
35839
  expertKey,
35847
35840
  query,
@@ -35849,7 +35842,8 @@ var ExecutionApp = (props) => {
35849
35842
  continueTimeoutMs,
35850
35843
  historicalEvents,
35851
35844
  onReady,
35852
- onComplete
35845
+ onComplete: handleComplete,
35846
+ onQueryReady
35853
35847
  });
35854
35848
  use_input_default((input, key) => {
35855
35849
  if (key.ctrl && input === "c") {
@@ -35857,36 +35851,44 @@ var ExecutionApp = (props) => {
35857
35851
  exit();
35858
35852
  }
35859
35853
  });
35860
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Box_default, { flexDirection: "column", children: [
35861
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ActivityLogPanel, { activities: state.activities }),
35862
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(StreamingDisplay, { streaming: state.streaming }),
35863
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
35864
- StatusPanel,
35854
+ if (exitResult) return null;
35855
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(Box_default, { flexDirection: "column", children: [
35856
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Static, { items: state.staticItems, children: (item, index) => {
35857
+ if (item.type === "logEntry") {
35858
+ if (item.detail) {
35859
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ActionRow, { indicatorColor: item.color, label: item.label, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Text, { dimColor: true, children: item.detail }) }, item.id);
35860
+ }
35861
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ActionRowSimple, { indicatorColor: item.color, text: item.label }, item.id);
35862
+ }
35863
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ActivityLogItem, { activity: item }, item.id || `activity-${index}`);
35864
+ } }),
35865
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
35866
+ InterfacePanel,
35865
35867
  {
35866
35868
  runtimeInfo: state.runtimeInfo,
35867
- eventCount: state.eventCount,
35868
- runStatus: state.runStatus
35869
- }
35870
- ),
35871
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
35872
- ContinueInputPanel,
35873
- {
35874
- isActive: state.isAcceptingContinue,
35875
35869
  runStatus: state.runStatus,
35876
- onSubmit: state.handleContinueSubmit
35870
+ streaming: state.streaming,
35871
+ onSubmit: state.handleSubmit
35877
35872
  }
35878
35873
  )
35879
35874
  ] });
35880
35875
  };
35881
35876
 
35882
35877
  // ../../packages/tui-components/src/execution/render.tsx
35883
- var import_jsx_runtime18 = __toESM(require_jsx_runtime(), 1);
35878
+ var import_jsx_runtime15 = __toESM(require_jsx_runtime(), 1);
35884
35879
  function renderExecution(params) {
35885
35880
  const eventQueue = new EventQueue();
35881
+ let resolveQuery;
35882
+ const queryReady = new Promise((resolve) => {
35883
+ resolveQuery = resolve;
35884
+ });
35885
+ if (params.query) {
35886
+ resolveQuery(params.query);
35887
+ }
35886
35888
  const result = new Promise((resolve, reject) => {
35887
- let resolved = false;
35889
+ let executionResult;
35888
35890
  const { waitUntilExit } = render_default(
35889
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
35891
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
35890
35892
  ExecutionApp,
35891
35893
  {
35892
35894
  ...params,
@@ -35894,14 +35896,18 @@ function renderExecution(params) {
35894
35896
  eventQueue.setHandler(handler);
35895
35897
  },
35896
35898
  onComplete: (result2) => {
35897
- resolved = true;
35898
- resolve(result2);
35899
+ executionResult = result2;
35900
+ },
35901
+ onQueryReady: (query) => {
35902
+ resolveQuery(query);
35899
35903
  }
35900
35904
  }
35901
35905
  )
35902
35906
  );
35903
35907
  waitUntilExit().then(() => {
35904
- if (!resolved) {
35908
+ if (executionResult) {
35909
+ resolve(executionResult);
35910
+ } else {
35905
35911
  reject(new PerstackError("Execution cancelled"));
35906
35912
  }
35907
35913
  }).catch(reject);
@@ -35910,21 +35916,20 @@ function renderExecution(params) {
35910
35916
  result,
35911
35917
  eventListener: (event) => {
35912
35918
  eventQueue.emit(event);
35913
- }
35919
+ },
35920
+ queryReady
35914
35921
  };
35915
35922
  }
35916
35923
 
35917
35924
  // ../../packages/tui-components/src/selection/app.tsx
35918
- var import_react45 = __toESM(require_react(), 1);
35919
- var import_jsx_runtime19 = __toESM(require_jsx_runtime(), 1);
35925
+ var import_react47 = __toESM(require_react(), 1);
35926
+ var import_jsx_runtime16 = __toESM(require_jsx_runtime(), 1);
35920
35927
  var selectionReducer = (_state, action) => {
35921
35928
  switch (action.type) {
35922
35929
  case "BROWSE_HISTORY":
35923
35930
  return { type: "browsingHistory", jobs: action.jobs };
35924
35931
  case "BROWSE_EXPERTS":
35925
35932
  return { type: "browsingExperts", experts: action.experts };
35926
- case "SELECT_EXPERT":
35927
- return { type: "enteringQuery", expertKey: action.expertKey };
35928
35933
  case "SELECT_JOB":
35929
35934
  return { type: "browsingCheckpoints", job: action.job, checkpoints: action.checkpoints };
35930
35935
  case "GO_BACK_FROM_CHECKPOINTS":
@@ -35937,7 +35942,6 @@ var SelectionApp = (props) => {
35937
35942
  const {
35938
35943
  showHistory,
35939
35944
  initialExpertKey,
35940
- initialQuery,
35941
35945
  initialCheckpoint,
35942
35946
  configuredExperts,
35943
35947
  recentExperts,
@@ -35946,51 +35950,47 @@ var SelectionApp = (props) => {
35946
35950
  onComplete
35947
35951
  } = props;
35948
35952
  const { exit } = use_app_default();
35949
- const allExperts = (0, import_react45.useMemo)(() => {
35953
+ const allExperts = (0, import_react47.useMemo)(() => {
35950
35954
  const configured = configuredExperts.map((e) => ({ ...e, source: "configured" }));
35951
35955
  const recent = recentExperts.filter((e) => !configured.some((c) => c.key === e.key)).map((e) => ({ ...e, source: "recent" }));
35952
35956
  return [...configured, ...recent];
35953
35957
  }, [configuredExperts, recentExperts]);
35954
35958
  const getInitialState = () => {
35955
- if (initialExpertKey && !initialQuery) {
35956
- return { type: "enteringQuery", expertKey: initialExpertKey };
35957
- }
35958
35959
  if (showHistory && historyJobs.length > 0) {
35959
35960
  return { type: "browsingHistory", jobs: historyJobs };
35960
35961
  }
35961
35962
  return { type: "browsingExperts", experts: allExperts };
35962
35963
  };
35963
- const [state, dispatch] = (0, import_react45.useReducer)(selectionReducer, void 0, getInitialState);
35964
- const [selectedCheckpoint, setSelectedCheckpoint] = (0, import_react45.useState)(
35965
- initialCheckpoint
35966
- );
35967
- (0, import_react45.useEffect)(() => {
35968
- if (initialExpertKey && initialQuery) {
35964
+ const [state, dispatch] = (0, import_react47.useReducer)(selectionReducer, void 0, getInitialState);
35965
+ const [exitResult, setExitResult] = (0, import_react47.useState)(null);
35966
+ (0, import_react47.useEffect)(() => {
35967
+ if (exitResult) {
35968
+ onComplete(exitResult);
35969
+ exit();
35970
+ }
35971
+ }, [exitResult, onComplete, exit]);
35972
+ (0, import_react47.useEffect)(() => {
35973
+ if (initialExpertKey) {
35969
35974
  onComplete({
35970
35975
  expertKey: initialExpertKey,
35971
- query: initialQuery,
35972
35976
  checkpoint: initialCheckpoint
35973
35977
  });
35974
35978
  exit();
35975
35979
  }
35976
- }, [initialExpertKey, initialQuery, initialCheckpoint, onComplete, exit]);
35977
- const { input: queryInput, handleInput: handleQueryInput } = useTextInput({
35978
- onSubmit: (query) => {
35979
- if (state.type === "enteringQuery" && query.trim()) {
35980
- onComplete({
35981
- expertKey: state.expertKey,
35982
- query: query.trim(),
35983
- checkpoint: selectedCheckpoint
35984
- });
35985
- exit();
35986
- }
35987
- }
35988
- });
35989
- use_input_default(handleQueryInput, { isActive: state.type === "enteringQuery" });
35990
- const handleExpertSelect = (0, import_react45.useCallback)((expertKey) => {
35991
- dispatch({ type: "SELECT_EXPERT", expertKey });
35992
- }, []);
35993
- const handleJobSelect = (0, import_react45.useCallback)(
35980
+ }, [initialExpertKey, initialCheckpoint, onComplete, exit]);
35981
+ const completeWithExpert = (0, import_react47.useCallback)(
35982
+ (expertKey, checkpoint) => {
35983
+ setExitResult({ expertKey, checkpoint });
35984
+ },
35985
+ []
35986
+ );
35987
+ const handleExpertSelect = (0, import_react47.useCallback)(
35988
+ (expertKey) => {
35989
+ completeWithExpert(expertKey);
35990
+ },
35991
+ [completeWithExpert]
35992
+ );
35993
+ const handleJobSelect = (0, import_react47.useCallback)(
35994
35994
  async (job) => {
35995
35995
  try {
35996
35996
  const checkpoints = await onLoadCheckpoints(job);
@@ -36001,39 +36001,39 @@ var SelectionApp = (props) => {
36001
36001
  },
36002
36002
  [onLoadCheckpoints]
36003
36003
  );
36004
- const handleJobResume = (0, import_react45.useCallback)(
36004
+ const handleJobResume = (0, import_react47.useCallback)(
36005
36005
  async (job) => {
36006
36006
  try {
36007
36007
  const checkpoints = await onLoadCheckpoints(job);
36008
36008
  const latestCheckpoint = checkpoints[0];
36009
36009
  if (latestCheckpoint) {
36010
- setSelectedCheckpoint(latestCheckpoint);
36010
+ completeWithExpert(job.expertKey, latestCheckpoint);
36011
+ } else {
36012
+ completeWithExpert(job.expertKey);
36011
36013
  }
36012
- dispatch({ type: "SELECT_EXPERT", expertKey: job.expertKey });
36013
36014
  } catch {
36014
- dispatch({ type: "SELECT_EXPERT", expertKey: job.expertKey });
36015
+ completeWithExpert(job.expertKey);
36015
36016
  }
36016
36017
  },
36017
- [onLoadCheckpoints]
36018
+ [onLoadCheckpoints, completeWithExpert]
36018
36019
  );
36019
- const handleCheckpointResume = (0, import_react45.useCallback)(
36020
+ const handleCheckpointResume = (0, import_react47.useCallback)(
36020
36021
  (checkpoint) => {
36021
- setSelectedCheckpoint(checkpoint);
36022
36022
  if (state.type === "browsingCheckpoints") {
36023
- dispatch({ type: "SELECT_EXPERT", expertKey: state.job.expertKey });
36023
+ completeWithExpert(state.job.expertKey, checkpoint);
36024
36024
  }
36025
36025
  },
36026
- [state]
36026
+ [state, completeWithExpert]
36027
36027
  );
36028
- const handleBack = (0, import_react45.useCallback)(() => {
36028
+ const handleBack = (0, import_react47.useCallback)(() => {
36029
36029
  if (state.type === "browsingCheckpoints") {
36030
36030
  dispatch({ type: "GO_BACK_FROM_CHECKPOINTS", jobs: historyJobs });
36031
36031
  }
36032
36032
  }, [state, historyJobs]);
36033
- const handleSwitchToExperts = (0, import_react45.useCallback)(() => {
36033
+ const handleSwitchToExperts = (0, import_react47.useCallback)(() => {
36034
36034
  dispatch({ type: "BROWSE_EXPERTS", experts: allExperts });
36035
36035
  }, [allExperts]);
36036
- const handleSwitchToHistory = (0, import_react45.useCallback)(() => {
36036
+ const handleSwitchToHistory = (0, import_react47.useCallback)(() => {
36037
36037
  dispatch({ type: "BROWSE_HISTORY", jobs: historyJobs });
36038
36038
  }, [historyJobs]);
36039
36039
  use_input_default((input, key) => {
@@ -36041,7 +36041,7 @@ var SelectionApp = (props) => {
36041
36041
  exit();
36042
36042
  }
36043
36043
  });
36044
- const contextValue = (0, import_react45.useMemo)(
36044
+ const contextValue = (0, import_react47.useMemo)(
36045
36045
  () => ({
36046
36046
  onExpertSelect: handleExpertSelect,
36047
36047
  onQuerySubmit: () => {
@@ -36070,57 +36070,38 @@ var SelectionApp = (props) => {
36070
36070
  handleSwitchToHistory
36071
36071
  ]
36072
36072
  );
36073
- if (initialExpertKey && initialQuery) {
36073
+ if (exitResult || initialExpertKey) {
36074
36074
  return null;
36075
36075
  }
36076
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(Box_default, { flexDirection: "column", children: [
36077
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(InputAreaProvider, { value: contextValue, children: (state.type === "browsingHistory" || state.type === "browsingExperts" || state.type === "browsingCheckpoints") && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
36078
- BrowserRouter,
36079
- {
36080
- inputState: state,
36081
- showEventsHint: false
36082
- }
36083
- ) }),
36084
- state.type === "enteringQuery" && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(Box_default, { flexDirection: "column", borderStyle: "single", borderColor: "gray", children: [
36085
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(Text, { children: [
36086
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Text, { color: "cyan", bold: true, children: "Expert:" }),
36087
- " ",
36088
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Text, { children: state.expertKey }),
36089
- selectedCheckpoint && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(Text, { color: "gray", children: [
36090
- " (resuming from step ",
36091
- selectedCheckpoint.stepNumber,
36092
- ")"
36093
- ] })
36094
- ] }),
36095
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(Box_default, { children: [
36096
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Text, { color: "gray", children: "Query: " }),
36097
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Text, { children: queryInput }),
36098
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Text, { color: "cyan", children: "_" })
36099
- ] }),
36100
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Text, { dimColor: true, children: "Press Enter to start" })
36101
- ] })
36102
- ] });
36076
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Box_default, { flexDirection: "column", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(InputAreaProvider, { value: contextValue, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
36077
+ BrowserRouter,
36078
+ {
36079
+ inputState: state,
36080
+ showEventsHint: false
36081
+ }
36082
+ ) }) });
36103
36083
  };
36104
36084
 
36105
36085
  // ../../packages/tui-components/src/selection/render.tsx
36106
- var import_jsx_runtime20 = __toESM(require_jsx_runtime(), 1);
36086
+ var import_jsx_runtime17 = __toESM(require_jsx_runtime(), 1);
36107
36087
  async function renderSelection(params) {
36108
36088
  return new Promise((resolve, reject) => {
36109
- let resolved = false;
36089
+ let selectionResult;
36110
36090
  const { waitUntilExit } = render_default(
36111
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
36091
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
36112
36092
  SelectionApp,
36113
36093
  {
36114
36094
  ...params,
36115
36095
  onComplete: (result) => {
36116
- resolved = true;
36117
- resolve(result);
36096
+ selectionResult = result;
36118
36097
  }
36119
36098
  }
36120
36099
  )
36121
36100
  );
36122
36101
  waitUntilExit().then(() => {
36123
- if (!resolved) {
36102
+ if (selectionResult) {
36103
+ resolve(selectionResult);
36104
+ } else {
36124
36105
  reject(new PerstackError("Selection cancelled"));
36125
36106
  }
36126
36107
  }).catch(reject);
@@ -36164,7 +36145,6 @@ async function startHandler(expertKey, query, options, handlerOptions) {
36164
36145
  const selection = await renderSelection({
36165
36146
  showHistory,
36166
36147
  initialExpertKey: input.expertKey,
36167
- initialQuery: input.query,
36168
36148
  initialCheckpoint: checkpoint ? {
36169
36149
  id: checkpoint.id,
36170
36150
  jobId: checkpoint.jobId,
@@ -36184,10 +36164,6 @@ async function startHandler(expertKey, query, options, handlerOptions) {
36184
36164
  console.error("Expert key is required");
36185
36165
  return;
36186
36166
  }
36187
- if (!selection.query && !selection.checkpoint) {
36188
- console.error("Query is required");
36189
- return;
36190
- }
36191
36167
  let currentCheckpoint = selection.checkpoint ? getCheckpointById(selection.checkpoint.jobId, selection.checkpoint.id) : checkpoint;
36192
36168
  if (currentCheckpoint && currentCheckpoint.expert.key !== selection.expertKey) {
36193
36169
  console.error(
@@ -36196,17 +36172,21 @@ async function startHandler(expertKey, query, options, handlerOptions) {
36196
36172
  return;
36197
36173
  }
36198
36174
  const lockfile = handlerOptions.lockfile;
36199
- let currentQuery = selection.query;
36175
+ let currentQuery = input.query ?? null;
36200
36176
  let currentJobId = currentCheckpoint?.jobId ?? input.options.jobId ?? createId();
36201
36177
  let isNextQueryInteractiveToolResult = input.options.interactiveToolCallResult ?? false;
36202
36178
  let isFirstIteration = true;
36203
36179
  const initialHistoricalEvents = currentCheckpoint ? getAllEventContentsForJob(currentCheckpoint.jobId, currentCheckpoint.stepNumber) : void 0;
36204
- while (currentQuery !== null) {
36180
+ while (true) {
36205
36181
  const historicalEvents = isFirstIteration ? initialHistoricalEvents : void 0;
36206
36182
  const runId = createId();
36207
- const { result: executionResult, eventListener } = renderExecution({
36183
+ const {
36184
+ result: executionResult,
36185
+ eventListener,
36186
+ queryReady
36187
+ } = renderExecution({
36208
36188
  expertKey: selection.expertKey,
36209
- query: currentQuery,
36189
+ query: currentQuery ?? void 0,
36210
36190
  config: {
36211
36191
  runtimeVersion,
36212
36192
  model,
@@ -36218,13 +36198,14 @@ async function startHandler(expertKey, query, options, handlerOptions) {
36218
36198
  continueTimeoutMs: CONTINUE_TIMEOUT_MS,
36219
36199
  historicalEvents
36220
36200
  });
36201
+ const resolvedQuery = await queryReady;
36221
36202
  const runResult = await run(
36222
36203
  {
36223
36204
  setting: {
36224
36205
  jobId: currentJobId,
36225
36206
  runId,
36226
36207
  expertKey: selection.expertKey,
36227
- input: isNextQueryInteractiveToolResult && currentCheckpoint ? parseInteractiveToolCallResult(currentQuery, currentCheckpoint) : { text: currentQuery },
36208
+ input: isNextQueryInteractiveToolResult && currentCheckpoint ? parseInteractiveToolCallResult(resolvedQuery, currentCheckpoint) : { text: resolvedQuery },
36228
36209
  experts,
36229
36210
  model,
36230
36211
  providerConfig,
@@ -36260,7 +36241,7 @@ async function startHandler(expertKey, query, options, handlerOptions) {
36260
36241
  isNextQueryInteractiveToolResult = runResult.status === "stoppedByInteractiveTool";
36261
36242
  isFirstIteration = false;
36262
36243
  } else {
36263
- currentQuery = null;
36244
+ break;
36264
36245
  }
36265
36246
  }
36266
36247
  }
@@ -36268,7 +36249,7 @@ async function startHandler(expertKey, query, options, handlerOptions) {
36268
36249
  // package.json
36269
36250
  var package_default = {
36270
36251
  name: "create-expert",
36271
- version: "0.0.29",
36252
+ version: "0.0.31",
36272
36253
  description: "Create and modify Perstack expert definitions"};
36273
36254
 
36274
36255
  // bin/cli.ts