@prisma/cli 3.0.0-dev.97.1 → 8.0.0-rc.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.
Files changed (99) hide show
  1. package/README.md +3 -14
  2. package/dist/adapters/local-state.js +14 -3
  3. package/dist/{lib/auth → auth}/client.js +11 -3
  4. package/dist/auth/errors.js +50 -0
  5. package/dist/{lib/auth → auth}/guard.js +7 -6
  6. package/dist/{lib/auth → auth}/login.js +147 -6
  7. package/dist/{lib/auth/auth-ops.js → auth/operations.js} +63 -13
  8. package/dist/auth/recipient.js +42 -0
  9. package/dist/{adapters → auth}/token-storage.js +28 -7
  10. package/dist/auth/workspaces.js +171 -0
  11. package/dist/cli-command.js +14 -0
  12. package/dist/cli-name.js +12 -0
  13. package/dist/cli.js +1 -1
  14. package/dist/cli2.js +25 -8
  15. package/dist/command-arguments.js +12 -0
  16. package/dist/commands/agent/index.js +60 -0
  17. package/dist/commands/app/index.js +11 -6
  18. package/dist/commands/auth/index.js +2 -3
  19. package/dist/commands/bucket/index.js +123 -0
  20. package/dist/commands/build/index.js +29 -0
  21. package/dist/commands/database/index.js +92 -2
  22. package/dist/commands/feedback/index.js +20 -0
  23. package/dist/commands/git/index.js +1 -1
  24. package/dist/commands/init/index.js +33 -0
  25. package/dist/commands/project/index.js +54 -5
  26. package/dist/controllers/agent-setup.js +52 -0
  27. package/dist/controllers/agent.js +228 -0
  28. package/dist/controllers/app-env-api.js +3 -2
  29. package/dist/controllers/app-env-file.js +1 -1
  30. package/dist/controllers/app-env.js +5 -5
  31. package/dist/controllers/app.js +423 -358
  32. package/dist/controllers/auth.js +62 -254
  33. package/dist/controllers/branch.js +5 -16
  34. package/dist/controllers/bucket.js +184 -0
  35. package/dist/controllers/build.js +88 -0
  36. package/dist/controllers/database.js +230 -85
  37. package/dist/controllers/feedback.js +90 -0
  38. package/dist/controllers/init.js +814 -0
  39. package/dist/controllers/project.js +345 -184
  40. package/dist/controllers/select-prompt-port.js +1 -0
  41. package/dist/{shell/errors.js → errors.js} +8 -40
  42. package/dist/lib/agent/cli-command.js +20 -0
  43. package/dist/lib/agent/constants.js +12 -0
  44. package/dist/lib/agent/package-manager.js +99 -0
  45. package/dist/lib/agent/setup-status.js +83 -0
  46. package/dist/lib/app/app-provider.js +168 -95
  47. package/dist/lib/app/branch-database-deploy.js +70 -42
  48. package/dist/lib/app/branch-database.js +39 -20
  49. package/dist/lib/app/build-settings.js +8 -3
  50. package/dist/lib/app/build.js +16 -14
  51. package/dist/lib/app/bun-project.js +1 -1
  52. package/dist/lib/app/compute-config.js +29 -31
  53. package/dist/lib/app/deploy-plan.js +1 -0
  54. package/dist/lib/app/deploy-progress.js +7 -7
  55. package/dist/lib/app/env-config.js +1 -1
  56. package/dist/lib/app/env-file.js +2 -2
  57. package/dist/lib/app/env-vars.js +1 -1
  58. package/dist/lib/app/local-dev.js +1 -1
  59. package/dist/lib/app/production-deploy-gate.js +3 -2
  60. package/dist/lib/bucket/provider.js +139 -0
  61. package/dist/lib/database/provider.js +235 -17
  62. package/dist/lib/diagnostics.js +2 -1
  63. package/dist/lib/feedback.js +15 -0
  64. package/dist/lib/git/local-branch.js +1 -1
  65. package/dist/lib/project/interactive-setup.js +6 -5
  66. package/dist/lib/project/local-pin.js +1 -1
  67. package/dist/lib/project/provider.js +93 -0
  68. package/dist/lib/project/resolution.js +11 -8
  69. package/dist/lib/project/setup.js +9 -6
  70. package/dist/lib/version.js +3 -2
  71. package/dist/lib/workspace-id.js +18 -0
  72. package/dist/payload-B88Qvzxk-CrtTXSOe.js +34 -0
  73. package/dist/presenters/agent.js +74 -0
  74. package/dist/presenters/app.js +33 -7
  75. package/dist/presenters/auth.js +3 -2
  76. package/dist/presenters/bucket.js +174 -0
  77. package/dist/presenters/database.js +193 -5
  78. package/dist/presenters/feedback.js +26 -0
  79. package/dist/presenters/init.js +30 -0
  80. package/dist/presenters/project.js +98 -4
  81. package/dist/shell/cli-command.js +2 -0
  82. package/dist/shell/command-meta.js +303 -4
  83. package/dist/shell/command-runner.js +13 -6
  84. package/dist/shell/help.js +6 -5
  85. package/dist/shell/output.js +65 -3
  86. package/dist/shell/prompt.js +12 -5
  87. package/dist/shell/runtime.js +4 -21
  88. package/dist/state-dir.js +12 -0
  89. package/dist/{shell/update-check.js → update-check.js} +6 -5
  90. package/dist/v8/cli.js +14699 -0
  91. package/dist/v8/sender.js +192 -0
  92. package/package.json +21 -13
  93. package/dist/adapters/mock-api.js +0 -136
  94. package/dist/lib/app/app-interaction.js +0 -5
  95. package/dist/shell/command-arguments.js +0 -6
  96. package/dist/use-cases/auth.js +0 -145
  97. package/dist/use-cases/branch.js +0 -47
  98. package/dist/use-cases/create-cli-gateways.js +0 -68
  99. package/dist/use-cases/project.js +0 -30
