Skip to content

Releases: uptide-dev/uptide

v0.18.3

Choose a tag to compare

@github-actions github-actions released this 23 Oct 03:34
155d2ef

Patch Changes

  • #271 b66598e Thanks @lucasbraum! - fix no longer hides an agent session that could not work. When the Anthropic API refuses the request (an invalid key, an empty credit balance, a model the key cannot use), the Agent SDK ends the session after one turn with nothing spent and the API's message; Uptide dropped that message, recorded "made no change" for every site and ran the feedback rounds into the same error. Now the task records the error (llm.tasks[].error, gate error), no further session starts, and every task that leaves nothing says why in llm.tasks[].noChange: the API's error, no turn, no output, a refusal, a stop, or every edit rejected. When nothing the agent did stayed, report.json (llm.agentIdle), the terminal and the PR body say "The agent did not change anything: ", and the PR body no longer says the code was migrated when every site is still manual.

  • #271 b66598e Thanks @lucasbraum! - The lockfile check no longer stops an upgrade when the package manager moves an unchanged package's dependency onto the copy the upgrade installs. Upgrading express 4 to 5, pnpm can move another package's qs or iconv-lite onto the newer copy express 5 brings: the old copy leaves the lockfile, and every package depending on it read as "same version, different resolution", so the run fell back to an agent-led draft. Such a move is now in scope when it stays in the same major (the same minor below 1.0) and never goes back, and the copy it left goes with it when nothing else needs it; the PR body and the terminal list each one as lockfile housekeeping ("onto the upgrade's copy"). A move to a release the upgrade did not bring, a downgrade, a major apart, or a change to what the repository declares itself is still refused. The same applies to npm (a nested copy dropped for the hoisted one) and Yarn Berry (a descriptor that now resolves to the upgrade's copy).

  • #273 51d0370 Thanks @lucasbraum! - fix and check in a checkout whose dependencies are not installed now stop before any analysis with PACKAGE_NOT_INSTALLED (exit 2), name the package.json that declares the package, say whether nothing is installed or only that package is missing, and give the frozen install for the lockfile (npm ci, pnpm install --frozen-lockfile, yarn install --frozen-lockfile, yarn install --immutable). Before, a node_modules in a directory above the project counted as the project's install, so a fresh clone under such a directory got past the check and fix failed with a misleading "has no upgrade". Uptide still installs nothing in your checkout. check --json now answers every refusal on stdout with {"error": {"code", "message"}}, as fix --json does. When the package is already at or past the target, fix says " is already at (target )".

  • #271 b66598e Thanks @lucasbraum! - The PR body titles each group of sites by what changed instead of an internal key: a pack rule's group by the pack's one-line summary of the rule (report.json keeps them as ruleSummaries), and sites no rule covers, keyed by the path of the declaration that changed (e.query), by what the compiler said there or by what changed ("e.query was removed in express 5.3.0").

v0.18.2

Choose a tag to compare

@github-actions github-actions released this 20 Oct 18:08
c64fb88

