Skip to content

fix(project): resolution hierarchy#15

Open
luanvdw wants to merge 4 commits into
mainfrom
fix/project-resolution
Open

fix(project): resolution hierarchy#15
luanvdw wants to merge 4 commits into
mainfrom
fix/project-resolution

Conversation

@luanvdw
Copy link
Copy Markdown
Member

@luanvdw luanvdw commented May 13, 2026

This PR removes outdated project link commands, and replaces it with the current resolution hierarchy through inference, with flags to fallback on

Summary

  • Remove project link from the Public Beta command surface and replace repo config linking with automatic project resolution.
  • Add shared project resolution with explicit --project, revalidated remembered local context, package-name inference, deploy-only creation, and stable structured errors.
  • Update app deploy and project env commands to use the shared resolver and return resolved project context where required.
  • Refresh project command help/copy and product docs for the active project model.

Testing

  • pnpm --filter @prisma/cli build
  • pnpm --filter @prisma/cli exec vitest run tests/project.test.ts tests/project-controller.test.ts tests/project-real-mode.test.ts tests/app-controller.test.ts tests/app-env.test.ts tests/app-env-vars.test.ts tests/shell.test.ts

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 13, 2026

Warning

Rate limit exceeded

@luanvdw has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 35 minutes and 40 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2ddea5c7-a821-45b2-8eed-b15e10013cbd

📥 Commits

Reviewing files that changed from the base of the PR and between 25bc339 and badae64.

📒 Files selected for processing (11)
  • docs/product/command-principles.md
  • packages/cli/src/controllers/app-env.ts
  • packages/cli/src/controllers/app.ts
  • packages/cli/src/controllers/project.ts
  • packages/cli/src/lib/project/resolution.ts
  • packages/cli/src/shell/errors.ts
  • packages/cli/src/use-cases/contracts.ts
  • packages/cli/src/use-cases/create-cli-gateways.ts
  • packages/cli/tests/app-controller.test.ts
  • packages/cli/tests/project.test.ts
  • packages/cli/tests/use-case-helpers.ts

Walkthrough

This PR refactors the Prisma CLI's project context model from a "linked project" approach (persisting project references in prisma.config.ts) to a "resolved project" approach that uses local state tracking, platform resolution, and interactive prompting. It removes the config adapter, adds project-resolution logic, updates type contracts, and wires commands to accept explicit --project flags and resolve context automatically.

Changes

Documentation and Public API Contracts

Layer / File(s) Summary
Public beta project resolution and terminology
docs/product/command-principles.md, docs/product/command-spec.md, docs/product/resource-model.md, docs/product/error-conventions.md
Documentation clarifies that preview CLI does not read/write repo config files, defines ordered project resolution (explicit flag → platform mapping → remembered state → package-name match → creation → prompt), and introduces new error codes (PROJECT_UNRESOLVED, PROJECT_NOT_FOUND, PROJECT_AMBIGUOUS, LOCAL_STATE_STALE).
Output format and style guide updates
docs/product/cli-style-guide.md, docs/product/output-conventions.md
Examples and patterns updated to reflect project show semantics (resolving project for current directory) instead of project link (linking repo to project). Annotation status removes "linked" in favor of "default".

Local State and Project Resolution Foundation

Layer / File(s) Summary
Remembered project tracking in local state
packages/cli/src/adapters/local-state.ts
LocalState now includes project section with rememberedByWorkspace and lastResolved tracking. New RememberedProjectState interface defines shape. LocalStateStore gains methods to read/set remembered projects per workspace.
Remove linked project config persistence
packages/cli/src/adapters/config.ts
File removed entirely; eliminates readLinkedProjectId, writeLinkedProjectId, assertLinkedProjectIdWritable, and UnsafeConfigWriteError.
Project resolution logic
packages/cli/src/lib/project/resolution.ts
New module implements resolveProjectTarget with ordered resolution steps: explicit --project, durable platform mapping (stubbed), remembered local state, package.json name match, optional creation, and interactive prompt. Includes factories for four resolution-failure CliError types and supporting helpers.

Type Contracts and Gateway Interfaces

Layer / File(s) Summary
Remove linked-project fields, add resolution context
packages/cli/src/types/project.ts, packages/cli/src/types/auth.ts, packages/cli/src/types/branch.ts, packages/cli/src/types/app.ts
Type updates remove linkedProjectId throughout and replace with resolved project context. ProjectListResult / ProjectShowResult now include non-nullable workspace/project and new ProjectResolution (with projectSource enum). AuthStateResult removes linkedProjectId. AppDeployResult replaces projectId with structured workspace, project, branch, and resolution. BranchListResult / BranchShowResult rename field to projectId.
Replace config gateway with state gateway
packages/cli/src/use-cases/contracts.ts, packages/cli/src/use-cases/create-cli-gateways.ts
ProjectConfigGateway replaced with ProjectStateGateway (reads/remembers project id from LocalStateStore). ProjectUseCases contract narrowed to only list(authState). Gateway factory updated to wire stateStore-backed project state.

Authentication and Use-Case Refactoring

Layer / File(s) Summary
Auth and branch use-cases align to remembered state
packages/cli/src/use-cases/auth.ts, packages/cli/src/use-cases/branch.ts, packages/cli/src/use-cases/project.ts
Auth use-cases remove linkedProjectId from return shape. Branch use-cases switch to projectStateGateway.readRememberedProjectId() and return projectId instead of linkedProjectId. Project use-cases simplified to only implement list (removed show and link).

Command Wiring for Project Selection

Layer / File(s) Summary
--project flag and resolution integration
packages/cli/src/commands/app/index.ts, packages/cli/src/commands/env.ts, packages/cli/src/commands/project/index.ts
App and env commands add --project <id-or-name> option to multiple subcommands. project show adds --project and JSON serialization. project link subcommand removed. Parsed projectRef threaded through to controller functions.

Controller Refactoring for Resolved Project Context

Layer / File(s) Summary
App deployment and env operations resolve project via auth
packages/cli/src/controllers/app.ts, packages/cli/src/controllers/app-env.ts
Controllers accept optional projectRef and resolve project via new resolveProjectTarget (authenticated workspace + explicit/remembered/inferred project). runAppDeploy returns full resolution context (workspace, project, branch, resolution) instead of just projectId. App/env commands no longer require linked project; explicit --project or resolved context enables operation.
Project list/show simplified and decoupled from config
packages/cli/src/controllers/project.ts
runProjectList requires auth and workspace, fetches real/fixture projects, removes linkedProjectId from result. runProjectShow now accepts optional explicitProject and resolves via resolveProjectTarget. Removed entire runProjectLink flow and linked-project discovery.

Output Rendering and Serialization

Layer / File(s) Summary
Render resolved project context instead of linked
packages/cli/src/presenters/project.ts, packages/cli/src/presenters/branch.ts, packages/cli/src/presenters/app.ts, packages/cli/src/output/patterns.ts
Project/branch/app presenters updated to display workspace/project/branch details from resolved context instead of linked id. status: null replaces "linked" annotation. Removed renderProjectLink and renderMutate logic.
ENV config parsing allows KEY-only with environment fallback
packages/cli/src/lib/app/env-config.ts
parseKeyValuePositional now accepts injectable env parameter; when input is KEY-only, it validates key shape and reads value from provided environment, enabling KEY assignment from process.env.
Command metadata and help text
packages/cli/src/shell/command-meta.ts
Command descriptions updated to reference "active project" and "resolved project" instead of "linked project". Examples added for env commands using explicit project.

Comprehensive Test Migration

