Skip to content

feat(harness): register coven-code as a first-class agent#16

Open
BunsDev wants to merge 3 commits into
mainfrom
feat/coven-code-harness
Open

feat(harness): register coven-code as a first-class agent#16
BunsDev wants to merge 3 commits into
mainfrom
feat/coven-code-harness

Conversation

@BunsDev
Copy link
Copy Markdown
Owner

@BunsDev BunsDev commented May 31, 2026

What changes

Adds OpenCoven's `coven-code` (the Claurst-based coding TUI) to comux's `AGENT_REGISTRY` so it appears in the pane-creation agent picker, the auto-detect / install scan, and ritual configs alongside claude, codex, opencode, etc.

Registry entry

  • shortLabel: `cv` (unique among the 11 existing two-letter codes — claude/cc, codex/cx, opencode/oc, cline/cl, gemini/gm, qwen/qw, amp/ap, pi/pi, cursor/cu, copilot/co, crush/cs)
  • promptTransport: `positional` (coven-code accepts the seed prompt as its trailing arg, same as claude/codex)
  • permissionFlags: maps comux's `plan`/`acceptEdits`/`bypassPermissions` to coven-code's `--permission-mode plan`/`accept-edits`/`bypass-permissions`
  • resumeCommandTemplate: `coven-code --resume{permissions}` for comux's "reopen worktree" continuation flow
  • commonPaths: `/.local/bin`, `/opt/homebrew/bin`, `/usr/local/bin`, `/bin`, `~/.npm-global/bin`

Why no other code changes

Every comux site that enumerates agents iterates `AGENT_IDS` / `AGENT_REGISTRY`:

  • pane creation (`paneCreation.ts`)
  • conflict-resolution agents (`conflictResolutionPane.ts`)
  • rituals (`rituals.ts`)
  • worktree-reopen preferred order (`reopenWorktree.ts`)
  • settings filter (`settingsManager.ts`)
  • agent detection (`agentDetection.ts`)

So coven-code flows through all of them automatically.

Context

This is step 1 of the comux ↔ coven-code integration Val asked for:

  1. ✅ Register coven-code as a comux harness (this PR)
  2. ⏳ MCP bridge so familiars running inside coven-code can spawn comux panes
  3. ⏳ Tauri desktop merge — comux becomes the desktop shell with coven-code as the canonical coding harness; coven-cave's chat surface gets folded into a comux pane mode

Test plan

  • `pnpm dev` → `n` to create pane → confirm `coven-code` appears in the agent picker
  • Pick `coven-code`, type a prompt → confirm pane launches `coven-code ""` in the worktree
  • Existing rituals (Start Coding, Review Stack, Release Check) still work
  • `comux doctor` reports `coven-code` install status

Pre-existing TS noise

`pnpm tsc --noEmit` already errors on main with a `CovenSessionsSource` duplicate-identifier in `src/utils/covenSessions.ts` — unrelated to this change. Worth fixing in a follow-up.

Adds OpenCoven's coven-code (the Claurst-based coding TUI) to comux's
AGENT_REGISTRY so it appears in the pane-creation agent picker, the
auto-detect / install scan, and ritual configs alongside claude,
codex, opencode, etc.

Registry entry:
- shortLabel: cv (unique among the 11 existing two-letter codes)
- promptTransport: positional (coven-code accepts the seed prompt
  as its trailing arg, same as claude/codex)
- permissionFlags: maps comux's plan/acceptEdits/bypassPermissions
  to coven-code's --permission-mode plan/accept-edits/bypass-permissions
- resumeCommandTemplate: `coven-code --resume{permissions}` for
  comux's "reopen worktree" continuation flow

No other code changes needed — every comux site that enumerates
agents iterates AGENT_IDS / AGENT_REGISTRY so coven-code now flows
through pane creation, conflict-resolution agents, rituals, the
worktree-reopen preferred order, and the settings filter
automatically.

Step 1 of the comux ↔ coven-code integration. Next: MCP bridge so
familiars running inside coven-code can spawn comux panes, and the
Tauri desktop merge (comux as the host shell).
Copilot AI review requested due to automatic review settings May 31, 2026 04:45
@vercel
Copy link
Copy Markdown

vercel Bot commented May 31, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
comux-docs Ready Ready Preview May 31, 2026 4:56am

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request registers a new agent, 'coven-code', in AGENT_IDS and configures its properties in AGENT_REGISTRY. However, the review points out a critical issue where launchAgentInPane lacks support for launching this new agent, which would result in a silent failure. A fix is recommended to add an explicit branch or fallback for 'coven-code' in launchAgentInPane.

