@prisma/cli 8.0.0-rc.13-dev.95 → 8.0.0-rc.13-dev.96
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/cli.js +51 -19
- package/package.json +7 -7
package/dist/cli.js
CHANGED
|
@@ -9,7 +9,7 @@ import { AuthError, createManagementApiClient, createManagementApiSdk } from "@p
|
|
|
9
9
|
import os from "node:os";
|
|
10
10
|
import path from "node:path";
|
|
11
11
|
import { randomBytes, randomUUID } from "node:crypto";
|
|
12
|
-
import fs, { mkdir, readFile, readdir, rename, rm, stat, unlink, writeFile } from "node:fs/promises";
|
|
12
|
+
import fs, { mkdir, readFile, readdir, rename, rm, rmdir, stat, unlink, writeFile } from "node:fs/promises";
|
|
13
13
|
import { mkdir as mkdir$1, readFile as readFile$1, writeFile as writeFile$1 } from "fs/promises";
|
|
14
14
|
import path$1 from "path";
|
|
15
15
|
import events from "node:events";
|
|
@@ -2045,9 +2045,14 @@ async function hasPackageJsonWorkspaces(root) {
|
|
|
2045
2045
|
}
|
|
2046
2046
|
//#endregion
|
|
2047
2047
|
//#region src/lib/skills/status.ts
|
|
2048
|
+
/** Reads every skill the installed source packages ship and the state
|
|
2049
|
+
* of each copy in the configured agents' directories, plus the copies
|
|
2050
|
+
* the next sync will remove. */
|
|
2048
2051
|
async function readSkillsStatus(cwd, options) {
|
|
2049
2052
|
const projectRoot = path.resolve(cwd);
|
|
2050
|
-
const
|
|
2053
|
+
const agents = options?.agents ?? DEFAULT_AGENTS;
|
|
2054
|
+
const dirs = agentSkillDirs(agents);
|
|
2055
|
+
const unconfiguredDirs = agentSkillDirs(KNOWN_AGENTS.filter((agent) => !agents.includes(agent)));
|
|
2051
2056
|
const checkDisabled = options?.checkDisabled ?? await readSkillsCheckDisabled(projectRoot);
|
|
2052
2057
|
const packages = await findInstalledSourcePackages(projectRoot);
|
|
2053
2058
|
const sources = await collectSkillSources(packages);
|
|
@@ -2059,7 +2064,7 @@ async function readSkillsStatus(cwd, options) {
|
|
|
2059
2064
|
checkDisabled,
|
|
2060
2065
|
packages,
|
|
2061
2066
|
skills,
|
|
2062
|
-
orphans: options?.orphans === false ? [] : await findOrphanedSkills(projectRoot, dirs, new Set(sources.keys())),
|
|
2067
|
+
orphans: options?.orphans === false ? [] : await findOrphanedSkills(projectRoot, dirs, new Set(sources.keys()), unconfiguredDirs),
|
|
2063
2068
|
upToDate: skills.every((skill) => skill.upToDate)
|
|
2064
2069
|
};
|
|
2065
2070
|
}
|
|
@@ -2145,16 +2150,25 @@ async function missingFromDisk(target) {
|
|
|
2145
2150
|
}
|
|
2146
2151
|
/**
|
|
2147
2152
|
* Copies in the harness directories that this CLI installed — their
|
|
2148
|
-
* SKILL.md names an allowlisted package as its `library` — and that
|
|
2149
|
-
*
|
|
2150
|
-
*
|
|
2153
|
+
* SKILL.md names an allowlisted package as its `library` — and that
|
|
2154
|
+
* nothing wants any more: in a configured directory, one no installed
|
|
2155
|
+
* package still provides; in the directory of an agent the config no
|
|
2156
|
+
* longer names, every one. A skill from anywhere else is someone
|
|
2157
|
+
* else's file and is never touched.
|
|
2151
2158
|
*/
|
|
2152
|
-
async function findOrphanedSkills(projectRoot, dirs, provided) {
|
|
2159
|
+
async function findOrphanedSkills(projectRoot, dirs, provided, unconfiguredDirs = []) {
|
|
2153
2160
|
const orphans = /* @__PURE__ */ new Map();
|
|
2154
|
-
|
|
2161
|
+
const scan = [...dirs.map((dir) => ({
|
|
2162
|
+
dir,
|
|
2163
|
+
wanted: provided
|
|
2164
|
+
})), ...unconfiguredDirs.map((dir) => ({
|
|
2165
|
+
dir,
|
|
2166
|
+
wanted: /* @__PURE__ */ new Set()
|
|
2167
|
+
}))];
|
|
2168
|
+
for (const { dir, wanted } of scan) {
|
|
2155
2169
|
const harnessDir = path.join(projectRoot, dir);
|
|
2156
2170
|
for (const skill of await skillDirectories(harnessDir)) {
|
|
2157
|
-
if (
|
|
2171
|
+
if (wanted.has(skill)) continue;
|
|
2158
2172
|
const stamp = await readSkillStamp(path.join(harnessDir, skill, "SKILL.md"));
|
|
2159
2173
|
if (stamp?.library === null || stamp === null) continue;
|
|
2160
2174
|
if (!isSkillSourcePackage(stamp.library)) continue;
|
|
@@ -5527,11 +5541,12 @@ const gitDisconnectCommand = defineCommand({
|
|
|
5527
5541
|
//#region src/lib/skills/sync.ts
|
|
5528
5542
|
/**
|
|
5529
5543
|
* Brings the harness skill directories in line with the installed
|
|
5530
|
-
* source packages: copies each skill tree
|
|
5531
|
-
* the package it came from, and removes
|
|
5532
|
-
*
|
|
5533
|
-
*
|
|
5534
|
-
*
|
|
5544
|
+
* source packages and the configured agents: copies each skill tree
|
|
5545
|
+
* whose stamp does not match the package it came from, and removes
|
|
5546
|
+
* copies whose source package is gone or whose agent the config no
|
|
5547
|
+
* longer names. A target directory that exists but is not this CLI's
|
|
5548
|
+
* copy is refused, never replaced. Doing nothing is the normal outcome
|
|
5549
|
+
* and is not an error.
|
|
5535
5550
|
*/
|
|
5536
5551
|
async function syncSkills(status) {
|
|
5537
5552
|
const synced = [];
|
|
@@ -5555,10 +5570,13 @@ async function syncSkills(status) {
|
|
|
5555
5570
|
}
|
|
5556
5571
|
const pruned = [];
|
|
5557
5572
|
for (const orphan of status.orphans) {
|
|
5558
|
-
for (const dir of orphan.dirs)
|
|
5559
|
-
|
|
5560
|
-
|
|
5561
|
-
|
|
5573
|
+
for (const dir of orphan.dirs) {
|
|
5574
|
+
await rm(path.join(status.projectRoot, dir, orphan.skill), {
|
|
5575
|
+
recursive: true,
|
|
5576
|
+
force: true
|
|
5577
|
+
});
|
|
5578
|
+
await removeEmptyHarnessDirs(status.projectRoot, dir);
|
|
5579
|
+
}
|
|
5562
5580
|
pruned.push({
|
|
5563
5581
|
skill: orphan.skill,
|
|
5564
5582
|
library: orphan.library,
|
|
@@ -5575,6 +5593,20 @@ async function syncSkills(status) {
|
|
|
5575
5593
|
checkDisabled: status.checkDisabled
|
|
5576
5594
|
};
|
|
5577
5595
|
}
|
|
5596
|
+
/**
|
|
5597
|
+
* A harness directory this CLI emptied by removing its last copy is
|
|
5598
|
+
* removed too, and so is its parent (`.claude/skills`, then `.claude`),
|
|
5599
|
+
* so opting an agent out leaves nothing behind. `rmdir` refuses a
|
|
5600
|
+
* directory holding anything else, which is exactly the user's file
|
|
5601
|
+
* that must stay.
|
|
5602
|
+
*/
|
|
5603
|
+
async function removeEmptyHarnessDirs(projectRoot, dir) {
|
|
5604
|
+
for (let current = dir; current !== "." && current !== ""; current = path.dirname(current)) try {
|
|
5605
|
+
await rmdir(path.join(projectRoot, current));
|
|
5606
|
+
} catch {
|
|
5607
|
+
return;
|
|
5608
|
+
}
|
|
5609
|
+
}
|
|
5578
5610
|
const OLD_CLI_GITIGNORE = /^\*\r?\n?$/;
|
|
5579
5611
|
async function removeOldCliGitignore(file) {
|
|
5580
5612
|
let content;
|
|
@@ -5778,7 +5810,7 @@ function bothSwitchesError() {
|
|
|
5778
5810
|
const skillsSyncCommand = defineCommand({
|
|
5779
5811
|
help: {
|
|
5780
5812
|
summary: "Copy the AI-agent instruction files (skills) from installed Prisma packages into this project",
|
|
5781
|
-
description: "Agent skills are instruction files that teach AI coding agents (Claude Code, Cursor, and others) how to use the installed Prisma packages. They ship inside the packages themselves, so they always describe the version in use. Sync copies them into the skill directories the agent
|
|
5813
|
+
description: "Agent skills are instruction files that teach AI coding agents (Claude Code, Cursor, and others) how to use the installed Prisma packages. They ship inside the packages themselves, so they always describe the version in use. Sync copies them into the skill directories of the agents that skills.agents in prisma.config.ts names (every known agent when unset), and removes copies whose package is gone or whose agent is no longer named there — agents: [] removes them all. It does nothing, and exits 0, when everything is already current.",
|
|
5782
5814
|
examples: ["skills sync", "skills sync --disable"]
|
|
5783
5815
|
},
|
|
5784
5816
|
needs: { config: skillsConfigSection },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma/cli",
|
|
3
|
-
"version": "8.0.0-rc.13-dev.
|
|
3
|
+
"version": "8.0.0-rc.13-dev.96",
|
|
4
4
|
"description": "Command-line interface for the Prisma Developer Platform.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -41,10 +41,10 @@
|
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@manypkg/tools": "^2.1.2",
|
|
43
43
|
"@prisma/cli-engine": "0.3.0",
|
|
44
|
-
"@prisma/composer-cli": "0.17.0-dev.
|
|
44
|
+
"@prisma/composer-cli": "0.17.0-dev.4",
|
|
45
45
|
"@prisma/compute-sdk": "0.42.0",
|
|
46
46
|
"@prisma/management-api-sdk": "1.69.0",
|
|
47
|
-
"@prisma/orm-toolchain": "8.0.0-rc.9-dev.
|
|
47
|
+
"@prisma/orm-toolchain": "8.0.0-rc.9-dev.2",
|
|
48
48
|
"@vercel/detect-agent": "^1.2.3",
|
|
49
49
|
"better-result": "^2.9.2",
|
|
50
50
|
"cross-spawn": "^7.0.6",
|
|
@@ -53,11 +53,11 @@
|
|
|
53
53
|
"open": "^11.0.0"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
|
-
"@prisma/composer": "0.17.0-dev.
|
|
56
|
+
"@prisma/composer": "0.17.0-dev.4",
|
|
57
57
|
"@prisma/credentials-store": "^7.8.0",
|
|
58
|
-
"@repo/cli-conformance": "8.0.0-rc.13-dev.
|
|
59
|
-
"@repo/cli-telemetry": "8.0.0-rc.13-dev.
|
|
60
|
-
"@repo/tsconfig": "8.0.0-rc.13-dev.
|
|
58
|
+
"@repo/cli-conformance": "8.0.0-rc.13-dev.96",
|
|
59
|
+
"@repo/cli-telemetry": "8.0.0-rc.13-dev.96",
|
|
60
|
+
"@repo/tsconfig": "8.0.0-rc.13-dev.96",
|
|
61
61
|
"@types/node": "^22.19.19",
|
|
62
62
|
"@types/cross-spawn": "^6.0.6",
|
|
63
63
|
"tsdown": "^0.21.10",
|