| Add psl-playground: browser PSL editor wired to the language server (#856) ## Linked issue n/a — small, self-contained dev tool. Builds on the language server from #852 (`prisma-next lsp`). ## Summary A private `apps/lsp-playground` package providing the `psl-playground` binary: it opens a PSL file in a browser CodeMirror 6 editor wired to `prisma-next lsp` over a single-port WebSocket bridge, giving you live PSL parse diagnostics without setting up an editor extension. ## At a glance ```bash # Open a blank scratch schema (no file, no config needed): psl-playground # Or open an existing PSL file: psl-playground path/to/schema.psl ``` Then open `http://localhost:5273/` and edit; diagnostics from `@prisma-next/psl-parser` update live. With no project config, the playground assumes a default-postgres setup. ``` CodeMirror 6 --LSP/WebSocket--> shared http server (port 5273) --spawn+stdio--> prisma-next lsp --stdio (codemirror-languageserver) (Vite middleware + vscode-ws-jsonrpc) (@prisma-next/language-server) ``` ## Decision This ships one thing: a browser playground for the PSL language server, as a private `apps/` package so it stays out of the framework build graph and `lint:deps` layering. Three design decisions shape it: 1. **CodeMirror 6 + `codemirror-languageserver`** for the editor (lighter than Monaco; grows into hover/completion as the server gains them). 2. **One port for everything.** Vite runs in middleware mode on a single `http.Server`; the LSP WebSocket bridge attaches an `upgrade` listener that only claims `/psl`, so the editor, Vite HMR, and the language server all share port 5273. 3. **PSL file optional; config optional.** With no argument the playground stages a scratch schema and generates a default-postgres config; an existing file already inside a project opens in place under its own config. ## How it fits together 1. **Resolve what to open.** `src/cli.ts` resolves the schema and the config above it: an explicit `--config` + file opens in place; an existing file inside a project opens in place under its discovered config; otherwise (no file / missing path / file with no project config) the schema is staged into `.playground/` and a default-postgres config is generated beside it. 2. **Stage for resolvability.** Staging into `.playground/` (`src/default-config.ts`, `stageSchema` in `src/cli.ts`) is required because the language server discovers a document's config by walking up from the document's own path, and the generated config's `@prisma-next/*` imports must resolve through the workspace `node_modules`. 3. **Bridge stdio over WebSocket.** `src/bridge.ts` attaches to the shared server, and on each `/psl` connection spawns `prisma-next lsp --stdio` and forwards JSON-RPC via `vscode-ws-jsonrpc` (`createServerProcess` + `forward`). 4. **Serve the editor.** Vite serves the page; a generated `src/client/runtime.ts` hands the client the document URI, root, schema text, and WS path; `src/client/main.ts` mounts CodeMirror with the `languageServer` extension pointed at the same origin. ## Behavior changes & evidence - `psl-playground` with **no argument** opens a scratch schema under default-postgres and publishes live diagnostics — `apps/lsp-playground/src/cli.ts`, `apps/lsp-playground/src/default-config.ts`. Validated manually end-to-end (no-arg launch → `PSL_UNTERMINATED_BLOCK`). - `psl-playground <file>` opens an existing schema; if it has no project config it is staged as a sandbox copy under default-postgres, otherwise opened in place — `apps/lsp-playground/src/cli.ts`. Validated manually (staged-copy launch → diagnostics). - Editor and LSP share a single port via Vite middleware mode + an `/psl`-scoped upgrade handler — `apps/lsp-playground/src/cli.ts`, `apps/lsp-playground/src/bridge.ts`. ## Reviewer notes - **Largest file is `src/cli.ts`** — the arg parsing + schema/config resolution + single-port wiring live there. The branching in schema/config resolution is the part to spot-check. - **Staging edits a copy, not your file.** For files outside a project, the playground deliberately opens a copy under `.playground/` rather than your original — both because the server needs the config's `@prisma-next/*` imports to resolve and because walk-up config discovery requires the schema to sit beside the generated config. This is intentional sandbox behaviour. - **Generated artefacts are gitignored.** `.playground/` and `src/client/runtime.ts` are written at launch and excluded from git; only sources are tracked. - **Build prerequisite.** The bridge spawns the built CLI (`@prisma-next/cli`'s `dist/cli.js`) and the generated config loads built postgres-stack packages, so a fresh checkout needs `pnpm install` + a build of those packages before first run. Noted in the README. - **No automated tests.** This is a dev tool validated by manual end-to-end runs (documented in Verification); it ships no unit tests. ## Compatibility / migration / risk No framework surface changes. `apps/` is exempt from `lint:deps`; the package is `private` and unpublished. Zero risk to shipped code. ## Testing performed - `pnpm --filter @prisma-next/lsp-playground typecheck` — clean - `pnpm --filter @prisma-next/lsp-playground lint` — clean (exit 0) - Manual end-to-end against rebased `origin/main`: no-arg launch and existing-file launch both serve the editor on port 5273 and publish `PSL_UNTERMINATED_BLOCK` for a broken schema over the shared-port WebSocket bridge. ## Skill update n/a — internal dev tool; no user-facing CLI/API/config surface of the framework changes (the `psl-playground` binary lives only in this private package). ## Alternatives considered - **Monaco + `monaco-languageclient`** — heavier (pulls the vscode-api shims); CodeMirror 6 is lighter and sufficient for diagnostics, and grows into later language features. - **Two ports (separate Vite + bridge servers)** — the original shape; collapsed to one shared `http.Server` to avoid hogging two ports. - **A Zed/VS Code dev extension** — more setup and editor-specific; a browser playground is editor-agnostic and instantly shareable. - **`lsp-ws-proxy` (Rust) or the 8-year-old `jsonrpc-ws-proxy`** — `vscode-ws-jsonrpc` is maintained, all-JS, and `pnpm`-installable. ## Checklist - [x] All commits are signed off (`git commit -s`) per the DCO. - [x] I read CONTRIBUTING.md and the change is scoped to one logical concern. - [x] Tests are updated (n/a — dev tool validated by manual end-to-end runs; no behavioural delta to framework code). - [ ] The PR title is in `TML-NNNN: <sentence-case title>` form (n/a — no Linear ticket; self-contained dev tool). - [x] The **Skill update** section above is filled in. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes **New Features** - Added an LSP playground web application for live PSL schema editing and diagnostics. - Supports opening an existing schema or using a scratch schema. - Provides real-time LSP updates in the browser via a WebSocket-to-LSP bridge. - Automatically locates the nearest project configuration or generates a default PostgreSQL configuration when needed. **Documentation** - Updated the playground README with local usage and workflow details. **Chores** - Updated ignore rules to exclude generated/staged playground output. **Tests** - Added a sample “broken” PSL fixture for validation scenarios. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Serhii Tatarintsev <tatarintsev@prisma.io> | 3 个月前 |
| refactor: rename every user-facing prisma-next identifier to Prisma 8 (#30262) ## Linked issue n/a — no Linear ticket. Completes the rename that #30248 started for prose; builds on #30261. ## At a glance Every `prisma-next` identifier a user can see is renamed. Before and after, for a scaffolded project: ```text // use prisma-next → // use prisma-8 (schema header) prisma-next.md → prisma-8.md (primer at the project root) PRISMA_NEXT_DISABLE_TELEMETRY → PRISMA_DISABLE_TELEMETRY (and every other PRISMA_NEXT_* variable) ~/.config/prisma-next/ → ~/.config/prisma-8/ (per-user telemetry config) prisma-next contract emit → prisma contract emit (CLI invocations in docs, fixtures, recordings) ``` ## Summary After #30248 the product was called Prisma 8 in prose, but the working name was still written into user projects and printed by the CLI: the schema header, the primer file, the environment variables, the per-user config directory, the language-server diagnostic source, the Standard Schema vendor string, the contract brand symbol, the advisory-lock domain, and about 650 fixture and doc files that spelled out `prisma-next …` commands. This PR renames all of it in one pass and tightens the legacy-name lint so the only occurrences left are the ones with a reason. ## Decision One commit. The mapping: | Surface | Before | After | |---|---|---| | Schema header | `// use prisma-next` | `// use prisma-8` | | Primer file `init` writes | `prisma-next.md` | `prisma-8.md` | | CLI environment variables | `PRISMA_NEXT_*` | `PRISMA_*` | | Per-user config directory | `prisma-next/` | `prisma-8/` | | Language-server diagnostic source | `prisma-next` | `prisma` | | Standard Schema vendor, VS Code publisher | `prisma-next` | `prisma` | | Contract brand symbol | `__prisma_next_brand__` | `__prisma_8_brand__` | | Postgres advisory-lock domain | `prisma_next.contract.marker` | `prisma_8.contract.marker` | | Example database names | `prisma_next_*` | `prisma_8_*` | | README banner image | `images/prisma-next.png` | `images/prisma-8.png` | | Telemetry docs URL | `prisma-next.dev/docs/…` | `www.prisma.io/docs/…` | | New-issue links | `github.com/prisma/prisma-next/issues/new` | `github.com/prisma/orm/issues/new` | | CLI invocations in prose, fixtures, and recordings | `prisma-next db verify` | `prisma db verify` | `prisma-8` is the slug the repo already uses for the skill, the examples, and the upgrade directories, so it is the slug for everything that needs one. Environment variables drop the infix entirely because `PRISMA_*` is what users expect and nothing else in the repo claims those names. What keeps the old name, each with a lint allowance that says why: - **Dated records**: changelog, release notes, ADRs, shipped upgrade instructions, gotcha logs, the framework-gaps review, and the `projects/` and `drive/` write-ups. - **Pinned links** into the old repository by number, Linear slugs, and links to ADRs whose filenames carry the name. - **`@cipherstash/prisma-next`**, a third party's published package name. - **Retirement proofs**: the list of old skill directories `init` deletes, and the tests asserting that no `prisma-next` bin or skill directory is installed any more. ## Behavior changes & evidence - **Schema header.** The inferred-schema printer and the `init` templates write `// use prisma-8`. The language server accepts both headers, so existing schemas keep their diagnostics and completion, and its Format action rewrites the old header to the new one. [packages/1-framework/3-tooling/language-server/src/schema-directive.ts](packages/1-framework/3-tooling/language-server/src/schema-directive.ts), [packages/1-framework/2-authoring/psl-printer/src/ast-to-print-document.ts](packages/1-framework/2-authoring/psl-printer/src/ast-to-print-document.ts). Evidence: the `renameLegacyDirective` tests, the server test that formats a legacy-headed schema, and the psl-printer tests. - **Environment variables.** Telemetry gating, the endpoint override, and the debug switch read the new names. `PRISMA_NEXT_DISABLE_TELEMETRY` is still honoured as an opt-out so nobody is silently opted back in; the endpoint and debug spellings are not. [packages/1-framework/3-tooling/cli-telemetry/src/gating.ts](packages/1-framework/3-tooling/cli-telemetry/src/gating.ts). Evidence: cli-telemetry gating tests. - **Per-user config directory.** [packages/1-framework/3-tooling/cli-telemetry/src/user-config.ts](packages/1-framework/3-tooling/cli-telemetry/src/user-config.ts). Existing users see the telemetry consent prompt once more; nothing else is lost. - **Primer file.** [packages/1-framework/3-tooling/cli/src/orm/init-scaffold.ts](packages/1-framework/3-tooling/cli/src/orm/init-scaffold.ts). Evidence: init-scaffold tests and template snapshots. - **Advisory-lock domain.** A CLI on this version and one on the previous version take different locks for the same marker. Both versions running migrations against one database at the same moment is already unsupported. - **Upgrade instructions.** Entries for the header, the environment variables, and the primer file are recorded in the rc.9 → rc.10 app and extension instructions with detection patterns, so the published upgrade skill applies the rename. ## Testing performed - `pnpm test` in cli (1437), cli-telemetry (112), language-server (312), psl-printer (63), framework-components (672), target-postgres (1607), vite-plugin-contract-emit (31), emitter (231), and `pnpm test:scripts` (507): all pass after `pnpm build`. The language-server tests hard-coded the old header's length in semantic-token arrays and span offsets; those expectations are updated. - Committed migration steps and their content-addressed contract snapshots are left untouched, since rewriting them would break their hashes; the lint treats them as dated records. - `pnpm lint:legacy-name` passes with the tightened allowances; `node --test scripts/lint-legacy-name.test.mjs` passes (14 tests, including new negative cases for the header, primer, and skill names). - `pnpm check:upgrade-coverage --mode pr --prev origin/main` passes. ## Skill update `skills/prisma-8` references and the two rc.9 → rc.10 upgrade instruction files are updated in this PR. ## Checklist - [x] All commits are signed off (`git commit -s`) per the [DCO](../CONTRIBUTING.md#developer-certificate-of-origin-dco). - [x] I read [CONTRIBUTING.md](../CONTRIBUTING.md) and the change is scoped to one logical concern. - [x] Tests are updated. - [ ] The PR title is in `TML-NNNN: <sentence-case title>` form. No Linear ticket exists for this change. - [x] The **Skill update** section above is filled in. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> | 15 天前 |
| feat(lsp-playground): multi-file scratch project with tabs and lazy opening (#30394) ## Overview The LSP playground becomes the multi-file test bench for the `multifile-psl` project: it no longer takes a schema path, and instead always opens a gitignored scratch directory (`apps/lsp-playground/.playground/scratch/`) seeded once with a three-file schema behind a glob config (`contract: './scratch/**/*.prisma'`). A tab strip renders one tab per file; a tab's document is opened in Monaco — and `textDocument/didOpen` sent — only on first click, so never-clicked tabs remain genuinely unmanaged, exactly like closed files in a real editor. ## Changes - **CLI (`src/cli.ts`):** positional schema arguments removed (a clear error points at the scratch workflow); the runtime contract served at `/__psl_playground_runtime.json` goes plural — `members: { uri, text }[]` plus the scratch-root URI. Members are re-discovered from disk on every start, so files added or edited between runs are picked up. - **Seeding (`src/default-config.ts`):** the scratch directory is seeded on first run with two directive-carrying files forming a cross-file relation and a namespace reopened across both, plus one directive-less file (the membership-exclusion demo); an existing scratch directory is never overwritten, so edits survive restarts. The generated config uses the glob. - **Client (`src/client/main.ts`, `index.html`):** one memory file per member in the filesystem overlay; tab strip with lazy opening. Switching to an already-open tab swaps the visible model without re-opening; each opened tab holds a pinned model reference — without it, the editor's model swap disposes its own reference and fires a spurious `didClose`/re-`didOpen` pair (caught by wire-level testing, not code review). - **`src/find-config.ts` deleted** — orphaned once positional arguments went away. - **README:** no-args usage, the tab/lazy-open behavior, and a plainly stated interim limitation (below), including annotations on the Manual QA steps that currently produce no output. ## Why The project's third slice (`lsp-whole-project`) makes the language server glob-aware and disk-reading; this bench exists so that work can be exercised by hand as it develops. The lazy-open design is deliberate: eager-opening every tab would make every file managed and the server's disk path unreachable from the playground. ## Interim limitation (deliberate) The current language server treats config `inputs` as literal paths, so against this glob config it is entirely inert — no diagnostics, folding, semantic tokens, or formatting, for any file, opened or not. That is the staged gap: when the glob-aware slice lands, opened and never-opened tabs alike come to life with zero further playground changes. Discovered during this slice's wire-level verification; the slice spec and project plan were amended accordingly (recorded as a falsified assumption in the project trace). ## Scope `apps/lsp-playground/**` only, plus project planning artifacts under `projects/multifile-psl/`. No language-server, provider, or config-package changes. ## Verification Wire-level probe (headless Chromium driving the real page, every LSP frame logged): exactly one `didOpen` per clicked tab, none before clicking, zero `didClose` across tab switches. Seed-once proven by editing a file and restarting. Positional-argument error path exercised. Playground typecheck and lint clean; re-validated (with a fresh server smoke) after merging `origin/main`, whose config-resolution change (`b313e84c58`) this bench's generated-config path survives. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * The playground now opens a multi-file scratch project with a file-picker sidebar. Files open when selected, and edits stay in memory. * Three example Prisma files are added when the scratch project is first created or is empty; existing files are preserved. * **Changes** * Launch the playground without a schema path; supplying one is an error. The schema path is no longer shown in the header. * Diagnostics, folding, semantic tokens, and formatting currently produce no output for scratch files. * **Documentation** * Updated setup and manual QA instructions to describe the scratch project and its current limitations. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Steven McClankerton <tatarintsev@prisma.io> Co-authored-by: Steven McClankerton <tatarintsev@prisma.io> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> | 1 天前 |
| Add psl-playground: browser PSL editor wired to the language server (#856) ## Linked issue n/a — small, self-contained dev tool. Builds on the language server from #852 (`prisma-next lsp`). ## Summary A private `apps/lsp-playground` package providing the `psl-playground` binary: it opens a PSL file in a browser CodeMirror 6 editor wired to `prisma-next lsp` over a single-port WebSocket bridge, giving you live PSL parse diagnostics without setting up an editor extension. ## At a glance ```bash # Open a blank scratch schema (no file, no config needed): psl-playground # Or open an existing PSL file: psl-playground path/to/schema.psl ``` Then open `http://localhost:5273/` and edit; diagnostics from `@prisma-next/psl-parser` update live. With no project config, the playground assumes a default-postgres setup. ``` CodeMirror 6 --LSP/WebSocket--> shared http server (port 5273) --spawn+stdio--> prisma-next lsp --stdio (codemirror-languageserver) (Vite middleware + vscode-ws-jsonrpc) (@prisma-next/language-server) ``` ## Decision This ships one thing: a browser playground for the PSL language server, as a private `apps/` package so it stays out of the framework build graph and `lint:deps` layering. Three design decisions shape it: 1. **CodeMirror 6 + `codemirror-languageserver`** for the editor (lighter than Monaco; grows into hover/completion as the server gains them). 2. **One port for everything.** Vite runs in middleware mode on a single `http.Server`; the LSP WebSocket bridge attaches an `upgrade` listener that only claims `/psl`, so the editor, Vite HMR, and the language server all share port 5273. 3. **PSL file optional; config optional.** With no argument the playground stages a scratch schema and generates a default-postgres config; an existing file already inside a project opens in place under its own config. ## How it fits together 1. **Resolve what to open.** `src/cli.ts` resolves the schema and the config above it: an explicit `--config` + file opens in place; an existing file inside a project opens in place under its discovered config; otherwise (no file / missing path / file with no project config) the schema is staged into `.playground/` and a default-postgres config is generated beside it. 2. **Stage for resolvability.** Staging into `.playground/` (`src/default-config.ts`, `stageSchema` in `src/cli.ts`) is required because the language server discovers a document's config by walking up from the document's own path, and the generated config's `@prisma-next/*` imports must resolve through the workspace `node_modules`. 3. **Bridge stdio over WebSocket.** `src/bridge.ts` attaches to the shared server, and on each `/psl` connection spawns `prisma-next lsp --stdio` and forwards JSON-RPC via `vscode-ws-jsonrpc` (`createServerProcess` + `forward`). 4. **Serve the editor.** Vite serves the page; a generated `src/client/runtime.ts` hands the client the document URI, root, schema text, and WS path; `src/client/main.ts` mounts CodeMirror with the `languageServer` extension pointed at the same origin. ## Behavior changes & evidence - `psl-playground` with **no argument** opens a scratch schema under default-postgres and publishes live diagnostics — `apps/lsp-playground/src/cli.ts`, `apps/lsp-playground/src/default-config.ts`. Validated manually end-to-end (no-arg launch → `PSL_UNTERMINATED_BLOCK`). - `psl-playground <file>` opens an existing schema; if it has no project config it is staged as a sandbox copy under default-postgres, otherwise opened in place — `apps/lsp-playground/src/cli.ts`. Validated manually (staged-copy launch → diagnostics). - Editor and LSP share a single port via Vite middleware mode + an `/psl`-scoped upgrade handler — `apps/lsp-playground/src/cli.ts`, `apps/lsp-playground/src/bridge.ts`. ## Reviewer notes - **Largest file is `src/cli.ts`** — the arg parsing + schema/config resolution + single-port wiring live there. The branching in schema/config resolution is the part to spot-check. - **Staging edits a copy, not your file.** For files outside a project, the playground deliberately opens a copy under `.playground/` rather than your original — both because the server needs the config's `@prisma-next/*` imports to resolve and because walk-up config discovery requires the schema to sit beside the generated config. This is intentional sandbox behaviour. - **Generated artefacts are gitignored.** `.playground/` and `src/client/runtime.ts` are written at launch and excluded from git; only sources are tracked. - **Build prerequisite.** The bridge spawns the built CLI (`@prisma-next/cli`'s `dist/cli.js`) and the generated config loads built postgres-stack packages, so a fresh checkout needs `pnpm install` + a build of those packages before first run. Noted in the README. - **No automated tests.** This is a dev tool validated by manual end-to-end runs (documented in Verification); it ships no unit tests. ## Compatibility / migration / risk No framework surface changes. `apps/` is exempt from `lint:deps`; the package is `private` and unpublished. Zero risk to shipped code. ## Testing performed - `pnpm --filter @prisma-next/lsp-playground typecheck` — clean - `pnpm --filter @prisma-next/lsp-playground lint` — clean (exit 0) - Manual end-to-end against rebased `origin/main`: no-arg launch and existing-file launch both serve the editor on port 5273 and publish `PSL_UNTERMINATED_BLOCK` for a broken schema over the shared-port WebSocket bridge. ## Skill update n/a — internal dev tool; no user-facing CLI/API/config surface of the framework changes (the `psl-playground` binary lives only in this private package). ## Alternatives considered - **Monaco + `monaco-languageclient`** — heavier (pulls the vscode-api shims); CodeMirror 6 is lighter and sufficient for diagnostics, and grows into later language features. - **Two ports (separate Vite + bridge servers)** — the original shape; collapsed to one shared `http.Server` to avoid hogging two ports. - **A Zed/VS Code dev extension** — more setup and editor-specific; a browser playground is editor-agnostic and instantly shareable. - **`lsp-ws-proxy` (Rust) or the 8-year-old `jsonrpc-ws-proxy`** — `vscode-ws-jsonrpc` is maintained, all-JS, and `pnpm`-installable. ## Checklist - [x] All commits are signed off (`git commit -s`) per the DCO. - [x] I read CONTRIBUTING.md and the change is scoped to one logical concern. - [x] Tests are updated (n/a — dev tool validated by manual end-to-end runs; no behavioural delta to framework code). - [ ] The PR title is in `TML-NNNN: <sentence-case title>` form (n/a — no Linear ticket; self-contained dev tool). - [x] The **Skill update** section above is filled in. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes **New Features** - Added an LSP playground web application for live PSL schema editing and diagnostics. - Supports opening an existing schema or using a scratch schema. - Provides real-time LSP updates in the browser via a WebSocket-to-LSP bridge. - Automatically locates the nearest project configuration or generates a default PostgreSQL configuration when needed. **Documentation** - Updated the playground README with local usage and workflow details. **Chores** - Updated ignore rules to exclude generated/staged playground output. **Tests** - Added a sample “broken” PSL fixture for validation scenarios. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Serhii Tatarintsev <tatarintsev@prisma.io> | 3 个月前 |
| feat(lsp-playground): multi-file scratch project with tabs and lazy opening (#30394) ## Overview The LSP playground becomes the multi-file test bench for the `multifile-psl` project: it no longer takes a schema path, and instead always opens a gitignored scratch directory (`apps/lsp-playground/.playground/scratch/`) seeded once with a three-file schema behind a glob config (`contract: './scratch/**/*.prisma'`). A tab strip renders one tab per file; a tab's document is opened in Monaco — and `textDocument/didOpen` sent — only on first click, so never-clicked tabs remain genuinely unmanaged, exactly like closed files in a real editor. ## Changes - **CLI (`src/cli.ts`):** positional schema arguments removed (a clear error points at the scratch workflow); the runtime contract served at `/__psl_playground_runtime.json` goes plural — `members: { uri, text }[]` plus the scratch-root URI. Members are re-discovered from disk on every start, so files added or edited between runs are picked up. - **Seeding (`src/default-config.ts`):** the scratch directory is seeded on first run with two directive-carrying files forming a cross-file relation and a namespace reopened across both, plus one directive-less file (the membership-exclusion demo); an existing scratch directory is never overwritten, so edits survive restarts. The generated config uses the glob. - **Client (`src/client/main.ts`, `index.html`):** one memory file per member in the filesystem overlay; tab strip with lazy opening. Switching to an already-open tab swaps the visible model without re-opening; each opened tab holds a pinned model reference — without it, the editor's model swap disposes its own reference and fires a spurious `didClose`/re-`didOpen` pair (caught by wire-level testing, not code review). - **`src/find-config.ts` deleted** — orphaned once positional arguments went away. - **README:** no-args usage, the tab/lazy-open behavior, and a plainly stated interim limitation (below), including annotations on the Manual QA steps that currently produce no output. ## Why The project's third slice (`lsp-whole-project`) makes the language server glob-aware and disk-reading; this bench exists so that work can be exercised by hand as it develops. The lazy-open design is deliberate: eager-opening every tab would make every file managed and the server's disk path unreachable from the playground. ## Interim limitation (deliberate) The current language server treats config `inputs` as literal paths, so against this glob config it is entirely inert — no diagnostics, folding, semantic tokens, or formatting, for any file, opened or not. That is the staged gap: when the glob-aware slice lands, opened and never-opened tabs alike come to life with zero further playground changes. Discovered during this slice's wire-level verification; the slice spec and project plan were amended accordingly (recorded as a falsified assumption in the project trace). ## Scope `apps/lsp-playground/**` only, plus project planning artifacts under `projects/multifile-psl/`. No language-server, provider, or config-package changes. ## Verification Wire-level probe (headless Chromium driving the real page, every LSP frame logged): exactly one `didOpen` per clicked tab, none before clicking, zero `didClose` across tab switches. Seed-once proven by editing a file and restarting. Positional-argument error path exercised. Playground typecheck and lint clean; re-validated (with a fresh server smoke) after merging `origin/main`, whose config-resolution change (`b313e84c58`) this bench's generated-config path survives. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * The playground now opens a multi-file scratch project with a file-picker sidebar. Files open when selected, and edits stay in memory. * Three example Prisma files are added when the scratch project is first created or is empty; existing files are preserved. * **Changes** * Launch the playground without a schema path; supplying one is an error. The schema path is no longer shown in the header. * Diagnostics, folding, semantic tokens, and formatting currently produce no output for scratch files. * **Documentation** * Updated setup and manual QA instructions to describe the scratch project and its current limitations. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Steven McClankerton <tatarintsev@prisma.io> Co-authored-by: Steven McClankerton <tatarintsev@prisma.io> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> | 1 天前 |
| feat(lsp-playground): multi-file scratch project with tabs and lazy opening (#30394) ## Overview The LSP playground becomes the multi-file test bench for the `multifile-psl` project: it no longer takes a schema path, and instead always opens a gitignored scratch directory (`apps/lsp-playground/.playground/scratch/`) seeded once with a three-file schema behind a glob config (`contract: './scratch/**/*.prisma'`). A tab strip renders one tab per file; a tab's document is opened in Monaco — and `textDocument/didOpen` sent — only on first click, so never-clicked tabs remain genuinely unmanaged, exactly like closed files in a real editor. ## Changes - **CLI (`src/cli.ts`):** positional schema arguments removed (a clear error points at the scratch workflow); the runtime contract served at `/__psl_playground_runtime.json` goes plural — `members: { uri, text }[]` plus the scratch-root URI. Members are re-discovered from disk on every start, so files added or edited between runs are picked up. - **Seeding (`src/default-config.ts`):** the scratch directory is seeded on first run with two directive-carrying files forming a cross-file relation and a namespace reopened across both, plus one directive-less file (the membership-exclusion demo); an existing scratch directory is never overwritten, so edits survive restarts. The generated config uses the glob. - **Client (`src/client/main.ts`, `index.html`):** one memory file per member in the filesystem overlay; tab strip with lazy opening. Switching to an already-open tab swaps the visible model without re-opening; each opened tab holds a pinned model reference — without it, the editor's model swap disposes its own reference and fires a spurious `didClose`/re-`didOpen` pair (caught by wire-level testing, not code review). - **`src/find-config.ts` deleted** — orphaned once positional arguments went away. - **README:** no-args usage, the tab/lazy-open behavior, and a plainly stated interim limitation (below), including annotations on the Manual QA steps that currently produce no output. ## Why The project's third slice (`lsp-whole-project`) makes the language server glob-aware and disk-reading; this bench exists so that work can be exercised by hand as it develops. The lazy-open design is deliberate: eager-opening every tab would make every file managed and the server's disk path unreachable from the playground. ## Interim limitation (deliberate) The current language server treats config `inputs` as literal paths, so against this glob config it is entirely inert — no diagnostics, folding, semantic tokens, or formatting, for any file, opened or not. That is the staged gap: when the glob-aware slice lands, opened and never-opened tabs alike come to life with zero further playground changes. Discovered during this slice's wire-level verification; the slice spec and project plan were amended accordingly (recorded as a falsified assumption in the project trace). ## Scope `apps/lsp-playground/**` only, plus project planning artifacts under `projects/multifile-psl/`. No language-server, provider, or config-package changes. ## Verification Wire-level probe (headless Chromium driving the real page, every LSP frame logged): exactly one `didOpen` per clicked tab, none before clicking, zero `didClose` across tab switches. Seed-once proven by editing a file and restarting. Positional-argument error path exercised. Playground typecheck and lint clean; re-validated (with a fresh server smoke) after merging `origin/main`, whose config-resolution change (`b313e84c58`) this bench's generated-config path survives. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * The playground now opens a multi-file scratch project with a file-picker sidebar. Files open when selected, and edits stay in memory. * Three example Prisma files are added when the scratch project is first created or is empty; existing files are preserved. * **Changes** * Launch the playground without a schema path; supplying one is an error. The schema path is no longer shown in the header. * Diagnostics, folding, semantic tokens, and formatting currently produce no output for scratch files. * **Documentation** * Updated setup and manual QA instructions to describe the scratch project and its current limitations. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Steven McClankerton <tatarintsev@prisma.io> Co-authored-by: Steven McClankerton <tatarintsev@prisma.io> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> | 1 天前 |
| chore(release): bump to 8.0.0-rc.12 (#30395) ## Release: 8.0.0-rc.11 → 8.0.0-rc.12 This is the release PR described in [docs/oss/versioning.md](https://github.com/prisma/orm/blob/main/docs/oss/versioning.md). It bumps every workspace package to 8.0.0-rc.12 and moves the Prisma dependencies to their latest versions. **Merging this PR ships the release.** The push to `main` carries the new root `version`. The `Publish to npm` workflow then publishes 8.0.0-rc.12 under `latest` and creates a pre-release GitHub Release from the notes file. ## Review these first - [docs/releases/v8.0.0-rc.12.md](https://github.com/prisma/orm/blob/release/8.0.0-rc.12/docs/releases/v8.0.0-rc.12.md): the release notes, which become the GitHub Release body. The same entry is at the top of `CHANGELOG.md`. - The upgrade guides for [apps](https://github.com/prisma/orm/blob/release/8.0.0-rc.12/skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.11-to-8.0.0-rc.12/instructions.md) and [extensions](https://github.com/prisma/orm/blob/release/8.0.0-rc.12/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.11-to-8.0.0-rc.12/instructions.md). They merge the 24 pending fragments. The original fragments are moved unchanged to `upgrade-instructions/releases/8.0.0-rc.11-to-8.0.0-rc.12/sources/`. - Four guide entries have no fragment behind them. The `migration new` default and its removed error codes (#30389) had no guide entry. Neither did the PSL parser API changes (#30312, #30344, #30335, #30379). I wrote those entries while preparing the release. - Where fragments contradicted later code, the guide follows the code. Examples: the Supabase storage hash, `voidParamsSchema`, and quoted defaults printed by `infer`. ## Dependency updates | Package | From | To | Where | | --- | --- | --- | --- | | `@prisma/cli-engine` | 0.4.0 | 0.6.1 | examples, test fixtures, apps (the toolchain packages were already on 0.6.1 from #30372) | | `@prisma/dev` | 0.25.1 | 0.25.2 | the workspace catalog | | `@prisma/compute-sdk` | ^0.39.0 | ^0.43.0 | `apps/telemetry-backend` | | `@prisma/management-api-sdk` | ^1.56.0 | ^1.76.0 | `apps/telemetry-backend` | compute-sdk 0.43 renames "service" to "app" and "version" to "deployment". The telemetry deploy script now uses the new names. Both SDK versions call `/v1/apps/{appId}`, so the ID stored in the existing `TELEMETRY_DEPLOY_SERVICE_ID` secret is still correct. The app's typecheck now includes `scripts/`, so it catches the next SDK rename. The repo does not depend on `@prisma/composer`. ## Fixes needed to publish - **The publish workflow has failed on `main` since #30372.** `check:conformance` called the `orm` config validator as `validate(value)`. Engine 0.6 always calls `validate(value, provenance)`, and the validator reads `provenance.files`, so it threw on every input. The check now passes the same provenance the engine would. The prisma-cli copy of this check already does this. - `set-version` rewrote `workspace:@internal/cli@<version>` to `workspace:<version>`, dropping the alias. The prisma7-adoption example uses that alias. This is the first bump since the alias was added. - `lint:legacy-name` and the `add-model-map` test pointed at the pending fragment paths. They now point at the archived sources. ## Verification Passed locally: - `pnpm build` - `pnpm typecheck` - `pnpm lint` - `pnpm test:scripts` (563 tests) - `pnpm check:conformance` - `pnpm check:publish-deps` - `pnpm check:upgrade-coverage`, in both publish and PR mode - `pnpm check:release-notes`, in both publish and PR mode - `pnpm lint:legacy-name` - `pnpm lint:skills` - `pnpm test:packages`: all 18,196 tests passed Not covered locally, left to CI: - Three `test:packages` suites install packed tarballs from the registry. This machine's pnpm refuses `@vercel/detect-agent@1.2.5` because it has no provenance. CI passed the same suites on #30390. - `prisma-8-cloudflare-worker` needs a local Hyperdrive database. - The telemetry backend tests need Node 24.16 with `Temporal`. This machine has 24.13. - `fixtures:check` needs Postgres. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added PostgreSQL full-text search, multi-file schemas, prepared ORM reads and aggregates, and conflict-skipping options for bulk creation. * Added support for using a Prisma 7 schema as the contract source, JavaScript `Date` timestamps on PostgreSQL, editor support for attribute arguments, and per-finding diagnostics. * **Breaking Changes** * Prisma 8 schema files now require `// use prisma-8` on the first line; unmapped models use their names verbatim for table names. * Replace `dbgenerated(...)` with SQL tagged literals. Defaults must be valid for their column types, creation timestamps use the application clock, and native PostgreSQL enums no longer support text operations. * Config naming and path resolution, migration starting points, and extension contracts have changed. * **Bug Fixes** * Improved migration checks and branching warnings, contract generation and inference, default verification, and type checking. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> | 2 天前 |
| feat: an application depends on one Prisma package (ADR 242) (#29864) ## What changes for someone using Prisma Today, an application that talks to Postgres installs a long list of our packages: ```jsonc { "dependencies": { "@prisma-next/postgres": "...", "@prisma-next/sql-runtime": "...", "@prisma-next/sql-orm-client": "...", "@prisma-next/target-postgres": "...", "@prisma-next/adapter-postgres": "...", "@prisma-next/sql-contract": "..." // ...a dozen more } } ``` After this PR, it installs one: ```jsonc { "dependencies": { "@prisma/orm-postgres": "0.16.0" } } ``` Everything else arrives as that package's own dependencies. Three of our example apps are converted in this PR to prove it — one per database — and each has exactly one Prisma package in its `dependencies`. This implements [ADR 242](https://github.com/prisma/prisma/pull/29852), which is already merged. ## What gets published 17 packages, all under the `@prisma` scope: - **3 database packages** — `@prisma/orm-postgres`, `orm-sqlite`, `orm-mongo`. An application installs exactly one. We call these *facades*: each is a small package that wires its database together and re-exports everything an application needs. - **6 extension packs** — PostGIS, pgvector, ParadeDB, Supabase, arktype-json, middleware-cache. Optional, installed alongside a database package. - **7 platform packages** — the framework, the toolchain, one per database family, one per database target. Applications never install these directly; they arrive as dependencies. Extension authors do install them. - **the `prisma` command**, as a bin-only package. Every other workspace package — around 50 of them — stops being published. They still exist in the repo as the unit we organise code in; they just stop having a life on the registry. **This PR does not make that switch yet.** It builds and proves the new surface while leaving today's publish list exactly as it is. Flipping it is a separate change. ## The problem this design has to avoid A published package can't depend on packages that won't exist on the registry. So each published package *contains a compiled copy* of the internal packages it covers. That creates a trap. If one application ends up with the same code twice — once inside a published package, once as its own package — then classes, registries, and anything compared by reference exist twice too. An `instanceof` check quietly returns false. Nothing crashes, nothing fails to compile, and both copies behave identically in isolation. You find out much later, somewhere unrelated. So the rule the whole design follows is: **every piece of internal code is published from exactly one package.** Concretely, that means: - Each published package is built in one pass, so code shared between its own entry points exists once. Verified from the build's source maps: no module appears in more than one chunk, in any published package. - When one published package needs code from another, it imports it as a real dependency rather than compiling in a second copy. - A facade re-exports from the platform packages; it never carries its own copy. `@prisma/orm-postgres/orm-client` and `@prisma/orm-family-sql/orm-client` are two names for the same object, and there's a test that asserts exactly that from installed tarballs. - One table in `packages/0-shared/publish-surface` maps every internal package to where it's published. The build, the code generator, and the lint checks all read it, so there's one answer to "where does this live" rather than three that can drift. ## Generated code follows the application Prisma writes imports into your project — contract types and migration files. Those imports have to name packages your project actually depends on, or they won't resolve. So the generator now reads the `package.json` next to the config it's generating for. A project that depends on `@prisma/orm-postgres` gets imports from that package. A project on today's names keeps today's names. Nothing to configure, because the manifest already says which it is. Contract hashes are unaffected, and that isn't an assumption — hashes are computed from a structure that import text never enters, and there's a test asserting the hash is identical across naming schemes *while* the emitted imports demonstrably differ. ## What stops the trap coming back Two checks, because the failure is silent and won't show up in a test suite: - Every example app and test project must use one naming scheme, not a mix. `lint-single-import-root` scans them and fails the build if any project imports from both, since that's the situation that loads code twice. - `lint-consumer-internal-imports` counts how many internal-package imports remain in those projects and compares against a committed number. It fails if the number goes up (someone added one) and also if it goes down without the number being updated (so improvements get locked in). Target is zero. The build itself also refuses to proceed if the published-package map would put one module in two places, or if a published package's `package.json` no longer matches what its code actually needs. ## Reading this PR It's large — 257 files — because it's a migration. The commits are grouped and meant to be read in order: 1. **Platform packages** — the build mechanism, and the seven platform packages it produces. 2. **Database packages, extension packs, the `prisma` command** — completes the set of 17. 3. **Generated imports become configurable** — one place decides which names get written, with today's names still the default. 4. **Database-family symmetry, publishing the map, the identity checks.** 5. **One package per application** — the three converted examples, the re-exports they proved necessary, and the counting check. 6. **Migration files follow the project too.** One thing worth knowing while reading: re-exporting a package republishes all of its sub-paths, not just the one that was needed. This PR adds 115 published sub-paths across the three database packages. Two candidates were dropped for exactly that reason — see below. ## Alternatives considered **Let an application install platform packages alongside its facade.** Nothing would need re-exporting and the facades would stay thinner. Rejected: an application would again juggle several Prisma dependencies whose correct combination it maintains by hand, and getting it wrong — upgrading one and not the other — produces the silent two-copies failure above. Re-exporting costs a generated line and nothing at runtime. **Re-export everything an application might plausibly want.** Rejected in review: because re-exporting brings a package's entire sub-path surface, generosity is expensive and hard to undo. Migration tooling (54 sub-paths) was dropped because its only users are extension packs, which install platform packages anyway; the SQL driver re-export was dropped because nothing imported it at all. What remains is what a converted example actually needed. **Flip the publish list in this same PR.** Rejected: it would mix "does the new surface work" with "is it safe to stop publishing 50 packages" in one review. The switch is mechanical once this lands, and gets its own change. ## Verification `build`, `typecheck` (156 tasks), `test:packages` (1077 files / 14087 tests), `test:e2e`, `lint`, `lint:deps`, `lint:docs`, `lint:manifests`, `check:publish-deps`, `check:clean-tree`, `lint:casts` and `lint:throws` (no new instances), `test:scripts`, coverage, the tarball-install suites, and regenerating every committed artifact leaves the tree unchanged. Known-unstable and unrelated to this change: the `relation-mode-gh-*` port suites (TML-3140), and several test timeouts that are too tight under load. ## Follow-ups TML-3124 switch the publish list · TML-3127 build cache can validate a stale published package on CI · TML-3140 unstable port suites · TML-3141 a test-helper sub-path reaches a package that is never published. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added consolidated public ORM packages for PostgreSQL, MongoDB, SQLite, framework tooling, database targets, and extensions. - Generated contracts, migrations, and scaffolds now adapt imports to the consuming project’s package surface. - Added facade-provided `prisma-next` CLI access and consolidated migration entrypoints. - **Documentation** - Updated installation, package naming, public entrypoint, and migration scaffolding guidance. - **Tests** - Added coverage for package installation, exports, CLI behavior, module identity, and import compatibility. - **Chores** - Added checks preventing incompatible internal and public package imports. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> | 1 个月前 |