vercel 54.6.0 → 54.7.0
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/chunks/{add-4JTZ2IN2.js → add-ACM2FI4N.js} +8 -8
- package/dist/chunks/{chunk-3TDGMELF.js → chunk-2R5WYHZW.js} +2 -2
- package/dist/chunks/{chunk-YP423QYK.js → chunk-3EOZ4ZDJ.js} +2 -2
- package/dist/chunks/{chunk-V23PMSXG.js → chunk-5K6XFQBY.js} +45 -777
- package/dist/chunks/{chunk-6PVIXIDG.js → chunk-6PSM4YC3.js} +3 -3
- package/dist/chunks/{chunk-TM2USC5N.js → chunk-7HAY2TY5.js} +3 -3
- package/dist/chunks/{chunk-ULXHXZCZ.js → chunk-7OUZIPHA.js} +1 -1
- package/dist/chunks/{chunk-KNTWCQDY.js → chunk-7Q62DZEF.js} +9 -7
- package/dist/chunks/{chunk-SRVNEJVN.js → chunk-CMQXECHW.js} +2 -2
- package/dist/chunks/{chunk-5EKBCYHA.js → chunk-CPWI2SWV.js} +2 -2
- package/dist/chunks/{chunk-XFSFHTAB.js → chunk-DDORH57D.js} +2 -2
- package/dist/chunks/{chunk-B43F7BHW.js → chunk-ERQAMRRQ.js} +2 -2
- package/dist/chunks/{chunk-LT7RPFRM.js → chunk-FO7QBAVZ.js} +4 -4
- package/dist/chunks/{chunk-TPCECDGK.js → chunk-FQ2EU7QM.js} +7 -7
- package/dist/chunks/{chunk-NYJXGEIR.js → chunk-FV5RQPKY.js} +1 -1
- package/dist/chunks/{chunk-JD4N3RDP.js → chunk-HW6MMF4G.js} +4 -4
- package/dist/chunks/{chunk-UGXBNJMO.js → chunk-IDFKAJW3.js} +1 -0
- package/dist/chunks/{chunk-7O3VXZBW.js → chunk-K5ISROJF.js} +1 -1
- package/dist/chunks/{chunk-MOA7PCJA.js → chunk-KFVFRVDK.js} +2 -2
- package/dist/chunks/{chunk-IZ6WAFPZ.js → chunk-L552VUSW.js} +2 -2
- package/dist/chunks/{chunk-TTOZFGDX.js → chunk-LOQRUMOE.js} +2 -2
- package/dist/chunks/{chunk-DJA3IN2X.js → chunk-O7SEN4RY.js} +2 -2
- package/dist/chunks/{chunk-PKUYGVBJ.js → chunk-QAHIBMRJ.js} +1513 -172
- package/dist/chunks/chunk-RKLHR2YE.js +152 -0
- package/dist/chunks/{chunk-XR64AS27.js → chunk-T4I25SRE.js} +66 -10
- package/dist/chunks/{chunk-C2V6DCWN.js → chunk-TIJBJ7EO.js} +2 -2
- package/dist/chunks/{chunk-YAOSNCGO.js → chunk-TJQZGB6S.js} +2 -2
- package/dist/chunks/{chunk-BT4S267X.js → chunk-TSUZWPXS.js} +4 -4
- package/dist/chunks/{chunk-C7WFNC2H.js → chunk-TVXUA533.js} +2 -2
- package/dist/chunks/{chunk-KSWKCPMW.js → chunk-UOYAPQ6P.js} +10 -14
- package/dist/chunks/{chunk-AQMLIXGD.js → chunk-WAGY7TO7.js} +1 -1
- package/dist/chunks/{chunk-ZINNI4TC.js → chunk-WWLVPUED.js} +1 -1
- package/dist/chunks/{chunk-OLXE4TRH.js → chunk-XC4VCXLN.js} +7 -7
- package/dist/chunks/{chunk-H33IJ7OP.js → chunk-XQUJUKTN.js} +1 -1
- package/dist/chunks/{chunk-OM5Z2KO5.js → chunk-ZTHVV4KB.js} +1 -1
- package/dist/chunks/{compile-vercel-config-TJYP77GR.js → compile-vercel-config-UMMPRYHE.js} +4 -4
- package/dist/chunks/{delete-KMJUZ2FR.js → delete-ZIUHVZKU.js} +6 -6
- package/dist/chunks/{disable-JNVD32GK.js → disable-3I6Y3PMB.js} +6 -6
- package/dist/chunks/{discard-IHJUBIIP.js → discard-P4QEYWQI.js} +6 -6
- package/dist/chunks/{edit-SHG24GD3.js → edit-C7W4II4F.js} +7 -7
- package/dist/chunks/{enable-BPPOFBS5.js → enable-YLFEOJHC.js} +6 -6
- package/dist/chunks/{export-NXMANIFJ.js → export-AEWPAFG5.js} +6 -6
- package/dist/chunks/{inspect-3QUNVUYY.js → inspect-UTKNO4PH.js} +8 -8
- package/dist/chunks/{list-DIFVR5IT.js → list-G2JFMLAP.js} +6 -6
- package/dist/chunks/{list-3EEABCQ5.js → list-K6T37XX7.js} +9 -9
- package/dist/chunks/{ls-W3EW6GXH.js → ls-SDUUITFJ.js} +8 -8
- package/dist/chunks/{publish-MJWCDLBZ.js → publish-CVDJGN4U.js} +6 -6
- package/dist/chunks/{query-C6RJSZM3.js → query-NZR7YNV5.js} +8 -8
- package/dist/chunks/{reorder-PPF7SVNU.js → reorder-XXHIOZ4E.js} +6 -6
- package/dist/chunks/{restore-EOJNTA2T.js → restore-SCM6T5BD.js} +6 -6
- package/dist/chunks/{rm-WEZ4K7UG.js → rm-I24CJRZY.js} +8 -8
- package/dist/chunks/{rule-inspect-PXCF73V3.js → rule-inspect-3K5RYFGG.js} +8 -8
- package/dist/chunks/{rules-DF7IFF4R.js → rules-T2VAUOFG.js} +8 -8
- package/dist/chunks/{schema-3UFDQZFG.js → schema-F6W32I35.js} +9 -9
- package/dist/chunks/{types-V6KTYGWP.js → types-LU2G5DD3.js} +4 -4
- package/dist/chunks/{update-FNAEWCUN.js → update-ZYQWTTCL.js} +8 -8
- package/dist/commands/build/index.js +534 -394
- package/dist/commands/deploy/index.js +23 -24
- package/dist/commands/dev/index.js +14 -14
- package/dist/commands/env/index.js +160 -95
- package/dist/commands/link/index.js +20 -21
- package/dist/commands/list/index.js +10 -10
- package/dist/commands-bulk.js +1503 -1277
- package/dist/index.js +20 -21
- package/dist/version.mjs +1 -1
- package/package.json +17 -17
- package/dist/chunks/chunk-76ZNZKIN.js +0 -17
- package/dist/chunks/chunk-HXXKDZQ6.js +0 -680
|
@@ -1,680 +0,0 @@
|
|
|
1
|
-
import { createRequire as __createRequire } from 'node:module';
|
|
2
|
-
import { fileURLToPath as __fileURLToPath } from 'node:url';
|
|
3
|
-
import { dirname as __dirname_ } from 'node:path';
|
|
4
|
-
const require = __createRequire(import.meta.url);
|
|
5
|
-
const __filename = __fileURLToPath(import.meta.url);
|
|
6
|
-
const __dirname = __dirname_(__filename);
|
|
7
|
-
import {
|
|
8
|
-
getEnvTargetPlaceholder
|
|
9
|
-
} from "./chunk-PKUYGVBJ.js";
|
|
10
|
-
import {
|
|
11
|
-
projectOption,
|
|
12
|
-
yesOption
|
|
13
|
-
} from "./chunk-H33IJ7OP.js";
|
|
14
|
-
import {
|
|
15
|
-
packageName
|
|
16
|
-
} from "./chunk-UGXBNJMO.js";
|
|
17
|
-
import {
|
|
18
|
-
output_manager_default
|
|
19
|
-
} from "./chunk-ZQKJVHXY.js";
|
|
20
|
-
import {
|
|
21
|
-
require_source
|
|
22
|
-
} from "./chunk-S7KYDPEM.js";
|
|
23
|
-
import {
|
|
24
|
-
__toESM
|
|
25
|
-
} from "./chunk-TZ2YI2VH.js";
|
|
26
|
-
|
|
27
|
-
// src/commands/build/command.ts
|
|
28
|
-
var buildCommand = {
|
|
29
|
-
name: "build",
|
|
30
|
-
aliases: [],
|
|
31
|
-
description: "Build the project.",
|
|
32
|
-
arguments: [],
|
|
33
|
-
options: [
|
|
34
|
-
{
|
|
35
|
-
name: "prod",
|
|
36
|
-
description: "Build a production deployment",
|
|
37
|
-
shorthand: null,
|
|
38
|
-
type: Boolean,
|
|
39
|
-
deprecated: false
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
name: "target",
|
|
43
|
-
shorthand: null,
|
|
44
|
-
type: String,
|
|
45
|
-
argument: "TARGET",
|
|
46
|
-
deprecated: false,
|
|
47
|
-
description: "Specify the target environment"
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
name: "output",
|
|
51
|
-
description: "Directory where built assets will be written to",
|
|
52
|
-
shorthand: null,
|
|
53
|
-
argument: "DIR",
|
|
54
|
-
type: String,
|
|
55
|
-
deprecated: false
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
...yesOption,
|
|
59
|
-
description: "Skip the confirmation prompt about pulling environment variables and project settings when not found locally"
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
name: "standalone",
|
|
63
|
-
description: "Create a standalone build with all dependencies inlined into function output folders",
|
|
64
|
-
shorthand: null,
|
|
65
|
-
type: Boolean,
|
|
66
|
-
deprecated: false
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
name: "id",
|
|
70
|
-
description: "Deployment ID to pull environment variables from (e.g. dpl_xxx)",
|
|
71
|
-
shorthand: null,
|
|
72
|
-
type: String,
|
|
73
|
-
argument: "ID",
|
|
74
|
-
deprecated: false
|
|
75
|
-
},
|
|
76
|
-
projectOption
|
|
77
|
-
],
|
|
78
|
-
examples: [
|
|
79
|
-
{
|
|
80
|
-
name: "Build the project",
|
|
81
|
-
value: `${packageName} build`
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
name: "Build the project in a specific directory",
|
|
85
|
-
value: `${packageName} build --cwd ./path-to-project`
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
name: "Build with deployment-scoped environment variables",
|
|
89
|
-
value: `${packageName} build --id dpl_xxx`
|
|
90
|
-
}
|
|
91
|
-
]
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
// src/util/agent/auto-install-agentic.ts
|
|
95
|
-
var import_chalk = __toESM(require_source(), 1);
|
|
96
|
-
import { readFile, writeFile } from "fs/promises";
|
|
97
|
-
import { access } from "fs/promises";
|
|
98
|
-
import { join } from "path";
|
|
99
|
-
import { homedir } from "os";
|
|
100
|
-
import { spawn } from "child_process";
|
|
101
|
-
import { KNOWN_AGENTS } from "@vercel/detect-agent";
|
|
102
|
-
import { z } from "zod";
|
|
103
|
-
var PREFS_FILE = "agent-preferences.json";
|
|
104
|
-
var CLAUDE_LEGACY_PLUGIN_ID = "vercel-plugin@vercel";
|
|
105
|
-
var CLAUDE_OFFICIAL_PLUGIN_ID = "vercel@claude-plugins-official";
|
|
106
|
-
var VERCEL_PLUGIN_VERSION_URL = "https://raw.githubusercontent.com/vercel/vercel-plugin/main/.claude-plugin/plugin.json";
|
|
107
|
-
var AGENT_TO_TARGET = {
|
|
108
|
-
[KNOWN_AGENTS.CLAUDE]: "claude-code",
|
|
109
|
-
[KNOWN_AGENTS.COWORK]: "claude-code"
|
|
110
|
-
};
|
|
111
|
-
function getPluginTargetForAgent(agentName) {
|
|
112
|
-
if (!agentName) {
|
|
113
|
-
return void 0;
|
|
114
|
-
}
|
|
115
|
-
if (agentName === KNOWN_AGENTS.CLAUDE || agentName.startsWith("claude-code") || agentName === KNOWN_AGENTS.COWORK) {
|
|
116
|
-
return "claude-code";
|
|
117
|
-
}
|
|
118
|
-
return AGENT_TO_TARGET[agentName];
|
|
119
|
-
}
|
|
120
|
-
var promptedAtSchema = z.codec(
|
|
121
|
-
z.union([z.iso.date(), z.iso.datetime()]),
|
|
122
|
-
z.date(),
|
|
123
|
-
{
|
|
124
|
-
decode: (value) => new Date(value),
|
|
125
|
-
encode: (value) => value.toISOString()
|
|
126
|
-
}
|
|
127
|
-
);
|
|
128
|
-
var agentPreferencesSchema = z.object({
|
|
129
|
-
pluginDeclined: z.boolean().optional(),
|
|
130
|
-
lastPromptedAt: promptedAtSchema.optional()
|
|
131
|
-
});
|
|
132
|
-
async function fileExists(filePath) {
|
|
133
|
-
try {
|
|
134
|
-
await access(filePath);
|
|
135
|
-
return true;
|
|
136
|
-
} catch {
|
|
137
|
-
return false;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
async function readPrefs(client) {
|
|
141
|
-
return await client.maybeReadConfig(PREFS_FILE, agentPreferencesSchema) ?? {};
|
|
142
|
-
}
|
|
143
|
-
async function writePrefs(client, prefs) {
|
|
144
|
-
try {
|
|
145
|
-
await client.writeConfig(PREFS_FILE, agentPreferencesSchema, prefs);
|
|
146
|
-
} catch {
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
async function getPluginTargets(agentName) {
|
|
150
|
-
const targetForAgent = getPluginTargetForAgent(agentName);
|
|
151
|
-
if (targetForAgent) {
|
|
152
|
-
return [targetForAgent];
|
|
153
|
-
}
|
|
154
|
-
if (agentName) {
|
|
155
|
-
return [];
|
|
156
|
-
}
|
|
157
|
-
const home = homedir();
|
|
158
|
-
const targets = [];
|
|
159
|
-
if (await fileExists(join(home, ".claude"))) {
|
|
160
|
-
targets.push("claude-code");
|
|
161
|
-
}
|
|
162
|
-
return targets;
|
|
163
|
-
}
|
|
164
|
-
async function readClaudeInstalledPluginsFromRegistry() {
|
|
165
|
-
try {
|
|
166
|
-
const raw = await readFile(
|
|
167
|
-
getClaudeInstalledPluginsRegistryPath(),
|
|
168
|
-
"utf-8"
|
|
169
|
-
);
|
|
170
|
-
const data = JSON.parse(raw);
|
|
171
|
-
const plugins = data?.plugins ?? {};
|
|
172
|
-
const entries = [];
|
|
173
|
-
for (const [id, installs] of Object.entries(plugins)) {
|
|
174
|
-
if (!Array.isArray(installs))
|
|
175
|
-
continue;
|
|
176
|
-
for (const install of installs) {
|
|
177
|
-
if (!install || typeof install !== "object")
|
|
178
|
-
continue;
|
|
179
|
-
entries.push({
|
|
180
|
-
id,
|
|
181
|
-
...install,
|
|
182
|
-
enabled: true
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
return entries;
|
|
187
|
-
} catch {
|
|
188
|
-
return [];
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
function getClaudeInstalledPluginsRegistryPath() {
|
|
192
|
-
return join(homedir(), ".claude", "plugins", "installed_plugins.json");
|
|
193
|
-
}
|
|
194
|
-
async function markStaleClaudePluginInstalls(plugins) {
|
|
195
|
-
return Promise.all(
|
|
196
|
-
plugins.map(async (plugin) => {
|
|
197
|
-
if (plugin.installPath && !await fileExists(plugin.installPath)) {
|
|
198
|
-
return { ...plugin, stale: true };
|
|
199
|
-
}
|
|
200
|
-
return plugin;
|
|
201
|
-
})
|
|
202
|
-
);
|
|
203
|
-
}
|
|
204
|
-
async function removeClaudePluginFromRegistry(pluginId) {
|
|
205
|
-
try {
|
|
206
|
-
const registryPath = getClaudeInstalledPluginsRegistryPath();
|
|
207
|
-
const raw = await readFile(registryPath, "utf-8");
|
|
208
|
-
const data = JSON.parse(raw);
|
|
209
|
-
if (!data.plugins || !(pluginId in data.plugins)) {
|
|
210
|
-
return false;
|
|
211
|
-
}
|
|
212
|
-
delete data.plugins[pluginId];
|
|
213
|
-
await writeFile(
|
|
214
|
-
registryPath,
|
|
215
|
-
`${JSON.stringify(data, null, 2)}
|
|
216
|
-
`,
|
|
217
|
-
"utf-8"
|
|
218
|
-
);
|
|
219
|
-
return true;
|
|
220
|
-
} catch (err) {
|
|
221
|
-
output_manager_default.debug(`Failed to remove Claude plugin registry entry: ${err}`);
|
|
222
|
-
return false;
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
async function isPluginInstalledForTarget(target) {
|
|
226
|
-
if (target === "claude-code") {
|
|
227
|
-
const status = await getClaudePluginStatus();
|
|
228
|
-
return status.state === "official-only";
|
|
229
|
-
}
|
|
230
|
-
return false;
|
|
231
|
-
}
|
|
232
|
-
async function confirm(client, message) {
|
|
233
|
-
if (!client.stdin.isTTY) {
|
|
234
|
-
return false;
|
|
235
|
-
}
|
|
236
|
-
return client.input.confirm(message, true);
|
|
237
|
-
}
|
|
238
|
-
function isSameDay(left, right) {
|
|
239
|
-
return left.getFullYear() === right.getFullYear() && left.getMonth() === right.getMonth() && left.getDate() === right.getDate();
|
|
240
|
-
}
|
|
241
|
-
function wasPromptedToday(prefs) {
|
|
242
|
-
return prefs.lastPromptedAt ? isSameDay(prefs.lastPromptedAt, /* @__PURE__ */ new Date()) : false;
|
|
243
|
-
}
|
|
244
|
-
async function markPromptedToday(client, prefs) {
|
|
245
|
-
prefs.lastPromptedAt = /* @__PURE__ */ new Date();
|
|
246
|
-
await writePrefs(client, prefs);
|
|
247
|
-
}
|
|
248
|
-
async function runCommand(command, args) {
|
|
249
|
-
return await new Promise((resolve) => {
|
|
250
|
-
const child = spawn(command, args, { stdio: "pipe" });
|
|
251
|
-
let stdout = "";
|
|
252
|
-
let stderr = "";
|
|
253
|
-
child.stdout.on("data", (chunk) => {
|
|
254
|
-
stdout += chunk.toString();
|
|
255
|
-
});
|
|
256
|
-
child.stderr.on("data", (chunk) => {
|
|
257
|
-
stderr += chunk.toString();
|
|
258
|
-
});
|
|
259
|
-
child.on("close", (code) => {
|
|
260
|
-
resolve({ exitCode: code ?? 1, stdout, stderr });
|
|
261
|
-
});
|
|
262
|
-
child.on("error", (err) => {
|
|
263
|
-
resolve({ exitCode: 1, stdout, stderr: `${stderr}${String(err)}` });
|
|
264
|
-
});
|
|
265
|
-
});
|
|
266
|
-
}
|
|
267
|
-
async function getClaudeInstalledPlugins() {
|
|
268
|
-
const result = await runCommand("claude", ["plugins", "list", "--json"]);
|
|
269
|
-
if (result.exitCode === 0) {
|
|
270
|
-
try {
|
|
271
|
-
const parsed = JSON.parse(result.stdout);
|
|
272
|
-
if (Array.isArray(parsed)) {
|
|
273
|
-
return markStaleClaudePluginInstalls(parsed);
|
|
274
|
-
}
|
|
275
|
-
} catch (err) {
|
|
276
|
-
output_manager_default.debug(`Failed to parse Claude plugin list JSON: ${err}`);
|
|
277
|
-
}
|
|
278
|
-
} else if (result.stderr.trim().length > 0) {
|
|
279
|
-
output_manager_default.debug(
|
|
280
|
-
`Failed to run 'claude plugins list --json': ${result.stderr}`
|
|
281
|
-
);
|
|
282
|
-
}
|
|
283
|
-
return markStaleClaudePluginInstalls(
|
|
284
|
-
await readClaudeInstalledPluginsFromRegistry()
|
|
285
|
-
);
|
|
286
|
-
}
|
|
287
|
-
async function fetchLatestVercelPluginVersion() {
|
|
288
|
-
try {
|
|
289
|
-
const response = await fetch(VERCEL_PLUGIN_VERSION_URL);
|
|
290
|
-
if (!response.ok) {
|
|
291
|
-
output_manager_default.debug(
|
|
292
|
-
`Failed to fetch latest Vercel plugin version: ${response.status}`
|
|
293
|
-
);
|
|
294
|
-
return void 0;
|
|
295
|
-
}
|
|
296
|
-
const manifest = await response.json();
|
|
297
|
-
return typeof manifest.version === "string" ? manifest.version : void 0;
|
|
298
|
-
} catch (err) {
|
|
299
|
-
output_manager_default.debug(`Failed to fetch latest Vercel plugin version: ${err}`);
|
|
300
|
-
return void 0;
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
function comparePluginVersions(a, b) {
|
|
304
|
-
if (!a && !b)
|
|
305
|
-
return 0;
|
|
306
|
-
if (!a)
|
|
307
|
-
return -1;
|
|
308
|
-
if (!b)
|
|
309
|
-
return 1;
|
|
310
|
-
const parse = (value) => value.split(".").map((part) => Number.parseInt(part, 10) || 0);
|
|
311
|
-
const left = parse(a);
|
|
312
|
-
const right = parse(b);
|
|
313
|
-
const maxLength = Math.max(left.length, right.length);
|
|
314
|
-
for (let i = 0; i < maxLength; i++) {
|
|
315
|
-
const l = left[i] ?? 0;
|
|
316
|
-
const r = right[i] ?? 0;
|
|
317
|
-
if (l > r)
|
|
318
|
-
return 1;
|
|
319
|
-
if (l < r)
|
|
320
|
-
return -1;
|
|
321
|
-
}
|
|
322
|
-
return 0;
|
|
323
|
-
}
|
|
324
|
-
function buildClaudePluginStatus(installedPlugins, latestVersion) {
|
|
325
|
-
const legacy = installedPlugins.find(
|
|
326
|
-
(plugin) => plugin.id === CLAUDE_LEGACY_PLUGIN_ID
|
|
327
|
-
);
|
|
328
|
-
const official = installedPlugins.find(
|
|
329
|
-
(plugin) => plugin.id === CLAUDE_OFFICIAL_PLUGIN_ID
|
|
330
|
-
);
|
|
331
|
-
let state = "none";
|
|
332
|
-
if (legacy && official)
|
|
333
|
-
state = "both";
|
|
334
|
-
else if (legacy)
|
|
335
|
-
state = "legacy-only";
|
|
336
|
-
else if (official)
|
|
337
|
-
state = "official-only";
|
|
338
|
-
return {
|
|
339
|
-
state,
|
|
340
|
-
legacy,
|
|
341
|
-
official,
|
|
342
|
-
latestVersion
|
|
343
|
-
};
|
|
344
|
-
}
|
|
345
|
-
function buildClaudePluginMigrationPlan(status) {
|
|
346
|
-
const plan = {
|
|
347
|
-
installOfficial: false,
|
|
348
|
-
updateOfficial: false,
|
|
349
|
-
removeLegacy: false,
|
|
350
|
-
removeLegacyMarketplace: false
|
|
351
|
-
};
|
|
352
|
-
switch (status.state) {
|
|
353
|
-
case "none":
|
|
354
|
-
plan.installOfficial = true;
|
|
355
|
-
break;
|
|
356
|
-
case "legacy-only":
|
|
357
|
-
plan.installOfficial = true;
|
|
358
|
-
plan.removeLegacy = true;
|
|
359
|
-
plan.removeLegacyMarketplace = true;
|
|
360
|
-
break;
|
|
361
|
-
case "both":
|
|
362
|
-
plan.removeLegacy = true;
|
|
363
|
-
plan.removeLegacyMarketplace = true;
|
|
364
|
-
break;
|
|
365
|
-
case "official-only":
|
|
366
|
-
break;
|
|
367
|
-
}
|
|
368
|
-
if (status.official?.version && status.latestVersion && comparePluginVersions(status.official.version, status.latestVersion) < 0) {
|
|
369
|
-
plan.updateOfficial = true;
|
|
370
|
-
}
|
|
371
|
-
return plan;
|
|
372
|
-
}
|
|
373
|
-
function hasClaudeMigrationActions(plan) {
|
|
374
|
-
return plan.installOfficial || plan.updateOfficial || plan.removeLegacy || plan.removeLegacyMarketplace;
|
|
375
|
-
}
|
|
376
|
-
function buildClaudePromptCopy(status, plan) {
|
|
377
|
-
if (plan.installOfficial && status.state === "none") {
|
|
378
|
-
return {
|
|
379
|
-
message: "",
|
|
380
|
-
confirm: "Working with Vercel is easier with the Vercel Plugin for Claude Code. Would you like to install it?"
|
|
381
|
-
};
|
|
382
|
-
}
|
|
383
|
-
if (plan.installOfficial && status.state === "legacy-only") {
|
|
384
|
-
return {
|
|
385
|
-
message: "",
|
|
386
|
-
confirm: "Working with Vercel is easier with the latest Vercel Plugin for Claude Code. Would you like to update it?"
|
|
387
|
-
};
|
|
388
|
-
}
|
|
389
|
-
if (status.state === "both" && plan.removeLegacy) {
|
|
390
|
-
return {
|
|
391
|
-
message: "",
|
|
392
|
-
confirm: "Working with Vercel is easier with the latest Vercel Plugin for Claude Code. Would you like to update it?"
|
|
393
|
-
};
|
|
394
|
-
}
|
|
395
|
-
if (plan.updateOfficial) {
|
|
396
|
-
const fromVersion = status.official?.version ?? "your current version";
|
|
397
|
-
const toVersion = status.latestVersion ?? "the latest version";
|
|
398
|
-
return {
|
|
399
|
-
message: "",
|
|
400
|
-
confirm: `Working with Vercel is easier with the latest Vercel Plugin for Claude Code. Would you like to update from ${fromVersion} to ${toVersion}?`
|
|
401
|
-
};
|
|
402
|
-
}
|
|
403
|
-
return {
|
|
404
|
-
message: "The Vercel plugin needs attention in Claude Code before your agent harness is fully up to date.",
|
|
405
|
-
confirm: "Apply the Vercel plugin changes for Claude Code?"
|
|
406
|
-
};
|
|
407
|
-
}
|
|
408
|
-
async function runClaudeCommand(spinnerMessage, successMessage, failureMessage, args, options) {
|
|
409
|
-
output_manager_default.spinner(spinnerMessage);
|
|
410
|
-
const result = await runCommand("claude", args);
|
|
411
|
-
output_manager_default.stopSpinner();
|
|
412
|
-
if (result.exitCode === 0) {
|
|
413
|
-
if (!options?.quietSuccess) {
|
|
414
|
-
output_manager_default.success(successMessage);
|
|
415
|
-
}
|
|
416
|
-
return true;
|
|
417
|
-
}
|
|
418
|
-
output_manager_default.warn(failureMessage);
|
|
419
|
-
output_manager_default.debug(
|
|
420
|
-
`Claude command failed: claude ${args.join(" ")}
|
|
421
|
-
${result.stderr || result.stdout}`
|
|
422
|
-
);
|
|
423
|
-
return false;
|
|
424
|
-
}
|
|
425
|
-
async function removeStaleLegacyClaudePlugin(removeMarketplace) {
|
|
426
|
-
output_manager_default.spinner("Removing the stale legacy Vercel Claude plugin...");
|
|
427
|
-
const removedRegistryEntry = await removeClaudePluginFromRegistry(
|
|
428
|
-
CLAUDE_LEGACY_PLUGIN_ID
|
|
429
|
-
);
|
|
430
|
-
output_manager_default.stopSpinner();
|
|
431
|
-
if (!removedRegistryEntry) {
|
|
432
|
-
output_manager_default.warn(
|
|
433
|
-
"Could not remove the stale legacy Vercel Claude plugin registry entry."
|
|
434
|
-
);
|
|
435
|
-
return false;
|
|
436
|
-
}
|
|
437
|
-
output_manager_default.success("Removed the stale legacy Vercel Claude plugin");
|
|
438
|
-
if (removeMarketplace) {
|
|
439
|
-
const removedMarketplace = await runClaudeCommand(
|
|
440
|
-
"Removing the legacy Vercel marketplace...",
|
|
441
|
-
"Removed the legacy Vercel marketplace",
|
|
442
|
-
"Removed the stale legacy Vercel plugin, but could not remove the legacy marketplace.",
|
|
443
|
-
["plugins", "marketplace", "remove", "vercel"],
|
|
444
|
-
{ quietSuccess: true }
|
|
445
|
-
);
|
|
446
|
-
if (!removedMarketplace) {
|
|
447
|
-
output_manager_default.log("Cleanup command: claude plugins marketplace remove vercel");
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
return true;
|
|
451
|
-
}
|
|
452
|
-
async function runClaudeMigration(plan) {
|
|
453
|
-
let removedStaleLegacy = false;
|
|
454
|
-
if (plan.removeLegacy) {
|
|
455
|
-
const statusBeforeInstall = await getClaudePluginStatus();
|
|
456
|
-
if (statusBeforeInstall.legacy?.stale) {
|
|
457
|
-
removedStaleLegacy = await removeStaleLegacyClaudePlugin(
|
|
458
|
-
plan.removeLegacyMarketplace
|
|
459
|
-
);
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
if (plan.installOfficial) {
|
|
463
|
-
const installed = await runClaudeCommand(
|
|
464
|
-
"Installing the official Vercel Claude plugin...",
|
|
465
|
-
"Updated the Vercel plugin",
|
|
466
|
-
"Failed to install the official Vercel Claude plugin.",
|
|
467
|
-
["plugins", "install", CLAUDE_OFFICIAL_PLUGIN_ID]
|
|
468
|
-
);
|
|
469
|
-
if (!installed) {
|
|
470
|
-
return;
|
|
471
|
-
}
|
|
472
|
-
} else if (plan.updateOfficial) {
|
|
473
|
-
await runClaudeCommand(
|
|
474
|
-
"Updating the official Vercel Claude plugin...",
|
|
475
|
-
"Updated the Vercel plugin",
|
|
476
|
-
"Failed to update the official Vercel Claude plugin.",
|
|
477
|
-
["plugins", "update", CLAUDE_OFFICIAL_PLUGIN_ID]
|
|
478
|
-
);
|
|
479
|
-
}
|
|
480
|
-
const statusAfterInstall = await getClaudePluginStatus();
|
|
481
|
-
if (!statusAfterInstall.official) {
|
|
482
|
-
output_manager_default.warn(
|
|
483
|
-
"Skipping Claude cleanup because the official Vercel plugin is not installed."
|
|
484
|
-
);
|
|
485
|
-
return;
|
|
486
|
-
}
|
|
487
|
-
if (plan.removeLegacy && statusAfterInstall.legacy) {
|
|
488
|
-
const removedLegacy = await runClaudeCommand(
|
|
489
|
-
"Removing the legacy Vercel Claude plugin...",
|
|
490
|
-
"Removed the legacy Vercel Claude plugin",
|
|
491
|
-
"Installed the official Vercel Claude plugin, but could not remove the legacy install.",
|
|
492
|
-
["plugins", "uninstall", CLAUDE_LEGACY_PLUGIN_ID],
|
|
493
|
-
{ quietSuccess: true }
|
|
494
|
-
);
|
|
495
|
-
if (!removedLegacy) {
|
|
496
|
-
output_manager_default.log(
|
|
497
|
-
`Cleanup command: claude plugins uninstall ${CLAUDE_LEGACY_PLUGIN_ID}`
|
|
498
|
-
);
|
|
499
|
-
return;
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
if (plan.removeLegacyMarketplace && !removedStaleLegacy) {
|
|
503
|
-
const finalStatus = await getClaudePluginStatus();
|
|
504
|
-
if (!finalStatus.legacy) {
|
|
505
|
-
const removedMarketplace = await runClaudeCommand(
|
|
506
|
-
"Removing the legacy Vercel marketplace...",
|
|
507
|
-
"Removed the legacy Vercel marketplace",
|
|
508
|
-
"Removed the legacy Vercel plugin, but could not remove the legacy marketplace.",
|
|
509
|
-
["plugins", "marketplace", "remove", "vercel"],
|
|
510
|
-
{ quietSuccess: true }
|
|
511
|
-
);
|
|
512
|
-
if (!removedMarketplace) {
|
|
513
|
-
output_manager_default.log("Cleanup command: claude plugins marketplace remove vercel");
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
async function getClaudePluginStatus() {
|
|
519
|
-
const [installedPlugins, latestVersion] = await Promise.all([
|
|
520
|
-
getClaudeInstalledPlugins(),
|
|
521
|
-
fetchLatestVercelPluginVersion()
|
|
522
|
-
]);
|
|
523
|
-
return buildClaudePluginStatus(installedPlugins, latestVersion);
|
|
524
|
-
}
|
|
525
|
-
async function applyPluginActions(targets, claudePlan) {
|
|
526
|
-
for (const target of targets) {
|
|
527
|
-
if (target === "claude-code" && claudePlan) {
|
|
528
|
-
await runClaudeMigration(claudePlan);
|
|
529
|
-
} else {
|
|
530
|
-
output_manager_default.debug(`Skipping unsupported plugin target: ${target}`);
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
|
-
async function autoInstallVercelPlugin(client, options) {
|
|
535
|
-
try {
|
|
536
|
-
const prefs = await readPrefs(client);
|
|
537
|
-
const applyMode = options?.mode === "apply";
|
|
538
|
-
if (!prefs.pluginDeclined || applyMode) {
|
|
539
|
-
const targets = await getPluginTargets(client.agentName);
|
|
540
|
-
const uninstalledTargets = [];
|
|
541
|
-
const claudeStatus = targets.includes("claude-code") ? await getClaudePluginStatus() : void 0;
|
|
542
|
-
const claudePlan = claudeStatus ? buildClaudePluginMigrationPlan(claudeStatus) : void 0;
|
|
543
|
-
for (const target of targets) {
|
|
544
|
-
if (target === "claude-code") {
|
|
545
|
-
if (claudePlan && hasClaudeMigrationActions(claudePlan)) {
|
|
546
|
-
uninstalledTargets.push(target);
|
|
547
|
-
}
|
|
548
|
-
continue;
|
|
549
|
-
}
|
|
550
|
-
if (!await isPluginInstalledForTarget(target)) {
|
|
551
|
-
uninstalledTargets.push(target);
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
|
-
if (uninstalledTargets.length > 0) {
|
|
555
|
-
if (!applyMode && wasPromptedToday(prefs)) {
|
|
556
|
-
return;
|
|
557
|
-
}
|
|
558
|
-
if (applyMode) {
|
|
559
|
-
prefs.pluginDeclined = false;
|
|
560
|
-
await writePrefs(client, prefs);
|
|
561
|
-
await applyPluginActions(uninstalledTargets, claudePlan);
|
|
562
|
-
return;
|
|
563
|
-
}
|
|
564
|
-
const promptMessages = [];
|
|
565
|
-
let confirmMessage = "Install the Vercel plugin?";
|
|
566
|
-
if (uninstalledTargets.includes("claude-code") && claudeStatus && claudePlan) {
|
|
567
|
-
const claudePrompt = buildClaudePromptCopy(claudeStatus, claudePlan);
|
|
568
|
-
promptMessages.push(claudePrompt.message);
|
|
569
|
-
confirmMessage = claudePrompt.confirm;
|
|
570
|
-
}
|
|
571
|
-
const promptMessage = promptMessages.join(" ").trim();
|
|
572
|
-
if (promptMessage) {
|
|
573
|
-
output_manager_default.log(promptMessage);
|
|
574
|
-
}
|
|
575
|
-
const accepted = await confirm(client, confirmMessage);
|
|
576
|
-
await markPromptedToday(client, prefs);
|
|
577
|
-
if (accepted) {
|
|
578
|
-
prefs.pluginDeclined = false;
|
|
579
|
-
await writePrefs(client, prefs);
|
|
580
|
-
await applyPluginActions(uninstalledTargets, claudePlan);
|
|
581
|
-
} else {
|
|
582
|
-
prefs.pluginDeclined = true;
|
|
583
|
-
await writePrefs(client, prefs);
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
}
|
|
587
|
-
} catch (err) {
|
|
588
|
-
output_manager_default.debug(`Auto-install agent tooling failed: ${err}`);
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
async function showPluginTipIfNeeded(client) {
|
|
592
|
-
try {
|
|
593
|
-
const prefs = await readPrefs(client);
|
|
594
|
-
if (prefs.pluginDeclined)
|
|
595
|
-
return;
|
|
596
|
-
const targets = await getPluginTargets();
|
|
597
|
-
for (const target of targets) {
|
|
598
|
-
if (!await isPluginInstalledForTarget(target)) {
|
|
599
|
-
output_manager_default.log(
|
|
600
|
-
import_chalk.default.dim(
|
|
601
|
-
"Tip: Run `npx plugins add vercel/vercel-plugin` to enhance your agent experience"
|
|
602
|
-
)
|
|
603
|
-
);
|
|
604
|
-
return;
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
} catch {
|
|
608
|
-
}
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
// src/commands/pull/command.ts
|
|
612
|
-
var pullCommand = {
|
|
613
|
-
name: "pull",
|
|
614
|
-
aliases: [],
|
|
615
|
-
description: "Pull latest environment variables and project settings from Vercel. ",
|
|
616
|
-
arguments: [
|
|
617
|
-
{
|
|
618
|
-
name: "project-path",
|
|
619
|
-
required: false
|
|
620
|
-
}
|
|
621
|
-
],
|
|
622
|
-
options: [
|
|
623
|
-
{
|
|
624
|
-
name: "environment",
|
|
625
|
-
description: "Deployment environment [development]",
|
|
626
|
-
argument: "TARGET",
|
|
627
|
-
shorthand: null,
|
|
628
|
-
type: String,
|
|
629
|
-
deprecated: false
|
|
630
|
-
},
|
|
631
|
-
{
|
|
632
|
-
name: "git-branch",
|
|
633
|
-
description: "Specify the Git branch to pull specific Environment Variables for",
|
|
634
|
-
argument: "NAME",
|
|
635
|
-
shorthand: null,
|
|
636
|
-
type: String,
|
|
637
|
-
deprecated: false
|
|
638
|
-
},
|
|
639
|
-
{
|
|
640
|
-
name: "prod",
|
|
641
|
-
shorthand: null,
|
|
642
|
-
type: Boolean,
|
|
643
|
-
deprecated: false
|
|
644
|
-
},
|
|
645
|
-
{
|
|
646
|
-
...yesOption,
|
|
647
|
-
description: "Skip questions when setting up new project using default scope and settings"
|
|
648
|
-
},
|
|
649
|
-
projectOption
|
|
650
|
-
],
|
|
651
|
-
examples: [
|
|
652
|
-
{
|
|
653
|
-
name: "Pull the latest Environment Variables and Project Settings from the cloud",
|
|
654
|
-
value: `${packageName} pull`
|
|
655
|
-
},
|
|
656
|
-
{
|
|
657
|
-
name: "Pull the latest Environment Variables and Project Settings from the cloud targeting a directory",
|
|
658
|
-
value: `${packageName} pull ./path-to-project`
|
|
659
|
-
},
|
|
660
|
-
{
|
|
661
|
-
name: "Pull for a specific environment",
|
|
662
|
-
value: `${packageName} pull --environment=${getEnvTargetPlaceholder()}`
|
|
663
|
-
},
|
|
664
|
-
{
|
|
665
|
-
name: "Pull for a preview feature branch",
|
|
666
|
-
value: `${packageName} pull --environment=preview --git-branch=feature-branch`
|
|
667
|
-
},
|
|
668
|
-
{
|
|
669
|
-
name: "If you want to download environment variables to a specific file, use `vercel env pull` instead",
|
|
670
|
-
value: `${packageName} env pull`
|
|
671
|
-
}
|
|
672
|
-
]
|
|
673
|
-
};
|
|
674
|
-
|
|
675
|
-
export {
|
|
676
|
-
buildCommand,
|
|
677
|
-
pullCommand,
|
|
678
|
-
autoInstallVercelPlugin,
|
|
679
|
-
showPluginTipIfNeeded
|
|
680
|
-
};
|