Skip to content

fix: add a typecheck gate and fix the 14 errors it found - #168

Merged
dawsontoth merged 1 commit into
mainfrom
fix/typecheck-gate
Sep 11, 2026
Merged

fix: add a typecheck gate and fix the 14 errors it found#168
dawsontoth merged 1 commit into
mainfrom
fix/typecheck-gate

Conversation

@dawsontoth

Copy link
Copy Markdown
Contributor

Independent of the two build PRs (#166 / #167) — this lands cleanly whichever of those you pick.

Nothing in this repo runs tsc

tsup transpiles through esbuild without typechecking, lint is oxlint, format is dprint. So type errors have been accumulating unnoticed. tsc --noEmit reports 14.

They are identical under TypeScript 6.0.3 and 7.0.2 — I diffed the two runs, zero difference either way. None of this is TS 7 fallout; it's just never been checked.

Two are real bugs

tools/browser/browserClickTool.ts:14 — puppeteer calls the option count, not clickCount:

await page.click(selector, { button, clickCount });   // clickCount silently dropped

The tool exposes a clickCount parameter to the model and describes it as "The number of times to click." Puppeteer ignored the unknown key, so every request single-clicked — double-click has never worked.

agent/runAgentForOnePass.ts:219,321stream.state._maxTurns is number | null upstream, while trackedState.maxTurns is number and feeds this guard:

if (trackedState.currentTurn + 1 >= trackedState.maxTurns) { /* abort the run */ }

A null would make currentTurn + 1 >= null true immediately and abort on the first turn. Now falls back to the configured limit, and the change-detection comparison uses the same normalized value so it can't get stuck permanently dirty.

One is a behavior change — please look at this one

ink/components/BlinkingTextInput.tsx used wrap="end", which is not a valid Ink wrap value. Ink's wrapText matches "wrap", "hard", and startsWith("truncate")"end" falls through all three, so the text was passed through untouched, neither wrapped nor truncated.

I changed it to truncate-end, which is what the name was reaching for (Ink's own truncate default is position: 'end'). That means the text is now truncated to the box width instead of overflowing it. There are no tests for this component, so it's worth an eyeball. If the intent was genuinely "leave the text alone", wrap="wrap" is closer to today's rendering.

The rest are correctness-neutral

  • tools/files/applyPatchTool.ts threaded a bare string where getHarperSkillTool accepts a union of skill names. Now derives HarperSkillName from the exported list — no casts, no any.
  • Four configurationWizard test files omitted required props (defaultValue, plus onExit for ProviderStep). Passing "" matches the undefined they were effectively getting, so rendering is unchanged — the tests pass identically before and after.

The gate

Adds npm run typecheck and a Typecheck job to Verify PR, so this stays at zero.

Verification

npm run typecheck  exit 0   (was 14 errors)
npm run lint       exit 0
npm run format     exit 0
npm run build      exit 0
npm test           53 files / 345 tests passed

🤖 Generated with Claude Code

Nothing in this repo runs `tsc`. tsup transpiles through esbuild without
typechecking, lint is oxlint and format is dprint, so type errors have been
accumulating unnoticed. `tsc --noEmit` reports 14 of them, identical under
TypeScript 6.0.3 and 7.0.2 - none are upgrade fallout.

Two are real bugs:

- tools/browser/browserClickTool.ts: puppeteer calls the option `count`, not
  `clickCount`. The unknown key was silently dropped, so the tool's
  clickCount parameter never worked and every request single-clicked.

- agent/runAgentForOnePass.ts: `stream.state._maxTurns` is `number | null`
  upstream, but `trackedState.maxTurns` is `number` and feeds the
  `currentTurn + 1 >= maxTurns` guard. A null would have made that guard
  fire immediately and abort the run. Now falls back to the configured
  limit, and the change-detection comparison uses the same normalized value
  so it can't get stuck dirty.

The rest are correctness-neutral:

- ink/components/BlinkingTextInput.tsx used `wrap="end"`, which is not a
  valid Ink wrap value. Ink matches "wrap", "hard", and anything starting
  with "truncate", so "end" fell through every branch and the text was
  passed through untouched. Changed to `truncate-end`, which is what the
  name was reaching for. **This is a real behavior change** - that text is
  now truncated to the box width instead of overflowing it. Flagging it for
  review; if the intent was to leave the text alone, `wrap="wrap"` would
  preserve today's rendering more closely.

- tools/files/applyPatchTool.ts threaded a bare `string` where
  getHarperSkillTool accepts a union of skill names. Now derives
  `HarperSkillName` from the exported list, with no casts.

- The four configurationWizard test files omitted required props
  (`defaultValue`, and `onExit` for ProviderStep). Passing `""` matches the
  undefined they were effectively getting, so behavior is unchanged - the
  tests pass identically before and after.

Adds `npm run typecheck` and a Typecheck job to Verify PR so this stays at
zero.

Verified: typecheck, lint, format, build, and 53 files / 345 tests all pass.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request introduces several fixes and improvements, including correct handling of nullish _maxTurns in the agent runner, updating text wrapping to "truncate-end" in BlinkingTextInput, adding a "typecheck" script, and refining TypeScript types in applyPatchTool. It also updates various wizard component tests to include missing props. However, a critical issue was identified in browserClickTool.ts where changing the Puppeteer click option from clickCount to count is incorrect and will cause multi-click requests to fail.

Comment thread tools/browser/browserClickTool.ts
@dawsontoth
dawsontoth merged commit 79192dd into main Sep 11, 2026
6 checks passed
@dawsontoth
dawsontoth deleted the fix/typecheck-gate branch September 11, 2026 15:05
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 0.16.53 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant