Constrain PickerMenu description width to the terminal's real width - #987
Closed
Ref34t wants to merge 3 commits into
Closed
Constrain PickerMenu description width to the terminal's real width#987Ref34t wants to merge 3 commits into
Ref34t wants to merge 3 commits into
Conversation
The wizard had no way to recognize a WordPress project, so `npx @posthog/wizard` in a WordPress directory detected nothing and fell through to the Node fallback whenever a theme build had left a package.json behind. - `Integration.wordpress`, ordered after laravel and before the language fallbacks, so a site with a theme package.json resolves to WordPress - `src/frameworks/wordpress/` — a FrameworkConfig following the shape in .claude/skills/adding-framework-support, with composer package management and no package.json checks - detection covers the four real shapes: an installed site (wp-config.php, wp-load.php, wp-includes/version.php), unpacked core before install (wp-config-sample.php), a Composer-managed install where core is not in the root (roots/wordpress, johnpbloch/wordpress, wpackagist-*), and a standalone plugin or theme directory identified by its `Plugin Name:` / `Theme Name:` header - context gathering reports project type, plugins directory (including Bedrock's web/app/plugins), and an existing plugin entry file so the agent extends that plugin instead of creating a second one - prompts carry the WordPress-specific rules: plugin over functions.php, ABSPATH guard, esc_js on the token, client SDK for pageviews and the PHP SDK for server-side actions, flush after capture - version read from $wp_version in wp-includes/version.php, bucketed as 6.4.x - 9 detection tests, including the negative cases (a Laravel project and a plain Composer PHP project must not be claimed) Depends on PostHog/context-mill#279, which adds the matching `integration-wordpress` variant with `framework: wordpress`. The pinned skill-menu fixture in variant-resolution.test.ts is updated to match — without that variant released, the cross-repo contract test fails for wordpress. pnpm build, pnpm test (1576 passing), pnpm fix — all clean.
The prompt lines about shipping a plugin instead of editing functions.php, the ABSPATH guard, esc_js on the token, and flushing after capture are all in the wordpress block of context-mill's commandments.yaml, which reaches the agent with the skill. Repeating them here duplicates integration knowledge across the boundary AGENTS.md draws between the two repos, and would drift the moment either side is edited. getAdditionalContextLines now carries only what the skill cannot know: the project shape this run is pointed at. pnpm build, pnpm test (1576 passing), pnpm fix — clean.
Multi-select options with a description wrapped that text in a Box fixed at 56 columns, regardless of the actual terminal width. On a narrow terminal this let the row render wider than the physical screen, and the terminal's own line-wrapping (which Ink doesn't control) then misaligned Ink's cursor bookkeeping for every row after it, producing overlapping/corrupted text. Reads the live terminal width via Ink's useStdout() and clamps the description width to it (floor 20, cap 56 — the original constant, kept as an upper bound), accounting for the outer margin, grid columns, and the description's own indent. Adds a regression test that drives real Ink renders at several terminal widths by patching ink-testing-library's Stdout prototype, since the library hardcodes 100 columns with no override. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #986.
The bug
Multi-select options with a
descriptionwrapped that text in aBoxfixed atwidth={56}, regardless of the actual terminal width. On a narrow terminal this let the row render wider than the physical screen. The terminal's own line-wrapping (which Ink doesn't control) then misaligned Ink's cursor bookkeeping for every row after it — producing the overlapping/corrupted text in #986: checkbox labels merging into their descriptions (No+Skip custom scouts...→NoSkip custom scouts...), the Confirm button overlapping the last option's wrapped tail, and — on a second checklist in the same run — fragments of multiple different tool names bleeding together (FrillrebaseghtVMreads like "Frill" + "Firebase" + something ending "...VM" overlapping).How I found it
Reproduced headlessly with
ink-testing-library, patching itsStdoutprototype to drive real widths (100 → 40 columns) since the library hardcodes 100 columns with no override. Themessagetext reflowed correctly at every width; the description did not — identical wrap points from 100 down to 40 columns, confirming the fixed width never adapted.The fix
descriptionWidth()inPickerMenu.tsxreads the live terminal width via Ink'suseStdout()and clamps to it — floor of 20 characters, cap of 56 (the original constant, kept as an upper bound on wide terminals), accounting for the outer margin, the per-column share when the grid has more than one column, and the description's own indent.Verified the fix directly: re-ran the same headless harness after the change — longest rendered line now tracks the terminal width exactly (100 cols → 62, 60 cols → 60, 40 cols → 40), instead of staying near-constant regardless of width.
Also found while investigating
PickerMenu(InputDemo.tsx) never exercises thedescriptionprop at all — the exact code path that broke had zero coverage in the one place built to catch this visually.ink-testing-libraryis a real devDependency but was unused anywhere in this repo before this fix. This is the first.tsxtest file —vitest.config.tswas already configured for it (esbuild: { jsx: 'automatic' }), just never exercised.Testing
pnpm build— clean, including smoke + warlock security testspnpm test— 1579/1579 passing (1576 existing + 3 new)pnpm lint— 0 errorssrc/ui/tui/primitives/__tests__/PickerMenu.test.tsx, using the same monkeypatch-the-Stdout-prototype technique used to find the bug, kept as a permanent regression testOpened as a draft — background on how this surfaced (a real self-driving run against a Laravel/Vue app, not a wizard-workbench fixture) is in #986.