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