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

  • Provide agents agents.provideMediumAdds agents to the app.Provide the Claude Code agent and pass its tool calls to plugin tools
  • Run named programs processMediumStarts the listed programs.Run the Claude Code CLI (sessions, sign-in, `claude update`), and ask the npm installation that owns it about a newer versionPrograms: claudenpm
  • Read files fs.readMediumReads files in the listed places.Read Claude Code's sessions, settings and skills (in ~/.claude, other accounts' ~/.claude-* folders, the shared skills and the folder you choose in Settings), the project's .claude folder, the administrator's skill policy, and once, what the previous provider keptPlaces: ~/.claude/**~/.claude*/**~/.agents/skills/**the open workspaceits own data folder/Library/Application Support/ClaudeCode/managed-settings.json/etc/claude-code/managed-settings.json${settings.configDir}
  • Environment variables envMediumReads the listed environment variables.Find Claude Code's configuration directory, and the launch settings you set in CLAUDE_* variables (extra arguments, MCP servers, setting sources, appended system prompt, extra folders)Variables: HOMECLAUDE_CONFIG_DIRCLAUDE_EXTRA_ARGSCLAUDE_MCP_CONFIGCLAUDE_STRICT_MCP_CONFIGCLAUDE_SETTING_SOURCESCLAUDE_APPEND_SYSTEM_PROMPTCLAUDE_ADD_DIRS

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

VersionPublishedPlugin APISizePermissionsStatus
0.2.0latestOct 5, 2026>=2 <3128.7 KB4 permissionsListed

Reviews and comments

0 threads · 0 reviews

No comments yet.