Skip to content

Commit 14c0ec8

Browse files
Agent skills install from the npm packages the project already has (#219)
In a project that has `@prisma/orm-postgres` installed, this now works — no network, no extra tooling: ```console $ prisma skills sync Synced 1 skill. project /work/my-app check enabled Skill Package Version Installed into prisma-8 @prisma/orm-postgres 8.1.0 .claude/skills, .cursor/skills, .agents/skills, .windsurf/skills ``` And after `pnpm up @prisma/orm-postgres` bumps the package but nobody re-runs sync, every `prisma` command appends one line to stderr: ```text Prisma agent skills are out of date (installed @prisma/orm-postgres 8.1.0, synced 8.0.0). Run: prisma skills sync ``` > **Base**: `main`, rebased onto #218's squash merge (`3a8f7d2`) on 2026-08-22; the branch carries only this PR's own commits. ## The decision Agent skills now travel **inside the npm packages they describe**, and this PR adds the CLI half of that: `prisma skills sync` copies them into place, `prisma skills list` reports status, `prisma init` sets a project up once, and a staleness notice after every command keeps the copies from silently rotting. An agent skill is a directory with a `SKILL.md` — instructions that teach a coding agent (Claude Code, Cursor, Codex, Windsurf) how to use a library. Each harness auto-indexes skills from a known project directory (`.claude/skills/`, `.cursor/skills/`, `.agents/skills/`, `.windsurf/skills/`); a skill anywhere else is invisible. So a skill is only useful if something copies it into those directories and keeps the copy matching the installed package version. Until now that something was `prisma orm init` shelling out to a third-party CLI that cloned our skills from GitHub at a ref *named after* the package version — a convention, not a guarantee — and nothing ever detected that the copies had gone stale. ## How sync decides what to install Sync resolves a **hardcoded allowlist** of four packages — `@prisma/orm-postgres`, `@prisma/orm-sqlite`, `@prisma/orm-mongo`, `@prisma/composer` — by name from the project root and each workspace member directory. It never scans `node_modules`: a skill is instructions an agent will follow, so a scanner would let any transitive dependency inject instructions into the agent. That invariant is stated (and marked permanent) at the allowlist declaration, and this PR's trust boundary is exactly the code's — the only skills installed come from packages the user deliberately installed. Each shipped `SKILL.md` carries a version stamp in its frontmatter, under the Agent Skills spec's `metadata` map (custom top-level keys are not spec-defined): ```yaml metadata: library: "@prisma/orm-postgres" library_version: "8.1.0" ``` Sync compares the installed package's version against the stamp in each harness copy and re-copies on mismatch. Pruning removes only copies whose stamp names an allowlisted package that is no longer installed — a skill some other tool put there is never touched. The synced copies are ordinary files git tracks; sync removes the `*` ignore file an earlier revision wrote into its copies, but leaves any `.gitignore` a user authored in place. If two workspace members pin different versions of one package, the highest wins and sync warns. Yarn PnP works because all reads go through Node's resolution and fs layers (there is a test that fakes the PnP zip filesystem to prove it). **Sync refuses what it does not own.** A target directory whose `SKILL.md` is unstamped, unreadable, or stamped by a non-allowlisted package — a hand-written skill colliding on name — is left byte-for-byte intact, reported in a `refused` array and a `SKILLS.UNMANAGED_DIRECTORY` diagnostic, and the summary line never claims "up to date" without naming it. A directory whose `SKILL.md` is genuinely absent (an interrupted copy) is repaired. ## `prisma init` `prisma init` initializes a repository for Prisma development, purely locally — no platform calls. Two steps, each with an opt-out (`--no-postinstall`, `--no-skills`), always exit 0, never prompts, idempotent: 1. Adds `"postinstall": "prisma skills sync || exit 0"` to the **current directory's** `package.json`, so skills resync on every install and upgrade. A different existing postinstall script is never clobbered or chained — init reports it and tells the user what to append. BOM, CRLF, indentation, and trailing-newline style are preserved; an unreadable, unwritable, or malformed manifest is a diagnostic, not a failure. 2. Runs the skills sync in-process at the discovered workspace root. A sync failure is a diagnostic on a successful init. This is a new command reusing a retired name: #218 deleted the old compute-config wizard, and nothing from it returns. Sync itself still never touches `package.json` (a test pins byte-identity across a sync run) — writing the hook is exclusively the act of a user running `init`. ## The `prisma agent` group is deleted `prisma agent install|update|status` — the old installer that shelled out to `npx skills@latest` for the v6/v7 skills — is gone (operator ruling, 2026-08-21). The post-login tip that advertised it now offers `prisma skills sync` instead, only when installed packages actually have stale copies, and can no longer fail a login that already succeeded. ## The staleness notice It prints to stderr, after the command's own output, never changes the exit code, and is deliberately **not** TTY-dependent — its main reader is an agent running the CLI without one. Off switches: `--quiet`, `--json` / `--format json`, `--version`, `PRISMA_SKILLS_CHECK=0`, `CI`/`GITHUB_ACTIONS`, `skills: { check: false }` in `prisma.config.ts` (an explicit `--config <path>` is honored), a persistent opt-out written by `prisma skills sync --disable` (stored in `.prisma/skills.json`), and any `skills` command itself. Flag scanning stops at a bare `--`. The per-command cost is stat calls and small file reads; `prisma.config.ts` is only evaluated after staleness is already established. With the init-written postinstall as the primary trigger, the notice is the backstop for projects that never ran `init` or removed the script. ## Pin and state dir find the project root `.prisma/local.json` (the link pin) and the state dir are now discovered by walking up from the cwd to the **nearest** directory containing `.prisma/` — a pure filesystem check, no config file is read — so a repo linked at its root works from `apps/api/`. Nearest wins deliberately: a subdirectory linked to a different project beats the root. Commands that rewrite or delete the pin operate on the file they found, not on the cwd. When no `.prisma/` exists, behavior is unchanged. ## The rename: `CLI_NAME` is now `prisma` The published package (`prisma`) has installed a bin named `prisma` since 8.0.0-rc.3, but every string the CLI printed still said `prisma-cli`. This PR moves `CLI_NAME`, so help text, error guidance, and the notice above all name the binary users actually have. There is no compatibility layer: the CLI is pre-rc and owes old spellings nothing, so every producer of error guidance was fixed to emit the current commands directly, and the display-time rewriter that used to patch up legacy spellings (`renameAppCopy` and friends) was deleted rather than extended. `fromLegacyCliError` survives only as a structural converter (legacy error shape → `CliError`); it no longer rewrites or filters any copy. Deliberate survivals, so nobody "finishes" the rename by mistake: the `@prisma/cli` package's own bin and README, the update-check entrypoint matcher and cache directory, `git@github.com:prisma/prisma-cli.git` repo URLs, and the `utm_source`/`utm_campaign` sign-in tags. ## Tests 90+ new tests: npm/pnpm/Yarn-PnP fixture projects, every sync/check state (stale, never-synced, in-sync, refused, opted out), the collision and unreadable-skill refusals (chmod-based), pruning on package removal, a two-member monorepo with the version-conflict warning, every off switch, init's full package.json edge-case matrix (foreign script, non-object `scripts`, BOM, CRLF, read-only file, missing manifest), a credential-free e2e driving the built binary through `init` twice, a `readdir`-count regression test bounding workspace-glob expansion, and the legacy-error mapper suite. ## For other owners - The feedback client's user-agent changed from `prisma-cli/<version>` to `prisma/<version>` — wire-visible; whoever reads that dashboard should know. - `isLikelyGlobalNpmEntrypoint` (update-check) still matches only `prisma-cli` install paths, so a globally installed `prisma` gets the docs-link fallback instead of a concrete update command. Pre-existing, untouched here, newly conspicuous. - The browser login success page still shows a static `npx skills add prisma/skills` copy button — the last surface promoting the retired installer; its removal is pending an operator decision. - prisma/prisma#30097 (`orm init`) drops its scaffold-time sync call per operator ruling — follow-up on that PR. **Merge order**: #218 is merged; this PR next, then prisma/prisma#30096 (packaging) → #30097, and prisma/composer#251's npm release — all ship skills only this CLI can read. ## Alternatives considered - **Keep fetching from GitHub via `npx skills add`** (status quo): version matched by ref-name convention only, unmanaged copies, network access during init, and an unpinned third-party CLI in our init path. - **Discover skills by scanning `node_modules`**: prompt-injection by construction — any transitive dependency could plant instructions. Permanently rejected. - **Symlinks into `node_modules` instead of copies**: no `node_modules` under Yarn PnP, symlink creation needs elevation on Windows, and only Claude Code documents following symlinked skills. Version-stamped, checked, auto-resynced copies are a managed cache. - **A line in `AGENTS.md` telling agents to run sync each session**: rejected by the team — agents shouldn't carry maintenance duties. - **A `postinstall` in our own packages**: dependency lifecycle scripts are blocked by default in pnpm 10+, bun, and Deno. Permanently rejected. - **Writing a `postinstall` from `prisma orm init` or from sync itself** (the original design): rejected — a routine command silently editing your `package.json`, or re-adding a script you removed, is not acceptable. The operator's final ruling: the hook is written only by `prisma init`, a command whose whole point the user invokes deliberately; nothing automatic ever edits the manifest, and the staleness notice covers everyone else. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
1 parent b02432d commit 14c0ec8

123 files changed

Lines changed: 6069 additions & 2098 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.drive/projects/prisma-cli-v8/deferred.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,3 +454,20 @@ The cleanup PR removed the compute config and `init`, made service commands para
454454
- ~~**orm-toolchain's shipped help examples name retired spellings.**~~ Closed (2026-08-22) by prisma#30102: the family keys are the mount paths and the examples follow; `tests/orm-mount.test.ts` now asserts upstream stays clean.
455455
- ~~**The deployment-id targeting asymmetry is undocumented.**~~ Closed on the PR branch (2026-08-21): every deployment-id command (`promote|start|stop|delete|show`, `logs --deployment`) now resolves the id globally with no service parameter, per the "Subjects are positional" ruling.
456456
- **`GET /v1/deployments/{id}` omits the parent `appId`.** Verified against `@prisma/management-api-sdk@1.55.0`: the response carries id/status/url/previewDomain/envVars/createdAt and no owning-app pointer, so `showDeployment` finds the owner via `findAppForDeployment` — a scan of every project's service list and each service's deployments — and every id-targeted command pays it per run. The fix is in pdp-control-plane: include `appId` in the deployment representation; the CLI then swaps the scan for one `GET /v1/apps/{appId}`.
457+
458+
## From the agent-skills delivery (project closed 2026-08-22)
459+
460+
- **Config evaluation fails through unrealpath'd pnpm symlinks; the verified fix waits for the next engine release.** The engine's lazy `await import("c12")` (packages/cli-engine/src/config-loader.ts) resolves through a pnpm symlink without realpathing, so c12's own `pathe` import walks up from the symlink path and misses its store siblings — `CLI.CONFIG_UNREADABLE: Cannot find package 'pathe'`. Affects this repo's dev layout and pnpm `hoist=false` installs only; npm and default-pnpm installs work. The fix is one line, verified empirically: import c12 via `pathToFileURL(realpathSync(fileURLToPath(import.meta.resolve("c12"))))`. It was implemented on PR #219 and reverted because any engine change forces a version bump and the families (`@prisma/orm-toolchain`, `@prisma/composer-cli`) peer-pin the engine exactly, requiring a coordinated family release. Ship it with the next engine version train; the init e2e's rerun workaround (removing the config before the second binary run) comes out at the same time.
461+
462+
463+
The agent-skills project (skills sync/list, `prisma init`, the staleness notice; PR #219) closed with these items still open; details were in its own ledger, summarized here as the surviving record.
464+
465+
- **When facade skill content diverges per database, split the skill by name — never add a carrier package** (operator concurred 2026-08-21). Today every facade ships an identical `prisma-8` skill and conflicts are arbitrated by highest version, safe only while content is identical and versions are lockstep. A transitive carrier package is unresolvable from the project root under pnpm; a direct-dependency skills package breaks the installed-version guarantee. The allowlist grows one deliberate line per facade either way.
466+
- **The browser login success page still shows a static `npx skills add prisma/skills` copy button** (`packages/cli/src/auth/login.ts` ~571) — the last surface promoting the retired third-party installer after the `agent` group's deletion. Decided 2026-08-24: the operator is having the responsible team remove it; not part of PR #219.
467+
- **Composer website hero copy** (prisma/composer `website/src/template.ts`): still says `npx skills add prisma/composer`; the replacement wording and its release timing belong to the site owner, and the new command only exists once the CLI ships.
468+
- **`check-skill-packaging.mjs` hardcodes `@prisma/composer`** (prisma/composer) while `stage-skills.mjs` is generic; generalize when a second skill-bearing composer package appears.
469+
- **Turbo race: `pnpm test` can rebuild `cli-engine` dist while `cli` tests import it** (intermittent `Failed to resolve entry for package "@prisma/cli-engine"`). Fix: `dependsOn` on the engine build in turbo.json.
470+
- **Windows CI: the credential-manager suite needs an owner** — two distinct timing-sensitive tests flaked on 2026-08-21 (`credential-manager.test.ts` "holds no lock while the workspace name is fetched", run 32477175789; `credential-manager-processes.test.ts` "exchanges one refresh token once", run 32497093995), both on pushes touching nothing near credentials.
471+
- **Windows CI: `skills-sync.test.ts` timed out once at the 5s default** (run 32474645762) with a teardown ENOTEMPTY from cleanup racing the timed-out test. If it recurs, raise the suite's per-test timeout on Windows rather than chasing the race.
472+
- **`isLikelyGlobalNpmEntrypoint` (update-check.ts) matches only `prisma-cli` install paths**, so a globally-installed `prisma` gets the docs-link fallback instead of a concrete update command; `selectUpdateInstruction` still names `@prisma/cli`. Newly conspicuous after the CLI_NAME → prisma rename.
473+
- **The feedback client's user-agent changed from `prisma-cli/<version>` to `prisma/<version>`** — wire-visible; whoever reads that dashboard should know.
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Finding and resolving prisma.config.ts when a repository has more than one
2+
3+
Status: design discussion. Nothing below is decided except where explicitly marked. This document exists so the discussion can start from the constraints and the options already explored, rather than rediscovering them.
4+
5+
## Background: how the config file works in the Prisma 8 CLI
6+
7+
`prisma.config.ts` is the Prisma 8 CLI's configuration file. It is real TypeScript that the CLI evaluates, and its default export must be wrapped in `definePrismaConfig(...)`, which stamps a version marker on the object. A `prisma.config.ts` without the marker — for example one written for Prisma 7, which uses the same filename — is rejected with a clear error rather than half-interpreted.
8+
9+
Every top-level key in the config object is a **section**, and each section belongs to one part of the CLI: `skills` configures the agent-skills feature today, and the ORM will have its own section. The set of section names is closed — a key the CLI does not recognise is an error, on the theory that silently ignoring settings a user wrote is worse than failing.
10+
11+
Today the CLI reads **exactly one file**: the one named with `--config`, otherwise `prisma.config.ts` in the directory the command runs in. It never looks anywhere else. Commands that have no config settings never read or evaluate the file at all.
12+
13+
## The problem
14+
15+
Two facts collide.
16+
17+
**First: commands run from subdirectories.** If the config sits at the repository root and you run a command from `apps/api/`, a current-directory-only lookup finds nothing. The CLI needs to search upward. But the moment it searches upward, a repository can have several `prisma.config.ts` files on the path between the current directory and the root — and the CLI needs a rule for which one answers.
18+
19+
**Second: different commands need different files.** Take this repository, which reflects the most common real-world layout:
20+
21+
```
22+
acme/
23+
prisma.config.ts ← deploy target, platform settings
24+
packages/
25+
db/
26+
prisma.config.ts ← ORM settings (schema location, migrations)
27+
api/
28+
```
29+
30+
The ORM's settings live in the package that owns the database code — that is the mainstream pattern, not an edge case. But `prisma deploy`, `prisma project link`, and everything Composer-related is scoped to the repository as a whole; those settings live at the root. So when you run an ORM command from `packages/db`, the right file is `packages/db/prisma.config.ts` — and when you run `prisma deploy` from that same directory, the right file is the root one.
31+
32+
No rule that picks **one file for everything** can satisfy both. That is the core finding of the design work so far, and the two rejected options below show each half of it failing.
33+
34+
## Rejected: "the highest file wins"
35+
36+
Rule: search upward from the current directory; the file closest to the filesystem root wins, unless a file on the way declares `root: true`, which stops the search there (like ESLint's old `root: true`).
37+
38+
In the example repo, every command run inside `packages/db` — including ORM commands — reads the **root** config. The ORM settings in `packages/db/prisma.config.ts` are ignored completely. The only escape is declaring `root: true` in the package's file, which then hides the root config from that package entirely — so `deploy` breaks from inside the package instead. One file, all or nothing, in either direction. This breaks the mainstream ORM layout, so it was rejected. (It was briefly implemented; see the appendix.)
39+
40+
## Rejected: "the nearest file wins"
41+
42+
Rule: search upward; the first file found wins.
43+
44+
Now the ORM case works: inside `packages/db`, the package's config answers. But run `prisma deploy` from `packages/db` and the CLI reads the package's config too — which has no deploy settings, and the root config that has them is never consulted. Root-scoped commands only work from the repository root. Rejected.
45+
46+
A third option — letting each part of the CLI declare "I am root-scoped" or "I am nearest-scoped" and searching accordingly — was rejected as redundant: where a section is *written* already encodes that, without inventing a declaration mechanism that every feature has to get right.
47+
48+
## Proposed (not decided): resolve per section, nearest definition wins
49+
50+
Rule: search upward from the current directory and collect **every** `prisma.config.ts` on the path; a file declaring `root: true` ends the collection. Then resolve each **section** independently: a section comes from the nearest file that defines it. Sections are atomic — the nearest definition wins whole; there is no merging of a section across files.
51+
52+
In the example repo, from inside `packages/db`:
53+
54+
- ORM command → the `orm` section is defined in `packages/db/prisma.config.ts` → the package's settings apply. ✓
55+
- `prisma deploy` → the nested file has no deploy/Composer section → the search continues upward and finds it in the root file. ✓
56+
- `skills: { check: false }` written at the root reaches `packages/db` too, because the nested file only shadows the sections it actually defines. ✓
57+
58+
The costs, stated plainly:
59+
60+
1. A command may evaluate more than one file — every config on the path up to the stopping point. Config files are executable TypeScript, so that is real user code running and a transpile per file. It is bounded by directory depth and cacheable within a run, and only commands that actually consume config trigger any of it.
61+
2. A broken file anywhere on the path — Prisma 7 format, syntax error — fails the command with an error naming that file. The proposal is to fail early rather than skip broken files, on the theory that a half-read path is worse than an error that says exactly which file to fix.
62+
3. The loader's result stops being "one file's contents" and becomes a resolved view over several files, and every diagnostic must say which file it is about. That is genuine engineering work in the CLI engine.
63+
64+
## Open questions for this discussion
65+
66+
- Is per-section nearest-first the right model, or is there a simpler rule that satisfies both the nested-ORM layout and root-scoped commands?
67+
- Two files on the path define the same section: nearest silently wins, or wins with a printed notice?
68+
- Where does the upward search stop when no file declares `root: true` — filesystem root, home directory, or a repository boundary such as the directory containing `.git`? (Under a one-file rule this mattered little; under collect-everything, every file on the path gets evaluated, so the stopping point deserves a fresh look.)
69+
- What does `--config <file>` mean here: read only that file, or treat it as the nearest layer with the search continuing above it?
70+
- Does the unknown-section check run per file, so a typo'd key in a nested file still errors even though the command's sections resolved elsewhere?
71+
- Should `prisma init` scaffold a `prisma.config.ts` once this design lands, and does the `root: true` marker keep that name?
72+
73+
## Appendix: prior implementation, kept as reference
74+
75+
The "highest file wins" rule was implemented in the CLI engine and then removed when the discussion surfaced the nested-ORM problem (branch `claude/agent-skills-npm-packages-770857` in prisma/prisma-cli; commits `ba48d46` and `f72503c`, removed by `9b2f9d0` — recoverable from history). A code review of that implementation catalogued edge cases any future implementation should handle regardless of the chosen rule: resolve the search's starting directory through symlinks so errors name real paths; keep loader tests anchored so a stray config file in a real ancestor of the checkout cannot leak into them; enforce reserved-key handling on the engine side of the pluggable-loader boundary, not only inside the default loader; and name the offending value in validation errors. The full findings are in the same repository under `.drive/projects/agent-skills-npm-packages/reviews/code-review.md`, round "Init slice — Round 1".

biome.jsonc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
"includes": [
7070
"packages/cli-engine/src/exports/**",
7171
"packages/cli-telemetry/src/exports/**",
72+
"packages/prisma/src/config.ts",
7273
"packages/cli/src/shell/cli-command.ts",
7374
"packages/cli/src/shell/command-arguments.ts",
7475
"packages/cli/src/shell/errors.ts",

docs/architecture/overview.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ flowchart TD
2222
## Command Flow
2323

2424
1. `packages/cli/src/bin.ts` starts the Node process and calls `main`.
25-
2. `packages/cli/src/main.ts` builds the CLI, runs the update check, and
26-
hands the engine a runtime assembled from `process`.
25+
2. `packages/cli/src/main.ts` builds the CLI, runs the update check, hands the engine a runtime assembled from `process`, and after the command has run reports out-of-date agent skills.
2726
3. `packages/cli/src/cli.ts` mounts every command and command family.
2827
4. The engine parses argv, decides interactivity and credentials, dispatches
2928
the handler, and renders its result.
@@ -52,6 +51,7 @@ implementation.
5251
Local state boundaries are also explicit:
5352

5453
- `.prisma/local.json` stores the linked project ID (a gitignored local pin, not a committed config file).
54+
- `.prisma/skills.json` stores whether the agent-skills staleness check is silenced for this project (written by `skills sync --disable`).
5555
- Active branch and app selection are local CLI state.
5656
- Secret values must not be printed in human output or structured output.
5757

docs/product/cli-style-guide.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,8 @@ project show → This directory is not linked to a Prisma Project.
8383
│ project: Not linked
8484
8585
Next steps:
86-
- Link an existing Project you choose: prisma-cli project link <id-or-name>
87-
- Create a new Project: prisma-cli project create billing-api
86+
- Link an existing Project you choose: prisma project link <id-or-name>
87+
- Create a new Project: prisma project create billing-api
8888
```
8989

9090
Rules:

docs/product/command-principles.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ Use the other convention docs for adjacent concerns:
2828

2929
The long-term command surface grows through workflow groups such as:
3030

31-
- `agent`
31+
- `skills`
3232
- `auth`
3333
- `project`
3434
- `branch`
@@ -38,7 +38,7 @@ The long-term command surface grows through workflow groups such as:
3838
- `app`
3939
- `git`
4040

41-
The preview implements only `agent`, `auth`, `project`, `git`, `branch`, `database`, `bucket`, and `app`.
41+
The preview implements only `auth`, `project`, `git`, `branch`, `database`, `bucket`, `app`, `skills`, and `init`.
4242

4343
## Stable Nouns
4444

@@ -93,6 +93,14 @@ No current branch command uses `use`; branch targeting follows explicit flags or
9393

9494
Build and release an app into a target branch.
9595

96+
### `init`
97+
98+
Prepare the current repository for Prisma development, entirely locally: add the `postinstall` script that keeps the Prisma agent skills in sync (`prisma skills sync || exit 0`), scaffold a `prisma.config.ts` recording which agents get skills, then sync the skills once now.
99+
100+
The scaffolded config imports `definePrismaConfig` from `prisma/config` and spells out `skills: { agents: [...] }`. The agents come from the `--skills` flag (`--skills=claude,cursor`, validated against the known agent names), or the default set when the flag is absent. `--skills=none` records the choice rather than merely skipping: the scaffold is written with `skills: { agents: [] }` — the committed record that no agent skills are wanted — and the sync is skipped on that run; with `agents: []` in place, later syncs, `skills list`, and the staleness notice all treat the project as having no skills to manage. There is no harness detection: the config is the only authority on which agents a project uses.
101+
102+
`init` calls no platform API, never prompts, and never edits a file the user already owns: a `postinstall` script the user wrote and an existing `prisma.config.ts` are both left alone and reported as diagnostics — the config diagnostic shows the exact `skills: { agents: [...] }` snippet to add by hand. Everything lands in the current directory: the hook in its `package.json`, the config beside it, the skill copies in the agent directories under it. Rerunning is safe; each step reports what is already done and the command exits 0.
103+
96104
### `logs`
97105

98106
Resolve a service version and show or stream its logs.

docs/product/error-conventions.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ Examples:
6666
- unexpected `undefined`
6767
- internal serialization or state invariant broken
6868

69-
Bugs should fail fast and preserve stack traces. Catch them only at the outermost boundary for crash formatting. At that boundary, `--json` runs still emit the standard error envelope with code `UNEXPECTED_ERROR`, and both output modes point at `prisma-cli feedback` pre-filled with the failing command and error line (`--quiet` suppresses the human hint; expected failures never carry the feedback suggestion).
69+
Bugs should fail fast and preserve stack traces. Catch them only at the outermost boundary for crash formatting. At that boundary, `--json` runs still emit the standard error envelope with code `UNEXPECTED_ERROR`, and both output modes point at `prisma feedback` pre-filled with the failing command and error line (`--quiet` suppresses the human hint; expected failures never carry the feedback suggestion).
7070

7171
## Boundary Handling
7272

@@ -107,7 +107,7 @@ This is usually a missing env var, a failed DB connection,
107107
or a crash on startup.
108108
109109
See what happened
110-
prisma-cli app logs --deployment <id>
110+
prisma app logs --deployment <id>
111111
112112
URL
113113
https://cv-...
@@ -231,7 +231,7 @@ These codes are the minimum stable set for the MVP:
231231
Recommended meanings:
232232

233233
- `USAGE_ERROR`: invalid arguments or invalid command combination
234-
- `UNEXPECTED_ERROR`: the CLI crashed on an unexpected fault; the envelope carries a `recover` next action suggesting `prisma-cli feedback`
234+
- `UNEXPECTED_ERROR`: the CLI crashed on an unexpected fault; the envelope carries a `recover` next action suggesting `prisma feedback`
235235
- `FEEDBACK_SEND_FAILED`: the feedback service was unreachable, timed out, or returned a non-2xx response
236236
- `AUTH_REQUIRED`: command needs an authenticated session
237237
- `AUTH_CONFIG_INVALID`: environment auth configuration is present but unusable, such as an empty `PRISMA_SERVICE_TOKEN`

0 commit comments

Comments
 (0)