Skip to content

Board UX fixes, intake dialog polish, and over-engineering cleanup - #25

Merged
aorumbayev merged 10 commits into
mainfrom
verifyx
Jul 21, 2026
Merged

Board UX fixes, intake dialog polish, and over-engineering cleanup#25
aorumbayev merged 10 commits into
mainfrom
verifyx

Conversation

@aorumbayev

Copy link
Copy Markdown
Member

Summary

Nine commits: board/intake UX fixes, complexity-gate restructuring, and a whole-codebase over-engineering cleanup (−299 net lines in the final commit, none touching user-visible behavior).

UX and fixes

  • Render intake gates as markdown two-column dialogs
  • Reliable board keyboard selection plus Tab cycling
  • Clearer intake decision action labels; Review menu leads with approve
  • Scrollable task details overflow
  • Tolerate trailing commas in OpenCode plugin config

Verification infrastructure

  • Gate src complexity before test support files; restore logic/TUI complexity tiers

Over-engineering cleanup (audit-driven)

  • Remove test-only DI seams (CreateTaskDependencies bag, createUpdateController optional deps); tests mock modules instead
  • Dedupe patch.ts lock/read/merge/update skeleton into one private helper, public API unchanged
  • Delete shellGitRunner; server uses bunGitRunner (now a const)
  • Board passes store down instead of drilling cap/sendBackStopThreshold/checkCommand through four component layers
  • Drop verified-dead code: setupCommand field, unused hook prop, test:ci script, dead dialog width sizes, oxfmt pass in install script
  • Delete redundant tests: update-launch.test.ts (re-implemented wiring locally), byte-identical duplicate gateBadges mode tests

Testing

  • bun run check clean (verifyx gates + package check against OpenCode 1.17.20 and 1.17.13)
  • 646 curated tests + 3 integration tests, 0 fail

🤖 Generated with Claude Code

aorumbayev and others added 9 commits July 17, 2026 01:24
Replace the logic/TUI two-tier split with src at MI 52 first and test/
support files at MI 40 second so the fast verify path scores all source
before slower test fixtures.

Co-authored-by: Cursor <cursoragent@cursor.com>
Score non-TUI logic at MI 52 and the TUI surface at 50, then fold artificial
verifyx micro-splits back into cohesive modules so the gate matches the
architecture instead of forcing file fragmentation.

Co-authored-by: Cursor <cursoragent@cursor.com>
Replace host DialogSelect/Prompt/Confirm for the intake chain so
assumptions, questions, and mode rationale are readable as markdown,
with short actions beside the body (answer step stays full-width stacked).

Co-authored-by: Cursor <cursoragent@cursor.com>
Hand-edited opencode.json often keeps a trailing comma; strict JSON
parse made plugin:install:prod fail with an opaque SyntaxError.

Co-authored-by: Cursor <cursoragent@cursor.com>
Keep selectedColumn synced with the highlighted card, auto-select on refresh, blur leftover host focus on open, and cycle root tasks with Tab/Shift+Tab.

Co-authored-by: Cursor <cursoragent@cursor.com>
Approve/Reject were ambiguous when a clarifying question was on screen; Accept assumption / Override with answer name the object of the choice.

Co-authored-by: Cursor <cursoragent@cursor.com>
- delete CreateTaskDependencies bag and createUpdateController's optional
  check/confirm/runCommand/now; tests mock modules instead
- dedupe patch.ts lock/read/merge/update skeleton into withKaganUpdate
- delete shellGitRunner; server uses bunGitRunner (now a const, not a factory)
- board passes store instead of drilling cap/sendBackStopThreshold/checkCommand
- inline buildEditorContext/listEditorSignals/listEditorDialogControls into hook
- drop dead code: setupCommand field, unused checkCommand hook prop, test:ci
  script, HOST_DIALOG_WIDTH size param, oxfmt pass in install-plugin
- fold eligible predicate into spawnHelper; store parses options once
- delete update-launch.test.ts (re-implemented wiring) and duplicate
  gateBadges mode tests; simplify git-shell fixture (preload already isolates)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Jul 21, 2026

