Why: Allow consumers to download an immutable module revision without nested source checkouts or local path replacements. Evidence: SELF package tests and the prior canonical-path rejection are recorded in the Dev dependency-workspace task card; remote consumption is replayed against the committed candidate. Impact: Change the module identity and its Go imports while preserving API behavior. Existing historical submodule revisions remain buildable. Refs: Versioned dependencies U1/U3; feature/dependency-workspace
42 lines
1.3 KiB
Go
42 lines
1.3 KiB
Go
package plugins
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
core "git-ssh.u1680832.nyat.app/weichen/Agent-System-Core.git"
|
|
)
|
|
|
|
// agentBannedKeys 是插件代理声明禁带的键:钩子、MCP 与权限模式归宿主与
|
|
// 基座,插件画像只能声明身份与工具面(N1 WP1 验收条款)。
|
|
var agentBannedKeys = map[string]bool{
|
|
"hooks": true,
|
|
"mcp": true,
|
|
"permissionMode": true,
|
|
}
|
|
|
|
// parseAgentAsset 解析 agents/ 资产:禁带键定位到字段、未知键拒绝、
|
|
// id 必填。任一违规由调用方整批拒绝该插件(fail-closed)。
|
|
func parseAgentAsset(raw []byte) (core.PluginAgentDecl, error) {
|
|
var probe map[string]json.RawMessage
|
|
if err := json.Unmarshal(raw, &probe); err != nil {
|
|
return core.PluginAgentDecl{}, fmt.Errorf("agent json: %w", err)
|
|
}
|
|
for key := range probe {
|
|
if agentBannedKeys[key] {
|
|
return core.PluginAgentDecl{}, fmt.Errorf("插件代理不得声明 %s", key)
|
|
}
|
|
}
|
|
dec := json.NewDecoder(bytes.NewReader(raw))
|
|
dec.DisallowUnknownFields()
|
|
var item core.PluginAgentDecl
|
|
if err := dec.Decode(&item); err != nil {
|
|
return core.PluginAgentDecl{}, fmt.Errorf("agent json: %w", err)
|
|
}
|
|
if item.ID == "" {
|
|
return core.PluginAgentDecl{}, fmt.Errorf("agent missing id")
|
|
}
|
|
return item, nil
|
|
}
|