@fastgpt-plugin/cli 0.2.0 → 0.2.2-alpha.1

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/README.en.md CHANGED
@@ -4,6 +4,36 @@ Language: [简体中文](./README.md) | [English](./README.en.md)
4
4
 
5
5
  Command-line tool for FastGPT plugin development. It is used to create, build, test, debug, and package FastGPT tools and tool suites.
6
6
 
7
+ ### Quick Start
8
+
9
+ ```bash
10
+ npx @fastgpt-plugin/cli create dx-hello --type tool --description "DX hello world"
11
+ cd dx-hello
12
+ pnpm install
13
+ pnpm run dev
14
+ pnpm run debug
15
+ pnpm run debug:run
16
+ pnpm run build
17
+ pnpm run check
18
+ pnpm run pack
19
+ ```
20
+
21
+ `pnpm run dev` calls `fastgpt-plugin dev . --watch` for remote FastGPT
22
+ integration debugging.
23
+
24
+ Use `--dependency-mode catalog` only inside a pnpm workspace that defines the
25
+ matching catalog entries:
26
+
27
+ ```bash
28
+ npx @fastgpt-plugin/cli create dx-hello --type tool --dependency-mode catalog
29
+ ```
30
+
31
+ Use `--verbose` on any command when you need a full stack trace:
32
+
33
+ ```bash
34
+ npx @fastgpt-plugin/cli --verbose check --entry . --output ./dist
35
+ ```
36
+
7
37
  ### Features
8
38
 
9
39
  - **Unified build flow**
package/README.md CHANGED
@@ -4,6 +4,34 @@
4
4
 
5
5
  FastGPT 插件开发的命令行工具,用于创建、构建和测试 FastGPT 工具 / 工具集。
6
6
 
7
+ ### 快速开始
8
+
9
+ ```bash
10
+ npx @fastgpt-plugin/cli create dx-hello --type tool --description "DX hello world"
11
+ cd dx-hello
12
+ pnpm install
13
+ pnpm run dev
14
+ pnpm run debug
15
+ pnpm run debug:run
16
+ pnpm run build
17
+ pnpm run check
18
+ pnpm run pack
19
+ ```
20
+
21
+ `pnpm run dev` 会调用 `fastgpt-plugin dev . --watch`,用于 FastGPT 远程集成调试。
22
+
23
+ 仅在定义了对应 catalog entry 的 pnpm workspace 中使用 `--dependency-mode catalog`:
24
+
25
+ ```bash
26
+ npx @fastgpt-plugin/cli create dx-hello --type tool --dependency-mode catalog
27
+ ```
28
+
29
+ 需要完整 stack trace 时,在命令中加 `--verbose`:
30
+
31
+ ```bash
32
+ npx @fastgpt-plugin/cli --verbose check --entry . --output ./dist
33
+ ```
34
+
7
35
  ### Features
8
36
 
9
37
  - **统一构建流程**
package/dist/index.js CHANGED
@@ -21,6 +21,14 @@ import { Command } from "commander";
21
21
 
22
22
  //#region src/helpers.ts
23
23
  const logger = consola;
24
+ function shouldShowVerboseError(explicit) {
25
+ return explicit === true || process.argv.includes("--verbose") || process.env.FASTGPT_PLUGIN_CLI_VERBOSE === "1";
26
+ }
27
+ function formatCliError(error, verbose) {
28
+ if (shouldShowVerboseError(verbose)) return error instanceof Error ? error : new Error(String(error));
29
+ if (error instanceof Error) return error.message || error.name;
30
+ return String(error);
31
+ }
24
32
 
25
33
  //#endregion
26
34
  //#region ../../packages/domain/src/value-objects/i18n-string.vo.ts
