diff --git a/.changeset/cli-copilot.md b/.changeset/cli-copilot.md index 91025b51..9a36cd35 100644 --- a/.changeset/cli-copilot.md +++ b/.changeset/cli-copilot.md @@ -2,4 +2,4 @@ 'aicodeman': minor --- -GitHub Copilot CLI is a run mode. It appears in the Run menu, the welcome screen and the cron agent list once `copilot` is installed, runs in tmux like the other agent CLIs, reports working and idle from its `Working` footer, shows the model it reads off its footer on the tab, and is listed in CLI management with an install command (`npm install -g @github/copilot`). It takes the same launch options as the other agent CLIs: a `copilotConfig` on the session create and quick-start bodies with `model` (`--model`), `resumeSessionId` (`--resume`), `continueSession` (`--continue`, which Past Sessions sends) and `allowAll` (`--yolo`, which the Run button sends and which is clamped off for non-granted multi-user owners), a tab name you set yourself as `--name`, Custom Model Endpoints through Copilot's BYOK variables, MCP sync of its `mcp-config.json`, and a `GET /api/copilot/status` probe. A plain drag selects text (Auto Copy works) while the wheel and phone swipes scroll its transcript, `codeman agent spawn` waits for its composer, `codeman agent read` returns its last answer, and the header plan-usage chip gains a Copilot row with the month's premium-request quota (not shown for Free or unlimited plans). +GitHub Copilot CLI is a run mode. It appears in the Run menu, the welcome screen and the cron agent list once `copilot` is installed, runs in tmux like the other agent CLIs, reports working and idle from its `Working` footer, shows the model it reads off its footer on the tab, and is listed in CLI management with an install command (`npm install -g @github/copilot`). It takes the same launch options as the other agent CLIs: a `copilotConfig` on the session create and quick-start bodies with `model` (`--model`), `resumeSessionId` (`--resume`), `continueSession` (`--continue`, which Past Sessions sends) and `allowAll` (`--yolo`, which the Run button sends and which is clamped off for non-granted multi-user owners), a tab name you set yourself as `--name`, Custom Model Endpoints through Copilot's BYOK variables, MCP sync of its `mcp-config.json`, and a `GET /api/copilot/status` probe. A plain drag selects text (Auto Copy works) while the wheel and phone swipes scroll its transcript, `codeman agent spawn` waits for its composer, and `codeman agent read` returns its last answer. diff --git a/CLAUDE.md b/CLAUDE.md index b055956a..31b0be65 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -156,7 +156,7 @@ Codeman is a Claude Code session manager with web interface and autonomous Ralph **Auto-resume on usage limit** (opt-in per session, top of the Respawn tab): when Claude halts on a subscription limit, `usage-limit-patterns.ts` (pure, unit-tested) parses the reset time and `SessionAutoOps` arms a timer for reset+2min, then sends Esc + `continue`. ⚠️ Respawn cycles are blocked while paused (`isLimitPaused` guard in `onIdleDetected`), which is what prevents `/clear` from wiping the paused conversation. Claude-mode only. → [architecture-invariants#auto-resume-on-usage-limit](docs/architecture-invariants.md#auto-resume-on-usage-limit) -**Plan-usage chip** (`showPlanUsageLimits`, per-device: desktop default **ON**, handhelds OFF): resolve DISPLAY only through `planUsageChipEnabled()` (settings-ui.js). The same setting is the server-side COLLECTION switch, read fresh by `readPlanUsageTelemetryEnabled()` (hooks-config.ts) at every claude create/respawn. ⚠️ An ABSENT key reads as ON in the reader; `GET /api/settings` must never write. ⚠️ A save sends `showPlanUsageLimits` ONLY when it flips the chip on that device (`planUsageCollectionFlip()`), or a phone switches collection off for every desktop. Claude data comes from the statusLine exporter, injected as an EPHEMERAL `claude --settings` flag (`resolveStatusLineCliCommand`), never written to disk, WRAPPING a user's own statusLine, posting to `POST /api/status-telemetry`. Codex comes from a read-only `account/rateLimits/read` poll (main bucket only). Copilot comes from `GET api.github.com/copilot_internal/user` (`quota_snapshots.premium_interactions`, one monthly `mo` window, omitted when unlimited or when there is no premium quota: a Free account answers `entitlement: 0, has_quota: false`; undocumented endpoint, 10-minute host poll, fail-silent, token from `COPILOT_GITHUB_TOKEN`/`GH_TOKEN`/`GITHUB_TOKEN` then `authTokens` in `config.json`; `src/utils/copilot-plan-usage.ts`). The statusline's `prompt_cache` object (Claude Code v2.1.251+) is kept by `StatusTelemetrySchema` (every documented scalar field, null-tolerant; `parsePromptCache()` in usage-telemetry.ts normalizes only the stored subset) and shown in the footer as `cache:until HH:MM` / `cache:cold` (only when the user has no statusline of their own) and in Session Options → Respawn (`#promptCacheStatus`, fed by `Session.promptCache` in `toState()` plus the change-only `session:promptCache` SSE event, worded by the pure `CodemanPromptCache.format`): warm-until/cold, the re-cache stake, the hit rate, the last miss's causes, and a `Context compacted at HH:MM` note after a compaction or a tool-result clearing (stamped on the first warm report whose `recache_tokens_if_cold` is null after one that carried it, never from `expected_rebuilds`, which Claude Code bumps only at the next request; NEVER an alert). ⚠️ `Session.setPromptCache()` stamps `compactedAt` onto a NEW object (never mutating the parsed report) and the route broadcasts the STORED object; the last report is restored on restart (constructor `promptCache`, like `displayModel`) and the readout is time-aware (a passed `expiresAt` reads cold, not stale-warm). It is the source of truth for the cache TTL, never the plan tier. → [architecture-invariants#plan-usage-chip-statusline-telemetry](docs/architecture-invariants.md#plan-usage-chip-statusline-telemetry), `docs/usage-limits-display-plan.md` +**Plan-usage chip** (`showPlanUsageLimits`, per-device: desktop default **ON**, handhelds OFF): resolve DISPLAY only through `planUsageChipEnabled()` (settings-ui.js). The same setting is the server-side COLLECTION switch, read fresh by `readPlanUsageTelemetryEnabled()` (hooks-config.ts) at every claude create/respawn. ⚠️ An ABSENT key reads as ON in the reader; `GET /api/settings` must never write. ⚠️ A save sends `showPlanUsageLimits` ONLY when it flips the chip on that device (`planUsageCollectionFlip()`), or a phone switches collection off for every desktop. Claude data comes from the statusLine exporter, injected as an EPHEMERAL `claude --settings` flag (`resolveStatusLineCliCommand`), never written to disk, WRAPPING a user's own statusLine, posting to `POST /api/status-telemetry`. Codex comes from a read-only `account/rateLimits/read` poll (main bucket only). The statusline's `prompt_cache` object (Claude Code v2.1.251+) is kept by `StatusTelemetrySchema` (every documented scalar field, null-tolerant; `parsePromptCache()` in usage-telemetry.ts normalizes only the stored subset) and shown in the footer as `cache:until HH:MM` / `cache:cold` (only when the user has no statusline of their own) and in Session Options → Respawn (`#promptCacheStatus`, fed by `Session.promptCache` in `toState()` plus the change-only `session:promptCache` SSE event, worded by the pure `CodemanPromptCache.format`): warm-until/cold, the re-cache stake, the hit rate, the last miss's causes, and a `Context compacted at HH:MM` note after a compaction or a tool-result clearing (stamped on the first warm report whose `recache_tokens_if_cold` is null after one that carried it, never from `expected_rebuilds`, which Claude Code bumps only at the next request; NEVER an alert). ⚠️ `Session.setPromptCache()` stamps `compactedAt` onto a NEW object (never mutating the parsed report) and the route broadcasts the STORED object; the last report is restored on restart (constructor `promptCache`, like `displayModel`) and the readout is time-aware (a passed `expiresAt` reads cold, not stale-warm). It is the source of truth for the cache TTL, never the plan tier. → [architecture-invariants#plan-usage-chip-statusline-telemetry](docs/architecture-invariants.md#plan-usage-chip-statusline-telemetry), `docs/usage-limits-display-plan.md` **Orchestrator**: State machine that turns a user goal into a phased plan and drives it to completion: `idle → planning → approval → executing → verifying → (replanning) → completed/failed`. `OrchestratorLoop` (engine) delegates plan generation to `orchestrator-planner` and per-phase verification gates to `orchestrator-verifier`, executing phases via team agents/`task-queue`. State persists under the `orchestrator` key in `state.json`. Distinct from Ralph (single-session autonomous loop) — orchestrator coordinates multi-phase, multi-agent execution. See `docs/orchestrator-loop-architecture.md`. diff --git a/README.md b/README.md index de7bb706..fb983ce8 100644 --- a/README.md +++ b/README.md @@ -479,7 +479,7 @@ PTY Output → 16ms Server Batch → DEC 2026 Wrap → SSE → Client rAF → xt - **OSC 52 clipboard**: a program in a session that sets the clipboard with OSC 52 (Claude Code's `/copy`, a tmux yank, vim) puts the text on your browser's clipboard, in the main terminal and in every tile. Clipboard read requests are refused, and replaying a buffer never copies - **MCP server sync** _(opt-in)_: copies the user-level MCP servers each installed CLI has (Claude, Codex, Gemini, OpenCode, Antigravity, and GitHub Copilot CLI) into the others' own config files. Additive only, a server you switched off is never copied, **Preview** shows the changes first, and the previous file is kept as `.codeman-bak`. App Settings → Agents & CLIs; admin only in multi-user mode - **CJK / IME input** — full composition support for Chinese / Japanese / Korean, with Ctrl- and Alt-modified navigation keys passed through to the CLI -- **Plan usage in the header** — live Claude subscription usage (the 5-hour and weekly windows) from a statusline exporter Codeman hands to `claude` at spawn and never writes into your settings files, plus Codex limits from its own app-server and GitHub Copilot's monthly premium-request quota (read with the CLI's own sign-in token); per device, on for desktops and off for phones +- **Plan usage in the header** — live Claude subscription usage (the 5-hour and weekly windows) from a statusline exporter Codeman hands to `claude` at spawn and never writes into your settings files, plus Codex limits from its own app-server; per device, on for desktops and off for phones - **Prompt-cache readout**: each Claude session shows whether its prompt cache is warm (`cache:until HH:MM`) or cold, in the footer (when you have no statusline of your own) and in Session Options → Respawn, with the cost of a re-cache and a note after a compaction. Display only; it survives a restart - **Session list, your way** — the header strip, a left sidebar with a filter box, or a vertical rail whose detailed rows carry created and state stamps and sort by activity; the phone home screen and the desktop home rail use the same order. On the rail, **Search sessions** narrows the list to the tabs that match, across every group, and a tab with an alert stays visible even when its name does not. Named **tab groups** collapse, reorder and take drags; a group's menu has **New session**, and a worker an agent spawns lands right after its parent (**Spawned tabs follow their parent**, off by default, keeps it moving with the parent). **Add to Focus** pins a shortcut to any tab in a section at the top of the rail, and **CLI Logos on Tabs** can be switched off per device - **Terminal looks** — seven skins, four of them light, per-device font family and weight (the bundled JetBrains Mono covers weights 100 to 800), and opt-in animations for tabs, agent windows, the terminal pane, connection lines and [tile-grid tiles](#tile-grid), all in App Settings → Animations (with a lab to try them) diff --git a/docs/copilot-integration.md b/docs/copilot-integration.md index f43062bd..5379b615 100644 --- a/docs/copilot-integration.md +++ b/docs/copilot-integration.md @@ -121,28 +121,6 @@ work from inside a Copilot tab and against Copilot workers: dropped, so a session that has not been asked anything answers nothing. - `interrupt` sends a bare ESC; `rm` refuses itself. -## Plan usage - -The header chip gets a **Copilot** row with one `mo` window: the calendar-month premium-request -quota. The tooltip adds the counts and the reset date. - -- **Source.** `GET https://api.github.com/copilot_internal/user` → - `quota_snapshots.premium_interactions` (`entitlement`, `remaining`, `percent_remaining`; - `quota_reset_date_utc`). `chat` and `completions` are `unlimited` on the paid plans and metered - (200 and 2000) on Free; the chip shows neither. It - is the quota the editors show, but it is **not part of GitHub's documented REST API**. -- **When.** Every 10 minutes from the host, read-only, only while the CLI is installed, a - token resolves and plan-usage display is on (turning the chip off stops the request). -- **Token.** `COPILOT_GITHUB_TOKEN`, `GH_TOKEN`, `GITHUB_TOKEN`, then the signed-in user's - `authTokens` entry in `/config.json` (github.com sign-ins only). - It is sent only to api.github.com over HTTPS with redirects refused, and is never logged or - put in an error. -- **Failure.** Offline, 401, a changed shape, an unlimited quota or a premium quota of zero (a - Free account answers `entitlement: 0`, `has_quota: false`) all yield no row. Overage - is clamped to 100% in the bar and the real count is kept. - -`copilot billing` exists only inside the TUI, so there is no CLI route to the same number. - ## Docker cases The agent image installs `@github/copilot`, and a docker case runs Copilot like any mode. **No @@ -172,6 +150,5 @@ real remote host. - `agent read` does not model tool-call rows: they open with the same `●` bullet and read as part of the answer. - `agent read` sees the visible screen, so an answer longer than one screen is its tail. -- The plan-usage endpoint is undocumented and may change shape; the row then disappears. - Custom endpoints: tool calls through a BYOK endpoint were not exercised. - Remote SSH was not exercised against a real remote host. diff --git a/docs/wiki/Agent-CLIs.md b/docs/wiki/Agent-CLIs.md index 413993df..5b9c1ca5 100644 --- a/docs/wiki/Agent-CLIs.md +++ b/docs/wiki/Agent-CLIs.md @@ -72,7 +72,7 @@ output. The other CLIs expose no equivalent. | Docker cases, remote SSH cases | Yes | Yes | | Precise idle detection | Yes | Codex, Pi, OpenCode, OMP, Copilot and Gemini: same screen check, via their own prompt and working line. DeepSeek: reports its end of turn itself. Antigravity and Grok: generic cues only, unreliable | | Auto-resume when a usage limit resets | Yes | No | -| Plan usage chip | Yes | Codex and GitHub Copilot (monthly premium requests); others no | +| Plan usage chip | Yes | No | | Approvals Inbox | Yes | DeepSeek and Codex as alerts (answer in the terminal); others no | | Read My Mind | Yes | No | | Ralph loop and its task tracker | Yes | No | @@ -302,13 +302,6 @@ not available: wait on `idle`, `exit` or an output marker. plain drag selects text (and Auto Copy works) and clicks still reach Copilot. The wheel, and a swipe on a phone, scroll Copilot's own transcript; Shift+wheel scrolls Codeman's local history. -**Plan usage.** The header chip gains a **Copilot** row with one `mo` window: this month's -premium requests used. The tooltip shows the counts (for example `1215 of 5000 requests`) and -the reset date. It is read from GitHub's `copilot_internal/user` endpoint with Copilot's own -token, every 10 minutes, only while Copilot is installed and signed in and the chip is on. That -endpoint is not part of GitHub's documented API: if it fails, or your plan has no premium -quota (Free) or an unlimited one, the row is simply absent. - **MCP servers.** [MCP server sync](Settings-Reference) includes Copilot's `~/.copilot/mcp-config.json` (relocated by `COPILOT_HOME`), as a target and a source. diff --git a/docs/wiki/The-Dashboard.md b/docs/wiki/The-Dashboard.md index f2c2a4ba..e621e14b 100644 --- a/docs/wiki/The-Dashboard.md +++ b/docs/wiki/The-Dashboard.md @@ -148,7 +148,7 @@ The right side of the header. Almost all of these are off until you enable them | CPU / MEM | On | Server resource use. Drawn as a compact pill by default; see Header Stats Style below. | | File Viewer | On | Toggles the file browser panel. | | Settings gear | Always on | App Settings. | -| Plan usage chip | On, desktop only | Live Claude subscription usage (needs its telemetry exporter, which the same setting installs), plus a Codex row and a GitHub Copilot row (`mo`: this month's premium requests, with counts and the reset date in the tooltip) when those CLIs are signed in. | +| Plan usage chip | On, desktop only | Live Claude subscription usage. Claude-only, and needs its telemetry exporter, which the same setting installs. | | Session Manager | Off | The full session list, live and historical. | | Approvals bell | Off | Cross-session queue of prompts waiting on a human. Appears only when the count is above zero. Never shown on phones. | | Read My Mind 🧠 | Off | Predicts your next prompt for this case. Claude-only. |