Repository navigation
codeman@1.46.0
Minor Changes
-
de1aab9: ### Thanks
- @JDProfresh for five PRs: a phone keyboard that no longer costs Claude its transcript (#711, measured in #672), a + on each session tab that starts a session beside it (#712, shaped in Discussion #700), a tunnel that needs its own opt-in instead of the LAN one (#718, from their report #706), a settings.json that two writers can no longer tear (#719), and a DeepSeek test that passes on current Node (#710).
- @aakhter for six PRs:
codeman agent spawnin a project directory (#708), worker ids kept when the readiness check fails (#709), the offline Codex history reader (#707), experimental bounded inspection and guarded submission for agents (#694, from Discussion #695), links that follow URLs and paths across wrapped rows and table cells (#686), and file paths with spaces linked as one path (#687). - @opticon454 for the Fetch button and fetch interval in the Git status window (#714).
- @johoja12 for Cmd+K arrows that switch the CLI both ways after you type a case name (#717).
Fetch from the Git status window (#714). The Git status window has a Fetch button next to Refresh. It runs
git fetchfor the repositories it lists and shows each one's result. An optional interval runs it for you: off by default, app-wide in App Settings, Bottom bar, with a per-session override in Session Options, Git. A fetch only moves remote-tracking refs (HEAD, the index and the working tree stay as they are), it never runs for a Docker or remote session, and it is bounded in time, output and concurrency.Start a session beside any tab (#712, opt-in). Turn on New Session Button on Tabs (App Settings, Tabs) and each session tab gets a +: pick any CLI its case can run (a Docker case offers what its container has) and the new session starts in that case or worktree and that tab's group, without touching the toolbar's case or Run mode. The row menu offers the same as "New session here…" for the keyboard.
The phone keyboard no longer costs Claude its transcript (#711). Every keyboard open and close used to resize the PTY, and Claude Code answers each height change by reprinting only the tail that fits, so lines above it were lost from tmux for good (25 of 100 in five keyboard cycles). A local Claude session now keeps its rows while the keyboard is up and slides the screen so the composer stays above the keyboard. On by default as Keep Size Under Keyboard (App Settings, per device); off restores the old resize. Fullscreen Claude (mouse tracking on) still resizes as before.
Typing stays smooth in a long prompt (#713). The local echo overlay (the instant preview of what you type) rebuilt every character of the prompt on each keystroke, so on a phone-class CPU a 4,000-character prompt took most of a second per key. It now rebuilds only the line that changed, with one paint layer per line, so a keystroke costs the same however long the prompt is. Every character still sits on its terminal cell. This ships in
xterm-zerolag-inputtoo.Links survive wrapping and spaces (#686, #687). A URL or path a CLI wrapped inside a table cell or an indented paragraph now links whole instead of in fragments, URLs keep balanced parentheses (
…/Team-Space(QA)Archive/…), a full-width table divider no longer glues onto the row below, and OSC 8 hyperlinks open through Codeman's own opener after a confirmation. A file path with spaces (/mnt/c/OneDrive - Contoso/report.docx,Saved to: ~/My Docs/plan.md) links as one path in the terminal and the response viewer when the line bounds it, and a shell prompt that prints its working directory no longer turns the whole command line into one link.codeman agent spawnin a project directory (#708). Without a case name,spawnstarts the worker in the current directory, or in an existing directory given with--working-dir, throughPOST /api/v1/sessionsand the mode's start route. Named cases still use quick-start.--jsonprints{ sessionId, workingDir, created: true }plusready,readinessErrororstartupError. An empty--working-dir, a bare spawn from your home directory (it would install Codeman's hooks into~/.claude; pass--working-dir ~to mean it) and an unknown--modeare refused with exit 4 before any request.Read saved Codex conversations offline (#707).
codeman history readreads Codex's saved rollouts without a Codeman server: by file, by Codex session id, or a whole conversation with its sub-agents and forks, filtered by topic or UTC date with whole turns kept. Reads and output have separate, raisable budgets, and anything it could not read or attribute (a compressed.jsonl.zstrollout, a file still being written) is reported throughcomplete: falseinstead of failing the lookup. The codeman skill routes to it.Experimental: bounded inspection and guarded submission for agents (#694, opt-in).
codeman agent inspectreads bounded, cursor-paged evidence from another session (a local Codex session's attributed rollout records, otherwise a labelled pane snapshot), andagent stage/agent submittype one line into a verified local Codex composer and later send exactly one Enter against a hash-confirmed receipt. Off by default behind Experimental agent coordination (App Settings, Cross-session features); while off the three routes answer403 FORBIDDENnaming the setting. These routes and verbs are experimental under the versioning policy and may change in a minor or patch release. During the few milliseconds of a guarded submit, other input is held and written in order afterwards; a tagged input POST in that window answers409 CONFLICTso its sender retries, and an untagged one (the phone keys, the Stop button) is held and answered once written.Cmd+K arrows switch the CLI both ways (#717). After typing a case name in Cmd+K, plain Left and Right now both change the New session row's CLI whenever the caret is at either end of the query (only Right did before). Inside the query the arrows move the caret as usual.
Fixes.
- Security: a LAN install's acknowledgement no longer opens a public tunnel (#718).
CODEMAN_ALLOW_UNAUTHENTICATED_NETWORK(and--allow-unauthenticated-network), which the installer writes for every LAN install without a password, also let the Cloudflare tunnel start, so one click on the welcome screen's tunnel link published full terminal control to a public URL with no login and no confirm. It now covers the network bind only. An unauthenticated tunnel has its own opt-in,CODEMAN_ALLOW_UNAUTHENTICATED_TUNNEL=1orcodeman web --allow-unauthenticated-tunnel(carried bycodeman web -dandcodeman service install), which the installer never writes; if you relied on the network variable to start the tunnel without a password, set one of those. With no password and no multi-user mode, the browser now asks before every tunnel enable, using the newloginConfiguredfield ofGET /api/tunnel/status. Both acknowledgement variables and their flags are now listed as stable in the versioning policy. - settings.json can no longer be torn (#719). A quick-start's
lastUsedCasewrite was not awaited and not atomic, so it could overlap the next settings save and leave one write's bytes over the tail of the other, after which every reader saw{}. Every write to settings.json now goes through one serialized writer that writes a temp file and renames it into place, and a file that does not parse is refused with409 CONFLICTinstead of being overwritten with only the writer's own keys. A case rename checks this before it ends any session. - A worker id is never lost (#709). When
codeman agent spawncreated a worker but its readiness request failed, it exited without the new session id. It now prints the id (and--jsoncarries it) and exits 1, so the caller can inspect or delete the worker.codeman agentandcodeman mcpalso name the error code (such asECONNREFUSED) when a request fails with an empty message. - The DeepSeek transcript test passes on Node 24.22+ and 26.10+ (#710). It pinned Node's old zstd decoder, which stopped at the first frame until nodejs/node#65865.
Fixes applied while landing. The Git fetch interval field is no longer reset by a session update while you type in it, a session holding only half an override shows the app's value for the other half, reading a repository's
core.sshCommandno longer doubles the fetch timeout, aGIT_SSHin the server's environment is honoured, and the Fetch button's disabled and busy styles no longer reach other icon buttons and stop pulsing under reduced motion (#714). A + launch keeps the toolbar on its own case, and pressing the + again closes its picker (#712). The fetch scheduler no longer logs the text of a malformed settings.json on every 15-second tick (the parser's message could quote an API key; it now says the file is not valid JSON, once), and a fetch is skipped while the Docker case list cannot be read, so it can never run inside a Docker workspace (#714). A case rename answers409 CONFLICTfor a settings.json it cannot write before it ends any session (#719). The unauthenticated-tunnel warning no longer fires in multi-user mode, where the tunnel has a login in front of it (#718). Untagged input during a guarded submit is held instead of refused, and the skill's staging guide says so (#694). A shell prompt line (a spaced working directory followed by$included) and a labelled../spaced path link as they should, and a bold label or inline code before a path in the response viewer splits it as the terminal does (#687); a URL whose row soft-wraps no longer glues a trailing column onto the next path, and in a table a link in the column right of a wrapped URL stays clickable on the URL's first row (#686). The keyboard hold reads the terminal's height only while rows are held (#711). The README, the plugin's README and its marketplace description now say the codeman skill reads saved Codex conversations outside a Codeman session and refuses everything else there (#707).Docs and tests. New sections for the keyboard hold (next to the terminal geometry rule it is an exception to), the tab +, Git fetch, the settings writer, the tunnel opt-in, the directory spawn, the offline history reader and the experimental agent routes, in CLAUDE.md, the API reference, the architecture notes, the wiki and the codeman skill.