Patch Changes

  • #267 907dffb Thanks @lucasbraum! - The agent can no longer change dependencies outside the upgrade. An agent edit that changes or removes an existing dependency in any package.json, or touches overrides, resolutions or the pnpm field, is refused and reverted. Uptide sends the refusal back to the agent in the next feedback round, naming the package, and records it in report.json (outOfScopeDependencyEdits). That includes the upgraded package and its planned companions, whose versions the engine wrote: only a rewrite to the same value is allowed. The agent may still add a new dependency: it is kept, recorded (agentAddedDependencies) and listed under "Added by the agent" in the PR body. Lockfiles, .npmrc, .yarnrc(.yml), .pnpmfile.cjs, pnpm-workspace.yaml and new package.json files are read-only for the agent.

  • #267 907dffb Thanks @lucasbraum! - A companion that would move a new major is planned only when the upgraded package asks for it: its own manifest at the target pins the companion, the companion's manifest declares the upgraded package, or the upgraded package's pack names it. When a third package asks for it (@guardian/libs 33 pinning @guardian/ophan-tracker-js 3.1.0 during a typescript upgrade), Uptide no longer moves it. The PR lists it under "Blocked" with the declaring package, the manifest field and the range. Release pairs still move with their lead: react-dom with react, @ai-sdk/* with ai, @sentry/profiling-node with @sentry/node.

  • #267 907dffb Thanks @lucasbraum! - A package that does not move no longer drags another one through its pins: fix typescript on guardian/support-dotcom-components moved @guardian/ophan-tracker-js 2.8.3 → 3.1.0 because @guardian/libs 33.0.0, which stayed, pins it. A pin the same manifest also declares as a peer the install satisfies moves nothing either, and a pin reason now names the manifest field and the installed version.

  • #266 a5e3f57 Thanks @lucasbraum! - uptide fix no longer upgrades a peer blocker across a major that no migration pack covers. Before, redis 5 → 6 next to typeorm 0.3 (which peers on redis ^5) moved typeorm to 1.1.0 and ended in an agent-led draft. Now the blocker keeps its version, with a peer override scoped to it in package.json: npm overrides.<blocker>.<peer>, pnpm pnpm.peerDependencyRules.allowedVersions, Yarn resolutions["<blocker>/<peer>"]. The lockfile scope check still covers the install. The PR body names the override, which release was not taken and why. In report.json, each peerConflicts entry now has strategy (override, blocked or none), declined and override. If verification fails with the override, the blocker is reported as a blocker and is still not upgraded. A blocker you name on the command line, or one whose major a pack covers, is upgraded as before.

  • #264 2089d0a Thanks @lucasbraum! - uptide fix no longer stops when the package manager resolves a different version than the target. Yarn classic ignored the pin for a direct dependency and resolved a range such as ^7.0.105 to its newest match (7.0.146). Now the lockfile resolves exactly the target with npm, pnpm, Yarn classic and Yarn Berry, and the manifest keeps its range. If the package manager still resolves another version, the run continues only when that version is in the same major, inside the manifest range and covered by the pack. The PR body, the terminal summary and report.json (resolvedVersion, lockfile.resolved) then name both versions. Otherwise the run stops with an error that names the target, the resolved version and the reason.

  • #268 4cee03a Thanks @lucasbraum! - fix computes the agent's cost itself, per model and token class, from Uptide's price table: report.json and --json list each model's uncached input, cache read, 5-minute and 1-hour cache write and output tokens, the rate applied to each and the cost, so the total can be redone by hand. The Agent SDK's own figure is kept apart as sdkReportedCostUsd; --max-cost counts the higher of the two, a gap above 5% is printed as a warning, and a model missing from the table uses the SDK's figure, marked unverified. llm.inputTokens now counts uncached input only.

  • #268 4cee03a Thanks @lucasbraum! - Sonnet 5.5 cache reads are priced at the published $0.10 per million tokens (0.05x input), not $0.20. Every Anthropic rate in the price table was checked against Anthropic's pricing page on 2026-10-20, and a test now pins each one.

v0.18.1

Choose a tag to compare

@github-actions github-actions released this 19 Oct 18:59
5ffd256

Patch Changes

v0.18.0

Choose a tag to compare

@github-actions github-actions released this 19 Oct 17:35
9018eb7

Minor Changes

  • #261 93f029e Thanks @lucasbraum! - Sentry 10 → 11: report every Sentry.init whose data collection widens because dataCollection is unset, citing the migration guide, and give the agent the guide's exact v10 baseline. After a fix, a site counts as kept only when every category is at least that restrictive, so a partial edit such as a cookie deny list stays open in the PR instead of being reported as kept. The agent now keeps privacy settings at their most restrictive value, or leaves them as a decision, when no cited edit exists.

  • #253 e48373d Thanks @lucasbraum! - Find Stripe's clover billing-mode default change at subscription creation sites, across the six affected APIs. Respect request API-version pins, preserve classic billing at documented parameter paths, and report unresolved parameters or semantics as decisions. Verify quoted sources against full-page hashes at pack-build time without vendoring Stripe pages. Score the dms-saas silent billing change in UpgradeBench.

Patch Changes

  • #260 8ea1a87 Thanks @lucasbraum! - A build that fails the same way before and after the upgrade (same command, status and output; only durations and clock times may differ) no longer fails verification. Builds are now compared to the baseline the same way tests are. The PR says ⚠️ build: failing at baseline, not checked, and the verdict reads no new errors, not verification passed. A build that passed at baseline and fails after the upgrade still fails, and so does one that fails differently. Without a pack, a run like this still does not publish, because its build cannot verify the bump.

  • #259 0db73c8 Thanks @lucasbraum! - Let the agent add a property the upgraded types made required to a test fixture: only to the object the compiler's TS2739, TS2740 or TS2741 error points at, and only with a literal value. Every other test input change is still rejected. Each such property is listed under "Tests changed: review" in the PR body and in report.json (file, line, property and the value the agent chose). Name a test that asserts a dependency default the upgrade changed (Sentry's dataCollection and attachStacktrace) under "Decisions for you", instead of leaving it to fail unexplained.

  • #251 773dbbe Thanks @lucasbraum! - Calibrate the SDK pre-run cost estimate from recorded migrations, accounting for shared rule knowledge instead of charging a full session allowance per site. Keep the configured spending limit and per-call budget enforcement unchanged.

  • #258 3a4898f Thanks @lucasbraum! - Discover independent nested projects when fixing a dependency absent from the root project. Run installation, migration and verification in the selected project's directory, preserving its lockfile and package manager. When several projects declare the dependency, name their manifests and require an explicit directory.

  • #257 7b9ed7f Thanks @lucasbraum! - Run pinned npm through Corepack when local npm differs. When the pin is unavailable, allow local npm with a compatible v3 lockfile, record the fallback in the report, and reject frozen installs that rewrite the lockfile.

