Skip to content

Commit 22cb563

Browse files
committed
chore: version packages
Plan-usage chip defaults ON on desktop (handhelds stay OFF), resolved through a single planUsageChipEnabled() helper so the checkbox, the chip and the create-time statusLineTelemetry flag cannot disagree. Correct the stale "Cron button defaults ON" comment (it is OFF in code, template and CSS) and the styles.css comment claiming the server strips the chip's hidden class. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent f0e13f9 commit 22cb563

11 files changed

Lines changed: 66 additions & 23 deletions

File tree

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
# aicodeman
22

3+
## 1.9.3
4+
5+
### Patch Changes
6+
7+
- Plan-usage chip now defaults ON on desktop, plus the reworked `xterm-zerolag-input` README.
8+
- **Plan-usage chip defaults ON (desktop).** The `showPlanUsageLimits` chip (live 5-hour and weekly plan usage from the Claude statusline) used to be opt-in and default OFF, so most users never saw it. Desktop now defaults ON; handhelds still default OFF so the phone header stays minimal and the `mobile-header-buttons-policy` guard keeps passing. Devices with an explicitly stored preference keep whatever they chose, so nobody's OFF gets overridden.
9+
- **One resolver behind the chip.** Added `planUsageChipEnabled()` in settings-ui.js and routed all three call sites through it: the App Settings checkbox, the chip's visibility, and the create-time `statusLineTelemetry` flag in session-ui.js. Those three had independent `?? false` / `=== true` defaults, and a chip revealed without the telemetry flag renders `` forever, so a default flip on one site alone would have shipped a permanently empty chip.
10+
- **Cron button comment corrected.** The App Settings comment claimed "Cron button defaults ON" while the code, the template (`btn-cron--hidden`) and the CSS all default it OFF. Verified against a fresh browser profile: the button is hidden and its checkbox unchecked out of the box. Comment now matches, and states why the two halves stay consistent.
11+
- **Docs.** CLAUDE.md, `docs/architecture-invariants.md` and `docs/usage-limits-display-plan.md` updated for the new default and the single-resolver rule; the stale `styles.css` comment claiming the server strips the chip's hidden class at render was corrected (display is per-device, so the client reveals it).
12+
- **`xterm-zerolag-input` README rework** (0.1.5 shipped the content; this republishes with the graphic and promo changes): replaced the misaligned 8-line keystroke-flow diagram with a two-line stock-vs-zerolag contrast, added a Codeman callout above the demo GIF with links to getcodeman.com and the repo, and rewrote the Origin section so it argues the extraction story instead of repeating the promo.
13+
314
## 1.9.2
415

516
### Patch Changes

