Files
HomeAgent/internal/plugin/proc/corehandler_secrets.go
JianFeeeee 3f834794c5 refactor: SDK module 路径统一改为 hologramagentsdk(59 文件 + go.mod)
## 为什么必须做

SDK 仓(独立仓库)已把 module 从 `github.com/JianFeeeee/homeagentsdk`
改名为 `hologramagentsdk`。主仓通过 `replace` 直接引用它的**物理目录**:

    replace github.com/JianFeeeee/homeagentsdk => ./third_party/homeagent-sdk

一旦 SDK 侧改成新 module 名,主仓立刻炸:

    go: ./third_party/homeagent-sdk@ used for two different module paths
        (github.com/JianFeeeee/hologramagentsdk and github.com/JianFeeeee/homeagentsdk)

Go **不允许**同一目录被两个 module 路径 replace。所以不能"新旧并存",
只能把主仓 59 个文件的 import 全部改到新名,并删掉旧 replace。

## 一个被证伪的前提

我最初按"third_party/homeagent-sdk 是独立仓库,不能在此仓修改其源码"
来处理,并因此判断两个仓的改动可以隔离。实际上主仓是靠 `replace` 指向
该目录的物理副本 —— **两个仓的改动不可能真正隔离**:SDK 侧改 module 名,
主仓必然跟着改 import。

这个前提应该在做任何改动之前用 `go list -m` 验证,而不是假设。

## 连带修掉两处

| 缺陷 | 性质 |
|---|---|
| `TestLuaSDKMockSingleSource` 失败 | SDK 的 `sdk/lua/sdk.lua` 变了,主仓内嵌副本未同步(跑 `scripts/sync-lua-sdk.sh` 修复) |
| `sdkModuleNames` 分散两处 | 已在 SDK 仓合并为单一数据源(见 SDK 仓 725732b) |

第一条是**副本一致性判据抓到的**,不是我自己发现的 —— 这类判据的价值在此:
两个仓必然有副本,靠人记住"改了 A 要同步 B"是做不到的。

## 验证

- `go build ./...` / `go vet ./...` 干净
- `go test ./... -count=1`:**58 包 0 失败**
- `internal/plugin`(Lua SDK 副本一致性)+ `internal/sdk` 全绿
- 主仓 `third_party/homeagent-sdk/` 与 SDK 仓 `main` 无差异
2026-10-23 15:51:02 +08:00

120 lines
3.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package proc
// 变量库的 proc 桥(内核侧)。
//
// ## 与 settings 的分工
//
// settings —— **每个插件自己的**配置(各自的 config_<name> 表)
// secrets —— **全进程共享的**变量库(security.Global() 单例)
//
// 这个区别是本质的:变量库全局唯一(设计 S10),主/子/驻留子 agent
// 与全部插件共用同一套别名。所以它不该走 settings 的命名空间机制。
//
// ## 为何需要这层桥
//
// 外部插件是**子进程**,它的 `sdk.Secrets()` 拿到的是模板里的
// `procSecrets`(见 templates/proc_main.go.tmpl),它把调用转成 RPC
// 发到这里。这条链路有 4 个地方要同时改(协议常量 / 路由 / 分发 / 能力表),
// 少一处就报 "未知 method" —— 真机 e2e 会立刻发现(本次已踩过一次)。
import (
"encoding/base64"
"encoding/json"
"fmt"
pubsdk "github.com/JianFeeeee/hologramagentsdk/sdk"
)
func (h *coreHandler) secrets(method string, params json.RawMessage) (interface{}, error) {
sec := h.sdk.Secrets()
if sec == nil {
return nil, errUnavailable("secrets")
}
switch method {
case MethodSecretsAvailable:
// 明确的可用性查询(不靠 List 推断 —— 见 secrets_impl 的注释)
return map[string]interface{}{"available": sec.Available()}, nil
case MethodSecretsStore:
var p struct {
Value string `json:"value"`
Note string `json:"note"`
}
if err := unmarshal(params, &p); err != nil {
return nil, err
}
alias, err := sec.Store(p.Value, p.Note)
if err != nil {
return nil, err
}
// ★ 只回别名,不回显明文(与 SDK 的契约一致)
return map[string]interface{}{"alias": alias}, nil
case MethodSecretsList:
infos := sec.List()
if infos == nil {
infos = []pubsdk.SecretInfo{}
}
return map[string]interface{}{"infos": infos}, nil
case MethodSecretsForget:
var p struct {
Alias string `json:"alias"`
}
if err := unmarshal(params, &p); err != nil {
return nil, err
}
return nil, sec.Forget(p.Alias)
case MethodSecretsFill:
var p struct {
Text string `json:"text"`
}
if err := unmarshal(params, &p); err != nil {
return nil, err
}
out, n, aliases := sec.Fill(p.Text)
if aliases == nil {
aliases = []string{}
}
return map[string]interface{}{
"text": out, "replaced": n, "aliases": aliases,
}, nil
case MethodSecretsEncrypt:
// 二进制负载经 base64 过 RPC(JSON 不能直接带 bytes)
var p struct {
PlainB64 string `json:"plain_b64"`
}
if err := unmarshal(params, &p); err != nil {
return nil, err
}
raw, err := base64.StdEncoding.DecodeString(p.PlainB64)
if err != nil {
return nil, fmt.Errorf("secrets.encrypt: base64 解码失败: %w", err)
}
enc, err := sec.Encrypt(raw)
if err != nil {
return nil, err
}
return map[string]interface{}{"encrypted": enc}, nil
case MethodSecretsDecrypt:
var p struct {
Stored string `json:"stored"`
}
if err := unmarshal(params, &p); err != nil {
return nil, err
}
plain, err := sec.Decrypt(p.Stored)
if err != nil {
return nil, err
}
return map[string]interface{}{
"plain_b64": base64.StdEncoding.EncodeToString(plain),
}, nil
}
return nil, fmt.Errorf("未知 secrets method: %s", method)
}