@prisma/cli 8.0.0-rc.1 → 8.0.0-rc.10
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 +25 -29
- package/dist/cli.js +14551 -16
- package/dist/{v8/sender.js → sender.js} +1 -1
- package/package.json +17 -18
- package/dist/adapters/git.js +0 -54
- package/dist/adapters/local-state.js +0 -155
- package/dist/auth/client.js +0 -30
- package/dist/auth/errors.js +0 -50
- package/dist/auth/guard.js +0 -39
- package/dist/auth/login.js +0 -471
- package/dist/auth/operations.js +0 -208
- package/dist/auth/recipient.js +0 -42
- package/dist/auth/token-storage.js +0 -439
- package/dist/auth/workspaces.js +0 -171
- package/dist/cli-command.js +0 -14
- package/dist/cli-name.js +0 -12
- package/dist/cli2.js +0 -136
- package/dist/command-arguments.js +0 -12
- package/dist/commands/agent/index.js +0 -60
- package/dist/commands/app/index.js +0 -350
- package/dist/commands/auth/index.js +0 -95
- package/dist/commands/branch/index.js +0 -27
- package/dist/commands/bucket/index.js +0 -123
- package/dist/commands/build/index.js +0 -29
- package/dist/commands/database/index.js +0 -249
- package/dist/commands/env.js +0 -99
- package/dist/commands/feedback/index.js +0 -20
- package/dist/commands/git/index.js +0 -36
- package/dist/commands/init/index.js +0 -33
- package/dist/commands/project/index.js +0 -118
- package/dist/commands/version/index.js +0 -18
- package/dist/controllers/agent-setup.js +0 -52
- package/dist/controllers/agent.js +0 -228
- package/dist/controllers/app-env-api.js +0 -55
- package/dist/controllers/app-env-file.js +0 -181
- package/dist/controllers/app-env.js +0 -502
- package/dist/controllers/app.js +0 -2508
- package/dist/controllers/auth.js +0 -124
- package/dist/controllers/branch.js +0 -92
- package/dist/controllers/bucket.js +0 -184
- package/dist/controllers/build.js +0 -88
- package/dist/controllers/database.js +0 -463
- package/dist/controllers/feedback.js +0 -90
- package/dist/controllers/init.js +0 -814
- package/dist/controllers/project.js +0 -892
- package/dist/controllers/select-prompt-port.js +0 -13
- package/dist/controllers/version.js +0 -12
- package/dist/errors.js +0 -102
- package/dist/lib/agent/cli-command.js +0 -20
- package/dist/lib/agent/constants.js +0 -12
- package/dist/lib/agent/package-manager.js +0 -99
- package/dist/lib/agent/setup-status.js +0 -83
- package/dist/lib/app/app-provider.js +0 -617
- package/dist/lib/app/branch-database-api.js +0 -102
- package/dist/lib/app/branch-database-deploy.js +0 -353
- package/dist/lib/app/branch-database.js +0 -234
- package/dist/lib/app/build-settings.js +0 -98
- package/dist/lib/app/build.js +0 -82
- package/dist/lib/app/bun-project.js +0 -45
- package/dist/lib/app/compute-config.js +0 -145
- package/dist/lib/app/deploy-output.js +0 -24
- package/dist/lib/app/deploy-plan.js +0 -59
- package/dist/lib/app/deploy-progress.js +0 -100
- package/dist/lib/app/domain-guidance.js +0 -14
- package/dist/lib/app/env-config.js +0 -67
- package/dist/lib/app/env-file.js +0 -82
- package/dist/lib/app/env-vars.js +0 -50
- package/dist/lib/app/local-dev.js +0 -109
- package/dist/lib/app/production-deploy-gate.js +0 -162
- package/dist/lib/app/read-branch.js +0 -30
- package/dist/lib/bucket/provider.js +0 -139
- package/dist/lib/database/provider.js +0 -385
- package/dist/lib/diagnostics.js +0 -16
- package/dist/lib/feedback.js +0 -15
- package/dist/lib/fs/home-path.js +0 -24
- package/dist/lib/git/local-branch.js +0 -53
- package/dist/lib/git/local-status.js +0 -57
- package/dist/lib/project/interactive-setup.js +0 -57
- package/dist/lib/project/local-pin.js +0 -200
- package/dist/lib/project/provider.js +0 -93
- package/dist/lib/project/resolution.js +0 -389
- package/dist/lib/project/setup.js +0 -138
- package/dist/lib/version.js +0 -56
- package/dist/lib/workspace-id.js +0 -18
- package/dist/output/patterns.js +0 -90
- package/dist/presenters/agent.js +0 -74
- package/dist/presenters/app-env.js +0 -265
- package/dist/presenters/app.js +0 -672
- package/dist/presenters/auth.js +0 -184
- package/dist/presenters/branch.js +0 -46
- package/dist/presenters/bucket.js +0 -174
- package/dist/presenters/database.js +0 -462
- package/dist/presenters/feedback.js +0 -26
- package/dist/presenters/init.js +0 -30
- package/dist/presenters/project.js +0 -268
- package/dist/presenters/verbose-context.js +0 -64
- package/dist/presenters/version.js +0 -29
- package/dist/shell/cli-command.js +0 -2
- package/dist/shell/command-meta.js +0 -923
- package/dist/shell/command-runner.js +0 -119
- package/dist/shell/diagnostics-output.js +0 -57
- package/dist/shell/global-flags.js +0 -37
- package/dist/shell/help.js +0 -90
- package/dist/shell/output.js +0 -144
- package/dist/shell/prompt.js +0 -48
- package/dist/shell/runtime.js +0 -38
- package/dist/shell/ui.js +0 -116
- package/dist/state-dir.js +0 -12
- package/dist/update-check.js +0 -248
- package/dist/v8/cli.js +0 -14699
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
import { attachCommandDescriptor } from "../../shell/command-meta.js";
|
|
2
|
-
import { addCompactGlobalFlags, addGlobalFlags } from "../../shell/global-flags.js";
|
|
3
|
-
import { configureRuntimeCommand } from "../../shell/runtime.js";
|
|
4
|
-
import { runCommand } from "../../shell/command-runner.js";
|
|
5
|
-
import { runProjectCreate, runProjectLink, runProjectList, runProjectRemove, runProjectRename, runProjectShow, runProjectTransfer } from "../../controllers/project.js";
|
|
6
|
-
import { renderProjectList, renderProjectRemove, renderProjectRename, renderProjectSetup, renderProjectShow, renderProjectTransfer, serializeProjectList, serializeProjectRemove, serializeProjectRename, serializeProjectSetup, serializeProjectShow, serializeProjectTransfer } from "../../presenters/project.js";
|
|
7
|
-
import { createEnvCommand } from "../env.js";
|
|
8
|
-
import { Command, Option } from "commander";
|
|
9
|
-
//#region src/commands/project/index.ts
|
|
10
|
-
function createProjectCommand(runtime) {
|
|
11
|
-
const project = attachCommandDescriptor(configureRuntimeCommand(new Command("project"), runtime), "project");
|
|
12
|
-
addCompactGlobalFlags(project);
|
|
13
|
-
project.addCommand(createProjectListCommand(runtime));
|
|
14
|
-
project.addCommand(createProjectShowCommand(runtime));
|
|
15
|
-
project.addCommand(createProjectCreateCommand(runtime));
|
|
16
|
-
project.addCommand(createProjectLinkCommand(runtime));
|
|
17
|
-
project.addCommand(createProjectRenameCommand(runtime));
|
|
18
|
-
project.addCommand(createProjectRemoveCommand(runtime));
|
|
19
|
-
project.addCommand(createProjectTransferCommand(runtime));
|
|
20
|
-
project.addCommand(createEnvCommand(runtime));
|
|
21
|
-
return project;
|
|
22
|
-
}
|
|
23
|
-
function createProjectRenameCommand(runtime) {
|
|
24
|
-
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("rename"), runtime), "project.rename");
|
|
25
|
-
command.argument("<name>", "New project name").addOption(new Option("--project <id-or-name>", "Project id or name"));
|
|
26
|
-
addGlobalFlags(command);
|
|
27
|
-
command.action(async (name, options) => {
|
|
28
|
-
const projectRef = options.project;
|
|
29
|
-
await runCommand(runtime, "project.rename", options, (context) => runProjectRename(context, name, { project: projectRef }), {
|
|
30
|
-
renderHuman: (context, descriptor, result) => renderProjectRename(context, descriptor, result),
|
|
31
|
-
renderJson: (result) => serializeProjectRename(result)
|
|
32
|
-
});
|
|
33
|
-
});
|
|
34
|
-
return command;
|
|
35
|
-
}
|
|
36
|
-
function createProjectRemoveCommand(runtime) {
|
|
37
|
-
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("remove"), runtime), "project.remove");
|
|
38
|
-
command.argument("<project>", "Project id or name").addOption(new Option("--confirm <project-id>", "Exact project id required to remove"));
|
|
39
|
-
addGlobalFlags(command);
|
|
40
|
-
command.action(async (projectRef, options) => {
|
|
41
|
-
const confirm = options.confirm;
|
|
42
|
-
await runCommand(runtime, "project.remove", options, (context) => runProjectRemove(context, projectRef, { confirm }), {
|
|
43
|
-
renderHuman: (context, descriptor, result) => renderProjectRemove(context, descriptor, result),
|
|
44
|
-
renderJson: (result) => serializeProjectRemove(result)
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
return command;
|
|
48
|
-
}
|
|
49
|
-
function createProjectTransferCommand(runtime) {
|
|
50
|
-
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("transfer"), runtime), "project.transfer");
|
|
51
|
-
command.argument("<project>", "Project id or name").addOption(new Option("--to-workspace <id-or-name>", "Locally authenticated workspace to receive the project")).addOption(new Option("--recipient-token <token>", "Access token for the receiving workspace")).addOption(new Option("--confirm <project-id>", "Exact project id required to transfer"));
|
|
52
|
-
addGlobalFlags(command);
|
|
53
|
-
command.action(async (projectRef, options) => {
|
|
54
|
-
const toWorkspace = options.toWorkspace;
|
|
55
|
-
const recipientToken = options.recipientToken;
|
|
56
|
-
const confirm = options.confirm;
|
|
57
|
-
await runCommand(runtime, "project.transfer", options, (context) => runProjectTransfer(context, projectRef, {
|
|
58
|
-
toWorkspace,
|
|
59
|
-
recipientToken,
|
|
60
|
-
confirm
|
|
61
|
-
}), {
|
|
62
|
-
renderHuman: (context, descriptor, result) => renderProjectTransfer(context, descriptor, result),
|
|
63
|
-
renderJson: (result) => serializeProjectTransfer(result)
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
return command;
|
|
67
|
-
}
|
|
68
|
-
function createProjectCreateCommand(runtime) {
|
|
69
|
-
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("create"), runtime), "project.create");
|
|
70
|
-
command.argument("<name>", "Project name").addOption(new Option("--region <region>", "Prisma Compute region id"));
|
|
71
|
-
addGlobalFlags(command);
|
|
72
|
-
command.action(async (name, options) => {
|
|
73
|
-
const region = options.region;
|
|
74
|
-
await runCommand(runtime, "project.create", options, (context) => runProjectCreate(context, String(name), { region }), {
|
|
75
|
-
renderHuman: (context, descriptor, result) => renderProjectSetup(context, descriptor, result),
|
|
76
|
-
renderJson: (result) => serializeProjectSetup(result)
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
return command;
|
|
80
|
-
}
|
|
81
|
-
function createProjectLinkCommand(runtime) {
|
|
82
|
-
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("link"), runtime), "project.link");
|
|
83
|
-
command.argument("[id-or-name]", "Project id or name");
|
|
84
|
-
addGlobalFlags(command);
|
|
85
|
-
command.action(async (projectRef, options) => {
|
|
86
|
-
await runCommand(runtime, "project.link", options, (context) => runProjectLink(context, typeof projectRef === "string" ? projectRef : void 0), {
|
|
87
|
-
renderHuman: (context, descriptor, result) => renderProjectSetup(context, descriptor, result),
|
|
88
|
-
renderJson: (result) => serializeProjectSetup(result)
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
return command;
|
|
92
|
-
}
|
|
93
|
-
function createProjectListCommand(runtime) {
|
|
94
|
-
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("list"), runtime), "project.list");
|
|
95
|
-
addGlobalFlags(command);
|
|
96
|
-
command.action(async (options) => {
|
|
97
|
-
await runCommand(runtime, "project.list", options, (context) => runProjectList(context), {
|
|
98
|
-
renderHuman: (context, descriptor, result) => renderProjectList(context, descriptor, result),
|
|
99
|
-
renderJson: (result) => serializeProjectList(result)
|
|
100
|
-
});
|
|
101
|
-
});
|
|
102
|
-
return command;
|
|
103
|
-
}
|
|
104
|
-
function createProjectShowCommand(runtime) {
|
|
105
|
-
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("show"), runtime), "project.show");
|
|
106
|
-
command.option("--project <id-or-name>", "Project id or name");
|
|
107
|
-
addGlobalFlags(command);
|
|
108
|
-
command.action(async (options) => {
|
|
109
|
-
const projectRef = options.project;
|
|
110
|
-
await runCommand(runtime, "project.show", options, (context) => runProjectShow(context, projectRef), {
|
|
111
|
-
renderHuman: (context, descriptor, result) => renderProjectShow(context, descriptor, result),
|
|
112
|
-
renderJson: (result) => serializeProjectShow(result)
|
|
113
|
-
});
|
|
114
|
-
});
|
|
115
|
-
return command;
|
|
116
|
-
}
|
|
117
|
-
//#endregion
|
|
118
|
-
export { createProjectCommand };
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { attachCommandDescriptor } from "../../shell/command-meta.js";
|
|
2
|
-
import { addGlobalFlags } from "../../shell/global-flags.js";
|
|
3
|
-
import { configureRuntimeCommand } from "../../shell/runtime.js";
|
|
4
|
-
import { runCommand } from "../../shell/command-runner.js";
|
|
5
|
-
import { runVersion } from "../../controllers/version.js";
|
|
6
|
-
import { renderVersionSuccess } from "../../presenters/version.js";
|
|
7
|
-
import { Command } from "commander";
|
|
8
|
-
//#region src/commands/version/index.ts
|
|
9
|
-
function createVersionCommand(runtime) {
|
|
10
|
-
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("version"), runtime), "version");
|
|
11
|
-
addGlobalFlags(command);
|
|
12
|
-
command.action(async (options) => {
|
|
13
|
-
await runCommand(runtime, "version", options, (context) => runVersion(context), { renderHuman: (context, descriptor, result) => renderVersionSuccess(context, descriptor, result) });
|
|
14
|
-
});
|
|
15
|
-
return command;
|
|
16
|
-
}
|
|
17
|
-
//#endregion
|
|
18
|
-
export { createVersionCommand };
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { resolvePrismaCliPackageCommand } from "../lib/agent/cli-command.js";
|
|
2
|
-
import { PRISMA_AGENT_INSTALL_ARGS, PRISMA_COMPUTE_AGENT_SKILL } from "../lib/agent/constants.js";
|
|
3
|
-
import { readPrismaAgentSetupStatus, shouldOfferPrismaAgentSetup } from "../lib/agent/setup-status.js";
|
|
4
|
-
import { runAgentInstall } from "./agent.js";
|
|
5
|
-
import { renderSummaryLine } from "../shell/ui.js";
|
|
6
|
-
import { canPrompt } from "../shell/runtime.js";
|
|
7
|
-
import { confirmPrompt } from "../shell/prompt.js";
|
|
8
|
-
//#region src/controllers/agent-setup.ts
|
|
9
|
-
/**
|
|
10
|
-
* One-time interactive offer to install the Prisma Compute skill for the
|
|
11
|
-
* project. Shared by the commands that establish a project setup (init,
|
|
12
|
-
* deploy); the answer is remembered, so whichever command runs first asks.
|
|
13
|
-
* Returns warnings; a failed install must not fail the calling command.
|
|
14
|
-
*/
|
|
15
|
-
async function maybePromptForAgentSetup(context, projectDir) {
|
|
16
|
-
if (!canPrompt(context) || context.flags.yes || context.flags.quiet) return [];
|
|
17
|
-
if (!shouldOfferPrismaAgentSetup(await readPrismaAgentSetupStatus({
|
|
18
|
-
cwd: projectDir,
|
|
19
|
-
stateStore: context.stateStore,
|
|
20
|
-
signal: context.runtime.signal,
|
|
21
|
-
requiredSkill: "prisma-compute"
|
|
22
|
-
}))) return [];
|
|
23
|
-
if (!await confirmPrompt({
|
|
24
|
-
input: context.runtime.stdin,
|
|
25
|
-
output: context.runtime.stderr,
|
|
26
|
-
signal: context.runtime.signal,
|
|
27
|
-
message: "Install the Prisma Compute skill for this project?",
|
|
28
|
-
initialValue: true
|
|
29
|
-
})) {
|
|
30
|
-
await context.stateStore.setAgentSetupPromptDismissedAt((/* @__PURE__ */ new Date()).toISOString());
|
|
31
|
-
return [];
|
|
32
|
-
}
|
|
33
|
-
try {
|
|
34
|
-
await runAgentInstall(context, { skill: [PRISMA_COMPUTE_AGENT_SKILL] }, "install", { cwd: projectDir });
|
|
35
|
-
if (!context.flags.quiet && !context.flags.json) context.output.stderr.write(`${renderSummaryLine(context.ui, "success", "Installed the Prisma Compute skill for this project.")}\n\n`);
|
|
36
|
-
return [];
|
|
37
|
-
} catch (error) {
|
|
38
|
-
const message = error instanceof Error ? error.message : "Prisma skill install failed.";
|
|
39
|
-
if (!context.flags.quiet && !context.flags.json) context.output.stderr.write(`${renderSummaryLine(context.ui, "warning", `Skipped Prisma skill install: ${message}`)}\n\n`);
|
|
40
|
-
return [`The Prisma Compute skill was not installed. Run ${await resolvePrismaCliPackageCommand({
|
|
41
|
-
cwd: projectDir,
|
|
42
|
-
signal: context.runtime.signal,
|
|
43
|
-
args: [
|
|
44
|
-
...PRISMA_AGENT_INSTALL_ARGS,
|
|
45
|
-
"--skill",
|
|
46
|
-
PRISMA_COMPUTE_AGENT_SKILL
|
|
47
|
-
]
|
|
48
|
-
})} to try again.`];
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
//#endregion
|
|
52
|
-
export { maybePromptForAgentSetup };
|
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
import { resolveSkillsPackageRunner } from "../lib/agent/package-manager.js";
|
|
2
|
-
import { resolvePrismaCliPackageCommand } from "../lib/agent/cli-command.js";
|
|
3
|
-
import { DEFAULT_PRISMA_AGENT_SKILLS, DEFAULT_PRISMA_AGENT_TARGETS, PRISMA_AGENT_INSTALL_ARGS, PRISMA_AGENT_STATUS_ARGS, PRISMA_SKILLS_SOURCE, SKILLS_CLI_PACKAGE } from "../lib/agent/constants.js";
|
|
4
|
-
import { readPrismaAgentSetupStatus, resolvePrismaAgentSetupCwd } from "../lib/agent/setup-status.js";
|
|
5
|
-
import { formatShellCommand } from "../command-arguments.js";
|
|
6
|
-
import { CliError } from "../errors.js";
|
|
7
|
-
import { execa } from "execa";
|
|
8
|
-
//#region src/controllers/agent.ts
|
|
9
|
-
async function runAgentInstall(context, options, operation = "install", runOptions = {}) {
|
|
10
|
-
const dryRun = options.dryRun === true;
|
|
11
|
-
const cwd = await resolvePrismaAgentSetupCwd({
|
|
12
|
-
cwd: runOptions.cwd ?? context.runtime.cwd,
|
|
13
|
-
signal: context.runtime.signal
|
|
14
|
-
});
|
|
15
|
-
const skills = await installSkills(context, {
|
|
16
|
-
command: await buildSkillsInstallCommand(context, options, cwd),
|
|
17
|
-
cwd,
|
|
18
|
-
dryRun
|
|
19
|
-
});
|
|
20
|
-
const nextSteps = await resolveAgentInstallNextSteps(context, {
|
|
21
|
-
cwd,
|
|
22
|
-
dryRun,
|
|
23
|
-
global: options.global === true
|
|
24
|
-
});
|
|
25
|
-
return {
|
|
26
|
-
command: `agent.${operation}`,
|
|
27
|
-
result: {
|
|
28
|
-
operation,
|
|
29
|
-
skills
|
|
30
|
-
},
|
|
31
|
-
warnings: [],
|
|
32
|
-
nextSteps
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
async function resolveAgentInstallNextSteps(context, options) {
|
|
36
|
-
if (options.dryRun) return [];
|
|
37
|
-
return [`Run ${await resolvePrismaCliPackageCommand({
|
|
38
|
-
cwd: options.cwd,
|
|
39
|
-
signal: context.runtime.signal,
|
|
40
|
-
args: options.global ? [...PRISMA_AGENT_STATUS_ARGS, "--global"] : PRISMA_AGENT_STATUS_ARGS
|
|
41
|
-
})} to verify the installed Prisma skills.`];
|
|
42
|
-
}
|
|
43
|
-
async function runAgentStatus(context, options = {}) {
|
|
44
|
-
const statusScope = options.global ? "global" : "project";
|
|
45
|
-
const cwd = await resolvePrismaAgentSetupCwd({
|
|
46
|
-
cwd: context.runtime.cwd,
|
|
47
|
-
signal: context.runtime.signal
|
|
48
|
-
});
|
|
49
|
-
const status = await readPrismaAgentSetupStatus({
|
|
50
|
-
cwd,
|
|
51
|
-
stateStore: context.stateStore,
|
|
52
|
-
signal: context.runtime.signal
|
|
53
|
-
});
|
|
54
|
-
const installCommand = await resolvePrismaCliPackageCommand({
|
|
55
|
-
cwd,
|
|
56
|
-
signal: context.runtime.signal,
|
|
57
|
-
args: options.global ? [...PRISMA_AGENT_INSTALL_ARGS, "--global"] : PRISMA_AGENT_INSTALL_ARGS
|
|
58
|
-
});
|
|
59
|
-
const skillsList = await listInstalledPrismaSkills(context, cwd, statusScope);
|
|
60
|
-
const skillsInstalled = skillsList.status === "ok" ? skillsList.skills.length > 0 : statusScope === "project" && status.skillsInstalled;
|
|
61
|
-
const warnings = skillsList.status === "ok" ? [] : [statusScope === "project" ? `Could not read installed skills with ${formatShellCommand(skillsList.command)}: ${skillsList.message}. Falling back to ${status.skillsLockPath}.` : `Could not read globally installed skills with ${formatShellCommand(skillsList.command)}: ${skillsList.message}.`];
|
|
62
|
-
const statusSource = resolveStatusSource(skillsList, statusScope);
|
|
63
|
-
return {
|
|
64
|
-
command: "agent.status",
|
|
65
|
-
result: {
|
|
66
|
-
skills: skillsList.status === "ok" ? skillsList.skills : [],
|
|
67
|
-
skillsListCommand: skillsList.command,
|
|
68
|
-
statusScope,
|
|
69
|
-
skillsLockPath: status.skillsLockPath,
|
|
70
|
-
skillsLockInstalled: status.skillsInstalled,
|
|
71
|
-
skillsInstalled,
|
|
72
|
-
statusSource,
|
|
73
|
-
promptDismissedAt: status.promptDismissedAt
|
|
74
|
-
},
|
|
75
|
-
warnings,
|
|
76
|
-
nextSteps: skillsInstalled ? [] : [`Run ${installCommand} to install or refresh Prisma skills.`]
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
async function buildSkillsInstallCommand(context, options, cwd) {
|
|
80
|
-
const command = [
|
|
81
|
-
...await resolveSkillsPackageRunner({
|
|
82
|
-
cwd,
|
|
83
|
-
signal: context.runtime.signal
|
|
84
|
-
}),
|
|
85
|
-
SKILLS_CLI_PACKAGE,
|
|
86
|
-
"add",
|
|
87
|
-
PRISMA_SKILLS_SOURCE
|
|
88
|
-
];
|
|
89
|
-
const skills = options.skill && options.skill.length > 0 ? options.skill : DEFAULT_PRISMA_AGENT_SKILLS;
|
|
90
|
-
const agents = resolveTargetAgents(options);
|
|
91
|
-
for (const skill of skills) command.push("--skill", skill);
|
|
92
|
-
for (const agent of agents) command.push("--agent", agent);
|
|
93
|
-
if (options.global) command.push("--global");
|
|
94
|
-
if (options.copy || process.platform === "win32") command.push("--copy");
|
|
95
|
-
command.push("--yes");
|
|
96
|
-
return command;
|
|
97
|
-
}
|
|
98
|
-
function resolveTargetAgents(options) {
|
|
99
|
-
if (options.allAgents) return ["*"];
|
|
100
|
-
if (options.agent && options.agent.length > 0) return options.agent;
|
|
101
|
-
return DEFAULT_PRISMA_AGENT_TARGETS;
|
|
102
|
-
}
|
|
103
|
-
async function installSkills(context, options) {
|
|
104
|
-
if (options.dryRun) return {
|
|
105
|
-
status: "would-install",
|
|
106
|
-
command: options.command
|
|
107
|
-
};
|
|
108
|
-
await runChildProcess(context, options.command, options.cwd);
|
|
109
|
-
return {
|
|
110
|
-
status: "installed",
|
|
111
|
-
command: options.command
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
async function listInstalledPrismaSkills(context, cwd, scope) {
|
|
115
|
-
const command = [
|
|
116
|
-
...await resolveSkillsPackageRunner({
|
|
117
|
-
cwd,
|
|
118
|
-
signal: context.runtime.signal
|
|
119
|
-
}),
|
|
120
|
-
SKILLS_CLI_PACKAGE,
|
|
121
|
-
"list",
|
|
122
|
-
...scope === "global" ? ["-g"] : [],
|
|
123
|
-
"--json"
|
|
124
|
-
];
|
|
125
|
-
try {
|
|
126
|
-
const { stdout } = await runChildProcessCapture(context, command, cwd);
|
|
127
|
-
return {
|
|
128
|
-
status: "ok",
|
|
129
|
-
command,
|
|
130
|
-
skills: parseSkillsListOutput(stdout).filter((skill) => isPrismaSkillName(skill.name))
|
|
131
|
-
};
|
|
132
|
-
} catch (error) {
|
|
133
|
-
if (isAbortError(error) || context.runtime.signal.aborted) throw error;
|
|
134
|
-
return {
|
|
135
|
-
status: "failed",
|
|
136
|
-
command,
|
|
137
|
-
message: error instanceof Error ? error.message : String(error)
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
async function runChildProcess(context, command, cwd) {
|
|
142
|
-
const [executable, args] = splitCommand(command);
|
|
143
|
-
try {
|
|
144
|
-
await execa(executable, args, {
|
|
145
|
-
cwd,
|
|
146
|
-
env: context.runtime.env,
|
|
147
|
-
cancelSignal: context.runtime.signal,
|
|
148
|
-
stdin: "ignore"
|
|
149
|
-
});
|
|
150
|
-
} catch (error) {
|
|
151
|
-
if (isAbortError(error)) throw error;
|
|
152
|
-
throw skillsInstallFailed(command, exitCodeFromError(error), error);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
async function runChildProcessCapture(context, command, cwd) {
|
|
156
|
-
const [executable, args] = splitCommand(command);
|
|
157
|
-
const result = await execa(executable, args, {
|
|
158
|
-
cwd,
|
|
159
|
-
env: context.runtime.env,
|
|
160
|
-
cancelSignal: context.runtime.signal,
|
|
161
|
-
stdin: "ignore"
|
|
162
|
-
});
|
|
163
|
-
return {
|
|
164
|
-
stdout: result.stdout ?? "",
|
|
165
|
-
stderr: result.stderr ?? ""
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
function splitCommand(command) {
|
|
169
|
-
const [executable, ...args] = command;
|
|
170
|
-
if (!executable) throw new Error("Cannot run an empty command.");
|
|
171
|
-
return [executable, args];
|
|
172
|
-
}
|
|
173
|
-
function isAbortError(error) {
|
|
174
|
-
return error instanceof Error && error.name === "AbortError" || isObject(error) && error.isCanceled === true;
|
|
175
|
-
}
|
|
176
|
-
function exitCodeFromError(error) {
|
|
177
|
-
if (!isObject(error) || typeof error.exitCode !== "number") return null;
|
|
178
|
-
return error.exitCode;
|
|
179
|
-
}
|
|
180
|
-
function isObject(value) {
|
|
181
|
-
return typeof value === "object" && value !== null;
|
|
182
|
-
}
|
|
183
|
-
function resolveStatusSource(skillsList, statusScope) {
|
|
184
|
-
if (skillsList.status === "ok") return "skills-cli";
|
|
185
|
-
return statusScope === "project" ? "skills-lock" : "unavailable";
|
|
186
|
-
}
|
|
187
|
-
function parseSkillsListOutput(output) {
|
|
188
|
-
const parsed = JSON.parse(output);
|
|
189
|
-
if (!Array.isArray(parsed)) throw new Error("skills list did not return a JSON array");
|
|
190
|
-
return parsed.flatMap((item) => {
|
|
191
|
-
const skill = parseInstalledSkill(item);
|
|
192
|
-
return skill ? [skill] : [];
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
function parseInstalledSkill(value) {
|
|
196
|
-
if (typeof value !== "object" || value === null) return null;
|
|
197
|
-
const candidate = value;
|
|
198
|
-
if (typeof candidate.name !== "string" || typeof candidate.path !== "string" || typeof candidate.scope !== "string" || !Array.isArray(candidate.agents)) return null;
|
|
199
|
-
return {
|
|
200
|
-
name: candidate.name,
|
|
201
|
-
path: candidate.path,
|
|
202
|
-
scope: candidate.scope,
|
|
203
|
-
agents: candidate.agents.filter((agent) => typeof agent === "string")
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
|
-
function isPrismaSkillName(name) {
|
|
207
|
-
return name === "prisma" || name.startsWith("prisma-");
|
|
208
|
-
}
|
|
209
|
-
function skillsInstallFailed(command, code, error) {
|
|
210
|
-
const commandText = formatShellCommand(command);
|
|
211
|
-
return new CliError({
|
|
212
|
-
code: "AGENT_SKILLS_INSTALL_FAILED",
|
|
213
|
-
domain: "cli",
|
|
214
|
-
summary: "Prisma skills install failed",
|
|
215
|
-
why: `The skills installer exited with code ${code ?? "unknown"}.`,
|
|
216
|
-
fix: "Run the command below to retry the installer directly.",
|
|
217
|
-
debug: formatErrorDebug(error),
|
|
218
|
-
exitCode: 1,
|
|
219
|
-
nextSteps: [commandText]
|
|
220
|
-
});
|
|
221
|
-
}
|
|
222
|
-
function formatErrorDebug(error) {
|
|
223
|
-
if (error instanceof Error) return error.stack ?? error.message;
|
|
224
|
-
if (error === void 0) return;
|
|
225
|
-
return String(error);
|
|
226
|
-
}
|
|
227
|
-
//#endregion
|
|
228
|
-
export { runAgentInstall, runAgentStatus };
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { CliError, authRequiredError } from "../errors.js";
|
|
2
|
-
//#region src/controllers/app-env-api.ts
|
|
3
|
-
async function findVariableByNaturalKey(client, projectId, key, resolved, signal) {
|
|
4
|
-
const { data, error, response } = await client.GET("/v1/environment-variables", {
|
|
5
|
-
params: { query: {
|
|
6
|
-
projectId,
|
|
7
|
-
class: resolved.apiTarget.class,
|
|
8
|
-
key,
|
|
9
|
-
...resolved.apiTarget.branchId !== null ? { branchId: resolved.apiTarget.branchId } : {}
|
|
10
|
-
} },
|
|
11
|
-
signal
|
|
12
|
-
});
|
|
13
|
-
if (error || !data) throw apiCallError(`Failed to look up ${key}`, response, error);
|
|
14
|
-
return data.data.filter((row) => rowMatchesExactScope(row, resolved))[0] ?? null;
|
|
15
|
-
}
|
|
16
|
-
function toMetadata(row, requestedScope) {
|
|
17
|
-
const rowScope = row.branchId === null ? {
|
|
18
|
-
kind: "role",
|
|
19
|
-
role: row.class
|
|
20
|
-
} : requestedScope;
|
|
21
|
-
return {
|
|
22
|
-
id: row.id,
|
|
23
|
-
key: row.key,
|
|
24
|
-
scope: rowScope,
|
|
25
|
-
source: formatDescriptorLabel(rowScope),
|
|
26
|
-
isManagedBySystem: row.isManagedBySystem,
|
|
27
|
-
updatedAt: row.updatedAt
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
function rowMatchesExactScope(row, resolved) {
|
|
31
|
-
return row.class === resolved.apiTarget.class && row.branchId === resolved.apiTarget.branchId;
|
|
32
|
-
}
|
|
33
|
-
function apiCallError(summary, response, error) {
|
|
34
|
-
const status = response?.status ?? 0;
|
|
35
|
-
const apiCode = error?.error?.code;
|
|
36
|
-
const apiMessage = error?.error?.message;
|
|
37
|
-
const apiHint = error?.error?.hint;
|
|
38
|
-
if (status === 401 || status === 403) return authRequiredError(["prisma auth login"]);
|
|
39
|
-
return new CliError({
|
|
40
|
-
code: apiCode ?? "ENV_API_ERROR",
|
|
41
|
-
domain: "app",
|
|
42
|
-
summary,
|
|
43
|
-
why: apiMessage ?? `The Management API returned status ${status || "unknown"}.`,
|
|
44
|
-
fix: apiHint ?? "Re-run with --trace for the underlying API response details.",
|
|
45
|
-
exitCode: 1,
|
|
46
|
-
nextSteps: []
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
function formatDescriptorLabel(scope) {
|
|
50
|
-
if (scope.kind === "role") return scope.role ?? "unknown";
|
|
51
|
-
if (scope.kind === "overview") return "overview";
|
|
52
|
-
return `branch:${scope.branchName ?? scope.branchId ?? "unknown"}`;
|
|
53
|
-
}
|
|
54
|
-
//#endregion
|
|
55
|
-
export { apiCallError, findVariableByNaturalKey, toMetadata };
|
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
import { CliError } from "../errors.js";
|
|
2
|
-
import { formatScopeLabel } from "../lib/app/env-config.js";
|
|
3
|
-
import { apiCallError, findVariableByNaturalKey, toMetadata } from "./app-env-api.js";
|
|
4
|
-
//#region src/controllers/app-env-file.ts
|
|
5
|
-
async function runEnvAddFile(context, client, projectId, resolved, filePath, assignments, verboseContext) {
|
|
6
|
-
const existing = await findVariablesByNaturalKey(client, projectId, assignments.map((assignment) => assignment.key), resolved, context.runtime.signal);
|
|
7
|
-
const existingKeys = assignments.map((assignment) => assignment.key).filter((key) => existing.has(key));
|
|
8
|
-
if (existingKeys.length > 0) throw new CliError({
|
|
9
|
-
code: "ENV_VARIABLE_ALREADY_EXISTS",
|
|
10
|
-
domain: "app",
|
|
11
|
-
summary: `${existingKeys.length} environment variable(s) already exist in ${formatScopeLabel(resolved.scope)}`,
|
|
12
|
-
why: `Existing keys: ${formatKeyList(existingKeys)}.`,
|
|
13
|
-
fix: "Split the input file by key state: update existing keys and add new keys separately.",
|
|
14
|
-
exitCode: 1,
|
|
15
|
-
nextSteps: splitFileNextSteps(filePath, resolved.scope, {
|
|
16
|
-
existingKeys,
|
|
17
|
-
first: "update-existing"
|
|
18
|
-
}),
|
|
19
|
-
meta: { keys: existingKeys }
|
|
20
|
-
});
|
|
21
|
-
const warnings = await missingPreviewDefaultWarnings(client, projectId, resolved.scope, assignments.map((assignment) => assignment.key), context.runtime.signal);
|
|
22
|
-
const variables = [];
|
|
23
|
-
for (const assignment of assignments) try {
|
|
24
|
-
const { data, error, response } = await client.POST("/v1/environment-variables", {
|
|
25
|
-
body: {
|
|
26
|
-
projectId,
|
|
27
|
-
class: resolved.apiTarget.class,
|
|
28
|
-
...resolved.apiTarget.branchId !== null ? { branchId: resolved.apiTarget.branchId } : {},
|
|
29
|
-
key: assignment.key,
|
|
30
|
-
value: assignment.value
|
|
31
|
-
},
|
|
32
|
-
signal: context.runtime.signal
|
|
33
|
-
});
|
|
34
|
-
if (error || !data) throw apiCallError(`Failed to add ${assignment.key}`, response, error);
|
|
35
|
-
variables.push(toMetadata(data.data, resolved.descriptor));
|
|
36
|
-
} catch (error) {
|
|
37
|
-
throw envFileApplyFailedError("add", filePath, resolved.scope, assignment.key, variables, error);
|
|
38
|
-
}
|
|
39
|
-
return {
|
|
40
|
-
command: "project.env.add",
|
|
41
|
-
result: {
|
|
42
|
-
projectId,
|
|
43
|
-
verboseContext,
|
|
44
|
-
scope: resolved.descriptor,
|
|
45
|
-
variables,
|
|
46
|
-
file: {
|
|
47
|
-
path: filePath,
|
|
48
|
-
count: variables.length
|
|
49
|
-
}
|
|
50
|
-
},
|
|
51
|
-
warnings,
|
|
52
|
-
nextSteps: []
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
async function runEnvUpdateFile(context, client, projectId, resolved, filePath, assignments, verboseContext) {
|
|
56
|
-
const existing = await findVariablesByNaturalKey(client, projectId, assignments.map((assignment) => assignment.key), resolved, context.runtime.signal);
|
|
57
|
-
const missingKeys = assignments.map((assignment) => assignment.key).filter((key) => !existing.has(key));
|
|
58
|
-
if (missingKeys.length > 0) throw new CliError({
|
|
59
|
-
code: "ENV_VARIABLE_NOT_FOUND",
|
|
60
|
-
domain: "app",
|
|
61
|
-
summary: `${missingKeys.length} environment variable(s) not found in ${formatScopeLabel(resolved.scope)}`,
|
|
62
|
-
why: `Missing keys: ${formatKeyList(missingKeys)}.`,
|
|
63
|
-
fix: "Split the input file by key state: add missing keys and update existing keys separately.",
|
|
64
|
-
exitCode: 1,
|
|
65
|
-
nextSteps: splitFileNextSteps(filePath, resolved.scope, {
|
|
66
|
-
missingKeys,
|
|
67
|
-
first: "add-missing"
|
|
68
|
-
}),
|
|
69
|
-
meta: { keys: missingKeys }
|
|
70
|
-
});
|
|
71
|
-
const variables = [];
|
|
72
|
-
for (const assignment of assignments) {
|
|
73
|
-
const existingVariable = existing.get(assignment.key);
|
|
74
|
-
if (!existingVariable) continue;
|
|
75
|
-
try {
|
|
76
|
-
const { data, error, response } = await client.PATCH("/v1/environment-variables/{envVarId}", {
|
|
77
|
-
params: { path: { envVarId: existingVariable.id } },
|
|
78
|
-
body: { value: assignment.value },
|
|
79
|
-
signal: context.runtime.signal
|
|
80
|
-
});
|
|
81
|
-
if (error || !data) throw apiCallError(`Failed to update value for ${assignment.key}`, response, error);
|
|
82
|
-
variables.push(toMetadata(data.data, resolved.descriptor));
|
|
83
|
-
} catch (error) {
|
|
84
|
-
throw envFileApplyFailedError("update", filePath, resolved.scope, assignment.key, variables, error);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
return {
|
|
88
|
-
command: "project.env.update",
|
|
89
|
-
result: {
|
|
90
|
-
projectId,
|
|
91
|
-
verboseContext,
|
|
92
|
-
scope: resolved.descriptor,
|
|
93
|
-
variables,
|
|
94
|
-
file: {
|
|
95
|
-
path: filePath,
|
|
96
|
-
count: variables.length
|
|
97
|
-
}
|
|
98
|
-
},
|
|
99
|
-
warnings: [],
|
|
100
|
-
nextSteps: []
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
async function findVariablesByNaturalKey(client, projectId, keys, resolved, signal) {
|
|
104
|
-
const found = /* @__PURE__ */ new Map();
|
|
105
|
-
for (const key of keys) {
|
|
106
|
-
const row = await findVariableByNaturalKey(client, projectId, key, resolved, signal);
|
|
107
|
-
if (row) found.set(key, row);
|
|
108
|
-
}
|
|
109
|
-
return found;
|
|
110
|
-
}
|
|
111
|
-
async function missingPreviewDefaultWarnings(client, projectId, scope, keys, signal) {
|
|
112
|
-
if (scope.kind !== "branch") return [];
|
|
113
|
-
const previewScope = {
|
|
114
|
-
scope: {
|
|
115
|
-
kind: "role",
|
|
116
|
-
role: "preview"
|
|
117
|
-
},
|
|
118
|
-
descriptor: {
|
|
119
|
-
kind: "role",
|
|
120
|
-
role: "preview"
|
|
121
|
-
},
|
|
122
|
-
apiTarget: {
|
|
123
|
-
class: "preview",
|
|
124
|
-
branchId: null
|
|
125
|
-
}
|
|
126
|
-
};
|
|
127
|
-
const missing = [];
|
|
128
|
-
for (const key of keys) if (!await findVariableByNaturalKey(client, projectId, key, previewScope, signal)) missing.push(key);
|
|
129
|
-
if (missing.length === 0) return [];
|
|
130
|
-
if (missing.length === 1) return [`Variable "${missing[0]}" does not exist in preview. It will only exist on ${formatScopeLabel(scope)}.`];
|
|
131
|
-
return [`Variables ${formatKeyList(missing)} do not exist in preview. They will only exist on ${formatScopeLabel(scope)}.`];
|
|
132
|
-
}
|
|
133
|
-
function envFileApplyFailedError(command, filePath, scope, failedKey, writtenVariables, error) {
|
|
134
|
-
const writtenKeys = writtenVariables.map((variable) => variable.key);
|
|
135
|
-
const cause = error instanceof CliError ? error.summary : error instanceof Error ? error.message : "Unknown error.";
|
|
136
|
-
return new CliError({
|
|
137
|
-
code: "ENV_FILE_APPLY_FAILED",
|
|
138
|
-
domain: "app",
|
|
139
|
-
summary: `Failed to ${command} "${failedKey}" from "${filePath}"`,
|
|
140
|
-
why: writtenKeys.length === 0 ? `No variables were written before ${failedKey} failed. Cause: ${cause}` : `Written keys before failure: ${formatKeyList(writtenKeys)}. Cause: ${cause}`,
|
|
141
|
-
fix: "Inspect the target scope, then retry the remaining keys once the API issue is resolved.",
|
|
142
|
-
exitCode: 1,
|
|
143
|
-
nextSteps: [`prisma-cli project env list ${formatScopeFlag(scope)}`, retryStepForApplyFailure(command, filePath, scope, writtenKeys)],
|
|
144
|
-
meta: {
|
|
145
|
-
file: filePath,
|
|
146
|
-
failedKey,
|
|
147
|
-
writtenKeys
|
|
148
|
-
}
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
function retryStepForApplyFailure(command, filePath, scope, writtenKeys) {
|
|
152
|
-
if (command === "update") return `prisma-cli project env update --file ${filePath} ${formatScopeFlag(scope)}`;
|
|
153
|
-
if (writtenKeys.length === 0) return `prisma-cli project env add --file ${filePath} ${formatScopeFlag(scope)}`;
|
|
154
|
-
return `prisma-cli project env add --file <remaining.env> ${formatScopeFlag(scope)}`;
|
|
155
|
-
}
|
|
156
|
-
function splitFileNextSteps(filePath, scope, options) {
|
|
157
|
-
const scopeFlag = formatScopeFlag(scope);
|
|
158
|
-
const existingFile = `${filePath}.existing`;
|
|
159
|
-
const newFile = `${filePath}.new`;
|
|
160
|
-
if (options.first === "update-existing") return [
|
|
161
|
-
`# existing keys: ${formatKeyList(options.existingKeys)}`,
|
|
162
|
-
`prisma-cli project env update --file ${existingFile} ${scopeFlag}`,
|
|
163
|
-
"# new keys only",
|
|
164
|
-
`prisma-cli project env add --file ${newFile} ${scopeFlag}`
|
|
165
|
-
];
|
|
166
|
-
return [
|
|
167
|
-
`# missing keys: ${formatKeyList(options.missingKeys)}`,
|
|
168
|
-
`prisma-cli project env add --file ${newFile} ${scopeFlag}`,
|
|
169
|
-
"# existing keys only",
|
|
170
|
-
`prisma-cli project env update --file ${existingFile} ${scopeFlag}`
|
|
171
|
-
];
|
|
172
|
-
}
|
|
173
|
-
function formatKeyList(keys) {
|
|
174
|
-
return keys.map((key) => `"${key}"`).join(", ");
|
|
175
|
-
}
|
|
176
|
-
function formatScopeFlag(scope) {
|
|
177
|
-
if (scope.kind === "role") return `--role ${scope.role}`;
|
|
178
|
-
return `--branch ${scope.branchName}`;
|
|
179
|
-
}
|
|
180
|
-
//#endregion
|
|
181
|
-
export { runEnvAddFile, runEnvUpdateFile };
|