mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-09-30 20:49:41 +02:00
docs(wiki): catch the manual up to 1.29.0 and add the three run modes it never had
The wiki was written for seven run modes and never received Grok Build, DeepSeek Harness or OMP. They now appear everywhere the others do: the modes table and per-CLI notes, install commands, environment prefixes, the Quick Start table, the requirements rows, the vocabulary, and every "seven modes" count. The 1.27 to 1.29.0 changes land on the pages that own them: attaching a case to an existing container, multi-case adoption and the copy-a-case picker (Docker Cases); file reads over ssh in remote cases and what stays unavailable (Remote SSH Sessions, Working With Files, Security); single-page app routing, frame recovery, localhost links as tabs and the egress guard (Web Tabs); DeepSeek as the one non-Claude mode with real stop/blocked signals and Approvals items, Codex's own work detection, last-response, the model-endpoint routes and refreshed counts (HTTP API, Driving From An Agent, Hooks, Notifications, Keeping Agents Running, Core Concepts); Shift+drag, right-click copy, Auto Copy, the Ctrl+Z guard, font weight, the vertical rail and its activity sort (Keyboard Shortcuts, Input And Voice, The Dashboard, Settings Reference); the 600px phone cutoff, Codex shift arrows and iPhone Duo (Mobile Guide); the Docker Compose route and its update rule (Installation, Running As A Service); four new symptom entries and a "which CLIs" question (Troubleshooting, FAQ). Custom model endpoints are deliberately left to #430, which adds that page and edits Agent CLIs, Settings Reference and the sidebar; these edits stay out of the regions #430, #428 and #376 touch, and all three still merge cleanly on top. Both READMEs: the web-tab menu entry is labelled "Add URL" in the UI, not "Add dashboard". Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -443,7 +443,7 @@ PTY Output → 16ms Server Batch → DEC 2026 Wrap → SSE → Client rAF → xt
|
|||||||
- **Clone a GitHub repo as a case** — paste a repository URL into **Add Case → Clone Repo** and Codeman clones it into `~/codeman-cases/<name>` and registers it as a normal case, ready to run an agent in. It preflights the URL while you type (tells you whether it can be cloned anonymously and offers the repo's real branches and tags for the optional branch/tag field), fills the case name in from the URL, and lets you pick which CLI the Run button should use. Public repositories over `https://`; Codeman never collects or stores credentials
|
- **Clone a GitHub repo as a case** — paste a repository URL into **Add Case → Clone Repo** and Codeman clones it into `~/codeman-cases/<name>` and registers it as a normal case, ready to run an agent in. It preflights the URL while you type (tells you whether it can be cloned anonymously and offers the repo's real branches and tags for the optional branch/tag field), fills the case name in from the URL, and lets you pick which CLI the Run button should use. Public repositories over `https://`; Codeman never collects or stores credentials
|
||||||
- **Multi-CLI** — run **Claude Code**, **OpenCode**, **Codex**, **Antigravity**, **Gemini**, **Pi**, **Grok**, **DeepSeek Harness**, or **OMP** per session; env-var prefixes auto-gate (`CLAUDE_CODE_*` vs `OPENCODE_*` vs `CODEX_*` vs `ANTIGRAVITY_*` vs `GEMINI_*`/`GOOGLE_*` vs `PI_*` vs `GROK_*`/`XAI_*` vs `DSH_*`/`DEEPSEEK_*` vs `OMP_*`). See [`docs/opencode-integration.md`](docs/opencode-integration.md), [`docs/pi-integration.md`](docs/pi-integration.md), [`docs/grok-integration.md`](docs/grok-integration.md), [`docs/deepseek-integration.md`](docs/deepseek-integration.md) and [`docs/omp-integration.md`](docs/omp-integration.md)
|
- **Multi-CLI** — run **Claude Code**, **OpenCode**, **Codex**, **Antigravity**, **Gemini**, **Pi**, **Grok**, **DeepSeek Harness**, or **OMP** per session; env-var prefixes auto-gate (`CLAUDE_CODE_*` vs `OPENCODE_*` vs `CODEX_*` vs `ANTIGRAVITY_*` vs `GEMINI_*`/`GOOGLE_*` vs `PI_*` vs `GROK_*`/`XAI_*` vs `DSH_*`/`DEEPSEEK_*` vs `OMP_*`). See [`docs/opencode-integration.md`](docs/opencode-integration.md), [`docs/pi-integration.md`](docs/pi-integration.md), [`docs/grok-integration.md`](docs/grok-integration.md), [`docs/deepseek-integration.md`](docs/deepseek-integration.md) and [`docs/omp-integration.md`](docs/omp-integration.md)
|
||||||
- **Custom model endpoints** _(new in 1.29.0, HTTP API for now)_ — point a session's CLI at any OpenAI-compatible endpoint instead of its native backend: a local llama.cpp, llama-swap, Ollama or vLLM box, or a cloud gateway such as Azure AI Foundry or OpenRouter. Save an endpoint once (`POST /api/model-endpoints`; its models are discovered from `/v1/models`), apply it to a session (`POST /api/sessions/:id/custom-model`), and the CLI restarts in place on that endpoint. Verified live for Claude, OpenCode, Pi, Grok and OMP; Codex, Gemini and DeepSeek have documented gaps, Antigravity has no mechanism. A toolbar picker is the follow-up. See [`docs/custom-model-endpoints.md`](docs/custom-model-endpoints.md)
|
- **Custom model endpoints** _(new in 1.29.0, HTTP API for now)_ — point a session's CLI at any OpenAI-compatible endpoint instead of its native backend: a local llama.cpp, llama-swap, Ollama or vLLM box, or a cloud gateway such as Azure AI Foundry or OpenRouter. Save an endpoint once (`POST /api/model-endpoints`; its models are discovered from `/v1/models`), apply it to a session (`POST /api/sessions/:id/custom-model`), and the CLI restarts in place on that endpoint. Verified live for Claude, OpenCode, Pi, Grok and OMP; Codex, Gemini and DeepSeek have documented gaps, Antigravity has no mechanism. A toolbar picker is the follow-up. See [`docs/custom-model-endpoints.md`](docs/custom-model-endpoints.md)
|
||||||
- **Web tabs** — open Grafana, Uptime Kuma, a Vite dev server or any dashboard URL as a tab beside your sessions (Run dropdown → **Web / URL** → **Add dashboard**). Dashboards are proxied through Codeman's own origin, so an `http://` target works from a phone over HTTPS and through the tunnel, single-page apps route on their own paths, and a frame that reloads recovers itself. A `localhost` link an agent prints opens as a web tab automatically. See [`docs/web-tabs.md`](docs/web-tabs.md)
|
- **Web tabs** — open Grafana, Uptime Kuma, a Vite dev server or any dashboard URL as a tab beside your sessions (Run dropdown → **Web / URL** → **Add URL**). Dashboards are proxied through Codeman's own origin, so an `http://` target works from a phone over HTTPS and through the tunnel, single-page apps route on their own paths, and a frame that reloads recovers itself. A `localhost` link an agent prints opens as a web tab automatically. See [`docs/web-tabs.md`](docs/web-tabs.md)
|
||||||
- **Docker sessions** — run a case inside an isolated, hardened container. One checkbox on **Create New** spins up a container with sensible defaults and starts the agent inside it; multiple sessions share one per-case container, or attach a case to a container you already run; export a container + its workspace to a portable `.tar.gz` to move it to another machine. See [`docs/docker-cases.md`](docs/docker-cases.md)
|
- **Docker sessions** — run a case inside an isolated, hardened container. One checkbox on **Create New** spins up a container with sensible defaults and starts the agent inside it; multiple sessions share one per-case container, or attach a case to a container you already run; export a container + its workspace to a portable `.tar.gz` to move it to another machine. See [`docs/docker-cases.md`](docs/docker-cases.md)
|
||||||
- **Remote SSH sessions** — point a case at another machine and run the agent there inside a durable remote tmux: survives SSH drops, auto-reconnects, and can discover + attach sessions already running on the host; file previews and downloads come over the same ssh connection. See [`docs/remote-sessions.md`](docs/remote-sessions.md)
|
- **Remote SSH sessions** — point a case at another machine and run the agent there inside a durable remote tmux: survives SSH drops, auto-reconnects, and can discover + attach sessions already running on the host; file previews and downloads come over the same ssh connection. See [`docs/remote-sessions.md`](docs/remote-sessions.md)
|
||||||
- **Effort & Ultracode** — set a per-session default effort (`low`–`max`) or enable **ultracode** (dynamic multi-agent workflows). Soft defaults only — switchable anytime with `/effort` in-session. Extended-thinking budget is configurable too
|
- **Effort & Ultracode** — set a per-session default effort (`low`–`max`) or enable **ultracode** (dynamic multi-agent workflows). Soft defaults only — switchable anytime with `/effort` in-session. Extended-thinking budget is configurable too
|
||||||
|
|||||||
+1
-1
@@ -445,7 +445,7 @@ PTY 输出 → 16ms 服务端批处理 → DEC 2026 包裹 → SSE → 客户端
|
|||||||
- **把 GitHub 仓库克隆成 case** —— 在 **Add Case → Clone Repo** 里粘贴一个仓库 URL,Codeman 会把它克隆到 `~/codeman-cases/<name>` 并注册为普通 case,随时可以跑智能体。输入时它会预检 URL(告诉你能否匿名克隆,并为可选的分支/标签字段提供仓库真实的分支与标签),从 URL 里填好 case 名,还让你选 Run 按钮该用哪个 CLI。支持 `https://` 的公开仓库;Codeman 绝不收集或保存凭据
|
- **把 GitHub 仓库克隆成 case** —— 在 **Add Case → Clone Repo** 里粘贴一个仓库 URL,Codeman 会把它克隆到 `~/codeman-cases/<name>` 并注册为普通 case,随时可以跑智能体。输入时它会预检 URL(告诉你能否匿名克隆,并为可选的分支/标签字段提供仓库真实的分支与标签),从 URL 里填好 case 名,还让你选 Run 按钮该用哪个 CLI。支持 `https://` 的公开仓库;Codeman 绝不收集或保存凭据
|
||||||
- **多 CLI** —— 每个会话可选 **Claude Code**、**OpenCode**、**Codex**、**Antigravity**、**Gemini**、**Pi**、**Grok**、**DeepSeek Harness** 或 **OMP**;环境变量前缀自动隔离(`CLAUDE_CODE_*`、`OPENCODE_*`、`CODEX_*`、`ANTIGRAVITY_*`、`GEMINI_*`/`GOOGLE_*`、`PI_*`、`GROK_*`/`XAI_*`、`DSH_*`/`DEEPSEEK_*` 与 `OMP_*`)。详见 [`docs/opencode-integration.md`](docs/opencode-integration.md)、[`docs/pi-integration.md`](docs/pi-integration.md)、[`docs/grok-integration.md`](docs/grok-integration.md)、[`docs/deepseek-integration.md`](docs/deepseek-integration.md) 与 [`docs/omp-integration.md`](docs/omp-integration.md)
|
- **多 CLI** —— 每个会话可选 **Claude Code**、**OpenCode**、**Codex**、**Antigravity**、**Gemini**、**Pi**、**Grok**、**DeepSeek Harness** 或 **OMP**;环境变量前缀自动隔离(`CLAUDE_CODE_*`、`OPENCODE_*`、`CODEX_*`、`ANTIGRAVITY_*`、`GEMINI_*`/`GOOGLE_*`、`PI_*`、`GROK_*`/`XAI_*`、`DSH_*`/`DEEPSEEK_*` 与 `OMP_*`)。详见 [`docs/opencode-integration.md`](docs/opencode-integration.md)、[`docs/pi-integration.md`](docs/pi-integration.md)、[`docs/grok-integration.md`](docs/grok-integration.md)、[`docs/deepseek-integration.md`](docs/deepseek-integration.md) 与 [`docs/omp-integration.md`](docs/omp-integration.md)
|
||||||
- **自定义模型端点**(1.29.0 新增,目前仅 HTTP API)—— 让某个会话的 CLI 指向任意 OpenAI 兼容端点,而不是它自己的官方后端:本地的 llama.cpp、llama-swap、Ollama 或 vLLM 机器,也可以是 Azure AI Foundry、OpenRouter 这类云端网关。端点只需保存一次(`POST /api/model-endpoints`,模型列表从它的 `/v1/models` 自动发现),再应用到会话(`POST /api/sessions/:id/custom-model`),CLI 就会在原地重启并接上该端点。Claude、OpenCode、Pi、Grok 与 OMP 已实测通过;Codex、Gemini 与 DeepSeek 存在已记录的缺口,Antigravity 没有可用机制。工具栏选择器是下一步。详见 [`docs/custom-model-endpoints.md`](docs/custom-model-endpoints.md)
|
- **自定义模型端点**(1.29.0 新增,目前仅 HTTP API)—— 让某个会话的 CLI 指向任意 OpenAI 兼容端点,而不是它自己的官方后端:本地的 llama.cpp、llama-swap、Ollama 或 vLLM 机器,也可以是 Azure AI Foundry、OpenRouter 这类云端网关。端点只需保存一次(`POST /api/model-endpoints`,模型列表从它的 `/v1/models` 自动发现),再应用到会话(`POST /api/sessions/:id/custom-model`),CLI 就会在原地重启并接上该端点。Claude、OpenCode、Pi、Grok 与 OMP 已实测通过;Codex、Gemini 与 DeepSeek 存在已记录的缺口,Antigravity 没有可用机制。工具栏选择器是下一步。详见 [`docs/custom-model-endpoints.md`](docs/custom-model-endpoints.md)
|
||||||
- **Web 标签页** —— 把 Grafana、Uptime Kuma、一个 Vite 开发服务器或任何仪表盘 URL 作为标签页打开在会话旁边(Run 下拉菜单 → **Web / URL** → **Add dashboard**)。仪表盘通过 Codeman 自己的源代理,因此 `http://` 目标在手机上走 HTTPS 也能用、走隧道也能用;单页应用能在自己的路径上正常路由,页面自己重载后也能自行恢复。智能体打印出的 `localhost` 链接会自动以 Web 标签页打开。详见 [`docs/web-tabs.md`](docs/web-tabs.md)
|
- **Web 标签页** —— 把 Grafana、Uptime Kuma、一个 Vite 开发服务器或任何仪表盘 URL 作为标签页打开在会话旁边(Run 下拉菜单 → **Web / URL** → **Add URL**)。仪表盘通过 Codeman 自己的源代理,因此 `http://` 目标在手机上走 HTTPS 也能用、走隧道也能用;单页应用能在自己的路径上正常路由,页面自己重载后也能自行恢复。智能体打印出的 `localhost` 链接会自动以 Web 标签页打开。详见 [`docs/web-tabs.md`](docs/web-tabs.md)
|
||||||
- **Docker 会话** —— 在隔离且加固的容器中运行 case。**Create New** 上勾选一个复选框即可用合理的默认值启动容器并在其中启动智能体;同一 case 的多个会话共享一个容器,也可以把 case 挂到你已经在跑的容器上;可将容器连同工作区导出为可移植的 `.tar.gz`,迁移到另一台机器。详见 [`docs/docker-cases.md`](docs/docker-cases.md)
|
- **Docker 会话** —— 在隔离且加固的容器中运行 case。**Create New** 上勾选一个复选框即可用合理的默认值启动容器并在其中启动智能体;同一 case 的多个会话共享一个容器,也可以把 case 挂到你已经在跑的容器上;可将容器连同工作区导出为可移植的 `.tar.gz`,迁移到另一台机器。详见 [`docs/docker-cases.md`](docs/docker-cases.md)
|
||||||
- **远程 SSH 会话** —— 把 case 指向另一台机器,让智能体在那里一个持久的远程 tmux 中运行:SSH 断连不中断任务、自动重连,还能发现并附着主机上已在运行的会话;文件预览与下载走同一条 ssh 连接。详见 [`docs/remote-sessions.md`](docs/remote-sessions.md)
|
- **远程 SSH 会话** —— 把 case 指向另一台机器,让智能体在那里一个持久的远程 tmux 中运行:SSH 断连不中断任务、自动重连,还能发现并附着主机上已在运行的会话;文件预览与下载走同一条 ssh 连接。详见 [`docs/remote-sessions.md`](docs/remote-sessions.md)
|
||||||
- **Effort 与 Ultracode** —— 设置每会话的默认 effort(`low`–`max`),或启用 **ultracode**(动态多智能体工作流)。这些都只是软默认值 —— 会话中可随时用 `/effort` 切换。扩展思考预算也可配置
|
- **Effort 与 Ultracode** —— 设置每会话的默认 effort(`low`–`max`),或启用 **ultracode**(动态多智能体工作流)。这些都只是软默认值 —— 会话中可随时用 `/effort` 切换。扩展思考预算也可配置
|
||||||
|
|||||||
+85
-11
@@ -1,9 +1,9 @@
|
|||||||
# Agent CLIs
|
# Agent CLIs
|
||||||
|
|
||||||
Codeman drives seven run modes: six agent CLIs plus a plain shell. This page covers picking
|
Codeman drives ten run modes: nine agent CLIs plus a plain shell. This page covers picking
|
||||||
one, setting it up, and the differences that actually change how you work.
|
one, setting it up, and the differences that actually change how you work.
|
||||||
|
|
||||||
## The seven modes
|
## The ten modes
|
||||||
|
|
||||||
| Mode | CLI | Get it |
|
| Mode | CLI | Get it |
|
||||||
| -------------------- | ---------------------------- | ---------------------------------------------------------------------- |
|
| -------------------- | ---------------------------- | ---------------------------------------------------------------------- |
|
||||||
@@ -13,6 +13,9 @@ one, setting it up, and the differences that actually change how you work.
|
|||||||
| **Gemini** | `gemini` | [github.com/google-gemini/gemini-cli](https://github.com/google-gemini/gemini-cli) |
|
| **Gemini** | `gemini` | [github.com/google-gemini/gemini-cli](https://github.com/google-gemini/gemini-cli) |
|
||||||
| **Antigravity** | `agy` | [antigravity.google](https://antigravity.google) |
|
| **Antigravity** | `agy` | [antigravity.google](https://antigravity.google) |
|
||||||
| **Pi** | `pi` | [pi.dev](https://pi.dev) |
|
| **Pi** | `pi` | [pi.dev](https://pi.dev) |
|
||||||
|
| **Grok Build** | `grok` | [github.com/xai-org/grok-build](https://github.com/xai-org/grok-build) |
|
||||||
|
| **DeepSeek Harness** | `dsh` | [github.com/deepseek-ai/deepseek-harness](https://github.com/deepseek-ai/deepseek-harness) |
|
||||||
|
| **OMP** | `omp` | [github.com/can1357/oh-my-pi](https://github.com/can1357/oh-my-pi) |
|
||||||
| **Terminal / Shell** | your `$SHELL` | Already installed. |
|
| **Terminal / Shell** | your `$SHELL` | Already installed. |
|
||||||
|
|
||||||
Any combination works, including all of them. The run mode is chosen per session from the
|
Any combination works, including all of them. The run mode is chosen per session from the
|
||||||
@@ -47,8 +50,12 @@ If a CLI is installed but a Run button for it never appears:
|
|||||||
precisely to avoid this; a hand-written plist or unit will not.
|
precisely to avoid this; a hand-written plist or unit will not.
|
||||||
3. Restart the server after installing a new CLI.
|
3. Restart the server after installing a new CLI.
|
||||||
|
|
||||||
`pi` is additionally version-probed rather than trusted by name, because `pi` is a generic
|
`pi`, `grok`, `omp` and `dsh` are additionally identity-probed rather than trusted by name:
|
||||||
enough command that something else on your PATH may answer to it.
|
`pi` and `omp` are generic enough that something else on your PATH may answer to them,
|
||||||
|
`grok` has npm squatters, and Debian ships an unrelated `dsh` (dancer's shell). Each has a
|
||||||
|
status endpoint (`/api/grok/status`, `/api/deepseek/status`, `/api/omp/status`) that reports
|
||||||
|
the path and version that actually resolved, so a misresolution is visible rather than
|
||||||
|
presenting as "the mode just does not work".
|
||||||
|
|
||||||
## Claude is the reference mode
|
## Claude is the reference mode
|
||||||
|
|
||||||
@@ -62,15 +69,15 @@ output. The other CLIs expose no equivalent.
|
|||||||
| Respawn cycling and unattended runs | Yes | Yes |
|
| Respawn cycling and unattended runs | Yes | Yes |
|
||||||
| Cron jobs | Yes | Yes |
|
| Cron jobs | Yes | Yes |
|
||||||
| Docker cases, remote SSH cases | Yes | Yes |
|
| Docker cases, remote SSH cases | Yes | Yes |
|
||||||
| Precise idle detection (hook-driven) | Yes | Output-stabilization fallback, coarser |
|
| Precise idle detection | Yes | Codex: same screen check, via its own prompt and working line. DeepSeek: reports its state itself. Others: output stabilization, coarser |
|
||||||
| Auto-resume when a usage limit resets | Yes | No |
|
| Auto-resume when a usage limit resets | Yes | No |
|
||||||
| Plan usage chip | Yes | No |
|
| Plan usage chip | Yes | No |
|
||||||
| Approvals Inbox | Yes | No |
|
| Approvals Inbox | Yes | DeepSeek yes; others no |
|
||||||
| Read My Mind | Yes | No |
|
| Read My Mind | Yes | No |
|
||||||
| Ralph loop and its task tracker | Yes | No |
|
| Ralph loop and its task tracker | Yes | No |
|
||||||
| Subagent and team windows | Yes | No |
|
| Subagent and team windows | Yes | No |
|
||||||
| Model, effort, and ultracode controls | Yes | No |
|
| Model, effort, and ultracode controls | Yes | No |
|
||||||
| `stop` and `blocked` wait signals | Yes | 400 if you ask for them explicitly |
|
| `stop` and `blocked` wait signals | Yes | DeepSeek yes; elsewhere 400 if you ask for them explicitly |
|
||||||
| The bundled agent skill | Yes | No |
|
| The bundled agent skill | Yes | No |
|
||||||
|
|
||||||
Everything that makes a session a session works everywhere. What is Claude-only is mostly
|
Everything that makes a session a session works everywhere. What is Claude-only is mostly
|
||||||
@@ -124,6 +131,11 @@ Two behaviours that are deliberate and worth knowing:
|
|||||||
- **The wheel is not forwarded** into its transcript. Codex ignores the mouse reports
|
- **The wheel is not forwarded** into its transcript. Codex ignores the mouse reports
|
||||||
Codeman would send, so forwarding produced a dead wheel. Scrolling in a Codex session is
|
Codeman would send, so forwarding produced a dead wheel. Scrolling in a Codex session is
|
||||||
local scrollback.
|
local scrollback.
|
||||||
|
- **Work detection is Codex's own.** Codex declares its `›` composer glyph and its
|
||||||
|
`esc to interrupt` working line, so it gets the same screen-checked idle detection Claude
|
||||||
|
does; before 1.26.1 every Codex session reported idle for its whole life. Codex
|
||||||
|
conversations also appear in Past Sessions and can be resumed, and on phones the keyboard
|
||||||
|
bar grows `⇧←` / `⇧→` for Codex's queued-message editing and prompt stack.
|
||||||
|
|
||||||
### Gemini
|
### Gemini
|
||||||
|
|
||||||
@@ -157,6 +169,60 @@ Pi needs the opposite instincts from every other CLI here.
|
|||||||
|
|
||||||
Guide: [`docs/pi-integration.md`](https://github.com/Ark0N/Codeman/blob/master/docs/pi-integration.md).
|
Guide: [`docs/pi-integration.md`](https://github.com/Ark0N/Codeman/blob/master/docs/pi-integration.md).
|
||||||
|
|
||||||
|
### Grok Build
|
||||||
|
|
||||||
|
xAI's `grok`, installed with `curl -fsSL https://x.ai/cli/install.sh | bash` into
|
||||||
|
`~/.grok/bin`. Codex-shaped on permissions and OpenCode-shaped on rendering:
|
||||||
|
|
||||||
|
- **Its bypass switch is `--always-approve`**, Grok's own `bypassPermissions` mode, and the
|
||||||
|
Run button sends it the way it sends Codex's. In multi-user mode a user without a grant
|
||||||
|
has it stripped.
|
||||||
|
- **Authentication is Grok's own**: browser OAuth on first run (a device-code screen inside
|
||||||
|
a Codeman pane), `grok login --device-auth` for headless hosts, or `XAI_API_KEY` as a
|
||||||
|
per-session environment override.
|
||||||
|
- It renders a full-screen TUI, so scrolling is local scrollback.
|
||||||
|
|
||||||
|
Guide: [`docs/grok-integration.md`](https://github.com/Ark0N/Codeman/blob/master/docs/grok-integration.md).
|
||||||
|
|
||||||
|
### DeepSeek Harness
|
||||||
|
|
||||||
|
The mode wired least like the others, for two reasons worth knowing before you use it.
|
||||||
|
|
||||||
|
**`dsh` is a launcher, not an agent.** It boots a *profile*, and the three DeepSeek ships
|
||||||
|
(`web`, `headless`, `base`) cannot drive a terminal pane. So "installed" and "runnable" are
|
||||||
|
different questions: the Run menu offers **DeepSeek** only once a pane-capable profile
|
||||||
|
exists, and until then shows **DeepSeek — add a terminal profile…**, which installs the
|
||||||
|
community `dsh-tui` with one click (`pnpm` must be on PATH, because the launcher spawns it
|
||||||
|
directly).
|
||||||
|
|
||||||
|
**Permissions are an environment variable, not a flag.** The harness has no
|
||||||
|
skip-permissions switch. `DSH_PERMISSION_MODE` (`read-only`, `workspace-write`,
|
||||||
|
`danger-full-access`) is the whole control, and it is the one setting Codeman deliberately
|
||||||
|
carries as an environment variable, because the harness reads it as a soft boot-time
|
||||||
|
default. In multi-user mode a user without a grant is clamped to `workspace-write`.
|
||||||
|
|
||||||
|
The reward for the odd wiring: **DeepSeek is the one non-Claude mode with real signals.**
|
||||||
|
Its terminal front door reports idle, working and blocked to Codeman, so a DeepSeek
|
||||||
|
session gets precise idle detection, the `stop` and `blocked` wait signals, and Approvals
|
||||||
|
Inbox items. Answers are read from the harness's own transcript on disk rather than
|
||||||
|
scraped off the pane. The model is not a session setting; it is part of the profile.
|
||||||
|
|
||||||
|
Guide: [`docs/deepseek-integration.md`](https://github.com/Ark0N/Codeman/blob/master/docs/deepseek-integration.md).
|
||||||
|
|
||||||
|
### OMP
|
||||||
|
|
||||||
|
Oh My Pi, installed with `curl -fsSL https://omp.sh/install | sh` into `~/.local/bin`.
|
||||||
|
OMP owns its auth, provider routing and approval mode entirely in `~/.omp`: there is no
|
||||||
|
Codeman-side login, key field, or bypass switch. Run `omp` once outside Codeman to finish
|
||||||
|
its own onboarding, and every session started through Codeman inherits that config. Its
|
||||||
|
documented default approval mode is `yolo`, so an OMP pane auto-approves tool use with no
|
||||||
|
flag from Codeman; change that in OMP's own config, not here.
|
||||||
|
|
||||||
|
OMP conversations appear in Past Sessions and can be resumed, and a respawn continues the
|
||||||
|
same conversation with `--continue`.
|
||||||
|
|
||||||
|
Guide: [`docs/omp-integration.md`](https://github.com/Ark0N/Codeman/blob/master/docs/omp-integration.md).
|
||||||
|
|
||||||
### Terminal / Shell
|
### Terminal / Shell
|
||||||
|
|
||||||
A plain shell in a tmux session. No agent, no hooks, no idle detection.
|
A plain shell in a tmux session. No agent, no hooks, no idle detection.
|
||||||
@@ -180,9 +246,15 @@ respawns. Which variables are accepted depends on the mode:
|
|||||||
| Gemini | `GEMINI_*`, `GOOGLE_*` |
|
| Gemini | `GEMINI_*`, `GOOGLE_*` |
|
||||||
| Antigravity | `ANTIGRAVITY_*` |
|
| Antigravity | `ANTIGRAVITY_*` |
|
||||||
| Pi | `PI_*` |
|
| Pi | `PI_*` |
|
||||||
|
| Grok | `GROK_*`, `XAI_*` |
|
||||||
|
| DeepSeek | `DSH_*`, `DEEPSEEK_*` |
|
||||||
|
| OMP | `OMP_*` |
|
||||||
|
|
||||||
Anything outside the allowlist is rejected at the schema. This is intentional: the allowlist
|
Anything outside the allowlist is rejected at the schema. This is intentional: the allowlist
|
||||||
is one global list, so widening it for one CLI widens it for all of them.
|
is one global list, so widening it for one CLI widens it for all of them. In multi-user mode
|
||||||
|
the keys that could redirect a CLI's traffic or move its config home (`DSH_PERMISSION_MODE`,
|
||||||
|
`DSH_HOME`, `DEEPSEEK_BASE_URL`, `OMP_AUTH_BROKER_URL`, and the base URLs and config
|
||||||
|
directories of the others) are dropped for a user without the bypass grant.
|
||||||
|
|
||||||
Two things that deliberately do **not** travel as environment variables: **effort**, because
|
Two things that deliberately do **not** travel as environment variables: **effort**, because
|
||||||
an environment variable hard-locks it and blocks `/effort`, and **model**, which is written
|
an environment variable hard-locks it and blocks `/effort`, and **model**, which is written
|
||||||
@@ -192,9 +264,11 @@ into the case's `.claude/settings.local.json` so that `/model` keeps working.
|
|||||||
|
|
||||||
- **Claude Code** if you want every Codeman feature. Unattended overnight runs, usage-limit
|
- **Claude Code** if you want every Codeman feature. Unattended overnight runs, usage-limit
|
||||||
auto-resume, the Approvals Inbox, and subagent visualization all assume it.
|
auto-resume, the Approvals Inbox, and subagent visualization all assume it.
|
||||||
- **Codex, OpenCode, Gemini, Antigravity** when you prefer that agent or that model. You get
|
- **Codex, OpenCode, Gemini, Antigravity, Grok, OMP** when you prefer that agent or that
|
||||||
the session layer, respawn, cron, Docker, and remote SSH; you do not get the hook-driven
|
model. You get the session layer, respawn, cron, Docker, and remote SSH; you do not get the
|
||||||
features.
|
hook-driven features.
|
||||||
|
- **DeepSeek Harness** if you want DeepSeek's models with real status signals. It is the one
|
||||||
|
non-Claude mode that reports idle, working and blocked to Codeman itself.
|
||||||
- **Pi** if you want a fast, unsandboxed agent and you understand what project trust does.
|
- **Pi** if you want a fast, unsandboxed agent and you understand what project trust does.
|
||||||
- **Shell** for the times you want a terminal on your phone with no agent at all. It is a
|
- **Shell** for the times you want a terminal on your phone with no agent at all. It is a
|
||||||
genuinely useful mode, not a fallback.
|
genuinely useful mode, not a fallback.
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ Conventions for wiki pages:
|
|||||||
- Images are referenced from the main repository over raw URLs rather than being copied into
|
- Images are referenced from the main repository over raw URLs rather than being copied into
|
||||||
the wiki.
|
the wiki.
|
||||||
- Say what the default is, especially when it is off. Most of Codeman is opt-in.
|
- Say what the default is, especially when it is off. Most of Codeman is opt-in.
|
||||||
- Label Claude-only behaviour every time it appears. Six of the seven run modes are not
|
- Label Claude-only behaviour every time it appears. Nine of the ten run modes are not
|
||||||
Claude.
|
Claude.
|
||||||
|
|
||||||
## Conduct
|
## Conduct
|
||||||
|
|||||||
@@ -50,10 +50,10 @@ A session carries state the case does not:
|
|||||||
## Run mode
|
## Run mode
|
||||||
|
|
||||||
The **run mode** is which CLI the session runs: `claude`, `opencode`, `codex`, `gemini`,
|
The **run mode** is which CLI the session runs: `claude`, `opencode`, `codex`, `gemini`,
|
||||||
`antigravity`, `pi`, or `shell`. It is chosen at start and does not change afterwards; to
|
`antigravity`, `pi`, `grok`, `deepseek`, `omp`, or `shell`. It is chosen at start and does not change afterwards; to
|
||||||
switch, start another session.
|
switch, start another session.
|
||||||
|
|
||||||
Claude is the reference mode. Six of the seven are not Claude, and a number of Codeman
|
Claude is the reference mode. Nine of the ten are not Claude, and a number of Codeman
|
||||||
features are Claude-only for structural reasons rather than missing effort: they depend on
|
features are Claude-only for structural reasons rather than missing effort: they depend on
|
||||||
Claude Code's hook system or on parsing its terminal output. Every such feature is labelled
|
Claude Code's hook system or on parsing its terminal output. Every such feature is labelled
|
||||||
Claude-only where it appears, and [Agent CLIs](Agent-CLIs) lists them in one place.
|
Claude-only where it appears, and [Agent CLIs](Agent-CLIs) lists them in one place.
|
||||||
@@ -68,8 +68,8 @@ Where a case runs is **separate from** which CLI it runs. There are three locati
|
|||||||
| **Docker** | One long-lived container per case; sessions `docker exec` into it. See [Docker Cases](Docker-Cases). |
|
| **Docker** | One long-lived container per case; sessions `docker exec` into it. See [Docker Cases](Docker-Cases). |
|
||||||
| **Remote SSH** | A durable tmux server on the remote host, fronted by a local pane running `ssh`. See [Remote SSH Sessions](Remote-SSH-Sessions). |
|
| **Remote SSH** | A durable tmux server on the remote host, fronted by a local pane running `ssh`. See [Remote SSH Sessions](Remote-SSH-Sessions). |
|
||||||
|
|
||||||
This matters because it is a common source of confusion: Docker is **not** an eighth run
|
This matters because it is a common source of confusion: Docker is **not** an eleventh run
|
||||||
mode. All seven run modes work in all three locations. A case is docker-backed or
|
mode. All ten run modes work in all three locations. A case is docker-backed or
|
||||||
ssh-backed; a session is claude or codex or shell.
|
ssh-backed; a session is claude or codex or shell.
|
||||||
|
|
||||||
**Web tabs** are the other thing that is not a session. A saved dashboard URL renders as a
|
**Web tabs** are the other thing that is not a session. A saved dashboard URL renders as a
|
||||||
@@ -155,9 +155,11 @@ report events back: a permission prompt appeared, the turn finished, the agent w
|
|||||||
task completed. Those events drive tab alerts, the Approvals Inbox, notifications, and the
|
task completed. Those events drive tab alerts, the Approvals Inbox, notifications, and the
|
||||||
wait primitives.
|
wait primitives.
|
||||||
|
|
||||||
This is why some features are Claude-only. The other CLIs have no equivalent hook system,
|
This is why some features are Claude-only. The one partial exception is DeepSeek Harness,
|
||||||
so for them Codeman falls back to watching terminal output, which is coarser: it can see
|
whose terminal front door reports idle, working and blocked to Codeman over the harness's
|
||||||
that something happened, not what it was.
|
own supervisor contract, so it gets the hook-driven signals without a hook file. The other
|
||||||
|
CLIs have no equivalent, so for them Codeman falls back to watching terminal output, which
|
||||||
|
is coarser: it can see that something happened, not what it was.
|
||||||
|
|
||||||
See [Hooks And Integrations](Hooks-And-Integrations).
|
See [Hooks And Integrations](Hooks-And-Integrations).
|
||||||
|
|
||||||
@@ -167,7 +169,7 @@ See [Hooks And Integrations](Hooks-And-Integrations).
|
|||||||
| --------------- | ---------------------------------------------------------------------------- |
|
| --------------- | ---------------------------------------------------------------------------- |
|
||||||
| **Case** | Named working directory. |
|
| **Case** | Named working directory. |
|
||||||
| **Session** | One CLI in one tmux session. |
|
| **Session** | One CLI in one tmux session. |
|
||||||
| **Run mode** | Which CLI: claude, opencode, codex, gemini, antigravity, pi, shell. |
|
| **Run mode** | Which CLI: claude, opencode, codex, gemini, antigravity, pi, grok, deepseek, omp, shell. |
|
||||||
| **Respawn** | Restarting the CLI on idle to keep an unattended run going. |
|
| **Respawn** | Restarting the CLI on idle to keep an unattended run going. |
|
||||||
| **Ralph loop** | An autonomous single-session task loop. |
|
| **Ralph loop** | An autonomous single-session task loop. |
|
||||||
| **Orchestrator**| A phased plan driven across multiple agents. |
|
| **Orchestrator**| A phased plan driven across multiple agents. |
|
||||||
@@ -178,6 +180,6 @@ See [Hooks And Integrations](Hooks-And-Integrations).
|
|||||||
## Read next
|
## Read next
|
||||||
|
|
||||||
- [The Dashboard](The-Dashboard) - what the UI is showing you.
|
- [The Dashboard](The-Dashboard) - what the UI is showing you.
|
||||||
- [Agent CLIs](Agent-CLIs) - the seven run modes in detail.
|
- [Agent CLIs](Agent-CLIs) - the ten run modes in detail.
|
||||||
- [Keeping Agents Running](Keeping-Agents-Running) - respawn, idle detection, usage limits.
|
- [Keeping Agents Running](Keeping-Agents-Running) - respawn, idle detection, usage limits.
|
||||||
- [`docs/architecture-invariants.md`](https://github.com/Ark0N/Codeman/blob/master/docs/architecture-invariants.md) - the mechanisms behind all of this, for contributors.
|
- [`docs/architecture-invariants.md`](https://github.com/Ark0N/Codeman/blob/master/docs/architecture-invariants.md) - the mechanisms behind all of this, for contributors.
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ Run a case inside its own container instead of directly on your host: for isolat
|
|||||||
reproducible toolchain, and for the ability to pick the whole environment up and move it to
|
reproducible toolchain, and for the ability to pick the whole environment up and move it to
|
||||||
another machine.
|
another machine.
|
||||||
|
|
||||||
A docker case is a **location overlay**, not a run mode. All seven run modes work inside a
|
A docker case is a **location overlay**, not a run mode. All ten run modes work inside a
|
||||||
container. See [Core Concepts](Core-Concepts).
|
container. See [Core Concepts](Core-Concepts).
|
||||||
|
|
||||||
## One-time setup: the base image
|
## One-time setup: the base image
|
||||||
@@ -26,7 +26,7 @@ A zero exit code proves the layers ran, not that the toolchain works. Verify:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker run --rm codeman/agent:base bash -lc \
|
docker run --rm codeman/agent:base bash -lc \
|
||||||
'for c in claude codex gemini opencode agy pi; do printf "%-9s " $c; $c --version 2>&1 | head -1; done'
|
'for c in claude codex gemini opencode agy pi grok dsh omp; do printf "%-9s " $c; $c --version 2>&1 | head -1; done'
|
||||||
```
|
```
|
||||||
|
|
||||||
The image is secret-free. Credentials are delivered at runtime, never baked in, so exports
|
The image is secret-free. Credentials are delivered at runtime, never baked in, so exports
|
||||||
@@ -79,6 +79,25 @@ Exactly one long-lived container per case, shared by every session in it.
|
|||||||
conversation** from the bind-mounted transcript.
|
conversation** from the bind-mounted transcript.
|
||||||
- Deleting the case removes the container. The workspace on the host survives.
|
- Deleting the case removes the container. The workspace on the host survives.
|
||||||
|
|
||||||
|
## Attaching to a container you already run
|
||||||
|
|
||||||
|
Tick **Attach to an existing container** on **Add Case → Docker** to link a case to a
|
||||||
|
container that already exists instead of creating one. Codeman only `exec`s into it and
|
||||||
|
never creates, starts, stops, restarts or removes it, so a container that is missing or
|
||||||
|
stopped fails with a message rather than being fixed for you. Drift detection does not
|
||||||
|
apply (the container carries no Codeman configuration label). The full-image export is
|
||||||
|
refused, since it would `docker commit` someone else's container, and the workspace export
|
||||||
|
skips the pause that keeps an owned container consistent during the capture.
|
||||||
|
|
||||||
|
One adopted container can back several cases at different in-container directories, and
|
||||||
|
**copy an existing case** pre-fills the form from a sibling on the same container. An exact
|
||||||
|
twin (the same container and the same directory) is refused, as is a container another
|
||||||
|
user adopted.
|
||||||
|
|
||||||
|
Adoption is **admin-only in multi-user mode**. Linking creates Codeman's own container
|
||||||
|
with one bind mount that has already been checked; an adopted container's mounts belong to
|
||||||
|
whoever started it, and one that mounts `/` hands the adopter the host.
|
||||||
|
|
||||||
## Credentials
|
## Credentials
|
||||||
|
|
||||||
Your existing host logins work inside the container without logging in again. Credentials
|
Your existing host logins work inside the container without logging in again. Credentials
|
||||||
@@ -92,10 +111,12 @@ the container instead.
|
|||||||
|
|
||||||
Bind mounts are excluded from image capture, so exports stay secret-free.
|
Bind mounts are excluded from image capture, so exports stay secret-free.
|
||||||
|
|
||||||
One consequence worth knowing: Pi's credentials are seeded per file rather than as a whole
|
One consequence worth knowing: Pi, Grok and OMP credentials are seeded per file rather than
|
||||||
directory, because that directory also holds sessions, extensions, and installed packages,
|
as whole directories, because those directories also hold sessions, extensions, downloads and
|
||||||
which can be gigabytes. So in-container Pi sessions are invisible from the host, and `pi -c`
|
installed packages, which can be gigabytes. So in-container Pi and Grok sessions are
|
||||||
inside a docker case sees only that container's history.
|
invisible from the host (`pi -c` and `grok -c` inside a docker case see only that
|
||||||
|
container's history). OMP's `sessions/` is the exception and is shared read-write, because
|
||||||
|
Codeman reads it host-side for history and resume.
|
||||||
|
|
||||||
## Isolation
|
## Isolation
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,10 @@ create-time sweep would yank the skill out from under other live sessions sharin
|
|||||||
directory. Remove them per case with `codeman skill uninstall --case <name>`.
|
directory. Remove them per case with `codeman skill uninstall --case <name>`.
|
||||||
|
|
||||||
The skill ships with the verb index always loaded, plus on-demand references for the verbs,
|
The skill ships with the verb index always loaded, plus on-demand references for the verbs,
|
||||||
worked multi-worker recipes, endpoint tables, and cross-session messaging.
|
worked multi-worker recipes, endpoint tables, and cross-session messaging. It drives
|
||||||
|
DeepSeek Harness workers the same way it drives Claude ones (`spawn_workers alpha
|
||||||
|
beta:deepseek` is a mixed fleet in one call), since those are the two modes with real
|
||||||
|
completion signals.
|
||||||
|
|
||||||
## The manual path
|
## The manual path
|
||||||
|
|
||||||
@@ -92,8 +95,9 @@ Read these before writing any code. Each one has cost somebody an afternoon.
|
|||||||
5. **Wait instead of polling, and a timeout is not an error.** The wait endpoints answer
|
5. **Wait instead of polling, and a timeout is not an error.** The wait endpoints answer
|
||||||
`200` with `wait.timedOut: true`. Loop over short waits rather than one long call, because
|
`200` with `wait.timedOut: true`. Loop over short waits rather than one long call, because
|
||||||
tunnels cut idle connections.
|
tunnels cut idle connections.
|
||||||
6. **Only `claude` sessions emit `stop` and `blocked`.** They come from Claude Code hooks.
|
6. **Only `claude` and `deepseek` sessions emit `stop` and `blocked`.** Claude's come from
|
||||||
Shell and the external CLIs accept only `idle`, `working`, and `exit`; asking for `stop`
|
Claude Code hooks, DeepSeek's from the harness reporting its state to Codeman. Shell and
|
||||||
|
the other external CLIs accept only `idle`, `working`, and `exit`; asking for `stop`
|
||||||
explicitly there is a `400`, while omitting `until` is always safe. On a shell session
|
explicitly there is a `400`, while omitting `until` is always safe. On a shell session
|
||||||
`idle` fires **once at startup and never again**, so synchronize hook-less sessions with an
|
`idle` fires **once at startup and never again**, so synchronize hook-less sessions with an
|
||||||
output marker instead.
|
output marker instead.
|
||||||
@@ -130,7 +134,10 @@ curl -s -X POST "$API/api/sessions/$ID/input" \
|
|||||||
# Or wait for a marker in the output, which works on shell sessions too
|
# Or wait for a marker in the output, which works on shell sessions too
|
||||||
curl -s "$API/api/sessions/$ID/wait-output?contains=DONE_17909&from=buffer" | jq
|
curl -s "$API/api/sessions/$ID/wait-output?contains=DONE_17909&from=buffer" | jq
|
||||||
|
|
||||||
# Read the terminal back
|
# Read the last answer as clean text (claude, codex, deepseek sessions)
|
||||||
|
curl -s "$API/api/sessions/$ID/last-response" | jq -r '.data.text'
|
||||||
|
|
||||||
|
# Or read the terminal back
|
||||||
curl -s "$API/api/sessions/$ID/terminal?tail=4000" | jq -r '.data.output'
|
curl -s "$API/api/sessions/$ID/terminal?tail=4000" | jq -r '.data.output'
|
||||||
|
|
||||||
# Clean up, by exact id
|
# Clean up, by exact id
|
||||||
@@ -157,7 +164,13 @@ Make it unique per call, because tmux repaints replay old screen text.
|
|||||||
|
|
||||||
### Reading output
|
### Reading output
|
||||||
|
|
||||||
Use `terminal?tail=`, not `/output`. The latter's text field is empty for every tmux-backed
|
For `claude`, `codex` and `deepseek` sessions, read the answer from the transcript rather
|
||||||
|
than the screen: `GET /api/sessions/:id/last-response` returns the last reply as clean text
|
||||||
|
with no TUI frames or repaint noise. Poll it briefly rather than reading once, because the
|
||||||
|
transcript lands slightly after the `stop` signal, so a read immediately after send-and-wait
|
||||||
|
returns often comes back empty.
|
||||||
|
|
||||||
|
For everything else, use `terminal?tail=`, not `/output`. The latter's text field is empty for every tmux-backed
|
||||||
session, which is every interactive session. `tail` counts **bytes**, and what comes back is
|
session, which is every interactive session. `tail` counts **bytes**, and what comes back is
|
||||||
terminal data with ANSI sequences included.
|
terminal data with ANSI sequences included.
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,12 @@ No. Codeman drives agent CLIs you have already installed and logged in yourself.
|
|||||||
subscription or key that CLI uses is what pays for the tokens. Codeman never collects,
|
subscription or key that CLI uses is what pays for the tokens. Codeman never collects,
|
||||||
stores, or refreshes your credentials.
|
stores, or refreshes your credentials.
|
||||||
|
|
||||||
|
### Which agent CLIs does it support?
|
||||||
|
|
||||||
|
Claude Code, OpenCode, Codex, Gemini, Antigravity, Pi, Grok Build, DeepSeek Harness and
|
||||||
|
OMP, plus a plain shell, chosen per session. Claude is the reference mode and a few features
|
||||||
|
are Claude-only; [Agent CLIs](Agent-CLIs) has the table.
|
||||||
|
|
||||||
### Does Codeman send my code or prompts anywhere?
|
### Does Codeman send my code or prompts anywhere?
|
||||||
|
|
||||||
No. There is no telemetry, no analytics, and no phone-home. The only network traffic
|
No. There is no telemetry, no analytics, and no phone-home. The only network traffic
|
||||||
|
|||||||
+18
-9
@@ -66,14 +66,14 @@ self-signed certificate, add `-k`.
|
|||||||
|
|
||||||
## Endpoint map
|
## Endpoint map
|
||||||
|
|
||||||
Roughly 200 handlers across 24 route modules. By domain:
|
Roughly 235 handlers across 26 route modules. By domain:
|
||||||
|
|
||||||
| Domain | Handlers | Covers |
|
| Domain | Handlers | Covers |
|
||||||
| ------------------- | -------- | --------------------------------------------------- |
|
| ------------------- | -------- | --------------------------------------------------- |
|
||||||
| System | 45 | Status, settings, search, digest, updates. |
|
| System | 56 | Status, settings, digest, updates, tunnel. |
|
||||||
| Sessions | 34 | Create, input, terminal, wait, kill. |
|
| Sessions | 34 | Create, input, terminal, wait, last response, kill. |
|
||||||
| Cases | 29 | Create, link, clone, remote and docker cases. |
|
| Cases | 34 | Create, link, clone, remote and docker cases. |
|
||||||
| Files | 16 | Preview, edit, raw, attachments, path picker. |
|
| Files | 17 | Preview, edit, raw, attachments, path picker. |
|
||||||
| Orchestrator | 10 | Plans and phases. |
|
| Orchestrator | 10 | Plans and phases. |
|
||||||
| Ralph | 9 | Loop control and configuration. |
|
| Ralph | 9 | Loop control and configuration. |
|
||||||
| Cron | 9 | Jobs and run history. |
|
| Cron | 9 | Jobs and run history. |
|
||||||
@@ -82,10 +82,12 @@ Roughly 200 handlers across 24 route modules. By domain:
|
|||||||
| Respawn | 7 | Respawn configuration and presets. |
|
| Respawn | 7 | Respawn configuration and presets. |
|
||||||
| Webviews | 6 | Saved dashboards, plus the proxy. |
|
| Webviews | 6 | Saved dashboards, plus the proxy. |
|
||||||
| Mux | 5 | tmux operations. |
|
| Mux | 5 | tmux operations. |
|
||||||
|
| Custom model endpoints | 5 | Saved OpenAI-compatible endpoints, and applying one to a session. |
|
||||||
| Push | 4 | Web push subscriptions. |
|
| Push | 4 | Web push subscriptions. |
|
||||||
| Read My Mind | 4 | Intent profiles and prediction. |
|
| Read My Mind | 4 | Intent profiles and prediction. |
|
||||||
| Scheduled | 4 | The legacy scheduled-run concept. |
|
| Scheduled | 4 | The legacy scheduled-run concept. |
|
||||||
| Approvals | 3 | The inbox and answering. |
|
| Approvals | 4 | The inbox, answering, acknowledging. |
|
||||||
|
| Tab layout | 2 | Named tab groups per owner. |
|
||||||
| Teams, me, search, hooks, clipboard, telemetry, voice, ws | 1-2 each | |
|
| Teams, me, search, hooks, clipboard, telemetry, voice, ws | 1-2 each | |
|
||||||
|
|
||||||
Each route module documents its own endpoints in its file header.
|
Each route module documents its own endpoints in its file header.
|
||||||
@@ -114,12 +116,13 @@ Three semantics that break callers who assume otherwise:
|
|||||||
`wait-output` matches a **literal substring, never a regex.** That is deliberate: no regex
|
`wait-output` matches a **literal substring, never a regex.** That is deliberate: no regex
|
||||||
means no catastrophic backtracking on attacker-influenced output.
|
means no catastrophic backtracking on attacker-influenced output.
|
||||||
|
|
||||||
Only `claude` sessions emit `stop` and `blocked`, because those come from Claude Code hooks.
|
Only `claude` and `deepseek` sessions emit `stop` and `blocked`: Claude's come from Claude
|
||||||
Shell and external CLI sessions accept `idle`, `working`, and `exit`.
|
Code hooks, DeepSeek's from the harness reporting its state to Codeman. Shell and the other
|
||||||
|
external CLI sessions accept `idle`, `working`, and `exit`.
|
||||||
|
|
||||||
## SSE
|
## SSE
|
||||||
|
|
||||||
`GET /api/events` is the live event stream. 156 event names, kept in sync between server and
|
`GET /api/events` is the live event stream. 158 event names, kept in sync between server and
|
||||||
client with a test that fails on drift.
|
client with a test that fails on drift.
|
||||||
|
|
||||||
The heartbeat is a **named** `sse:heartbeat` event rather than an SSE comment, because
|
The heartbeat is a **named** `sse:heartbeat` event rather than an SSE comment, because
|
||||||
@@ -141,6 +144,12 @@ curl -s "$API/api/sessions" | jq '.data[].name' # live sessions
|
|||||||
curl -s "$API/api/sessions/unified" | jq # live + historical, deduped
|
curl -s "$API/api/sessions/unified" | jq # live + historical, deduped
|
||||||
curl -s "$API/api/subagents" | jq # background agents
|
curl -s "$API/api/subagents" | jq # background agents
|
||||||
curl -s "$API/api/search?q=deploy" | jq # cross-session search
|
curl -s "$API/api/search?q=deploy" | jq # cross-session search
|
||||||
|
|
||||||
|
# with ID set to a session id:
|
||||||
|
curl -s "$API/api/sessions/$ID/last-response" | jq -r '.data.text' # last answer, from the transcript (claude, codex, deepseek)
|
||||||
|
curl -s "$API/api/model-endpoints" | jq # saved custom OpenAI-compatible endpoints
|
||||||
|
curl -s -X POST "$API/api/sessions/$ID/custom-model" -H 'Content-Type: application/json' \
|
||||||
|
-d '{"endpointId":"local-llama","modelId":"qwen3-27b"}' | jq # restart the CLI on that endpoint; {"clear":true} undoes it
|
||||||
```
|
```
|
||||||
|
|
||||||
## Limits
|
## Limits
|
||||||
|
|||||||
+4
-4
@@ -5,8 +5,8 @@
|
|||||||
<h3 align="center">Mission control for AI coding agents</h3>
|
<h3 align="center">Mission control for AI coding agents</h3>
|
||||||
|
|
||||||
Codeman runs your coding agents on your own machine and puts them behind one dashboard you
|
Codeman runs your coding agents on your own machine and puts them behind one dashboard you
|
||||||
can open from any device. It spawns Claude Code, OpenCode, Codex, Antigravity, Gemini, or
|
can open from any device. It spawns Claude Code, OpenCode, Codex, Antigravity, Gemini, Pi,
|
||||||
Pi inside persistent tmux sessions, streams the real terminal to the browser, and keeps
|
Grok, DeepSeek Harness, or OMP inside persistent tmux sessions, streams the real terminal to the browser, and keeps
|
||||||
working while you are away from the keyboard: it re-prompts idle agents, resumes when a
|
working while you are away from the keyboard: it re-prompts idle agents, resumes when a
|
||||||
subscription limit resets, runs jobs on a schedule, and shows every background subagent
|
subscription limit resets, runs jobs on a schedule, and shows every background subagent
|
||||||
live.
|
live.
|
||||||
@@ -33,7 +33,7 @@ codeman web # then open http://localhost:3000
|
|||||||
|
|
||||||
**Already running it**
|
**Already running it**
|
||||||
|
|
||||||
- [Agent CLIs](Agent-CLIs) - the seven run modes, their setup, and which features are Claude-only.
|
- [Agent CLIs](Agent-CLIs) - the ten run modes, their setup, and which features are Claude-only.
|
||||||
- [Mobile Guide](Mobile-Guide) - phone and tablet use, QR login, the touch keyboard bar.
|
- [Mobile Guide](Mobile-Guide) - phone and tablet use, QR login, the touch keyboard bar.
|
||||||
- [Remote Access](Remote-Access) - Tailscale, Cloudflare tunnel, LAN plus password, QR login.
|
- [Remote Access](Remote-Access) - Tailscale, Cloudflare tunnel, LAN plus password, QR login.
|
||||||
- [Keeping Agents Running](Keeping-Agents-Running) - idle detection, respawn cycling, auto-resume on usage limits.
|
- [Keeping Agents Running](Keeping-Agents-Running) - idle detection, respawn cycling, auto-resume on usage limits.
|
||||||
@@ -122,7 +122,7 @@ codeman web # then open http://localhost:3000
|
|||||||
| OS | macOS or Linux. Windows works through WSL2. |
|
| OS | macOS or Linux. Windows works through WSL2. |
|
||||||
| Node.js | 22 or newer. |
|
| Node.js | 22 or newer. |
|
||||||
| tmux | Required. Sessions live in tmux, which is what makes them survive restarts. |
|
| tmux | Required. Sessions live in tmux, which is what makes them survive restarts. |
|
||||||
| An agent CLI | At least one of Claude Code, OpenCode, Codex, Gemini, Antigravity, Pi. Plain shell sessions need none. |
|
| An agent CLI | At least one of Claude Code, OpenCode, Codex, Gemini, Antigravity, Pi, Grok Build, DeepSeek Harness, OMP. Plain shell sessions need none. |
|
||||||
| Network | Binds to `127.0.0.1` by default. Reaching it from another device is a deliberate step: see [Remote Access](Remote-Access). |
|
| Network | Binds to `127.0.0.1` by default. Reaching it from another device is a deliberate step: see [Remote Access](Remote-Access). |
|
||||||
|
|
||||||
Codeman is MIT licensed, self-hosted, and sends no telemetry. Everything runs on your
|
Codeman is MIT licensed, self-hosted, and sends no telemetry. Everything runs on your
|
||||||
|
|||||||
@@ -19,9 +19,11 @@ terminal into something that can notify you.
|
|||||||
| `teammate_idle` | An agent-team member goes idle. | Team surfaces. |
|
| `teammate_idle` | An agent-team member goes idle. | Team surfaces. |
|
||||||
| `task_completed` | A task finishes. | Task tracking, run summary. |
|
| `task_completed` | A task finishes. | Task tracking, run summary. |
|
||||||
|
|
||||||
This is why several Codeman features are Claude-only. The other CLIs have no hook system, so
|
This is why several Codeman features are Claude-only. The one partial exception is DeepSeek
|
||||||
for them Codeman watches terminal output, which reveals that something happened but not what
|
Harness, whose terminal front door reports idle, working and blocked to Codeman over the
|
||||||
it was.
|
harness's own supervisor contract, so it gets the hook-driven surfaces without any hook
|
||||||
|
file. The other CLIs have no equivalent, so for them Codeman watches terminal output, which
|
||||||
|
reveals that something happened but not what it was.
|
||||||
|
|
||||||
### How hooks get installed
|
### How hooks get installed
|
||||||
|
|
||||||
@@ -67,7 +69,7 @@ sit beside the agents with no code at all. See [Web Tabs](Web-Tabs).
|
|||||||
### 2. SSE events
|
### 2. SSE events
|
||||||
|
|
||||||
`GET /api/events` streams everything Codeman knows: session lifecycle, output, agent
|
`GET /api/events` streams everything Codeman knows: session lifecycle, output, agent
|
||||||
activity, approvals, cron runs. 155 named events, stable under semantic versioning.
|
activity, approvals, cron runs. 158 named events, stable under semantic versioning.
|
||||||
|
|
||||||
This is the seam for anything that reacts. A bot that pings your chat channel when an agent
|
This is the seam for anything that reacts. A bot that pings your chat channel when an agent
|
||||||
needs a human is a short script over this stream.
|
needs a human is a short script over this stream.
|
||||||
|
|||||||
@@ -27,6 +27,15 @@ The result is the property you want on a phone: a connection that drops mid-prom
|
|||||||
loses the prompt and never delivers it twice. Two browser tabs on the same session coexist,
|
loses the prompt and never delivers it twice. Two browser tabs on the same session coexist,
|
||||||
and only a reconnect from the *same* tab supersedes the old connection.
|
and only a reconnect from the *same* tab supersedes the old connection.
|
||||||
|
|
||||||
|
## Selecting and copying
|
||||||
|
|
||||||
|
Agent CLIs hold the mouse: clicks and drags are reported into the transcript rather than
|
||||||
|
selecting text. `Shift+drag` starts a selection anyway, right-click copies it (with nothing
|
||||||
|
selected the native context menu is left alone), and `Ctrl+Shift+C` copies without ever
|
||||||
|
interrupting. **Auto Copy Selection** in **App Settings → Terminal & Input**, off by
|
||||||
|
default, copies the moment you release the mouse. On phones, long-press selects; see
|
||||||
|
[Mobile Guide](Mobile-Guide).
|
||||||
|
|
||||||
## Zero-lag local echo
|
## Zero-lag local echo
|
||||||
|
|
||||||
On touch devices, keystrokes are painted in the terminal immediately and sent when you press
|
On touch devices, keystrokes are painted in the terminal immediately and sent when you press
|
||||||
@@ -55,6 +64,8 @@ reconcile against the real buffer and only apply while the cursor is on the comp
|
|||||||
Chinese, Japanese, and Korean input needs an IME, and an IME needs a real text field.
|
Chinese, Japanese, and Korean input needs an IME, and an IME needs a real text field.
|
||||||
Turning on CJK input in **App Settings → Terminal & Input** puts an always-visible textarea
|
Turning on CJK input in **App Settings → Terminal & Input** puts an always-visible textarea
|
||||||
below the terminal that owns composition, then delivers the composed text to the session.
|
below the terminal that owns composition, then delivers the composed text to the session.
|
||||||
|
Ctrl- and Alt-modified navigation keys typed through it reach the CLI as the modified
|
||||||
|
sequences, so word jumps and history keys keep working.
|
||||||
|
|
||||||
## Voice dictation
|
## Voice dictation
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ Getting Codeman onto a machine, verifying it works, updating it, and removing it
|
|||||||
| **macOS or Linux** | Windows works through WSL2. See [Windows](#windows-wsl) below. |
|
| **macOS or Linux** | Windows works through WSL2. See [Windows](#windows-wsl) below. |
|
||||||
| **Node.js 22+** | The installer offers to install it if missing. |
|
| **Node.js 22+** | The installer offers to install it if missing. |
|
||||||
| **tmux** | Not optional. Sessions live inside tmux, which is what makes them survive a server restart, a dropped connection, or a closed laptop. |
|
| **tmux** | Not optional. Sessions live inside tmux, which is what makes them survive a server restart, a dropped connection, or a closed laptop. |
|
||||||
| **An agent CLI** | At least one of [Claude Code](https://docs.anthropic.com/en/docs/claude-code), [OpenCode](https://opencode.ai), [Codex](https://developers.openai.com/codex/cli), [Antigravity](https://antigravity.google), [Gemini CLI](https://github.com/google-gemini/gemini-cli), [Pi](https://pi.dev). Plain shell sessions need none. See [Agent CLIs](Agent-CLIs). |
|
| **An agent CLI** | At least one of [Claude Code](https://docs.anthropic.com/en/docs/claude-code), [OpenCode](https://opencode.ai), [Codex](https://developers.openai.com/codex/cli), [Antigravity](https://antigravity.google), [Gemini CLI](https://github.com/google-gemini/gemini-cli), [Pi](https://pi.dev), [Grok Build](https://github.com/xai-org/grok-build), [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness), [OMP](https://github.com/can1357/oh-my-pi). Plain shell sessions need none. See [Agent CLIs](Agent-CLIs). |
|
||||||
|
|
||||||
Codeman itself sends no telemetry and phones no home. The only network traffic is your
|
Codeman itself sends no telemetry and phones no home. The only network traffic is your
|
||||||
browser to your server, and whatever the agent CLI you chose does on its own.
|
browser to your server, and whatever the agent CLI you chose does on its own.
|
||||||
@@ -20,13 +20,16 @@ browser to your server, and whatever the agent CLI you chose does on its own.
|
|||||||
curl -fsSL https://getcodeman.com/install | bash
|
curl -fsSL https://getcodeman.com/install | bash
|
||||||
```
|
```
|
||||||
|
|
||||||
This installs Node.js and tmux if they are missing, clones Codeman into `~/.codeman/app`,
|
This installs Node.js, tmux and a build toolchain if they are missing (node-pty ships no
|
||||||
and builds it.
|
Linux prebuild, so it compiles from source), clones Codeman into `~/.codeman/app`, and
|
||||||
|
builds it.
|
||||||
|
|
||||||
What it asks you:
|
What it asks you:
|
||||||
|
|
||||||
1. **Permission for every system change.** Package installs and agent CLI downloads are
|
1. **Permission for every system change.** Package installs and agent CLI downloads are
|
||||||
prompted individually. Nothing is installed silently.
|
prompted individually. Nothing is installed silently. If no agent CLI is found, a menu
|
||||||
|
offers to install any of them (DeepSeek excepted: its npm package installs only a
|
||||||
|
launcher with no runnable profile), or you skip and install one yourself later.
|
||||||
2. **How the dashboard should be reachable.** Three choices:
|
2. **How the dashboard should be reachable.** Three choices:
|
||||||
- **Tailscale** (recommended for phone access): keeps the loopback bind and walks you
|
- **Tailscale** (recommended for phone access): keeps the loopback bind and walks you
|
||||||
through `tailscale serve`, including the tailnet HTTPS toggle, then verifies the result
|
through `tailscale serve`, including the tailnet HTTPS toggle, then verifies the result
|
||||||
@@ -101,6 +104,21 @@ at server start, so markup changes need a restart.
|
|||||||
|
|
||||||
See [Contributing](Contributing) for the rest of the development loop.
|
See [Contributing](Contributing) for the rest of the development loop.
|
||||||
|
|
||||||
|
## Route D: Docker Compose
|
||||||
|
|
||||||
|
Codeman itself can run in a container and spawn Docker cases as sibling containers through
|
||||||
|
the host's Docker socket. Copy `docker/.env.example` to `docker/.env`, set
|
||||||
|
`CODEMAN_PASSWORD`, then:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bash docker/Start-Codeman.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Run the script again after updating rather than a plain `docker compose up`, so the rebuilt
|
||||||
|
image, the refreshed volumes and the entrypoint arrive together. The full guide, including
|
||||||
|
storage and networking options, is
|
||||||
|
[`docker/README.md`](https://github.com/Ark0N/Codeman/blob/master/docker/README.md).
|
||||||
|
|
||||||
## Installing an agent CLI
|
## Installing an agent CLI
|
||||||
|
|
||||||
Codeman drives CLIs, it does not bundle them. Install at least one:
|
Codeman drives CLIs, it does not bundle them. Install at least one:
|
||||||
@@ -113,6 +131,9 @@ Codeman drives CLIs, it does not bundle them. Install at least one:
|
|||||||
| **Antigravity** | See [antigravity.google](https://antigravity.google) | Google's successor to the consumer Gemini CLI. |
|
| **Antigravity** | See [antigravity.google](https://antigravity.google) | Google's successor to the consumer Gemini CLI. |
|
||||||
| **Gemini CLI** | See [github.com/google-gemini/gemini-cli](https://github.com/google-gemini/gemini-cli) | Enterprise only since Google's June 2026 consumer cutover. |
|
| **Gemini CLI** | See [github.com/google-gemini/gemini-cli](https://github.com/google-gemini/gemini-cli) | Enterprise only since Google's June 2026 consumer cutover. |
|
||||||
| **Pi** | See [pi.dev](https://pi.dev) | No permission prompts and no sandbox by design. Read [Agent CLIs](Agent-CLIs) before using it on a repo you care about. |
|
| **Pi** | See [pi.dev](https://pi.dev) | No permission prompts and no sandbox by design. Read [Agent CLIs](Agent-CLIs) before using it on a repo you care about. |
|
||||||
|
| **Grok Build** | `curl -fsSL https://x.ai/cli/install.sh \| bash` | xAI. Lands in `~/.grok/bin`; `grok login --device-auth` for headless hosts. |
|
||||||
|
| **DeepSeek Harness** | `npm i -g @deepseek-ai/dsh pnpm`, then a terminal profile | The npm package is only a launcher. Codeman's Run menu installs the community terminal profile for you. See [Agent CLIs](Agent-CLIs). |
|
||||||
|
| **OMP** | `curl -fsSL https://omp.sh/install \| sh` | Oh My Pi. Run it once by hand to finish its own onboarding. |
|
||||||
|
|
||||||
Log each CLI in once, by hand, before pointing Codeman at it. Codeman never collects or
|
Log each CLI in once, by hand, before pointing Codeman at it. Codeman never collects or
|
||||||
stores your CLI credentials.
|
stores your CLI credentials.
|
||||||
@@ -161,6 +182,7 @@ Full detail, including logs and the self-updater, is in
|
|||||||
| Installer | Re-run the one-liner, or **App Settings → System → Updates** in the UI. |
|
| Installer | Re-run the one-liner, or **App Settings → System → Updates** in the UI. |
|
||||||
| npm | `npm update -g aicodeman` |
|
| npm | `npm update -g aicodeman` |
|
||||||
| git clone | `git pull && npm install && npm run build`, then restart. |
|
| git clone | `git pull && npm install && npm run build`, then restart. |
|
||||||
|
| Docker Compose | Re-run `Start-Codeman.sh`. The in-app updater works too, and refuses a release that changes the container definition until you re-run the script. |
|
||||||
|
|
||||||
The in-app updater covers git-clone installs supervised by systemd or launchd. It restarts
|
The in-app updater covers git-clone installs supervised by systemd or launchd. It restarts
|
||||||
the process that is running it, so the actual work happens in a detached script and the
|
the process that is running it, so the actual work happens in a detached script and the
|
||||||
|
|||||||
@@ -27,9 +27,12 @@ keystroke echo. Idle now lands a few seconds after a turn genuinely ends.
|
|||||||
There are several layers stacked on that: a completion message from the CLI, an AI check,
|
There are several layers stacked on that: a completion message from the CLI, an AI check,
|
||||||
output silence, and token stability.
|
output silence, and token stability.
|
||||||
|
|
||||||
**For every other CLI**, there are no hooks to lean on, so detection is output
|
**For the other CLIs** it depends on what the CLI tells Codeman. Codex declares its own
|
||||||
stabilization: the session is idle when output stops changing. Coarser, and it is why the
|
prompt glyph and working line, so it gets the same screen check Claude does (before 1.26.1
|
||||||
features further down this page are Claude-only.
|
every Codex session reported idle for its whole life). DeepSeek Harness reports idle,
|
||||||
|
working and blocked to Codeman itself, which is as precise as hooks. Everything else is
|
||||||
|
output stabilization: the session is idle when output stops changing. Coarser, and it is
|
||||||
|
why the features further down this page are Claude-only.
|
||||||
|
|
||||||
## The Respawn Controller
|
## The Respawn Controller
|
||||||
|
|
||||||
@@ -101,13 +104,18 @@ subscription plan.
|
|||||||
**Claude only.** A header chip showing live subscription usage, on by default on desktop and
|
**Claude only.** A header chip showing live subscription usage, on by default on desktop and
|
||||||
off on phones.
|
off on phones.
|
||||||
|
|
||||||
It works by installing a status line exporter into Claude Code, which posts Claude's own
|
It works through a status line exporter that Codeman hands to `claude` as an ephemeral
|
||||||
rate limit data back to Codeman. The exporter is marker-identified, so it only ever touches
|
setting when it spawns the session, never written to disk, which posts Claude's own rate
|
||||||
a status line Codeman installed, never one you wrote yourself, and it prints your footer
|
limit data back to Codeman. Your own status line (project-local, project, then
|
||||||
through so the in-terminal status line still works.
|
`~/.claude/settings.json`) is wrapped and printed through, and a `claude` you run by hand
|
||||||
|
outside Codeman sees nothing of it. Workspaces an older Codeman wrote the exporter into are
|
||||||
|
cleaned up the first time a session starts there. Codex limits come from a read-only poll of
|
||||||
|
its own app-server. Known limit: sessions inside a Docker case do not feed the chip yet.
|
||||||
|
|
||||||
The chip and the exporter are the same setting. Turning the chip on without the exporter
|
The chip and the exporter are the same setting. Turning the chip on without the exporter
|
||||||
would leave it showing a dash forever, so resolve it in one place: **App Settings**.
|
would leave it showing a dash forever, so resolve it in one place: **App Settings**. A
|
||||||
|
device writes the switch only when it flips the chip, so a phone (chip off by default)
|
||||||
|
saving its font size cannot switch collection off for your desktop.
|
||||||
|
|
||||||
## Circuit breakers
|
## Circuit breakers
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,9 @@ Press `Ctrl+?` in the app for the same list in a floating overlay.
|
|||||||
| `Ctrl+Shift+R` | Restore terminal size. |
|
| `Ctrl+Shift+R` | Restore terminal size. |
|
||||||
| `Ctrl` `+` / `Ctrl` `-` | Font size. |
|
| `Ctrl` `+` / `Ctrl` `-` | Font size. |
|
||||||
| `Shift+Wheel` | Scroll the local buffer, even where the wheel is forwarded to the CLI. |
|
| `Shift+Wheel` | Scroll the local buffer, even where the wheel is forwarded to the CLI. |
|
||||||
|
| `Shift+drag` | Start a selection in a pane whose mouse events go to the CLI. |
|
||||||
|
| Right-click | Copy the selection. With nothing selected the native menu is left alone. |
|
||||||
|
| `Ctrl+Z` | Swallowed in agent sessions so a running CLI cannot be suspended. Normal job control in a shell. |
|
||||||
|
|
||||||
## Everything else
|
## Everything else
|
||||||
|
|
||||||
|
|||||||
@@ -30,8 +30,12 @@ require a secure context.
|
|||||||
| Toolbar | Bottom: Run, Stop, **Enter**, case picker, voice, settings. |
|
| Toolbar | Bottom: Run, Stop, **Enter**, case picker, voice, settings. |
|
||||||
| Keyboard bar | Above the on-screen keyboard when it is open. |
|
| Keyboard bar | Above the on-screen keyboard when it is open. |
|
||||||
|
|
||||||
Layout respects notch and home-indicator safe areas, touch targets are 44px, and the case
|
The phone layout applies up to 599px of viewport width, so the Plus and Pro Max iPhones,
|
||||||
picker is a bottom sheet rather than a dropdown.
|
the Pixel Pro and a folded Z Fold get it too; wider devices get the tablet layout. Layout
|
||||||
|
respects notch and home-indicator safe areas, touch targets are 44px, and the case picker is
|
||||||
|
a bottom sheet rather than a dropdown. On a folding phone (iPhone Duo) dialogs stay clear of
|
||||||
|
the hinge, and opening or closing the device is treated as the device changing shape, never
|
||||||
|
as the keyboard appearing.
|
||||||
|
|
||||||
**Swipe left and right** on the terminal to switch sessions.
|
**Swipe left and right** on the terminal to switch sessions.
|
||||||
|
|
||||||
@@ -58,7 +62,9 @@ A row of keys above the virtual keyboard, and what it contains depends on the se
|
|||||||
|
|
||||||
**Agent sessions** get quick actions: `/init`, `/clear`, `/compact`, a clipboard key, `Esc`,
|
**Agent sessions** get quick actions: `/init`, `/clear`, `/compact`, a clipboard key, `Esc`,
|
||||||
a path picker, an image key, and 🧠 when Read My Mind is on. Destructive commands need a
|
a path picker, an image key, and 🧠 when Read My Mind is on. Destructive commands need a
|
||||||
double press, so you cannot fire `/clear` with a stray thumb.
|
double press, so you cannot fire `/clear` with a stray thumb. On Codex sessions the bar also
|
||||||
|
shows `⇧←` and `⇧→`, the Shift-modified arrows Codex binds to editing the last queued
|
||||||
|
message and walking the prompt stack.
|
||||||
|
|
||||||
**Shell sessions** automatically swap it for terminal controls: `Ctrl`, `Esc`, `Tab`, four
|
**Shell sessions** automatically swap it for terminal controls: `Ctrl`, `Esc`, `Tab`, four
|
||||||
arrows, paste, and dismiss. Your normal preference is remembered and restored when you
|
arrows, paste, and dismiss. Your normal preference is remembered and restored when you
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ reloading the dashboard while a permission dialog is blocking a session does not
|
|||||||
with a normal-looking tab.
|
with a normal-looking tab.
|
||||||
|
|
||||||
For Claude sessions, these come from Claude Code's hooks and are precise about *why* the
|
For Claude sessions, these come from Claude Code's hooks and are precise about *why* the
|
||||||
session stopped. For other CLIs there are no hooks, so you get the coarser output-based
|
session stopped; DeepSeek Harness sessions report the same states themselves. For the other
|
||||||
signal.
|
CLIs there are no hooks, so you get the coarser output-based signal.
|
||||||
|
|
||||||
## Window title and OS notifications
|
## Window title and OS notifications
|
||||||
|
|
||||||
@@ -62,7 +62,8 @@ Once subscribed, a blocking prompt reaches your phone even from a locked screen.
|
|||||||
|
|
||||||
## The Approvals Inbox
|
## The Approvals Inbox
|
||||||
|
|
||||||
**Opt-in, off by default. Claude sessions only.**
|
**Opt-in, off by default. Claude sessions, plus DeepSeek Harness sessions, whose terminal
|
||||||
|
front door reports its prompts to Codeman.**
|
||||||
|
|
||||||
One queue of every prompt currently waiting on a human, across all your sessions, answerable
|
One queue of every prompt currently waiting on a human, across all your sessions, answerable
|
||||||
in place. When you have eight workers running, this is the difference between checking eight
|
in place. When you have eight workers running, this is the difference between checking eight
|
||||||
@@ -136,7 +137,8 @@ from the lock screen.
|
|||||||
- **No push over plain HTTP.** It is a browser requirement, not a Codeman one.
|
- **No push over plain HTTP.** It is a browser requirement, not a Codeman one.
|
||||||
- **iOS needs the home screen install.** A Safari tab will never receive push.
|
- **iOS needs the home screen install.** A Safari tab will never receive push.
|
||||||
- **The bell is invisible at zero.** That is deliberate, not a broken setting.
|
- **The bell is invisible at zero.** That is deliberate, not a broken setting.
|
||||||
- **Approvals are Claude-only.** They are built on hook events the other CLIs do not emit.
|
- **Approvals need real signals.** They are built on hook events, which Claude emits and
|
||||||
|
DeepSeek Harness reports itself; the other CLIs do neither.
|
||||||
- **A stale menu answer is refused, not sent.** If you answer a card for a dialog that has
|
- **A stale menu answer is refused, not sent.** If you answer a card for a dialog that has
|
||||||
since gone away, Codeman declines rather than typing a digit into the composer.
|
since gone away, Codeman declines rather than typing a digit into the composer.
|
||||||
|
|
||||||
|
|||||||
@@ -67,6 +67,9 @@ one:
|
|||||||
| **Gemini** | Enterprise only since Google's consumer cutover. |
|
| **Gemini** | Enterprise only since Google's consumer cutover. |
|
||||||
| **Antigravity** | Google's successor to the consumer Gemini CLI. |
|
| **Antigravity** | Google's successor to the consumer Gemini CLI. |
|
||||||
| **Pi** | No permission prompts and no sandbox by design. |
|
| **Pi** | No permission prompts and no sandbox by design. |
|
||||||
|
| **Grok Build** | xAI's CLI. |
|
||||||
|
| **DeepSeek Harness** | Needs a terminal profile; the menu offers to install one. |
|
||||||
|
| **OMP** | Oh My Pi, configured entirely through its own `~/.omp`. |
|
||||||
| **Terminal / Shell** | A plain shell, no agent. Also the **Run Shell** button. |
|
| **Terminal / Shell** | A plain shell, no agent. Also the **Run Shell** button. |
|
||||||
|
|
||||||
The dropdown also lists any saved dashboard URLs ([Web Tabs](Web-Tabs)) and your recent
|
The dropdown also lists any saved dashboard URLs ([Web Tabs](Web-Tabs)) and your recent
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ Point a case at another machine and the agent runs **there**, with the same dash
|
|||||||
mobile UI, and autonomy features. Your laptop becomes a window onto a session living on the
|
mobile UI, and autonomy features. Your laptop becomes a window onto a session living on the
|
||||||
remote host.
|
remote host.
|
||||||
|
|
||||||
Like Docker, this is a **location overlay** on a case, not a run mode. All seven run modes
|
Like Docker, this is a **location overlay** on a case, not a run mode. All ten run modes
|
||||||
work remotely. See [Core Concepts](Core-Concepts).
|
work remotely. See [Core Concepts](Core-Concepts).
|
||||||
|
|
||||||
## Why bother
|
## Why bother
|
||||||
@@ -52,7 +52,10 @@ A watcher with bounded backoff notices a dead SSH pane and quietly reattaches to
|
|||||||
running remote session. On by default; the kill switch is in
|
running remote session. On by default; the kill switch is in
|
||||||
**App Settings → Agents & CLIs → Remote auto-reconnect**.
|
**App Settings → Agents & CLIs → Remote auto-reconnect**.
|
||||||
|
|
||||||
Intentional kills are never revived. Closing a session means closing it.
|
Intentional kills are never revived. Closing a session means closing it. Neither is a clean
|
||||||
|
exit inside the pane (Ctrl-D, `exit`, Ctrl-C at the CLI's prompt): that tears the remote
|
||||||
|
tmux session down, and the watcher revives a session only when that durable session is
|
||||||
|
verifiably still alive. Only a transport drop is reconnected.
|
||||||
|
|
||||||
## Discover and attach
|
## Discover and attach
|
||||||
|
|
||||||
@@ -70,6 +73,14 @@ Attaching to someone else's session and closing your tab must not end their run,
|
|||||||
not. Several clients can attach the same remote session at different window sizes without
|
not. Several clients can attach the same remote session at different window sizes without
|
||||||
clamping each other, and discovery shows a shared badge with the client count.
|
clamping each other, and discovery shows a shared badge with the client count.
|
||||||
|
|
||||||
|
## Files
|
||||||
|
|
||||||
|
Previews, downloads and text reads in a remote case go over the same ssh connection the
|
||||||
|
session uses, so a clicked path opens the file on the machine the agent is on, `Range`
|
||||||
|
seeking included. Nothing is copied to the Codeman host. Editing, Office previews,
|
||||||
|
thumbnails, the file tree and the tail viewer are not available remotely and answer a clear
|
||||||
|
400 rather than a misleading 404. Details in [Working With Files](Working-With-Files).
|
||||||
|
|
||||||
## Security
|
## Security
|
||||||
|
|
||||||
Every SSH command line in Codeman flows through one builder that shell-escapes every
|
Every SSH command line in Codeman flows through one builder that shell-escapes every
|
||||||
|
|||||||
@@ -139,6 +139,7 @@ log stream --predicate 'process == "node"' # macOS, noisy
|
|||||||
| Installer | Re-run the one-liner, or **App Settings → System → Updates**. |
|
| Installer | Re-run the one-liner, or **App Settings → System → Updates**. |
|
||||||
| npm | `npm update -g aicodeman` |
|
| npm | `npm update -g aicodeman` |
|
||||||
| git clone | `git pull && npm install && npm run build`, then restart. |
|
| git clone | `git pull && npm install && npm run build`, then restart. |
|
||||||
|
| Docker Compose | Re-run `Start-Codeman.sh`, or the in-app updater, which restarts the container in place. |
|
||||||
|
|
||||||
### The in-app updater
|
### The in-app updater
|
||||||
|
|
||||||
@@ -170,6 +171,18 @@ service without colliding with the main one. `CODEMAN_DATA_DIR` and `CODEMAN_TMU
|
|||||||
exist for the rare case where they need to differ, but setting only one of them recreates
|
exist for the rare case where they need to differ, but setting only one of them recreates
|
||||||
exactly the problem you were avoiding.
|
exactly the problem you were avoiding.
|
||||||
|
|
||||||
|
## Running Codeman itself in Docker
|
||||||
|
|
||||||
|
The Compose deployment in `docker/` runs the server in a container and spawns Docker cases
|
||||||
|
as sibling containers through the mounted host socket. Start it with
|
||||||
|
`bash docker/Start-Codeman.sh` rather than a bare `docker compose up`: the script pre-creates
|
||||||
|
the bind-mounted directories with the right owner, honours a `docker-compose.override.yml`,
|
||||||
|
and refreshes the build volumes when the checkout moved under them. The in-app updater
|
||||||
|
applies code only and restarts by letting the container exit, so it refuses a release that
|
||||||
|
changes the Dockerfile, the compose file, or adds a new `.env` key, until you re-run the
|
||||||
|
script. Guide:
|
||||||
|
[`docker/README.md`](https://github.com/Ark0N/Codeman/blob/master/docker/README.md).
|
||||||
|
|
||||||
## The tunnel as a service
|
## The tunnel as a service
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ be wrong for at least one of them:
|
|||||||
| **File Viewer** | Real path resolution before boundary checks, so symlinks cannot escape. Sensitive trees blocked. Edit mode adds an extension allowlist, a size cap, `.git` denial, and optimistic concurrency. It never creates files. |
|
| **File Viewer** | Real path resolution before boundary checks, so symlinks cannot escape. Sensitive trees blocked. Edit mode adds an extension allowlist, a size cap, `.git` denial, and optimistic concurrency. It never creates files. |
|
||||||
| **Attachments** | An id-based registry, so browser requests never carry absolute paths. The magic-link scanner is prompt-injectable by nature and is therefore force-confined to the session's workspace. Extension allowlist, not a blocklist. |
|
| **Attachments** | An id-based registry, so browser requests never carry absolute paths. The magic-link scanner is prompt-injectable by nature and is therefore force-confined to the session's workspace. Extension allowlist, not a blocklist. |
|
||||||
| **Path picker** | Its own root allowlist rather than the workspace confinement. In multi-user mode a non-admin gets only their own user space, because per-user spaces live inside the home directory. |
|
| **Path picker** | Its own root allowlist rather than the workspace confinement. In multi-user mode a non-admin gets only their own user space, because per-user spaces live inside the home directory. |
|
||||||
|
| **Remote cases** | Reads go over the session's own ssh connection and are resolved and contained on the remote host, with a bounded number of ssh children. Nothing is copied to the Codeman host; writes, Office previews and thumbnails are refused. |
|
||||||
|
|
||||||
Downloads block sensitive paths outright (`.env`, credentials files, `~/.ssh`, AWS
|
Downloads block sensitive paths outright (`.env`, credentials files, `~/.ssh`, AWS
|
||||||
credentials), and SVG and HTML are served as downloads with `nosniff` so they cannot execute
|
credentials), and SVG and HTML are served as downloads with `nosniff` so they cannot execute
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ supervised by systemd or launchd; npm installs report as non-updatable. See
|
|||||||
| Extended Keyboard Bar | Per device | Which accessory bar phones get. Shell sessions override it while they are active. |
|
| Extended Keyboard Bar | Per device | Which accessory bar phones get. Shell sessions override it while they are active. |
|
||||||
| Wheel Scrolls Local History | Off | Keeps the wheel on the local buffer instead of forwarding it to the CLI. |
|
| Wheel Scrolls Local History | Off | Keeps the wheel on the local buffer instead of forwarding it to the CLI. |
|
||||||
| Auto Copy Selection | Off | Copies highlighted terminal text to the clipboard the moment you finish selecting it. Ctrl+C still copies on demand. |
|
| Auto Copy Selection | Off | Copies highlighted terminal text to the clipboard the moment you finish selecting it. Ctrl+C still copies on demand. |
|
||||||
|
| Normal / Bold font weight | xterm defaults | Per device, each slot from 100 to 900. The bundled JetBrains Mono renders every step, so a lighter normal weight makes Claude's bold headings stand out. Applies live to the terminal, both echo overlays and open team panes. |
|
||||||
| WebGL Renderer | On | With a GPU-stall watchdog that falls back to DOM rendering. |
|
| WebGL Renderer | On | With a GPU-stall watchdog that falls back to DOM rendering. |
|
||||||
| Gesture Control | Off | Camera hand tracking. Also needs `CODEMAN_GESTURE=1` on the server. |
|
| Gesture Control | Off | Camera hand tracking. Also needs `CODEMAN_GESTURE=1` on the server. |
|
||||||
|
|
||||||
@@ -72,7 +73,9 @@ every session or only the active tab.
|
|||||||
| Entrance Animations | Per-surface animation styles for tabs, terminals, windows, and lineage lines. All default to the legacy no-animation behaviour. |
|
| Entrance Animations | Per-surface animation styles for tabs, terminals, windows, and lineage lines. All default to the legacy no-animation behaviour. |
|
||||||
| Display Name | Your name in the UI. Cosmetic only; it never renames the package, CLI, API, or storage. |
|
| Display Name | Your name in the UI. Cosmetic only; it never renames the package, CLI, API, or storage. |
|
||||||
| Interface Language | English or Simplified Chinese. Per device. |
|
| Interface Language | English or Simplified Chinese. Per device. |
|
||||||
| Session List Layout | Header tab strip (default) or a collapsible left sidebar. See [The Dashboard](The-Dashboard#session-list-layout). |
|
| Session List Layout | Header tab strip (default), a collapsible left sidebar, or the sidebar with detailed rows. See [The Dashboard](The-Dashboard#session-list-layout). |
|
||||||
|
| Tab Orientation | Keeps the header list but turns the strip vertical beside the terminal, resizable, with detailed rows by default. Desktop and tablet only. |
|
||||||
|
| Vertical Rail Order | *By activity* (default) sorts the rail the way the home screens are sorted; *Manual* keeps your tab order and drag-reordering. |
|
||||||
| Tall Tabs | Taller tab strip. |
|
| Tall Tabs | Taller tab strip. |
|
||||||
| Pop-out Button on Tabs | Adds the detach control to tabs, with a per-tab override. |
|
| Pop-out Button on Tabs | Adds the detach control to tabs, with a per-tab override. |
|
||||||
| Spawn Lineage Lines | Arcs from a parent tab to sessions it spawned. Desktop only, on by default. |
|
| Spawn Lineage Lines | Arcs from a parent tab to sessions it spawned. Desktop only, on by default. |
|
||||||
@@ -156,6 +159,9 @@ Some things are configured before the server starts, not in the UI:
|
|||||||
| `CODEMAN_DOCKER_BRIDGE_HOOKS` | Lets in-container hooks reach the host on a loopback bind. |
|
| `CODEMAN_DOCKER_BRIDGE_HOOKS` | Lets in-container hooks reach the host on a loopback bind. |
|
||||||
| `CODEMAN_FILE_PICKER_ROOTS` | Extra roots for the path picker. |
|
| `CODEMAN_FILE_PICKER_ROOTS` | Extra roots for the path picker. |
|
||||||
| `CODEMAN_ALLOW_UNAUTHENTICATED_NETWORK` | Acknowledges exposing the server with no password. |
|
| `CODEMAN_ALLOW_UNAUTHENTICATED_NETWORK` | Acknowledges exposing the server with no password. |
|
||||||
|
| `CODEMAN_BASE_URL` | Mounts Codeman under a sub-path behind a reverse proxy that forwards the prefix unchanged. See [Remote Access](Remote-Access). |
|
||||||
|
| `CODEMAN_MAX_DOWNLOAD_BYTES` | Cap on raw file bodies and downloads. 2 GB by default, `0` for none. |
|
||||||
|
| `CODEMAN_MAX_REMOTE_FILE_SSH` | Concurrent ssh reads for files in remote cases. 4 by default. |
|
||||||
|
|
||||||
## Gotchas
|
## Gotchas
|
||||||
|
|
||||||
|
|||||||
@@ -22,12 +22,14 @@ page says so and names the setting.
|
|||||||
|
|
||||||
The session list lives in the header as a horizontal strip by default. With a lot of
|
The session list lives in the header as a horizontal strip by default. With a lot of
|
||||||
sessions open that strip stops being scannable, so **App Settings → Appearance → Tabs →
|
sessions open that strip stops being scannable, so **App Settings → Appearance → Tabs →
|
||||||
Session List Layout** can move it into a vertical sidebar on the left instead.
|
Session List Layout** can move it into a vertical sidebar on the left instead, and
|
||||||
|
**Tab Orientation** can turn the strip itself into a vertical rail.
|
||||||
|
|
||||||
| Layout | Behaviour |
|
| Layout | Behaviour |
|
||||||
| -------------------- | --------------------------------------------------------------------------------- |
|
| -------------------- | --------------------------------------------------------------------------------- |
|
||||||
| **Header tab strip** | The default. Wraps to a second row on desktop, scrolls sideways on a phone. |
|
| **Header tab strip** | The default. Wraps to a second row on desktop, scrolls sideways on a phone. |
|
||||||
| **Left sidebar** | A vertical list with a filter box and a live session count. `Alt+B` collapses it to a narrow rail that keeps the status dots and task badges visible. On a phone it is an off-canvas drawer rather than a docked rail. |
|
| **Left sidebar** | A vertical list with a filter box and a live session count. `Alt+B` collapses it to a narrow rail that keeps the status dots and task badges visible. On a phone it is an off-canvas drawer rather than a docked rail. A detailed variant adds the home screen's per-session line (`created 3d ago · working 12m`) and a status pill. |
|
||||||
|
| **Vertical rail** | The strip turned vertical beside the terminal, resizable, with detailed rows by default. **Vertical Rail Order** sorts it by activity (blocked on you first, then longest running, then most recently quiet), the same order as the home screens; pick *Manual* to get your own order and drag-reordering back. Desktop and tablet only. |
|
||||||
|
|
||||||
It is the same list either way, just re-hosted: tab order, drag-to-reorder, the `Alt+1`
|
It is the same list either way, just re-hosted: tab order, drag-to-reorder, the `Alt+1`
|
||||||
to `Alt+9` numbers and every status colour below behave identically in both. The setting is
|
to `Alt+9` numbers and every status colour below behave identically in both. The setting is
|
||||||
@@ -154,6 +156,10 @@ Worth knowing:
|
|||||||
always local scrollback. Other CLIs scroll locally.
|
always local scrollback. Other CLIs scroll locally.
|
||||||
- **Selection copy.** `Ctrl+C` copies when text is selected and interrupts when it is not.
|
- **Selection copy.** `Ctrl+C` copies when text is selected and interrupts when it is not.
|
||||||
`Ctrl+Shift+C` always copies.
|
`Ctrl+Shift+C` always copies.
|
||||||
|
- **Selecting where the CLI owns the mouse.** `Shift+drag` starts a selection even in a pane
|
||||||
|
whose mouse events are forwarded to the CLI, and right-click copies the selection (with
|
||||||
|
nothing selected the native menu is left alone). **Auto Copy Selection** in App Settings
|
||||||
|
copies the moment you release.
|
||||||
- **Zero-lag input.** On touch devices, keystrokes paint locally before the round trip. See
|
- **Zero-lag input.** On touch devices, keystrokes paint locally before the round trip. See
|
||||||
[Input And Voice](Input-And-Voice).
|
[Input And Voice](Input-And-Voice).
|
||||||
- **Renderer.** WebGL by default, with a watchdog that falls back to DOM rendering if the
|
- **Renderer.** WebGL by default, with a watchdog that falls back to DOM rendering if the
|
||||||
@@ -167,8 +173,9 @@ which lists past sessions including Claude conversations started outside Codeman
|
|||||||
|
|
||||||
Two extras depending on the device:
|
Two extras depending on the device:
|
||||||
|
|
||||||
- **Desktop, wide windows**: your open tabs appear as a rail docked to the left edge, in tab
|
- **Desktop, wide windows**: your open tabs appear as a rail docked to the left edge, in
|
||||||
order, with created and last-active stamps. It needs at least 1180px of width; below that
|
overview order (blocked on you first, then longest running, then most recently quiet),
|
||||||
|
with created and state-duration stamps. It needs at least 1180px of width; below that
|
||||||
it is hidden so it cannot overlap the search panel.
|
it is hidden so it cannot overlap the search panel.
|
||||||
- **Phones**: tapping the "C" logo gives a session overview instead: NEEDS YOU first, then
|
- **Phones**: tapping the "C" logo gives a session overview instead: NEEDS YOU first, then
|
||||||
current sessions, then past ones. On by default.
|
current sessions, then past ones. On by default.
|
||||||
@@ -204,7 +211,9 @@ so it is fast and cannot be turned into a traversal.
|
|||||||
## Appearance
|
## Appearance
|
||||||
|
|
||||||
**App Settings → Appearance** carries the theme skins, including light ones. The choice is
|
**App Settings → Appearance** carries the theme skins, including light ones. The choice is
|
||||||
applied before the first paint, so there is no flash of the wrong theme on load.
|
applied before the first paint, so there is no flash of the wrong theme on load. Terminal
|
||||||
|
font family and weight are per device too: a normal and a bold weight, each from 100 to
|
||||||
|
900, and the bundled JetBrains Mono renders every step.
|
||||||
|
|
||||||
The same section has the entrance animations for tabs, terminals, agent windows, and
|
The same section has the entrance animations for tabs, terminals, agent windows, and
|
||||||
lineage lines. All of them default to the legacy no-animation behaviour, so an untouched
|
lineage lines. All of them default to the legacy no-animation behaviour, so an untouched
|
||||||
|
|||||||
@@ -138,6 +138,12 @@ That is the PTY-exit circuit breaker. Repeated rapid PTY exits trip it, and it b
|
|||||||
automatic restarts so a broken configuration does not spin forever. Reset it explicitly from
|
automatic restarts so a broken configuration does not spin forever. Reset it explicitly from
|
||||||
the session's controls. Reattaching does not clear it, deliberately.
|
the session's controls. Reattaching does not clear it, deliberately.
|
||||||
|
|
||||||
|
### Typed prompts are silently ignored after restoring a tab
|
||||||
|
|
||||||
|
Update. A browser whose input sequence counter fell behind the server's (a restored tab,
|
||||||
|
cleared site data) used to have every prompt deduplicated away. Since 1.29.0 the duplicate
|
||||||
|
acknowledgement carries the watermark and the client re-sends.
|
||||||
|
|
||||||
### Sessions I did not create appeared, or my session resized itself
|
### Sessions I did not create appeared, or my session resized itself
|
||||||
|
|
||||||
Two Codeman servers are running against the same data directory and tmux socket. The second
|
Two Codeman servers are running against the same data directory and tmux socket. The second
|
||||||
@@ -167,6 +173,16 @@ Things to try:
|
|||||||
Codex ignores the mouse reports that forwarding would send, so Codeman does not forward
|
Codex ignores the mouse reports that forwarding would send, so Codeman does not forward
|
||||||
there. Scrolling is local, and `Shift+Wheel` behaves the same way.
|
there. Scrolling is local, and `Shift+Wheel` behaves the same way.
|
||||||
|
|
||||||
|
### Selected text is invisible on a light skin
|
||||||
|
|
||||||
|
Update. Every skin named its selection colour under a key xterm renamed in v5, so the four
|
||||||
|
light skins painted white at 30% over near-white. Fixed in 1.29.0.
|
||||||
|
|
||||||
|
### `Ctrl+Z` suspended my agent
|
||||||
|
|
||||||
|
Update. Since 1.28.0 `Ctrl+Z` is swallowed in agent sessions, so a running CLI cannot be
|
||||||
|
stopped by job control. Shell sessions keep it.
|
||||||
|
|
||||||
### `Ctrl+C` copies when I wanted to interrupt
|
### `Ctrl+C` copies when I wanted to interrupt
|
||||||
|
|
||||||
With a selection, `Ctrl+C` copies. With no selection, it interrupts. Clear the selection
|
With a selection, `Ctrl+C` copies. With no selection, it interrupts. Clear the selection
|
||||||
@@ -252,11 +268,25 @@ node scripts/build-agent-image.mjs --no-cache
|
|||||||
A plain rebuild reuses the cached `npm install -g` layer and keeps the CLIs frozen at their
|
A plain rebuild reuses the cached `npm install -g` layer and keeps the CLIs frozen at their
|
||||||
original versions while reporting success.
|
original versions while reporting success.
|
||||||
|
|
||||||
|
### Every file in a remote case says "File not found"
|
||||||
|
|
||||||
|
Update. Before 1.29.0 the file routes resolved every path on the Codeman host, so in a
|
||||||
|
remote case every click failed while the file plainly existed on the other machine. Reads
|
||||||
|
now go over ssh; see [Working With Files](Working-With-Files). Editing and Office previews
|
||||||
|
stay unavailable remotely and say so with a 400.
|
||||||
|
|
||||||
|
### Compose: the server crash-loops with `EACCES` on first start
|
||||||
|
|
||||||
|
Start the stack with `bash docker/Start-Codeman.sh` rather than a plain `docker compose up`,
|
||||||
|
and update: since 1.29.0 the entrypoint corrects a root-owned bind mount before dropping
|
||||||
|
privileges. See [Running As A Service](Running-As-A-Service).
|
||||||
|
|
||||||
### A remote SSH session dropped and did not come back
|
### A remote SSH session dropped and did not come back
|
||||||
|
|
||||||
A bounded-backoff watcher reattaches dropped sessions, and it is on by default. Intentional
|
A bounded-backoff watcher reattaches dropped sessions, and it is on by default. Intentional
|
||||||
kills are never revived. Check the host is reachable and that the remote tmux server is
|
kills are never revived, and neither is a clean exit inside the pane (Ctrl-D, `exit`): only
|
||||||
still running.
|
a transport drop is reconnected. Check the host is reachable and that the remote tmux server
|
||||||
|
is still running.
|
||||||
|
|
||||||
## Gathering diagnostics
|
## Gathering diagnostics
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,23 @@ Switching tabs does not reload a dashboard. Frames stay alive in the background,
|
|||||||
took a while to authenticate is still there when you come back. Past six live frames, the
|
took a while to authenticate is still there when you come back. Past six live frames, the
|
||||||
least recently viewed is dropped to bound memory.
|
least recently viewed is dropped to bound memory.
|
||||||
|
|
||||||
|
## Single-page apps, reloads and links
|
||||||
|
|
||||||
|
A history-routed dashboard (React Router, Vue Router, a Vite dev server) sees the path it
|
||||||
|
would see on its own origin, not the proxy prefix, so it renders its real route instead of
|
||||||
|
its own "page not found". A navigation the page starts itself afterwards, a dev server's
|
||||||
|
full reload or a root-absolute `location.href`, would land outside the proxy with no
|
||||||
|
capability; Codeman recognises it, answers with a small recovery page, and remounts the
|
||||||
|
frame at the path that was lost, bounded to five recoveries a minute per frame. A reload on
|
||||||
|
the dashboard's landing page is recovered the same way.
|
||||||
|
|
||||||
|
A `localhost` or `127.0.0.1` link in agent output opens as a web tab automatically, reusing
|
||||||
|
a saved dashboard for the same server or saving one under its `host:port`. On a phone that
|
||||||
|
address only exists on the Codeman box, so the link would otherwise be a guaranteed
|
||||||
|
connection error. LAN and tailnet addresses still open directly. `*.localhost` names are
|
||||||
|
deliberately not auto-routed: they are DNS names rather than address literals, and the link
|
||||||
|
came from agent output. Add such a dashboard by hand instead.
|
||||||
|
|
||||||
## Why dashboards are proxied
|
## Why dashboards are proxied
|
||||||
|
|
||||||
A plain cross-origin iframe fails three ways at once in the setup Codeman actually ships in:
|
A plain cross-origin iframe fails three ways at once in the setup Codeman actually ships in:
|
||||||
@@ -89,6 +106,12 @@ The proxy authenticates on an in-memory capability embedded in the path, which i
|
|||||||
exempt from the cookie and Origin checks that every API route enforces. That exemption is
|
exempt from the cookie and Origin checks that every API route enforces. That exemption is
|
||||||
fenced to safe methods and non-API paths, and there is a test pinning it in place.
|
fenced to safe methods and non-API paths, and there is a test pinning it in place.
|
||||||
|
|
||||||
|
Saved URLs are refused when they point at a link-local or cloud-metadata address, at save
|
||||||
|
time and again against the address the name resolves to at connect time; loopback and
|
||||||
|
private ranges stay allowed, because a `localhost` Grafana is the feature. Capabilities are
|
||||||
|
revoked on logout, and proxied responses carry a same-origin referrer policy so a dashboard
|
||||||
|
cannot hand the capability-bearing URL to a third party.
|
||||||
|
|
||||||
Two failure modes that only appear inside a sandboxed frame, and that curl can never
|
Two failure modes that only appear inside a sandboxed frame, and that curl can never
|
||||||
reproduce, are handled: runtime-built root-absolute URLs escaping the injected base, and
|
reproduce, are handled: runtime-built root-absolute URLs escaping the injected base, and
|
||||||
same-host requests being CORS-checked with a null origin. Both present as the dashboard's own
|
same-host requests being CORS-checked with a null origin. Both present as the dashboard's own
|
||||||
|
|||||||
@@ -110,6 +110,22 @@ it is written. Outside the workspace they open in the preview instead: the tail
|
|||||||
|
|
||||||
Nothing is registered until you click. Opening a file this way does not add an attachment card.
|
Nothing is registered until you click. Opening a file this way does not add an attachment card.
|
||||||
|
|
||||||
|
## Remote (SSH) cases
|
||||||
|
|
||||||
|
In a remote case the workspace lives on the other machine, and so do the files. Previews,
|
||||||
|
downloads, text reads and the clicked-path route all go over the same ssh connection the
|
||||||
|
session uses: one `realpath` plus `stat` probe for the file and the workspace root, then a
|
||||||
|
streamed `cat` (or a slice of it, so video seeking works). Symlinks are resolved on the host
|
||||||
|
that can resolve them, the size cap applies to the remote size before a byte is requested,
|
||||||
|
and an unreachable host answers 502 rather than pretending the file is missing. Nothing is
|
||||||
|
ever copied onto the Codeman host, and a same-named local file is never served under a
|
||||||
|
remote name.
|
||||||
|
|
||||||
|
Not available over ssh, and said so with a 400 instead of a misleading 404: editing in
|
||||||
|
place, Office previews and generated thumbnails (both need the bytes on the server's disk),
|
||||||
|
the file tree and path picker, and the tail viewer. Docker cases are unaffected, because
|
||||||
|
their workspace is bind-mounted at the same path.
|
||||||
|
|
||||||
## The path picker
|
## The path picker
|
||||||
|
|
||||||
For choosing a path rather than typing one. It appears in two places:
|
For choosing a path rather than typing one. It appears in two places:
|
||||||
|
|||||||
Reference in New Issue
Block a user