fix: load tool API keys from auth.json at session startup (#563)
Export TOOL_KEYS constant and add loadToolApiKeys() function to load API keys from ~/.gsd/agent/auth.json into environment variables. Called in session_start handler so tool-based extensions (Context7, Brave Search, Jina, Tavily, Groq) work immediately without requiring /gsd config.
This commit is contained in:
parent
c20c57b941
commit
dfd2a1b5b4
2 changed files with 32 additions and 3 deletions
|
|
@ -628,7 +628,12 @@ function serializePreferencesToFrontmatter(prefs: Record<string, unknown>): stri
|
|||
|
||||
// ─── Tool Config Wizard ───────────────────────────────────────────────────────
|
||||
|
||||
const TOOL_KEYS = [
|
||||
/**
|
||||
* Tool API key configurations.
|
||||
* This is the source of truth for tool credentials - used by both the config wizard
|
||||
* and session startup to load keys from auth.json into environment variables.
|
||||
*/
|
||||
export const TOOL_KEYS = [
|
||||
{ id: "tavily", env: "TAVILY_API_KEY", label: "Tavily Search", hint: "tavily.com/app/api-keys" },
|
||||
{ id: "brave", env: "BRAVE_API_KEY", label: "Brave Search", hint: "brave.com/search/api" },
|
||||
{ id: "context7", env: "CONTEXT7_API_KEY", label: "Context7 Docs", hint: "context7.com/dashboard" },
|
||||
|
|
@ -636,6 +641,27 @@ const TOOL_KEYS = [
|
|||
{ id: "groq", env: "GROQ_API_KEY", label: "Groq Voice", hint: "console.groq.com" },
|
||||
] as const;
|
||||
|
||||
/**
|
||||
* Load tool API keys from auth.json into environment variables.
|
||||
* Called at session startup to ensure tools have access to their credentials.
|
||||
*/
|
||||
export function loadToolApiKeys(): void {
|
||||
try {
|
||||
const authPath = join(process.env.HOME ?? "", ".gsd", "agent", "auth.json");
|
||||
if (!existsSync(authPath)) return;
|
||||
|
||||
const auth = AuthStorage.create(authPath);
|
||||
for (const tool of TOOL_KEYS) {
|
||||
const cred = auth.get(tool.id);
|
||||
if (cred && "key" in cred && cred.key && !process.env[tool.env]) {
|
||||
process.env[tool.env] = cred.key;
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// Failed to load tool keys — ignore, they can still be set via env vars
|
||||
}
|
||||
}
|
||||
|
||||
function getConfigAuthStorage(): InstanceType<typeof AuthStorage> {
|
||||
const authPath = join(process.env.HOME ?? "", ".gsd", "agent", "auth.json");
|
||||
mkdirSync(dirname(authPath), { recursive: true });
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import type {
|
|||
} from "@gsd/pi-coding-agent";
|
||||
import { createBashTool, createWriteTool, createReadTool, createEditTool, isToolCallEventType } from "@gsd/pi-coding-agent";
|
||||
|
||||
import { registerGSDCommand } from "./commands.js";
|
||||
import { registerGSDCommand, loadToolApiKeys } from "./commands.js";
|
||||
import { registerExitCommand } from "./exit-command.js";
|
||||
import { registerWorktreeCommand, getWorktreeOriginalCwd, getActiveWorktreeName } from "./worktree-command.js";
|
||||
import { saveFile, formatContinue, loadFile, parseContinue, parseSummary } from "./files.js";
|
||||
|
|
@ -188,7 +188,7 @@ export default function (pi: ExtensionAPI) {
|
|||
};
|
||||
pi.registerTool(dynamicEdit as any);
|
||||
|
||||
// ── session_start: render branded GSD header + remote channel status ──
|
||||
// ── session_start: render branded GSD header + load tool keys + remote status ──
|
||||
pi.on("session_start", async (_event, ctx) => {
|
||||
// Theme access throws in RPC mode (no TUI) — header is decorative, skip it
|
||||
try {
|
||||
|
|
@ -204,6 +204,9 @@ export default function (pi: ExtensionAPI) {
|
|||
// RPC mode — no TUI, skip header rendering
|
||||
}
|
||||
|
||||
// Load tool API keys from auth.json into environment
|
||||
loadToolApiKeys();
|
||||
|
||||
// Notify remote questions status if configured
|
||||
try {
|
||||
const [{ getRemoteConfigStatus }, { getLatestPromptSummary }] = await Promise.all([
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue