Skip to content

T-QO8E-new-hosts-claude-codex-cursor-under-lib-services-host-hosts

State: closed/done · Impact: medium · Complexity: large

New host implementations under lib/services/host/hosts/: claude (Claude Code, via CLI or the desktop app’s launch-with-prompt entry), codex (the Codex CLI or app), cursor (the cursor-agent CLI, or opening the worktree in Cursor with the prompt). Each implements the session/terminal parts with an available() probe.

Three new hosts under solutions/ontological/lib/services/host/hosts/, each implementing session ONLY (not terminal — Host extends Partial<HostParts> already supports a partial host; arbitrary command-running isn’t these hosts’ job). Each is ENGINE-NATIVE: it hardcodes its own CLI and ignores req.engine entirely — terminal/orca/cmux stay the WRAPPER hosts that pick an AgentEngine’s binary via engineArgv. AgentEngine (host/engines.ts) deliberately stays 'claude' | 'codex' — 'cursor' is a HostName, never an AgentEngine member (see that file’s doc comment for why).

The three new host modules share the same attribute set — available() probe, session() mechanism, hostSessionId strategy, verification status:

Hostavailable()session() mechanismhostSessionId strategyVerified?
hosts/claude.tsonPath('claude') (the exported helper from hosts/terminal.ts)claude --bg -n <title> <prompt> via spawnRunner('claude').run([...], {cwd, timeoutMs: 30_000}) — the command seam’s sync door, same shape as hosts/orca.ts/cmux.ts, since --bg backgrounds and returns quickly on its ownBest-effort parse from stdout; falls back to null rather than guessing wrong, never fails the launch on an unparsable idUNVERIFIED — no local claude install to observe the real --bg stdout format
hosts/codex.tsonPath('codex')codex has no background/detach flag (confirmed against codex --help/codex exec --help/codex resume --help), so this host detaches it itself: spawnRunnerAsync('codex').run([req.prompt], {cwd}), fired but NOT awaited (the promise only settles once the codex session ends) — the command seam’s long-lived-process doorA SHORT bounded, purely SYNCHRONOUS poll (up to ~10 reads, ~200ms apart via spawnRunner('sh').run(['-c','sleep …']), capped at ~2s) of ~/.codex/session_index.jsonl for the newest entry stamped after launch — best-effort and race-prone under concurrent codex launches, a documented known limitation rather than something solved hereCLI flags confirmed via --help; the session-index poll itself is not live-verified against a real run
hosts/cursor.tsTrue when cursor-agent OR (degraded) cursor (the editor’s own CLI shim) is on PATH — binary selection is injectable for testscursor-agent present: detached spawnRunnerAsync launch, same reasoning as codex. Only cursor present: cursor <cwd> opens the worktree folder in the editor but delivers no prompt — there is no documented cursor flag to seed the agent panel, a deliberate, accepted limitation, not a bug to route around with a clipboard/temp-file trickAlways null (no known local session-index file for cursor-agent, unlike codex — a documented gap pending live verification; real attach support may need cursor-agent ls/--resume, wired in once session attach exists, T-QMGC)UNVERIFIED — cursor-agent is not installed on any development machine used for this task; everything here is from published Cursor CLI docs (cursor.com/docs/cli), not a live run

Contract change these hosts required: HostParts.session’s return type changed from a raw number to { exitCode: number; hostSessionId: string | null } (contract.ts) — a hard cutover across all 3 pre-existing hosts (terminal/orca/cmux, which now return { exitCode, hostSessionId: null }) and both launchInteractive callers (session/ops/launch.ts, pr/ops/review.ts). HostName also gained the three new members; HOST_NAMES and a new HostNameSchema (z.enum over it) are the one place that enumeration lives now, consumed by lib/config/load.ts’s host.default/pr_review.host/orchestrator.workflows.<name>.host fields and session launch’s/pr review’s own --host flags instead of each hand-duplicating the literal union.

AreaNote
solutions/ontological/lib/services/host/hosts/claude.tsNew engine-native claude host (--bg, best-effort id parsing)
solutions/ontological/lib/services/host/hosts/codex.tsNew engine-native codex host (detached spawn, session-index poll)
solutions/ontological/lib/services/host/hosts/cursor.tsNew engine-native cursor host (cursor-agent / degraded cursor-editor fallback)
solutions/ontological/lib/services/host/contract.tsHostName +3, HostNameSchema, HostParts.session return-shape cutover
solutions/ontological/lib/services/host/index.tshostRegistry() registers the three new hosts
solutions/ontological/lib/services/session/ops/launch.ts, solutions/ontological/lib/services/pr/ops/review.tslaunchInteractive callers updated for the {exitCode, hostSessionId} shape
solutions/ontological/lib/config/load.tshost.default/pr_review.host/orchestrator.workflows.<name>.host consolidated onto HostNameSchema
  • AC-1: Each of claude/codex/cursor exports available() and returns true only when that tool is actually present (proven via an injectable probe in unit tests — no real installed-tool dependency; cursor-agent in particular is not installed anywhere this task was implemented or tested).
  • AC-2: A session() launch against each produces the argv/spawn shape documented above, proven with the command-seam’s injectable CommandRunner/AsyncCommandRunner fakes (hosts/tests/hosts.test.ts) — NOT a live smoke test against a real installed tool, which the task’s testing constraints explicitly rule out (no real interactive claude/ codex/cursor-agent process may be launched by a test).
  • Wiring hostSessionId into .sdlc/sessions/<id>/record.json or a session attach/session list surface — that is T-QMGC’s job. This task only makes the id available on session()’s return value.
  • Verifying claude --bg’s real stdout shape or installing cursor-agent to confirm its real CLI surface — both documented as UNVERIFIED, to be confirmed live in a follow-up once those tools are available.
  • none

← Back to Tasks