Skip to content

Commit a84ef52

Browse files
committed
chore: version packages
1 parent 692c894 commit a84ef52

10 files changed

Lines changed: 226 additions & 54 deletions

File tree

CHANGELOG.md

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

3+
## 0.5.5
4+
5+
### Patch Changes
6+
7+
- Add 1M Opus context quick setting — per-case and global toggle that writes `model: "opus[1m]"` to `.claude/settings.local.json` when creating new sessions. Fix mobile layout: banners (respawn, timer, orchestrator) between header and main content now visible by switching from margin-top on `.main` to padding-top on `.app`. Add tablet-optimized respawn banner styles and mobile phone banner refinements.
8+
39
## 0.5.4
410

511
### Patch Changes

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ When user says "COM":
5252
4. **Sync CLAUDE.md version**: Update the `**Version**` line below to match the new version from `package.json`
5353
5. **Commit and deploy**: `git add -A && git commit -m "chore: version packages" && git push && npm run build && systemctl --user restart codeman-web`
5454
55-
**Version**: 0.5.4 (must match `package.json`)
55+
**Version**: 0.5.5 (must match `package.json`)
5656
5757
## Project Overview
5858

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": "0.5.4",
3+
"version": "0.5.5",
44
"description": "The missing control plane for AI coding agents - run 20 autonomous agents with real-time monitoring and session persistence",
55
"type": "module",
66
"main": "dist/index.js",

src/hooks-config.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,34 @@ export async function updateCaseEnvVars(casePath: string, envVars: Record<string
116116
await writeFile(settingsPath, JSON.stringify(existing, null, 2) + '\n');
117117
}
118118

119+
/**
120+
* Updates the `model` field in .claude/settings.local.json for the given case path.
121+
* Pass a non-empty string to set, or empty/null to remove.
122+
*/
123+
export async function updateCaseModel(casePath: string, model: string | null): Promise<void> {
124+
const claudeDir = join(casePath, '.claude');
125+
if (!existsSync(claudeDir)) {
126+
await mkdir(claudeDir, { recursive: true });
127+
}
128+
129+
const settingsPath = join(claudeDir, 'settings.local.json');
130+
let existing: Record<string, unknown> = {};
131+
132+
try {
133+
existing = JSON.parse(await readFile(settingsPath, 'utf-8'));
134+
} catch {
135+
existing = {};
136+
}
137+
138+
if (model) {
139+
existing.model = model;
140+
} else {
141+
delete existing.model;
142+
}
143+
144+
await writeFile(settingsPath, JSON.stringify(existing, null, 2) + '\n');
145+
}
146+
119147
/**
120148
* Writes hooks config to .claude/settings.local.json in the given case path.
121149
* Merges with existing file content, only touching the `hooks` key.

src/web/public/index.html

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,11 @@ <h3 class="history-title">Resume Conversation</h3>
384384
<span>Agent Teams</span>
385385
</label>
386386
<span class="form-hint">Enable experimental Agent Teams for new sessions in this case</span>
387+
<label class="checkbox-inline" style="margin-top: 6px;">
388+
<input type="checkbox" id="caseOpusContext1m" onchange="app.onCaseSettingChanged()">
389+
<span>1M Opus Context</span>
390+
</label>
391+
<span class="form-hint">Use 1M token context window for new sessions</span>
387392
</div>
388393
</div>
389394
<!-- Mobile-only case button + gear -->
@@ -408,6 +413,11 @@ <h3 class="history-title">Resume Conversation</h3>
408413
<span>Agent Teams</span>
409414
</label>
410415
<span class="form-hint">Enable Agent Teams for new sessions</span>
416+
<label class="checkbox-inline" style="margin-top: 6px;">
417+
<input type="checkbox" id="caseOpusContext1mMobile" onchange="app.onCaseSettingChangedMobile()">
418+
<span>1M Opus Context</span>
419+
</label>
420+
<span class="form-hint">Use 1M token context window</span>
411421
</div>
412422
</div>
413423

@@ -1046,6 +1056,14 @@ <h3>App Settings</h3>
10461056
</label>
10471057
<span class="form-hint">Enable experimental Agent Teams for all new Claude sessions (disabled by default)</span>
10481058
</div>
1059+
<div class="form-row form-row-switch">
1060+
<label>1M Opus Context</label>
1061+
<label class="switch">
1062+
<input type="checkbox" id="appSettingsOpusContext1m">
1063+
<span class="slider"></span>
1064+
</label>
1065+
<span class="form-hint">Use 1M token context window (model: opus[1m]) for all new sessions</span>
1066+
</div>
10491067
<!-- Nice Priority Section -->
10501068
<div class="form-section-header">Nice Priority</div>
10511069
<div class="form-row form-row-switch">

src/web/public/mobile.css

Lines changed: 144 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,14 @@ html.mobile-init .file-browser-panel {
6565
max-height: calc(48px + var(--safe-area-top));
6666
}
6767

68-
/* Add top margin to main content to account for fixed header */
69-
.main {
70-
margin-top: 54px;
68+
/* Push ALL content below fixed header (not just .main) so banners
69+
(respawn, timer, orchestrator) between header and main are visible */
70+
.app {
71+
padding-top: 54px;
7172
}
7273

73-
.ios-device .main {
74-
margin-top: calc(54px + var(--safe-area-top));
74+
.ios-device .app {
75+
padding-top: calc(54px + var(--safe-area-top));
7576
}
7677

7778
/* Font controls - smaller on tablet, visibility controlled by JS */
@@ -235,6 +236,37 @@ html.mobile-init .file-browser-panel {
235236
font-size: 0.7rem;
236237
}
237238

239+
/* ---- Respawn Banner: Tablet Optimizations ---- */
240+
241+
.respawn-banner {
242+
padding: 0.25rem 0.5rem;
243+
padding-left: calc(0.5rem + var(--safe-area-left));
244+
padding-right: calc(0.5rem + var(--safe-area-right));
245+
font-size: 0.65rem;
246+
}
247+
248+
.respawn-compact-layout {
249+
gap: 0.75rem;
250+
}
251+
252+
.respawn-status-row1 {
253+
gap: 0.4rem;
254+
}
255+
256+
.respawn-action-log {
257+
max-height: 2.6em;
258+
font-size: 0.6rem;
259+
}
260+
261+
.respawn-countdown-timer {
262+
font-size: 0.55rem;
263+
}
264+
265+
/* Respawn timer bar — slimmer on tablet */
266+
.respawn-timer-bar {
267+
width: 24px;
268+
}
269+
238270
/* Show desktop voice button on tablet (hidden by max-width:1023px in styles.css,
239271
mobile .btn-voice-mobile only shows at <430px) */
240272
.toolbar-center .btn-toolbar.btn-voice {
@@ -327,18 +359,22 @@ html.mobile-init .file-browser-panel {
327359
max-height: calc(36px + var(--safe-area-top));
328360
}
329361

330-
/* Add top margin to main content to account for fixed header,
331-
and bottom padding for the fixed toolbar (40px) so terminal
332-
content doesn't extend behind it. JS overrides paddingBottom
362+
/* Push ALL content below fixed header (not just .main) so banners
363+
(respawn, timer, orchestrator) between header and main are visible.
364+
Bottom padding for the fixed toolbar (40px) so terminal content
365+
doesn't extend behind it. JS overrides paddingBottom on .main
333366
when keyboard is visible, and resetLayout() clears the inline
334367
style to re-expose this CSS value. */
335-
.main {
336-
margin-top: 42px;
337-
padding-bottom: calc(40px + var(--safe-area-bottom));
368+
.app {
369+
padding-top: 42px;
338370
}
339371

340-
.ios-device .main {
341-
margin-top: calc(42px + var(--safe-area-top));
372+
.ios-device .app {
373+
padding-top: calc(42px + var(--safe-area-top));
374+
}
375+
376+
.main {
377+
padding-bottom: calc(40px + var(--safe-area-bottom));
342378
}
343379

344380
/* iOS Safari: toolbar is pushed up by (100vh - --app-height) to clear the
@@ -1213,31 +1249,70 @@ html.mobile-init .file-browser-panel {
12131249
/* ---- Respawn Banner: Mobile Optimizations ---- */
12141250

12151251
.respawn-banner {
1216-
padding: 0.4rem 0.5rem;
1252+
padding: 0.3rem 0.5rem;
12171253
padding-left: calc(0.5rem + var(--safe-area-left));
12181254
padding-right: calc(0.5rem + var(--safe-area-right));
1219-
font-size: 0.7rem;
1255+
font-size: 0.65rem;
12201256
}
12211257

12221258
/* Stack banner vertically on mobile — status on top, action log below */
12231259
.respawn-compact-layout {
12241260
flex-direction: column;
1225-
gap: 0.25rem;
1261+
gap: 0.15rem;
12261262
}
12271263

12281264
/* Let status column shrink to fit */
12291265
.respawn-status-col {
12301266
flex-shrink: 1;
12311267
min-width: 0;
1268+
gap: 0.1rem;
12321269
}
12331270

1234-
/* Wrap status row items — tokens/timer may go to second line */
1271+
/* Row1: wrap allowed, key info prioritized via order */
12351272
.respawn-status-row1 {
12361273
flex-wrap: wrap;
1237-
gap: 0.35rem;
1274+
gap: 0.25rem;
1275+
row-gap: 0.1rem;
1276+
}
1277+
1278+
/* State label — smaller on phone, stays first */
1279+
.respawn-state {
1280+
font-size: 0.6rem;
1281+
padding: 0.05rem 0.3rem;
1282+
}
1283+
1284+
/* Confidence badge — compact */
1285+
.respawn-banner .detection-confidence {
1286+
font-size: 0.5rem;
1287+
padding: 0.02rem 0.2rem;
1288+
}
1289+
1290+
/* Cycles — compact */
1291+
.respawn-cycles {
1292+
font-size: 0.55rem;
1293+
}
1294+
1295+
/* Run timer — compact */
1296+
.respawn-timer {
1297+
font-size: 0.55rem;
1298+
padding: 0 0.25rem;
1299+
}
1300+
1301+
/* Tokens — compact, truncate if long */
1302+
.respawn-tokens {
1303+
font-size: 0.55rem;
1304+
overflow: hidden;
1305+
text-overflow: ellipsis;
1306+
white-space: nowrap;
1307+
max-width: 120px;
1308+
}
1309+
1310+
/* Spinner icon — smaller on phone */
1311+
.respawn-indicator {
1312+
font-size: 0.65rem;
12381313
}
12391314

1240-
/* Stop button — 44px touch target */
1315+
/* Stop button — 36px touch target, pushed right */
12411316
.respawn-banner .btn-icon-only {
12421317
min-width: 36px;
12431318
min-height: 36px;
@@ -1247,26 +1322,50 @@ html.mobile-init .file-browser-panel {
12471322
justify-content: center;
12481323
margin-left: auto;
12491324
border-radius: 6px;
1325+
flex-shrink: 0;
12501326
}
12511327

1252-
/* Action log — horizontal strip below status, border on top instead of left */
1253-
.respawn-action-log {
1254-
border-left: none;
1255-
border-top: 1px solid rgba(34, 197, 94, 0.2);
1256-
padding-left: 0;
1257-
padding-top: 0.25rem;
1258-
max-height: 2em;
1259-
font-size: 0.6rem;
1328+
/* Row2: tighter spacing, smaller text */
1329+
.respawn-status-row2 {
1330+
font-size: 0.55rem;
1331+
gap: 0.3rem;
1332+
min-height: 0;
1333+
flex-wrap: wrap;
12601334
}
12611335

1262-
/* Countdown timers — tighter on mobile */
1336+
/* Detection badges — smaller on phone */
1337+
.respawn-banner .detection-hook,
1338+
.respawn-banner .detection-ai-check,
1339+
.respawn-banner .detection-status {
1340+
font-size: 0.55rem;
1341+
padding: 0.02rem 0.2rem;
1342+
}
1343+
1344+
/* Countdown timers — inline, no progress bars */
12631345
.respawn-countdown-timers {
12641346
gap: 0.2rem;
12651347
}
12661348

12671349
.respawn-countdown-timer {
1350+
font-size: 0.5rem;
1351+
padding: 0.02rem 0.2rem;
1352+
gap: 0.15rem;
1353+
}
1354+
1355+
/* Hide progress bars on phone — values are enough */
1356+
.respawn-countdown-timer .respawn-timer-bar {
1357+
display: none;
1358+
}
1359+
1360+
/* Action log — single-line strip below status, show latest entry only */
1361+
.respawn-action-log {
1362+
border-left: none;
1363+
border-top: 1px solid rgba(34, 197, 94, 0.15);
1364+
padding-left: 0;
1365+
padding-top: 0.15rem;
1366+
max-height: 1.4em;
12681367
font-size: 0.55rem;
1269-
padding: 0.05rem 0.25rem;
1368+
overflow: hidden;
12701369
}
12711370

12721371
/* ---- Session Options Modal: Respawn Tab Mobile Optimizations ---- */
@@ -1292,28 +1391,27 @@ html.mobile-init .file-browser-panel {
12921391
border-radius: 5px;
12931392
}
12941393

1295-
/* Duration preset buttons — single row, all 7 items */
1394+
/* Duration preset buttons — grid layout, 4 columns for even spacing */
12961395
.duration-presets {
1297-
display: flex;
1298-
flex-wrap: wrap;
1299-
gap: 0.25rem;
1396+
display: grid;
1397+
grid-template-columns: repeat(4, 1fr);
1398+
gap: 0.2rem;
13001399
}
13011400

13021401
.duration-preset-btn {
1303-
min-height: 28px;
1304-
padding: 0.2rem 0.4rem;
1402+
min-height: 32px;
1403+
padding: 0.2rem 0.25rem;
13051404
font-size: 0.65rem;
13061405
border-radius: 5px;
13071406
text-align: center;
1308-
flex: 1 1 auto;
1309-
min-width: 0;
13101407
}
13111408

1312-
/* Custom duration — inline with other presets */
1409+
/* Custom duration — spans full row below */
13131410
.duration-custom {
1314-
flex-wrap: wrap;
1411+
grid-column: 1 / -1;
1412+
display: flex;
13151413
gap: 0.25rem;
1316-
flex: 1 1 100%;
1414+
align-items: center;
13171415
}
13181416

13191417
.duration-custom .duration-preset-btn {
@@ -1331,24 +1429,23 @@ html.mobile-init .file-browser-panel {
13311429
font-size: 16px; /* Prevents iOS zoom */
13321430
}
13331431

1334-
/* Preset selector row — compact inline */
1432+
/* Preset selector row — full-width dropdown, buttons below */
13351433
.preset-selector {
1336-
display: flex;
1337-
flex-wrap: wrap;
1434+
display: grid;
1435+
grid-template-columns: 1fr 1fr;
13381436
gap: 0.25rem;
13391437
}
13401438

13411439
.preset-selector select {
1342-
width: 100%;
1343-
min-height: 28px;
1440+
grid-column: 1 / -1;
1441+
min-height: 32px;
13441442
font-size: 16px; /* Prevents iOS zoom */
13451443
border-radius: 5px;
13461444
padding: 0.2rem 0.4rem;
13471445
}
13481446

13491447
.preset-selector .btn {
1350-
flex: 1;
1351-
min-height: 28px;
1448+
min-height: 32px;
13521449
font-size: 0.65rem;
13531450
border-radius: 5px;
13541451
padding: 0.2rem 0.4rem;

0 commit comments

Comments
 (0)