UNPKG

@essentialai/cogent-bridge

Version:

Cogent Bridge — cross-agent comms for Claude Code, OpenAI Codex and Slack. Codex users: install with `curl -fsSL https://cogent.tools/install.sh | sh`, then start with `cogent-codex` for real-time peer wake.

134 lines • 7.25 kB
import { CliExecResult } from "../types.js"; /** * Every transcript directory that could hold this cwd's sessions. * * 🔴 WHY THIS IS NOT ONE PATH. Claude Code names a project dir by replacing each * non-alphanumeric char of the cwd with "-", so EVERY representation of the same * directory encodes to a DIFFERENT name: a trailing slash, a "." segment, or a * symlinked path (macOS `/tmp` -> `/private/tmp`, `/var` -> `/private/var`) each * produce a dir that does not exist. The cwd here is a string the AGENT supplied * to cogent_register_peer — it is not guaranteed to be the canonical form. * * That mismatch is how a fresh dev machine got ZERO candidates from its very * first register (2026-08-31) and refused every wake thereafter. The Codex rail * had already canonicalised for this reason (codex-cli.ts `cwdCanonicals`); this * is the Claude Code rail reaching parity. * * Exported so callers can LOG what was probed — a miss used to be indistinguishable * from an empty dir, which is what made the failure undiagnosable from the logs. */ export declare function projectDirsFor(cwd: string): Promise<string[]>; /** * Every config root that could hold this machine's Claude Code transcripts, * best-first. * * 🔴 WHY THIS IS A LIST. `claudeConfigDir()` returns ONE guess — the env var if * this process happens to see it, otherwise `~/.claude`. A single guess has no * way to be wrong loudly: it just scans a directory that does not exist and * reports "no sessions". Users relocate their agent state (small system disks, * synced or encrypted home dirs, multi-account machines, containers), and the * env var does not always reach the process that needs it. * * Order is deliberate: * 1. `CLAUDE_CONFIG_DIR` — an explicit instruction always wins. * 2. LEARNED roots — recovered from transcript paths the agent itself reported * (agent-sessions.ts). These are the only entries PROVEN to have held a real * transcript, which is why they outrank the conventional defaults. * 3. `~/.claude`, then `~/.config/claude` — the conventional locations. * * Probing a few extra directories costs one failed `readdir` each; missing the * user's actual directory costs them the entire auto-wake feature. */ export declare function claudeConfigRoots(): Promise<string[]>; /** * The transcript this cwd's agent REPORTED for itself, if the record is still * valid on disk. This is layer 1 — the authoritative path — and it bypasses both * the root guess and the cwd-encoding guess entirely. * * Returns null when nothing was ever recorded (an agent running without our * plugin) or when the recorded transcript has since been removed, in which case * the caller falls back to discovery. */ export declare function recordedCandidate(cwd: string): Promise<{ sessionId: string; mtimeMs: number; } | null>; /** * One-line description of the transcript BASE dir and how many project dirs it * holds. Used only when a resolve finds zero candidates, because it separates the * two causes that look identical in the logs: * • base absent / 0 project dirs → the bridge is looking at the WRONG config dir * entirely (Claude Code's environment lives elsewhere and CLAUDE_CONFIG_DIR did * not reach this process). * • base holds N project dirs but none match → the CWD is the wrong one (or a * representation this build cannot map — see {@link projectDirsFor}). * Never throws. */ export declare function transcriptBaseSummary(): Promise<string>; /** * List all Claude Code session candidates for a cwd as {sessionId, mtimeMs}. * Scans every {@link projectDirsFor} dir for *.jsonl — honoring CLAUDE_CONFIG_DIR * (default ~/.claude). Returns [] on any error or an empty/absent dir (the * resolver treats [] as "no candidates"). Never throws — Vault: Returning-null/ * Option error pattern (typescript-master-vault concepts/Error_Handling). Dirs * and stats are probed in parallel (Vault: Parallelism); results are deduped by * sessionId so two cwd forms resolving to one dir cannot inflate the count (a * false ">1" would make the resolver call it "ambiguous" and refuse). */ export declare function listCandidates(cwd: string): Promise<{ sessionId: string; mtimeMs: number; }[]>; /** * Detect the most recently active Claude Code session for a given cwd (newest * mtime wins). Returns null if none. Preserved for existing callers; new code * should use the confidence-aware resolveSession() (session-resolver.ts). */ export declare function detectCurrentSession(cwd: string): Promise<string | null>; /** * Check whether a Claude Code session file exists on disk. * Returns false if the file is missing (session ended or ID is wrong). * * Probes every {@link projectDirsFor} form — a pin validated under the canonical * cwd must still validate when the agent registered a symlinked/trailing-slash * representation of the same directory, or the resolver silently drops the pin * and falls back to guessing by mtime. */ export declare function validateSession(sessionId: string, cwd: string): Promise<boolean>; /** * The config root that actually HOLDS this session's transcript, or null. * * 🔴 WHY DISCOVERY ALONE WAS NOT ENOUGH. {@link claudeConfigRoots} lets us FIND a * session under any of several roots, but `claude --resume <id>` is a separate * process that searches exactly ONE root — whatever `CLAUDE_CONFIG_DIR` says, or * `~/.claude`. Finding a session in root B and then resuming against root A fails * with an empty stdout and "No conversation found with session ID" on stderr, * which upstream reported as the useless "busy, or produced no output" (shipped * 3.21.0–3.21.3; measured against a real Claude Code on 2026-09-01). * * So resume must be told where discovery looked. The invariant: anything that can * FIND a session must be able to say WHERE it found it. * * Layer 1 (the agent's own reported transcript) wins, exactly as in * {@link listCandidates} — its root is a recorded fact rather than a search. Only * then do we probe roots × cwd forms for `<root>/projects/<enc>/<id>.jsonl`. * Returns null when no root holds it, in which case the caller must NOT invent a * value — an inherited `CLAUDE_CONFIG_DIR` is still better than a guess. */ export declare function rootForSession(sessionId: string, cwd: string): Promise<string | null>; /** COG-86: the only tools a default (`COGENT_WAKE_TOOLS=read`) wake gets. */ export declare const READ_ONLY_WAKE_TOOLS = "Read,Glob,Grep"; export declare const READ_ONLY_WAKE_NOTICE: string; export declare function execClaude(sessionId: string, message: string, cwd: string, timeoutMs?: number): Promise<CliExecResult>; /** * Parse a Claude Code `--output-format json` result envelope. Returns the final * assistant message (`.result`, or `null` when absent/non-string) plus whether * the run reported an error — or `null` ONLY when the text is not a * `type:"result"` envelope at all (→ caller uses the raw-stdout fallback). * Slice 3 (Story 8.4). */ export declare function parseClaudeJsonReply(raw: string): { result: string | null; isError: boolean; } | null; //# sourceMappingURL=cc-cli.d.ts.map