Repository navigation
fix(check): respect TypeScript project compile scope (UPT-49) - #138
Merged
Merged
Conversation
lucasbraum
force-pushed
the
fix/upt-49-tsconfig-scope
branch
from
October 15, 2026 00:17
b2bdb5f to
c454ae6
Compare
lucasbraum
force-pushed
the
fix/upt-49-tsconfig-scope
branch
from
October 15, 2026 00:46
c454ae6 to
a0082b8
Compare
7 of 8 tasks
Signed-off-by: Lucas Braum <lucasbraum@gmail.com>
…ct scope Config files a pack reads (next.config.mjs) are read by their tool, not compiled, so the tsconfig scope filter must not drop them. Restores the inventory-only assertion in companion-group.test.ts that #138 had flipped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Lucas Braum <lucasbraum@gmail.com>
Signed-off-by: Lucas Braum <lucasbraum@gmail.com>
Signed-off-by: Lucas Braum <lucasbraum@gmail.com>
The setup-import cache added for dependency augmentations is keyed by program, so register it with shared-state like every other module-level TypeScript holder. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Lucas Braum <lucasbraum@gmail.com>
lucasbraum
force-pushed
the
fix/upt-49-tsconfig-scope
branch
from
October 15, 2026 04:58
2ae3d3b to
02f8eb4
Compare
lucasbraum
marked this pull request as ready for review
October 15, 2026 04:58
Merged
7 of 8 tasks
lucasbraum
added a commit
that referenced
this pull request
Oct 15, 2026
…PT-49 (UPT-56) compileCompilerUpgrade now takes its projects from #138's projectScope and counts a compiler diagnostic only in a file a project covers, as for any package. Pack findings in tsconfig files are not compiler diagnostics: the check test pins an extended base config outside every include, in an excluded directory, still reported. The network test pins an uncovered file's compiler error dropped. Docs and RESEARCH.md say so; the re-score on the new scope and its 14 open false positives are recorded there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Lucas Braum <lucasbraum@gmail.com>
lucasbraum
added a commit
that referenced
this pull request
Oct 15, 2026
After UPT-49 (#138) check compiles every project of the TypeScript project scope, tsconfig*.json included, while packs:truth still compiled tsconfig.json alone. #150's Pack test failed on that gap: 14 breaking false positives in shogo82148/typescript-action __tests__, type-checked through tsconfig.eslint.json (its jest.config.js runs ts-jest with it), where the repository's own upgrade added types ["jest", "node"]. packs:truth now drafts on projectScope, the same project list check uses. All seven typescript repositories were redrafted with it, before re-scoring: shogo gains those 14 compiler sites under generic; the other new diagnostics are inherited options on newly compiled leaf configs (signalk tsconfig.build.json, Borewit lib/tsconfig.prod.json), expected where the option is set as before. Nothing else changed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Lucas Braum <lucasbraum@gmail.com>
lucasbraum
added a commit
that referenced
this pull request
Oct 15, 2026
…ompiler (UPT-56) (#150) ## Pack `typescript` `>=5 <6` → `>=6 <7` (default 6.0.3), for UPT-56. **Candidate, by choice:** under today's gate the run measures verified (7 public repositories, 0 breaking false positives). The stricter gate (UPT-48) is landing separately, so `verification.json` keeps its candidate record until this branch is rebased on UPT-48 and re-scored with `--write`. The upgraded package is the compiler itself, so this also changes the engine. How `check` resolves the compiler for this upgrade: - **Installed side:** the repository's own `node_modules/typescript`, the nearest one from the workspace up. - **Target side:** the `typescript` copy `check` fetched at the target, the release `fix` installs, loaded from that directory. - **Never the bundled compiler** (ts-morph's 6.0.2). With no TypeScript installed, the compile is skipped and the report says why. A target with no JavaScript API (TypeScript 7) is skipped and named the same way. - **What is compiled:** every project of the workspace (its tsconfig, its references, every nested `tsconfig.json`), all files, not only importers of `typescript`. The coverage line names both compilers: "compiled 13 of 13 files … with the repo's TypeScript 5.9.3 and 6.0.3". - **tsconfig diagnostics** (TS5101/TS5107/TS5011) are pack findings from the inventory, reported in the file that sets the option, not compile findings. So the UPT-49 project scope (#138) does not drop them. `packs/typescript/check.test.ts` pins this with a tsconfig outside every `include`. Engine changes, in their own commit: - `compileCompilerUpgrade` in `adapters/typescript/compile.ts`. - `loadCompiler` drops Node's cached module when the version on disk changed, and the compiler cache is keyed by version. Without this, `fix` would verify a TypeScript 6 install with the 5.x module loaded earlier from the same path. - A workspace that imports nothing is still checked when a named pack's inventory matches. - `companionsOf` reports a peer conflict even when `list` does not group the peer with the lead. Before, `@typescript-eslint/parser` 8.56.0 (`typescript <6.0.0`) was planned as a conflict and then dropped from the report; it is now listed as possible impact and left where it is. - `packs:truth`: - reads `tsconfig*.json` in the upgrade diff and lists tsconfig option errors; - anchors insertions in JSON; - loads the linked target compiler by its real path. Node's cached resolution kept handing back the installed 5.x, so the first drafts silently compiled 5.x twice. ## Sources Read 2026-10-14, pinned in RESEARCH.md: the TypeScript 6.0 release notes (TypeScript-Website `119f931`), Announcing TypeScript 6.0 (2026-03-23), Announcing TypeScript 7.0 (2026-07-08), and tags v5.9.3 / v6.0.3. Every diagnostic code was read from 6.0.3 itself. **Range decision:** two packs. 6.0 deprecates (errors unless `ignoreDeprecations: "6.0"` is set) what 7.0 removes. `packs/queue.json` gets 5 → 6 (candidate) and 6 → 7, **blocked**: `typescript@7.0.2` exports no compiler API (a new one is planned for 7.1). ## Rules and behavior notes Mechanical, each with an exact replacement from the notes and unchanged behavior: - `downlevel-iteration`: removes the line. Declined with an ES3/ES5 target, with `ignoreDeprecations` set, or when the property shares its line. - `module-keyword`: TS1540, `module Foo {` → `namespace Foo {`. Declined for a quoted ambient module. - `import-assertions`: TS2880, `assert {` → `with {`. Declined unless `{` or `:` follows. Assisted, reported where set, with a guide: - `base-url`: the `paths` rewrite is exact, but bare-import lookup and bundlers that read `baseUrl` can change. - `module-resolution-node10`, `module-resolution-classic`: bundler vs nodenext is the owner's call. - `target-es5`, `module-format-removed`, `out-file`, `interop-false`, `always-strict-false`: each changes emit. - `root-dir`: TS5011 at `outDir` when `include` is one directory and `rootDir` is unset. Behavior note `changed-defaults` (a decision): lists, per tsconfig, the 6.0 defaults it leaves unset through in-repo `extends` (strict, types, noUncheckedSideEffectImports). The owner pins or keeps each. Defaults are not pinned by rule: a static pin would hit every tsconfig that leaves them unset, and most of those compile cleanly. The code errors those defaults cause are the compiler's findings. `requiresBuild: true`. The instructions forbid `any`, `@ts-ignore`/`@ts-expect-error`/`@ts-nocheck`, `ignoreDeprecations`, `skipLibCheck` and loosening strictness. ## Ground-truth repositories Committed in `2699e8c`, the first commit of this branch, **before the first scoring run**; nothing was changed after scoring. Drafted with `pnpm packs:truth` (6.0.3 on every `tsconfig.json`, plus the upgrade diff), then assigned by hand. | Repository | Before | Upgrade | Expected | | --- | --- | --- | --- | | m-lyon/recipe (`client/`) | `f6e44b5` (5.6.2) | pull request 113 (merged) | 1 | | robrechtme/recipes | `0853747` | pull request 7 (merged) | 2 | | JosephMaynard/dependency-radar | `1920eb3` | pull request 46 (merged) | 116 | | CroffZ/github-release-notifier | `d9353f2` | pull request 5 (merged) | 12 | | SignalK/signalk-derived-data | `02f635e` | pull request 239 (merged) | 418 | | shogo82148/typescript-action | `0f03405` | pull request 487 (merged) | 3 | | Borewit/music-metadata | `783509b` | pull request 2661 (merged) | 851 | Most expected sites are `generic` compiler sites, which mostly come from the `types: []` and `strict` defaults. ## `uptide pack test` output ``` uptide pack test typescript · verified, recorded candidate fixtures 7 cases, 14 sites · pass ground truth m-lyon/recipe@f6e44b530c4d typescript 5.6.2 → 6.0.3 predicted 1, expected 1, false positives 0, false negatives 0 robrechtme/recipes@0853747427b7 typescript 5.9.3 → 6.0.3 predicted 2, expected 2, false positives 0, false negatives 0 MagicZebraLtd/dependency-radar@1920eb3217b7 typescript 5.9.3 → 6.0.3 predicted 115, expected 116, false positives 0, false negatives 1 CroffZ/github-release-notifier@d9353f2471c5 typescript 5.9.3 → 6.0.3 predicted 11, expected 12, false positives 0, false negatives 1 SignalK/signalk-derived-data@02f635e8232a typescript 5.9.3 → 6.0.3 predicted 417, expected 418, false positives 0, false negatives 1 shogo82148/typescript-action@0f03405c7267 typescript 5.9.3 → 6.0.3 predicted 2, expected 3, false positives 0, false negatives 1 Borewit/music-metadata@783509b27bac typescript 5.9.3 → 6.0.3 predicted 831, expected 851, false positives 0, false negatives 20 rule precision recall tp fp fn base-url 100% 100% 4 0 0 changed-defaults n/a 0% 0 0 4 generic 100% 99% 1371 0 18 module-resolution-node10 100% 67% 2 0 1 root-dir 100% 50% 1 0 1 target-es5 100% 100% 1 0 0 overall (sites) 100% 98% 1379 0 24 behavior notes (sites) n/a 0% 0 0 4 breaking (sites) 100% 99% 1379 0 20 ``` It exits 1 only because `verification.json` still holds the candidate record, which is the point. The 24 false negatives are explained in RESEARCH.md: - 18 second-round Borewit lines (17 tightened test lines and a TS6385 deprecation); - 2 same-change tsconfig lines no rule predicts; - 4 `changed-defaults` decision sites, which are behavior-only, not missed breaks. **Under UPT-48 as specified:** - 7 repositories and 1,399 expected breaking sites: both meet the minimums. - Real-world true positives per rule: `base-url` 4, `module-resolution-node10` 2, `target-es5` 1, `root-dir` 1. - The three mechanical rewrites met **no** real site. They become unexercised and run as assisted; their only evidence is the fixtures. ## Checklist - [x] Every rule and note comes from a source listed in `meta.sources` - [x] Every rule that rewrites or detects has a fixture case, with a site it must leave alone (`keep`): 7 cases, 14 sites - [x] Ground truth: public repositories at the commit before their upgrade; expected findings read from their own upgrade commit and the compiler, never copied from Uptide's output - [x] At least two public repositories for `verified`: 7, held at candidate until UPT-48 - [ ] `verification.json` written with `--write`: **deliberately not yet**, after the rebase on UPT-48 - [x] `pnpm lint && pnpm typecheck && pnpm test` pass locally (1,731 core and 454 CLI tests) - [x] Changeset added - [x] No private code, names or paths: fixtures are synthetic, ground truth is public To check before merge: - Pack CI's record check fails until `--write`. That is expected while this is a draft. - #138 (UPT-49) also edits `compile.ts`. Whichever lands second rebases, and `compileCompilerUpgrade` could then take its project list from #138's `projectScope`. - Known limits: - `extends` to a package config is not read; - `root-dir` reads one file; - errors that appear only after the first fixes are not predicted. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Signed-off-by: Lucas Braum <lucasbraum@gmail.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
lucasbraum
pushed a commit
that referenced
this pull request
Oct 15, 2026
…quired-move fixes Rebased on main after #138, #142 and #154 and re-ran pack test --write on the unchanged ground truth: breaking 3 TP / 0 FP / 17 FN (100% precision, 15% recall). It stays a candidate: check reports openai-guardrails-js blocked on a required @openai/agents major and prompty blocked on @azure/ai-projects' openai ^6 dependency. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FX2nBoNEvDh9v71yDhEzxL Signed-off-by: Claude <noreply@anthropic.com>
lucasbraum
pushed a commit
that referenced
this pull request
Oct 15, 2026
This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and publish to npm yourself or [setup this action to publish automatically](https://github.com/changesets/action#with-publishing). If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated. # Releases ## uptide@0.13.0 ### Minor Changes - [#134](#134) [`b795705`](b795705) Thanks [@lucasbraum](https://github.com/lucasbraum)! - Packs can name alternate leads: packages a repository declares instead of the pack's own (`react-router-dom` for `react-router`). `check` and `fix` asked for either name use the pack; where only the alternate is declared, the lead is analyzed at the version installed through it, pnpm stores included, and `fix` declares it beside the alternate at the target before upgrading both. - [#149](#149) [`3303118`](3303118) Thanks [@lucasbraum](https://github.com/lucasbraum)! - Add a candidate express 4 to 5 migration pack. Route strings that path-to-regexp 8 rejects or reads differently are found on calls of an Express app or router (including lists registered in a loop); `req.params` values widened to `string | string[]`, `req.param`, `res.sendfile`, `express.static.mime` and `express.query` are claimed from the compiler; `res.redirect(url, status)`, `app.param(fn)`, `res.redirect('back')` and `res.send(<number>)` are found in the source; runtime defaults (async errors, `req.body`, the query parser, `urlencoded`, dotfiles, Node 18) go to decisions. No rule rewrites. With the pack in use, `check` no longer adds its text-matched express 5 runtime findings. - [#148](#148) [`5143c46`](5143c46) Thanks [@lucasbraum](https://github.com/lucasbraum)! - Add a candidate joi 17 to 18 migration pack. `new ValidationError(message, {}, original)`, which stops compiling for code written against joi 17.0–17.6, is rewritten to pass `[]`; the Node.js 20 requirement and the top-level domains joi 18 no longer accepts in `email()`, `domain()` and `uri()` are reported as decisions. Scored against two public repositories, one of them a negative control. - [#131](#131) [`413d3da`](413d3da) Thanks [@lucasbraum](https://github.com/lucasbraum)! - Add a verified lucide-react 0.x to 1.x migration pack. Brand icons removed in 1.x are found at their imports and every use, with a guide whose replacement choice goes to the owner; icon names dropped during 0.x are renamed at the import or member; deep `dist/` imports, untyped icon lookups, the `absoluteStrokeWidth` and `IconNode` deprecations, and the `aria-hidden` default for repositories before 0.489.0 are reported. Lucide's lockstep packages move together and the consumer's build is required. Verified against three public repositories, one of them a negative control. - [#132](#132) [`107c107`](107c107) Thanks [@lucasbraum](https://github.com/lucasbraum)! - Add a verified React Router 6 → 7 migration pack, which also runs for applications that declare only `react-router-dom`. It moves `react-router-dom` imports to `react-router`. It reports, with a guide for the agent, the rest of the upgrade: the removed `future` prop and router option, `react-router-dom/server`, lowercase `formMethod` comparisons and `json`/`defer` calls (found by syntax where the compiler is blind), the other removed exports, and `generatePath` calls that pass `null` for a required parameter. The six v6 future flags that become defaults are reported as decisions where the repository's router setup has not enabled them. React Router 7 → 8 is a separate upgrade. - [#142](#142) [`9c57934`](9c57934) Thanks [@lucasbraum](https://github.com/lucasbraum)! - `check` and `fix` plan what the target version requires: a package the target, or anything moving with it, declares as a peer or dependency at a range the installed copy rejects moves to the lowest release of its major that satisfies it (openai 7 moves zod 3.24.2 to 3.25.0), shown apart from release-group companions ("moved because openai 7.4.0 requires zod ^3.25 || ^4.0"). A move only a new major makes is never made: it is reported as a blocker with the exact range in `check`, the PR body and `pack test`. The npm install scope guard no longer lets a declared root dependency change because a moved package peers on it. - [#128](#128) [`06f11ab`](06f11ab) Thanks [@lucasbraum](https://github.com/lucasbraum)! - Add verified Sentry JavaScript SDK 10 to 11 migration packs for `@sentry/nextjs` and `@sentry/browser`, with the SDK's lockstep release group, a required build for Next.js, and inventory-scoped decisions for data collection, span streaming, sampling and platform minimums. Mechanical rules move `withSentryConfig` to `@sentry/nextjs/config` and the removed build options under `webpack`, remove `enableLogs`/`enableMetrics: true`, and rename exports, integration names and `httpIntegration` options; privacy, sampling, profiling and OpenTelemetry choices stay assisted and are reported for the owner. Fix `uptide pack new` dropping registry entries long enough to be wrapped. - [#155](#155) [`922c5ab`](922c5ab) Thanks [@lucasbraum](https://github.com/lucasbraum)! - `uptide pack test` applies a stricter verified gate: at least five expected breaking sites across the public ground-truth repositories, besides two repositories and no breaking false positive. Upgrades the compiler cannot see are gated on their behavior notes instead. Mechanical rules no real site exercises are recorded as unexercised, and `check` and `fix` run their sites as assisted. `@sentry/browser` and `@sentry/react` become candidates (fewer than five real breaking sites). A pack can lower the minimum only with a written reason in its RESEARCH.md. The README packs table shows each pack's breaking-site count. The output shows the gate's class, site counts and every reason a pack is a candidate. - [#147](#147) [`0b88170`](0b88170) Thanks [@lucasbraum](https://github.com/lucasbraum)! - `check` and `fix` remove a deprecated `@types` stub instead of upgrading to it. When the release the upgrade would move `@types/<pkg>` to is deprecated on npm, and `<pkg>`'s target declares its own types (`types`, `typings` or a `types` export), the plan removes it: "Removed: @types/ioredis, ioredis 5 ships its own types", in `check` and in the PR body. `check` now diffs such a package against its own target types instead of failing on a stub with no declarations, and `fix` removes the entry in the same install, with the install scope guard allowing exactly that removal. - [#150](#150) [`4c3212b`](4c3212b) Thanks [@lucasbraum](https://github.com/lucasbraum)! - `check typescript` judges a TypeScript 5 to 6 upgrade with both compilers: every project of the workspace is compiled with the installed TypeScript and with the target's, and what is new at the target is a finding; the bundled compiler never stands in, and a target without a JavaScript API (TypeScript 7) is reported as not compiled. A candidate typescript 5 to 6 pack reports the tsconfig options 6.0 deprecates where they are set, the rootDir default, module-keyword namespaces and import assertions. A peer that rejects the target (typescript-eslint on TypeScript 6) is now reported as a peer conflict even when it is not grouped with the package. - [#137](#137) [`21894d7`](21894d7) Thanks [@lucasbraum](https://github.com/lucasbraum)! - Add `verify.build` to uptide.yml: the package.json script a migration pack's required build runs. Unset, Uptide runs `build:ci`, then `build-ci`, then `build`. When a build fails before the framework's build starts because it needs an environment variable or a database (`prisma db push` without `DATABASE_URL`), the pull request and the report say so ("build needs DATABASE_URL; set verify.build") instead of a bare "build failed". `uptide init` writes the setting as a comment. ### Patch Changes - [#141](#141) [`9debb6d`](9debb6d) Thanks [@lucasbraum](https://github.com/lucasbraum)! - `check` no longer reports a pre-existing type error as a breaking site when the upgrade only changes its wording, such as a type the message prints in full. An error at the same place with a different reason is still reported. - [#129](#129) [`e796e4c`](e796e4c) Thanks [@lucasbraum](https://github.com/lucasbraum)! - Add a candidate ioredis 5 to 6 migration pack: client constructions that inherit the RESP3, reconnect and keep-alive defaults ioredis 6 changed, compiler-blind sites (`mode === 'subscriber'`, commands in a `connect` listener with the offline queue off, AUTH recognized by command name), dependents that bundle ioredis 5, instrumentation that stops patching ioredis 6, and Node 20. It is scored against five public upgrades and stays a candidate: none of them has a breaking site to verify it with. - [#139](#139) [`9ba005a`](9ba005a) Thanks [@lucasbraum](https://github.com/lucasbraum)! - Allow local check and fix smoke tests of registered candidate packs with --allow-candidate, with an explicit unverified banner. Reject candidate opt-in in the Action and with publication flags, and prevent stored candidate runs from being published. Label pack-claimed assisted sites by rule id even with --no-llm. - [#157](#157) [`f3af6a1`](f3af6a1) Thanks [@lucasbraum](https://github.com/lucasbraum)! - `check` no longer reports a blocker for a direct dependency whose plain dependency range rejects the target (`@azure/ai-projects` on `openai ^6`, verdaccio pinning express 4): the package manager gives it its own nested copy, so it is listed as staying, with the new major that would accept the target when there is one. `pack test` counts a `with` move that `check` leaves and explains (a blocker, a new-major stay or a peer conflict) as explained, and one of a package that does not depend on the lead as the repository's choice; neither fails the run. - [#130](#130) [`5ced450`](5ced450) Thanks [@lucasbraum](https://github.com/lucasbraum)! - Add a candidate openai 4 to 7 migration pack: named path parameters, `del` → `delete`, promoted beta chat helpers, renamed runner events, removed entry points and request-option overloads are rewritten where unambiguous; tool-call unions, `httpAgent`, `fileFromPath` and the other removals get agent guides; `APIError.headers`, Web `Response` bodies and double-encoded path ids are detected even in code typed `any`; Node 22, zod, fetch and client-subclass decisions carry repository evidence. It stays a candidate (the dependency is still checked and fixed as generic) until two engine gaps its ground truth exposed are closed. - [#136](#136) [`578a042`](578a042) Thanks [@lucasbraum](https://github.com/lucasbraum)! - Fold implicit-any errors (TS7006, TS7031, TS7019) inside an option the target removed into the pack finding on that option, as downstream evidence: the callbacks lost the types the option gave them, and the same edit resolves them. They no longer stand as separate breaking sites. - [#143](#143) [`883e587`](883e587) Thanks [@lucasbraum](https://github.com/lucasbraum)! - `uptide pack test` scores each expected site at the severity of the rule or behavior note it belongs to, so a missed note that only needs a look, or a decision, no longer counts as a missed break. Behavior-note sites get their own precision and recall in the output and in `verification.json` (`behavior`, with the counts behind each rate), false negatives show their severity, and a rate with nothing to measure prints `n/a` instead of 100%, in `pack test` and in the README's packs table. - [#154](#154) [`7aa3d58`](7aa3d58) Thanks [@lucasbraum](https://github.com/lucasbraum)! - `uptide pack test` fails a pack's `verification.json` only when it claims more than the run measures (recorded verified, measured candidate). A pack recorded as candidate on purpose passes, with `recorded candidate by choice; measures verified`, and a record whose numbers differ gets a note instead of a failure. A `generic` ground-truth site now counts as a true positive for the rule that claims it. - [#152](#152) [`ca31aee`](ca31aee) Thanks [@lucasbraum](https://github.com/lucasbraum)! - `uptide pack test` takes several packs: `uptide pack test zod ai`. - [#159](#159) [`1e157fd`](1e157fd) Thanks [@lucasbraum](https://github.com/lucasbraum)! - `uptide pack test --json` times each ground-truth repository: `timing` gives the fetch, install and check wall time and the process's peak memory. - [#144](#144) [`0881185`](0881185) Thanks [@lucasbraum](https://github.com/lucasbraum)! - Ground truth can name a site for an upgrade that only adds lines inside an existing call, such as an option added to a constructor: the site is the call's start line, so a pack finding there scores as a true positive instead of a false positive. `pnpm packs:truth` drafts these anchors from insert-only hunks for review, and docs/packs.md and CONTRIBUTING describe the rule. - [#156](#156) [`9039e3c`](9039e3c) Thanks [@lucasbraum](https://github.com/lucasbraum)! - Public ground truth now exercises three rules that ran as assisted: zod `error-params`, stripe `api-version-unpinned` and next `stable-cache-exports`. Their rewrites run mechanically again. All three packs stay verified. - [#138](#138) [`0db5640`](0db5640) Thanks [@lucasbraum](https://github.com/lucasbraum)! - Respect repository tsconfig file selection, recursive project references, and workspace project options when checking dependency upgrades. Compiler diagnostics outside every TypeScript project no longer produce breaking findings; pack rules and build-configuration findings retain their own scope. Repositories without a tsconfig retain importer-based compilation, with that fallback stated in the report. Anchor missing members supplied by dependency augmentations at their setup import, retaining affected calls as evidence instead of counting each call as a separate breaking edit. - [#151](#151) [`9ddaaff`](9ddaaff) Thanks [@lucasbraum](https://github.com/lucasbraum)! - Add a candidate redis (node-redis) 4 to 5 and 5 to 6 migration pack, one rule set per major: an upgrade gets the rules of the majors it crosses, so 4 to 6 gets both. 4 to 5 covers `legacyMode`, `commandOptions` and isolation, scan iterators that yield batches, string SCAN cursors, boolean replies that became numbers, enums that became constants, `keepAlive`, `@redis/graph` and internal `dist` imports; 5 to 6 covers the RESP3 client type, `unstableResp3`, and the client defaults 6 changes (RESP3, command timeout, keep-alive delay, maintenance notifications) with a decision per client. Scored against five public upgrades; it stays a candidate until the stricter verified gate lands, since the core 4 to 5 API changes have no real site yet. - [#135](#135) [`42a3b54`](42a3b54) Thanks [@lucasbraum](https://github.com/lucasbraum)! - Move only packages released with the upgraded one. A pack's declared release group now bounds the lead's npm scope, and without one a same-scope package moves only when a pin, a peer or a release at the target relates it to the group. Packages of the scope that are versioned on their own (`@sentry/vite-plugin` 5.x, `@sentry/cli`, the old `@sentry/utils` 8.x) are reported as "stays at X" in `check`, the pull request and `pack test` instead of making `fix` refuse the whole upgrade. Registers the verified `@sentry/react` 10 to 11 pack. - [#146](#146) [`09b8682`](09b8682) Thanks [@lucasbraum](https://github.com/lucasbraum)! - Report Stripe clients pinned to different API versions at the top of `check` and of the PR body, as a decision for the owner: every `new Stripe(...)` in TypeScript and JavaScript sources, scripts included, with the version it speaks after the upgrade (an unpinned client speaks the SDK default). The PR's decisions list, for each client behind the target, the changelog entries it would cross for the resources it calls. No pin is rewritten. - [#140](#140) [`bc428d1`](bc428d1) Thanks [@lucasbraum](https://github.com/lucasbraum)! - Keep migration PR bodies within their size budget while preserving summaries, representative diffs, decisions, review warnings and verification ahead of changelog and transitive detail. Keep every evidenced Stripe change visible and uncapped; group and cap only other changes to used resources, link the full changelog, and identify omitted text in the retained report. - [#145](#145) [`3c8902d`](3c8902d) Thanks [@lucasbraum](https://github.com/lucasbraum)! - The zod pack migrates `ZodError#errors` to `.issues` by rule: reads (`error.errors[0].message`, `error?.errors`) and destructuring (`const { errors } = error` becomes `const { issues: errors } = error`) where the type checker resolves the receiver to `ZodError`, and reads off an untyped catch binding of a zod parse. Writes are left to the agent. - [#127](#127) [`c4ead4f`](c4ead4f) Thanks [@lucasbraum](https://github.com/lucasbraum)! - zod: `check` now reports `ZodError#formErrors` and `#errors` read off an untyped catch binding of a zod `parse`/`parseAsync` (`catch (error: any) { return error.formErrors.fieldErrors }`), which zod 4 removed and the compiler cannot see. Files that only import a schema from the repository's own module (`@/lib/zod`) are covered too. `fix` rewrites `<err>.formErrors.fieldErrors` and `<err>.formErrors.formErrors` to `z.flattenError(<err>)`, importing `z` where it is missing; every other read goes to the agent. Co-authored-by: uptide-release[bot] <338861287+uptide-release[bot]@users.noreply.github.com>
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.
Related to UPT-49 — Compile scope must match the repo's own tsconfig.
Explicit importer roots bypassed TypeScript project selection, so
checkreported compiler errors in files outside the repository's own tsconfig. In guardrails, that meant four errors in its excludedexamples/files.Changes
shared-state.test.tsfailure on the previous head).The earlier React Router
verification.jsonrefresh was dropped in the rebase: main already carries the identical record.Validation
Head
02f8eb4, rebased on main7aa3d58.pnpm lint,pnpm typecheck: pass.vitest run src/shared-state.test.ts src/adapters/typescript src/check src/packs/stripe: 357 passed.pnpm teston the previous rebase (onto0b88170): core 1763 passed, cli 456 passed.Resources:
check, main vs branchLocal macOS, Node 22.20.0,
--max-old-space-size=4096, warm offline cache. The harness callscheckin-process with the registered pack (as pack test does). Two alternating rounds each (main, branch, main, branch). Measured on engine3895d17against main0881185. The later rebases only brought in main's own commits, so these runs were not repeated.9ee0b8f, React → 19.0.05cb3c7d, Vitest → 5.0.2Both are within the ~10% target. Host load averages were 4.5–7.9 on 11 CPUs.
Pack re-score: main vs branch
Engine
3895d17vs main0881185, one pack at a time with cache eviction. Breaking TP / FP / FN:unverifiedsites (below)unverifiedFPs on opentelemetry-ecosystem-explorer, none addedThe react difference: excalidraw
dev-docs/is part of the root workspace. On main, the root workspace's analysis aborts withEEXIST(symlinking@types/react-domintonode_modules), so main never reports these sites. The branch analyzes it and reportsdev-docs/src/components/Homepage/index.tsx:7anddev-docs/src/theme/ReactLiveScope/index.js:10, bothunverified. ThatEEXISTis an existing main bug, not changed here.OpenAI (#130), throwaway overlay
uptide pack test openaion02f8eb4with #130 cherry-picked, in a throwaway worktree. Nothing was pushed.examples/…multiturn_with_prompt_injection_detection.tsfalse positives (:331, :413, :428, :430) are gone. Noexamples/site is predicted.src/base-client.ts:368is still reported (breaking).unverifiedsites, unchanged from feat(packs): add candidate openai 4 to 7 migration pack #130's own run.verification.jsonas stale because it improves on the recorded precision. feat(packs): add candidate openai 4 to 7 migration pack #130 should re-record after this lands.🤖 Generated with Claude Code