@lobehub/cli 0.0.24 → 0.0.25

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.
Files changed (3) hide show
  1. package/dist/index.js +1427 -441
  2. package/man/man1/lh.1 +1 -1
  3. package/package.json +5 -4
package/dist/index.js CHANGED
@@ -7440,11 +7440,21 @@ const DEFAULT_DESKTOP_HOTKEY_CONFIG = DESKTOP_HOTKEYS_REGISTRATION.reduce((acc,
7440
7440
  }, {});
7441
7441
 
7442
7442
  //#endregion
7443
- //#region ../desktop/stubs/business-const/src/index.ts
7444
- const DEFAULT_MINI_MODEL = "gpt-5.4-mini";
7445
- const DEFAULT_MINI_PROVIDER = "openai";
7443
+ //#region ../../packages/business/const/src/branding.ts
7444
+ const ORG_NAME = "LobeHub";
7445
+ const COPYRIGHT = `© ${(/* @__PURE__ */ new Date()).getFullYear()} ${ORG_NAME}`;
7446
+ const COPYRIGHT_FULL = `${COPYRIGHT}. All rights reserved.`;
7447
+
7448
+ //#endregion
7449
+ //#region ../../packages/business/const/src/llm.ts
7446
7450
  const DEFAULT_MODEL = "deepseek-v4-pro";
7447
7451
  const DEFAULT_PROVIDER = "deepseek";
7452
+ const DEFAULT_MINI_MODEL = "gpt-5.4-mini";
7453
+ const DEFAULT_MINI_PROVIDER = "openai";
7454
+
7455
+ //#endregion
7456
+ //#region ../../packages/business/const/src/index.ts
7457
+ const isDev$1 = process.env.NODE_ENV === "development";
7448
7458
 
7449
7459
  //#endregion
7450
7460
  //#region ../../packages/const/src/meta.ts
@@ -7730,7 +7740,7 @@ const INTEREST_AREA_KEYS = [
7730
7740
  const interestAreaKeySet = new Set(INTEREST_AREA_KEYS);
7731
7741
 
7732
7742
  //#endregion
7733
- //#region ../desktop/node_modules/.pnpm/react@19.2.4/node_modules/react/cjs/react-jsx-runtime.production.js
7743
+ //#region node_modules/.pnpm/react@19.2.5/node_modules/react/cjs/react-jsx-runtime.production.js
7734
7744
  /**
7735
7745
  * @license React
7736
7746
  * react-jsx-runtime.production.js
@@ -7765,7 +7775,7 @@ var require_react_jsx_runtime_production = /* @__PURE__ */ __commonJSMin(((expor
7765
7775
  }));
7766
7776
 
7767
7777
  //#endregion
7768
- //#region ../desktop/node_modules/.pnpm/react@19.2.4/node_modules/react/cjs/react.production.js
7778
+ //#region node_modules/.pnpm/react@19.2.5/node_modules/react/cjs/react.production.js
7769
7779
  /**
7770
7780
  * @license React
7771
7781
  * react.production.js
@@ -8122,11 +8132,11 @@ var require_react_production = /* @__PURE__ */ __commonJSMin(((exports) => {
8122
8132
  exports.useTransition = function() {
8123
8133
  return ReactSharedInternals.H.useTransition();
8124
8134
  };
8125
- exports.version = "19.2.4";
8135
+ exports.version = "19.2.5";
8126
8136
  }));
8127
8137
 
8128
8138
  //#endregion
8129
- //#region ../desktop/node_modules/.pnpm/react@19.2.4/node_modules/react/cjs/react.development.js
8139
+ //#region node_modules/.pnpm/react@19.2.5/node_modules/react/cjs/react.development.js
8130
8140
  /**
8131
8141
  * @license React
8132
8142
  * react.development.js
@@ -8880,20 +8890,20 @@ var require_react_development = /* @__PURE__ */ __commonJSMin(((exports, module)
8880
8890
  exports.useTransition = function() {
8881
8891
  return resolveDispatcher().useTransition();
8882
8892
  };
8883
- exports.version = "19.2.4";
8893
+ exports.version = "19.2.5";
8884
8894
  "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error());
8885
8895
  })();
8886
8896
  }));
8887
8897
 
8888
8898
  //#endregion
8889
- //#region ../desktop/node_modules/.pnpm/react@19.2.4/node_modules/react/index.js
8899
+ //#region node_modules/.pnpm/react@19.2.5/node_modules/react/index.js
8890
8900
  var require_react = /* @__PURE__ */ __commonJSMin(((exports, module) => {
8891
8901
  if (process.env.NODE_ENV === "production") module.exports = require_react_production();
8892
8902
  else module.exports = require_react_development();
8893
8903
  }));
8894
8904
 
8895
8905
  //#endregion
8896
- //#region ../desktop/node_modules/.pnpm/react@19.2.4/node_modules/react/cjs/react-jsx-runtime.development.js
8906
+ //#region node_modules/.pnpm/react@19.2.5/node_modules/react/cjs/react-jsx-runtime.development.js
8897
8907
  /**
8898
8908
  * @license React
8899
8909
  * react-jsx-runtime.development.js
@@ -9093,14 +9103,14 @@ var require_react_jsx_runtime_development = /* @__PURE__ */ __commonJSMin(((expo
9093
9103
  }));
9094
9104
 
9095
9105
  //#endregion
9096
- //#region ../desktop/node_modules/.pnpm/react@19.2.4/node_modules/react/jsx-runtime.js
9106
+ //#region node_modules/.pnpm/react@19.2.5/node_modules/react/jsx-runtime.js
9097
9107
  var require_jsx_runtime = /* @__PURE__ */ __commonJSMin(((exports, module) => {
9098
9108
  if (process.env.NODE_ENV === "production") module.exports = require_react_jsx_runtime_production();
9099
9109
  else module.exports = require_react_jsx_runtime_development();
9100
9110
  }));
9101
9111
 
9102
9112
  //#endregion
9103
- //#region ../desktop/node_modules/.pnpm/@icons-pack+react-simple-icons@13.13.0_react@19.2.4/node_modules/@icons-pack/react-simple-icons/icons/SiCaldotcom.mjs
9113
+ //#region node_modules/.pnpm/@icons-pack+react-simple-icons@13.13.0_react@19.2.5/node_modules/@icons-pack/react-simple-icons/icons/SiCaldotcom.mjs
9104
9114
  var import_jsx_runtime = require_jsx_runtime();
9105
9115
  var import_react = /* @__PURE__ */ __toESM$2(require_react(), 1);
9106
9116
  const defaultColor = "#292929";
@@ -9119,7 +9129,7 @@ const SiCaldotcom = import_react.forwardRef(function SiCaldotcom2({ title = "Cal
9119
9129
  });
9120
9130
 
9121
9131
  //#endregion
9122
- //#region ../desktop/node_modules/.pnpm/klavis@2.15.0_encoding@0.1.13/node_modules/klavis/dist/esm/api/types/McpServerName.mjs
9132
+ //#region node_modules/.pnpm/klavis@2.15.0/node_modules/klavis/dist/esm/api/types/McpServerName.mjs
9123
9133
  /**
9124
9134
  * This file was auto-generated by Fern from our API Definition.
9125
9135
  */
@@ -9204,7 +9214,7 @@ const McpServerName = {
9204
9214
  };
9205
9215
 
9206
9216
  //#endregion
9207
- //#region ../desktop/node_modules/.pnpm/klavis@2.15.0_encoding@0.1.13/node_modules/klavis/dist/esm/core/json.mjs
9217
+ //#region node_modules/.pnpm/klavis@2.15.0/node_modules/klavis/dist/esm/core/json.mjs
9208
9218
  /**
9209
9219
  * Serialize a value to JSON
9210
9220
  * @param value A JavaScript value, usually an object or array, to be converted.
@@ -9217,7 +9227,7 @@ const toJson = (value, replacer, space) => {
9217
9227
  };
9218
9228
 
9219
9229
  //#endregion
9220
- //#region ../desktop/node_modules/.pnpm/klavis@2.15.0_encoding@0.1.13/node_modules/klavis/dist/esm/errors/KlavisError.mjs
9230
+ //#region node_modules/.pnpm/klavis@2.15.0/node_modules/klavis/dist/esm/errors/KlavisError.mjs
9221
9231
  /**
9222
9232
  * This file was auto-generated by Fern from our API Definition.
9223
9233
  */
@@ -9243,7 +9253,7 @@ function buildMessage({ message, statusCode, body }) {
9243
9253
  }
9244
9254
 
9245
9255
  //#endregion
9246
- //#region ../desktop/node_modules/.pnpm/klavis@2.15.0_encoding@0.1.13/node_modules/klavis/dist/esm/api/errors/UnprocessableEntityError.mjs
9256
+ //#region node_modules/.pnpm/klavis@2.15.0/node_modules/klavis/dist/esm/api/errors/UnprocessableEntityError.mjs
9247
9257
  /**
9248
9258
  * This file was auto-generated by Fern from our API Definition.
9249
9259
  */
@@ -9260,7 +9270,7 @@ var UnprocessableEntityError = class UnprocessableEntityError extends KlavisErro
9260
9270
  };
9261
9271
 
9262
9272
  //#endregion
9263
- //#region ../desktop/node_modules/.pnpm/klavis@2.15.0_encoding@0.1.13/node_modules/klavis/dist/esm/api/errors/BadRequestError.mjs
9273
+ //#region node_modules/.pnpm/klavis@2.15.0/node_modules/klavis/dist/esm/api/errors/BadRequestError.mjs
9264
9274
  /**
9265
9275
  * This file was auto-generated by Fern from our API Definition.
9266
9276
  */
@@ -9277,7 +9287,7 @@ var BadRequestError = class BadRequestError extends KlavisError {
9277
9287
  };
9278
9288
 
9279
9289
  //#endregion
9280
- //#region ../desktop/node_modules/.pnpm/klavis@2.15.0_encoding@0.1.13/node_modules/klavis/dist/esm/core/fetcher/Headers.mjs
9290
+ //#region node_modules/.pnpm/klavis@2.15.0/node_modules/klavis/dist/esm/core/fetcher/Headers.mjs
9281
9291
  let Headers$1;
9282
9292
  if (typeof globalThis.Headers !== "undefined") Headers$1 = globalThis.Headers;
