@ai-setting/roy-agent-cli 1.7.18 → 1.7.20

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.
@@ -1088,7 +1088,7 @@ var init_slash_command_popup = __esm(() => {
1088
1088
  });
1089
1089
  });
1090
1090
 
1091
- // src/render/markdown.ts
1091
+ // src/render/markdown.js
1092
1092
  import { Marked } from "marked";
1093
1093
  import { highlight } from "cli-highlight";
1094
1094
  function setMarkdownEnabled(enabled) {
@@ -1497,7 +1497,8 @@ var init_markdown = __esm(() => {
1497
1497
  ANSI_CSI_RE = /\u001b\[[0-9;?]*[ -/]*[@-~]/g;
1498
1498
  });
1499
1499
 
1500
- // src/tui/Markdown.tsx
1500
+ // src/tui/Markdown.js
1501
+ import React2 from "react";
1501
1502
  import { Text as Text2 } from "ink";
1502
1503
  import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
1503
1504
  var Markdown = ({ text, width }) => {
@@ -1514,7 +1515,7 @@ var init_Markdown = __esm(() => {
1514
1515
  init_markdown();
1515
1516
  });
1516
1517
 
1517
- // src/tui/theme.ts
1518
+ // src/tui/theme.js
1518
1519
  function shouldSuppressColors(env) {
1519
1520
  if (env.NO_COLOR && env.NO_COLOR !== "0" && env.NO_COLOR !== "false") {
1520
1521
  return true;
@@ -1558,14 +1559,11 @@ var init_theme = __esm(() => {
1558
1559
  };
1559
1560
  });
1560
1561
 
1561
- // src/tui/StatusBar.tsx
1562
+ // src/tui/StatusBar.js
1563
+ import React3 from "react";
1562
1564
  import { Box as Box2, Text as Text3 } from "ink";
1563
1565
  import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
1564
- var StatusBar = ({
1565
- model,
1566
- workdir,
1567
- tokenCount
1568
- }) => {
1566
+ var StatusBar = ({ model, workdir, tokenCount }) => {
1569
1567
  const theme = getTheme();
1570
1568
  return /* @__PURE__ */ jsxDEV3(Box2, {
1571
1569
  borderStyle: "single",
@@ -1676,7 +1674,7 @@ __export(exports_repl_ink, {
1676
1674
  REPLInk: () => REPLInk,
1677
1675
  MultilineInput: () => MultilineInput
1678
1676
  });
1679
- import * as React2 from "react";
1677
+ import * as React4 from "react";
1680
1678
  import { Box as Box3, Text as Text4, Static, useApp, useInput as useInput2 } from "ink";
1681
1679
  import { createLogger as createLogger5 } from "@ai-setting/roy-agent-core";
1682
1680
  import { jsxDEV as jsxDEV4 } from "react/jsx-dev-runtime";
@@ -1701,7 +1699,7 @@ function REPLInk(props) {
1701
1699
  onEscape
1702
1700
  } = props;
1703
1701
  const { exit: appExit } = useApp();
1704
- const [messages, setMessages] = React2.useState(() => [
1702
+ const [messages, setMessages] = React4.useState(() => [
1705
1703
  withMessageId({
1706
1704
  role: "system",
1707
1705
  kind: "welcome",
@@ -1709,47 +1707,47 @@ function REPLInk(props) {
1709
1707
  }),
1710
1708
  ...initialMessages.map(withMessageId)
1711
1709
  ]);
1712
- const [mode, setMode] = React2.useState(initialMode);
1713
- const [statusBarCtx, setStatusBarCtxState] = React2.useState({
1710
+ const [mode, setMode] = React4.useState(initialMode);
1711
+ const [statusBarCtx, setStatusBarCtxState] = React4.useState({
1714
1712
  mode: initialMode,
1715
1713
  cwd: initialStatusBarCtx.cwd ?? initialContext.cwd,
1716
1714
  gitBranch: initialStatusBarCtx.gitBranch,
1717
1715
  model: initialStatusBarCtx.model ?? initialContext.model
1718
1716
  });
1719
- const [inputValue, setInputValue] = React2.useState("");
1720
- const [popupIndex, setPopupIndex] = React2.useState(0);
1721
- const filteredCmds = React2.useMemo(() => {
1717
+ const [inputValue, setInputValue] = React4.useState("");
1718
+ const [popupIndex, setPopupIndex] = React4.useState(0);
1719
+ const filteredCmds = React4.useMemo(() => {
1722
1720
  if (!/^\/\S*$/.test(inputValue))
1723
1721
  return [];
1724
1722
  return filterCommands(inputValue);
1725
1723
  }, [inputValue]);
1726
1724
  const showPopup = filteredCmds.length > 0;
1727
- React2.useEffect(() => {
1725
+ React4.useEffect(() => {
1728
1726
  setPopupIndex(0);
1729
1727
  }, [filteredCmds]);
1730
1728
  const safePopupIndex = clampSelectedIndex(popupIndex, filteredCmds.length);
1731
- const handlePopupSelect = React2.useCallback((cmd) => {
1729
+ const handlePopupSelect = React4.useCallback((cmd) => {
1732
1730
  multilineInputRef.current?.setBuffer(cmd.cmd + " ");
1733
1731
  setInputValue(cmd.cmd + " ");
1734
1732
  }, []);
1735
- const handlePopupClose = React2.useCallback(() => {
1733
+ const handlePopupClose = React4.useCallback(() => {
1736
1734
  const current = multilineInputRef.current?.getBuffer() ?? "";
1737
1735
  const stripped = current.replace(/^\/+/, "");
1738
1736
  multilineInputRef.current?.setBuffer(stripped);
1739
1737
  setInputValue(stripped);
1740
1738
  }, []);
1741
- const handlePopupIndexChange = React2.useCallback((idx) => {
1739
+ const handlePopupIndexChange = React4.useCallback((idx) => {
1742
1740
  setPopupIndex(idx);
1743
1741
  }, []);
1744
- const streamingIndexRef = React2.useRef(-1);
1745
- const lastFlushTsRef = React2.useRef(0);
1742
+ const streamingIndexRef = React4.useRef(-1);
1743
+ const lastFlushTsRef = React4.useRef(0);
1746
1744
  const STALE_STREAM_THRESHOLD_MS = 1000;
1747
- const multilineInputRef = React2.useRef(null);
1748
- const lastEscapeTsRef = React2.useRef(0);
1749
- const pendingDeltaRef = React2.useRef("");
1750
- const throttleTimerRef = React2.useRef(null);
1751
- const isFirstDeltaInStreamRef = React2.useRef(true);
1752
- const flushStreamingDelta = React2.useCallback(() => {
1745
+ const multilineInputRef = React4.useRef(null);
1746
+ const lastEscapeTsRef = React4.useRef(0);
1747
+ const pendingDeltaRef = React4.useRef("");
1748
+ const throttleTimerRef = React4.useRef(null);
1749
+ const isFirstDeltaInStreamRef = React4.useRef(true);
1750
+ const flushStreamingDelta = React4.useCallback(() => {
1753
1751
  const delta = pendingDeltaRef.current;
1754
1752
  pendingDeltaRef.current = "";
1755
1753
  throttleTimerRef.current = null;
@@ -1778,7 +1776,7 @@ function REPLInk(props) {
1778
1776
  });
1779
1777
  lastFlushTsRef.current = Date.now();
1780
1778
  }, []);
1781
- React2.useEffect(() => {
1779
+ React4.useEffect(() => {
1782
1780
  return () => {
1783
1781
  if (throttleTimerRef.current !== null) {
1784
1782
  clearTimeout(throttleTimerRef.current);
@@ -1786,8 +1784,8 @@ function REPLInk(props) {
1786
1784
  }
1787
1785
  };
1788
1786
  }, []);
1789
- const apiRef = React2.useRef(null);
1790
- React2.useEffect(() => {
1787
+ const apiRef = React4.useRef(null);
1788
+ React4.useEffect(() => {
1791
1789
  const api = {
1792
1790
  appendMessage: (msg) => {
1793
1791
  setMessages((msgs) => [...msgs, withMessageId(msg)]);
@@ -1863,7 +1861,7 @@ function REPLInk(props) {
1863
1861
  apiRef.current = api;
1864
1862
  onReady?.(api);
1865
1863
  }, [appExit, onCommand, onReady]);
1866
- const handleEscapeCascade = React2.useCallback(() => {
1864
+ const handleEscapeCascade = React4.useCallback(() => {
1867
1865
  const now = Date.now();
1868
1866
  if (now - lastEscapeTsRef.current < 100) {
1869
1867
  return;
@@ -1907,7 +1905,7 @@ function REPLInk(props) {
1907
1905
  }
1908
1906
  }
1909
1907
  });
1910
- const handleSubmit = React2.useCallback(async (value) => {
1908
+ const handleSubmit = React4.useCallback(async (value) => {
1911
1909
  if (!value || value.trim() === "") {
1912
1910
  return;
1913
1911
  }
@@ -1936,7 +1934,7 @@ function REPLInk(props) {
1936
1934
  ]);
1937
1935
  }
1938
1936
  }, [onCommand, onSubmit]);
1939
- const staticItems = React2.useMemo(() => {
1937
+ const staticItems = React4.useMemo(() => {
1940
1938
  if (messages.length <= 1)
1941
1939
  return [];
1942
1940
  return messages.slice(0, -1);
@@ -1944,8 +1942,8 @@ function REPLInk(props) {
1944
1942
  const tailMsg = messages.length > 0 ? messages[messages.length - 1] : null;
1945
1943
  const terminalWidth = process.stdout.columns ?? 80;
1946
1944
  const terminalHeight = process.stdout.rows ?? 24;
1947
- const dynamicTailBounds = React2.useMemo(() => computeDynamicTailBounds(terminalHeight, 12, showPopup), [terminalHeight, showPopup]);
1948
- const staticTailBounds = React2.useMemo(() => computeDynamicTailBounds(terminalHeight, 12, showPopup), [terminalHeight, showPopup]);
1945
+ const dynamicTailBounds = React4.useMemo(() => computeDynamicTailBounds(terminalHeight, 12, showPopup), [terminalHeight, showPopup]);
1946
+ const staticTailBounds = React4.useMemo(() => computeDynamicTailBounds(terminalHeight, 12, showPopup), [terminalHeight, showPopup]);
1949
1947
  const tailKey = messages.length > 0 ? tailMsg?.id ?? `tail-${messages.length - 1}` : "tail-empty";
1950
1948
  const statusBarModel = shortModel(statusBarCtx.model);
1951
1949
  const statusBarWorkdir = statusBarCtx.cwd;
@@ -2012,7 +2010,7 @@ function shortModel(model) {
2012
2010
  }
2013
2011
  async function renderInkREPL(props) {
2014
2012
  const ink = await import("ink");
2015
- const { waitUntilExit } = ink.render(React2.createElement(REPLInk, props));
2013
+ const { waitUntilExit } = ink.render(React4.createElement(REPLInk, props));
2016
2014
  await waitUntilExit();
2017
2015
  }
2018
2016
  var MarkdownBounded, inkLogger, _msgIdCounter = 0, MultilineInput, MessageView;
@@ -2024,7 +2022,7 @@ var init_repl_ink = __esm(() => {
2024
2022
  init_Markdown();
2025
2023
  init_StatusBar();
2026
2024
  init_dynamic_tail();
2027
- MarkdownBounded = React2.memo(({ text, bounds, width }) => {
2025
+ MarkdownBounded = React4.memo(({ text, bounds, width }) => {
2028
2026
  const out = renderBoundedAssistant(text, bounds, width);
2029
2027
  if (!out) {
2030
2028
  return null;
@@ -2034,16 +2032,16 @@ var init_repl_ink = __esm(() => {
2034
2032
  }, undefined, false, undefined, this);
2035
2033
  });
2036
2034
  inkLogger = createLogger5("repl-ink");
2037
- MultilineInput = React2.memo(React2.forwardRef(function MultilineInput2(props, ref) {
2035
+ MultilineInput = React4.memo(React4.forwardRef(function MultilineInput2(props, ref) {
2038
2036
  const { onSubmit, placeholder, popupActive, onChange, onEscape } = props;
2039
- const [buffer, setBuffer] = React2.useState("");
2040
- const [cursor, setCursor] = React2.useState(0);
2041
- React2.useEffect(() => {
2037
+ const [buffer, setBuffer] = React4.useState("");
2038
+ const [cursor, setCursor] = React4.useState(0);
2039
+ React4.useEffect(() => {
2042
2040
  if (popupActive || buffer.startsWith("/")) {
2043
2041
  onChange?.(buffer);
2044
2042
  }
2045
2043
  }, [buffer, onChange, popupActive]);
2046
- React2.useImperativeHandle(ref, () => ({
2044
+ React4.useImperativeHandle(ref, () => ({
2047
2045
  clearBuffer: () => {
2048
2046
  setBuffer("");
2049
2047
  setCursor(0);
@@ -2281,7 +2279,7 @@ var init_repl_ink = __esm(() => {
2281
2279
  })
2282
2280
  }, undefined, false, undefined, this);
2283
2281
  }));
2284
- MessageView = React2.memo(function MessageView2({
2282
+ MessageView = React4.memo(function MessageView2({
2285
2283
  msg,
2286
2284
  terminalWidth,
2287
2285
  tailBounds
@@ -9461,7 +9459,7 @@ class CliQuietModeService {
9461
9459
  // package.json
9462
9460
  var package_default = {
9463
9461
  name: "@ai-setting/roy-agent-cli",
9464
- version: "1.7.18",
9462
+ version: "1.7.20",
9465
9463
  type: "module",
9466
9464
  description: "CLI for roy-agent - Non-interactive command execution",
9467
9465
  main: "./dist/index.js",
@@ -11294,7 +11292,8 @@ var TaskEventTypes = {
11294
11292
  TASK_COMPLETED: "task.background.completed",
11295
11293
  TASK_FAILED: "task.background.failed",
11296
11294
  TASK_TIMEOUT: "task.background.timeout",
11297
- TASK_STOPPED: "task.background.stopped"
11295
+ TASK_STOPPED: "task.background.stopped",
11296
+ TASK_ASK_USER: "task.background.ask_user"
11298
11297
  };
11299
11298
  var EventSourceEventTypes = {
11300
11299
  EVENT_SOURCE_STARTED: "event-source.started",
@@ -11324,6 +11323,8 @@ class EventMessageFormatter {
11324
11323
  return this.formatTaskTimeout(payload);
11325
11324
  case TaskEventTypes.TASK_STOPPED:
11326
11325
  return this.formatTaskStopped(payload);
11326
+ case TaskEventTypes.TASK_ASK_USER:
11327
+ return this.formatTaskAskUser(payload);
11327
11328
  case EventSourceEventTypes.EVENT_SOURCE_STARTED:
11328
11329
  return this.formatEventSourceStarted(payload);
11329
11330
  case EventSourceEventTypes.EVENT_SOURCE_STOPPED:
@@ -11431,6 +11432,34 @@ Task #${taskId}`;
11431
11432
  message += this.appendSubSessionId(payload);
11432
11433
  return message;
11433
11434
  }
11435
+ formatTaskAskUser(payload) {
11436
+ const desc = payload.description || "未命名任务";
11437
+ const bgProcessId = payload.backgroundTaskId || "";
11438
+ const subSessionId = payload.subSessionId || "";
11439
+ const query = payload.query || "(空问题)";
11440
+ let message = `${this.prefix} ❓ 后台子代理「${desc}」请求用户输入`;
11441
+ if (bgProcessId) {
11442
+ message += `
11443
+ bgprocess: ${bgProcessId}`;
11444
+ }
11445
+ if (subSessionId) {
11446
+ message += `
11447
+ subSessionId: ${subSessionId}`;
11448
+ }
11449
+ message += `
11450
+
11451
+ ${query}`;
11452
+ if (payload.hints && payload.hints.length > 0) {
11453
+ message += `
11454
+
11455
+ [\uD83E\uDD16 Agent 操作提示]`;
11456
+ for (const hint of payload.hints) {
11457
+ message += `
11458
+ ${hint}`;
11459
+ }
11460
+ }
11461
+ return message;
11462
+ }
11434
11463
  appendSubSessionId(payload) {
11435
11464
  if (payload.subSessionId) {
11436
11465
  return `
@@ -12839,10 +12868,23 @@ ${COLORS.system("[通知2] ❯ " + message.replace(/\n/g, `
12839
12868
  }
12840
12869
  }
12841
12870
  const agentFromEvent = envEvent.metadata?.agent;
12871
+ let envEventForAgent = envEvent;
12872
+ const eventReplyChannel = envEvent?.metadata?.replyChannel;
12873
+ if (eventReplyChannel) {
12874
+ this.lastReplyChannel = eventReplyChannel;
12875
+ } else if (this.lastReplyChannel) {
12876
+ envEventForAgent = {
12877
+ ...envEvent,
12878
+ metadata: {
12879
+ ...envEvent?.metadata ?? {},
12880
+ replyChannel: this.lastReplyChannel
12881
+ }
12882
+ };
12883
+ }
12842
12884
  this.currentAgentContext = {
12843
12885
  agentType: agentFromEvent,
12844
12886
  pluginEnabled,
12845
- envEvent,
12887
+ envEvent: envEventForAgent,
12846
12888
  plugins,
12847
12889
  eventSessionId,
12848
12890
  systemPrompt: envEvent.metadata?.systemPrompt
@@ -12850,6 +12892,7 @@ ${COLORS.system("[通知2] ❯ " + message.replace(/\n/g, `
12850
12892
  await this.executeInternal(message, { showPrompt: true });
12851
12893
  }
12852
12894
  currentAgentContext = undefined;
12895
+ lastReplyChannel = undefined;
12853
12896
  isIdle() {
12854
12897
  return !this.isExecuting;
12855
12898
  }
@@ -13597,27 +13640,25 @@ function createInteractiveCommand(externalEnvService) {
13597
13640
  var InteractiveCommand = createInteractiveCommand();
13598
13641
 
13599
13642
  // src/commands/run.ts
13600
- import React6 from "react";
13643
+ import React9 from "react";
13601
13644
  import { render } from "ink";
13602
13645
 
13603
- // src/RunTui.tsx
13604
- import { useState as useState6, useCallback as useCallback4, useRef as useRef2, useEffect as useEffect5 } from "react";
13646
+ // src/RunTui.js
13647
+ import React8, { useState as useState6, useCallback as useCallback4, useRef as useRef2, useEffect as useEffect5 } from "react";
13605
13648
  import { Box as Box6, Text as Text8, useApp as useApp2 } from "ink";
13606
13649
 
13607
- // src/tui/App.tsx
13650
+ // src/tui/App.js
13608
13651
  init_Markdown();
13652
+ import React6 from "react";
13609
13653
  import { Box as Box4, Static as Static2, Text as Text6 } from "ink";
13610
13654
 
13611
- // src/tui/Spinner.tsx
13655
+ // src/tui/Spinner.js
13612
13656
  init_theme();
13613
- import { useEffect as useEffect3, useState as useState3 } from "react";
13657
+ import React5, { useEffect as useEffect3, useState as useState3 } from "react";
13614
13658
  import { Text as Text5 } from "ink";
13615
13659
  import { jsxDEV as jsxDEV5 } from "react/jsx-dev-runtime";
13616
13660
  var FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
13617
- var Spinner = ({
13618
- label,
13619
- intervalMs = 80
13620
- }) => {
13661
+ var Spinner = ({ label, intervalMs = 80 }) => {
13621
13662
  const [frame, setFrame] = useState3(0);
13622
13663
  const theme = getTheme();
13623
13664
  useEffect3(() => {
@@ -13641,7 +13682,7 @@ var Spinner = ({
13641
13682
  }, undefined, true, undefined, this);
13642
13683
  };
13643
13684
 
13644
- // src/tui/App.tsx
13685
+ // src/tui/App.js
13645
13686
  init_StatusBar();
13646
13687
  init_theme();
13647
13688
  import { jsxDEV as jsxDEV6 } from "react/jsx-dev-runtime";
@@ -13712,14 +13753,7 @@ var HistoryEntry = ({ item }) => {
13712
13753
  ]
13713
13754
  }, undefined, true, undefined, this);
13714
13755
  };
13715
- var App = ({
13716
- history,
13717
- status,
13718
- model,
13719
- workdir,
13720
- streamingText,
13721
- tokenCount
13722
- }) => {
13756
+ var App = ({ history, status, model, workdir, streamingText, tokenCount }) => {
13723
13757
  const theme = getTheme();
13724
13758
  return /* @__PURE__ */ jsxDEV6(Box4, {
13725
13759
  flexDirection: "column",
@@ -13786,22 +13820,15 @@ var App = ({
13786
13820
  }, undefined, true, undefined, this);
13787
13821
  };
13788
13822
 
13789
- // src/tui/index.ts
13823
+ // src/tui/index.js
13790
13824
  init_Markdown();
13791
13825
  init_StatusBar();
13792
13826
 
13793
- // src/tui/TextInput.tsx
13794
- import { useEffect as useEffect4, useState as useState4 } from "react";
13827
+ // src/tui/TextInput.js
13828
+ import React7, { useEffect as useEffect4, useState as useState4 } from "react";
13795
13829
  import { Box as Box5, Text as Text7, useInput as useInput3 } from "ink";
13796
13830
  import { jsxDEV as jsxDEV7 } from "react/jsx-dev-runtime";
13797
- var TextInput = ({
13798
- label,
13799
- prefix,
13800
- onSubmit,
13801
- onCancel,
13802
- placeholder,
13803
- history = []
13804
- }) => {
13831
+ var TextInput = ({ label, prefix, onSubmit, onCancel, placeholder, history = [] }) => {
13805
13832
  const [value, setValue] = useState4("");
13806
13833
  const [historyIndex, setHistoryIndex] = useState4(-1);
13807
13834
  const [draft, setDraft] = useState4("");
@@ -13891,11 +13918,12 @@ var TextInput = ({
13891
13918
  }, undefined, true, undefined, this);
13892
13919
  };
13893
13920
 
13894
- // src/tui/index.ts
13921
+ // src/tui/index.js
13895
13922
  init_theme();
13896
- init_welcome_card2();
13897
13923
 
13898
- // src/tui/use-streaming-accumulator.ts
13924
+ // src/tui/welcome-card.js
13925
+ init_welcome_card();
13926
+ // src/tui/use-streaming-accumulator.js
13899
13927
  import { useCallback as useCallback3, useState as useState5 } from "react";
13900
13928
  function useStreamingAccumulator() {
13901
13929
  const [status, setStatus] = useState5("idle");
@@ -13929,10 +13957,10 @@ function useStreamingAccumulator() {
13929
13957
  return { status, streamingText, start, append, finish, fail };
13930
13958
  }
13931
13959
 
13932
- // src/RunTui.tsx
13960
+ // src/RunTui.js
13933
13961
  init_markdown();
13934
13962
 
13935
- // src/slash.ts
13963
+ // src/slash.js
13936
13964
  var CLEAR_SENTINEL = "__CLEAR__";
13937
13965
  function dispatchSlashCommand(raw, ctx) {
13938
13966
  const text = raw.trim();
@@ -14004,18 +14032,9 @@ function dispatchSlashCommand(raw, ctx) {
14004
14032
  }
14005
14033
  }
14006
14034
 
14007
- // src/RunTui.tsx
14035
+ // src/RunTui.js
14008
14036
  import { jsxDEV as jsxDEV8 } from "react/jsx-dev-runtime";
14009
- var RunScreen = ({
14010
- handleQuery,
14011
- streamHandleQuery,
14012
- model,
14013
- workdir,
14014
- maxLines: initialMaxLines,
14015
- markdownEnabled: markdownEnabled2,
14016
- onExit,
14017
- onRegisterHandlers
14018
- }) => {
14037
+ var RunScreen = ({ handleQuery, streamHandleQuery, model, workdir, maxLines: initialMaxLines, markdownEnabled: markdownEnabled2, onExit, onRegisterHandlers }) => {
14019
14038
  const [history, setHistory] = useState6([]);
14020
14039
  const [errorMessage, setErrorMessage] = useState6(null);
14021
14040
  const [maxLines, setMaxLines] = useState6(initialMaxLines);
@@ -14211,49 +14230,1088 @@ var RunTui_default = RunScreen;
14211
14230
  // src/commands/run.ts
14212
14231
  init_markdown();
14213
14232
 
14214
- // src/commands/run-shutdown.ts
14215
- import { TempFileManager as TempFileManager3 } from "@ai-setting/roy-agent-core/utils/temp-file-manager";
14216
- async function shutdownRunSteps(deps) {
14217
- const {
14218
- lspManagerDispose,
14219
- pluginAdapterDispose,
14220
- stopEventHandler,
14221
- stopTaskEventHandler,
14222
- queryExecutor,
14223
- env,
14224
- envService,
14225
- shouldDisposeEnvService,
14226
- output,
14227
- logger: logger6
14228
- } = deps;
14233
+ // src/commands/shared/session-manager.js
14234
+ import { parseImageInput as parseImageInput3 } from "@ai-setting/roy-agent-core";
14235
+
14236
+ class SessionManager2 {
14237
+ sessionComponent;
14238
+ output;
14239
+ quiet;
14240
+ attachedImagesMap = new Map;
14241
+ constructor(options) {
14242
+ this.sessionComponent = options.sessionComponent;
14243
+ this.output = options.output;
14244
+ this.quiet = options.quiet;
14245
+ }
14246
+ async init(sessionId, isContinue) {
14247
+ let targetSessionId = sessionId;
14248
+ let isNewSession = false;
14249
+ if (isContinue && !targetSessionId) {
14250
+ const activeSession = await this.sessionComponent.getActiveSession();
14251
+ if (activeSession) {
14252
+ targetSessionId = activeSession.id;
14253
+ if (!this.quiet) {
14254
+ this.output.info(`继续会话: ${activeSession.title} (${targetSessionId})`);
14255
+ }
14256
+ } else {
14257
+ this.output.warn("没有找到上次会话,将创建新会话");
14258
+ }
14259
+ }
14260
+ if (targetSessionId) {
14261
+ await this.sessionComponent.setActiveSession(targetSessionId);
14262
+ const session2 = await this.sessionComponent.get(targetSessionId);
14263
+ if (session2) {
14264
+ if (!this.quiet) {
14265
+ this.output.info(`会话: ${session2.title} (${targetSessionId})`);
14266
+ }
14267
+ } else {
14268
+ this.output.warn(`会话不存在: ${targetSessionId},将创建新会话`);
14269
+ targetSessionId = undefined;
14270
+ }
14271
+ }
14272
+ if (!targetSessionId) {
14273
+ const newSession = await this.sessionComponent.create({
14274
+ title: `Session - ${new Date().toLocaleString("zh-CN")}`
14275
+ });
14276
+ targetSessionId = newSession.id;
14277
+ isNewSession = true;
14278
+ await this.sessionComponent.setActiveSession(targetSessionId);
14279
+ if (!this.quiet) {
14280
+ this.output.info(`创建新会话: ${newSession.title} (${targetSessionId})`);
14281
+ }
14282
+ }
14283
+ this.clearAttachments();
14284
+ const session = await this.sessionComponent.get(targetSessionId);
14285
+ return {
14286
+ sessionId: targetSessionId,
14287
+ isNewSession,
14288
+ sessionTitle: session?.title || "Unknown"
14289
+ };
14290
+ }
14291
+ async switchSession(sessionId) {
14292
+ return this.init(sessionId, false);
14293
+ }
14294
+ async getCurrentSession() {
14295
+ return this.sessionComponent.getActiveSession();
14296
+ }
14297
+ async attachImage(rawPath) {
14298
+ const normalized = rawPath.trim();
14299
+ if (!normalized) {
14300
+ throw new Error("attachImage: empty path");
14301
+ }
14302
+ const existing = this.attachedImagesMap.get(normalized);
14303
+ if (existing) {
14304
+ return existing;
14305
+ }
14306
+ const part = await parseImageInput3(normalized);
14307
+ this.attachedImagesMap.set(normalized, part);
14308
+ return part;
14309
+ }
14310
+ listAttachments() {
14311
+ return Array.from(this.attachedImagesMap.values());
14312
+ }
14313
+ clearAttachments() {
14314
+ this.attachedImagesMap.clear();
14315
+ }
14316
+ async getQueryPayload(text) {
14317
+ if (this.attachedImagesMap.size === 0) {
14318
+ return text;
14319
+ }
14320
+ return [
14321
+ { type: "text", text },
14322
+ ...this.listAttachments()
14323
+ ];
14324
+ }
14325
+ }
14326
+
14327
+ // src/commands/shared/query-executor.js
14328
+ init_stream_output_service();
14329
+ import { ContextError as ContextError4, ErrorCodes as ErrorCodes4, TracedAs as TracedAs7 } from "@ai-setting/roy-agent-core";
14330
+ var __decorate = function(decorators, target, key, desc) {
14331
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
14332
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
14333
+ r = Reflect.decorate(decorators, target, key, desc);
14334
+ else
14335
+ for (var i = decorators.length - 1;i >= 0; i--)
14336
+ if (d = decorators[i])
14337
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
14338
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
14339
+ };
14340
+
14341
+ class QueryExecutor2 {
14342
+ env;
14343
+ sessionComponent;
14344
+ output;
14345
+ quiet;
14346
+ silent = false;
14347
+ streamService = null;
14348
+ unsubscribe = null;
14349
+ streamOptions = {
14350
+ showReasoning: true,
14351
+ showToolCalls: true,
14352
+ showToolResults: false
14353
+ };
14354
+ _pendingContextConfig = null;
14355
+ _pendingChunkCallback = undefined;
14356
+ constructor(options) {
14357
+ this.env = options.env;
14358
+ this.sessionComponent = options.sessionComponent;
14359
+ this.output = options.output;
14360
+ this.quiet = options.quiet;
14361
+ this.silent = options.silent ?? false;
14362
+ }
14363
+ initSummaryAgent(llmComponent, promptComponent) {
14364
+ const session = this.sessionComponent;
14365
+ if (typeof session.setSummaryComponents === "function") {
14366
+ session.setSummaryComponents(promptComponent, llmComponent);
14367
+ }
14368
+ }
14369
+ initStreamOutput(llmComponent, providerId = "minimax") {
14370
+ if (llmComponent) {
14371
+ const contextConfig = llmComponent.getContextThresholdConfig(providerId);
14372
+ this._pendingContextConfig = contextConfig;
14373
+ }
14374
+ }
14375
+ subscribeToEvents(options) {
14376
+ this.streamOptions = options;
14377
+ if (this.streamService) {
14378
+ this.streamService.setOptions(options);
14379
+ }
14380
+ if (this.unsubscribe) {
14381
+ return;
14382
+ }
14383
+ this.streamService = new StreamOutputService({
14384
+ ...options,
14385
+ silent: this.silent ?? false
14386
+ });
14387
+ if (this._pendingChunkCallback !== undefined) {
14388
+ this.streamService.setChunkCallback(this._pendingChunkCallback);
14389
+ this._pendingChunkCallback = undefined;
14390
+ }
14391
+ if (this._pendingContextConfig) {
14392
+ this.streamService.setContextInfo(this._pendingContextConfig.contextWindow, this._pendingContextConfig.contextWindow * this._pendingContextConfig.thresholdRatio);
14393
+ this._pendingContextConfig = null;
14394
+ }
14395
+ this.unsubscribe = this.env.subscribeTo([
14396
+ "llm.start",
14397
+ "llm.text",
14398
+ "llm.reasoning",
14399
+ "llm.completed",
14400
+ "llm.error",
14401
+ "tool.call",
14402
+ "tool.result",
14403
+ "tool.error",
14404
+ "context.threshold_exceeded",
14405
+ "context.compacting",
14406
+ "context.compacted"
14407
+ ], (event) => this.handleEvent(event));
14408
+ }
14409
+ setChunkCallback(cb) {
14410
+ if (this.streamService) {
14411
+ this.streamService.setChunkCallback(cb);
14412
+ } else {
14413
+ this._pendingChunkCallback = cb;
14414
+ }
14415
+ }
14416
+ handleEvent(event) {
14417
+ if (event.type === "context.threshold_exceeded" && !this.quiet) {
14418
+ const payload = event.payload;
14419
+ this.output.warn(`⚙ 上下文阈值 (${payload.totalTokens}/${payload.contextWindow})`);
14420
+ }
14421
+ if (event.type === "context.compacting" && !this.quiet) {
14422
+ this.output.info("⚙ 压缩中...");
14423
+ }
14424
+ if (event.type === "context.compacted" && !this.quiet) {
14425
+ this.output.success(`✓ 已压缩 (${event.payload.checkpointId})`);
14426
+ }
14427
+ this.streamService?.handleEvent(event);
14428
+ }
14429
+ async execute(message, sessionId, streamOptions, traceId, agentContext) {
14430
+ const options = {
14431
+ showReasoning: streamOptions?.showReasoning ?? this.streamOptions.showReasoning,
14432
+ showToolCalls: streamOptions?.showToolCalls ?? this.streamOptions.showToolCalls,
14433
+ showToolResults: streamOptions?.showToolResults ?? this.streamOptions.showToolResults
14434
+ };
14435
+ this.subscribeToEvents(options);
14436
+ this.streamService?.reset();
14437
+ if (!this.quiet) {
14438
+ this.output.info(`执行: ${message}`);
14439
+ }
14440
+ const contextHandler = new ContextHandlerService(this.env, this.sessionComponent, { maxRetries: 1, autoCompact: true });
14441
+ const { systemPrompt: agentContextSystemPrompt, eventSourceSystemPrompt: agentContextPreloadedPrompts, ...restAgentContext } = agentContext ?? {};
14442
+ let eventSourceFinalPrompt;
14443
+ if (typeof agentContextSystemPrompt === "string" && agentContextSystemPrompt.length > 0) {
14444
+ eventSourceFinalPrompt = agentContextSystemPrompt;
14445
+ } else if (typeof agentContextPreloadedPrompts === "string" && agentContextPreloadedPrompts.length > 0) {
14446
+ eventSourceFinalPrompt = agentContextPreloadedPrompts;
14447
+ }
14448
+ const context = {
14449
+ sessionId,
14450
+ metadata: {
14451
+ originalQuery: message,
14452
+ traceId,
14453
+ systemPrompt: eventSourceFinalPrompt
14454
+ },
14455
+ ...restAgentContext
14456
+ };
14457
+ let result;
14458
+ try {
14459
+ result = await contextHandler.handleQueryWithContext(message, context);
14460
+ } catch (error) {
14461
+ if (error instanceof ContextError4 && error.code === ErrorCodes4.CONTEXT_THRESHOLD_EXCEEDED) {
14462
+ this.output.error(`上下文阈值超出限制: ${error.usage?.totalTokens}/${error.contextWindow}`);
14463
+ this.output.info("请手动压缩会话: roy-agent sessions compact " + sessionId);
14464
+ }
14465
+ throw error;
14466
+ }
14467
+ if (!this.quiet) {
14468
+ this.output.success("执行完成");
14469
+ }
14470
+ return result;
14471
+ }
14472
+ dispose() {
14473
+ if (this.unsubscribe) {
14474
+ this.unsubscribe();
14475
+ this.unsubscribe = null;
14476
+ }
14477
+ }
14478
+ getFullText() {
14479
+ return this.streamService?.getFullText() ?? "";
14480
+ }
14481
+ getLastUsage() {
14482
+ return this.streamService?.getUsageInfo() ?? null;
14483
+ }
14484
+ resetStream() {
14485
+ this.streamService?.reset();
14486
+ }
14487
+ async compact(sessionId) {
14488
+ try {
14489
+ const envCore = this.env.getComponent("core");
14490
+ if (envCore?.pushEnvEvent) {
14491
+ envCore.pushEnvEvent({
14492
+ type: "context.compacting",
14493
+ metadata: { sessionId },
14494
+ payload: {}
14495
+ });
14496
+ }
14497
+ const result = await this.sessionComponent.compact(sessionId, {
14498
+ summary: "Manual compact from interactive mode"
14499
+ });
14500
+ if (envCore?.pushEnvEvent) {
14501
+ envCore.pushEnvEvent({
14502
+ type: "context.compacted",
14503
+ metadata: { sessionId },
14504
+ payload: {
14505
+ checkpointId: result.checkpoint.id,
14506
+ messagesCompacted: result.deletedMessageCount
14507
+ }
14508
+ });
14509
+ }
14510
+ return {
14511
+ success: true,
14512
+ checkpoint: result.checkpoint,
14513
+ deletedMessageCount: result.deletedMessageCount
14514
+ };
14515
+ } catch (error) {
14516
+ const errorMessage = error instanceof Error ? error.message : String(error);
14517
+ this.output.error(`压缩失败: ${errorMessage}`);
14518
+ return {
14519
+ success: false,
14520
+ error: errorMessage
14521
+ };
14522
+ }
14523
+ }
14524
+ }
14525
+ __decorate([
14526
+ TracedAs7("cli.query-executor.execute", { recordParams: true, log: true })
14527
+ ], QueryExecutor2.prototype, "execute", null);
14528
+
14529
+ // src/commands/interactive-event-sources.js
14530
+ import { TracedAs as TracedAs8 } from "@ai-setting/roy-agent-core";
14531
+ var __decorate2 = function(decorators, target, key, desc) {
14532
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
14533
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
14534
+ r = Reflect.decorate(decorators, target, key, desc);
14535
+ else
14536
+ for (var i = decorators.length - 1;i >= 0; i--)
14537
+ if (d = decorators[i])
14538
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
14539
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
14540
+ };
14541
+ async function startSingleEventSource2(eventSourceComponent, output, eventSourceId) {
14542
+ return EventSourceStarter2.instance.runSingle(eventSourceComponent, output, eventSourceId);
14543
+ }
14544
+ async function startEventSources2(eventSourceIds, eventSourceComponent, output) {
14545
+ return EventSourceStarter2.instance.run(eventSourceIds, eventSourceComponent, output);
14546
+ }
14547
+
14548
+ class EventSourceStarter2 {
14549
+ static instance = new EventSourceStarter2;
14550
+ async run(eventSourceIds, eventSourceComponent, output) {
14551
+ return startEventSourcesImpl2(eventSourceIds, eventSourceComponent, output);
14552
+ }
14553
+ async runSingle(eventSourceComponent, output, eventSourceId) {
14554
+ return startSingleEventSourceImpl2(eventSourceComponent, output, eventSourceId);
14555
+ }
14556
+ }
14557
+ __decorate2([
14558
+ TracedAs8("interactive.startEventSources", { recordParams: false, log: false })
14559
+ ], EventSourceStarter2.prototype, "run", null);
14560
+ __decorate2([
14561
+ TracedAs8("interactive.startSingleEventSource", { recordParams: false, log: false })
14562
+ ], EventSourceStarter2.prototype, "runSingle", null);
14563
+ async function startEventSourcesImpl2(eventSourceIds, eventSourceComponent, output) {
14564
+ const results = [];
14565
+ if (!eventSourceIds || eventSourceIds.length === 0) {
14566
+ return { results, total: 0, successCount: 0, failedCount: 0 };
14567
+ }
14568
+ for (const id of eventSourceIds) {
14569
+ if (!id)
14570
+ continue;
14571
+ const result = await startSingleEventSource2(eventSourceComponent, output, id);
14572
+ results.push(result);
14573
+ }
14574
+ const successCount = results.filter((r) => r.success).length;
14575
+ const failedCount = results.length - successCount;
14576
+ if (results.length > 1) {
14577
+ if (failedCount > 0) {
14578
+ output.info(`
14579
+ ✅ 成功启动 ${successCount}/${results.length} 个事件源`);
14580
+ } else {
14581
+ output.success(`
14582
+ ✅ 成功启动 ${successCount}/${results.length} 个事件源`);
14583
+ }
14584
+ }
14585
+ return { results, total: results.length, successCount, failedCount };
14586
+ }
14587
+ async function startSingleEventSourceImpl2(eventSourceComponent, output, eventSourceId) {
14588
+ const sources = eventSourceComponent.list();
14589
+ const matchedSource = sources.find((s) => s.id === eventSourceId || s.id.startsWith(eventSourceId));
14590
+ if (!matchedSource) {
14591
+ output.error(`❌ 事件源不存在: ${eventSourceId}`);
14592
+ output.info(`可用的事件源:`);
14593
+ for (const s of sources) {
14594
+ output.info(` - ${s.id.substring(0, 8)}: ${s.name} (${s.type})`);
14595
+ }
14596
+ return {
14597
+ id: eventSourceId,
14598
+ name: eventSourceId,
14599
+ success: false,
14600
+ status: "not_found",
14601
+ error: `EventSource not found: ${eventSourceId}`
14602
+ };
14603
+ }
14604
+ const actualId = matchedSource.id;
14605
+ const status = eventSourceComponent.getStatus(actualId);
14606
+ if (status === "running") {
14607
+ output.info(`\uD83D\uDCE1 事件源 ${matchedSource.name} 已在运行中`);
14608
+ return {
14609
+ id: actualId,
14610
+ name: matchedSource.name,
14611
+ success: true,
14612
+ status: "skipped"
14613
+ };
14614
+ }
14615
+ try {
14616
+ await eventSourceComponent.startSource(actualId);
14617
+ const verifyStatus = eventSourceComponent.getStatus(actualId);
14618
+ if (verifyStatus !== "running") {
14619
+ const errMsg = `启动后状态异常: ${verifyStatus}`;
14620
+ output.error(`❌ ${errMsg}`);
14621
+ return {
14622
+ id: actualId,
14623
+ name: matchedSource.name,
14624
+ success: false,
14625
+ status: "failed",
14626
+ error: errMsg
14627
+ };
14628
+ }
14629
+ output.success(`\uD83D\uDCE1 已启动事件源: ${matchedSource.name} (${verifyStatus})`);
14630
+ return {
14631
+ id: actualId,
14632
+ name: matchedSource.name,
14633
+ success: true,
14634
+ status: "started"
14635
+ };
14636
+ } catch (error) {
14637
+ const errMsg = error instanceof Error ? error.message : String(error);
14638
+ output.error(`❌ 启动事件源失败: ${matchedSource.name} - ${errMsg}`);
14639
+ return {
14640
+ id: actualId,
14641
+ name: matchedSource.name,
14642
+ success: false,
14643
+ status: "failed",
14644
+ error: errMsg
14645
+ };
14646
+ }
14647
+ }
14648
+
14649
+ // src/commands/collect-event-source-system-prompts.js
14650
+ import { resolveBountyIMSystemPrompt as resolveBountyIMSystemPrompt2 } from "@ai-setting/roy-agent-core";
14651
+ function resolveSystemPromptForSource2(config) {
14652
+ if (config.type === "bounty-im") {
14653
+ const imServerUrl = config.imServerUrl || config.options && config.options.imServerUrl;
14654
+ const address = config.address || config.options && config.options.address || "unknown";
14655
+ return resolveBountyIMSystemPrompt2({
14656
+ configSystemPrompt: config.systemPrompt,
14657
+ currentAddress: address,
14658
+ imServerUrl
14659
+ });
14660
+ }
14661
+ return config.systemPrompt;
14662
+ }
14663
+ function collectEventSourceSystemPrompts2(eventSourceIds, eventSourceComponent) {
14664
+ const result = [];
14665
+ for (const id of eventSourceIds) {
14666
+ const config = eventSourceComponent.get(id);
14667
+ if (!config)
14668
+ continue;
14669
+ const prompt = resolveSystemPromptForSource2(config);
14670
+ if (!prompt)
14671
+ continue;
14672
+ result.push({ id, type: config.type, prompt });
14673
+ }
14674
+ return result;
14675
+ }
14676
+ function joinResolvedSystemPrompts2(prompts) {
14677
+ return prompts.map((p) => p.prompt).join(`
14678
+
14679
+ ---
14680
+
14681
+ `);
14682
+ }
14683
+
14684
+ // src/commands/act-agent-validation.js
14685
+ function validateActAgent2(agentComponent, agentName) {
14686
+ if (!agentName || agentName === "default") {
14687
+ return { valid: true };
14688
+ }
14689
+ if (!agentComponent?.getAgent(agentName)) {
14690
+ return {
14691
+ valid: false,
14692
+ message: `Agent "${agentName}" 不存在`
14693
+ };
14694
+ }
14695
+ return { valid: true };
14696
+ }
14697
+ function buildActAgentContext2(agentName) {
14698
+ if (!agentName || agentName === "default") {
14699
+ return;
14700
+ }
14701
+ return { agentType: agentName };
14702
+ }
14703
+
14704
+ // src/commands/shared/event-handler.js
14705
+ import { TracedAs as TracedAs9 } from "@ai-setting/roy-agent-core";
14706
+ var __decorate3 = function(decorators, target, key, desc) {
14707
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
14708
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
14709
+ r = Reflect.decorate(decorators, target, key, desc);
14710
+ else
14711
+ for (var i = decorators.length - 1;i >= 0; i--)
14712
+ if (d = decorators[i])
14713
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
14714
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
14715
+ };
14716
+
14717
+ class EventHandler2 {
14718
+ env;
14719
+ eventTypes;
14720
+ onEvent;
14721
+ onEventWithEnv;
14722
+ formatter;
14723
+ isIdle;
14724
+ idleCheckInterval;
14725
+ queue = [];
14726
+ isProcessing = false;
14727
+ isStopped = false;
14728
+ unsubscribe = null;
14729
+ sessionComponent = null;
14730
+ activeEventSessionId = null;
14731
+ constructor(options) {
14732
+ this.env = options.env;
14733
+ this.eventTypes = options.eventTypes;
14734
+ this.onEvent = options.onEvent;
14735
+ this.onEventWithEnv = options.onEventWithEnv;
14736
+ this.formatter = options.formatter ?? new EventMessageFormatter;
14737
+ this.isIdle = options.isIdle ?? (() => true);
14738
+ this.idleCheckInterval = options.idleCheckInterval ?? 100;
14739
+ this.sessionComponent = options.sessionComponent ?? null;
14740
+ }
14741
+ start() {
14742
+ this.isStopped = false;
14743
+ this.unsubscribe = this.env.subscribeAll((event) => {
14744
+ if (this.matchesEventType(event.type)) {
14745
+ this.handleEvent(event);
14746
+ }
14747
+ });
14748
+ return () => this.stop();
14749
+ }
14750
+ matchesEventType(eventType) {
14751
+ for (const pattern of this.eventTypes) {
14752
+ if (this.matchPattern(eventType, pattern)) {
14753
+ return true;
14754
+ }
14755
+ }
14756
+ return false;
14757
+ }
14758
+ matchPattern(eventType, pattern) {
14759
+ if (pattern === "*")
14760
+ return true;
14761
+ if (pattern.endsWith(".*")) {
14762
+ const prefix = pattern.slice(0, -2);
14763
+ return eventType === prefix || eventType.startsWith(prefix + ".");
14764
+ }
14765
+ return eventType === pattern;
14766
+ }
14767
+ stop() {
14768
+ this.isStopped = true;
14769
+ if (this.unsubscribe) {
14770
+ this.unsubscribe();
14771
+ this.unsubscribe = null;
14772
+ }
14773
+ this.queue = [];
14774
+ this.isProcessing = false;
14775
+ this.clearActiveSession();
14776
+ }
14777
+ handleEvent(event) {
14778
+ if (this.isStopped) {
14779
+ return;
14780
+ }
14781
+ const formatted = this.formatter.formatWithEvent(event);
14782
+ this.enqueue(formatted);
14783
+ }
14784
+ enqueue(formattedEvent) {
14785
+ if (this.isStopped) {
14786
+ return;
14787
+ }
14788
+ this.queue.push(formattedEvent);
14789
+ if (!this.isProcessing) {
14790
+ this.processQueue();
14791
+ }
14792
+ }
14793
+ getQueueLength() {
14794
+ return this.queue.length;
14795
+ }
14796
+ isQueueEmpty() {
14797
+ return this.queue.length === 0;
14798
+ }
14799
+ async processQueue() {
14800
+ this.isProcessing = true;
14801
+ const sessionId = await this.ensureActiveSession();
14802
+ if (this.isStopped) {
14803
+ this.clearActiveSession();
14804
+ this.isProcessing = false;
14805
+ return;
14806
+ }
14807
+ while (!this.isStopped && this.queue.length > 0) {
14808
+ await this.waitForIdle();
14809
+ if (this.isStopped) {
14810
+ break;
14811
+ }
14812
+ const item = this.queue.shift();
14813
+ if (!item) {
14814
+ break;
14815
+ }
14816
+ if (sessionId) {
14817
+ item.eventSessionId = sessionId;
14818
+ }
14819
+ try {
14820
+ if (this.onEventWithEnv) {
14821
+ await this.onEventWithEnv(item);
14822
+ continue;
14823
+ }
14824
+ await this.onEvent(item.message);
14825
+ } catch (error) {
14826
+ console.error(`[EventHandler] 处理事件失败:`, error);
14827
+ }
14828
+ }
14829
+ this.isProcessing = false;
14830
+ }
14831
+ async ensureActiveSession() {
14832
+ if (!this.sessionComponent)
14833
+ return null;
14834
+ if (this.activeEventSessionId)
14835
+ return this.activeEventSessionId;
14836
+ const triggerSessionId = this.queue.map((item) => item.triggerSessionId).find((id) => !!id);
14837
+ if (triggerSessionId) {
14838
+ try {
14839
+ const existing = await this.sessionComponent.get(triggerSessionId);
14840
+ if (existing) {
14841
+ if (this.isStopped) {
14842
+ return null;
14843
+ }
14844
+ this.activeEventSessionId = existing.id;
14845
+ await this.sessionComponent.setActiveSession(existing.id);
14846
+ return existing.id;
14847
+ }
14848
+ console.warn(`[EventHandler] Parent session ${triggerSessionId} not found, trying global active session`);
14849
+ } catch (error) {
14850
+ console.error(`[EventHandler] Failed to lookup parent session ${triggerSessionId}:`, error);
14851
+ }
14852
+ }
14853
+ try {
14854
+ const activeId = this.sessionComponent.getActiveSessionId();
14855
+ if (activeId) {
14856
+ const existing = await this.sessionComponent.get(activeId);
14857
+ if (existing) {
14858
+ if (this.isStopped) {
14859
+ return null;
14860
+ }
14861
+ this.activeEventSessionId = existing.id;
14862
+ return existing.id;
14863
+ }
14864
+ }
14865
+ } catch (error) {
14866
+ console.error(`[EventHandler] Failed to lookup global active session:`, error);
14867
+ }
14868
+ return this.createNewEventSession();
14869
+ }
14870
+ async createNewEventSession() {
14871
+ try {
14872
+ const session = await this.sessionComponent.create({
14873
+ title: `Event Session - ${new Date().toLocaleString()}`
14874
+ });
14875
+ if (this.isStopped) {
14876
+ this.activeEventSessionId = null;
14877
+ return null;
14878
+ }
14879
+ this.activeEventSessionId = session.id;
14880
+ await this.sessionComponent.setActiveSession(session.id);
14881
+ return session.id;
14882
+ } catch (error) {
14883
+ console.error(`[EventHandler] 创建事件 session 失败:`, error);
14884
+ return null;
14885
+ }
14886
+ }
14887
+ clearActiveSession() {
14888
+ this.activeEventSessionId = null;
14889
+ }
14890
+ getActiveEventSessionId() {
14891
+ return this.activeEventSessionId;
14892
+ }
14893
+ async waitForIdle() {
14894
+ while (!this.isStopped && !this.isIdle()) {
14895
+ await this.sleep(this.idleCheckInterval);
14896
+ }
14897
+ }
14898
+ sleep(ms) {
14899
+ return new Promise((resolve) => setTimeout(resolve, ms));
14900
+ }
14901
+ }
14902
+ __decorate3([
14903
+ TracedAs9("cli.event-handler.handleEvent", { recordParams: true })
14904
+ ], EventHandler2.prototype, "handleEvent", null);
14905
+
14906
+ // src/commands/shared/task-event-handler.js
14907
+ import { createLogger as createLogger7 } from "@ai-setting/roy-agent-core";
14908
+ var logger6 = createLogger7("task-event-handler");
14909
+ var TASK_EVENTS2 = {
14910
+ CREATED: "task.created",
14911
+ UPDATED: "task.updated",
14912
+ COMPLETED: "task.completed",
14913
+ DELETED: "task.deleted",
14914
+ OPERATION_ADDED: "task.operation_added",
14915
+ DELEGATED: "task.delegated"
14916
+ };
14917
+
14918
+ class TaskEventHandler2 {
14919
+ env;
14920
+ enabled;
14921
+ unsubscribe = null;
14922
+ constructor(options) {
14923
+ this.env = options.env;
14924
+ this.enabled = options.enabled ?? true;
14925
+ }
14926
+ start() {
14927
+ if (!this.enabled) {
14928
+ return () => {};
14929
+ }
14930
+ this.unsubscribe = this.env.subscribeAll((event) => {
14931
+ if (event.type.startsWith("task.")) {
14932
+ this.handleEvent(event);
14933
+ }
14934
+ });
14935
+ logger6.info("[TaskEventHandler] Started");
14936
+ return () => this.stop();
14937
+ }
14938
+ stop() {
14939
+ if (this.unsubscribe) {
14940
+ this.unsubscribe();
14941
+ this.unsubscribe = null;
14942
+ logger6.info("[TaskEventHandler] Stopped");
14943
+ }
14944
+ }
14945
+ handleEvent(event) {
14946
+ const payload = event.payload;
14947
+ switch (event.type) {
14948
+ case TASK_EVENTS2.CREATED:
14949
+ this.logTaskCreated(payload);
14950
+ break;
14951
+ case TASK_EVENTS2.UPDATED:
14952
+ this.logTaskUpdated(payload);
14953
+ break;
14954
+ case TASK_EVENTS2.COMPLETED:
14955
+ this.logTaskCompleted(payload);
14956
+ break;
14957
+ case TASK_EVENTS2.DELETED:
14958
+ this.logTaskDeleted(payload);
14959
+ break;
14960
+ case TASK_EVENTS2.OPERATION_ADDED:
14961
+ this.logOperationAdded(payload);
14962
+ break;
14963
+ case TASK_EVENTS2.DELEGATED:
14964
+ this.logTaskDelegated(payload);
14965
+ break;
14966
+ default:
14967
+ logger6.info(`[${event.type}]`, payload);
14968
+ }
14969
+ }
14970
+ logTaskCreated(payload) {
14971
+ const task = payload.task;
14972
+ logger6.info(`\uD83D\uDCDD Task created: #${task.id} - ${task.title}`);
14973
+ logger6.info(` Status: ${task.status}, Priority: ${task.priority}, Type: ${task.type || "normal"}`);
14974
+ if (task.project_path) {
14975
+ logger6.info(` Project: ${task.project_path}`);
14976
+ }
14977
+ if (task.context) {
14978
+ logger6.info(` Context: ${task.context}`);
14979
+ }
14980
+ }
14981
+ logTaskUpdated(payload) {
14982
+ const task = payload.task;
14983
+ const changes = payload.changes;
14984
+ logger6.info(`✏️ Task updated: #${task.id} - ${task.title}`);
14985
+ logger6.info(` Status: ${task.status}, Priority: ${task.priority}, Type: ${task.type || "normal"}, Progress: ${task.progress}%`);
14986
+ if (changes) {
14987
+ logger6.info(` Changes: ${JSON.stringify(changes)}`);
14988
+ }
14989
+ }
14990
+ logTaskCompleted(payload) {
14991
+ const task = payload.task;
14992
+ logger6.info(`✅ Task completed: #${task.id} - ${task.title}`);
14993
+ logger6.info(` Progress: ${task.progress}%, Updated: ${task.updatedAt}`);
14994
+ }
14995
+ logTaskDeleted(payload) {
14996
+ logger6.info(`\uD83D\uDDD1️ Task deleted: #${payload.taskId}`);
14997
+ }
14998
+ logOperationAdded(payload) {
14999
+ const op = payload.operation;
15000
+ logger6.info(`\uD83D\uDCCB Operation added to task #${payload.taskId}:`);
15001
+ logger6.info(` [${op.milestoneType}] ${op.milestoneTitle}`);
15002
+ logger6.info(` Session: ${op.sessionId}`);
15003
+ }
15004
+ logTaskDelegated(payload) {
15005
+ logger6.info(`\uD83D\uDE80 Task delegated: #${payload.taskId}`);
15006
+ logger6.info(` Background: ${payload.backgroundTaskId}, Type: ${payload.subagentType}`);
15007
+ logger6.info(` ${payload.description}`);
15008
+ }
15009
+ }
15010
+
15011
+ // src/commands/shared/event-message-formatter.js
15012
+ var TaskEventTypes2 = {
15013
+ TASK_STARTED: "task.background.started",
15014
+ TASK_PROGRESS: "task.background.progress",
15015
+ TASK_COMPLETED: "task.background.completed",
15016
+ TASK_FAILED: "task.background.failed",
15017
+ TASK_TIMEOUT: "task.background.timeout",
15018
+ TASK_STOPPED: "task.background.stopped",
15019
+ TASK_ASK_USER: "task.background.ask_user"
15020
+ };
15021
+ var EventSourceEventTypes2 = {
15022
+ EVENT_SOURCE_STARTED: "event-source.started",
15023
+ EVENT_SOURCE_STOPPED: "event-source.stopped",
15024
+ EVENT_SOURCE_EVENT_PREFIX: "event-source.event."
15025
+ };
15026
+
15027
+ class EventMessageFormatter2 {
15028
+ prefix;
15029
+ showTimestamp;
15030
+ constructor(options = {}) {
15031
+ this.prefix = options.prefix ?? "[通知]";
15032
+ this.showTimestamp = options.showTimestamp ?? false;
15033
+ }
15034
+ format(event) {
15035
+ const { type, payload } = event;
15036
+ switch (type) {
15037
+ case TaskEventTypes2.TASK_STARTED:
15038
+ return this.formatTaskStarted(payload);
15039
+ case TaskEventTypes2.TASK_PROGRESS:
15040
+ return this.formatTaskProgress(payload);
15041
+ case TaskEventTypes2.TASK_COMPLETED:
15042
+ return this.formatTaskCompleted(payload);
15043
+ case TaskEventTypes2.TASK_FAILED:
15044
+ return this.formatTaskFailed(payload);
15045
+ case TaskEventTypes2.TASK_TIMEOUT:
15046
+ return this.formatTaskTimeout(payload);
15047
+ case TaskEventTypes2.TASK_STOPPED:
15048
+ return this.formatTaskStopped(payload);
15049
+ case TaskEventTypes2.TASK_ASK_USER:
15050
+ return this.formatTaskAskUser(payload);
15051
+ case EventSourceEventTypes2.EVENT_SOURCE_STARTED:
15052
+ return this.formatEventSourceStarted(payload);
15053
+ case EventSourceEventTypes2.EVENT_SOURCE_STOPPED:
15054
+ return this.formatEventSourceStopped(payload);
15055
+ default:
15056
+ if (type.startsWith(EventSourceEventTypes2.EVENT_SOURCE_EVENT_PREFIX)) {
15057
+ return this.formatEventSourceEvent(event);
15058
+ }
15059
+ return this.formatGeneric(event);
15060
+ }
15061
+ }
15062
+ formatTaskStarted(payload) {
15063
+ const desc = payload.description || "未命名任务";
15064
+ return `${this.prefix} \uD83D\uDCE2 后台任务「${desc}」已启动`;
15065
+ }
15066
+ formatTaskProgress(payload) {
15067
+ const desc = payload.description || "未命名任务";
15068
+ const message = payload.progressMessage || "";
15069
+ const taskId = payload.associatedTaskId;
15070
+ let result = `${this.prefix} \uD83D\uDD04 后台任务「${desc}」`;
15071
+ if (taskId !== undefined) {
15072
+ result += `[Task #${taskId}] `;
15073
+ }
15074
+ result += `还在进行中,请耐心等待。需查询具体进度可调用 task_get / task_operation_list 等工具`;
15075
+ if (message)
15076
+ result += ` - ${message}`;
15077
+ return result;
15078
+ }
15079
+ formatTaskCompleted(payload) {
15080
+ const desc = payload.description || "未命名任务";
15081
+ const result = payload.result;
15082
+ const time = payload.executionTimeMs ? `(${this.formatDuration(payload.executionTimeMs)})` : "";
15083
+ const bgProcessId = payload.backgroundTaskId || "";
15084
+ const taskId = payload.associatedTaskId;
15085
+ let message = `${this.prefix} ✅ 后台任务「${desc}」已完成 ${time}`;
15086
+ if (bgProcessId) {
15087
+ message += `
15088
+ bgprocess: ${bgProcessId}`;
15089
+ }
15090
+ if (taskId !== undefined) {
15091
+ message += `
15092
+ Task #${taskId}`;
15093
+ }
15094
+ if (result) {
15095
+ message += `
15096
+ 结果: ${result}`;
15097
+ }
15098
+ message += this.appendSubSessionId(payload);
15099
+ return message;
15100
+ }
15101
+ formatTaskFailed(payload) {
15102
+ const desc = payload.description || "未命名任务";
15103
+ const error = payload.error || "未知错误";
15104
+ const time = payload.executionTimeMs ? `(${this.formatDuration(payload.executionTimeMs)})` : "";
15105
+ const bgProcessId = payload.backgroundTaskId || "";
15106
+ const taskId = payload.associatedTaskId;
15107
+ let message = `${this.prefix} ❌ 后台任务「${desc}」失败 ${time}`;
15108
+ if (bgProcessId) {
15109
+ message += `
15110
+ bgprocess: ${bgProcessId}`;
15111
+ }
15112
+ if (taskId !== undefined) {
15113
+ message += `
15114
+ Task #${taskId}`;
15115
+ }
15116
+ if (error) {
15117
+ const truncatedError = error.length > 100 ? error.substring(0, 100) + "..." : error;
15118
+ message += `
15119
+ 错误: ${truncatedError}`;
15120
+ }
15121
+ message += this.appendSubSessionId(payload);
15122
+ return message;
15123
+ }
15124
+ formatTaskTimeout(payload) {
15125
+ const desc = payload.description || "未命名任务";
15126
+ const time = payload.executionTimeMs ? `(${this.formatDuration(payload.executionTimeMs)})` : "";
15127
+ const bgProcessId = payload.backgroundTaskId || "";
15128
+ const taskId = payload.associatedTaskId;
15129
+ let message = `${this.prefix} ⏱️ 后台任务「${desc}」超时 ${time}`;
15130
+ if (bgProcessId) {
15131
+ message += `
15132
+ bgprocess: ${bgProcessId}`;
15133
+ }
15134
+ if (taskId !== undefined) {
15135
+ message += `
15136
+ Task #${taskId}`;
15137
+ }
15138
+ message += this.appendSubSessionId(payload);
15139
+ return message;
15140
+ }
15141
+ formatTaskStopped(payload) {
15142
+ const desc = payload.description || "未命名任务";
15143
+ const time = payload.executionTimeMs ? `(${this.formatDuration(payload.executionTimeMs)})` : "";
15144
+ const bgProcessId = payload.backgroundTaskId || "";
15145
+ const taskId = payload.associatedTaskId;
15146
+ let message = `${this.prefix} \uD83D\uDED1 后台任务「${desc}」已停止 ${time}`;
15147
+ if (bgProcessId) {
15148
+ message += `
15149
+ bgprocess: ${bgProcessId}`;
15150
+ }
15151
+ if (taskId !== undefined) {
15152
+ message += `
15153
+ Task #${taskId}`;
15154
+ }
15155
+ message += this.appendSubSessionId(payload);
15156
+ return message;
15157
+ }
15158
+ formatTaskAskUser(payload) {
15159
+ const desc = payload.description || "未命名任务";
15160
+ const bgProcessId = payload.backgroundTaskId || "";
15161
+ const subSessionId = payload.subSessionId || "";
15162
+ const query = payload.query || "(空问题)";
15163
+ let message = `${this.prefix} ❓ 后台子代理「${desc}」请求用户输入`;
15164
+ if (bgProcessId) {
15165
+ message += `
15166
+ bgprocess: ${bgProcessId}`;
15167
+ }
15168
+ if (subSessionId) {
15169
+ message += `
15170
+ subSessionId: ${subSessionId}`;
15171
+ }
15172
+ message += `
15173
+
15174
+ ${query}`;
15175
+ if (payload.hints && payload.hints.length > 0) {
15176
+ message += `
15177
+
15178
+ [\uD83E\uDD16 Agent 操作提示]`;
15179
+ for (const hint of payload.hints) {
15180
+ message += `
15181
+ ${hint}`;
15182
+ }
15183
+ }
15184
+ return message;
15185
+ }
15186
+ appendSubSessionId(payload) {
15187
+ if (payload.subSessionId) {
15188
+ return `
15189
+ subSessionId: ${payload.subSessionId}`;
15190
+ }
15191
+ return "";
15192
+ }
15193
+ formatGeneric(event) {
15194
+ return `${this.prefix} 收到事件: ${event.type}`;
15195
+ }
15196
+ formatEventSourceStarted(payload) {
15197
+ return `${this.prefix} \uD83D\uDCE1 事件源「${payload.sourceId}」(类型: ${payload.sourceType}) 已启动`;
15198
+ }
15199
+ formatEventSourceStopped(payload) {
15200
+ return `${this.prefix} \uD83D\uDCE1 事件源「${payload.sourceId}」(类型: ${payload.sourceType}) 已停止`;
15201
+ }
15202
+ formatEventSourceEvent(event) {
15203
+ const payload = event.payload;
15204
+ const sourceType = payload?.sourceType || "unknown";
15205
+ const message = payload?.message || "";
15206
+ if (message) {
15207
+ return `[${sourceType}] ${message}`;
15208
+ }
15209
+ return `[${sourceType}] ${JSON.stringify(payload, null, 2)}`;
15210
+ }
15211
+ formatDuration(ms) {
15212
+ if (ms < 1000)
15213
+ return `${ms}ms`;
15214
+ if (ms < 60000)
15215
+ return `${(ms / 1000).toFixed(1)}秒`;
15216
+ const minutes = Math.floor(ms / 60000);
15217
+ const seconds = Math.floor(ms % 60000 / 1000);
15218
+ return `${minutes}分${seconds}秒`;
15219
+ }
15220
+ formatWithEvent(event) {
15221
+ const triggerSessionId = extractTriggerSessionId2(event);
15222
+ return {
15223
+ message: this.format(event),
15224
+ envEvent: event,
15225
+ triggerSessionId
15226
+ };
15227
+ }
15228
+ }
15229
+ function extractTriggerSessionId2(event) {
15230
+ const triggerSessionId = event?.metadata?.trigger_session_id;
15231
+ if (typeof triggerSessionId === "string" && triggerSessionId.length > 0) {
15232
+ return triggerSessionId;
15233
+ }
15234
+ return;
15235
+ }
15236
+
15237
+ // src/commands/lifecycle.js
15238
+ var DEFAULT_LOGGER2 = {
15239
+ warn: (msg) => console.error(`[shutdown] ${msg}`)
15240
+ };
15241
+ function registerShutdownHandlers2(cleanup, options = {}) {
15242
+ const logger7 = options.logger ?? DEFAULT_LOGGER2;
15243
+ const exitCode = options.exitCode ?? 0;
15244
+ const shutdownMessage = options.shutdownMessage ?? "Cleaning up...";
15245
+ let shuttingDown = false;
15246
+ const shutdown = async (signal) => {
15247
+ if (shuttingDown) {
15248
+ return;
15249
+ }
15250
+ shuttingDown = true;
15251
+ try {
15252
+ logger7.debug?.(`[${signal}] ${shutdownMessage}`);
15253
+ } catch {}
15254
+ if (cleanup) {
15255
+ try {
15256
+ await cleanup();
15257
+ } catch (err) {
15258
+ const message = err instanceof Error ? err.message : String(err);
15259
+ try {
15260
+ logger7.warn(`Cleanup failed: ${message}`);
15261
+ } catch {
15262
+ try {
15263
+ process.stderr.write(`[shutdown] Cleanup failed: ${message}
15264
+ `);
15265
+ } catch {}
15266
+ }
15267
+ }
15268
+ }
15269
+ try {
15270
+ process.exit(exitCode);
15271
+ } catch {}
15272
+ };
15273
+ process.on("SIGINT", shutdown);
15274
+ process.on("SIGTERM", shutdown);
15275
+ return {
15276
+ dispose: () => {
15277
+ process.removeListener("SIGINT", shutdown);
15278
+ process.removeListener("SIGTERM", shutdown);
15279
+ }
15280
+ };
15281
+ }
15282
+
15283
+ // src/commands/run-shutdown.js
15284
+ import { TempFileManager as TempFileManager3 } from "@ai-setting/roy-agent-core/utils/temp-file-manager";
15285
+ async function shutdownRunSteps(deps) {
15286
+ const { lspManagerDispose, pluginAdapterDispose, stopEventHandler, stopTaskEventHandler, queryExecutor, env, envService, shouldDisposeEnvService, output, logger: logger7 } = deps;
14229
15287
  try {
14230
15288
  stopEventHandler();
14231
15289
  } catch (err) {
14232
- logger6?.warn?.(`[Shutdown] EventHandler.stop failed: ${err}`);
15290
+ logger7?.warn?.(`[Shutdown] EventHandler.stop failed: ${err}`);
14233
15291
  }
14234
15292
  try {
14235
15293
  stopTaskEventHandler();
14236
15294
  } catch (err) {
14237
- logger6?.warn?.(`[Shutdown] TaskEventHandler.stop failed: ${err}`);
15295
+ logger7?.warn?.(`[Shutdown] TaskEventHandler.stop failed: ${err}`);
14238
15296
  }
14239
15297
  if (lspManagerDispose) {
14240
15298
  try {
14241
15299
  await lspManagerDispose();
14242
15300
  } catch (err) {
14243
- logger6?.warn?.(`[Shutdown] LSP Manager dispose failed: ${err}`);
15301
+ logger7?.warn?.(`[Shutdown] LSP Manager dispose failed: ${err}`);
14244
15302
  }
14245
15303
  }
14246
15304
  if (pluginAdapterDispose) {
14247
15305
  try {
14248
15306
  await pluginAdapterDispose();
14249
15307
  } catch (err) {
14250
- logger6?.warn?.(`[Shutdown] PluginAdapter dispose failed: ${err}`);
15308
+ logger7?.warn?.(`[Shutdown] PluginAdapter dispose failed: ${err}`);
14251
15309
  }
14252
15310
  }
14253
15311
  try {
14254
15312
  queryExecutor.dispose();
14255
15313
  } catch (err) {
14256
- logger6?.warn?.(`[Shutdown] QueryExecutor.dispose failed: ${err}`);
15314
+ logger7?.warn?.(`[Shutdown] QueryExecutor.dispose failed: ${err}`);
14257
15315
  }
14258
15316
  try {
14259
15317
  const eventSourceComponent = env.getComponent("event-source");
@@ -14262,7 +15320,7 @@ async function shutdownRunSteps(deps) {
14262
15320
  if (sources && sources.length > 0) {
14263
15321
  for (const source of sources) {
14264
15322
  const status = eventSourceComponent.getStatus?.(source.id);
14265
- logger6?.debug?.(`[Shutdown] 检查事件源: ${source.id}, 状态: ${status}`);
15323
+ logger7?.debug?.(`[Shutdown] 检查事件源: ${source.id}, 状态: ${status}`);
14266
15324
  if (status !== "stopped" && status !== "created") {
14267
15325
  try {
14268
15326
  await eventSourceComponent.stopSource(source.id);
@@ -14275,20 +15333,20 @@ async function shutdownRunSteps(deps) {
14275
15333
  }
14276
15334
  }
14277
15335
  } catch (err) {
14278
- logger6?.warn?.(`[Shutdown] EventSource cleanup failed: ${err}`);
15336
+ logger7?.warn?.(`[Shutdown] EventSource cleanup failed: ${err}`);
14279
15337
  }
14280
15338
  if (shouldDisposeEnvService) {
14281
15339
  try {
14282
15340
  await envService.dispose();
14283
15341
  } catch (err) {
14284
- logger6?.warn?.(`[Shutdown] envService.dispose failed: ${err}`);
15342
+ logger7?.warn?.(`[Shutdown] envService.dispose failed: ${err}`);
14285
15343
  }
14286
15344
  }
14287
15345
  try {
14288
15346
  await TempFileManager3.getInstance().cleanupAll();
14289
- logger6?.debug?.("[Shutdown] TempFileManager cleaned up");
15347
+ logger7?.debug?.("[Shutdown] TempFileManager cleaned up");
14290
15348
  } catch (err) {
14291
- logger6?.warn?.(`[Shutdown] TempFileManager cleanup failed: ${err}`);
15349
+ logger7?.warn?.(`[Shutdown] TempFileManager cleanup failed: ${err}`);
14292
15350
  }
14293
15351
  }
14294
15352
 
@@ -14314,14 +15372,14 @@ async function loadHandleQuery(options, hooks) {
14314
15372
  if (!sessionComponent) {
14315
15373
  throw new Error("Failed to create session component");
14316
15374
  }
14317
- const sessionManager = new SessionManager({
15375
+ const sessionManager = new SessionManager2({
14318
15376
  sessionComponent,
14319
15377
  output,
14320
15378
  quiet: true
14321
15379
  });
14322
15380
  const sessionResult = await sessionManager.init(options.session, options.continue);
14323
15381
  const sessionId = sessionResult.sessionId;
14324
- const queryExecutor = new QueryExecutor({
15382
+ const queryExecutor = new QueryExecutor2({
14325
15383
  env,
14326
15384
  sessionComponent,
14327
15385
  output,
@@ -14331,13 +15389,13 @@ async function loadHandleQuery(options, hooks) {
14331
15389
  let agentContext = undefined;
14332
15390
  if (options.agent && options.agent !== "default") {
14333
15391
  const agentComponent = env.getComponent("agent");
14334
- const validation = validateActAgent(agentComponent, options.agent);
15392
+ const validation = validateActAgent2(agentComponent, options.agent);
14335
15393
  if (!validation.valid) {
14336
15394
  output.error(validation.message);
14337
15395
  output.info("提示: roy-agent agents list");
14338
15396
  process.exit(1);
14339
15397
  }
14340
- agentContext = buildActAgentContext(options.agent);
15398
+ agentContext = buildActAgentContext2(options.agent);
14341
15399
  }
14342
15400
  let eventSourceSystemPrompt;
14343
15401
  const rawEventSourceIds = options.eventSource;
@@ -14349,9 +15407,9 @@ async function loadHandleQuery(options, hooks) {
14349
15407
  output.info("请确保 EventSourceComponent 已正确注册");
14350
15408
  process.exit(1);
14351
15409
  }
14352
- const summary = await startEventSources(eventSourceIds, eventSourceComponent, output);
14353
- const preloadedPrompts = collectEventSourceSystemPrompts(eventSourceIds, eventSourceComponent);
14354
- eventSourceSystemPrompt = preloadedPrompts.length > 0 ? joinResolvedSystemPrompts(preloadedPrompts) : undefined;
15410
+ const summary = await startEventSources2(eventSourceIds, eventSourceComponent, output);
15411
+ const preloadedPrompts = collectEventSourceSystemPrompts2(eventSourceIds, eventSourceComponent);
15412
+ eventSourceSystemPrompt = preloadedPrompts.length > 0 ? joinResolvedSystemPrompts2(preloadedPrompts) : undefined;
14355
15413
  if (eventSourceIds.length === 1 && summary.failedCount > 0) {
14356
15414
  process.exit(1);
14357
15415
  }
@@ -14375,14 +15433,14 @@ async function loadHandleQuery(options, hooks) {
14375
15433
  }, undefined, mergedContext);
14376
15434
  return String(result ?? "");
14377
15435
  };
14378
- const taskEventHandler = new TaskEventHandler({
15436
+ const taskEventHandler = new TaskEventHandler2({
14379
15437
  env,
14380
15438
  enabled: true
14381
15439
  });
14382
- const eventHandler = new EventHandler({
15440
+ const eventHandler = new EventHandler2({
14383
15441
  env,
14384
15442
  eventTypes: ["task.background.*", "event-source.event.*"],
14385
- formatter: new EventMessageFormatter({ prefix: "[通知]" }),
15443
+ formatter: new EventMessageFormatter2({ prefix: "[通知]" }),
14386
15444
  isIdle: hooks?.isIdle ?? (() => true),
14387
15445
  sessionComponent,
14388
15446
  onEvent: async (_message) => {},
@@ -14532,7 +15590,7 @@ function createRunCommand() {
14532
15590
  isIdle: () => runState.isIdle(),
14533
15591
  onNotification: (msg, envEvent) => runState.onNotification(msg, envEvent)
14534
15592
  });
14535
- const shutdownHandle = registerShutdownHandlers(async () => {
15593
+ const shutdownHandle = registerShutdownHandlers2(async () => {
14536
15594
  await shutdownRunSteps({
14537
15595
  lspManagerDispose: null,
14538
15596
  pluginAdapterDispose: null,
@@ -14549,7 +15607,7 @@ function createRunCommand() {
14549
15607
  const streamHandleQuery = createStreamHandleQuery(queryExecutor, sessionId, argv, agentContext, eventSourceSystemPrompt);
14550
15608
  const stopEventHandler = eventHandler.start();
14551
15609
  const stopTaskEventHandler = taskEventHandler.start();
14552
- const { waitUntilExit } = render(React6.createElement(RunTui_default, {
15610
+ const { waitUntilExit } = render(React9.createElement(RunTui_default, {
14553
15611
  handleQuery,
14554
15612
  streamHandleQuery,
14555
15613
  model: argv.model,
@@ -14586,23 +15644,15 @@ function createRunCommand() {
14586
15644
  var RunCommand = createRunCommand();
14587
15645
 
14588
15646
  // src/commands/chat.ts
14589
- import React8 from "react";
15647
+ import React11 from "react";
14590
15648
  import { render as render2 } from "ink";
14591
15649
 
14592
- // src/ChatTui.tsx
14593
- import { useEffect as useEffect6, useRef as useRef3, useState as useState7 } from "react";
15650
+ // src/ChatTui.js
15651
+ import React10, { useEffect as useEffect6, useRef as useRef3, useState as useState7 } from "react";
14594
15652
  import { Box as Box7, useApp as useApp3 } from "ink";
14595
15653
  init_markdown();
14596
15654
  import { jsxDEV as jsxDEV9 } from "react/jsx-dev-runtime";
14597
- var ChatScreen = ({
14598
- handleQuery,
14599
- streamHandleQuery,
14600
- message,
14601
- model,
14602
- workdir,
14603
- maxLines,
14604
- markdownEnabled: markdownEnabled2
14605
- }) => {
15655
+ var ChatScreen = ({ handleQuery, streamHandleQuery, message, model, workdir, maxLines, markdownEnabled: markdownEnabled2 }) => {
14606
15656
  const [history, setHistory] = useState7([
14607
15657
  { role: "user", content: message, id: "h-init-1" }
14608
15658
  ]);
@@ -14737,7 +15787,7 @@ function createChatCommand() {
14737
15787
  }
14738
15788
  const maxLines = Number.parseInt(argv.maxLines ?? "500", 10);
14739
15789
  const handleQuery = await loadHandleQuery2(argv);
14740
- const { waitUntilExit } = render2(React8.createElement(ChatTui_default, {
15790
+ const { waitUntilExit } = render2(React11.createElement(ChatTui_default, {
14741
15791
  handleQuery,
14742
15792
  message: argv.message,
14743
15793
  model: argv.model,
@@ -25698,7 +26748,7 @@ import { existsSync as existsSync5, readFileSync as readFileSync4, writeFileSync
25698
26748
  import { join as join6, resolve } from "node:path";
25699
26749
  import { homedir as homedir4 } from "node:os";
25700
26750
 
25701
- // src/commands/install/cleanup-stale-plugin-copies.ts
26751
+ // src/commands/install/cleanup-stale-plugin-copies.js
25702
26752
  import { existsSync as existsSync4, readFileSync as readFileSync3, rmSync, cpSync } from "node:fs";
25703
26753
  import { join as join5 } from "node:path";
25704
26754
  import { homedir as nodeHomedir, tmpdir as nodeTmpdir } from "node:os";