@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 +30 -0
- package/README.md +28 -0
- package/dist/index.js +93 -21
- package/package.json +9 -1
- package/templates/tool/README.md +50 -1
- package/templates/tool/index.spec.ts +14 -0
- package/templates/tool/index.tool.ts +2 -1
- package/templates/tool/index.toolset.ts +4 -2
- package/templates/tool/package.json +9 -5
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
|
|
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
|
|
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
|
|
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("
|
|
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
|
-
|
|
514
|
-
|
|
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.
|
|
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>", "
|
|
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("
|
|
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>", "
|
|
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("
|
|
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
|
|
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.
|
|
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": {
|
package/templates/tool/README.md
CHANGED
|
@@ -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": "
|
|
16
|
-
"@fastgpt-plugin/sdk-factory": "
|
|
17
|
-
"typescript": "
|
|
18
|
-
"vitest": "
|
|
19
|
-
"zod": "
|
|
19
|
+
"@fastgpt-plugin/cli": "{{cliPackageVersion}}",
|
|
20
|
+
"@fastgpt-plugin/sdk-factory": "{{sdkFactoryPackageVersion}}",
|
|
21
|
+
"typescript": "{{typescriptPackageVersion}}",
|
|
22
|
+
"vitest": "{{vitestPackageVersion}}",
|
|
23
|
+
"zod": "{{zodPackageVersion}}"
|
|
20
24
|
}
|
|
21
25
|
}
|