@prisma/cli 3.0.0-beta.0 → 3.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -96,6 +96,19 @@ npx prisma-cli app promote <deployment-id>
96
96
  - Stable command groups, flags, and error codes for scripts and agents.
97
97
  - Environment variable values are not printed back to the terminal.
98
98
 
99
+ ### Agent skills
100
+
101
+ For agent-guided Next.js deploys, install the Prisma CLI skill cluster at the
102
+ project level. Match the skill ref to the installed CLI version:
103
+
104
+ ```bash
105
+ npx prisma-cli version
106
+ pnpm dlx skills@latest add prisma/prisma-cli/skills#cli-v<cli-version> --all
107
+ ```
108
+
109
+ The skills teach agents how to prepare a Next.js app, run `app deploy`, verify
110
+ the result, and route CLI / Compute feedback to the right Prisma channel.
111
+
99
112
  ---
100
113
 
101
114
  ## Beta notes
@@ -59,26 +59,27 @@ function createRunCommand(runtime) {
59
59
  }
60
60
  function createDeployCommand(runtime) {
61
61
  const command = attachCommandDescriptor(configureRuntimeCommand(new Command("deploy"), runtime), "app.deploy");
62
- command.addOption(new Option("--app <name>", "App name")).addOption(new Option("--project <id-or-name>", "Project id or name")).addOption(new Option("--branch <name>", "Branch name")).addOption(new Option("--framework <name>", "Framework to deploy").choices([
62
+ command.addOption(new Option("--app <name>", "App name")).addOption(new Option("--project <id-or-name>", "Project id or name")).addOption(new Option("--create-project <name>", "Create and link a new Project before deploying")).addOption(new Option("--branch <name>", "Branch name")).addOption(new Option("--framework <name>", "Framework to deploy").choices([
63
63
  "nextjs",
64
64
  "hono",
65
- "tanstack-start"
66
- ])).addOption(new Option("--entry <path>", "Entrypoint path for Bun or auto deploys")).addOption(new Option("--build-type <type>", "Legacy deploy build type").choices([...PREVIEW_BUILD_TYPES]).default("auto").hideHelp()).addOption(new Option("--http-port <port>", "HTTP port override for the deployed app")).addOption(new Option("--env <name=value>", "Environment variable").argParser(collectRepeatableValues));
65
+ "tanstack-start",
66
+ "bun"
67
+ ])).addOption(new Option("--entry <path>", "Entrypoint path for Bun deploys")).addOption(new Option("--http-port <port>", "HTTP port override for the deployed app")).addOption(new Option("--env <name=value>", "Environment variable").argParser(collectRepeatableValues));
67
68
  addGlobalFlags(command);
68
69
  command.action(async (options) => {
69
70
  const appName = options.app;
70
71
  const entry = options.entry;
71
- const buildType = options.buildType;
72
72
  const branchName = options.branch;
73
73
  const framework = options.framework;
74
74
  const httpPort = options.httpPort;
75
75
  const envAssignments = options.env;
76
76
  const projectRef = options.project;
77
+ const createProjectName = options.createProject;
77
78
  await runCommand(runtime, "app.deploy", options, (context) => runAppDeploy(context, appName, {
78
79
  projectRef,
80
+ createProjectName,
79
81
  branchName,
80
82
  entrypoint: entry,
81
- buildType,
82
83
  framework,
83
84
  httpPort,
84
85
  envAssignments
@@ -1,9 +1,9 @@
1
1
  import { attachCommandDescriptor } from "../../shell/command-meta.js";
2
2
  import { addCompactGlobalFlags, addGlobalFlags } from "../../shell/global-flags.js";
3
3
  import { configureRuntimeCommand } from "../../shell/runtime.js";
4
- import { runProjectList, runProjectShow } from "../../controllers/project.js";
4
+ import { runProjectCreate, runProjectLink, runProjectList, runProjectShow } from "../../controllers/project.js";
5
5
  import { runCommand } from "../../shell/command-runner.js";
6
- import { renderProjectList, renderProjectShow, serializeProjectList, serializeProjectShow } from "../../presenters/project.js";
6
+ import { renderProjectList, renderProjectSetup, renderProjectShow, serializeProjectList, serializeProjectSetup, serializeProjectShow } from "../../presenters/project.js";
7
7
  import { createEnvCommand } from "../env.js";
8
8
  import { Command } from "commander";
9
9
  //#region src/commands/project/index.ts
@@ -12,9 +12,35 @@ function createProjectCommand(runtime) {
12
12
  addCompactGlobalFlags(project);
13
13
  project.addCommand(createProjectListCommand(runtime));
14
14
  project.addCommand(createProjectShowCommand(runtime));
15
+ project.addCommand(createProjectCreateCommand(runtime));
16
+ project.addCommand(createProjectLinkCommand(runtime));
15
17
  project.addCommand(createEnvCommand(runtime));
16
18
  return project;
17
19
  }
20
+ function createProjectCreateCommand(runtime) {
21
+ const command = attachCommandDescriptor(configureRuntimeCommand(new Command("create"), runtime), "project.create");
22
+ command.argument("<name>", "Project name");
23
+ addGlobalFlags(command);
24
+ command.action(async (name, options) => {
25
+ await runCommand(runtime, "project.create", options, (context) => runProjectCreate(context, String(name)), {
26
+ renderHuman: (context, descriptor, result) => renderProjectSetup(context, descriptor, result),
27
+ renderJson: (result) => serializeProjectSetup(result)
28
+ });
29
+ });
30
+ return command;
31
+ }
32
+ function createProjectLinkCommand(runtime) {
33
+ const command = attachCommandDescriptor(configureRuntimeCommand(new Command("link"), runtime), "project.link");
34
+ command.argument("[id-or-name]", "Project id or name");
35
+ addGlobalFlags(command);
36
+ command.action(async (projectRef, options) => {
37
+ await runCommand(runtime, "project.link", options, (context) => runProjectLink(context, typeof projectRef === "string" ? projectRef : void 0), {
38
+ renderHuman: (context, descriptor, result) => renderProjectSetup(context, descriptor, result),
39
+ renderJson: (result) => serializeProjectSetup(result)
40
+ });
41
+ });
42
+ return command;
43
+ }
18
44
  function createProjectListCommand(runtime) {
19
45
  const command = attachCommandDescriptor(configureRuntimeCommand(new Command("list"), runtime), "project.list");
20
46
  addGlobalFlags(command);
@@ -1,7 +1,6 @@
1
1
  import { CliError, authRequiredError, usageError, workspaceRequiredError } from "../shell/errors.js";
2
2
  import { requireComputeAuth } from "../lib/auth/guard.js";
3
3
  import { resolveProjectTarget } from "../lib/project/resolution.js";
4
- import { createSelectPromptPort } from "./select-prompt-port.js";
5
4
  import { requireAuthenticatedAuthState } from "./auth.js";
6
5
  import { listRealWorkspaceProjects } from "./project.js";
7
6
  import { formatScopeLabel, parseKeyValuePositional, resolveEnvScope } from "../lib/app/env-config.js";
@@ -19,7 +18,7 @@ async function runEnvAdd(context, rawAssignment, flags) {
19
18
  command: "add"
20
19
  });
21
20
  if (!scope) throw usageError(`prisma-cli project env add requires --role or --branch`, "Writing without an explicit scope is rejected.", "Pass --role production, --role preview, or --branch <git-name>.", [`prisma-cli project env add ${key}=${value} --role production`], "app");
22
- const { client, projectId } = await requireClientAndProject(context, flags.projectRef);
21
+ const { client, projectId } = await requireClientAndProject(context, flags.projectRef, "project env add");
23
22
  const resolved = await resolveScopeToApi(client, projectId, scope, { createBranchIfMissing: true });
24
23
  if (await findVariableByNaturalKey(client, projectId, key, resolved)) throw new CliError({
25
24
  code: "ENV_VARIABLE_ALREADY_EXISTS",
@@ -70,7 +69,7 @@ async function runEnvUpdate(context, rawAssignment, flags) {
70
69
  command: "update"
71
70
  });
72
71
  if (!scope) throw usageError(`prisma-cli project env update requires --role or --branch`, "Writing without an explicit scope is rejected.", "Pass --role production, --role preview, or --branch <git-name>.", [`prisma-cli project env update ${key}=${value} --role production`], "app");
73
- const { client, projectId } = await requireClientAndProject(context, flags.projectRef);
72
+ const { client, projectId } = await requireClientAndProject(context, flags.projectRef, "project env update");
74
73
  const resolved = await resolveScopeToApi(client, projectId, scope, { createBranchIfMissing: false });
75
74
  const existing = await findVariableByNaturalKey(client, projectId, key, resolved);
76
75
  if (!existing) throw new CliError({
@@ -103,7 +102,7 @@ async function runEnvList(context, flags) {
103
102
  requireExplicit: false,
104
103
  command: "list"
105
104
  }) ?? defaultRoleScope();
106
- const { client, projectId } = await requireClientAndProject(context, flags.projectRef);
105
+ const { client, projectId } = await requireClientAndProject(context, flags.projectRef, "project env list");
107
106
  const resolved = await resolveScopeToApi(client, projectId, scope, { createBranchIfMissing: false });
108
107
  const variables = await listVariables(client, projectId, resolved);
109
108
  return {
@@ -124,7 +123,7 @@ async function runEnvRemove(context, key, flags) {
124
123
  command: "remove"
125
124
  });
126
125
  if (!scope) throw usageError("prisma-cli project env remove requires --role or --branch", "Writing without an explicit scope is rejected.", "Pass --role production, --role preview, or --branch <git-name>.", [`prisma-cli project env remove ${key} --role production`], "app");
127
- const { client, projectId } = await requireClientAndProject(context, flags.projectRef);
126
+ const { client, projectId } = await requireClientAndProject(context, flags.projectRef, "project env remove");
128
127
  const resolved = await resolveScopeToApi(client, projectId, scope, { createBranchIfMissing: false });
129
128
  const existing = await findVariableByNaturalKey(client, projectId, key, resolved);
130
129
  if (!existing) throw new CliError({
@@ -149,7 +148,7 @@ async function runEnvRemove(context, key, flags) {
149
148
  nextSteps: []
150
149
  };
151
150
  }
152
- async function requireClientAndProject(context, explicitProject) {
151
+ async function requireClientAndProject(context, explicitProject, commandName) {
153
152
  const authState = await requireAuthenticatedAuthState(context);
154
153
  const client = await requireComputeAuth(context.runtime.env);
155
154
  if (!client) throw authRequiredError(["prisma-cli auth login"]);
@@ -161,8 +160,7 @@ async function requireClientAndProject(context, explicitProject) {
161
160
  workspace: authState.workspace,
162
161
  explicitProject,
163
162
  listProjects: () => listRealWorkspaceProjects(client, authState.workspace),
164
- prompt: createSelectPromptPort(context),
165
- remember: true
163
+ commandName
166
164
  })).project.id
167
165
  };
168
166
  }