Skip to content

WL-0MMJ927NG14R0NES: TUI tree height configurable (7-14 lines)#1566

Merged
SorraTheOrc merged 8 commits intomainfrom
feature/WL-0MMJ927NG14R0NES-tui-layout
Apr 20, 2026
Merged

WL-0MMJ927NG14R0NES: TUI tree height configurable (7-14 lines)#1566
SorraTheOrc merged 8 commits intomainfrom
feature/WL-0MMJ927NG14R0NES-tui-layout

Conversation

@SorraTheOrc
Copy link
Copy Markdown
Member

Summary

Implements configurable tree height in the TUI layout with min/max bounds (7-14 lines) and dynamic resize support.

Changes

  • Added (7) and (14) constants in
  • Added method to for dynamic height setting
  • Added method to for dynamic height/top positioning
  • Implemented function in that:
    • Computes available terminal height
    • Clamps preferred tree height (H/2) to [7, 14] range
    • Allocates remaining space to description pane
  • Added resize event handler to re-compute layout on terminal resize
  • Added unit tests for new constants and component methods

Acceptance Criteria Met

  • ✅ Work item tree height respects a minimum of 7 lines
  • ✅ Work item tree height respects a maximum of 14 lines
  • ✅ Description pane fills remaining vertical space
  • ✅ Resize handler maintains correct layout on terminal resize
  • ✅ Unit tests added for new constants and component methods
  • ✅ All 1482 tests pass

Testing

Run:

worklog@1.0.0 test
vitest run