Copy link
Copy Markdown

Greptile Summary

This PR streamlines the board and server code while polishing several TUI workflows. The main changes are:

  • Root-card cycling with Tab and more reliable board focus.
  • Markdown intake dialogs and scrollable task details.
  • Clearer Review and intake actions.
  • Consolidated server update, task creation, and git-runner code.
  • Trailing-comma support for installer-managed configuration.

Confidence Score: 4/5

The changed config parsing path can silently alter quoted values and needs a fix before merging.

Trailing-comma recovery operates on raw text rather than JSON tokens. A recoverable config can be parsed and saved with modified string data.

scripts/install-plugin.ts

T-Rex T-Rex Logs

What T-Rex did

  • Reproduced the fallback rewrite of a quoted value during the Bun installer reset path using a disposable XDG_CONFIG_HOME.
  • Observed that the trailing comma was tolerated and that the quoted value changed from "keep comma, } exactly" to "keep comma} exactly" during the update.
  • Ran runtime assertions to verify that the modified config parsed successfully and the plugin reset completed.
  • Inspected the UI-related proofs and confirmed the OpenTUI frame layout: Markdown occupies the left column, actions occupy the right column, the long question wraps inside the dialog, and interaction.enterApproved is true.

View all artifacts

T-Rex Ran code and verified through T-Rex

Important Files Changed

Filename Overview
scripts/install-plugin.ts Adds trailing-comma recovery, but the raw replacement can alter commas inside quoted values.
src/git/runner.ts Replaces the shell-backed git runner with a shared Bun runner and updates callers to use its value form.
src/server/session/patch.ts Consolidates serialized metadata updates while preserving fresh-read and merge behavior.
src/server/helpers/spawn.ts Consolidates helper eligibility and switches review git operations to the shared Bun runner.
src/tui/board/store/selection.ts Adds wrapped root-card navigation while retaining child-aware row selection.
src/tui/dialogs/task-details-view.tsx Keeps the task summary pinned and moves long detail sections into a bounded scroll area.

Fix All in Claude Code Fix All in Codex

Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
scripts/install-plugin.ts:30
**Fallback Rewrites Quoted Values**

When an invalid config has both a trailing comma and a quoted value containing `, }` or `, ]`, this raw-text replacement removes the comma inside the string as well. The second parse can then succeed and the installer writes back silently changed configuration data; trailing commas need to be removed with a string-aware scanner or JSONC parser.

Reviews (1): Last reviewed commit: "refactor: remove test-only DI seams and ..." | Re-trigger Greptile

Comment thread scripts/install-plugin.ts Outdated
} catch {
// hand-edited OpenCode configs often keep a trailing comma
try {
return JSON.parse(text.replace(/,\s*([}\]])/g, "$1")) as Record<string, unknown>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Fallback Rewrites Quoted Values

When an invalid config has both a trailing comma and a quoted value containing , } or , ], this raw-text replacement removes the comma inside the string as well. The second parse can then succeed and the installer writes back silently changed configuration data; trailing commas need to be removed with a string-aware scanner or JSONC parser.

Context Used: AGENTS.md (source)

Artifacts

Repro: executable harness invoking the actual installer reset path with a disposable config home

  • Contains supporting evidence from the run (text/x-shellscript; charset=utf-8).

Repro: input config containing both the quoted comma sequence and actual trailing comma

  • Contains supporting evidence from the run (application/json; charset=utf-8).

Repro: successful execution trace showing the original and silently modified quoted values

  • Keeps the command output available without making the summary code-heavy.

View artifacts

T-Rex Ran code and verified through T-Rex

Prompt To Fix With AI
This is a comment left during a code review.
Path: scripts/install-plugin.ts
Line: 30

Comment:
**Fallback Rewrites Quoted Values**

When an invalid config has both a trailing comma and a quoted value containing `, }` or `, ]`, this raw-text replacement removes the comma inside the string as well. The second parse can then succeed and the installer writes back silently changed configuration data; trailing commas need to be removed with a string-aware scanner or JSONC parser.

