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.

109 lines • 4.86 kB
import { getConfig } from "../config.js"; import { listCandidatesFor, probePathsFor, reportedSessionFor, validateSessionFor, } from "./exec-remote.js"; /** * Pure acceptance-gate logic — no fs, fully deterministic and unit-tested. * Prefer-exact: a live pin wins. Refuse-if-close: on ambiguity, return null * rather than resume the wrong session. Vault: the Returning-null / Option * error pattern (typescript-master-vault concepts/Error_Handling) — an * un-resolvable wake is a null result, not an exception. */ export function decideResolution(candidates, pinnedSessionId, pinnedExists, marginMs) { const sorted = [...candidates].sort((a, b) => b.mtimeMs - a.mtimeMs); const count = sorted.length; const gap = count >= 2 ? sorted[0].mtimeMs - sorted[1].mtimeMs : null; if (pinnedSessionId && pinnedExists) { return { sessionId: pinnedSessionId, decision: "pinned-exact", confidence: "high", candidateCount: count, mtimeGapMs: gap, }; } if (count === 0) { return { sessionId: null, decision: "none", confidence: "none", candidateCount: 0, mtimeGapMs: null, fallbackReason: "no candidate sessions found for cwd", }; } if (count === 1) { return { sessionId: sorted[0].sessionId, decision: "single-candidate", confidence: "high", candidateCount: 1, mtimeGapMs: null, }; } if (gap >= marginMs) { return { sessionId: sorted[0].sessionId, decision: "newest-clear", confidence: "medium", candidateCount: count, mtimeGapMs: gap, }; } return { sessionId: null, decision: "ambiguous", confidence: "none", candidateCount: count, mtimeGapMs: gap, fallbackReason: `${count} candidate sessions within ${gap}ms (< ${marginMs}ms margin); pinned session ${pinnedSessionId ?? "unset"} not on disk`, }; } /** * Async adapter: gather candidates + pin-existence concurrently, then decide. * Vault: Parallelism (task parallelism) — the two independent fs probes run via * Promise.all. marginMs defaults to COGENT_RESOLVER_AMBIGUOUS_MARGIN_MS. */ export async function resolveSession(platform, cwd, pinnedSessionId, marginMs) { const [candidates, pinnedExists, reported] = await Promise.all([ listCandidatesFor(platform, cwd), pinnedSessionId ? validateSessionFor(platform, pinnedSessionId, cwd) : Promise.resolve(false), // Layer 1 is an ENHANCEMENT over discovery, never a dependency of it: if the // learned-record lookup is unavailable or throws, resolution must still run // exactly as it did before this layer existed. Promise.resolve() .then(() => reportedSessionFor(platform, cwd)) .catch(() => null), ]); const margin = marginMs ?? getConfig().COGENT_RESOLVER_AMBIGUOUS_MARGIN_MS; // LAYER 1. When the caller's pin does not check out, fall back to the session // the AGENT ITSELF reported (agent-sessions.ts, written from the hook payload). // Promoting it to the pin reuses the existing prefer-exact path, so it resolves // "pinned-exact"/HIGH instead of being re-guessed by mtime among candidates. // An explicit pin that DOES validate still wins — the caller knows best. const effectivePin = pinnedExists ? pinnedSessionId : (reported ?? pinnedSessionId); const effectiveExists = pinnedExists || (reported !== null && reported === effectivePin); const res = decideResolution(candidates, effectivePin, effectiveExists, margin); // Diagnostics are gathered ONLY on the zero-candidate path — the one that is // otherwise a dead end — so the happy path does no extra fs work, and a probe // that fails can never degrade a resolution that already succeeded. if (res.candidateCount === 0) { try { const probedPaths = await probePathsFor(platform, cwd); if (probedPaths.length) { res.probedPaths = probedPaths; // Name the directory in the reason itself: this string is what reaches // the sender over the wire AND the operator in the log, and it was the // missing half of every "no candidate sessions found for cwd" report. if (res.fallbackReason) { res.fallbackReason = `${res.fallbackReason} (cwd=${cwd}; scanned ${probedPaths.join(", ")})`; } } } catch { // diagnostics only — never let this change the outcome } } return res; } //# sourceMappingURL=session-resolver.js.map