中文 | English
devgen 支持通过插件机制扩展功能,允许用户使用 genkit 框架开发自定义代码生成工具。
插件系统支持两种加载方式:
| 类型 | 说明 | 适用场景 |
|---|---|---|
source |
Go 源码,运行时编译 | 开发调试、快速迭代 |
plugin |
预编译 Go plugin (.so) | 高性能、生产环境 |
在项目根目录创建 devgen.toml:
# 插件定义(必需)
[[plugins]]
name = "myplugin" # 插件名称
path = "./plugins/mygen" # 插件路径
type = "source" # source | plugin注意:
[tools.xxx]配置块已不再需要。推荐在插件代码中实现ConfigurableTool接口来提供注解元数据。
所有插件都需要实现 genkit.Tool 接口:
type Tool interface {
Name() string
Run(gen *Generator, log *Logger) error
}为了让 VSCode 扩展自动识别插件的注解,实现 genkit.ConfigurableTool 接口:
type ConfigurableTool interface {
Tool
Config() ToolConfig
}示例:
func (m *MyGenerator) Config() genkit.ToolConfig {
return genkit.ToolConfig{
OutputSuffix: "_gen.go",
Annotations: []genkit.AnnotationConfig{
{
Name: "gen",
Type: "type",
Doc: "Generate code for this type",
Params: &genkit.AnnotationParams{
Values: []string{"json", "xml", "yaml"},
},
},
},
}
}这样无需在 devgen.toml 中额外配置 [tools.xxx],VSCode 扩展会通过 devgen config --json 命令自动从插件获取配置。
可以使用以下命令查看所有工具(内置 + 插件)的配置:
# JSON 格式(VSCode 扩展使用)
devgen config --json
# TOML 格式
devgen config最简单的方式,无需预编译:
// plugins/mygen/mygen.go
package main
import "github.com/tlipoca9/devgen/genkit"
type MyGenerator struct{}
func (m *MyGenerator) Name() string { return "mygen" }
// Config 提供 VSCode 扩展所需的注解元数据
func (m *MyGenerator) Config() genkit.ToolConfig {
return genkit.ToolConfig{
OutputSuffix: "_gen.go",
Annotations: []genkit.AnnotationConfig{
{Name: "gen", Type: "type", Doc: "Generate code for this type"},
},
}
}
func (m *MyGenerator) Run(gen *genkit.Generator, log *genkit.Logger) error {
for _, pkg := range gen.Packages {
for _, typ := range pkg.Types {
// 检查注解
if !genkit.HasAnnotation(typ.Doc, "mygen", "gen") {
continue
}
// 生成代码
g := gen.NewGeneratedFile(
pkg.Dir+"/"+strings.ToLower(typ.Name)+"_gen.go",
genkit.GoImportPath(pkg.PkgPath),
)
g.P("// Code generated by mygen. DO NOT EDIT.")
g.P()
g.P("package ", pkg.Name)
// ... 生成更多代码
}
}
return nil
}
// 必须导出 Tool 变量
var Tool genkit.Tool = &MyGenerator{}
// 必须有 main 函数(即使为空)
func main() {}配置:
[[plugins]]
name = "mygen"
path = "./plugins/mygen"
type = "source"适合需要最高性能的生产环境:
// 与 source 类型代码相同
package main
import "github.com/tlipoca9/devgen/genkit"
type MyGenerator struct{}
func (m *MyGenerator) Name() string { return "mygen" }
func (m *MyGenerator) Config() genkit.ToolConfig {
return genkit.ToolConfig{
OutputSuffix: "_gen.go",
Annotations: []genkit.AnnotationConfig{
{Name: "gen", Type: "type", Doc: "Generate code for this type"},
},
}
}
func (m *MyGenerator) Run(gen *genkit.Generator, log *genkit.Logger) error {
// ...
return nil
}
var Tool genkit.Tool = &MyGenerator{}
func main() {}编译为 .so 文件:
go build -buildmode=plugin -o mygen.so ./plugins/mygen配置:
[[plugins]]
name = "mygen"
path = "./plugins/mygen.so"
type = "plugin"注意:Go plugin 仅支持 Linux 和 macOS。
VSCode 扩展会自动从实现了 ConfigurableTool 接口的插件获取注解配置,提供:
- 注解语法高亮
- 自动补全
- 参数验证
如果插件未实现 ConfigurableTool,也可以在 devgen.toml 中手动配置:
[tools.mygen]
output_suffix = "_gen.go"
[[tools.mygen.annotations]]
name = "gen"
type = "type"
doc = "Generate code for this type"
[tools.mygen.annotations.params]
type = "enum"
values = ["json", "xml", "yaml"]完整示例请参考 examples/plugin。
为了让 AI 助手(Kiro、CodeBuddy、Cursor)理解你的插件,实现 genkit.RuleTool 接口:
type RuleTool interface {
Tool
Rules() []Rule
}示例:
func (m *MyGenerator) Rules() []genkit.Rule {
return []genkit.Rule{
{
Name: "mygen",
Description: "MyGenerator 使用指南",
Globs: []string{"**/*.go"},
AlwaysApply: false,
Content: mygenRuleContent,
},
}
}最佳实践:将规则内容存储在单独的 markdown 文件中并嵌入:
// rules/embed.go
package rules
import _ "embed"
//go:embed mygen.md
var MygenRule string然后在插件中引用:
import "myapp/plugins/mygen/rules"
func (m *MyGenerator) Rules() []genkit.Rule {
return []genkit.Rule{
{
Name: "mygen",
Description: "MyGenerator 使用指南",
Globs: []string{"**/*.go"},
Content: rules.MygenRule,
},
}
}生成 AI Rules:
# 预览规则
devgen rules --agent kiro
# 为 Kiro 生成规则
devgen rules --agent kiro -w
# 为 CodeBuddy 生成规则
devgen rules --agent codebuddy -w
# 为 Cursor 生成规则
devgen rules --agent cursor -w规则内容结构:
你的规则 markdown 应包含:
- 何时使用 - 使用场景和案例
- 快速开始 - 分步入门指南
- 注解参考 - 详细的注解文档
- 完整示例 - 完整的工作示例
- 常见错误 - 故障排除指南,包含 ❌/✅ 对比
参考 enumgen 规则 和 validategen 规则 的实现。
规则如何与不同 AI 助手协作:
每个 AI 助手使用不同的 frontmatter 格式。devgen 会自动适配你的规则:
| 助手 | Frontmatter 格式 |
|---|---|
| Kiro | inclusion: fileMatch + fileMatchPattern: ['**/*.go'] |
| CodeBuddy | description: "..." + globs: **/*.go + alwaysApply: false |
| Cursor | description: "..." + globs: **/*.go + alwaysApply: false |
适配器系统会自动处理转换 - 你只需提供一次内容。
type Tool interface {
Name() string
Run(gen *Generator, log *Logger) error
}type ConfigurableTool interface {
Tool
Config() ToolConfig
}type RuleTool interface {
Tool
Rules() []Rule
}
type Rule struct {
Name string // 规则文件名(不含扩展名)
Description string // 简短描述,用于 AI 上下文加载
Globs []string // 触发自动加载的文件模式
AlwaysApply bool // 是否始终包含在上下文中
Content string // 完整的 markdown 文档
}type ToolConfig struct {
OutputSuffix string // 生成文件后缀
Annotations []AnnotationConfig // 注解配置
}
type AnnotationConfig struct {
Name string // 注解名称
Type string // "type" 或 "field"
Doc string // 文档说明
Params *AnnotationParams // 参数配置
LSP *LSPConfig // LSP 集成配置
}
type AnnotationParams struct {
Type interface{} // 参数类型
Values []string // 枚举值
Placeholder string // 占位符
MaxArgs int // 最大参数数量
Docs map[string]string // 枚举值文档
}type Generator struct {
Packages []*Package // 解析后的包信息
}
// 创建生成文件
func (g *Generator) NewGeneratedFile(path string, importPath GoImportPath) *GeneratedFiletype Package struct {
Name string // 包名
PkgPath string // 完整导入路径
Dir string // 目录路径
GoFiles []string // Go 源文件列表
Types []*TypeInfo // 类型信息
Enums []*EnumInfo // 枚举信息
}// 检查文档是否包含指定注解
func HasAnnotation(doc, tool, name string) bool
// 获取 Tool 的配置
func GetToolConfig(t Tool) ToolConfig