diff --git a/plugin/index.ts b/plugin/index.ts index b792ba1..142b443 100644 --- a/plugin/index.ts +++ b/plugin/index.ts @@ -940,9 +940,10 @@ function register(api: PluginAPI): void { // ---- dynamic-kb-* family (DESIGN-DYNAMIC-BLOCK.md §3.3 / §4.4) // Cross-runtime mirror of HarborForge.PlexumPlugin/internal/tools/kb.go + - // /internal/kbblock + /internal/kbclient. v1 auth = plugin-level apiKey - // via Bearer (per-agent hf-token resolution is a TODO matching the - // Plexum side). + // /internal/kbblock + /internal/kbclient. v1 auth: per-agent hf-token + // resolved via secret-mgr (matches the rest of the Hangman-Lab + // openclaw plugins). Falls back to plugin-level apiKey when no + // per-agent token is configured. const kbCfg = resolveConfig(); const kbBackendUrl = typeof kbCfg?.backendUrl === 'string' && kbCfg.backendUrl @@ -951,8 +952,24 @@ function register(api: PluginAPI): void { const kbApiKey = typeof kbCfg?.apiKey === 'string' ? (kbCfg.apiKey as string) : ''; const kbDeps: KBDeps = { client: kbApiKey ? new KBClient(kbBackendUrl, kbApiKey) : null, - tokenFor: null, - makeClient: null, + tokenFor: async (agentId: string): Promise => { + // Per-agent hf-token via secret-mgr (decision #20 mirror). + // Spawn the existing secret-mgr binary with AGENT_ID set; same + // path ClawSkills `tc-ctrl get-token` workflow shells to. + try { + const { spawnSync } = await import('node:child_process'); + const res = spawnSync('secret-mgr', ['get-secret', '--key', 'hf-token'], { + env: { ...process.env, AGENT_ID: agentId }, + encoding: 'utf8', + timeout: 5000, + }); + if (res.status === 0 && res.stdout.trim()) return res.stdout.trim(); + return null; + } catch { + return null; + } + }, + makeClient: (token: string) => new KBClient(kbBackendUrl, token), turnFor: () => 0, };