@prisma/cli 3.0.0-dev.36.1 → 3.0.0-dev.38.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
@@ -42,41 +42,52 @@ async function readAuthState(env) {
42
42
  authenticated: false,
43
43
  provider: null,
44
44
  user: null,
45
- workspace: null
45
+ workspace: null,
46
+ credential: null
46
47
  };
48
+ const client = await requireComputeAuth(env);
49
+ const currentPrincipal = await readCurrentPrincipalAuthState(client);
50
+ if (currentPrincipal) return currentPrincipal;
47
51
  const claims = decodeJwtPayload(tokens.accessToken);
48
52
  return buildAuthState({
49
53
  workspaceIdFromCredential: tokens.workspaceId,
50
54
  claims,
51
- env
55
+ env,
56
+ client
52
57
  });
53
58
  }
54
59
  async function readServiceTokenAuthState(token, env) {
60
+ const client = await requireComputeAuth(env);
61
+ const currentPrincipal = await readCurrentPrincipalAuthState(client);
62
+ if (currentPrincipal) return currentPrincipal;
55
63
  const claims = decodeJwtPayload(token);
56
64
  const workspaceId = workspaceIdFromClaims(claims);
57
65
  if (!workspaceId) return {
58
66
  authenticated: false,
59
67
  provider: null,
60
68
  user: null,
61
- workspace: null
69
+ workspace: null,
70
+ credential: null
62
71
  };
63
72
  return buildAuthState({
64
73
  workspaceIdFromCredential: workspaceId,
65
74
  claims,
66
- env
75
+ env,
76
+ client
67
77
  });
68
78
  }
69
- async function buildAuthState({ workspaceIdFromCredential, claims, env }) {
79
+ async function buildAuthState({ workspaceIdFromCredential, claims, env, client }) {
70
80
  let workspaceId = workspaceIdFromCredential;
71
81
  let workspaceName = workspaceIdFromCredential;
72
- const client = await requireComputeAuth(env);
82
+ client ??= await requireComputeAuth(env);
73
83
  if (client) try {
74
84
  const { data, response } = await client.GET("/v1/workspaces/{id}", { params: { path: { id: workspaceIdFromCredential } } });
75
85
  if (response?.status === 401) return {
76
86
  authenticated: false,
77
87
  provider: null,
78
88
  user: null,
79
- workspace: null
89
+ workspace: null,
90
+ credential: null
80
91
  };
81
92
  if (data?.data?.id) {
82
93
  workspaceId = data.data.id;
@@ -92,9 +103,39 @@ async function buildAuthState({ workspaceIdFromCredential, claims, env }) {
92
103
  workspace: {
93
104
  id: workspaceId,
94
105
  name: workspaceName
95
- }
106
+ },
107
+ credential: null
96
108
  };
97
109
  }
110
+ async function readCurrentPrincipalAuthState(client) {
111
+ if (!client) return null;
112
+ try {
113
+ const { data, response } = await client.GET("/v1/me");
114
+ if (response?.status === 401) return {
115
+ authenticated: false,
116
+ provider: null,
117
+ user: null,
118
+ workspace: null,
119
+ credential: null
120
+ };
121
+ const principal = data?.data;
122
+ if (!principal) return null;
123
+ if (!principal.credential) return null;
124
+ return {
125
+ authenticated: true,
126
+ provider: null,
127
+ user: principal.user ? {
128
+ id: principal.user.id,
129
+ email: principal.user.email,
130
+ name: principal.user.name
131
+ } : null,
132
+ workspace: principal.workspace,
133
+ credential: principal.credential
134
+ };
135
+ } catch {
136
+ return null;
137
+ }
138
+ }
98
139
  async function performLogout(env) {
99
140
  await new FileTokenStorage(env).clearTokens();
100
141
  }
@@ -7,9 +7,10 @@ function renderAuthSuccess(context, descriptor, command, result) {
7
7
  key: "provider",
8
8
  value: providerLabel(result.provider)
9
9
  });
10
- if (result.user) rows.push({
10
+ const userLabel = authUserLabel(result);
11
+ if (userLabel) rows.push({
11
12
  key: "user",
12
- value: result.user.email
13
+ value: userLabel
13
14
  });
14
15
  if (result.workspace?.name) rows.push({
15
16
  key: "workspace",
@@ -45,10 +46,7 @@ function renderAuthSuccess(context, descriptor, command, result) {
45
46
  value: "signed in",
46
47
  tone: "success"
47
48
  },
48
- ...result.user ? [{
49
- key: "user",
50
- value: result.user.email
51
- }] : [],
49
+ ...authUserRows(result),
52
50
  ...result.provider ? [{
53
51
  key: "provider",
54
52
  value: providerLabel(result.provider)
@@ -69,5 +67,20 @@ function providerLabel(provider) {
69
67
  if (provider === "google") return "Google";
70
68
  return "";
71
69
  }
70
+ function authUserLabel(result) {
71
+ return result.user?.email ?? credentialUserLabel(result);
72
+ }
73
+ function authUserRows(result) {
74
+ const userLabel = authUserLabel(result);
75
+ return userLabel ? [{
76
+ key: "user",
77
+ value: userLabel
78
+ }] : [];
79
+ }
80
+ function credentialUserLabel(result) {
81
+ if (result.credential?.type === "service_token") return result.credential.name ? `<service token: ${result.credential.name}>` : "<service token>";
82
+ if (result.credential?.type === "management_token") return result.credential.name ? `<management token: ${result.credential.name}>` : "<management token>";
83
+ return null;
84
+ }
72
85
  //#endregion
73
86
  export { renderAuthSuccess };
@@ -180,11 +180,13 @@ const DESCRIPTORS = [
180
180
  "deploy"
181
181
  ],
182
182
  description: "Creates a new deployment for the app",
183
+ longDescription: "Agent skills for guided Next.js deploys are available from the Prisma CLI skill cluster.",
183
184
  examples: [
184
185
  "prisma-cli app deploy",
185
186
  "prisma-cli app deploy --app my-app --env DATABASE_URL=postgresql://example",
186
187
  "prisma-cli app deploy --app my-app --framework nextjs --http-port 3000",
187
- "prisma-cli app deploy --branch feat-login --framework hono"
188
+ "prisma-cli app deploy --branch feat-login --framework hono",
189
+ "pnpm dlx skills@latest add prisma/prisma-cli/skills#cli-v<cli-version> --all"
188
190
  ]
189
191
  },
190
192
  {
@@ -45,7 +45,8 @@ async function resolveCurrentAuthState(dependencies) {
45
45
  authenticated: false,
46
46
  provider: null,
47
47
  user: null,
48
- workspace: null
48
+ workspace: null,
49
+ credential: null
49
50
  };
50
51
  const provider = dependencies.identityGateway.getProvider(session.provider);
51
52
  const user = dependencies.identityGateway.getUser(session.userId);
@@ -54,13 +55,23 @@ async function resolveCurrentAuthState(dependencies) {
54
55
  authenticated: false,
55
56
  provider: null,
56
57
  user: null,
57
- workspace: null
58
+ workspace: null,
59
+ credential: null
58
60
  };
59
61
  return {
60
62
  authenticated: true,
61
63
  provider: provider.id,
62
- user: { email: user.email },
63
- workspace
64
+ user: {
65
+ id: user.id,
66
+ email: user.email,
67
+ name: user.name
68
+ },
69
+ workspace,
70
+ credential: {
71
+ type: "oauth",
72
+ id: null,
73
+ name: null
74
+ }
64
75
  };
65
76
  }
66
77
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prisma/cli",
3
- "version": "3.0.0-dev.36.1",
3
+ "version": "3.0.0-dev.38.1",
4
4
  "description": "Command-line interface for the Prisma Developer Platform.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -39,7 +39,7 @@
39
39
  "@prisma/compute-sdk": "^0.19.0",
40
40
  "c12": "4.0.0-beta.4",
41
41
  "@prisma/credentials-store": "^7.7.0",
42
- "@prisma/management-api-sdk": "^1.33.1",
42
+ "@prisma/management-api-sdk": "^1.34.0",
43
43
  "colorette": "^2.0.20",
44
44
  "commander": "^12.1.0",
45
45
  "magicast": "^0.3.5",