UNPKG

@phren/cli

Version:

Knowledge layer for AI agents - CLI, MCP server, and data layer

40 lines (39 loc) • 2.21 kB
import { existsSync } from "node:fs"; import path from "node:path"; import { z } from "zod"; import { homeDir } from "../home-paths.js"; import { claudeHomes } from "./claude-accounts.js"; import { BridgeError, bridgeRoot } from "./protocol.js"; import { terminalProvider } from "./terminal.js"; export const accountAddSchema = z.object({ slug: z.string().regex(/^[a-z0-9][a-z0-9-]{0,31}$/) }).strict(); const adding = new Set(); const pendingPanes = new Map(); /** Open a shell for the owner to complete the existing interactive flow. */ export async function addClaudeAccount(input, server) { const { slug } = accountAddSchema.parse(input); const key = `${bridgeRoot()}\0${slug}`; if (adding.has(key) || claudeHomes().some(home => home.id === slug) || existsSync(path.join(homeDir(), `.claude-${slug}`))) throw new BridgeError(409, "That Claude account already exists or is being added."); adding.add(key); try { const terminal = terminalProvider(); if (!terminal.shellCommand) throw new BridgeError(503, "This terminal cannot open an interactive account login."); const pending = pendingPanes.get(key); if (pending && (await terminal.listPanes(pending.server)).some(pane => pane.pane === pending.pane)) throw new BridgeError(409, "That Claude account is already being added in an open pane."); pendingPanes.delete(key); const before = new Set((await terminal.listPanes(server)).map(pane => pane.pane)); await terminal.create(server, { label: `Add Claude account ${slug}`, cwd: homeDir() }); const created = (await terminal.listPanes(server)).filter(pane => !before.has(pane.pane)); if (created.length !== 1) throw new BridgeError(409, "The new account pane could not be identified safely."); const pane = created[0]; pendingPanes.set(key, { server, pane: pane.pane }); await terminal.shellCommand(server, pane.pane, `phren bridge accounts add -- '${slug}'`); return { target: { server, workspace: pane.workspace, tab: pane.tab, pane: pane.pane, source: "claude" }, terminalOnly: true }; } finally { adding.delete(key); } }