Commit Graph
6 Commits
Author SHA1 Message Date
Codeman maintainer 382d7dd406 fix(tabs): route the lineage spine between the state labels and the tabs
With tabArrangement 'state' (the default) and lineage lines on (the desktop
default), the spine ran straight through the WORKING / WAITING / NEEDS YOU
label of every row it passed. #538's
`.session-tabs.tabs-triage:is(.tabs-auto-wrap, .tabs-two-rows)` pads the
strip by the label gutter and pulls each label to the strip's edge with a
negative margin; it outranks #544's `.lineage-tree.tabs-auto-wrap`
`padding-left: 20px`, so the spine channel disappeared, and the spine,
anchored at the strip's left edge (computeLineageTree), sat in the label
column.

The channel now opens BETWEEN the label column and the tabs: with lineage,
the state strip pads by gutter + --lineage-spine-channel, every label keeps
its column at the edge (still under the brand) and hands the channel back
after itself, and the lead label still starts right after the brand.
computeLineageTree takes the channel's left edge as `spineLeft`, which
session-lineage.js reads back from the padding the CSS laid out (content edge
minus the channel), so the two cannot drift; without it, or where the channel
is the padding itself (classic, ledger, case), the spine stays at the strip's
edge exactly as before. The spine's clamp now only considers tabs in rows the
spine can run beside (every row after the first), so a first row that starts
left of the channel (a quiet idle group right after the brand) no longer
drags the spine back over the labels.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 21:36:04 +02:00
Codeman maintainer f5acf19a11 fix(tabs): one lineage row gap for every tab arrangement, no double gap at state breaks
#544 reserves a 12px row gap for the lineage routes on
`.session-tabs.lineage-tree.tabs-auto-wrap`, and #538's arrangements set
their own row spacing at an equal or higher specificity later in the file:

- The ledger grid's `gap: 4px 6px` and the case strip's `gap: 6px` won, so
  the lanes packed onto the cell borders (y 39/40/41 in a 4px gap).
- In the state rows every `.tab-triage-break` is a zero-height flex line of
  its own, so each group boundary cost two row gaps: rows 54px apart instead
  of 42, and the header 12px taller per group (including a trailing one after
  the last group). A negative margin on the break cannot cancel it, because a
  flex line's cross size is clamped at zero (measured in Chromium).

The lineage row gap is now one custom property, `--lineage-row-gap`, set only
by the lineage rule. The ledger and both cluster gaps read it with their own
fallback, and the wrapped state strip spaces its rows with a bottom margin on
every item except the breaks (row-gap 0), its last row's margin replacing the
bottom padding. Rows are now one gap apart in every case, with lineage and
without (4px then, where a group boundary used to be 8px).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 21:36:04 +02:00
Codeman maintainer 55cafc282f feat(tabs): no label on the idle row (#426)
Idle is the default state of a tab, so naming it only adds noise. The
idle group is now quiet: its heading element stays (it anchors the row's
order band and, as the first row, holds its place beside the brand) but
draws no label or count. Needs you, Waiting and Working are unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-06 06:29:40 +02:00
Codeman maintainer bb5fd5ee97 fix(tabs): state rows start under the brand, labels left-aligned (#426)
In the desktop header strip grouped by state, the brand leaves the flow
and sits over the strip's top-left corner, so every row after the first
starts at the left edge under "Codeman" instead of leaving that corner
empty. Labels are left-aligned in the measured column; the first row's
heading takes its natural width beside the brand (--tab-triage-brand,
kept by a ResizeObserver so no render pass reads layout for it).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-06 06:25:26 +02:00
Codeman maintainer e3dfbf6591 feat(tabs): Tab Layout setting with by case (A) and ledger (B), reversible state order, cleaner tiles (#426)
Tab Grouping becomes Tab Layout (tabArrangement: 'state' | 'case' |
'ledger' | 'classic', default 'state'), the first row of App Settings,
Appearance, Tabs, so the old and the new strip are one choice apart.

- By case (option A): each case's tabs sit in one .tab-cluster box in
  first-appearance order, labelled with the case and its count, coloured
  by a stable hash into the session palette. Membership is
  _mobileOverviewCaseFor(), the home screens' own match. Inside a box with
  company a generated w75-api-gateway reads w75; the -<case> stays in the
  DOM in a .tab-name-case span only .tabs-clusters hides. The incremental
  render path rebuilds only when the cluster structure key changes. The
  rail and the sidebar get a labelled section per case; phones dissolve
  the boxes into the chip row. Drag stays inside one box.
- Ledger (option B): CSS only on .tabs-ledger, desktop header strip: an
  auto-fill column grid of equal cells in mono type with a 3px status
  bar. Its markup is identical to classic's.
- State Order (tabStateOrder: 'urgent-first' | 'urgent-last'): flips the
  by-state groups so needs you can be the bottom row.
- By state: the label column is measured to the widest label on screen
  and the labels are right-aligned in it, instead of a fixed 92px gutter
  that left short labels far from their tabs.
- Tiles: a three-row grid (label, value, bar) with pixel line-heights in
  the bundled JetBrains Mono, 36px like the header. The bar used to lie
  over a fixed 28px tile, and a taller system mono (SF Mono) pushed the
  value into it. The WS tile's grid moved onto an inner .connection-tile
  span because JS writes the indicator's display inline. Compact uses the
  same font and a matched WS size.

Tests: test/tab-clusters.test.ts (new), plus the rename and the reversed
order in test/tab-triage.test.ts.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-06 04:08:02 +02:00
Codeman maintainer 9b0d305223 feat(tabs,header): group tabs by state and add header stats styles (#426)
Two directions from Discussion #426, each a per-device setting and the
new default.

Tab Grouping (tabGrouping: 'state' | 'none', default 'state', option C):
tabs are grouped needs you (red, plus failed sessions), waiting (yellow),
working and idle (also ended, exited panes and web tabs), most urgent on
top. The desktop header strip draws a row per group with its label and
count in a left gutter; the flat vertical rail and the sidebar draw a
section per group; tablets keep their scrolling row with inline dividers;
phones keep the chip row in group order without headings. Classification
is the home screens' own (_mobileOverviewState/_mobileOverviewExit), the
fold into four groups is pure in CodemanTabTriage (constants.js). It is
flex `order` plus aria-hidden heading/break elements reconciled in place
after both render paths, never a DOM reorder, so Alt+N, the keyboard walk
and drag keep reading tab order; a drop is refused across groups. Named
groups in the vertical rail take precedence.

Header Stats Style (headerStatsStyle: 'classic' | 'compact' | 'tiles',
default 'tiles', option G): tiles give WS, CPU, MEM and each plan window
a label-over-value tile with a bar underneath; compact is one WS/CPU/MEM
pill with sparklines plus a plan-ring pill; classic is the header as
before. Desktop only (classic below 768px and in solo windows). The
clustered styles move #connectionIndicator into #headerSystemStats and
WS stays out of a hidden System Stats pill. The extra parts are always
rendered and hidden by default in CSS, so classic is unchanged.

Tests: test/tab-triage.test.ts, test/header-stats-style.test.ts; three
source pins in test/tab-rail-order.test.ts follow renamed lines.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-06 04:08:01 +02:00