Skip to content

Commit ee65a6f

Browse files
authored
Improve CLI template developer experience (#497)
* Improve CLI docs and create/check workflows * chore(cli): bump cli version to 0.2.1 * build: update prepare script and workspace allowBuilds
1 parent 788123f commit ee65a6f

34 files changed

Lines changed: 665 additions & 278 deletions

CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Changelog
2+
3+
This file is the release-notes index for FastGPT Plugin.
4+
5+
## Unreleased
6+
7+
- CLI scaffolding now generates standalone plugin projects with published npm
8+
semver dependencies by default.
9+
- CLI scaffolding keeps `--dependency-mode catalog` for official pnpm workspaces
10+
that define matching catalog entries.
11+
- Generated plugin projects include `dev`, `debug`, `debug:run`, `check`, `build`,
12+
`test`, and `pack` scripts in the README path.
13+
- CLI user-facing errors hide stack traces by default and show them with
14+
`--verbose`.
15+
16+
## v1.0.0 Infrastructure Upgrade
17+
18+
- See the [v1.0.0 Upgrade Guide](./docs/upgrade/v1.0.0.md) for production
19+
migration steps, compatibility notes, and the validation checklist.

README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,41 @@ Deeply **modularize** FastGPT to achieve maximum **extensibility**.
3535
- [x] URL install SSRF protection
3636
- [ ] More plugin types beyond tools
3737

38+
## 5-Minute Plugin Hello World
39+
40+
Create a standalone tool plugin with published npm dependencies:
41+
42+
```bash
43+
npx @fastgpt-plugin/cli create dx-hello --type tool --description "DX hello world"
44+
cd dx-hello
45+
pnpm install
46+
pnpm run dev
47+
pnpm run debug
48+
pnpm run debug:run
49+
pnpm run build
50+
pnpm run check
51+
pnpm run pack
52+
```
53+
54+
Expected result:
55+
56+
- `pnpm run dev` starts a remote FastGPT integration debug session.
57+
- `pnpm run debug` prints the plugin manifest, schemas, and runnable debug command.
58+
- `pnpm run debug:run` executes the generated sample tool once.
59+
- `pnpm run build` writes `dist/index.js` and `dist/manifest.json`.
60+
- `pnpm run check` validates the generated build output.
61+
- `pnpm run pack` creates `dx-hello.pkg` for upload.
62+
63+
When generating plugins inside an official pnpm workspace that defines catalog
64+
entries, use catalog dependencies:
65+
66+
```bash
67+
npx @fastgpt-plugin/cli create dx-hello --type tool --dependency-mode catalog
68+
```
69+
3870
## Documentation & Development Guides
3971

72+
- [Changelog](./CHANGELOG.md)
4073
- [Development Specifications](./dev.md)
4174
- [v1.0.0 Upgrade Guide](./docs/upgrade/v1.0.0.md)
4275
- [Architecture](./docs/dev/architecture.md)

README_zh_CN.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,40 @@ FastGPT 已有系统工具已经迁移到这个仓库,新工具也将在这个
3535
- [x] URL 安装 SSRF 防护
3636
- [ ] 工具以外的更多插件类型
3737

38+
## 5 分钟插件 Hello World
39+
40+
创建一个使用 npm 发布版依赖的独立工具插件:
41+
42+
```bash
43+
npx @fastgpt-plugin/cli create dx-hello --type tool --description "DX hello world"
44+
cd dx-hello
45+
pnpm install
46+
pnpm run dev
47+
pnpm run debug
48+
pnpm run debug:run
49+
pnpm run build
50+
pnpm run check
51+
pnpm run pack
52+
```
53+
54+
预期结果:
55+
56+
- `pnpm run dev` 启动 FastGPT 远程集成调试会话。
57+
- `pnpm run debug` 输出插件 manifest、schema 和可运行的调试命令。
58+
- `pnpm run debug:run` 执行一次生成的示例工具。
59+
- `pnpm run build` 生成 `dist/index.js``dist/manifest.json`
60+
- `pnpm run check` 校验构建产物。
61+
- `pnpm run pack` 生成可上传的 `dx-hello.pkg`
62+
63+
如果在定义了 catalog 的官方 pnpm workspace 中生成插件,使用 catalog 依赖:
64+
65+
```bash
66+
npx @fastgpt-plugin/cli create dx-hello --type tool --dependency-mode catalog
67+
```
68+
3869
## 文档
3970

71+
- [版本记录](./CHANGELOG.md)
4072
- [开发规范](./dev_zh_CN.md)
4173
- [v1.0.0 更新文档](./docs/upgrade/v1.0.0.zh.md)
4274
- [项目架构](./docs/dev/architecture.zh.md)

apps/cli/README.en.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,36 @@ Language: [简体中文](./README.md) | [English](./README.en.md)
44

55
Command-line tool for FastGPT plugin development. It is used to create, build, test, debug, and package FastGPT tools and tool suites.
66

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+
737
### Features
838

939
- **Unified build flow**

apps/cli/README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,34 @@
44

55
FastGPT 插件开发的命令行工具,用于创建、构建和测试 FastGPT 工具 / 工具集。
66

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+
735
### Features
836

937
- **统一构建流程**

apps/cli/package.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
{
22
"name": "@fastgpt-plugin/cli",
3-
"version": "0.2.0",
3+
"version": "0.2.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+
],
412
"type": "module",
513
"private": false,
614
"publishConfig": {

apps/cli/src/build/index.spec.ts

Lines changed: 0 additions & 64 deletions
This file was deleted.

apps/cli/src/check/index.spec.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { mkdtemp, mkdir, rm, writeFile } from 'node:fs/promises';
2+
import { tmpdir } from 'node:os';
3+
import path from 'node:path';
4+
5+
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
6+
7+
import { checkBuildOutput } from './index';
8+
9+
describe('checkBuildOutput', () => {
10+
let testCwd: string;
11+
12+
beforeEach(async () => {
13+
testCwd = await mkdtemp(path.join(tmpdir(), 'fastgpt-plugin-check-'));
14+
});
15+
16+
afterEach(async () => {
17+
await rm(testCwd, { recursive: true, force: true });
18+
});
19+
20+
it('入口目录不存在时应优先报告 entry 错误', async () => {
21+
const missingEntry = path.join(testCwd, 'missing-plugin');
22+
23+
const result = await checkBuildOutput({
24+
entry: missingEntry,
25+
output: './dist'
26+
});
27+
28+
expect(result.ok).toBe(false);
29+
expect(result.errors).toHaveLength(1);
30+
expect(result.errors[0]).toContain(`入口目录不存在: ${missingEntry}`);
31+
});
32+
33+
it('相对 output 应基于 entry 目录解析', async () => {
34+
const entryDir = path.join(testCwd, 'plugin');
35+
await mkdir(entryDir, { recursive: true });
36+
await writeFile(path.join(entryDir, 'index.ts'), 'export default {};\n', 'utf-8');
37+
38+
const result = await checkBuildOutput({
39+
entry: entryDir,
40+
output: './dist'
41+
});
42+
43+
expect(result.ok).toBe(false);
44+
expect(result.errors).toEqual([
45+
`构建产物目录不存在: ${path.join(entryDir, 'dist')}。请先运行 pnpm run build,或使用 --output 指向 dist 目录。`
46+
]);
47+
});
48+
});

apps/cli/src/check/index.ts

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,40 @@ export interface CheckResult {
2424
* - manifest.json 引用的 logo 文件存在
2525
*/
2626
export async function checkBuildOutput(options: CheckOptions): Promise<CheckResult> {
27-
const outputDir = path.resolve(options.output);
27+
const entryDir = path.resolve(options.entry);
28+
const outputDir = path.resolve(entryDir, options.output);
2829

2930
const errors: string[] = [];
3031
const warnings: string[] = [];
3132

33+
if (!(await pathExists(entryDir))) {
34+
errors.push(`入口目录不存在: ${entryDir}。请使用 --entry 指向包含 index.ts 的插件源码目录。`);
35+
return {
36+
ok: false,
37+
errors,
38+
warnings
39+
};
40+
}
41+
42+
const entryIndexPath = path.join(entryDir, 'index.ts');
43+
if (!(await pathExists(entryIndexPath))) {
44+
errors.push(`入口目录缺少 index.ts: ${entryIndexPath}。请确认 --entry 指向插件项目根目录。`);
45+
return {
46+
ok: false,
47+
errors,
48+
warnings
49+
};
50+
}
51+
52+
if (!(await pathExists(outputDir))) {
53+
errors.push(`构建产物目录不存在: ${outputDir}。请先运行 pnpm run build,或使用 --output 指向 dist 目录。`);
54+
return {
55+
ok: false,
56+
errors,
57+
warnings
58+
};
59+
}
60+
3261
const indexJsPath = path.join(outputDir, 'index.js');
3362
if (!(await pathExists(indexJsPath))) {
3463
errors.push(`缺少构建产物 dist/index.js:${indexJsPath}`);

apps/cli/src/cmd.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@ import { Command } from 'commander';
1010
function createProgram(): Command {
1111
const program = new Command();
1212

13-
program.name(CLI_NAME).version(CLI_VERSION).description('FastGPT 插件开发 CLI');
13+
program
14+
.name(CLI_NAME)
15+
.version(CLI_VERSION)
16+
.description('FastGPT plugin development CLI / FastGPT 插件开发 CLI')
17+
.option('--verbose', '显示完整错误堆栈 / Show full error stack');
1418

1519
new BuildCommand().register(program);
1620
new CheckCommand().register(program);

0 commit comments

Comments
 (0)