@robota-sdk/agent-cli 3.0.0-beta.35 → 3.0.0-beta.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -184,7 +184,8 @@ var import_ink14 = require("ink");
184
184
  // src/ui/App.tsx
185
185
  var import_react16 = require("react");
186
186
  var import_ink13 = require("ink");
187
- var import_agent_core3 = require("@robota-sdk/agent-core");
187
+ var import_agent_core6 = require("@robota-sdk/agent-core");
188
+ var import_agent_core7 = require("@robota-sdk/agent-core");
188
189
 
189
190
  // src/ui/hooks/useSession.ts
190
191
  var import_react = require("react");
@@ -280,6 +281,7 @@ var NOOP_TERMINAL = {
280
281
  function useSession(props) {
281
282
  const [permissionRequest, setPermissionRequest] = (0, import_react.useState)(null);
282
283
  const [streamingText, setStreamingText] = (0, import_react.useState)("");
284
+ const streamingTextRef = (0, import_react.useRef)("");
283
285
  const [activeTools, setActiveTools] = (0, import_react.useState)([]);
284
286
  const permissionQueueRef = (0, import_react.useRef)([]);
285
287
  const processingRef = (0, import_react.useRef)(false);
@@ -311,8 +313,15 @@ function useSession(props) {
311
313
  processNextPermission();
312
314
  });
313
315
  };
316
+ let flushTimer = null;
314
317
  const onTextDelta = (delta) => {
315
- setStreamingText((prev) => prev + delta);
318
+ streamingTextRef.current += delta;
319
+ if (!flushTimer) {
320
+ flushTimer = setTimeout(() => {
321
+ setStreamingText(streamingTextRef.current);
322
+ flushTimer = null;
323
+ }, 16);
324
+ }
316
325
  };