CLAUDE.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ When user says "COM":
7474
7575
CI runs `npm run check:lockfile` on every push/PR, so lockfile drift fails the build even if the `version-packages` script is bypassed.
7676
77-
**Version**: 1.9.2 (must match `package.json`)
77+
**Version**: 1.9.3 (must match `package.json`)
7878
7979
## Project Overview
8080
@@ -183,7 +183,7 @@ Codeman is a Claude Code session manager with web interface and autonomous Ralph
183183
184184
**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)
185185
186-
**Plan-usage chip** (statusLine telemetry, opt-in `showPlanUsageLimits`, default OFF): Codeman injects its own `statusLine.command` exporter which POSTs Claude's `rate_limits` blob to `POST /api/status-telemetry`. The exporter is identified by a marker, so it only ever adds/updates/removes a statusLine that is **ours**, never a user's hand-authored one, and it prints the footer through so the in-terminal statusline is not blanked. Claude-mode only; distinct from auto-resume, which reacts to the limit *message* rather than showing live %. → [architecture-invariants#plan-usage-chip-statusline-telemetry](docs/architecture-invariants.md#plan-usage-chip-statusline-telemetry), `docs/usage-limits-display-plan.md`
186+
**Plan-usage chip** (statusLine telemetry, `showPlanUsageLimits`, per-device: desktop default **ON**, handhelds OFF via the mobile block in `getDefaultSettings()`): resolve it ONLY through `planUsageChipEnabled()` in settings-ui.js, which backs all three call sites (the App Settings checkbox, the chip's visibility, and the `statusLineTelemetry` flag on session create). A chip shown without telemetry renders `—` forever. Codeman injects its own `statusLine.command` exporter which POSTs Claude's `rate_limits` blob to `POST /api/status-telemetry`. The exporter is identified by a marker, so it only ever adds/updates/removes a statusLine that is **ours**, never a user's hand-authored one, and it prints the footer through so the in-terminal statusline is not blanked. Claude-mode only; distinct from auto-resume, which reacts to the limit *message* rather than showing live %. → [architecture-invariants#plan-usage-chip-statusline-telemetry](docs/architecture-invariants.md#plan-usage-chip-statusline-telemetry), `docs/usage-limits-display-plan.md`
187187
188188
**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`.
189189

docs/architecture-invariants.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ Implementation detail extracted from `CLAUDE.md` so that file stays small enough
4646

4747
### Plan-usage chip (statusLine telemetry)
4848

49-
**Plan-usage chip** (statusLine telemetry, opt-in `showPlanUsageLimits`, default OFF): Claude Code (v2.1.80+) pipes a JSON blob to a configured `statusLine.command` on each render; on Pro/Max it carries a `rate_limits` object (`five_hour`/`seven_day` windows only — no Opus weekly field — each `{used_percentage 0-100, resets_at epoch-SECONDS}`). Codeman injects its OWN statusLine exporter (`generateStatusLineCommand()` in `hooks-config.ts`, identified by the `/api/status-telemetry` marker — it only ever adds/updates/removes a statusLine that is _ours_, never a user's hand-authored one) that POSTs the blob to `POST /api/status-telemetry`. That route (auth-exempt like `/api/hook-event` — localhost-only, hook-secret-gated whenever auth is active, COD-91) parses via `usage-telemetry.ts` (pure, unit-tested), broadcasts SSE `session:statusTelemetry` (de-duped per session by `telemetrySignature` since the statusline fires on every assistant message), and returns a compact plain-text footer for the exporter to **print-through** (so injecting our statusLine doesn't blank the in-terminal footer). `plan-usage-latest.ts` holds the process-wide last value, replayed in the SSE init snapshot (`getLightState`) so the header chip (`#planUsageChip`, toggled by `showPlanUsageLimits` in settings-ui.js) renders immediately on page load / reconnect without per-browser localStorage. Claude-mode only. **Distinct from auto-resume** (which reacts to the limit _message_; this proactively shows the live %). Design: `docs/usage-limits-display-plan.md`. Tests: `test/usage-telemetry.test.ts`.
49+
**Plan-usage chip** (statusLine telemetry, `showPlanUsageLimits`, per-device: desktop default **ON** since 1.9.3, handhelds OFF): Claude Code (v2.1.80+) pipes a JSON blob to a configured `statusLine.command` on each render; on Pro/Max it carries a `rate_limits` object (`five_hour`/`seven_day` windows only — no Opus weekly field — each `{used_percentage 0-100, resets_at epoch-SECONDS}`). Codeman injects its OWN statusLine exporter (`generateStatusLineCommand()` in `hooks-config.ts`, identified by the `/api/status-telemetry` marker — it only ever adds/updates/removes a statusLine that is _ours_, never a user's hand-authored one) that POSTs the blob to `POST /api/status-telemetry`. That route (auth-exempt like `/api/hook-event` — localhost-only, hook-secret-gated whenever auth is active, COD-91) parses via `usage-telemetry.ts` (pure, unit-tested), broadcasts SSE `session:statusTelemetry` (de-duped per session by `telemetrySignature` since the statusline fires on every assistant message), and returns a compact plain-text footer for the exporter to **print-through** (so injecting our statusLine doesn't blank the in-terminal footer). `plan-usage-latest.ts` holds the process-wide last value, replayed in the SSE init snapshot (`getLightState`) so the header chip (`#planUsageChip`, revealed by `planUsageChipEnabled()` in settings-ui.js, the single resolver behind the checkbox, the chip and the create-time `statusLineTelemetry` flag) renders immediately on page load / reconnect without per-browser localStorage. Claude-mode only. **Distinct from auto-resume** (which reacts to the limit _message_; this proactively shows the live %). Design: `docs/usage-limits-display-plan.md`. Tests: `test/usage-telemetry.test.ts`.
5050

5151
### Cron jobs
5252

docs/usage-limits-display-plan.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Plan Usage Limits Display — Design & As-Built
22

3-
> **Status: SHIPPED — deployed to prod + pushed to master, not yet released (2026-06-14).** Opt-in via App Settings → Display → **Plan Usage Limits** (`showPlanUsageLimits`, default OFF). Commits `c82f6c8` (feature) → `4d9d93d` (end-to-end fixes) → `eae225b` (per-user reconcile) → `95fb5fc` (init-snapshot replay). Full suite green (2869), CI green. No changeset/version bump yet.
3+
> **Status: SHIPPED — deployed to prod + pushed to master, not yet released (2026-06-14).** App Settings → Display → **Plan Usage Limits** (`showPlanUsageLimits`). **Default changed in 1.9.3: desktop now defaults ON, handhelds stay OFF, resolved via `planUsageChipEnabled()`.** The per-device notes further down describing it as opt-in/synced record the original 2026-06-14 shape, not current behavior. Commits `c82f6c8` (feature) → `4d9d93d` (end-to-end fixes) → `eae225b` (per-user reconcile) → `95fb5fc` (init-snapshot replay). Full suite green (2869), CI green. No changeset/version bump yet.
44
>
55
> Two surfaces from one `statusLine` callback:
66
> - **Header chip** (top-right) — account-wide **plan limits**: `5h 35% · 7d 38%`, per-window green/yellow/red.

package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "aicodeman",
3-
"version": "1.9.2",
3+
"version": "1.9.3",
44
"description": "Mission control for AI coding agents - run 20 autonomous agents with real-time monitoring and session persistence",
55
"type": "module",
66
"main": "dist/index.js",

packages/xterm-zerolag-input/CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
# xterm-zerolag-input
22

3+
## 0.1.6
4+
5+
### Patch Changes
6+
7+
- Plan-usage chip now defaults ON on desktop, plus the reworked `xterm-zerolag-input` README.
8+
- **Plan-usage chip defaults ON (desktop).** The `showPlanUsageLimits` chip (live 5-hour and weekly plan usage from the Claude statusline) used to be opt-in and default OFF, so most users never saw it. Desktop now defaults ON; handhelds still default OFF so the phone header stays minimal and the `mobile-header-buttons-policy` guard keeps passing. Devices with an explicitly stored preference keep whatever they chose, so nobody's OFF gets overridden.
9+
- **One resolver behind the chip.** Added `planUsageChipEnabled()` in settings-ui.js and routed all three call sites through it: the App Settings checkbox, the chip's visibility, and the create-time `statusLineTelemetry` flag in session-ui.js. Those three had independent `?? false` / `=== true` defaults, and a chip revealed without the telemetry flag renders `` forever, so a default flip on one site alone would have shipped a permanently empty chip.
10+
- **Cron button comment corrected.** The App Settings comment claimed "Cron button defaults ON" while the code, the template (`btn-cron--hidden`) and the CSS all default it OFF. Verified against a fresh browser profile: the button is hidden and its checkbox unchecked out of the box. Comment now matches, and states why the two halves stay consistent.
11+
- **Docs.** CLAUDE.md, `docs/architecture-invariants.md` and `docs/usage-limits-display-plan.md` updated for the new default and the single-resolver rule; the stale `styles.css` comment claiming the server strips the chip's hidden class at render was corrected (display is per-device, so the client reveals it).
12+
- **`xterm-zerolag-input` README rework** (0.1.5 shipped the content; this republishes with the graphic and promo changes): replaced the misaligned 8-line keystroke-flow diagram with a two-line stock-vs-zerolag contrast, added a Codeman callout above the demo GIF with links to getcodeman.com and the repo, and rewrote the Origin section so it argues the extraction story instead of repeating the promo.
13+
314
## 0.1.5
415

516
### Patch Changes

packages/xterm-zerolag-input/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "xterm-zerolag-input",
3-
"version": "0.1.5",
3+
"version": "0.1.6",
44
"description": "Instant keystroke feedback overlay for xterm.js — eliminates perceived input latency over high-RTT connections",
55
"type": "module",
66
"main": "dist/index.cjs",

src/web/public/session-ui.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -716,7 +716,7 @@ Object.assign(CodemanApp.prototype, {
716716
// is shared by sibling sessions, so create-with-false must not yank it
717717
// — see the comment in session-routes create). Disabling the setting
718718
// removes it via the App Settings toggle path (system-routes), not here.
719-
statusLineTelemetry: globalSettings.showPlanUsageLimits === true,
719+
statusLineTelemetry: this.planUsageChipEnabled(globalSettings),
720720
})
721721
}).then(r => r.json())
722722
);

