Skip to content

Port ref set|delete|list and format onto the engine - #29980

Open
wmadden-electric wants to merge 3 commits into
s5-orm-adopt-engine-8from
s5-orm-ref-format
Open

Port ref set|delete|list and format onto the engine#29980
wmadden-electric wants to merge 3 commits into
s5-orm-adopt-engine-8from
s5-orm-ref-format

Conversation

@wmadden-electric

Copy link
Copy Markdown
Contributor

Stacked on #29978. Review that first; this diff is the four commands and their tests.

What this looks like in practice

ref list, through the engine binary against examples/prisma-8-demo. The commander printed one line per ref; the engine renders a self-sizing table, and the Invariants column appears only when some ref carries any:

Ref      Contract
head     3d2c56a
staging  0b4bec6

Ref names render green, hashes cyan, and with NO_COLOR=1 every escape is stripped and the column widths still hold.

The decision

Four more commands ported as engine result commands — ref set, ref delete, ref list, format — following the template migration list set. Still additive: the commander CLI keeps working and keeps owning the prisma-next binary.

The one judgement call worth surfacing: these commands now write nothing to stdout in human mode. Two contract rules disagreed. The earlier one named ref set|delete|list among the commands whose payload lines move to the stdout presentation; the later one — written after the design discussion that established what the machine channel is for — says stdout carries only lines another program parses, and a command supplies it only where it has such lines. Set ref "x" → <hash> is a rendering for a reader, not a document. The later rule wins, so those lines are human output on stderr, and the same reasoning applies to format's success line. Recorded in the findings file so the divergence entry quotes the rule that was applied rather than the one it superseded.