317
326
  const onToolExecution = (event) => {
318
327
  if (event.type === "start") {
@@ -391,6 +400,7 @@ function useSession(props) {
391
400
  }
392
401
  const clearStreamingText = (0, import_react.useCallback)(() => {
393
402
  setStreamingText("");
403
+ streamingTextRef.current = "";
394
404
  setActiveTools([]);
395
405
  }, []);
396
406
  return {
@@ -405,16 +415,11 @@ function useSession(props) {
405
415
  // src/ui/hooks/useMessages.ts
406
416
  var import_react2 = require("react");
407
417
  var MAX_RENDERED_MESSAGES = 100;
408
- var msgIdCounter = 0;
409
- function nextId() {
410
- msgIdCounter += 1;
411
- return `msg_${msgIdCounter}`;
412
- }
413
418
  function useMessages() {
414
419
  const [messages, setMessages] = (0, import_react2.useState)([]);
415
420
  const addMessage = (0, import_react2.useCallback)((msg) => {
416
421
  setMessages((prev) => {
417
- const updated = [...prev, { ...msg, id: nextId(), timestamp: /* @__PURE__ */ new Date() }];
422
+ const updated = [...prev, msg];
418
423
  if (updated.length > MAX_RENDERED_MESSAGES) {
419
424
  return updated.slice(-MAX_RENDERED_MESSAGES);
420
425
  }
@@ -426,6 +431,7 @@ function useMessages() {
426
431
 
427
432
  // src/ui/hooks/useSlashCommands.ts
428
433
  var import_react3 = require("react");
434
+ var import_agent_core = require("@robota-sdk/agent-core");
429
435
 
430
436
  // src/commands/slash-executor.ts
431
437
  var VALID_MODES2 = ["plan", "default", "acceptEdits", "bypassPermissions"];
@@ -692,11 +698,14 @@ function useSlashCommands(session, addMessage, setMessages, exit, registry, pend
692
698
  const cmd = parts[0]?.toLowerCase() ?? "";
693
699
  const args = parts.slice(1).join(" ");
694
700
  const clearMessages = () => setMessages([]);
701
+ const slashAddMessage = (msg) => {
702
+ addMessage((0, import_agent_core.createSystemMessage)(msg.content));
703
+ };
695
704
  const result = await executeSlashCommand(
696
705
  cmd,
697
706
  args,
698
707
  session,
699
- addMessage,
708
+ slashAddMessage,
700
709
  clearMessages,
701
710
  registry,
702
711
  pluginCallbacks
@@ -729,7 +738,9 @@ function useSlashCommands(session, addMessage, setMessages, exit, registry, pend
729
738
 
730
739
  // src/ui/hooks/useSubmitHandler.ts
731
740
  var import_react4 = require("react");
741
+ var import_node_crypto = require("crypto");
732
742
  var import_agent_sdk2 = require("@robota-sdk/agent-sdk");
743
+ var import_agent_core2 = require("@robota-sdk/agent-core");
733
744
 
734
745
  // src/utils/tool-call-extractor.ts
735
746
  var TOOL_ARG_MAX_LENGTH = 80;
@@ -886,21 +897,50 @@ async function runSessionPrompt(prompt, session, addMessage, clearStreamingText,
886
897
  historyBefore
887
898
  );
888
899
  if (toolSummaries.length > 0) {
889
- addMessage({
890
- role: "tool",
891
- content: JSON.stringify(toolSummaries),
892
- toolName: `${toolSummaries.length} tools`
893
- });
900
+ addMessage(
901
+ (0, import_agent_core2.createToolMessage)(JSON.stringify(toolSummaries), {
902
+ toolCallId: (0, import_node_crypto.randomUUID)(),
903
+ name: `${toolSummaries.length} tools`
904
+ })
905
+ );
894
906
  }
895
- addMessage({ role: "assistant", content: response || "(empty response)" });
907
+ addMessage((0, import_agent_core2.createAssistantMessage)(response || "(empty response)"));
896
908
  syncContextState(session, setContextState);
897
909
  } catch (err) {
898
910
  clearStreamingText();
899
- if (err instanceof DOMException && err.name === "AbortError") {
900
- addMessage({ role: "system", content: "Cancelled." });
911
+ const isAbortError = err instanceof DOMException && err.name === "AbortError" || err instanceof Error && (err.message.includes("aborted") || err.message.includes("abort"));
912
+ if (isAbortError) {
913
+ const history = session.getHistory();
914
+ const toolSummaries = extractToolCallsWithDiff(
915
+ history,
916
+ historyBefore
917
+ );
918
+ if (toolSummaries.length > 0) {
919
+ addMessage(
920
+ (0, import_agent_core2.createToolMessage)(JSON.stringify(toolSummaries), {
921
+ toolCallId: (0, import_node_crypto.randomUUID)(),
922
+ name: `${toolSummaries.length} tools`
923
+ })
924
+ );
925
+ }
926
+ const assistantParts = [];
927
+ let lastAssistantState = "complete";
928
+ for (let i = historyBefore; i < history.length; i++) {
929
+ const msg = history[i];
930
+ if (msg && msg.role === "assistant" && msg.content) {
931
+ assistantParts.push(msg.content);
932
+ if (msg.state === "interrupted") lastAssistantState = "interrupted";
933
+ }
934
+ }
935
+ if (assistantParts.length > 0) {
936
+ addMessage(
937
+ (0, import_agent_core2.createAssistantMessage)(assistantParts.join("\n\n"), { state: lastAssistantState })
938
+ );
939
+ }
940
+ addMessage((0, import_agent_core2.createSystemMessage)("Interrupted by user."));
901
941
  } else {
902
942
  const errMsg = err instanceof Error ? err.message : String(err);
903
- addMessage({ role: "system", content: `Error: ${errMsg}` });
943
+ addMessage((0, import_agent_core2.createSystemMessage)(`Error: ${errMsg}`));
904
944
  }
905
945
  } finally {
906
946
  setIsThinking(false);
@@ -953,7 +993,7 @@ function useSubmitHandler(session, addMessage, handleSlashCommand, clearStreamin
953
993
  const runInFork = createForkRunner(session);
954
994
  const result = await executeSkill(skill, args, { runInFork });
955
995
  if (result.mode === "fork") {
956
- addMessage({ role: "assistant", content: result.result ?? "(empty response)" });
996
+ addMessage((0, import_agent_core2.createAssistantMessage)(result.result ?? "(empty response)"));
957
997
  syncContextState(session, setContextState);
958
998
  return;
959
999
  }
@@ -988,7 +1028,7 @@ function useSubmitHandler(session, addMessage, handleSlashCommand, clearStreamin
988
1028
  hookInput
989
1029
  );
990
1030
  }
991
- addMessage({ role: "user", content: input });
1031
+ addMessage((0, import_agent_core2.createUserMessage)(input));
992
1032
  return runSessionPrompt(
993
1033
  input,
994
1034
  session,
@@ -1055,16 +1095,16 @@ var CommandRegistry = class {
1055
1095
  };
1056
1096
 
1057
1097
  // src/commands/builtin-source.ts
1058
- var import_agent_core = require("@robota-sdk/agent-core");
1098
+ var import_agent_core3 = require("@robota-sdk/agent-core");
1059
1099
  function buildModelSubcommands() {
1060
1100
  const seen = /* @__PURE__ */ new Set();
1061
1101
  const commands = [];
1062
- for (const model of Object.values(import_agent_core.CLAUDE_MODELS)) {
1102
+ for (const model of Object.values(import_agent_core3.CLAUDE_MODELS)) {
1063
1103
  if (seen.has(model.name)) continue;
1064
1104
  seen.add(model.name);
1065
1105
  commands.push({
1066
1106
  name: model.id,
1067
- description: `${model.name} (${(0, import_agent_core.formatTokenCount)(model.contextWindow).toUpperCase()})`,
1107
+ description: `${model.name} (${(0, import_agent_core3.formatTokenCount)(model.contextWindow).toUpperCase()})`,
1068
1108
  source: "builtin"
1069
1109
  });
1070
1110
  }
@@ -1459,6 +1499,7 @@ function usePluginCallbacks(cwd) {
1459
1499
  // src/ui/MessageList.tsx
1460
1500
  var import_react7 = __toESM(require("react"), 1);
1461
1501
  var import_ink2 = require("ink");
1502
+ var import_agent_core4 = require("@robota-sdk/agent-core");
1462
1503
 
1463
1504
  // src/ui/render-markdown.ts
1464
1505
  var import_marked = require("marked");
@@ -1544,9 +1585,14 @@ function RoleLabel({ role }) {
1544
1585
  }
1545
1586
  }
1546
1587
  function ToolMessage({ message }) {
1588
+ if (!(0, import_agent_core4.isToolMessage)(message)) {
1589
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, {});
1590
+ }
1591
+ const toolName = message.name;
1592
+ const content = message.content;
1547
1593
  let summaries = null;
1548
1594
  try {
1549
- const parsed = JSON.parse(message.content);
1595
+ const parsed = JSON.parse(content);
1550
1596
  if (Array.isArray(parsed) && parsed.length > 0 && typeof parsed[0].line === "string") {
1551
1597
  summaries = parsed;
1552
1598
  }
@@ -1559,9 +1605,9 @@ function ToolMessage({ message }) {
1559
1605
  "Tool:",
1560
1606
  " "
1561
1607
  ] }),
1562
- message.toolName && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ink2.Text, { color: "white", dimColor: true, children: [
1608
+ toolName && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ink2.Text, { color: "white", dimColor: true, children: [
1563
1609
  "[",
1564
- message.toolName,
1610
+ toolName,
1565
1611
  "]"
1566
1612
  ] })
1567
1613
  ] }),
@@ -1577,16 +1623,16 @@ function ToolMessage({ message }) {
1577
1623
  ] }, i))
1578
1624
  ] });
1579
1625
  }
1580
- const lines = message.content.split("\n").filter((l) => l.trim());
1626
+ const lines = content.split("\n").filter((l) => l.trim());
1581
1627
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ink2.Box, { flexDirection: "column", marginBottom: 1, children: [
1582
1628
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ink2.Box, { children: [
1583
1629
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ink2.Text, { color: "white", bold: true, children: [
1584
1630
  "Tool:",
1585
1631
  " "
1586
1632
  ] }),
1587
- message.toolName && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ink2.Text, { color: "white", dimColor: true, children: [
1633
+ toolName && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ink2.Text, { color: "white", dimColor: true, children: [
1588
1634
  "[",
1589
- message.toolName,
1635
+ toolName,
1590
1636
  "]"
1591
1637
  ] })
1592
1638
  ] }),
@@ -1602,21 +1648,15 @@ function ToolMessage({ message }) {
1602
1648
  var MessageItem = import_react7.default.memo(function MessageItem2({
1603
1649
  message
1604
1650
  }) {
1605
- if (message.role === "tool") {
1651
+ if ((0, import_agent_core4.isToolMessage)(message)) {
1606
1652
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ToolMessage, { message });
1607
1653
  }
1654
+ const content = message.content ?? "";
1655
+ const isInterrupted = message.state === "interrupted";
1608
1656
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ink2.Box, { flexDirection: "column", marginBottom: 1, children: [
1609
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ink2.Box, { children: [
1610
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RoleLabel, { role: message.role }),
1611
- message.toolName && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ink2.Text, { color: "magenta", dimColor: true, children: [
1612
- "[",
1613
- message.toolName,
1614
- "]",
1615
- " "
1616
- ] })
1617
- ] }),
1657
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_ink2.Box, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RoleLabel, { role: message.role }) }),
1618
1658
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_ink2.Text, { children: " " }),
1619
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_ink2.Box, { marginLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_ink2.Text, { wrap: "wrap", children: message.role === "assistant" ? renderMarkdown(message.content) : message.content }) })
1659
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_ink2.Box, { marginLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_ink2.Text, { wrap: "wrap", children: (0, import_agent_core4.isAssistantMessage)(message) ? renderMarkdown(content + (isInterrupted ? "\n\n_(interrupted)_" : "")) : content }) })
1620
1660
  ] });
1621
1661
  });
1622
1662
  function MessageList({ messages }) {
@@ -1625,7 +1665,7 @@ function MessageList({ messages }) {
1625
1665
 
1626
1666
  // src/ui/StatusBar.tsx
1627
1667
  var import_ink3 = require("ink");
1628
- var import_agent_core2 = require("@robota-sdk/agent-core");
1668
+ var import_agent_core5 = require("@robota-sdk/agent-core");
1629
1669
  var import_jsx_runtime3 = require("react/jsx-runtime");
1630
1670
  var CONTEXT_YELLOW_THRESHOLD = 70;
1631
1671
  var CONTEXT_RED_THRESHOLD = 90;
@@ -1665,9 +1705,9 @@ function StatusBar({
1665
1705
  "Context: ",
1666
1706
  Math.round(contextPercentage),
1667
1707
  "% (",
1668
- (0, import_agent_core2.formatTokenCount)(contextUsedTokens),
1708
+ (0, import_agent_core5.formatTokenCount)(contextUsedTokens),
1669
1709
  "/",
1670
- (0, import_agent_core2.formatTokenCount)(contextMaxTokens),
1710
+ (0, import_agent_core5.formatTokenCount)(contextMaxTokens),
1671
1711
  ")"
1672
1712
  ] })
1673
1713
  ] }),
@@ -1914,7 +1954,12 @@ function useAutocomplete(value, registry) {
1914
1954
  }
1915
1955
  };
1916
1956
  }
1917
- function InputArea({ onSubmit, isDisabled, registry }) {
1957
+ function InputArea({
1958
+ onSubmit,
1959
+ isDisabled,
1960
+ isAborting,
1961
+ registry
1962
+ }) {
1918
1963
  const [value, setValue] = (0, import_react10.useState)("");
1919
1964
  const pasteStore = (0, import_react10.useRef)(/* @__PURE__ */ new Map());
1920
1965
  const pasteIdRef = (0, import_react10.useRef)(0);
@@ -1995,19 +2040,27 @@ function InputArea({ onSubmit, isDisabled, registry }) {
1995
2040
  isSubcommandMode
1996
2041
  }
1997
2042
  ),
1998
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_ink7.Box, { borderStyle: "single", borderColor: isDisabled ? "gray" : "green", paddingLeft: 1, children: isDisabled ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(WaveText, { text: " Waiting for response..." }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_ink7.Box, { children: [
1999
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_ink7.Text, { color: "green", bold: true, children: "> " }),
2000
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2001
- CjkTextInput,
2002
- {
2003
- value,
2004
- onChange: setValue,
2005
- onSubmit: handleSubmit,
2006
- onPaste: handlePaste,
2007
- placeholder: "Type a message or /help"
2008
- }
2009
- )
2010
- ] }) })
2043
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2044
+ import_ink7.Box,
2045
+ {
2046
+ borderStyle: "single",
2047
+ borderColor: isAborting ? "yellow" : isDisabled ? "gray" : "green",
2048
+ paddingLeft: 1,
2049
+ children: isDisabled ? isAborting ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_ink7.Text, { color: "yellow", children: " Interrupting..." }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(WaveText, { text: " Waiting for response... (ESC to interrupt)" }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_ink7.Box, { children: [
2050
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_ink7.Text, { color: "green", bold: true, children: "> " }),
2051
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2052
+ CjkTextInput,
2053
+ {
2054
+ value,
2055
+ onChange: setValue,
2056
+ onSubmit: handleSubmit,
2057
+ onPaste: handlePaste,
2058
+ placeholder: "Type a message or /help"
2059
+ }
2060
+ )
2061
+ ] })
2062
+ }
2063
+ )
2011
2064
  ] });
