@prisma/cli 3.0.0-dev.102.1 → 3.0.0-dev.105.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/dist/adapters/local-state.js +14 -3
- package/dist/adapters/token-storage.js +1 -1
- package/dist/cli2.js +4 -2
- package/dist/commands/agent/index.js +60 -0
- package/dist/commands/app/index.js +5 -3
- package/dist/commands/auth/index.js +1 -1
- package/dist/commands/git/index.js +1 -1
- package/dist/commands/project/index.js +1 -1
- package/dist/controllers/agent.js +228 -0
- package/dist/controllers/app.js +156 -72
- package/dist/controllers/auth.js +38 -3
- package/dist/controllers/project.js +2 -2
- package/dist/controllers/select-prompt-port.js +1 -0
- package/dist/lib/agent/cli-command.js +17 -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/branch-database-deploy.js +3 -2
- package/dist/lib/app/branch-database.js +2 -1
- package/dist/lib/app/build-settings.js +1 -1
- package/dist/lib/app/build.js +2 -2
- package/dist/lib/app/bun-project.js +1 -1
- package/dist/lib/app/compute-config.js +27 -29
- package/dist/lib/app/deploy-plan.js +1 -0
- package/dist/lib/app/env-file.js +1 -1
- package/dist/lib/app/local-dev.js +1 -1
- package/dist/lib/app/production-deploy-gate.js +2 -1
- package/dist/lib/auth/login.js +1 -1
- package/dist/lib/git/local-branch.js +1 -1
- package/dist/lib/project/interactive-setup.js +1 -0
- package/dist/lib/project/local-pin.js +1 -1
- package/dist/lib/project/resolution.js +2 -2
- package/dist/lib/project/setup.js +1 -1
- package/dist/presenters/agent.js +74 -0
- package/dist/presenters/auth.js +1 -1
- package/dist/presenters/project.js +1 -1
- package/dist/shell/cli-command.js +12 -0
- package/dist/shell/command-arguments.js +7 -1
- package/dist/shell/command-meta.js +72 -0
- package/dist/shell/command-runner.js +1 -1
- package/dist/shell/help.js +6 -5
- package/dist/shell/prompt.js +7 -3
- package/dist/shell/runtime.js +2 -2
- package/dist/shell/update-check.js +2 -2
- package/package.json +3 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
1
|
import path from "node:path";
|
|
2
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
3
3
|
//#region src/adapters/local-state.ts
|
|
4
4
|
const DEFAULT_STATE = {
|
|
5
5
|
auth: null,
|
|
@@ -12,7 +12,8 @@ const DEFAULT_STATE = {
|
|
|
12
12
|
app: {
|
|
13
13
|
selectedByProject: {},
|
|
14
14
|
knownLiveDeploymentByProject: {}
|
|
15
|
-
}
|
|
15
|
+
},
|
|
16
|
+
agent: { setupPromptDismissedAt: null }
|
|
16
17
|
};
|
|
17
18
|
const DEFAULT_STATE_FILE_NAME = "state.json";
|
|
18
19
|
function resolveLocalStateFilePath(stateDir) {
|
|
@@ -43,7 +44,8 @@ var LocalStateStore = class {
|
|
|
43
44
|
app: {
|
|
44
45
|
selectedByProject: parsed.app?.selectedByProject ?? {},
|
|
45
46
|
knownLiveDeploymentByProject: parsed.app?.knownLiveDeploymentByProject ?? {}
|
|
46
|
-
}
|
|
47
|
+
},
|
|
48
|
+
agent: { setupPromptDismissedAt: parsed.agent?.setupPromptDismissedAt ?? null }
|
|
47
49
|
};
|
|
48
50
|
} catch (error) {
|
|
49
51
|
if (error.code === "ENOENT") return structuredClone(DEFAULT_STATE);
|
|
@@ -139,6 +141,15 @@ var LocalStateStore = class {
|
|
|
139
141
|
await this.write(state);
|
|
140
142
|
return state;
|
|
141
143
|
}
|
|
144
|
+
async readAgentSetupPromptDismissedAt() {
|
|
145
|
+
return (await this.read()).agent.setupPromptDismissedAt;
|
|
146
|
+
}
|
|
147
|
+
async setAgentSetupPromptDismissedAt(dismissedAt) {
|
|
148
|
+
const state = await this.read();
|
|
149
|
+
state.agent.setupPromptDismissedAt = dismissedAt;
|
|
150
|
+
await this.write(state);
|
|
151
|
+
return state;
|
|
152
|
+
}
|
|
142
153
|
};
|
|
143
154
|
//#endregion
|
|
144
155
|
export { LocalStateStore, resolveLocalStateFilePath };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getAuthFilePath } from "../lib/auth/client.js";
|
|
2
|
-
import fs from "node:fs/promises";
|
|
3
2
|
import path from "node:path";
|
|
3
|
+
import fs from "node:fs/promises";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
5
5
|
import { CredentialsStore } from "@prisma/credentials-store";
|
|
6
6
|
//#region src/adapters/token-storage.ts
|
package/dist/cli2.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { CliError } from "./shell/errors.js";
|
|
2
|
-
import "./shell/prompt.js";
|
|
3
2
|
import { attachCommandDescriptor } from "./shell/command-meta.js";
|
|
4
|
-
import { addCompactGlobalFlags } from "./shell/global-flags.js";
|
|
5
3
|
import { createShellUi } from "./shell/ui.js";
|
|
4
|
+
import { addCompactGlobalFlags } from "./shell/global-flags.js";
|
|
6
5
|
import { configureRuntimeCommand, createCommandContext } from "./shell/runtime.js";
|
|
7
6
|
import { formatUnexpectedError, writeHumanError, writeJsonError, writeJsonSuccess } from "./shell/output.js";
|
|
7
|
+
import { createAgentCommand } from "./commands/agent/index.js";
|
|
8
|
+
import "./shell/prompt.js";
|
|
8
9
|
import { createAppCommand } from "./commands/app/index.js";
|
|
9
10
|
import { createAuthCommand } from "./commands/auth/index.js";
|
|
10
11
|
import { createBranchCommand } from "./commands/branch/index.js";
|
|
@@ -46,6 +47,7 @@ function createProgram(runtime) {
|
|
|
46
47
|
program.addOption(new Option("--version", "Print the CLI version and exit."));
|
|
47
48
|
program.name("prisma").showSuggestionAfterError();
|
|
48
49
|
program.addCommand(createVersionCommand(runtime));
|
|
50
|
+
program.addCommand(createAgentCommand(runtime));
|
|
49
51
|
program.addCommand(createAuthCommand(runtime));
|
|
50
52
|
program.addCommand(createProjectCommand(runtime));
|
|
51
53
|
program.addCommand(createGitCommand(runtime));
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { runAgentInstall, runAgentStatus } from "../../controllers/agent.js";
|
|
2
|
+
import { attachCommandDescriptor } from "../../shell/command-meta.js";
|
|
3
|
+
import { renderAgentInstall, renderAgentStatus, serializeAgentInstall, serializeAgentStatus } from "../../presenters/agent.js";
|
|
4
|
+
import { addCompactGlobalFlags, addGlobalFlags } from "../../shell/global-flags.js";
|
|
5
|
+
import { configureRuntimeCommand } from "../../shell/runtime.js";
|
|
6
|
+
import { runCommand } from "../../shell/command-runner.js";
|
|
7
|
+
import { Command, Option } from "commander";
|
|
8
|
+
//#region src/commands/agent/index.ts
|
|
9
|
+
function createAgentCommand(runtime) {
|
|
10
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("agent"), runtime), "agent");
|
|
11
|
+
addCompactGlobalFlags(command);
|
|
12
|
+
command.addCommand(createAgentInstallCommand(runtime));
|
|
13
|
+
command.addCommand(createAgentUpdateCommand(runtime));
|
|
14
|
+
command.addCommand(createAgentStatusCommand(runtime));
|
|
15
|
+
return command;
|
|
16
|
+
}
|
|
17
|
+
function createAgentInstallCommand(runtime) {
|
|
18
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("install"), runtime), "agent.install");
|
|
19
|
+
addAgentInstallOptions(command);
|
|
20
|
+
addGlobalFlags(command);
|
|
21
|
+
command.action(async (options) => {
|
|
22
|
+
await runCommand(runtime, "agent.install", options, (context) => runAgentInstall(context, options, "install"), {
|
|
23
|
+
renderHuman: (context, descriptor, result) => renderAgentInstall(context, descriptor, result),
|
|
24
|
+
renderJson: (result) => serializeAgentInstall(result)
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
return command;
|
|
28
|
+
}
|
|
29
|
+
function createAgentUpdateCommand(runtime) {
|
|
30
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("update"), runtime), "agent.update");
|
|
31
|
+
addAgentInstallOptions(command);
|
|
32
|
+
addGlobalFlags(command);
|
|
33
|
+
command.action(async (options) => {
|
|
34
|
+
await runCommand(runtime, "agent.update", options, (context) => runAgentInstall(context, options, "update"), {
|
|
35
|
+
renderHuman: (context, descriptor, result) => renderAgentInstall(context, descriptor, result),
|
|
36
|
+
renderJson: (result) => serializeAgentInstall(result)
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
return command;
|
|
40
|
+
}
|
|
41
|
+
function createAgentStatusCommand(runtime) {
|
|
42
|
+
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("status"), runtime), "agent.status");
|
|
43
|
+
command.addOption(new Option("--global", "Check globally installed Prisma skills instead of project skills"));
|
|
44
|
+
addGlobalFlags(command);
|
|
45
|
+
command.action(async (options) => {
|
|
46
|
+
await runCommand(runtime, "agent.status", options, (context) => runAgentStatus(context, options), {
|
|
47
|
+
renderHuman: (context, descriptor, result) => renderAgentStatus(context, descriptor, result),
|
|
48
|
+
renderJson: (result) => serializeAgentStatus(result)
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
return command;
|
|
52
|
+
}
|
|
53
|
+
function addAgentInstallOptions(command) {
|
|
54
|
+
command.addOption(new Option("--agent <agent>", "Agent target for Prisma skills; repeat for multiple agents").argParser(collectValues)).addOption(new Option("--all-agents", "Install Prisma skills for every agent supported by the skills CLI")).addOption(new Option("--skill <skill>", "Prisma skill to install; repeat for multiple skills").argParser(collectValues)).addOption(new Option("--global", "Install skills into the user directory instead of the project")).addOption(new Option("--copy", "Ask the skills CLI to copy files instead of symlinking them")).addOption(new Option("--dry-run", "Show changes without writing files"));
|
|
55
|
+
}
|
|
56
|
+
function collectValues(value, previous) {
|
|
57
|
+
return [...previous ?? [], value];
|
|
58
|
+
}
|
|
59
|
+
//#endregion
|
|
60
|
+
export { createAgentCommand };
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { usageError } from "../../shell/errors.js";
|
|
2
|
-
import { APP_BUILD_TYPES } from "../../lib/app/build.js";
|
|
3
2
|
import { attachCommandDescriptor } from "../../shell/command-meta.js";
|
|
4
3
|
import { addCompactGlobalFlags, addGlobalFlags } from "../../shell/global-flags.js";
|
|
5
4
|
import { configureRuntimeCommand } from "../../shell/runtime.js";
|
|
5
|
+
import { runCommand, runStreamingCommand } from "../../shell/command-runner.js";
|
|
6
|
+
import { APP_BUILD_TYPES } from "../../lib/app/build.js";
|
|
6
7
|
import { runAppBuild, runAppDeploy, runAppDomainAdd, runAppDomainRemove, runAppDomainRetry, runAppDomainShow, runAppDomainWait, runAppListDeploys, runAppLogs, runAppOpen, runAppPromote, runAppRemove, runAppRollback, runAppRun, runAppShow, runAppShowDeploy } from "../../controllers/app.js";
|
|
7
8
|
import { isAppDeployAllResult, renderAppBuild, renderAppDeploy, renderAppDeployAll, renderAppDomainAdd, renderAppDomainRemove, renderAppDomainRetry, renderAppDomainShow, renderAppListDeploys, renderAppOpen, renderAppPromote, renderAppRemove, renderAppRollback, renderAppRun, renderAppShow, renderAppShowDeploy, serializeAppBuild, serializeAppDeploy, serializeAppDeployAll, serializeAppDomainAdd, serializeAppDomainRemove, serializeAppDomainRetry, serializeAppDomainShow, serializeAppListDeploys, serializeAppOpen, serializeAppPromote, serializeAppRemove, serializeAppRollback, serializeAppRun, serializeAppShow, serializeAppShowDeploy } from "../../presenters/app.js";
|
|
8
|
-
import { runCommand, runStreamingCommand } from "../../shell/command-runner.js";
|
|
9
9
|
import { Command, Option } from "commander";
|
|
10
10
|
import { FRAMEWORK_KEYS, LOCAL_DEV_BUILD_TYPES } from "@prisma/compute-sdk/config";
|
|
11
11
|
//#region src/commands/app/index.ts
|
|
@@ -66,7 +66,7 @@ function createRunCommand(runtime) {
|
|
|
66
66
|
}
|
|
67
67
|
function createDeployCommand(runtime) {
|
|
68
68
|
const command = attachCommandDescriptor(configureRuntimeCommand(new Command("deploy"), runtime), "app.deploy");
|
|
69
|
-
command.argument("[app]", "App target from prisma.compute.ts when the config defines multiple apps").addOption(new Option("--app <name>", "App name")).addOption(new Option("--project <id-or-name>", "Project id or name")).addOption(new Option("--create-project <name>", "Create and link a new Project before deploying")).addOption(new Option("--branch <name>", "Branch name")).addOption(new Option("--framework <name>", "Framework to deploy").choices([...FRAMEWORK_KEYS])).addOption(new Option("--entry <path>", "Entrypoint path for Bun deploys")).addOption(new Option("--http-port <port>", "HTTP port override for the deployed app")).addOption(new Option("--env <name=value|file>", "Environment variable assignment or dotenv file").argParser(collectRepeatableValues)).addOption(new Option("--db", "Create and wire a Prisma Postgres database for this deploy target")).addOption(new Option("--no-db", "Skip database setup")).addOption(new Option("--prod", "Confirm intent to deploy to production"));
|
|
69
|
+
command.argument("[app]", "App target from prisma.compute.ts when the config defines multiple apps").addOption(new Option("--app <name>", "App name")).addOption(new Option("--project <id-or-name>", "Project id or name")).addOption(new Option("--create-project <name>", "Create and link a new Project before deploying")).addOption(new Option("--branch <name>", "Branch name")).addOption(new Option("--framework <name>", "Framework to deploy").choices([...FRAMEWORK_KEYS])).addOption(new Option("--entry <path>", "Entrypoint path for Bun deploys")).addOption(new Option("--http-port <port>", "HTTP port override for the deployed app")).addOption(new Option("--region <region>", "Region for a newly created app; existing apps keep their region")).addOption(new Option("--env <name=value|file>", "Environment variable assignment or dotenv file").argParser(collectRepeatableValues)).addOption(new Option("--db", "Create and wire a Prisma Postgres database for this deploy target")).addOption(new Option("--no-db", "Skip database setup")).addOption(new Option("--prod", "Confirm intent to deploy to production"));
|
|
70
70
|
addGlobalFlags(command);
|
|
71
71
|
command.action(async (configTarget, options) => {
|
|
72
72
|
const appName = options.app;
|
|
@@ -74,6 +74,7 @@ function createDeployCommand(runtime) {
|
|
|
74
74
|
const branchName = options.branch;
|
|
75
75
|
const framework = options.framework;
|
|
76
76
|
const httpPort = options.httpPort;
|
|
77
|
+
const region = options.region;
|
|
77
78
|
const envAssignments = options.env;
|
|
78
79
|
const projectRef = options.project;
|
|
79
80
|
const createProjectName = options.createProject;
|
|
@@ -89,6 +90,7 @@ function createDeployCommand(runtime) {
|
|
|
89
90
|
entrypoint: entry,
|
|
90
91
|
framework,
|
|
91
92
|
httpPort,
|
|
93
|
+
region,
|
|
92
94
|
envAssignments,
|
|
93
95
|
prod: prod === true,
|
|
94
96
|
db,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { attachCommandDescriptor } from "../../shell/command-meta.js";
|
|
2
2
|
import { addCompactGlobalFlags, addGlobalFlags } from "../../shell/global-flags.js";
|
|
3
3
|
import { configureRuntimeCommand } from "../../shell/runtime.js";
|
|
4
|
-
import { runAuthLogin, runAuthLogout, runAuthWhoAmI, runAuthWorkspaceList, runAuthWorkspaceLogout, runAuthWorkspaceUse } from "../../controllers/auth.js";
|
|
5
4
|
import { runCommand } from "../../shell/command-runner.js";
|
|
5
|
+
import { runAuthLogin, runAuthLogout, runAuthWhoAmI, runAuthWorkspaceList, runAuthWorkspaceLogout, runAuthWorkspaceUse } from "../../controllers/auth.js";
|
|
6
6
|
import { renderAuthSuccess, renderAuthWorkspaceList, renderAuthWorkspaceLogout, renderAuthWorkspaceUse, serializeAuthWorkspaceList, serializeAuthWorkspaceLogout, serializeAuthWorkspaceUse } from "../../presenters/auth.js";
|
|
7
7
|
import { Command, Option } from "commander";
|
|
8
8
|
//#region src/commands/auth/index.ts
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { attachCommandDescriptor } from "../../shell/command-meta.js";
|
|
2
2
|
import { addCompactGlobalFlags, addGlobalFlags } from "../../shell/global-flags.js";
|
|
3
3
|
import { configureRuntimeCommand } from "../../shell/runtime.js";
|
|
4
|
-
import { runGitConnect, runGitDisconnect } from "../../controllers/project.js";
|
|
5
4
|
import { runCommand } from "../../shell/command-runner.js";
|
|
5
|
+
import { runGitConnect, runGitDisconnect } from "../../controllers/project.js";
|
|
6
6
|
import { renderGitConnect, renderGitDisconnect } from "../../presenters/project.js";
|
|
7
7
|
import { Command } from "commander";
|
|
8
8
|
//#region src/commands/git/index.ts
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { attachCommandDescriptor } from "../../shell/command-meta.js";
|
|
2
2
|
import { addCompactGlobalFlags, addGlobalFlags } from "../../shell/global-flags.js";
|
|
3
3
|
import { configureRuntimeCommand } from "../../shell/runtime.js";
|
|
4
|
-
import { runProjectCreate, runProjectLink, runProjectList, runProjectShow } from "../../controllers/project.js";
|
|
5
4
|
import { runCommand } from "../../shell/command-runner.js";
|
|
5
|
+
import { runProjectCreate, runProjectLink, runProjectList, runProjectShow } from "../../controllers/project.js";
|
|
6
6
|
import { renderProjectList, renderProjectSetup, renderProjectShow, serializeProjectList, serializeProjectSetup, serializeProjectShow } from "../../presenters/project.js";
|
|
7
7
|
import { createEnvCommand } from "../env.js";
|
|
8
8
|
import { Command } from "commander";
|
|
@@ -0,0 +1,228 @@
|
|
|
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 "../shell/command-arguments.js";
|
|
6
|
+
import { CliError } from "../shell/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 };
|