@@ -405,18 +413,23 @@ function formatDuration(ms) {
405
413
  * - 统一命令接口类型
406
414
  * - 强制实现 register 方法,用于向 Commander 注册自身
407
415
  */
408
- var BaseCommand = class {};
416
+ var BaseCommand = class {
417
+ addCommonOptions(command) {
418
+ return command.option("--verbose", "显示完整错误堆栈 / Show full error stack");
419
+ }
420
+ };
409
421
 
410
422
  //#endregion
411
423
  //#region src/commands/build.ts
412
424
  var BuildCommand = class extends BaseCommand {
413
425
  register(parent) {
414
- parent.command("build").description("构建 FastGPT 插件为可分发的包").option("-e, --entry <path>", "工具入口目录", process.cwd()).option("-o, --output <path>", "输出目录", "./dist").option("-m, --minify", "压缩输出代码", false).option("-f, --format <format>", "输出格式: esm | cjs", "esm").action(async (opts) => {
426
+ this.addCommonOptions(parent.command("build").description("Build a distributable FastGPT plugin / 构建 FastGPT 插件").option("-e, --entry <path>", "插件源码目录 / Plugin source directory", process.cwd()).option("-o, --output <path>", "输出目录 / Output directory", "./dist").option("-m, --minify", "压缩输出代码 / Minify output", false).option("-f, --format <format>", "输出格式 / Output format: esm | cjs", "esm")).action(async (opts) => {
415
427
  await this.run({
416
428
  entry: opts.entry,
417
429
  output: opts.output,
418
430
  minify: opts.minify,
419
- format: opts.format
431
+ format: opts.format,
432
+ verbose: opts.verbose
420
433
  });
421
434
  });
422
435
  }
@@ -435,7 +448,7 @@ var BuildCommand = class extends BaseCommand {
435
448
  } else logger.info("未检测到输出文件,请检查配置。");
436
449
  } catch (error) {
437
450
  logger.error("构建失败,详情如下:");
438
- logger.error(error instanceof Error ? error : new Error(String(error)));
451
+ logger.error(formatCliError(error, options.verbose));
439
452
  logger.info("如果这是在 CI 中发生的,请查看上方构建日志以获取更多信息。");
440
453
  process.exit(1);
441
454
  }
@@ -451,9 +464,35 @@ var BuildCommand = class extends BaseCommand {
451
464
  * - manifest.json 引用的 logo 文件存在
452
465
  */
453
466
  async function checkBuildOutput(options) {
454
- const outputDir = path.resolve(options.output);
467
+ const entryDir = path.resolve(options.entry);
468
+ const outputDir = path.resolve(entryDir, options.output);
455
469
  const errors = [];
456
470
  const warnings = [];
471
+ if (!await pathExists(entryDir)) {
472
+ errors.push(`入口目录不存在: ${entryDir}。请使用 --entry 指向包含 index.ts 的插件源码目录。`);
473
+ return {
474
+ ok: false,
475
+ errors,
476
+ warnings
477
+ };
478
+ }
479
+ const entryIndexPath = path.join(entryDir, "index.ts");
480
+ if (!await pathExists(entryIndexPath)) {
481
+ errors.push(`入口目录缺少 index.ts: ${entryIndexPath}。请确认 --entry 指向插件项目根目录。`);
482
+ return {
483
+ ok: false,
484
+ errors,
485
+ warnings
486
+ };
487
+ }
488
+ if (!await pathExists(outputDir)) {
489
+ errors.push(`构建产物目录不存在: ${outputDir}。请先运行 pnpm run build,或使用 --output 指向 dist 目录。`);
490
+ return {
491
+ ok: false,
492
+ errors,
493
+ warnings
494
+ };
495
+ }
457
496
  const indexJsPath = path.join(outputDir, "index.js");
458
497
  if (!await pathExists(indexJsPath)) errors.push(`缺少构建产物 dist/index.js:${indexJsPath}`);
459
498
  const manifestPath = path.join(outputDir, "manifest.json");
@@ -505,13 +544,15 @@ async function pathExists(p) {
505
544
  //#region src/commands/check.ts
506
545
  var CheckCommand = class extends BaseCommand {
507
546
  register(parent) {
508
- parent.command("check").description("检查构建产物的正确性(manifest.json、config.json、index.js)").option("-e, --entry <path>", "工具源码目录", process.cwd()).option("-o, --output <path>", "构建输出目录", "./dist").action(async (opts) => {
547
+ this.addCommonOptions(parent.command("check").description("Check plugin build output / 检查插件构建产物").option("-e, --entry <path>", "插件源码目录 / Plugin source directory", process.cwd()).option("-o, --output <path>", "构建输出目录 / Build output directory", "./dist")).action(async (opts) => {
509
548
  await this.run(opts);
510
549
  });
511
550
  }
512
551
  async run(options) {
513
- logger.info(`检查目录: ${options.entry}`);
514
- logger.info(`产物目录: ${options.output}`);
552
+ const entryDir = path.resolve(options.entry);
553
+ const outputDir = path.resolve(entryDir, options.output);
554
+ logger.info(`检查目录: ${entryDir}`);
555
+ logger.info(`产物目录: ${outputDir}`);
515
556
  const result = await checkBuildOutput(options);
516
557
  if (result.warnings.length > 0) for (const w of result.warnings) logger.warn(w);
517
558
  if (result.errors.length > 0) {
@@ -526,7 +567,7 @@ var CheckCommand = class extends BaseCommand {
526
567
  //#endregion
527
568
  //#region package.json
528
569
  var name = "@fastgpt-plugin/cli";
529
- var version = "0.2.0";
570
+ var version = "0.2.2-alpha.1";
530
571
 
531
572
  //#endregion
532
573
  //#region src/constants.ts
@@ -555,6 +596,14 @@ async function inputPrompt(deps, options) {
555
596
  });
556
597
  }
557
598
 
599
+ //#endregion
600
+ //#region src/prompts/create/normalize.ts
601
+ function normalizeDependencyMode(mode) {
602
+ if (!mode || mode === "semver") return "semver";
603
+ if (mode === "catalog") return "catalog";
604
+ throw new Error(`依赖模式不支持: ${mode}。可选值: semver | catalog`);
605
+ }
606
+
558
607
  //#endregion
559
608
  //#region src/prompts/create/prompt.ts
560
609
  var CreatePrompt = class {
@@ -568,6 +617,7 @@ var CreatePrompt = class {
568
617
  * - 否则使用交互式 prompt 补全缺失部分
569
618
  */
570
619
  async run(input) {
620
+ const dependencyMode = normalizeDependencyMode(input.dependencyModeFlag);
571
621
  const getPluginType = () => {
572
622
  if (!input.typeFlag) return void 0;
573
623
  return input.typeFlag === "tool-suite" ? "tool-suite" : "tool";
@@ -577,7 +627,8 @@ var CreatePrompt = class {
577
627
  name: input.nameArg,
578
628
  cwd: input.cwd,
579
629
  type: pluginType,
580
- description: input.descriptionFlag
630
+ description: input.descriptionFlag,
631
+ dependencyMode
581
632
  };
582
633
  const getPluginNameInputPrompt = async () => {
583
634
  return await inputPrompt(this.deps, {
@@ -612,20 +663,29 @@ var CreatePrompt = class {
612
663
  name,
613
664
  cwd: input.cwd,
614
665
  type,
615
- description
666
+ description,
667
+ dependencyMode
616
668
  };
617
669
  }
618
670
  };
619
671
 
620
672
  //#endregion
621
673
  //#region src/commands/create.ts
674
+ const TEMPLATE_DEPENDENCY_VERSIONS = {
675
+ "@fastgpt-plugin/cli": "^0.2.0",
676
+ "@fastgpt-plugin/sdk-factory": "^0.0.1",
677
+ typescript: "^5.9.3",
678
+ vitest: "^4.0.18",
679
+ zod: "^4"
680
+ };
622
681
  var CreateCommand = class extends BaseCommand {
623
682
  register(parent) {
624
- parent.command("create").description("创建新的 FastGPT 插件项目").argument("[name]", "插件名称").option("-t, --type <type>", "插件类型: 单工具 | 工具集").option("-d, --description <desc>", "插件描述").option("--cwd <path>", "工作目录", process.cwd()).action(async (name, opts) => {
683
+ this.addCommonOptions(parent.command("create").description("Create a new FastGPT plugin project / 创建新的 FastGPT 插件项目").argument("[name]", "插件名称 / Plugin name").option("-t, --type <type>", "插件类型 / Plugin type: tool | tool-suite").option("-d, --description <desc>", "插件描述 / Plugin description").option("--cwd <path>", "工作目录 / Working directory", process.cwd()).option("--dependency-mode <mode>", "依赖版本模式 / Dependency version mode: semver | catalog", "semver")).action(async (name, opts) => {
625
684
  const options = await new CreatePrompt().run({
626
685
  nameArg: name,
627
686
  typeFlag: opts.type,
628
687
  descriptionFlag: opts.description,
688
+ dependencyModeFlag: opts.dependencyMode,
629
689
  cwd: opts.cwd
630
690
  });
631
691
  await this.run(options);
@@ -642,16 +702,28 @@ var CreateCommand = class extends BaseCommand {
642
702
  const filePath = path.join(targetDir, rel);
643
703
  await this.ensureDir(path.dirname(filePath));
644
704
  const raw = await fs.readFile(templatePath, "utf-8");
645
- const content = this.applyPlaceholders(raw, options.name, description);
705
+ const content = this.applyPlaceholders(raw, options.name, description, options.type, options.dependencyMode);
646
706
  await fs.writeFile(filePath, content, "utf-8");
647
707
  }
648
708
  await this.finalizeIndexTemplate(targetDir, options.type);
649
709
  logger.success(`创建插件项目: ${options.name} (${options.type})`, { cwd: options.cwd });
650
710
  }
651
- applyPlaceholders(text, name, description) {
711
+ applyPlaceholders(text, name, description, type, dependencyMode) {
652
712
  name = path.basename(name);
653
713
  name = kebabCase(name);
654
- return text.replace(/\{\{name\}\}/g, name).replace(/\{\{description\}\}/g, description);
714
+ return text.replace(/\{\{name\}\}/g, name).replace(/\{\{description\}\}/g, description).replace(/\{\{debugRunInput\}\}/g, this.pickDebugRunInput(type)).replace(/\{\{debugRunInputJson\}\}/g, this.pickDebugRunInputJson(type)).replace(/\{\{debugRunToolOption\}\}/g, this.pickDebugRunToolOption(type)).replace(/\{\{dependencyMode\}\}/g, dependencyMode).replace(/\{\{cliPackageVersion\}\}/g, this.pickDependencyVersion("@fastgpt-plugin/cli", dependencyMode)).replace(/\{\{sdkFactoryPackageVersion\}\}/g, this.pickDependencyVersion("@fastgpt-plugin/sdk-factory", dependencyMode)).replace(/\{\{typescriptPackageVersion\}\}/g, this.pickDependencyVersion("typescript", dependencyMode)).replace(/\{\{vitestPackageVersion\}\}/g, this.pickDependencyVersion("vitest", dependencyMode)).replace(/\{\{zodPackageVersion\}\}/g, this.pickDependencyVersion("zod", dependencyMode));
715
+ }
716
+ pickDebugRunInput(type) {
717
+ return type === "tool-suite" ? "{\"query\":\"select 1\"}" : "{\"delay\":0}";
718
+ }
719
+ pickDebugRunInputJson(type) {
720
+ return this.pickDebugRunInput(type).replace(/"/g, "\\\"");
721
+ }
722
+ pickDebugRunToolOption(type) {
723
+ return type === "tool-suite" ? " --tool mysql" : "";
724
+ }
725
+ pickDependencyVersion(name, dependencyMode) {
726
+ return dependencyMode === "catalog" ? "catalog:" : TEMPLATE_DEPENDENCY_VERSIONS[name];
655
727
  }
656
728
  async collectTemplateFiles(root) {
657
729
  const result = [];
@@ -3611,7 +3683,7 @@ function sanitizePathSegment$1(value) {
3611
3683
  //#region src/commands/debug.ts
3612
3684
  var DebugCommand = class extends BaseCommand {
3613
3685
  register(parent) {
3614
- parent.command("debug <entries...>").description("直接加载本地插件目录并调试工具").option("-t, --tool <childId>", "工具集子工具 ID").option("--run", "立即执行一次工具调试", false).option("-i, --input <json>", "工具输入 JSON 字符串").option("--input-file <path>", "工具输入 JSON 文件路径").option("--secrets <json>", "secrets JSON 字符串").option("--secrets-file <path>", "secrets JSON 文件路径").option("--system-var <json>", "systemVar JSON 字符串").option("--system-var-file <path>", "systemVar JSON 文件路径").option("--upload-dir <path>", "虚拟 uploadFile 的输出目录").option("--connect <keyOrUrl>", "兼容入口:FastGPT debug connection key 或 connect link,建议改用 dev 命令").option("--reconnect", "兼容入口:断线后自动重连", true).option("--no-reconnect", "兼容入口:关闭自动重连").option("--reconnect-interval-ms <ms>", "兼容入口:重连间隔").action(async (entries, opts) => {
3686
+ this.addCommonOptions(parent.command("debug <entries...>").description("Load and debug a local plugin / 本地加载并调试插件").option("-t, --tool <childId>", "工具集子工具 ID / Child tool ID").option("--run", "立即执行一次工具调试 / Run the tool once", false).option("-i, --input <json>", "工具输入 JSON 字符串 / Tool input JSON string").option("--input-file <path>", "工具输入 JSON 文件路径 / Tool input JSON file").option("--secrets <json>", "secrets JSON 字符串 / secrets JSON string").option("--secrets-file <path>", "secrets JSON 文件路径 / secrets JSON file").option("--system-var <json>", "systemVar JSON 字符串 / systemVar JSON string").option("--system-var-file <path>", "systemVar JSON 文件路径 / systemVar JSON file").option("--upload-dir <path>", "虚拟 uploadFile 的输出目录 / virtual uploadFile output directory").option("--connect <keyOrUrl>", "兼容入口:FastGPT debug connection key 或 connect link,建议改用 dev 命令").option("--reconnect", "兼容入口:断线后自动重连", true).option("--no-reconnect", "兼容入口:关闭自动重连").option("--reconnect-interval-ms <ms>", "兼容入口:重连间隔")).action(async (entries, opts) => {
3615
3687
  await this.run(entries, opts);
3616
3688
  });
3617
3689
  }
@@ -3793,7 +3865,7 @@ function sanitizePathSegment(value) {
3793
3865
  //#region src/commands/dev.ts
3794
3866
  var DevCommand = class extends BaseCommand {
3795
3867
  register(parent) {
3796
- parent.command("dev [entries...]").description("启动 FastGPT 插件集成开发会话").option("--connect <keyOrUrl>", "可选:FastGPT debug connection key 或 connect link,适合脚本和 Agent").option("--reconnect", "断线后自动重连", true).option("--no-reconnect", "关闭自动重连").option("--reconnect-interval-ms <ms>", "重连间隔").option("--upload-dir <path>", "虚拟 uploadFile 的输出目录").option("--watch", "监听插件文件变化并自动重载远程调试会话", false).option("--no-interactive", "使用纯文本状态输出,适合脚本和 Agent").action(async (entries, opts) => {
3868
+ this.addCommonOptions(parent.command("dev [entries...]").description("Start remote FastGPT integration debugging / 启动 FastGPT 插件集成开发会话").option("--connect <keyOrUrl>", "FastGPT debug connection key 或 connect link").option("--reconnect", "断线后自动重连 / Reconnect after disconnect", true).option("--no-reconnect", "关闭自动重连 / Disable reconnect").option("--reconnect-interval-ms <ms>", "重连间隔 / Reconnect interval").option("--upload-dir <path>", "虚拟 uploadFile 的输出目录 / virtual uploadFile output directory").option("--watch", "监听插件文件变化并自动重载远程调试会话 / Watch and hot reload plugins", false).option("--no-interactive", "使用纯文本状态输出,适合脚本和 Agent")).action(async (entries, opts) => {
3797
3869
  await this.run(entries, opts);
3798
3870
  });
3799
3871
  }
@@ -3818,7 +3890,7 @@ var DevCommand = class extends BaseCommand {
3818
3890
  */
3819
3891
  var PackCommand = class extends BaseCommand {
3820
3892
  register(parent) {
3821
- parent.command("pack").description("基于 build 产物打包 FastGPT 工具或工具集").option("-e, --entry <path>", "工具源码根目录", process.cwd()).option("-d, --dist <path>", "构建产物目录", "./dist").option("-o, --output <path>", "pkg 输出目录(默认使用入口目录)").option("-n, --name <name>", "包名称(默认使用入口目录名)").action(async (opts) => {
3893
+ this.addCommonOptions(parent.command("pack").description("Pack a FastGPT plugin into .pkg / 打包 FastGPT 插件").option("-e, --entry <path>", "插件源码目录 / Plugin source directory", process.cwd()).option("-d, --dist <path>", "构建产物目录 / Build output directory", "./dist").option("-o, --output <path>", "pkg 输出目录 / .pkg output directory").option("-n, --name <name>", "包名称 / Package name")).action(async (opts) => {
3822
3894
  await this.run(opts);
3823
3895
  });
3824
3896
  }
@@ -3843,7 +3915,7 @@ var PackCommand = class extends BaseCommand {
3843
3915
  logger.info(`输出文件: ${pkgPath}`);
3844
3916
  } catch (error) {
3845
3917
  logger.error("打包失败,详情如下:");
3846
- logger.error(error instanceof Error ? error : new Error(String(error)));
3918
+ logger.error(formatCliError(error, options.verbose));
3847
3919
  process.exit(1);
3848
3920
  }
3849
3921
  }
@@ -3889,7 +3961,7 @@ async function ensureDir(dir) {
3889
3961
  //#region src/cmd.ts
3890
3962
  function createProgram() {
3891
3963
  const program = new Command();
3892
- program.name(CLI_NAME).version(CLI_VERSION).description("FastGPT 插件开发 CLI");
3964
+ program.name(CLI_NAME).version(CLI_VERSION).description("FastGPT plugin development CLI / FastGPT 插件开发 CLI").option("--verbose", "显示完整错误堆栈 / Show full error stack");
3893
3965
  new BuildCommand().register(program);
3894
3966
  new CheckCommand().register(program);
3895
3967
  new CreateCommand().register(program);
@@ -3913,7 +3985,7 @@ const main = async () => {
3913
3985
  await run();
3914
3986
  } catch (error) {
3915
3987
  if (error instanceof Error && (error.name === "ExitPromptError" || error.message.includes("SIGINT") || error.message.includes("force closed"))) process.exit(130);
3916
- logger.error(error);
3988
+ logger.error(formatCliError(error));
3917
3989
  process.exitCode = 1;
3918
3990
  }
3919
3991
  };
package/package.json CHANGED
@@ -1,6 +1,14 @@
1
1
  {
2
2
  "name": "@fastgpt-plugin/cli",
3
- "version": "0.2.0",
3
+ "version": "0.2.2-alpha.1",
4
+ "description": "CLI for creating, debugging, building, checking, and packaging FastGPT Plugin tools.",
5
+ "keywords": [
6
+ "fastgpt",
7
+ "fastgpt-plugin",
8
+ "plugin",
9
+ "cli",
10
+ "developer-tools"
11
+ ],
4
12
  "type": "module",
5
13
  "private": false,
6
14
  "publishConfig": {
@@ -2,10 +2,59 @@
2
2
 
3
3
  {{description}}
4
4
 
5
- ## 开发
5
+ ## Quick Start
6
6
 
7
7
  ```bash
8
8
  pnpm install
9
+ pnpm run dev
10
+ pnpm run debug
11
+ pnpm run debug:run
9
12
  pnpm run build
13
+ pnpm run check
10
14
  pnpm run test
15
+ pnpm run pack
11
16
  ```
17
+
18
+ `pnpm run dev` starts the remote FastGPT integration debug session with watch
19
+ mode enabled. Paste the FastGPT connection key when prompted, or pass one
20
+ directly:
21
+
22
+ ```bash
23
+ fastgpt-plugin dev . --watch --connect '<connection-key-or-connect-link>'
24
+ ```
25
+
26
+ `pnpm run debug` prints the plugin manifest, schema, and child-tool debug
27
+ commands. `pnpm run debug:run` executes the tool once with sample JSON input.
28
+ For tools with required input fields, replace the sample input:
29
+
30
+ ```bash
31
+ npx @fastgpt-plugin/cli debug . --run{{debugRunToolOption}} --input '{{debugRunInput}}'
32
+ ```
33
+
34
+ ## Output
35
+
36
+ - `pnpm run build` writes `dist/index.js`, `dist/manifest.json`, copied logos,
37
+ and optional static files.
38
+ - `pnpm run check` validates the build output before upload.
39
+ - `pnpm run pack` creates a `.pkg` file that can be uploaded to FastGPT Plugin.
40
+
41
+ ## Dependency Mode
42
+
43
+ This project was generated with `{{dependencyMode}}` dependencies.
44
+
45
+ - `semver` uses published npm versions and works as a standalone plugin project.
46
+ - `catalog` is for pnpm workspace repositories that define matching catalog
47
+ entries, such as the official plugin repository.
48
+
49
+ To generate a workspace-oriented project:
50
+
51
+ ```bash
52
+ npx @fastgpt-plugin/cli create my-tool --type tool --dependency-mode catalog
53
+ ```
54
+
55
+ ## Troubleshooting
56
+
57
+ - Missing `index.ts`: run commands from the plugin project root, or pass
58
+ `--entry <plugin-dir>`.
59
+ - Invalid JSON input: wrap input in a JSON object, for example `--input '{}'`.
60
+ - Need a stack trace: rerun the command with `--verbose`.
@@ -0,0 +1,14 @@
1
+ import { describe, expect, it } from 'vitest';
2
+
3
+ import plugin from './index';
4
+
5
+ describe('plugin template', () => {
6
+ it('exports a valid FastGPT plugin manifest', () => {
7
+ const manifest = plugin.getUserToolManifest();
8
+
9
+ expect(manifest.pluginId).toBeTruthy();
10
+ expect(manifest.version).toMatch(/^\d+\.\d+\.\d+$/);
11
+ expect(manifest.name).toBeDefined();
12
+ expect(manifest.description).toBeDefined();
13
+ });
14
+ });
@@ -10,7 +10,8 @@ const handler = createToolHandler({
10
10
  inputSchema: z.object({
11
11
  delay: z.number().meta({
12
12
  title: 'Delay',
13
- description: 'Delay duration in milliseconds'
13
+ description: 'Delay duration in milliseconds',
14
+ isToolParams: true
14
15
  } satisfies InputSchemaMetaType)
15
16
  }),
16
17
  outputSchema: z.object({}).meta({} satisfies OutputSchemaMetaType),
@@ -33,7 +33,8 @@ const secretSchema = z.object({
33
33
  const mysqlHandler = createToolHandler({
34
34
  inputSchema: z.object({
35
35
  query: z.string().meta({
36
- title: 'SQL Query'
36
+ title: 'SQL Query',
37
+ isToolParams: true
37
38
  } satisfies InputSchemaMetaType)
38
39
  }),
39
40
  outputSchema: z.object({
@@ -62,7 +63,8 @@ const mysqlHandler = createToolHandler({
62
63
  const pgsqlHandler = createToolHandler({
63
64
  inputSchema: z.object({
64
65
  query: z.string().meta({
65
- title: 'SQL Query'
66
+ title: 'SQL Query',
67
+ isToolParams: true
66
68
  } satisfies InputSchemaMetaType)
67
69
  }),
68
70
  outputSchema: z.object({
@@ -7,15 +7,19 @@
7
7
  "scripts": {
8
8
  "build": "npx @fastgpt-plugin/cli build --minify",
9
9
  "build:dev": "npx @fastgpt-plugin/cli build",
10
+ "check": "npx @fastgpt-plugin/cli check --entry . --output ./dist",
11
+ "dev": "fastgpt-plugin dev . --watch",
12
+ "debug": "npx @fastgpt-plugin/cli debug .",
13
+ "debug:run": "npx @fastgpt-plugin/cli debug . --run{{debugRunToolOption}} --input '{{debugRunInputJson}}'",
10
14
  "pack": "npx @fastgpt-plugin/cli pack",
11
15
  "test": "vitest run"
12
16
  },
13
17
  "dependencies": {},
14
18
  "devDependencies": {
15
- "@fastgpt-plugin/cli": "catalog:",
16
- "@fastgpt-plugin/sdk-factory": "catalog:",
17
- "typescript": "catalog:",
18
- "vitest": "catalog:",
19
- "zod": "catalog:"
19
+ "@fastgpt-plugin/cli": "{{cliPackageVersion}}",
20
+ "@fastgpt-plugin/sdk-factory": "{{sdkFactoryPackageVersion}}",
21
+ "typescript": "{{typescriptPackageVersion}}",
22
+ "vitest": "{{vitestPackageVersion}}",
23
+ "zod": "{{zodPackageVersion}}"
20
24
  }
21
25
  }