**Context Used:** AGENTS.md ([source](https://app.greptile.com/kagan/github/kagan-sh/kagan/-/custom-context?memory=88a14340-9a15-4297-925d-3656d144ad2a))

How can I resolve this? If you propose a fix, please make it concise.

Fix in Claude Code Fix in Codex

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 7a0669d — replaced the raw regex with a string-aware scanner that tracks quote/escape state, so , } / , ] inside quoted values are left untouched; only structural trailing commas are stripped.

Raw regex fallback also removed ", }" / ", ]" sequences inside quoted
config values, silently rewriting them on the reparse-and-write path.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@aorumbayev
aorumbayev merged commit 930a968 into main Jul 21, 2026
3 checks passed
@aorumbayev
aorumbayev deleted the verifyx branch July 21, 2026 14:53
aorumbayev added a commit that referenced this pull request Jul 21, 2026
* refactor: gate src complexity before test support files

Replace the logic/TUI two-tier split with src at MI 52 first and test/
support files at MI 40 second so the fast verify path scores all source
before slower test fixtures.

* refactor: restore logic/TUI complexity tiers and cohesive layout

Score non-TUI logic at MI 52 and the TUI surface at 50, then fold artificial
verifyx micro-splits back into cohesive modules so the gate matches the
architecture instead of forcing file fragmentation.

* feat: render intake gates with markdown two-column dialogs

Replace host DialogSelect/Prompt/Confirm for the intake chain so
assumptions, questions, and mode rationale are readable as markdown,
with short actions beside the body (answer step stays full-width stacked).

* fix: tolerate trailing commas in OpenCode plugin config

Hand-edited opencode.json often keeps a trailing comma; strict JSON
parse made plugin:install:prod fail with an opaque SyntaxError.

* fix: make board keyboard selection reliable and add Tab cycling

Keep selectedColumn synced with the highlighted card, auto-select on refresh, blur leftover host focus on open, and cycle root tasks with Tab/Shift+Tab.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: clarify intake decision action labels

Approve/Reject were ambiguous when a clarifying question was on screen; Accept assumption / Override with answer name the object of the choice.

* feat: lead Review menu with approve

* fix: scroll task details overflow

* refactor: remove test-only DI seams and dead flexibility

- delete CreateTaskDependencies bag and createUpdateController's optional
  check/confirm/runCommand/now; tests mock modules instead
- dedupe patch.ts lock/read/merge/update skeleton into withKaganUpdate
- delete shellGitRunner; server uses bunGitRunner (now a const, not a factory)
- board passes store instead of drilling cap/sendBackStopThreshold/checkCommand
- inline buildEditorContext/listEditorSignals/listEditorDialogControls into hook
- drop dead code: setupCommand field, unused checkCommand hook prop, test:ci
  script, HOST_DIALOG_WIDTH size param, oxfmt pass in install-plugin
- fold eligible predicate into spawnHelper; store parses options once
- delete update-launch.test.ts (re-implemented wiring) and duplicate
  gateBadges mode tests; simplify git-shell fixture (preload already isolates)

* fix: strip trailing commas with string-aware scanner