v0.17.2

Choose a tag to compare

@github-actions github-actions released this 19 Oct 05:31
40b3344

Patch Changes

  • #250 ec35174 Thanks @lucasbraum! - Report matching candidate packs that the Action did not use, with their name and status, without changing which packs run.

v0.17.1

Choose a tag to compare

@github-actions github-actions released this 19 Oct 03:35
ca60cd8

Patch Changes

  • #245 2945857 Thanks @lucasbraum! - check finds the migration pack of any member of an upgrade group: the member a pack covers now leads the group, so react 18 → 19 named together with react-dom (as the Uptide Action names every used dependency) is analyzed by the react pack and reported as react, verified, instead of react-dom with no pack.

  • #249 5078510 Thanks @lucasbraum! - setup PRs pin Action v0.17.0

v0.17.0

Choose a tag to compare

@github-actions github-actions released this 19 Oct 02:20
63e91ef

Minor Changes

  • #244 c9d839d Thanks @lucasbraum! - Behavior records: a silent change with a cited source and a usage site the type checker resolved (ADR 0017). The first, for zod 3 → 4: a zod object passed to the MCP SDK as a tool's inputSchema loses additionalProperties: false in the schema clients see. check lists each site, fix tells the agent the quotes and the edit (.strict()) and puts the record under "Decisions for you", saying it also makes the server reject unknown keys. The agent also gets the lines of the target's own CHANGELOG.md that name what the repository uses and say a behavior changed, read from the copy already installed. pack test scores "silent changes caught" against a new silent ground truth and fails on any false positive there.

Patch Changes

  • #243 f1c4a89 Thanks @lucasbraum! - A Stripe PR no longer says "none affect your code". It says how many API changes matched the code by field name and how many breaking changes can't be matched that way, and lists those breaking changes in the open, a new default first. The bundled Stripe changelog is regenerated, and "parameter" no longer tags an entry as a meter change.

v0.16.1

Choose a tag to compare

@github-actions github-actions released this 18 Oct 23:45
0a8e6f1

Patch Changes

v0.16.0

Choose a tag to compare

@github-actions github-actions released this 18 Oct 21:46
63b7c9b

Minor Changes

  • #237 717468a Thanks @lucasbraum! - npx uptide fix gets the Agent SDK executor. The package stays as small as before: @anthropic-ai/claude-agent-sdk is not installed with Uptide. An SDK installed next to Uptide is used as it is; otherwise the first fix that needs it installs the version Uptide is tested with into Uptide's cache (~/.cache/uptide/agent-sdk/<version>), says so in one line with its size, and later runs reuse it. When that install fails (offline, a proxy) or the SDK cannot run, fix runs the patch executor and says so on the first line of its output and at the top of the PR body, with the reason and how to get the SDK executor. report.json records llm.executor and, after a fallback, the reason in llm.sdkMissing. The privacy notice names the SDK only when the SDK will run, and the LLM line names the executor. --agent sdk without a usable SDK stops before any work instead of failing mid-run.

  • #239 e1e8c40 Thanks @lucasbraum! - uptide fix runs only with the Claude Agent SDK; if it can't, it doesn't run. Before the first download, an interactive terminal asks once: uptide fix needs the Claude Agent SDK (about 300 MB, downloaded once to <cache>). Download now? [Y/n] (default yes). With --yes, or without a terminal, it downloads and says so in one line. Once cached, it never asks again. Answering n, an SDK that can't be fetched or loaded (offline, a proxy, no binary for the platform), a missing ANTHROPIC_API_KEY, another provider, or llm.enabled: false / executor: patch in uptide.yml all stop fix with exit 2 before any clone or spending. The run prints one message with the reason and the fix, and --json returns it as error.code: "SDK_UNAVAILABLE". There is no fallback to the patch executor anywhere: the Uptide Action stops the run with the same message. --no-llm, --agent and --provider are gone from help and docs. llm.sdkMissing is gone from report.json, and uptide init no longer writes executor.

Patch Changes

  • #236 9b35b9d Thanks @lucasbraum! - A repository build that fails on the final head is no longer published as a ready PR. When it fails, fix builds the parent commit in the same clone to compare. If the parent fails too, the build line says "already failing before this upgrade" and nothing is blocked. If the parent passes, the upgrade broke the build: verification fails, and the PR opens only as a draft with "Build broken by this upgrade" at the top. If the parent can't be checked out, installed or built, verification still fails and the PR says "Build fails on this upgrade; the parent build could not be checked" with the reason, never that the parent passed. The GitHub Action opens these runs as draft PRs, the same way it opens agent-led runs. The head build also skips workspaces already built on that head, so a workspace whose output a consumer reads is no longer built twice.

  • #233 1ad8071 Thanks @lucasbraum! - The PR description's build check now gives the build's actual result: passed, failed with its first error, or not run and why. When a migration pack doesn't require a build, fix still runs the repository's build once on the final head, and uptide verify runs it again, and reports what happened. "Not required by the pack" now appears next to that result instead of replacing it. Before, the line read "build not required" even when the repository's build failed. A build the pack doesn't require still doesn't block verification or publishing.

  • #238 6f07d3f Thanks @lucasbraum! - An SDK session's edits are no longer thrown away because of one flaky test. Before the gate rejects a session on test failures, it runs the failing test files once more, alone, with their runner and the same isolation as the full run. A file that passes then is recorded as flaky (llm.tasks[].flaky in report.json, and a line in the PR body's review list) and the edits stay. A file that fails twice still rejects them, and a failure that names no test file (a build, a timeout) is never rerun. Final verification keeps its full gate: it runs the flaky files again, and if one fails there, verification fails and the PR body says so. fix also stops starting verification feedback sessions when what is left of --max-cost is below the mean cost of the run's sessions so far, so it no longer starts a session it can't afford; the PR's feedback line says when this happened.

  • #234 066deab Thanks @lucasbraum! - fix on npm no longer loses a package the repo imports without declaring it when the ERESOLVE retry re-resolves the lockfile. If the retry drops such a package from the top of node_modules, it runs again keeping that package and the locked packages that require it at their old versions; if that conflicts, the first retry stands. Either way the summary and the PR body name the package under "Imported but not declared" and suggest adding it to package.json. fix never adds it for you.

v0.15.1

Choose a tag to compare

@github-actions github-actions released this 18 Oct 17:04
41a2e75