2012
2065
  }
2013
2066
 
@@ -2131,7 +2184,7 @@ function StreamingIndicator({ text, activeTools }) {
2131
2184
  const hasTools = activeTools.length > 0;
2132
2185
  const hasText = text.length > 0;
2133
2186
  if (!hasTools && !hasText) {
2134
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_ink10.Text, { color: "yellow", children: "Thinking..." });
2187
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_jsx_runtime10.Fragment, {});
2135
2188
  }
2136
2189
  return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_ink10.Box, { flexDirection: "column", children: [
2137
2190
  hasTools && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_ink10.Box, { flexDirection: "column", marginBottom: 1, children: [
@@ -2655,6 +2708,7 @@ function App(props) {
2655
2708
  const pendingModelChangeRef = (0, import_react16.useRef)(null);
2656
2709
  const [pendingModelId, setPendingModelId] = (0, import_react16.useState)(null);
2657
2710
  const [showPluginTUI, setShowPluginTUI] = (0, import_react16.useState)(false);
2711
+ const [isAborting, setIsAborting] = (0, import_react16.useState)(false);
2658
2712
  const pluginCallbacks = usePluginCallbacks(props.cwd ?? process.cwd());
2659
2713
  const handleSlashCommand = useSlashCommands(
2660
2714
  session,
@@ -2678,11 +2732,16 @@ function App(props) {
2678
2732
  );
2679
2733
  (0, import_ink13.useInput)(
2680
2734
  (_input, key) => {
2681
- if (key.ctrl && _input === "c") exit();
2682
- if (key.escape && isThinking) session.abort();
2735
+ if (key.escape && isThinking) {
2736
+ setIsAborting(true);
2737
+ session.abort();
2738
+ }
2683
2739
  },
2684
2740
  { isActive: !permissionRequest && !showPluginTUI }
2685
2741
  );
2742
+ (0, import_react16.useEffect)(() => {
2743
+ if (!isThinking) setIsAborting(false);
2744
+ }, [isThinking]);
2686
2745
  return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_ink13.Box, { flexDirection: "column", children: [
2687
2746
  /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_ink13.Box, { flexDirection: "column", paddingX: 1, marginBottom: 1, children: [
2688
2747
  /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_ink13.Text, { color: "cyan", bold: true, children: `
@@ -2705,7 +2764,7 @@ function App(props) {
2705
2764
  pendingModelId && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2706
2765
  ConfirmPrompt,
2707
2766
  {
2708
- message: `Change model to ${(0, import_agent_core3.getModelName)(pendingModelId)}? This will restart the session.`,
2767
+ message: `Change model to ${(0, import_agent_core6.getModelName)(pendingModelId)}? This will restart the session.`,
2709
2768
  onSelect: (index) => {
2710
2769
  setPendingModelId(null);
2711
2770
  pendingModelChangeRef.current = null;
@@ -2713,19 +2772,21 @@ function App(props) {
2713
2772
  try {
2714
2773
  const settingsPath = getUserSettingsPath();
2715
2774
  updateModelInSettings(settingsPath, pendingModelId);
2716
- addMessage({
2717
- role: "system",
2718
- content: `Model changed to ${(0, import_agent_core3.getModelName)(pendingModelId)}. Restarting...`
2719
- });
2775
+ addMessage(
2776
+ (0, import_agent_core7.createSystemMessage)(
2777
+ `Model changed to ${(0, import_agent_core6.getModelName)(pendingModelId)}. Restarting...`
2778
+ )
2779
+ );
2720
2780
  setTimeout(() => exit(), EXIT_DELAY_MS2);
2721
2781
  } catch (err) {
2722
- addMessage({
2723
- role: "system",
2724
- content: `Failed: ${err instanceof Error ? err.message : String(err)}`
2725
- });
2782
+ addMessage(
2783
+ (0, import_agent_core7.createSystemMessage)(
2784
+ `Failed: ${err instanceof Error ? err.message : String(err)}`
2785
+ )
2786
+ );
2726
2787
  }
2727
2788
  } else {
2728
- addMessage({ role: "system", content: "Model change cancelled." });
2789
+ addMessage((0, import_agent_core7.createSystemMessage)("Model change cancelled."));
2729
2790
  }
2730
2791
  }
2731
2792
  }
@@ -2735,14 +2796,14 @@ function App(props) {
2735
2796
  {
2736
2797
  callbacks: pluginCallbacks,
2737
2798
  onClose: () => setShowPluginTUI(false),
2738
- addMessage: (msg) => addMessage(msg)
2799
+ addMessage: (msg) => addMessage((0, import_agent_core7.createSystemMessage)(msg.content))
2739
2800
  }
2740
2801
  ),
2741
2802
  /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2742
2803
  StatusBar,
2743
2804
  {
2744
2805
  permissionMode: session.getPermissionMode(),
2745
- modelName: (0, import_agent_core3.getModelName)(props.config.provider.model),
2806
+ modelName: (0, import_agent_core6.getModelName)(props.config.provider.model),
2746
2807
  sessionId: session.getSessionId(),
2747
2808
  messageCount: messages.length,
2748
2809
  isThinking,
@@ -2756,6 +2817,7 @@ function App(props) {
2756
2817
  {
2757
2818
  onSubmit: handleSubmit,
2758
2819
  isDisabled: isThinking || !!permissionRequest || showPluginTUI,
2820
+ isAborting,
2759
2821
  registry
2760
2822
  }
2761
2823
  ),
@@ -2778,12 +2840,15 @@ function renderApp(options) {
2778
2840
  const instance = (0, import_ink14.render)(/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(App, { ...options }), {
2779
2841
  exitOnCtrlC: true
2780
2842
  });
2781
- instance.waitUntilExit().catch((err) => {
2843
+ instance.waitUntilExit().then(() => {
2844
+ process.exit(0);
2845
+ }).catch((err) => {
2782
2846
  if (err) {
2783
2847
  process.stderr.write(`
2784
2848
  [EXIT ERROR] ${err}
2785
2849
  `);
2786
2850
  }
2851
+ process.exit(1);
2787
2852
  });
2788
2853
  }
2789
2854
 
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  startCli
3
- } from "./chunk-27OPEZHA.js";
3
+ } from "./chunk-P323ORQX.js";
4
4
 
5
5
  // src/index.ts
6
6
  import { Session, SessionStore, query, TRUST_TO_MODE } from "@robota-sdk/agent-sdk";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@robota-sdk/agent-cli",
3
- "version": "3.0.0-beta.35",
3
+ "version": "3.0.0-beta.37",
4
4
  "description": "AI coding assistant CLI built on Robota SDK",
5
5
  "type": "module",
6
6
  "bin": {