@@ -1,7 +1,7 @@
1
+ import { formatCommandArgument } from "../command-arguments.js";
1
2
  import { formatDescriptorLabel } from "../shell/command-meta.js";
2
3
  import { padDisplay, renderNextSteps, renderSummaryLine, renderVerboseBlock } from "../shell/ui.js";
3
4
  import { shortenHomePath } from "../lib/fs/home-path.js";
4
- import { formatCommandArgument } from "../shell/command-arguments.js";
5
5
  import { renderMutate, renderShow, serializeList } from "../output/patterns.js";
6
6
  import { renderResolvedProjectContextBlock } from "./verbose-context.js";
7
7
  import stringWidth from "string-width";
@@ -17,9 +17,13 @@ function renderProjectList(context, descriptor, result) {
17
17
  return lines;
18
18
  }
19
19
  const nameWidth = Math.max(4, ...result.projects.map((project) => stringWidth(project.name)));
20
+ const idWidth = Math.max(2, ...result.projects.map((project) => project.id.length));
20
21
  lines.push(rail);
21
- lines.push(`${rail} ${ui.accent(padDisplay("name", nameWidth))} ${ui.accent("id")}`);
22
- for (const project of result.projects) lines.push(`${rail} ${padDisplay(project.name, nameWidth)} ${project.id}`);
22
+ lines.push(`${rail} ${ui.accent(padDisplay("name", nameWidth))} ${ui.accent(padDisplay("id", idWidth))} ${ui.accent("region")}`);
23
+ for (const project of result.projects) {
24
+ const region = project.defaultRegion ? project.defaultRegion : ui.dim("none");
25
+ lines.push(`${rail} ${padDisplay(project.name, nameWidth)} ${padDisplay(project.id, idWidth)} ${region}`);
26
+ }
23
27
  if (result.localBinding?.status === "not-linked" || result.localBinding?.status === "invalid") lines.push(...renderNextSteps(["Link an existing Project you choose: prisma-cli project link <id-or-name>", "Create a new Project: prisma-cli project create <name>"]));
24
28
  return lines;
25
29
  }
