From f0d3c08c0f1412af55673d6359a4588b123abcb7 Mon Sep 17 00:00:00 2001 From: Tyler Hogarth <5163494+tylerhogarth@users.noreply.github.com> Date: Wed, 26 Aug 2026 13:57:03 +0200 Subject: [PATCH 1/9] The prisma-8 skill splits into prisma-orm-core-concepts and prisma-orm-migrations The consolidated prisma-8 router is retired. Its content now ships as two skills: prisma-orm-core-concepts (mental model, structured-error diagnosis, and every development workflow: quickstart, contract, queries, runtime, build, Supabase, feedback, upgrades) and prisma-orm-migrations (authoring, the graph/refs/plan-origin model, deploy review). The core-concepts skill gains a new references/concepts.md grounded in the public core-concepts docs, and the former debug.md becomes references/failure-modes.md. Packaging and CLI follow: sync-package-skills and set-version iterate a shared SKILL_NAMES list, prisma-8 joins RETIRED_SKILL_NAMES so orm init deletes stale copies, and check-upgrade-coverage points at the upgrading tree in its new home. DEVELOPING.md replaces the one-skill principle with two fixed trigger territories (migrations vs everything else), and the journey tests, READMEs, and contributor skills are repointed. Co-Authored-By: Claude Fable 5 Signed-off-by: Tyler Hogarth <5163494+tylerhogarth@users.noreply.github.com> --- README.md | 4 +- docs/oss/versioning.md | 2 +- .../0-shared/extension-author-tools/README.md | 6 +- .../test/package-skills.test.ts | 61 +++---- .../cli/src/commands/init/skill-sources.ts | 26 +-- .../test/commands/init/skill-sources.test.ts | 6 +- .../cli/test/orm/init-scaffold.test.ts | 4 +- scripts/check-upgrade-coverage.mjs | 6 +- scripts/check-upgrade-coverage.test.mjs | 162 +++++++++++------- scripts/lint-throws.test.mjs | 4 +- scripts/set-version.ts | 17 +- scripts/sync-package-skills.ts | 45 ++--- skills-contrib/draft-release-notes/SKILL.md | 8 +- .../record-upgrade-instructions/SKILL.md | 20 +-- skills/DEVELOPING.md | 31 ++-- skills/README.md | 23 +-- .../01-onboarding-first-query.md | 4 +- skills/journey-tests/02a-add-relation.md | 2 +- skills/journey-tests/02b-rename-with-hint.md | 4 +- .../02c-data-transform-placeholder.md | 2 +- skills/journey-tests/02d-capability-gate.md | 2 +- skills/journey-tests/02e-hash-mismatch.md | 2 +- skills/journey-tests/02f-merge-preview.md | 2 +- .../journey-tests/02g-diamond-convergence.md | 2 +- skills/journey-tests/02h-query-interface.md | 2 +- skills/journey-tests/02i-greenfield-trap.md | 2 +- skills/journey-tests/03-capability-gaps.md | 24 +-- skills/journey-tests/05-build-vite.md | 4 +- skills/journey-tests/05b-build-nextjs-gap.md | 8 +- skills/journey-tests/06-feedback-bug.md | 4 +- skills/journey-tests/06b-feedback-feature.md | 14 +- .../07-first-touch-orientation.md | 10 +- skills/journey-tests/08-supabase-rls.md | 4 +- skills/journey-tests/README.md | 36 ++-- .../SKILL.md | 48 ++---- .../references/build.md | 2 +- .../references/concepts.md | 146 ++++++++++++++++ .../references/contract.md | 12 +- .../references/failure-modes.md} | 18 +- .../references/feedback.md | 4 +- .../references/queries-mongo.md | 2 +- .../references/queries-postgres.md | 2 +- .../references/queries.md | 2 +- .../references/quickstart.md | 14 +- .../references/runtime.md | 2 +- .../references/supabase.md | 4 +- .../references/upgrade-app.md | 0 .../references/upgrade-extension.md | 0 .../app/upgrades/0.10-to-0.11/instructions.md | 0 .../app/upgrades/0.11-to-0.12/instructions.md | 2 +- .../re-emit-closed-mongo-contracts.ts | 0 .../re-emit-domain-namespaced-contracts.ts | 0 .../re-emit-postgres-public-default.ts | 0 .../strip-migration-labels-hints.ts | 0 .../app/upgrades/0.12-to-0.13/instructions.md | 0 .../re-emit-mti-variant-link-columns.ts | 0 .../app/upgrades/0.13-to-0.14/instructions.md | 2 +- .../migration-op-factories-to-methods.ts | 0 .../0.13-to-0.14/uuid-preset-rename.ts | 0 .../app/upgrades/0.14-to-0.15/instructions.md | 0 .../app/upgrades/0.15-to-0.16/instructions.md | 0 .../app/upgrades/0.16-to-0.17/instructions.md | 0 .../strip-sha256-hash-prefixes.ts | 0 .../0.17-to-8.0.0-rc.1/instructions.md | 0 .../app/upgrades/0.7-to-0.8/instructions.md | 0 .../app/upgrades/0.8-to-0.9/instructions.md | 0 .../0.8-to-0.9/strip-inline-contracts.ts | 0 .../app/upgrades/0.9-to-0.10/instructions.md | 0 .../0.9-to-0.10/stamp-storage-types-kind.ts | 0 .../8.0.0-rc.1-to-8.0.0-rc.2/instructions.md | 0 .../8.0.0-rc.2-to-8.0.0-rc.3/instructions.md | 0 .../8.0.0-rc.3-to-8.0.0-rc.4/instructions.md | 0 .../8.0.0-rc.4-to-8.0.0-rc.5/instructions.md | 0 .../8.0.0-rc.5-to-8.0.0-rc.6/instructions.md | 0 .../8.0.0-rc.6-to-8.0.0-rc.7/instructions.md | 0 .../8.0.0-rc.7-to-8.0.0-rc.8/instructions.md | 0 .../upgrades/0.10-to-0.11/instructions.md | 0 .../upgrades/0.11-to-0.12/instructions.md | 2 +- .../migrate-contract-testing-imports.ts | 0 .../regenerate-extension-public-baseline.ts | 0 .../strip-migration-labels-hints.ts | 0 .../upgrades/0.12-to-0.13/instructions.md | 0 .../upgrades/0.13-to-0.14/instructions.md | 2 +- .../migration-op-factories-to-methods.ts | 0 .../0.13-to-0.14/uuid-preset-rename.ts | 0 .../upgrades/0.14-to-0.15/instructions.md | 0 .../upgrades/0.15-to-0.16/instructions.md | 0 .../upgrades/0.16-to-0.17/instructions.md | 0 .../strip-sha256-hash-prefixes.ts | 0 .../0.17-to-8.0.0-rc.1/instructions.md | 0 .../upgrades/0.7-to-0.8/instructions.md | 0 .../upgrades/0.8-to-0.9/instructions.md | 0 .../0.8-to-0.9/strip-inline-contracts.ts | 0 .../upgrades/0.9-to-0.10/instructions.md | 0 .../0.9-to-0.10/stamp-storage-types-kind.ts | 0 .../8.0.0-rc.1-to-8.0.0-rc.2/instructions.md | 0 .../8.0.0-rc.2-to-8.0.0-rc.3/instructions.md | 0 .../8.0.0-rc.3-to-8.0.0-rc.4/instructions.md | 0 .../8.0.0-rc.4-to-8.0.0-rc.5/instructions.md | 0 .../8.0.0-rc.5-to-8.0.0-rc.6/instructions.md | 0 .../8.0.0-rc.6-to-8.0.0-rc.7/instructions.md | 0 .../8.0.0-rc.7-to-8.0.0-rc.8/instructions.md | 0 skills/prisma-orm-migrations/SKILL.md | 64 +++++++ .../references/migration-model.md | 6 +- .../references/migration-review.md | 10 +- .../references/migrations.md | 26 +-- ...nit-skill-distribution.integration.test.ts | 18 +- 107 files changed, 604 insertions(+), 337 deletions(-) rename skills/{prisma-8 => prisma-orm-core-concepts}/SKILL.md (62%) rename skills/{prisma-8 => prisma-orm-core-concepts}/references/build.md (98%) create mode 100644 skills/prisma-orm-core-concepts/references/concepts.md rename skills/{prisma-8 => prisma-orm-core-concepts}/references/contract.md (98%) rename skills/{prisma-8/references/debug.md => prisma-orm-core-concepts/references/failure-modes.md} (92%) rename skills/{prisma-8 => prisma-orm-core-concepts}/references/feedback.md (98%) rename skills/{prisma-8 => prisma-orm-core-concepts}/references/queries-mongo.md (98%) rename skills/{prisma-8 => prisma-orm-core-concepts}/references/queries-postgres.md (99%) rename skills/{prisma-8 => prisma-orm-core-concepts}/references/queries.md (99%) rename skills/{prisma-8 => prisma-orm-core-concepts}/references/quickstart.md (98%) rename skills/{prisma-8 => prisma-orm-core-concepts}/references/runtime.md (99%) rename skills/{prisma-8 => prisma-orm-core-concepts}/references/supabase.md (98%) rename skills/{prisma-8 => prisma-orm-core-concepts}/references/upgrade-app.md (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/references/upgrade-extension.md (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/app/upgrades/0.10-to-0.11/instructions.md (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/app/upgrades/0.11-to-0.12/instructions.md (98%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/app/upgrades/0.11-to-0.12/re-emit-closed-mongo-contracts.ts (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/app/upgrades/0.11-to-0.12/re-emit-domain-namespaced-contracts.ts (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/app/upgrades/0.11-to-0.12/re-emit-postgres-public-default.ts (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/app/upgrades/0.11-to-0.12/strip-migration-labels-hints.ts (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/app/upgrades/0.12-to-0.13/instructions.md (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/app/upgrades/0.12-to-0.13/re-emit-mti-variant-link-columns.ts (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/app/upgrades/0.13-to-0.14/instructions.md (99%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/app/upgrades/0.13-to-0.14/migration-op-factories-to-methods.ts (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/app/upgrades/0.13-to-0.14/uuid-preset-rename.ts (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/app/upgrades/0.14-to-0.15/instructions.md (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/app/upgrades/0.15-to-0.16/instructions.md (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/app/upgrades/0.16-to-0.17/instructions.md (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/app/upgrades/0.16-to-0.17/strip-sha256-hash-prefixes.ts (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/app/upgrades/0.17-to-8.0.0-rc.1/instructions.md (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/app/upgrades/0.7-to-0.8/instructions.md (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/app/upgrades/0.8-to-0.9/instructions.md (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/app/upgrades/0.8-to-0.9/strip-inline-contracts.ts (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/app/upgrades/0.9-to-0.10/instructions.md (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/app/upgrades/0.9-to-0.10/stamp-storage-types-kind.ts (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/app/upgrades/8.0.0-rc.1-to-8.0.0-rc.2/instructions.md (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/app/upgrades/8.0.0-rc.2-to-8.0.0-rc.3/instructions.md (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/app/upgrades/8.0.0-rc.3-to-8.0.0-rc.4/instructions.md (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/app/upgrades/8.0.0-rc.4-to-8.0.0-rc.5/instructions.md (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/app/upgrades/8.0.0-rc.5-to-8.0.0-rc.6/instructions.md (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/app/upgrades/8.0.0-rc.6-to-8.0.0-rc.7/instructions.md (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/app/upgrades/8.0.0-rc.7-to-8.0.0-rc.8/instructions.md (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/extension/upgrades/0.10-to-0.11/instructions.md (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/extension/upgrades/0.11-to-0.12/instructions.md (99%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/extension/upgrades/0.11-to-0.12/migrate-contract-testing-imports.ts (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/extension/upgrades/0.11-to-0.12/regenerate-extension-public-baseline.ts (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/extension/upgrades/0.11-to-0.12/strip-migration-labels-hints.ts (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/extension/upgrades/0.12-to-0.13/instructions.md (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/extension/upgrades/0.13-to-0.14/instructions.md (99%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/extension/upgrades/0.13-to-0.14/migration-op-factories-to-methods.ts (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/extension/upgrades/0.13-to-0.14/uuid-preset-rename.ts (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/extension/upgrades/0.14-to-0.15/instructions.md (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/extension/upgrades/0.15-to-0.16/instructions.md (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/extension/upgrades/0.16-to-0.17/instructions.md (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/extension/upgrades/0.16-to-0.17/strip-sha256-hash-prefixes.ts (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/extension/upgrades/0.17-to-8.0.0-rc.1/instructions.md (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/extension/upgrades/0.7-to-0.8/instructions.md (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/extension/upgrades/0.8-to-0.9/instructions.md (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/extension/upgrades/0.8-to-0.9/strip-inline-contracts.ts (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/extension/upgrades/0.9-to-0.10/instructions.md (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/extension/upgrades/0.9-to-0.10/stamp-storage-types-kind.ts (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/extension/upgrades/8.0.0-rc.1-to-8.0.0-rc.2/instructions.md (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/extension/upgrades/8.0.0-rc.2-to-8.0.0-rc.3/instructions.md (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/extension/upgrades/8.0.0-rc.3-to-8.0.0-rc.4/instructions.md (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/extension/upgrades/8.0.0-rc.4-to-8.0.0-rc.5/instructions.md (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/extension/upgrades/8.0.0-rc.5-to-8.0.0-rc.6/instructions.md (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/extension/upgrades/8.0.0-rc.6-to-8.0.0-rc.7/instructions.md (100%) rename skills/{prisma-8 => prisma-orm-core-concepts}/upgrading/extension/upgrades/8.0.0-rc.7-to-8.0.0-rc.8/instructions.md (100%) create mode 100644 skills/prisma-orm-migrations/SKILL.md rename skills/{prisma-8 => prisma-orm-migrations}/references/migration-model.md (98%) rename skills/{prisma-8 => prisma-orm-migrations}/references/migration-review.md (96%) rename skills/{prisma-8 => prisma-orm-migrations}/references/migrations.md (94%) diff --git a/README.md b/README.md index 988b94fa3068..48c84df9a055 100644 --- a/README.md +++ b/README.md @@ -62,13 +62,13 @@ Just describe what you want. For example: > *"Add a `posts` model with a relation to `users`, then write a query that loads each user's three most recent posts."* -The agent loads the `prisma-8` skill, opens its contract and queries references, then drives the change end-to-end. +The agent loads the `prisma-orm-core-concepts` skill, opens its contract and queries references, then drives the change end-to-end. For the full catalogue and what each skill covers, see [`skills/README.md`](./skills/README.md). ## Found a bug, missing a feature, or have a question for the team? -Ask your agent. The `prisma-8` skill's feedback flow drafts a structured GitHub issue or hands you a Prisma Discord link for live Q&A. You can review and confirm before anything is submitted. +Ask your agent. The `prisma-orm-core-concepts` skill's feedback flow drafts a structured GitHub issue or hands you a Prisma Discord link for live Q&A. You can review and confirm before anything is submitted. ## For extension authors diff --git a/docs/oss/versioning.md b/docs/oss/versioning.md index 1cd3e8094214..27366547a0f4 100644 --- a/docs/oss/versioning.md +++ b/docs/oss/versioning.md @@ -21,7 +21,7 @@ Every workspace package — publishable, private, the workspace root, and exampl This invariant has consequences that ecosystem participants need to plan for: -- **Agent skills, the upgrade instructions, and any other tooling we ship alongside the framework version in lockstep with it.** A skill installed at the same time as `@internal/postgres@0.8.0` is a `0.8.0` skill and reasons about a `0.8.0` contract. There is no separate skill-version axis to track. This is now physical rather than conventional: the `prisma-8` skill ships inside the `@prisma/orm-postgres`, `@prisma/orm-sqlite` and `@prisma/orm-mongo` tarballs (copied in by each package's `prepack`), and `scripts/set-version.ts` stamps its `metadata.library_version` frontmatter with the version being published. Getting the skill and getting the code are one install, and a consumer can compare the stamp on its synced copy against its installed packages. +- **Agent skills, the upgrade instructions, and any other tooling we ship alongside the framework version in lockstep with it.** A skill installed at the same time as `@internal/postgres@0.8.0` is a `0.8.0` skill and reasons about a `0.8.0` contract. There is no separate skill-version axis to track. This is now physical rather than conventional: the `prisma-orm-core-concepts` and `prisma-orm-migrations` skills ship inside the `@prisma/orm-postgres`, `@prisma/orm-sqlite` and `@prisma/orm-mongo` tarballs (copied in by each package's `prepack`), and `scripts/set-version.ts` stamps each skill's `metadata.library_version` frontmatter with the version being published. Getting the skill and getting the code are one install, and a consumer can compare the stamp on its synced copy against its installed packages. - **Extension authors that depend on internal framework packages must pin those dependencies to the framework version their consumers will use.** If your extension depends on `@internal/sql-core` (an internal framework package), publish each version of your extension targeting one specific Prisma Next minor and pin to it exactly (`"@internal/sql-core": "0.8.0"`, not `"^0.8.0"`). Internal packages do not promise inter-minor compatibility — `0.8.x` and `0.9.x` may have incompatible internals even when the user-visible surface looks similar. The extension's published version range communicates which framework minor it targets. - **Internal packages are never published, but they still version in lockstep** so a contributor cloning the repo at any commit sees one consistent answer to "what version is this code?" The `private: true` flag means `pnpm publish` skips them. diff --git a/packages/0-shared/extension-author-tools/README.md b/packages/0-shared/extension-author-tools/README.md index d928160f3835..076492830c89 100644 --- a/packages/0-shared/extension-author-tools/README.md +++ b/packages/0-shared/extension-author-tools/README.md @@ -1,8 +1,8 @@ # @internal/extension-author-tools -CLI tools that pair with the extension-upgrade branch of the [`prisma-8`](../../../skills/prisma-8/references/upgrade-extension.md) agent skill. Today this package ships one tool; future tools for extension authors using the upgrade-skill flow will land here. +CLI tools that pair with the extension-upgrade branch of the [`prisma-orm-core-concepts`](../../../skills/prisma-orm-core-concepts/references/upgrade-extension.md) agent skill. Today this package ships one tool; future tools for extension authors using the upgrade-skill flow will land here. -The agent-readable upgrade procedure itself (the flow in [`references/upgrade-extension.md`](../../../skills/prisma-8/references/upgrade-extension.md) and the `upgrades/-to-/instructions.md` set under [`upgrading/extension/`](../../../skills/prisma-8/upgrading/extension/)) ships inside the `@prisma/orm-*` tarballs. This package is the npm-published companion that supplies the CI bin the skill drives. +The agent-readable upgrade procedure itself (the flow in [`references/upgrade-extension.md`](../../../skills/prisma-orm-core-concepts/references/upgrade-extension.md) and the `upgrades/-to-/instructions.md` set under [`upgrading/extension/`](../../../skills/prisma-orm-core-concepts/upgrading/extension/)) ships inside the `@prisma/orm-*` tarballs. This package is the npm-published companion that supplies the CI bin the skill drives. ## Installation @@ -18,7 +18,7 @@ npm install --save-dev @internal/extension-author-tools CI guard for extension packages. Asserts that every `@internal/*` entry under the package's `peerDependencies` (and, optionally, `dependencies`) is pinned to an exact version, not a range. -This is the invariant the [extension-upgrade flow](../../../skills/prisma-8/references/upgrade-extension.md) relies on at upgrade time: extension authors pin every `@internal/*` peer to a single exact version per release of their extension, so the skill can mechanically advance both the framework deps and the extension's published version in lockstep. +This is the invariant the [extension-upgrade flow](../../../skills/prisma-orm-core-concepts/references/upgrade-extension.md) relies on at upgrade time: extension authors pin every `@internal/*` peer to a single exact version per release of their extension, so the skill can mechanically advance both the framework deps and the extension's published version in lockstep. Run from the extension's repository root: diff --git a/packages/0-shared/publish-surface/test/package-skills.test.ts b/packages/0-shared/publish-surface/test/package-skills.test.ts index d17681d5ef09..72174f90b493 100644 --- a/packages/0-shared/publish-surface/test/package-skills.test.ts +++ b/packages/0-shared/publish-surface/test/package-skills.test.ts @@ -1,6 +1,7 @@ /** - * The `prisma-8` agent skill ships inside the tarball of every package an - * application depends on directly, so the skill a user has always describes + * The Prisma Next agent skills (`prisma-orm-core-concepts`, + * `prisma-orm-migrations`) ship inside the tarball of every package an + * application depends on directly, so the skills a user has always describe * the version they installed. * * That claim is only worth as much as the artifact that proves it, and every @@ -26,7 +27,7 @@ import { publicShells, type ShellName } from '../src/shells'; const repoRoot = join(dirname(fileURLToPath(import.meta.url)), '..', '..', '..', '..'); const facades: ShellName[] = ['@prisma/orm-postgres', '@prisma/orm-sqlite', '@prisma/orm-mongo']; -const SKILL_NAME = 'prisma-8'; +const SKILL_NAMES = ['prisma-orm-core-concepts', 'prisma-orm-migrations'] as const; interface Manifest { readonly version: string; @@ -93,10 +94,10 @@ function packAndUnpack(facade: ShellName): string { return join(work, 'package'); } -describe('the skill source in the repository', () => { - it('carries the stamp the version sweep maintains', () => { +describe('the skill sources in the repository', () => { + it.each(SKILL_NAMES)('%s carries the stamp the version sweep maintains', (skillName) => { const rootVersion = manifestAt(repoRoot).version; - const source = readFileSync(join(repoRoot, 'skills', SKILL_NAME, 'SKILL.md'), 'utf8'); + const source = readFileSync(join(repoRoot, 'skills', skillName, 'SKILL.md'), 'utf8'); expect(metadataValue(source, 'library_version')).toBe(rootVersion); }); }); @@ -112,30 +113,32 @@ describe.each(facades)('%s', (facade) => { ); }); - it('carries the whole skill tree in its tarball, stamped with what shipped it', () => { + it('carries every skill tree in its tarball, stamped with what shipped it', () => { const packedRoot = packAndUnpack(facade); - const packedSkillDir = join(packedRoot, 'skills', SKILL_NAME); - - expect( - existsSync(join(packedSkillDir, 'SKILL.md')), - `the ${facade} tarball has no skills/${SKILL_NAME}/SKILL.md`, - ).toBe(true); - - const packedSkill = readFileSync(join(packedSkillDir, 'SKILL.md'), 'utf8'); - expect(metadataValue(packedSkill, 'library')).toBe(facade); - expect(metadataValue(packedSkill, 'library_version')).toBe(manifestAt(packedRoot).version); - - // The tarball and the repository's tracked tree must serve the same - // instructions: the only difference is the package each copy names. - const sourceDir = join(repoRoot, 'skills', SKILL_NAME); - expect(filesUnder(packedSkillDir)).toEqual(filesUnder(sourceDir)); - for (const file of filesUnder(sourceDir)) { - if (file === 'SKILL.md') continue; - expect(readFileSync(join(packedSkillDir, file), 'utf8')).toBe( - readFileSync(join(sourceDir, file), 'utf8'), - ); + for (const skillName of SKILL_NAMES) { + const packedSkillDir = join(packedRoot, 'skills', skillName); + + expect( + existsSync(join(packedSkillDir, 'SKILL.md')), + `the ${facade} tarball has no skills/${skillName}/SKILL.md`, + ).toBe(true); + + const packedSkill = readFileSync(join(packedSkillDir, 'SKILL.md'), 'utf8'); + expect(metadataValue(packedSkill, 'library')).toBe(facade); + expect(metadataValue(packedSkill, 'library_version')).toBe(manifestAt(packedRoot).version); + + // The tarball and the repository's tracked tree must serve the same + // instructions: the only difference is the package each copy names. + const sourceDir = join(repoRoot, 'skills', skillName); + expect(filesUnder(packedSkillDir)).toEqual(filesUnder(sourceDir)); + for (const file of filesUnder(sourceDir)) { + if (file === 'SKILL.md') continue; + expect(readFileSync(join(packedSkillDir, file), 'utf8')).toBe( + readFileSync(join(sourceDir, file), 'utf8'), + ); + } + const sourceSkill = readFileSync(join(sourceDir, 'SKILL.md'), 'utf8'); + expect(packedSkill).toBe(sourceSkill.replace(/^(\s+)library:.*$/m, `$1library: '${facade}'`)); } - const sourceSkill = readFileSync(join(sourceDir, 'SKILL.md'), 'utf8'); - expect(packedSkill).toBe(sourceSkill.replace(/^(\s+)library:.*$/m, `$1library: '${facade}'`)); }, 60_000); }); diff --git a/packages/1-framework/3-tooling/cli/src/commands/init/skill-sources.ts b/packages/1-framework/3-tooling/cli/src/commands/init/skill-sources.ts index f5c616ebbeb8..7802a38da381 100644 --- a/packages/1-framework/3-tooling/cli/src/commands/init/skill-sources.ts +++ b/packages/1-framework/3-tooling/cli/src/commands/init/skill-sources.ts @@ -1,6 +1,6 @@ -// The agent skills ship inside the packages they describe — the `prisma-8` -// skill travels in the `@prisma/orm-*` tarball a project installs — so init -// no longer fetches or installs them from anywhere. Skills setup belongs to +// The agent skills ship inside the packages they describe — the +// `prisma-orm-*` skills travel in the `@prisma/orm-*` tarball a project +// installs — so init no longer fetches or installs them from anywhere. Skills setup belongs to // the family-level `prisma init` command; the only skill work left in // `orm init` is deleting the retired directories below. @@ -9,17 +9,19 @@ // ------------------------------------------------------------------- /** - * Skill directories that predate the consolidated `prisma-8` skill: the - * per-workflow usage cluster (including the renamed - * `prisma-8-migration-review` spelling it briefly shipped under), the - * pre-rename spellings of the consolidated skill and the extension-author - * upgrade skill, any hand-rolled `prisma-next` stub, and the two standalone - * upgrade skills that folded into the `prisma-8` router. Projects initialised - * before those changes carry these as sibling directories in each agent's - * install root; left in place they compete with the current skill for - * activation, so init removes them on every run. + * Skill directories that predate the current `prisma-orm-*` skill set: the + * consolidated `prisma-8` router it replaced, the per-workflow usage cluster + * that preceded the router (including the renamed `prisma-8-migration-review` + * spelling it briefly shipped under), the pre-rename spellings of the + * consolidated skill and the extension-author upgrade skill, any hand-rolled + * `prisma-next` stub, and the two standalone upgrade skills that folded into + * the `prisma-8` router. Projects initialised before those changes carry + * these as sibling directories in each agent's install root; left in place + * they compete with the current skills for activation, so init removes them + * on every run. */ export const RETIRED_SKILL_NAMES = [ + 'prisma-8', 'prisma-next', 'prisma-next-quickstart', 'prisma-next-contract', diff --git a/packages/1-framework/3-tooling/cli/test/commands/init/skill-sources.test.ts b/packages/1-framework/3-tooling/cli/test/commands/init/skill-sources.test.ts index f730e29024ba..a0eeaf722be7 100644 --- a/packages/1-framework/3-tooling/cli/test/commands/init/skill-sources.test.ts +++ b/packages/1-framework/3-tooling/cli/test/commands/init/skill-sources.test.ts @@ -20,10 +20,14 @@ describe('legacy skill cleanup', () => { expect(RETIRED_SKILL_NAMES).toContain('prisma-8-extension-upgrade'); }); + it('retires the consolidated router the prisma-orm-* skills replaced', () => { + expect(RETIRED_SKILL_NAMES).toContain('prisma-8'); + }); + it('names one directory per harness root and retired skill', () => { const dirs = legacySkillDirs(); expect(dirs).toHaveLength(AGENT_SKILL_ROOTS.length * RETIRED_SKILL_NAMES.length); expect(dirs).toContain('.cursor/skills/prisma-next-upgrade'); - expect(dirs).not.toContain('.claude/skills/prisma-8'); + expect(dirs).toContain('.claude/skills/prisma-8'); }); }); diff --git a/packages/1-framework/3-tooling/cli/test/orm/init-scaffold.test.ts b/packages/1-framework/3-tooling/cli/test/orm/init-scaffold.test.ts index 9abcbe05c6b8..6b062b32bb02 100644 --- a/packages/1-framework/3-tooling/cli/test/orm/init-scaffold.test.ts +++ b/packages/1-framework/3-tooling/cli/test/orm/init-scaffold.test.ts @@ -162,7 +162,7 @@ describe('init scaffold', () => { expect(run.exitCode).toBe(0); expect(manifest.scripts?.postinstall).toBeUndefined(); - expect(gitignore).not.toContain('skills/prisma-8/'); + expect(gitignore).not.toContain('skills/prisma-'); }, timeouts.coldTransformImport, ); @@ -175,7 +175,7 @@ describe('init scaffold', () => { const retired = join(projectDir, '.claude/skills/prisma-next-queries'); mkdirSync(retired, { recursive: true }); writeFileSync(join(retired, 'SKILL.md'), '# stale\n', 'utf-8'); - const installed = join(projectDir, '.agents/skills/prisma-8'); + const installed = join(projectDir, '.agents/skills/prisma-orm-core-concepts'); mkdirSync(installed, { recursive: true }); writeFileSync(join(installed, 'SKILL.md'), '# installed\n', 'utf-8'); diff --git a/scripts/check-upgrade-coverage.mjs b/scripts/check-upgrade-coverage.mjs index c22d6b8133f3..b3682ad50bff 100644 --- a/scripts/check-upgrade-coverage.mjs +++ b/scripts/check-upgrade-coverage.mjs @@ -127,8 +127,8 @@ export function parseChangesFrontmatter(src) { return { ok: false, reason: 'changes key absent' }; } -const USER_SKILL_PKG = 'skills/prisma-8/upgrading/app'; -const EXT_SKILL_PKG = 'skills/prisma-8/upgrading/extension'; +const USER_SKILL_PKG = 'skills/prisma-orm-core-concepts/upgrading/app'; +const EXT_SKILL_PKG = 'skills/prisma-orm-core-concepts/upgrading/extension'; /** * Substrates covered by the gate. Each entry pairs a diff pathspec @@ -284,7 +284,7 @@ const TRANSITION_PATH = new RegExp( * Parse a path under `/upgrades//...` and return * the transition segment, or null if the path does not match. * - * Example: `skills/prisma-8/upgrading/app/upgrades/0.7-to-0.8/foo.ts` + * Example: `skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.7-to-0.8/foo.ts` * → `'0.7-to-0.8'` */ export function parseTransitionFromPath(path) { diff --git a/scripts/check-upgrade-coverage.test.mjs b/scripts/check-upgrade-coverage.test.mjs index 8f7c61ff8629..55b29bcaf5de 100644 --- a/scripts/check-upgrade-coverage.test.mjs +++ b/scripts/check-upgrade-coverage.test.mjs @@ -65,21 +65,29 @@ afterEach(() => { describe('parseTransitionFromPath', () => { it('extracts the transition segment for the user skill', () => { assert.equal( - parseTransitionFromPath('skills/prisma-8/upgrading/app/upgrades/0.7-to-0.8/foo.ts'), + parseTransitionFromPath( + 'skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.7-to-0.8/foo.ts', + ), '0.7-to-0.8', ); }); it('extracts the transition segment for the extension skill', () => { assert.equal( parseTransitionFromPath( - 'skills/prisma-8/upgrading/extension/upgrades/0.7-to-0.8/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.7-to-0.8/instructions.md', ), '0.7-to-0.8', ); }); it('returns null for paths outside an upgrades// subdirectory', () => { - assert.equal(parseTransitionFromPath('skills/prisma-8/upgrading/app/SKILL.md'), null); - assert.equal(parseTransitionFromPath('skills/prisma-8/upgrading/app/upgrades/'), null); + assert.equal( + parseTransitionFromPath('skills/prisma-orm-core-concepts/upgrading/app/SKILL.md'), + null, + ); + assert.equal( + parseTransitionFromPath('skills/prisma-orm-core-concepts/upgrading/app/upgrades/'), + null, + ); assert.equal(parseTransitionFromPath('examples/foo/bar.ts'), null); }); }); @@ -264,7 +272,10 @@ describe('check-upgrade-coverage — coverage rule (publish style: prev.minor < const result = runScript(['--prev', prev, '--head', 'HEAD']); assert.notEqual(result.status, 0); assert.match(result.stderr, /coverage/); - assert.match(result.stderr, /skills\/prisma-8\/upgrading\/app\/upgrades\/0\.6-to-0\.7/); + assert.match( + result.stderr, + /skills\/prisma-orm-core-concepts\/upgrading\/app\/upgrades\/0\.6-to-0\.7/, + ); assert.match(result.stderr, /examples\/demo\/src\/main\.ts/); }); @@ -278,7 +289,10 @@ describe('check-upgrade-coverage — coverage rule (publish style: prev.minor < commitAll('head'); const result = runScript(['--prev', prev, '--head', 'HEAD']); assert.notEqual(result.status, 0); - assert.match(result.stderr, /skills\/prisma-8\/upgrading\/extension\/upgrades\/0\.6-to-0\.7/); + assert.match( + result.stderr, + /skills\/prisma-orm-core-concepts\/upgrading\/extension\/upgrades\/0\.6-to-0\.7/, + ); }); it('requires both directories when both substrates change; passes once both are present', () => { @@ -295,15 +309,18 @@ describe('check-upgrade-coverage — coverage rule (publish style: prev.minor < // Neither directory present → both missing. const missingBoth = runScript(['--prev', prev, '--head', 'HEAD']); assert.notEqual(missingBoth.status, 0); - assert.match(missingBoth.stderr, /skills\/prisma-8\/upgrading\/app\/upgrades\/0\.6-to-0\.7/); assert.match( missingBoth.stderr, - /skills\/prisma-8\/upgrading\/extension\/upgrades\/0\.6-to-0\.7/, + /skills\/prisma-orm-core-concepts\/upgrading\/app\/upgrades\/0\.6-to-0\.7/, + ); + assert.match( + missingBoth.stderr, + /skills\/prisma-orm-core-concepts\/upgrading\/extension\/upgrades\/0\.6-to-0\.7/, ); // Add only the user-skill directory; extension-skill still missing. writeRepoFile( - 'skills/prisma-8/upgrading/app/upgrades/0.6-to-0.7/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.6-to-0.7/instructions.md', '---\nfrom: "0.6"\nto: "0.7"\nchanges: []\n---\n', ); commitAll('add user-skill dir'); @@ -311,16 +328,16 @@ describe('check-upgrade-coverage — coverage rule (publish style: prev.minor < assert.notEqual(missingExt.status, 0); assert.match( missingExt.stderr, - /skills\/prisma-8\/upgrading\/extension\/upgrades\/0\.6-to-0\.7/, + /skills\/prisma-orm-core-concepts\/upgrading\/extension\/upgrades\/0\.6-to-0\.7/, ); assert.doesNotMatch( missingExt.stderr, - /skills\/prisma-8\/upgrading\/app\/upgrades\/0\.6-to-0\.7/, + /skills\/prisma-orm-core-concepts\/upgrading\/app\/upgrades\/0\.6-to-0\.7/, ); // Add the extension-skill directory; both present → pass. writeRepoFile( - 'skills/prisma-8/upgrading/extension/upgrades/0.6-to-0.7/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.6-to-0.7/instructions.md', '---\nfrom: "0.6"\nto: "0.7"\nchanges: []\n---\n', ); commitAll('add ext-skill dir'); @@ -338,7 +355,10 @@ describe('check-upgrade-coverage — coverage rule (publish style: prev.minor < commitAll('head'); const result = runScript(['--mode', 'publish', '--head', 'HEAD']); assert.notEqual(result.status, 0); - assert.match(result.stderr, /skills\/prisma-8\/upgrading\/app\/upgrades\/0\.6-to-0\.7/); + assert.match( + result.stderr, + /skills\/prisma-orm-core-concepts\/upgrading\/app\/upgrades\/0\.6-to-0\.7/, + ); }); it('publish mode: default --prev skips pre-release tags and picks the last stable v[0-9]* tag', () => { @@ -357,11 +377,11 @@ describe('check-upgrade-coverage — coverage rule (publish style: prev.minor < // both authored mid-cycle. writeRepoFile('examples/demo/src/main.ts', 'b\n'); writeRepoFile( - 'skills/prisma-8/upgrading/app/upgrades/0.6-to-0.7/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.6-to-0.7/instructions.md', '---\nfrom: "0.6"\nto: "0.7"\nchanges: []\n---\n', ); writeRepoFile( - 'skills/prisma-8/upgrading/extension/upgrades/0.6-to-0.7/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.6-to-0.7/instructions.md', '---\nfrom: "0.6"\nto: "0.7"\nchanges: []\n---\n', ); commitAll('feature with upgrade entry'); @@ -391,7 +411,10 @@ describe('check-upgrade-coverage — coverage rule (PR style: prev.minor === hea commitAll('head'); const result = runScript(['--prev', prev, '--head', 'HEAD']); assert.notEqual(result.status, 0); - assert.match(result.stderr, /skills\/prisma-8\/upgrading\/app\/upgrades\/0\.7-to-0\.8/); + assert.match( + result.stderr, + /skills\/prisma-orm-core-concepts\/upgrading\/app\/upgrades\/0\.7-to-0\.8/, + ); assert.doesNotMatch(result.stderr, /upgrades\/0\.6-to-0\.7/); }); @@ -401,7 +424,7 @@ describe('check-upgrade-coverage — coverage rule (PR style: prev.minor === hea const prev = git('rev-parse', 'HEAD'); writeRepoFile('examples/demo/src/main.ts', 'export const a = 2;\n'); writeRepoFile( - 'skills/prisma-8/upgrading/app/upgrades/0.7-to-0.8/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.7-to-0.8/instructions.md', '---\nfrom: "0.7"\nto: "0.8"\nchanges: []\n---\n', ); commitAll('head'); @@ -463,14 +486,14 @@ describe('check-upgrade-coverage — new-entries rule', () => { // (allowed transitions are 0.7-to-0.8 and 0.8-to-0.9). writePackageJson('0.7.0'); writeRepoFile( - 'skills/prisma-8/upgrading/app/upgrades/0.6-to-0.7/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.6-to-0.7/instructions.md', '---\nfrom: "0.6"\nto: "0.7"\nchanges: []\n---\n', ); commitAll('prev'); const prev = git('rev-parse', 'HEAD'); writePackageJson('0.8.0'); writeRepoFile( - 'skills/prisma-8/upgrading/app/upgrades/0.6-to-0.7/new-script.ts', + 'skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.6-to-0.7/new-script.ts', 'export const x = 1;\n', ); commitAll('head'); @@ -481,8 +504,8 @@ describe('check-upgrade-coverage — new-entries rule', () => { // Either of the allowed transitions should be mentioned. assert.match(result.stderr, /0\.7-to-0\.8|0\.8-to-0\.9/); // The "move the new file under" diagnostic should name both cluster paths. - assert.match(result.stderr, /skills\/prisma-8\/upgrading\/app\/upgrades/); - assert.match(result.stderr, /skills\/prisma-8\/upgrading\/extension\/upgrades/); + assert.match(result.stderr, /skills\/prisma-orm-core-concepts\/upgrading\/app\/upgrades/); + assert.match(result.stderr, /skills\/prisma-orm-core-concepts\/upgrading\/extension\/upgrades/); }); it('publish mode: accepts an added file under either prev→head or head→head+1', () => { @@ -493,11 +516,11 @@ describe('check-upgrade-coverage — new-entries rule', () => { const prev = git('rev-parse', 'HEAD'); writePackageJson('0.8.0'); writeRepoFile( - 'skills/prisma-8/upgrading/app/upgrades/0.7-to-0.8/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.7-to-0.8/instructions.md', '---\nfrom: "0.7"\nto: "0.8"\nchanges: []\n---\n', ); writeRepoFile( - 'skills/prisma-8/upgrading/extension/upgrades/0.8-to-0.9/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.8-to-0.9/instructions.md', '---\nfrom: "0.8"\nto: "0.9"\nchanges: []\n---\n', ); commitAll('head'); @@ -514,7 +537,7 @@ describe('check-upgrade-coverage — new-entries rule', () => { const prev = git('rev-parse', 'HEAD'); writePackageJson('0.7.0'); writeRepoFile( - 'skills/prisma-8/upgrading/app/upgrades/0.7-to-0.8/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.7-to-0.8/instructions.md', '---\nfrom: "0.7"\nto: "0.8"\nchanges: []\n---\n', ); commitAll('head'); @@ -530,7 +553,7 @@ describe('check-upgrade-coverage — new-entries rule', () => { const prev = git('rev-parse', 'HEAD'); writePackageJson('0.7.0'); writeRepoFile( - 'skills/prisma-8/upgrading/app/upgrades/0.6-to-0.7/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.6-to-0.7/instructions.md', '---\nfrom: "0.6"\nto: "0.7"\nchanges: []\n---\n', ); commitAll('head'); @@ -539,8 +562,8 @@ describe('check-upgrade-coverage — new-entries rule', () => { assert.match(result.stderr, /new-entries-stale-transition/); assert.match(result.stderr, /0\.7-to-0\.8/); // The "move the new file under" diagnostic should name both cluster paths. - assert.match(result.stderr, /skills\/prisma-8\/upgrading\/app\/upgrades/); - assert.match(result.stderr, /skills\/prisma-8\/upgrading\/extension\/upgrades/); + assert.match(result.stderr, /skills\/prisma-orm-core-concepts\/upgrading\/app\/upgrades/); + assert.match(result.stderr, /skills\/prisma-orm-core-concepts\/upgrading\/extension\/upgrades/); }); it('treats a git mv from outside the upgrades tree into a valid transition directory as a move, not an addition', () => { @@ -560,11 +583,11 @@ describe('check-upgrade-coverage — new-entries rule', () => { // Simulate `git mv` by writing the file at the new path (same content) // and removing the old path. Git's rename detection (-M) infers the move. writeRepoFile( - 'skills/prisma-8/upgrading/app/upgrades/0.6-to-0.7/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.6-to-0.7/instructions.md', '---\nfrom: "0.6"\nto: "0.7"\nchanges: []\n---\n', ); git('rm', 'packages/0-shared/upgrade-skill/upgrades/0.6-to-0.7/instructions.md'); - git('add', 'skills/prisma-8/upgrading/app/upgrades/0.6-to-0.7/instructions.md'); + git('add', 'skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.6-to-0.7/instructions.md'); git('commit', '-m', 'move upgrade instructions to new cluster'); const result = runScript(['--prev', prev, '--head', 'HEAD']); @@ -575,7 +598,7 @@ describe('check-upgrade-coverage — new-entries rule', () => { it('accepts a modification to an existing file in a stale transition directory', () => { writePackageJson('0.7.0'); writeRepoFile( - 'skills/prisma-8/upgrading/app/upgrades/0.6-to-0.7/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.6-to-0.7/instructions.md', '---\nfrom: "0.6"\nto: "0.7"\nchanges: []\n---\n# v1\n', ); commitAll('prev'); @@ -583,7 +606,7 @@ describe('check-upgrade-coverage — new-entries rule', () => { writePackageJson('0.8.0'); // Same path — modification, not add. writeRepoFile( - 'skills/prisma-8/upgrading/app/upgrades/0.6-to-0.7/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.6-to-0.7/instructions.md', '---\nfrom: "0.6"\nto: "0.7"\nchanges: []\n---\n# v2 — bug fix\n', ); commitAll('head'); @@ -608,25 +631,34 @@ describe('check-upgrade-coverage — skip-publish chain (head.minor > prev.minor const missingBoth = runScript(['--prev', prev, '--head', 'HEAD']); assert.notEqual(missingBoth.status, 0); - assert.match(missingBoth.stderr, /skills\/prisma-8\/upgrading\/app\/upgrades\/0\.7-to-0\.8/); - assert.match(missingBoth.stderr, /skills\/prisma-8\/upgrading\/app\/upgrades\/0\.8-to-0\.9/); + assert.match( + missingBoth.stderr, + /skills\/prisma-orm-core-concepts\/upgrading\/app\/upgrades\/0\.7-to-0\.8/, + ); + assert.match( + missingBoth.stderr, + /skills\/prisma-orm-core-concepts\/upgrading\/app\/upgrades\/0\.8-to-0\.9/, + ); assert.doesNotMatch(missingBoth.stderr, /upgrades\/0\.7-to-0\.9/); writeRepoFile( - 'skills/prisma-8/upgrading/app/upgrades/0.7-to-0.8/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.7-to-0.8/instructions.md', '---\nfrom: "0.7"\nto: "0.8"\nchanges: []\n---\n', ); commitAll('add 0.7-to-0.8'); const missingSecond = runScript(['--prev', prev, '--head', 'HEAD']); assert.notEqual(missingSecond.status, 0); - assert.match(missingSecond.stderr, /skills\/prisma-8\/upgrading\/app\/upgrades\/0\.8-to-0\.9/); + assert.match( + missingSecond.stderr, + /skills\/prisma-orm-core-concepts\/upgrading\/app\/upgrades\/0\.8-to-0\.9/, + ); assert.doesNotMatch( missingSecond.stderr, - /skills\/prisma-8\/upgrading\/app\/upgrades\/0\.7-to-0\.8[^/]*$/m, + /skills\/prisma-orm-core-concepts\/upgrading\/app\/upgrades\/0\.7-to-0\.8[^/]*$/m, ); writeRepoFile( - 'skills/prisma-8/upgrading/app/upgrades/0.8-to-0.9/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.8-to-0.9/instructions.md', '---\nfrom: "0.8"\nto: "0.9"\nchanges: []\n---\n', ); commitAll('add 0.8-to-0.9'); @@ -640,23 +672,23 @@ describe('check-upgrade-coverage — skip-publish chain (head.minor > prev.minor const prev = git('rev-parse', 'HEAD'); writePackageJson('0.9.0'); writeRepoFile( - 'skills/prisma-8/upgrading/app/upgrades/0.7-to-0.8/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.7-to-0.8/instructions.md', '---\nfrom: "0.7"\nto: "0.8"\nchanges: []\n---\n', ); writeRepoFile( - 'skills/prisma-8/upgrading/app/upgrades/0.8-to-0.9/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.8-to-0.9/instructions.md', '---\nfrom: "0.8"\nto: "0.9"\nchanges: []\n---\n', ); writeRepoFile( - 'skills/prisma-8/upgrading/extension/upgrades/0.7-to-0.8/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.7-to-0.8/instructions.md', '---\nfrom: "0.7"\nto: "0.8"\nchanges: []\n---\n', ); writeRepoFile( - 'skills/prisma-8/upgrading/extension/upgrades/0.8-to-0.9/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.8-to-0.9/instructions.md', '---\nfrom: "0.8"\nto: "0.9"\nchanges: []\n---\n', ); writeRepoFile( - 'skills/prisma-8/upgrading/app/upgrades/0.9-to-0.10/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.9-to-0.10/instructions.md', '---\nfrom: "0.9"\nto: "0.10"\nchanges: []\n---\n', ); commitAll('head'); @@ -671,15 +703,15 @@ describe('check-upgrade-coverage — skip-publish chain (head.minor > prev.minor writePackageJson('0.9.0'); // Coverage directories for the chain so coverage isn't the failure mode. writeRepoFile( - 'skills/prisma-8/upgrading/app/upgrades/0.7-to-0.8/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.7-to-0.8/instructions.md', '---\nfrom: "0.7"\nto: "0.8"\nchanges: []\n---\n', ); writeRepoFile( - 'skills/prisma-8/upgrading/app/upgrades/0.8-to-0.9/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.8-to-0.9/instructions.md', '---\nfrom: "0.8"\nto: "0.9"\nchanges: []\n---\n', ); writeRepoFile( - 'skills/prisma-8/upgrading/app/upgrades/0.6-to-0.7/new-script.ts', + 'skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.6-to-0.7/new-script.ts', 'export const x = 1;\n', ); commitAll('head'); @@ -708,8 +740,8 @@ describe('check-upgrade-coverage — skip-publish chain (head.minor > prev.minor .filter((v) => v.rule === 'coverage' && v.substrate === 'examples/') .map((v) => v.requiredDir); assert.deepEqual(coverageDirs.sort(), [ - 'skills/prisma-8/upgrading/app/upgrades/0.7-to-0.8', - 'skills/prisma-8/upgrading/app/upgrades/0.8-to-0.9', + 'skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.7-to-0.8', + 'skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.8-to-0.9', ]); }); }); @@ -734,12 +766,12 @@ describe('check-upgrade-coverage — release-candidate release PR', () => { assert.notEqual(missing.status, 0); assert.match( missing.stderr, - /skills\/prisma-8\/upgrading\/app\/upgrades\/8\.0\.0-rc\.1-to-8\.0\.0-rc\.2/, + /skills\/prisma-orm-core-concepts\/upgrading\/app\/upgrades\/8\.0\.0-rc\.1-to-8\.0\.0-rc\.2/, ); assert.doesNotMatch(missing.stderr, /upgrades\/8\.0-to-8\.1/); writeRepoFile( - 'skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.1-to-8.0.0-rc.2/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/app/upgrades/8.0.0-rc.1-to-8.0.0-rc.2/instructions.md', '---\nfrom: "8.0.0-rc.1"\nto: "8.0.0-rc.2"\nchanges: []\n---\n', ); commitAll('record the rc.1 → rc.2 entry'); @@ -753,7 +785,7 @@ describe('check-upgrade-coverage — release-candidate release PR', () => { const prev = git('rev-parse', 'HEAD'); writeRepoFile('examples/demo/src/main.ts', 'export const a = 2;\n'); writeRepoFile( - 'skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.1-to-8.0.0-rc.2/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/app/upgrades/8.0.0-rc.1-to-8.0.0-rc.2/instructions.md', '---\nfrom: "8.0.0-rc.1"\nto: "8.0.0-rc.2"\nchanges: []\n---\n', ); commitAll('head'); @@ -850,7 +882,7 @@ describe('check-upgrade-coverage — per-PR correspondence rule', () => { it('substrate touched + in-flight instructions.md NOT in diff → violation', () => { writePackageJson('0.7.0'); writeRepoFile( - 'skills/prisma-8/upgrading/app/upgrades/0.7-to-0.8/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.7-to-0.8/instructions.md', '---\nfrom: "0.7"\nto: "0.8"\nchanges: []\n---\n', ); commitAll('prev — directory already exists'); @@ -862,7 +894,7 @@ describe('check-upgrade-coverage — per-PR correspondence rule', () => { assert.match(result.stderr, /per-pr-declaration/); assert.match( result.stderr, - /skills\/prisma-8\/upgrading\/app\/upgrades\/0\.7-to-0\.8\/instructions\.md/, + /skills\/prisma-orm-core-concepts\/upgrading\/app\/upgrades\/0\.7-to-0\.8\/instructions\.md/, ); }); @@ -872,7 +904,7 @@ describe('check-upgrade-coverage — per-PR correspondence rule', () => { const prev = git('rev-parse', 'HEAD'); writeRepoFile('examples/demo/src/main.ts', 'export const a = 2;\n'); writeRepoFile( - 'skills/prisma-8/upgrading/app/upgrades/0.7-to-0.8/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.7-to-0.8/instructions.md', '---\nfrom: "0.7"\nto: "0.8"\nchanges:\n - id: my-change\n summary: Some migration step.\n---\n', ); commitAll('head'); @@ -886,7 +918,7 @@ describe('check-upgrade-coverage — per-PR correspondence rule', () => { const prev = git('rev-parse', 'HEAD'); writeRepoFile('examples/demo/src/main.ts', 'export const a = 2;\n'); writeRepoFile( - 'skills/prisma-8/upgrading/app/upgrades/0.7-to-0.8/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.7-to-0.8/instructions.md', '---\nfrom: "0.7"\nto: "0.8"\nchanges: []\n---\n', ); commitAll('head'); @@ -910,11 +942,11 @@ describe('check-upgrade-coverage — per-PR correspondence rule', () => { // correspondence check then fires independently for each cluster. writePackageJson('0.7.0'); writeRepoFile( - 'skills/prisma-8/upgrading/app/upgrades/0.7-to-0.8/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.7-to-0.8/instructions.md', '---\nfrom: "0.7"\nto: "0.8"\nchanges: []\n---\n', ); writeRepoFile( - 'skills/prisma-8/upgrading/extension/upgrades/0.7-to-0.8/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.7-to-0.8/instructions.md', '---\nfrom: "0.7"\nto: "0.8"\nchanges: []\n---\n', ); commitAll('prev — both directories already exist'); @@ -924,7 +956,7 @@ describe('check-upgrade-coverage — per-PR correspondence rule', () => { writeRepoFile('examples/demo/src/main.ts', 'b\n'); writeRepoFile('packages/3-extensions/pgvector/src/main.ts', 'b\n'); writeRepoFile( - 'skills/prisma-8/upgrading/app/upgrades/0.7-to-0.8/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.7-to-0.8/instructions.md', '---\nfrom: "0.7"\nto: "0.8"\nchanges: []\n---\nupdated\n', ); commitAll('head — only user-skill instructions.md updated'); @@ -933,15 +965,15 @@ describe('check-upgrade-coverage — per-PR correspondence rule', () => { assert.match(missingExt.stderr, /per-pr-declaration/); assert.match( missingExt.stderr, - /skills\/prisma-8\/upgrading\/extension\/upgrades\/0\.7-to-0\.8\/instructions\.md/, + /skills\/prisma-orm-core-concepts\/upgrading\/extension\/upgrades\/0\.7-to-0\.8\/instructions\.md/, ); assert.doesNotMatch( missingExt.stderr, - /skills\/prisma-8\/upgrading\/app\/upgrades\/0\.7-to-0\.8\/instructions\.md/, + /skills\/prisma-orm-core-concepts\/upgrading\/app\/upgrades\/0\.7-to-0\.8\/instructions\.md/, ); writeRepoFile( - 'skills/prisma-8/upgrading/extension/upgrades/0.7-to-0.8/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.7-to-0.8/instructions.md', '---\nfrom: "0.7"\nto: "0.8"\nchanges: []\n---\nupdated\n', ); commitAll('head — both instructions.md updated'); @@ -955,7 +987,7 @@ describe('check-upgrade-coverage — per-PR correspondence rule', () => { const prev = git('rev-parse', 'HEAD'); writeRepoFile('examples/demo/src/main.ts', 'export const a = 2;\n'); writeRepoFile( - 'skills/prisma-8/upgrading/app/upgrades/0.7-to-0.8/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.7-to-0.8/instructions.md', '---\nfrom: "0.7"\nto: "0.8"\n---\n', ); commitAll('head — instructions.md missing changes key'); @@ -969,11 +1001,11 @@ describe('check-upgrade-coverage — translation-irrelevant substrate diffs need function seedTransitionDir() { writePackageJson('0.7.0'); writeRepoFile( - 'skills/prisma-8/upgrading/app/upgrades/0.7-to-0.8/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.7-to-0.8/instructions.md', '---\nfrom: "0.7"\nto: "0.8"\nchanges: []\n---\n', ); writeRepoFile( - 'skills/prisma-8/upgrading/extension/upgrades/0.7-to-0.8/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.7-to-0.8/instructions.md', '---\nfrom: "0.7"\nto: "0.8"\nchanges: []\n---\n', ); } @@ -1233,7 +1265,7 @@ describe('check-upgrade-coverage — release sweep per-PR declaration', () => { writePackageJson('8.0.0-rc.3'); writeRepoFile('examples/demo/package.json', '{"name":"demo","version":"8.0.0-rc.3"}\n'); writeRepoFile( - 'skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.3-to-8.0.0-rc.4/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/app/upgrades/8.0.0-rc.3-to-8.0.0-rc.4/instructions.md', '---\nfrom: "8.0.0-rc.3"\nto: "8.0.0-rc.4"\nchanges: []\n---\n', ); commitAll('prev, directory already recorded by an earlier PR'); @@ -1252,7 +1284,7 @@ describe('check-upgrade-coverage — release sweep per-PR declaration', () => { writeRepoFile('examples/demo/package.json', '{"name":"demo","version":"8.0.0-rc.3"}\n'); writeRepoFile('examples/demo/src/main.ts', 'export const a = 1;\n'); writeRepoFile( - 'skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.3-to-8.0.0-rc.4/instructions.md', + 'skills/prisma-orm-core-concepts/upgrading/app/upgrades/8.0.0-rc.3-to-8.0.0-rc.4/instructions.md', '---\nfrom: "8.0.0-rc.3"\nto: "8.0.0-rc.4"\nchanges: []\n---\n', ); commitAll('prev'); diff --git a/scripts/lint-throws.test.mjs b/scripts/lint-throws.test.mjs index 5811de4e37c2..42b8605b99f7 100644 --- a/scripts/lint-throws.test.mjs +++ b/scripts/lint-throws.test.mjs @@ -89,7 +89,9 @@ describe('filterNoBareThrowDiags', () => { { category: 'plugin', message: msg, - location: { path: 'skills/prisma-8/upgrading/app/upgrades/0.9-to-0.10/codemod.ts' }, + location: { + path: 'skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.9-to-0.10/codemod.ts', + }, }, { category: 'plugin', message: msg, location: { path: 'packages/x/src/scripts.ts' } }, { category: 'plugin', message: msg, location: { path: 'packages/x/src/thing.ts' } }, diff --git a/scripts/set-version.ts b/scripts/set-version.ts index f5b492114732..abb3d8e15497 100755 --- a/scripts/set-version.ts +++ b/scripts/set-version.ts @@ -10,6 +10,7 @@ import { rewriteWorkspaceDeps, stampSkillMetadata, } from './set-version-utils.ts'; +import { SKILL_NAMES } from './sync-package-skills.ts'; const rootDir = path.dirname(path.dirname(fileURLToPath(import.meta.url))); @@ -92,12 +93,14 @@ for (const manifestPath of trackedManifests) { // The user-facing skills ship inside the `@prisma/orm-*` tarballs and carry // the version they were published with in their frontmatter, so a consumer -// can tell whether its synced copy still matches its installed packages. -const skillPath = path.join(rootDir, 'skills', 'prisma-8', 'SKILL.md'); -await fs.writeFile( - skillPath, - stampSkillMetadata(await fs.readFile(skillPath, 'utf-8'), 'library_version', version), -); -console.log(`Stamped ${path.relative(rootDir, skillPath)} with library_version ${version}`); +// can tell whether its synced copies still match its installed packages. +for (const skillName of SKILL_NAMES) { + const skillPath = path.join(rootDir, 'skills', skillName, 'SKILL.md'); + await fs.writeFile( + skillPath, + stampSkillMetadata(await fs.readFile(skillPath, 'utf-8'), 'library_version', version), + ); + console.log(`Stamped ${path.relative(rootDir, skillPath)} with library_version ${version}`); +} console.log(`\nDone! Updated ${updatedCount} packages.`); diff --git a/scripts/sync-package-skills.ts b/scripts/sync-package-skills.ts index 17c0e7a65fe6..a04807a86ef3 100644 --- a/scripts/sync-package-skills.ts +++ b/scripts/sync-package-skills.ts @@ -1,13 +1,13 @@ #!/usr/bin/env node /** - * Copies the user-facing `skills/prisma-8/` tree into the packages that ship - * it, stamping each copy with the package it now belongs to. + * Copies the user-facing `skills/prisma-orm-*` trees into the packages that + * ship them, stamping each copy with the package it now belongs to. * * Usage: node scripts/sync-package-skills.ts [...] * * Run from each shipping package's `prepack`, so the tarball always carries - * the skill tree that matches the code beside it. The copies are build + * the skill trees that match the code beside it. The copies are build * output: they are gitignored, and `files` carries them into the tarball. */ @@ -31,36 +31,41 @@ export const SKILL_ANCHOR_PACKAGES: ReadonlyMap = new Map([ ['@prisma/orm-mongo', 'packages/9-public/@prisma/orm-mongo'], ]); -export const SKILL_NAME = 'prisma-8'; +export const SKILL_NAMES = ['prisma-orm-core-concepts', 'prisma-orm-migrations'] as const; -export async function syncPackageSkills(packageName: string): Promise { +export async function syncPackageSkills(packageName: string): Promise { const packageDir = SKILL_ANCHOR_PACKAGES.get(packageName); if (packageDir === undefined) { const shipping = [...SKILL_ANCHOR_PACKAGES.keys()].join(', '); - throw new Error(`${packageName} does not ship the ${SKILL_NAME} skill; expected ${shipping}`); + throw new Error(`${packageName} does not ship the Prisma skills; expected ${shipping}`); } - const source = path.join(rootDir, 'skills', SKILL_NAME); - const destination = path.join(rootDir, packageDir, 'skills', SKILL_NAME); - await fs.rm(destination, { recursive: true, force: true }); - await fs.cp(source, destination, { recursive: true }); + const destinations: string[] = []; + await fs.rm(path.join(rootDir, packageDir, 'skills'), { recursive: true, force: true }); + for (const skillName of SKILL_NAMES) { + const source = path.join(rootDir, 'skills', skillName); + const destination = path.join(rootDir, packageDir, 'skills', skillName); + await fs.cp(source, destination, { recursive: true }); - // The source tree names one canonical package; each copy names its own, so - // a consumer reading the copy sees the package it resolved it from. - const skillMd = path.join(destination, 'SKILL.md'); - await fs.writeFile( - skillMd, - stampSkillMetadata(await fs.readFile(skillMd, 'utf-8'), 'library', packageName), - ); + // The source tree names one canonical package; each copy names its own, + // so a consumer reading the copy sees the package it resolved it from. + const skillMd = path.join(destination, 'SKILL.md'); + await fs.writeFile( + skillMd, + stampSkillMetadata(await fs.readFile(skillMd, 'utf-8'), 'library', packageName), + ); + destinations.push(destination); + } - return destination; + return destinations; } if (import.meta.url === `file://${process.argv[1]}`) { const requested = process.argv.slice(2); const targets = requested.length > 0 ? requested : [...SKILL_ANCHOR_PACKAGES.keys()]; for (const packageName of targets) { - const destination = await syncPackageSkills(packageName); - console.log(`Copied skills/${SKILL_NAME} to ${path.relative(rootDir, destination)}`); + for (const destination of await syncPackageSkills(packageName)) { + console.log(`Copied ${path.relative(rootDir, destination)}`); + } } } diff --git a/skills-contrib/draft-release-notes/SKILL.md b/skills-contrib/draft-release-notes/SKILL.md index 336521fec195..66b25ae561d0 100644 --- a/skills-contrib/draft-release-notes/SKILL.md +++ b/skills-contrib/draft-release-notes/SKILL.md @@ -129,8 +129,8 @@ A breaking change shipping in this release has a matching upgrade-instructions d **Recipe links must be absolute, tag-pinned URLs** — `https://github.com/prisma/prisma/blob/v$NEXT/...`. The notes file becomes the GitHub Release body via `--notes-file`, and the Release page does **not** reliably resolve repo-relative links, so a relative recipe path would publish as a dead migration link. Pinning to the release tag (`/blob/v$NEXT/`) means the link always resolves and never rots as the recipe tree evolves on `main`: -- User-facing migrations: `https://github.com/prisma/prisma/blob/v$NEXT/skills/prisma-8/upgrading/app/upgrades/-to-/` -- Extension-author migrations: `https://github.com/prisma/prisma/blob/v$NEXT/skills/prisma-8/upgrading/extension/upgrades/-to-/` +- User-facing migrations: `https://github.com/prisma/prisma/blob/v$NEXT/skills/prisma-orm-core-concepts/upgrading/app/upgrades/-to-/` +- Extension-author migrations: `https://github.com/prisma/prisma/blob/v$NEXT/skills/prisma-orm-core-concepts/upgrading/extension/upgrades/-to-/` A breaking change can affect one or both audiences — link whichever recipe directories exist. @@ -250,7 +250,7 @@ Cutting `v0.12.0` from `origin/main` (previous stable tag `v0.11.0`). 3. PR #1240's title is `TML-2536: contract deserializer seam`. Read TML-2536 in Linear → the user-facing outcome is "contract deserialization now goes through an explicit adapter seam". Write that outcome in public words; cite #1240, not TML-2536. 4. Triage: #1240 changes the contract format → **always-include, breaking**. A CI-cache tweak (#1237) and a test-only refactor (#1239) → **default-exclude**, dropped silently. A new `includeMany` capability (#1234) → feature. A null-handling bug fix (#1242) → fix. First-time contributor @somebody on #1238. 5. Categorize: Breaking changes (#1240) → Features (#1234) → Fixes (#1242) → New contributors (@somebody, #1238). -6. The breaking change's transition is `0.11-to-0.12`. The recipe dir `skills/prisma-8/upgrading/app/upgrades/0.11-to-0.12/` exists in the checkout → the breaking note links it as a tag-pinned URL, `https://github.com/prisma/prisma/blob/v0.12.0/skills/prisma-8/upgrading/app/upgrades/0.11-to-0.12/`. (If it were absent, the note would describe the required adapter migration inline instead.) +6. The breaking change's transition is `0.11-to-0.12`. The recipe dir `skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.11-to-0.12/` exists in the checkout → the breaking note links it as a tag-pinned URL, `https://github.com/prisma/prisma/blob/v0.12.0/skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.11-to-0.12/`. (If it were absent, the note would describe the required adapter migration inline instead.) 7. #1240 is a code-visible contract-shape/runtime change, so it earns a before/after example — lifted from the `0.11-to-0.12` recipe (a TS runtime change, so a `ts` fence). @somebody's contributor line, with absolute links: `- [@somebody](https://github.com/somebody) made their first contribution in [#1238](https://github.com/prisma/prisma-next/pull/1238)`. 8. Write `docs/releases/v0.12.0.md` (every PR ref + handle an absolute link; the breaking entry carries a before/after): @@ -261,7 +261,7 @@ Contract deserialization gains an explicit adapter seam, and queries can now eag ## Breaking changes -- **Contract deserialization requires an adapter seam** — deserialization now goes through an explicit seam adapter; existing code must register one. See the [0.11-to-0.12 upgrade recipe](https://github.com/prisma/prisma-next/blob/v0.12.0/skills/prisma-8/upgrading/app/upgrades/0.11-to-0.12/). ([#1240](https://github.com/prisma/prisma-next/pull/1240)) +- **Contract deserialization requires an adapter seam** — deserialization now goes through an explicit seam adapter; existing code must register one. See the [0.11-to-0.12 upgrade recipe](https://github.com/prisma/prisma-next/blob/v0.12.0/skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.11-to-0.12/). ([#1240](https://github.com/prisma/prisma-next/pull/1240)) Before: diff --git a/skills-contrib/record-upgrade-instructions/SKILL.md b/skills-contrib/record-upgrade-instructions/SKILL.md index 62a622f1bfe6..0e3082f495b7 100644 --- a/skills-contrib/record-upgrade-instructions/SKILL.md +++ b/skills-contrib/record-upgrade-instructions/SKILL.md @@ -19,8 +19,8 @@ This skill fires on PRs **inside this repo** that make a breaking change to Pris The published skills you will be authoring entries into: -- `skills/prisma-8/upgrading/app/` — the upgrading branch of the `prisma-8` skill, shipped inside the `@prisma/orm-*` tarballs. **Audience: users of Prisma Next** (consumers of the public package API: `@internal/postgres`, `@internal/mongo`, the contract files in `prisma/`, on-disk migration shape). -- `skills/prisma-8/upgrading/extension/` — the extension-author half of the same branch. **Audience: authors of Prisma Next extensions** (consumers of the framework SPI: `@internal/contract`, `@internal/framework-components`, `@internal/migration-tools`, etc.). +- `skills/prisma-orm-core-concepts/upgrading/app/` — the upgrading branch of the `prisma-orm-core-concepts` skill, shipped inside the `@prisma/orm-*` tarballs. **Audience: users of Prisma Next** (consumers of the public package API: `@internal/postgres`, `@internal/mongo`, the contract files in `prisma/`, on-disk migration shape). +- `skills/prisma-orm-core-concepts/upgrading/extension/` — the extension-author half of the same branch. **Audience: authors of Prisma Next extensions** (consumers of the framework SPI: `@internal/contract`, `@internal/framework-components`, `@internal/migration-tools`, etc.). The two skill clusters are independent (no shared content). Cross-audience breaking changes — where the same on-disk transformation applies to both substrates — are recorded *separately* in each cluster, including duplicated colocated scripts. @@ -44,8 +44,8 @@ Two mechanical signals, each tied to one destination package: | Substrate touched by the PR | Destination skill | | ------------------------------ | -------------------------------------------------------------- | -| `examples/` | `skills/prisma-8/upgrading/app/` | -| `packages/3-extensions/` | `skills/prisma-8/upgrading/extension/` | +| `examples/` | `skills/prisma-orm-core-concepts/upgrading/app/` | +| `packages/3-extensions/` | `skills/prisma-orm-core-concepts/upgrading/extension/` | | Both | Both — duplicated entries (see below) | The substrate diff is the signal that an entry is required. The agent fixing the red tests in those substrates sees the signal directly; the reviewer sees the same diff. The release-pipeline check (`pnpm check:upgrade-coverage`) enforces the outcome — a substrate diff without the matching directory fails the PR. @@ -67,7 +67,7 @@ For each PR that hits one or both signals, walk these steps in order. 2. **Identify the touched substrate(s).** Compute `git diff origin/..HEAD` restricted to `examples/` and to `packages/3-extensions/`. Each non-empty substrate corresponds to one destination package per the routing table above. The "both" case is normal — the rare PR (e.g. a structural on-disk migration shape change) touches both. -3. **Find or create the directory in each destination.** For each destination, the directory is `/upgrades//` from step 1 (so e.g. `skills/prisma-8/upgrading/app/upgrades/0.7-to-0.8/` for the user-skill). If the directory already exists (an earlier PR on the same transition created it, or the placeholder shipped with the initial mechanism PR is still there), **do not create a duplicate** — append a new entry to the existing `instructions.md`'s `changes[]` array. +3. **Find or create the directory in each destination.** For each destination, the directory is `/upgrades//` from step 1 (so e.g. `skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.7-to-0.8/` for the user-skill). If the directory already exists (an earlier PR on the same transition created it, or the placeholder shipped with the initial mechanism PR is still there), **do not create a duplicate** — append a new entry to the existing `instructions.md`'s `changes[]` array. 4. **Write the entry into `instructions.md`.** Each `changes[]` entry carries an `id` (kebab-case, unique within the transition), a one-line `summary`, an optional `detection` block (glob + content predicate the consumer's agent runs to know whether the change applies to that consumer's project), and an optional `script:` reference (relative path to a colocated script next to `instructions.md`). For changes that need agent reasoning across the codebase rather than a deterministic script, the entry omits `script:` and the agent follows the prose body of `instructions.md` instead. @@ -147,7 +147,7 @@ The PR that introduces the breaking change must contain, in addition to the fram - **The new entry directory in each affected skill** — `/upgrades//instructions.md` plus any colocated scripts (the in-flight transition being the one determined in step 1 of the authoring workflow). - **The post-instructions state of every affected substrate** — these substrates would have been left broken without the entry; the entry's effect on the substrate *is* the diff that brings them back to green. The `` substrate state and the validation-by-execution output state must be identical outside the substrate's `test/` directories, which the entry neither writes nor updates. -- **A reference in the PR description naming each entry directory** (e.g. *"Adds entries to `skills/prisma-8/upgrading/app/upgrades/0.7-to-0.8/` and `skills/prisma-8/upgrading/extension/upgrades/0.7-to-0.8/`."*). +- **A reference in the PR description naming each entry directory** (e.g. *"Adds entries to `skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.7-to-0.8/` and `skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.7-to-0.8/`."*). The human reviewer + the CI gate (`pnpm check:upgrade-coverage`) both check this shape, but the gate is **necessary-but-not-sufficient** — it only asserts that the in-flight transition *directory* exists, not that *this PR's* substrate diff has a matching `changes[]` entry. So a PR can have a real substrate diff, contribute no entry, and still pass the gate green whenever an earlier PR already created the transition directory. (This is exactly how a breaking change can ship undocumented: the directory was already there, so the gate stayed green.) The gap is load-bearing for the reviewer: **the human reviewer must verify that every substrate diff in the PR has a corresponding entry** — the gate will not catch a missing entry once the directory exists. The reviewer also catches the semantic case (entry exists but its prose / scripts don't match the framework change). @@ -183,7 +183,7 @@ Two corollaries of a release cut: ## Out of scope -This skill records **upgrade instructions** — code-translation entries the published skills will replay against consumer projects. It does **not** add the per-step bump-install-instructions-validate-commit loop to entry bodies. That flow is general content carried in the published `SKILL.md` files (`skills/prisma-8/references/upgrade-app.md` and `skills/prisma-8/references/upgrade-extension.md`) and runs around your entry. Your entry only contains the code-translation work specific to the transition. +This skill records **upgrade instructions** — code-translation entries the published skills will replay against consumer projects. It does **not** add the per-step bump-install-instructions-validate-commit loop to entry bodies. That flow is general content carried in the published `SKILL.md` files (`skills/prisma-orm-core-concepts/references/upgrade-app.md` and `skills/prisma-orm-core-concepts/references/upgrade-extension.md`) and runs around your entry. Your entry only contains the code-translation work specific to the transition. This skill also does not enforce the exact-pin rule for extensions — that is `prisma-8-check-pins` (a `bin` of `@internal/extension-author-tools`), and it runs in extension authors' own CI plus in the extension-upgrade skill's per-step flow. @@ -198,9 +198,9 @@ Both substrates are touched → both skill packages need entries. 1. Read root `package.json` on the PR branch → `version: "0.7.0"`. Currently-published minor is `0.7`, so the in-flight transition is `0.7 → 0.8`. Directory is `upgrades/0.7-to-0.8/` in each skill package. 2. Both substrates touched. -3. `skills/prisma-8/upgrading/app/upgrades/0.7-to-0.8/instructions.md` already exists (placeholder shipped with the initial mechanism PR). Append a `changes[]` entry — call it `migration-metadata-shape-update`. Same for `skills/prisma-8/upgrading/extension/upgrades/0.7-to-0.8/instructions.md`. +3. `skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.7-to-0.8/instructions.md` already exists (placeholder shipped with the initial mechanism PR). Append a `changes[]` entry — call it `migration-metadata-shape-update`. Same for `skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.7-to-0.8/instructions.md`. 4. The user-skill entry may be prose-only (e.g. "rename the imported type from `MigrationMetadata` to `MigrationManifest` in any consumer code"), since the user-facing fix is a simple rename. -5. The extension-skill entry needs more work — the SPI changed shape, not just name. Author `skills/prisma-8/upgrading/extension/upgrades/0.7-to-0.8/update-migration-tools-imports.ts` and reference it from the entry's `script:` field. If the same transformation also applies to the example, copy the script into the user-skill cluster's directory too. +5. The extension-skill entry needs more work — the SPI changed shape, not just name. Author `skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.7-to-0.8/update-migration-tools-imports.ts` and reference it from the entry's `script:` field. If the same transformation also applies to the example, copy the script into the user-skill cluster's directory too. 6. Validate by execution: revert `packages/3-extensions/` to pre-PR → run the extension-skill entry → verify `pnpm test --filter='./packages/3-extensions/*'` green, the non-test paths matching ``, and the test paths still at ``. Then revert `examples/` to pre-PR → run the user-skill entry → verify `pnpm --filter test` green for the touched example, with the same two path checks. 7. Commit on the PR branch with both entry directories, the colocated script(s), and the matching substrate post-state. @@ -208,4 +208,4 @@ Both substrates are touched → both skill packages need entries. - Mechanism Linear ticket: [TML-2519](https://linear.app/prisma-company/issue/TML-2519). - Coverage gate script: `scripts/check-upgrade-coverage.mjs` (invoked as `pnpm check:upgrade-coverage`). -- Published skills whose entries you are authoring: `skills/prisma-8/upgrading/app/`, `skills/prisma-8/upgrading/extension/`. +- Published skills whose entries you are authoring: `skills/prisma-orm-core-concepts/upgrading/app/`, `skills/prisma-orm-core-concepts/upgrading/extension/`. diff --git a/skills/DEVELOPING.md b/skills/DEVELOPING.md index 8ff404ea2199..fe9e82c53ecf 100644 --- a/skills/DEVELOPING.md +++ b/skills/DEVELOPING.md @@ -4,31 +4,36 @@ Contributor guide for the Prisma Next skills cluster. If you are *using* the ski ## What this tree is -Skills that teach an LLM agent how to operate Prisma Next end-to-end. The usage surface is one consolidated skill: [`skills/prisma-8/SKILL.md`](./prisma-8/SKILL.md) is the runtime-matched entry point (its `description:` frontmatter fires on any Prisma Next work) and routes via its routing table into workflow-scoped reference files under [`skills/prisma-8/references/`](./prisma-8/references/) — one user goal per reference file. Upgrading is part of the same skill: [`references/upgrade-app.md`](./prisma-8/references/upgrade-app.md) and [`references/upgrade-extension.md`](./prisma-8/references/upgrade-extension.md) carry the two flows, and the per-transition instructions they replay live under [`prisma-8/upgrading/app/upgrades/`](./prisma-8/upgrading/app/upgrades/) and [`prisma-8/upgrading/extension/upgrades/`](./prisma-8/upgrading/extension/upgrades/). +Skills that teach an LLM agent how to operate Prisma Next end-to-end. The usage surface is two skills with fixed trigger territories: + +- [`prisma-orm-core-concepts`](./prisma-orm-core-concepts/SKILL.md) — everything except migrations: the mental model, structured-error diagnosis, and the development workflows (quickstart, contract authoring, queries, runtime, build, Supabase, feedback, upgrades). Fires whenever the agent works with Prisma ORM. +- [`prisma-orm-migrations`](./prisma-orm-migrations/SKILL.md) — migration authoring, the graph/refs model, deploy review. Fires on migration work. + +Each `SKILL.md` is the runtime-matched entry point for its territory and routes via its routing table into workflow-scoped reference files under that skill's `references/` — one user goal per reference file. Upgrading is part of the core-concepts skill: [`references/upgrade-app.md`](./prisma-orm-core-concepts/references/upgrade-app.md) and [`references/upgrade-extension.md`](./prisma-orm-core-concepts/references/upgrade-extension.md) carry the two flows, and the per-transition instructions they replay live under [`prisma-orm-core-concepts/upgrading/app/upgrades/`](./prisma-orm-core-concepts/upgrading/app/upgrades/) and [`prisma-orm-core-concepts/upgrading/extension/upgrades/`](./prisma-orm-core-concepts/upgrading/extension/upgrades/). ## Design principles -The consolidated shape is deliberate. These principles govern every change to the published skills; a change that regresses one of them needs an explicit reason in the PR. +The two-skill shape is deliberate. These principles govern every change to the published skills; a change that regresses one of them needs an explicit reason in the PR. -### One skill, not a cluster +### Two skills, fixed territories -The usage surface is exactly one installable skill. Agent runtimes match skills against the user's prompt by `description:` — a cluster of sibling skills forces each description to carve out its own trigger territory, and the boundaries drift, overlap, and misfire as the cluster grows. One skill means one activation decision ("is this Prisma Next work?") followed by an explicit routing step the skill itself controls. +The usage surface is exactly two installable skills — core-concepts and migrations — and the set is closed. Agent runtimes match skills against the user's prompt by `description:`, and sibling descriptions carve trigger territory that drifts, overlaps, and misfires as a cluster grows (the pre-consolidation per-workflow cluster failed exactly this way; its names live on in the CLI's retired-skills cleanup list). The boundary is migrations-vs-everything-else: `prisma-orm-core-concepts` fires whenever the agent works with Prisma ORM at all, `prisma-orm-migrations` on migration work specifically, and each `SKILL.md` carries a *Related skills* section that hands misrouted tasks to the sibling. -**A new top-level skill needs a structural reason, not a topical one.** The upgrade flows used to be two sibling skills because their install ref policy differed (always-`main` vs version-pinned); now that the skill ships inside the packages, every copy is version-matched by construction and that reason is gone. A new workflow, feature area, or extension is a new reference file plus a routing-table row, never a new sibling skill. +**A new top-level skill needs a structural reason, not a topical one.** A new workflow, feature area, or extension is a new reference file plus a routing-table row in the skill that owns its territory — never a new sibling skill. When a task genuinely straddles both territories (a migration triggered by a contract edit, an error envelope raised mid-migration), the answer is cross-routing between the existing two, not a third skill. ### Progressive disclosure -`SKILL.md` is the only always-loaded content, so it must earn its context budget. It carries three things: the activation description, the routing table, and the canonical mental model — nothing else. Everything workflow-specific lives in a reference file that is loaded only when its routing-table row matches. API detail, worked examples, pitfalls, and capability gaps all belong at the reference layer. +Each skill's `SKILL.md` is the only always-loaded content for its territory, so it must earn its context budget. It carries three things: the activation description, the routing table, and the canonical mental model — nothing else. Everything workflow-specific lives in a reference file that is loaded only when its routing-table row matches. API detail, worked examples, pitfalls, and capability gaps all belong at the reference layer. The test for placement: *would every Prisma Next task benefit from the agent having read this?* If yes, it may live in `SKILL.md`. If only some tasks would, it goes in a reference file. -**The exception: cross-cutting gotchas.** A fact that defies a reasonable assumption — and that the agent has no obvious trigger to look up before it acts — needs to be read *before* the agent hits the situation, not after. A reference file only loads once its routing-table row matches, so a surprising fact scoped to one reference is fine there (its own *Common Pitfalls* section covers it). A surprising fact that cuts across workflows — the kind where an agent already committed to a plan under a wrong assumption has no reason to go back and check a reference it never routed to — belongs in `SKILL.md` itself. The Mongo ORM addressing rule (`db.orm.` uses storage names, not PSL model names) is the existing example: it lives in `SKILL.md`'s canonical-model paragraph, not buried in `references/queries.md`, because an agent that already assumed model-name addressing has no reason to open the queries reference to find out it's wrong. Keep this tier small — it is competing for the same ~150-line budget as everything else in `SKILL.md`. +**The exception: cross-cutting gotchas.** A fact that defies a reasonable assumption — and that the agent has no obvious trigger to look up before it acts — needs to be read *before* the agent hits the situation, not after. A reference file only loads once its routing-table row matches, so a surprising fact scoped to one reference is fine there (its own *Common Pitfalls* section covers it). A surprising fact that cuts across workflows — the kind where an agent already committed to a plan under a wrong assumption has no reason to go back and check a reference it never routed to — belongs in the owning skill's `SKILL.md` itself. Two standing examples: the Mongo ORM addressing rule (`db.orm.` uses storage names, not PSL model names) lives in the core-concepts `SKILL.md`'s canonical-model paragraph, not buried in `references/queries.md`; the plan-origin rule (`migration plan` never chains from the newest migration on disk) lives in the migrations `SKILL.md`. Keep this tier small — it is competing for the same ~150-line budget as everything else in a `SKILL.md`. ### Length budgets -- **`SKILL.md`: ~150 lines.** It is an index and a mental model, not a manual. If it is growing, content is leaking up from the reference layer — push it back down. +- **Each `SKILL.md`: ~150 lines.** It is an index and a mental model, not a manual. If it is growing, content is leaking up from the reference layer — push it back down. - **Reference files: ~200–350 lines.** Below that range, consider whether the file earns its routing-table row or should merge into a sibling. Above it, split into a companion reference (the `queries.md` → `queries-postgres.md` / `queries-mongo.md` split is the template) and link the companions from the parent reference's routing row. -- **`description:` frontmatter: one activation trigger, not a keyword dump.** The 1024-character registry limit is a ceiling, not a target. The description answers "does this skill apply to the current work?"; the per-workflow trigger phrases (CLI flags, error codes, feature vocabulary) live in the routing table's *Triggers* column, where there is room to be exhaustive. +- **`description:` frontmatter: the skill's trigger territory, not a keyword dump.** The 1024-character registry limit is a ceiling, not a target. Each description answers "does this skill — as opposed to its sibling — apply to the current work?"; the per-workflow trigger phrases (CLI flags, error codes, feature vocabulary) live in the routing table's *Triggers* column, where there is room to be exhaustive. ### Point at the source of truth instead of copying it @@ -84,7 +89,7 @@ Procedural workflow sections — *"step 1: run X; step 2: read Y; step 3: if Z, #### Worked example — `references/migration-review.md` -The pilot rewrite of [`skills/prisma-8/references/migration-review.md`](./prisma-next/references/migration-review.md) is the canonical worked example for this principle in this cluster. Before that rewrite, the skill contained: +The pilot rewrite of [`skills/prisma-orm-migrations/references/migration-review.md`](./prisma-orm-migrations/references/migration-review.md) is the canonical worked example for this principle in this cluster. Before that rewrite, the skill contained: - A five-step *"diamond convergence procedure"* for resolving concurrent migrations. - A four-step *"detect that main advanced"* workflow. @@ -106,7 +111,7 @@ A skill that teaches the verbose form has handed the agent a worse mental model **Verify each user-authored import:** ```bash -rg "from '@internal/" skills/prisma-8/references/.md \ +rg "from '@internal/" skills/*/references/.md \ | rg -v '@internal/(postgres|mongo|sqlite|extension-|[a-z]+-plugin-)' \ | rg -v 'framework-rendered' ``` @@ -130,7 +135,7 @@ Commit `bf742221c` (`examples: migrate to @internal/ façade imports`) d These are well-trodden but worth listing in one place: -- **`description:` frontmatter is a runtime matcher, not marketing prose.** Only the consolidated `SKILL.md` carries frontmatter; its description fires on any Prisma Next work. Per-workflow trigger phrases — CLI flags, error codes, feature names, foreign-tool vocabulary a user would type — live in the routing table's *Triggers* column, and a new reference file must add its row there. +- **`description:` frontmatter is a runtime matcher, not marketing prose.** Only the three `SKILL.md` files carry frontmatter; each description fires on its skill's territory. Per-workflow trigger phrases — CLI flags, error codes, feature names, foreign-tool vocabulary a user would type — live in the owning skill's routing table's *Triggers* column, and a new reference file must add its row there. - **One workflow per reference file.** File size is bounded by the per-file line ceiling. If a workflow grows past it, split into a companion reference (the queries → queries-postgres/queries-mongo split is the template) — don't sprawl. - **Provide a default, not a menu.** When more than one tool or approach would work (PSL vs. the TS builder, `db update` vs. `migration plan`, which query lane for a given target), commit to the one that's the recommended path for the common case and state it first. Mention the alternative briefly, as an escape hatch with the condition under which it applies — don't present both as equally-weighted options and leave the choice to the agent. An agent handed a menu without a default either guesses or asks; a stated default lets it proceed. - **Omit what the agent already knows.** Every sentence should teach something the agent wouldn't get right without it: a Prisma Next-specific convention, a non-obvious constraint, the actual verified tool surface. Don't explain what a foreign-key constraint is, what a connection pool does, or other general engineering or database knowledge the agent already has — that's editorial padding that pushes genuinely load-bearing content further from the top of the file and erodes the length budgets above. When rewriting or extending a reference file, apply the test explicitly: *would the agent get this wrong without this sentence?* If no, cut it. @@ -142,7 +147,7 @@ These are well-trodden but worth listing in one place: 1. Read [`README.md`](./README.md) for the user-facing scope of the skills. 2. Read the [`skill-specialist` persona](https://github.com/prisma/ignite/blob/main/skills/.curated/drive-agent-personas/personas/skill-specialist.md) in the Ignite persona library — it's the canonical lens for skill work. -3. Read [`skills/prisma-8/references/migration-review.md`](./prisma-next/references/migration-review.md) for the worked example of concepts-over-procedures. +3. Read [`skills/prisma-orm-migrations/references/migration-review.md`](./prisma-orm-migrations/references/migration-review.md) for the worked example of concepts-over-procedures. 4. Draft the reference file, **verifying each tool-surface claim against the framework source as you write it** (see *Verify the tool surface as you author* above for the ripgrep commands). The shape: - A routing-table row in `SKILL.md` as the matcher (CLI flags, error codes, feature names — all verified). - Preamble + canonical mental-model headline. diff --git a/skills/README.md b/skills/README.md index 80bd65b8c642..47ec07dd491b 100644 --- a/skills/README.md +++ b/skills/README.md @@ -4,23 +4,26 @@ Agent skills for [Prisma Next](https://github.com/prisma/prisma) (Prisma 8) — > **Edit your data contract. Prisma handles the rest.** > -> **You get the skill by installing the packages.** `prisma-8` ships inside the `@prisma/orm-postgres`, `@prisma/orm-sqlite` and `@prisma/orm-mongo` tarballs, so the skill in your project always describes the version you installed. +> **You get the skills by installing the packages.** The `prisma-orm-*` skills ship inside the `@prisma/orm-postgres`, `@prisma/orm-sqlite` and `@prisma/orm-mongo` tarballs, so the skills in your project always describe the version you installed. ## What's in the box -One installable skill: +Two installable skills, split by trigger territory: | Skill | Scope | |---|---| -| [`prisma-8`](./prisma-8/) | `SKILL.md` is a router: a description trigger that fires on any Prisma Next work, a routing table, and progressive disclosure into [`prisma-8/references/`](./prisma-8/references/) — adoption/quickstart, contract authoring, migration authoring, migration review on deploy, queries (with Postgres/SQLite and Mongo companions), runtime wiring, build integration, Supabase/RLS, structured-error debugging, feedback routing, and upgrading (both an application and an extension package). | +| [`prisma-orm-core-concepts`](./prisma-orm-core-concepts/) | Everything except migrations. The mental model (contract vs schema, emitting, hashes and the marker, plans, the query APIs, façade layering, capabilities, codecs, extensions, middleware, the migration graph, offline-vs-online CLI commands), structured-error diagnosis, and the development workflows: adoption/quickstart, contract authoring, queries (with Postgres/SQLite and Mongo companions), runtime wiring, build integration, Supabase/RLS, feedback routing, and upgrading (both an application and an extension package, with the per-transition instructions under [`prisma-orm-core-concepts/upgrading/`](./prisma-orm-core-concepts/upgrading/)). Fires whenever the agent works with Prisma ORM. | +| [`prisma-orm-migrations`](./prisma-orm-migrations/) | Migration authoring, the migration graph / refs / plan-origin model, and deploy-time migration review. Fires on migration planning, applying, and review. | + +Each `SKILL.md` is a router: a description trigger that carves that skill's territory, a routing table, and progressive disclosure into the skill's `references/` files. The skills cross-reference each other by name (they install as a set), and each carries the shared version-freshness preamble. The task-oriented reference files follow a shared shape: preamble + canonical mental-model headline, *When to Use* / *When Not to Use*, *Key Concepts*, *Workflow*, *Common Pitfalls*, **What Prisma Next doesn't do yet**, and *Checklist*. The two upgrade references are procedures rather than reference material, so they carry their own step-by-step shape instead. -Upgrading is a branch of the same skill rather than a separate one. [`references/upgrade-app.md`](./prisma-8/references/upgrade-app.md) and [`references/upgrade-extension.md`](./prisma-8/references/upgrade-extension.md) carry the two flows; the per-transition instructions and codemods they replay live under [`prisma-8/upgrading/app/upgrades/-to-/`](./prisma-8/upgrading/app/upgrades/) and [`prisma-8/upgrading/extension/upgrades/-to-/`](./prisma-8/upgrading/extension/upgrades/). The version you upgrade *to* carries the instructions for the transitions leading to it. +Upgrading is a branch of the core-concepts skill. [`prisma-orm-core-concepts/references/upgrade-app.md`](./prisma-orm-core-concepts/references/upgrade-app.md) and [`prisma-orm-core-concepts/references/upgrade-extension.md`](./prisma-orm-core-concepts/references/upgrade-extension.md) carry the two flows; the per-transition instructions and codemods they replay live under [`prisma-orm-core-concepts/upgrading/app/upgrades/-to-/`](./prisma-orm-core-concepts/upgrading/app/upgrades/) and [`prisma-orm-core-concepts/upgrading/extension/upgrades/-to-/`](./prisma-orm-core-concepts/upgrading/extension/upgrades/). The version you upgrade *to* carries the instructions for the transitions leading to it. ## Install -The skill arrives with the packages, and `prisma skills sync` copies it from the installed package into the agent directories at your project root (`.claude/skills/`, `.cursor/skills/`, `.agents/skills/`, `.windsurf/skills/`). The family-level `prisma init` command sets the skills up for you; `prisma orm init` does not touch them. After adding an agent runtime, or to refresh the copies, run the sync directly: +The skills arrive with the packages, and `prisma skills sync` copies them from the installed package into the agent directories at your project root (`.claude/skills/`, `.cursor/skills/`, `.agents/skills/`, `.windsurf/skills/`). The family-level `prisma init` command sets the skills up for you; `prisma orm init` does not touch them. After adding an agent runtime, or to refresh the copies, run the sync directly: ```bash pnpm exec prisma skills sync @@ -30,27 +33,27 @@ Every `prisma` command also checks the synced copies against the installed packa ### Manual fallback — install from GitHub -If you want the skill without installing the packages, the `skills` CLI can still read this directory. Pin the ref to your Prisma Next version so the skill surface matches your runtime surface: +If you want the skills without installing the packages, the `skills` CLI can still read this directory. Pin the ref to your Prisma Next version so the skill surface matches your runtime surface. Install both — they route to each other and are meant to travel together: ```bash -pnpm dlx skills add prisma/prisma/skills#v --skill prisma-8 -y +pnpm dlx skills add prisma/prisma/skills#v --all ``` This is interoperability, not the recommended path: nothing keeps a copy installed this way up to date. -The skills are always installed at the **project level** — there is no host-wide / global install path. The skill's surface (commands it references, exit codes it expects, capability claims it makes) tracks the project's `@internal/*` version, and a global install would have to pick a single version for every project on the host. Per-project keeps the skill, CLI, runtime, and extension packs coherent on every project the user works in. +The skills are always installed at the **project level** — there is no host-wide / global install path. Each skill's surface (commands it references, exit codes it expects, capability claims it makes) tracks the project's `@internal/*` version, and a global install would have to pick a single version for every project on the host. Per-project keeps the skills, CLI, runtime, and extension packs coherent on every project the user works in. To limit a `skills add` install to one agent runtime, add `-a ` (e.g. `-a claude-code`, `-a cursor`, `-a codex`). The `skills` CLI's `--help` lists the supported agent ids. ## Capability-gap honesty -Prisma Next is in early access (`0.x`). Each reference file carries a *What Prisma Next doesn't do yet* section that names features the framework doesn't implement (model validations, lifecycle callbacks, Studio, runtime-apply migrations, `EXPLAIN`, prepared statements, `db.batch()`, multi-database routing, Next.js plugin, …) along with the workaround and a route to [`prisma-8/references/feedback.md`](./prisma-8/references/feedback.md) so the request becomes a tracked issue instead of a one-line URL. +Prisma Next is in early access. Each reference file carries a *What Prisma Next doesn't do yet* section that names features the framework doesn't implement (model validations, lifecycle callbacks, Studio, runtime-apply migrations, `EXPLAIN`, prepared statements, `db.batch()`, multi-database routing, Next.js plugin, …) along with the workaround and a route to [`prisma-orm-core-concepts/references/feedback.md`](./prisma-orm-core-concepts/references/feedback.md) so the request becomes a tracked issue instead of a one-line URL. The pattern is deliberate: it gives the agent something concrete to say when a user asks about an unbuilt feature, instead of confabulating a plausible-looking API call against something that doesn't exist. ## Versioning -The skill is versioned with the rest of Prisma Next and ships inside the tarballs, so there is no separate skill-version axis to track ([`docs/oss/versioning.md`](../docs/oss/versioning.md)). Each published copy carries `metadata.library` (the package it shipped in) and `metadata.library_version` (the version it shipped at) in its frontmatter — `metadata` is where the [Agent Skills spec](https://agentskills.io) puts keys beyond `name` and `description`; `prisma skills sync` compares that stamp against the installed package to decide whether your copy is current. +The skills are versioned with the rest of Prisma Next and ship inside the tarballs, so there is no separate skill-version axis to track ([`docs/oss/versioning.md`](../docs/oss/versioning.md)). Each published copy carries `metadata.library` (the package it shipped in) and `metadata.library_version` (the version it shipped at) in its frontmatter — `metadata` is where the [Agent Skills spec](https://agentskills.io) puts keys beyond `name` and `description`; `prisma skills sync` compares that stamp against the installed package to decide whether your copies are current. ## Contributing / authoring diff --git a/skills/journey-tests/01-onboarding-first-query.md b/skills/journey-tests/01-onboarding-first-query.md index 55d2154d5324..3df3916c6f06 100644 --- a/skills/journey-tests/01-onboarding-first-query.md +++ b/skills/journey-tests/01-onboarding-first-query.md @@ -1,6 +1,6 @@ # Journey 01 — Onboarding to first query -**Skills under test:** `prisma-next-quickstart`, `prisma-next-contract`, `prisma-next-migrations`, `prisma-next-queries`. +**Skills under test:** `prisma-orm-core-concepts` (quickstart, contract, queries), `prisma-orm-migrations` (migrations). **Example app:** A fresh directory scaffolded with `pnpm dlx @prisma/cli orm init` (run inside the new directory — `init` operates in `cwd` and does not take a project-name argument), or `examples/prisma-8-demo` with the User model deleted. @@ -17,7 +17,7 @@ - [ ] Adds a `User` model with `id` (auto-increment PK) and `email` (string, unique). - [ ] Runs `pnpm prisma contract emit` (or the project-pm equivalent). - [ ] Plans + applies a migration (or uses `db update` for dev). -- [ ] Writes a query handler that calls `db.orm.User.select(...).all()` (the ORM lane is the default; the SQL builder and raw lanes are alternatives the `prisma-next-queries` skill covers). +- [ ] Writes a query handler that calls `db.orm.User.select(...).all()` (the ORM lane is the default; the SQL builder and raw lanes are alternatives the `prisma-orm-core-concepts` (queries) skill covers). - [ ] Runs the handler and observes the empty array (or rows if seeded). ## Success criteria diff --git a/skills/journey-tests/02a-add-relation.md b/skills/journey-tests/02a-add-relation.md index e9f4bf74e73b..d3fd838f76f1 100644 --- a/skills/journey-tests/02a-add-relation.md +++ b/skills/journey-tests/02a-add-relation.md @@ -1,6 +1,6 @@ # Journey 02a — Add a relation, apply, query -**Skills under test:** `prisma-next-contract`, `prisma-next-migrations`, `prisma-next-queries`. +**Skills under test:** `prisma-orm-core-concepts` (contract), `prisma-orm-migrations` (migrations), `prisma-orm-core-concepts` (queries). **Example app:** A project that already has a `User` model. diff --git a/skills/journey-tests/02b-rename-with-hint.md b/skills/journey-tests/02b-rename-with-hint.md index 23d7cd49a0fc..3f50429403c8 100644 --- a/skills/journey-tests/02b-rename-with-hint.md +++ b/skills/journey-tests/02b-rename-with-hint.md @@ -1,6 +1,6 @@ # Journey 02b — Rename a column (capability gap: no in-contract hint) -**Skills under test:** `prisma-next-contract`, `prisma-next-migrations`, `prisma-next-feedback`. +**Skills under test:** `prisma-orm-core-concepts` (contract, feedback), `prisma-orm-migrations` (migrations). ## Prompt @@ -14,7 +14,7 @@ - [ ] Runs `migration plan --name rename-user-email`. - [ ] Runs `migration show ` and confirms the plan is a `DROP COLUMN` + `ADD COLUMN` — the destructive shape the user was warned about. - [ ] Walks the user through hand-editing `migration.ts` to rewrite the destructive op as a `RENAME COLUMN`, then `node migrations/app//migration.ts` to self-emit and `db migrate`. -- [ ] Offers to route a feature request for a first-class rename hint via `prisma-next-feedback`. +- [ ] Offers to route a feature request for a first-class rename hint via `prisma-orm-core-concepts` (feedback). ## Success criteria diff --git a/skills/journey-tests/02c-data-transform-placeholder.md b/skills/journey-tests/02c-data-transform-placeholder.md index b15ab3eca06f..1510d89d38df 100644 --- a/skills/journey-tests/02c-data-transform-placeholder.md +++ b/skills/journey-tests/02c-data-transform-placeholder.md @@ -1,6 +1,6 @@ # Journey 02c — Fill a placeholder data transform -**Skills under test:** `prisma-next-migrations`. +**Skills under test:** `prisma-orm-migrations` (migrations). **Acceptance criterion:** AC5c. diff --git a/skills/journey-tests/02d-capability-gate.md b/skills/journey-tests/02d-capability-gate.md index e8c05f85dce6..15cd24285837 100644 --- a/skills/journey-tests/02d-capability-gate.md +++ b/skills/journey-tests/02d-capability-gate.md @@ -1,6 +1,6 @@ # Journey 02d — Capability-gated `returning()` -**Skills under test:** `prisma-next-queries`, `prisma-next-contract`. +**Skills under test:** `prisma-orm-core-concepts` (queries, contract). **Acceptance criterion:** AC5d. diff --git a/skills/journey-tests/02e-hash-mismatch.md b/skills/journey-tests/02e-hash-mismatch.md index 21f9c67180e6..cae48b9fb77c 100644 --- a/skills/journey-tests/02e-hash-mismatch.md +++ b/skills/journey-tests/02e-hash-mismatch.md @@ -1,6 +1,6 @@ # Journey 02e — Recover from `MIGRATION.HASH_MISMATCH` -**Skills under test:** `prisma-next-debug`, `prisma-next-migrations`. +**Skills under test:** `prisma-orm-core-concepts` (failure-modes), `prisma-orm-migrations` (migrations). **Acceptance criterion:** AC5e. diff --git a/skills/journey-tests/02f-merge-preview.md b/skills/journey-tests/02f-merge-preview.md index 8af10a128ef2..590b26236dbb 100644 --- a/skills/journey-tests/02f-merge-preview.md +++ b/skills/journey-tests/02f-merge-preview.md @@ -1,6 +1,6 @@ # Journey 02f — "What's about to run on merge?" -**Skills under test:** `prisma-8-migration-review`. +**Skills under test:** `prisma-orm-migrations` (migration-review). **Acceptance criterion:** AC5f. diff --git a/skills/journey-tests/02g-diamond-convergence.md b/skills/journey-tests/02g-diamond-convergence.md index a9b918f201bd..49c7e7a1a3f1 100644 --- a/skills/journey-tests/02g-diamond-convergence.md +++ b/skills/journey-tests/02g-diamond-convergence.md @@ -1,6 +1,6 @@ # Journey 02g — Resolve a diamond-convergence conflict -**Skills under test:** `prisma-8-migration-review`, `prisma-next-migrations`. +**Skills under test:** `prisma-orm-migrations` (migration-review), `prisma-orm-migrations` (migrations). **Acceptance criterion:** AC5g. diff --git a/skills/journey-tests/02h-query-interface.md b/skills/journey-tests/02h-query-interface.md index e58f5356742b..4233f3a55fec 100644 --- a/skills/journey-tests/02h-query-interface.md +++ b/skills/journey-tests/02h-query-interface.md @@ -1,6 +1,6 @@ # Journey 02h — Pick the right query interface -**Skills under test:** `prisma-next-queries`. +**Skills under test:** `prisma-orm-core-concepts` (queries). **Acceptance criterion:** AC5h. diff --git a/skills/journey-tests/02i-greenfield-trap.md b/skills/journey-tests/02i-greenfield-trap.md index 2a5a6f6c7f44..3a9096b52dba 100644 --- a/skills/journey-tests/02i-greenfield-trap.md +++ b/skills/journey-tests/02i-greenfield-trap.md @@ -1,6 +1,6 @@ # Journey 02i — Second plan in a project with no `db` ref -**Skills under test:** `prisma-8` (migration-model, migrations). +**Skills under test:** `prisma-orm-migrations` (migration-model, migrations). **Acceptance criterion:** — (added with the migration mental-model rework). diff --git a/skills/journey-tests/03-capability-gaps.md b/skills/journey-tests/03-capability-gaps.md index 2507612e2f0b..aead3da5877b 100644 --- a/skills/journey-tests/03-capability-gaps.md +++ b/skills/journey-tests/03-capability-gaps.md @@ -1,10 +1,10 @@ # Journey 03 — Capability-gap honesty -**Skills under test:** `prisma-next-contract`, `prisma-next-migrations`, `prisma-next-queries`, `prisma-next-build`, `prisma-next-debug`, `prisma-next-feedback`. +**Skills under test:** `prisma-orm-core-concepts` (contract, queries, build, failure-modes, feedback), `prisma-orm-migrations` (migrations). -**Acceptance criterion:** The agent names the gap, names the workaround, and routes to `prisma-next-feedback`; it does not fabricate an API call. +**Acceptance criterion:** The agent names the gap, names the workaround, and routes to `prisma-orm-core-concepts` (feedback); it does not fabricate an API call. -The point: when the user asks about a feature Prisma Next doesn't have yet, the agent must NOT confabulate an API. It must name the gap, suggest the workaround, and route to `prisma-next-feedback` so the request becomes a tracked issue. +The point: when the user asks about a feature Prisma Next doesn't have yet, the agent must NOT confabulate an API. It must name the gap, suggest the workaround, and route to `prisma-orm-core-concepts` (feedback) so the request becomes a tracked issue. ## Prompts and expected responses @@ -14,15 +14,15 @@ The point: when the user asks about a feature Prisma Next doesn't have yet, the - [ ] Agent names the gap: validations not first-class in PN. - [ ] Agent suggests app-side validation with arktype or zod. -- [ ] Agent routes to `prisma-next-feedback` for the feature request. +- [ ] Agent routes to `prisma-orm-core-concepts` (feedback) for the feature request. ### 03b — Lifecycle callbacks > Run a `beforeSave` hook on User to lowercase the email. - [ ] Agent names the gap: lifecycle callbacks not first-class. -- [ ] Agent suggests middleware (per `prisma-next-runtime`) or app code. -- [ ] Agent routes to `prisma-next-feedback` for the feature request. +- [ ] Agent suggests middleware (per `prisma-orm-core-concepts` (runtime)) or app code. +- [ ] Agent routes to `prisma-orm-core-concepts` (feedback) for the feature request. ### 03c — Studio @@ -30,7 +30,7 @@ The point: when the user asks about a feature Prisma Next doesn't have yet, the - [ ] Agent names the gap: Studio not shipped. - [ ] Agent suggests `prisma db schema` for CLI tree output. -- [ ] Agent routes to `prisma-next-feedback` for the feature request. +- [ ] Agent routes to `prisma-orm-core-concepts` (feedback) for the feature request. ### 03d — EXPLAIN @@ -38,7 +38,7 @@ The point: when the user asks about a feature Prisma Next doesn't have yet, the - [ ] Agent names the gap: no `.explain()` first-class method. - [ ] Agent suggests ``db.raw.sql`EXPLAIN ANALYZE ${...}` ``. -- [ ] Agent routes to `prisma-next-feedback` for the feature request. +- [ ] Agent routes to `prisma-orm-core-concepts` (feedback) for the feature request. ### 03e — Runtime-apply migrations @@ -46,18 +46,18 @@ The point: when the user asks about a feature Prisma Next doesn't have yet, the - [ ] Agent names the gap: no runtime-apply migrations API. - [ ] Agent suggests `prisma db migrate` from the deploy pipeline. -- [ ] Agent routes to `prisma-next-feedback` for the feature request. +- [ ] Agent routes to `prisma-orm-core-concepts` (feedback) for the feature request. ### 03f — Next.js plugin > Set up Prisma Next contract auto-emit in my Next.js project. -- [ ] Agent loads `prisma-next-build`. +- [ ] Agent loads `prisma-orm-core-concepts` (build). - [ ] Agent names the gap: no first-party Next.js plugin yet. - [ ] Agent suggests the `prebuild` script workaround. -- [ ] Agent routes to `prisma-next-feedback` if the user wants the gap closed. +- [ ] Agent routes to `prisma-orm-core-concepts` (feedback) if the user wants the gap closed. ## Success criteria -- [ ] For each prompt, the agent named the gap, named the workaround, and routed the user to `prisma-next-feedback` (not just a bare URL). +- [ ] For each prompt, the agent named the gap, named the workaround, and routed the user to `prisma-orm-core-concepts` (feedback) (not just a bare URL). - [ ] The agent did NOT fabricate an API call against a non-existent surface (`User.validates(...)`, `db.studio()`, `query.explain()`, `db.applyMigrations()`, `@internal/next-plugin-contract-emit`). diff --git a/skills/journey-tests/05-build-vite.md b/skills/journey-tests/05-build-vite.md index 518b242991de..63c497de5572 100644 --- a/skills/journey-tests/05-build-vite.md +++ b/skills/journey-tests/05-build-vite.md @@ -1,6 +1,6 @@ # Journey 05 — Vite plugin happy path -**Skill under test:** `prisma-next-build`. +**Skill under test:** `prisma-orm-core-concepts` (build). **Acceptance criterion:** The build workflow routes to the Vite plugin path and avoids unsupported package names. @@ -22,7 +22,7 @@ The agent runtime has Prisma Next skills registered (project level, as `init` in ## Expected agent behaviour -- [ ] Skill matcher fires on `prisma-next-build` (description contains "vite plugin", "vite.config.ts", "contract emit on save"). +- [ ] Skill matcher fires on `prisma-orm-core-concepts` (build) (description contains "vite plugin", "vite.config.ts", "contract emit on save"). - [ ] Agent installs `@internal/vite-plugin-contract-emit` as a devDependency via the project's package manager. - [ ] Agent edits `vite.config.ts` to register `prismaVitePlugin('prisma.config.ts')` (note: the argument is the *config path*, not the schema path). - [ ] Agent starts `vite dev` (or instructs the user to) and waits for the initial emit log line. diff --git a/skills/journey-tests/05b-build-nextjs-gap.md b/skills/journey-tests/05b-build-nextjs-gap.md index 0ea338c18a6a..c0dfbb681904 100644 --- a/skills/journey-tests/05b-build-nextjs-gap.md +++ b/skills/journey-tests/05b-build-nextjs-gap.md @@ -1,6 +1,6 @@ # Journey 05b — Next.js gap (no first-party plugin yet) -**Skills under test:** `prisma-next-build`, `prisma-next-feedback`. +**Skills under test:** `prisma-orm-core-concepts` (build, feedback). **Acceptance criterion:** AC8b (Next.js prompt) from `specs/usage-skill.spec.md`. @@ -16,16 +16,16 @@ A fresh Next.js project (`pnpm create next-app`) into which `prisma orm init` ha ## Expected agent behaviour -- [ ] Skill matcher fires on `prisma-next-build` (description contains "next plugin", "next.js plugin", "withPrismaNext"). +- [ ] Skill matcher fires on `prisma-orm-core-concepts` (build) (description contains "next plugin", "next.js plugin", "withPrismaNext"). - [ ] Agent surfaces the *What PN doesn't do yet* entry: no first-party Next.js plugin exists. - [ ] Agent does NOT fabricate `@internal/next` or `withPrismaNext` — those packages / exports do not exist. - [ ] Agent recommends the workaround: 1. Add a `prebuild` script to `package.json` running `prisma contract emit`. 2. Run `prisma contract emit` manually during development when the contract source changes, or wire a `tsx --watch` script. -- [ ] Agent asks the user if they want to file a feature request and, if yes, routes to the `prisma-next-feedback` skill (does NOT open an issue without explicit user confirmation). +- [ ] Agent asks the user if they want to file a feature request and, if yes, routes to the `prisma-orm-core-concepts` (feedback) skill (does NOT open an issue without explicit user confirmation). ## Success criteria - [ ] No fabricated `@internal/next` / `withPrismaNext` / `@internal/next-plugin-contract-emit` imports in any file the agent touches. - [ ] `package.json` contains a `prebuild` script that runs `prisma contract emit`. -- [ ] The user is offered the `prisma-next-feedback` route for filing a request. +- [ ] The user is offered the `prisma-orm-core-concepts` (feedback) route for filing a request. diff --git a/skills/journey-tests/06-feedback-bug.md b/skills/journey-tests/06-feedback-bug.md index 1a0a9a61e96e..9a977cfda97d 100644 --- a/skills/journey-tests/06-feedback-bug.md +++ b/skills/journey-tests/06-feedback-bug.md @@ -1,6 +1,6 @@ # Journey 06 — Feedback skill: bug report -**Skill under test:** `prisma-next-feedback`. +**Skill under test:** `prisma-orm-core-concepts` (feedback). **Acceptance criterion:** AC8c (bug report path) from `specs/usage-skill.spec.md`. @@ -14,7 +14,7 @@ A `prisma orm init`-scaffolded project (any target). ## Expected agent behaviour -- [ ] Skill matcher fires on `prisma-next-feedback`. +- [ ] Skill matcher fires on `prisma-orm-core-concepts` (feedback). - [ ] Agent classifies as a **bug report** (the CLI exit code is arguably wrong vs. documented behaviour). Not a feature request. - [ ] Agent produces a minimal reproduction: - A small `schema.psl` excerpt (renamed to neutral domain names like `User`, `Post`). diff --git a/skills/journey-tests/06b-feedback-feature.md b/skills/journey-tests/06b-feedback-feature.md index a7b2fcd8477c..f1cd1146b26a 100644 --- a/skills/journey-tests/06b-feedback-feature.md +++ b/skills/journey-tests/06b-feedback-feature.md @@ -1,6 +1,6 @@ # Journey 06b — Feedback skill: feature request via capability-gap route -**Skills under test:** `prisma-next-contract`, `prisma-next-feedback`. +**Skills under test:** `prisma-orm-core-concepts` (contract, feedback). **Acceptance criterion:** AC8c (feature request path) from `specs/usage-skill.spec.md`. @@ -14,7 +14,7 @@ First prompt (originates the route): > add a validation: email must contain '@' -Expected: `prisma-next-contract` fires, names the validations capability gap, names the arktype / zod workaround, and routes the user to `prisma-next-feedback` for the feature request. +Expected: `prisma-orm-core-concepts` (contract) fires, names the validations capability gap, names the arktype / zod workaround, and routes the user to `prisma-orm-core-concepts` (feedback) for the feature request. Second prompt (after the user says yes to the route): @@ -22,12 +22,12 @@ Second prompt (after the user says yes to the route): ## Expected agent behaviour -- [ ] On the first prompt, `prisma-next-contract` activates and does not confabulate a `@validates` PSL attribute. -- [ ] On the routing offer, the agent surfaces the *What PN doesn't do yet* entry plus the offer to file via `prisma-next-feedback`. -- [ ] On the second prompt, `prisma-next-feedback` fires. +- [ ] On the first prompt, `prisma-orm-core-concepts` (contract) activates and does not confabulate a `@validates` PSL attribute. +- [ ] On the routing offer, the agent surfaces the *What PN doesn't do yet* entry plus the offer to file via `prisma-orm-core-concepts` (feedback). +- [ ] On the second prompt, `prisma-orm-core-concepts` (feedback) fires. - [ ] Agent classifies as **feature request** (not a bug). - [ ] Agent produces the body using the feature-request fields from `.github/ISSUE_TEMPLATE/feature_request.yml`: *What problem are you trying to solve?* / *Proposed solution* / *Alternatives considered* / *Scope and impact*. -- [ ] *Alternatives considered* references back to `prisma-next-contract`'s *What PN doesn't do yet* entry on validations (arktype / zod workaround). +- [ ] *Alternatives considered* references back to `prisma-orm-core-concepts` (contract)'s *What PN doesn't do yet* entry on validations (arktype / zod workaround). - [ ] Title in `feat(area): summary` form, e.g. `feat(contract): first-class field-level validations in PSL`. - [ ] User is prompted for confirmation before submission. - [ ] On user confirmation, submitted via `gh issue create` or via the prefilled new-issue URL. @@ -36,5 +36,5 @@ Second prompt (after the user says yes to the route): - [ ] No fabricated `@validates` API in any prose or code the agent produces. - [ ] Body's *Alternatives considered* references arktype / zod (matching the source skill's gap entry). -- [ ] Body's *What problem are you trying to solve?* references the source skill (`prisma-next-contract`). +- [ ] Body's *What problem are you trying to solve?* references the source skill (`prisma-orm-core-concepts` (contract)). - [ ] User confirmation step happened before submission. diff --git a/skills/journey-tests/07-first-touch-orientation.md b/skills/journey-tests/07-first-touch-orientation.md index f0284e583ae3..9b5e9a238f33 100644 --- a/skills/journey-tests/07-first-touch-orientation.md +++ b/skills/journey-tests/07-first-touch-orientation.md @@ -1,6 +1,6 @@ # Journey 07 — First-touch orientation -**Skills under test:** `prisma-next-quickstart` (First-touch orientation path), with hand-offs to `prisma-next-queries` and optionally `prisma-next-contract`. +**Skills under test:** `prisma-orm-core-concepts` (quickstart) (First-touch orientation path), with hand-offs to `prisma-orm-core-concepts` (queries) and optionally `prisma-orm-core-concepts` (contract). **Example app:** A Prisma Next project the user is encountering for the first time. Three flavours of this initial state should all pass: @@ -32,10 +32,10 @@ The journey should pass on each of: - [ ] Runs the snippet and confirms it round-trips data. - [ ] Surfaces CLI commands (`db init`, optionally `db update`, `contract emit`) **only when the user's current move requires them** — not as a pre-emptive tour. The *Commands you'll use day-to-day* table is offered as a reference once the first round-trip works, not recited beforehand. - [ ] Asks the user what they want to build next and routes: - - More queries → `prisma-next-queries`. - - Schema changes → `prisma-next-contract`. - - Runtime config / middleware → `prisma-next-runtime`. - - Dev-server integration → `prisma-next-build`. + - More queries → `prisma-orm-core-concepts` (queries). + - Schema changes → `prisma-orm-core-concepts` (contract). + - Runtime config / middleware → `prisma-orm-core-concepts` (runtime). + - Dev-server integration → `prisma-orm-core-concepts` (build). ## Success criteria diff --git a/skills/journey-tests/08-supabase-rls.md b/skills/journey-tests/08-supabase-rls.md index a69d64874109..930ae80453be 100644 --- a/skills/journey-tests/08-supabase-rls.md +++ b/skills/journey-tests/08-supabase-rls.md @@ -1,8 +1,8 @@ # Journey 08 — Supabase: RLS-scoped profile listing -**Skills under test:** `prisma-next-supabase`, `prisma-next-contract`, `prisma-next-queries`. +**Skills under test:** `prisma-orm-core-concepts` (supabase), `prisma-orm-core-concepts` (contract), `prisma-orm-core-concepts` (queries). -**Example app:** `examples/supabase` (the canonical Supabase walking skeleton), or a fresh project wired per the `prisma-next-supabase` config workflow against a disposable Supabase project. +**Example app:** `examples/supabase` (the canonical Supabase walking skeleton), or a fresh project wired per the `prisma-orm-core-concepts` (supabase) config workflow against a disposable Supabase project. ## Prompt diff --git a/skills/journey-tests/README.md b/skills/journey-tests/README.md index a91bac93a491..6454d6f6bfc6 100644 --- a/skills/journey-tests/README.md +++ b/skills/journey-tests/README.md @@ -32,21 +32,23 @@ Cross-runtime automation against a moving model surface is its own research proj ## Journey index -| File | Skill(s) under test | Acceptance criterion | +The *Skill (references) under test* column names the installed skill and, in parentheses, the reference files inside it the journey exercises. + +| File | Skill (references) under test | Acceptance criterion | |---|---|---| -| [`01-onboarding-first-query.md`](01-onboarding-first-query.md) | quickstart, contract, migrations, queries | AC4 | -| [`02a-add-relation.md`](02a-add-relation.md) | contract, migrations, queries | AC5a | -| [`02b-rename-with-hint.md`](02b-rename-with-hint.md) | contract, migrations | AC5b | -| [`02c-data-transform-placeholder.md`](02c-data-transform-placeholder.md) | migrations | AC5c | -| [`02d-capability-gate.md`](02d-capability-gate.md) | queries, contract | AC5d | -| [`02e-hash-mismatch.md`](02e-hash-mismatch.md) | debug, migrations | AC5e | -| [`02f-merge-preview.md`](02f-merge-preview.md) | migration-review | AC5f | -| [`02g-diamond-convergence.md`](02g-diamond-convergence.md) | migration-review, migrations | AC5g | -| [`02h-query-interface.md`](02h-query-interface.md) | queries | AC5h | -| [`02i-greenfield-trap.md`](02i-greenfield-trap.md) | migration-model, migrations | — | -| [`03-capability-gaps.md`](03-capability-gaps.md) | contract, migrations, queries, build, debug, feedback | AC6 | -| [`05-build-vite.md`](05-build-vite.md) | build | AC8b | -| [`05b-build-nextjs-gap.md`](05b-build-nextjs-gap.md) | build, feedback | AC8b (Next.js path) | -| [`06-feedback-bug.md`](06-feedback-bug.md) | feedback | AC8c (bug path) | -| [`06b-feedback-feature.md`](06b-feedback-feature.md) | contract, feedback | AC8c (feature path) | -| [`07-first-touch-orientation.md`](07-first-touch-orientation.md) | quickstart (first-touch path), queries, contract | AC4 (orientation entry point) | +| [`01-onboarding-first-query.md`](01-onboarding-first-query.md) | prisma-orm-core-concepts (quickstart, contract, queries), prisma-orm-migrations (migrations) | AC4 | +| [`02a-add-relation.md`](02a-add-relation.md) | prisma-orm-core-concepts (contract, queries), prisma-orm-migrations (migrations) | AC5a | +| [`02b-rename-with-hint.md`](02b-rename-with-hint.md) | prisma-orm-core-concepts (contract), prisma-orm-migrations (migrations) | AC5b | +| [`02c-data-transform-placeholder.md`](02c-data-transform-placeholder.md) | prisma-orm-migrations (migrations) | AC5c | +| [`02d-capability-gate.md`](02d-capability-gate.md) | prisma-orm-core-concepts (queries, contract) | AC5d | +| [`02e-hash-mismatch.md`](02e-hash-mismatch.md) | prisma-orm-core-concepts (failure-modes), prisma-orm-migrations (migrations) | AC5e | +| [`02f-merge-preview.md`](02f-merge-preview.md) | prisma-orm-migrations (migration-review) | AC5f | +| [`02g-diamond-convergence.md`](02g-diamond-convergence.md) | prisma-orm-migrations (migration-review, migrations) | AC5g | +| [`02h-query-interface.md`](02h-query-interface.md) | prisma-orm-core-concepts (queries) | AC5h | +| [`02i-greenfield-trap.md`](02i-greenfield-trap.md) | prisma-orm-migrations (migration-model, migrations) | — | +| [`03-capability-gaps.md`](03-capability-gaps.md) | prisma-orm-core-concepts (contract, queries, build, failure-modes, feedback), prisma-orm-migrations (migrations) | AC6 | +| [`05-build-vite.md`](05-build-vite.md) | prisma-orm-core-concepts (build) | AC8b | +| [`05b-build-nextjs-gap.md`](05b-build-nextjs-gap.md) | prisma-orm-core-concepts (build, feedback) | AC8b (Next.js path) | +| [`06-feedback-bug.md`](06-feedback-bug.md) | prisma-orm-core-concepts (feedback) | AC8c (bug path) | +| [`06b-feedback-feature.md`](06b-feedback-feature.md) | prisma-orm-core-concepts (contract, feedback) | AC8c (feature path) | +| [`07-first-touch-orientation.md`](07-first-touch-orientation.md) | prisma-orm-core-concepts (quickstart first-touch path, queries, contract) | AC4 (orientation entry point) | diff --git a/skills/prisma-8/SKILL.md b/skills/prisma-orm-core-concepts/SKILL.md similarity index 62% rename from skills/prisma-8/SKILL.md rename to skills/prisma-orm-core-concepts/SKILL.md index d24bc563a7d4..320dd8fe0b82 100644 --- a/skills/prisma-8/SKILL.md +++ b/skills/prisma-orm-core-concepts/SKILL.md @@ -1,20 +1,10 @@ --- -name: prisma-8 +name: prisma-orm-core-concepts description: >- - Comprehensive guide for building with Prisma 8 (Prisma Next), the - contract-first data layer. Use whenever working on Prisma code in a project - that uses it — authoring or editing the data contract (contract.prisma, PSL, - TypeScript builders), migrations, queries (db.orm / db.sql), runtime wiring - (db.ts, middleware, DATABASE_URL), build-tool integration, Supabase / RLS, - reading PN-* structured errors, or filing feedback — and for orientation - questions like "what is Prisma Next" or comparisons to other ORMs. Signals - that this skill applies: @internal/* imports, prisma.config.ts, - contract.prisma / contract.json / contract.d.ts, the prisma-next CLI, - PN-* error codes. Also covers upgrading Prisma in a project — "upgrade - Prisma 8", "bump Prisma Next", "move to Prisma Next X.Y", or dealing - with an @internal/* version bump, in a consumer app or in an extension - package. Does not apply to Prisma ORM 7 or earlier - (schema.prisma + @prisma/client projects). + Use whenever working with Prisma 8 (Prisma Next) — writing queries, editing + the schema / data contract, running prisma CLI commands, wiring the runtime, + debugging errors, or otherwise developing against the database. Does not + apply to Prisma ORM 7 or earlier (schema.prisma + @prisma/client projects). metadata: library: '@prisma/orm-postgres' library_version: '8.0.0-rc.8' @@ -24,23 +14,21 @@ metadata: > **Edit your data contract. Prisma handles the rest.** -Prisma 8 moves fast, and your training data about it is very likely outdated. This skill ships inside the installed Prisma packages, so it describes the exact version this project has — treat it and its reference files as the source of truth, over anything you remember about Prisma. The `metadata.library_version` in this file's frontmatter is the version it was published with; if it does not match the project's installed Prisma packages, run `prisma skills sync` and re-read. +Prisma 8 moves fast, and your training data about it is very likely outdated. This skill ships inside the installed Prisma packages, so it describes the exact version this project has — treat it and its reference files as the source of truth, over anything you remember about Prisma. If `metadata.library_version` in this file's frontmatter does not match the project's installed Prisma packages, run `prisma skills sync` and re-read. -Prisma Next is a contract-first data layer. This skill routes every Prisma Next task to the right reference file — open the reference before writing code; do not answer from this file alone. +This skill routes every Prisma Next task to the right reference file — open the reference before writing code; do not answer from this file alone. ## The canonical model (one paragraph) -You author a **data contract** (a `contract.prisma` file, or a TypeScript builder). The framework emits machine-readable artifacts (`contract.json`, `contract.d.ts`) and gives you two runtime surfaces on SQL targets: a typed SQL query builder (`db.sql..`) and a typed ORM client (`db.orm..`). On MongoDB targets only the ORM lane exists, and its keys are collection storage names (`db.orm.users`) rather than PSL model names — [`references/queries.md`](references/queries.md) § *MongoDB ORM addressing* covers the rule. Migrations are planned from the contract diff; you review them, optionally edit the `migration.ts` for data transforms, and apply. +You author a **data contract** (a `contract.prisma` file, or a TypeScript builder). The framework emits machine-readable artifacts (`contract.json`, `contract.d.ts`) and gives you two runtime surfaces on SQL targets: a typed SQL query builder (`db.sql..
`) and a typed ORM client (`db.orm..`). On MongoDB targets only the ORM lane exists, and its keys are collection storage names (`db.orm.users`) rather than PSL model names — [`references/queries.md`](references/queries.md) § *MongoDB ORM addressing* covers the rule. Every query compiles to a **plan** before execution, and the database carries a **marker** naming the contract hash it satisfies. Migrations are planned from the contract diff; the `prisma-orm-migrations` skill owns that flow. Three steps the user does: 1. **Edit your data contract.** ([`references/contract.md`](references/contract.md)) -2. **The system plans the migrations for you.** ([`references/migrations.md`](references/migrations.md)) -3. **If you need data migrations, you edit `migration.ts` and execute it.** ([`references/migrations.md`](references/migrations.md)) +2. **The system plans the migrations for you.** (`prisma-orm-migrations` skill) +3. **If you need data migrations, you edit `migration.ts` and execute it.** (`prisma-orm-migrations` skill) -Everything else — queries, runtime wiring, build integration, debugging, feedback — sits on top of those three. - -One cross-cutting migration fact: `migration plan` does **not** chain from the newest migration on disk. Its origin is `--from`, else the `db` ref, else an empty database — so a project with no ref keeps planning from scratch. Over existing migrations the CLI refuses that (`MIGRATION.PLAN_ORIGIN_UNKNOWN`) instead of writing a full-create package; choose the exit that matches your intent rather than reflexively passing `--from @empty`. [`references/migration-model.md`](references/migration-model.md) § *The trap* explains which to choose. +Everything else — queries, runtime wiring, build integration, upgrades, debugging, feedback — sits on top of those three. ## Routing table @@ -48,16 +36,14 @@ Open the reference whose triggers match the task. If more than one matches, open | Task | Reference | Triggers | | --- | --- | --- | +| Understand the system | [`references/concepts.md`](references/concepts.md) | "what is Prisma Next / Prisma 8", "how does it work", comparisons to Drizzle / Kysely / TypeORM / classic Prisma, contract vs schema, emit / artifacts, hashes, marker / database signature, plans, query lanes, façade / family / target / adapter / driver layering, capabilities, codecs, extensions, middleware, migration-graph analogy, which commands are offline vs touch the database | +| Diagnose a failure | [`references/failure-modes.md`](references/failure-modes.md) | any structured error envelope (code, domain, severity, why, fix, meta), emit failed, query won't typecheck, query crashed, migration won't apply, `BUDGET.ROWS_EXCEEDED`, `BUDGET.TIME_EXCEEDED`, `RUNTIME.ABORTED`, `PLAN.HASH_MISMATCH`, `CONTRACT.MARKER_MISSING`, PN-RUN-* / PN-MIG-* / PN-CLI-* / PN-SCHEMA-* codes, drift, capability missing, planner conflict, EXPLAIN, query log, script won't exit / close connection | | Adopt / set up / first steps | [`references/quickstart.md`](references/quickstart.md) | new project, existing database, "what can I do with Prisma Next", "where do I start", "just ran createprisma", `npx create-prisma`, first steps, first query, `prisma orm init` greenfield setup, `contract infer` + `db sign` brownfield adoption, connect-write-read first arc, day-to-day commands (`contract emit`, `db init`, `db update`, `migration plan`, `db migrate`, `db schema`, `db verify`), flags `--target` / `--authoring` / `--schema-path` / `--probe-db` / `--output` | | Edit the data contract | [`references/contract.md`](references/contract.md) | schema, models, fields, attributes, relations, indexes, enums, value objects (composite types), type aliases, namespaces (Postgres schemas), cross-contract foreign keys (cross-space FK), polymorphic types (`@@discriminator` / `@@base`), extension namespaces (`pgvector.Vector(...)`, `cipherstash.EncryptedString(...)`), `prisma.config.ts` / `defineConfig`, `prisma contract emit`, PSL, `contract.prisma`, `contract.ts`, `contract.json`, `contract.d.ts`, `@internal/postgres/config`, `@internal/postgres/contract-builder`, `@internal/mongo/config`, `extensions:`, pgvector, cipherstash, postgis, paradedb, `@@control`, control policy (managed / tolerated / external / observed), soft delete, validations, callbacks | -| Author migrations | [`references/migrations.md`](references/migrations.md) | `db update` vs `migration plan`, `db migrate`, `migration new`, `migration show`, `db update --dry-run`, `db verify`, `db sign`, data migration, `dataTransform`, placeholder sentinels in framework-rendered `migration.ts`, `MIGRATION.HASH_MISMATCH`, PN-MIG-2001 unfilled placeholder, schema drift | -| Migration graph, refs, plan origin | [`references/migration-model.md`](references/migration-model.md) | migration graph, refs, `migration ref set` / `list` / `delete`, the `db` ref, `--advance-ref`, `migration plan --from`, `from: (baseline)` in plan output, greenfield / from-scratch plan, baseline, first migration before deploy (Composer / CD-managed databases), chaining migrations, retrofitting migrations onto an existing database, `MIGRATION.HASH_NOT_IN_GRAPH`, `MIGRATION.PATH_UNREACHABLE` at plan/chain time | -| Review migrations on deploy | [`references/migration-review.md`](references/migration-review.md) | "what migrations are going to run", "what runs on deploy / merge", merge conflict, diamond convergence, concurrent migrations, migration status, ref management for CI, staging / production environment refs, `MIGRATION.DIVERGED`, `MIGRATION.NO_MARKER`, `MIGRATION.MARKER_NOT_IN_HISTORY`, `db migrate status`, `db migrate diff`, `db migrate resolve` | | Write queries | [`references/queries.md`](references/queries.md) | query, where, select, project, orderBy, limit, offset, take, skip, include, lookup, first, all, count, aggregate, groupBy, create, update, delete, upsert, returning, transaction, `db.orm`, `db.sql`, `db.query.from(...)` (Mongo pipeline), namespace-aware accessors, `.all()` Thenable, single-use iterators (`RUNTIME.ITERATOR_CONSUMED`), target-declared aggregate types (`count`, integer `sum`, and integer `avg` are `number`; `count` and integer `sum` throw outside ±(2^53 − 1) rather than round, while `avg` is a fraction already and carries no guard; `countBigInt` / `sumBigInt` / `avgDecimal` are the lossless forms, `avgDecimal` on PostgreSQL only), drizzle-style, kysely-style. Postgres/SQLite specifics: [`references/queries-postgres.md`](references/queries-postgres.md); Mongo specifics: [`references/queries-mongo.md`](references/queries-mongo.md) | | Wire the runtime | [`references/runtime.md`](references/runtime.md) | `db.ts`, `postgres(...)` / `sqlite(...)` / `mongo(...)` façades, middleware composition (telemetry, lints, budgets), `DATABASE_URL`, `.env`, connection pool / `poolOptions`, dev vs prod config, transactions, read replicas, multi-database, script won't exit / hangs, `db.close` / `pool.end`, `await using` / `[Symbol.asyncDispose]` | | Build-tool integration | [`references/build.md`](references/build.md) | Vite plugin (`@internal/vite-plugin-contract-emit`, Vite 7/8), `vite.config.ts`, contract emit on save, HMR / dev server, Next.js / Webpack / esbuild / Rollup / Turbopack (named gaps, not fabricated) | | Supabase | [`references/supabase.md`](references/supabase.md) | `@internal/extension-supabase`, RLS, row level security, policies (`policy_select` / `policy_update` / `@@rls`, `auth.uid()`), role binding (`asUser(jwt)` / `asAnon()` / `asServiceRole()`), `auth.users`, cross-space FKs to `supabase:auth.AuthUser`, JWT / JWKS (`SUPABASE_JWKS_URL`, `SUPABASE_JWT_SECRET`), `SUPABASE.JWT_INVALID`, `SUPABASE.CONFIG_INVALID`, `RoleBoundDb`, session pooler | -| Debug an error | [`references/debug.md`](references/debug.md) | any structured error envelope (code, domain, severity, why, fix, meta), emit failed, query won't typecheck, query crashed, migration won't apply, `MIGRATION.HASH_MISMATCH`, `BUDGET.ROWS_EXCEEDED`, `BUDGET.TIME_EXCEEDED`, `RUNTIME.ABORTED`, `PLAN.HASH_MISMATCH`, `CONTRACT.MARKER_MISSING`, PN-RUN-*/ PN-MIG-* / PN-CLI-*/ PN-SCHEMA-* codes, drift, capability missing, planner conflict, EXPLAIN, query log, script won't exit / close connection | | Upgrade Prisma in an app | [`references/upgrade-app.md`](references/upgrade-app.md) | "upgrade Prisma", "upgrade Prisma Next", "bump Prisma Next", "move to Prisma Next X.Y", `@internal/*` version bump in an application, per-transition upgrade instructions in [`upgrading/app/upgrades/`](upgrading/app/upgrades/), extension-pin pre-flight, `PN-UPGRADE-*` | | Upgrade Prisma in an extension | [`references/upgrade-extension.md`](references/upgrade-extension.md) | the same request in a package that *is* a Prisma extension (`@internal/contract` / SPI dependency, `^@.*/extension-` name), `prisma-8-check-pins`, exact-pin rule, per-transition instructions in [`upgrading/extension/upgrades/`](upgrading/extension/upgrades/) | | File feedback / ask the team | [`references/feedback.md`](references/feedback.md) | bug report, file an issue, feature request, missing feature, capability gap, "this is broken", surprising behaviour, Q&A / design discussion, ask the Prisma team, Prisma Discord (pris.ly/discord), extension-author questions | @@ -71,17 +57,21 @@ For a vague prompt, ask **one** disambiguating question. Pick from: - *"Are you new to Prisma Next and asking what you can do with it, or where to start?"* → [`references/quickstart.md`](references/quickstart.md) (first-touch orientation path). - *"Do you want to set up a new Prisma Next project, or wire it into an existing database?"* → [`references/quickstart.md`](references/quickstart.md). - *"Do you want to edit your data contract (add a model / field / relation), or work with the database (migrations, queries)?"* → [`references/contract.md`](references/contract.md) vs the others. -- *"Is this about authoring a migration, or about reviewing what's going to run on deploy?"* → [`references/migrations.md`](references/migrations.md) vs [`references/migration-review.md`](references/migration-review.md). If it's about where a plan starts, refs, or an unexpected from-scratch plan → [`references/migration-model.md`](references/migration-model.md). - *"Is this about wiring Prisma Next into your build tool (Vite / Next.js / …), or about wiring `db.ts` and middleware at runtime?"* → [`references/build.md`](references/build.md) vs [`references/runtime.md`](references/runtime.md). -- *"What error or symptom are you seeing?"* → [`references/debug.md`](references/debug.md). +- *"What error or symptom are you seeing?"* → [`references/failure-modes.md`](references/failure-modes.md). - *"Do you want to report this as a bug to the Prisma Next team, or is this a feature request?"* → [`references/feedback.md`](references/feedback.md). - *"Is the project you want to upgrade an application, or a Prisma extension package?"* → [`references/upgrade-app.md`](references/upgrade-app.md) vs [`references/upgrade-extension.md`](references/upgrade-extension.md). If you still can't tell which reference applies, ask the user what they want to do. Do not guess. +## Related skills + +Planning, authoring, reviewing, or applying migrations — `db update`, `migration plan`, `db migrate`, refs, deploy review, `MIGRATION.*` codes — is owned by the sibling `prisma-orm-migrations` skill; the two install together. + ## Checklist - [ ] If the task matches a routing-table row, open that reference before writing code. - [ ] If the prompt is vague, ask one disambiguating question. - [ ] Do not attempt to answer from this file alone — the references carry the verified tool surface. - [ ] If the user describes a missing feature or a misbehaviour they want fixed, open [`references/feedback.md`](references/feedback.md). +- [ ] If the task is migration planning / applying / review, route to `prisma-orm-migrations`. diff --git a/skills/prisma-8/references/build.md b/skills/prisma-orm-core-concepts/references/build.md similarity index 98% rename from skills/prisma-8/references/build.md rename to skills/prisma-orm-core-concepts/references/build.md index f0bfa8a51c80..56e89e350865 100644 --- a/skills/prisma-8/references/build.md +++ b/skills/prisma-orm-core-concepts/references/build.md @@ -114,7 +114,7 @@ See [`examples/react-router-demo`](https://github.com/prisma/prisma/tree/main/ex 2. **Vite 6 or earlier.** Not supported. Upgrade Vite to 7 or 8. 3. **The plugin warns: *"watching only the config; loader resolved inputs unavailable."*** The plugin couldn't resolve `contract.source.inputs` from the loader. The fallback watches only `prisma.config.ts` itself, so contract edits won't re-emit. Causes: the config file throws during loading; the contract source path resolves outside the Vite root. Fix the config error first, then check that the contract source path in the config is relative to (or inside) the Vite root. 4. **Expecting `vite build` to re-emit.** It doesn't. Add a `prebuild` script. -5. **Emit errors during dev**: the plugin surfaces them via Vite's error overlay. Read the overlay; the underlying cause is a contract authoring problem — chain to `references/debug.md` for resolution (PSL syntax, missing namespace, conflicting extensions). +5. **Emit errors during dev**: the plugin surfaces them via Vite's error overlay. Read the overlay; the underlying cause is a contract authoring problem — chain to `references/failure-modes.md` for resolution (PSL syntax, missing namespace, conflicting extensions). 6. **Re-installing dependencies without the plugin's peer-range move.** When PN bumps the plugin's peer range, you must re-run `pnpm install` so the lockfile picks up the new range. A stale lockfile keeps the old plugin and produces confusing version mismatch warnings. ## What Prisma Next doesn't do yet diff --git a/skills/prisma-orm-core-concepts/references/concepts.md b/skills/prisma-orm-core-concepts/references/concepts.md new file mode 100644 index 000000000000..3fb8ea165288 --- /dev/null +++ b/skills/prisma-orm-core-concepts/references/concepts.md @@ -0,0 +1,146 @@ + +# Prisma Next — Core Concepts + +> **Edit your data contract. Prisma handles the rest.** + +This reference carries the mental model behind Prisma 8 (Prisma Next): the vocabulary the CLI, the runtime, and the sibling skills all assume. Read the section the question is about; read the whole file when the user is orienting ("what is Prisma Next", "how does it compare to X"). + +## When to Use + +- User asks *"what is Prisma Next / Prisma 8"*, *"how does it work"*, or compares it to another ORM (Drizzle, Kysely, TypeORM, classic Prisma). +- User asks what a contract, plan, marker, ref, capability, codec, extension, or middleware *is*. +- User asks why two files (`contract.json`, `contract.d.ts`) exist, or what `contract emit` produces. +- User asks which CLI commands touch the database and which are offline. + +## When Not to Use + +- User wants to *do* something — edit the contract, write a query, wire `db.ts`, set up a project → the workflow references in this skill's routing table. +- User wants to plan, apply, or review a migration → the `prisma-orm-migrations` skill. +- User pasted an error envelope → [`failure-modes.md`](failure-modes.md). + +## The contract and the schema + +You author a **contract**: the description of the data your application needs — models, fields, relations, and their mapping onto tables or collections. It lives in `contract.prisma` (PSL, the canonical surface) or a TypeScript builder file. The **schema** is what the database actually has right now — the live tables and indexes. In Prisma 8, you author a contract, and the schema is what the database has: + +- Queries are typed against the **contract**. +- Migrations move the **schema** toward the contract. +- Verification (`db verify`) confirms the schema satisfies the contract. + +The distinction is load-bearing: the contract can be ahead of the schema (you edited but haven't migrated), behind it (someone changed the database out-of-band), or in agreement. Every CLI diagnostic about "drift" is a statement about the two disagreeing. + +## Emitting: from source to artifacts + +**Emitting** is the build step: `prisma contract emit` compiles the contract source into two plain files colocated with it: + +- `contract.json` — the canonical, content-hashed Contract IR. Read by the migration planner, the runtime, and `db verify`. +- `contract.d.ts` — the precise TypeScript types the runtime and query lanes propagate. + +Every other part of the toolchain reads these artifacts, not your source file. Emission is deterministic — the same source produces the same artifacts — so both are committed to version control. The pair works like `package.json` and a lockfile: the source is what you asked for; the artifacts are the exact resolved result. Edit the source, never the artifacts. + +## Hashes and the database marker + +Every emitted contract has a content **hash** — a fingerprint that names that exact contract state. The database carries the complementary half: a **marker** (the docs also call it the database signature) — a small record stored in the database itself naming the contract hash the database currently satisfies. On Postgres it is a row in `prisma_contract.marker`; on Mongo, a document in `_prisma_migrations`. `db sign` writes it (after a schema verification passes); `db migrate`, `db update`, and `db init` advance it. + +The two sides verify each other: the runtime compares the contract hash against the marker before executing queries, and the migration runner checks the marker matches a migration's `from` hash before applying it. When contract and marker disagree, that state is **drift**, and `db verify` is the diagnostic that reveals it. + +## Queries compile to plans + +A **plan** is the compiled form of a query: a plain data object holding the statement to run, its parameters, and metadata about what the query touches. Every query — whichever API authored it — becomes a plan before execution. The SQL builder shows this explicitly: + +```typescript +const plan = db.sql.user + .select('id', 'name') + .where((f, fns) => fns.eq(f.active, true)) + .limit(10) + .build(); +const rows = await db.runtime().execute(plan); +``` + +Plans matter for two reasons: every query goes through the same execution pipeline, and a plan is *data* — it exists as an object before anything reaches the database, which is what lets middleware inspect, veto, or record it. Raw queries are still plans, so middleware and telemetry see them like any other query. + +## The query APIs + +All query surfaces are typed against the contract and all produce plans: + +- **ORM client** (`db.orm`) — model-shaped queries and mutations; operations like `.include(...)` coordinate multiple queries. The default lane. +- **SQL builder** (`db.sql`, Postgres/SQLite) — composable joins, grouping, computed projections; raw SQL (`db.raw.sql`) as the escape hatch. +- **Pipeline builder** (`db.query.from(...)`, Mongo) — typed aggregation pipelines; raw commands as the escape hatch. + +Raw results bypass codec decoding — values arrive as the driver returns them. Lane selection guidance lives in this skill's `references/queries.md`. + +## The stack behind one package + +A project installs **one façade package per target** — `@prisma/orm-postgres`, `@prisma/orm-sqlite`, or `@prisma/orm-mongo` — and user code imports only the façade subpaths (`@internal/postgres/config`, `@internal/postgres/runtime`, …). Behind the façade sit the layers: the database **family** (SQL or document), the **target** dialect (Postgres), the **adapter** (translates plans to the dialect), and the **driver** (holds the connection). The layering exists for extensibility — Prisma 8's core is small, and everything around it, Postgres support included, plugs in through the same public interfaces. Supporting a new database means new target, adapter, and driver implementations, not a fork of the core. + +## Capabilities + +A **capability** is a specific feature a database may or may not support — `RETURNING` clauses, lateral joins, vector indexes. The active adapter advertises its capabilities and they become part of the emitted contract; the typed query surface gates on them at authoring time, so a method that needs a missing capability (e.g. `.returning(...)` without the `returning` capability) does not typecheck. Extensions can add capabilities; they are enabled through `extensions: [...]` in `prisma.config.ts`, not by hand-editing a capability list. + +## Codecs + +A **codec** converts values between JavaScript and the database's wire format, in both directions. Every column type in the contract has one — a Postgres `timestamptz` column produces a JavaScript `Date` on read and encodes it back on write. Picking a column type in PSL is also picking the codec that handles every value the column carries. Extensions introduce codecs for new types; raw query results bypass codecs entirely. + +## Extensions + +An **extension** is an installable package that adds capability to the whole toolchain: new column types with their codecs, query operations, index kinds. Registered once in `prisma.config.ts`: + +```typescript +import pgvector from '@internal/extension-pgvector/control'; +import { defineConfig } from '@internal/postgres/config'; + +export default defineConfig({ + contract: './src/prisma/contract.prisma', + extensions: [pgvector], + db: { connection: process.env.DATABASE_URL }, +}); +``` + +After registration the extension's types appear in the contract language (`pgvector.Vector(length: 1536)`), the emitted types, the query builders, and the planned migrations. Extension authoring and the available packs are covered in this skill's `references/contract.md`. + +## Middleware + +A **middleware** is a plain object with a name and one or more hooks that run around every query. Registered once in `db.ts`, it sees the structured plan object — so it can log, enforce limits, or reject before anything executes. Built-in middleware includes telemetry, `lints` (blocks risky query shapes), and `budgets` (row/latency caps); a cache middleware ships as an extension package. Composition and custom middleware are covered in this skill's `references/runtime.md`. + +## Migrations: a graph of contracts + +A **migration** records how to move the schema between two contract states. Each is a package on disk: an editable `migration.ts`, compiled operations (`ops.json`), and a manifest recording the `from` and `to` contract hashes. Together they form a directed **graph** — contracts (by hash) are nodes, migrations are edges. A **ref** is a named pointer at a contract (`production`, `staging`), managed with `migration ref`. + +The git analogy holds up well: + +| Git | Prisma 8 | +| --- | --- | +| Commit | Contract (by hash) | +| Patch | Migration | +| Branch / tag | Ref | +| HEAD | Database marker | +| `git checkout` | `db migrate --to` | + +The full model — plan origins, refs, deploy review — is the `prisma-orm-migrations` skill. + +## How CLI commands combine + +One division governs the CLI: **`db ...` commands connect to a live database and can change it; `contract ...` and `migration ...` commands work on the files in your repository.** The one exception is `contract infer`, which reads a live database without modifying it. + +The workflows compose from that division: + +1. **Development** — `contract emit` → `migration plan --name ` → `db migrate`. +2. **Prototyping** — `contract emit` → `db update --dry-run` → `db update` (no migration files; dev databases only). +3. **Adoption** — `contract infer` → review → `contract emit` → `db sign`. +4. **CI/CD** — `migration check` (offline artifact/graph integrity) → `migration status --to --db $URL` (read-only gate) → `db migrate --to --db $URL`. + +## What Prisma Next doesn't do yet + +Concept-level gaps a user orienting on the system tends to ask about — each with today's workaround, detailed in [`failure-modes.md`](failure-modes.md) § *What Prisma Next doesn't do yet*: + +- **Studio / GUI database browser** — use `prisma db schema` or a third-party client. +- **`EXPLAIN` integration** — write the `EXPLAIN` as a raw query. +- **First-class query logger middleware** — write a small custom middleware. + +To request any of these, route to this skill's `references/feedback.md`. + +## Checklist + +- [ ] Answered the orientation question from this file's model, then routed the *doing* to the matching workflow reference (or the `prisma-orm-migrations` skill). +- [ ] Kept the contract/schema distinction straight: contract = authored intent, schema = live database state. +- [ ] Did not present emitted artifacts (`contract.json`, `contract.d.ts`) as editable. +- [ ] Did not confabulate a capability toggle, Studio, or EXPLAIN API — named the gap and the workaround instead. diff --git a/skills/prisma-8/references/contract.md b/skills/prisma-orm-core-concepts/references/contract.md similarity index 98% rename from skills/prisma-8/references/contract.md rename to skills/prisma-orm-core-concepts/references/contract.md index 28dce731df79..99b3b77dedc7 100644 --- a/skills/prisma-8/references/contract.md +++ b/skills/prisma-orm-core-concepts/references/contract.md @@ -6,8 +6,8 @@ The data contract is the single source of truth for your data layer. You edit a contract source — `contract.prisma` (PSL, the canonical surface) or `contract.ts` (TypeScript builder) — and the framework derives types, migrations, and runtime configuration from it. The three-step user model: 1. **You edit your data contract.** -2. **The system plans the migrations for you.** (`references/migrations.md`) -3. **If you need data migrations, you edit `migration.ts` and execute it.** (`references/migrations.md`) +2. **The system plans the migrations for you.** (`prisma-orm-migrations/references/migrations.md`) +3. **If you need data migrations, you edit `migration.ts` and execute it.** (`prisma-orm-migrations/references/migrations.md`) Behind step 1 the agent runs `prisma contract emit` after every contract edit (or installs the Vite plugin so the bundler runs it on save — see `references/build.md`). Emit reads the contract source through the provider the façade picks based on the file extension of `contract:` in `prisma.config.ts`, then writes two artefacts colocated with the source: @@ -30,12 +30,12 @@ Both files are **emitted artefacts**. Edit the source; never the JSON or `.d.ts` ## When Not to Use -- User wants to apply a contract change to the DB → `references/migrations.md`. +- User wants to apply a contract change to the DB → `prisma-orm-migrations/references/migrations.md`. - User wants to write a query against the contract → `references/queries.md`. - User wants to wire `db.ts` (runtime entry point, middleware, env config) → `references/runtime.md`. - User wants the Vite / bundler integration → `references/build.md`. - User wants to set up Prisma Next for the first time → `references/quickstart.md`. -- User wants a deeper read of a single structured error envelope → `references/debug.md`. +- User wants a deeper read of a single structured error envelope → `references/failure-modes.md`. - User wants to file a missing-feature request → `references/feedback.md`. ## Key Concepts @@ -343,7 +343,7 @@ model AuditLog { } ``` -A contract-level default can be set via `defaultControlPolicy` on `prismaContract(path, { defaultControlPolicy })`. See `references/migrations.md` for how control policies affect DDL planning. +A contract-level default can be set via `defaultControlPolicy` on `prismaContract(path, { defaultControlPolicy })`. See `prisma-orm-migrations/references/migrations.md` for how control policies affect DDL planning. ## Workflow — `@internal/extension-supabase` @@ -384,7 +384,7 @@ Infer captures indexes at full fidelity — expression, partial (`where:`), uniq 3. **Wrong factory/import path for the TS builder.** `defineContract`, `field`, `model`, `rel` come from `@internal/postgres/contract-builder` (or `@internal/mongo/contract-builder`). Outside the callback overload, the available field constructors are `field.column(...)`, `field.generated(...)`, `field.namedType(...)`. 4. **Reaching into internal packages from user code.** User-authored files (`prisma.config.ts`, `contract.ts`, `db.ts`, control clients) import only from `@internal//` and `@internal/extension-/`. Imports from `@internal/cli/*`, `@internal/family-*`, `@internal/target-*`, `@internal/adapter-*`, `@internal/driver-*`, or `@internal/sql-contract-*` are framework-internal — the façade composes them for you. If a façade subpath you need is missing for your target, see *What Prisma Next doesn't do yet* and route to `references/feedback.md`. The canonical worked examples are `examples/multi-extension-monorepo/app/prisma.config.ts` and `examples/prisma-8-postgis-demo/prisma.config.ts`. 5. **Confusing the config `extensions` with the TS builder's `extensions`.** Same packs, two surfaces, one field name but two shapes: `defineConfig({ extensions: [pgvector] })` (array of *control* descriptors from `@internal/extension-/control`) versus `defineContract({ extensions: { pgvector } })` (record of *pack* descriptors from `@internal/extension-/pack`). -6. **Renaming a field and expecting the planner to detect it.** Prisma Next has no in-contract rename hint; the planner sees a destructive drop+add. Hand-edit `migration.ts` after `migration plan` (see `references/migrations.md`), or use the keep-then-drop two-migration pattern. +6. **Renaming a field and expecting the planner to detect it.** Prisma Next has no in-contract rename hint; the planner sees a destructive drop+add. Hand-edit `migration.ts` after `migration plan` (see `prisma-orm-migrations/references/migrations.md`), or use the keep-then-drop two-migration pattern. ## What Prisma Next doesn't do yet diff --git a/skills/prisma-8/references/debug.md b/skills/prisma-orm-core-concepts/references/failure-modes.md similarity index 92% rename from skills/prisma-8/references/debug.md rename to skills/prisma-orm-core-concepts/references/failure-modes.md index 3a4e2cf68b31..72e4a1193cf7 100644 --- a/skills/prisma-8/references/debug.md +++ b/skills/prisma-orm-core-concepts/references/failure-modes.md @@ -1,5 +1,5 @@ -# Prisma Next — Debug +# Prisma Next — Failure Modes (Structured Errors) > **Edit your data contract. Prisma handles the rest.** @@ -82,24 +82,24 @@ The single source of truth: read the envelope, find the row by `code` (or `meta. | `PN-CLI-4003` *Contract validation failed* | `contract emit`, `db *` | Re-run `pnpm prisma-cli contract emit` after fixing the contract source named in `where.path`. See `references/contract.md`. | | `PN-CLI-4005` *Database connection is required* | `db *`, `db migrate`, `migration status` | Pass `--db ` or set `db.connection` in `prisma.config.ts`. | | `PN-CLI-4011` *Missing extension packs in config* | `contract emit` (e.g. contract uses `pgvector.Vector(...)` but config does not list the pgvector pack) | Add the descriptors named in `meta.missingExtensions` to `extensions` in `prisma.config.ts`. See `references/contract.md`. | -| `PN-CLI-4020` *Migration planning failed* | `db init`, `db update` | Inspect `meta.conflicts`. Recovery is per-conflict — chain to `references/migrations.md`. | +| `PN-CLI-4020` *Migration planning failed* | `db init`, `db update` | Inspect `meta.conflicts`. Recovery is per-conflict — chain to `prisma-orm-migrations/references/migrations.md`. | | `PN-CLI-5002/5003/5004/…` *Init errors* | `prisma orm init` | Re-run with the missing/invalid flags listed in `meta.missingFlags` or `meta.allowed`. | -| `PN-MIG-2001` *Unfilled migration placeholder* | `node migrations/app//migration.ts` (self-emit) or `db migrate` | Edit `migration.ts`, replace the named `placeholder("")` with a real query closure, self-emit. See `references/migrations.md`. | +| `PN-MIG-2001` *Unfilled migration placeholder* | `node migrations/app//migration.ts` (self-emit) or `db migrate` | Edit `migration.ts`, replace the named `placeholder("")` with a real query closure, self-emit. See `prisma-orm-migrations/references/migrations.md`. | | `PN-MIG-2002` *migration.ts not found* | Reading a migration package | Restore from version control or scaffold a fresh package with `migration plan`. | -| `PN-MIG-2003` *Invalid default export* | Loading `migration.ts` | Use `export default class extends Migration { ... }` (or factory `() => ({ ... })`). See `references/migrations.md`. | +| `PN-MIG-2003` *Invalid default export* | Loading `migration.ts` | Use `export default class extends Migration { ... }` (or factory `() => ({ ... })`). See `prisma-orm-migrations/references/migrations.md`. | | `PN-MIG-2005` *dataTransform contract mismatch* | Building a data-transform query plan | Pass the same `endContract` reference to both `dataTransform(endContract, …)` and the query-builder context. | | `PN-RUN-3001` *Database not signed* | `db verify`, runtime startup | DB has no marker yet. Run `prisma db init --db ` (baseline empty DB) or `db update --db ` (apply contract directly). | -| `PN-RUN-3002` *Hash mismatch* | `db verify`, runtime startup | Marker disagrees with contract hash. Either migrate forward (`db migrate` / `db update`), or — if the DB is correct after a manual fix-up — `db sign`. See `references/migrations.md`. | +| `PN-RUN-3002` *Hash mismatch* | `db verify`, runtime startup | Marker disagrees with contract hash. Either migrate forward (`db migrate` / `db update`), or — if the DB is correct after a manual fix-up — `db sign`. See `prisma-orm-migrations/references/migrations.md`. | | `PN-RUN-3003` *Target mismatch* | Runtime startup | Contract target ≠ config target; align them (see `meta.expected` / `meta.actual`). | | `PN-RUN-3004` *Schema verification failed* | `db verify` (full mode) | Inspect `meta.verificationResult`. Run `db update` to reconcile, or adjust contract. | | `PN-RUN-3010` *Schema verification failed (CLI surface)* | `db verify` schema-only | Same as 3004. | | `PN-RUN-3020` *Migration runner failed* | `db migrate`, `db update`, `db init` | Inspect `meta` for the conflict; reconcile schema drift, then re-run. Previously applied migrations are preserved. | | `PN-RUN-3030` *Destructive changes require confirmation* | `db update` (interactive prompt fires; non-interactive returns this code) | Re-run with `-y` (or `--yes`) to apply, or `--dry-run` to preview. **Only `db update` has this flow** — `db migrate` does not gate destructive ops on a flag. | -| `PN-RUN-3000` *(wrapper)* | `db migrate`, others wrapping `MigrationToolsError` | Read `meta.code`. Cases: `MIGRATION.HASH_MISMATCH` (re-emit: `node migrations/app//migration.ts`); `MIGRATION.AMBIGUOUS_TARGET` (concurrent migrations — `references/migration-review.md`); `MIGRATION.STALE_CONTRACT_BOOKENDS` (re-run `migration plan`); `MIGRATION.NO_INVARIANT_PATH` / `MIGRATION.UNKNOWN_INVARIANT` (`references/migration-review.md`); `MIGRATION.PATH_UNREACHABLE` / `MIGRATION.MARKER_MISMATCH` (run `db migrate --show --db $URL` to inspect the path, then `migration plan --from --to ` or `migration list` to audit the graph — see `references/migration-review.md`). | +| `PN-RUN-3000` *(wrapper)* | `db migrate`, others wrapping `MigrationToolsError` | Read `meta.code`. Cases: `MIGRATION.HASH_MISMATCH` (re-emit: `node migrations/app//migration.ts`); `MIGRATION.AMBIGUOUS_TARGET` (concurrent migrations — `prisma-orm-migrations/references/migration-review.md`); `MIGRATION.STALE_CONTRACT_BOOKENDS` (re-run `migration plan`); `MIGRATION.NO_INVARIANT_PATH` / `MIGRATION.UNKNOWN_INVARIANT` (`prisma-orm-migrations/references/migration-review.md`); `MIGRATION.PATH_UNREACHABLE` / `MIGRATION.MARKER_MISMATCH` (run `db migrate --show --db $URL` to inspect the path, then `migration plan --from --to ` or `migration list` to audit the graph — see `prisma-orm-migrations/references/migration-review.md`). | | `PN-SCHEMA-0001` | `db verify` schema check | Live schema does not satisfy contract. `meta.verificationResult` has the diff. Run `db update` or adjust the contract. | -| `MIGRATION.UP_TO_DATE` / `.DATABASE_BEHIND` | `migration status` `info` diagnostics | Informational; exit 0. See `references/migration-review.md`. | -| `MIGRATION.MISSING_INVARIANTS` | `migration status` `info` diagnostic | The live marker reached the destination hash structurally but doesn't carry all invariants the target ref requires. Run `db migrate --to --db $URL` to take a path that covers the missing invariants. See `references/migration-review.md`. | -| `MIGRATION.NO_MARKER` / `.MARKER_NOT_IN_HISTORY` / `.DIVERGED` / `CONTRACT.AHEAD` / `CONTRACT.UNREADABLE` | `migration status` `warn` diagnostics (exit 0; CI gates parse `--json`) | Read `severity` *and* `code`. `references/migration-review.md` covers the diamond/diverged/marker-out-of-history flows. | +| `MIGRATION.UP_TO_DATE` / `.DATABASE_BEHIND` | `migration status` `info` diagnostics | Informational; exit 0. See `prisma-orm-migrations/references/migration-review.md`. | +| `MIGRATION.MISSING_INVARIANTS` | `migration status` `info` diagnostic | The live marker reached the destination hash structurally but doesn't carry all invariants the target ref requires. Run `db migrate --to --db $URL` to take a path that covers the missing invariants. See `prisma-orm-migrations/references/migration-review.md`. | +| `MIGRATION.NO_MARKER` / `.MARKER_NOT_IN_HISTORY` / `.DIVERGED` / `CONTRACT.AHEAD` / `CONTRACT.UNREADABLE` | `migration status` `warn` diagnostics (exit 0; CI gates parse `--json`) | Read `severity` *and* `code`. `prisma-orm-migrations/references/migration-review.md` covers the diamond/diverged/marker-out-of-history flows. | | `BUDGET.ROWS_EXCEEDED` / `BUDGET.TIME_EXCEEDED` | Runtime, when the `budgets` middleware is active | Tune `budgets({ maxRows, maxLatencyMs, ... })` or rewrite the query. See `references/runtime.md`. | | `LINT.SELECT_STAR` / `LINT.NO_LIMIT` / `LINT.DELETE_WITHOUT_WHERE` / `LINT.UPDATE_WITHOUT_WHERE` / `LINT.READ_ONLY_MUTATION` | Runtime, when the `lints` middleware is active | Fix the query (add a `WHERE` / `LIMIT` / explicit columns), or relax the lint config. See `references/runtime.md`. | | `PLAN.HASH_MISMATCH` | Runtime, executing a precompiled plan | The contract the plan was built against does not match the runtime contract. Re-emit, rebuild, redeploy. | diff --git a/skills/prisma-8/references/feedback.md b/skills/prisma-orm-core-concepts/references/feedback.md similarity index 98% rename from skills/prisma-8/references/feedback.md rename to skills/prisma-orm-core-concepts/references/feedback.md index a46c2c874267..38a58941aad3 100644 --- a/skills/prisma-8/references/feedback.md +++ b/skills/prisma-orm-core-concepts/references/feedback.md @@ -14,7 +14,7 @@ Canonical channels: ## When to Use -- A capability-gap entry from another `prisma-next-*` skill fired and the user said *"yes, file the feature request"*. +- A capability-gap entry from another Prisma Next skill (`prisma-orm-*`) fired and the user said *"yes, file the feature request"*. - User says *"this is a bug"*, *"file this"*, *"report this"*, *"file an issue against PN"*, *"send feedback"*, *"this should be a feature"*. - User describes an unexpected behaviour — wrong exit code, error message that didn't match what happened, type signature that doesn't match runtime behaviour, planner refused a migration that looked safe — and wants it on the framework team's radar. - User asks *"can I ask the Prisma team about this?"*, *"is there somewhere I can talk to the team?"*, *"is this the intended way to do X?"*, *"how should I integrate with PN?"*, or any other open-ended Q&A or design-feedback prompt — including extension authors asking integration questions. @@ -42,7 +42,7 @@ The user wants to hand something off to the team. Which channel? - The user describes a concrete bug (see *Classify* below for the bug-vs-feature split). - The user has a concrete feature request — a named capability, a specific API shape, a specific CLI flag — that they want on the backlog. -- A capability-gap entry from another `prisma-next-*` skill routed them here for a feature request. +- A capability-gap entry from another Prisma Next skill (`prisma-orm-*`) routed them here for a feature request. **Prisma Discord** () if any of: diff --git a/skills/prisma-8/references/queries-mongo.md b/skills/prisma-orm-core-concepts/references/queries-mongo.md similarity index 98% rename from skills/prisma-8/references/queries-mongo.md rename to skills/prisma-orm-core-concepts/references/queries-mongo.md index 07c914e1437b..ad80cc5ea4af 100644 --- a/skills/prisma-8/references/queries-mongo.md +++ b/skills/prisma-orm-core-concepts/references/queries-mongo.md @@ -220,7 +220,7 @@ Update callbacks return arrays of field operations (`.set`, `.inc`, `.push`, `.p ## Reference Files -- Example queries under [`examples/mongo-demo/src/server.ts`](examples/mongo-demo/src/server.ts) — ORM reads, `.include`, `.variant`, and pipeline DSL via `db.query`. +- Example queries under [`examples/mongo-demo/src/server.ts`](../../../examples/mongo-demo/src/server.ts) — ORM reads, `.include`, `.variant`, and pipeline DSL via `db.query`. - Integration tests under `examples/mongo-demo/test/` (`blog.test.ts`, `crud-lifecycle.test.ts`, `query-builder-writes.test.ts`). - Query builder README under `packages/2-mongo-family/5-query-builders/query-builder/README.md`. - ORM collection surface under `packages/2-mongo-family/5-query-builders/orm/src/collection.ts`. diff --git a/skills/prisma-8/references/queries-postgres.md b/skills/prisma-orm-core-concepts/references/queries-postgres.md similarity index 99% rename from skills/prisma-8/references/queries-postgres.md rename to skills/prisma-orm-core-concepts/references/queries-postgres.md index aab647ab8df2..d38eb904937e 100644 --- a/skills/prisma-8/references/queries-postgres.md +++ b/skills/prisma-orm-core-concepts/references/queries-postgres.md @@ -395,7 +395,7 @@ Cross-namespace relations (e.g. `public.Profile` → `auth.User`) follow the sam ## Reference Files -- Example queries under [`examples/prisma-8-demo/src/orm-client/`](examples/prisma-8-demo/src/orm-client/) and [`examples/prisma-8-demo/src/queries/`](examples/prisma-8-demo/src/queries/) — canonical ORM and SQL-builder shapes. +- Example queries under [`examples/prisma-8-demo/src/orm-client/`](../../../examples/prisma-8-demo/src/orm-client/) and [`examples/prisma-8-demo/src/queries/`](../../../examples/prisma-8-demo/src/queries/) — canonical ORM and SQL-builder shapes. - ORM client source under `packages/3-extensions/sql-orm-client/src/`. - SQL builder source under `packages/2-sql/4-lanes/sql-builder/src/`. diff --git a/skills/prisma-8/references/queries.md b/skills/prisma-orm-core-concepts/references/queries.md similarity index 99% rename from skills/prisma-8/references/queries.md rename to skills/prisma-orm-core-concepts/references/queries.md index 50b62bed6c80..5995913a4f4a 100644 --- a/skills/prisma-8/references/queries.md +++ b/skills/prisma-orm-core-concepts/references/queries.md @@ -20,7 +20,7 @@ Once the contract is emitted and the DB is up to date, this skill covers everyth - User wants to add / change a model → `references/contract.md`. - User wants to wire `db.ts` or add middleware → `references/runtime.md`. - User is querying through a Supabase role-bound db (`asUser` / `asAnon` / `asServiceRole`, RLS, `auth.*` admin reads) → `references/supabase.md` for the role-binding surface; everything in this skill then applies to the returned `RoleBoundDb`. -- User wants to debug a query failure (structured error envelope) → `references/debug.md`. +- User wants to debug a query failure (structured error envelope) → `references/failure-modes.md`. ## Pick your target diff --git a/skills/prisma-8/references/quickstart.md b/skills/prisma-orm-core-concepts/references/quickstart.md similarity index 98% rename from skills/prisma-8/references/quickstart.md rename to skills/prisma-orm-core-concepts/references/quickstart.md index abc357224801..d9341766f1e8 100644 --- a/skills/prisma-8/references/quickstart.md +++ b/skills/prisma-orm-core-concepts/references/quickstart.md @@ -270,13 +270,13 @@ A reference table — not a script to recite at the user. Commands surface in th |---|---|---| | Apply the current contract to the DB the first time | `prisma db init` | this skill | | Re-emit `contract.json` + `contract.d.ts` after editing the contract source | `prisma contract emit` | `references/contract.md` | -| Quick dev-only schema sync (no migration history kept) | `prisma db update` | `references/migrations.md` | -| Plan a migration from a contract diff | `prisma migration plan --name ` | `references/migrations.md` | -| Apply pending migrations | `prisma db migrate` | `references/migrations.md` | -| Inspect the live database | `prisma db schema` | `references/debug.md` | -| Confirm the DB matches the contract (drift check) | `prisma db verify` | `references/debug.md` | +| Quick dev-only schema sync (no migration history kept) | `prisma db update` | `prisma-orm-migrations/references/migrations.md` | +| Plan a migration from a contract diff | `prisma migration plan --name ` | `prisma-orm-migrations/references/migrations.md` | +| Apply pending migrations | `prisma db migrate` | `prisma-orm-migrations/references/migrations.md` | +| Inspect the live database | `prisma db schema` | `references/failure-modes.md` | +| Confirm the DB matches the contract (drift check) | `prisma db verify` | `references/failure-modes.md` | | Bring an existing DB into a PN contract | `prisma contract infer --db "$DATABASE_URL"` | this skill (brownfield) | -| Decode a structured error envelope | (read the `code` / `why` / `fix` fields) | `references/debug.md` | +| Decode a structured error envelope | (read the `code` / `why` / `fix` fields) | `references/failure-modes.md` | | Report a bug or request a feature | (file via the feedback skill) | `references/feedback.md` | ## Decision — PSL vs TypeScript authoring @@ -299,7 +299,7 @@ Switch authoring later by re-running `prisma orm init` in the same directory. Th ## What Prisma Next doesn't do yet - **Migration from another ORM.** Prisma Next doesn't migrate your schema *from* Drizzle / Prisma 6/7 / Sequelize / TypeORM / Kysely / Knex / a raw driver. Workaround: install the matching `@internal/migrate-from--skill` if one exists for your source, or treat the source as a brownfield database and `contract infer` from it. If you need a guided migration flow built-in, file a feature request via the `references/feedback.md` skill. -- **`prisma db push`-style production sync.** `db update` is the quick development path; for production, use migrations (`migration plan` + `db migrate`). PN deliberately does not offer a "push-to-prod-without-a-migration" surface — see `references/migrations.md`. +- **`prisma db push`-style production sync.** `db update` is the quick development path; for production, use migrations (`migration plan` + `db migrate`). PN deliberately does not offer a "push-to-prod-without-a-migration" surface — see `prisma-orm-migrations/references/migrations.md`. - **Studio / GUI database browser.** Use `prisma db schema` for a CLI tree-style summary of the live DB. If you need an interactive UI, file a feature request via the `references/feedback.md` skill. ## Reference Files diff --git a/skills/prisma-8/references/runtime.md b/skills/prisma-orm-core-concepts/references/runtime.md similarity index 99% rename from skills/prisma-8/references/runtime.md rename to skills/prisma-orm-core-concepts/references/runtime.md index 6db0e8e9e697..864960f80cd0 100644 --- a/skills/prisma-8/references/runtime.md +++ b/skills/prisma-orm-core-concepts/references/runtime.md @@ -21,7 +21,7 @@ This skill covers the **runtime entry point** — `db.ts` — and how to compose - User is on Supabase — the `supabase()` role-first factory, `asUser(jwt)` / `asAnon()` / `asServiceRole()`, JWT config, RLS → `references/supabase.md`. - User wants to edit the contract → `references/contract.md`. - User wants to wire Prisma Next into a build tool (Vite plugin, Next.js, …) → `references/build.md`. -- User wants to debug a connection / runtime error → `references/debug.md`. +- User wants to debug a connection / runtime error → `references/failure-modes.md`. - User wants to file a bug or feature request → `references/feedback.md`. ## Key Concepts diff --git a/skills/prisma-8/references/supabase.md b/skills/prisma-orm-core-concepts/references/supabase.md similarity index 98% rename from skills/prisma-8/references/supabase.md rename to skills/prisma-orm-core-concepts/references/supabase.md index bfdadef78870..e0791e13bb5f 100644 --- a/skills/prisma-8/references/supabase.md +++ b/skills/prisma-orm-core-concepts/references/supabase.md @@ -19,7 +19,7 @@ This skill covers using Prisma Next against a **Supabase** project end-to-end: c - General contract editing (models, fields, relations) → `references/contract.md`. - Non-Supabase `db.ts` wiring, middleware, teardown → `references/runtime.md`. - General query shapes (filtering, includes, aggregates) → `references/queries.md` — everything there applies to a role-bound `db` too. -- Migration planning / applying → `references/migrations.md`. +- Migration planning / applying → `prisma-orm-migrations/references/migrations.md`. ## Key Concepts @@ -111,7 +111,7 @@ The pieces: - **Predicates are verbatim SQL strings.** Quote camelCase column names inside them (`\"userId\"`), and cast where needed — `auth.uid()` returns `uuid`. Renames in your contract do not rewrite predicate bodies. - **TS-builder parity exists.** `@internal/postgres/contract-builder` exports `policySelect` / `policyInsert` / `policyUpdate` / `policyDelete` / `policyAll`, `rlsEnabled(Model)`, and `role('anon')` — mirroring the PSL lowering key-for-key (identical emitted wire names). PSL is the canonical path shown here. -Emit + migrate as usual (`prisma contract emit`, then `references/migrations.md`). The plan creates your table, its FK, `ENABLE ROW LEVEL SECURITY`, and the `CREATE POLICY` statements — and **no DDL for `auth.*`**. +Emit + migrate as usual (`prisma contract emit`, then `prisma-orm-migrations/references/migrations.md`). The plan creates your table, its FK, `ENABLE ROW LEVEL SECURITY`, and the `CREATE POLICY` statements — and **no DDL for `auth.*`**. ## Workflow — `db.ts` with the `supabase()` factory diff --git a/skills/prisma-8/references/upgrade-app.md b/skills/prisma-orm-core-concepts/references/upgrade-app.md similarity index 100% rename from skills/prisma-8/references/upgrade-app.md rename to skills/prisma-orm-core-concepts/references/upgrade-app.md diff --git a/skills/prisma-8/references/upgrade-extension.md b/skills/prisma-orm-core-concepts/references/upgrade-extension.md similarity index 100% rename from skills/prisma-8/references/upgrade-extension.md rename to skills/prisma-orm-core-concepts/references/upgrade-extension.md diff --git a/skills/prisma-8/upgrading/app/upgrades/0.10-to-0.11/instructions.md b/skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.10-to-0.11/instructions.md similarity index 100% rename from skills/prisma-8/upgrading/app/upgrades/0.10-to-0.11/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.10-to-0.11/instructions.md diff --git a/skills/prisma-8/upgrading/app/upgrades/0.11-to-0.12/instructions.md b/skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.11-to-0.12/instructions.md similarity index 98% rename from skills/prisma-8/upgrading/app/upgrades/0.11-to-0.12/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.11-to-0.12/instructions.md index 04a1cc889364..52271d10b691 100644 --- a/skills/prisma-8/upgrading/app/upgrades/0.11-to-0.12/instructions.md +++ b/skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.11-to-0.12/instructions.md @@ -348,7 +348,7 @@ After re-emitting, run `pnpm typecheck && pnpm test`. The regenerated `contract. ## `runtime-qualified-sql-default-namespace` -Starting at the 0.12 release, runtime SQL on Postgres qualifies table identifiers with the storage namespace the flat DSL/ORM surface resolved ([ADR 223](../../../../docs/architecture%20docs/adrs/ADR%20223%20-%20Target-owned%20default%20namespace.md)). Un-namespaced Postgres models continue to resolve through the `public` default; explicit `namespace unbound { … }` in PSL still maps to `__unbound__`. +Starting at the 0.12 release, runtime SQL on Postgres qualifies table identifiers with the storage namespace the flat DSL/ORM surface resolved ([ADR 223](../../../../../../docs/architecture%20docs/adrs/ADR%20223%20-%20Target-owned%20default%20namespace.md)). Un-namespaced Postgres models continue to resolve through the `public` default; explicit `namespace unbound { … }` in PSL still maps to `__unbound__`. ### Application code diff --git a/skills/prisma-8/upgrading/app/upgrades/0.11-to-0.12/re-emit-closed-mongo-contracts.ts b/skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.11-to-0.12/re-emit-closed-mongo-contracts.ts similarity index 100% rename from skills/prisma-8/upgrading/app/upgrades/0.11-to-0.12/re-emit-closed-mongo-contracts.ts rename to skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.11-to-0.12/re-emit-closed-mongo-contracts.ts diff --git a/skills/prisma-8/upgrading/app/upgrades/0.11-to-0.12/re-emit-domain-namespaced-contracts.ts b/skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.11-to-0.12/re-emit-domain-namespaced-contracts.ts similarity index 100% rename from skills/prisma-8/upgrading/app/upgrades/0.11-to-0.12/re-emit-domain-namespaced-contracts.ts rename to skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.11-to-0.12/re-emit-domain-namespaced-contracts.ts diff --git a/skills/prisma-8/upgrading/app/upgrades/0.11-to-0.12/re-emit-postgres-public-default.ts b/skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.11-to-0.12/re-emit-postgres-public-default.ts similarity index 100% rename from skills/prisma-8/upgrading/app/upgrades/0.11-to-0.12/re-emit-postgres-public-default.ts rename to skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.11-to-0.12/re-emit-postgres-public-default.ts diff --git a/skills/prisma-8/upgrading/app/upgrades/0.11-to-0.12/strip-migration-labels-hints.ts b/skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.11-to-0.12/strip-migration-labels-hints.ts similarity index 100% rename from skills/prisma-8/upgrading/app/upgrades/0.11-to-0.12/strip-migration-labels-hints.ts rename to skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.11-to-0.12/strip-migration-labels-hints.ts diff --git a/skills/prisma-8/upgrading/app/upgrades/0.12-to-0.13/instructions.md b/skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.12-to-0.13/instructions.md similarity index 100% rename from skills/prisma-8/upgrading/app/upgrades/0.12-to-0.13/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.12-to-0.13/instructions.md diff --git a/skills/prisma-8/upgrading/app/upgrades/0.12-to-0.13/re-emit-mti-variant-link-columns.ts b/skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.12-to-0.13/re-emit-mti-variant-link-columns.ts similarity index 100% rename from skills/prisma-8/upgrading/app/upgrades/0.12-to-0.13/re-emit-mti-variant-link-columns.ts rename to skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.12-to-0.13/re-emit-mti-variant-link-columns.ts diff --git a/skills/prisma-8/upgrading/app/upgrades/0.13-to-0.14/instructions.md b/skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.13-to-0.14/instructions.md similarity index 99% rename from skills/prisma-8/upgrading/app/upgrades/0.13-to-0.14/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.13-to-0.14/instructions.md index 076bef34a160..53022ea43d32 100644 --- a/skills/prisma-8/upgrading/app/upgrades/0.13-to-0.14/instructions.md +++ b/skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.13-to-0.14/instructions.md @@ -332,7 +332,7 @@ override get operations() { The colocated script applies this transformation automatically. Run it from your project root: ```bash -pnpm exec tsx .claude/skills/prisma-8/upgrading/app/upgrades/0.13-to-0.14/migration-op-factories-to-methods.ts +pnpm exec tsx .claude/skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.13-to-0.14/migration-op-factories-to-methods.ts ``` ## `postgres-contract-serializer` diff --git a/skills/prisma-8/upgrading/app/upgrades/0.13-to-0.14/migration-op-factories-to-methods.ts b/skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.13-to-0.14/migration-op-factories-to-methods.ts similarity index 100% rename from skills/prisma-8/upgrading/app/upgrades/0.13-to-0.14/migration-op-factories-to-methods.ts rename to skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.13-to-0.14/migration-op-factories-to-methods.ts diff --git a/skills/prisma-8/upgrading/app/upgrades/0.13-to-0.14/uuid-preset-rename.ts b/skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.13-to-0.14/uuid-preset-rename.ts similarity index 100% rename from skills/prisma-8/upgrading/app/upgrades/0.13-to-0.14/uuid-preset-rename.ts rename to skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.13-to-0.14/uuid-preset-rename.ts diff --git a/skills/prisma-8/upgrading/app/upgrades/0.14-to-0.15/instructions.md b/skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.14-to-0.15/instructions.md similarity index 100% rename from skills/prisma-8/upgrading/app/upgrades/0.14-to-0.15/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.14-to-0.15/instructions.md diff --git a/skills/prisma-8/upgrading/app/upgrades/0.15-to-0.16/instructions.md b/skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.15-to-0.16/instructions.md similarity index 100% rename from skills/prisma-8/upgrading/app/upgrades/0.15-to-0.16/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.15-to-0.16/instructions.md diff --git a/skills/prisma-8/upgrading/app/upgrades/0.16-to-0.17/instructions.md b/skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.16-to-0.17/instructions.md similarity index 100% rename from skills/prisma-8/upgrading/app/upgrades/0.16-to-0.17/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.16-to-0.17/instructions.md diff --git a/skills/prisma-8/upgrading/app/upgrades/0.16-to-0.17/strip-sha256-hash-prefixes.ts b/skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.16-to-0.17/strip-sha256-hash-prefixes.ts similarity index 100% rename from skills/prisma-8/upgrading/app/upgrades/0.16-to-0.17/strip-sha256-hash-prefixes.ts rename to skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.16-to-0.17/strip-sha256-hash-prefixes.ts diff --git a/skills/prisma-8/upgrading/app/upgrades/0.17-to-8.0.0-rc.1/instructions.md b/skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.17-to-8.0.0-rc.1/instructions.md similarity index 100% rename from skills/prisma-8/upgrading/app/upgrades/0.17-to-8.0.0-rc.1/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.17-to-8.0.0-rc.1/instructions.md diff --git a/skills/prisma-8/upgrading/app/upgrades/0.7-to-0.8/instructions.md b/skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.7-to-0.8/instructions.md similarity index 100% rename from skills/prisma-8/upgrading/app/upgrades/0.7-to-0.8/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.7-to-0.8/instructions.md diff --git a/skills/prisma-8/upgrading/app/upgrades/0.8-to-0.9/instructions.md b/skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.8-to-0.9/instructions.md similarity index 100% rename from skills/prisma-8/upgrading/app/upgrades/0.8-to-0.9/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.8-to-0.9/instructions.md diff --git a/skills/prisma-8/upgrading/app/upgrades/0.8-to-0.9/strip-inline-contracts.ts b/skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.8-to-0.9/strip-inline-contracts.ts similarity index 100% rename from skills/prisma-8/upgrading/app/upgrades/0.8-to-0.9/strip-inline-contracts.ts rename to skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.8-to-0.9/strip-inline-contracts.ts diff --git a/skills/prisma-8/upgrading/app/upgrades/0.9-to-0.10/instructions.md b/skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.9-to-0.10/instructions.md similarity index 100% rename from skills/prisma-8/upgrading/app/upgrades/0.9-to-0.10/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.9-to-0.10/instructions.md diff --git a/skills/prisma-8/upgrading/app/upgrades/0.9-to-0.10/stamp-storage-types-kind.ts b/skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.9-to-0.10/stamp-storage-types-kind.ts similarity index 100% rename from skills/prisma-8/upgrading/app/upgrades/0.9-to-0.10/stamp-storage-types-kind.ts rename to skills/prisma-orm-core-concepts/upgrading/app/upgrades/0.9-to-0.10/stamp-storage-types-kind.ts diff --git a/skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.1-to-8.0.0-rc.2/instructions.md b/skills/prisma-orm-core-concepts/upgrading/app/upgrades/8.0.0-rc.1-to-8.0.0-rc.2/instructions.md similarity index 100% rename from skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.1-to-8.0.0-rc.2/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/app/upgrades/8.0.0-rc.1-to-8.0.0-rc.2/instructions.md diff --git a/skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.2-to-8.0.0-rc.3/instructions.md b/skills/prisma-orm-core-concepts/upgrading/app/upgrades/8.0.0-rc.2-to-8.0.0-rc.3/instructions.md similarity index 100% rename from skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.2-to-8.0.0-rc.3/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/app/upgrades/8.0.0-rc.2-to-8.0.0-rc.3/instructions.md diff --git a/skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.3-to-8.0.0-rc.4/instructions.md b/skills/prisma-orm-core-concepts/upgrading/app/upgrades/8.0.0-rc.3-to-8.0.0-rc.4/instructions.md similarity index 100% rename from skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.3-to-8.0.0-rc.4/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/app/upgrades/8.0.0-rc.3-to-8.0.0-rc.4/instructions.md diff --git a/skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.4-to-8.0.0-rc.5/instructions.md b/skills/prisma-orm-core-concepts/upgrading/app/upgrades/8.0.0-rc.4-to-8.0.0-rc.5/instructions.md similarity index 100% rename from skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.4-to-8.0.0-rc.5/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/app/upgrades/8.0.0-rc.4-to-8.0.0-rc.5/instructions.md diff --git a/skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.5-to-8.0.0-rc.6/instructions.md b/skills/prisma-orm-core-concepts/upgrading/app/upgrades/8.0.0-rc.5-to-8.0.0-rc.6/instructions.md similarity index 100% rename from skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.5-to-8.0.0-rc.6/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/app/upgrades/8.0.0-rc.5-to-8.0.0-rc.6/instructions.md diff --git a/skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.6-to-8.0.0-rc.7/instructions.md b/skills/prisma-orm-core-concepts/upgrading/app/upgrades/8.0.0-rc.6-to-8.0.0-rc.7/instructions.md similarity index 100% rename from skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.6-to-8.0.0-rc.7/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/app/upgrades/8.0.0-rc.6-to-8.0.0-rc.7/instructions.md diff --git a/skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.7-to-8.0.0-rc.8/instructions.md b/skills/prisma-orm-core-concepts/upgrading/app/upgrades/8.0.0-rc.7-to-8.0.0-rc.8/instructions.md similarity index 100% rename from skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.7-to-8.0.0-rc.8/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/app/upgrades/8.0.0-rc.7-to-8.0.0-rc.8/instructions.md diff --git a/skills/prisma-8/upgrading/extension/upgrades/0.10-to-0.11/instructions.md b/skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.10-to-0.11/instructions.md similarity index 100% rename from skills/prisma-8/upgrading/extension/upgrades/0.10-to-0.11/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.10-to-0.11/instructions.md diff --git a/skills/prisma-8/upgrading/extension/upgrades/0.11-to-0.12/instructions.md b/skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.11-to-0.12/instructions.md similarity index 99% rename from skills/prisma-8/upgrading/extension/upgrades/0.11-to-0.12/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.11-to-0.12/instructions.md index 8866e317c612..feca2c1a562f 100644 --- a/skills/prisma-8/upgrading/extension/upgrades/0.11-to-0.12/instructions.md +++ b/skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.11-to-0.12/instructions.md @@ -681,7 +681,7 @@ Run `pnpm typecheck && pnpm test` on your extension package. The import codemod ## `default-namespace-domain-access-retire-projection-helpers` -Starting at the 0.12 release (runtime qualification, [ADR 223](../../../../docs/architecture%20docs/adrs/ADR%20223%20-%20Target-owned%20default%20namespace.md)), the foundation `contract` package retires the transitional projection helpers introduced during the symmetric domain-plane migration. Extension code that still calls them will fail to compile after the bump. +Starting at the 0.12 release (runtime qualification, [ADR 223](../../../../../../docs/architecture%20docs/adrs/ADR%20223%20-%20Target-owned%20default%20namespace.md)), the foundation `contract` package retires the transitional projection helpers introduced during the symmetric domain-plane migration. Extension code that still calls them will fail to compile after the bump. The default namespace a bare name resolves through is **inferred** from the contract (sole namespace, else insertion order) — there are no `…ForSqlTarget` / `…ForMongo` helpers to import. A target's default namespace is declared on its descriptor (`defaultNamespaceId`) and consumed only by authoring; runtime code resolves target-agnostically. diff --git a/skills/prisma-8/upgrading/extension/upgrades/0.11-to-0.12/migrate-contract-testing-imports.ts b/skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.11-to-0.12/migrate-contract-testing-imports.ts similarity index 100% rename from skills/prisma-8/upgrading/extension/upgrades/0.11-to-0.12/migrate-contract-testing-imports.ts rename to skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.11-to-0.12/migrate-contract-testing-imports.ts diff --git a/skills/prisma-8/upgrading/extension/upgrades/0.11-to-0.12/regenerate-extension-public-baseline.ts b/skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.11-to-0.12/regenerate-extension-public-baseline.ts similarity index 100% rename from skills/prisma-8/upgrading/extension/upgrades/0.11-to-0.12/regenerate-extension-public-baseline.ts rename to skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.11-to-0.12/regenerate-extension-public-baseline.ts diff --git a/skills/prisma-8/upgrading/extension/upgrades/0.11-to-0.12/strip-migration-labels-hints.ts b/skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.11-to-0.12/strip-migration-labels-hints.ts similarity index 100% rename from skills/prisma-8/upgrading/extension/upgrades/0.11-to-0.12/strip-migration-labels-hints.ts rename to skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.11-to-0.12/strip-migration-labels-hints.ts diff --git a/skills/prisma-8/upgrading/extension/upgrades/0.12-to-0.13/instructions.md b/skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.12-to-0.13/instructions.md similarity index 100% rename from skills/prisma-8/upgrading/extension/upgrades/0.12-to-0.13/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.12-to-0.13/instructions.md diff --git a/skills/prisma-8/upgrading/extension/upgrades/0.13-to-0.14/instructions.md b/skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.13-to-0.14/instructions.md similarity index 99% rename from skills/prisma-8/upgrading/extension/upgrades/0.13-to-0.14/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.13-to-0.14/instructions.md index 2bfa011761e0..79d75e903eff 100644 --- a/skills/prisma-8/upgrading/extension/upgrades/0.13-to-0.14/instructions.md +++ b/skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.13-to-0.14/instructions.md @@ -320,7 +320,7 @@ override get operations() { The colocated script applies this transformation automatically. Run it from your extension root: ```bash -pnpm exec tsx .claude/skills/prisma-8/upgrading/extension/upgrades/0.13-to-0.14/migration-op-factories-to-methods.ts +pnpm exec tsx .claude/skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.13-to-0.14/migration-op-factories-to-methods.ts ``` ## `create-runtime-removed` diff --git a/skills/prisma-8/upgrading/extension/upgrades/0.13-to-0.14/migration-op-factories-to-methods.ts b/skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.13-to-0.14/migration-op-factories-to-methods.ts similarity index 100% rename from skills/prisma-8/upgrading/extension/upgrades/0.13-to-0.14/migration-op-factories-to-methods.ts rename to skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.13-to-0.14/migration-op-factories-to-methods.ts diff --git a/skills/prisma-8/upgrading/extension/upgrades/0.13-to-0.14/uuid-preset-rename.ts b/skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.13-to-0.14/uuid-preset-rename.ts similarity index 100% rename from skills/prisma-8/upgrading/extension/upgrades/0.13-to-0.14/uuid-preset-rename.ts rename to skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.13-to-0.14/uuid-preset-rename.ts diff --git a/skills/prisma-8/upgrading/extension/upgrades/0.14-to-0.15/instructions.md b/skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.14-to-0.15/instructions.md similarity index 100% rename from skills/prisma-8/upgrading/extension/upgrades/0.14-to-0.15/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.14-to-0.15/instructions.md diff --git a/skills/prisma-8/upgrading/extension/upgrades/0.15-to-0.16/instructions.md b/skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.15-to-0.16/instructions.md similarity index 100% rename from skills/prisma-8/upgrading/extension/upgrades/0.15-to-0.16/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.15-to-0.16/instructions.md diff --git a/skills/prisma-8/upgrading/extension/upgrades/0.16-to-0.17/instructions.md b/skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.16-to-0.17/instructions.md similarity index 100% rename from skills/prisma-8/upgrading/extension/upgrades/0.16-to-0.17/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.16-to-0.17/instructions.md diff --git a/skills/prisma-8/upgrading/extension/upgrades/0.16-to-0.17/strip-sha256-hash-prefixes.ts b/skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.16-to-0.17/strip-sha256-hash-prefixes.ts similarity index 100% rename from skills/prisma-8/upgrading/extension/upgrades/0.16-to-0.17/strip-sha256-hash-prefixes.ts rename to skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.16-to-0.17/strip-sha256-hash-prefixes.ts diff --git a/skills/prisma-8/upgrading/extension/upgrades/0.17-to-8.0.0-rc.1/instructions.md b/skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.17-to-8.0.0-rc.1/instructions.md similarity index 100% rename from skills/prisma-8/upgrading/extension/upgrades/0.17-to-8.0.0-rc.1/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.17-to-8.0.0-rc.1/instructions.md diff --git a/skills/prisma-8/upgrading/extension/upgrades/0.7-to-0.8/instructions.md b/skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.7-to-0.8/instructions.md similarity index 100% rename from skills/prisma-8/upgrading/extension/upgrades/0.7-to-0.8/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.7-to-0.8/instructions.md diff --git a/skills/prisma-8/upgrading/extension/upgrades/0.8-to-0.9/instructions.md b/skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.8-to-0.9/instructions.md similarity index 100% rename from skills/prisma-8/upgrading/extension/upgrades/0.8-to-0.9/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.8-to-0.9/instructions.md diff --git a/skills/prisma-8/upgrading/extension/upgrades/0.8-to-0.9/strip-inline-contracts.ts b/skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.8-to-0.9/strip-inline-contracts.ts similarity index 100% rename from skills/prisma-8/upgrading/extension/upgrades/0.8-to-0.9/strip-inline-contracts.ts rename to skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.8-to-0.9/strip-inline-contracts.ts diff --git a/skills/prisma-8/upgrading/extension/upgrades/0.9-to-0.10/instructions.md b/skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.9-to-0.10/instructions.md similarity index 100% rename from skills/prisma-8/upgrading/extension/upgrades/0.9-to-0.10/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.9-to-0.10/instructions.md diff --git a/skills/prisma-8/upgrading/extension/upgrades/0.9-to-0.10/stamp-storage-types-kind.ts b/skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.9-to-0.10/stamp-storage-types-kind.ts similarity index 100% rename from skills/prisma-8/upgrading/extension/upgrades/0.9-to-0.10/stamp-storage-types-kind.ts rename to skills/prisma-orm-core-concepts/upgrading/extension/upgrades/0.9-to-0.10/stamp-storage-types-kind.ts diff --git a/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.1-to-8.0.0-rc.2/instructions.md b/skills/prisma-orm-core-concepts/upgrading/extension/upgrades/8.0.0-rc.1-to-8.0.0-rc.2/instructions.md similarity index 100% rename from skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.1-to-8.0.0-rc.2/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/extension/upgrades/8.0.0-rc.1-to-8.0.0-rc.2/instructions.md diff --git a/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.2-to-8.0.0-rc.3/instructions.md b/skills/prisma-orm-core-concepts/upgrading/extension/upgrades/8.0.0-rc.2-to-8.0.0-rc.3/instructions.md similarity index 100% rename from skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.2-to-8.0.0-rc.3/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/extension/upgrades/8.0.0-rc.2-to-8.0.0-rc.3/instructions.md diff --git a/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.3-to-8.0.0-rc.4/instructions.md b/skills/prisma-orm-core-concepts/upgrading/extension/upgrades/8.0.0-rc.3-to-8.0.0-rc.4/instructions.md similarity index 100% rename from skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.3-to-8.0.0-rc.4/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/extension/upgrades/8.0.0-rc.3-to-8.0.0-rc.4/instructions.md diff --git a/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.4-to-8.0.0-rc.5/instructions.md b/skills/prisma-orm-core-concepts/upgrading/extension/upgrades/8.0.0-rc.4-to-8.0.0-rc.5/instructions.md similarity index 100% rename from skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.4-to-8.0.0-rc.5/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/extension/upgrades/8.0.0-rc.4-to-8.0.0-rc.5/instructions.md diff --git a/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.5-to-8.0.0-rc.6/instructions.md b/skills/prisma-orm-core-concepts/upgrading/extension/upgrades/8.0.0-rc.5-to-8.0.0-rc.6/instructions.md similarity index 100% rename from skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.5-to-8.0.0-rc.6/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/extension/upgrades/8.0.0-rc.5-to-8.0.0-rc.6/instructions.md diff --git a/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.6-to-8.0.0-rc.7/instructions.md b/skills/prisma-orm-core-concepts/upgrading/extension/upgrades/8.0.0-rc.6-to-8.0.0-rc.7/instructions.md similarity index 100% rename from skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.6-to-8.0.0-rc.7/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/extension/upgrades/8.0.0-rc.6-to-8.0.0-rc.7/instructions.md diff --git a/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.7-to-8.0.0-rc.8/instructions.md b/skills/prisma-orm-core-concepts/upgrading/extension/upgrades/8.0.0-rc.7-to-8.0.0-rc.8/instructions.md similarity index 100% rename from skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.7-to-8.0.0-rc.8/instructions.md rename to skills/prisma-orm-core-concepts/upgrading/extension/upgrades/8.0.0-rc.7-to-8.0.0-rc.8/instructions.md diff --git a/skills/prisma-orm-migrations/SKILL.md b/skills/prisma-orm-migrations/SKILL.md new file mode 100644 index 000000000000..02761090c5f8 --- /dev/null +++ b/skills/prisma-orm-migrations/SKILL.md @@ -0,0 +1,64 @@ +--- +name: prisma-orm-migrations +description: >- + Use when creating, planning, reviewing, or applying database migrations in a + Prisma 8 (Prisma Next) project — "apply my contract change", "plan a + migration", "what runs on deploy", data backfills, editing migration.ts, + migration refs, drift recovery — or when the user mentions db update, + migration plan, db migrate, migration ref, dataTransform, placeholder, + migration graph, baseline, `from: (baseline)`, diamond convergence / + concurrent migrations, migration status, or a MIGRATION.* / PN-MIG-* / + PN-RUN-300x code. Does not apply to Prisma ORM 7 or earlier + (schema.prisma + @prisma/client projects). +metadata: + library: '@prisma/orm-postgres' + library_version: '8.0.0-rc.8' +--- + +# Prisma Next (Prisma 8) — Migrations + +> **Edit your data contract. Prisma handles the rest.** + +Prisma 8 moves fast, and your training data about it is very likely outdated. This skill ships inside the installed Prisma packages, so it describes the exact version this project has — treat it and its reference files as the source of truth, over anything you remember about Prisma. If `metadata.library_version` in this file's frontmatter does not match the project's installed Prisma packages, run `prisma skills sync` and re-read. + +This skill routes every migration task to the right reference file — open the reference before writing code; do not answer from this file alone. + +## The canonical model (one paragraph) + +Migrations are planned from a **contract diff**, not written by hand. You edit the data contract; `migration plan` diffs it against a resolved origin and writes a migration package (`migration.json`, `ops.json`, and a framework-rendered `migration.ts`); you review it, fill any data-transform `placeholder(...)` holes in `migration.ts`, self-emit, and apply with `db migrate`. The on-disk packages form a **graph** — nodes are contract hashes, edges are migrations — and a live database's position in it is recorded by its **marker**, offline by **refs**. + +## One cross-cutting fact — plan origin + +`migration plan` does **not** chain from the newest migration on disk. Its origin is `--from`, else the `db` ref, else an empty database — so a project with no ref keeps planning from scratch. Over existing migrations the CLI refuses that (`MIGRATION.PLAN_ORIGIN_UNKNOWN`) instead of writing a full-create package; choose the exit that matches your intent rather than reflexively passing `--from @empty`. [`references/migration-model.md`](references/migration-model.md) § *The trap* explains which to choose. + +## Routing table + +Open the reference whose triggers match the task. If more than one matches, open each — they are written to compose. + +| Task | Reference | Triggers | +| --- | --- | --- | +| Author migrations | [`references/migrations.md`](references/migrations.md) | `db update` vs `migration plan`, `db migrate`, `migration new`, `migration show`, `db update --dry-run`, `db verify`, `db sign`, data migration, `dataTransform`, placeholder sentinels in framework-rendered `migration.ts`, `MIGRATION.HASH_MISMATCH`, PN-MIG-2001 unfilled placeholder, schema drift | +| Migration graph, refs, plan origin | [`references/migration-model.md`](references/migration-model.md) | migration graph, refs, `migration ref set` / `list` / `delete`, the `db` ref, `--advance-ref`, `migration plan --from`, `from: (baseline)` in plan output, greenfield / from-scratch plan, baseline, first migration before deploy (Composer / CD-managed databases), chaining migrations, retrofitting migrations onto an existing database, `MIGRATION.HASH_NOT_IN_GRAPH`, `MIGRATION.PATH_UNREACHABLE` at plan/chain time | +| Review migrations on deploy | [`references/migration-review.md`](references/migration-review.md) | "what migrations are going to run", "what runs on deploy / merge", merge conflict, diamond convergence, concurrent migrations, migration status, ref management for CI, staging / production environment refs, `MIGRATION.DIVERGED`, `MIGRATION.NO_MARKER`, `MIGRATION.MARKER_NOT_IN_HISTORY`, `db migrate status`, `db migrate diff`, `db migrate resolve` | + +## Routing rules + +If the task clearly matches a row, open that reference directly without asking. + +For a vague prompt, ask **one** disambiguating question: + +- *"Is this about authoring a migration, or about reviewing what's going to run on deploy?"* → [`references/migrations.md`](references/migrations.md) vs [`references/migration-review.md`](references/migration-review.md). +- If it's about where a plan starts, refs, or an unexpected from-scratch plan → [`references/migration-model.md`](references/migration-model.md). + +If you still can't tell which reference applies, ask the user what they want to do. Do not guess. + +## Related skills + +The Prisma Next skills install as a set; everything outside migrations — editing the data contract, queries, runtime wiring, build integration, upgrades, error-envelope diagnosis, orientation questions, filing feedback — is owned by the sibling `prisma-orm-core-concepts` skill. + +## Checklist + +- [ ] If the task matches a routing-table row, open that reference before writing code. +- [ ] If the prompt is vague, ask one disambiguating question. +- [ ] Do not attempt to answer from this file alone — the references carry the verified tool surface. +- [ ] If the task is contract editing, queries, or feedback, route to `prisma-orm-core-concepts` instead. diff --git a/skills/prisma-8/references/migration-model.md b/skills/prisma-orm-migrations/references/migration-model.md similarity index 98% rename from skills/prisma-8/references/migration-model.md rename to skills/prisma-orm-migrations/references/migration-model.md index 208aeafe44c0..6c89eed586a2 100644 --- a/skills/prisma-8/references/migration-model.md +++ b/skills/prisma-orm-migrations/references/migration-model.md @@ -17,7 +17,7 @@ This reference teaches the model behind migration planning: what the migration g - Filling placeholders, applying migrations, hash mismatches, drift recovery → `references/migrations.md`. - What runs on deploy, environment refs in CI, concurrent-migration conflicts → `references/migration-review.md`. -- First-time adoption of an existing database (`contract infer` + `db sign` mechanics) → `references/quickstart.md` § *Brownfield-DB*. +- First-time adoption of an existing database (`contract infer` + `db sign` mechanics) → `prisma-orm-core-concepts/references/quickstart.md` § *Brownfield-DB*. ## Key Concepts @@ -125,7 +125,7 @@ If you skip the chaining, the next default plan resolves to greenfield: the trap ## Workflow — adopt a pre-existing database -The concept: a database that predates Prisma Next enters the system by describing it, not migrating it — `contract infer` derives the contract from the live schema, and after review + `contract emit`, `db sign` records the marker. Full recipe: `references/quickstart.md` § *Brownfield-DB*. +The concept: a database that predates Prisma Next enters the system by describing it, not migrating it — `contract infer` derives the contract from the live schema, and after review + `contract emit`, `db sign` records the marker. Full recipe: `prisma-orm-core-concepts/references/quickstart.md` § *Brownfield-DB*. ```bash pnpm prisma contract infer --db "$DATABASE_URL" --output src/prisma/contract.prisma @@ -161,7 +161,7 @@ The concept: the database exists and its marker is accurate (hash **M**) — it ## What Prisma Next doesn't do yet -- **No plan-time ref advancement.** `migration plan` cannot advance a ref for you; keeping the chain current is manual (`migration ref set` after each plan, or `--from` every time). If you want a plan-time advancement flag, file a feature request via the `references/feedback.md` skill. +- **No plan-time ref advancement.** `migration plan` cannot advance a ref for you; keeping the chain current is manual (`migration ref set` after each plan, or `--from` every time). If you want a plan-time advancement flag, file a feature request via the `prisma-orm-core-concepts/references/feedback.md` skill. ## Checklist diff --git a/skills/prisma-8/references/migration-review.md b/skills/prisma-orm-migrations/references/migration-review.md similarity index 96% rename from skills/prisma-8/references/migration-review.md rename to skills/prisma-orm-migrations/references/migration-review.md index 60378e2fce47..e7e5943b3027 100644 --- a/skills/prisma-8/references/migration-review.md +++ b/skills/prisma-orm-migrations/references/migration-review.md @@ -18,8 +18,8 @@ The skill teaches *the system's mental model* — what a ref is, what a marker i ## When Not to Use - User wants to *author* a migration → `references/migrations.md`. -- User wants to fix a hash-mismatch / drift in a single env → `references/migrations.md` (re-plan path) or `references/debug.md` (envelope-driven). -- User wants to edit the contract → `references/contract.md`. +- User wants to fix a hash-mismatch / drift in a single env → `references/migrations.md` (re-plan path) or `prisma-orm-core-concepts/references/failure-modes.md` (envelope-driven). +- User wants to edit the contract → `prisma-orm-core-concepts/references/contract.md`. ## Key Concepts — the navigation model @@ -78,7 +78,7 @@ Both flags are also available on `migration list` and `migration graph`. `migrat ### Plan- and apply-time diagnostics -These codes surface on `migration plan`, `migration ref set`, and `db migrate` — not on `migration status`. See [Migration System § Recovery affordances](../../docs/architecture%20docs/subsystems/7.%20Migration%20System.md#recovery-affordances) and [ADR 218](../../docs/architecture%20docs/adrs/ADR%20218%20-%20Refs%20with%20paired%20contract%20snapshots%20and%20universal%20graph-node%20invariant.md). +These codes surface on `migration plan`, `migration ref set`, and `db migrate` — not on `migration status`. See [Migration System § Recovery affordances](../../../docs/architecture%20docs/subsystems/7.%20Migration%20System.md#recovery-affordances) and [ADR 218](../../../docs/architecture%20docs/adrs/ADR%20218%20-%20Refs%20with%20paired%20contract%20snapshots%20and%20universal%20graph-node%20invariant.md). | Code | When | Meaning | Next move | |---|---|---|---| @@ -206,8 +206,8 @@ For a human-readable ordered preview of the migration path before applying, use ## What Prisma Next doesn't do yet -- **Per-environment migration ordering beyond the default chain.** If you need staging to skip a migration that production requires (or vice versa), the supported path is to author the per-env divergence as separate migrations and gate them in your deploy script. If you want first-class per-env routing, file a feature request via the `references/feedback.md` skill. -- **A built-in side-by-side "branch diff" view.** There is a full-graph render (`migration graph`) that shows branches, but no `git diff`-style comparison between two branches' migration sets. Workaround: run `migration status` on each branch and `diff` the output. If you want a built-in branch-comparison view, file a feature request via the `references/feedback.md` skill. +- **Per-environment migration ordering beyond the default chain.** If you need staging to skip a migration that production requires (or vice versa), the supported path is to author the per-env divergence as separate migrations and gate them in your deploy script. If you want first-class per-env routing, file a feature request via the `prisma-orm-core-concepts/references/feedback.md` skill. +- **A built-in side-by-side "branch diff" view.** There is a full-graph render (`migration graph`) that shows branches, but no `git diff`-style comparison between two branches' migration sets. Workaround: run `migration status` on each branch and `diff` the output. If you want a built-in branch-comparison view, file a feature request via the `prisma-orm-core-concepts/references/feedback.md` skill. ## Reference Files diff --git a/skills/prisma-8/references/migrations.md b/skills/prisma-orm-migrations/references/migrations.md similarity index 94% rename from skills/prisma-8/references/migrations.md rename to skills/prisma-orm-migrations/references/migrations.md index d21a1cb69a37..72cc41d0e1ae 100644 --- a/skills/prisma-8/references/migrations.md +++ b/skills/prisma-orm-migrations/references/migrations.md @@ -5,7 +5,7 @@ The three-step user model: -1. **You edit your data contract.** (`references/contract.md`) +1. **You edit your data contract.** (`prisma-orm-core-concepts/references/contract.md`) 2. **Prisma Next plans the migration for you.** ← this skill 3. **If a data transform is needed, you edit `migration.ts` and self-emit.** ← this skill @@ -25,8 +25,8 @@ Once the contract changes, you choose how the change reaches the database. This - User wants to know what migrations *will run on deploy* / on merge, or to manage refs and invariants → `references/migration-review.md`. - User is deciding where a plan should chain from, saw `from: (baseline)` unexpectedly, is setting up migrations for a deploy-first (Composer / CD-managed) project, or is retrofitting migrations onto an existing database → `references/migration-model.md`. -- User wants to edit the contract → `references/contract.md`. -- User wants a deeper read of a single structured error envelope → `references/debug.md`. +- User wants to edit the contract → `prisma-orm-core-concepts/references/contract.md`. +- User wants a deeper read of a single structured error envelope → `prisma-orm-core-concepts/references/failure-modes.md`. ## Key Concepts @@ -139,7 +139,7 @@ If the `db` ref's pointer is itself missing and the hash isn't a graph node eith `db` is a **default ref name**, not a reserved one. The framework overwrites it on the next dev cycle; you may `migration ref set db ` explicitly and accept that a subsequent `db update` replaces it when run against the default URL. -Canonical detail: [Migration System § Contract resolution through the snapshot store](../../docs/architecture%20docs/subsystems/7.%20Migration%20System.md#contract-resolution-through-the-snapshot-store), [§ `migration plan`](../../docs/architecture%20docs/subsystems/7.%20Migration%20System.md#migration-plan), [§ Recovery affordances](../../docs/architecture%20docs/subsystems/7.%20Migration%20System.md#recovery-affordances), [ADR 218 — Refs with paired contract snapshots and universal graph-node invariant](../../docs/architecture%20docs/adrs/ADR%20218%20-%20Refs%20with%20paired%20contract%20snapshots%20and%20universal%20graph-node%20invariant.md) (TML-2629, its paired-snapshot part superseded — see the ADR's Status note), and [ADR 240 — Contract snapshots live in a content-addressed store](../../docs/architecture%20docs/adrs/ADR%20240%20-%20Contract%20snapshots%20live%20in%20a%20content-addressed%20store.md). +Canonical detail: [Migration System § Contract resolution through the snapshot store](../../../docs/architecture%20docs/subsystems/7.%20Migration%20System.md#contract-resolution-through-the-snapshot-store), [§ `migration plan`](../../../docs/architecture%20docs/subsystems/7.%20Migration%20System.md#migration-plan), [§ Recovery affordances](../../../docs/architecture%20docs/subsystems/7.%20Migration%20System.md#recovery-affordances), [ADR 218 — Refs with paired contract snapshots and universal graph-node invariant](../../../docs/architecture%20docs/adrs/ADR%20218%20-%20Refs%20with%20paired%20contract%20snapshots%20and%20universal%20graph-node%20invariant.md) (TML-2629, its paired-snapshot part superseded — see the ADR's Status note), and [ADR 240 — Contract snapshots live in a content-addressed store](../../../docs/architecture%20docs/adrs/ADR%20240%20-%20Contract%20snapshots%20live%20in%20a%20content-addressed%20store.md). ## Workflow — `db update` (quick path) @@ -247,7 +247,7 @@ MigrationCLI.run(import.meta.url, M); Replace both `placeholder(...)` calls with query-plan closures built from `endContract`. The `check` closure must return a **rowset query whose presence of any row signals "work remains"** — conventionally `
.select('id').where().limit(1)`. Scalar/aggregate shapes (`count(*)`, `bool_and(...)`) silently break the contract: the runner wraps `check` twice (`EXISTS(...)` for precheck, `NOT EXISTS(...)` for postcheck), and a query that always returns one row makes `EXISTS` always true and `NOT EXISTS` always false. -Build the query builder against `endContract` so the storage hashes line up — using a different contract reference raises `PN-MIG-2005`. The filled-in shape (the rendered scaffold above with `placeholder(...)` calls replaced; if you need an extra factory like `setNotNull`, add it to the *existing* `@internal/postgres/migration` import line rather than authoring a second import). See `references/queries.md` for the surrounding `db` setup: +Build the query builder against `endContract` so the storage hashes line up — using a different contract reference raises `PN-MIG-2005`. The filled-in shape (the rendered scaffold above with `placeholder(...)` calls replaced; if you need an extra factory like `setNotNull`, add it to the *existing* `@internal/postgres/migration` import line rather than authoring a second import). See `prisma-orm-core-concepts/references/queries.md` for the surrounding `db` setup: ```typescript import endContract from '../../snapshots/93f07d1b…c9e1e5a2/contract.json' with { type: 'json' }; @@ -408,7 +408,7 @@ pnpm prisma db sign --db $DATABASE_URL The concept: drift means `db verify` reports the live DB schema doesn't match what the marker says it should be. Two valid moves, picked by which side is correct: - **The contract is right; the DB is wrong** → run a migration. Either `db update` (quick path, dev DB only) or `migration plan` + `db migrate` (everywhere else). -- **The DB is right; the contract or marker is wrong** → edit the contract to match the DB (see `references/contract.md`), emit, then `db sign` to refresh the marker. +- **The DB is right; the contract or marker is wrong** → edit the contract to match the DB (see `prisma-orm-core-concepts/references/contract.md`), emit, then `db sign` to refresh the marker. The diagnostic that reveals which side is right: @@ -478,16 +478,16 @@ In non-interactive contexts (CI, `--no-interactive`, `--json`), the destructive- 5. **Routine `db verify` after a successful `db update` or `db migrate`.** Redundant on the happy path — reserve `db verify` for drift diagnosis (manual edits, restore, failed `db migrate`). 6. **Aggregate `check` closure in Postgres `this.dataTransform`.** Returning `count(*)` or `bool_and(...)` breaks the precheck/postcheck contract — both sides resolve to constants. Use a rowset shape: `select('id').where().limit(1)`. 7. **Two contract references in one migration.** Building a query plan against a different contract than the one passed to `this.dataTransform(endContract, ...)` raises `PN-MIG-2005`. Always import `endContract` once at module scope and use the same reference. -8. **Renaming and expecting the planner to detect it (Postgres).** Prisma Next has no in-contract rename hint today; the planner emits a destructive drop+add. Hand-edit `migration.ts` to rewrite the destructive op as a `rawSql({ ... })` that issues `ALTER TABLE ... RENAME COLUMN ...` (or use the two-migration keep / backfill / drop pattern), then self-emit. See `references/contract.md` § *Edit a field — rename*. +8. **Renaming and expecting the planner to detect it (Postgres).** Prisma Next has no in-contract rename hint today; the planner emits a destructive drop+add. Hand-edit `migration.ts` to rewrite the destructive op as a `rawSql({ ... })` that issues `ALTER TABLE ... RENAME COLUMN ...` (or use the two-migration keep / backfill / drop pattern), then self-emit. See `prisma-orm-core-concepts/references/contract.md` § *Edit a field — rename*. 9. **Planning with no `db` ref and no `--from` in a project that already has migrations.** The origin falls through to the empty database, which would make the plan a full-create migration; `migration plan` refuses with `MIGRATION.PLAN_ORIGIN_UNKNOWN` rather than writing it. Pick the exit that matches your intent — the error lists them, and `references/migration-model.md` § *The trap* explains which to choose. 10. **Hand-authoring `migration.ts` from a blank file, or rewriting the rendered import line.** Migration files are framework-rendered — let `prisma migration plan` (or `migration new`) render the package, then edit only the holes the framework leaves for you. On Postgres leave the rendered `@internal/postgres/migration` (or `@internal/sqlite/migration`) import path alone; on Mongo use `@internal/family-mongo/migration` + `@internal/target-mongo/migration` as rendered. Add symbols to the existing factory import line rather than introducing new import paths. ## What Prisma Next doesn't do yet -- **Runtime-apply migrations.** Prisma Next doesn't apply pending migrations from your app's startup code (the "Drizzle pattern" for serverless / edge). Workaround: run `prisma db migrate` from your deploy pipeline before the app starts. If you need runtime-apply built-in, file a feature request via the `references/feedback.md` skill. -- **Seeds-as-first-class.** Prisma Next doesn't ship a `prisma db seed` equivalent. Workaround: write a TypeScript script that imports your `db` instance and runs your setup queries; invoke it from `package.json`'s scripts. If you need first-class seeding, file a feature request via the `references/feedback.md` skill. -- **Migration squashing.** Prisma Next doesn't squash older migrations into a baseline. They accumulate; for very large histories, manual baseline-and-truncate is the path. If you need built-in squashing, file a feature request via the `references/feedback.md` skill. -- **In-contract rename hints.** The planner cannot detect that a field rename is a rename rather than a drop+add. Workaround: hand-edit `migration.ts` to issue a `RENAME COLUMN` via `rawSql(...)`, or use a keep / backfill / drop pattern across two migrations. If you need a contract-level rename hint, file a feature request via the `references/feedback.md` skill. +- **Runtime-apply migrations.** Prisma Next doesn't apply pending migrations from your app's startup code (the "Drizzle pattern" for serverless / edge). Workaround: run `prisma db migrate` from your deploy pipeline before the app starts. If you need runtime-apply built-in, file a feature request via the `prisma-orm-core-concepts/references/feedback.md` skill. +- **Seeds-as-first-class.** Prisma Next doesn't ship a `prisma db seed` equivalent. Workaround: write a TypeScript script that imports your `db` instance and runs your setup queries; invoke it from `package.json`'s scripts. If you need first-class seeding, file a feature request via the `prisma-orm-core-concepts/references/feedback.md` skill. +- **Migration squashing.** Prisma Next doesn't squash older migrations into a baseline. They accumulate; for very large histories, manual baseline-and-truncate is the path. If you need built-in squashing, file a feature request via the `prisma-orm-core-concepts/references/feedback.md` skill. +- **In-contract rename hints.** The planner cannot detect that a field rename is a rename rather than a drop+add. Workaround: hand-edit `migration.ts` to issue a `RENAME COLUMN` via `rawSql(...)`, or use a keep / backfill / drop pattern across two migrations. If you need a contract-level rename hint, file a feature request via the `prisma-orm-core-concepts/references/feedback.md` skill. ## Graph and history commands @@ -500,11 +500,11 @@ For the full graph topology: `pnpm prisma migration graph` (also supports `--leg ## `@@control` and DDL scope -Objects whose `@@control` policy excludes them from Prisma Next's managed surface are omitted from planned DDL. The four policies are: `managed` (Prisma plans and applies DDL), `tolerated` (object may exist, no DDL emitted), `external` (object is expected to exist, no DDL), `observed` (Prisma reads but never writes). Declare `@@control(managed|tolerated|external|observed)` in your schema; see `references/contract.md` and [`packages/2-sql/2-authoring/contract-psl/README.md`](../../packages/2-sql/2-authoring/contract-psl/README.md) for authoring syntax. +Objects whose `@@control` policy excludes them from Prisma Next's managed surface are omitted from planned DDL. The four policies are: `managed` (Prisma plans and applies DDL), `tolerated` (object may exist, no DDL emitted), `external` (object is expected to exist, no DDL), `observed` (Prisma reads but never writes). Declare `@@control(managed|tolerated|external|observed)` in your schema; see `prisma-orm-core-concepts/references/contract.md` and [`packages/2-sql/2-authoring/contract-psl/README.md`](../../../packages/2-sql/2-authoring/contract-psl/README.md) for authoring syntax. ## Telemetry -The CLI collects anonymous usage data by default. To opt out, set `PRISMA_NEXT_DISABLE_TELEMETRY=1` or `DO_NOT_TRACK=1` in your environment. See [`docs/Telemetry.md`](../../docs/Telemetry.md) for the full opt-out reference. +The CLI collects anonymous usage data by default. To opt out, set `PRISMA_NEXT_DISABLE_TELEMETRY=1` or `DO_NOT_TRACK=1` in your environment. See [`docs/Telemetry.md`](../../../docs/Telemetry.md) for the full opt-out reference. ## Checklist diff --git a/test/integration/test/cli.init-skill-distribution.integration.test.ts b/test/integration/test/cli.init-skill-distribution.integration.test.ts index 21a01a0f42bd..aa1c2bdc6abe 100644 --- a/test/integration/test/cli.init-skill-distribution.integration.test.ts +++ b/test/integration/test/cli.init-skill-distribution.integration.test.ts @@ -104,16 +104,20 @@ describe('init skill distribution (offline integration, real CLI)', () => { testDirs.add(testDir); expect(manifestOf(testDir).scripts?.['postinstall']).toBeUndefined(); - expect(gitignoreOf(testDir)).not.toContain('skills/prisma-8/'); + expect(gitignoreOf(testDir)).not.toContain('skills/prisma-'); }); - it('removes skill directories the router replaced', { timeout: 60_000 }, async () => { + it('removes retired skill directories', { timeout: 60_000 }, async () => { const testDir = createIntegrationTestDir(); testDirs.add(testDir); writeFileSync(join(testDir, 'pnpm-lock.yaml'), '', 'utf8'); - const retired = join(testDir, '.agents', 'skills', 'prisma-next-upgrade'); - mkdirSync(retired, { recursive: true }); - writeFileSync(join(retired, 'SKILL.md'), '---\nname: prisma-next-upgrade\n---\n', 'utf8'); + const retiredNames = ['prisma-next-upgrade', 'prisma-8']; + const retiredDirs = retiredNames.map((name) => { + const dir = join(testDir, '.agents', 'skills', name); + mkdirSync(dir, { recursive: true }); + writeFileSync(join(dir, 'SKILL.md'), `---\nname: ${name}\n---\n`, 'utf8'); + return dir; + }); const { fakeBinDir, logPath } = createFakeManagerHarness(testDir); const { exitCode, stderr } = runEngineInit(testDir, { @@ -122,7 +126,9 @@ describe('init skill distribution (offline integration, real CLI)', () => { }); expect(exitCode, stderr).toBe(0); - expect(existsSync(retired)).toBe(false); + for (const dir of retiredDirs) { + expect(existsSync(dir)).toBe(false); + } }); }); From a3af533e10d0d3ea25d262d7f3d9caebd17322d5 Mon Sep 17 00:00:00 2001 From: Tyler Hogarth <5163494+tylerhogarth@users.noreply.github.com> Date: Thu, 27 Aug 2026 13:20:26 +0200 Subject: [PATCH 2/9] Journey 07 metadata lists runtime and build; DEVELOPING counts two SKILL.md files Journey 07 routes to prisma-orm-core-concepts (runtime) and (build) in its checklist, so the README row and the journey Skills-under-test line now list them. DEVELOPING.md said "three SKILL.md files" from the pre-split plan; the PR ships two. Co-Authored-By: Claude Fable 5 Signed-off-by: Tyler Hogarth <5163494+tylerhogarth@users.noreply.github.com> --- skills/DEVELOPING.md | 2 +- skills/journey-tests/07-first-touch-orientation.md | 2 +- skills/journey-tests/README.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/skills/DEVELOPING.md b/skills/DEVELOPING.md index fe9e82c53ecf..b4901663f7b3 100644 --- a/skills/DEVELOPING.md +++ b/skills/DEVELOPING.md @@ -135,7 +135,7 @@ Commit `bf742221c` (`examples: migrate to @internal/ façade imports`) d These are well-trodden but worth listing in one place: -- **`description:` frontmatter is a runtime matcher, not marketing prose.** Only the three `SKILL.md` files carry frontmatter; each description fires on its skill's territory. Per-workflow trigger phrases — CLI flags, error codes, feature names, foreign-tool vocabulary a user would type — live in the owning skill's routing table's *Triggers* column, and a new reference file must add its row there. +- **`description:` frontmatter is a runtime matcher, not marketing prose.** Only the two `SKILL.md` files carry frontmatter; each description fires on its skill's territory. Per-workflow trigger phrases — CLI flags, error codes, feature names, foreign-tool vocabulary a user would type — live in the owning skill's routing table's *Triggers* column, and a new reference file must add its row there. - **One workflow per reference file.** File size is bounded by the per-file line ceiling. If a workflow grows past it, split into a companion reference (the queries → queries-postgres/queries-mongo split is the template) — don't sprawl. - **Provide a default, not a menu.** When more than one tool or approach would work (PSL vs. the TS builder, `db update` vs. `migration plan`, which query lane for a given target), commit to the one that's the recommended path for the common case and state it first. Mention the alternative briefly, as an escape hatch with the condition under which it applies — don't present both as equally-weighted options and leave the choice to the agent. An agent handed a menu without a default either guesses or asks; a stated default lets it proceed. - **Omit what the agent already knows.** Every sentence should teach something the agent wouldn't get right without it: a Prisma Next-specific convention, a non-obvious constraint, the actual verified tool surface. Don't explain what a foreign-key constraint is, what a connection pool does, or other general engineering or database knowledge the agent already has — that's editorial padding that pushes genuinely load-bearing content further from the top of the file and erodes the length budgets above. When rewriting or extending a reference file, apply the test explicitly: *would the agent get this wrong without this sentence?* If no, cut it. diff --git a/skills/journey-tests/07-first-touch-orientation.md b/skills/journey-tests/07-first-touch-orientation.md index 9b5e9a238f33..4ccddd64274f 100644 --- a/skills/journey-tests/07-first-touch-orientation.md +++ b/skills/journey-tests/07-first-touch-orientation.md @@ -1,6 +1,6 @@ # Journey 07 — First-touch orientation -**Skills under test:** `prisma-orm-core-concepts` (quickstart) (First-touch orientation path), with hand-offs to `prisma-orm-core-concepts` (queries) and optionally `prisma-orm-core-concepts` (contract). +**Skills under test:** `prisma-orm-core-concepts` (quickstart) (First-touch orientation path), with hand-offs to `prisma-orm-core-concepts` (queries) and optionally `prisma-orm-core-concepts` (contract, runtime, build). **Example app:** A Prisma Next project the user is encountering for the first time. Three flavours of this initial state should all pass: diff --git a/skills/journey-tests/README.md b/skills/journey-tests/README.md index 6454d6f6bfc6..4eaa97853a6e 100644 --- a/skills/journey-tests/README.md +++ b/skills/journey-tests/README.md @@ -51,4 +51,4 @@ The *Skill (references) under test* column names the installed skill and, in par | [`05b-build-nextjs-gap.md`](05b-build-nextjs-gap.md) | prisma-orm-core-concepts (build, feedback) | AC8b (Next.js path) | | [`06-feedback-bug.md`](06-feedback-bug.md) | prisma-orm-core-concepts (feedback) | AC8c (bug path) | | [`06b-feedback-feature.md`](06b-feedback-feature.md) | prisma-orm-core-concepts (contract, feedback) | AC8c (feature path) | -| [`07-first-touch-orientation.md`](07-first-touch-orientation.md) | prisma-orm-core-concepts (quickstart first-touch path, queries, contract) | AC4 (orientation entry point) | +| [`07-first-touch-orientation.md`](07-first-touch-orientation.md) | prisma-orm-core-concepts (quickstart first-touch path, queries, contract, runtime, build) | AC4 (orientation entry point) | From 9c7d6a476317e0ccd1341491861f44a3412535ff Mon Sep 17 00:00:00 2001 From: Tyler Hogarth <5163494+tylerhogarth@users.noreply.github.com> Date: Thu, 27 Aug 2026 13:20:41 +0200 Subject: [PATCH 3/9] Review: correct upgrade-instruction and versioning-doc details Addresses the doc-side CodeRabbit findings on the skill split: - versioning.md names the published @prisma/orm-postgres tarball in the lockstep example, not the private @internal/postgres. - upgrade-app.md runs the extension-compatibility pre-flight before the Step 0 version bump; the pre-flight only reads prisma.config.ts and installed package.json files, so it needs no bump. - Codemod invocations in 0.11-to-0.12, 0.12-to-0.13 and 0.16-to-0.17 instructions (app and extension) use the synced skill path instead of a bare ./