Divergences from the commander CLI

  • --config is no longer declared by any of the four (it is the engine's shared flag); --format pretty is --format human.
  • Human output moves to stderr; zero bytes on stdout in human mode, where the commander wrote its confirmation lines there.
  • --json is the engine's result frame ({"kind":"result","envelope":{…}}) rather than the bare document. The documents themselves are unchanged inside envelope.result. The contract predicted "pretty-printed"; the engine frames compactly instead, which is engine-owned and identical for every ported command — recorded so the divergence file words it correctly.
  • ref list renders a table instead of one name → hash [invariants: …] line per ref. The empty case keeps its wording as an info summary.
  • format loses its styled header card; the success line keeps its wording and gains the engine's ✔. format --quiet now renders it.
  • Error envelopes carry typed nextActions and a docs URL instead of fix prose. Exit codes unchanged; no error codes added or changed.
  • No header card was added to any ref command — the inventory records that none prints one today, so none was invented.

Reviewer notes

A module mock in the package's own suite silently broke the ported tests, in both directions. test/commands/ref.test.ts mocked @internal/migration-tools/refs and then dynamically imported the operation module under that mock. With isolate: false the operation stayed cached bound to the stubbed writeRef, so engine-level ref set wrote nothing — and the reverse file ordering defeated the old file's mock instead. That file only ever drove the operation layer, so its coverage moved wholesale onto createTestCli and the file is deleted. One case did not move: a writeRef rejection proving the temp-file-and-rename is atomic, which is @internal/migration-tools' own contract and belongs in its package.

This is the second time in this port that isolate: false plus a module mock has produced a test passing for the wrong reason. Worth remembering as a class.

Verification

pnpm build, pnpm --filter @internal/cli test (133 files, 1589 tests), pnpm typecheck, pnpm lint, pnpm lint:deps, check:error-reference (277 codes, unchanged), plus the six journey files covering these commands and the ref-pointer integration suite. Each command was run through the built binary against a real example project and diffed against the commander CLI, piped and through a pty, with colour and with NO_COLOR=1. Both CLIs' format produce an identical rewrite of the demo's contract.prisma.

🤖 Generated with Claude Code

wmadden-electric and others added 2 commits August 12, 2026 00:15
Four more ORM commands become engine result commands, mounted in the `orm`
family and in the prisma-next bin tree under a new `ref` group. The commander
versions stay: this adds the engine definitions beside them.

Rendering follows the migration commands already on the engine. `ref set` and
`ref delete` each report one summary block; `ref list` builds a `table` the
engine sizes, gaining an Invariants column only when a ref carries any, and
saying "No refs defined" when the project has none; `format` reports the one
summary block the contract asks for. Spans carry a tone — ref names `ref`,
contract hashes `identifier` — and no handler writes an escape sequence, so
NO_COLOR strips the paint without moving a column. None of the four supplies a
`stdout` presentation: their lines are for a reader, not for another program,
so human mode writes nothing to stdout where the commander shell wrote the
payload there.

The handlers call the existing control-API operations with `(config, cwd)` from
the context. `executeFormat` took a `cwd` and ignored it, so a relative
`contract.source.inputs[0]` resolved against the process directory; it now
resolves against the passed one. In production the config loader already hands
over absolute paths, so this only shows up under a harness that supplies a cwd
per run — which is what the new tests do.

Errors return `notOk(normalizeError(...))` at the handler boundary, so every
settled envelope carries typed `nextActions` and no `fix` prose. No error code
changes: all nine the four commands can raise are already in the error
reference.

Coverage moves onto `createTestCli`, asserting envelopes, presented data and
exit codes rather than output bytes, including the rendered ref table and the
fact that `ref delete` removes a ref without prompting. `test/commands/ref.test.ts`
is deleted rather than kept: it drove the operation layer through a module mock
plus a dynamic import, which under `isolate: false` left the operation module
bound to a stubbed `writeRef` for every later file. Its cases are all present in
the new suites, except the injected write failure, which is
`@internal/migration-tools`' own atomicity contract and tested there.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
The journey helpers `runRef` and `runFormat` now go through `runOnEngine`, so
every journey step that sets, lists or deletes a ref — and the format journey —
exercises the ported commands rather than the commander ones, and reports the
engine result (events, stream frames, the presented result) alongside the exit
code. `runFormatWithConfig` is gone: `runOnEngine` reads the journey context, so
a caller no longer threads a directory and a config path by hand.

The journey shell declares the `ref` group, which the engine requires before it
will mount `ref set|list|delete`.

Assertions move with the channels. The format journey reads "Nothing to format"
off stderr, where human prose now goes, and checks stdout stayed empty; its
refusal case pins the dotted code on the errored envelope instead of only a
non-zero exit. The ref pointer e2e drops its console-capture wrapper for the
harness, reading the drawn table off stderr and the refused hash off the
envelope.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
@wmadden-electric
wmadden-electric requested a review from a team as a code owner August 11, 2026 22:19
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro Plus

Run ID: 3e43beec-606c-4575-aeb7-29a974af347e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@pkg-pr-new

pkg-pr-new Bot commented Aug 11, 2026

Copy link
Copy Markdown

Open in StackBlitz

prisma-next

npm i https://pkg.pr.new/prisma-next@29980

@prisma/orm-extension-arktype-json

npm i https://pkg.pr.new/@prisma/orm-extension-arktype-json@29980

@prisma/orm-extension-middleware-cache

npm i https://pkg.pr.new/@prisma/orm-extension-middleware-cache@29980

@prisma/orm-extension-paradedb

npm i https://pkg.pr.new/@prisma/orm-extension-paradedb@29980

@prisma/orm-extension-pgvector

npm i https://pkg.pr.new/@prisma/orm-extension-pgvector@29980

@prisma/orm-extension-postgis

npm i https://pkg.pr.new/@prisma/orm-extension-postgis@29980

@prisma/orm-extension-supabase

npm i https://pkg.pr.new/@prisma/orm-extension-supabase@29980

@prisma/orm-family-mongo

npm i https://pkg.pr.new/@prisma/orm-family-mongo@29980

@prisma/orm-family-sql

npm i https://pkg.pr.new/@prisma/orm-family-sql@29980

@prisma/orm-framework

npm i https://pkg.pr.new/@prisma/orm-framework@29980

@prisma/orm-mongo

npm i https://pkg.pr.new/@prisma/orm-mongo@29980

@prisma/orm-postgres

npm i https://pkg.pr.new/@prisma/orm-postgres@29980

@prisma/orm-sqlite

npm i https://pkg.pr.new/@prisma/orm-sqlite@29980

@prisma/orm-target-mongo

npm i https://pkg.pr.new/@prisma/orm-target-mongo@29980

@prisma/orm-target-postgres

npm i https://pkg.pr.new/@prisma/orm-target-postgres@29980

@prisma/orm-target-sqlite

npm i https://pkg.pr.new/@prisma/orm-target-sqlite@29980

@prisma/orm-toolchain

npm i https://pkg.pr.new/@prisma/orm-toolchain@29980

commit: 8a7603c

@github-actions

Copy link
Copy Markdown
Contributor

size-limit report 📦

Path Size
postgres / no-emit 170.11 KB (0%)
postgres / emit 147.84 KB (0%)
mongo / no-emit 100.41 KB (0%)
mongo / emit 90.25 KB (0%)
cf-worker / no-emit 194.31 KB (0%)
cf-worker / emit 169.66 KB (0%)

…ref-format

Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>

# Conflicts:
#	packages/1-framework/3-tooling/cli/src/orm/cli.ts
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.

2 participants