src/web/public/settings-ui.js

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -325,9 +325,11 @@ Object.assign(CodemanApp.prototype, {
325325
document.getElementById('appSettingsUltracodeFloatingWindows').checked =
326326
settings.ultracodeFloatingWindows ?? defaults.ultracodeFloatingWindows ?? false;
327327
document.getElementById('appSettingsShowMultiMonitorButton').checked = settings.showMultiMonitorButton ?? defaults.showMultiMonitorButton ?? false;
328-
document.getElementById('appSettingsShowPlanUsageLimits').checked = settings.showPlanUsageLimits ?? defaults.showPlanUsageLimits ?? false;
328+
document.getElementById('appSettingsShowPlanUsageLimits').checked = this.planUsageChipEnabled(settings);
329329
document.getElementById('appSettingsShowRedrawButton').checked = settings.showRedrawButton ?? defaults.showRedrawButton ?? false;
330-
// Session Manager + Away Digest buttons default OFF; Cron button defaults ON.
330+
// Session Manager, Away Digest and Cron buttons all default OFF (opt-in under
331+
// Display → Header Displays; the Cron button also ships with btn-cron--hidden
332+
// in the template, so an unchecked box and a hidden button stay consistent).
331333
document.getElementById('appSettingsShowSessionButton').checked = settings.showSessionButton ?? defaults.showSessionButton ?? false;
332334
document.getElementById('appSettingsShowAwayDigestButton').checked = settings.showAwayDigestButton ?? defaults.showAwayDigestButton ?? false;
333335
document.getElementById('appSettingsShowCronButton').checked = settings.showCronButton ?? defaults.showCronButton ?? false;
@@ -1798,6 +1800,9 @@ Object.assign(CodemanApp.prototype, {
17981800
showUltracodeAgents: false,
17991801
ultracodeFloatingWindows: false,
18001802
showMultiMonitorButton: false,
1803+
// Desktop defaults this ON (see planUsageChipEnabled); handhelds keep it
1804+
// OFF so the phone header stays minimal and the mobile-header-buttons
1805+
// policy guard keeps passing.
18011806
showPlanUsageLimits: false,
18021807
showAttachmentsButton: false,
18031808
showFileViewerButton: false,
@@ -1889,6 +1894,18 @@ Object.assign(CodemanApp.prototype, {
18891894
}
18901895
},
18911896

1897+
// Resolved per-device state of the plan-usage chip. Desktop defaults ON,
1898+
// handhelds default OFF (the mobile block in getDefaultSettings() sets false,
1899+
// and the mobile-header-buttons-policy guard depends on that staying false).
1900+
// Single source of truth for THREE call sites that must never disagree: the
1901+
// App Settings checkbox, the chip's visibility, and the statusLineTelemetry
1902+
// flag sent on session create. A chip shown without telemetry renders "—"
1903+
// forever, which is exactly the drift this helper prevents.
1904+
planUsageChipEnabled(settings = null) {
1905+
const s = settings ?? this.loadAppSettingsFromStorage();
1906+
return s.showPlanUsageLimits ?? this.getDefaultSettings().showPlanUsageLimits ?? true;
1907+
},
1908+
18921909
applyHeaderVisibilitySettings() {
18931910
const settings = this.loadAppSettingsFromStorage();
18941911
const defaults = this.getDefaultSettings();
@@ -1967,11 +1984,13 @@ Object.assign(CodemanApp.prototype, {
19671984
ultracodeBtn.classList.toggle('btn-ultracode-agents--hidden', !showUltracodeAgents);
19681985
}
19691986

1970-
// Plan-usage chip — hidden by default (App Settings → Display → "Plan Usage
1971-
// Limits"). Server renders the initial state on reload; this handles a live
1972-
// toggle from a settings save. Marker class (base is display:inline-flex
1973-
// !important), matching the response-viewer/multimonitor pattern.
1974-
const showPlanUsageLimits = settings.showPlanUsageLimits ?? defaults.showPlanUsageLimits ?? false;
1987+
// Plan-usage chip — shown by default on desktop, OFF on handhelds (App
1988+
// Settings → Display → "Plan Usage Limits"). The template always ships it
1989+
// hidden because display is per-device and the server cannot know a
1990+
// localStorage value, so THIS is what reveals it on every load as well as
1991+
// on a live toggle. Marker class (base is display:inline-flex !important),
1992+
// matching the response-viewer/multimonitor pattern.
1993+
const showPlanUsageLimits = this.planUsageChipEnabled(settings);
19751994
const planUsageChip = document.getElementById('planUsageChip');
19761995
if (planUsageChip) {
19771996
planUsageChip.classList.toggle('header-plan-usage--hidden', !showPlanUsageLimits);
@@ -2247,9 +2266,10 @@ Object.assign(CodemanApp.prototype, {
22472266
'terminalWheelLocalScrollback',
22482267
'showSessionButton', 'showAwayDigestButton', 'showCronButton',
22492268
]);
2250-
// The plan-usage chip is a PER-DEVICE display setting (default OFF): desktop
2251-
// can show it while mobile stays hidden. It used to sync, so an older
2252-
// server.json may still carry `true` — drop it so the server value is NEVER
2269+
// The plan-usage chip is a PER-DEVICE display setting (desktop default ON,
2270+
// handheld default OFF): desktop can show it while mobile stays hidden. It
2271+
// used to sync, so an older server.json may still carry a value — drop it
2272+
// so the server value is NEVER
22532273
// seeded into a device that didn't explicitly enable it (collection is handled
22542274
// separately via the statusLineTelemetry action, not this display flag).
22552275
delete appSettings.showPlanUsageLimits;

0 commit comments

Comments
 (0)