mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-10-15 12:15:16 +00:00
## 背景 仓库早已迁移到 GitHub(`github.com/JianFeeeee/HomeAgent`,CI/CD 都在那边跑), gitcode 保留为**国内只读镜像**(`ci.yml` 的 sync-gitcode-main 快进推送)。 但 go.mod 的 module 路径一直是 `gitcode.com/JianFeeeee/...` —— 既与权威源 不符,`meta.SourceURL`(AGPL §13 的源码提供入口)也指向镜像而非实际运行的代码。 ## 关键区分(这是本次改动安全的前提) 两个 module 是**不同**的,影响面差一个数量级: | module | 谁依赖 | 改它的后果 | |---|---|---| | `.../HomeAgent`(主仓) | **只有主仓自己** | 内部重构,零外部影响 | | `.../homeagent-sdk`(SDK 仓) | 主仓 49 文件 + 所有外部插件 | 需重编插件 | ★ 实测确认:**插件不 import 主仓 module**(`strings qq/plugin.bin | grep HomeAgent` = 0), 只依赖 SDK 仓。而插件与内核的边界是 **RPC 方法名字符串** (`plugin.init` / `tool.invoke`…,见 proc/protocol.go),**与 Go module 名无关**。 ⇒ module 改名**不改变任何 wire 协议**,现网已装的插件照常运行。 SDK 的 GitHub 仓名是 `homeagentsdk`(无连字符),module 路径必须与之精确匹配, 否则 `go get` 会因路径不符失败,故取 `github.com/JianFeeeee/homeagentsdk`。 ## 改动 - `go.mod` / `go.sum`:两个 module 路径 + require/replace - 277 个 Go 文件 + Makefile + 打包脚本的 import 与 ldflags 路径 - SDK 仓 `meta.CoreModule`、`tools/hmapdev` 的 module 声明与工程模板 - 对外文档/链接的仓库地址(README、PLUGIN_DEV、OVERVIEW 等) ## 明确**保留** gitcode 的地方(镜像机制,不能动) - `GITCODE_TOKEN`、`GC_URL="…@gitcode.com"`(CI 同步 job) - `gitcode.com/api/v5/...`(release 附件上传) - git remote `gitcode`(镜像拉取/推送) - `docs/zh/ci-cd-runbook.md`(整篇讲镜像运维) ## 验证 - `go build ./...` / `go vet ./...` 绿 - `go test ./... -count=1` → 48 包 ok / 0 FAIL - hmapdev 工具链编译通过(`third_party/homeagent-sdk/tools/hmapdev`) - 全仓残留检查:module 形态的 `gitcode.com/JianFeeeee` = 0 - 镜像机制抽验:GC_URL / @gitcode / api/v5 / remote 均完好 ## 顺带修正 `hmapdev/templates.go` 的注释此前写「gitcode 的模块不在 proxy.golang.org 上」—— module 已迁 GitHub,该论断不再成立。改为如实说明**为何仍默认 replace 到本机 SDK**: 离线可构建、避免版本漂移、内网可用。理由与托管地无关,故 replace 保留。
195 lines
4.8 KiB
Go
195 lines
4.8 KiB
Go
package sdk
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
internalConfig "github.com/JianFeeeee/HomeAgent/internal/config"
|
|
)
|
|
|
|
type settingsImpl struct {
|
|
pluginName string
|
|
reg *internalConfig.ConfigRegistry
|
|
dataDir string
|
|
}
|
|
|
|
func NewSettings(name string, reg *internalConfig.ConfigRegistry) SettingsAPI {
|
|
return &settingsImpl{pluginName: name, reg: reg}
|
|
}
|
|
|
|
// SetDataDir 注入本插件的数据目录(内核装配时调用)。
|
|
func (s *settingsImpl) SetDataDir(dir string) { s.dataDir = dir }
|
|
|
|
// DataDir 返回插件专属数据目录 <data>/plugin_data/<name>,保证目录存在。
|
|
func (s *settingsImpl) DataDir() string { return s.dataDir }
|
|
|
|
func (s *settingsImpl) Get(key string) (interface{}, error) {
|
|
if s.reg == nil {
|
|
return nil, nil
|
|
}
|
|
return s.reg.PluginConfig(s.pluginName).Get(key)
|
|
}
|
|
func (s *settingsImpl) Set(key string, value interface{}) error {
|
|
if s.reg == nil {
|
|
return nil
|
|
}
|
|
return s.reg.PluginConfig(s.pluginName).Set(key, value)
|
|
}
|
|
func (s *settingsImpl) Remove(key string) error {
|
|
if s.reg == nil {
|
|
return nil
|
|
}
|
|
return s.reg.PluginConfig(s.pluginName).Remove(key)
|
|
}
|
|
func (s *settingsImpl) RemoveCore(key string) error {
|
|
if s.reg == nil {
|
|
return nil
|
|
}
|
|
return s.reg.Delete(coreKey(key))
|
|
}
|
|
func (s *settingsImpl) List(prefix string) ([]string, error) {
|
|
if s.reg == nil {
|
|
return nil, nil
|
|
}
|
|
return s.reg.PluginConfig(s.pluginName).List(prefix)
|
|
}
|
|
func coreKey(key string) string {
|
|
if strings.HasPrefix(key, "core.") {
|
|
return key
|
|
}
|
|
return "core." + key
|
|
}
|
|
|
|
func (s *settingsImpl) GetCore(key string) (interface{}, error) {
|
|
if s.reg == nil {
|
|
return nil, nil
|
|
}
|
|
return s.reg.Get(coreKey(key))
|
|
}
|
|
func (s *settingsImpl) SetCore(key string, value interface{}) error {
|
|
if s.reg == nil {
|
|
return nil
|
|
}
|
|
return s.reg.Set(coreKey(key), value)
|
|
}
|
|
func (s *settingsImpl) ListCore(prefix string) ([]string, error) {
|
|
if s.reg == nil {
|
|
return nil, nil
|
|
}
|
|
p := coreKey(prefix)
|
|
if p == "core." {
|
|
p = "core."
|
|
}
|
|
return s.reg.List(p), nil
|
|
}
|
|
func (s *settingsImpl) GetPlugin(plugin, key string) (interface{}, error) {
|
|
if s.reg == nil {
|
|
return nil, nil
|
|
}
|
|
return s.reg.PluginConfig(plugin).Get(key)
|
|
}
|
|
func (s *settingsImpl) SetPlugin(plugin, key string, value interface{}) error {
|
|
if s.reg == nil {
|
|
return nil
|
|
}
|
|
return s.reg.PluginConfig(plugin).Set(key, value)
|
|
}
|
|
func (s *settingsImpl) RemovePlugin(plugin, key string) error {
|
|
if s.reg == nil {
|
|
return nil
|
|
}
|
|
return s.reg.PluginConfig(plugin).Remove(key)
|
|
}
|
|
func (s *settingsImpl) ListPlugin(plugin, prefix string) ([]string, error) {
|
|
if s.reg == nil {
|
|
return nil, nil
|
|
}
|
|
return s.reg.PluginConfig(plugin).List(prefix)
|
|
}
|
|
func (s *settingsImpl) RegisterDef(def ConfigDef) {
|
|
if s.reg == nil {
|
|
return
|
|
}
|
|
s.reg.PluginConfig(s.pluginName).RegisterDef(internalConfig.ConfigDef{
|
|
Key: def.Key, Type: def.Type, DisplayName: def.DisplayName, Description: def.Description,
|
|
Category: def.Category, Options: def.Options,
|
|
Default: stringifyDefault(def.Default),
|
|
})
|
|
}
|
|
func (s *settingsImpl) Defs(prefix string) []*ConfigDef {
|
|
if s.reg == nil {
|
|
return nil
|
|
}
|
|
defs := s.reg.PluginConfig(s.pluginName).ListDefs(prefix)
|
|
out := make([]*ConfigDef, len(defs))
|
|
for i, d := range defs {
|
|
// ConfigDef = pubsdk.ConfigDef (type alias), so direct conversion works
|
|
cpy := ConfigDef{
|
|
Key: d.Key, Type: d.Type, DisplayName: d.DisplayName, Description: d.Description,
|
|
Category: d.Category, Options: d.Options, Default: d.Default,
|
|
}
|
|
out[i] = &cpy
|
|
}
|
|
return out
|
|
}
|
|
func (s *settingsImpl) Dump() map[string]interface{} {
|
|
if s.reg == nil {
|
|
return nil
|
|
}
|
|
return s.reg.Dump()
|
|
}
|
|
func (s *settingsImpl) Plugins() []string {
|
|
if s.reg == nil {
|
|
return nil
|
|
}
|
|
names := s.reg.ListPlugins()
|
|
result := make([]string, 0, len(names)+1)
|
|
result = append(result, "core")
|
|
result = append(result, names...)
|
|
return result
|
|
}
|
|
func (s *settingsImpl) DefsCore(prefix string) []*ConfigDef {
|
|
if s.reg == nil {
|
|
return nil
|
|
}
|
|
// 只取核心命名空间:插件 def 已限定在 "plugin.<name>.",不能当核心 def 返回。
|
|
return mapDefs(s.reg.ListCoreDefs(prefix))
|
|
}
|
|
func (s *settingsImpl) DefsPlugin(plugin, prefix string) []*ConfigDef {
|
|
if s.reg == nil {
|
|
return nil
|
|
}
|
|
return mapDefs(s.reg.PluginConfig(plugin).ListDefs(prefix))
|
|
}
|
|
|
|
func mapDefs(defs []*internalConfig.ConfigDef) []*ConfigDef {
|
|
out := make([]*ConfigDef, len(defs))
|
|
for i, d := range defs {
|
|
out[i] = &ConfigDef{
|
|
Key: d.Key, Type: d.Type, DisplayName: d.DisplayName, Description: d.Description,
|
|
Category: d.Category, Options: d.Options, Default: d.Default,
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
func stringifyDefault(v interface{}) string {
|
|
if v == nil {
|
|
return ""
|
|
}
|
|
switch x := v.(type) {
|
|
case string:
|
|
return x
|
|
case bool:
|
|
if x {
|
|
return "true"
|
|
}
|
|
return "false"
|
|
default:
|
|
return fmt.Sprint(v)
|
|
}
|
|
}
|
|
|
|
// Ensure settingsImpl satisfies SettingsAPI (pubsdk.SettingsAPI via type alias).
|
|
var _ SettingsAPI = (*settingsImpl)(nil)
|