�[1m�[46m RUN �[49m�[22m �[36mv4.0.18 �[39m�[90m/home/rgardler/projects/ContextHub�[39m

�[32m✓�[39m tests/cli/github-push-batching.test.ts �[2m(�[22m�[2m7 tests�[22m�[2m)�[22m�[33m 1782�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m --id with a valid item pushes only that item (command completes without error) �[33m 319�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m push with many items completes and writes timestamp (batching path) �[33m 416�[2mms�[22m�[39m
�[32m✓�[39m tests/cli/audit.test.ts �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[33m 2086�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m prints audit completion message and text in human mode �[33m 997�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m returns JSON in --json mode �[33m 980�[2mms�[22m�[39m
�[32m✓�[39m tests/github-label-events.test.ts �[2m(�[22m�[2m33 tests�[22m�[2m)�[22m�[33m 3591�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m returns empty array and caches on API failure �[33m 3550�[2mms�[22m�[39m
�[32m✓�[39m tests/github-assign-issue.test.ts �[2m(�[22m�[2m11 tests�[22m�[2m)�[22m�[33m 4010�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m retries on rate-limit errors �[33m 1506�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m retries on 403 errors �[33m 503�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m returns error after exhausting retries on persistent rate limit �[33m 1505�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m returns fallback error when stderr is empty �[33m 480�[2mms�[22m�[39m
�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1000h�[?1002h�[?1005h�[?1l�>�[?12l�[?25h�[H�[2J�[?1000l�[?1002l�[?1005l�[?1049l�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1l�>�[?12l�[?25h�[H�[2J�[?1049l�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1l�>�[?12l�[?25h�[H�[2J�[?1049l�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1l�>�[?12l�[?25h�[H�[2J�[?1049l�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?12l�[?25h�[?25l�[?12l�[?25h�[?1l�>�[?12l�[?25h�[H�[2J�[?1049l�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?12l�[?25h�[?25l�[?12l�[?25h�[?25l�[?12l�[?25h�[?1l�>�[?12l�[?25h�[H�[2J�[?1049l�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?12l�[?25h�[?25l�[?12l�[?25h�[?25l�[?12l�[?25h�[?25l�[?12l�[?25h�[?1l�>�[?12l�[?25h�[H�[2J�[?1049l�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1l�>�[?12l�[?25h�[H�[2J�[?1049l�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1l�>�[?12l�[?25h�[H�[2J�[?1049l�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?12l�[?25h�[?1l�>�[?12l�[?25h�[H�[2J�[?1049l�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1l�>�[?12l�[?25h�[H�[2J�[?1049l�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1l�>�[?12l�[?25h�[H�[2J�[?1049l�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?12l�[?25h�[?25l�[?12l�[?25h�[?25l�[?12l�[?25h�[?1l�>�[?12l�[?25h�[H�[2J�[?1049l�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1l�>�[?12l�[?25h�[H�[2J�[?1049l�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1l�>�[?12l�[?25h�[H�[2J�[?1049l�Ptmux;��[?1003h�\�Ptmux;��[?1003l�\ �[32m✓�[39m tests/tui/tui-update-dialog.test.ts �[2m(�[22m�[2m36 tests�[22m�[2m)�[22m�[33m 1629�[2mms�[22m�[39m
�[32m✓�[39m tests/unit/database-upsert.test.ts �[2m(�[22m�[2m13 tests�[22m�[2m | �[22m�[33m2 skipped�[39m�[2m)�[22m�[33m 1413�[2mms�[22m�[39m
�[32m✓�[39m tests/integration/github-upsert-preservation.test.ts �[2m(�[22m�[2m9 tests�[22m�[2m)�[22m�[33m 1469�[2mms�[22m�[39m
�[32m✓�[39m tests/fts-search.test.ts �[2m(�[22m�[2m58 tests�[22m�[2m)�[22m�[33m 5810�[2mms�[22m�[39m
�[32m✓�[39m tests/normalize-sqlite-bindings.test.ts �[2m(�[22m�[2m39 tests�[22m�[2m)�[22m�[33m 1631�[2mms�[22m�[39m
�[32m✓�[39m tests/plugin-integration.test.ts �[2m(�[22m�[2m14 tests�[22m�[2m)�[22m�[33m 5364�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should load and execute a simple external plugin �[33m 860�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should show plugin information with plugins command �[33m 304�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should allow plugin to access worklog database �[33m 818�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should respect WORKLOG_PLUGIN_DIR environment variable �[33m 340�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should not load .d.ts or .map files as plugins �[33m 301�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should load plugins from the global directory �[33m 308�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should load plugins from both local and global directories �[33m 385�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should give local plugin precedence over global with same filename �[33m 352�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should show both directories in plugins command JSON output �[33m 337�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should still use WORKLOG_PLUGIN_DIR as single override when set �[33m 312�[2mms�[22m�[39m
�[32m✓�[39m tests/cli/update-batch.test.ts �[2m(�[22m�[2m25 tests�[22m�[2m)�[22m�[33m 5555�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should preserve per-id ordering in results array �[33m 301�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should exit non-zero even when majority of ids succeed �[33m 324�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/controller-watch.test.ts �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[33m 1296�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should refresh when database file changes �[33m 455�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should refresh on every watch event (no mtime filtering) �[33m 419�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should watch WAL file for SQLite WAL mode �[33m 419�[2mms�[22m�[39m
�[32m✓�[39m tests/cli/debug-inproc.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[33m 1469�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m debug in-process runner outputs �[33m 1467�[2mms�[22m�[39m
�[32m✓�[39m tests/integration/audit-skill-cli.test.ts �[2m(�[22m�[2m5 tests�[22m�[2m)�[22m�[33m 1530�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m redacts email addresses in audit text while preserving valid first line �[33m 311�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m preserves historical comments while storing new structured audit �[33m 409�[2mms�[22m�[39m
�[32m✓�[39m tests/search-fallback.test.ts �[2m(�[22m�[2m10 tests�[22m�[2m)�[22m�[33m 1301�[2mms�[22m�[39m
�[32m✓�[39m tests/cli/openbrain-close.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[33m 1374�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m appends to queue when openBrainEnabled=true and ob fails �[33m 721�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/opencode-child-lifecycle.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[33m 1009�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m removes listeners and kills child on stopServer and allows restart without leaking �[33m 1007�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/controller-watch-integration.test.ts �[2m(�[22m�[2m2 tests�[22m�[2m)�[22m�[33m 1070�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should detect changes when database file is modified �[33m 550�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should detect changes when WAL file is modified (SQLite WAL mode) �[33m 517�[2mms�[22m�[39m
�[32m✓�[39m tests/sync-worktree.test.ts �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[33m 742�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m error propagates when git branch -D fails on an existing branch �[33m 353�[2mms�[22m�[39m
�[32m✓�[39m tests/cli/github-push-force.test.ts �[2m(�[22m�[2m5 tests�[22m�[2m)�[22m�[33m 902�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m --all with seeded items shows item count in output �[33m 305�[2mms�[22m�[39m
�[32m✓�[39m tests/cli/github-push-start-timestamp.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[33m 893�[2mms�[22m�[39m
�[32m✓�[39m test/tui-integration.test.ts �[2m(�[22m�[2m10 tests�[22m�[2m)�[22m�[33m 692�[2mms�[22m�[39m
�[32m✓�[39m tests/cli/team.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[33m 740�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should import data from a file �[33m 392�[2mms�[22m�[39m
�[32m✓�[39m tests/cli/helpers-tree-rendering.test.ts �[2m(�[22m�[2m6 tests�[22m�[2m)�[22m�[33m 801�[2mms�[22m�[39m
�[32m✓�[39m tests/next-regression.test.ts �[2m(�[22m�[2m73 tests�[22m�[2m)�[22m�[33m 9278�[2mms�[22m�[39m
�[32m✓�[39m test/validator.test.ts �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[33m 714�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m validator script exits zero and prints OK �[33m 352�[2mms�[22m�[39m
�[32m✓�[39m tests/migrations.test.ts �[2m(�[22m�[2m2 tests�[22m�[2m)�[22m�[33m 421�[2mms�[22m�[39m
�[32m✓�[39m tests/cli/status.test.ts �[2m(�[22m�[2m6 tests�[22m�[2m | �[22m�[33m1 skipped�[39m�[2m)�[22m�[33m 850�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should show correct counts in database summary �[33m 397�[2mms�[22m�[39m
�[32m✓�[39m tests/cli/doctor-upgrade.test.ts �[2m(�[22m�[2m2 tests�[22m�[2m)�[22m�[33m 478�[2mms�[22m�[39m
�[32m✓�[39m tests/config.test.ts �[2m(�[22m�[2m19 tests�[22m�[2m)�[22m�[33m 749�[2mms�[22m�[39m
�[32m✓�[39m tests/cli/fresh-install.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[33m 8800�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m wl init --json produces clean stderr (no plugin errors) �[33m 1269�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m wl stats --json returns valid JSON after fresh init �[33m 2323�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m wl list --json --verbose shows no plugin errors �[33m 2599�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m first-init and re-init both include statsPlugin in JSON �[33m 2607�[2mms�[22m�[39m
�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1l�>�[?12l�[?25h�[H�[2J�[?1049l�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1l�>�[?12l�[?25h�[H�[2J�[?1049l�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1l�>�[?12l�[?25h�[H�[2J�[?1049l�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1l�>�[?12l�[?25h�[H�[2J�[?1049l�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1l�>�[?12l�[?25h�[H�[2J�[?1049l�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1l�>�[?12l�[?25h�[H�[2J�[?1049l�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1000h�[?1002h�Ptmux;��[?1003h�\�[?1005h�[?1l�>�[?12l�[?25h�[H�[2J�[?1000l�[?1002l�Ptmux;��[?1003l�\�[?1005l�[?1049l�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1000h�[?1002h�Ptmux;��[?1003h�\�[?1005h�[?1l�>�[?12l�[?25h�[H�[2J�[?1000l�[?1002l�Ptmux;��[?1003l�\�[?1005l�[?1049l�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1000h�[?1002h�Ptmux;��[?1003h�\�[?1005h�[?1l�>�[?12l�[?25h�[H�[2J�[?1000l�[?1002l�Ptmux;��[?1003l�\�[?1005l�[?1049l�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1l�>�[?12l�[?25h�[H�[2J�[?1049l�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1l�>�[?12l�[?25h�[H�[2J�[?1049l �[32m✓�[39m tests/plugin-loader.test.ts �[2m(�[22m�[2m37 tests�[22m�[2m)�[22m�[33m 581�[2mms�[22m�[39m
�[32m✓�[39m tests/comment-e2e-normalization.test.ts �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[33m 494�[2mms�[22m�[39m
�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1l�>�[?12l�[?25h�[H�[2J�[?1049l�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1l�>�[?12l�[?25h�[H�[2J�[?1049l�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1l�>�[?12l�[?25h�[H�[2J�[?1049l�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1l�>�[?12l�[?25h�[H�[2J�[?1049l�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1000h�[?1002h�Ptmux;��[?1003h�\�[?1005h�[?1l�>�[?12l�[?25h�[H�[2J�[?1000l�[?1002l�Ptmux;��[?1003l�\�[?1005l�[?1049l�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1000h�[?1002h�Ptmux;��[?1003h�\�[?1005h�[?1l�>�[?12l�[?25h�[H�[2J�[?1000l�[?1002l�Ptmux;��[?1003l�\�[?1005l�[?1049l�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1000h�[?1002h�Ptmux;��[?1003h�\�[?1005h�[?1l�>�[?12l�[?25h�[H�[2J�[?1000l�[?1002l�Ptmux;��[?1003l�\�[?1005l�[?1049l �[32m✓�[39m test/throttler.test.ts �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[33m 519�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m refills tokens over time according to rate �[33m 502�[2mms�[22m�[39m
�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1l�>�[?12l�[?25h�[H�[2J�[?1049l�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1000h�[?1002h�Ptmux;��[?1003h�\�[?1005h�[?1l�>�[?12l�[?25h�[H�[2J�[?1000l�[?1002l�Ptmux;��[?1003l�\�[?1005l�[?1049l �[32m✓�[39m tests/tui/tui-mouse-guard.test.ts �[2m(�[22m�[2m20 tests�[22m�[2m)�[22m�[33m 516�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/opencode-integration.test.ts �[2m(�[22m�[2m16 tests�[22m�[2m)�[22m�[33m 527�[2mms�[22m�[39m
�[32m✓�[39m tests/cli/initialization-check.test.ts �[2m(�[22m�[2m15 tests�[22m�[2m)�[22m�[33m 672�[2mms�[22m�[39m
�[32m✓�[39m tests/cli/show-json-audit.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[33m 391�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m includes structured audit object when audit present and omits when absent �[33m 388�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/spawn-impl.test.ts �[2m(�[22m�[2m2 tests�[22m�[2m)�[22m�[33m 407�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m uses injected spawnImpl in runNextWorkItems instead of raw spawn �[33m 373�[2mms�[22m�[39m
�[32m✓�[39m tests/validator.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[33m 411�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m validator script exits zero and prints OK �[33m 408�[2mms�[22m�[39m
�[32m✓�[39m tests/cli/create-description-file.test.ts �[2m(�[22m�[2m2 tests�[22m�[2m)�[22m�[33m 405�[2mms�[22m�[39m
�[32m✓�[39m tests/cli/doctor-prune.test.ts �[2m(�[22m�[2m2 tests�[22m�[2m)�[22m�[33m 414�[2mms�[22m�[39m
�[32m✓�[39m tests/cli/init.test.ts �[2m(�[22m�[2m7 tests�[22m�[2m)�[22m�[33m 10079�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should insert the AGENTS.md pointer line when an existing file is present �[33m 1090�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should not duplicate the AGENTS.md pointer line on re-run �[33m 1135�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should create semaphore when config exists but semaphore does not �[33m 1076�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should allow init command without initialization �[33m 1007�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should sync remote work items on init in new checkout �[33m 2236�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should place .worklog in main repo when initializing �[33m 1432�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should find main repo .worklog when in subdirectory �[33m 2099�[2mms�[22m�[39m
�[32m✓�[39m tests/cli/smoke.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[33m 363�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m dist CLI loads without syntax errors and prints version �[33m 360�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/copy-id.test.ts �[2m(�[22m�[2m6 tests�[22m�[2m)�[22m�[33m 377�[2mms�[22m�[39m
�[32m✓�[39m tests/cli/github-push-timestamp.test.ts �[2m(�[22m�[2m2 tests�[22m�[2m)�[22m�[33m 327�[2mms�[22m�[39m
�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1000h�[?1002h�[?1005h�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1000h�[?1002h�[?1005h�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1000h�[?1002h�[?1005h�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1000h�[?1002h�[?1005h�Ptmux;��]0;Worklog TUI��\�Ptmux;��[?1003h�\�Ptmux;��]0;Worklog TUI��\�Ptmux;��[?1003h�\�Ptmux;��]0;Worklog TUI��\�Ptmux;��[?1003h�\ �[32m✓�[39m tests/tui/layout.test.ts �[2m(�[22m�[2m16 tests�[22m�[2m)�[22m�[33m 385�[2mms�[22m�[39m
�[?1l�>�[?12l�[?25h�[H�[2J�[?1000l�[?1002l�Ptmux;��[?1003l�\�[?1005l�[?1049l�[?1l�>�[?12l�[?25h�[H�[2J�[?1000l�[?1002l�Ptmux;��[?1003l�\�[?1005l�[?1049l�[?1l�>�[?12l�[?25h�[H�[2J�[?1000l�[?1002l�Ptmux;��[?1003l�\�[?1005l�[?1049l�[?1l�>�[?12l�[?25h�[H�[2J�[?1000l�[?1002l�Ptmux;��[?1003l�\�[?1005l�[?1049l �[32m✓�[39m tests/grouping.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[33m 352�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m prints commands under the expected groups in order �[33m 349�[2mms�[22m�[39m
�[32m✓�[39m tests/integration/github-throttler-concurrency.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[33m 375�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m limits concurrent GitHub API calls to WL_GITHUB_CONCURRENCY �[33m 372�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/filter.test.ts �[2m(�[22m�[2m2 tests�[22m�[2m)�[22m�[33m 367�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m opens modal and cancel returns focus to list �[33m 348�[2mms�[22m�[39m
�[32m✓�[39m test/migrations.test.ts �[2m(�[22m�[2m2 tests�[22m�[2m)�[22m�[32m 263�[2mms�[22m�[39m
�[32m✓�[39m test/tui-opencode-integration.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[33m 315�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m wires autocomplete on the textarea and accepts suggestion on Enter �[33m 312�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/controller.test.ts �[2m(�[22m�[2m8 tests�[22m�[2m)�[22m�[32m 285�[2mms�[22m�[39m
�[32m✓�[39m tests/cli/human-show-list-audit-snapshots.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[33m 338�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m renders concise/list and single-item human outputs with and without audit (snapshots) �[33m 334�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/tui-github-metadata.test.ts �[2m(�[22m�[2m16 tests�[22m�[2m)�[22m�[33m 354�[2mms�[22m�[39m
�[90mstdout�[2m | tests/debug/update-debug.test.ts�[2m > �[22m�[2mdebug update with description-file
�[22m�[39mCREATE STDOUT:
{
"success": true,
"workItem": {
"id": "DBG-0MO6G6EQ20006JMW",
"title": "To update",
"description": "",
"status": "open",
"priority": "medium",
"sortIndex": 100,
"parentId": null,
"createdAt": "2026-04-20T00:19:16.106Z",
"updatedAt": "2026-04-20T00:19:16.106Z",
"tags": [],
"assignee": "",
"stage": "idea",
"issueType": "",
"createdBy": "",
"deletedBy": "",
"deleteReason": "",
"risk": "",
"effort": "",
"needsProducerReview": false
}
}

CREATE STDERR:
Invalid config: statusStageCompatibility for status "open" references unknown stage "idea"

�[90mstdout�[2m | tests/debug/update-debug.test.ts�[2m > �[22m�[2mdebug update with description-file
�[22m�[39mUPDATE STDOUT:
{
"success": true,
"workItem": {
"id": "DBG-0MO6G6EQ20006JMW",
"title": "To update",
"description": "Debug desc",
"status": "open",
"priority": "medium",
"sortIndex": 100,
"parentId": null,
"createdAt": "2026-04-20T00:19:16.106Z",
"updatedAt": "2026-04-20T00:19:16.186Z",
"tags": [],
"assignee": "",
"stage": "idea",
"issueType": "",
"createdBy": "",
"deletedBy": "",
"deleteReason": "",
"risk": "",
"effort": "",
"needsProducerReview": false
}
}

UPDATE STDERR:
Invalid config: statusStageCompatibility for status "open" references unknown stage "idea"

�[32m✓�[39m tests/tui/copilot-filter.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[33m 317�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m filters to items assigned to @github-copilot �[33m 314�[2mms�[22m�[39m
�[32m✓�[39m tests/debug/update-debug.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[32m 245�[2mms�[22m�[39m
�[32m✓�[39m tests/cli/github-pre-filter-fallback.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[32m 165�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/focus-cycling-integration.test.ts �[2m(�[22m�[2m10 tests�[22m�[2m)�[22m�[33m 321�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/persistence-integration.test.ts �[2m(�[22m�[2m7 tests�[22m�[2m)�[22m�[32m 246�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/next-dialog-wrap.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[33m 317�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m enables wrapping for the next dialog text �[33m 314�[2mms�[22m�[39m
�[32m✓�[39m tests/sort-operations.test.ts �[2m(�[22m�[2m40 tests�[22m�[2m)�[22m�[33m 12745�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should handle 500 items efficiently �[33m 918�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should handle 500 items per hierarchy level �[33m 914�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should reindex 500 items efficiently �[33m 1268�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should handle 1000 items efficiently �[33m 1731�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should handle 1000 items per hierarchy level �[33m 1900�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should reindex 500 items efficiently �[33m 1318�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should find next item efficiently with 500 items �[33m 903�[2mms�[22m�[39m
�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1000h�[?1002h�[?1005h�Ptmux;��]0;test��\�Ptmux;��[?1003h�\ �[32m✓�[39m tests/tui/widget-create-destroy.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[32m 271�[2mms�[22m�[39m
�[?1l�>�[?12l�[?25h�[H�[2J�[?1000l�[?1002l�Ptmux;��[?1003l�\�[?1005l�[?1049l �[32m✓�[39m tests/computeScore.debug.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[32m 148�[2mms�[22m�[39m
�[32m✓�[39m tests/computeScore.nonstack.unit.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[32m 130�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/opencode-layout-integration.test.ts �[2m(�[22m�[2m8 tests�[22m�[2m)�[22m�[32m 238�[2mms�[22m�[39m
�[?1049h�[?1h�=�[1;1r�[?25l�[1;1H�[H�[2J�[?1000h�[?1002h�[?1005h�7�[1;1H�[1;40;37mP�[m�8�7�[1;1H �8�7�[1;1H�[1;40;37mP�[m�8�7�[1;1H �8�7�[1;1H�[1;40;37mP�[m�8�7�[1;1H �8�7�[1;1H�[1;40;37mP�[m�8�7�[1;1H �8�7�[1;1H�[1;40;37mP�[m�8�7�[1;1H �8�7�[1;1H�[1;40;37mP�[m�8�7�[1;1H �8�7�[1;1H�[1;40;37mP�[m�8�7�[1;1H �8�7�[1;1H�[1;40;37mP�[m�8�7�[1;1H �8�7�[1;1H�[1;40;37mP�[m�8�7�[1;1H �8�7�[1;1H�[1;40;37mP�[m�8�7�[1;1H �8�7�[1;1H�[1;40;37mP�[m�8�7�[1;1H �8�7�[1;1H�[1;40;37mP�[m�8�7�[1;1H �8�7�[1;1H�[1;40;37mP�[m�8�7�[1;1H �8�7�[1;1H�[1;40;37mP�[m�8�7�[1;1H �8�7�[1;1H�[1;40;37mP�[m�8�7�[1;1H �8�7�[1;1H�[1;40;37mP�[m�8�7�[1;1H �8�7�[1;1H�[1;40;37mP�[m�8�7�[1;1H �8�7�[1;1H�[1;40;37mP�[m�8�7�[1;1H �8�7�[1;1H�[1;40;37mP�[m�8�7�[1;1H �8�7�[1;1H�[1;40;37mP�[m�8�7�[1;1H �8�7�[1;1H�[1;40;37mP�[m�8�7�[1;1H �8�7�[1;1H�[1;40;37mP�[m�8�7�[1;1H �8�7�[1;1H�[1;40;37mP�[m�8�7�[1;1H �8�7�[1;1H�[1;40;37mP�[m�8�7�[1;1H �8�7�[1;1H�[1;40;37mP�[m�8�7�[1;1H �8�7�[1;1H�[1;40;37mP�[m�8�7�[1;1H �8�7�[1;1H�[1;40;37mP�[m�8�7�[1;1H �8�7�[1;1H�[1;40;37mP�[m�8�7�[1;1H �8�7�[1;1H�[1;40;37mP�[m�8�7�[1;1H �8�7�[1;1H�[1;40;37mP�[m�8�7�[1;1H �8�Ptmux;��]0;test��\�Ptmux;��[?1003h�\ �[32m✓�[39m tests/tui/widget-create-destroy-others.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[32m 218�[2mms�[22m�[39m
�[?1l�>�[?12l�[?25h�[H�[2J�[?1000l�[?1002l�Ptmux;��[?1003l�\�[?1005l�[?1049l �[32m✓�[39m test/comment-update.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[32m 151�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/tui-50-50-layout.test.ts �[2m(�[22m�[2m9 tests�[22m�[2m)�[22m�[32m 216�[2mms�[22m�[39m
�[32m✓�[39m tests/cli/inproc-harness.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[32m 238�[2mms�[22m�[39m
�[32m✓�[39m tests/integration/audit-roundtrip.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[32m 225�[2mms�[22m�[39m
�[32m✓�[39m tests/cli/throttler-tokenbucket.test.ts �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[32m 136�[2mms�[22m�[39m
�[32m✓�[39m tests/cli/misc.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[32m 148�[2mms�[22m�[39m
�[32m✓�[39m tests/cli/git-mock-roundtrip.test.ts �[2m(�[22m�[2m2 tests�[22m�[2m)�[22m�[32m 103�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/create-dialog-input-regression.test.ts �[2m(�[22m�[2m2 tests�[22m�[2m)�[22m�[32m 157�[2mms�[22m�[39m
�[32m✓�[39m tests/computeScore.nonstack.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[32m 140�[2mms�[22m�[39m
�[32m✓�[39m test/tui-opencode-sse-handler.test.ts �[2m(�[22m�[2m14 tests�[22m�[2m)�[22m�[32m 116�[2mms�[22m�[39m
�[32m✓�[39m tests/cli/issue-status.test.ts �[2m(�[22m�[2m50 tests�[22m�[2m)�[22m�[33m 12402�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should display work item with children in tree format in non-JSON mode �[33m 372�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should preserve stale sortIndex order with --no-re-sort flag �[33m 346�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should list in-progress work items in JSON mode �[33m 422�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should filter by assignee �[33m 361�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should filter search results by --assignee �[33m 330�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should filter search results by --issue-type �[33m 313�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should filter search results by --stage �[33m 318�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should output human-readable format without --json �[33m 315�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should filter search results by --needs-producer-review true �[33m 544�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should default --needs-producer-review to true when value omitted �[33m 548�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should filter search results by --needs-producer-review false �[33m 472�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should accept "yes" as true for --needs-producer-review �[33m 435�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should accept "no" as false for --needs-producer-review �[33m 449�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should error for invalid --needs-producer-review value �[33m 464�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/tui-mouse-select.test.ts �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[32m 144�[2mms�[22m�[39m
�[32m✓�[39m tests/jsonl.test.ts �[2m(�[22m�[2m13 tests�[22m�[2m)�[22m�[32m 147�[2mms�[22m�[39m
�[32m✓�[39m test/tui-chords.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[32m 89�[2mms�[22m�[39m
�[32m✓�[39m tests/github-push-state.test.ts �[2m(�[22m�[2m18 tests�[22m�[2m)�[22m�[32m 81�[2mms�[22m�[39m
�[32m✓�[39m tests/cli/unlock.test.ts �[2m(�[22m�[2m10 tests�[22m�[2m)�[22m�[32m 103�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/opencode-prompt-input.test.ts �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[32m 132�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/opencode-triple-keypress.repro.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[32m 84�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/dialog-integration.test.ts �[2m(�[22m�[2m2 tests�[22m�[2m)�[22m�[32m 124�[2mms�[22m�[39m
�[32m✓�[39m tests/github-import-label-resolution.test.ts �[2m(�[22m�[2m27 tests�[22m�[2m)�[22m�[32m 68�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/dialog-focus-cycling-extended.test.ts �[2m(�[22m�[2m2 tests�[22m�[2m)�[22m�[32m 89�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/opencode-activity.test.ts �[2m(�[22m�[2m5 tests�[22m�[2m)�[22m�[32m 77�[2mms�[22m�[39m
�[32m✓�[39m tests/github-sync-deleted.test.ts �[2m(�[22m�[2m10 tests�[22m�[2m)�[22m�[32m 37�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/tui-detail-scroll-preserve.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[32m 62�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/audit-termination.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[32m 64�[2mms�[22m�[39m
�[32m✓�[39m tests/github-sync-comments.test.ts �[2m(�[22m�[2m7 tests�[22m�[2m)�[22m�[32m 33�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/perf.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[32m 38�[2mms�[22m�[39m
�[32m✓�[39m tests/unit/openbrain.test.ts �[2m(�[22m�[2m17 tests�[22m�[2m)�[22m�[32m 42�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/clipboard.test.ts �[2m(�[22m�[2m20 tests�[22m�[2m)�[22m�[32m 46�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/reorder-shortcuts.test.ts �[2m(�[22m�[2m2 tests�[22m�[2m)�[22m�[32m 48�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/event-cleanup.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[32m 47�[2mms�[22m�[39m
�[32m✓�[39m tests/github-pre-filter.test.ts �[2m(�[22m�[2m35 tests�[22m�[2m)�[22m�[32m 26�[2mms�[22m�[39m
�[32m✓�[39m tests/github-sync-output.test.ts �[2m(�[22m�[2m9 tests�[22m�[2m)�[22m�[32m 29�[2mms�[22m�[39m
�[32m✓�[39m tests/github-label-categories.test.ts �[2m(�[22m�[2m42 tests�[22m�[2m)�[22m�[32m 45�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/incremental-rendering.test.ts �[2m(�[22m�[2m12 tests�[22m�[2m)�[22m�[32m 32�[2mms�[22m�[39m
�[32m✓�[39m tests/unit/human-audit-format.test.ts �[2m(�[22m�[2m2 tests�[22m�[2m)�[22m�[32m 22�[2mms�[22m�[39m
�[32m✓�[39m tests/cli/delegate-guard-rails.test.ts �[2m(�[22m�[2m16 tests�[22m�[2m)�[22m�[32m 37�[2mms�[22m�[39m
�[32m✓�[39m tests/lib/github-helper.test.ts �[2m(�[22m�[2m23 tests�[22m�[2m)�[22m�[32m 42�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/toggle-do-not-delegate.test.ts �[2m(�[22m�[2m2 tests�[22m�[2m)�[22m�[32m 51�[2mms�[22m�[39m
�[32m✓�[39m test/tui/virtual-list.test.ts �[2m(�[22m�[2m27 tests�[22m�[2m)�[22m�[32m 24�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/move-mode.test.ts �[2m(�[22m�[2m12 tests�[22m�[2m)�[22m�[32m 29�[2mms�[22m�[39m
�[32m✓�[39m tests/unit/audit-readiness.test.ts �[2m(�[22m�[2m3 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/opencode-session-selection.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[32m 28�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/textarea-helper.test.ts �[2m(�[22m�[2m2 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m
�[32m✓�[39m tests/sync.test.ts �[2m(�[22m�[2m20 tests�[22m�[2m | �[22m�[33m1 skipped�[39m�[2m)�[22m�[32m 27�[2mms�[22m�[39m
�[90mstdout�[2m | tests/cli/reviewed.test.ts�[2m > �[22m�[2mreviewed command�[2m > �[22m�[2mtoggles needsProducerReview when value omitted
�[22m�[39mneedsProducerReview set to true for WL-TEST-1

�[90mstdout�[2m | tests/cli/reviewed.test.ts�[2m > �[22m�[2mreviewed command�[2m > �[22m�[2msets needsProducerReview when value provided
�[22m�[39mneedsProducerReview set to true for WL-TEST-1

�[90mstdout�[2m | tests/cli/reviewed.test.ts�[2m > �[22m�[2mreviewed command�[2m > �[22m�[2msets needsProducerReview when value provided
�[22m�[39mneedsProducerReview set to false for WL-TEST-1

�[32m✓�[39m tests/cli/reviewed.test.ts �[2m(�[22m�[2m2 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m
�[32m✓�[39m tests/github-comment-import-push.test.ts �[2m(�[22m�[2m7 tests�[22m�[2m)�[22m�[32m 35�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/autocomplete-widget.test.ts �[2m(�[22m�[2m2 tests�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/state.test.ts �[2m(�[22m�[2m7 tests�[22m�[2m)�[22m�[32m 26�[2mms�[22m�[39m
�[90mstdout�[2m | tests/cli/update-do-not-delegate.test.ts�[2m > �[22m�[2mupdate --do-not-delegate�[2m > �[22m�[2madds the tag when true
�[22m�[39mUpdated work item:
Sample WL-TEST-1
Status: Open · Stage: Undefined | Priority: medium
SortIndex: 0
Risk: —
Effort: —
Tags: do-not-delegate

�[90mstdout�[2m | tests/cli/update-do-not-delegate.test.ts�[2m > �[22m�[2mupdate --do-not-delegate�[2m > �[22m�[2mremoves the tag when false
�[22m�[39mUpdated work item:
Sample WL-TEST-1
Status: Open · Stage: Undefined | Priority: medium
SortIndex: 0
Risk: —
Effort: —

�[32m✓�[39m tests/cli/update-do-not-delegate.test.ts �[2m(�[22m�[2m2 tests�[22m�[2m)�[22m�[32m 27�[2mms�[22m�[39m
�[32m✓�[39m tests/github-label-resolution.test.ts �[2m(�[22m�[2m16 tests�[22m�[2m)�[22m�[32m 20�[2mms�[22m�[39m
�[32m✓�[39m tests/opencode-audit.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[32m 21�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/opencode-sse.test.ts �[2m(�[22m�[2m6 tests�[22m�[2m)�[22m�[32m 21�[2mms�[22m�[39m
�[32m✓�[39m test/doctor-status-stage.test.ts �[2m(�[22m�[2m5 tests�[22m�[2m)�[22m�[32m 12�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/opencode-client.test.ts �[2m(�[22m�[2m2 tests�[22m�[2m)�[22m�[32m 19�[2mms�[22m�[39m
�[32m✓�[39m tests/cli/issue-management.test.ts �[2m(�[22m�[2m49 tests�[22m�[2m)�[22m�[33m 14355�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should apply flags to all provided ids �[33m 399�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should return per-id results in batch JSON output �[33m 351�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should continue processing after a failure for one id �[33m 386�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should exit non-zero when any id fails in batch �[33m 389�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should handle all invalid ids gracefully �[33m 371�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should handle status/stage conflict for one id without stopping others �[33m 416�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should preserve legacy single-id JSON shape for single id �[33m 438�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should remove a dependency edge �[33m 342�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should unblock dependents when a blocking item is closed �[33m 459�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should unblock dependents when a blocking item is deleted �[33m 396�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should re-block dependents when a closed blocker is reopened �[33m 521�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should keep dependent blocked when only one of multiple blockers is closed �[33m 526�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should unblock dependent when all blockers are closed �[33m 541�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should handle chain dependencies: close A unblocks B but C stays blocked �[33m 698�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should unblock multiple dependents when shared blocker is closed �[33m 570�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should close with reason and still unblock dependents �[33m 366�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should list dependency edges �[33m 436�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should list outbound-only dependency edges �[33m 345�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should list inbound-only dependency edges �[33m 352�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should unblock dependent when sole blocker moves to in_review stage via update �[33m 346�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should keep dependent blocked when only one of multiple blockers moves to in_review �[33m 476�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should unblock dependent when all blockers move to in_review �[33m 583�[2mms�[22m�[39m
�[32m✓�[39m tests/cli/throttler-github-sync.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[32m 11�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/status-stage-validation.test.ts �[2m(�[22m�[2m8 tests�[22m�[2m)�[22m�[32m 13�[2mms�[22m�[39m
�[32m✓�[39m test/tui-style.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[32m 11�[2mms�[22m�[39m
�[32m✓�[39m tests/github-sync-rate-limit.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[32m 12�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/tui-state.test.ts �[2m(�[22m�[2m6 tests�[22m�[2m)�[22m�[32m 22�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/bench-expand.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[32m 10�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/persistence.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[32m 12�[2mms�[22m�[39m
�[32m✓�[39m tests/cli/throttler-schedule-spy.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[32m 12�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/dialog-focus.test.ts �[2m(�[22m�[2m2 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m
�[32m✓�[39m tests/unit/markdown-renderer.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[32m 12�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/updatePane-delta.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m
�[32m✓�[39m tests/cli/action-opts-normalization.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[32m 9�[2mms�[22m�[39m
�[32m✓�[39m test/tui/id-utils.test.ts �[2m(�[22m�[2m7 tests�[22m�[2m)�[22m�[32m 23�[2mms�[22m�[39m
�[32m✓�[39m tests/github-sync-self-link.test.ts �[2m(�[22m�[2m2 tests�[22m�[2m)�[22m�[32m 21�[2mms�[22m�[39m
�[32m✓�[39m tests/audit.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[32m 17�[2mms�[22m�[39m
�[32m✓�[39m test/doctor-dependency-check.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[32m 13�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/shutdown-flow.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m
�[32m✓�[39m tests/unit/audit-redaction.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/autocomplete.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[32m 7�[2mms�[22m�[39m
�[2m�[90m↓�[39m�[22m tests/github-sync-load.long.test.ts �[2m(�[22m�[2m1 test�[22m�[2m | �[22m�[33m1 skipped�[39m�[2m)�[22m
�[32m✓�[39m tests/tui/markdown-detail-rendering.test.ts �[2m(�[22m�[2m1 test�[22m�[2m)�[22m�[32m 6�[2mms�[22m�[39m
�[32m✓�[39m tests/tui/composing-blankline.test.ts �[2m(�[22m�[2m2 tests�[22m�[2m)�[22m�[32m 8�[2mms�[22m�[39m
�[2m�[90m↓�[39m�[22m tests/lockless-reads.test.ts �[2m(�[22m�[2m1 test�[22m�[2m | �[22m�[33m1 skipped�[39m�[2m)�[22m
�[32m✓�[39m tests/database.test.ts �[2m(�[22m�[2m152 tests�[22m�[2m | �[22m�[33m3 skipped�[39m�[2m)�[22m�[33m 16938�[2mms�[22m�[39m
�[32m✓�[39m tests/file-lock.test.ts �[2m(�[22m�[2m73 tests�[22m�[2m)�[22m�[33m 24574�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should respect the timeout option �[33m 305�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should recover from corrupted lock file with garbage content �[33m 1590�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should recover from an empty lock file (0 bytes) �[33m 3611�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should use increasing delays between retry attempts �[33m 2003�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should cap delay at maxRetryDelay �[33m 5003�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should add jitter within 0-25% of base delay �[33m 5003�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should serialize writes across multiple processes (no lost increments) �[33m 1118�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should serialize writes when workers run concurrently (parallel spawn) �[33m 936�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m should log stale lock cleanup reason when lock is corrupted �[33m 2373�[2mms�[22m�[39m

�[2m Test Files �[22m �[1m�[32m146 passed�[39m�[22m�[2m | �[22m�[33m2 skipped�[39m�[90m (148)�[39m
�[2m Tests �[22m �[1m�[32m1482 passed�[39m�[22m�[2m | �[22m�[33m9 skipped�[39m�[90m (1491)�[39m
�[2m Start at �[22m 17:19:02
�[2m Duration �[22m 25.48s�[2m (transform 17.14s, setup 2.61s, import 46.87s, tests 176.64s, environment 36ms)�[22m - all tests pass.

Manual test: Open TUI on terminals of different heights (24, 40, 60 lines) and verify:

  • Tree is never less than 7 lines
  • Tree is never more than 14 lines
  • Description fills remaining space

Files Changed

    • added MIN_TREE_HEIGHT, MAX_TREE_HEIGHT
    • added setHeight method
    • added setHeightAndTop method
    • added updateLayoutHeights and resize handler
    • added unit tests

Closes WL-0MMJ927NG14R0NES

Sorra added 7 commits April 19, 2026 16:10
…s, and add CLI needs-producer-review yes/no parsing tests
…C3H5)

- Add 6 test cases for search command --needs-producer-review flag
- Tests cover true/false/yes/no values, default behavior, and invalid input
- Tests verify filtering works correctly with SQLite-backed search
…in TUI layout

- Add MIN_TREE_HEIGHT (7) and MAX_TREE_HEIGHT (14) constants
- Add setHeight method to ListComponent for dynamic resizing
- Add setHeightAndTop method to DetailComponent for dynamic resizing
- Implement updateLayoutHeights function in controller that clamps
  preferred tree height to [7, 14] range and allocates remaining
  space to description pane
- Add resize event handler to re-compute layout on terminal resize
- Add unit tests for constants and new component methods

This change improves the TUI layout by:
- Ensuring the work item tree is always at least 7 lines for navigation context
- Capping the tree at 14 lines so description is always visible
- Allowing the description pane to take more space for long content
- Maintaining cross-platform terminal compatibility
- Add setHeight method to MetadataPaneComponent
- Update updateLayoutHeights in controller to also resize
  metadata pane to match tree height
- Add unit test for MetadataPaneComponent.setHeight

This ensures the metadata pane (top-right) scales correctly
when the work item tree is clamped to 7-14 lines.
@SorraTheOrc
Copy link
Copy Markdown
Member Author

All CI checks are passing

This PR is ready for review.

Posted automatically by AMPA PR Monitor.

1 similar comment
@SorraTheOrc
Copy link
Copy Markdown
Member Author

All CI checks are passing

This PR is ready for review.

Posted automatically by AMPA PR Monitor.

…ormat to full

- Add src/cli-output.ts: CLI integration layer for markdown rendering
- Add --format markdown CLI option (default in TTY, opt-out with --format text)
- Add ctx.markdown to PluginContext for command use
- Add unit tests for cli-output module
- Change default format from concise to full
- Add --format summary for minimal output (title + status only)
- Update CLI.md documentation
- Update config defaults to humanDisplay: full

Closes WL-0MNMEDEMF001XB34
@SorraTheOrc SorraTheOrc merged commit 2a68e22 into main Apr 20, 2026
4 checks passed
@SorraTheOrc SorraTheOrc deleted the feature/WL-0MMJ927NG14R0NES-tui-layout branch April 28, 2026 18:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant