Files
Codeman/.changeset/f68abcf7.md
T
Codeman maintainer 6aecc3b858 chore: changeset for the 1.34.0 landing (#499, #514, #515, #517, #519, #520, #521, #522, #523, #524, #530, #531)
One consolidated minor changeset with the Thanks block first; the four contributor changesets (#520, #521, #522, #523) are folded into it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-04 23:53:56 +02:00

7.3 KiB

aicodeman, xterm-zerolag-input
aicodeman xterm-zerolag-input
minor minor

Thanks

  • @opticon454 for four PRs in one batch: webhook notifications (#523), MCP server sync (#521), the Shift+Enter keypress fix (#520) and the newline chord plus Key tester (#522). Every review item was answered in one round, and the merge-order map across all four made landing them together easy.
  • @aakhter for the grouped vertical rail (#517) and its ARIA tree and full-row activation (#519), which give the owner tab-layout API its first frontend, and for the iOS IME composition preview (#499), carried through three careful review rounds including the overlay rework in the zerolag package.
  • @irisitymichaelgrundberg for per-session Claude models on POST /api/sessions (#514) and Codex reasoning effort per session (#515), both kept registry-driven with no CLI id branching.
  • @timkjr for keeping Pane B painting during a history pull and its "disconnected" marker last in every interleaving (#524), with an old-versus-new table measured in real Chrome.

Webhook notifications (#523). Settings → Notifications → Webhook posts the same events as Web Push (permission prompts, questions, errors, idle) to ntfy, Slack, Discord or any JSON URL, so a headless server can reach a phone with no browser open. Off by default. The URL is a bearer secret: it lives in its own 0600 file (~/.codeman/webhook.json), is never returned by the API, and the routes (GET/PUT /api/webhook, POST /api/webhook/test) are admin only in multi-user mode. Delivery goes through the web-tab egress guard (link-local and cloud-metadata targets refused), does not follow redirects, times out after 5 s, dedupes repeats, and neutralises @everyone/Slack control characters in agent-supplied text.

MCP server sync (#521). Opt-in (mcpSyncEnabled, synced, off by default; GET/POST /api/mcp-sync answer 403 until it is on). Settings → Agents & CLIs → MCP servers previews or copies each installed, enabled CLI's MCP servers into the others' own config files (Claude, Gemini, Codex, OpenCode, Antigravity). It only adds missing servers, never edits or removes one, skips servers you switched off, keeps a .codeman-bak of every file it changes, re-parses the result before writing, writes through symlinked dotfiles, leaves files that receive env values or headers readable by you only, and reports same-name conflicts instead of overwriting. CLIs with no known MCP config (Pi, Grok, OMP, DeepSeek) are listed as unsupported. Adds the smol-toml dependency to read Codex's config.toml safely.

Claude advisor tool. Claude Code's experimental advisor (a stronger model the session's main model consults at decision points) can now be set per session: an advisorModel field on POST /api/sessions, POST /api/quick-start and POST /api/ralph-loop/start (fable, opus, sonnet, or a full id in those families), and a synced App Settings default under Models → Advisor. It rides the launch's one --settings JSON rather than the --advisor flag, because the flag exits at launch on any pairing the CLI refuses and would leave a dead pane on every respawn. It is persisted, so respawns and both restore paths keep it, and /advisor still switches it in-session. Agents using the codeman skill can give their claude workers one with CODEMAN_WORKER_ADVISOR=opus.

Per-session Claude model (#514) and Codex reasoning effort (#515). POST /api/sessions takes an optional model that launches that one Claude session with claude --model <id> and writes nothing to disk (modelOverride still writes the case default). It is persisted, so both recovery paths relaunch on it. codexConfig.reasoningEffort starts a codex session at a chosen effort (--config model_reasoning_effort=<level>), and it survives respawn and resume.

Grouped vertical rail (#517, #519). When the owner has tab groups (/api/tab-layout), the vertical rail draws them as collapsible sections, with collapse remembered per device, the active row always visible, and lineage arcs anchored to a collapsed group's header. The grouped rail is an ARIA tree with one tab stop and the standard arrow-key model. With no groups, the rail is unchanged byte for byte. Editing groups from the browser comes in a follow-up.

iOS IME composition preview (#499). On iOS Safari, the text an IME is composing (Japanese, Chinese, Korean, and the predictive composition on English keyboards) is now drawn in the terminal before it commits, inside the local-echo overlay when local echo is on. Inert on every other platform. The xterm-zerolag-input package gains setComposition().

Key tester and newline chord (#522). Settings → Terminal & Input has a Key tester that shows the keydown/keypress/keyup events the browser reports, to diagnose a device where a shortcut behaves differently. Keys pressed in it never trigger app shortcuts. Shift+Enter's newline chord is now CLI registry data (capabilities.newline, line feed by default); no stock CLI changes.

Fixes. Shift+Enter no longer submits the prompt after inserting the newline: the key handler swallowed only keydown, so xterm's keypress still sent a bare \r (#520). Claude sessions created at the same moment (spawn_workers, a multi-tab Run) no longer fall out of tmux onto the direct-PTY fallback: the statusLine exporter's temp file name collided within one millisecond (#531). Pane B of the split view keeps painting during a history pull, and its "disconnected" marker stays the last line however a close, a pull and a refresh interleave (#524).

Fixes applied while landing. Webhooks: the App Settings Save button now saves webhook edits too (a refused URL keeps the dialog open with a warning), Send test saves pending edits first, and a Remove URL button clears a saved URL. MCP sync: a config file that fails to parse is reported by line and column only, never by quoting its content, which can hold API keys; the sync follows CLAUDE_CONFIG_DIR, CODEX_HOME, XDG_CONFIG_HOME and GEMINI_CLI_HOME from the server's environment and skips a target it cannot place instead of writing a file the CLI never reads; Preview before saving says to save first; and the MCP group is hidden from non-admins in multi-user mode. Grouped rail: a collapsed group's header shows the red or yellow ring of a hidden row that needs you; layout reads rebuild the rail only when something it draws changed, and failed reads back off (5, 10, 20, 40 s) instead of retrying every 5 s forever; a corrupted collapse preference resets instead of disabling collapse; Ctrl+Shift+{ / } only moves a tab within its own group; tapping a group header or row no longer dismisses the phone keyboard; keys pressed on a row's own buttons no longer move tree focus; and screen-reader positions stay correct after a re-sort. Sessions: model on POST /api/sessions refuses a value starting with a dash, and model or advisorModel together with attachRemoteSession is now a 400 instead of being ignored; non-Claude sessions no longer report or persist Claude's default model. Split view: a refresh queued behind a history pull no longer leaves a second, stale "disconnected" marker above its replay. iOS IME: a composition on an empty prompt now follows the prompt when output or a resize moves it, and the xterm-zerolag-input README documents setComposition(). The Shift+Enter and Key tester browser tests now drive the shipped handlers instead of copies.