Skip to content

feat(cli): add project rename, remove, and transfer#107

Open
AmanVarshney01 wants to merge 3 commits into
mainfrom
feat/project-rename-remove-transfer
Open

feat(cli): add project rename, remove, and transfer#107
AmanVarshney01 wants to merge 3 commits into
mainfrom
feat/project-rename-remove-transfer

Conversation

@AmanVarshney01

@AmanVarshney01 AmanVarshney01 commented Jul 2, 2026

Copy link
Copy Markdown
Member

Completes the project group's remote lifecycle: rename, remove, and transfer. Spec-first (command-spec.md + resource-model.md updated in the same change).

$ prisma-cli project rename "Acme Dashboard v2"
✔ Renamed. Directory bindings pin the project id, so they stay valid.

$ prisma-cli project remove proj_999 --confirm proj_999
✔ The project, its databases, and its apps were removed.
  This directory's local project binding was cleared.

$ prisma-cli project transfer proj_123 --to-workspace "Prisma Labs" --confirm proj_123
✔ The project now belongs to the recipient workspace.
  This directory's local project binding now points at the recipient workspace.

Design notes

  • The transfer API authorizes with a recipient access token, not a workspace id. --to-workspace resolves a locally stored OAuth session (same targets as auth workspace use) through a new workspace-pinned FileTokenStorage view that refreshes via the SDK and can never move the active-workspace selection; --recipient-token is the cross-account/headless path. Under PRISMA_SERVICE_TOKEN, --to-workspace fails with TRANSFER_RECIPIENT_UNAVAILABLE.
  • Remove and transfer take an explicit positional target (never the bound project) plus exact-id --confirm.
  • Local pin hygiene: remove clears a matching .prisma/local.json; transfer rewrites it to the recipient workspace when known, else clears it; both best-effort with warnings.
  • Structured codes: PROJECT_REMOVE_BLOCKED (active deployments), PROJECT_TRANSFER_REJECTED, PROJECT_RENAME_FAILED, TRANSFER_RECIPIENT_REQUIRED/_UNAVAILABLE, CONFIRMATION_REQUIRED with meta.

Testing: 14 new integration tests, full suite green, and all three commands verified against the live Management API with scratch projects, including a real cross-workspace transfer (project visible in the recipient workspace, pin rewritten, cleaned up afterwards).

Note: merge after #106 or rebase; both touch mock-api.ts/fixtures.

Completes the project group's remote lifecycle:

- project rename <name>: renames the resolved Project (durable binding
  or --project); pins bind by id, so directory bindings stay valid
- project remove <project> --confirm <project-id>: permanent removal
  with the exact-id confirmation convention; surfaces the platform's
  active-deployments block as PROJECT_REMOVE_BLOCKED and clears this
  directory's local pin when it pointed at the removed project
- project transfer <project> (--to-workspace <id-or-name> |
  --recipient-token <token>) --confirm <project-id>: moves a Project to
  another workspace. --to-workspace resolves a locally stored OAuth
  session (the auth workspace use targets) and authorizes the transfer
  with it, refreshing through the SDK via a workspace-pinned token
  storage view that never touches the active-workspace pointer.
  --recipient-token is the cross-account and headless path. A matching
  local pin is rewritten to the recipient workspace when known,
  otherwise cleared.

Structured recovery codes for agents: PROJECT_RENAME_FAILED,
PROJECT_REMOVE_BLOCKED, PROJECT_TRANSFER_REJECTED,
TRANSFER_RECIPIENT_REQUIRED, TRANSFER_RECIPIENT_UNAVAILABLE, plus the
existing workspace selection errors and CONFIRMATION_REQUIRED with
expectedConfirm/receivedConfirm meta.

Spec-first: command-spec.md and resource-model.md updated alongside
the implementation.
@AmanVarshney01

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 95396e8f-4b8f-44a7-bbdd-b229d6d8e681

📥 Commits

Reviewing files that changed from the base of the PR and between bdd2bda and 6870b84.

📒 Files selected for processing (2)
  • packages/cli/src/controllers/project.ts
  • packages/cli/src/lib/project/provider.ts
👮 Files not reviewed due to content moderation or server errors (2)
  • packages/cli/src/lib/project/provider.ts
  • packages/cli/src/controllers/project.ts

Summary by CodeRabbit

  • New Features
    • Added CLI commands: project rename, project remove, and project transfer, with human and JSON output including confirmation and recipient/workspace details.
    • Added documentation covering project lifecycle behavior and pinning/confirmation semantics.
  • Bug Fixes
    • Improved local project pin handling for rename/remove/transfer (rewrite/clear behavior) and stricter validation for inputs, confirmations, and destination availability.
    • Enhanced workspace resolution when a pinned workspace is configured.
  • Tests
    • Added integration coverage for rename/remove/transfer and updated related project listing expectations.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main CLI change: adding project rename, remove, and transfer commands.