Raw regex fallback also removed ", }" / ", ]" sequences inside quoted
config values, silently rewriting them on the reparse-and-write path.
aorumbayev added a commit that referenced this pull request Jul 27, 2026
* Board UX fixes, intake dialog polish (#25)

* refactor: gate src complexity before test support files

Replace the logic/TUI two-tier split with src at MI 52 first and test/
support files at MI 40 second so the fast verify path scores all source
before slower test fixtures.

* refactor: restore logic/TUI complexity tiers and cohesive layout

Score non-TUI logic at MI 52 and the TUI surface at 50, then fold artificial
verifyx micro-splits back into cohesive modules so the gate matches the
architecture instead of forcing file fragmentation.

* feat: render intake gates with markdown two-column dialogs

Replace host DialogSelect/Prompt/Confirm for the intake chain so
assumptions, questions, and mode rationale are readable as markdown,
with short actions beside the body (answer step stays full-width stacked).

* fix: tolerate trailing commas in OpenCode plugin config

Hand-edited opencode.json often keeps a trailing comma; strict JSON
parse made plugin:install:prod fail with an opaque SyntaxError.

* fix: make board keyboard selection reliable and add Tab cycling

Keep selectedColumn synced with the highlighted card, auto-select on refresh, blur leftover host focus on open, and cycle root tasks with Tab/Shift+Tab.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: clarify intake decision action labels

Approve/Reject were ambiguous when a clarifying question was on screen; Accept assumption / Override with answer name the object of the choice.

* feat: lead Review menu with approve

* fix: scroll task details overflow

* refactor: remove test-only DI seams and dead flexibility

- delete CreateTaskDependencies bag and createUpdateController's optional
  check/confirm/runCommand/now; tests mock modules instead
- dedupe patch.ts lock/read/merge/update skeleton into withKaganUpdate
- delete shellGitRunner; server uses bunGitRunner (now a const, not a factory)
- board passes store instead of drilling cap/sendBackStopThreshold/checkCommand
- inline buildEditorContext/listEditorSignals/listEditorDialogControls into hook
- drop dead code: setupCommand field, unused checkCommand hook prop, test:ci
  script, HOST_DIALOG_WIDTH size param, oxfmt pass in install-plugin
- fold eligible predicate into spawnHelper; store parses options once
- delete update-launch.test.ts (re-implemented wiring) and duplicate
  gateBadges mode tests; simplify git-shell fixture (preload already isolates)

* fix: strip trailing commas with string-aware scanner

Raw regex fallback also removed ", }" / ", ]" sequences inside quoted
config values, silently rewriting them on the reparse-and-write path.

* build(deps-dev): bump @types/bun from 1.3.13 to 1.3.14

Bumps [@types/bun](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/bun) from 1.3.13 to 1.3.14.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/bun)