Layer / File(s) Summary
Test infrastructure and helpers
packages/cli/tests/helpers.ts, packages/cli/tests/use-case-helpers.ts
Test helpers refactored to use LocalStateStore for remembered-project seeding and to remove writePrismaConfig usage. createTestCommandContext and createUseCaseGateways updated to work with projectId state instead of linked config.
Controller and integration tests
packages/cli/tests/app-controller.test.ts, packages/cli/tests/app-env-vars.test.ts, packages/cli/tests/app-env.test.ts, packages/cli/tests/project-controller.test.ts, packages/cli/tests/project-real-mode.test.ts, packages/cli/tests/project-usecases.test.ts, packages/cli/tests/project.test.ts
Tests refactored to mock auth/workspace context centrally, use remembered-project environment variables, and validate new runAppDeploy result shapes (workspace/project/branch/resolution). Removed tests covering linked-project config reading/writing. Added tests for resolution error cases (PROJECT_NOT_FOUND, PROJECT_UNRESOLVED, PROJECT_AMBIGUOUS, LOCAL_STATE_STALE).
Auth and branch use-case tests
packages/cli/tests/auth-ops.test.ts, packages/cli/tests/auth-usecases.test.ts, packages/cli/tests/auth-real-mode.test.ts, packages/cli/tests/auth.test.ts, packages/cli/tests/branch-usecases.test.ts, packages/cli/tests/branch.test.ts
Tests updated to remove linkedProjectId assertions and writePrismaConfig calls. Branch tests use new rememberProject helper to seed local state. Auth tests validate new state shape without linked-project fields.
Config adapter and shell tests
packages/cli/tests/config-adapter.test.ts, packages/cli/tests/shell.test.ts
Config-adapter test file removed (no longer needed). Shell tests updated to expect project show (with AUTH_REQUIRED) instead of project link (with USAGE_ERROR) in non-interactive mode.

🎯 4 (Complex) | ⏱️ ~60 minutes

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/project-resolution
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch fix/project-resolution