Description check ✅ Passed The description is directly related to the changeset and accurately describes the new project lifecycle commands and behavior.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/project-rename-remove-transfer
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch feat/project-rename-remove-transfer

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🤖 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-spec.md`:
- Line 699: Update the `prisma-cli project rename` heading to mark `--project
<id-or-name>` as optional, matching the bracket convention used by other
commands like `project link`; adjust the command title in the command-spec docs
so it no longer implies the flag is required and stays consistent with the body
text and examples.

In `@packages/cli/src/adapters/mock-api.ts`:
- Around line 211-214: removeProject() in mock-api.ts currently deletes matching
databases but leaves their databaseConnections behind, creating orphaned state.
Update removeProject() to mirror removeDatabase() by collecting the removed
database IDs from this.data.databases and filtering
this.data.databaseConnections to drop any entries whose databaseId matches those
removed databases. Keep the change localized to the removeProject() flow and the
database/databaseConnections state management symbols.

In `@packages/cli/src/adapters/token-storage.ts`:
- Around line 51-57: The pinned/read-only token path in token-storage must not
mutate the active workspace. Update the workspace resolution flow in
token-storage so `resolveWorkspace()` uses a non-migrating read path instead of
`listWorkspaces()`, and ensure any refresh logic bypasses
`maybeActivateWorkspaceId` whenever `pinnedWorkspaceId` is set. This should keep
`activeWorkspaceId` untouched during pinned SDK auth/refresh while still
resolving the pinned workspace’s credentials correctly.
- Line 359: The return in the token storage match handling uses an unnecessary
non-null assertion, since the existing length checks already guarantee a match
in the relevant branch. Update the logic in token-storage.ts around the
match-selection flow so the return from the matches array uses the indexed value
directly without the non-null assertion, keeping the surrounding validation in
place.

In `@packages/cli/src/controllers/project.ts`:
- Around line 802-866: `requireProjectCommandContext` and
`requireProjectMutationContext` both duplicate real-mode auth/client setup, and
`requireProjectCommandContext` also calls `requireProjectClient(context)` twice.
Refactor these paths to create the `ManagementApiClient` once per command
invocation, reuse it for both `listProjects` and
`createManagementProjectProvider`, and have `requireProjectMutationContext`
delegate to `requireProjectClient` instead of redoing the
`requireComputeAuth`/`authRequiredError` flow. Keep the changes centered around
`requireProjectCommandContext`, `requireProjectMutationContext`, and
`requireProjectClient`.

In `@packages/cli/src/lib/project/provider.ts`:
- Around line 51-60: The project rename flow in provider.ts is casting the API
payload directly to RawProjectRecord without validating its shape. Update the
logic around the result.data.data handling to add a runtime check for the
required project fields (at least id and name, and url when present) before
building the return object. If the payload is invalid, fail fast with the same
error path used by projectRenameFailedError so malformed Management API
responses do not propagate into ProjectSummary.
- Around line 41-61: renameProject currently collapses every failure into
PROJECT_RENAME_FAILED, which hides non-name-related errors; update the error
handling in renameProject to match removeProject/transferProject by
special-casing the expected validation failure and otherwise passing through the
underlying API error via projectApiError so the original error code/status is
preserved. Keep the existing success path and use the same client.PATCH result
handling around result.error, result.data, and projectRenameFailedError to
locate the change.
🪄 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: 0fb346c3-7d41-482e-8f6b-c60f907b46d5

📥 Commits

Reviewing files that changed from the base of the PR and between f152fe3 and 358fd71.

📒 Files selected for processing (15)
  • docs/product/command-spec.md
  • docs/product/resource-model.md
  • packages/cli/fixtures/mock-api.json
  • packages/cli/src/adapters/mock-api.ts
  • packages/cli/src/adapters/token-storage.ts
  • packages/cli/src/commands/project/index.ts
  • packages/cli/src/controllers/project.ts
  • packages/cli/src/lib/auth/recipient.ts
  • packages/cli/src/lib/project/provider.ts
  • packages/cli/src/presenters/project.ts
  • packages/cli/src/shell/command-meta.ts
  • packages/cli/src/types/project.ts
  • packages/cli/tests/project-mutations.test.ts
  • packages/cli/tests/project-usecases.test.ts
  • packages/cli/tests/project.test.ts

Comment thread docs/product/command-spec.md
Comment thread packages/cli/src/adapters/mock-api.ts
Comment thread packages/cli/src/adapters/token-storage.ts
Comment thread packages/cli/src/adapters/token-storage.ts Outdated
Comment thread packages/cli/src/controllers/project.ts
Comment thread packages/cli/src/lib/project/provider.ts
Comment thread packages/cli/src/lib/project/provider.ts Outdated
- resolveWorkspace no longer runs the legacy auth-context migration, so
  it is genuinely read-only, and pinned token-storage views skip
  workspace activation entirely, even when no active workspace is set;
  the transfer contract no longer depends on call order
- renameProject maps only 400/422 to PROJECT_RENAME_FAILED and surfaces
  other API failures (401/403/5xx) through the generic error passthrough
  instead of misreporting them as a rejected name
- requireProjectCommandContext builds the ManagementApiClient once per
  invocation; requireProjectMutationContext reuses requireProjectClient
- mock removeProject also deletes the removed databases' connections
- drop a redundant non-null assertion in resolveWorkspace
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 2, 2026
…runner

remove/transfer confirmation nextSteps, transfer recipient errors, the
post-transfer workspace-use hint, and provider recovery commands now
render through the project's package runner (pnpm dlx / bunx / npx -y
with @prisma/cli@latest) instead of the hardcoded prisma-cli bin name,
matching the agent group's convention.
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