Comment thread src/utils/agentLaunch.ts
},
defaultEnabled: false,
},
'coven-code': {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Missing Launch Support in launchAgentInPane

The agent coven-code is successfully registered in AGENT_IDS and AGENT_REGISTRY. However, launchAgentInPane (lines 566–669) only contains explicit if/else branches for claude, codex, and opencode:

if (agent === 'claude') {
  // ...
} else if (agent === 'codex') {
  // ...
} else if (agent === 'opencode') {
  // ...
}

Because there is no fallback or explicit branch for coven-code, attempting to launch this agent will result in a silent failure (the tmux pane will be created, but the command will never be sent).

Recommended Fix

You should add an explicit branch for coven-code in launchAgentInPane, or implement a generic fallback for all other registered agents. For example, adding a branch for coven-code (similar to claude since both use positional transport):

} else if (agent === 'coven-code') {
  const permissionFlags = getPermissionFlags('coven-code', permissionMode);
  const permissionSuffix = permissionFlags ? ` ${permissionFlags}` : '';
  let covenCmd: string;
  if (hasInitialPrompt) {
    let promptFilePath: string | null = null;
    try {
      promptFilePath = await writePromptFile(projectRoot, slug, prompt);
    } catch {
      // Fall back to inline escaping if prompt file write fails
    }

    if (promptFilePath) {
      const promptBootstrap = buildPromptReadAndDeleteSnippet(promptFilePath);
      covenCmd = `${promptBootstrap}; coven-code "$COMUX_PROMPT_CONTENT"${permissionSuffix}`;
    } else {
      const escapedPrompt = prompt
        .replace(/\\/g, '\\\\')
        .replace(/"/g, '\\"')
        .replace(/`/g, '\\`')
        .replace(/\$/g, '\\$');
      covenCmd = `coven-code "${escapedPrompt}"${permissionSuffix}`;
    }
  } else {
    covenCmd = `coven-code${permissionSuffix}`;
  }
  await tmuxService.sendShellCommand(paneId, covenCmd);
  await tmuxService.sendTmuxKeys(paneId, 'Enter');
}

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Adds a `comux mcp` subcommand that boots a stdio JSON-RPC 2.0 MCP
server, so any MCP client (coven-code, Claude Code, OpenCode, etc.)
can let its familiar fan work into parallel comux panes mid-
conversation without leaving its session.

Wire-up on the client (e.g. ~/.coven-code/settings.json):

    {
      "mcp_servers": [
        { "name": "comux", "command": "comux", "args": ["mcp"], "type": "stdio" }
      ]
    }

Tool surface, this commit:
- `comux_list_panes` — live. Reads `<projectRoot>/.comux/comux.config.json`
  via the existing `daemon/panes.ts:listPanes` so the MCP path and the
  Ink TUI path share state.
- `comux_create_pane` — shape-only stub. Schema is final; behaviour
  lands in the next commit (wires into paneCreation + TmuxService).
- `comux_kill_pane` — shape-only stub.

Implementation notes:
- Hand-rolled JSON-RPC 2.0 (no `@modelcontextprotocol/sdk` dep yet) —
  the surface is small enough that adding a runtime dep this early
  isn't worth it. Easy to swap if the tool list grows.
- stderr is reserved for logs; stdout carries protocol frames only.
- Server stays alive until stdin EOF — clients signal end-of-session
  by closing their write end.

Smoke-tested locally:

    (echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}'; \
     echo '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'; \
     echo '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"comux_list_panes","arguments":{}}}') \
      | comux mcp

returns initialize + tools/list + an empty `panes: []` for a project
without comux state, exactly as expected.

Step 2 of the comux ↔ coven-code integration. Next commits in this
PR series: wire create/kill, add list_rituals/run_ritual,
list_worktrees, send_to_pane, get_pane_output.
Brings the comux MCP bridge from "shape-only" to actually-useful for any
familiar that wants to inspect a comux project without leaving its chat.

Live tools after this commit (4 of 6 from the planned surface):
- `comux_list_panes`      (already)
- `comux_get_pane_output` — `tmux capture-pane -p -e -J -S - -t <id>`
  via the existing `daemon/panes.ts:capturePaneSync`. Returns ANSI-
  escaped bytes; optional `strip_ansi: true` flag for callers that
  just want the plain text.
- `comux_list_rituals`    — `getBuiltInRituals()` + `listProjectRituals(root)`
  from `utils/rituals.ts`. Returns built-ins + project-saved rituals
  with `scope: "builtin" | "project"`.
- `comux_list_worktrees`  — `git -C <root> worktree list --porcelain`
  parsed to `[{path, head, branch, bare?, detached?, locked?}]`.

Still stubs (need to coordinate with the comux daemon for tmux-session
ownership, landing in the next commit):
- `comux_create_pane`
- `comux_kill_pane`

Smoke-tested locally against the live comux repo: list_worktrees returns
4 real worktrees, list_rituals returns the 5 built-in rituals.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants