snow-ai 0.7.32 → 0.7.33

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/bundle/cli.mjs CHANGED
@@ -1545,7 +1545,7 @@ var require_react_development = __commonJS({
1545
1545
  var dispatcher = resolveDispatcher();
1546
1546
  return dispatcher.useReducer(reducer2, initialArg, init);
1547
1547
  }
1548
- function useRef31(initialValue) {
1548
+ function useRef32(initialValue) {
1549
1549
  var dispatcher = resolveDispatcher();
1550
1550
  return dispatcher.useRef(initialValue);
1551
1551
  }
@@ -2136,8 +2136,8 @@ var require_react_development = __commonJS({
2136
2136
  if (enqueueTaskImpl === null) {
2137
2137
  try {
2138
2138
  var requireString = ("require" + Math.random()).slice(0, 7);
2139
- var nodeRequire = module2 && module2[requireString];
2140
- enqueueTaskImpl = nodeRequire.call(module2, "timers").setImmediate;
2139
+ var nodeRequire2 = module2 && module2[requireString];
2140
+ enqueueTaskImpl = nodeRequire2.call(module2, "timers").setImmediate;
2141
2141
  } catch (_err) {
2142
2142
  enqueueTaskImpl = function(callback) {
2143
2143
  {
@@ -2339,7 +2339,7 @@ var require_react_development = __commonJS({
2339
2339
  exports2.useLayoutEffect = useLayoutEffect2;
2340
2340
  exports2.useMemo = useMemo48;
2341
2341
  exports2.useReducer = useReducer8;
2342
- exports2.useRef = useRef31;
2342
+ exports2.useRef = useRef32;
2343
2343
  exports2.useState = useState94;
2344
2344
  exports2.useSyncExternalStore = useSyncExternalStore4;
2345
2345
  exports2.useTransition = useTransition;
@@ -49434,10 +49434,10 @@ var init_esm = __esm({
49434
49434
  }
49435
49435
  async _formatEntry(dirent, path62) {
49436
49436
  let entry;
49437
- const basename7 = this._isDirent ? dirent.name : dirent;
49437
+ const basename8 = this._isDirent ? dirent.name : dirent;
49438
49438
  try {
49439
- const fullPath = presolve(pjoin(path62, basename7));
49440
- entry = { path: prelative(this._root, fullPath), fullPath, basename: basename7 };
49439
+ const fullPath = presolve(pjoin(path62, basename8));
49440
+ entry = { path: prelative(this._root, fullPath), fullPath, basename: basename8 };
49441
49441
  entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
49442
49442
  } catch (err) {
49443
49443
  this._onError(err);
@@ -49965,9 +49965,9 @@ var init_handler = __esm({
49965
49965
  _watchWithNodeFs(path62, listener) {
49966
49966
  const opts = this.fsw.options;
49967
49967
  const directory = sysPath.dirname(path62);
49968
- const basename7 = sysPath.basename(path62);
49968
+ const basename8 = sysPath.basename(path62);
49969
49969
  const parent = this.fsw._getWatchedDir(directory);
49970
- parent.add(basename7);
49970
+ parent.add(basename8);
49971
49971
  const absolutePath = sysPath.resolve(path62);
49972
49972
  const options3 = {
49973
49973
  persistent: opts.persistent
@@ -49977,7 +49977,7 @@ var init_handler = __esm({
49977
49977
  let closer;
49978
49978
  if (opts.usePolling) {
49979
49979
  const enableBin = opts.interval !== opts.binaryInterval;
49980
- options3.interval = enableBin && isBinaryPath(basename7) ? opts.binaryInterval : opts.interval;
49980
+ options3.interval = enableBin && isBinaryPath(basename8) ? opts.binaryInterval : opts.interval;
49981
49981
  closer = setFsWatchFileListener(path62, absolutePath, options3, {
49982
49982
  listener,
49983
49983
  rawEmitter: this.fsw._emitRaw
@@ -50000,10 +50000,10 @@ var init_handler = __esm({
50000
50000
  return;
50001
50001
  }
50002
50002
  const dirname13 = sysPath.dirname(file2);
50003
- const basename7 = sysPath.basename(file2);
50003
+ const basename8 = sysPath.basename(file2);
50004
50004
  const parent = this.fsw._getWatchedDir(dirname13);
50005
50005
  let prevStats = stats;
50006
- if (parent.has(basename7))
50006
+ if (parent.has(basename8))
50007
50007
  return;
50008
50008
  const listener = async (path62, newStats) => {
50009
50009
  if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file2, 5))
@@ -50028,9 +50028,9 @@ var init_handler = __esm({
50028
50028
  prevStats = newStats2;
50029
50029
  }
50030
50030
  } catch (error40) {
50031
- this.fsw._remove(dirname13, basename7);
50031
+ this.fsw._remove(dirname13, basename8);
50032
50032
  }
50033
- } else if (parent.has(basename7)) {
50033
+ } else if (parent.has(basename8)) {
50034
50034
  const at = newStats.atimeMs;
50035
50035
  const mt = newStats.mtimeMs;
50036
50036
  if (!at || at <= mt || mt !== prevStats.mtimeMs) {
@@ -51048,9 +51048,9 @@ var init_logger = __esm({
51048
51048
  rotateLog(filePath) {
51049
51049
  const timestamp = Date.now();
51050
51050
  const ext = path8.extname(filePath);
51051
- const basename7 = path8.basename(filePath, ext);
51051
+ const basename8 = path8.basename(filePath, ext);
51052
51052
  const dirname13 = path8.dirname(filePath);
51053
- const rotatedPath = path8.join(dirname13, `${basename7}-${timestamp}${ext}`);
51053
+ const rotatedPath = path8.join(dirname13, `${basename8}-${timestamp}${ext}`);
51054
51054
  fs8.renameSync(filePath, rotatedPath);
51055
51055
  }
51056
51056
  writeLog(level, message, meta) {
@@ -53660,6 +53660,7 @@ __export(apiConfig_exports, {
53660
53660
  getSnowConfig: () => getSnowConfig,
53661
53661
  getSystemPromptConfig: () => getSystemPromptConfig,
53662
53662
  loadConfig: () => loadConfig,
53663
+ normalizeBaseUrlMode: () => normalizeBaseUrlMode,
53663
53664
  reloadConfig: () => reloadConfig,
53664
53665
  saveConfig: () => saveConfig,
53665
53666
  saveCustomHeaders: () => saveCustomHeaders,
@@ -53679,6 +53680,12 @@ function normalizeStreamIdleTimeoutSec(value) {
53679
53680
  }
53680
53681
  return value;
53681
53682
  }
53683
+ function normalizeBaseUrlMode(value) {
53684
+ if (value === "base" || value === "endpoint") {
53685
+ return value;
53686
+ }
53687
+ return "auto";
53688
+ }
53682
53689
  function getGlobalMCPConfigFilePath() {
53683
53690
  return join3(CONFIG_DIR, "settings.json");
53684
53691
  }
@@ -53735,12 +53742,14 @@ function loadConfig() {
53735
53742
  apiConfig = {
53736
53743
  ...DEFAULT_CONFIG3.snowcfg,
53737
53744
  ...configWithoutMcp.snowcfg,
53745
+ baseUrlMode: normalizeBaseUrlMode(configWithoutMcp.snowcfg.baseUrlMode),
53738
53746
  requestMethod: normalizeRequestMethod(configWithoutMcp.snowcfg.requestMethod),
53739
53747
  streamIdleTimeoutSec: normalizeStreamIdleTimeoutSec(configWithoutMcp.snowcfg.streamIdleTimeoutSec)
53740
53748
  };
53741
53749
  } else {
53742
53750
  apiConfig = {
53743
53751
  ...DEFAULT_CONFIG3.snowcfg,
53752
+ baseUrlMode: DEFAULT_CONFIG3.snowcfg.baseUrlMode,
53744
53753
  requestMethod: DEFAULT_CONFIG3.snowcfg.requestMethod,
53745
53754
  streamIdleTimeoutSec: DEFAULT_STREAM_IDLE_TIMEOUT_SEC
53746
53755
  };
@@ -53788,11 +53797,13 @@ function reloadConfig() {
53788
53797
  async function updateSnowConfig(apiConfig) {
53789
53798
  const currentConfig = loadConfig();
53790
53799
  const normalizedIdleTimeoutSec = normalizeStreamIdleTimeoutSec(apiConfig.streamIdleTimeoutSec ?? currentConfig.snowcfg.streamIdleTimeoutSec);
53800
+ const normalizedBaseUrlMode = normalizeBaseUrlMode(apiConfig.baseUrlMode ?? currentConfig.snowcfg.baseUrlMode);
53791
53801
  const updatedConfig = {
53792
53802
  ...currentConfig,
53793
53803
  snowcfg: {
53794
53804
  ...currentConfig.snowcfg,
53795
53805
  ...apiConfig,
53806
+ baseUrlMode: normalizedBaseUrlMode,
53796
53807
  streamIdleTimeoutSec: normalizedIdleTimeoutSec
53797
53808
  }
53798
53809
  };
@@ -54123,6 +54134,7 @@ var init_apiConfig = __esm({
54123
54134
  DEFAULT_CONFIG3 = {
54124
54135
  snowcfg: {
54125
54136
  baseUrl: "https://api.openai.com/v1",
54137
+ baseUrlMode: "auto",
54126
54138
  apiKey: "",
54127
54139
  requestMethod: "chat",
54128
54140
  advancedModel: "",
@@ -56315,6 +56327,103 @@ var init_version = __esm({
56315
56327
  }
56316
56328
  });
56317
56329
 
56330
+ // dist/api/endpointResolver.js
56331
+ function normalizeBaseUrlValue(baseUrl) {
56332
+ return baseUrl.trim().replace(/\/+$/, "");
56333
+ }
56334
+ function resolveApiEndpoint(baseUrl, kind, mode = "auto", options3 = {}) {
56335
+ const normalizedBaseUrl = normalizeBaseUrlValue(baseUrl);
56336
+ if (mode === "endpoint") {
56337
+ return normalizedBaseUrl;
56338
+ }
56339
+ if (mode === "auto" && isFullEndpointForKind(normalizedBaseUrl, kind)) {
56340
+ return normalizedBaseUrl;
56341
+ }
56342
+ const baseForAppend = mode === "auto" ? stripKnownEndpointSuffix(normalizedBaseUrl) || normalizedBaseUrl : normalizedBaseUrl;
56343
+ return appendEndpointSuffix(baseForAppend, kind, options3);
56344
+ }
56345
+ function appendEndpointSuffix(baseUrl, kind, options3) {
56346
+ const normalizedBaseUrl = normalizeBaseUrlValue(baseUrl);
56347
+ if (kind === "geminiStreamGenerateContent") {
56348
+ const modelName = normalizeGeminiModelName(options3.modelName || "model-id");
56349
+ return `${normalizedBaseUrl}/${modelName}:streamGenerateContent?alt=sse`;
56350
+ }
56351
+ if (kind === "anthropicMessages") {
56352
+ const betaQuery = options3.anthropicBeta ? "?beta=true" : "";
56353
+ return `${normalizedBaseUrl}${ENDPOINT_SUFFIXES.anthropicMessages}${betaQuery}`;
56354
+ }
56355
+ return `${normalizedBaseUrl}${ENDPOINT_SUFFIXES[kind]}`;
56356
+ }
56357
+ function normalizeGeminiModelName(modelName) {
56358
+ const trimmed = modelName.trim() || "model-id";
56359
+ return trimmed.startsWith("models/") ? trimmed : `models/${trimmed}`;
56360
+ }
56361
+ function isFullEndpointForKind(baseUrl, kind) {
56362
+ const pathname = getNormalizedPathname(baseUrl);
56363
+ if (!pathname) {
56364
+ return false;
56365
+ }
56366
+ if (kind === "geminiStreamGenerateContent") {
56367
+ return pathname.endsWith(":streamGenerateContent");
56368
+ }
56369
+ return pathname.endsWith(ENDPOINT_SUFFIXES[kind]);
56370
+ }
56371
+ function stripKnownEndpointSuffix(baseUrl) {
56372
+ try {
56373
+ const url2 = new URL(baseUrl);
56374
+ const pathname = normalizePathname(url2.pathname);
56375
+ const knownSuffix = getKnownEndpointSuffix(pathname);
56376
+ if (!knownSuffix) {
56377
+ return void 0;
56378
+ }
56379
+ const nextPathname = pathname.slice(0, -knownSuffix.length) || "/";
56380
+ url2.pathname = nextPathname;
56381
+ url2.search = "";
56382
+ url2.hash = "";
56383
+ return normalizeBaseUrlValue(url2.toString());
56384
+ } catch {
56385
+ return void 0;
56386
+ }
56387
+ }
56388
+ function getKnownEndpointSuffix(pathname) {
56389
+ if (pathname.endsWith(ENDPOINT_SUFFIXES.chat)) {
56390
+ return ENDPOINT_SUFFIXES.chat;
56391
+ }
56392
+ if (pathname.endsWith(ENDPOINT_SUFFIXES.responses)) {
56393
+ return ENDPOINT_SUFFIXES.responses;
56394
+ }
56395
+ if (pathname.endsWith(ENDPOINT_SUFFIXES.anthropicMessages)) {
56396
+ return ENDPOINT_SUFFIXES.anthropicMessages;
56397
+ }
56398
+ if (pathname.endsWith(ENDPOINT_SUFFIXES.models)) {
56399
+ return ENDPOINT_SUFFIXES.models;
56400
+ }
56401
+ const geminiEndpointMatch = pathname.match(/\/models\/[^/]+:streamGenerateContent$/);
56402
+ return geminiEndpointMatch == null ? void 0 : geminiEndpointMatch[0];
56403
+ }
56404
+ function getNormalizedPathname(baseUrl) {
56405
+ try {
56406
+ return normalizePathname(new URL(baseUrl).pathname);
56407
+ } catch {
56408
+ return void 0;
56409
+ }
56410
+ }
56411
+ function normalizePathname(pathname) {
56412
+ return pathname.replace(/\/+$/, "") || "/";
56413
+ }
56414
+ var ENDPOINT_SUFFIXES;
56415
+ var init_endpointResolver = __esm({
56416
+ "dist/api/endpointResolver.js"() {
56417
+ "use strict";
56418
+ ENDPOINT_SUFFIXES = {
56419
+ chat: "/chat/completions",
56420
+ responses: "/responses",
56421
+ models: "/models",
56422
+ anthropicMessages: "/messages"
56423
+ };
56424
+ }
56425
+ });
56426
+
56318
56427
  // dist/api/chat.js
56319
56428
  var chat_exports = {};
56320
56429
  __export(chat_exports, {
@@ -56610,7 +56719,7 @@ async function* createStreamingChatCompletion(options3, abortSignal, onRetry) {
56610
56719
  requestBody["reasoning_effort"] = config3.chatThinking.reasoning_effort;
56611
56720
  }
56612
56721
  }
56613
- const url2 = `${config3.baseUrl}/chat/completions`;
56722
+ const url2 = resolveApiEndpoint(config3.baseUrl, "chat", config3.baseUrlMode);
56614
56723
  const customHeaders = options3.customHeaders || getCustomHeadersForConfig(config3);
56615
56724
  const fetchOptions = addProxyToFetchOptions(url2, {
56616
56725
  method: "POST",
@@ -56780,6 +56889,7 @@ var init_chat = __esm({
56780
56889
  init_proxyUtils();
56781
56890
  init_usageLogger();
56782
56891
  init_version();
56892
+ init_endpointResolver();
56783
56893
  }
56784
56894
  });
56785
56895
 
@@ -57113,7 +57223,7 @@ async function* createStreamingResponse(options3, abortSignal, onRetry) {
57113
57223
  include: ["reasoning.encrypted_content"],
57114
57224
  prompt_cache_key: options3.prompt_cache_key
57115
57225
  };
57116
- const url2 = `${config3.baseUrl}/responses`;
57226
+ const url2 = resolveApiEndpoint(config3.baseUrl, "responses", config3.baseUrlMode);
57117
57227
  const customHeaders = options3.customHeaders || getCustomHeadersForConfig(config3);
57118
57228
  const fetchOptions = addProxyToFetchOptions(url2, {
57119
57229
  method: "POST",
@@ -57296,6 +57406,7 @@ var init_responses = __esm({
57296
57406
  init_proxyUtils();
57297
57407
  init_usageLogger();
57298
57408
  init_version();
57409
+ init_endpointResolver();
57299
57410
  }
57300
57411
  });
57301
57412
 
@@ -57566,9 +57677,7 @@ async function* createStreamingGeminiCompletion(options3, abortSignal, onRetry)
57566
57677
  const effectiveModel = options3.model || config3.advancedModel || "";
57567
57678
  const modelName = effectiveModel.startsWith("models/") ? effectiveModel : `models/${effectiveModel}`;
57568
57679
  const baseUrl = config3.baseUrl && config3.baseUrl !== "https://api.openai.com/v1" ? config3.baseUrl : "https://generativelanguage.googleapis.com/v1beta";
57569
- const urlObj = new URL(`${baseUrl}/${modelName}:streamGenerateContent`);
57570
- urlObj.searchParams.set("alt", "sse");
57571
- const url2 = urlObj.toString();
57680
+ const url2 = resolveApiEndpoint(baseUrl, "geminiStreamGenerateContent", config3.baseUrlMode, { modelName });
57572
57681
  const customHeaders = options3.customHeaders || getCustomHeadersForConfig(config3);
57573
57682
  const fetchOptions = addProxyToFetchOptions(url2, {
57574
57683
  method: "POST",
@@ -57783,6 +57892,7 @@ var init_gemini = __esm({
57783
57892
  init_proxyUtils();
57784
57893
  init_usageLogger();
57785
57894
  init_version();
57895
+ init_endpointResolver();
57786
57896
  geminiConfig = null;
57787
57897
  }
57788
57898
  });
@@ -58272,7 +58382,7 @@ async function* createStreamingAnthropicCompletion(options3, abortSignal, onRetr
58272
58382
  ...customHeaders
58273
58383
  };
58274
58384
  const baseUrl = (config3.baseUrl && config3.baseUrl !== "https://api.openai.com/v1" ? config3.baseUrl : "https://api.anthropic.com/v1").replace(/\/+$/, "");
58275
- const url2 = config3.anthropicBeta ? `${baseUrl}/messages?beta=true` : `${baseUrl}/messages`;
58385
+ const url2 = resolveApiEndpoint(baseUrl, "anthropicMessages", config3.baseUrlMode, { anthropicBeta: config3.anthropicBeta });
58276
58386
  const fetchOptions = addProxyToFetchOptions(url2, {
58277
58387
  method: "POST",
58278
58388
  headers,
@@ -58479,6 +58589,7 @@ var init_anthropic = __esm({
58479
58589
  init_usageLogger();
58480
58590
  init_devMode();
58481
58591
  init_version();
58592
+ init_endpointResolver();
58482
58593
  anthropicConfig = null;
58483
58594
  persistentUserId = null;
58484
58595
  }
@@ -180307,6 +180418,10 @@ var init_en = __esm({
180307
180418
  moreBelow: "{count} more below",
180308
180419
  profile: "Profile:",
180309
180420
  baseUrl: "Base URL:",
180421
+ baseUrlMode: "Base URL Mode:",
180422
+ baseUrlModeAuto: "Auto",
180423
+ baseUrlModeBase: "Base URL",
180424
+ baseUrlModeEndpoint: "Full Endpoint",
180310
180425
  apiKey: "API Key:",
180311
180426
  requestMethod: "Request Method:",
180312
180427
  requestUrlLabel: "Request URL: ",
@@ -180730,6 +180845,7 @@ var init_en = __esm({
180730
180845
  toolSearch: "Toggle Tool Search (progressive tool loading). Enabled by default to save context",
180731
180846
  hybridCompress: "Toggle Hybrid Compress mode (AI summary + smart truncation for /compact and auto-compress)",
180732
180847
  team: "Toggle Agent Team mode - orchestrate multiple agents working together in independent Git worktrees",
180848
+ ultraTodo: "Toggle Ultra TODO mode - phase-gated task management with required completion checks",
180733
180849
  branch: "Fork current conversation into a new branch",
180734
180850
  worktree: "Open Git branch management panel for switching, creating and deleting branches",
180735
180851
  diff: "Review file changes from a conversation in IDE diff view",
@@ -180765,6 +180881,14 @@ var init_en = __esm({
180765
180881
  statusEnabled: "Simple mode: Enabled",
180766
180882
  statusDisabled: "Simple mode: Disabled"
180767
180883
  },
180884
+ // Ultra TODO command messages
180885
+ ultraTodo: {
180886
+ toggling: "Toggling Ultra TODO mode",
180887
+ enabled: "Ultra TODO enabled. todo-manage is disabled and todo-ultra is available.",
180888
+ disabled: "Ultra TODO disabled. todo-manage is available again.",
180889
+ failed: "Failed to toggle Ultra TODO: {error}",
180890
+ unknownError: "Unknown error"
180891
+ },
180768
180892
  // Export command messages
180769
180893
  export: {
180770
180894
  exporting: "Exporting conversation...",
@@ -181330,6 +181454,7 @@ var init_en = __esm({
181330
181454
  toolSearchEnabled: "\u267E\uFE0E Tool Search ON - Tools loaded on demand",
181331
181455
  hybridCompressEnabled: "\u21CC Hybrid Compress ON - AI summary + smart truncation",
181332
181456
  teamModeActive: "\u2691 Agent Team Mode Active - Orchestrating multiple agents with independent worktrees",
181457
+ ultraTodoActive: "\u25C8 Ultra TODO Mode Active - phase advancement requires completion checks",
181333
181458
  tokens: " tokens",
181334
181459
  cached: "cached",
181335
181460
  newCache: "new cache"
@@ -182110,6 +182235,10 @@ var init_zh = __esm({
182110
182235
  moreBelow: "\u4E0B\u65B9\u8FD8\u6709 {count} \u9879",
182111
182236
  profile: "\u914D\u7F6E\u6587\u4EF6:",
182112
182237
  baseUrl: "Base URL:",
182238
+ baseUrlMode: "Base URL \u6A21\u5F0F:",
182239
+ baseUrlModeAuto: "\u81EA\u52A8",
182240
+ baseUrlModeBase: "\u57FA\u7840\u5730\u5740",
182241
+ baseUrlModeEndpoint: "\u5B8C\u6574\u7AEF\u70B9",
182113
182242
  apiKey: "API \u5BC6\u94A5:",
182114
182243
  requestMethod: "\u8BF7\u6C42\u65B9\u5F0F:",
182115
182244
  requestUrlLabel: "\u8BF7\u6C42 URL: ",
@@ -182533,6 +182662,7 @@ var init_zh = __esm({
182533
182662
  toolSearch: "\u5207\u6362\u5DE5\u5177\u641C\u7D22\uFF08\u6E10\u8FDB\u5F0F\u5DE5\u5177\u52A0\u8F7D\uFF09\u3002\u9ED8\u8BA4\u542F\u7528\u4EE5\u8282\u7701\u4E0A\u4E0B\u6587",
182534
182663
  hybridCompress: "\u5207\u6362\u6DF7\u5408\u538B\u7F29\u6A21\u5F0F\uFF08AI \u6458\u8981 + \u667A\u80FD\u622A\u65AD\uFF0C\u7528\u4E8E /compact \u548C\u81EA\u52A8\u538B\u7F29\uFF09",
182535
182664
  team: "\u5207\u6362 Agent Team \u6A21\u5F0F - \u534F\u8C03\u591A\u4E2A\u4EE3\u7406\u5728\u72EC\u7ACB Git Worktree \u4E2D\u5E76\u884C\u5DE5\u4F5C",
182665
+ ultraTodo: "\u5207\u6362 Ultra TODO \u6A21\u5F0F - \u6309\u9636\u6BB5\u7EC6\u5206\u4EFB\u52A1\u5E76\u5728\u9636\u6BB5\u63A8\u8FDB\u524D\u5F3A\u5236\u6821\u9A8C",
182536
182666
  branch: "\u5C06\u5F53\u524D\u5BF9\u8BDD\u5206\u53C9\u4E3A\u65B0\u5206\u652F\uFF0C\u53EF\u7528 /resume \u8FD4\u56DE\u539F\u4F1A\u8BDD",
182537
182667
  worktree: "\u6253\u5F00 Git \u5206\u652F\u7BA1\u7406\u9762\u677F\uFF0C\u652F\u6301\u5207\u6362\u3001\u65B0\u5EFA\u548C\u5220\u9664\u5206\u652F",
182538
182668
  diff: "\u5728 IDE \u4E2D\u67E5\u770B\u5BF9\u8BDD\u7684\u6587\u4EF6\u4FEE\u6539 Diff",
@@ -182568,6 +182698,14 @@ var init_zh = __esm({
182568
182698
  statusEnabled: "\u7B80\u6613\u6A21\u5F0F: \u5DF2\u542F\u7528",
182569
182699
  statusDisabled: "\u7B80\u6613\u6A21\u5F0F: \u5DF2\u7981\u7528"
182570
182700
  },
182701
+ // Ultra TODO 命令消息
182702
+ ultraTodo: {
182703
+ toggling: "\u6B63\u5728\u5207\u6362 Ultra TODO \u6A21\u5F0F",
182704
+ enabled: "Ultra TODO \u5DF2\u542F\u7528\u3002todo-manage \u5DF2\u7981\u7528\uFF0Ctodo-ultra \u53EF\u7528\u3002",
182705
+ disabled: "Ultra TODO \u5DF2\u7981\u7528\u3002todo-manage \u5DF2\u91CD\u65B0\u53EF\u7528\u3002",
182706
+ failed: "\u5207\u6362 Ultra TODO \u5931\u8D25\uFF1A{error}",
182707
+ unknownError: "\u672A\u77E5\u9519\u8BEF"
182708
+ },
182571
182709
  // 导出命令消息
182572
182710
  export: {
182573
182711
  exporting: "\u6B63\u5728\u5BFC\u51FA\u5BF9\u8BDD...",
@@ -183132,6 +183270,7 @@ var init_zh = __esm({
183132
183270
  toolSearchEnabled: "\u267E\uFE0E \u5DE5\u5177\u641C\u7D22\u5DF2\u5F00\u542F - \u6309\u9700\u641C\u7D22\u52A0\u8F7D\u5DE5\u5177",
183133
183271
  hybridCompressEnabled: "\u21CC \u6DF7\u5408\u538B\u7F29\u5DF2\u5F00\u542F - AI \u6458\u8981 + \u667A\u80FD\u622A\u65AD",
183134
183272
  teamModeActive: "\u2691 Agent Team \u6A21\u5F0F\u5DF2\u6FC0\u6D3B - \u591A\u4EE3\u7406\u72EC\u7ACB Worktree \u534F\u540C\u5DE5\u4F5C",
183273
+ ultraTodoActive: "\u25C8 Ultra TODO \u6A21\u5F0F\u5DF2\u6FC0\u6D3B - \u9636\u6BB5\u4EFB\u52A1\u63A8\u8FDB\u5C06\u5F3A\u5236\u6821\u9A8C",
183135
183274
  tokens: " \u4E2A\u8BCD\u5143",
183136
183275
  cached: "\u5DF2\u7F13\u5B58",
183137
183276
  newCache: "\u65B0\u7F13\u5B58"
@@ -183912,6 +184051,10 @@ var init_zh_TW = __esm({
183912
184051
  moreBelow: "\u4E0B\u65B9\u9084\u6709 {count} \u9805",
183913
184052
  profile: "\u914D\u7F6E\u6A94\u6848:",
183914
184053
  baseUrl: "Base URL:",
184054
+ baseUrlMode: "Base URL \u6A21\u5F0F:",
184055
+ baseUrlModeAuto: "\u81EA\u52D5",
184056
+ baseUrlModeBase: "\u57FA\u790E\u5730\u5740",
184057
+ baseUrlModeEndpoint: "\u5B8C\u6574\u7AEF\u9EDE",
183915
184058
  apiKey: "API \u91D1\u9470:",
183916
184059
  requestMethod: "\u8ACB\u6C42\u65B9\u5F0F:",
183917
184060
  requestUrlLabel: "\u8ACB\u6C42 URL: ",
@@ -184335,6 +184478,7 @@ var init_zh_TW = __esm({
184335
184478
  toolSearch: "\u5207\u63DB\u5DE5\u5177\u641C\u5C0B\uFF08\u6F38\u9032\u5F0F\u5DE5\u5177\u8F09\u5165\uFF09\u3002\u9810\u8A2D\u555F\u7528\u4EE5\u7BC0\u7701\u4E0A\u4E0B\u6587",
184336
184479
  hybridCompress: "\u5207\u63DB\u6DF7\u5408\u58D3\u7E2E\u6A21\u5F0F\uFF08AI \u6458\u8981 + \u667A\u6167\u622A\u65B7\uFF0C\u7528\u65BC /compact \u548C\u81EA\u52D5\u58D3\u7E2E\uFF09",
184337
184480
  team: "\u5207\u63DB Agent Team \u6A21\u5F0F - \u5354\u8ABF\u591A\u500B\u4EE3\u7406\u5728\u7368\u7ACB Git Worktree \u4E2D\u4E26\u884C\u5DE5\u4F5C",
184481
+ ultraTodo: "\u5207\u63DB Ultra TODO \u6A21\u5F0F - \u6309\u968E\u6BB5\u7D30\u5206\u4EFB\u52D9\u4E26\u5728\u968E\u6BB5\u63A8\u9032\u524D\u5F37\u5236\u6821\u9A57",
184338
184482
  branch: "\u5C07\u76EE\u524D\u5C0D\u8A71\u5206\u53C9\u70BA\u65B0\u5206\u652F\uFF0C\u53EF\u7528 /resume \u8FD4\u56DE\u539F\u6703\u8A71",
184339
184483
  worktree: "\u958B\u555F Git \u5206\u652F\u7BA1\u7406\u9762\u677F\uFF0C\u652F\u63F4\u5207\u63DB\u3001\u65B0\u5EFA\u548C\u522A\u9664\u5206\u652F",
184340
184484
  diff: "\u5728 IDE \u4E2D\u67E5\u770B\u5C0D\u8A71\u7684\u6A94\u6848\u4FEE\u6539 Diff",
@@ -184370,6 +184514,14 @@ var init_zh_TW = __esm({
184370
184514
  statusEnabled: "\u7C21\u6613\u6A21\u5F0F: \u5DF2\u555F\u7528",
184371
184515
  statusDisabled: "\u7C21\u6613\u6A21\u5F0F: \u5DF2\u505C\u7528"
184372
184516
  },
184517
+ // Ultra TODO 命令訊息
184518
+ ultraTodo: {
184519
+ toggling: "\u6B63\u5728\u5207\u63DB Ultra TODO \u6A21\u5F0F",
184520
+ enabled: "Ultra TODO \u5DF2\u555F\u7528\u3002todo-manage \u5DF2\u505C\u7528\uFF0Ctodo-ultra \u53EF\u7528\u3002",
184521
+ disabled: "Ultra TODO \u5DF2\u505C\u7528\u3002todo-manage \u5DF2\u91CD\u65B0\u53EF\u7528\u3002",
184522
+ failed: "\u5207\u63DB Ultra TODO \u5931\u6557\uFF1A{error}",
184523
+ unknownError: "\u672A\u77E5\u932F\u8AA4"
184524
+ },
184373
184525
  // 導出命令消息
184374
184526
  export: {
184375
184527
  exporting: "\u6B63\u5728\u5C0E\u51FA\u5C0D\u8A71...",
@@ -184934,6 +185086,7 @@ var init_zh_TW = __esm({
184934
185086
  toolSearchEnabled: "\u267E\uFE0E \u5DE5\u5177\u641C\u5C0B\u5DF2\u958B\u555F - \u6309\u9700\u641C\u5C0B\u8F09\u5165\u5DE5\u5177",
184935
185087
  hybridCompressEnabled: "\u21CC \u6DF7\u5408\u58D3\u7E2E\u5DF2\u958B\u555F - AI \u6458\u8981 + \u667A\u6167\u622A\u65B7",
184936
185088
  teamModeActive: "\u2691 Agent Team \u6A21\u5F0F\u5DF2\u555F\u7528 - \u591A\u4EE3\u7406\u7368\u7ACB Worktree \u5354\u540C\u5DE5\u4F5C",
185089
+ ultraTodoActive: "\u25C8 Ultra TODO \u6A21\u5F0F\u5DF2\u555F\u7528 - \u968E\u6BB5\u4EFB\u52D9\u63A8\u9032\u5C07\u5F37\u5236\u6821\u9A57",
184937
185090
  tokens: " \u500B\u8A5E\u5143",
184938
185091
  cached: "\u5DF2\u5FEB\u53D6",
184939
185092
  newCache: "\u65B0\u5FEB\u53D6"
@@ -335614,8 +335767,8 @@ ${fromBody}`;
335614
335767
  }
335615
335768
  exports22.endsWithSlashGlobStar = endsWithSlashGlobStar;
335616
335769
  function isAffectDepthOfReadingPattern(pattern) {
335617
- const basename7 = path62.basename(pattern);
335618
- return endsWithSlashGlobStar(pattern) || isStaticPattern(basename7);
335770
+ const basename8 = path62.basename(pattern);
335771
+ return endsWithSlashGlobStar(pattern) || isStaticPattern(basename8);
335619
335772
  }
335620
335773
  exports22.isAffectDepthOfReadingPattern = isAffectDepthOfReadingPattern;
335621
335774
  function expandPatternsWithBraceExpansion(patterns) {
@@ -364508,6 +364661,7 @@ __export(projectSettings_exports, {
364508
364661
  getSubAgentMaxSpawnDepth: () => getSubAgentMaxSpawnDepth,
364509
364662
  getTeamMode: () => getTeamMode,
364510
364663
  getToolSearchEnabled: () => getToolSearchEnabled,
364664
+ getUltraTodoEnabled: () => getUltraTodoEnabled,
364511
364665
  getVulnerabilityHuntingMode: () => getVulnerabilityHuntingMode,
364512
364666
  getYoloMode: () => getYoloMode,
364513
364667
  setAutoFormatEnabled: () => setAutoFormatEnabled,
@@ -364517,6 +364671,7 @@ __export(projectSettings_exports, {
364517
364671
  setSubAgentMaxSpawnDepth: () => setSubAgentMaxSpawnDepth,
364518
364672
  setTeamMode: () => setTeamMode,
364519
364673
  setToolSearchEnabled: () => setToolSearchEnabled,
364674
+ setUltraTodoEnabled: () => setUltraTodoEnabled,
364520
364675
  setVulnerabilityHuntingMode: () => setVulnerabilityHuntingMode,
364521
364676
  setYoloMode: () => setYoloMode
364522
364677
  });
@@ -364538,7 +364693,8 @@ function loadSettings() {
364538
364693
  planMode: pick2("planMode"),
364539
364694
  vulnerabilityHuntingMode: pick2("vulnerabilityHuntingMode"),
364540
364695
  hybridCompressEnabled: pick2("hybridCompressEnabled"),
364541
- teamMode: pick2("teamMode")
364696
+ teamMode: pick2("teamMode"),
364697
+ ultraTodoEnabled: pick2("ultraTodoEnabled")
364542
364698
  };
364543
364699
  }
364544
364700
  function setField(key, value, scope = "project") {
@@ -364618,6 +364774,13 @@ function getTeamMode() {
364618
364774
  function setTeamMode(enabled) {
364619
364775
  setField("teamMode", enabled);
364620
364776
  }
364777
+ function getUltraTodoEnabled() {
364778
+ const settings = loadSettings();
364779
+ return settings.ultraTodoEnabled ?? false;
364780
+ }
364781
+ function setUltraTodoEnabled(enabled) {
364782
+ setField("ultraTodoEnabled", enabled);
364783
+ }
364621
364784
  var DEFAULT_SUB_AGENT_MAX_SPAWN_DEPTH;
364622
364785
  var init_projectSettings = __esm({
364623
364786
  "dist/utils/config/projectSettings.js"() {
@@ -366828,6 +366991,17 @@ ${exportList}`);
366828
366991
  */
366829
366992
  async editFile(filePath, operations, contextLines = 8) {
366830
366993
  if (Array.isArray(filePath)) {
366994
+ if (filePath.length > 0 && typeof filePath[0] === "string") {
366995
+ if (!operations || operations.length === 0) {
366996
+ throw new Error("operations array is required when filePath is an array of path strings");
366997
+ }
366998
+ const pathList = filePath;
366999
+ const configs = pathList.map((file2) => ({
367000
+ path: file2,
367001
+ operations
367002
+ }));
367003
+ return await this.editFile(configs, void 0, contextLines);
367004
+ }
366831
367005
  return await executeBatchOperation(filePath, (fileItem) => {
366832
367006
  const cfg = fileItem;
366833
367007
  return { path: cfg.path, operations: cfg.operations };
@@ -367041,7 +367215,7 @@ ${exportList}`);
367041
367215
  },
367042
367216
  {
367043
367217
  name: "filesystem-edit",
367044
- description: 'OPTIONAL strict edit tool: Hash-anchored editing using content hashes from filesystem-read. Line format: "lineNum:hash\u2192content" (e.g. "42:a3\u2192code"). Use anchors "lineNum:hash" to reference lines \u2014 no text reproduction needed. **OPERATIONS**: (1) replace \u2014 replaces startAnchor..endAnchor with content; (2) insert_after \u2014 inserts content after startAnchor; (3) delete \u2014 removes startAnchor..endAnchor, set content to empty string "". **WORKFLOW**: filesystem-read \u2192 note anchors \u2192 call this tool with operations. **ANCHOR FORMAT**: "lineNum:hash" e.g. "10:a3". endAnchor is always required (inclusive range). Single-line edits: set endAnchor to the same anchor as startAnchor. **SUPPORTS BATCH**: Pass array of {path, operations} for multi-file edits.',
367218
+ description: 'OPTIONAL strict edit tool: Hash-anchored editing using content hashes from filesystem-read. Line format: "lineNum:hash\u2192content" (e.g. "42:a3\u2192code"). Use anchors "lineNum:hash" to reference lines \u2014 no text reproduction needed. **OPERATIONS**: (1) replace \u2014 replaces startAnchor..endAnchor with content; (2) insert_after \u2014 inserts content after startAnchor; (3) delete \u2014 removes startAnchor..endAnchor, set content to empty string "". **WORKFLOW**: filesystem-read \u2192 note anchors \u2192 call this tool with operations. **ANCHOR FORMAT**: "lineNum:hash" e.g. "10:a3". endAnchor is always required (inclusive range). Single-line edits: set endAnchor to the same anchor as startAnchor. **SUPPORTS BATCH**: Pass array of {path, operations}, or path string[] with shared top-level operations (same as filesystem-replaceedit batch).',
367045
367219
  inputSchema: {
367046
367220
  type: "object",
367047
367221
  properties: {
@@ -367051,6 +367225,14 @@ ${exportList}`);
367051
367225
  type: "string",
367052
367226
  description: "Path to a single file to edit"
367053
367227
  },
367228
+ {
367229
+ type: "array",
367230
+ items: {
367231
+ type: "string",
367232
+ description: "File path (use with top-level operations for unified batch edit)"
367233
+ },
367234
+ description: "Array of file paths sharing the same top-level operations"
367235
+ },
367054
367236
  {
367055
367237
  type: "array",
367056
367238
  items: {
@@ -369842,8 +370024,9 @@ __export(aceCodeSearch_exports, {
369842
370024
  import { promises as fs26, createReadStream as createReadStream2 } from "fs";
369843
370025
  import * as path26 from "path";
369844
370026
  import { spawn as spawn4 } from "child_process";
370027
+ import { createRequire } from "module";
369845
370028
  import { createInterface as createInterface2 } from "readline";
369846
- var ACECodeSearchService, mcpTools3, aceCodeSearchService;
370029
+ var nodeRequire, ACECodeSearchService, mcpTools3, aceCodeSearchService;
369847
370030
  var init_aceCodeSearch = __esm({
369848
370031
  "dist/mcp/aceCodeSearch.js"() {
369849
370032
  "use strict";
@@ -369860,6 +370043,7 @@ var init_aceCodeSearch = __esm({
369860
370043
  init_pathRemote_utils();
369861
370044
  init_remote_utils();
369862
370045
  init_constants_utils();
370046
+ nodeRequire = createRequire(import.meta.url);
369863
370047
  ACECodeSearchService = class _ACECodeSearchService {
369864
370048
  constructor(basePath = process.cwd(), options3) {
369865
370049
  Object.defineProperty(this, "basePath", {
@@ -369940,6 +370124,12 @@ var init_aceCodeSearch = __esm({
369940
370124
  writable: true,
369941
370125
  value: /* @__PURE__ */ new Map()
369942
370126
  });
370127
+ Object.defineProperty(this, "bundledRipgrepPath", {
370128
+ enumerable: true,
370129
+ configurable: true,
370130
+ writable: true,
370131
+ value: void 0
370132
+ });
369943
370133
  Object.defineProperty(this, "isGitRepoCache", {
369944
370134
  enumerable: true,
369945
370135
  configurable: true,
@@ -370137,6 +370327,7 @@ var init_aceCodeSearch = __esm({
370137
370327
  }
370138
370328
  if (!(options3 == null ? void 0 : options3.preserveCommandCache)) {
370139
370329
  this.commandAvailabilityCache.clear();
370330
+ this.bundledRipgrepPath = void 0;
370140
370331
  this.isGitRepoCache = null;
370141
370332
  }
370142
370333
  }
@@ -370239,6 +370430,26 @@ var init_aceCodeSearch = __esm({
370239
370430
  this.commandAvailabilityCache.set(command, available);
370240
370431
  return available;
370241
370432
  }
370433
+ /**
370434
+ * Get the ripgrep binary bundled by @vscode/ripgrep.
370435
+ * Keep this dependency loaded at runtime so local search does not depend on a
370436
+ * system-level rg installation.
370437
+ */
370438
+ getBundledRipgrepPath() {
370439
+ const cached2 = this.bundledRipgrepPath;
370440
+ if (cached2 !== void 0) {
370441
+ return cached2;
370442
+ }
370443
+ try {
370444
+ const ripgrep = nodeRequire("@vscode/ripgrep");
370445
+ const rgPath = typeof ripgrep.rgPath === "string" ? ripgrep.rgPath : "";
370446
+ this.bundledRipgrepPath = rgPath.length > 0 ? rgPath : null;
370447
+ } catch (error40) {
370448
+ logger.debug("Bundled ripgrep unavailable, falling back to system search tools", error40);
370449
+ this.bundledRipgrepPath = null;
370450
+ }
370451
+ return this.bundledRipgrepPath;
370452
+ }
370242
370453
  /**
370243
370454
  * Check if a directory is a Git repository (with caching)
370244
370455
  */
@@ -370691,17 +370902,22 @@ var init_aceCodeSearch = __esm({
370691
370902
  });
370692
370903
  }
370693
370904
  /**
370694
- * Strategy 2: Use system grep (or ripgrep if available) for fast searching
370695
- * Enhanced with timeout protection to prevent hanging on Windows
370905
+ * Strategy 2: Use ripgrep/grep for fast searching.
370906
+ * Enhanced with timeout protection to prevent hanging on Windows.
370696
370907
  */
370697
- async systemGrepSearch(pattern, fileGlob, maxResults = 100, grepCommand = "grep") {
370908
+ async systemGrepSearch(pattern, fileGlob, maxResults = 100, grepCommand = "grep", isRegex = true) {
370698
370909
  this.markActivity();
370699
- const isRipgrep = grepCommand === "rg";
370910
+ const commandName = path26.basename(grepCommand).toLowerCase();
370911
+ const isRipgrep = commandName === "rg" || commandName === "rg.exe";
370912
+ const displayCommand = isRipgrep ? "rg" : commandName || grepCommand;
370700
370913
  const timeoutMs = 15e3;
370701
370914
  return new Promise((resolve13, reject2) => {
370702
370915
  var _a20;
370703
- const args2 = isRipgrep ? ["-n", "-i", "--no-heading"] : ["-r", "-n", "-H", "-E", "-i"];
370916
+ const args2 = isRipgrep ? ["-n", "-i", "--no-heading", "--color=never", "--hidden"] : ["-r", "-n", "-H", "-i"];
370704
370917
  if (isRipgrep) {
370918
+ if (!isRegex) {
370919
+ args2.push("-F");
370920
+ }
370705
370921
  GREP_EXCLUDE_DIRS.forEach((dir) => args2.push("--glob", `!${dir}/`));
370706
370922
  if (fileGlob) {
370707
370923
  const normalizedGlob = fileGlob.replace(/\\/g, "/");
@@ -370709,6 +370925,7 @@ var init_aceCodeSearch = __esm({
370709
370925
  expandedGlobs.forEach((glob) => args2.push("--glob", glob));
370710
370926
  }
370711
370927
  } else {
370928
+ args2.push(isRegex ? "-E" : "-F");
370712
370929
  GREP_EXCLUDE_DIRS.forEach((dir) => args2.push(`--exclude-dir=${dir}`));
370713
370930
  if (fileGlob) {
370714
370931
  const normalizedGlob = fileGlob.replace(/\\/g, "/");
@@ -370745,8 +370962,8 @@ var init_aceCodeSearch = __esm({
370745
370962
  };
370746
370963
  const timeoutId = setTimeout(() => {
370747
370964
  finalize(() => {
370748
- logger.warn(`${grepCommand} timed out after ${timeoutMs}ms, killing process`);
370749
- reject2(new Error(`${grepCommand} timed out after ${timeoutMs}ms`));
370965
+ logger.warn(`${displayCommand} timed out after ${timeoutMs}ms, killing process`);
370966
+ reject2(new Error(`${displayCommand} timed out after ${timeoutMs}ms`));
370750
370967
  }, true);
370751
370968
  }, timeoutMs);
370752
370969
  (_a20 = timeoutId.unref) == null ? void 0 : _a20.call(timeoutId);
@@ -370759,7 +370976,7 @@ var init_aceCodeSearch = __esm({
370759
370976
  });
370760
370977
  child.once("error", (err) => {
370761
370978
  finalize(() => {
370762
- reject2(new Error(`Failed to start ${grepCommand}: ${err.message}`));
370979
+ reject2(new Error(`Failed to start ${displayCommand}: ${err.message}`));
370763
370980
  });
370764
370981
  });
370765
370982
  child.once("close", (code) => {
@@ -370772,7 +370989,7 @@ var init_aceCodeSearch = __esm({
370772
370989
  } else if (code === 1) {
370773
370990
  resolve13([]);
370774
370991
  } else if (stderrData) {
370775
- reject2(new Error(`${grepCommand} exited with code ${code}: ${stderrData}`));
370992
+ reject2(new Error(`${displayCommand} exited with code ${code}: ${stderrData}`));
370776
370993
  } else {
370777
370994
  resolve13([]);
370778
370995
  }
@@ -370992,19 +371209,37 @@ var init_aceCodeSearch = __esm({
370992
371209
  * Internal text search implementation (separated for timeout wrapping)
370993
371210
  *
370994
371211
  * Strategy priority:
370995
- * 1. git grep (fastest, works in git repos)
370996
- * 2. system grep (reliable on all platforms, especially Windows)
370997
- * 3. ripgrep (fast but can hang on Windows)
370998
- * 4. JavaScript fallback (always works)
371212
+ * 1. bundled ripgrep from @vscode/ripgrep (consistent local rg search)
371213
+ * 2. system ripgrep (if bundled rg is unavailable)
371214
+ * 3. git grep (fast fallback in Git repositories)
371215
+ * 4. system grep
371216
+ * 5. JavaScript fallback (always works)
370999
371217
  */
371000
371218
  async executeTextSearch(pattern, fileGlob, isRegex = true, maxResults = 100) {
371001
371219
  this.markActivity();
371220
+ const bundledRipgrepPath = this.getBundledRipgrepPath();
371221
+ if (bundledRipgrepPath) {
371222
+ try {
371223
+ const results2 = await this.systemGrepSearch(pattern, fileGlob, maxResults, bundledRipgrepPath, isRegex);
371224
+ return await this.sortResultsByRecency(results2);
371225
+ } catch (error40) {
371226
+ logger.info("Bundled ripgrep failed, trying next strategy");
371227
+ }
371228
+ }
371002
371229
  const [isGitRepo3, gitAvailable, rgAvailable, grepAvailable] = await Promise.all([
371003
371230
  this.isGitRepository(),
371004
371231
  this.isCommandAvailableCached("git"),
371005
371232
  this.isCommandAvailableCached("rg"),
371006
371233
  this.isCommandAvailableCached("grep")
371007
371234
  ]);
371235
+ if (rgAvailable) {
371236
+ try {
371237
+ const results2 = await this.systemGrepSearch(pattern, fileGlob, maxResults, "rg", isRegex);
371238
+ return await this.sortResultsByRecency(results2);
371239
+ } catch (error40) {
371240
+ logger.info("System ripgrep failed, trying next strategy");
371241
+ }
371242
+ }
371008
371243
  if (isGitRepo3 && gitAvailable) {
371009
371244
  try {
371010
371245
  const results2 = await this.gitGrepSearch(pattern, fileGlob, maxResults, isRegex);
@@ -371014,17 +371249,9 @@ var init_aceCodeSearch = __esm({
371014
371249
  } catch (error40) {
371015
371250
  }
371016
371251
  }
371017
- if (rgAvailable) {
371018
- try {
371019
- const results2 = await this.systemGrepSearch(pattern, fileGlob, maxResults, "rg");
371020
- return await this.sortResultsByRecency(results2);
371021
- } catch (error40) {
371022
- logger.info("Ripgrep failed, trying next strategy");
371023
- }
371024
- }
371025
371252
  if (grepAvailable) {
371026
371253
  try {
371027
- const results2 = await this.systemGrepSearch(pattern, fileGlob, maxResults, "grep");
371254
+ const results2 = await this.systemGrepSearch(pattern, fileGlob, maxResults, "grep", isRegex);
371028
371255
  return await this.sortResultsByRecency(results2);
371029
371256
  } catch (error40) {
371030
371257
  logger.info("System grep failed, falling back to JavaScript search");
@@ -445252,7 +445479,10 @@ var init_todo = __esm({
445252
445479
  sessionId,
445253
445480
  todos,
445254
445481
  createdAt: (existingList == null ? void 0 : existingList.createdAt) ?? now,
445255
- updatedAt: now
445482
+ updatedAt: now,
445483
+ ultraMode: existingList == null ? void 0 : existingList.ultraMode,
445484
+ phases: existingList == null ? void 0 : existingList.phases,
445485
+ currentPhaseId: existingList == null ? void 0 : existingList.currentPhaseId
445256
445486
  };
445257
445487
  await fs35.writeFile(todoPath, JSON.stringify(todoList, null, 2));
445258
445488
  todoEvents.emitTodoUpdate(sessionId, todos);
@@ -445391,6 +445621,271 @@ var init_todo = __esm({
445391
445621
  async createEmptyTodo(sessionId) {
445392
445622
  return this.saveTodoList(sessionId, [], null);
445393
445623
  }
445624
+ createId(prefix) {
445625
+ return `${prefix}-${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
445626
+ }
445627
+ createTextResult(value) {
445628
+ return {
445629
+ content: [
445630
+ {
445631
+ type: "text",
445632
+ text: typeof value === "string" ? value : JSON.stringify(value, null, 2)
445633
+ }
445634
+ ]
445635
+ };
445636
+ }
445637
+ createErrorResult(text2) {
445638
+ return {
445639
+ content: [
445640
+ {
445641
+ type: "text",
445642
+ text: text2
445643
+ }
445644
+ ],
445645
+ isError: true
445646
+ };
445647
+ }
445648
+ async getOrCreateTodoList(sessionId, ultraMode = false) {
445649
+ const existingList = await this.getTodoList(sessionId);
445650
+ if (!existingList) {
445651
+ const now = (/* @__PURE__ */ new Date()).toISOString();
445652
+ return this.saveTodoList(sessionId, [], {
445653
+ sessionId,
445654
+ todos: [],
445655
+ createdAt: now,
445656
+ updatedAt: now,
445657
+ ultraMode,
445658
+ phases: ultraMode ? [] : void 0
445659
+ });
445660
+ }
445661
+ if (ultraMode && !existingList.ultraMode) {
445662
+ return this.saveTodoList(sessionId, existingList.todos, {
445663
+ ...existingList,
445664
+ ultraMode: true,
445665
+ phases: existingList.phases ?? []
445666
+ });
445667
+ }
445668
+ return existingList;
445669
+ }
445670
+ saveUltraTodoList(sessionId, todoList) {
445671
+ return this.saveTodoList(sessionId, todoList.todos, {
445672
+ ...todoList,
445673
+ ultraMode: true,
445674
+ phases: todoList.phases ?? []
445675
+ });
445676
+ }
445677
+ getPhaseTodos(todoList, phaseId) {
445678
+ return todoList.todos.filter((todo) => todo.phaseId === phaseId);
445679
+ }
445680
+ getIncompletePhaseTodos(todoList, phaseId) {
445681
+ return this.getPhaseTodos(todoList, phaseId).filter((todo) => todo.status !== "completed");
445682
+ }
445683
+ findPhase(todoList, phaseId) {
445684
+ var _a20;
445685
+ return (_a20 = todoList.phases) == null ? void 0 : _a20.find((phase) => phase.id === phaseId);
445686
+ }
445687
+ normalizeStringArray(value) {
445688
+ if (Array.isArray(value) && value.every((item) => typeof item === "string")) {
445689
+ return value.map((item) => item.trim()).filter(Boolean);
445690
+ }
445691
+ if (typeof value === "string") {
445692
+ try {
445693
+ const parsed = JSON.parse(value);
445694
+ if (Array.isArray(parsed) && parsed.every((item) => typeof item === "string")) {
445695
+ return parsed.map((item) => item.trim()).filter(Boolean);
445696
+ }
445697
+ } catch {
445698
+ return [value.trim()].filter(Boolean);
445699
+ }
445700
+ }
445701
+ return null;
445702
+ }
445703
+ buildIncompletePhaseMessage(phase, incompleteTodos) {
445704
+ const items = incompleteTodos.map((todo) => `- ${todo.id} [${todo.status}]: ${todo.content}`).join("\n");
445705
+ return `Blocked: phase "${phase.title}" cannot advance because ${incompleteTodos.length} item(s) are not completed. Complete or update them first.
445706
+ ${items}`;
445707
+ }
445708
+ async executeUltraTodoTool(sessionId, args2) {
445709
+ const rawAction = args2["action"];
445710
+ const allowedActions = [
445711
+ "get",
445712
+ "add_phase",
445713
+ "add_item",
445714
+ "update_item",
445715
+ "complete_phase",
445716
+ "advance_phase",
445717
+ "delete_item"
445718
+ ];
445719
+ if (typeof rawAction !== "string" || !allowedActions.includes(rawAction)) {
445720
+ return this.createErrorResult('Error: "action" must be one of: get, add_phase, add_item, update_item, complete_phase, advance_phase, delete_item');
445721
+ }
445722
+ try {
445723
+ const action = rawAction;
445724
+ const todoList = await this.getOrCreateTodoList(sessionId, true);
445725
+ todoList.phases = todoList.phases ?? [];
445726
+ switch (action) {
445727
+ case "get": {
445728
+ if (todoList.todos.length > 0) {
445729
+ todoEvents.emitTodoUpdate(sessionId, todoList.todos);
445730
+ }
445731
+ return this.createTextResult(todoList);
445732
+ }
445733
+ case "add_phase": {
445734
+ const title = typeof args2["title"] === "string" ? args2["title"].trim() : "";
445735
+ const items = this.normalizeStringArray(args2["items"]);
445736
+ if (!title) {
445737
+ return this.createErrorResult('Error: action=add_phase requires "title"');
445738
+ }
445739
+ if (!items || items.length === 0) {
445740
+ return this.createErrorResult('Error: action=add_phase requires non-empty "items" so every phase is decomposed into concrete TODO items');
445741
+ }
445742
+ const now = (/* @__PURE__ */ new Date()).toISOString();
445743
+ const phaseId = this.createId("phase");
445744
+ const shouldBecomeCurrent = !todoList.currentPhaseId;
445745
+ const phase = {
445746
+ id: phaseId,
445747
+ title,
445748
+ status: shouldBecomeCurrent ? "inProgress" : "pending",
445749
+ createdAt: now,
445750
+ updatedAt: now
445751
+ };
445752
+ const phaseTodos = items.map((content) => ({
445753
+ id: this.createId("todo"),
445754
+ content,
445755
+ status: "pending",
445756
+ createdAt: now,
445757
+ updatedAt: now,
445758
+ phaseId
445759
+ }));
445760
+ todoList.phases.push(phase);
445761
+ todoList.todos = [...todoList.todos, ...phaseTodos];
445762
+ if (shouldBecomeCurrent) {
445763
+ todoList.currentPhaseId = phaseId;
445764
+ }
445765
+ const result2 = await this.saveUltraTodoList(sessionId, todoList);
445766
+ return this.createTextResult(result2);
445767
+ }
445768
+ case "add_item": {
445769
+ const content = typeof args2["content"] === "string" ? args2["content"].trim() : "";
445770
+ const phaseId = typeof args2["phaseId"] === "string" && args2["phaseId"].trim() ? args2["phaseId"].trim() : todoList.currentPhaseId;
445771
+ const parentId = typeof args2["parentId"] === "string" && args2["parentId"].trim() ? args2["parentId"].trim() : void 0;
445772
+ if (!content) {
445773
+ return this.createErrorResult('Error: action=add_item requires "content"');
445774
+ }
445775
+ if (!phaseId || !this.findPhase(todoList, phaseId)) {
445776
+ return this.createErrorResult('Error: action=add_item requires a valid "phaseId" or an active current phase');
445777
+ }
445778
+ const validatedParentId = parentId && todoList.todos.some((todo) => todo.id === parentId) ? parentId : void 0;
445779
+ const now = (/* @__PURE__ */ new Date()).toISOString();
445780
+ todoList.todos.push({
445781
+ id: this.createId("todo"),
445782
+ content,
445783
+ status: "pending",
445784
+ createdAt: now,
445785
+ updatedAt: now,
445786
+ parentId: validatedParentId,
445787
+ phaseId
445788
+ });
445789
+ const result2 = await this.saveUltraTodoList(sessionId, todoList);
445790
+ return this.createTextResult(result2);
445791
+ }
445792
+ case "update_item": {
445793
+ const todoId = args2["todoId"];
445794
+ const status = args2["status"];
445795
+ const content = args2["content"];
445796
+ if (todoId === void 0 || todoId === null) {
445797
+ return this.createErrorResult('Error: action=update_item requires "todoId"');
445798
+ }
445799
+ if (status !== void 0 && !["pending", "inProgress", "completed"].includes(status)) {
445800
+ return this.createErrorResult('Error: "status" must be one of: pending, inProgress, completed');
445801
+ }
445802
+ const ids = Array.isArray(todoId) ? todoId : [todoId];
445803
+ const idSet = new Set(ids);
445804
+ const updatedAt = (/* @__PURE__ */ new Date()).toISOString();
445805
+ let anyFound = false;
445806
+ todoList.todos = todoList.todos.map((todo) => {
445807
+ if (!idSet.has(todo.id)) {
445808
+ return todo;
445809
+ }
445810
+ anyFound = true;
445811
+ return {
445812
+ ...todo,
445813
+ ...status ? { status } : {},
445814
+ ...typeof content === "string" ? { content } : {},
445815
+ updatedAt
445816
+ };
445817
+ });
445818
+ if (!anyFound) {
445819
+ return this.createTextResult("TODO item not found");
445820
+ }
445821
+ const result2 = await this.saveUltraTodoList(sessionId, todoList);
445822
+ return this.createTextResult(result2);
445823
+ }
445824
+ case "complete_phase": {
445825
+ const phaseId = typeof args2["phaseId"] === "string" && args2["phaseId"].trim() ? args2["phaseId"].trim() : todoList.currentPhaseId;
445826
+ if (!phaseId) {
445827
+ return this.createErrorResult('Error: action=complete_phase requires "phaseId" or an active current phase');
445828
+ }
445829
+ const phase = this.findPhase(todoList, phaseId);
445830
+ if (!phase) {
445831
+ return this.createErrorResult(`Error: phase not found: ${phaseId}`);
445832
+ }
445833
+ const incompleteTodos = this.getIncompletePhaseTodos(todoList, phaseId);
445834
+ if (incompleteTodos.length > 0) {
445835
+ return this.createErrorResult(this.buildIncompletePhaseMessage(phase, incompleteTodos));
445836
+ }
445837
+ phase.status = "completed";
445838
+ phase.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
445839
+ const result2 = await this.saveUltraTodoList(sessionId, todoList);
445840
+ return this.createTextResult(result2);
445841
+ }
445842
+ case "advance_phase": {
445843
+ const currentPhaseId = todoList.currentPhaseId;
445844
+ if (currentPhaseId) {
445845
+ const currentPhase = this.findPhase(todoList, currentPhaseId);
445846
+ if (!currentPhase) {
445847
+ return this.createErrorResult(`Error: current phase not found: ${currentPhaseId}`);
445848
+ }
445849
+ const incompleteTodos = this.getIncompletePhaseTodos(todoList, currentPhaseId);
445850
+ if (incompleteTodos.length > 0) {
445851
+ return this.createErrorResult(this.buildIncompletePhaseMessage(currentPhase, incompleteTodos));
445852
+ }
445853
+ currentPhase.status = "completed";
445854
+ currentPhase.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
445855
+ }
445856
+ const requestedNextPhaseId = typeof args2["nextPhaseId"] === "string" && args2["nextPhaseId"].trim() ? args2["nextPhaseId"].trim() : void 0;
445857
+ const nextPhase = requestedNextPhaseId ? this.findPhase(todoList, requestedNextPhaseId) : todoList.phases.find((phase) => phase.status !== "completed");
445858
+ if (requestedNextPhaseId && !nextPhase) {
445859
+ return this.createErrorResult(`Error: next phase not found: ${requestedNextPhaseId}`);
445860
+ }
445861
+ if (nextPhase) {
445862
+ nextPhase.status = "inProgress";
445863
+ nextPhase.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
445864
+ todoList.currentPhaseId = nextPhase.id;
445865
+ } else {
445866
+ todoList.currentPhaseId = void 0;
445867
+ }
445868
+ const result2 = await this.saveUltraTodoList(sessionId, todoList);
445869
+ return this.createTextResult(result2);
445870
+ }
445871
+ case "delete_item": {
445872
+ const todoId = args2["todoId"];
445873
+ if (todoId === void 0 || todoId === null) {
445874
+ return this.createErrorResult('Error: action=delete_item requires "todoId"');
445875
+ }
445876
+ const ids = Array.isArray(todoId) ? todoId : [todoId];
445877
+ const idSet = new Set(ids);
445878
+ todoList.todos = todoList.todos.filter((todo) => !idSet.has(todo.id) && !idSet.has(todo.parentId ?? ""));
445879
+ const result2 = await this.saveUltraTodoList(sessionId, todoList);
445880
+ return this.createTextResult(result2);
445881
+ }
445882
+ default:
445883
+ return this.createErrorResult(`Unknown action: ${String(action)}`);
445884
+ }
445885
+ } catch (error40) {
445886
+ return this.createErrorResult(`Error executing ultra-todo (${rawAction}): ${error40 instanceof Error ? error40.message : String(error40)}`);
445887
+ }
445888
+ }
445394
445889
  /**
445395
445890
  * 复制 TODO 列表到新会话(用于会话压缩时继承 TODO)
445396
445891
  * @param fromSessionId - 源会话ID
@@ -445409,7 +445904,12 @@ var init_todo = __esm({
445409
445904
  // 更新时间戳
445410
445905
  updatedAt: now
445411
445906
  }));
445412
- return this.saveTodoList(toSessionId, copiedTodos, null);
445907
+ return this.saveTodoList(toSessionId, copiedTodos, {
445908
+ ...sourceTodoList,
445909
+ sessionId: toSessionId,
445910
+ createdAt: now,
445911
+ updatedAt: now
445912
+ });
445413
445913
  }
445414
445914
  /**
445415
445915
  * 删除整个会话的 TODO 列表
@@ -445443,7 +445943,89 @@ var init_todo = __esm({
445443
445943
  /**
445444
445944
  * 获取所有工具定义(单一 todo-manage,通过 action 区分 get / add / update / delete)
445445
445945
  */
445446
- getTools() {
445946
+ getTools(ultraMode = false) {
445947
+ if (ultraMode) {
445948
+ return [
445949
+ {
445950
+ name: "todo-ultra",
445951
+ description: `Ultra TODO session planner: use required field "action" \u2014 one of get | add_phase | add_item | update_item | complete_phase | advance_phase | delete_item.
445952
+
445953
+ Ultra TODO is stricter than todo-manage. Every requirement phase MUST be decomposed into concrete TODO items. Before advancing to the next phase, the current phase is automatically checked; if any item is not completed, the tool blocks advancement and returns the incomplete items.
445954
+
445955
+ ACTIONS:
445956
+ - get: Current ultra TODO state with phases, currentPhaseId, and items.
445957
+ - add_phase: Create a phase and its decomposed TODO items. Required: "title" and non-empty "items" (string[] or JSON string array).
445958
+ - add_item: Add one item to a phase. Required: "content" and a valid "phaseId" unless there is an active current phase. Optional "parentId".
445959
+ - update_item: Update item status/content. Required "todoId" (string or string[]). Optional "status" (pending|inProgress|completed) and/or "content".
445960
+ - complete_phase: Mark a phase completed only if all its items are completed. Optional "phaseId"; defaults to current phase.
445961
+ - advance_phase: Move from current phase to the next phase. Blocks if current phase has incomplete items. Optional "nextPhaseId".
445962
+ - delete_item: Delete item(s), cascading direct children. Required "todoId" (string or string[]).
445963
+
445964
+ IMPORTANT:
445965
+ - Do not start a new phase until advance_phase succeeds.
445966
+ - If advance_phase or complete_phase is blocked, update every listed incomplete item before trying again.
445967
+ - In Ultra TODO mode, the legacy todo-manage tool is not available.`,
445968
+ inputSchema: {
445969
+ type: "object",
445970
+ properties: {
445971
+ action: {
445972
+ type: "string",
445973
+ enum: [
445974
+ "get",
445975
+ "add_phase",
445976
+ "add_item",
445977
+ "update_item",
445978
+ "complete_phase",
445979
+ "advance_phase",
445980
+ "delete_item"
445981
+ ],
445982
+ description: "Which Ultra TODO operation to run."
445983
+ },
445984
+ title: {
445985
+ type: "string",
445986
+ description: "For action=add_phase: phase title."
445987
+ },
445988
+ items: {
445989
+ oneOf: [
445990
+ { type: "array", items: { type: "string" } },
445991
+ { type: "string" }
445992
+ ],
445993
+ description: "For action=add_phase: required decomposed items as string[] or JSON string array."
445994
+ },
445995
+ phaseId: {
445996
+ type: "string",
445997
+ description: "For add_item/complete_phase: target phase id. Defaults to current phase where applicable."
445998
+ },
445999
+ nextPhaseId: {
446000
+ type: "string",
446001
+ description: "For action=advance_phase: optional explicit next phase id."
446002
+ },
446003
+ content: {
446004
+ type: "string",
446005
+ description: "For add_item: item content. For update_item: optional updated content."
446006
+ },
446007
+ parentId: {
446008
+ type: "string",
446009
+ description: "For action=add_item: optional parent TODO id."
446010
+ },
446011
+ todoId: {
446012
+ oneOf: [
446013
+ { type: "string" },
446014
+ { type: "array", items: { type: "string" } }
446015
+ ],
446016
+ description: "For update_item/delete_item: item id(s) from action=get."
446017
+ },
446018
+ status: {
446019
+ type: "string",
446020
+ enum: ["pending", "inProgress", "completed"],
446021
+ description: "For action=update_item only."
446022
+ }
446023
+ },
446024
+ required: ["action"]
446025
+ }
446026
+ }
446027
+ ];
446028
+ }
445447
446029
  return [
445448
446030
  {
445449
446031
  name: "todo-manage",
@@ -445534,6 +446116,9 @@ EXAMPLES:
445534
446116
  isError: true
445535
446117
  };
445536
446118
  }
446119
+ if (toolName === "ultra" || toolName === "ultra-todo") {
446120
+ return this.executeUltraTodoTool(sessionId, args2);
446121
+ }
445537
446122
  if (toolName !== "manage") {
445538
446123
  return {
445539
446124
  content: [
@@ -453420,6 +454005,14 @@ var init_messageFormatter = __esm({
453420
454005
  });
453421
454006
 
453422
454007
  // dist/utils/config/toolDisplayConfig.js
454008
+ var toolDisplayConfig_exports = {};
454009
+ __export(toolDisplayConfig_exports, {
454010
+ TWO_STEP_DISPLAY_TOOL_NAMES: () => TWO_STEP_DISPLAY_TOOL_NAMES,
454011
+ extractFilesystemEditDiffDataForPersistence: () => extractFilesystemEditDiffDataForPersistence,
454012
+ extractFilesystemEditDiffFromRawResult: () => extractFilesystemEditDiffFromRawResult,
454013
+ isToolNeedTwoStepDisplay: () => isToolNeedTwoStepDisplay,
454014
+ isToolOnlyShowCompleted: () => isToolOnlyShowCompleted
454015
+ });
453423
454016
  function isToolNeedTwoStepDisplay(toolName) {
453424
454017
  if (TWO_STEP_TOOLS.has(toolName)) {
453425
454018
  return true;
@@ -453429,6 +454022,35 @@ function isToolNeedTwoStepDisplay(toolName) {
453429
454022
  }
453430
454023
  return false;
453431
454024
  }
454025
+ function isToolOnlyShowCompleted(toolName) {
454026
+ return !isToolNeedTwoStepDisplay(toolName);
454027
+ }
454028
+ function extractFilesystemEditDiffFromRawResult(toolName, toolResult) {
454029
+ if (toolName !== "filesystem-edit" && toolName !== "filesystem-replaceedit") {
454030
+ return void 0;
454031
+ }
454032
+ if (!toolResult || typeof toolResult !== "object") {
454033
+ return void 0;
454034
+ }
454035
+ const result2 = toolResult;
454036
+ if (result2["oldContent"] && result2["newContent"]) {
454037
+ return {
454038
+ oldContent: result2["oldContent"],
454039
+ newContent: result2["newContent"],
454040
+ filename: result2["filePath"] || result2["path"] || result2["filename"],
454041
+ completeOldContent: result2["completeOldContent"],
454042
+ completeNewContent: result2["completeNewContent"],
454043
+ contextStartLine: result2["contextStartLine"]
454044
+ };
454045
+ }
454046
+ if (Array.isArray(result2["results"]) && result2["results"].length > 0) {
454047
+ return {
454048
+ batchResults: result2["results"],
454049
+ isBatch: true
454050
+ };
454051
+ }
454052
+ return void 0;
454053
+ }
453432
454054
  function extractFilesystemEditDiffDataForPersistence(toolName, content) {
453433
454055
  if (toolName !== "filesystem-edit" && toolName !== "filesystem-replaceedit" || content.startsWith("Error:")) {
453434
454056
  return void 0;
@@ -464325,6 +464947,7 @@ var init_useSchedulerExecutionState = __esm({
464325
464947
  var tokenLimiter_exports = {};
464326
464948
  __export(tokenLimiter_exports, {
464327
464949
  getToolResultTokenLimit: () => getToolResultTokenLimit,
464950
+ stripFilesystemDiffPayload: () => stripFilesystemDiffPayload,
464328
464951
  validateTokenLimit: () => validateTokenLimit,
464329
464952
  wrapToolResultWithTokenLimit: () => wrapToolResultWithTokenLimit
464330
464953
  });
@@ -464450,29 +465073,62 @@ async function truncateToTokenLimit(content, maxTokens) {
464450
465073
  return content.slice(0, maxChars);
464451
465074
  }
464452
465075
  }
465076
+ function stripFilesystemDiffPayload(result2) {
465077
+ if (!result2 || typeof result2 !== "object") {
465078
+ return result2;
465079
+ }
465080
+ if (result2.oldContent !== void 0 || result2.newContent !== void 0) {
465081
+ const { oldContent: _oldContent, newContent: _newContent, completeOldContent: _completeOldContent, completeNewContent: _completeNewContent, replacedContent: _replacedContent, ...rest2 } = result2;
465082
+ return rest2;
465083
+ }
465084
+ if (Array.isArray(result2.results)) {
465085
+ return {
465086
+ ...result2,
465087
+ results: result2.results.map((item) => {
465088
+ if (!item || typeof item !== "object") {
465089
+ return item;
465090
+ }
465091
+ const { oldContent: _oldContent, newContent: _newContent, completeOldContent: _completeOldContent, completeNewContent: _completeNewContent, replacedContent: _replacedContent, ...rest2 } = item;
465092
+ return rest2;
465093
+ })
465094
+ };
465095
+ }
465096
+ return result2;
465097
+ }
465098
+ function isFilesystemEditToolName(toolName) {
465099
+ return toolName === "filesystem-edit" || toolName === "filesystem-replaceedit";
465100
+ }
464453
465101
  async function wrapToolResultWithTokenLimit(result2, toolName, maxTokens) {
464454
465102
  const limit = maxTokens ?? getToolResultTokenLimit();
464455
465103
  const validation = await validateTokenLimit(result2, limit);
464456
- if (!validation.isValid) {
464457
- let contentStr;
464458
- if (typeof result2 === "string") {
464459
- contentStr = result2;
464460
- } else if (typeof result2 === "object") {
464461
- contentStr = JSON.stringify(result2, null, 2);
464462
- } else {
464463
- contentStr = String(result2);
465104
+ if (validation.isValid) {
465105
+ return result2;
465106
+ }
465107
+ const strippedForModel = isFilesystemEditToolName(toolName) && result2 && typeof result2 === "object" ? stripFilesystemDiffPayload(result2) : null;
465108
+ if (strippedForModel) {
465109
+ const strippedValidation = await validateTokenLimit(strippedForModel, limit);
465110
+ if (strippedValidation.isValid) {
465111
+ return strippedForModel;
464464
465112
  }
464465
- const reservedTokens = 100;
464466
- const truncateLimit = Math.max(limit - reservedTokens, limit * 0.9);
464467
- const truncatedContent = await truncateToTokenLimit(contentStr, truncateLimit);
464468
- const truncationNotice = `
465113
+ }
465114
+ const sourceForTruncation = strippedForModel ?? result2;
465115
+ let contentStr;
465116
+ if (typeof sourceForTruncation === "string") {
465117
+ contentStr = sourceForTruncation;
465118
+ } else if (typeof sourceForTruncation === "object") {
465119
+ contentStr = JSON.stringify(sourceForTruncation, null, 2);
465120
+ } else {
465121
+ contentStr = String(sourceForTruncation);
465122
+ }
465123
+ const reservedTokens = 100;
465124
+ const truncateLimit = Math.max(limit - reservedTokens, limit * 0.9);
465125
+ const truncatedContent = await truncateToTokenLimit(contentStr, truncateLimit);
465126
+ const truncationNotice = `
464469
465127
 
464470
465128
  [TRUNCATED] Tool "${toolName}" output was truncated due to token limit.
464471
465129
  Original: ~${validation.tokenCount} tokens | Limit: ${limit} tokens
464472
465130
  The content above is incomplete. Consider using more specific queries or filters to get smaller results.`;
464473
- return truncatedContent + truncationNotice;
464474
- }
464475
- return result2;
465131
+ return truncatedContent + truncationNotice;
464476
465132
  }
464477
465133
  var DEFAULT_TOOL_RESULT_TOKEN_LIMIT;
464478
465134
  var init_tokenLimiter = __esm({
@@ -464547,7 +465203,7 @@ async function generateConfigHash() {
464547
465203
  const skillTools = await getMCPTools2(projectRoot);
464548
465204
  const { loadCodebaseConfig: loadCodebaseConfig2 } = await Promise.resolve().then(() => (init_codebaseConfig(), codebaseConfig_exports));
464549
465205
  const codebaseConfig = loadCodebaseConfig2();
464550
- const { getTeamMode: getTeamMode2 } = await Promise.resolve().then(() => (init_projectSettings(), projectSettings_exports));
465206
+ const { getTeamMode: getTeamMode2, getUltraTodoEnabled: getUltraTodoEnabled2 } = await Promise.resolve().then(() => (init_projectSettings(), projectSettings_exports));
464551
465207
  const sessionHasGoal = !!((_a20 = sessionManager.getCurrentSession()) == null ? void 0 : _a20.hasGoal);
464552
465208
  const sessionId = ((_b14 = sessionManager.getCurrentSession()) == null ? void 0 : _b14.id) || "";
464553
465209
  return JSON.stringify({
@@ -464560,6 +465216,7 @@ async function generateConfigHash() {
464560
465216
  disabledMCPTools: getDisabledMCPTools(),
464561
465217
  optInEnabledMCPTools: getOptInEnabledMCPKeysMerged(),
464562
465218
  teamMode: getTeamMode2(),
465219
+ ultraTodoEnabled: getUltraTodoEnabled2(),
464563
465220
  sessionHasGoal,
464564
465221
  sessionId
464565
465222
  });
@@ -464620,7 +465277,9 @@ async function refreshToolsCache() {
464620
465277
  addBuiltInService("terminal", mcpTools2, "terminal");
464621
465278
  const todoSvc = getTodoService();
464622
465279
  await todoSvc.initialize();
464623
- const todoTools = todoSvc.getTools();
465280
+ const { getUltraTodoEnabled: getUltraTodoEnabled2 } = await Promise.resolve().then(() => (init_projectSettings(), projectSettings_exports));
465281
+ const ultraTodoEnabled = getUltraTodoEnabled2();
465282
+ const todoTools = todoSvc.getTools(ultraTodoEnabled);
464624
465283
  addBuiltInService("todo", todoTools.map((t) => ({
464625
465284
  name: t.name,
464626
465285
  description: t.description || "",
@@ -465302,6 +465961,16 @@ async function executeMCPTool(toolName, args2, abortSignal, onTokenUpdate) {
465302
465961
  if (!isMCPToolEnabled(serviceName, actualToolName)) {
465303
465962
  throw new Error(`Tool "${actualToolName}" in service "${serviceName}" is currently disabled. You can re-enable it in the MCP panel (V to view tools, Tab to toggle).`);
465304
465963
  }
465964
+ if (serviceName === "todo") {
465965
+ const { getUltraTodoEnabled: getUltraTodoEnabled2 } = await Promise.resolve().then(() => (init_projectSettings(), projectSettings_exports));
465966
+ const ultraTodoEnabled = getUltraTodoEnabled2();
465967
+ if (ultraTodoEnabled && actualToolName === "manage") {
465968
+ throw new Error("Legacy todo-manage is disabled while Ultra TODO mode is enabled. Use todo-ultra instead.");
465969
+ }
465970
+ if (!ultraTodoEnabled && actualToolName === "ultra") {
465971
+ throw new Error("Ultra TODO tool is disabled. Enable it with /ultra-todo first.");
465972
+ }
465973
+ }
465305
465974
  if (serviceName === "todo") {
465306
465975
  result2 = await getTodoService().executeTool(actualToolName, args2);
465307
465976
  } else if (serviceName === "goal") {
@@ -465676,8 +466345,16 @@ Received: ${JSON.stringify(args2.description)}`
465676
466345
  } catch (error40) {
465677
466346
  throw error40;
465678
466347
  }
466348
+ const { extractFilesystemEditDiffFromRawResult: extractFilesystemEditDiffFromRawResult2 } = await Promise.resolve().then(() => (init_toolDisplayConfig(), toolDisplayConfig_exports));
466349
+ const preservedEditDiffData = extractFilesystemEditDiffFromRawResult2(toolName, result2);
465679
466350
  const { wrapToolResultWithTokenLimit: wrapToolResultWithTokenLimit2 } = await Promise.resolve().then(() => (init_tokenLimiter(), tokenLimiter_exports));
465680
466351
  result2 = await wrapToolResultWithTokenLimit2(result2, toolName);
466352
+ if (preservedEditDiffData) {
466353
+ return {
466354
+ __toolResultContent: result2,
466355
+ editDiffData: preservedEditDiffData
466356
+ };
466357
+ }
465681
466358
  return result2;
465682
466359
  }
465683
466360
  function isConnectionError(error40) {
@@ -470603,25 +471280,21 @@ ${injectedSummary}`
470603
471280
  }
470604
471281
  } else {
470605
471282
  const toolResult = await executeMCPTool(toolCall.function.name, args2, abortSignal, onTokenUpdate);
471283
+ const { extractFilesystemEditDiffFromRawResult: extractFilesystemEditDiffFromRawResult2 } = await Promise.resolve().then(() => (init_toolDisplayConfig(), toolDisplayConfig_exports));
470606
471284
  let editDiffData;
470607
- if (typeof toolResult === "object" && toolResult !== null && (toolCall.function.name === "filesystem-edit" || toolCall.function.name === "filesystem-replaceedit")) {
470608
- if (toolResult.oldContent && toolResult.newContent) {
470609
- editDiffData = {
470610
- oldContent: toolResult.oldContent,
470611
- newContent: toolResult.newContent,
470612
- filename: args2["filePath"],
470613
- completeOldContent: toolResult.completeOldContent,
470614
- completeNewContent: toolResult.completeNewContent,
470615
- contextStartLine: toolResult.contextStartLine
470616
- };
470617
- } else if (toolResult.results && Array.isArray(toolResult.results)) {
470618
- editDiffData = {
470619
- batchResults: toolResult.results,
470620
- isBatch: true
470621
- };
471285
+ let contentSource = toolResult;
471286
+ if (toolResult && typeof toolResult === "object" && "editDiffData" in toolResult && toolResult.editDiffData) {
471287
+ editDiffData = toolResult.editDiffData;
471288
+ if ("__toolResultContent" in toolResult) {
471289
+ contentSource = toolResult.__toolResultContent;
471290
+ }
471291
+ } else {
471292
+ editDiffData = extractFilesystemEditDiffFromRawResult2(toolCall.function.name, toolResult);
471293
+ if (editDiffData && !editDiffData["filename"] && typeof args2["filePath"] === "string") {
471294
+ editDiffData["filename"] = args2["filePath"];
470622
471295
  }
470623
471296
  }
470624
- const { textContent, images } = extractMultimodalContent(toolResult);
471297
+ const { textContent, images } = extractMultimodalContent(contentSource);
470625
471298
  result2 = {
470626
471299
  tool_call_id: toolCall.id,
470627
471300
  role: "tool",
@@ -473343,6 +474016,30 @@ function useCommandHandler(options3) {
473343
474016
  }
473344
474017
  return newValue;
473345
474018
  });
474019
+ } else if (result2.success && result2.action === "toggleUltraTodo") {
474020
+ const messages = translations[getCurrentLanguage()].commandPanel.commandOutput.ultraTodo;
474021
+ try {
474022
+ const { getUltraTodoEnabled: getUltraTodoEnabled2, setUltraTodoEnabled: setUltraTodoEnabled2 } = await Promise.resolve().then(() => (init_projectSettings(), projectSettings_exports));
474023
+ const { refreshMCPToolsCache: refreshMCPToolsCache2 } = await Promise.resolve().then(() => (init_mcpToolsManager(), mcpToolsManager_exports));
474024
+ const newValue = !getUltraTodoEnabled2();
474025
+ setUltraTodoEnabled2(newValue);
474026
+ options3.setUltraTodoEnabled(newValue);
474027
+ await refreshMCPToolsCache2();
474028
+ const commandMessage = {
474029
+ role: "command",
474030
+ content: newValue ? messages.enabled : messages.disabled,
474031
+ commandName
474032
+ };
474033
+ options3.setMessages((prev) => [...prev, commandMessage]);
474034
+ } catch (error40) {
474035
+ const errorMsg = error40 instanceof Error ? error40.message : messages.unknownError;
474036
+ const errorMessage = {
474037
+ role: "command",
474038
+ content: messages.failed.replace("{error}", errorMsg),
474039
+ commandName
474040
+ };
474041
+ options3.setMessages((prev) => [...prev, errorMessage]);
474042
+ }
473346
474043
  } else if (result2.success && result2.action === "initProject" && result2.prompt) {
473347
474044
  const commandMessage = {
473348
474045
  role: "command",
@@ -473894,21 +474591,18 @@ function extractEditDiffData(toolCall, result2) {
473894
474591
  }
473895
474592
  try {
473896
474593
  const resultData = JSON.parse(result2.content);
473897
- if (resultData.oldContent && resultData.newContent) {
473898
- return {
473899
- oldContent: resultData.oldContent,
473900
- newContent: resultData.newContent,
473901
- filename: JSON.parse(toolCall.function.arguments).filePath,
473902
- completeOldContent: resultData.completeOldContent,
473903
- completeNewContent: resultData.completeNewContent,
473904
- contextStartLine: resultData.contextStartLine
473905
- };
473906
- }
473907
- if (resultData.results && Array.isArray(resultData.results)) {
473908
- return {
473909
- batchResults: resultData.results,
473910
- isBatch: true
473911
- };
474594
+ const fromParsed = extractFilesystemEditDiffFromRawResult(toolCall.function.name, resultData);
474595
+ if (fromParsed) {
474596
+ if (!fromParsed["filename"]) {
474597
+ try {
474598
+ const callArgs = JSON.parse(toolCall.function.arguments);
474599
+ if (typeof callArgs.filePath === "string") {
474600
+ fromParsed["filename"] = callArgs.filePath;
474601
+ }
474602
+ } catch {
474603
+ }
474604
+ }
474605
+ return fromParsed;
473912
474606
  }
473913
474607
  } catch {
473914
474608
  }
@@ -477141,6 +477835,36 @@ var init_toolsearch = __esm({
477141
477835
  }
477142
477836
  });
477143
477837
 
477838
+ // dist/utils/commands/ultraTodo.js
477839
+ var ultraTodo_exports = {};
477840
+ __export(ultraTodo_exports, {
477841
+ default: () => ultraTodo_default
477842
+ });
477843
+ function getMessages5() {
477844
+ const currentLanguage = getCurrentLanguage();
477845
+ return translations[currentLanguage].commandPanel.commandOutput.ultraTodo;
477846
+ }
477847
+ var ultraTodo_default;
477848
+ var init_ultraTodo = __esm({
477849
+ "dist/utils/commands/ultraTodo.js"() {
477850
+ "use strict";
477851
+ init_languageConfig();
477852
+ init_commandExecutor();
477853
+ init_i18n();
477854
+ registerCommand("ultra-todo", {
477855
+ execute: () => {
477856
+ const messages = getMessages5();
477857
+ return {
477858
+ success: true,
477859
+ action: "toggleUltraTodo",
477860
+ message: messages.toggling
477861
+ };
477862
+ }
477863
+ });
477864
+ ultraTodo_default = {};
477865
+ }
477866
+ });
477867
+
477144
477868
  // dist/utils/commands/hybridCompress.js
477145
477869
  var hybridCompress_exports = {};
477146
477870
  __export(hybridCompress_exports, {
@@ -477209,7 +477933,7 @@ var autoformat_exports = {};
477209
477933
  __export(autoformat_exports, {
477210
477934
  default: () => autoformat_default
477211
477935
  });
477212
- function getMessages5() {
477936
+ function getMessages6() {
477213
477937
  const currentLanguage = getCurrentLanguage();
477214
477938
  return translations[currentLanguage].commandPanel.commandOutput.autoFormat;
477215
477939
  }
@@ -477225,7 +477949,7 @@ var init_autoformat = __esm({
477225
477949
  execute: (args2) => {
477226
477950
  const trimmedArgs = args2 == null ? void 0 : args2.trim().toLowerCase();
477227
477951
  const enabled = getAutoFormatEnabled();
477228
- const messages = getMessages5();
477952
+ const messages = getMessages6();
477229
477953
  if (trimmedArgs === "status") {
477230
477954
  return {
477231
477955
  success: true,
@@ -477422,6 +478146,7 @@ var init_utils2 = __esm({
477422
478146
  init_todoPicker();
477423
478147
  init_todolist();
477424
478148
  init_toolsearch();
478149
+ init_ultraTodo();
477425
478150
  init_hybridCompress();
477426
478151
  init_usage();
477427
478152
  init_vulnerability_hunting();
@@ -481264,7 +481989,7 @@ function Menu({ options: options3, onSelect, onSelectionChange, maxHeight, defau
481264
481989
  { key: option.value },
481265
481990
  import_react64.default.createElement(
481266
481991
  Text,
481267
- { color: actualIndex === selectedIndex ? theme14.colors.menuSelected : option.color || theme14.colors.menuNormal, bold: true },
481992
+ { color: option.color || (actualIndex === selectedIndex ? theme14.colors.menuSelected : theme14.colors.menuNormal), bold: true },
481268
481993
  actualIndex === selectedIndex ? "\u276F " : " ",
481269
481994
  option.label
481270
481995
  )
@@ -484101,6 +484826,7 @@ var init_types5 = __esm({
484101
484826
  };
484102
484827
  SELECT_FIELDS = [
484103
484828
  "profile",
484829
+ "baseUrlMode",
484104
484830
  "requestMethod",
484105
484831
  "systemPromptId",
484106
484832
  "customHeadersSchemeId",
@@ -484119,8 +484845,8 @@ var init_types5 = __esm({
484119
484845
  });
484120
484846
 
484121
484847
  // dist/api/models.js
484122
- async function fetchOpenAIModels(baseUrl, apiKey, customHeaders) {
484123
- const url2 = `${baseUrl}/models`;
484848
+ async function fetchOpenAIModels(modelsUrl, apiKey, customHeaders) {
484849
+ const url2 = modelsUrl;
484124
484850
  const headers = {
484125
484851
  "Content-Type": "application/json",
484126
484852
  ...customHeaders
@@ -484228,7 +484954,7 @@ async function fetchAvailableModels(overrideConfig) {
484228
484954
  case "chat":
484229
484955
  case "responses":
484230
484956
  default:
484231
- models = await fetchOpenAIModels(config3.baseUrl.replace(/\/$/, ""), config3.apiKey, customHeaders);
484957
+ models = await fetchOpenAIModels(resolveApiEndpoint(config3.baseUrl, "models", config3.baseUrlMode), config3.apiKey, customHeaders);
484232
484958
  break;
484233
484959
  }
484234
484960
  return models.sort((a, b) => a.id.localeCompare(b.id));
@@ -484251,6 +484977,7 @@ var init_models2 = __esm({
484251
484977
  "use strict";
484252
484978
  init_apiConfig();
484253
484979
  init_proxyUtils();
484980
+ init_endpointResolver();
484254
484981
  }
484255
484982
  });
484256
484983
 
@@ -484266,6 +484993,7 @@ function useConfigState(options3) {
484266
484993
  const [renameProfileName, setRenameProfileName] = (0, import_react69.useState)("");
484267
484994
  const [markedProfiles, setMarkedProfiles] = (0, import_react69.useState)(/* @__PURE__ */ new Set());
484268
484995
  const [baseUrl, setBaseUrl] = (0, import_react69.useState)("");
484996
+ const [baseUrlMode, setBaseUrlMode] = (0, import_react69.useState)("auto");
484269
484997
  const [apiKey, setApiKey] = (0, import_react69.useState)("");
484270
484998
  const [requestMethod, setRequestMethod] = (0, import_react69.useState)("chat");
484271
484999
  const [systemPromptId, setSystemPromptId] = (0, import_react69.useState)(void 0);
@@ -484336,6 +485064,7 @@ function useConfigState(options3) {
484336
485064
  // 防止用户切换 active profile 或对 profile 进行增删改。
484337
485065
  ...targetProfileName ? [] : ["profile"],
484338
485066
  "baseUrl",
485067
+ "baseUrlMode",
484339
485068
  "apiKey",
484340
485069
  "requestMethod",
484341
485070
  "systemPromptId",
@@ -484437,6 +485166,7 @@ function useConfigState(options3) {
484437
485166
  const targetConfig = targetProfileName ? loadProfile(targetProfileName) : void 0;
484438
485167
  const config3 = (targetConfig == null ? void 0 : targetConfig.snowcfg) ?? getSnowConfig();
484439
485168
  setBaseUrl(config3.baseUrl);
485169
+ setBaseUrlMode(config3.baseUrlMode || "auto");
484440
485170
  setApiKey(config3.apiKey);
484441
485171
  setRequestMethod(config3.requestMethod || "chat");
484442
485172
  setSystemPromptId(config3.systemPromptId);
@@ -484479,6 +485209,7 @@ function useConfigState(options3) {
484479
485209
  setLoadError("");
484480
485210
  const tempConfig = {
484481
485211
  baseUrl,
485212
+ baseUrlMode,
484482
485213
  apiKey,
484483
485214
  requestMethod,
484484
485215
  customHeadersSchemeId
@@ -484516,6 +485247,8 @@ function useConfigState(options3) {
484516
485247
  return activeProfile;
484517
485248
  if (currentField === "baseUrl")
484518
485249
  return baseUrl;
485250
+ if (currentField === "baseUrlMode")
485251
+ return baseUrlMode;
484519
485252
  if (currentField === "apiKey")
484520
485253
  return apiKey;
484521
485254
  if (currentField === "advancedModel")
@@ -484573,18 +485306,15 @@ function useConfigState(options3) {
484573
485306
  const getRequestUrl = () => {
484574
485307
  const resolvedBaseUrl = getResolvedBaseUrl(requestMethod);
484575
485308
  if (requestMethod === "responses") {
484576
- return `${resolvedBaseUrl}/responses`;
485309
+ return resolveApiEndpoint(resolvedBaseUrl, "responses", baseUrlMode);
484577
485310
  }
484578
485311
  if (requestMethod === "anthropic") {
484579
- const endpoint = anthropicBeta ? "/messages?beta=true" : "/messages";
484580
- return `${resolvedBaseUrl}${endpoint}`;
485312
+ return resolveApiEndpoint(resolvedBaseUrl, "anthropicMessages", baseUrlMode, { anthropicBeta });
484581
485313
  }
484582
485314
  if (requestMethod === "gemini") {
484583
- const effectiveModel = advancedModel || "model-id";
484584
- const modelName = effectiveModel.startsWith("models/") ? effectiveModel : `models/${effectiveModel}`;
484585
- return `${resolvedBaseUrl}/${modelName}:streamGenerateContent?alt=sse`;
485315
+ return resolveApiEndpoint(resolvedBaseUrl, "geminiStreamGenerateContent", baseUrlMode, { modelName: advancedModel || "model-id" });
484586
485316
  }
484587
- return `${resolvedBaseUrl}/chat/completions`;
485317
+ return resolveApiEndpoint(resolvedBaseUrl, "chat", baseUrlMode);
484588
485318
  };
484589
485319
  const getSystemPromptSelectItems = () => {
484590
485320
  const activeNames = activeSystemPromptIds.map((id) => getSystemPromptNameById(id)).join(", ");
@@ -484657,6 +485387,7 @@ function useConfigState(options3) {
484657
485387
  const currentConfig = {
484658
485388
  snowcfg: {
484659
485389
  baseUrl,
485390
+ baseUrlMode,
484660
485391
  apiKey,
484661
485392
  requestMethod,
484662
485393
  systemPromptId,
@@ -484771,6 +485502,7 @@ function useConfigState(options3) {
484771
485502
  if (validationErrors.length === 0) {
484772
485503
  const config3 = {
484773
485504
  baseUrl,
485505
+ baseUrlMode,
484774
485506
  apiKey,
484775
485507
  requestMethod,
484776
485508
  systemPromptId,
@@ -484824,6 +485556,7 @@ function useConfigState(options3) {
484824
485556
  const fullConfig = {
484825
485557
  snowcfg: {
484826
485558
  baseUrl,
485559
+ baseUrlMode,
484827
485560
  apiKey,
484828
485561
  requestMethod,
484829
485562
  systemPromptId,
@@ -484884,6 +485617,8 @@ function useConfigState(options3) {
484884
485617
  // API settings
484885
485618
  baseUrl,
484886
485619
  setBaseUrl,
485620
+ baseUrlMode,
485621
+ setBaseUrlMode,
484887
485622
  apiKey,
484888
485623
  setApiKey,
484889
485624
  requestMethod,
@@ -485005,6 +485740,7 @@ var init_useConfigState = __esm({
485005
485740
  import_react69 = __toESM(require_react(), 1);
485006
485741
  init_apiConfig();
485007
485742
  init_models2();
485743
+ init_endpointResolver();
485008
485744
  init_configManager();
485009
485745
  init_i18n();
485010
485746
  init_ThemeContext();
@@ -485601,6 +486337,7 @@ function ConfigFieldRenderer({ field, state }) {
485601
486337
  // API settings
485602
486338
  baseUrl,
485603
486339
  setBaseUrl,
486340
+ baseUrlMode,
485604
486341
  apiKey,
485605
486342
  setApiKey,
485606
486343
  requestMethod,
@@ -485687,6 +486424,22 @@ function ConfigFieldRenderer({ field, state }) {
485687
486424
  import_react72.default.createElement(Text, { color: theme14.colors.menuSecondary }, baseUrl || t.configScreen.notSet)
485688
486425
  )
485689
486426
  );
486427
+ case "baseUrlMode":
486428
+ return import_react72.default.createElement(
486429
+ Box_default,
486430
+ { key: field, flexDirection: "column" },
486431
+ import_react72.default.createElement(
486432
+ Text,
486433
+ { color: activeColor },
486434
+ activeIndicator,
486435
+ t.configScreen.baseUrlMode
486436
+ ),
486437
+ !isCurrentlyEditing && import_react72.default.createElement(
486438
+ Box_default,
486439
+ { marginLeft: 3 },
486440
+ import_react72.default.createElement(Text, { color: theme14.colors.menuSecondary }, baseUrlMode === "base" ? t.configScreen.baseUrlModeBase : baseUrlMode === "endpoint" ? t.configScreen.baseUrlModeEndpoint : t.configScreen.baseUrlModeAuto)
486441
+ )
486442
+ );
485690
486443
  case "apiKey":
485691
486444
  return import_react72.default.createElement(
485692
486445
  Box_default,
@@ -486397,13 +487150,15 @@ var init_ConfigFieldRenderer = __esm({
486397
487150
 
486398
487151
  // dist/ui/pages/configScreen/ConfigSelectPanel.js
486399
487152
  function ConfigSelectPanel({ state }) {
486400
- const { t, theme: theme14, currentField, setIsEditing, requestMethod, setRequestMethod, requestMethodOptions, thinkingMode, setThinkingMode, thinkingEffort, setThinkingEffort, geminiThinkingLevel, setGeminiThinkingLevel, responsesVerbosity, setResponsesVerbosity, anthropicSpeed, setAnthropicSpeed, chatReasoningEffort, setChatReasoningEffort, getCustomHeadersSchemeSelectItems, getCustomHeadersSchemeSelectedValue, applyCustomHeadersSchemeSelectValue } = state;
487153
+ const { t, theme: theme14, currentField, setIsEditing, baseUrlMode, setBaseUrlMode, requestMethod, setRequestMethod, requestMethodOptions, thinkingMode, setThinkingMode, thinkingEffort, setThinkingEffort, geminiThinkingLevel, setGeminiThinkingLevel, responsesVerbosity, setResponsesVerbosity, anthropicSpeed, setAnthropicSpeed, chatReasoningEffort, setChatReasoningEffort, getCustomHeadersSchemeSelectItems, getCustomHeadersSchemeSelectedValue, applyCustomHeadersSchemeSelectValue } = state;
486401
487154
  const getFieldLabel = () => {
486402
487155
  switch (currentField) {
486403
487156
  case "profile":
486404
487157
  return t.configScreen.profile.replace(":", "");
486405
487158
  case "requestMethod":
486406
487159
  return t.configScreen.requestMethod.replace(":", "");
487160
+ case "baseUrlMode":
487161
+ return t.configScreen.baseUrlMode.replace(":", "");
486407
487162
  case "advancedModel":
486408
487163
  return t.configScreen.advancedModel.replace(":", "");
486409
487164
  case "basicModel":
@@ -486447,6 +487202,17 @@ function ConfigSelectPanel({ state }) {
486447
487202
  setRequestMethod(item.value);
486448
487203
  setIsEditing(false);
486449
487204
  } }),
487205
+ currentField === "baseUrlMode" && import_react73.default.createElement(ScrollableSelectInput, { items: [
487206
+ { label: t.configScreen.baseUrlModeAuto, value: "auto" },
487207
+ { label: t.configScreen.baseUrlModeBase, value: "base" },
487208
+ {
487209
+ label: t.configScreen.baseUrlModeEndpoint,
487210
+ value: "endpoint"
487211
+ }
487212
+ ], initialIndex: Math.max(0, ["auto", "base", "endpoint"].indexOf(baseUrlMode)), isFocused: true, onSelect: (item) => {
487213
+ setBaseUrlMode(item.value);
487214
+ setIsEditing(false);
487215
+ } }),
486450
487216
  currentField === "systemPromptId" && import_react73.default.createElement(SystemPromptSelect, { state }),
486451
487217
  currentField === "customHeadersSchemeId" && (() => {
486452
487218
  const items = getCustomHeadersSchemeSelectItems();
@@ -570854,6 +571620,10 @@ function useCommandPanel(buffer, isProcessing = false) {
570854
571620
  name: "team",
570855
571621
  description: t.commandPanel.commands.team || "Toggle Agent Team mode - orchestrate multiple agents working together"
570856
571622
  },
571623
+ {
571624
+ name: "ultra-todo",
571625
+ description: t.commandPanel.commands.ultraTodo || "Toggle Ultra TODO mode with phase-gated task management"
571626
+ },
570857
571627
  {
570858
571628
  name: "pixel",
570859
571629
  description: t.commandPanel.commands.pixel || "Open the terminal pixel editor",
@@ -577564,6 +578334,7 @@ var init_builtinIds = __esm({
577564
578334
  modePlan: "builtin.mode-plan",
577565
578335
  modeHunt: "builtin.mode-hunt",
577566
578336
  modeTeam: "builtin.mode-team",
578337
+ modeUltraTodo: "builtin.mode-ultra-todo",
577567
578338
  toolSearch: "builtin.tool-search",
577568
578339
  hybridCompress: "builtin.hybrid-compress",
577569
578340
  ideConnection: "builtin.ide-connection",
@@ -577730,7 +578501,7 @@ function buildContextWindowState(contextUsage) {
577730
578501
  hasAnyCache: hasAnthropicCache || hasOpenAICache
577731
578502
  };
577732
578503
  }
577733
- function StatusLine({ yoloMode = false, planMode = false, vulnerabilityHuntingMode = false, toolSearchDisabled = true, hybridCompressEnabled = false, teamMode = false, vscodeConnectionStatus, editorContext, connectionStatus, connectionInstanceName, contextUsage, codebaseIndexing = false, codebaseProgress, watcherEnabled = false, fileUpdateNotification, copyStatusMessage, currentProfileName, compressBlockToast }) {
578504
+ function StatusLine({ yoloMode = false, planMode = false, vulnerabilityHuntingMode = false, toolSearchDisabled = true, hybridCompressEnabled = false, teamMode = false, ultraTodoEnabled = false, vscodeConnectionStatus, editorContext, connectionStatus, connectionInstanceName, contextUsage, codebaseIndexing = false, codebaseProgress, watcherEnabled = false, fileUpdateNotification, copyStatusMessage, currentProfileName, compressBlockToast }) {
577734
578505
  const { t, language } = useI18n();
577735
578506
  const { theme: theme14 } = useTheme();
577736
578507
  const simpleMode = getSimpleMode();
@@ -577764,6 +578535,7 @@ function StatusLine({ yoloMode = false, planMode = false, vulnerabilityHuntingMo
577764
578535
  toolSearchEnabled: !toolSearchDisabled,
577765
578536
  hybridCompress: hybridCompressEnabled,
577766
578537
  team: teamMode,
578538
+ ultraTodo: ultraTodoEnabled,
577767
578539
  simple: simpleMode
577768
578540
  },
577769
578541
  ide: {
@@ -577847,6 +578619,7 @@ function StatusLine({ yoloMode = false, planMode = false, vulnerabilityHuntingMo
577847
578619
  vscodeConnectionStatus,
577848
578620
  vulnerabilityHuntingMode,
577849
578621
  watcherEnabled,
578622
+ ultraTodoEnabled,
577850
578623
  yoloMode
577851
578624
  ]);
577852
578625
  const { items: statusLineHookItems, externalHookIds } = useStatusLineHookItems(statusLineHookContext);
@@ -577924,7 +578697,7 @@ function StatusLine({ yoloMode = false, planMode = false, vulnerabilityHuntingMo
577924
578697
  )
577925
578698
  );
577926
578699
  };
577927
- const hasAnyStatus = yoloMode || planMode || vulnerabilityHuntingMode || teamMode || !toolSearchDisabled || hybridCompressEnabled || vscodeConnectionStatus && vscodeConnectionStatus !== "disconnected" || connectionStatus && connectionStatus !== "disconnected" || contextUsage || codebaseIndexing || watcherEnabled || fileUpdateNotification || copyStatusMessage || currentProfileName || compressBlockToast || statusLineHookItems.length > 0 || detailedMemoryStatusText;
578700
+ const hasAnyStatus = yoloMode || planMode || vulnerabilityHuntingMode || teamMode || ultraTodoEnabled || !toolSearchDisabled || hybridCompressEnabled || vscodeConnectionStatus && vscodeConnectionStatus !== "disconnected" || connectionStatus && connectionStatus !== "disconnected" || contextUsage || codebaseIndexing || watcherEnabled || fileUpdateNotification || copyStatusMessage || currentProfileName || compressBlockToast || statusLineHookItems.length > 0 || detailedMemoryStatusText;
577928
578701
  if (!hasAnyStatus) {
577929
578702
  return null;
577930
578703
  }
@@ -577960,6 +578733,9 @@ function StatusLine({ yoloMode = false, planMode = false, vulnerabilityHuntingMo
577960
578733
  if (teamMode && !isBuiltinOverridden(BUILTIN_STATUSLINE_IDS.modeTeam)) {
577961
578734
  statusItems.push({ text: "\u2691 Team", color: "#10B981" });
577962
578735
  }
578736
+ if (ultraTodoEnabled && !isBuiltinOverridden(BUILTIN_STATUSLINE_IDS.modeUltraTodo)) {
578737
+ statusItems.push({ text: "\u25C8 Ultra TODO", color: "#A78BFA" });
578738
+ }
577963
578739
  if (hybridCompressEnabled && !isBuiltinOverridden(BUILTIN_STATUSLINE_IDS.hybridCompress)) {
577964
578740
  statusItems.push({
577965
578741
  text: "\u21CC Hybrid Compress",
@@ -578100,6 +578876,11 @@ function StatusLine({ yoloMode = false, planMode = false, vulnerabilityHuntingMo
578100
578876
  null,
578101
578877
  import_react121.default.createElement(Text, { color: "#10B981", dimColor: true }, t.chatScreen.teamModeActive)
578102
578878
  ),
578879
+ ultraTodoEnabled && !isBuiltinOverridden(BUILTIN_STATUSLINE_IDS.modeUltraTodo) && import_react121.default.createElement(
578880
+ Box_default,
578881
+ null,
578882
+ import_react121.default.createElement(Text, { color: "#A78BFA", dimColor: true }, t.chatScreen.ultraTodoActive)
578883
+ ),
578103
578884
  hybridCompressEnabled && !isBuiltinOverridden(BUILTIN_STATUSLINE_IDS.hybridCompress) && import_react121.default.createElement(
578104
578885
  Box_default,
578105
578886
  null,
@@ -580327,6 +581108,7 @@ var init_ChatFooter = __esm({
580327
581108
  await init_TodoTree();
580328
581109
  init_sessionManager();
580329
581110
  init_todoEvents();
581111
+ init_mcpToolsManager();
580330
581112
  init_ConnectionManager();
580331
581113
  await init_IdeSelectPanel();
580332
581114
  ReviewCommitPanel2 = (0, import_react132.lazy)(() => init_ReviewCommitPanel().then(() => ReviewCommitPanel_exports));
@@ -580350,22 +581132,55 @@ var init_ChatFooter = __esm({
580350
581132
  return unsubscribe;
580351
581133
  }, []);
580352
581134
  (0, import_react132.useEffect)(() => {
580353
- const currentSession = sessionManager.getCurrentSession();
580354
- if (!currentSession) {
580355
- setShowTodos(false);
580356
- setTodos([]);
580357
- return;
580358
- }
581135
+ var _a20;
581136
+ let disposed = false;
581137
+ let observedSessionId = ((_a20 = sessionManager.getCurrentSession()) == null ? void 0 : _a20.id) ?? null;
581138
+ const loadTodosForCurrentSession = async (force = false) => {
581139
+ var _a21;
581140
+ const currentSession = sessionManager.getCurrentSession();
581141
+ const nextSessionId = (currentSession == null ? void 0 : currentSession.id) ?? null;
581142
+ if (!force && nextSessionId === observedSessionId) {
581143
+ return;
581144
+ }
581145
+ observedSessionId = nextSessionId;
581146
+ if (!currentSession) {
581147
+ if (!disposed) {
581148
+ setShowTodos(false);
581149
+ setTodos([]);
581150
+ }
581151
+ return;
581152
+ }
581153
+ try {
581154
+ const todoList = await getTodoService().getTodoList(currentSession.id);
581155
+ if (disposed || ((_a21 = sessionManager.getCurrentSession()) == null ? void 0 : _a21.id) !== currentSession.id) {
581156
+ return;
581157
+ }
581158
+ setTodos((todoList == null ? void 0 : todoList.todos) ?? []);
581159
+ } catch (error40) {
581160
+ console.error("Failed to load current session TODO list:", error40);
581161
+ if (!disposed) {
581162
+ setTodos([]);
581163
+ }
581164
+ }
581165
+ };
580359
581166
  const handleTodoUpdate = (data) => {
580360
- if (data.sessionId === currentSession.id) {
581167
+ const currentSession = sessionManager.getCurrentSession();
581168
+ if (currentSession && data.sessionId === currentSession.id) {
581169
+ observedSessionId = currentSession.id;
580361
581170
  setTodos(data.todos);
580362
581171
  if (data.todos.length > 0 && props.isProcessing) {
580363
581172
  setShowTodos(true);
580364
581173
  }
580365
581174
  }
580366
581175
  };
581176
+ const unsubscribeSessionChanges = sessionManager.onMessagesChanged(() => {
581177
+ void loadTodosForCurrentSession(false);
581178
+ });
581179
+ void loadTodosForCurrentSession(true);
580367
581180
  todoEvents.onTodoUpdate(handleTodoUpdate);
580368
581181
  return () => {
581182
+ disposed = true;
581183
+ unsubscribeSessionChanges();
580369
581184
  todoEvents.offTodoUpdate(handleTodoUpdate);
580370
581185
  };
580371
581186
  }, [props.isProcessing]);
@@ -580432,7 +581247,7 @@ var init_ChatFooter = __esm({
580432
581247
  { marginTop: 1 },
580433
581248
  import_react132.default.createElement(TodoTree, { todos })
580434
581249
  ),
580435
- import_react132.default.createElement(StatusLine, { yoloMode: props.yoloMode, planMode: props.planMode, vulnerabilityHuntingMode: props.vulnerabilityHuntingMode, toolSearchDisabled: props.toolSearchDisabled, hybridCompressEnabled: props.hybridCompressEnabled, teamMode: props.teamMode, vscodeConnectionStatus: props.vscodeConnectionStatus, editorContext: props.editorContext, connectionStatus, connectionInstanceName, contextUsage: props.contextUsage, codebaseIndexing: props.codebaseIndexing, codebaseProgress: props.codebaseProgress, watcherEnabled: props.watcherEnabled, fileUpdateNotification: props.fileUpdateNotification, copyStatusMessage, currentProfileName: props.currentProfileName, compressBlockToast: props.compressBlockToast }),
581250
+ import_react132.default.createElement(StatusLine, { yoloMode: props.yoloMode, planMode: props.planMode, vulnerabilityHuntingMode: props.vulnerabilityHuntingMode, toolSearchDisabled: props.toolSearchDisabled, hybridCompressEnabled: props.hybridCompressEnabled, teamMode: props.teamMode, ultraTodoEnabled: props.ultraTodoEnabled, vscodeConnectionStatus: props.vscodeConnectionStatus, editorContext: props.editorContext, connectionStatus, connectionInstanceName, contextUsage: props.contextUsage, codebaseIndexing: props.codebaseIndexing, codebaseProgress: props.codebaseProgress, watcherEnabled: props.watcherEnabled, fileUpdateNotification: props.fileUpdateNotification, copyStatusMessage, currentProfileName: props.currentProfileName, compressBlockToast: props.compressBlockToast }),
580436
581251
  props.showBackgroundPanel && import_react132.default.createElement(BackgroundProcessPanel, { processes: props.backgroundProcesses, selectedIndex: props.selectedProcessIndex, terminalWidth: props.terminalWidth })
580437
581252
  ),
580438
581253
  props.showReviewCommitPanel && import_react132.default.createElement(
@@ -588875,6 +589690,7 @@ function TodoListPanel({ onClose }) {
588875
589690
  const [loading, setLoading] = (0, import_react164.useState)(true);
588876
589691
  const [deleting, setDeleting] = (0, import_react164.useState)(false);
588877
589692
  const [currentSessionId2, setCurrentSessionId] = (0, import_react164.useState)(null);
589693
+ const currentSessionIdRef = (0, import_react164.useRef)(null);
588878
589694
  const [selectedIndex, setSelectedIndex] = (0, import_react164.useState)(0);
588879
589695
  const [markedTodoIds, setMarkedTodoIds] = (0, import_react164.useState)(/* @__PURE__ */ new Set());
588880
589696
  const [pendingDelete, setPendingDelete] = (0, import_react164.useState)(false);
@@ -588907,7 +589723,9 @@ function TodoListPanel({ onClose }) {
588907
589723
  const showOverflowHint = flattenedTodos.length > maxVisibleItems;
588908
589724
  const loadTodos = (0, import_react164.useCallback)(async () => {
588909
589725
  const currentSession = sessionManager.getCurrentSession();
588910
- setCurrentSessionId((currentSession == null ? void 0 : currentSession.id) ?? null);
589726
+ const nextSessionId = (currentSession == null ? void 0 : currentSession.id) ?? null;
589727
+ currentSessionIdRef.current = nextSessionId;
589728
+ setCurrentSessionId(nextSessionId);
588911
589729
  if (!currentSession) {
588912
589730
  setTodos([]);
588913
589731
  setLoading(false);
@@ -588927,6 +589745,16 @@ function TodoListPanel({ onClose }) {
588927
589745
  (0, import_react164.useEffect)(() => {
588928
589746
  void loadTodos();
588929
589747
  }, [loadTodos]);
589748
+ (0, import_react164.useEffect)(() => {
589749
+ const handleSessionChange = () => {
589750
+ var _a20;
589751
+ const nextSessionId = ((_a20 = sessionManager.getCurrentSession()) == null ? void 0 : _a20.id) ?? null;
589752
+ if (nextSessionId !== currentSessionIdRef.current) {
589753
+ void loadTodos();
589754
+ }
589755
+ };
589756
+ return sessionManager.onMessagesChanged(handleSessionChange);
589757
+ }, [loadTodos]);
588930
589758
  (0, import_react164.useEffect)(() => {
588931
589759
  const handleTodoUpdate = (data) => {
588932
589760
  if (data.sessionId === currentSessionId2) {
@@ -593798,6 +594626,7 @@ function useChatScreenCommands(workingDirectory) {
593798
594626
  Promise.resolve().then(() => (init_newPrompt(), newPrompt_exports)),
593799
594627
  Promise.resolve().then(() => (init_autoformat(), autoformat_exports)),
593800
594628
  Promise.resolve().then(() => (init_toolsearch(), toolsearch_exports)),
594629
+ Promise.resolve().then(() => (init_ultraTodo(), ultraTodo_exports)),
593801
594630
  Promise.resolve().then(() => (init_hybridCompress(), hybridCompress_exports)),
593802
594631
  Promise.resolve().then(() => (init_team2(), team_exports)),
593803
594632
  Promise.resolve().then(() => (init_btw(), btw_exports)),
@@ -594042,6 +594871,7 @@ function useChatScreenModes({ enableYolo, enablePlan }) {
594042
594871
  const [toolSearchDisabled, setToolSearchDisabled] = (0, import_react182.useState)(() => !getToolSearchEnabled());
594043
594872
  const [hybridCompressEnabled, setHybridCompressEnabled2] = (0, import_react182.useState)(() => getHybridCompressEnabled());
594044
594873
  const [teamMode, setTeamMode2] = (0, import_react182.useState)(() => getTeamMode());
594874
+ const [ultraTodoEnabled, setUltraTodoEnabled2] = (0, import_react182.useState)(() => getUltraTodoEnabled());
594045
594875
  const [simpleMode, setSimpleMode2] = (0, import_react182.useState)(() => getSimpleMode());
594046
594876
  const [showThinking, setShowThinking] = (0, import_react182.useState)(() => {
594047
594877
  const config3 = getSnowConfig();
@@ -594065,6 +594895,9 @@ function useChatScreenModes({ enableYolo, enablePlan }) {
594065
594895
  (0, import_react182.useEffect)(() => {
594066
594896
  setTeamMode(teamMode);
594067
594897
  }, [teamMode]);
594898
+ (0, import_react182.useEffect)(() => {
594899
+ setUltraTodoEnabled(ultraTodoEnabled);
594900
+ }, [ultraTodoEnabled]);
594068
594901
  (0, import_react182.useEffect)(() => {
594069
594902
  const interval = setInterval(() => {
594070
594903
  const currentSimpleMode = getSimpleMode();
@@ -594100,6 +594933,8 @@ function useChatScreenModes({ enableYolo, enablePlan }) {
594100
594933
  setHybridCompressEnabled: setHybridCompressEnabled2,
594101
594934
  teamMode,
594102
594935
  setTeamMode: setTeamMode2,
594936
+ ultraTodoEnabled,
594937
+ setUltraTodoEnabled: setUltraTodoEnabled2,
594103
594938
  simpleMode,
594104
594939
  showThinking
594105
594940
  };
@@ -594345,7 +595180,7 @@ function ChatScreen({ autoResume, resumeSessionId: resumeSessionId2, enableYolo,
594345
595180
  const { columns: terminalWidth, rows: terminalHeight } = useTerminalSize();
594346
595181
  const workingDirectory = process.cwd();
594347
595182
  const { messages, setMessages, isSaving, pendingMessages, setPendingMessages, pendingMessagesRef, userInterruptedRef, remountKey, setRemountKey, setCurrentContextPercentage, currentContextPercentageRef, isExecutingTerminalCommand, setIsExecutingTerminalCommand, customCommandExecution, setCustomCommandExecution, isCompressing, setIsCompressing, compressionError, setCompressionError, showPermissionsPanel, setShowPermissionsPanel, showSubAgentDepthPanel, setShowSubAgentDepthPanel, restoreInputContent, setRestoreInputContent, inputDraftContent, setInputDraftContent, bashSensitiveCommand, setBashSensitiveCommand, suppressLoadingIndicator, setSuppressLoadingIndicator, hookError, setHookError, pendingUserQuestion, setPendingUserQuestion, requestUserQuestion, compressionStatus, setCompressionStatus, isResumingSession, setIsResumingSession, btwPrompt, setBtwPrompt } = useChatScreenLocalState();
594348
- const { yoloMode, setYoloMode: setYoloMode2, planMode, setPlanMode: setPlanMode2, vulnerabilityHuntingMode, setVulnerabilityHuntingMode: setVulnerabilityHuntingMode2, toolSearchDisabled, setToolSearchDisabled, hybridCompressEnabled, setHybridCompressEnabled: setHybridCompressEnabled2, teamMode, setTeamMode: setTeamMode2, simpleMode, showThinking } = useChatScreenModes({ enableYolo, enablePlan });
595183
+ const { yoloMode, setYoloMode: setYoloMode2, planMode, setPlanMode: setPlanMode2, vulnerabilityHuntingMode, setVulnerabilityHuntingMode: setVulnerabilityHuntingMode2, toolSearchDisabled, setToolSearchDisabled, hybridCompressEnabled, setHybridCompressEnabled: setHybridCompressEnabled2, teamMode, setTeamMode: setTeamMode2, ultraTodoEnabled, setUltraTodoEnabled: setUltraTodoEnabled2, simpleMode, showThinking } = useChatScreenModes({ enableYolo, enablePlan });
594349
595184
  const streamingState = useStreamingState();
594350
595185
  const vscodeState = useVSCodeState();
594351
595186
  const snapshotState = useSnapshotState(messages.length);
@@ -594502,6 +595337,7 @@ function ChatScreen({ autoResume, resumeSessionId: resumeSessionId2, enableYolo,
594502
595337
  setToolSearchDisabled,
594503
595338
  setHybridCompressEnabled: setHybridCompressEnabled2,
594504
595339
  setTeamMode: setTeamMode2,
595340
+ setUltraTodoEnabled: setUltraTodoEnabled2,
594505
595341
  setContextUsage: streamingState.setContextUsage,
594506
595342
  setCurrentContextPercentage,
594507
595343
  currentContextPercentageRef,
@@ -594674,6 +595510,7 @@ function ChatScreen({ autoResume, resumeSessionId: resumeSessionId2, enableYolo,
594674
595510
  toolSearchDisabled,
594675
595511
  hybridCompressEnabled,
594676
595512
  teamMode,
595513
+ ultraTodoEnabled,
594677
595514
  setTeamMode: setTeamMode2,
594678
595515
  contextUsage: footerContextUsage,
594679
595516
  initialContent: restoreInputContent,
@@ -597657,7 +598494,7 @@ __export(daemonLogger_exports, {
597657
598494
  DaemonLogger: () => DaemonLogger
597658
598495
  });
597659
598496
  import { existsSync as existsSync38, statSync as statSync2, renameSync as renameSync2, writeFileSync as writeFileSync22, appendFileSync as appendFileSync2, mkdirSync as mkdirSync21 } from "fs";
597660
- import { join as join43, dirname as dirname12, basename as basename6 } from "path";
598497
+ import { join as join43, dirname as dirname12, basename as basename7 } from "path";
597661
598498
  var DaemonLogger;
597662
598499
  var init_daemonLogger = __esm({
597663
598500
  "dist/utils/sse/daemonLogger.js"() {
@@ -597748,7 +598585,7 @@ var init_daemonLogger = __esm({
597748
598585
  */
597749
598586
  rotate() {
597750
598587
  const logDir = dirname12(this.logFilePath);
597751
- const logFileName = basename6(this.logFilePath);
598588
+ const logFileName = basename7(this.logFilePath);
597752
598589
  const dateDir = this.getDateDirectory();
597753
598590
  const archiveDateDir = join43(logDir, "archive", dateDir);
597754
598591
  if (!existsSync38(archiveDateDir)) {
@@ -611097,7 +611934,7 @@ var require_package3 = __commonJS({
611097
611934
  "package.json"(exports2, module2) {
611098
611935
  module2.exports = {
611099
611936
  name: "snow-ai",
611100
- version: "0.7.32",
611937
+ version: "0.7.33",
611101
611938
  description: "Agentic coding in your terminal",
611102
611939
  license: "MIT",
611103
611940
  bin: {
@@ -611149,6 +611986,7 @@ var require_package3 = __commonJS({
611149
611986
  ],
611150
611987
  dependencies: {
611151
611988
  "@microsoft/signalr": "^10.0.0",
611989
+ "@vscode/ripgrep": "^1.18.0",
611152
611990
  "abort-controller": "^3.0.0",
611153
611991
  eventsource: "^2.0.2",
611154
611992
  "fetch-cookie": "^3.0.1",