Skip to content

Latest commit

 

History

History
417 lines (313 loc) · 9.13 KB

File metadata and controls

417 lines (313 loc) · 9.13 KB

DevGen 插件系统

中文 | 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 框架

所有插件都需要实现 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

Source 类型(推荐)

最简单的方式,无需预编译:

// 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"

Go Plugin 类型

适合需要最高性能的生产环境:

// 与 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 扩展集成

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 Rules 集成(可选)

为了让 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 应包含:

  1. 何时使用 - 使用场景和案例
  2. 快速开始 - 分步入门指南
  3. 注解参考 - 详细的注解文档
  4. 完整示例 - 完整的工作示例
  5. 常见错误 - 故障排除指南,包含 ❌/✅ 对比

参考 enumgen 规则validategen 规则 的实现。

规则如何与不同 AI 助手协作

每个 AI 助手使用不同的 frontmatter 格式。devgen 会自动适配你的规则:

助手 Frontmatter 格式
Kiro inclusion: fileMatch + fileMatchPattern: ['**/*.go']
CodeBuddy description: "..." + globs: **/*.go + alwaysApply: false
Cursor description: "..." + globs: **/*.go + alwaysApply: false

适配器系统会自动处理转换 - 你只需提供一次内容。

API 参考

genkit.Tool

type Tool interface {
    Name() string
    Run(gen *Generator, log *Logger) error
}

genkit.ConfigurableTool

type ConfigurableTool interface {
    Tool
    Config() ToolConfig
}

genkit.RuleTool

type RuleTool interface {
    Tool
    Rules() []Rule
}

type Rule struct {
    Name        string   // 规则文件名(不含扩展名)
    Description string   // 简短描述,用于 AI 上下文加载
    Globs       []string // 触发自动加载的文件模式
    AlwaysApply bool     // 是否始终包含在上下文中
    Content     string   // 完整的 markdown 文档
}

genkit.ToolConfig

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 // 枚举值文档
}

genkit.Generator

type Generator struct {
    Packages []*Package  // 解析后的包信息
}

// 创建生成文件
func (g *Generator) NewGeneratedFile(path string, importPath GoImportPath) *GeneratedFile

genkit.Package

type 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