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.

196 lines • 9.76 kB
export interface PeerInfo { peerId: string; sessionId: string; cwd: string; label: string; registeredAt: string; lastSeenAt: string; /** cogent-bridge npm version of the registering client (optional, added in 3.1.6). */ clientVersion?: string; /** * Peer participation mode (optional, added in 3.2.0 / Phase 17 OBS-01..03). * - "agent" (default if absent): inbound directed messages trigger * `execClaude` via the auto-relay path. Standard CC peer behavior. * - "observer": peer receives WS frames and remains targetable in * `cogent_list_peers`, but the auto-relay short-circuits — no * subprocess is spawned. Useful for operators using their MCP client * as a passive watcher without polluting the transcript with phantom * relay replies. * Absent on records produced by pre-3.2.0 clients (treated as "agent"). */ mode?: "observer" | "agent"; /** * Cloud/relay channel session id, kept distinct from the local `sessionId` * the resolver finds on disk (they used to collide). Local-only — NOT sent on * the relay register wire. Added 3.5.9. */ channelSessionId?: string; /** * Advertised capabilities, e.g. ["auto-resume"] | ["observer"]. A local rail * for the later relay slice; NOT sent on the wire yet. Added 3.5.9. */ capabilities?: string[]; /** * Durable workspace identifier (Slice 5 / Story 8.6). A STABLE id for the * workspace that does NOT depend on the mutable, lossy cwd hint. UNLIKE * channelSessionId/capabilities, this IS sent on the relay wire (the server * .strict() schema was extended in lockstep). Optional; back-compat. */ workspaceId?: string; /** Durable thread/conversation identifier (Slice 5 / Story 8.6). On the wire; optional. */ threadId?: string; /** * Cogent Mail auto-provisioned mailbox (M2.7). Present ONLY on a cloud register RESPONSE * for a Team channel where the relay minted (or resolved) this peer's mailbox via the * control-plane provisioner. `password` is returned ONCE (on first create / explicit rotate) * and is never persisted server-side — the bridge saves it to its local 0600 store and drops * it. Absent on free channels and on re-registers that don't re-issue a password. */ mailbox?: { address: string; password?: string; }; /** * Cogent Mail provisioning FAILURE (2026-09-04). Present ONLY on a cloud register response for a * Team channel where provisioning was attempted and did not produce a mailbox. Its whole purpose * is to separate "Team, but broken — retry" from "free tier, mail was never available here", * which are indistinguishable from the agent's side otherwise. Never carries a credential. */ mailboxError?: { code: string; message: string; }; } export interface MessageRecord { id: string; fromPeerId: string; toPeerId: string; message: string; response: string | null; timestamp: string; durationMs: number | null; success: boolean; error: string | null; /** * Marks a message as the auto-relay echo (the FE->BE response sent back * after a directed message-with-reply). Server 3.1.6+ filters these out * of `cogent_get_history` by default. Absent / false === regular message. * Forward-compat: older servers omit the field; older clients ignore it. * Added in client 3.1.11 (260511-o3p). */ isRelayEcho?: boolean; /** * Marks a directed send that was delivered+acked but whose reply did not * arrive within the fast-path window (COGENT_FASTPATH_MS). The reply will * land asynchronously via the existing inject-only path. Such a record is * a successful async delivery (success:true), NOT a failure — response * stays null until/unless the late reply updates it. * Absent/false === a normal completed exchange. * Added in 260527-mkz (busy-agent async-relay). */ pending?: boolean; /** * The SENDER declares this message terminal: it conveys information and expects no reply. * Absent/true === today's behaviour (a directed message demands an answer). * * 🔴 WHY THIS IS A WIRE FIELD AND NOT A CONVENTION IN THE TEXT (2026-09-21). Rail C decides * "unanswered" from ADDRESSING alone: a directed message to me is pending until I send a * directed reply to its sender. A terminal acknowledgement is still a directed message, so it * demands a reply, and that reply is itself directed — two agents running the same hook * acknowledge each other forever. Observed live between po-backend and po-integrator, which * burned turns exchanging ACKs and then NEGOTIATED A PROSE PROTOCOL between themselves * ("send closures as undirected broadcasts", `ACK_*` prefixes, "no reply needed" in the body). * The hook reads addressing, not prose, so none of it could work — and the agreed workaround * was structurally incapable of clearing anything, because a broadcast never clears a directed * message (check-on-stop.lib.mjs:137-141). * * memory/typescript-master-vault/concepts/Typesafe_Protocols.md names this exactly: a protocol * describes every legal message "along with the expected shape of any response", and when that * expectation is "described informally — in documentation, comments, or untyped JSON schemas" * the two ends drift. So the expectation becomes a typed field the receiver can act on, rather * than an English sentence two agents have to agree to honour. * * Deliberately a boolean, not a `kind` discriminated union (which the same vault note would * otherwise favour): the only consumer needs exactly one bit, and a union would be mapped * straight back down to it. CLAUDE.md — do not over-design. */ replyExpected?: boolean; /** * Wake-trace correlation id. The relay mints one per inbound message and stamps it on the * stored record, so it rides frames and poll (server/src/routes/messages.ts); the bridge * prefers it and mints its own only when absent (auto-relay.ts). Content-free. Added 3.5.9. */ traceId?: string; /** * Platform this message ORIGINATED from (the relay stamps it, default "cc"). * Read by Slice 4 (Story 8.5) to distinguish an AGENT-origin broadcast * (cc/codex — manual by default, anti-debate) from a HUMAN-origin broadcast * (slack/gchat/web — still auto-relays so a Slack user gets an answer). * Absent on older records → treated as agent-origin (safe default). */ originPlatform?: "cc" | "codex" | "slack" | "gchat" | "web"; /** * Cogent Mail M2.5 — file REFERENCES carried alongside the message (the byte transport * is email; this is the reference layer). Either a public `url` or a `mailMessageId` the * recipient fetches with `cogent_fetch_mail`. Optional/additive → no-attachment messages * are unchanged. Mirrors @essentialai/cogent `Attachment`. */ attachments?: Attachment[]; } /** Cogent Mail M2.5 attachment reference (mirrors @essentialai/cogent `Attachment`). */ export interface Attachment { url?: string; mailMessageId?: string; name?: string; mimeType?: string; size?: number; } export interface SendMessageResult { success: boolean; response: string | null; error: string | null; durationMs: number; } export interface CliExecResult { stdout: string; stderr: string; exitCode: number | null; /** * Slice 3 (Story 8.4) — how the reply was captured: * - "event_stream": parsed from a structured envelope (Claude `--output-format * json` `.result`; Codex `-o` last-message file) — the * `machine_readable_event_stream` tier, trusted (`stable:true`). * - "stdout_compat": fell back to raw stdout because a structured envelope was * unavailable — `stable:false`; the downgrade is surfaced in the wake trace, * never disguised as a clean auto-capture (AC3). * Absent on non-reply results (timeouts, spawn/CLI errors). */ captureContract?: "event_stream" | "stdout_compat"; /** Slice 3: true only for a trusted structured capture. */ stable?: boolean; /** * True when a non-zero Codex exit was caused by the OS sandbox failing to * initialize (unprivileged user namespaces blocked on the host — `bwrap: * setting up uid map: Permission denied`). Lets the caller surface an * actionable message instead of a generic failure. Absent otherwise. */ sandboxBlocked?: boolean; /** * True when the `app-server` codex-wake rail could not REACH the daemon * (socket missing, ws upgrade failed, initialize errored) — as opposed to a * turn that ran but failed. Lets `execRemote` gracefully fall back to the * `exec-resume` rail so a mis-launched agent still degrades to current * behavior. Absent on the `exec-resume` rail and on successful app-server runs. */ appServerUnavailable?: boolean; /** * True when a non-zero Codex exit was the SINGLE-WRITER thread-store conflict * (`-32600 already has an active writer`) — i.e. the codex agent is live in an * interactive TUI, so `codex exec resume` cannot get the writer. Lets auto-relay * surface an honest "queued — answers at its next turn" message (and point at * COGENT_CODEX_WAKE=app-server) instead of an alarming "could not capture a * reply". Absent otherwise. Only the `exec-resume` rail sets it. */ codexLiveSession?: boolean; } //# sourceMappingURL=types.d.ts.map