Patch Changes

  • #220 cf86d65 Thanks @lucasbraum! - With an assisting agent, a root pin Uptide cannot update safely (a nested override such as overrides > pkg > peerDependencies > react) no longer stops fix with exit 2: the run continues as an agent-led draft that leaves the pin as written and names it, with its exact path and value, at the top of the PR body. The agent-led peer reason now names each blocker's first release that accepts the target, or says none does. An agent-led draft must pass the repository's clean install (npm ci or the manager's frozen install) before delivery; if it does not, the PR says so at the top. Without an agent, with --no-llm, or on a safety refusal, fix still exits 2.

  • #232 e4a2885 Thanks @lucasbraum! - uptide fix spends less wall time on test runs and dependency copies:

    • The agent's own run_tests check runs only its runner's related tests when the test script builds first and then runs a script that is just the runner (pnpm run build && pnpm run test:unit). The gate after the agent's edits and the final verification run exactly what they ran before.
    • The upgrade's install moves the installed node_modules out of its temporary worktree instead of copying it.
    • Each phase of the fix report lists the repository's commands it ran (installs, generators, builds, type-checks, tests, lint, format) with their count and summed wall time. An agent-led run's clean install has its own phase.
  • #223 2dc2162 Thanks @lucasbraum! - fix no longer stops with "baseline tests modified the working tree" when the test run only writes new untracked files, such as a junit test-report.xml that is not gitignored. Those files are recorded as test artifacts (testArtifacts in the report), kept out of every commit, the agent's diff and the pending-changes check, and removed before each later test run, uptide verify included. A change to a tracked file during baseline tests still refuses the run.

  • #215 abddcb3 Thanks @lucasbraum! - check no longer lists possible impact (type changes nothing confirmed as breaking) on its first screen: each package says it in one line, +N possible impact in M files, not counted as breaking, and --details and --json still have every site. A package whose types were partly verified no longer repeats its coverage line in the heading, and a monorepo's unbuilt workspace chains are one count on that line.

  • #213 2de3a18 Thanks @lucasbraum! - A companion pack that moves with the lead's fix (react beside next) now gets its own scan context and inventory, and the PR body carries a section with its review notes.

  • #212 733cfbe Thanks @lucasbraum! - pack test --write records how many breaking sites a finding landed on at any severity and as breaking, out of all breaking sites it scored, and the pack tables show both ("Found, any severity", "Found as breaking") in place of the single recall column. Packs recorded before it show —.

  • #224 09f68df Thanks @lucasbraum! - fix on npm no longer stops when the lock-only install hits ERESOLVE from the old lockfile. It retries without the lockfile entries of the moved packages, their companions and the packages whose peers they satisfy, and only then with the whole lockfile re-resolved; the report says which step worked, and the lockfile check reports the churn as usual. It never uses --legacy-peer-deps or --force. When every step fails, fix ends blocked, naming the conflicting packages from npm's ERESOLVE report. fix --json now prints JSON on every exit, a failure included; when the run already has its report (a PR body over GitHub's size limit), that report comes with the error.

  • #221 ff8de8e Thanks @lucasbraum! - fix no longer rejects an agent patch for test files the parent commit already failed, whichever test scope ran them: when the test script builds first and the build failed on the error being fixed, the start had no test results to compare with, so a correct patch was reverted every round. The patch's tests also run with the pack's follow-ups in place (a test asserting the old Stripe API version), which fix still applies and reports after the agent. When a PR body cannot fit, the stored report.json the error points to is now written first. check and fix now also analyze files that reach a package's wrapper through a barrel (import { getStripeClient } from '../stripe' with export * from './client'). Edited files are formatted with oxfmt and dprint as well as biome and prettier, from the workspace that holds them, with its own configuration, else the root's. The stripe pack adds request-options: request options passed in the params slot (subscriptions.cancel(id, { idempotencyKey })), which SDK 22 rejects, move to the third argument. It runs assisted until a ground-truth repository exercises it.

  • #226 448c3cb Thanks @lucasbraum! - uptide fix judges consumed workspace builds on the final head, not on the tree right after the bump. A build that failed after the bump and passes once the edits land no longer starts a feedback round, adds an "Agent-led draft" reason or shows "Build failed" in the PR body. The builds run again only when the tree changed since their last result, and not at all when the verification build already built those workspaces. The fix report's buildRuns gives the number of builds the run executed and their wall time.

  • #218 13e343b Thanks @lucasbraum! - check folds a compile error into the breaking site it comes from when the compiler traces its value there (an errors.map(e => e.message) under a result.error.errors that zod 4 no longer types, and the narrowing that depended on it). The rule's line shows +N downstream errors, --details lists them under their site, and --json carries them as that finding's downstream. They are no longer separate breaking sites. fix still verifies against every error.

  • #214 195ae10 Thanks @lucasbraum! - A rewrite rule below 80% precision over at least 5 scored ground-truth sites now runs as assisted in fix (react-router dom-imports); smaller samples (next middleware-proxy) stay mechanical and are flagged in the compatibility table. Pack status is unchanged.

  • #218 13e343b Thanks @lucasbraum! - pack test runs a ground-truth repository's code generators (prisma generate, local graphql-codegen) after its install, as fix does. It fetches the Prisma engines the locked version needs itself, so generators stay off the network. A repository whose generator still fails is incomplete and fails the pack, unless its ground truth declares withoutGenerated

  • #227 ae175a9 Thanks @lucasbraum! - A migration whose evidence is larger than GitHub's PR description limit no longer stops fix with "Required migration evidence exceeds the PR body budget" and loses the run. Long required lists get a compact form when they do not fit. Lockfile churn shows counts per kind of change and the first packages. Manual sites are grouped by rule, with counts and the first locations. Remaining type errors show the first entries. Every full list stays in report.json and, in the Uptide Action, in the job summary, which the description links to. If even the compact form does not fit, the description is a short summary that says so at the top: the verdict, the checks, the counts and where the full report is. The branch and report.json are always kept.

    An agent's decisions under "Decisions for you" name the files the agent changed, five at most, and count the rest, instead of every file in the task's scope. A verification-feedback task scoped to the whole repository made each of its decisions a list of hundreds of files.

  • #219 [12dc612](https://github.com/...

Read more