feat: v0.7.0 — secrets partagés par provider : am providers set-token/token, namespace keyring providers/<nom>, résolution @secret en cascade agent → provider (closes #89)

Corrige au passage deux bugs du keyring (#36) : features natifs manquants du crate keyring (set() no-op silencieux, rien ne persistait) + index __index__ jamais purgé au remove (list fantômes).
This commit is contained in:
2026-08-19 16:09:34 -04:00
parent d38cd7352f
commit 7312e6ceab
15 changed files with 400 additions and 54 deletions
+14 -5
View File
@@ -664,17 +664,22 @@ pub static HELP_SPECS: &[HelpSpec] = &[
name: "secret",
category: "Commands",
usage: "secret {flags} <set|unset|list>",
about: "Manage secrets in the OS keyring (values never shown or logged).",
about: "Manage secrets in the OS keyring (values never shown or logged). Secrets are scoped to an agent (agent/NAME) or to a provider (providers/<p>/<VAR>, shared by every agent of that provider, issue #89).",
search_terms: &["keyring", "token", "password"],
flags: &[],
subcommands: &[
("set", "Store a secret for an agent"),
("set", "Store a secret for an agent or a provider"),
("unset", "Remove a secret"),
],
parameters: &[],
parameters: &[
HelpParam { name: "--agent", typ: "string", desc: "Agent the secret belongs to" },
HelpParam { name: "--provider", typ: "string", desc: "Provider the secret belongs to (issue #89)" },
HelpParam { name: "--value", typ: "string", desc: "Secret value (never logged)" },
],
io: None,
examples: &[
HelpExample { desc: "Store a token.", code: "secret set OPENAI_KEY --agent claude-code --value sk-..." },
HelpExample { desc: "Store a provider token.", code: "secret set api_key --provider openai --value sk-... (or: providers set-token openai)" },
HelpExample { desc: "Use it at launch.", code: "start claude-code --env OPENAI_KEY=@secret" },
],
},
@@ -682,12 +687,13 @@ pub static HELP_SPECS: &[HelpSpec] = &[
name: "providers",
category: "Commands",
usage: "providers {flags} <list|show|add|remove|default>",
about: "Manage the LLM provider registry: base URLs, models, the default model and the default provider (issue #88). Tokens are never stored here — they live in the OS keyring (issue #89).",
search_terms: &["provider", "token", "registry", "llm", "model", "api"],
about: "Manage the LLM provider registry: base URLs, models, the default model and the default provider (issue #88). Tokens are never stored here — they live in the OS keyring under providers/<name>/api_key (issue #89).",
search_terms: &["provider", "token", "registry", "llm", "model", "api", "keyring"],
flags: &[
HelpFlag { short: "", long: "--base-url", value: "URL", desc: "Base URL of the provider API (add)" },
HelpFlag { short: "", long: "--model", value: "MODEL", desc: "Model used by default for this provider (add)" },
HelpFlag { short: "", long: "--models", value: "MODELS", desc: "Comma-separated model list (add)" },
HelpFlag { short: "", long: "--value", value: "VALUE", desc: "Token value (set-token; never logged)" },
],
subcommands: &[
("list", "List the registered providers (default starred)"),
@@ -695,12 +701,15 @@ pub static HELP_SPECS: &[HelpSpec] = &[
("add", "Register or update a provider"),
("remove", "Remove a provider"),
("default", "Set the default provider"),
("set-token", "Store the provider token in the OS keyring (issue #89)"),
("token", "Check whether a provider token exists (value never shown)"),
],
parameters: &[],
io: None,
examples: &[
HelpExample { desc: "List the providers.", code: "providers" },
HelpExample { desc: "Register DeepSeek.", code: "providers add deepseek --base-url https://api.deepseek.com --model deepseek-chat --models deepseek-chat,deepseek-reasoner" },
HelpExample { desc: "Store its shared token.", code: "providers set-token deepseek --value sk-..." },
HelpExample { desc: "Make it the default.", code: "providers default deepseek" },
HelpExample { desc: "Machine-readable list.", code: "providers --json" },
],