@prisma/cli 3.0.0-beta.4 → 3.0.0-beta.6

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.
@@ -5,8 +5,12 @@ import { readFile } from "node:fs/promises";
5
5
  import path from "node:path";
6
6
  //#region src/lib/project/resolution.ts
7
7
  async function resolveProjectTarget(options) {
8
+ const localPin = await readImplicitLocalPin(options, { allowEnvProjectId: true });
8
9
  const projects = await options.listProjects();
9
- const target = await resolveBoundProjectTarget(options, projects, { allowEnvProjectId: true });
10
+ const target = await resolveBoundProjectTarget(options, projects, {
11
+ allowEnvProjectId: true,
12
+ localPin
13
+ });
10
14
  if (target) return target;
11
15
  throw await projectSetupRequiredError({
12
16
  cwd: options.context.runtime.cwd,
@@ -16,8 +20,12 @@ async function resolveProjectTarget(options) {
16
20
  });
17
21
  }
18
22
  async function inspectProjectBinding(options) {
23
+ const localPin = await readImplicitLocalPin(options, { allowEnvProjectId: false });
19
24
  const projects = await options.listProjects();
20
- const target = await resolveBoundProjectTarget(options, projects, { allowEnvProjectId: false });
25
+ const target = await resolveBoundProjectTarget(options, projects, {
26
+ allowEnvProjectId: false,
27
+ localPin
28
+ });
21
29
  if (target) return target;
22
30
  return {
23
31
  workspace: options.workspace,
@@ -73,6 +81,28 @@ function localStateStaleError() {
73
81
  nextSteps: ["prisma-cli project list", "prisma-cli project link <id-or-name>"]
74
82
  });
75
83
  }
84
+ function localProjectWorkspaceMismatchError(options) {
85
+ return new CliError({
86
+ code: "LOCAL_PROJECT_WORKSPACE_MISMATCH",
87
+ domain: "project",
88
+ summary: "Project link uses another workspace",
89
+ why: `${LOCAL_RESOLUTION_PIN_RELATIVE_PATH} links this directory to project ${options.pinnedProjectId} in workspace ${options.pinnedWorkspaceId}, but your current CLI session is workspace "${options.activeWorkspace.name}" (${options.activeWorkspace.id}).`,
90
+ fix: "Sign in to the linked workspace, or relink this directory to a project in the current workspace.",
91
+ meta: {
92
+ pinPath: LOCAL_RESOLUTION_PIN_RELATIVE_PATH,
93
+ pinnedWorkspaceId: options.pinnedWorkspaceId,
94
+ pinnedProjectId: options.pinnedProjectId,
95
+ activeWorkspaceId: options.activeWorkspace.id,
96
+ activeWorkspaceName: options.activeWorkspace.name
97
+ },
98
+ exitCode: 1,
99
+ nextSteps: [
100
+ "prisma-cli auth login",
101
+ "prisma-cli project list",
102
+ "prisma-cli project link <id-or-name>"
103
+ ]
104
+ });
105
+ }
76
106
  async function buildProjectSetupSuggestion(options) {
77
107
  const suggestedName = await inferTargetName(options.cwd, options.signal);
78
108
  const candidates = sortProjects(options.projects.filter((project) => projectMatchesSuggestedName(project, suggestedName.name))).map(toProjectSummary);
@@ -192,10 +222,15 @@ async function resolveBoundProjectTarget(options, projects, settings) {
192
222
  targetNameSource: "env"
193
223
  });
194
224
  }
195
- const localPin = await readLocalResolutionPin(options.context.runtime.cwd, options.context.runtime.signal);
225
+ const localPin = settings.localPin;
226
+ if (!localPin) return null;
196
227
  if (localPin.kind === "invalid") throw localStateStaleError();
197
228
  if (localPin.kind === "present") {
198
- if (localPin.pin.workspaceId !== options.workspace.id) throw localStateStaleError();
229
+ if (localPin.pin.workspaceId !== options.workspace.id) throw localProjectWorkspaceMismatchError({
230
+ pinnedWorkspaceId: localPin.pin.workspaceId,
231
+ pinnedProjectId: localPin.pin.projectId,
232
+ activeWorkspace: options.workspace
233
+ });
199
234
  const project = projects.find((candidate) => candidate.id === localPin.pin.projectId);
200
235
  if (!project) throw localStateStaleError();
201
236
  return resolvedTarget(options.workspace, project, "local-pin", {
@@ -210,6 +245,16 @@ async function resolveBoundProjectTarget(options, projects, settings) {
210
245
  });
211
246
  return null;
212
247
  }
248
+ async function readImplicitLocalPin(options, settings) {
249
+ if (options.explicitProject || settings.allowEnvProjectId && options.envProjectId) return null;
250
+ const localPin = await readLocalResolutionPin(options.context.runtime.cwd, options.context.runtime.signal);
251
+ if (localPin.kind === "present" && localPin.pin.workspaceId !== options.workspace.id) throw localProjectWorkspaceMismatchError({
252
+ pinnedWorkspaceId: localPin.pin.workspaceId,
253
+ pinnedProjectId: localPin.pin.projectId,
254
+ activeWorkspace: options.workspace
255
+ });
256
+ return localPin;
257
+ }
213
258
  function resolvedTarget(workspace, project, projectSource, resolutionDetails) {
214
259
  return {
215
260
  workspace,
@@ -1,4 +1,6 @@
1
+ import { renderVerboseBlock } from "../shell/ui.js";
1
2
  import { renderList, renderShow, serializeList } from "../output/patterns.js";
3
+ import { renderResolvedProjectContextBlock, stripVerboseContext } from "./verbose-context.js";
2
4
  //#region src/presenters/app-env.ts
3
5
  function scopeLabel(scope) {
4
6
  if (scope.kind === "role") return scope.role ?? "unknown";
@@ -14,8 +16,102 @@ function listTargetLabel(result) {
14
16
  }
15
17
  return scopeLabel(result.scope);
16
18
  }
19
+ function renderEnvVerboseBlocks(context, result) {
20
+ return [...renderEnvResolvedContextBlock(context, result.verboseContext), ...renderEnvTargetBlock(context, result)];
21
+ }
22
+ function renderEnvResolvedContextBlock(context, verboseContext) {
23
+ return renderResolvedProjectContextBlock(context.ui, verboseContext);
24
+ }
25
+ function renderEnvTargetBlock(context, result) {
26
+ return renderVerboseBlock(context.ui, envTargetRows(result), { title: "Env target" });
27
+ }
28
+ function envTargetRows(result) {
29
+ return [
30
+ {
31
+ key: "project id",
32
+ value: result.projectId,
33
+ tone: "dim"
34
+ },
35
+ {
36
+ key: "scope",
37
+ value: scopeLabel(result.scope)
38
+ },
39
+ ...envListTargetRows(result),
40
+ ...envFileRows(result),
41
+ {
42
+ key: "keys",
43
+ value: formatKeyNames(envResultKeys(result)),
44
+ tone: envResultKeys(result).length > 0 ? "default" : "dim"
45
+ }
46
+ ];
47
+ }
48
+ function envListTargetRows(result) {
49
+ if (!("target" in result)) return [];
50
+ return [
51
+ {
52
+ key: "target source",
53
+ value: result.target.source
54
+ },
55
+ {
56
+ key: "env map",
57
+ value: result.target.envMap
58
+ },
59
+ ...result.target.branchName ? [{
60
+ key: "branch",
61
+ value: result.target.branchName
62
+ }] : [],
63
+ ...result.target.branchId ? [{
64
+ key: "branch id",
65
+ value: result.target.branchId,
66
+ tone: "dim"
67
+ }] : [],
68
+ ...result.target.branchExists === false ? [{
69
+ key: "branch state",
70
+ value: "not created yet",
71
+ tone: "warning"
72
+ }] : []
73
+ ];
74
+ }
75
+ function envFileRows(result) {
76
+ if (!("file" in result) || !result.file) return [];
77
+ return [{
78
+ key: "file",
79
+ value: result.file.path
80
+ }, {
81
+ key: "file count",
82
+ value: String(result.file.count)
83
+ }];
84
+ }
85
+ function envResultKeys(result) {
86
+ if ("variables" in result && result.variables) return result.variables.map((variable) => variable.key).sort((left, right) => left.localeCompare(right));
87
+ if ("variable" in result && result.variable) return [result.variable.key];
88
+ if ("key" in result) return [result.key];
89
+ return [];
90
+ }
91
+ function formatKeyNames(keys) {
92
+ return keys.length > 0 ? keys.join(", ") : "none";
93
+ }
17
94
  function renderEnvAdd(context, descriptor, result) {
18
- return renderShow({
95
+ if (result.variables !== void 0) {
96
+ const lines = renderList({
97
+ title: "Setting new environment variables from file.",
98
+ descriptor,
99
+ parentContext: {
100
+ key: "target",
101
+ value: `${scopeLabel(result.scope)} from ${result.file.path}`
102
+ },
103
+ items: result.variables.map((variable) => ({
104
+ noun: "variable",
105
+ label: `${variable.key} (${variable.source})`,
106
+ id: variable.id,
107
+ status: variable.isManagedBySystem ? "default" : null
108
+ })),
109
+ emptyMessage: "No environment variables imported."
110
+ }, context.ui);
111
+ lines.push(...renderEnvVerboseBlocks(context, result));
112
+ return lines;
113
+ }
114
+ const lines = renderShow({
19
115
  title: "Setting a new environment variable.",
20
116
  descriptor,
21
117
  fields: [
@@ -43,12 +139,33 @@ function renderEnvAdd(context, descriptor, result) {
43
139
  }
44
140
  ]
45
141
  }, context.ui);
142
+ lines.push(...renderEnvVerboseBlocks(context, result));
143
+ return lines;
46
144
  }
47
145
  function serializeEnvAdd(result) {
48
- return result;
146
+ return stripVerboseContext(result);
49
147
  }
50
148
  function renderEnvUpdate(context, descriptor, result) {
51
- return renderShow({
149
+ if (result.variables !== void 0) {
150
+ const lines = renderList({
151
+ title: "Replacing environment variable values from file.",
152
+ descriptor,
153
+ parentContext: {
154
+ key: "target",
155
+ value: `${scopeLabel(result.scope)} from ${result.file.path}`
156
+ },
157
+ items: result.variables.map((variable) => ({
158
+ noun: "variable",
159
+ label: `${variable.key} (${variable.source})`,
160
+ id: variable.id,
161
+ status: variable.isManagedBySystem ? "default" : null
162
+ })),
163
+ emptyMessage: "No environment variables updated."
164
+ }, context.ui);
165
+ lines.push(...renderEnvVerboseBlocks(context, result));
166
+ return lines;
167
+ }
168
+ const lines = renderShow({
52
169
  title: "Replacing the environment variable's value.",
53
170
  descriptor,
54
171
  fields: [
@@ -76,12 +193,14 @@ function renderEnvUpdate(context, descriptor, result) {
76
193
  }
77
194
  ]
78
195
  }, context.ui);
196
+ lines.push(...renderEnvVerboseBlocks(context, result));
197
+ return lines;
79
198
  }
80
199
  function serializeEnvUpdate(result) {
81
- return result;
200
+ return stripVerboseContext(result);
82
201
  }
83
202
  function renderEnvList(context, descriptor, result) {
84
- return renderList({
203
+ const lines = renderList({
85
204
  title: "Listing environment variables for the selected scope.",
86
205
  descriptor,
87
206
  parentContext: {
@@ -96,26 +215,29 @@ function renderEnvList(context, descriptor, result) {
96
215
  })),
97
216
  emptyMessage: "No environment variables defined in this scope."
98
217
  }, context.ui);
218
+ lines.push(...renderEnvVerboseBlocks(context, result));
219
+ return lines;
99
220
  }
100
221
  function serializeEnvList(result) {
222
+ const serializable = stripVerboseContext(result);
101
223
  return {
102
- projectId: result.projectId,
103
- scope: result.scope,
104
- target: result.target,
224
+ projectId: serializable.projectId,
225
+ scope: serializable.scope,
226
+ target: serializable.target,
105
227
  ...serializeList({
106
- context: { target: listTargetLabel(result) },
107
- items: result.variables.map((variable) => ({
228
+ context: { target: listTargetLabel(serializable) },
229
+ items: serializable.variables.map((variable) => ({
108
230
  noun: "variable",
109
231
  label: `${variable.key} (${variable.source})`,
110
232
  id: variable.id,
111
233
  status: variable.isManagedBySystem ? "default" : null
112
234
  }))
113
235
  }),
114
- variables: result.variables
236
+ variables: serializable.variables
115
237
  };
116
238
  }
117
239
  function renderEnvRm(context, descriptor, result) {
118
- return renderShow({
240
+ const lines = renderShow({
119
241
  title: "Removing the environment variable from the scope.",
120
242
  descriptor,
121
243
  fields: [
@@ -133,9 +255,11 @@ function renderEnvRm(context, descriptor, result) {
133
255
  }
134
256
  ]
135
257
  }, context.ui);
258
+ lines.push(...renderEnvVerboseBlocks(context, result));
259
+ return lines;
136
260
  }
137
261
  function serializeEnvRm(result) {
138
- return result;
262
+ return stripVerboseContext(result);
139
263
  }
140
264
  //#endregion
141
265
  export { renderEnvAdd, renderEnvList, renderEnvRm, renderEnvUpdate, serializeEnvAdd, serializeEnvList, serializeEnvRm, serializeEnvUpdate };
@@ -1,6 +1,8 @@
1
+ import { renderVerboseBlock } from "../shell/ui.js";
1
2
  import { renderDeployOutputRows } from "../lib/app/deploy-output.js";
2
3
  import { formatDomainFailureFix } from "../lib/app/domain-guidance.js";
3
4
  import { renderList, renderShow, serializeList } from "../output/patterns.js";
5
+ import { renderResolvedProjectContextBlock, stripVerboseContext } from "./verbose-context.js";
4
6
  //#region src/presenters/app.ts
5
7
  function renderAppBuild(context, descriptor, result) {
6
8
  return renderShow({
@@ -30,23 +32,153 @@ function renderAppDeploy(context, descriptor, result) {
30
32
  return [
31
33
  `Live in ${formatDuration(result.durationMs)}`,
32
34
  ...result.deployment.url ? [context.ui.link(result.deployment.url)] : [],
35
+ ...renderBranchDatabaseDeploySummary(context, result),
33
36
  "",
34
37
  ...renderDeployOutputRows(context.ui, [{
35
38
  label: "Logs",
36
39
  value: "prisma-cli app logs"
37
- }])
40
+ }]),
41
+ ...renderDeployResolvedContextBlock(context, result),
42
+ ...renderDeploySettingsBlock(context, result)
38
43
  ];
39
44
  }
40
45
  function serializeAppDeploy(result) {
41
- const { localPin: _localPin, ...serialized } = result;
42
- return serialized;
46
+ const { deploySettings: _deploySettings, localPin: _localPin, ...serialized } = result;
47
+ const { id: _branchId, ...branch } = serialized.branch;
48
+ return {
49
+ ...serialized,
50
+ branch
51
+ };
52
+ }
53
+ function renderBranchDatabaseDeploySummary(context, result) {
54
+ if (!result.branchDatabase || result.branchDatabase.status !== "created") return [];
55
+ return ["", ...renderDeployOutputRows(context.ui, [
56
+ {
57
+ label: "Database",
58
+ value: result.branchDatabase.database?.name ?? "created"
59
+ },
60
+ {
61
+ label: "Env",
62
+ value: result.branchDatabase.envVars.join(", ")
63
+ },
64
+ ...result.branchDatabase.schema ? [{
65
+ label: "Schema",
66
+ value: formatBranchDatabaseSchemaCommand(result.branchDatabase.schema.command)
67
+ }] : []
68
+ ])];
69
+ }
70
+ function formatBranchDatabaseSchemaCommand(command) {
71
+ switch (command) {
72
+ case "migrate-deploy": return "prisma migrate deploy";
73
+ case "db-push": return "prisma db push";
74
+ case "prisma-next-db-init": return "prisma-next db init";
75
+ }
43
76
  }
44
77
  function formatDuration(durationMs) {
45
78
  if (durationMs < 1e3) return `${durationMs}ms`;
46
79
  return `${(durationMs / 1e3).toFixed(1)}s`;
47
80
  }
81
+ function renderDeployResolvedContextBlock(context, result) {
82
+ return renderResolvedProjectContextBlock(context.ui, {
83
+ workspace: result.workspace,
84
+ project: result.project,
85
+ resolution: result.resolution,
86
+ branch: {
87
+ id: result.branch.id,
88
+ name: result.branch.name,
89
+ kind: result.branch.kind
90
+ }
91
+ }, { extraRows: [
92
+ {
93
+ key: "app",
94
+ value: result.app.name
95
+ },
96
+ {
97
+ key: "app id",
98
+ value: result.app.id,
99
+ tone: "dim"
100
+ },
101
+ {
102
+ key: "deployment id",
103
+ value: result.deployment.id,
104
+ tone: "dim"
105
+ },
106
+ {
107
+ key: "deployment status",
108
+ value: result.deployment.status
109
+ },
110
+ ...result.localPin ? [{
111
+ key: "local pin",
112
+ value: result.localPin.path
113
+ }] : [],
114
+ {
115
+ key: "deploy duration",
116
+ value: formatDuration(result.durationMs)
117
+ }
118
+ ] });
119
+ }
120
+ function renderDeploySettingsBlock(context, result) {
121
+ return renderVerboseBlock(context.ui, [...deploySettingsRows(result.deploySettings), ...branchDatabaseRows(result.branchDatabase)], { title: "Deploy settings" });
122
+ }
123
+ function deploySettingsRows(settings) {
124
+ return [
125
+ {
126
+ key: "framework",
127
+ value: `${settings.framework.name} (${settings.framework.buildType})`
128
+ },
129
+ {
130
+ key: "framework source",
131
+ value: settings.framework.source,
132
+ tone: "dim"
133
+ },
134
+ {
135
+ key: "entrypoint",
136
+ value: settings.entrypoint ?? "derived from build output",
137
+ tone: settings.entrypoint ? "default" : "dim"
138
+ },
139
+ {
140
+ key: "http port",
141
+ value: String(settings.httpPort)
142
+ },
143
+ {
144
+ key: "region",
145
+ value: settings.region ?? "existing app region",
146
+ tone: settings.region ? "default" : "dim"
147
+ },
148
+ {
149
+ key: "env vars",
150
+ value: formatEnvVarNames(settings.envVars),
151
+ tone: settings.envVars.length > 0 ? "default" : "dim"
152
+ }
153
+ ];
154
+ }
155
+ function branchDatabaseRows(branchDatabase) {
156
+ if (!branchDatabase) return [{
157
+ key: "branch db",
158
+ value: "not configured",
159
+ tone: "dim"
160
+ }];
161
+ return [
162
+ {
163
+ key: "branch db",
164
+ value: branchDatabase.status === "created" ? `created${branchDatabase.database ? ` (${branchDatabase.database.name})` : ""}` : `skipped${branchDatabase.reason ? ` (${branchDatabase.reason})` : ""}`,
165
+ tone: branchDatabase.status === "created" ? "success" : "dim"
166
+ },
167
+ ...branchDatabase.envVars.length > 0 ? [{
168
+ key: "branch db env",
169
+ value: branchDatabase.envVars.join(", ")
170
+ }] : [],
171
+ ...branchDatabase.schema ? [{
172
+ key: "branch db schema",
173
+ value: `${formatBranchDatabaseSchemaCommand(branchDatabase.schema.command)} (${branchDatabase.schema.source}, ${branchDatabase.schema.path})`
174
+ }] : []
175
+ ];
176
+ }
177
+ function formatEnvVarNames(envVars) {
178
+ return envVars.length > 0 ? envVars.join(", ") : "none";
179
+ }
48
180
  function renderAppListDeploys(context, descriptor, result) {
49
- return renderList({
181
+ const lines = renderList({
50
182
  title: "Listing deployments for the selected app.",
51
183
  descriptor,
52
184
  parentContext: {
@@ -61,20 +193,23 @@ function renderAppListDeploys(context, descriptor, result) {
61
193
  })),
62
194
  emptyMessage: result.app ? "No deployments found." : "No apps found."
63
195
  }, context.ui);
196
+ lines.push(...renderResolvedProjectContextBlock(context.ui, result.verboseContext));
197
+ return lines;
64
198
  }
65
199
  function serializeAppListDeploys(result) {
66
- if (!result.app) return {
67
- projectId: result.projectId,
200
+ const { verboseContext: _verboseContext, ...serializable } = result;
201
+ if (!serializable.app) return {
202
+ projectId: serializable.projectId,
68
203
  app: null,
69
204
  items: [],
70
205
  count: 0
71
206
  };
72
207
  return {
73
- projectId: result.projectId,
74
- app: result.app,
208
+ projectId: serializable.projectId,
209
+ app: serializable.app,
75
210
  ...serializeList({
76
- context: { app: result.app.name },
77
- items: result.deployments.map((deployment) => ({
211
+ context: { app: serializable.app.name },
212
+ items: serializable.deployments.map((deployment) => ({
78
213
  noun: "deployment",
79
214
  label: deployment.id,
80
215
  id: deployment.id,
@@ -84,7 +219,7 @@ function serializeAppListDeploys(result) {
84
219
  };
85
220
  }
86
221
  function renderAppShow(context, descriptor, result) {
87
- return renderShow({
222
+ const lines = renderShow({
88
223
  title: "Showing the selected app state.",
89
224
  descriptor,
90
225
  fields: [
@@ -114,9 +249,11 @@ function renderAppShow(context, descriptor, result) {
114
249
  }
115
250
  ]
116
251
  }, context.ui);
252
+ lines.push(...renderResolvedProjectContextBlock(context.ui, result.verboseContext));
253
+ return lines;
117
254
  }
118
255
  function serializeAppShow(result) {
119
- return result;
256
+ return stripVerboseContext(result);
120
257
  }
121
258
  function renderAppShowDeploy(context, descriptor, result) {
122
259
  return renderShow({
@@ -158,7 +295,7 @@ function serializeAppShowDeploy(result) {
158
295
  return result;
159
296
  }
160
297
  function renderAppOpen(context, descriptor, result) {
161
- return renderShow({
298
+ const lines = renderShow({
162
299
  title: result.opened ? "Opening the live URL for the selected app." : "Resolving the live URL for the selected app.",
163
300
  descriptor,
164
301
  fields: [
@@ -182,9 +319,11 @@ function renderAppOpen(context, descriptor, result) {
182
319
  }
183
320
  ]
184
321
  }, context.ui);
322
+ lines.push(...renderResolvedProjectContextBlock(context.ui, result.verboseContext));
323
+ return lines;
185
324
  }
186
325
  function serializeAppOpen(result) {
187
- return result;
326
+ return stripVerboseContext(result);
188
327
  }
189
328
  function renderAppDomainAdd(context, descriptor, result) {
190
329
  return renderShow({
@@ -286,7 +425,7 @@ function serializeAppDomainRetry(result) {
286
425
  return result;
287
426
  }
288
427
  function renderAppPromote(context, descriptor, result) {
289
- return renderShow({
428
+ const lines = renderShow({
290
429
  title: "Switching the live deployment for the selected app.",
291
430
  descriptor,
292
431
  fields: [
@@ -324,12 +463,14 @@ function renderAppPromote(context, descriptor, result) {
324
463
  }
325
464
  ]
326
465
  }, context.ui);
466
+ lines.push(...renderResolvedProjectContextBlock(context.ui, result.verboseContext));
467
+ return lines;
327
468
  }
328
469
  function serializeAppPromote(result) {
329
- return result;
470
+ return stripVerboseContext(result);
330
471
  }
331
472
  function renderAppRollback(context, descriptor, result) {
332
- return renderShow({
473
+ const lines = renderShow({
333
474
  title: "Restoring the selected app to an earlier deployment.",
334
475
  descriptor,
335
476
  fields: [
@@ -372,9 +513,11 @@ function renderAppRollback(context, descriptor, result) {
372
513
  }] : []
373
514
  ]
374
515
  }, context.ui);
516
+ lines.push(...renderResolvedProjectContextBlock(context.ui, result.verboseContext));
517
+ return lines;
375
518
  }
376
519
  function serializeAppRollback(result) {
377
- return result;
520
+ return stripVerboseContext(result);
378
521
  }
379
522
  function renderAppRun(_context, _descriptor, _result) {
380
523
  return [];
@@ -383,7 +526,7 @@ function serializeAppRun(result) {
383
526
  return result;
384
527
  }
385
528
  function renderAppRemove(context, descriptor, result) {
386
- return renderShow({
529
+ const lines = renderShow({
387
530
  title: "Removing the selected app.",
388
531
  descriptor,
389
532
  fields: [
@@ -402,9 +545,11 @@ function renderAppRemove(context, descriptor, result) {
402
545
  }
403
546
  ]
404
547
  }, context.ui);
548
+ lines.push(...renderResolvedProjectContextBlock(context.ui, result.verboseContext));
549
+ return lines;
405
550
  }
406
551
  function serializeAppRemove(result) {
407
- return result;
552
+ return stripVerboseContext(result);
408
553
  }
409
554
  function toneForStatus(status) {
410
555
  if (status === "running" || status === "ready" || status === "healthy") return "success";
@@ -1,5 +1,6 @@
1
1
  import { formatColumns } from "../shell/ui.js";
2
2
  import { formatDescriptorLabel } from "../shell/command-meta.js";
3
+ import { renderResolvedProjectContextBlock } from "./verbose-context.js";
3
4
  //#region src/presenters/branch.ts
4
5
  function renderBranchList(context, descriptor, result) {
5
6
  const ui = context.ui;
@@ -9,6 +10,7 @@ function renderBranchList(context, descriptor, result) {
9
10
  lines.push(rail);
10
11
  if (result.branches.length === 0) {
11
12
  lines.push(`${rail} ${ui.dim("No branches found.")}`);
13
+ lines.push(...renderBranchResolvedContextBlock(context, result));
12
14
  return lines;
13
15
  }
14
16
  const widths = [
@@ -26,14 +28,19 @@ function renderBranchList(context, descriptor, result) {
26
28
  branch.role,
27
29
  branch.envMap
28
30
  ], widths)}`);
31
+ lines.push(...renderBranchResolvedContextBlock(context, result));
29
32
  return lines;
30
33
  }
31
34
  function serializeBranchList(result) {
35
+ const { verboseContext: _verboseContext, ...serializable } = result;
32
36
  return {
33
- projectId: result.projectId,
34
- projectName: result.projectName,
35
- branches: result.branches
37
+ projectId: serializable.projectId,
38
+ projectName: serializable.projectName,
39
+ branches: serializable.branches
36
40
  };
37
41
  }
42
+ function renderBranchResolvedContextBlock(context, result) {
43
+ return renderResolvedProjectContextBlock(context.ui, result.verboseContext);
44
+ }
38
45
  //#endregion
39
46
  export { renderBranchList, serializeBranchList };