Official
claude
Claude Code agent provider: runs the Claude Code CLI headless for each account.
The app opens the listing; nothing installs until an agent in your Plugins workspace has read the files and you enable the plugin. In a terminal: cvg install convergence/claude@0.2.0
Permissions in 0.2.0
Files
instances.ts2.6 KB
// Claude accounts, each served as its own Convergence agent (the Rust
// `instances.rs`).
//
// One Claude Code install can hold several logins, kept apart by
// `CLAUDE_CONFIG_DIR`. The accounts are the plugin's stored value
// `instances` (plugin storage, key `instances`), a list like
//
// [{ "id": "personal", "name": "Claude Personal", "configDir": "~/.claude_personal" },
// { "id": "openrouter", "configDir": "~/.claude_openrouter",
// "env": { "ANTHROPIC_BASE_URL": "https://openrouter.ai/api" } }]
//
// Each entry becomes the agent id `claude:<id>`, beside the default
// `claude`. A configuration directory holds the login, the settings and
// the stored transcripts, so two accounts never see each other's work:
// `continuationKey` is that directory. `env` is how a router preset is
// expressed; `HOME` and `CLAUDE_CONFIG_DIR` in it are refused.
import { objectOf } from "./wire.ts";
export interface Instance {
id: string;
name?: string | null;
configDir?: string | null;
env?: Record<string, string>;
}
/// The default account, which uses the ambient environment.
export function defaultAccount(): Instance {
return { id: "", name: null, configDir: null, env: {} };
}
export function agentId(instance: Instance) {
return instance.id ? `claude:${instance.id}` : "claude";
}
export function displayName(instance: Instance) {
if (typeof instance.name === "string" && instance.name.trim()) return instance.name;
return instance.id ? `Claude Code (${instance.id})` : "Claude Code";
}
/// Every configured account, the default one first. Entries with a
/// missing or repeated id are left out (and reported), never the default.
export function parseInstances(value: unknown) {
const all = [defaultAccount()];
if (value === null || value === undefined) return all;
if (!Array.isArray(value)) {
console.warn("the stored claude instances are not a list; only the default account is served");
return all;
}
for (const raw of value) {
const entry = objectOf(raw);
const id = typeof entry?.id === "string" ? entry.id.trim() : "";
if (!id || all.some((known) => known.id === id)) {
console.warn("ignoring a claude instance with a missing or repeated id");
continue;
}
const env: Record<string, string> = {};
if (entry.env && typeof entry.env === "object") {
for (const [name, text] of Object.entries(entry.env)) if (typeof text === "string") env[name] = text;
}
all.push({
id,
name: typeof entry.name === "string" ? entry.name : null,
configDir: typeof entry.configDir === "string" ? entry.configDir : null,
env,
});
}
return all;
}Versions
| Version | Published | Plugin API | Size | Permissions | Status |
|---|---|---|---|---|---|
| 0.2.0latest | Oct 5, 2026 | >=2 <3 | 128.7 KB | 4 permissions | Listed |
No comments yet.