Spec: /opt/pulse-vault/pulse-null/specs/in-progress/agent-cli-adapters-spec.md
pulse-null's only agentic-CLI provider is named claude-code and Claude's shapes leak through every generic path (claude_bin, ClaudeCliError, claude_code_bootstrap, .claude/settings.json, and a generated .recall-echo.toml that hardcodes provider = "claude-code" for an entity that runs Grok through a bash shim). This introduces one generic cli provider behind a CliAdapter trait with claude, grok (the shim ported to Rust) and codex adapters; config becomes provider = "cli" + adapter = … + cli_bin with one-release aliases for the old keys; each adapter owns its argv, output parsing, probes, refusal signature, env hygiene and entity integration (instruction file, hooks); the chosen adapter drives recall-echo's [llm] provider and [capture] sources; a CI lint rejects vendor names in generic code. Rule: never a provider name in a generic flow, logic, hook or config. Stacked on PN-104 (#104 / PR #105).
Spec: /opt/pulse-vault/pulse-null/specs/in-progress/agent-cli-adapters-spec.md
pulse-null's only agentic-CLI provider is named
claude-codeand Claude's shapes leak through every generic path (claude_bin,ClaudeCliError,claude_code_bootstrap,.claude/settings.json, and a generated.recall-echo.tomlthat hardcodesprovider = "claude-code"for an entity that runs Grok through a bash shim). This introduces one genericcliprovider behind aCliAdaptertrait withclaude,grok(the shim ported to Rust) andcodexadapters; config becomesprovider = "cli"+adapter = …+cli_binwith one-release aliases for the old keys; each adapter owns its argv, output parsing, probes, refusal signature, env hygiene and entity integration (instruction file, hooks); the chosen adapter drives recall-echo's[llm] providerand[capture] sources; a CI lint rejects vendor names in generic code. Rule: never a provider name in a generic flow, logic, hook or config. Stacked on PN-104 (#104 / PR #105).