@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.
- package/README.md +3 -14
- package/dist/adapters/local-state.js +14 -3
- package/dist/{lib/auth → auth}/client.js +11 -3
- package/dist/auth/errors.js +50 -0
- package/dist/{lib/auth → auth}/guard.js +7 -6
- package/dist/{lib/auth → auth}/login.js +147 -6
- package/dist/{lib/auth/auth-ops.js → auth/operations.js} +63 -13
- package/dist/auth/recipient.js +42 -0
- package/dist/{adapters → auth}/token-storage.js +28 -7
- package/dist/auth/workspaces.js +171 -0
- package/dist/cli-command.js +14 -0
- package/dist/cli-name.js +12 -0
- package/dist/cli.js +1 -1
- package/dist/cli2.js +25 -8
- package/dist/command-arguments.js +12 -0
- package/dist/commands/agent/index.js +60 -0
- package/dist/commands/app/index.js +11 -6
- package/dist/commands/auth/index.js +2 -3
- package/dist/commands/bucket/index.js +123 -0
- package/dist/commands/build/index.js +29 -0
- package/dist/commands/database/index.js +92 -2
- package/dist/commands/feedback/index.js +20 -0
- package/dist/commands/git/index.js +1 -1
- package/dist/commands/init/index.js +33 -0
- package/dist/commands/project/index.js +54 -5
- package/dist/controllers/agent-setup.js +52 -0
- package/dist/controllers/agent.js +228 -0
- package/dist/controllers/app-env-api.js +3 -2
- package/dist/controllers/app-env-file.js +1 -1
- package/dist/controllers/app-env.js +5 -5
- package/dist/controllers/app.js +423 -358
- package/dist/controllers/auth.js +62 -254
- package/dist/controllers/branch.js +5 -16
- package/dist/controllers/bucket.js +184 -0
- package/dist/controllers/build.js +88 -0
- package/dist/controllers/database.js +230 -85
- package/dist/controllers/feedback.js +90 -0
- package/dist/controllers/init.js +814 -0
- package/dist/controllers/project.js +345 -184
- package/dist/controllers/select-prompt-port.js +1 -0
- package/dist/{shell/errors.js → errors.js} +8 -40
- package/dist/lib/agent/cli-command.js +20 -0
- package/dist/lib/agent/constants.js +12 -0
- package/dist/lib/agent/package-manager.js +99 -0
- package/dist/lib/agent/setup-status.js +83 -0
- package/dist/lib/app/app-provider.js +168 -95
- package/dist/lib/app/branch-database-deploy.js +70 -42
- package/dist/lib/app/branch-database.js +39 -20
- package/dist/lib/app/build-settings.js +8 -3
- package/dist/lib/app/build.js +16 -14
- package/dist/lib/app/bun-project.js +1 -1
- package/dist/lib/app/compute-config.js +29 -31
- package/dist/lib/app/deploy-plan.js +1 -0
- package/dist/lib/app/deploy-progress.js +7 -7
- package/dist/lib/app/env-config.js +1 -1
- package/dist/lib/app/env-file.js +2 -2
- package/dist/lib/app/env-vars.js +1 -1
- package/dist/lib/app/local-dev.js +1 -1
- package/dist/lib/app/production-deploy-gate.js +3 -2
- package/dist/lib/bucket/provider.js +139 -0
- package/dist/lib/database/provider.js +235 -17
- package/dist/lib/diagnostics.js +2 -1
- package/dist/lib/feedback.js +15 -0
- package/dist/lib/git/local-branch.js +1 -1
- package/dist/lib/project/interactive-setup.js +6 -5
- package/dist/lib/project/local-pin.js +1 -1
- package/dist/lib/project/provider.js +93 -0
- package/dist/lib/project/resolution.js +11 -8
- package/dist/lib/project/setup.js +9 -6
- package/dist/lib/version.js +3 -2
- package/dist/lib/workspace-id.js +18 -0
- package/dist/payload-B88Qvzxk-CrtTXSOe.js +34 -0
- package/dist/presenters/agent.js +74 -0
- package/dist/presenters/app.js +33 -7
- package/dist/presenters/auth.js +3 -2
- package/dist/presenters/bucket.js +174 -0
- package/dist/presenters/database.js +193 -5
- package/dist/presenters/feedback.js +26 -0
- package/dist/presenters/init.js +30 -0
- package/dist/presenters/project.js +98 -4
- package/dist/shell/cli-command.js +2 -0
- package/dist/shell/command-meta.js +303 -4
- package/dist/shell/command-runner.js +13 -6
- package/dist/shell/help.js +6 -5
- package/dist/shell/output.js +65 -3
- package/dist/shell/prompt.js +12 -5
- package/dist/shell/runtime.js +4 -21
- package/dist/state-dir.js +12 -0
- package/dist/{shell/update-check.js → update-check.js} +6 -5
- package/dist/v8/cli.js +14699 -0
- package/dist/v8/sender.js +192 -0
- package/package.json +21 -13
- package/dist/adapters/mock-api.js +0 -136
- package/dist/lib/app/app-interaction.js +0 -5
- package/dist/shell/command-arguments.js +0 -6
- package/dist/use-cases/auth.js +0 -145
- package/dist/use-cases/branch.js +0 -47
- package/dist/use-cases/create-cli-gateways.js +0 -68
- 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)
|
|
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 };
|
|
@@ -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
|
|
507
|
-
examples: [
|
|
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 "
|
|
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
|
|
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 = [
|
|
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(),
|
package/dist/shell/help.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
...
|
|
39
|
+
...resolvedExamples.map((example) => `${rail} $ ${example}`)
|
|
39
40
|
];
|
|
40
41
|
}
|
|
41
42
|
function renderDocsPath(rail, ui, docsPath) {
|
package/dist/shell/output.js
CHANGED
|
@@ -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
|
|
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 };
|