@luanvdw luanvdw marked this pull request as ready for review May 13, 2026 13:53
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/product/command-principles.md`:
- Around line 86-88: Remove the duplicated sentence "use changes local active
context only": keep a single occurrence and delete the repeated bullet point so
the phrase appears only once (locate the duplicate instances of the exact string
"`use` changes local active context only" in the surrounding text and remove the
redundant bullet entry).

In `@packages/cli/src/controllers/app.ts`:
- Around line 180-184: The block in runAppDeploy duplicates
requireProviderAndProjectContext; replace the manual fetch-and-resolve
(requirePreviewAppProviderWithClient + resolveProjectContext) with a single call
to requireProviderAndProjectContext(context, options?.projectRef, { allowCreate:
true }) to obtain { client, provider, target } (or destructure the returned
target) and then set projectId = target.project.id; ensure you still have client
and provider available from that helper for the rest of runAppDeploy.
- Around line 1430-1433: The guard for missing workspace on the result of
requireAuthenticatedAuthState is correct but the thrown error is wrong; replace
the authRequiredError([...]) call with a workspace-specific usage error that
instructs the user to run the workspace selection/creation flow (e.g., call
usageError(...) with a message and next steps like "run prisma-cli workspaces
select or create" or whatever the project's workspace selection command is).
Update this pattern in the current function in
packages/cli/src/controllers/app.ts (the block using
requireAuthenticatedAuthState and throwing authRequiredError) and mirror the
same change in the other occurrences noted (project.ts and app-env.ts) to
consistently guide authenticated-but-no-workspace users to the workspace
selection flow instead of asking them to log in again.
- Around line 559-562: The call to readLastResolvedProject() can return a
project from a different workspace and its id is passed unchecked into
readKnownLiveDeployment(), which leaks cross-workspace state; update the logic
around rememberedProject (from readLastResolvedProject()) to validate that
rememberedProject.workspaceId === context.auth.workspaceId before using it — if
it doesn’t match, treat rememberedProject as null (or re-call a workspace-scoped
variant of readLastResolvedProject that accepts the current workspace id) so
that readKnownLiveDeployment(rememberedProject.id, deployment.app.id) is only
invoked for projects in the authenticated workspace.

In `@packages/cli/src/lib/project/resolution.ts`:
- Around line 156-170: readPackageName currently assumes JSON.parse returns an
object and accesses parsed.name, which throws when package.json parses to a
primitive (e.g., null); update readPackageName to guard that parsed is a
non-null object (e.g., typeof parsed === "object" && parsed !== null) before
accessing parsed.name and treat any non-object root as a missing name (return
null) so it no longer throws a TypeError for primitive JSON roots.

In `@packages/cli/src/use-cases/create-cli-gateways.ts`:
- Around line 66-76: readRememberedProjectId and rememberProjectId are using
different state APIs (readLastResolvedProject vs setRememberedProject) causing
inconsistent reads after writes; update one to use the other's state accessor so
both read and write target the same source. Specifically, in projectStateGateway
adjust either readRememberedProjectId to call the remembered-project read method
(e.g., context.stateStore.readRememberedProject or equivalent) or change
rememberProjectId to persist via the last-resolved API (e.g.,
context.stateStore.setLastResolvedProject) so both use the same state methods
(reference projectStateGateway, readRememberedProjectId, rememberProjectId,
context.stateStore.readLastResolvedProject,
context.stateStore.setRememberedProject).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: fa3690d8-cea7-463c-a85e-6a84ea40e7a5

📥 Commits

Reviewing files that changed from the base of the PR and between 720e29a and 25bc339.

📒 Files selected for processing (48)
  • docs/product/cli-style-guide.md
  • docs/product/command-principles.md
  • docs/product/command-spec.md
  • docs/product/error-conventions.md
  • docs/product/output-conventions.md
  • docs/product/resource-model.md
  • packages/cli/src/adapters/config.ts
  • packages/cli/src/adapters/local-state.ts
  • packages/cli/src/commands/app/index.ts
  • packages/cli/src/commands/env.ts
  • packages/cli/src/commands/project/index.ts
  • packages/cli/src/controllers/app-env.ts
  • packages/cli/src/controllers/app.ts
  • packages/cli/src/controllers/project.ts
  • packages/cli/src/lib/app/env-config.ts
  • packages/cli/src/lib/auth/auth-ops.ts
  • packages/cli/src/lib/project/resolution.ts
  • packages/cli/src/output/patterns.ts
  • packages/cli/src/presenters/app.ts
  • packages/cli/src/presenters/branch.ts
  • packages/cli/src/presenters/project.ts
  • packages/cli/src/shell/command-meta.ts
  • packages/cli/src/types/app.ts
  • packages/cli/src/types/auth.ts
  • packages/cli/src/types/branch.ts
  • packages/cli/src/types/project.ts
  • packages/cli/src/use-cases/auth.ts
  • packages/cli/src/use-cases/branch.ts
  • packages/cli/src/use-cases/contracts.ts
  • packages/cli/src/use-cases/create-cli-gateways.ts
  • packages/cli/src/use-cases/project.ts
  • packages/cli/tests/app-controller.test.ts
  • packages/cli/tests/app-env-vars.test.ts
  • packages/cli/tests/app-env.test.ts
  • packages/cli/tests/auth-ops.test.ts
  • packages/cli/tests/auth-real-mode.test.ts
  • packages/cli/tests/auth-usecases.test.ts
  • packages/cli/tests/auth.test.ts
  • packages/cli/tests/branch-usecases.test.ts
  • packages/cli/tests/branch.test.ts
  • packages/cli/tests/config-adapter.test.ts
  • packages/cli/tests/helpers.ts
  • packages/cli/tests/project-controller.test.ts
  • packages/cli/tests/project-real-mode.test.ts
  • packages/cli/tests/project-usecases.test.ts
  • packages/cli/tests/project.test.ts
  • packages/cli/tests/shell.test.ts
  • packages/cli/tests/use-case-helpers.ts
💤 Files with no reviewable changes (6)
  • packages/cli/tests/config-adapter.test.ts
  • packages/cli/tests/auth-real-mode.test.ts
  • packages/cli/tests/auth-ops.test.ts
  • packages/cli/src/adapters/config.ts
  • packages/cli/src/types/auth.ts
  • packages/cli/src/lib/auth/auth-ops.ts

Comment thread docs/product/command-principles.md Outdated
Comment thread packages/cli/src/controllers/app.ts Outdated
Comment thread packages/cli/src/controllers/app.ts Outdated
Comment thread packages/cli/src/controllers/app.ts
Comment thread packages/cli/src/lib/project/resolution.ts
Comment thread packages/cli/src/use-cases/create-cli-gateways.ts Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant