import type { CliAdapter, CliId } from './types.js'; /** The default Claude Code data root (`CLAUDE_CONFIG_DIR` equivalent): where * `projects/`, `sessions/`, `tasks/`, `keybindings.json` and `settings.json` * live. Claude-family forks (e.g. Seed CLI) relocate this — every helper below * takes an optional `dataDir` so the same machinery drives both. Defaulting to * `~/.claude` keeps all existing call sites byte-for-byte unchanged. */ export declare const DEFAULT_CLAUDE_DATA_DIR: string; /** Maximum UTF-8 payload for one tmux `send-keys -l` burst. A whole long line * is enough to trip Claude Code's paste detector even when line-to-line sends * are throttled, so split every non-empty line into small, paced chunks. */ export declare const CLAUDE_INPUT_CHUNK_BYTES = 96; /** Split without cutting a Unicode code point or exceeding the byte budget. */ export declare function chunkTextByUtf8Bytes(text: string, maxBytes?: number): string[]; /** Resolve the JSONL transcript path Claude Code writes user/assistant turns to. * Claude Code's project-hash scheme replaces every non-[A-Za-z0-9-] char with `-` * (observed: `/foo/life_workspace` → `-foo-life-workspace`; `/`, `.`, `_` all become `-`). * Always operates on realpath(cwd) — see realpathCwd above. */ export declare function claudeJsonlPathForSession(sessionId: string, cwd: string, dataDir?: string): string; /** The `/projects/` dir holding this cwd's transcripts (and its * `memory/` subdir). Read isolation ALLOWs this back in under the whole-process * Seatbelt wrapper — the projects tree is denied, then the bot's OWN project dir * is re-allowed so its main process can read transcripts (resume) + memory, while * every OTHER bot's project dir stays denied. Always uses realpath(cwd). */ export declare function claudeProjectDir(cwd: string, dataDir?: string): string; export interface ClaudeResumeTargetSyncResult { targetPath: string; sourcePath?: string; copied: boolean; } /** * Claude stores a session transcript under the hash of the cwd where that * session last ran. Botmux's `/cd` deliberately keeps the logical session id, * so a later `claude --resume ` from the new cwd would otherwise look in a * different project directory and fail twice before falling back to a clean * session. * * Before a cold resume, find the newest copy of this exact session id anywhere * under the effective Claude data root and mirror it into the new cwd's project * directory. Copies are retained in older project directories because they are * useful native Claude history; choosing the newest candidate on every resume * prevents a later `/cd` back to an earlier cwd from reviving a stale branch. * * The Claude data root is writable by the sandboxed CLI while this helper runs * in the unsandboxed worker. Treat every scanned leaf as hostile: UUID-gate the * filename, reject symlink/non-regular source and target entries, enforce * realpath containment, and atomically replace the target via a private temp * inode so copy cannot read or write through a child-planted symlink. */ export declare function syncClaudeResumeTargetToCwd(sessionId: string, cwd: string, dataDir?: string): ClaudeResumeTargetSyncResult; /** Returns the absolute path to Claude Code's per-process session state file. * Claude writes `{pid, sessionId, cwd, procStart, status, updatedAt, ...}` * here. Empirical scope (Claude Code 2.1.123): `status` and `updatedAt` * refresh on every state change, but `sessionId` is written ONCE at * process start. `--resume` is a fresh spawn → fresh pid file with the * resumed id; in-pane `/clear` does NOT rewrite the pid file's * `sessionId` even though it rotates the on-disk jsonl. Callers that * rely on this for rotation tracking must therefore treat a "matching * sessionId" answer as "no spawn-time rotation observed", not "no * rotation at all" — the latter requires fingerprint corroboration. */ export declare function claudePidStatePath(pid: number, dataDir?: string): string; /** Resolve Claude Code's authoritative current session id via * ~/.claude/sessions/.json. Validates pid + sessionId UUID + cwd so a * stale or unrelated pid file can't redirect us to the wrong jsonl. On Linux * also matches procStart against /proc//stat to reject PID reuse. If * procStart is present but cannot be verified on Linux, fail closed; callers * fall back to fingerprint detection. */ export declare function resolveJsonlFromPid(pid: number, expectedCwd: string, dataDir?: string): { path: string; cliSessionId: string; } | null; /** Linux-only: probe `/proc//fd` for any signal that reveals Claude's * CURRENT sessionId — not the spawn-time one the pid file records. Two * signals are checked: * 1. Direct `.jsonl` symlinks under `~/.claude/projects/...` — Claude * opens-writes-closes per event, so this only hits if the probe * lands during a write window. * 2. `~/.claude/tasks/(/...)` symlinks — Claude holds the * tasks directory and its `.lock` file open continuously for the * duration of the active session, so this signal is reliable even * between writes. This is the path that catches in-pane `/clear` * rotations the pid file can't see (pid file's `sessionId` is set * once at process start; tasks dir tracks every rotation). * Returns deduplicated sessionIds in arbitrary order; caller picks one * (typically by mtime of the corresponding jsonl). Returns [] on * non-Linux platforms or if /proc lookup fails. */ export declare function findOpenClaudeSessionIds(pid: number, dataDir?: string): string[]; /** A member of the Claude-family CLIs: Claude Code itself and forks that share * its on-disk session layout (per-project JSONL transcripts, `sessions/.json` * pid-state, `tasks/` fd locks, keybindings.json, settings.json hooks) but * relocate the data root and/or rename the binary. Seed CLI * is one such fork — it reuses * this entire adapter, only swapping `dataDir`/`stateJsonPath`/binary. */ export interface ClaudeFamilyVariant { /** CliId for this variant (`claude-code`, `seed`, …). */ readonly id: CliId; /** Binary name printed in the user-facing `buildResumeCommand` handoff. */ readonly resumeBin: string; /** Data root: `projects/`, `sessions/`, `tasks/`, `keybindings.json`, * `settings.json`. `~/.claude` for Claude Code; Seed's `.claude-runtime`. */ readonly dataDir: string; /** Path to the `.claude.json` state / folder-trust file. Lives at * `~/.claude.json` (home) for Claude Code, but *inside* the data root for * forks that set CLAUDE_CONFIG_DIR — so it can't be derived from dataDir. */ readonly stateJsonPath: string; /** Env injected at spawn so the forked CLI actually writes to `dataDir`. * undefined for Claude Code, which already * defaults to ~/.claude. */ readonly spawnEnv?: Readonly>; /** Curated `botmux setup` model candidates. Claude Code lists Anthropic * aliases; forks whose model set is gateway-defined * pass undefined so setup skips the prompt. */ readonly modelChoices?: readonly string[]; /** Auth/login paths kept real+writable in the file sandbox (see CliAdapter.authPaths). */ readonly authPaths?: readonly string[]; /** Opt in only after this concrete fork passes the terminal contract. */ readonly reliableTurnTerminal?: boolean; } export declare function createClaudeCodeAdapter(pathOverride?: string): CliAdapter; export declare function createClaudeFamilyAdapter(variant: ClaudeFamilyVariant, rawBin: string): CliAdapter; export declare const create: typeof createClaudeCodeAdapter; //# sourceMappingURL=claude-code.d.ts.map