uptide 0.0.1 → 0.2.0-next.20261002214842

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Uptide contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,222 @@
1
+ # Uptide
2
+
3
+ **Renovate updates the version. We update the code.**
4
+
5
+ Uptide tells you which of your call sites a dependency upgrade breaks, then migrates
6
+ them on a branch it has verified with your own compiler and tests. Today it covers
7
+ **zod 3 → 4** and **stripe**, in TypeScript repositories.
8
+
9
+ ## Quickstart (30 seconds)
10
+
11
+ No account, no config. In your repository, with dependencies installed:
12
+
13
+ ```sh
14
+ npx uptide # where zod and stripe stand: installed, latest, majors behind
15
+ npx uptide check # which of your lines the upgrade breaks
16
+ npx uptide fix --only zod # migrate on a new branch; nothing is pushed
17
+ ```
18
+
19
+ Requires Node 20 or newer. `check` reads npm, pnpm (workspaces and catalogs), yarn
20
+ classic and bun (text lockfile) repositories. `fix` supports npm (lockfile v2/v3, including workspaces), pnpm, and Yarn classic/Berry with the node-modules linker.
21
+
22
+ ## What `check` prints
23
+
24
+ Real output, zod 3.23.8 → 4.6.5 on the pnpm workspace fixture in
25
+ [`packages/cli/smoke/fixtures/pnpm`](packages/cli/smoke/fixtures/pnpm):
26
+
27
+ ```console
28
+ $ uptide check --only zod
29
+ uptide check · smoke-pnpm (pnpm, 2 packages) · 3.0s
30
+
31
+ zod 3.23.8 → 4.6.5 major ✗ 4 breaking in 2 files 4 by rule
32
+
33
+ zod
34
+ ✗ New error API (required_error → error) 4 sites by rule
35
+
36
+ Next
37
+ npx uptide fix --only zod migrate on a new branch, verify, no push
38
+ npx uptide check --only zod --details every site and reason
39
+ ```
40
+
41
+ One row per dependency, one line per change, and the commands to run next. Each change
42
+ says who migrates it, from a dry run of the same rules `fix` applies: **by rule** (a
43
+ deterministic transform), **by agent** (the assisted fixer, verified by your compiler), or
44
+ **manual** (no migration pack covers it). `--details` lists every site with its snippet,
45
+ the reason, the raw compiler message and the analysis notes.
46
+
47
+ While it runs, a terminal shows one live line with the current phase, which disappears
48
+ when the work ends; `--verbose` keeps one line per phase with timings. In a pipe or with
49
+ `--ci`, stderr gets a start line and the final timing. The report is on stdout. `check`
50
+ diffs the public API of the installed and the target version, finds your usages of what
51
+ changed, compiles your code against the target, and loads both versions in a sandboxed
52
+ Node. Nothing in your repository is executed.
53
+
54
+ | Flag | Meaning |
55
+ | --- | --- |
56
+ | `--only zod,stripe` | dependencies to check (the default); `--only all` checks every dependency |
57
+ | `--target zod@4.6.5` | exact target, repeatable; default is `latest` |
58
+ | `--details` | every site, reason, compiler message and analysis note |
59
+ | `--verbose` | one progress line per analysis phase, with timings |
60
+ | `--cwd <dir>` | repository to work on |
61
+ | `--json` | the full report as JSON on stdout |
62
+ | `--ci` | plain log output: no color, no spinner (`NO_COLOR` is respected too) |
63
+
64
+ Exit codes, for scripts and CI: **0** nothing breaking, **1** breaking changes found,
65
+ **2** uptide could not answer (bad arguments, unsupported repository, no network). When
66
+ it cannot answer, it says why and prints the exact command to run next.
67
+
68
+ ## What `fix` does, and how it verifies
69
+
70
+ On the same fixture (output abridged):
71
+
72
+ ```console
73
+ $ uptide fix --only zod --no-llm
74
+ ✔ Repository smoke-pnpm (pnpm workspace, 2 packages) (29ms)
75
+ assisted fixes off (--no-llm): no code leaves this machine
76
+ ✔ Migration of zod (check, upgrade, fixes, verification) verification passed (5.3s)
77
+
78
+ ## Upgrade zod 3.23.8 → 4.6.5
79
+
80
+ Assisted fixes disabled (--no-llm).
81
+
82
+ | **Changes** | 4 sites in 2 files · 4 by rule · 0 by agent |
83
+ | **Types** | ✅ 4 errors after the bump → 0 |
84
+ ```
85
+
86
+ Everything below happens in a temporary clone of your repository, never in your checkout:
87
+ your branch, files, git hooks and git config are compared before and after and must be
88
+ the same. You get the migration branch as a ref and the run stored inside `.git`. The
89
+ clone is removed when the run is over; it is kept, and its path printed, when the run
90
+ fails or you pass `--keep`, and `uptide clean` removes kept clones older than 7 days.
91
+
92
+ 1. **Starts clean.** It needs a git repository with a clean working tree, and works on a
93
+ new branch `uptide/<package>-<version>`. Nothing is pushed unless you pass `--pr --yes`.
94
+ 2. **Upgrades.** Bumps the version in every workspace that declares it (and in pnpm
95
+ catalogs), preserving `^`, `~`, or exact ranges. Installs run in a temporary git worktree with lifecycle scripts disabled. The real package manager produces the lockfile; Uptide rejects changes outside the target dependency subtree before copying it back unchanged. One commit.
96
+ 3. **Rule-based fixes.** Deterministic rewrites for the changes it has rules for, such as
97
+ zod's `required_error` / `invalid_type_error` (add `--include-deprecated` for
98
+ `z.string().email()`-style chains). One commit.
99
+ 4. **Assisted fixes (optional).** With `ANTHROPIC_API_KEY` set, sites the rules cannot
100
+ migrate go to the LLM one at a time. A patch is kept only if it removes its compiler
101
+ error and introduces none; otherwise it is reverted and the site is left for you.
102
+ `--no-llm` turns this off.
103
+ 5. **Verifies.** Type-checks with *your* TypeScript (or the bundled compiler when absent) before and after and subtracts the
104
+ errors you already had; runs the tests of the affected workspaces (each workspace's
105
+ `test` script, else the vitest or jest configuration that covers it, scoped to the
106
+ tests related to the migrated files, else the root `test` script) and reports what ran;
107
+ by default only tests that need no database, cache or queue run, and the report counts the
108
+ integration tests it left out (`--with-services --yes` includes them, after printing what
109
+ they connect to); formats the files it edited, and only those, with your formatter and runs your lint
110
+ (biome, prettier, eslint) on them, where a new lint failure fails verification; for zod,
111
+ compares v3 and v4 behaviour of your schemas on generated inputs. The exit code is 0
112
+ only if no new type error remains and tests pass. Passing compilation does not prove
113
+ runtime equivalence, so the report in `.uptide/pr-body.md` lists what to review.
114
+
115
+ Stripe API-version changes are never rewritten by rule: they are assisted or left for
116
+ you, with the relevant changelog entries and a dashboard/webhook checklist in the report.
117
+
118
+ ## Scope
119
+
120
+ - **Dependencies:** zod 3 → 4 and stripe (14 and newer). Other dependencies can be
121
+ checked with `uptide check --only <package>`, but that generic check is frozen
122
+ ([decision](docs/decisions/0010-check-freeze.md)) and has no migrations.
123
+ - **Languages:** TypeScript, and JavaScript the compiler can see (`allowJs`).
124
+ - **Package managers:** `check` on npm, pnpm, yarn classic, bun; `fix` on npm v2/v3, pnpm, and Yarn classic/Berry (node-modules).
125
+ - **Not supported:** Yarn Plug'n'Play, bun's binary lockfile, Deno.
126
+
127
+ ## Privacy
128
+
129
+ Analysis runs locally. Your code is sent only to the LLM provider (Anthropic), only
130
+ for assisted fixes in `uptide fix`, and only with your own ANTHROPIC_API_KEY: for each
131
+ site the rules cannot migrate, the finding, the enclosing function and the compiler
132
+ error. `uptide fix --no-llm` turns assisted fixes off. No telemetry, no account.
133
+ Other network use: your npm registry for package metadata and tarballs, and GitHub
134
+ only when you pass `fix --pr` or run `pr-body`.
135
+
136
+ ## GitHub Action: Renovate / Dependabot
137
+
138
+ Use [the example workflow](examples/uptide-workflow.yml), pinning a reviewed commit of `lucasbraum/uptide`. It checks same-repository bot PRs on `pull_request`
139
+ `opened`/`synchronize`, detects zod/stripe upgrades from manifests, catalogs and lockfile
140
+ importers, and maintains one sticky findings comment. `only` selects dependencies;
141
+ `paths` selects repository-relative source directories/globs.
142
+
143
+ `fix: 'true'` plus `anthropic-api-key` enables migration. Comparison uses **PR-head
144
+ source with the base dependency graph** in a temporary worktree. Final verification
145
+ uses the actual PR-head manifests/lockfile; only source patches are transferred. A
146
+ passing migration pushes **one commit on the existing PR branch**. Manual sites,
147
+ failed tests/types, or a changed PR head prevent publication. No force-push or merge.
148
+ Current migration support is TypeScript, zod and stripe, using npm, pnpm or Yarn with node_modules. Missing workspace test
149
+ scripts are reported, not claimed as passing tests. Code context may be sent to
150
+ Anthropic only in assisted mode. Install/test children receive no API/token secrets.
151
+
152
+ Use `contents: write` and `pull-requests: write`, `persist-credentials: false`, and the
153
+ same-PR concurrency group shown in the example. Dependabot PRs normally receive a
154
+ read-only `GITHUB_TOKEN` and do not receive ordinary Actions secrets: configure the
155
+ key and an appropriately scoped write token as **Dependabot secrets**, or run in a
156
+ maintainer-controlled workflow. Do not change to `pull_request_target` to bypass
157
+ this boundary. Fork PRs are skipped. See [GitHub's Dependabot restrictions](https://docs.github.com/en/code-security/reference/supply-chain-security/troubleshoot-dependabot/dependabot-on-actions).
158
+
159
+ ```sh
160
+ pnpm eval:action # local GitHub API simulation + real check/fix/tsc/tests/git remote
161
+ ```
162
+
163
+ This creates an isolated demo repository and bare local remote under `eval-out/`,
164
+ with a zod 3 baseline, a Renovate-style bump branch, and the verified migration result.
165
+ It also proves that a final-verification failure cannot push. The generated README
166
+ contains commands to publish your throwaway repository. **No hosted GitHub run or PR
167
+ is created by this evaluation.** The real workflow requires a bot-authored PR; a
168
+ human-authored imitation is intentionally rejected.
169
+
170
+ ## PR descriptions
171
+
172
+ `fix` saves `.uptide/report.json` with the verified commit, Uptide version/commit, rule IDs, patches, agent
173
+ reasoning and run metadata. PR bodies show a computed risk, a five-row summary, changes
174
+ grouped by rule, and actionable review items.
175
+
176
+ To regenerate an existing description without another migration or any push:
177
+
178
+ ```sh
179
+ uptide pr-body --pr 82 --preview # review the complete proposal first
180
+ uptide pr-body --pr 82 # update only the description
181
+ # For a retained eval run, add --cwd /path/to/target/repo --run /path/to/report.json.
182
+ ```
183
+
184
+ The selected PR must match the stored run's branch and verified commit. Risk is Low
185
+ for verified rule-only edits, Medium for agent edits, sensitive paths or missing tests,
186
+ and High for unverified sites, behavior changes or remaining manual work. Unchecked
187
+ schema samples are called out separately; they do not imply unresolved compiler sites.
188
+
189
+ Builds embed the Uptide commit and whether its source checkout had working-tree changes.
190
+ `pnpm exec tsx scripts/reverify-run.ts <run.json> [output.json]` refreshes behavior
191
+ and type verification on the recorded commit without installing or changing source.
192
+ Diffs, file lists, verification and run details are collapsed; the Action comment and
193
+ terminal share the compact migration renderer.
194
+
195
+ ## Development
196
+
197
+ ```sh
198
+ pnpm test # offline regressions
199
+ UPTIDE_NETWORK=1 pnpm test # real package digests and Stripe tsc fixture
200
+ pnpm eval:fix ../wayapi --without-key
201
+ pnpm eval:fix ../wayapi --with-key
202
+ # Only after reviewing a successful eval, publish from another temporary worktree:
203
+ pnpm eval:fix ../wayapi --with-key --pr --yes
204
+ pnpm eval:fix /path/to/repo --only=stripe --target=stripe@22.6.2 --without-key
205
+ ```
206
+
207
+ `eval:fix` creates a temporary git worktree, copies installed dependencies (not symlinks
208
+ to the source repo), and retains the result for review. Artifacts go in `eval-out/`.
209
+ `--with-key` fails explicitly when no key is configured. `pnpm eval:stripe-fixture`
210
+ measures the checked-in Stripe consumer with real `tsc`; `pnpm build:stripe-changelog`
211
+ refreshes the versioned public changelog JSON. Migration execution never fetches it.
212
+
213
+ `uptide diff <pkg> <from> <to> [--json]` compares the full public surface of two
214
+ versions. Tarballs, surfaces and runtime probes are cached in `~/.cache/uptide/`.
215
+ Releasing is described in [docs/releasing.md](docs/releasing.md); `pnpm smoke` runs the
216
+ packed CLI against npm v3, npm workspaces v2, pnpm catalogs, Yarn classic and Yarn Berry fixtures in clean Node 20/22 containers. Run `pnpm smoke 20` and `pnpm smoke 22`. Each case verifies zod migration and a compatible Stripe SDK upgrade without an LLM; lifecycle-script traps must remain untouched. Lockfile diffs and JSON results are saved beside the temporary CLI tarball.
217
+
218
+ Yarn PnP remains unsupported. Missing package-manager binaries or mismatched pinned versions fail with an exact Corepack recovery command. Unsupported range/lockfile syntax fails explicitly rather than silently broadening the upgrade.
219
+
220
+ ## License
221
+
222
+ [MIT](LICENSE).