deepfish-ai 2.0.9 → 2.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -8403,10 +8403,10 @@ var require_lib = __commonJS({
8403
8403
  exports2.analyse = analyse;
8404
8404
  var detectFile = (filepath, opts = {}) => new Promise((resolve, reject) => {
8405
8405
  let fd;
8406
- const fs24 = (0, node_1.default)();
8406
+ const fs26 = (0, node_1.default)();
8407
8407
  const handler = (err, buffer) => {
8408
8408
  if (fd) {
8409
- fs24.closeSync(fd);
8409
+ fs26.closeSync(fd);
8410
8410
  }
8411
8411
  if (err) {
8412
8412
  reject(err);
@@ -8418,9 +8418,9 @@ var require_lib = __commonJS({
8418
8418
  };
8419
8419
  const sampleSize = (opts === null || opts === void 0 ? void 0 : opts.sampleSize) || 0;
8420
8420
  if (sampleSize > 0) {
8421
- fd = fs24.openSync(filepath, "r");
8421
+ fd = fs26.openSync(filepath, "r");
8422
8422
  let sample = Buffer.allocUnsafe(sampleSize);
8423
- fs24.read(fd, sample, 0, sampleSize, opts.offset, (err, bytesRead) => {
8423
+ fs26.read(fd, sample, 0, sampleSize, opts.offset, (err, bytesRead) => {
8424
8424
  if (err) {
8425
8425
  handler(err, null);
8426
8426
  } else {
@@ -8432,22 +8432,22 @@ var require_lib = __commonJS({
8432
8432
  });
8433
8433
  return;
8434
8434
  }
8435
- fs24.readFile(filepath, handler);
8435
+ fs26.readFile(filepath, handler);
8436
8436
  });
8437
8437
  exports2.detectFile = detectFile;
8438
8438
  var detectFileSync = (filepath, opts = {}) => {
8439
- const fs24 = (0, node_1.default)();
8439
+ const fs26 = (0, node_1.default)();
8440
8440
  if (opts && opts.sampleSize) {
8441
- const fd = fs24.openSync(filepath, "r");
8441
+ const fd = fs26.openSync(filepath, "r");
8442
8442
  let sample = Buffer.allocUnsafe(opts.sampleSize);
8443
- const bytesRead = fs24.readSync(fd, sample, 0, opts.sampleSize, opts.offset);
8443
+ const bytesRead = fs26.readSync(fd, sample, 0, opts.sampleSize, opts.offset);
8444
8444
  if (bytesRead < opts.sampleSize) {
8445
8445
  sample = sample.subarray(0, bytesRead);
8446
8446
  }
8447
- fs24.closeSync(fd);
8447
+ fs26.closeSync(fd);
8448
8448
  return (0, exports2.detect)(sample);
8449
8449
  }
8450
- return (0, exports2.detect)(fs24.readFileSync(filepath));
8450
+ return (0, exports2.detect)(fs26.readFileSync(filepath));
8451
8451
  };
8452
8452
  exports2.detectFileSync = detectFileSync;
8453
8453
  exports2.default = {
@@ -8631,6 +8631,79 @@ var ADD_MODEL_Config = {
8631
8631
  // src/cli/cli-utils/getGlobalPath.ts
8632
8632
  var import_path2 = __toESM(require("path"));
8633
8633
  var import_fs_extra = __toESM(require("fs-extra"));
8634
+
8635
+ // src/cli/cli-utils/node-root.ts
8636
+ var { execSync } = require("child_process");
8637
+ var path2 = require("path");
8638
+ var fs = require("fs");
8639
+ function safeExec(cmd) {
8640
+ try {
8641
+ return execSync(cmd, { encoding: "utf8", stdio: "pipe" }).trim();
8642
+ } catch (err) {
8643
+ return null;
8644
+ }
8645
+ }
8646
+ function resolveValidPath(targetPath) {
8647
+ if (!targetPath) return null;
8648
+ try {
8649
+ const realPath = fs.realpathSync(targetPath);
8650
+ return fs.existsSync(realPath) ? realPath : null;
8651
+ } catch (err) {
8652
+ return null;
8653
+ }
8654
+ }
8655
+ function getNvmGlobalPath() {
8656
+ const nvmDir = process.env["NVM_DIR"] || (process.platform === "win32" ? path2.join(process.env["USERPROFILE"], ".nvm") : path2.join(process.env["HOME"], ".nvm"));
8657
+ const nodeVersion = safeExec("nvm current");
8658
+ if (!nodeVersion || nodeVersion.includes("N/A")) return null;
8659
+ const nvmGlobalPath = path2.join(
8660
+ nvmDir,
8661
+ "versions",
8662
+ "node",
8663
+ nodeVersion,
8664
+ "lib",
8665
+ "node_modules"
8666
+ );
8667
+ return resolveValidPath(nvmGlobalPath);
8668
+ }
8669
+ function getNpmGlobalPath() {
8670
+ const npmPath = safeExec("npm root -g");
8671
+ return resolveValidPath(npmPath);
8672
+ }
8673
+ function getFallbackGlobalPath() {
8674
+ try {
8675
+ const nodeExecPath = process.execPath;
8676
+ let globalPrefix;
8677
+ if (process.platform === "win32") {
8678
+ globalPrefix = path2.dirname(path2.dirname(nodeExecPath));
8679
+ } else {
8680
+ globalPrefix = path2.dirname(path2.dirname(path2.dirname(nodeExecPath)));
8681
+ }
8682
+ const fallbackPath = path2.join(globalPrefix, "lib", "node_modules");
8683
+ return resolveValidPath(fallbackPath);
8684
+ } catch (err) {
8685
+ return null;
8686
+ }
8687
+ }
8688
+ function getGlobalNodeModulesPath() {
8689
+ const nvmPath = getNvmGlobalPath();
8690
+ if (nvmPath) {
8691
+ return nvmPath;
8692
+ }
8693
+ const npmPath = getNpmGlobalPath();
8694
+ if (npmPath) {
8695
+ return npmPath;
8696
+ }
8697
+ const fallbackPath = getFallbackGlobalPath();
8698
+ if (fallbackPath) {
8699
+ return fallbackPath;
8700
+ }
8701
+ console.error("\u65E0\u6CD5\u83B7\u53D6\u5168\u5C40 node_modules \u8DEF\u5F84");
8702
+ return null;
8703
+ }
8704
+ var node_root_default = getGlobalNodeModulesPath;
8705
+
8706
+ // src/cli/cli-utils/getGlobalPath.ts
8634
8707
  var getDirname = () => __dirname;
8635
8708
  function getHomePath() {
8636
8709
  return HOME_DIR;
@@ -8693,6 +8766,10 @@ function getScanDirPaths() {
8693
8766
  const paths = /* @__PURE__ */ new Set();
8694
8767
  paths.add(import_path2.default.join(workspacePath, ".deepfish-ai"));
8695
8768
  paths.add(import_path2.default.join(homePath));
8769
+ const nodeRoot = import_path2.default.join(node_root_default(), "@deepfish-ai");
8770
+ if (import_fs_extra.default.existsSync(nodeRoot)) {
8771
+ paths.add(nodeRoot);
8772
+ }
8696
8773
  return Array.from(paths);
8697
8774
  }
8698
8775
  function getMCPFilePath() {
@@ -8728,8 +8805,11 @@ function handleConfigView() {
8728
8805
  }
8729
8806
  const content = import_fs_extra2.default.readFileSync(configPath, "utf-8");
8730
8807
  const data = import_json5.default.parse(content);
8808
+ data.aiList?.forEach((item) => {
8809
+ item.apiKey = "******";
8810
+ });
8731
8811
  logInfo("Current config:");
8732
- console.log(JSON.stringify(data, null, 2));
8812
+ logInfo(JSON.stringify(data, null, 2));
8733
8813
  }
8734
8814
  function handleConfigReset() {
8735
8815
  const configPath = getConfigPath();
@@ -8966,18 +9046,8 @@ function initConfig() {
8966
9046
  if (!import_fs_extra4.default.pathExistsSync(skillsRegisterPath)) {
8967
9047
  import_fs_extra4.default.writeFileSync(skillsRegisterPath, "[]", "utf-8");
8968
9048
  }
8969
- const dynamicToolsDir = getToolsPath();
8970
- import_fs_extra4.default.ensureDirSync(dynamicToolsDir);
8971
- const dynamicToolsRegisterPath = import_path3.default.join(dynamicToolsDir, "register.json");
8972
- if (!import_fs_extra4.default.pathExistsSync(dynamicToolsRegisterPath)) {
8973
- import_fs_extra4.default.writeFileSync(dynamicToolsRegisterPath, "[]", "utf-8");
8974
- }
8975
9049
  const toolsDir = getToolsPath();
8976
9050
  import_fs_extra4.default.ensureDirSync(toolsDir);
8977
- const toolsRegisterPath = import_path3.default.join(toolsDir, "register.json");
8978
- if (!import_fs_extra4.default.pathExistsSync(toolsRegisterPath)) {
8979
- import_fs_extra4.default.writeFileSync(toolsRegisterPath, "[]", "utf-8");
8980
- }
8981
9051
  const sessionsDir = getSessionsPath();
8982
9052
  import_fs_extra4.default.ensureDirSync(sessionsDir);
8983
9053
  const sessionsIndexPath = import_path3.default.join(sessionsDir, "sessions.json");
@@ -10494,10 +10564,10 @@ function mergeDefs(...defs) {
10494
10564
  function cloneDef(schema) {
10495
10565
  return mergeDefs(schema._zod.def);
10496
10566
  }
10497
- function getElementAtPath(obj, path22) {
10498
- if (!path22)
10567
+ function getElementAtPath(obj, path24) {
10568
+ if (!path24)
10499
10569
  return obj;
10500
- return path22.reduce((acc, key) => acc?.[key], obj);
10570
+ return path24.reduce((acc, key) => acc?.[key], obj);
10501
10571
  }
10502
10572
  function promiseAllObject(promisesObj) {
10503
10573
  const keys = Object.keys(promisesObj);
@@ -10906,11 +10976,11 @@ function explicitlyAborted(x, startIndex = 0) {
10906
10976
  }
10907
10977
  return false;
10908
10978
  }
10909
- function prefixIssues(path22, issues) {
10979
+ function prefixIssues(path24, issues) {
10910
10980
  return issues.map((iss) => {
10911
10981
  var _a3;
10912
10982
  (_a3 = iss).path ?? (_a3.path = []);
10913
- iss.path.unshift(path22);
10983
+ iss.path.unshift(path24);
10914
10984
  return iss;
10915
10985
  });
10916
10986
  }
@@ -11057,16 +11127,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
11057
11127
  }
11058
11128
  function formatError(error51, mapper = (issue2) => issue2.message) {
11059
11129
  const fieldErrors = { _errors: [] };
11060
- const processError = (error52, path22 = []) => {
11130
+ const processError = (error52, path24 = []) => {
11061
11131
  for (const issue2 of error52.issues) {
11062
11132
  if (issue2.code === "invalid_union" && issue2.errors.length) {
11063
- issue2.errors.map((issues) => processError({ issues }, [...path22, ...issue2.path]));
11133
+ issue2.errors.map((issues) => processError({ issues }, [...path24, ...issue2.path]));
11064
11134
  } else if (issue2.code === "invalid_key") {
11065
- processError({ issues: issue2.issues }, [...path22, ...issue2.path]);
11135
+ processError({ issues: issue2.issues }, [...path24, ...issue2.path]);
11066
11136
  } else if (issue2.code === "invalid_element") {
11067
- processError({ issues: issue2.issues }, [...path22, ...issue2.path]);
11137
+ processError({ issues: issue2.issues }, [...path24, ...issue2.path]);
11068
11138
  } else {
11069
- const fullpath = [...path22, ...issue2.path];
11139
+ const fullpath = [...path24, ...issue2.path];
11070
11140
  if (fullpath.length === 0) {
11071
11141
  fieldErrors._errors.push(mapper(issue2));
11072
11142
  } else {
@@ -11093,17 +11163,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
11093
11163
  }
11094
11164
  function treeifyError(error51, mapper = (issue2) => issue2.message) {
11095
11165
  const result = { errors: [] };
11096
- const processError = (error52, path22 = []) => {
11166
+ const processError = (error52, path24 = []) => {
11097
11167
  var _a3, _b;
11098
11168
  for (const issue2 of error52.issues) {
11099
11169
  if (issue2.code === "invalid_union" && issue2.errors.length) {
11100
- issue2.errors.map((issues) => processError({ issues }, [...path22, ...issue2.path]));
11170
+ issue2.errors.map((issues) => processError({ issues }, [...path24, ...issue2.path]));
11101
11171
  } else if (issue2.code === "invalid_key") {
11102
- processError({ issues: issue2.issues }, [...path22, ...issue2.path]);
11172
+ processError({ issues: issue2.issues }, [...path24, ...issue2.path]);
11103
11173
  } else if (issue2.code === "invalid_element") {
11104
- processError({ issues: issue2.issues }, [...path22, ...issue2.path]);
11174
+ processError({ issues: issue2.issues }, [...path24, ...issue2.path]);
11105
11175
  } else {
11106
- const fullpath = [...path22, ...issue2.path];
11176
+ const fullpath = [...path24, ...issue2.path];
11107
11177
  if (fullpath.length === 0) {
11108
11178
  result.errors.push(mapper(issue2));
11109
11179
  continue;
@@ -11135,8 +11205,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
11135
11205
  }
11136
11206
  function toDotPath(_path) {
11137
11207
  const segs = [];
11138
- const path22 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
11139
- for (const seg of path22) {
11208
+ const path24 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
11209
+ for (const seg of path24) {
11140
11210
  if (typeof seg === "number")
11141
11211
  segs.push(`[${seg}]`);
11142
11212
  else if (typeof seg === "symbol")
@@ -23828,13 +23898,13 @@ function resolveRef(ref, ctx) {
23828
23898
  if (!ref.startsWith("#")) {
23829
23899
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
23830
23900
  }
23831
- const path22 = ref.slice(1).split("/").filter(Boolean);
23832
- if (path22.length === 0) {
23901
+ const path24 = ref.slice(1).split("/").filter(Boolean);
23902
+ if (path24.length === 0) {
23833
23903
  return ctx.rootSchema;
23834
23904
  }
23835
23905
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
23836
- if (path22[0] === defsKey) {
23837
- const key = path22[1];
23906
+ if (path24[0] === defsKey) {
23907
+ const key = path24[1];
23838
23908
  if (!key || !ctx.defs[key]) {
23839
23909
  throw new Error(`Reference not found: ${ref}`);
23840
23910
  }
@@ -24318,8 +24388,8 @@ var Thinking = class {
24318
24388
  };
24319
24389
 
24320
24390
  // src/agent/AIAgent/utils/skill-parser.ts
24321
- var fs5 = require("fs-extra");
24322
- var path4 = require("path");
24391
+ var fs6 = require("fs-extra");
24392
+ var path5 = require("path");
24323
24393
  var yaml = require_js_yaml();
24324
24394
  function extractFrontmatter(content, skillPath) {
24325
24395
  const normalizedContent = content.replace(/^\uFEFF/, "");
@@ -24330,14 +24400,14 @@ function extractFrontmatter(content, skillPath) {
24330
24400
  return frontmatterMatch[1];
24331
24401
  }
24332
24402
  function parseSkillMetadataYaml(skillPath) {
24333
- const content = fs5.readFileSync(skillPath, "utf-8");
24403
+ const content = fs6.readFileSync(skillPath, "utf-8");
24334
24404
  const frontmatterContent = extractFrontmatter(content, skillPath);
24335
24405
  const frontmatter = yaml.load(frontmatterContent);
24336
24406
  return {
24337
24407
  name: frontmatter.name,
24338
24408
  description: frontmatter.description,
24339
24409
  homepage: frontmatter.homepage,
24340
- location: path4.dirname(skillPath),
24410
+ location: path5.dirname(skillPath),
24341
24411
  metadata: frontmatter.metadata || {},
24342
24412
  skillFilePath: skillPath
24343
24413
  };
@@ -24400,11 +24470,12 @@ var getSystemPrompt = (params) => {
24400
24470
  const memoryPrompt = getUserMemoryPrompt(params.memoryFilePath);
24401
24471
  const agentRulesPrompt = getAgentRulesPrompt(params.agentRulesPath);
24402
24472
  return `
24403
- ${params.systemPrompt || `\u8FD9\u662FDeepfish Cli\u7CFB\u7EDF,\u4F60\u662F\u7CFB\u7EDF\u4E2D\u4E25\u683C\u6309\u89C4\u5219\u6267\u884C\u4EFB\u52A1\u7684\u667A\u80FD\u4F53,\u4E0D\u80FD\u8FDD\u53CD\u4EFB\u4F55\u7CFB\u7EDF\u9650\u5236\u3002
24473
+ ${params.systemPrompt + `
24474
+ \u8FD9\u662FDeepfish Cli\u7CFB\u7EDF,\u4F60\u662F\u7CFB\u7EDF\u4E2D\u4E25\u683C\u6309\u89C4\u5219\u6267\u884C\u4EFB\u52A1\u7684\u667A\u80FD\u4F53,\u4E0D\u80FD\u8FDD\u53CD\u4EFB\u4F55\u7CFB\u7EDF\u9650\u5236\u3002
24404
24475
  # \u6CE8\u610F\u6CE8\u610F\u4E8B\u9879:
24405
24476
  1.\u5982\u679C\u4EFB\u52A1\u6BD4\u8F83\u590D\u6742\uFF0C\u5E94\u8BE5\u5148\u8FDB\u884C\u62C6\u5206\uFF0C\u5206\u89E3\u6210\u591A\u4E2A\u6B65\u9AA4\uFF0C\u521B\u5EFA\u5B50\u667A\u80FD\u4F53\u6765\u9010\u6B65\u5B8C\u6210\u3002
24406
24477
  2.\u4E34\u65F6\u6587\u4EF6\u5FC5\u987B\u4F7F\u7528"tmp_"\u4F5C\u4E3A\u524D\u7F00\u547D\u540D\uFF0C\u5E76\u5728\u4EFB\u52A1\u7ED3\u675F\u540E\u5220\u9664\uFF0C\u4E0D\u80FD\u5728\u5DE5\u4F5C\u76EE\u5F55\u4E2D\u7559\u4E0B\u4EFB\u4F55\u4E34\u65F6\u6587\u4EF6\u3002
24407
- 3.\u5C3D\u91CF\u4F7F\u7528"execute_command"\u3001"execute_js_code"\u5DE5\u5177\u5B8C\u6210\u4EFB\u52A1
24478
+ 3.\u5C3D\u91CF\u4F7F\u7528"execute_command"\u3001"execute_js_code"\u5DE5\u5177\u7ED3\u5408Nodejs\u4EE3\u7801\u5B8C\u6210\u4EFB\u52A1
24408
24479
  4.\u786C\u6027\u89C4\u5219\uFF1A\u65E0\u8BBA\u6846\u67B6\u5185\u7F6E\u82F1\u6587\u6A21\u677F\uFF0C\u4F60\u7684\u6BCF\u4E00\u6B65\u601D\u8003\uFF08Thought\uFF09\u3001\u89C2\u5BDF\u5206\u6790\u3001\u7ED3\u8BBA\u56DE\u7B54\uFF0C**\u4E25\u683C\u4F7F\u7528\u7B80\u4F53\u4E2D\u6587**\uFF0C\u7981\u6B62\u82F1\u6587\u3002`}
24409
24480
 
24410
24481
  # \u57FA\u7840\u73AF\u5883\u4FE1\u606F
@@ -24416,21 +24487,24 @@ ${memoryPrompt}
24416
24487
  ${agentRulesPrompt}
24417
24488
  `;
24418
24489
  };
24419
- var subSystemPrompt = (workspace, osType, skills, excludeSkills) => {
24420
- let skillPrompt = getSkillPrompt(skills, excludeSkills);
24421
- return `
24490
+ var subSystemPrompt = (params) => {
24491
+ const skillPrompt = getSkillPrompt(params.skills, params.excludeSkills);
24492
+ const basePrompt = `
24422
24493
  \u8FD9\u662FDeepfish Cli\u7CFB\u7EDF,\u4F60\u662F\u7CFB\u7EDF\u4E2D\u4E25\u683C\u6309\u89C4\u5219\u6267\u884C\u4EFB\u52A1\u7684\u5B50\u667A\u80FD\u4F53,\u4E0D\u80FD\u8FDD\u53CD\u4EFB\u4F55\u7CFB\u7EDF\u9650\u5236\u3002
24423
24494
  ### \u57FA\u7840\u73AF\u5883\u4FE1\u606F
24424
- \u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\uFF1A${workspace}
24425
- \u64CD\u4F5C\u7CFB\u7EDF\u7C7B\u578B\uFF1A${osType}
24495
+ \u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\uFF1A${params.workspace}
24496
+ \u64CD\u4F5C\u7CFB\u7EDF\u7C7B\u578B\uFF1A${params.osType}
24426
24497
 
24427
24498
  \u6CE8\u610F:
24428
24499
  1.\u5B50\u667A\u80FD\u4F53\u53EA\u80FD\u5B8C\u6210\u5355\u4E2A\u4EFB\u52A1,\u4E0D\u80FD\u521B\u5EFA\u65B0\u7684\u5B50\u667A\u80FD\u4F53\u3002
24429
24500
  2.\u4E34\u65F6\u6587\u4EF6\u5FC5\u987B\u4F7F\u7528"tmp_"\u4F5C\u4E3A\u524D\u7F00\u547D\u540D\uFF0C\u5E76\u5728\u4EFB\u52A1\u7ED3\u675F\u540E\u5220\u9664\uFF0C\u4E0D\u80FD\u5728\u5DE5\u4F5C\u76EE\u5F55\u4E2D\u7559\u4E0B\u4EFB\u4F55\u4E34\u65F6\u6587\u4EF6\u3002
24430
- 3.\u5C3D\u91CF\u4F7F\u7528"execute_command"\u3001"execute_js_code"\u5DE5\u5177\u5B8C\u6210\u4EFB\u52A1
24501
+ 3.\u5C3D\u91CF\u4F7F\u7528"execute_command"\u3001"execute_js_code"\u5DE5\u5177\u7ED3\u5408Nodejs\u4EE3\u7801\u5B8C\u6210\u4EFB\u52A1
24431
24502
  4.\u786C\u6027\u89C4\u5219\uFF1A\u65E0\u8BBA\u6846\u67B6\u5185\u7F6E\u82F1\u6587\u6A21\u677F\uFF0C\u4F60\u7684\u6BCF\u4E00\u6B65\u601D\u8003\uFF08Thought\uFF09\u3001\u89C2\u5BDF\u5206\u6790\u3001\u7ED3\u8BBA\u56DE\u7B54\uFF0C**\u4E25\u683C\u4F7F\u7528\u7B80\u4F53\u4E2D\u6587**\uFF0C\u7981\u6B62\u82F1\u6587\u3002
24432
24503
 
24433
24504
  ${skillPrompt}
24505
+ `;
24506
+ return `
24507
+ ${params.systemPrompt + basePrompt}
24434
24508
  `;
24435
24509
  };
24436
24510
 
@@ -24667,9 +24741,8 @@ function toLangChainTool(func, description) {
24667
24741
  const wrappedFunc = async (args, runtime) => {
24668
24742
  try {
24669
24743
  const boundFunc = func.bind({
24670
- createSubAgent: async (prompt) => {
24671
- const subAgent = await runtime.context.curAgent.createSubAgent();
24672
- return subAgent.execute(prompt);
24744
+ createSubAgent: async (systemPrompt, prompt) => {
24745
+ return runtime.context.curAgent.subExecute(systemPrompt, prompt);
24673
24746
  },
24674
24747
  curAgent: runtime.context.curAgent
24675
24748
  });
@@ -24688,10 +24761,11 @@ function toLangChainTool(func, description) {
24688
24761
  schema
24689
24762
  });
24690
24763
  }
24691
- function scanUserTools(excludeTools) {
24692
- const files = _scanUserToolsFile();
24764
+ function scanUserTools(excludeTools, externalTools) {
24765
+ const files1 = _scanUserToolsFile();
24766
+ const files2 = _scanExternalToolsFile(externalTools);
24693
24767
  const tools = [];
24694
- files.forEach((toolFile) => {
24768
+ [...files1, ...files2].forEach((toolFile) => {
24695
24769
  _loadToolsFromFile(toolFile.filePath, tools, excludeTools);
24696
24770
  });
24697
24771
  return tools;
@@ -24722,53 +24796,75 @@ function getUserToolList() {
24722
24796
  });
24723
24797
  return toolOpts;
24724
24798
  }
24799
+ function _scanToolsFile(filePath) {
24800
+ let toolFile = null;
24801
+ if (import_fs_extra8.default.statSync(filePath).isDirectory()) {
24802
+ const subDirPath = import_path8.default.resolve(filePath);
24803
+ const subFiles = import_fs_extra8.default.readdirSync(subDirPath);
24804
+ const indexFile = subFiles.find((f) => f === "index.js" || f === "index.cjs");
24805
+ if (indexFile) {
24806
+ const filePath2 = _scanDeepFishJsFile(import_path8.default.resolve(subDirPath, indexFile));
24807
+ if (filePath2) {
24808
+ toolFile = {
24809
+ filePath: filePath2,
24810
+ dir: subDirPath
24811
+ };
24812
+ }
24813
+ } else {
24814
+ subFiles.forEach((subFile) => {
24815
+ const filePath2 = _scanDeepFishJsFile(import_path8.default.resolve(subDirPath, subFile));
24816
+ if (filePath2) {
24817
+ toolFile = {
24818
+ filePath: filePath2,
24819
+ dir: subDirPath
24820
+ };
24821
+ }
24822
+ });
24823
+ }
24824
+ } else {
24825
+ const toolfilePath = _scanDeepFishJsFile(filePath);
24826
+ if (toolfilePath) {
24827
+ toolFile = {
24828
+ filePath: toolfilePath,
24829
+ dir: null
24830
+ };
24831
+ }
24832
+ }
24833
+ return toolFile;
24834
+ }
24835
+ function _scanExternalToolsFile(externalTools) {
24836
+ const toolFiles = [];
24837
+ externalTools.forEach((filePath) => {
24838
+ const toolFile = _scanToolsFile(filePath);
24839
+ if (toolFile) {
24840
+ toolFiles.push(toolFile);
24841
+ }
24842
+ });
24843
+ return toolFiles;
24844
+ }
24725
24845
  function _scanUserToolsFile() {
24726
24846
  const toolFiles = [];
24727
24847
  const scanPaths = getScanDirPaths();
24728
24848
  scanPaths.forEach((scanPath) => {
24729
- const toolsDir = import_path8.default.resolve(scanPath, "tools");
24849
+ let toolsDir = scanPath;
24850
+ if (!scanPath.endsWith("@deepfish-ai")) {
24851
+ toolsDir = import_path8.default.resolve(scanPath, "tools");
24852
+ }
24730
24853
  if (import_fs_extra8.default.pathExistsSync(toolsDir)) {
24731
24854
  const files = import_fs_extra8.default.readdirSync(toolsDir);
24732
24855
  files.forEach((file2) => {
24733
- if (import_fs_extra8.default.statSync(import_path8.default.resolve(toolsDir, file2)).isDirectory()) {
24734
- const subDirPath = import_path8.default.resolve(toolsDir, file2);
24735
- const subFiles = import_fs_extra8.default.readdirSync(subDirPath);
24736
- const indexFile = subFiles.find((f) => f === "index.js" || f === "index.cjs");
24737
- if (indexFile) {
24738
- const filePath = _scanDeepFishJsFile(import_path8.default.resolve(subDirPath, indexFile), indexFile);
24739
- if (filePath) {
24740
- toolFiles.push({
24741
- filePath,
24742
- dir: subDirPath
24743
- });
24744
- }
24745
- } else {
24746
- subFiles.forEach((subFile) => {
24747
- const filePath = _scanDeepFishJsFile(import_path8.default.resolve(subDirPath, subFile), subFile);
24748
- if (filePath) {
24749
- toolFiles.push({
24750
- filePath,
24751
- dir: subDirPath
24752
- });
24753
- }
24754
- });
24755
- }
24756
- } else {
24757
- const filePath = _scanDeepFishJsFile(toolsDir, file2);
24758
- if (filePath) {
24759
- toolFiles.push({
24760
- filePath,
24761
- dir: null
24762
- });
24763
- }
24856
+ const filePath = import_path8.default.resolve(toolsDir, file2);
24857
+ const toolFile = _scanToolsFile(filePath);
24858
+ if (toolFile) {
24859
+ toolFiles.push(toolFile);
24764
24860
  }
24765
24861
  });
24766
24862
  }
24767
24863
  });
24768
24864
  return toolFiles;
24769
24865
  }
24770
- function _scanDeepFishJsFile(filePath, fileName) {
24771
- if (fileName.endsWith(".js") || fileName.endsWith(".cjs")) {
24866
+ function _scanDeepFishJsFile(filePath) {
24867
+ if (filePath.endsWith(".js") || filePath.endsWith(".cjs")) {
24772
24868
  const fileContent = import_fs_extra8.default.readFileSync(filePath, "utf-8");
24773
24869
  if (fileContent.includes("module.exports") && fileContent.includes("descriptions") && fileContent.includes("functions")) {
24774
24870
  return filePath;
@@ -24868,20 +24964,17 @@ var import_fs_extra9 = __toESM(require("fs-extra"));
24868
24964
 
24869
24965
  // src/agent/tools/subAgent.ts
24870
24966
  var import_langchain4 = require("langchain");
24871
- async function subAgentExec(prompt, runtime) {
24967
+ async function subAgentExec(systemPrompt, prompt, runtime) {
24872
24968
  const curAgent = runtime.context?.curAgent;
24873
- if (!curAgent || typeof curAgent.createSubAgent !== "function") {
24874
- throw new Error("\u5F53\u524D\u8FD0\u884C\u4E0A\u4E0B\u6587\u4E0D\u652F\u6301\u521B\u5EFA\u5B50 agent");
24875
- }
24876
- const subAgent = await curAgent.createSubAgent();
24877
- return subAgent.execute(prompt);
24969
+ return curAgent && curAgent.subExecute(systemPrompt, prompt);
24878
24970
  }
24879
24971
  var subAgentTool = (0, import_langchain4.tool)(
24880
- async ({ prompt }, runtime) => safeTool(() => subAgentExec(prompt, runtime)),
24972
+ async ({ systemPrompt, prompt }, runtime) => safeTool(() => subAgentExec(systemPrompt, prompt, runtime)),
24881
24973
  {
24882
24974
  name: "subAgent_exec",
24883
24975
  description: "\u521B\u5EFA\u4E00\u4E2A\u901A\u7528\u5B50 agent \u6765\u6267\u884C\u72EC\u7ACB\u4EFB\u52A1\uFF0C\u5E76\u8FD4\u56DE\u5B50 agent \u7684\u6267\u884C\u7ED3\u679C\u3002\u9002\u5408\u62C6\u5206\u590D\u6742\u4EFB\u52A1\u3001\u5E76\u884C\u8C03\u7814\u6216\u59D4\u6D3E\u5B50\u4EFB\u52A1\u3002",
24884
24976
  schema: external_exports.object({
24977
+ systemPrompt: external_exports.string().min(1).describe("\u5B50 agent \u7684\u7CFB\u7EDF\u63D0\u793A\u8BCD\uFF0C\u5B9A\u4E49\u5176\u89D2\u8272\u548C\u884C\u4E3A\u89C4\u8303"),
24885
24978
  prompt: external_exports.string().min(1).describe("\u4EA4\u7ED9\u901A\u7528\u5B50 agent \u6267\u884C\u7684\u5B8C\u6574\u4EFB\u52A1\u63CF\u8FF0")
24886
24979
  })
24887
24980
  }
@@ -24962,7 +25055,7 @@ var installPackageTool = (0, import_langchain5.tool)(
24962
25055
  );
24963
25056
  var executeJSCodeTool = (0, import_langchain5.tool)(async ({ code }, runtime) => safeTool(() => executeJSCode(code, runtime)), {
24964
25057
  name: "execute_js_code",
24965
- description: `\u6267\u884C\u4E00\u6BB5Node.js\u4EE3\u7801\u5E76\u8FD4\u56DE\u6267\u884C\u7ED3\u679C\u3002\u6CE8\u610F\uFF1A\u4EE3\u7801\u5FC5\u987B\u5305\u542B\u4E00\u4E2A__main()\u51FD\u6570\u4F5C\u4E3A\u6267\u884C\u5165\u53E3\uFF0C__main()\u51FD\u6570\u5185\u5FC5\u987B\u662F\u4E00\u4E2A\u4F7F\u7528async\u524D\u7F00\u7684\u51FD\u6570\u3002
25058
+ description: `\u6267\u884C\u4E00\u6BB5Node.js\u4EE3\u7801\u5E76\u8FD4\u56DE\u6267\u884C\u7ED3\u679C\u3002\u6CE8\u610F\uFF1A1.\u5982\u679C\u4EE3\u7801\u4E2D\u4F7F\u7528\u7B2C\u4E09\u65B9\u4F9D\u8D56\u5FC5\u987B\u5148\u4F7F\u7528check_package_installed\u5DE5\u5177\u68C0\u67E5\u5305\u662F\u5426\u5B89\u88C5\uFF0C\u5982\u679C\u672A\u5B89\u88C5\u9700\u8981\u6267\u884Cinstall_package\u5DE5\u5177\u5B89\u88C5\u6307\u5B9A\u7684npm\u5305;2.\u4EE3\u7801\u5FC5\u987B\u5305\u542B\u4E00\u4E2A__main()\u51FD\u6570\u4F5C\u4E3A\u6267\u884C\u5165\u53E3\uFF0C__main()\u51FD\u6570\u5185\u5FC5\u987B\u662F\u4E00\u4E2A\u4F7F\u7528async\u524D\u7F00\u7684\u51FD\u6570\u3002
24966
25059
  \u53EF\u7528\u5185\u7F6E\u51FD\u6570\uFF1A
24967
25060
  - agentExec(prompt: string): Promise<string>\uFF0C\u521B\u5EFA\u4E00\u4E2A\u901A\u7528\u5B50 agent \u6267\u884C\u6307\u5B9A\u4EFB\u52A1\u5E76\u8FD4\u56DE\u7ED3\u679C\uFF0C\u9002\u5408\u5C06\u590D\u6742\u4EFB\u52A1\u62C6\u5206\u7ED9\u5B50 agent \u5B8C\u6210\u3002
24968
25061
  \u793A\u4F8B\u4EE3\u7801\uFF1A
@@ -25658,7 +25751,10 @@ Commands:
25658
25751
  ai skills generate xxx \u6839\u636E\u63CF\u8FF0\u751F\u6210\u4E00\u4E2A\u65B0\u7684\u6280\u80FD\u6A21\u677F
25659
25752
 
25660
25753
  # Tools commands
25754
+ ai tools ls \u67E5\u770B\u5DF2\u5B89\u88C5\u6216\u5DF2\u914D\u7F6E\u7684\u5DE5\u5177\u5217\u8868
25661
25755
  ai tools dir \u6253\u5F00\u6216\u8F93\u51FA\u7528\u6237\u81EA\u5B9A\u4E49\u5DE5\u5177\u76EE\u5F55
25756
+ ai tools add <name> \u6DFB\u52A0\u6307\u5B9A\u540D\u79F0\u7684\u5DE5\u5177
25757
+ ai tools del <index> \u5220\u9664\u6307\u5B9A\u5E8F\u53F7\u7684\u81EA\u5B9A\u4E49\u5DE5\u5177
25662
25758
  ai tools generate xxx \u6839\u636E\u63CF\u8FF0\u751F\u6210\u4E00\u4E2A\u65B0\u7684\u5DE5\u5177\u6A21\u677F
25663
25759
 
25664
25760
  # Session commands
@@ -25670,9 +25766,15 @@ Commands:
25670
25766
  ai task add <task> \u5411\u4EFB\u52A1\u961F\u5217\u6DFB\u52A0\u4E00\u4E2A\u540E\u7EED\u4EFB\u52A1
25671
25767
  ai task del <index> \u5220\u9664\u6307\u5B9A\u5E8F\u53F7\u7684\u4EFB\u52A1
25672
25768
  ai task clear \u6E05\u7A7A\u5F53\u524D\u4EFB\u52A1\u961F\u5217
25769
+
25770
+ # Plan commands
25771
+ ai plan-do <\u4EFB\u52A1\u63CF\u8FF0> \u5C06\u590D\u6742\u4EFB\u52A1\u62C6\u89E3\u4E3A\u5B50\u4EFB\u52A1\u5E76\u9010\u6B65\u6267\u884C\u5B8C\u6210
25673
25772
 
25674
25773
  # MCP commands
25675
25774
  ai mcp edit \u6253\u5F00 MCP \u914D\u7F6E\u6587\u4EF6\u8FDB\u884C\u7F16\u8F91
25775
+ ai mcp ls \u67E5\u770B\u5DF2\u914D\u7F6E\u7684 MCP \u670D\u52A1\u5668\u5217\u8868
25776
+ ai mcp enable <name|index> \u542F\u7528\u6307\u5B9A\u540D\u79F0\u6216\u5E8F\u53F7\u7684 MCP \u670D\u52A1\u5668
25777
+ ai mcp disable <name|index> \u7981\u7528\u6307\u5B9A\u540D\u79F0\u6216\u5E8F\u53F7\u7684 MCP \u670D\u52A1\u5668
25676
25778
 
25677
25779
  # Serve commands
25678
25780
  ai serve \u542F\u52A8\u670D\u52A1\u6216\u8FDB\u5165\u670D\u52A1\u7BA1\u7406\u5165\u53E3
@@ -25760,14 +25862,14 @@ var builtinTools = [
25760
25862
  ...learnTools,
25761
25863
  ...fishInfoTools
25762
25864
  ];
25763
- async function getTools(excludeTools, excludeMCP) {
25764
- return [...builtinTools, ...await scanUserTools(excludeTools), ...await scanUserMcp(excludeMCP)];
25865
+ async function getTools(excludeTools, excludeMCP, externalTools = []) {
25866
+ return [...builtinTools, ...await scanUserTools(excludeTools, externalTools), ...await scanUserMcp(excludeMCP)];
25765
25867
  }
25766
25868
 
25767
25869
  // src/agent/skills/index.ts
25768
25870
  var import_path17 = __toESM(require("path"));
25769
25871
  function getSkills() {
25770
- return [...getRegisteredSkills(), import_path17.default.join(__dirname, "./view-learn-cache.md")];
25872
+ return [...getRegisteredSkills(), import_path17.default.join(__dirname, "./skills/view-learn-cache.md"), import_path17.default.join(__dirname, "./skills/generate-skill.md"), import_path17.default.join(__dirname, "./skills/generate-tool.md")];
25771
25873
  }
25772
25874
 
25773
25875
  // src/agent/AIAgent/index.ts
@@ -25824,8 +25926,8 @@ var SubAIAgent = class _SubAIAgent extends import_eventemitter_super.EventEmitte
25824
25926
  if (this.subLevel > 2) {
25825
25927
  this.excludeTools.push("subAgent_exec");
25826
25928
  }
25827
- this.tools = await getTools(this.excludeTools, this.excludeMCP);
25828
- this.skills = [...getSkills(), ...this.opt.skills || []];
25929
+ this.tools = await getTools(this.excludeTools, this.excludeMCP, this.opt.externalTools);
25930
+ this.skills = [...getSkills(), ...this.opt.externalSkills || []];
25829
25931
  const model = getModel(this.opt.modelOpt);
25830
25932
  const checkpointer = new FileSystemSaver({
25831
25933
  rootFolder: this.sessionDirPath
@@ -25846,7 +25948,13 @@ var SubAIAgent = class _SubAIAgent extends import_eventemitter_super.EventEmitte
25846
25948
  memoryFilePath: this.memoryFilePath,
25847
25949
  agentRulesPath: this.agentRulesPath,
25848
25950
  excludeSkills: this.excludeSkills
25849
- }) : subSystemPrompt(this.workspace, import_os3.default.platform(), this.skills, this.excludeSkills);
25951
+ }) : subSystemPrompt({
25952
+ systemPrompt: this.systemPrompt,
25953
+ workspace: this.workspace,
25954
+ osType: import_os3.default.platform(),
25955
+ skills: this.skills,
25956
+ excludeSkills: this.excludeSkills
25957
+ });
25850
25958
  const agent = (0, import_langchain18.createAgent)({
25851
25959
  model,
25852
25960
  checkpointer,
@@ -25859,14 +25967,6 @@ var SubAIAgent = class _SubAIAgent extends import_eventemitter_super.EventEmitte
25859
25967
  trigger: { tokens: this.opt.modelOpt.maxContextLength || 1e5 },
25860
25968
  keep: { messages: 50 }
25861
25969
  }),
25862
- (0, import_langchain18.humanInTheLoopMiddleware)({
25863
- interruptOn: {
25864
- install_package: {
25865
- allowedDecisions: ["approve", "reject"]
25866
- },
25867
- readEmailTool: false
25868
- }
25869
- }),
25870
25970
  (0, import_langchain18.todoListMiddleware)(),
25871
25971
  (0, import_deepagents.createPatchToolCallsMiddleware)()
25872
25972
  ],
@@ -25901,6 +26001,9 @@ var SubAIAgent = class _SubAIAgent extends import_eventemitter_super.EventEmitte
25901
26001
  resolve(msg);
25902
26002
  });
25903
26003
  for await (const [_namespace, mode, data] of stream) {
26004
+ if (Array.isArray(_namespace) && _namespace.length > 0) {
26005
+ continue;
26006
+ }
25904
26007
  if (mode === "messages") {
25905
26008
  const message = data[0].additional_kwargs.reasoning_content;
25906
26009
  this.emit("STREAM_CONTENT_OUTPUT" /* STREAM_CONTENT_OUTPUT */, message);
@@ -26016,8 +26119,8 @@ var AIAgent = class extends import_eventemitter_super2.EventEmitterSuper {
26016
26119
  this.maxSubAgentCount = opt.maxSubAgentCount || 2;
26017
26120
  }
26018
26121
  async init() {
26019
- this.tools = await getTools(this.excludeTools, this.excludeMCP);
26020
- this.skills = [...getSkills(), ...this.opt.skills || []];
26122
+ this.tools = await getTools(this.excludeTools, this.excludeMCP, this.opt.externalTools);
26123
+ this.skills = [...getSkills(), ...this.opt.externalSkills || []];
26021
26124
  const model = getModel(this.opt.modelOpt);
26022
26125
  const checkpointer = new FileSystemSaver({
26023
26126
  rootFolder: this.sessionDirPath
@@ -26042,14 +26145,6 @@ var AIAgent = class extends import_eventemitter_super2.EventEmitterSuper {
26042
26145
  trigger: { tokens: this.opt.modelOpt.maxContextLength || 1e5 },
26043
26146
  keep: { messages: 50 }
26044
26147
  }),
26045
- (0, import_langchain19.humanInTheLoopMiddleware)({
26046
- interruptOn: {
26047
- install_package: {
26048
- allowedDecisions: ["approve", "reject"]
26049
- },
26050
- readEmailTool: false
26051
- }
26052
- }),
26053
26148
  (0, import_langchain19.todoListMiddleware)(),
26054
26149
  (0, import_deepagents2.createPatchToolCallsMiddleware)()
26055
26150
  ],
@@ -26089,6 +26184,9 @@ var AIAgent = class extends import_eventemitter_super2.EventEmitterSuper {
26089
26184
  }
26090
26185
  );
26091
26186
  for await (const [_namespace, mode, data] of stream) {
26187
+ if (Array.isArray(_namespace) && _namespace.length > 0) {
26188
+ continue;
26189
+ }
26092
26190
  if (mode === "messages") {
26093
26191
  const message = data?.[0];
26094
26192
  const reasoning_content = message?.additional_kwargs?.reasoning_content;
@@ -26154,11 +26252,16 @@ var AIAgent = class extends import_eventemitter_super2.EventEmitterSuper {
26154
26252
  this.on("USE_TOOL_AFTER" /* USE_TOOL_AFTER */, (_toolId, _funcName, _funcArgs) => {
26155
26253
  });
26156
26254
  }
26157
- async createSubAgent() {
26255
+ async createSubAgent(systemPrompt) {
26158
26256
  const subAgent = new SubAIAgent(this.opt);
26257
+ systemPrompt && (subAgent.systemPrompt = systemPrompt);
26159
26258
  await subAgent.init();
26160
26259
  return subAgent;
26161
26260
  }
26261
+ async subExecute(systemPrompt, prompt) {
26262
+ const subAgent = await this.createSubAgent(systemPrompt);
26263
+ return subAgent.execute(prompt);
26264
+ }
26162
26265
  destory() {
26163
26266
  this.removeAllListeners();
26164
26267
  }
@@ -26411,7 +26514,7 @@ async function initAgent(config2, skills) {
26411
26514
  // CLI encoding format, can be set to utf-8, gbk, etc., or left empty for auto-detection
26412
26515
  maxSubAgentCount: config2.maxSubAgentCount,
26413
26516
  // Maximum parallel sub-agent execution count, -1 means unlimited
26414
- skills,
26517
+ externalSkills: skills,
26415
26518
  isPrintThinking: config2.isPrintThinking
26416
26519
  // Whether to print intermediate information during AI thinking, default is true
26417
26520
  });
@@ -26607,7 +26710,11 @@ function handleSkillsLs() {
26607
26710
  logInfo("No skills registered yet");
26608
26711
  } else {
26609
26712
  skills.forEach((skill, index) => {
26610
- logInfo(`[${index}] ${skill.name} (${skill.isEnabled ? "enabled" : "disabled"})`);
26713
+ if (skill.isEnabled) {
26714
+ logSuccess(`[${index}] ${skill.name} [\u221A]`);
26715
+ } else {
26716
+ logInfo(`[${index}] ${skill.name} [\xD7]`);
26717
+ }
26611
26718
  });
26612
26719
  }
26613
26720
  logInfo("=".repeat(50));
@@ -26670,7 +26777,7 @@ function handleSkillsDel(index) {
26670
26777
  const skill = skills[skillIndex];
26671
26778
  import_fs_extra20.default.removeSync(skill.skillPath);
26672
26779
  const skillDir = skill.skillDir;
26673
- const registerPath = import_path20.default.join(skillDir, "skills", "register.json");
26780
+ const registerPath = _getRegisterPath(skillDir);
26674
26781
  if (import_fs_extra20.default.existsSync(registerPath)) {
26675
26782
  let register = import_fs_extra20.default.readJSONSync(registerPath);
26676
26783
  register = register.filter((item) => item.skillPath !== skill.skillPath);
@@ -26688,7 +26795,7 @@ function handleSkillsEnable(index) {
26688
26795
  const skill = skills[skillIndex];
26689
26796
  skill.isEnabled = true;
26690
26797
  const skillDir = skill.skillDir;
26691
- const registerPath = import_path20.default.join(skillDir, "skills", "register.json");
26798
+ const registerPath = _getRegisterPath(skillDir);
26692
26799
  import_fs_extra20.default.writeJSONSync(
26693
26800
  registerPath,
26694
26801
  skills.filter((item) => item.skillDir === skillDir),
@@ -26706,7 +26813,7 @@ function handleSkillsDisable(index) {
26706
26813
  const skill = skills[skillIndex];
26707
26814
  skill.isEnabled = false;
26708
26815
  const skillDir = skill.skillDir;
26709
- const registerPath = import_path20.default.join(skillDir, "skills", "register.json");
26816
+ const registerPath = _getRegisterPath(skillDir);
26710
26817
  import_fs_extra20.default.writeJSONSync(
26711
26818
  registerPath,
26712
26819
  skills.filter((item) => item.skillDir === skillDir),
@@ -26741,7 +26848,7 @@ async function handleSkillsGenerate(target) {
26741
26848
  logError("Failed to start service, please check config or port availability");
26742
26849
  return;
26743
26850
  }
26744
- const generateSkillPath = import_path20.default.join(__dirname, "./generate-skill.md");
26851
+ const generateSkillPath = import_path20.default.join(__dirname, "./skills/generate-skill.md");
26745
26852
  const agent = await initAgent(config2, [generateSkillPath]);
26746
26853
  const prompt = `\u8BF7\u6839\u636E\u4EE5\u4E0B\u9700\u6C42\u751F\u6210\u4E00\u4E2ASkill\u6A21\u5757\uFF1A${target}
26747
26854
 
@@ -26774,12 +26881,14 @@ function _scanSkills(skillsDir) {
26774
26881
  return skills;
26775
26882
  }
26776
26883
  function _updateRegister(skillsDir) {
26777
- const registerPath = import_path20.default.resolve(skillsDir, "register.json");
26778
- if (import_fs_extra20.default.existsSync(skillsDir) && !import_fs_extra20.default.existsSync(registerPath)) {
26779
- import_fs_extra20.default.writeJSONSync(registerPath, [], { spaces: 2 });
26780
- } else if (!import_fs_extra20.default.existsSync(skillsDir)) {
26884
+ const registerPath = _getRegisterPath(skillsDir);
26885
+ if (!import_fs_extra20.default.existsSync(skillsDir)) {
26781
26886
  return;
26782
26887
  }
26888
+ if (!import_fs_extra20.default.existsSync(registerPath)) {
26889
+ import_fs_extra20.default.ensureDirSync(import_path20.default.dirname(registerPath));
26890
+ import_fs_extra20.default.writeJSONSync(registerPath, [], { spaces: 2 });
26891
+ }
26783
26892
  const skills = _scanSkills(skillsDir);
26784
26893
  let register = import_fs_extra20.default.readJSONSync(registerPath);
26785
26894
  const newRegister = [];
@@ -26804,7 +26913,7 @@ function getRegisteredSkills() {
26804
26913
  const skills = [];
26805
26914
  scanPaths.forEach((scanPath) => {
26806
26915
  _updateRegister(scanPath);
26807
- const registerPath = import_path20.default.join(scanPath, "skills", "register.json");
26916
+ const registerPath = _getRegisterPath(scanPath);
26808
26917
  if (import_fs_extra20.default.existsSync(registerPath)) {
26809
26918
  const register = import_fs_extra20.default.readJSONSync(registerPath);
26810
26919
  register.forEach((item) => {
@@ -26818,7 +26927,7 @@ function getRegisteredSkills() {
26818
26927
  }
26819
26928
  function _getSkillList(skillsDir) {
26820
26929
  let allSkills = [];
26821
- const registerPath = import_path20.default.join(skillsDir, "skills", "register.json");
26930
+ const registerPath = _getRegisterPath(skillsDir);
26822
26931
  if (import_fs_extra20.default.existsSync(registerPath)) {
26823
26932
  _updateRegister(skillsDir);
26824
26933
  const register = import_fs_extra20.default.readJSONSync(registerPath);
@@ -26839,6 +26948,14 @@ function _getAllSkills() {
26839
26948
  });
26840
26949
  return allSkills;
26841
26950
  }
26951
+ function _getRegisterPath(skillsDir) {
26952
+ const normalizedDir = import_path20.default.normalize(skillsDir);
26953
+ const baseName = import_path20.default.basename(normalizedDir).toLowerCase();
26954
+ if (baseName === "@deepfish-ai" || baseName === "skills") {
26955
+ return import_path20.default.join(normalizedDir, "register.json");
26956
+ }
26957
+ return import_path20.default.join(normalizedDir, "skills", "register.json");
26958
+ }
26842
26959
 
26843
26960
  // src/cli/cli-skills.ts
26844
26961
  function registerSkillsCommands(program) {
@@ -26955,7 +27072,7 @@ async function handleToolsGenerate(target) {
26955
27072
  logError("Failed to start service, please check config or port availability");
26956
27073
  return;
26957
27074
  }
26958
- const generateSkillPath = import_path21.default.join(__dirname, "./generate-tool.md");
27075
+ const generateSkillPath = import_path21.default.join(__dirname, "./skills/generate-tool.md");
26959
27076
  const agent = await initAgent(config2, [generateSkillPath]);
26960
27077
  const prompt = `Please use the "generate-tool" SKILL to generate a tool module according to the following requirements: ${target}
26961
27078
 
@@ -27091,21 +27208,92 @@ function registerTaskCommands(program) {
27091
27208
  }
27092
27209
 
27093
27210
  // src/cli/cli-core/mcp.ts
27211
+ var import_fs_extra22 = __toESM(require("fs-extra"));
27094
27212
  function handleMcpEdit() {
27095
27213
  const mcpPath = getMCPFilePath();
27096
27214
  editFile(mcpPath);
27097
27215
  }
27216
+ function readMcpConfig() {
27217
+ const mcpPath = getMCPFilePath();
27218
+ return import_fs_extra22.default.readJSONSync(mcpPath);
27219
+ }
27220
+ function writeMcpConfig(data) {
27221
+ const mcpPath = getMCPFilePath();
27222
+ import_fs_extra22.default.writeJSONSync(mcpPath, data, { spaces: 2 });
27223
+ }
27224
+ function handleMcpLs() {
27225
+ const config2 = readMcpConfig();
27226
+ const servers = config2.mcpServers || {};
27227
+ const entries = Object.entries(servers);
27228
+ if (entries.length === 0) {
27229
+ logWarning("No MCP servers configured yet");
27230
+ return;
27231
+ }
27232
+ logInfo("=".repeat(50));
27233
+ entries.forEach(([name, server], index) => {
27234
+ const disabled = server.disabled === true;
27235
+ if (disabled) {
27236
+ logInfo(`[${index}] ${name} [\xD7]`);
27237
+ } else {
27238
+ logSuccess(`[${index}] ${name} [\u221A]`);
27239
+ }
27240
+ });
27241
+ logInfo("=".repeat(50));
27242
+ }
27243
+ function handleMcpEnable(nameOrIndex) {
27244
+ const config2 = readMcpConfig();
27245
+ const servers = config2.mcpServers || {};
27246
+ const entries = Object.keys(servers);
27247
+ let targetIndex = -1;
27248
+ const index = parseInt(nameOrIndex, 10);
27249
+ if (!isNaN(index) && index >= 0 && index < entries.length) {
27250
+ targetIndex = index;
27251
+ } else {
27252
+ targetIndex = entries.findIndex((name) => name === nameOrIndex);
27253
+ }
27254
+ if (targetIndex === -1) {
27255
+ logError(`MCP server not found: ${nameOrIndex}`);
27256
+ return;
27257
+ }
27258
+ const serverName = entries[targetIndex];
27259
+ servers[serverName].disabled = false;
27260
+ writeMcpConfig(config2);
27261
+ logSuccess(`MCP server "${serverName}" enabled`);
27262
+ }
27263
+ function handleMcpDisable(nameOrIndex) {
27264
+ const config2 = readMcpConfig();
27265
+ const servers = config2.mcpServers || {};
27266
+ const entries = Object.keys(servers);
27267
+ let targetIndex = -1;
27268
+ const index = parseInt(nameOrIndex, 10);
27269
+ if (!isNaN(index) && index >= 0 && index < entries.length) {
27270
+ targetIndex = index;
27271
+ } else {
27272
+ targetIndex = entries.findIndex((name) => name === nameOrIndex);
27273
+ }
27274
+ if (targetIndex === -1) {
27275
+ logError(`MCP server not found: ${nameOrIndex}`);
27276
+ return;
27277
+ }
27278
+ const serverName = entries[targetIndex];
27279
+ servers[serverName].disabled = true;
27280
+ writeMcpConfig(config2);
27281
+ logSuccess(`MCP server "${serverName}" disabled`);
27282
+ }
27098
27283
 
27099
27284
  // src/cli/cli-mcp.ts
27100
27285
  function registerMcpCommands(program) {
27101
27286
  const mcp = program.command("mcp");
27102
27287
  mcp.command("edit").description("\u7F16\u8F91 MCP \u914D\u7F6E\u6587\u4EF6").action(handleMcpEdit);
27288
+ mcp.command("ls").description("\u5217\u51FA\u6240\u6709 MCP \u670D\u52A1\u5668").action(handleMcpLs);
27289
+ mcp.command("enable <nameOrIndex>").description("\u542F\u7528 MCP \u670D\u52A1\u5668").action(handleMcpEnable);
27290
+ mcp.command("disable <nameOrIndex>").description("\u7981\u7528 MCP \u670D\u52A1\u5668").action(handleMcpDisable);
27103
27291
  }
27104
27292
 
27105
27293
  // src/cli/cli-core/input.ts
27106
- var import_fs_extra22 = __toESM(require("fs-extra"));
27294
+ var import_fs_extra23 = __toESM(require("fs-extra"));
27107
27295
  var readline = __toESM(require("readline"));
27108
- async function handleInput(args) {
27296
+ async function handleInput(args, skills) {
27109
27297
  const input = args.join(" ");
27110
27298
  if (!input.trim()) {
27111
27299
  logError("Please enter content");
@@ -27113,7 +27301,7 @@ async function handleInput(args) {
27113
27301
  }
27114
27302
  try {
27115
27303
  const configPath = getConfigPath();
27116
- if (!import_fs_extra22.default.pathExistsSync(configPath)) {
27304
+ if (!import_fs_extra23.default.pathExistsSync(configPath)) {
27117
27305
  logError("Config file not found, please run init first");
27118
27306
  return;
27119
27307
  }
@@ -27128,7 +27316,7 @@ async function handleInput(args) {
27128
27316
  logError("Failed to start service, please check config or port availability");
27129
27317
  return;
27130
27318
  }
27131
- const agent = await initAgent(config2);
27319
+ const agent = await initAgent(config2, skills);
27132
27320
  const connResult = await connectAgentRoom(agent);
27133
27321
  if (!connResult.ok) {
27134
27322
  if (connResult.reason === "duplicate-id") {
@@ -27150,7 +27338,7 @@ async function handleInput(args) {
27150
27338
  async function multiInput() {
27151
27339
  try {
27152
27340
  const configPath = getConfigPath();
27153
- if (!import_fs_extra22.default.pathExistsSync(configPath)) {
27341
+ if (!import_fs_extra23.default.pathExistsSync(configPath)) {
27154
27342
  logError("Config file not found, please run init first");
27155
27343
  return;
27156
27344
  }
@@ -27207,6 +27395,24 @@ async function multiInput() {
27207
27395
  }
27208
27396
  }
27209
27397
 
27398
+ // src/cli/cli-core/plan.ts
27399
+ var import_path22 = __toESM(require("path"));
27400
+ async function handlePlan(args) {
27401
+ const input = args.join(" ");
27402
+ if (!input.trim()) {
27403
+ logError("Please enter content");
27404
+ return;
27405
+ }
27406
+ const skillPrompt = `\u4F7F\u7528SKILL-"planning-do"\u5C06\u7528\u6237\u4EFB\u52A1\u5206\u89E3\u5E76\u5B8C\u6210\uFF0C\u4EE5\u4E0B\u662F\u7528\u6237\u76EE\u6807\uFF1A${input}`;
27407
+ const skillPath = import_path22.default.join(__dirname, "./skills/planning-do.md");
27408
+ await handleInput([skillPrompt], [skillPath]);
27409
+ }
27410
+
27411
+ // src/cli/cli-plan.ts
27412
+ function registerPlanCommands(program) {
27413
+ program.command("plan-do").description("\u5C06\u590D\u6742\u4EFB\u52A1\u62C6\u89E3\u4E3A\u5B50\u4EFB\u52A1\u5E76\u9010\u6B65\u6267\u884C\u5B8C\u6210").argument("[input...]", "\u4EFB\u52A1\u63CF\u8FF0").action((input) => handlePlan(input));
27414
+ }
27415
+
27210
27416
  // src/cli/cli-input.ts
27211
27417
  function registerInputCommand(program) {
27212
27418
  program.argument("[inputs...]", "Natural language instruction or enter interactive mode").action(async (inputs) => {
@@ -27220,7 +27426,7 @@ function registerInputCommand(program) {
27220
27426
  }
27221
27427
 
27222
27428
  // src/cli/cli-core/cache.ts
27223
- var import_path22 = __toESM(require("path"));
27429
+ var import_path23 = __toESM(require("path"));
27224
27430
  var userCache2 = new UserCache();
27225
27431
  function resolveId(input) {
27226
27432
  const index = Number(input);
@@ -27254,7 +27460,7 @@ function handleCacheList() {
27254
27460
  function handleCacheEdit(input) {
27255
27461
  const id = resolveId(input);
27256
27462
  if (!id) return;
27257
- const filePath = import_path22.default.join(getUserStorePath(), `${id}.md`);
27463
+ const filePath = import_path23.default.join(getUserStorePath(), `${id}.md`);
27258
27464
  editFile(filePath);
27259
27465
  }
27260
27466
  function handleCacheDel(input) {
@@ -27299,6 +27505,7 @@ function main() {
27299
27505
  registerTaskCommands(program);
27300
27506
  registerCommonFlags(program);
27301
27507
  registerMcpCommands(program);
27508
+ registerPlanCommands(program);
27302
27509
  registerCacheCommands(program);
27303
27510
  registerHelpCommand(program);
27304
27511
  registerInputCommand(program);