// agent-system:单二进制服务(HTTP/SSE + 内嵌前端 + 双档存储)。 // 部署约束(设计 4.1 原则 8):非容器化;拷贝即运行。 // 嵌入式档默认(SQLite + 本地对象目录,零外部服务);--dsn 切换 PostgreSQL 档 //(多用户/多实例,认证默认开启,apikey 子命令管理密钥)。 package main import ( "encoding/json" "flag" "fmt" "os" "agent-system-backend/internal/app" ) var version = "0.1.0-dev" func main() { if len(os.Args) > 1 { switch os.Args[1] { case "version", "--version": fmt.Println("agent-system", version) return case "serve": os.Args = append([]string{os.Args[0]}, os.Args[2:]...) case "apikey": os.Exit(runAPIKey(os.Args[2:])) } } fs := flag.NewFlagSet("serve", flag.ExitOnError) addr := fs.String("addr", "127.0.0.1:8787", "监听地址") data := fs.String("data", "./data", "数据目录(SQLite 与工件对象目录)") pluginsDir := fs.String("plugins", "./plugins", "插件目录(声明资产热加载)") mock := fs.Bool("mock", false, "演示模式(等同 runtime.mock=true,不调用模型)") dsn := fs.String("dsn", "", "PostgreSQL 档 DSN(空 = 嵌入式 SQLite 档)") artifacts := fs.String("artifacts", "", "工件对象目录(默认 /artifacts;PG 档多实例时指向共享卷)") auth := fs.String("auth", "auto", "API key 认证:auto(PG 档开、嵌入式关)| on | off") fs.Parse(os.Args[1:]) if err := app.Run(app.Options{ Addr: *addr, DataDir: *data, PluginsDir: *pluginsDir, ForceMock: *mock, StorageDSN: *dsn, ArtifactsDir: *artifacts, AuthMode: *auth, }); err != nil { fmt.Fprintln(os.Stderr, "agent-system:", err) os.Exit(1) } } // runAPIKey:密钥管理子命令(create/list/revoke)。 func runAPIKey(args []string) int { // 子命令在前、flag 在后:先剥出子命令再解析(Go flag 遇位置参数即停)。 if len(args) == 0 { fmt.Fprintln(os.Stderr, "用法:agent-system apikey [--owner x --name y]") return 2 } sub := args[0] fs := flag.NewFlagSet("apikey "+sub, flag.ExitOnError) data := fs.String("data", "./data", "数据目录") dsn := fs.String("dsn", "", "PostgreSQL 档 DSN(空 = 嵌入式档)") owner := fs.String("owner", "", "租户名(owner)") name := fs.String("name", "default", "密钥名称") fs.Parse(args[1:]) if *owner == "" { fmt.Fprintln(os.Stderr, "apikey: --owner 必填") return 2 } switch sub { case "create": key, err := app.CreateAPIKey(*dsn, *data, *owner, *name) if err != nil { fmt.Fprintln(os.Stderr, "apikey create:", err) return 1 } // 明文仅此一次输出;库中只存 SHA-256 摘要。 fmt.Println(key) return 0 case "list": keys, err := app.ListAPIKeys(*dsn, *data, *owner) if err != nil { fmt.Fprintln(os.Stderr, "apikey list:", err) return 1 } out, _ := json.MarshalIndent(keys, "", " ") fmt.Println(string(out)) return 0 case "revoke": ok, err := app.RevokeAPIKey(*dsn, *data, *owner, *name) if err != nil { fmt.Fprintln(os.Stderr, "apikey revoke:", err) return 1 } if !ok { fmt.Fprintf(os.Stderr, "apikey revoke: 未找到 owner=%s name=%s 的有效密钥\n", *owner, *name) return 1 } fmt.Println("revoked") return 0 default: fmt.Fprintln(os.Stderr, "apikey: 未知子命令", sub) return 2 } }