---
updated-dependencies:
- dependency-name: "@types/bun"
  dependency-version: 1.3.14
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Al <7698600+aorumbayev@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
aorumbayev added a commit that referenced this pull request Jul 27, 2026
* Board UX fixes, intake dialog polish (#25)

* refactor: gate src complexity before test support files

Replace the logic/TUI two-tier split with src at MI 52 first and test/
support files at MI 40 second so the fast verify path scores all source
before slower test fixtures.

* refactor: restore logic/TUI complexity tiers and cohesive layout

Score non-TUI logic at MI 52 and the TUI surface at 50, then fold artificial
verifyx micro-splits back into cohesive modules so the gate matches the
architecture instead of forcing file fragmentation.

* feat: render intake gates with markdown two-column dialogs

Replace host DialogSelect/Prompt/Confirm for the intake chain so
assumptions, questions, and mode rationale are readable as markdown,
with short actions beside the body (answer step stays full-width stacked).

* fix: tolerate trailing commas in OpenCode plugin config

Hand-edited opencode.json often keeps a trailing comma; strict JSON
parse made plugin:install:prod fail with an opaque SyntaxError.

* fix: make board keyboard selection reliable and add Tab cycling

Keep selectedColumn synced with the highlighted card, auto-select on refresh, blur leftover host focus on open, and cycle root tasks with Tab/Shift+Tab.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: clarify intake decision action labels

Approve/Reject were ambiguous when a clarifying question was on screen; Accept assumption / Override with answer name the object of the choice.

* feat: lead Review menu with approve

* fix: scroll task details overflow

* refactor: remove test-only DI seams and dead flexibility

- delete CreateTaskDependencies bag and createUpdateController's optional
  check/confirm/runCommand/now; tests mock modules instead
- dedupe patch.ts lock/read/merge/update skeleton into withKaganUpdate
- delete shellGitRunner; server uses bunGitRunner (now a const, not a factory)
- board passes store instead of drilling cap/sendBackStopThreshold/checkCommand
- inline buildEditorContext/listEditorSignals/listEditorDialogControls into hook
- drop dead code: setupCommand field, unused checkCommand hook prop, test:ci
  script, HOST_DIALOG_WIDTH size param, oxfmt pass in install-plugin
- fold eligible predicate into spawnHelper; store parses options once
- delete update-launch.test.ts (re-implemented wiring) and duplicate
  gateBadges mode tests; simplify git-shell fixture (preload already isolates)

* fix: strip trailing commas with string-aware scanner

Raw regex fallback also removed ", }" / ", ]" sequences inside quoted
config values, silently rewriting them on the reparse-and-write path.

* build(deps): bump zod from 4.1.8 to 4.4.3

Bumps [zod](https://github.com/colinhacks/zod) from 4.1.8 to 4.4.3.
- [Release notes](https://github.com/colinhacks/zod/releases)
- [Commits](colinhacks/zod@v4.1.8...v4.4.3)

---
updated-dependencies:
- dependency-name: zod
  dependency-version: 4.4.3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Al <7698600+aorumbayev@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
aorumbayev added a commit that referenced this pull request Jul 27, 2026
* Board UX fixes, intake dialog polish (#25)

* refactor: gate src complexity before test support files

Replace the logic/TUI two-tier split with src at MI 52 first and test/
support files at MI 40 second so the fast verify path scores all source
before slower test fixtures.

* refactor: restore logic/TUI complexity tiers and cohesive layout

Score non-TUI logic at MI 52 and the TUI surface at 50, then fold artificial
verifyx micro-splits back into cohesive modules so the gate matches the
architecture instead of forcing file fragmentation.

* feat: render intake gates with markdown two-column dialogs

Replace host DialogSelect/Prompt/Confirm for the intake chain so
assumptions, questions, and mode rationale are readable as markdown,
with short actions beside the body (answer step stays full-width stacked).

* fix: tolerate trailing commas in OpenCode plugin config

Hand-edited opencode.json often keeps a trailing comma; strict JSON
parse made plugin:install:prod fail with an opaque SyntaxError.

* fix: make board keyboard selection reliable and add Tab cycling

Keep selectedColumn synced with the highlighted card, auto-select on refresh, blur leftover host focus on open, and cycle root tasks with Tab/Shift+Tab.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: clarify intake decision action labels

Approve/Reject were ambiguous when a clarifying question was on screen; Accept assumption / Override with answer name the object of the choice.

* feat: lead Review menu with approve

* fix: scroll task details overflow

* refactor: remove test-only DI seams and dead flexibility

- delete CreateTaskDependencies bag and createUpdateController's optional
  check/confirm/runCommand/now; tests mock modules instead
- dedupe patch.ts lock/read/merge/update skeleton into withKaganUpdate
- delete shellGitRunner; server uses bunGitRunner (now a const, not a factory)
- board passes store instead of drilling cap/sendBackStopThreshold/checkCommand
- inline buildEditorContext/listEditorSignals/listEditorDialogControls into hook
- drop dead code: setupCommand field, unused checkCommand hook prop, test:ci
  script, HOST_DIALOG_WIDTH size param, oxfmt pass in install-plugin
- fold eligible predicate into spawnHelper; store parses options once
- delete update-launch.test.ts (re-implemented wiring) and duplicate
  gateBadges mode tests; simplify git-shell fixture (preload already isolates)

* fix: strip trailing commas with string-aware scanner

Raw regex fallback also removed ", }" / ", ]" sequences inside quoted
config values, silently rewriting them on the reparse-and-write path.

* build(deps-dev): bump solid-js from 1.9.10 to 1.9.14

Bumps [solid-js](https://github.com/solidjs/solid) from 1.9.10 to 1.9.14.
- [Release notes](https://github.com/solidjs/solid/releases)
- [Changelog](https://github.com/solidjs/solid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/solidjs/solid/commits)

---
updated-dependencies:
- dependency-name: solid-js
  dependency-version: 1.9.14
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Al <7698600+aorumbayev@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
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