@@ -86,6 +90,95 @@ function renderProjectSetup(context, _descriptor, result) {
86
90
  function serializeProjectSetup(result) {
87
91
  return result;
88
92
  }
93
+ function renderProjectRename(context, descriptor, result) {
94
+ return renderMutate({
95
+ title: "Renaming project.",
96
+ descriptor,
97
+ context: [
98
+ {
99
+ key: "workspace",
100
+ value: result.workspace.name
101
+ },
102
+ {
103
+ key: "project",
104
+ value: result.previousName
105
+ },
106
+ {
107
+ key: "id",
108
+ value: result.project.id,
109
+ tone: "dim"
110
+ }
111
+ ],
112
+ operationDescription: "Renaming project",
113
+ operationCount: 1,
114
+ details: [`The project is now named "${result.project.name}". Directory bindings pin the project id, so they stay valid.`]
115
+ }, context.ui);
116
+ }
117
+ function serializeProjectRename(result) {
118
+ return result;
119
+ }
120
+ function renderProjectRemove(context, descriptor, result) {
121
+ return renderMutate({
122
+ title: "Removing project.",
123
+ descriptor,
124
+ context: [
125
+ {
126
+ key: "workspace",
127
+ value: result.workspace.name
128
+ },
129
+ {
130
+ key: "project",
131
+ value: result.project.name
132
+ },
133
+ {
134
+ key: "id",
135
+ value: result.project.id,
136
+ tone: "dim"
137
+ }
138
+ ],
139
+ operationDescription: "Removing project",
140
+ operationCount: 1,
141
+ details: ["The project, its databases, and its apps were removed.", ...result.localPin.cleared ? ["This directory's local project binding was cleared."] : []]
142
+ }, context.ui);
143
+ }
144
+ function serializeProjectRemove(result) {
145
+ return result;
146
+ }
147
+ function renderProjectTransfer(context, descriptor, result) {
148
+ return renderMutate({
149
+ title: "Transferring project.",
150
+ descriptor,
151
+ context: [
152
+ {
153
+ key: "workspace",
154
+ value: result.workspace.name
155
+ },
156
+ {
157
+ key: "project",
158
+ value: result.project.name
159
+ },
160
+ {
161
+ key: "id",
162
+ value: result.project.id,
163
+ tone: "dim"
164
+ },
165
+ {
166
+ key: "recipient",
167
+ value: result.recipient.workspaceName ?? result.recipient.workspaceId ?? "workspace of the provided recipient token"
168
+ }
169
+ ],
170
+ operationDescription: "Transferring project",
171
+ operationCount: 1,
172
+ details: [
173
+ "The project now belongs to the recipient workspace; this workspace no longer has access.",
174
+ ...result.localPin.action === "rewritten" ? ["This directory's local project binding now points at the recipient workspace."] : [],
175
+ ...result.localPin.action === "cleared" ? ["This directory's local project binding was cleared."] : []
176
+ ]
177
+ }, context.ui);
178
+ }
179
+ function serializeProjectTransfer(result) {
180
+ return result;
181
+ }
89
182
  function renderGitConnect(context, descriptor, result) {
90
183
  const connection = result.repositoryConnection;
91
184
  return renderMutate({
@@ -152,6 +245,7 @@ function renderBoundProjectShow(context, descriptor, result) {
152
245
  lines.push(rail);
153
246
  lines.push(`${rail} ${ui.dim("→")} ${ui.link(result.project.url)}`);
154
247
  }
248
+ if (result.project.defaultRegion) lines.push(`${rail} ${ui.accent(padDisplay("region", keyWidth))} ${ui.dim(result.project.defaultRegion)}`);
155
249
  lines.push(...renderResolvedProjectContextBlock(context.ui, {
156
250
  workspace: result.workspace,
157
251
  project: result.project,
@@ -171,4 +265,4 @@ function formatGitConnectionDetail(status) {
171
265
  }
172
266
  }
173
267
  //#endregion
174
- export { renderGitConnect, renderGitDisconnect, renderProjectList, renderProjectSetup, renderProjectShow, serializeProjectList, serializeProjectSetup, serializeProjectShow };
268
+ export { renderGitConnect, renderGitDisconnect, renderProjectList, renderProjectRemove, renderProjectRename, renderProjectSetup, renderProjectShow, renderProjectTransfer, serializeProjectList, serializeProjectRemove, serializeProjectRename, serializeProjectSetup, serializeProjectShow, serializeProjectTransfer };
@@ -0,0 +1,2 @@
1
+ import "../cli-command.js";
2
+ export {};
@@ -1,5 +1,11 @@
1
+ import { resolvePrismaCliPackageCommandFormatterSync } from "../lib/agent/cli-command.js";
2
+ import { PRISMA_AGENT_INSTALL_ARGS, PRISMA_AGENT_STATUS_ARGS, PRISMA_AGENT_UPDATE_ARGS, PRISMA_COMPUTE_AGENT_SKILL } from "../lib/agent/constants.js";
1
3
  //#region src/shell/command-meta.ts
2
4
  const COMMAND_DESCRIPTOR_ID = Symbol("prisma.commandDescriptorId");
5
+ function agentCommandExamples(runtime, commands) {
6
+ const formatCommand = resolvePrismaCliPackageCommandFormatterSync(runtime.cwd);
7
+ return commands.map((command) => formatCommand(command));
8
+ }
3
9
  const DESCRIPTORS = [
4
10
  {
5
11
  id: "root",
@@ -14,6 +20,99 @@ const DESCRIPTORS = [
14
20
  description: "Show CLI build and environment",
15
21
  examples: ["prisma-cli version", "prisma-cli version --json"]
16
22
  },
23
+ {
24
+ id: "feedback",
25
+ path: ["prisma", "feedback"],
26
+ description: "Send feedback to the Prisma CLI team",
27
+ longDescription: "Anonymous unless --email is passed. Every submission includes the CLI version, node version, and OS platform/arch, and nothing else.",
28
+ examples: ["prisma-cli feedback \"the deploy flow is great\"", "prisma-cli feedback \"please add X\" --email you@example.com"]
29
+ },
30
+ {
31
+ id: "init",
32
+ path: ["prisma", "init"],
33
+ description: "Write a committed compute config for this app",
34
+ examples: (runtime) => agentCommandExamples(runtime, [
35
+ ["init"],
36
+ [
37
+ "init",
38
+ "--framework",
39
+ "hono",
40
+ "--entry",
41
+ "src/index.ts"
42
+ ],
43
+ [
44
+ "init",
45
+ "--format",
46
+ "json"
47
+ ],
48
+ ["init", "--no-link"]
49
+ ])
50
+ },
51
+ {
52
+ id: "agent",
53
+ path: ["prisma", "agent"],
54
+ description: "Install Prisma context for AI coding agents",
55
+ examples: (runtime) => agentCommandExamples(runtime, [
56
+ PRISMA_AGENT_INSTALL_ARGS,
57
+ PRISMA_AGENT_UPDATE_ARGS,
58
+ PRISMA_AGENT_STATUS_ARGS
59
+ ])
60
+ },
61
+ {
62
+ id: "agent.install",
63
+ path: [
64
+ "prisma",
65
+ "agent",
66
+ "install"
67
+ ],
68
+ description: "Install Prisma skills for AI coding agents",
69
+ examples: (runtime) => agentCommandExamples(runtime, [
70
+ PRISMA_AGENT_INSTALL_ARGS,
71
+ [
72
+ ...PRISMA_AGENT_INSTALL_ARGS,
73
+ "--agent",
74
+ "codex"
75
+ ],
76
+ [...PRISMA_AGENT_INSTALL_ARGS, "--all-agents"],
77
+ [
78
+ ...PRISMA_AGENT_INSTALL_ARGS,
79
+ "--skill",
80
+ PRISMA_COMPUTE_AGENT_SKILL
81
+ ]
82
+ ])
83
+ },
84
+ {
85
+ id: "agent.update",
86
+ path: [
87
+ "prisma",
88
+ "agent",
89
+ "update"
90
+ ],
91
+ description: "Refresh Prisma skills for AI coding agents",
92
+ examples: (runtime) => agentCommandExamples(runtime, [
93
+ PRISMA_AGENT_UPDATE_ARGS,
94
+ [
95
+ ...PRISMA_AGENT_UPDATE_ARGS,
96
+ "--agent",
97
+ "codex"
98
+ ],
99
+ [...PRISMA_AGENT_UPDATE_ARGS, "--all-agents"]
100
+ ])
101
+ },
102
+ {
103
+ id: "agent.status",
104
+ path: [
105
+ "prisma",
106
+ "agent",
107
+ "status"
108
+ ],
109
+ description: "Show installed Prisma skills",
110
+ examples: (runtime) => agentCommandExamples(runtime, [
111
+ PRISMA_AGENT_STATUS_ARGS,
112
+ [...PRISMA_AGENT_STATUS_ARGS, "--json"],
113
+ [...PRISMA_AGENT_STATUS_ARGS, "--global"]
114
+ ])
115
+ },
17
116
  {
18
117
  id: "auth",
19
118
  path: ["prisma", "auth"],
@@ -124,6 +223,22 @@ const DESCRIPTORS = [
124
223
  description: "View your Platform branches",
125
224
  examples: ["prisma-cli branch list"]
126
225
  },
226
+ {
227
+ id: "build",
228
+ path: ["prisma", "build"],
229
+ description: "Inspect builds",
230
+ examples: ["prisma-cli build logs <build_id>"]
231
+ },
232
+ {
233
+ id: "build.logs",
234
+ path: [
235
+ "prisma",
236
+ "build",
237
+ "logs"
238
+ ],
239
+ description: "Stream the logs for a build",
240
+ examples: ["prisma-cli build logs <build_id>", "prisma-cli build logs <build_id> --follow"]
241
+ },
127
242
  {
128
243
  id: "database",
129
244
  path: ["prisma", "database"],
@@ -134,6 +249,105 @@ const DESCRIPTORS = [
134
249
  "prisma-cli database connection create db_123"
135
250
  ]
136
251
  },
252
+ {
253
+ id: "bucket",
254
+ path: ["prisma", "bucket"],
255
+ description: "Manage object-store buckets for a project",
256
+ examples: [
257
+ "prisma-cli bucket list",
258
+ "prisma-cli bucket create",
259
+ "prisma-cli bucket key create bkt_123"
260
+ ]
261
+ },
262
+ {
263
+ id: "bucket.list",
264
+ path: [
265
+ "prisma",
266
+ "bucket",
267
+ "list"
268
+ ],
269
+ description: "List object-store buckets for the resolved project",
270
+ examples: [
271
+ "prisma-cli bucket list",
272
+ "prisma-cli bucket list --branch preview",
273
+ "prisma-cli bucket list --json"
274
+ ]
275
+ },
276
+ {
277
+ id: "bucket.create",
278
+ path: [
279
+ "prisma",
280
+ "bucket",
281
+ "create"
282
+ ],
283
+ description: "Create an object-store bucket",
284
+ examples: [
285
+ "prisma-cli bucket create",
286
+ "prisma-cli bucket create --name my-store",
287
+ "prisma-cli bucket create --branch preview --json"
288
+ ]
289
+ },
290
+ {
291
+ id: "bucket.delete",
292
+ path: [
293
+ "prisma",
294
+ "bucket",
295
+ "delete"
296
+ ],
297
+ description: "Delete a bucket and all its access keys",
298
+ examples: ["prisma-cli bucket delete bkt_123"]
299
+ },
300
+ {
301
+ id: "bucket.key",
302
+ path: [
303
+ "prisma",
304
+ "bucket",
305
+ "key"
306
+ ],
307
+ description: "Manage access keys for an object-store bucket",
308
+ examples: [
309
+ "prisma-cli bucket key list bkt_123",
310
+ "prisma-cli bucket key create bkt_123",
311
+ "prisma-cli bucket key delete bkt_123 bkey_456"
312
+ ]
313
+ },
314
+ {
315
+ id: "bucket.key.list",
316
+ path: [
317
+ "prisma",
318
+ "bucket",
319
+ "key",
320
+ "list"
321
+ ],
322
+ description: "List access keys for a bucket",
323
+ examples: ["prisma-cli bucket key list bkt_123", "prisma-cli bucket key list bkt_123 --json"]
324
+ },
325
+ {
326
+ id: "bucket.key.create",
327
+ path: [
328
+ "prisma",
329
+ "bucket",
330
+ "key",
331
+ "create"
332
+ ],
333
+ description: "Create a bucket access key and print its one-time credentials",
334
+ examples: [
335
+ "prisma-cli bucket key create bkt_123",
336
+ "prisma-cli bucket key create bkt_123 --role read",
337
+ "prisma-cli bucket key create bkt_123 --name ci-key --role read_write"
338
+ ]
339
+ },
340
+ {
341
+ id: "bucket.key.delete",
342
+ path: [
343
+ "prisma",
344
+ "bucket",
345
+ "key",
346
+ "delete"
347
+ ],
348
+ description: "Revoke and delete a bucket access key",
349
+ examples: ["prisma-cli bucket key delete bkt_123 bkey_456"]
350
+ },
137
351
  {
138
352
  id: "git",
139
353
  path: ["prisma", "git"],
@@ -184,6 +398,36 @@ const DESCRIPTORS = [
184
398
  "prisma-cli project link \"Acme Dashboard\" --json"
185
399
  ]
186
400
  },
401
+ {
402
+ id: "project.rename",
403
+ path: [
404
+ "prisma",
405
+ "project",
406
+ "rename"
407
+ ],
408
+ description: "Rename the resolved Project",
409
+ examples: ["prisma-cli project rename \"Acme Dashboard v2\"", "prisma-cli project rename billing-api --project proj_123"]
410
+ },
411
+ {
412
+ id: "project.remove",
413
+ path: [
414
+ "prisma",
415
+ "project",
416
+ "remove"
417
+ ],
418
+ description: "Remove a Project permanently after exact id confirmation",
419
+ examples: ["prisma-cli project remove proj_123 --confirm proj_123"]
420
+ },
421
+ {
422
+ id: "project.transfer",
423
+ path: [
424
+ "prisma",
425
+ "project",
426
+ "transfer"
427
+ ],
428
+ description: "Transfer a Project to another workspace after exact id confirmation",
429
+ examples: ["prisma-cli project transfer proj_123 --to-workspace \"Prisma Labs\" --confirm proj_123", "prisma-cli project transfer proj_123 --recipient-token <token> --confirm proj_123"]
430
+ },
187
431
  {
188
432
  id: "git.connect",
189
433
  path: [
@@ -252,6 +496,26 @@ const DESCRIPTORS = [
252
496
  description: "Create a Prisma Postgres database and print its one-time connection URL",
253
497
  examples: ["prisma-cli database create my-db", "prisma-cli database create my-db --branch feature/foo --region eu-central-1"]
254
498
  },
499
+ {
500
+ id: "database.usage",
501
+ path: [
502
+ "prisma",
503
+ "database",
504
+ "usage"
505
+ ],
506
+ description: "Show usage metrics for a database",
507
+ examples: ["prisma-cli database usage db_123", "prisma-cli database usage acme-production --from 2026-06-01 --to 2026-06-30"]
508
+ },
509
+ {
510
+ id: "database.restore",
511
+ path: [
512
+ "prisma",
513
+ "database",
514
+ "restore"
515
+ ],
516
+ description: "Restore a database from a backup after exact id confirmation",
517
+ examples: ["prisma-cli database restore db_123 --backup bkp_456 --confirm db_123"]
518
+ },
255
519
  {
256
520
  id: "database.remove",
257
521
  path: [
@@ -262,6 +526,27 @@ const DESCRIPTORS = [
262
526
  description: "Remove a database after exact id confirmation",
263
527
  examples: ["prisma-cli database remove db_123 --confirm db_123"]
264
528
  },
529
+ {
530
+ id: "database.backup",
531
+ path: [
532
+ "prisma",
533
+ "database",
534
+ "backup"
535
+ ],
536
+ description: "Inspect platform-created database backups",
537
+ examples: ["prisma-cli database backup list db_123"]
538
+ },
539
+ {
540
+ id: "database.backup.list",
541
+ path: [
542
+ "prisma",
543
+ "database",
544
+ "backup",
545
+ "list"
546
+ ],
547
+ description: "List backups for a database",
548
+ examples: ["prisma-cli database backup list db_123", "prisma-cli database backup list acme-production --limit 50"]
549
+ },
265
550
  {
266
551
  id: "database.connection",
267
552
  path: [
@@ -298,6 +583,17 @@ const DESCRIPTORS = [
298
583
  description: "Create a database connection and print its one-time connection URL",
299
584
  examples: ["prisma-cli database connection create db_123", "prisma-cli database connection create db_123 --name readonly"]
300
585
  },
586
+ {
587
+ id: "database.connection.rotate",
588
+ path: [
589
+ "prisma",
590
+ "database",
591
+ "connection",
592
+ "rotate"
593
+ ],
594
+ description: "Rotate connection credentials and print the new one-time connection URL",
595
+ examples: ["prisma-cli database connection rotate conn_123 --confirm conn_123"]
596
+ },
301
597
  {
302
598
  id: "database.connection.remove",
303
599
  path: [
@@ -341,7 +637,6 @@ const DESCRIPTORS = [
341
637
  "deploy"
342
638
  ],
343
639
  description: "Creates a new deployment for the app",
344
- longDescription: "Agent skills for guided Next.js deploys are available from the Prisma CLI skill cluster.",
345
640
  examples: [
346
641
  "prisma-cli app deploy",
347
642
  "prisma-cli app deploy --project proj_123",
@@ -351,9 +646,9 @@ const DESCRIPTORS = [
351
646
  "prisma-cli app deploy --db",
352
647
  "prisma-cli app deploy --db --yes",
353
648
  "prisma-cli app deploy --app my-app --framework nextjs --http-port 3000",
649
+ "prisma-cli app deploy --app my-app --region us-west-1",
354
650
  "prisma-cli app deploy --branch feat-login --framework hono",
355
651
  "prisma-cli app deploy --prod --yes",
356
- "pnpm dlx skills@latest add prisma/prisma-cli/skills#cli-v<cli-version> --all",
357
652
  "prisma-cli app deploy --framework bun --entry src/server.ts"
358
653
  ]
359
654
  },
@@ -503,8 +798,12 @@ const DESCRIPTORS = [
503
798
  "app",
504
799
  "remove"
505
800
  ],
506
- description: "Remove the app from the current branch",
507
- examples: ["prisma-cli app remove --app hello-world", "prisma-cli app remove --app hello-world --yes"]
801
+ description: "Remove the app from the resolved branch",
802
+ examples: [
803
+ "prisma-cli app remove --app hello-world",
804
+ "prisma-cli app remove --app hello-world --yes",
805
+ "prisma-cli app remove --app hello-world --branch feature/foo --yes"
806
+ ]
508
807
  },
509
808
  {
510
809
  id: "project.env",
@@ -1,17 +1,19 @@
1
- import { CliError, authConfigInvalidError, authRequiredError, commandCanceledError } from "./errors.js";
1
+ import { CliError, authConfigInvalidError, authRequiredError, commandCanceledError } from "../errors.js";
2
2
  import { getCommandDescriptor } from "./command-meta.js";
3
+ import { renderSummaryLine } from "./ui.js";
4
+ import { isEmptyServiceTokenError } from "../auth/operations.js";
3
5
  import { resolveGlobalFlags } from "./global-flags.js";
4
6
  import { createCommandContext } from "./runtime.js";
5
- import { cliErrorToJson, writeHumanError, writeHumanLines, writeJsonError, writeJsonEvent, writeJsonSuccess } from "./output.js";
6
7
  import { collectCommandDiagnostics } from "../lib/diagnostics.js";
7
8
  import { renderCommandDiagnostics } from "./diagnostics-output.js";
9
+ import { cliErrorToJson, writeHumanError, writeHumanLines, writeJsonError, writeJsonEvent, writeJsonSuccess } from "./output.js";
8
10
  import { AuthError } from "@prisma/management-api-sdk";
9
11
  //#region src/shell/command-runner.ts
10
12
  function toCliError(error, runtime) {
11
13
  if (isCancellationError(error) || runtime.signal.aborted) return commandCanceledError();
12
14
  if (error instanceof CliError) return error;
13
15
  if (error instanceof AuthError) return authRequiredError(["prisma-cli auth login"], { debug: error.message });
14
- if (error instanceof Error && error.message.startsWith("PRISMA_SERVICE_TOKEN is set but empty")) return authConfigInvalidError(error.message);
16
+ if (isEmptyServiceTokenError(error)) return authConfigInvalidError(error.message);
15
17
  return null;
16
18
  }
17
19
  function isCancellationError(error) {
@@ -48,11 +50,16 @@ async function writeCommandSuccess(context, descriptor, success, presenter, dura
48
50
  return;
49
51
  }
50
52
  const rendered = presenter.renderHuman(context, descriptor, success.result);
53
+ const warningLines = success.warnings.map((warning) => renderSummaryLine(context.ui, "warning", warning));
51
54
  const diagnostics = await renderBestEffortCommandDiagnostics(context, {
52
55
  enabled: context.flags.verbose && rendered.length > 0,
53
56
  durationMs
54
57
  });
55
- const humanLines = [...rendered, ...diagnostics];
58
+ const humanLines = [
59
+ ...rendered,
60
+ ...warningLines,
61
+ ...diagnostics
62
+ ];
56
63
  if (stdout.length > 0 && humanLines.length > 0) humanLines.push("");
57
64
  writeHumanLines(context.output, humanLines);
58
65
  writeStdoutLines(context, stdout);
@@ -75,12 +82,12 @@ async function renderBestEffortCommandDiagnostics(context, options) {
75
82
  return [];
76
83
  }
77
84
  }
78
- async function runStreamingCommand(runtime, commandName, options, handler) {
85
+ async function runStreamingCommand(runtime, commandName, options, handler, streamOptions) {
79
86
  const flags = resolveGlobalFlags(runtime.argv, options);
80
87
  const context = await createCommandContext(runtime, flags);
81
88
  try {
82
89
  await handler(context);
83
- if (flags.json) writeJsonEvent(context.output, {
90
+ if (flags.json && (streamOptions?.emitJsonSuccessEvent ?? true)) writeJsonEvent(context.output, {
84
91
  type: "success",
85
92
  command: commandName,
86
93
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -1,6 +1,6 @@
1
1
  import { formatDescriptorLabel, getDescriptorForCommand } from "./command-meta.js";
2
- import { COMPACT_GLOBAL_OPTION_FLAGS, resolveGlobalFlags } from "./global-flags.js";
3
2
  import { createShellUi, padDisplay, wrapText } from "./ui.js";
3
+ import { COMPACT_GLOBAL_OPTION_FLAGS, resolveGlobalFlags } from "./global-flags.js";
4
4
  //#region src/shell/help.ts
5
5
  function renderHelp(command, runtime) {
6
6
  const descriptor = getDescriptorForCommand(command);
@@ -12,7 +12,7 @@ function renderHelp(command, runtime) {
12
12
  if (visibleCommands.length > 0) lines.push(...renderCommandRows(rail, ui, visibleCommands));
13
13
  lines.push(...renderLongDescription(rail, ui, descriptor.longDescription));
14
14
  lines.push(...renderVisibleOptions(rail, ui, visibleCommands, visibleOptions));
15
- lines.push(...renderExamples(rail, descriptor.examples));
15
+ lines.push(...renderExamples(rail, runtime, descriptor.examples));
16
16
  lines.push(...renderDocsPath(rail, ui, descriptor.docsPath));
17
17
  lines.push("");
18
18
  return `${lines.join("\n")}`;
@@ -30,12 +30,13 @@ function renderVisibleOptions(rail, ui, visibleCommands, visibleOptions) {
30
30
  function shouldLabelGlobalOptions(visibleCommands, visibleOptions) {
31
31
  return visibleCommands.length > 0 && visibleOptions.every((option) => COMPACT_GLOBAL_OPTION_FLAGS.includes(option.flags));
32
32
  }
33
- function renderExamples(rail, examples) {
34
- if (!examples || examples.length === 0) return [];
33
+ function renderExamples(rail, runtime, examples) {
34
+ const resolvedExamples = typeof examples === "function" ? examples(runtime) : examples;
35
+ if (!resolvedExamples || resolvedExamples.length === 0) return [];
35
36
  return [
36
37
  `${rail}`,
37
38
  `${rail} Examples:`,
38
- ...examples.map((example) => `${rail} $ ${example}`)
39
+ ...resolvedExamples.map((example) => `${rail} $ ${example}`)
39
40
  ];
40
41
  }
41
42
  function renderDocsPath(rail, ui, docsPath) {
@@ -1,3 +1,4 @@
1
+ import { formatCommandArgument } from "../command-arguments.js";
1
2
  import { renderNextSteps, renderSummaryLine } from "./ui.js";
2
3
  //#region src/shell/output.ts
3
4
  function writeJsonSuccess(output, success) {
@@ -23,15 +24,76 @@ function cliErrorToJson(error) {
23
24
  docsUrl: error.docsUrl
24
25
  };
25
26
  }
26
- function formatUnexpectedError(error, trace) {
27
+ function formatUnexpectedError(error, trace, feedbackCommand) {
28
+ const feedbackLine = feedbackCommand ? `Tell us what happened: ${feedbackCommand}` : null;
27
29
  const debug = error instanceof Error ? error.stack ?? error.message : String(error);
28
- if (trace) return `${debug}\n`;
30
+ if (trace) return [
31
+ debug,
32
+ ...feedbackLine ? [feedbackLine] : [],
33
+ ""
34
+ ].join("\n");
29
35
  return [
30
36
  `Unexpected CLI error: ${error instanceof Error && error.message ? error.message : String(error)}`,
31
37
  "More: Re-run with --trace for deeper diagnostics",
38
+ ...feedbackLine ? [feedbackLine] : [],
32
39
  ""
33
40
  ].join("\n");
34
41
  }
42
+ /** Command groups whose second argv token names the subcommand. */
43
+ const COMMAND_GROUPS = new Set([
44
+ "agent",
45
+ "auth",
46
+ "project",
47
+ "git",
48
+ "branch",
49
+ "build",
50
+ "database",
51
+ "app"
52
+ ]);
53
+ /** Best-effort `command` label for a crash that predates envelope assembly. */
54
+ function unexpectedErrorCommandLabel(argv) {
55
+ const [group, action] = argv.filter((arg) => !arg.startsWith("-"));
56
+ if (!group) return "unknown";
57
+ return action && COMMAND_GROUPS.has(group) ? `${group}.${action}` : group;
58
+ }
59
+ /**
60
+ * Pre-filled feedback command for a crash, so the report arrives carrying the
61
+ * failing command and the error's first line.
62
+ */
63
+ function unexpectedErrorFeedbackCommand(argv, error) {
64
+ return `prisma-cli feedback ${formatCommandArgument(`${unexpectedErrorCommandLabel(argv).replace(".", " ")} crashed: ${(error instanceof Error && error.message ? error.message : String(error)).split("\n")[0]}`.slice(0, 200))}`;
65
+ }
66
+ /**
67
+ * A crash must not break the `--json` contract: agents still get a structured
68
+ * envelope, with a recover action pointing at the feedback command.
69
+ */
70
+ function writeJsonUnexpectedError(output, argv, error) {
71
+ const feedbackCommand = unexpectedErrorFeedbackCommand(argv, error);
72
+ output.stdout.write(`${JSON.stringify({
73
+ ok: false,
74
+ command: unexpectedErrorCommandLabel(argv),
75
+ error: {
76
+ code: "UNEXPECTED_ERROR",
77
+ domain: "cli",
78
+ severity: "error",
79
+ summary: "Unexpected CLI error",
80
+ why: error instanceof Error && error.message ? error.message : String(error),
81
+ fix: "Re-run with --trace for deeper diagnostics, and report the crash.",
82
+ where: null,
83
+ meta: {},
84
+ docsUrl: null
85
+ },
86
+ warnings: [],
87
+ nextSteps: [feedbackCommand],
88
+ nextActions: [{
89
+ kind: "run-command",
90
+ journey: "recover",
91
+ label: "Report this crash to the Prisma team",
92
+ command: feedbackCommand,
93
+ reason: "This looks like a CLI bug; the pre-filled report carries the failing command and error."
94
+ }]
95
+ }, null, 2)}\n`);
96
+ }
35
97
  function writeJsonError(output, command, error) {
36
98
  output.stdout.write(`${JSON.stringify({
37
99
  ok: false,
@@ -79,4 +141,4 @@ function writeHumanError(output, ui, error, options) {
79
141
  writeHumanLines(output, lines);
80
142
  }
81
143
  //#endregion
82
- export { cliErrorToJson, formatUnexpectedError, writeHumanError, writeHumanLines, writeJsonError, writeJsonEvent, writeJsonSuccess };
144
+ export { cliErrorToJson, formatUnexpectedError, unexpectedErrorFeedbackCommand, writeHumanError, writeHumanLines, writeJsonError, writeJsonEvent, writeJsonSuccess, writeJsonUnexpectedError };