9283
9293
  else Headers$1 = class Headers {
@@ -9333,7 +9343,7 @@ else Headers$1 = class Headers {
9333
9343
  };
9334
9344
 
9335
9345
  //#endregion
9336
- //#region ../desktop/node_modules/.pnpm/klavis@2.15.0_encoding@0.1.13/node_modules/klavis/dist/esm/core/fetcher/RawResponse.mjs
9346
+ //#region node_modules/.pnpm/klavis@2.15.0/node_modules/klavis/dist/esm/core/fetcher/RawResponse.mjs
9337
9347
  /**
9338
9348
  * A raw response indicating that the request was aborted.
9339
9349
  */
@@ -9358,7 +9368,7 @@ const unknownRawResponse = {
9358
9368
  };
9359
9369
 
9360
9370
  //#endregion
9361
- //#region ../desktop/node_modules/.pnpm/klavis@2.15.0_encoding@0.1.13/node_modules/klavis/dist/esm/core/fetcher/Supplier.mjs
9371
+ //#region node_modules/.pnpm/klavis@2.15.0/node_modules/klavis/dist/esm/core/fetcher/Supplier.mjs
9362
9372
  var __awaiter$21 = void 0 && (void 0).__awaiter || function(thisArg, _arguments, P, generator) {
9363
9373
  function adopt(value) {
9364
9374
  return value instanceof P ? value : new P(function(resolve) {
@@ -9388,7 +9398,7 @@ var __awaiter$21 = void 0 && (void 0).__awaiter || function(thisArg, _arguments,
9388
9398
  };
9389
9399
 
9390
9400
  //#endregion
9391
- //#region ../desktop/node_modules/.pnpm/klavis@2.15.0_encoding@0.1.13/node_modules/klavis/dist/esm/core/runtime/runtime.mjs
9401
+ //#region node_modules/.pnpm/klavis@2.15.0/node_modules/klavis/dist/esm/core/runtime/runtime.mjs
9392
9402
  /**
9393
9403
  * A constant that indicates which environment and version the SDK is running in.
9394
9404
  */
@@ -9420,7 +9430,7 @@ function evaluateRuntime() {
9420
9430
  }
9421
9431
 
9422
9432
  //#endregion
9423
- //#region ../desktop/node_modules/.pnpm/klavis@2.15.0_encoding@0.1.13/node_modules/klavis/dist/esm/core/fetcher/getFetchFn.mjs
9433
+ //#region node_modules/.pnpm/klavis@2.15.0/node_modules/klavis/dist/esm/core/fetcher/getFetchFn.mjs
9424
9434
  var __awaiter$20 = void 0 && (void 0).__awaiter || function(thisArg, _arguments, P, generator) {
9425
9435
  function adopt(value) {
9426
9436
  return value instanceof P ? value : new P(function(resolve) {
@@ -9450,7 +9460,7 @@ var __awaiter$20 = void 0 && (void 0).__awaiter || function(thisArg, _arguments,
9450
9460
  };
9451
9461
 
9452
9462
  //#endregion
9453
- //#region ../desktop/node_modules/.pnpm/klavis@2.15.0_encoding@0.1.13/node_modules/klavis/dist/esm/core/fetcher/getRequestBody.mjs
9463
+ //#region node_modules/.pnpm/klavis@2.15.0/node_modules/klavis/dist/esm/core/fetcher/getRequestBody.mjs
9454
9464
  var __awaiter$19 = void 0 && (void 0).__awaiter || function(thisArg, _arguments, P, generator) {
9455
9465
  function adopt(value) {
9456
9466
  return value instanceof P ? value : new P(function(resolve) {
@@ -9480,7 +9490,7 @@ var __awaiter$19 = void 0 && (void 0).__awaiter || function(thisArg, _arguments,
9480
9490
  };
9481
9491
 
9482
9492
  //#endregion
9483
- //#region ../desktop/node_modules/.pnpm/klavis@2.15.0_encoding@0.1.13/node_modules/klavis/dist/esm/core/fetcher/stream-wrappers/chooseStreamWrapper.mjs
9493
+ //#region node_modules/.pnpm/klavis@2.15.0/node_modules/klavis/dist/esm/core/fetcher/stream-wrappers/chooseStreamWrapper.mjs
9484
9494
  var __awaiter$18 = void 0 && (void 0).__awaiter || function(thisArg, _arguments, P, generator) {
9485
9495
  function adopt(value) {
9486
9496
  return value instanceof P ? value : new P(function(resolve) {
@@ -9510,7 +9520,7 @@ var __awaiter$18 = void 0 && (void 0).__awaiter || function(thisArg, _arguments,
9510
9520
  };
9511
9521
 
9512
9522
  //#endregion
9513
- //#region ../desktop/node_modules/.pnpm/klavis@2.15.0_encoding@0.1.13/node_modules/klavis/dist/esm/core/fetcher/getResponseBody.mjs
9523
+ //#region node_modules/.pnpm/klavis@2.15.0/node_modules/klavis/dist/esm/core/fetcher/getResponseBody.mjs
9514
9524
  var __awaiter$17 = void 0 && (void 0).__awaiter || function(thisArg, _arguments, P, generator) {
9515
9525
  function adopt(value) {
9516
9526
  return value instanceof P ? value : new P(function(resolve) {
@@ -9540,7 +9550,7 @@ var __awaiter$17 = void 0 && (void 0).__awaiter || function(thisArg, _arguments,
9540
9550
  };
9541
9551
 
9542
9552
  //#endregion
9543
- //#region ../desktop/node_modules/.pnpm/klavis@2.15.0_encoding@0.1.13/node_modules/klavis/dist/esm/core/fetcher/makeRequest.mjs
9553
+ //#region node_modules/.pnpm/klavis@2.15.0/node_modules/klavis/dist/esm/core/fetcher/makeRequest.mjs
9544
9554
  var __awaiter$16 = void 0 && (void 0).__awaiter || function(thisArg, _arguments, P, generator) {
9545
9555
  function adopt(value) {
9546
9556
  return value instanceof P ? value : new P(function(resolve) {
@@ -9570,7 +9580,7 @@ var __awaiter$16 = void 0 && (void 0).__awaiter || function(thisArg, _arguments,
9570
9580
  };
9571
9581
 
9572
9582
  //#endregion
9573
- //#region ../desktop/node_modules/.pnpm/klavis@2.15.0_encoding@0.1.13/node_modules/klavis/dist/esm/core/fetcher/requestWithRetries.mjs
9583
+ //#region node_modules/.pnpm/klavis@2.15.0/node_modules/klavis/dist/esm/core/fetcher/requestWithRetries.mjs
9574
9584
  var __awaiter$15 = void 0 && (void 0).__awaiter || function(thisArg, _arguments, P, generator) {
9575
9585
  function adopt(value) {
9576
9586
  return value instanceof P ? value : new P(function(resolve) {
@@ -9600,7 +9610,7 @@ var __awaiter$15 = void 0 && (void 0).__awaiter || function(thisArg, _arguments,
9600
9610
  };
9601
9611
 
9602
9612
  //#endregion
9603
- //#region ../desktop/node_modules/.pnpm/klavis@2.15.0_encoding@0.1.13/node_modules/klavis/dist/esm/core/fetcher/Fetcher.mjs
9613
+ //#region node_modules/.pnpm/klavis@2.15.0/node_modules/klavis/dist/esm/core/fetcher/Fetcher.mjs
9604
9614
  var __awaiter$14 = void 0 && (void 0).__awaiter || function(thisArg, _arguments, P, generator) {
9605
9615
  function adopt(value) {
9606
9616
  return value instanceof P ? value : new P(function(resolve) {
@@ -9630,7 +9640,7 @@ var __awaiter$14 = void 0 && (void 0).__awaiter || function(thisArg, _arguments,
9630
9640
  };
9631
9641
 
9632
9642
  //#endregion
9633
- //#region ../desktop/node_modules/.pnpm/klavis@2.15.0_encoding@0.1.13/node_modules/klavis/dist/esm/core/fetcher/HttpResponsePromise.mjs
9643
+ //#region node_modules/.pnpm/klavis@2.15.0/node_modules/klavis/dist/esm/core/fetcher/HttpResponsePromise.mjs
9634
9644
  var __awaiter$13 = void 0 && (void 0).__awaiter || function(thisArg, _arguments, P, generator) {
9635
9645
  function adopt(value) {
9636
9646
  return value instanceof P ? value : new P(function(resolve) {
@@ -9660,7 +9670,7 @@ var __awaiter$13 = void 0 && (void 0).__awaiter || function(thisArg, _arguments,
9660
9670
  };
9661
9671
 
9662
9672
  //#endregion
9663
- //#region ../desktop/node_modules/.pnpm/url-join@4.0.1/node_modules/url-join/lib/url-join.js
9673
+ //#region node_modules/.pnpm/url-join@4.0.1/node_modules/url-join/lib/url-join.js
9664
9674
  var require_url_join = /* @__PURE__ */ __commonJSMin(((exports, module) => {
9665
9675
  (function(name, context, definition) {
9666
9676
  if (typeof module !== "undefined" && module.exports) module.exports = definition();
@@ -9699,7 +9709,7 @@ var require_url_join = /* @__PURE__ */ __commonJSMin(((exports, module) => {
9699
9709
  }));
9700
9710
 
9701
9711
  //#endregion
9702
- //#region ../desktop/node_modules/.pnpm/klavis@2.15.0_encoding@0.1.13/node_modules/klavis/dist/esm/api/resources/mcpServer/client/Client.mjs
9712
+ //#region node_modules/.pnpm/klavis@2.15.0/node_modules/klavis/dist/esm/api/resources/mcpServer/client/Client.mjs
9703
9713
  var import_url_join = /* @__PURE__ */ __toESM$2(require_url_join(), 1);
9704
9714
  /**
9705
9715
  * This file was auto-generated by Fern from our API Definition.
@@ -9733,7 +9743,7 @@ var __awaiter$12 = void 0 && (void 0).__awaiter || function(thisArg, _arguments,
9733
9743
  };
9734
9744
 
9735
9745
  //#endregion
9736
- //#region ../desktop/node_modules/.pnpm/klavis@2.15.0_encoding@0.1.13/node_modules/klavis/dist/esm/api/resources/whiteLabeling/client/Client.mjs
9746
+ //#region node_modules/.pnpm/klavis@2.15.0/node_modules/klavis/dist/esm/api/resources/whiteLabeling/client/Client.mjs
9737
9747
  /**
9738
9748
  * This file was auto-generated by Fern from our API Definition.
9739
9749
  */
@@ -9766,7 +9776,7 @@ var __awaiter$11 = void 0 && (void 0).__awaiter || function(thisArg, _arguments,
9766
9776
  };
9767
9777
 
9768
9778
  //#endregion
9769
- //#region ../desktop/node_modules/.pnpm/klavis@2.15.0_encoding@0.1.13/node_modules/klavis/dist/esm/api/resources/user/client/Client.mjs
9779
+ //#region node_modules/.pnpm/klavis@2.15.0/node_modules/klavis/dist/esm/api/resources/user/client/Client.mjs
9770
9780
  /**
9771
9781
  * This file was auto-generated by Fern from our API Definition.
9772
9782
  */
@@ -9799,7 +9809,7 @@ var __awaiter$10 = void 0 && (void 0).__awaiter || function(thisArg, _arguments,
9799
9809
  };
9800
9810
 
9801
9811
  //#endregion
9802
- //#region ../desktop/node_modules/.pnpm/klavis@2.15.0_encoding@0.1.13/node_modules/klavis/dist/esm/api/resources/oauth/client/Client.mjs
9812
+ //#region node_modules/.pnpm/klavis@2.15.0/node_modules/klavis/dist/esm/api/resources/oauth/client/Client.mjs
9803
9813
  /**
9804
9814
  * This file was auto-generated by Fern from our API Definition.
9805
9815
  */
@@ -9832,7 +9842,7 @@ var __awaiter$9 = void 0 && (void 0).__awaiter || function(thisArg, _arguments,
9832
9842
  };
9833
9843
 
9834
9844
  //#endregion
9835
- //#region ../desktop/node_modules/.pnpm/klavis@2.15.0_encoding@0.1.13/node_modules/klavis/dist/esm/api/resources/googleCloudOauth/client/Client.mjs
9845
+ //#region node_modules/.pnpm/klavis@2.15.0/node_modules/klavis/dist/esm/api/resources/googleCloudOauth/client/Client.mjs
9836
9846
  /**
9837
9847
  * This file was auto-generated by Fern from our API Definition.
9838
9848
  */
@@ -9865,7 +9875,7 @@ var __awaiter$8 = void 0 && (void 0).__awaiter || function(thisArg, _arguments,
9865
9875
  };
9866
9876
 
9867
9877
  //#endregion
9868
- //#region ../desktop/node_modules/.pnpm/klavis@2.15.0_encoding@0.1.13/node_modules/klavis/dist/esm/api/resources/googleFormsOauth/client/Client.mjs
9878
+ //#region node_modules/.pnpm/klavis@2.15.0/node_modules/klavis/dist/esm/api/resources/googleFormsOauth/client/Client.mjs
9869
9879
  /**
9870
9880
  * This file was auto-generated by Fern from our API Definition.
9871
9881
  */
@@ -9898,7 +9908,7 @@ var __awaiter$7 = void 0 && (void 0).__awaiter || function(thisArg, _arguments,
9898
9908
  };
9899
9909
 
9900
9910
  //#endregion
9901
- //#region ../desktop/node_modules/.pnpm/klavis@2.15.0_encoding@0.1.13/node_modules/klavis/dist/esm/api/resources/onedriveOauth/client/Client.mjs
9911
+ //#region node_modules/.pnpm/klavis@2.15.0/node_modules/klavis/dist/esm/api/resources/onedriveOauth/client/Client.mjs
9902
9912
  /**
9903
9913
  * This file was auto-generated by Fern from our API Definition.
9904
9914
  */
@@ -9931,7 +9941,7 @@ var __awaiter$6 = void 0 && (void 0).__awaiter || function(thisArg, _arguments,
9931
9941
  };
9932
9942
 
9933
9943
  //#endregion
9934
- //#region ../desktop/node_modules/.pnpm/klavis@2.15.0_encoding@0.1.13/node_modules/klavis/dist/esm/api/resources/outlookOauth/client/Client.mjs
9944
+ //#region node_modules/.pnpm/klavis@2.15.0/node_modules/klavis/dist/esm/api/resources/outlookOauth/client/Client.mjs
9935
9945
  /**
9936
9946
  * This file was auto-generated by Fern from our API Definition.
9937
9947
  */
@@ -9964,7 +9974,7 @@ var __awaiter$5 = void 0 && (void 0).__awaiter || function(thisArg, _arguments,
9964
9974
  };
9965
9975
 
9966
9976
  //#endregion
9967
- //#region ../desktop/node_modules/.pnpm/klavis@2.15.0_encoding@0.1.13/node_modules/klavis/dist/esm/api/resources/mscalendarOauth/client/Client.mjs
9977
+ //#region node_modules/.pnpm/klavis@2.15.0/node_modules/klavis/dist/esm/api/resources/mscalendarOauth/client/Client.mjs
9968
9978
  /**
9969
9979
  * This file was auto-generated by Fern from our API Definition.
9970
9980
  */
@@ -9997,7 +10007,7 @@ var __awaiter$4 = void 0 && (void 0).__awaiter || function(thisArg, _arguments,
9997
10007
  };
9998
10008
 
9999
10009
  //#endregion
10000
- //#region ../desktop/node_modules/.pnpm/klavis@2.15.0_encoding@0.1.13/node_modules/klavis/dist/esm/api/resources/teamsOauth/client/Client.mjs
10010
+ //#region node_modules/.pnpm/klavis@2.15.0/node_modules/klavis/dist/esm/api/resources/teamsOauth/client/Client.mjs
10001
10011
  /**
10002
10012
  * This file was auto-generated by Fern from our API Definition.
10003
10013
  */
@@ -10030,7 +10040,7 @@ var __awaiter$3 = void 0 && (void 0).__awaiter || function(thisArg, _arguments,
10030
10040
  };
10031
10041
 
10032
10042
  //#endregion
10033
- //#region ../desktop/node_modules/.pnpm/klavis@2.15.0_encoding@0.1.13/node_modules/klavis/dist/esm/api/resources/zoomOauth/client/Client.mjs
10043
+ //#region node_modules/.pnpm/klavis@2.15.0/node_modules/klavis/dist/esm/api/resources/zoomOauth/client/Client.mjs
10034
10044
  /**
10035
10045
  * This file was auto-generated by Fern from our API Definition.
10036
10046
  */
@@ -10063,7 +10073,7 @@ var __awaiter$2 = void 0 && (void 0).__awaiter || function(thisArg, _arguments,
10063
10073
  };
10064
10074
 
10065
10075
  //#endregion
10066
- //#region ../desktop/node_modules/.pnpm/klavis@2.15.0_encoding@0.1.13/node_modules/klavis/dist/esm/api/resources/sharesightOauth/client/Client.mjs
10076
+ //#region node_modules/.pnpm/klavis@2.15.0/node_modules/klavis/dist/esm/api/resources/sharesightOauth/client/Client.mjs
10067
10077
  /**
10068
10078
  * This file was auto-generated by Fern from our API Definition.
10069
10079
  */
@@ -10096,7 +10106,7 @@ var __awaiter$1 = void 0 && (void 0).__awaiter || function(thisArg, _arguments,
10096
10106
  };
10097
10107
 
10098
10108
  //#endregion
10099
- //#region ../desktop/node_modules/.pnpm/klavis@2.15.0_encoding@0.1.13/node_modules/klavis/dist/esm/api/resources/sandbox/client/Client.mjs
10109
+ //#region node_modules/.pnpm/klavis@2.15.0/node_modules/klavis/dist/esm/api/resources/sandbox/client/Client.mjs
10100
10110
  /**
10101
10111
  * This file was auto-generated by Fern from our API Definition.
10102
10112
  */
@@ -10345,7 +10355,7 @@ const KLAVIS_SERVER_TYPES = [
10345
10355
 
10346
10356
  //#endregion
10347
10357
  //#region ../../package.json
10348
- var version$3 = "2.2.0";
10358
+ var version$3 = "2.2.1";
10349
10359
 
10350
10360
  //#endregion
10351
10361
  //#region ../../packages/const/src/version.ts
@@ -11894,7 +11904,7 @@ const taskTemplates = [
11894
11904
  const KNOWN_TASK_TEMPLATE_IDS = new Set(taskTemplates.map((t) => t.id));
11895
11905
 
11896
11906
  //#endregion
11897
- //#region ../desktop/node_modules/.pnpm/url-join@5.0.0/node_modules/url-join/lib/url-join.js
11907
+ //#region node_modules/.pnpm/url-join@5.0.0/node_modules/url-join/lib/url-join.js
11898
11908
  function normalize(strArray) {
11899
11909
  var resultArray = [];
11900
11910
  if (strArray.length === 0) return "";
@@ -11943,7 +11953,7 @@ const TERMS_URL = urlJoin(OFFICIAL_SITE, "/terms");
11943
11953
  const AGENTS_INDEX_GITHUB = "https://github.com/lobehub/lobe-chat-agents";
11944
11954
  const AGENTS_INDEX_GITHUB_ISSUE = urlJoin(AGENTS_INDEX_GITHUB, "issues/new");
11945
11955
  const RELEASES_URL = urlJoin(GITHUB, "releases");
11946
- const CHANGELOG_URL = urlJoin(OFFICIAL_SITE, "changelog/versions");
11956
+ const CHANGELOG_URL = urlJoin(OFFICIAL_SITE, "changelog");
11947
11957
  const DOWNLOAD_URL = {
11948
11958
  android: "https://play.google.com/store/apps/details?id=com.lobehub.app",
11949
11959
  default: urlJoin(OFFICIAL_SITE, "/downloads"),
@@ -18254,6 +18264,1206 @@ async function checkPlatformCapability(params) {
18254
18264
  };
18255
18265
  }
18256
18266
 
18267
+ //#endregion
18268
+ //#region src/tools/getAgentProfile.ts
18269
+ const IDENTITY_FILES$1 = ["IDENTITY.md", "SOUL.md"];
18270
+ /**
18271
+ * Try to extract a description from the workspace identity file.
18272
+ * Looks for Creature / Vibe / Description fields in IDENTITY.md or SOUL.md.
18273
+ */
18274
+ function readDescriptionFromWorkspace(workspacePath) {
18275
+ for (const filename of IDENTITY_FILES$1) {
18276
+ const filePath = path.join(workspacePath, filename);
18277
+ if (!fs.existsSync(filePath)) continue;
18278
+ const match = fs.readFileSync(filePath, "utf8").match(/\*{0,2}(?:Creature|Vibe|Description):?\*{0,2}\s*(.+)/i);
18279
+ if (!match) continue;
18280
+ const value = match[1].trim();
18281
+ if (/^[_*((].*[))*_]$|^(?:tbd|todo|n\/?a|none|待定|未定)$/i.test(value)) continue;
18282
+ return value;
18283
+ }
18284
+ }
18285
+ function getOpenClawProfile(agentId) {
18286
+ let output;
18287
+ try {
18288
+ output = execFileSync("openclaw", [
18289
+ "agents",
18290
+ "list",
18291
+ "--json"
18292
+ ], {
18293
+ encoding: "utf8",
18294
+ timeout: 5e3
18295
+ });
18296
+ } catch {
18297
+ return {};
18298
+ }
18299
+ let agents;
18300
+ try {
18301
+ agents = JSON.parse(output);
18302
+ } catch {
18303
+ return {};
18304
+ }
18305
+ const agent = agentId ? agents.find((a) => a.id === agentId) : agents.find((a) => a.isDefault) ?? agents[0];
18306
+ if (!agent) return {};
18307
+ const title = agent.identityName || void 0;
18308
+ return {
18309
+ avatar: agent.identityEmoji || "🦞",
18310
+ description: agent.workspace ? readDescriptionFromWorkspace(agent.workspace) : void 0,
18311
+ title
18312
+ };
18313
+ }
18314
+ /**
18315
+ * Read the active Hermes profile name from `hermes profile list` output.
18316
+ * The active profile is marked with ◆ in the first column.
18317
+ */
18318
+ function getActiveHermesProfileName() {
18319
+ try {
18320
+ return execFileSync("hermes", ["profile", "list"], {
18321
+ encoding: "utf8",
18322
+ timeout: 5e3
18323
+ }).match(/◆(\S+)/)?.[1];
18324
+ } catch {
18325
+ return;
18326
+ }
18327
+ }
18328
+ /**
18329
+ * Read the filesystem path of a Hermes profile from `hermes profile show <name>`.
18330
+ */
18331
+ function getHermesProfilePath(profileName) {
18332
+ try {
18333
+ return (execFileSync("hermes", [
18334
+ "profile",
18335
+ "show",
18336
+ profileName
18337
+ ], {
18338
+ encoding: "utf8",
18339
+ timeout: 5e3
18340
+ }).match(/^Path:\s+(.+)/m)?.[1]?.trim())?.replace(/^~(?=\/|$)/, os.homedir());
18341
+ } catch {
18342
+ return;
18343
+ }
18344
+ }
18345
+ /**
18346
+ * Extract a one-line description from a Hermes SOUL.md file.
18347
+ * Strips HTML comments and Markdown headings, then returns the first
18348
+ * non-empty line of actual content.
18349
+ */
18350
+ function readHermesSoulDescription(soulPath) {
18351
+ try {
18352
+ let stripped = fs.readFileSync(soulPath, "utf8");
18353
+ let previous;
18354
+ do {
18355
+ previous = stripped;
18356
+ stripped = stripped.replaceAll(/<!--[\s\S]*?-->/g, "").replaceAll(/[<>]/g, "").replaceAll(/^#+\s.*$/gm, "");
18357
+ } while (stripped !== previous);
18358
+ return stripped.split("\n").map((l) => l.trim()).find((l) => l.length > 0) || void 0;
18359
+ } catch {
18360
+ return;
18361
+ }
18362
+ }
18363
+ function getHermesProfile() {
18364
+ const profileName = getActiveHermesProfileName();
18365
+ if (!profileName) return {};
18366
+ const profilePath = getHermesProfilePath(profileName);
18367
+ return {
18368
+ avatar: "⚡",
18369
+ description: profilePath ? readHermesSoulDescription(path.join(profilePath, "SOUL.md")) : void 0,
18370
+ title: profileName
18371
+ };
18372
+ }
18373
+ /**
18374
+ * Fetch the agent profile (title, avatar, description) from the platform
18375
+ * installed on this device. Dispatched by the server via `device.getAgentProfile`.
18376
+ *
18377
+ * - openclaw: `openclaw agents list --json` for name + emoji, workspace
18378
+ * IDENTITY.md for description fallback
18379
+ * - hermes: active profile name + SOUL.md description
18380
+ */
18381
+ async function getAgentProfile(params) {
18382
+ const { platform, agentId } = params;
18383
+ if (platform === "openclaw") return getOpenClawProfile(agentId);
18384
+ if (platform === "hermes") return getHermesProfile();
18385
+ return {};
18386
+ }
18387
+
18388
+ //#endregion
18389
+ //#region src/daemon/taskRegistry.ts
18390
+ function getRegistryPath() {
18391
+ return path.join(os.homedir(), ".lobehub", "task-registry.json");
18392
+ }
18393
+ function readRegistry() {
18394
+ try {
18395
+ return JSON.parse(fs.readFileSync(getRegistryPath(), "utf8"));
18396
+ } catch {
18397
+ return {};
18398
+ }
18399
+ }
18400
+ function writeRegistry(entries) {
18401
+ const dir = path.dirname(getRegistryPath());
18402
+ fs.mkdirSync(dir, {
18403
+ mode: 448,
18404
+ recursive: true
18405
+ });
18406
+ fs.writeFileSync(getRegistryPath(), JSON.stringify(entries, null, 2), { mode: 384 });
18407
+ }
18408
+ function saveTask(entry) {
18409
+ const registry = readRegistry();
18410
+ registry[entry.taskId] = entry;
18411
+ writeRegistry(registry);
18412
+ }
18413
+ function getTask(taskId) {
18414
+ return readRegistry()[taskId];
18415
+ }
18416
+ function removeTask(taskId) {
18417
+ const registry = readRegistry();
18418
+ delete registry[taskId];
18419
+ writeRegistry(registry);
18420
+ }
18421
+ function listTasks() {
18422
+ return Object.values(readRegistry());
18423
+ }
18424
+
18425
+ //#endregion
18426
+ //#region src/tools/heteroTask.ts
18427
+ const LOBEHUB_DIR_NAME = process.env.LOBEHUB_CLI_HOME || ".lobehub";
18428
+ const HERMES_SESSIONS_FILE = path.join(os.homedir(), LOBEHUB_DIR_NAME, "hermes-sessions.json");
18429
+ function getHermesSessionId(topicId) {
18430
+ try {
18431
+ return JSON.parse(fs.readFileSync(HERMES_SESSIONS_FILE, "utf8"))[topicId];
18432
+ } catch {
18433
+ return;
18434
+ }
18435
+ }
18436
+ function saveHermesSessionId(topicId, sessionId) {
18437
+ let data = {};
18438
+ try {
18439
+ data = JSON.parse(fs.readFileSync(HERMES_SESSIONS_FILE, "utf8"));
18440
+ } catch {}
18441
+ data[topicId] = sessionId;
18442
+ fs.mkdirSync(path.dirname(HERMES_SESSIONS_FILE), { recursive: true });
18443
+ fs.writeFileSync(HERMES_SESSIONS_FILE, JSON.stringify(data), "utf8");
18444
+ }
18445
+ /** Resolve the absolute path to the `lh` binary to avoid PATH issues in child processes. */
18446
+ function resolveLhPath() {
18447
+ try {
18448
+ return execFileSync("which", ["lh"], { encoding: "utf8" }).trim();
18449
+ } catch {
18450
+ return "lh";
18451
+ }
18452
+ }
18453
+ async function sendAutoNotify(topicId, taskId, text, agentId) {
18454
+ try {
18455
+ await (await getTrpcClient()).agentNotify.notify.mutate({
18456
+ agentId,
18457
+ content: text,
18458
+ role: "assistant",
18459
+ topicId
18460
+ });
18461
+ } catch (err) {
18462
+ log$7.error("Failed to send auto-notify:", err instanceof Error ? err.message : String(err));
18463
+ }
18464
+ }
18465
+ /**
18466
+ * Signal remote hetero task completion to the server so it can publish
18467
+ * `agent_runtime_end` to the gateway WS and close the frontend subscription.
18468
+ * Called on clean process exit (code=0, no signal) — error exits go through
18469
+ * `sendAutoNotify` which writes an error message AND triggers completion via
18470
+ * the `done` flag.
18471
+ */
18472
+ async function sendDoneSignal(topicId, agentId) {
18473
+ try {
18474
+ await (await getTrpcClient()).agentNotify.notify.mutate({
18475
+ agentId,
18476
+ content: "",
18477
+ done: true,
18478
+ role: "assistant",
18479
+ topicId
18480
+ });
18481
+ } catch (err) {
18482
+ log$7.error("Failed to send done signal:", err instanceof Error ? err.message : String(err));
18483
+ }
18484
+ }
18485
+ /**
18486
+ * Build the notify protocol injected into the first message of a new hetero-agent session.
18487
+ * Tells the agent how to push updates back to the LobeHub user via `lh notify`.
18488
+ */
18489
+ function buildNotifyProtocol(lhPath, topicId) {
18490
+ return `## Context: This task was dispatched by LobeHub
18491
+
18492
+ This conversation / task was sent to you by the **LobeHub platform** on behalf of a user. You are running as a background agent; the user is waiting for your response inside the LobeHub chat interface.
18493
+
18494
+ **When to call notify**: any time you have something meaningful to tell the user — a key finding, a decision you made, a result, a question, or your final answer. Think of it as speaking directly to the user in the chat window.
18495
+
18496
+ **What to hide**: internal work details such as tool call sequences, file reads, intermediate command output, retries, or low-level reasoning steps. The user cares about outcomes and insights, not your step-by-step mechanics.
18497
+
18498
+ ## Sending messages back to the user
18499
+
18500
+ Use the \`${lhPath} notify\` command. All your updates appear as a **single message bubble** in the UI — create it once and update it in place.\n\n**Step 1 — Open the bubble on your first meaningful update** (captures the messageId):\n\`\`\`\nMSG_ID=$(${lhPath} notify --topic ${topicId} --role assistant --content "Starting..." --json | grep -o '"messageId":"[^"]*"' | cut -d'"' -f4)\n\`\`\`\n\n**Step 2 — Update the same bubble as you make progress**:\n\`\`\`\n${lhPath} notify --topic ${topicId} --role assistant --message-id "$MSG_ID" --content "Still working..."\n\`\`\`\n\n**Step 3 — Replace with your complete, final response when done**:\n\`\`\`\n${lhPath} notify --topic ${topicId} --role assistant --message-id "$MSG_ID" --content "<your full response here>"\n\`\`\`\n\nRules:\n- Always use \`--json\` on the first call and capture \`messageId\` from the output.\n- Always pass \`--message-id\` on every subsequent call so updates overwrite the same bubble.\n- Write what matters to the user — not implementation steps or internal tool calls.\n- Call notify at least once when the task is done, even if there were no intermediate updates.`;
18501
+ }
18502
+ async function runHeteroTask(params) {
18503
+ const { agentId, agentType, cwd, operationId, prompt, taskId, topicId } = params;
18504
+ const workDir = cwd || process.cwd();
18505
+ const lhPath = resolveLhPath();
18506
+ if (agentType === "openclaw") {
18507
+ const openclawAgent = process.env.OPENCLAW_AGENT_ID ?? "main";
18508
+ const enrichedPrompt = `${prompt}\n\n${buildNotifyProtocol(lhPath, topicId)}`;
18509
+ for (const existing of listTasks()) if (existing.topicId === topicId && existing.agentType === "openclaw") {
18510
+ try {
18511
+ process.kill(existing.pid, "SIGTERM");
18512
+ } catch {}
18513
+ removeTask(existing.taskId);
18514
+ }
18515
+ const child = spawn("openclaw", [
18516
+ "agent",
18517
+ "--agent",
18518
+ openclawAgent,
18519
+ "--session-id",
18520
+ topicId,
18521
+ "--message",
18522
+ enrichedPrompt,
18523
+ "--local"
18524
+ ], {
18525
+ cwd: workDir,
18526
+ detached: true,
18527
+ env: { ...process.env },
18528
+ stdio: "ignore"
18529
+ });
18530
+ const pid = child.pid;
18531
+ if (pid === void 0) throw new Error("Failed to get PID for openclaw process");
18532
+ child.unref();
18533
+ saveTask({
18534
+ agentId,
18535
+ agentType,
18536
+ operationId,
18537
+ pid,
18538
+ startedAt: (/* @__PURE__ */ new Date()).toISOString(),
18539
+ taskId,
18540
+ topicId
18541
+ });
18542
+ log$7.info(`OpenClaw task started: taskId=${taskId} pid=${pid} agent=${openclawAgent}`);
18543
+ child.on("close", (code, signal) => {
18544
+ removeTask(taskId);
18545
+ if (code !== 0 || signal !== null) sendAutoNotify(topicId, taskId, signal ? `Task cancelled (signal: ${signal})` : `Task failed (exit code: ${code})`, agentId).finally(() => sendDoneSignal(topicId, agentId));
18546
+ else sendDoneSignal(topicId, agentId);
18547
+ });
18548
+ return JSON.stringify({
18549
+ pid,
18550
+ taskId
18551
+ });
18552
+ }
18553
+ if (agentType === "hermes") {
18554
+ for (const existing of listTasks()) if (existing.topicId === topicId && existing.agentType === "hermes") {
18555
+ try {
18556
+ process.kill(existing.pid, "SIGTERM");
18557
+ } catch {}
18558
+ removeTask(existing.taskId);
18559
+ }
18560
+ const existingSessionId = getHermesSessionId(topicId);
18561
+ const hermesArgs = [
18562
+ "chat",
18563
+ "--query",
18564
+ prompt,
18565
+ "--quiet",
18566
+ "--accept-hooks"
18567
+ ];
18568
+ if (existingSessionId) hermesArgs.push("--resume", existingSessionId);
18569
+ const child = spawn("hermes", hermesArgs, {
18570
+ cwd: workDir,
18571
+ detached: true,
18572
+ env: { ...process.env },
18573
+ stdio: [
18574
+ "ignore",
18575
+ "pipe",
18576
+ "ignore"
18577
+ ]
18578
+ });
18579
+ const pid = child.pid;
18580
+ if (pid === void 0) throw new Error("Failed to get PID for hermes process");
18581
+ child.unref();
18582
+ saveTask({
18583
+ agentId,
18584
+ agentType,
18585
+ operationId,
18586
+ pid,
18587
+ startedAt: (/* @__PURE__ */ new Date()).toISOString(),
18588
+ taskId,
18589
+ topicId
18590
+ });
18591
+ log$7.info(`Hermes task started: taskId=${taskId} pid=${pid}`);
18592
+ let stdout = "";
18593
+ child.stdout.on("data", (chunk) => {
18594
+ stdout += chunk.toString();
18595
+ });
18596
+ child.on("close", (code, signal) => {
18597
+ removeTask(taskId);
18598
+ if (code !== 0 || signal !== null) {
18599
+ sendAutoNotify(topicId, taskId, signal ? `Task cancelled (signal: ${signal})` : `Task failed (exit code: ${code})`, agentId).finally(() => sendDoneSignal(topicId, agentId));
18600
+ return;
18601
+ }
18602
+ const sessionId = stdout.match(/^session_id:\s*(\S+)/m)?.[1];
18603
+ const response = stdout.replace(/^session_id:[^\n]*\n?/, "").trim();
18604
+ if (sessionId) saveHermesSessionId(topicId, sessionId);
18605
+ if (response) sendAutoNotify(topicId, taskId, response, agentId).finally(() => sendDoneSignal(topicId, agentId));
18606
+ else sendDoneSignal(topicId, agentId);
18607
+ });
18608
+ return JSON.stringify({
18609
+ pid,
18610
+ taskId
18611
+ });
18612
+ }
18613
+ throw new Error(`Unsupported agentType: ${agentType}`);
18614
+ }
18615
+ async function cancelHeteroTask(params) {
18616
+ const { signal = "SIGINT", taskId } = params;
18617
+ const entry = getTask(taskId);
18618
+ if (!entry) return JSON.stringify({
18619
+ message: `No task found with taskId: ${taskId}`,
18620
+ success: false
18621
+ });
18622
+ try {
18623
+ process.kill(entry.pid, signal);
18624
+ } catch (err) {
18625
+ log$7.warn(`Failed to send ${signal} to pid ${entry.pid}: ${err instanceof Error ? err.message : String(err)}`);
18626
+ removeTask(taskId);
18627
+ await sendAutoNotify(entry.topicId, taskId, "Task already completed or cancelled", entry.agentId);
18628
+ }
18629
+ return JSON.stringify({
18630
+ pid: entry.pid,
18631
+ signal,
18632
+ taskId
18633
+ });
18634
+ }
18635
+
18636
+ //#endregion
18637
+ //#region ../../packages/prompts/src/prompts/fileSystem/formatCommandOutput.ts
18638
+ var formatCommandOutput;
18639
+ var init_formatCommandOutput = __esmMin((() => {
18640
+ formatCommandOutput = ({ success, exitCode, output, error }) => {
18641
+ const parts = [success ? "Output retrieved." : `Failed: ${error}`];
18642
+ if (exitCode !== void 0) parts.push(`Exit code: ${exitCode}`);
18643
+ if (output) parts.push(`Output:\n${output}`);
18644
+ if (error && success) parts.push(`Error: ${error}`);
18645
+ return parts.join("\n\n");
18646
+ };
18647
+ }));
18648
+
18649
+ //#endregion
18650
+ //#region ../../packages/prompts/src/prompts/fileSystem/formatCommandResult.ts
18651
+ var formatCommandResult;
18652
+ var init_formatCommandResult = __esmMin((() => {
18653
+ formatCommandResult = ({ success, shellId, error, stdout, stderr, exitCode }) => {
18654
+ const parts = [];
18655
+ const hasNonZeroExit = exitCode !== void 0 && exitCode !== 0;
18656
+ if (!success || hasNonZeroExit) {
18657
+ let header = "Command failed";
18658
+ if (hasNonZeroExit) header += ` with exit code ${exitCode}`;
18659
+ if (error) header += `: ${error}`;
18660
+ parts.push(header);
18661
+ } else if (shellId) parts.push(`Command started in background with shell_id: ${shellId}`);
18662
+ else parts.push("Command completed successfully.");
18663
+ if (stdout) parts.push(`Output:\n${stdout}`);
18664
+ if (stderr) parts.push(`Stderr:\n${stderr}`);
18665
+ return parts.join("\n\n");
18666
+ };
18667
+ }));
18668
+
18669
+ //#endregion
18670
+ //#region ../../packages/prompts/src/prompts/fileSystem/formatEditResult.ts
18671
+ var formatEditResult;
18672
+ var init_formatEditResult = __esmMin((() => {
18673
+ formatEditResult = ({ replacements, filePath, linesAdded, linesDeleted }) => {
18674
+ return `Successfully replaced ${replacements} occurrence(s) in ${filePath}${linesAdded || linesDeleted ? ` (+${linesAdded || 0} -${linesDeleted || 0})` : ""}`;
18675
+ };
18676
+ }));
18677
+
18678
+ //#endregion
18679
+ //#region ../../packages/prompts/src/prompts/fileSystem/formatFileContent.ts
18680
+ var formatFileContent;
18681
+ var init_formatFileContent = __esmMin((() => {
18682
+ formatFileContent = ({ path, content, lineRange }) => {
18683
+ return `File: ${path}${lineRange ? ` (lines ${lineRange[0]}-${lineRange[1]})` : ""}\n\n${content}`;
18684
+ };
18685
+ }));
18686
+
18687
+ //#endregion
18688
+ //#region ../../packages/prompts/src/prompts/fileSystem/formatFileList.ts
18689
+ var formatFileSize, formatDate, formatFileList;
18690
+ var init_formatFileList = __esmMin((() => {
18691
+ formatFileSize = (bytes) => {
18692
+ if (bytes === 0) return "0 B";
18693
+ const k = 1024;
18694
+ const sizes = [
18695
+ "B",
18696
+ "KB",
18697
+ "MB",
18698
+ "GB",
18699
+ "TB"
18700
+ ];
18701
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
18702
+ return `${Number.parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;
18703
+ };
18704
+ formatDate = (date) => {
18705
+ return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")} ${String(date.getHours()).padStart(2, "0")}:${String(date.getMinutes()).padStart(2, "0")}`;
18706
+ };
18707
+ formatFileList = ({ files, directory, sortBy, sortOrder, totalCount: totalCountParam }) => {
18708
+ if (files.length === 0) return `Directory ${directory} is empty`;
18709
+ const hasExtendedInfo = files.some((f) => f.size !== void 0 || f.modifiedTime !== void 0);
18710
+ const totalCount = totalCountParam ?? files.length;
18711
+ const isTruncated = totalCount > files.length;
18712
+ let header = `Found ${totalCount} item(s) in ${directory}`;
18713
+ const parts = [];
18714
+ if (isTruncated) parts.push(`showing first ${files.length}`);
18715
+ if (sortBy) parts.push(`sorted by ${sortBy} ${sortOrder || "desc"}`);
18716
+ if (parts.length > 0) header += ` (${parts.join(", ")})`;
18717
+ const fileList = files.map((f) => {
18718
+ const prefix = f.isDirectory ? "[D]" : "[F]";
18719
+ const name = f.name;
18720
+ if (hasExtendedInfo) {
18721
+ const date = f.modifiedTime ? formatDate(f.modifiedTime) : " ";
18722
+ const size = f.isDirectory ? " --" : f.size !== void 0 ? formatFileSize(f.size).padStart(10) : " ";
18723
+ return ` ${prefix} ${name.padEnd(40)} ${date} ${size}`;
18724
+ }
18725
+ return ` ${prefix} ${name}`;
18726
+ }).join("\n");
18727
+ return `${header}:\n${fileList}`;
18728
+ };
18729
+ }));
18730
+
18731
+ //#endregion
18732
+ //#region ../../packages/prompts/src/prompts/fileSystem/formatFileSearchResults.ts
18733
+ var formatFileSearchResults;
18734
+ var init_formatFileSearchResults = __esmMin((() => {
18735
+ formatFileSearchResults = (results) => {
18736
+ if (results.length === 0) return "No files found";
18737
+ const fileList = results.map((f) => ` ${f.path}`).join("\n");
18738
+ return `Found ${results.length} file(s):\n${fileList}`;
18739
+ };
18740
+ }));
18741
+
18742
+ //#endregion
18743
+ //#region ../../packages/prompts/src/prompts/fileSystem/formatGlobResults.ts
18744
+ var formatGlobResults;
18745
+ var init_formatGlobResults = __esmMin((() => {
18746
+ formatGlobResults = ({ totalFiles, files, maxDisplay = 50 }) => {
18747
+ const message = `Found ${totalFiles} files`;
18748
+ if (files.length === 0) return message;
18749
+ return `${message}:\n${files.slice(0, maxDisplay).map((f) => ` ${f}`).join("\n")}${files.length > maxDisplay ? `\n ... and ${files.length - maxDisplay} more` : ""}`;
18750
+ };
18751
+ }));
18752
+
18753
+ //#endregion
18754
+ //#region ../../packages/prompts/src/prompts/fileSystem/formatGrepResults.ts
18755
+ var formatGrepResults;
18756
+ var init_formatGrepResults = __esmMin((() => {
18757
+ formatGrepResults = ({ totalMatches, matches, maxDisplay = 20 }) => {
18758
+ const message = `Found ${totalMatches} matches in ${matches.length} locations`;
18759
+ if (matches.length === 0) return message;
18760
+ return `${message}:\n${matches.slice(0, maxDisplay).map((m) => {
18761
+ if (typeof m === "string") return ` ${m}`;
18762
+ const parts = [];
18763
+ if (m.path) parts.push(m.path);
18764
+ if (m.lineNumber !== void 0) parts.push(`:${m.lineNumber}`);
18765
+ if (m.content) if (parts.length > 0) parts.push(`: ${m.content}`);
18766
+ else parts.push(m.content);
18767
+ return ` ${parts.join("")}`;
18768
+ }).join("\n")}${matches.length > maxDisplay ? `\n ... and ${matches.length - maxDisplay} more` : ""}`;
18769
+ };
18770
+ }));
18771
+
18772
+ //#endregion
18773
+ //#region ../../packages/prompts/src/prompts/fileSystem/formatKillResult.ts
18774
+ var formatKillResult;
18775
+ var init_formatKillResult = __esmMin((() => {
18776
+ formatKillResult = ({ success, shellId, error }) => {
18777
+ return success ? `Successfully killed shell: ${shellId}` : `Failed to kill shell: ${error}`;
18778
+ };
18779
+ }));
18780
+
18781
+ //#endregion
18782
+ //#region ../../packages/prompts/src/prompts/fileSystem/formatMoveResults.ts
18783
+ var formatMoveResults;
18784
+ var init_formatMoveResults = __esmMin((() => {
18785
+ formatMoveResults = (results) => {
18786
+ const successCount = results.filter((r) => r.success).length;
18787
+ const failedCount = results.length - successCount;
18788
+ const allSucceeded = failedCount === 0;
18789
+ const allFailed = successCount === 0;
18790
+ if (allSucceeded) return `Successfully moved ${results.length} item(s).`;
18791
+ if (allFailed) return `Failed to move all ${results.length} item(s).`;
18792
+ return `Moved ${successCount} item(s) successfully. Failed to move ${failedCount} item(s).`;
18793
+ };
18794
+ }));
18795
+
18796
+ //#endregion
18797
+ //#region ../../packages/prompts/src/prompts/fileSystem/formatMultipleFiles.ts
18798
+ var formatMultipleFiles;
18799
+ var init_formatMultipleFiles = __esmMin((() => {
18800
+ formatMultipleFiles = (files) => {
18801
+ const fileContents = files.map((f) => `=== ${f.filename} ===\n${f.content}`).join("\n\n");
18802
+ return `Read ${files.length} file(s):\n\n${fileContents}`;
18803
+ };
18804
+ }));
18805
+
18806
+ //#endregion
18807
+ //#region ../../packages/prompts/src/prompts/fileSystem/formatRenameResult.ts
18808
+ var formatRenameResult;
18809
+ var init_formatRenameResult = __esmMin((() => {
18810
+ formatRenameResult = ({ success, oldPath, newName, error }) => {
18811
+ return success ? `Successfully renamed file ${oldPath} to ${newName}` : `Failed to rename file: ${error}`;
18812
+ };
18813
+ }));
18814
+
18815
+ //#endregion
18816
+ //#region ../../packages/prompts/src/prompts/fileSystem/formatWriteResult.ts
18817
+ var formatWriteResult;
18818
+ var init_formatWriteResult = __esmMin((() => {
18819
+ formatWriteResult = ({ success, path, error }) => {
18820
+ return success ? `Successfully wrote to ${path}` : `Failed to write file: ${error || "Unknown error"}`;
18821
+ };
18822
+ }));
18823
+
18824
+ //#endregion
18825
+ //#region ../../packages/prompts/src/prompts/fileSystem/index.ts
18826
+ var fileSystem_exports = /* @__PURE__ */ __exportAll({
18827
+ formatCommandOutput: () => formatCommandOutput,
18828
+ formatCommandResult: () => formatCommandResult,
18829
+ formatEditResult: () => formatEditResult,
18830
+ formatFileContent: () => formatFileContent,
18831
+ formatFileList: () => formatFileList,
18832
+ formatFileSearchResults: () => formatFileSearchResults,
18833
+ formatGlobResults: () => formatGlobResults,
18834
+ formatGrepResults: () => formatGrepResults,
18835
+ formatKillResult: () => formatKillResult,
18836
+ formatMoveResults: () => formatMoveResults,
18837
+ formatMultipleFiles: () => formatMultipleFiles,
18838
+ formatRenameResult: () => formatRenameResult,
18839
+ formatWriteResult: () => formatWriteResult
18840
+ });
18841
+ var init_fileSystem = __esmMin((() => {
18842
+ init_formatCommandOutput();
18843
+ init_formatCommandResult();
18844
+ init_formatEditResult();
18845
+ init_formatFileContent();
18846
+ init_formatFileList();
18847
+ init_formatFileSearchResults();
18848
+ init_formatGlobResults();
18849
+ init_formatGrepResults();
18850
+ init_formatKillResult();
18851
+ init_formatMoveResults();
18852
+ init_formatMultipleFiles();
18853
+ init_formatRenameResult();
18854
+ init_formatWriteResult();
18855
+ }));
18856
+
18857
+ //#endregion
18858
+ //#region ../../packages/tool-runtime/src/ComputerRuntime.ts
18859
+ init_fileSystem();
18860
+ /**
18861
+ * ComputerRuntime — abstract base for computer operations (file system, shell, search).
18862
+ *
18863
+ * Subclasses implement `callService` to delegate to their specific backend
18864
+ * (Electron IPC, cloud sandbox API, etc.). The base class handles:
18865
+ * - Normalizing raw results into formatted content via `@lobechat/prompts`
18866
+ * - Building consistent state objects for UI rendering
18867
+ */
18868
+ var ComputerRuntime = class {
18869
+ async listFiles(args) {
18870
+ try {
18871
+ const result = await this.callService("listLocalFiles", args);
18872
+ if (!result.success) return this.errorOutput(result, {
18873
+ files: [],
18874
+ totalCount: 0
18875
+ });
18876
+ const files = result.result?.files || [];
18877
+ const totalCount = result.result?.totalCount;
18878
+ const state = {
18879
+ files,
18880
+ totalCount
18881
+ };
18882
+ return {
18883
+ content: formatFileList({
18884
+ directory: args.path,
18885
+ files: files.map((f) => ({
18886
+ isDirectory: f.isDirectory,
18887
+ name: f.name
18888
+ })),
18889
+ sortBy: args.sortBy,
18890
+ sortOrder: args.sortOrder,
18891
+ totalCount
18892
+ }),
18893
+ state,
18894
+ success: true
18895
+ };
18896
+ } catch (error) {
18897
+ return this.handleError(error);
18898
+ }
18899
+ }
18900
+ async readFile(args) {
18901
+ try {
18902
+ const result = await this.callService("readLocalFile", args);
18903
+ if (!result.success) return this.errorOutput(result, {
18904
+ content: "",
18905
+ endLine: args.loc?.[1],
18906
+ path: args.path,
18907
+ startLine: args.loc?.[0]
18908
+ });
18909
+ const r = result.result || {};
18910
+ const fileContent = r.content || "";
18911
+ const state = {
18912
+ charCount: r.charCount ?? fileContent.length,
18913
+ content: fileContent,
18914
+ endLine: args.loc?.[1],
18915
+ fileType: r.fileType,
18916
+ filename: r.filename,
18917
+ loc: r.loc,
18918
+ path: args.path,
18919
+ startLine: args.loc?.[0],
18920
+ totalCharCount: r.totalCharCount,
18921
+ totalLines: r.totalLineCount ?? r.totalLines
18922
+ };
18923
+ return {
18924
+ content: formatFileContent({
18925
+ content: fileContent,
18926
+ lineRange: args.loc,
18927
+ path: args.path
18928
+ }),
18929
+ state,
18930
+ success: true
18931
+ };
18932
+ } catch (error) {
18933
+ return this.handleError(error);
18934
+ }
18935
+ }
18936
+ async writeFile(args) {
18937
+ try {
18938
+ const result = await this.callService("writeLocalFile", args);
18939
+ if (!result.success) return this.errorOutput(result, {
18940
+ path: args.path,
18941
+ success: false
18942
+ });
18943
+ const state = {
18944
+ bytesWritten: result.result?.bytesWritten,
18945
+ path: args.path,
18946
+ success: true
18947
+ };
18948
+ return {
18949
+ content: formatWriteResult({
18950
+ path: args.path,
18951
+ success: true
18952
+ }),
18953
+ state,
18954
+ success: true
18955
+ };
18956
+ } catch (error) {
18957
+ return this.handleError(error);
18958
+ }
18959
+ }
18960
+ async editFile(args) {
18961
+ try {
18962
+ const result = await this.callService("editLocalFile", args);
18963
+ if (!result.success) return this.errorOutput(result, {
18964
+ path: args.file_path,
18965
+ replacements: 0
18966
+ });
18967
+ const state = {
18968
+ diffText: result.result?.diffText,
18969
+ linesAdded: result.result?.linesAdded,
18970
+ linesDeleted: result.result?.linesDeleted,
18971
+ path: args.file_path,
18972
+ replacements: result.result?.replacements || 0
18973
+ };
18974
+ return {
18975
+ content: formatEditResult({
18976
+ filePath: args.file_path,
18977
+ linesAdded: state.linesAdded,
18978
+ linesDeleted: state.linesDeleted,
18979
+ replacements: state.replacements
18980
+ }),
18981
+ state,
18982
+ success: true
18983
+ };
18984
+ } catch (error) {
18985
+ return this.handleError(error);
18986
+ }
18987
+ }
18988
+ async searchFiles(args) {
18989
+ try {
18990
+ const result = await this.callService("searchLocalFiles", args);
18991
+ if (!result.success) return this.errorOutput(result, {
18992
+ results: [],
18993
+ totalCount: 0
18994
+ });
18995
+ const rawResults = result.result?.results || result.result;
18996
+ const results = Array.isArray(rawResults) ? rawResults : [];
18997
+ const state = {
18998
+ results,
18999
+ totalCount: result.result?.totalCount || results.length
19000
+ };
19001
+ return {
19002
+ content: formatFileSearchResults(results.map((r) => ({ path: r.path }))),
19003
+ state,
19004
+ success: true
19005
+ };
19006
+ } catch (error) {
19007
+ return this.handleError(error);
19008
+ }
19009
+ }
19010
+ async moveFiles(args) {
19011
+ try {
19012
+ const result = await this.callService("moveLocalFiles", args);
19013
+ if (!result.success) return this.errorOutput(result, {
19014
+ results: [],
19015
+ successCount: 0,
19016
+ totalCount: args.items.length
19017
+ });
19018
+ const rawResults = result.result?.results || result.result;
19019
+ const results = Array.isArray(rawResults) ? rawResults : [];
19020
+ const state = {
19021
+ results,
19022
+ successCount: result.result?.successCount ?? results.filter((r) => r.success).length,
19023
+ totalCount: args.items.length
19024
+ };
19025
+ return {
19026
+ content: formatMoveResults(results),
19027
+ state,
19028
+ success: true
19029
+ };
19030
+ } catch (error) {
19031
+ return this.handleError(error);
19032
+ }
19033
+ }
19034
+ async renameFile(args) {
19035
+ try {
19036
+ const result = await this.callService("renameLocalFile", args);
19037
+ if (!result.success) {
19038
+ const errorMsg = result.error?.message || result.result?.error;
19039
+ return {
19040
+ content: formatRenameResult({
19041
+ error: errorMsg,
19042
+ newName: args.newName,
19043
+ oldPath: args.oldPath,
19044
+ success: false
19045
+ }),
19046
+ state: {
19047
+ error: errorMsg,
19048
+ newPath: "",
19049
+ oldPath: args.oldPath,
19050
+ success: false
19051
+ },
19052
+ success: true
19053
+ };
19054
+ }
19055
+ const state = {
19056
+ error: result.result?.error,
19057
+ newPath: result.result?.newPath || "",
19058
+ oldPath: args.oldPath,
19059
+ success: true
19060
+ };
19061
+ return {
19062
+ content: formatRenameResult({
19063
+ error: result.result?.error,
19064
+ newName: args.newName,
19065
+ oldPath: args.oldPath,
19066
+ success: true
19067
+ }),
19068
+ state,
19069
+ success: true
19070
+ };
19071
+ } catch (error) {
19072
+ return this.handleError(error);
19073
+ }
19074
+ }
19075
+ async runCommand(args) {
19076
+ try {
19077
+ const result = await this.callService("runCommand", args);
19078
+ if (!result.success) return this.errorOutput(result, {
19079
+ error: result.error?.message,
19080
+ exitCode: result.result?.exitCode ?? result.result?.exit_code,
19081
+ isBackground: args.background || false,
19082
+ stderr: result.result?.stderr,
19083
+ stdout: result.result?.stdout,
19084
+ success: false
19085
+ });
19086
+ const r = result.result || {};
19087
+ const state = {
19088
+ commandId: r.commandId || r.shell_id,
19089
+ error: r.error,
19090
+ exitCode: r.exitCode ?? r.exit_code,
19091
+ isBackground: args.background || false,
19092
+ output: r.output,
19093
+ stderr: r.stderr,
19094
+ stdout: r.stdout,
19095
+ success: result.success
19096
+ };
19097
+ return {
19098
+ content: formatCommandResult({
19099
+ error: r.error,
19100
+ exitCode: r.exitCode ?? r.exit_code,
19101
+ shellId: r.commandId || r.shell_id,
19102
+ stderr: r.stderr,
19103
+ stdout: r.stdout || r.output,
19104
+ success: result.success
19105
+ }),
19106
+ state,
19107
+ success: true
19108
+ };
19109
+ } catch (error) {
19110
+ return this.handleError(error);
19111
+ }
19112
+ }
19113
+ async getCommandOutput(args) {
19114
+ try {
19115
+ const result = await this.callService("getCommandOutput", args);
19116
+ if (!result.success) return this.errorOutput(result, {
19117
+ error: result.error?.message,
19118
+ success: false
19119
+ });
19120
+ const r = result.result || {};
19121
+ const state = {
19122
+ error: r.error,
19123
+ exitCode: r.exitCode ?? r.exit_code,
19124
+ newOutput: r.newOutput || r.output,
19125
+ success: result.success
19126
+ };
19127
+ return {
19128
+ content: formatCommandOutput({
19129
+ error: r.error,
19130
+ exitCode: r.exitCode ?? r.exit_code,
19131
+ output: r.newOutput || r.output,
19132
+ success: result.success
19133
+ }),
19134
+ state,
19135
+ success: true
19136
+ };
19137
+ } catch (error) {
19138
+ return this.handleError(error);
19139
+ }
19140
+ }
19141
+ async killCommand(args) {
19142
+ try {
19143
+ const result = await this.callService("killCommand", args);
19144
+ if (!result.success) return this.errorOutput(result, {
19145
+ commandId: args.commandId,
19146
+ error: result.error?.message,
19147
+ success: false
19148
+ });
19149
+ const state = {
19150
+ commandId: args.commandId,
19151
+ error: result.result?.error,
19152
+ success: result.success
19153
+ };
19154
+ return {
19155
+ content: formatKillResult({
19156
+ error: result.result?.error,
19157
+ shellId: args.commandId,
19158
+ success: result.success
19159
+ }),
19160
+ state,
19161
+ success: true
19162
+ };
19163
+ } catch (error) {
19164
+ return this.handleError(error);
19165
+ }
19166
+ }
19167
+ async grepContent(args) {
19168
+ try {
19169
+ const result = await this.callService("grepContent", args);
19170
+ if (!result.success) return this.errorOutput(result, {
19171
+ matches: [],
19172
+ pattern: args.pattern,
19173
+ totalMatches: 0
19174
+ });
19175
+ const r = result.result || {};
19176
+ const matches = r.matches || [];
19177
+ const totalMatches = r.totalMatches ?? r.total_matches ?? 0;
19178
+ const state = {
19179
+ matches,
19180
+ pattern: args.pattern,
19181
+ totalMatches
19182
+ };
19183
+ return {
19184
+ content: formatGrepResults({
19185
+ matches,
19186
+ totalMatches
19187
+ }),
19188
+ state,
19189
+ success: true
19190
+ };
19191
+ } catch (error) {
19192
+ return this.handleError(error);
19193
+ }
19194
+ }
19195
+ async globFiles(args) {
19196
+ try {
19197
+ const result = await this.callService("globLocalFiles", args);
19198
+ if (!result.success) return this.errorOutput(result, {
19199
+ files: [],
19200
+ pattern: args.pattern,
19201
+ totalCount: 0
19202
+ });
19203
+ const files = result.result?.files || [];
19204
+ const totalCount = result.result?.totalCount ?? result.result?.total_files ?? files.length;
19205
+ const state = {
19206
+ files,
19207
+ pattern: args.pattern,
19208
+ totalCount
19209
+ };
19210
+ return {
19211
+ content: formatGlobResults({
19212
+ files,
19213
+ totalFiles: totalCount
19214
+ }),
19215
+ state,
19216
+ success: true
19217
+ };
19218
+ } catch (error) {
19219
+ return this.handleError(error);
19220
+ }
19221
+ }
19222
+ handleError(error) {
19223
+ return {
19224
+ content: error instanceof Error ? error.message : String(error),
19225
+ error,
19226
+ success: false
19227
+ };
19228
+ }
19229
+ errorOutput(result, state) {
19230
+ return {
19231
+ content: result.error?.message || (result.error !== void 0 ? JSON.stringify(result.error) : void 0) || (typeof state?.stderr === "string" ? state.stderr : void 0) || (typeof state?.error === "string" ? state.error : void 0) || "[UNKNOWN_EXEC_ERROR] Tool execution failed",
19232
+ state,
19233
+ success: true
19234
+ };
19235
+ }
19236
+ };
19237
+
19238
+ //#endregion
19239
+ //#region ../../packages/tool-runtime/src/LocalSystemExecutionRuntime.ts
19240
+ /**
19241
+ * Maps IPC tool names to localFileService method names.
19242
+ * IPC service uses different method names than the standard tool names.
19243
+ */
19244
+ const SERVICE_METHOD_MAP = {
19245
+ editLocalFile: "editLocalFile",
19246
+ getCommandOutput: "getCommandOutput",
19247
+ globLocalFiles: "globFiles",
19248
+ grepContent: "grepContent",
19249
+ killCommand: "killCommand",
19250
+ listLocalFiles: "listLocalFiles",
19251
+ moveLocalFiles: "moveLocalFiles",
19252
+ readLocalFile: "readLocalFile",
19253
+ renameLocalFile: "renameLocalFile",
19254
+ runCommand: "runCommand",
19255
+ searchLocalFiles: "searchLocalFiles",
19256
+ writeLocalFile: "writeFile"
19257
+ };
19258
+ /**
19259
+ * Local System Execution Runtime
19260
+ *
19261
+ * Extends ComputerRuntime for standard computer operations via Electron IPC.
19262
+ * Normalizes snake_case IPC results (exit_code, shell_id, total_matches)
19263
+ * into the camelCase format expected by ComputerRuntime.
19264
+ */
19265
+ var LocalSystemExecutionRuntime = class extends ComputerRuntime {
19266
+ service;
19267
+ constructor(service) {
19268
+ super();
19269
+ this.service = service;
19270
+ }
19271
+ async callService(toolName, params) {
19272
+ const methodName = SERVICE_METHOD_MAP[toolName];
19273
+ if (!methodName) return {
19274
+ error: { message: `Unknown tool: ${toolName}` },
19275
+ result: null,
19276
+ success: false
19277
+ };
19278
+ const ipcParams = this.denormalizeParams(toolName, params);
19279
+ const method = this.service[methodName];
19280
+ const result = await method(ipcParams);
19281
+ return this.normalizeResult(toolName, result);
19282
+ }
19283
+ /**
19284
+ * Map ComputerRuntime normalized params back to IPC field names.
19285
+ */
19286
+ denormalizeParams(toolName, params) {
19287
+ switch (toolName) {
19288
+ case "editLocalFile": return {
19289
+ file_path: params.path,
19290
+ new_string: params.replace,
19291
+ old_string: params.search,
19292
+ replace_all: params.all
19293
+ };
19294
+ case "listLocalFiles": return {
19295
+ limit: params.limit,
19296
+ path: params.directoryPath,
19297
+ sortBy: params.sortBy,
19298
+ sortOrder: params.sortOrder
19299
+ };
19300
+ case "moveLocalFiles": return { items: params.operations?.map((op) => ({
19301
+ newPath: op.destination,
19302
+ oldPath: op.source
19303
+ })) };
19304
+ case "renameLocalFile": return {
19305
+ newName: params.newName,
19306
+ path: params.oldPath
19307
+ };
19308
+ case "getCommandOutput": return {
19309
+ filter: params.filter,
19310
+ shell_id: params.commandId,
19311
+ timeout: params.timeout
19312
+ };
19313
+ case "killCommand": return { shell_id: params.commandId };
19314
+ case "readLocalFile": {
19315
+ const loc = params.startLine !== void 0 || params.endLine !== void 0 ? [params.startLine ?? 0, params.endLine ?? 200] : void 0;
19316
+ return {
19317
+ fullContent: params.fullContent,
19318
+ loc,
19319
+ path: params.path
19320
+ };
19321
+ }
19322
+ case "globLocalFiles": return {
19323
+ pattern: params.pattern,
19324
+ scope: params.directory
19325
+ };
19326
+ default: return params;
19327
+ }
19328
+ }
19329
+ /**
19330
+ * Batch read multiple files — unique to local system.
19331
+ */
19332
+ async readFiles(params) {
19333
+ try {
19334
+ const { formatMultipleFiles } = await Promise.resolve().then(() => (init_fileSystem(), fileSystem_exports));
19335
+ const results = await this.service.readLocalFiles(params);
19336
+ return {
19337
+ content: formatMultipleFiles(results),
19338
+ state: { filesContent: results },
19339
+ success: true
19340
+ };
19341
+ } catch (error) {
19342
+ return this.handleError(error);
19343
+ }
19344
+ }
19345
+ /**
19346
+ * Normalize raw IPC results into the ServiceResult format.
19347
+ * IPC methods return domain objects directly; we wrap them appropriately.
19348
+ */
19349
+ normalizeResult(toolName, raw) {
19350
+ switch (toolName) {
19351
+ case "runCommand": return {
19352
+ result: {
19353
+ error: raw.error,
19354
+ exitCode: raw.exit_code,
19355
+ output: raw.output,
19356
+ commandId: raw.shell_id,
19357
+ stderr: raw.stderr,
19358
+ stdout: raw.stdout,
19359
+ success: raw.success
19360
+ },
19361
+ success: raw.success
19362
+ };
19363
+ case "getCommandOutput": return {
19364
+ result: {
19365
+ exitCode: raw.exit_code,
19366
+ error: raw.error,
19367
+ newOutput: raw.output,
19368
+ success: raw.success
19369
+ },
19370
+ success: raw.success
19371
+ };
19372
+ case "killCommand": return {
19373
+ result: {
19374
+ error: raw.error,
19375
+ success: raw.success
19376
+ },
19377
+ success: raw.success
19378
+ };
19379
+ case "grepContent": return {
19380
+ error: raw.error ? { message: String(raw.error) } : void 0,
19381
+ result: {
19382
+ matches: raw.matches,
19383
+ totalMatches: raw.total_matches
19384
+ },
19385
+ success: raw.success
19386
+ };
19387
+ case "globLocalFiles": return {
19388
+ error: raw.error ? { message: String(raw.error) } : void 0,
19389
+ result: {
19390
+ files: raw.files,
19391
+ totalCount: raw.total_files
19392
+ },
19393
+ success: raw.success
19394
+ };
19395
+ case "listLocalFiles": return {
19396
+ result: {
19397
+ files: raw.files,
19398
+ totalCount: raw.totalCount
19399
+ },
19400
+ success: true
19401
+ };
19402
+ case "readLocalFile": return {
19403
+ result: {
19404
+ charCount: raw.charCount,
19405
+ content: raw.content,
19406
+ fileType: raw.fileType,
19407
+ filename: raw.filename,
19408
+ loc: raw.loc,
19409
+ totalCharCount: raw.totalCharCount,
19410
+ totalLineCount: raw.totalLineCount
19411
+ },
19412
+ success: true
19413
+ };
19414
+ case "writeLocalFile": return {
19415
+ result: {
19416
+ bytesWritten: raw.bytesWritten,
19417
+ success: raw.success
19418
+ },
19419
+ success: raw.success ?? true
19420
+ };
19421
+ case "editLocalFile": return {
19422
+ result: {
19423
+ diffText: raw.diffText,
19424
+ error: raw.error,
19425
+ linesAdded: raw.linesAdded,
19426
+ linesDeleted: raw.linesDeleted,
19427
+ replacements: raw.replacements
19428
+ },
19429
+ success: raw.success
19430
+ };
19431
+ case "searchLocalFiles": {
19432
+ const results = Array.isArray(raw) ? raw : [];
19433
+ return {
19434
+ result: {
19435
+ results,
19436
+ totalCount: results.length
19437
+ },
19438
+ success: true
19439
+ };
19440
+ }
19441
+ case "moveLocalFiles": {
19442
+ const results = Array.isArray(raw) ? raw : [];
19443
+ return {
19444
+ result: {
19445
+ results,
19446
+ successCount: results.filter((r) => r.success).length
19447
+ },
19448
+ success: true
19449
+ };
19450
+ }
19451
+ case "renameLocalFile": return {
19452
+ result: {
19453
+ error: raw.error,
19454
+ newPath: raw.newPath,
19455
+ success: raw.success
19456
+ },
19457
+ success: raw.success
19458
+ };
19459
+ default: return {
19460
+ result: raw,
19461
+ success: true
19462
+ };
19463
+ }
19464
+ }
19465
+ };
19466
+
18257
19467
  //#endregion
18258
19468
  //#region node_modules/.pnpm/ms@2.1.3/node_modules/ms/index.js
18259
19469
  var require_ms = /* @__PURE__ */ __commonJSMin(((exports, module) => {
@@ -206440,375 +207650,6 @@ async function runCommand$1({ command, cwd, description, env: extraEnv, run_in_b
206440
207650
  }
206441
207651
  }
206442
207652
 
206443
- //#endregion
206444
- //#region src/tools/getAgentProfile.ts
206445
- const IDENTITY_FILES$1 = ["IDENTITY.md", "SOUL.md"];
206446
- /**
206447
- * Try to extract a description from the workspace identity file.
206448
- * Looks for Creature / Vibe / Description fields in IDENTITY.md or SOUL.md.
206449
- */
206450
- function readDescriptionFromWorkspace(workspacePath) {
206451
- for (const filename of IDENTITY_FILES$1) {
206452
- const filePath = path.join(workspacePath, filename);
206453
- if (!fs.existsSync(filePath)) continue;
206454
- const match = fs.readFileSync(filePath, "utf8").match(/\*{0,2}(?:Creature|Vibe|Description):?\*{0,2}\s*(.+)/i);
206455
- if (!match) continue;
206456
- const value = match[1].trim();
206457
- if (/^[_*((].*[))*_]$|^(?:tbd|todo|n\/?a|none|待定|未定)$/i.test(value)) continue;
206458
- return value;
206459
- }
206460
- }
206461
- function getOpenClawProfile(agentId) {
206462
- let output;
206463
- try {
206464
- output = execFileSync("openclaw", [
206465
- "agents",
206466
- "list",
206467
- "--json"
206468
- ], {
206469
- encoding: "utf8",
206470
- timeout: 5e3
206471
- });
206472
- } catch {
206473
- return {};
206474
- }
206475
- let agents;
206476
- try {
206477
- agents = JSON.parse(output);
206478
- } catch {
206479
- return {};
206480
- }
206481
- const agent = agentId ? agents.find((a) => a.id === agentId) : agents.find((a) => a.isDefault) ?? agents[0];
206482
- if (!agent) return {};
206483
- const title = agent.identityName || void 0;
206484
- return {
206485
- avatar: agent.identityEmoji || "🦞",
206486
- description: agent.workspace ? readDescriptionFromWorkspace(agent.workspace) : void 0,
206487
- title
206488
- };
206489
- }
206490
- /**
206491
- * Read the active Hermes profile name from `hermes profile list` output.
206492
- * The active profile is marked with ◆ in the first column.
206493
- */
206494
- function getActiveHermesProfileName() {
206495
- try {
206496
- return execFileSync("hermes", ["profile", "list"], {
206497
- encoding: "utf8",
206498
- timeout: 5e3
206499
- }).match(/◆(\S+)/)?.[1];
206500
- } catch {
206501
- return;
206502
- }
206503
- }
206504
- /**
206505
- * Read the filesystem path of a Hermes profile from `hermes profile show <name>`.
206506
- */
206507
- function getHermesProfilePath(profileName) {
206508
- try {
206509
- return (execFileSync("hermes", [
206510
- "profile",
206511
- "show",
206512
- profileName
206513
- ], {
206514
- encoding: "utf8",
206515
- timeout: 5e3
206516
- }).match(/^Path:\s+(.+)/m)?.[1]?.trim())?.replace(/^~(?=\/|$)/, os.homedir());
206517
- } catch {
206518
- return;
206519
- }
206520
- }
206521
- /**
206522
- * Extract a one-line description from a Hermes SOUL.md file.
206523
- * Strips HTML comments and Markdown headings, then returns the first
206524
- * non-empty line of actual content.
206525
- */
206526
- function readHermesSoulDescription(soulPath) {
206527
- try {
206528
- let stripped = fs.readFileSync(soulPath, "utf8");
206529
- let previous;
206530
- do {
206531
- previous = stripped;
206532
- stripped = stripped.replaceAll(/<!--[\s\S]*?-->/g, "").replaceAll(/[<>]/g, "").replaceAll(/^#+\s.*$/gm, "");
206533
- } while (stripped !== previous);
206534
- return stripped.split("\n").map((l) => l.trim()).find((l) => l.length > 0) || void 0;
206535
- } catch {
206536
- return;
206537
- }
206538
- }
206539
- function getHermesProfile() {
206540
- const profileName = getActiveHermesProfileName();
206541
- if (!profileName) return {};
206542
- const profilePath = getHermesProfilePath(profileName);
206543
- return {
206544
- avatar: "⚡",
206545
- description: profilePath ? readHermesSoulDescription(path.join(profilePath, "SOUL.md")) : void 0,
206546
- title: profileName
206547
- };
206548
- }
206549
- /**
206550
- * Fetch the agent profile (title, avatar, description) from the platform
206551
- * installed on this device. Dispatched by the server via `device.getAgentProfile`.
206552
- *
206553
- * - openclaw: `openclaw agents list --json` for name + emoji, workspace
206554
- * IDENTITY.md for description fallback
206555
- * - hermes: active profile name + SOUL.md description
206556
- */
206557
- async function getAgentProfile(params) {
206558
- const { platform, agentId } = params;
206559
- if (platform === "openclaw") return getOpenClawProfile(agentId);
206560
- if (platform === "hermes") return getHermesProfile();
206561
- return {};
206562
- }
206563
-
206564
- //#endregion
206565
- //#region src/daemon/taskRegistry.ts
206566
- function getRegistryPath() {
206567
- return path.join(os.homedir(), ".lobehub", "task-registry.json");
206568
- }
206569
- function readRegistry() {
206570
- try {
206571
- return JSON.parse(fs.readFileSync(getRegistryPath(), "utf8"));
206572
- } catch {
206573
- return {};
206574
- }
206575
- }
206576
- function writeRegistry(entries) {
206577
- const dir = path.dirname(getRegistryPath());
206578
- fs.mkdirSync(dir, {
206579
- mode: 448,
206580
- recursive: true
206581
- });
206582
- fs.writeFileSync(getRegistryPath(), JSON.stringify(entries, null, 2), { mode: 384 });
206583
- }
206584
- function saveTask(entry) {
206585
- const registry = readRegistry();
206586
- registry[entry.taskId] = entry;
206587
- writeRegistry(registry);
206588
- }
206589
- function getTask(taskId) {
206590
- return readRegistry()[taskId];
206591
- }
206592
- function removeTask(taskId) {
206593
- const registry = readRegistry();
206594
- delete registry[taskId];
206595
- writeRegistry(registry);
206596
- }
206597
- function listTasks() {
206598
- return Object.values(readRegistry());
206599
- }
206600
-
206601
- //#endregion
206602
- //#region src/tools/heteroTask.ts
206603
- const LOBEHUB_DIR_NAME = process.env.LOBEHUB_CLI_HOME || ".lobehub";
206604
- const HERMES_SESSIONS_FILE = path.join(os.homedir(), LOBEHUB_DIR_NAME, "hermes-sessions.json");
206605
- function getHermesSessionId(topicId) {
206606
- try {
206607
- return JSON.parse(fs.readFileSync(HERMES_SESSIONS_FILE, "utf8"))[topicId];
206608
- } catch {
206609
- return;
206610
- }
206611
- }
206612
- function saveHermesSessionId(topicId, sessionId) {
206613
- let data = {};
206614
- try {
206615
- data = JSON.parse(fs.readFileSync(HERMES_SESSIONS_FILE, "utf8"));
206616
- } catch {}
206617
- data[topicId] = sessionId;
206618
- fs.mkdirSync(path.dirname(HERMES_SESSIONS_FILE), { recursive: true });
206619
- fs.writeFileSync(HERMES_SESSIONS_FILE, JSON.stringify(data), "utf8");
206620
- }
206621
- /** Resolve the absolute path to the `lh` binary to avoid PATH issues in child processes. */
206622
- function resolveLhPath() {
206623
- try {
206624
- return execFileSync("which", ["lh"], { encoding: "utf8" }).trim();
206625
- } catch {
206626
- return "lh";
206627
- }
206628
- }
206629
- async function sendAutoNotify(topicId, taskId, text, agentId) {
206630
- try {
206631
- await (await getTrpcClient()).agentNotify.notify.mutate({
206632
- agentId,
206633
- content: text,
206634
- role: "assistant",
206635
- topicId
206636
- });
206637
- } catch (err) {
206638
- log$7.error("Failed to send auto-notify:", err instanceof Error ? err.message : String(err));
206639
- }
206640
- }
206641
- /**
206642
- * Signal remote hetero task completion to the server so it can publish
206643
- * `agent_runtime_end` to the gateway WS and close the frontend subscription.
206644
- * Called on clean process exit (code=0, no signal) — error exits go through
206645
- * `sendAutoNotify` which writes an error message AND triggers completion via
206646
- * the `done` flag.
206647
- */
206648
- async function sendDoneSignal(topicId, agentId) {
206649
- try {
206650
- await (await getTrpcClient()).agentNotify.notify.mutate({
206651
- agentId,
206652
- content: "",
206653
- done: true,
206654
- role: "assistant",
206655
- topicId
206656
- });
206657
- } catch (err) {
206658
- log$7.error("Failed to send done signal:", err instanceof Error ? err.message : String(err));
206659
- }
206660
- }
206661
- /**
206662
- * Build the notify protocol injected into the first message of a new hetero-agent session.
206663
- * Tells the agent how to push updates back to the LobeHub user via `lh notify`.
206664
- */
206665
- function buildNotifyProtocol(lhPath, topicId) {
206666
- return `## Context: This task was dispatched by LobeHub
206667
-
206668
- This conversation / task was sent to you by the **LobeHub platform** on behalf of a user. You are running as a background agent; the user is waiting for your response inside the LobeHub chat interface.
206669
-
206670
- **When to call notify**: any time you have something meaningful to tell the user — a key finding, a decision you made, a result, a question, or your final answer. Think of it as speaking directly to the user in the chat window.
206671
-
206672
- **What to hide**: internal work details such as tool call sequences, file reads, intermediate command output, retries, or low-level reasoning steps. The user cares about outcomes and insights, not your step-by-step mechanics.
206673
-
206674
- ## Sending messages back to the user
206675
-
206676
- Use the \`${lhPath} notify\` command. All your updates appear as a **single message bubble** in the UI — create it once and update it in place.\n\n**Step 1 — Open the bubble on your first meaningful update** (captures the messageId):\n\`\`\`\nMSG_ID=$(${lhPath} notify --topic ${topicId} --role assistant --content "Starting..." --json | grep -o '"messageId":"[^"]*"' | cut -d'"' -f4)\n\`\`\`\n\n**Step 2 — Update the same bubble as you make progress**:\n\`\`\`\n${lhPath} notify --topic ${topicId} --role assistant --message-id "$MSG_ID" --content "Still working..."\n\`\`\`\n\n**Step 3 — Replace with your complete, final response when done**:\n\`\`\`\n${lhPath} notify --topic ${topicId} --role assistant --message-id "$MSG_ID" --content "<your full response here>"\n\`\`\`\n\nRules:\n- Always use \`--json\` on the first call and capture \`messageId\` from the output.\n- Always pass \`--message-id\` on every subsequent call so updates overwrite the same bubble.\n- Write what matters to the user — not implementation steps or internal tool calls.\n- Call notify at least once when the task is done, even if there were no intermediate updates.`;
206677
- }
206678
- async function runHeteroTask(params) {
206679
- const { agentId, agentType, cwd, operationId, prompt, taskId, topicId } = params;
206680
- const workDir = cwd || process.cwd();
206681
- const lhPath = resolveLhPath();
206682
- if (agentType === "openclaw") {
206683
- const openclawAgent = process.env.OPENCLAW_AGENT_ID ?? "main";
206684
- const enrichedPrompt = `${prompt}\n\n${buildNotifyProtocol(lhPath, topicId)}`;
206685
- for (const existing of listTasks()) if (existing.topicId === topicId && existing.agentType === "openclaw") {
206686
- try {
206687
- process.kill(existing.pid, "SIGTERM");
206688
- } catch {}
206689
- removeTask(existing.taskId);
206690
- }
206691
- const child = spawn("openclaw", [
206692
- "agent",
206693
- "--agent",
206694
- openclawAgent,
206695
- "--session-id",
206696
- topicId,
206697
- "--message",
206698
- enrichedPrompt,
206699
- "--local"
206700
- ], {
206701
- cwd: workDir,
206702
- detached: true,
206703
- env: { ...process.env },
206704
- stdio: "ignore"
206705
- });
206706
- const pid = child.pid;
206707
- if (pid === void 0) throw new Error("Failed to get PID for openclaw process");
206708
- child.unref();
206709
- saveTask({
206710
- agentId,
206711
- agentType,
206712
- operationId,
206713
- pid,
206714
- startedAt: (/* @__PURE__ */ new Date()).toISOString(),
206715
- taskId,
206716
- topicId
206717
- });
206718
- log$7.info(`OpenClaw task started: taskId=${taskId} pid=${pid} agent=${openclawAgent}`);
206719
- child.on("close", (code, signal) => {
206720
- removeTask(taskId);
206721
- if (code !== 0 || signal !== null) sendAutoNotify(topicId, taskId, signal ? `Task cancelled (signal: ${signal})` : `Task failed (exit code: ${code})`, agentId).finally(() => sendDoneSignal(topicId, agentId));
206722
- else sendDoneSignal(topicId, agentId);
206723
- });
206724
- return JSON.stringify({
206725
- pid,
206726
- taskId
206727
- });
206728
- }
206729
- if (agentType === "hermes") {
206730
- for (const existing of listTasks()) if (existing.topicId === topicId && existing.agentType === "hermes") {
206731
- try {
206732
- process.kill(existing.pid, "SIGTERM");
206733
- } catch {}
206734
- removeTask(existing.taskId);
206735
- }
206736
- const existingSessionId = getHermesSessionId(topicId);
206737
- const hermesArgs = [
206738
- "chat",
206739
- "--query",
206740
- prompt,
206741
- "--quiet",
206742
- "--accept-hooks"
206743
- ];
206744
- if (existingSessionId) hermesArgs.push("--resume", existingSessionId);
206745
- const child = spawn("hermes", hermesArgs, {
206746
- cwd: workDir,
206747
- detached: true,
206748
- env: { ...process.env },
206749
- stdio: [
206750
- "ignore",
206751
- "pipe",
206752
- "ignore"
206753
- ]
206754
- });
206755
- const pid = child.pid;
206756
- if (pid === void 0) throw new Error("Failed to get PID for hermes process");
206757
- child.unref();
206758
- saveTask({
206759
- agentId,
206760
- agentType,
206761
- operationId,
206762
- pid,
206763
- startedAt: (/* @__PURE__ */ new Date()).toISOString(),
206764
- taskId,
206765
- topicId
206766
- });
206767
- log$7.info(`Hermes task started: taskId=${taskId} pid=${pid}`);
206768
- let stdout = "";
206769
- child.stdout.on("data", (chunk) => {
206770
- stdout += chunk.toString();
206771
- });
206772
- child.on("close", (code, signal) => {
206773
- removeTask(taskId);
206774
- if (code !== 0 || signal !== null) {
206775
- sendAutoNotify(topicId, taskId, signal ? `Task cancelled (signal: ${signal})` : `Task failed (exit code: ${code})`, agentId).finally(() => sendDoneSignal(topicId, agentId));
206776
- return;
206777
- }
206778
- const sessionId = stdout.match(/^session_id:\s*(\S+)/m)?.[1];
206779
- const response = stdout.replace(/^session_id:[^\n]*\n?/, "").trim();
206780
- if (sessionId) saveHermesSessionId(topicId, sessionId);
206781
- if (response) sendAutoNotify(topicId, taskId, response, agentId).finally(() => sendDoneSignal(topicId, agentId));
206782
- else sendDoneSignal(topicId, agentId);
206783
- });
206784
- return JSON.stringify({
206785
- pid,
206786
- taskId
206787
- });
206788
- }
206789
- throw new Error(`Unsupported agentType: ${agentType}`);
206790
- }
206791
- async function cancelHeteroTask(params) {
206792
- const { signal = "SIGINT", taskId } = params;
206793
- const entry = getTask(taskId);
206794
- if (!entry) return JSON.stringify({
206795
- message: `No task found with taskId: ${taskId}`,
206796
- success: false
206797
- });
206798
- try {
206799
- process.kill(entry.pid, signal);
206800
- } catch (err) {
206801
- log$7.warn(`Failed to send ${signal} to pid ${entry.pid}: ${err instanceof Error ? err.message : String(err)}`);
206802
- removeTask(taskId);
206803
- await sendAutoNotify(entry.topicId, taskId, "Task already completed or cancelled", entry.agentId);
206804
- }
206805
- return JSON.stringify({
206806
- pid: entry.pid,
206807
- signal,
206808
- taskId
206809
- });
206810
- }
206811
-
206812
207653
  //#endregion
206813
207654
  //#region src/tools/shell.ts
206814
207655
  const processManager = new ShellProcessManager();
@@ -206829,42 +207670,186 @@ async function killCommand(params) {
206829
207670
  }
206830
207671
 
206831
207672
  //#endregion
206832
- //#region src/tools/index.ts
206833
- const methodMap = {
206834
- cancelHeteroTask,
206835
- checkPlatformCapability,
206836
- getAgentProfile,
206837
- editFile: editLocalFile,
207673
+ //#region src/tools/localSystemRuntime.ts
207674
+ /**
207675
+ * Stub for `ILocalSystemService` methods the CLI does not expose (batch read,
207676
+ * move, rename). These are never routed by {@link runLocalSystemTool}; the
207677
+ * interface just requires them, so we fail loudly if one is ever reached.
207678
+ */
207679
+ const unsupported = (method) => () => Promise.reject(/* @__PURE__ */ new Error(`${method} is not supported by the LobeHub CLI`));
207680
+ const runtime = new LocalSystemExecutionRuntime({
207681
+ editLocalFile,
206838
207682
  getCommandOutput,
206839
207683
  globFiles: globLocalFiles,
206840
207684
  grepContent,
206841
207685
  killCommand,
206842
- listFiles: listLocalFiles,
206843
- readFile: readLocalFile,
206844
- runCommand,
206845
- runHeteroTask,
206846
- searchFiles: searchLocalFiles,
206847
- writeFile: writeLocalFile,
206848
- editLocalFile,
206849
- globLocalFiles,
206850
207686
  listLocalFiles,
207687
+ moveLocalFiles: unsupported("moveLocalFiles"),
206851
207688
  readLocalFile,
207689
+ readLocalFiles: unsupported("readLocalFiles"),
207690
+ renameLocalFile: unsupported("renameLocalFile"),
207691
+ runCommand,
206852
207692
  searchLocalFiles,
206853
- writeLocalFile
207693
+ writeFile: writeLocalFile
207694
+ });
207695
+ /**
207696
+ * Legacy API name aliases used by older gateway versions. Normalized to the
207697
+ * current tool names before dispatch.
207698
+ */
207699
+ const LEGACY_API_ALIASES = {
207700
+ editLocalFile: "editFile",
207701
+ globLocalFiles: "globFiles",
207702
+ listLocalFiles: "listFiles",
207703
+ readLocalFile: "readFile",
207704
+ searchLocalFiles: "searchFiles",
207705
+ writeLocalFile: "writeFile"
206854
207706
  };
206855
- async function executeToolCall(apiName, argsStr, timeout) {
206856
- const handler = methodMap[apiName];
206857
- if (!handler) return {
206858
- content: "",
206859
- error: `Unknown tool API: ${apiName}`,
206860
- success: false
207707
+ /**
207708
+ * Resolve a relative path against a scope (CWD). Mirrors the desktop gateway's
207709
+ * inline copy of the renderer-side `resolveArgsWithScope` helper so the CLI and
207710
+ * desktop produce identical scoping for search/grep tools.
207711
+ */
207712
+ const resolveArgsWithScope = (args, pathField) => {
207713
+ const scope = args.scope;
207714
+ const bag = args;
207715
+ const currentPath = typeof bag[pathField] === "string" ? bag[pathField] : void 0;
207716
+ if (!scope) return args;
207717
+ if (!currentPath) return {
207718
+ ...args,
207719
+ [pathField]: scope
206861
207720
  };
207721
+ if (path.isAbsolute(currentPath)) return args;
207722
+ return {
207723
+ ...args,
207724
+ [pathField]: path.join(scope, currentPath)
207725
+ };
207726
+ };
207727
+ /**
207728
+ * Route file/shell tool calls through `LocalSystemExecutionRuntime` so the
207729
+ * result carries structured `state` (for client renders) and `content` is the
207730
+ * formatted prompt text — matching the desktop gateway path (PR #15114).
207731
+ *
207732
+ * Returns `null` when `apiName` is not a local-system tool, so the caller can
207733
+ * fall back to CLI-only tools (platform agents).
207734
+ */
207735
+ async function runLocalSystemTool(apiName, args) {
207736
+ switch (LEGACY_API_ALIASES[apiName] ?? apiName) {
207737
+ case "listFiles": {
207738
+ const p = args;
207739
+ return runtime.listFiles({
207740
+ directoryPath: p.path,
207741
+ limit: p.limit,
207742
+ sortBy: p.sortBy,
207743
+ sortOrder: p.sortOrder
207744
+ });
207745
+ }
207746
+ case "readFile": {
207747
+ const p = args;
207748
+ return runtime.readFile({
207749
+ endLine: p.loc?.[1],
207750
+ path: p.path,
207751
+ startLine: p.loc?.[0]
207752
+ });
207753
+ }
207754
+ case "writeFile": return runtime.writeFile(args);
207755
+ case "editFile": {
207756
+ const p = args;
207757
+ return runtime.editFile({
207758
+ all: p.replace_all,
207759
+ path: p.file_path,
207760
+ replace: p.new_string,
207761
+ search: p.old_string
207762
+ });
207763
+ }
207764
+ case "searchFiles": {
207765
+ const resolved = resolveArgsWithScope(args, "directory");
207766
+ return runtime.searchFiles({
207767
+ ...resolved,
207768
+ directory: resolved.directory || ""
207769
+ });
207770
+ }
207771
+ case "grepContent": {
207772
+ const resolved = resolveArgsWithScope(args, "path");
207773
+ return runtime.grepContent(resolved);
207774
+ }
207775
+ case "globFiles": {
207776
+ const p = args;
207777
+ return runtime.globFiles({
207778
+ directory: p.scope ?? p.cwd,
207779
+ pattern: p.pattern
207780
+ });
207781
+ }
207782
+ case "runCommand": {
207783
+ const p = args;
207784
+ return runtime.runCommand({
207785
+ ...p,
207786
+ background: p.run_in_background
207787
+ });
207788
+ }
207789
+ case "getCommandOutput": {
207790
+ const p = args;
207791
+ return runtime.getCommandOutput({
207792
+ commandId: p.shell_id,
207793
+ filter: p.filter,
207794
+ timeout: p.timeout
207795
+ });
207796
+ }
207797
+ case "killCommand": {
207798
+ const p = args;
207799
+ return runtime.killCommand({ commandId: p.shell_id });
207800
+ }
207801
+ default: return null;
207802
+ }
207803
+ }
207804
+
207805
+ //#endregion
207806
+ //#region src/tools/index.ts
207807
+ /**
207808
+ * CLI-only tools (platform agents). File/shell tools are handled separately by
207809
+ * {@link runLocalSystemTool}, which routes them through
207810
+ * `LocalSystemExecutionRuntime` so the result carries structured `state`.
207811
+ */
207812
+ const methodMap = {
207813
+ cancelHeteroTask,
207814
+ checkPlatformCapability,
207815
+ getAgentProfile,
207816
+ runHeteroTask
207817
+ };
207818
+ async function executeToolCall(apiName, argsStr, timeout) {
207819
+ let args;
206862
207820
  try {
206863
- const args = JSON.parse(argsStr);
206864
- const result = await handler(typeof timeout === "number" && Number.isFinite(timeout) && !("timeout" in args) ? {
206865
- ...args,
206866
- timeout
206867
- } : args);
207821
+ args = JSON.parse(argsStr);
207822
+ } catch (error) {
207823
+ const errorMsg = error instanceof Error ? error.message : String(error);
207824
+ log$7.error(`Tool call failed: ${apiName} - ${errorMsg}`);
207825
+ return {
207826
+ content: "",
207827
+ error: errorMsg,
207828
+ success: false
207829
+ };
207830
+ }
207831
+ const finalArgs = typeof timeout === "number" && Number.isFinite(timeout) && !("timeout" in args) ? {
207832
+ ...args,
207833
+ timeout
207834
+ } : args;
207835
+ try {
207836
+ const localResult = await runLocalSystemTool(apiName, finalArgs);
207837
+ if (localResult) {
207838
+ const { error } = localResult;
207839
+ return {
207840
+ content: localResult.content,
207841
+ error: error instanceof Error ? error.message : typeof error === "string" ? error : void 0,
207842
+ state: localResult.state,
207843
+ success: localResult.success
207844
+ };
207845
+ }
207846
+ const handler = methodMap[apiName];
207847
+ if (!handler) return {
207848
+ content: "",
207849
+ error: `Unknown tool API: ${apiName}`,
207850
+ success: false
207851
+ };
207852
+ const result = await handler(finalArgs);
206868
207853
  return {
206869
207854
  content: typeof result === "string" ? result : JSON.stringify(result),
206870
207855
  success: true
@@ -207028,6 +208013,7 @@ async function runConnect(options, isDaemonChild) {
207028
208013
  result: {
207029
208014
  content: result.content,
207030
208015
  error: result.error,
208016
+ state: result.state,
207031
208017
  success: result.success
207032
208018
  }
207033
208019
  });