fix(terminal): merge-time fixes for the copy gutter strip (#469)

- stock.ts: claude is no longer the only entry declaring transcriptGutter;
  codex declares it too.
- architecture-invariants: the strip applies when the session's CLI declares
  a margin (not detection), and a note that it keys on the session's launch
  mode, not on what is running in the pane (a claude pane dropped to a shell
  still loses up to two columns; copyStripMargin is the escape hatch).
- render-index-html test: the gutter map is injected for a solo
  /session/:id render as well.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Codeman maintainer
2026-09-23 11:40:03 +02:00
parent 10f87428c3
commit da6fa663e7
3 changed files with 17 additions and 4 deletions
+13
View File
@@ -143,6 +143,19 @@ describe('WebServer.renderIndexHtml', () => {
expect(html).toContain('btn-multimonitor--hidden');
});
it('injects the transcript-gutter map for a /session/:id window too', async () => {
// Every other payload is gated on !soloSessionId, but a solo window copies from a
// terminal like the main page does, so it needs the widths the copy strip keys on.
const { server } = makeServer();
const html = await render(server, 'sess-123');
const match = html.match(/window\.__codemanTranscriptGutter=(\{[^<]*\});/);
expect(match).not.toBeNull();
const map = JSON.parse(match![1]) as Record<string, number>;
expect(map.claude).toBe(2);
expect(map.codex).toBe(2);
expect(map.shell).toBeUndefined();
});
it('escapes the solo id so it cannot break out of the inline <script>', async () => {
const { server } = makeServer({});
const html = await render(server, 'a</script><b>');