vercel 54.14.2 → 54.14.5

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.
Files changed (52) hide show
  1. package/dist/chunks/{add-PKT6ULVJ.js → add-5Z2AAQMM.js} +4 -4
  2. package/dist/chunks/{chunk-G3NXHUFT.js → chunk-25XEQWUS.js} +1 -1
  3. package/dist/chunks/{chunk-JISJDGJF.js → chunk-2GOVUIMY.js} +1 -1
  4. package/dist/chunks/{chunk-Z3X747P6.js → chunk-2N7NBUQX.js} +1 -1
  5. package/dist/chunks/{chunk-IPWWE7PB.js → chunk-45S2Y3TD.js} +1 -1
  6. package/dist/chunks/{chunk-2XEEOHHH.js → chunk-6ABEFMPX.js} +1 -1
  7. package/dist/chunks/{chunk-4BFK3C7V.js → chunk-6H2YVMJJ.js} +1 -1
  8. package/dist/chunks/{chunk-O7RJHL34.js → chunk-6R3YPU76.js} +203 -6
  9. package/dist/chunks/chunk-BRQ6PX3U.js +593 -0
  10. package/dist/chunks/{chunk-3BR246Y6.js → chunk-EBIX223X.js} +2 -11
  11. package/dist/chunks/{chunk-2HN6DLIY.js → chunk-ETVOM3IR.js} +1 -1
  12. package/dist/chunks/{chunk-372SHB43.js → chunk-IXTKPQYW.js} +3 -3
  13. package/dist/chunks/{chunk-FEYVO2US.js → chunk-JLLN34XF.js} +90 -32
  14. package/dist/chunks/{chunk-O4V7CMVO.js → chunk-KSSRTKN4.js} +7 -5
  15. package/dist/chunks/{chunk-2ZSXQQXI.js → chunk-MOVGWTDQ.js} +8 -18
  16. package/dist/chunks/{chunk-SDZ5ICZL.js → chunk-PSG6ZBGQ.js} +1 -1
  17. package/dist/chunks/{chunk-FLW73SZ3.js → chunk-PXJA4KXE.js} +2 -2
  18. package/dist/chunks/{chunk-YLGMXYFG.js → chunk-R5MIXAJF.js} +2 -2
  19. package/dist/chunks/{chunk-J7BMPRCU.js → chunk-X23JL3ZL.js} +1 -1
  20. package/dist/chunks/{chunk-ILJH44MK.js → chunk-YE3C5CUX.js} +1 -1
  21. package/dist/chunks/{chunk-LQR3CHMH.js → chunk-YIAUEFUY.js} +211 -787
  22. package/dist/chunks/{chunk-OHIZ4SVU.js → chunk-ZR4XADWC.js} +15 -3
  23. package/dist/chunks/{compile-vercel-config-3LV7J3IZ.js → compile-vercel-config-UMUHH55E.js} +1 -1
  24. package/dist/chunks/{delete-GFW6Y6TZ.js → delete-NO2U3UGV.js} +2 -2
  25. package/dist/chunks/{disable-PGRAS2ZL.js → disable-AGDDHVKZ.js} +2 -2
  26. package/dist/chunks/{discard-S6N5Q4G5.js → discard-Q5HML52L.js} +2 -2
  27. package/dist/chunks/{edit-TICKX4ZV.js → edit-HSHJAKHM.js} +3 -3
  28. package/dist/chunks/{enable-L3BYWN6S.js → enable-YMJAXOGA.js} +2 -2
  29. package/dist/chunks/{export-NXS33U5T.js → export-RCACOTPE.js} +2 -2
  30. package/dist/chunks/{inspect-OOI5JN3Y.js → inspect-OJHOQHD2.js} +3 -3
  31. package/dist/chunks/{list-77WL6463.js → list-LLUDMAWA.js} +3 -3
  32. package/dist/chunks/{list-6EHRL2D4.js → list-R7V2P6TM.js} +2 -2
  33. package/dist/chunks/{ls-PBSOEXFG.js → ls-KAI6V7SU.js} +4 -4
  34. package/dist/chunks/{publish-CU2THVYW.js → publish-KCYVRDAT.js} +2 -2
  35. package/dist/chunks/{query-HEATRYAK.js → query-MBJLAQRX.js} +3 -3
  36. package/dist/chunks/{reorder-IQVKSM3H.js → reorder-C5BJWFJM.js} +2 -2
  37. package/dist/chunks/{restore-RDEOBGAS.js → restore-F63NO7XP.js} +2 -2
  38. package/dist/chunks/{rm-MCSGTU4J.js → rm-HT7YO3JX.js} +4 -4
  39. package/dist/chunks/{rule-inspect-3YK2XSL3.js → rule-inspect-IHEUI5JT.js} +4 -4
  40. package/dist/chunks/{rules-F4MRDDHM.js → rules-ZUBTVSNC.js} +6 -6
  41. package/dist/chunks/{schema-65C5EBJ7.js → schema-VAQSZY2H.js} +3 -3
  42. package/dist/chunks/{update-XB4WSRGY.js → update-BS5FBLIP.js} +4 -4
  43. package/dist/commands/build/index.js +53 -29
  44. package/dist/commands/deploy/index.js +12 -11
  45. package/dist/commands/dev/index.js +69 -22
  46. package/dist/commands/env/index.js +8 -6
  47. package/dist/commands/link/index.js +8 -15
  48. package/dist/commands/list/index.js +3 -3
  49. package/dist/commands-bulk.js +621 -101
  50. package/dist/index.js +9 -9
  51. package/dist/version.mjs +1 -1
  52. package/package.json +15 -15
@@ -0,0 +1,593 @@
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
+ output_manager_default
9
+ } from "./chunk-Z5SBJH6L.js";
10
+ import {
11
+ require_source
12
+ } from "./chunk-S7KYDPEM.js";
13
+ import {
14
+ __toESM
15
+ } from "./chunk-TZ2YI2VH.js";
16
+
17
+ // src/util/agent/auto-install-agentic.ts
18
+ var import_chalk = __toESM(require_source(), 1);
19
+ import { readFile, writeFile } from "fs/promises";
20
+ import { access } from "fs/promises";
21
+ import { dirname, join, resolve } from "path";
22
+ import { homedir } from "os";
23
+ import { spawn } from "child_process";
24
+ import { KNOWN_AGENTS } from "@vercel/detect-agent";
25
+ import { z } from "zod";
26
+ var PREFS_FILE = "agent-preferences.json";
27
+ var CLAUDE_LEGACY_PLUGIN_ID = "vercel-plugin@vercel";
28
+ var CLAUDE_OFFICIAL_PLUGIN_ID = "vercel@claude-plugins-official";
29
+ var VERCEL_PLUGIN_VERSION_URL = "https://raw.githubusercontent.com/vercel/vercel-plugin/main/.claude-plugin/plugin.json";
30
+ var AGENT_TO_TARGET = {
31
+ [KNOWN_AGENTS.CLAUDE]: "claude-code",
32
+ [KNOWN_AGENTS.COWORK]: "claude-code"
33
+ };
34
+ function getPluginTargetForAgent(agentName) {
35
+ if (!agentName) {
36
+ return void 0;
37
+ }
38
+ if (agentName === KNOWN_AGENTS.CLAUDE || agentName.startsWith("claude-code") || agentName === KNOWN_AGENTS.COWORK) {
39
+ return "claude-code";
40
+ }
41
+ return AGENT_TO_TARGET[agentName];
42
+ }
43
+ var promptedAtSchema = z.codec(
44
+ z.union([z.iso.date(), z.iso.datetime()]),
45
+ z.date(),
46
+ {
47
+ decode: (value) => new Date(value),
48
+ encode: (value) => value.toISOString()
49
+ }
50
+ );
51
+ var agentPreferencesSchema = z.object({
52
+ pluginDeclined: z.boolean().optional(),
53
+ pluginAutoUpdate: z.boolean().optional(),
54
+ lastPromptedAt: promptedAtSchema.optional(),
55
+ lastPluginAutoUpdateAttemptedAt: promptedAtSchema.optional(),
56
+ lastPluginAutoUpdateAttemptedKey: z.string().optional()
57
+ });
58
+ async function fileExists(filePath) {
59
+ try {
60
+ await access(filePath);
61
+ return true;
62
+ } catch {
63
+ return false;
64
+ }
65
+ }
66
+ async function readPrefs(client) {
67
+ return await client.maybeReadConfig(PREFS_FILE, agentPreferencesSchema) ?? {};
68
+ }
69
+ async function writePrefs(client, prefs) {
70
+ try {
71
+ await client.writeConfig(PREFS_FILE, agentPreferencesSchema, prefs);
72
+ } catch {
73
+ }
74
+ }
75
+ function encodeClaudeProjectDir(projectPath) {
76
+ return projectPath.replace(/[^A-Za-z0-9]/g, "-");
77
+ }
78
+ async function projectHasUsedClaudeCode(cwd) {
79
+ const home = homedir();
80
+ const projectsDir = join(home, ".claude", "projects");
81
+ let dir = resolve(cwd);
82
+ while (dir !== home) {
83
+ if (await fileExists(join(projectsDir, encodeClaudeProjectDir(dir)))) {
84
+ return true;
85
+ }
86
+ const parent = dirname(dir);
87
+ if (parent === dir) {
88
+ break;
89
+ }
90
+ dir = parent;
91
+ }
92
+ return false;
93
+ }
94
+ async function getPluginTargets(agentName, cwd) {
95
+ const targetForAgent = getPluginTargetForAgent(agentName);
96
+ if (targetForAgent) {
97
+ return [targetForAgent];
98
+ }
99
+ if (agentName) {
100
+ return [];
101
+ }
102
+ if (cwd && await projectHasUsedClaudeCode(cwd)) {
103
+ return ["claude-code"];
104
+ }
105
+ return [];
106
+ }
107
+ async function readClaudeInstalledPluginsFromRegistry() {
108
+ try {
109
+ const raw = await readFile(
110
+ getClaudeInstalledPluginsRegistryPath(),
111
+ "utf-8"
112
+ );
113
+ const data = JSON.parse(raw);
114
+ const plugins = data?.plugins ?? {};
115
+ const entries = [];
116
+ for (const [id, installs] of Object.entries(plugins)) {
117
+ if (!Array.isArray(installs))
118
+ continue;
119
+ for (const install of installs) {
120
+ if (!install || typeof install !== "object")
121
+ continue;
122
+ entries.push({
123
+ id,
124
+ ...install,
125
+ enabled: true
126
+ });
127
+ }
128
+ }
129
+ return entries;
130
+ } catch {
131
+ return [];
132
+ }
133
+ }
134
+ function getClaudeInstalledPluginsRegistryPath() {
135
+ return join(homedir(), ".claude", "plugins", "installed_plugins.json");
136
+ }
137
+ async function markStaleClaudePluginInstalls(plugins) {
138
+ return Promise.all(
139
+ plugins.map(async (plugin) => {
140
+ if (plugin.installPath && !await fileExists(plugin.installPath)) {
141
+ return { ...plugin, stale: true };
142
+ }
143
+ return plugin;
144
+ })
145
+ );
146
+ }
147
+ async function removeClaudePluginFromRegistry(pluginId) {
148
+ try {
149
+ const registryPath = getClaudeInstalledPluginsRegistryPath();
150
+ const raw = await readFile(registryPath, "utf-8");
151
+ const data = JSON.parse(raw);
152
+ if (!data.plugins || !(pluginId in data.plugins)) {
153
+ return false;
154
+ }
155
+ delete data.plugins[pluginId];
156
+ await writeFile(
157
+ registryPath,
158
+ `${JSON.stringify(data, null, 2)}
159
+ `,
160
+ "utf-8"
161
+ );
162
+ return true;
163
+ } catch (err) {
164
+ output_manager_default.debug(`Failed to remove Claude plugin registry entry: ${err}`);
165
+ return false;
166
+ }
167
+ }
168
+ async function isPluginInstalledForTarget(target) {
169
+ if (target === "claude-code") {
170
+ const status = await getClaudePluginStatus();
171
+ return status.state === "official-only";
172
+ }
173
+ return false;
174
+ }
175
+ async function confirm(client, message) {
176
+ if (!client.stdin.isTTY) {
177
+ return false;
178
+ }
179
+ return client.input.confirm(message, true);
180
+ }
181
+ function isSameDay(left, right) {
182
+ return left.getFullYear() === right.getFullYear() && left.getMonth() === right.getMonth() && left.getDate() === right.getDate();
183
+ }
184
+ function wasPromptedToday(prefs) {
185
+ return prefs.lastPromptedAt ? isSameDay(prefs.lastPromptedAt, /* @__PURE__ */ new Date()) : false;
186
+ }
187
+ function wasPluginAutoUpdateAttemptedToday(prefs, attemptKey) {
188
+ return prefs.lastPluginAutoUpdateAttemptedKey === attemptKey && !!prefs.lastPluginAutoUpdateAttemptedAt && isSameDay(prefs.lastPluginAutoUpdateAttemptedAt, /* @__PURE__ */ new Date());
189
+ }
190
+ async function markPromptedToday(client, prefs) {
191
+ prefs.lastPromptedAt = /* @__PURE__ */ new Date();
192
+ await writePrefs(client, prefs);
193
+ }
194
+ function markPluginAutoUpdateAttempted(prefs, attemptKey) {
195
+ if (!attemptKey)
196
+ return;
197
+ prefs.lastPluginAutoUpdateAttemptedAt = /* @__PURE__ */ new Date();
198
+ prefs.lastPluginAutoUpdateAttemptedKey = attemptKey;
199
+ }
200
+ async function runCommand(command, args) {
201
+ return await new Promise((resolve2) => {
202
+ const child = spawn(command, args, { stdio: "pipe" });
203
+ let stdout = "";
204
+ let stderr = "";
205
+ child.stdout.on("data", (chunk) => {
206
+ stdout += chunk.toString();
207
+ });
208
+ child.stderr.on("data", (chunk) => {
209
+ stderr += chunk.toString();
210
+ });
211
+ child.on("close", (code) => {
212
+ resolve2({ exitCode: code ?? 1, stdout, stderr });
213
+ });
214
+ child.on("error", (err) => {
215
+ resolve2({ exitCode: 1, stdout, stderr: `${stderr}${String(err)}` });
216
+ });
217
+ });
218
+ }
219
+ async function getClaudeInstalledPlugins() {
220
+ const result = await runCommand("claude", ["plugins", "list", "--json"]);
221
+ if (result.exitCode === 0) {
222
+ try {
223
+ const parsed = JSON.parse(result.stdout);
224
+ if (Array.isArray(parsed)) {
225
+ return markStaleClaudePluginInstalls(parsed);
226
+ }
227
+ } catch (err) {
228
+ output_manager_default.debug(`Failed to parse Claude plugin list JSON: ${err}`);
229
+ }
230
+ } else if (result.stderr.trim().length > 0) {
231
+ output_manager_default.debug(
232
+ `Failed to run 'claude plugins list --json': ${result.stderr}`
233
+ );
234
+ }
235
+ return markStaleClaudePluginInstalls(
236
+ await readClaudeInstalledPluginsFromRegistry()
237
+ );
238
+ }
239
+ async function fetchLatestVercelPluginVersion() {
240
+ try {
241
+ const response = await fetch(VERCEL_PLUGIN_VERSION_URL);
242
+ if (!response.ok) {
243
+ output_manager_default.debug(
244
+ `Failed to fetch latest Vercel plugin version: ${response.status}`
245
+ );
246
+ return void 0;
247
+ }
248
+ const manifest = await response.json();
249
+ return typeof manifest.version === "string" ? manifest.version : void 0;
250
+ } catch (err) {
251
+ output_manager_default.debug(`Failed to fetch latest Vercel plugin version: ${err}`);
252
+ return void 0;
253
+ }
254
+ }
255
+ function comparePluginVersions(a, b) {
256
+ if (!a && !b)
257
+ return 0;
258
+ if (!a)
259
+ return -1;
260
+ if (!b)
261
+ return 1;
262
+ const parse = (value) => value.split(".").map((part) => Number.parseInt(part, 10) || 0);
263
+ const left = parse(a);
264
+ const right = parse(b);
265
+ const maxLength = Math.max(left.length, right.length);
266
+ for (let i = 0; i < maxLength; i++) {
267
+ const l = left[i] ?? 0;
268
+ const r = right[i] ?? 0;
269
+ if (l > r)
270
+ return 1;
271
+ if (l < r)
272
+ return -1;
273
+ }
274
+ return 0;
275
+ }
276
+ function buildClaudePluginStatus(installedPlugins, latestVersion) {
277
+ const legacy = installedPlugins.find(
278
+ (plugin) => plugin.id === CLAUDE_LEGACY_PLUGIN_ID
279
+ );
280
+ const official = installedPlugins.find(
281
+ (plugin) => plugin.id === CLAUDE_OFFICIAL_PLUGIN_ID
282
+ );
283
+ let state = "none";
284
+ if (legacy && official)
285
+ state = "both";
286
+ else if (legacy)
287
+ state = "legacy-only";
288
+ else if (official)
289
+ state = "official-only";
290
+ return {
291
+ state,
292
+ legacy,
293
+ official,
294
+ latestVersion
295
+ };
296
+ }
297
+ function buildClaudePluginMigrationPlan(status) {
298
+ const plan = {
299
+ installOfficial: false,
300
+ updateOfficial: false,
301
+ removeLegacy: false,
302
+ removeLegacyMarketplace: false
303
+ };
304
+ switch (status.state) {
305
+ case "none":
306
+ plan.installOfficial = true;
307
+ break;
308
+ case "legacy-only":
309
+ plan.installOfficial = true;
310
+ plan.removeLegacy = true;
311
+ plan.removeLegacyMarketplace = true;
312
+ break;
313
+ case "both":
314
+ plan.removeLegacy = true;
315
+ plan.removeLegacyMarketplace = true;
316
+ break;
317
+ case "official-only":
318
+ break;
319
+ }
320
+ if (status.official?.version && status.latestVersion && comparePluginVersions(status.official.version, status.latestVersion) < 0) {
321
+ plan.updateOfficial = true;
322
+ }
323
+ return plan;
324
+ }
325
+ function hasClaudeMigrationActions(plan) {
326
+ return plan.installOfficial || plan.updateOfficial || plan.removeLegacy || plan.removeLegacyMarketplace;
327
+ }
328
+ function getClaudeAutoUpdateAttemptKey(status, plan) {
329
+ return [
330
+ status.state,
331
+ status.legacy?.version ?? "none",
332
+ status.official?.version ?? "none",
333
+ status.latestVersion ?? "unknown",
334
+ plan.installOfficial ? "install" : "",
335
+ plan.updateOfficial ? "update" : "",
336
+ plan.removeLegacy ? "remove-legacy" : "",
337
+ plan.removeLegacyMarketplace ? "remove-marketplace" : ""
338
+ ].join(":");
339
+ }
340
+ function buildClaudePromptCopy(status, plan) {
341
+ if (plan.installOfficial && status.state === "none") {
342
+ return {
343
+ message: "Vercel Plugin for Claude Code is not installed.",
344
+ confirm: "Would you like to install it now?"
345
+ };
346
+ }
347
+ if (plan.installOfficial && status.state === "legacy-only") {
348
+ return {
349
+ message: "Update available for Vercel Plugin for Claude Code (legacy -> official).",
350
+ confirm: "Would you like to update now?"
351
+ };
352
+ }
353
+ if (status.state === "both" && plan.removeLegacy) {
354
+ return {
355
+ message: "Vercel Plugin for Claude Code has a legacy install to clean up.",
356
+ confirm: "Would you like to update now?"
357
+ };
358
+ }
359
+ if (plan.updateOfficial) {
360
+ const fromVersion = status.official?.version;
361
+ const toVersion = status.latestVersion;
362
+ const versionRange = fromVersion && toVersion ? ` (v${fromVersion} -> v${toVersion})` : "";
363
+ return {
364
+ message: `Update available for Vercel Plugin for Claude Code${versionRange}.`,
365
+ confirm: "Would you like to update now?"
366
+ };
367
+ }
368
+ return {
369
+ message: "The Vercel plugin needs attention in Claude Code before your agent harness is fully up to date.",
370
+ confirm: "Apply the Vercel plugin changes for Claude Code?"
371
+ };
372
+ }
373
+ async function runClaudeCommand(spinnerMessage, successMessage, failureMessage, args, options) {
374
+ output_manager_default.spinner(spinnerMessage);
375
+ const result = await runCommand("claude", args);
376
+ output_manager_default.stopSpinner();
377
+ if (result.exitCode === 0) {
378
+ if (!options?.quietSuccess) {
379
+ output_manager_default.success(successMessage);
380
+ }
381
+ return true;
382
+ }
383
+ output_manager_default.warn(failureMessage);
384
+ output_manager_default.debug(
385
+ `Claude command failed: claude ${args.join(" ")}
386
+ ${result.stderr || result.stdout}`
387
+ );
388
+ return false;
389
+ }
390
+ async function removeStaleLegacyClaudePlugin(removeMarketplace) {
391
+ output_manager_default.spinner("Removing the stale legacy Vercel Claude plugin...");
392
+ const removedRegistryEntry = await removeClaudePluginFromRegistry(
393
+ CLAUDE_LEGACY_PLUGIN_ID
394
+ );
395
+ output_manager_default.stopSpinner();
396
+ if (!removedRegistryEntry) {
397
+ output_manager_default.warn(
398
+ "Could not remove the stale legacy Vercel Claude plugin registry entry."
399
+ );
400
+ return false;
401
+ }
402
+ output_manager_default.success("Removed the stale legacy Vercel Claude plugin");
403
+ if (removeMarketplace) {
404
+ const removedMarketplace = await runClaudeCommand(
405
+ "Removing the legacy Vercel marketplace...",
406
+ "Removed the legacy Vercel marketplace",
407
+ "Removed the stale legacy Vercel plugin, but could not remove the legacy marketplace.",
408
+ ["plugins", "marketplace", "remove", "vercel"],
409
+ { quietSuccess: true }
410
+ );
411
+ if (!removedMarketplace) {
412
+ output_manager_default.log("Cleanup command: claude plugins marketplace remove vercel");
413
+ }
414
+ }
415
+ return true;
416
+ }
417
+ async function runClaudeMigration(plan) {
418
+ let removedStaleLegacy = false;
419
+ if (plan.removeLegacy) {
420
+ const statusBeforeInstall = await getClaudePluginStatus();
421
+ if (statusBeforeInstall.legacy?.stale) {
422
+ removedStaleLegacy = await removeStaleLegacyClaudePlugin(
423
+ plan.removeLegacyMarketplace
424
+ );
425
+ }
426
+ }
427
+ if (plan.installOfficial) {
428
+ const installed = await runClaudeCommand(
429
+ "Installing the official Vercel Claude plugin...",
430
+ "Updated the Vercel plugin",
431
+ "Failed to install the official Vercel Claude plugin.",
432
+ ["plugins", "install", CLAUDE_OFFICIAL_PLUGIN_ID]
433
+ );
434
+ if (!installed) {
435
+ return;
436
+ }
437
+ } else if (plan.updateOfficial) {
438
+ await runClaudeCommand(
439
+ "Updating the official Vercel Claude plugin...",
440
+ "Updated the Vercel plugin",
441
+ "Failed to update the official Vercel Claude plugin.",
442
+ ["plugins", "update", CLAUDE_OFFICIAL_PLUGIN_ID]
443
+ );
444
+ }
445
+ const statusAfterInstall = await getClaudePluginStatus();
446
+ if (!statusAfterInstall.official) {
447
+ output_manager_default.warn(
448
+ "Skipping Claude cleanup because the official Vercel plugin is not installed."
449
+ );
450
+ return;
451
+ }
452
+ if (plan.removeLegacy && statusAfterInstall.legacy) {
453
+ const removedLegacy = await runClaudeCommand(
454
+ "Removing the legacy Vercel Claude plugin...",
455
+ "Removed the legacy Vercel Claude plugin",
456
+ "Installed the official Vercel Claude plugin, but could not remove the legacy install.",
457
+ ["plugins", "uninstall", CLAUDE_LEGACY_PLUGIN_ID],
458
+ { quietSuccess: true }
459
+ );
460
+ if (!removedLegacy) {
461
+ output_manager_default.log(
462
+ `Cleanup command: claude plugins uninstall ${CLAUDE_LEGACY_PLUGIN_ID}`
463
+ );
464
+ return;
465
+ }
466
+ }
467
+ if (plan.removeLegacyMarketplace && !removedStaleLegacy) {
468
+ const finalStatus = await getClaudePluginStatus();
469
+ if (!finalStatus.legacy) {
470
+ const removedMarketplace = await runClaudeCommand(
471
+ "Removing the legacy Vercel marketplace...",
472
+ "Removed the legacy Vercel marketplace",
473
+ "Removed the legacy Vercel plugin, but could not remove the legacy marketplace.",
474
+ ["plugins", "marketplace", "remove", "vercel"],
475
+ { quietSuccess: true }
476
+ );
477
+ if (!removedMarketplace) {
478
+ output_manager_default.log("Cleanup command: claude plugins marketplace remove vercel");
479
+ }
480
+ }
481
+ }
482
+ }
483
+ async function getClaudePluginStatus() {
484
+ const [installedPlugins, latestVersion] = await Promise.all([
485
+ getClaudeInstalledPlugins(),
486
+ fetchLatestVercelPluginVersion()
487
+ ]);
488
+ return buildClaudePluginStatus(installedPlugins, latestVersion);
489
+ }
490
+ async function applyPluginActions(targets, claudePlan) {
491
+ for (const target of targets) {
492
+ if (target === "claude-code" && claudePlan) {
493
+ await runClaudeMigration(claudePlan);
494
+ } else {
495
+ output_manager_default.debug(`Skipping unsupported plugin target: ${target}`);
496
+ }
497
+ }
498
+ }
499
+ async function autoInstallVercelPlugin(client, options) {
500
+ try {
501
+ const prefs = await readPrefs(client);
502
+ const applyMode = options?.mode === "apply";
503
+ if (!prefs.pluginDeclined || prefs.pluginAutoUpdate || applyMode) {
504
+ const targets = await getPluginTargets(client.agentName, client.cwd);
505
+ const uninstalledTargets = [];
506
+ const claudeStatus = targets.includes("claude-code") ? await getClaudePluginStatus() : void 0;
507
+ const claudePlan = claudeStatus ? buildClaudePluginMigrationPlan(claudeStatus) : void 0;
508
+ const claudeAutoUpdateAttemptKey = claudeStatus && claudePlan ? getClaudeAutoUpdateAttemptKey(claudeStatus, claudePlan) : void 0;
509
+ for (const target of targets) {
510
+ if (target === "claude-code") {
511
+ if (claudePlan && hasClaudeMigrationActions(claudePlan)) {
512
+ uninstalledTargets.push(target);
513
+ }
514
+ continue;
515
+ }
516
+ if (!await isPluginInstalledForTarget(target)) {
517
+ uninstalledTargets.push(target);
518
+ }
519
+ }
520
+ if (uninstalledTargets.length > 0) {
521
+ if (prefs.pluginAutoUpdate) {
522
+ if (claudeAutoUpdateAttemptKey && wasPluginAutoUpdateAttemptedToday(prefs, claudeAutoUpdateAttemptKey)) {
523
+ return;
524
+ }
525
+ prefs.pluginDeclined = false;
526
+ markPluginAutoUpdateAttempted(prefs, claudeAutoUpdateAttemptKey);
527
+ await writePrefs(client, prefs);
528
+ await applyPluginActions(uninstalledTargets, claudePlan);
529
+ return;
530
+ }
531
+ if (!applyMode && wasPromptedToday(prefs)) {
532
+ return;
533
+ }
534
+ if (applyMode) {
535
+ prefs.pluginDeclined = false;
536
+ prefs.pluginAutoUpdate = true;
537
+ await writePrefs(client, prefs);
538
+ await applyPluginActions(uninstalledTargets, claudePlan);
539
+ return;
540
+ }
541
+ const promptMessages = [];
542
+ let confirmMessage = "Install the Vercel plugin?";
543
+ if (uninstalledTargets.includes("claude-code") && claudeStatus && claudePlan) {
544
+ const claudePrompt = buildClaudePromptCopy(claudeStatus, claudePlan);
545
+ promptMessages.push(claudePrompt.message);
546
+ confirmMessage = claudePrompt.confirm;
547
+ }
548
+ const promptMessage = promptMessages.join(" ").trim();
549
+ if (promptMessage) {
550
+ output_manager_default.log(promptMessage);
551
+ }
552
+ const accepted = await confirm(client, confirmMessage);
553
+ await markPromptedToday(client, prefs);
554
+ if (accepted) {
555
+ prefs.pluginDeclined = false;
556
+ prefs.pluginAutoUpdate = true;
557
+ await writePrefs(client, prefs);
558
+ await applyPluginActions(uninstalledTargets, claudePlan);
559
+ } else {
560
+ prefs.pluginDeclined = true;
561
+ prefs.pluginAutoUpdate = false;
562
+ await writePrefs(client, prefs);
563
+ }
564
+ }
565
+ }
566
+ } catch (err) {
567
+ output_manager_default.debug(`Auto-install agent tooling failed: ${err}`);
568
+ }
569
+ }
570
+ async function showPluginTipIfNeeded(client) {
571
+ try {
572
+ const prefs = await readPrefs(client);
573
+ if (prefs.pluginDeclined)
574
+ return;
575
+ const targets = await getPluginTargets(client.agentName, client.cwd);
576
+ for (const target of targets) {
577
+ if (!await isPluginInstalledForTarget(target)) {
578
+ output_manager_default.log(
579
+ import_chalk.default.dim(
580
+ "Tip: Run `npx plugins add vercel/vercel-plugin` to enhance your agent experience"
581
+ )
582
+ );
583
+ return;
584
+ }
585
+ }
586
+ } catch {
587
+ }
588
+ }
589
+
590
+ export {
591
+ autoInstallVercelPlugin,
592
+ showPluginTipIfNeeded
593
+ };
@@ -18,7 +18,7 @@ import {
18
18
  require_lib,
19
19
  require_minimatch,
20
20
  require_pluralize
21
- } from "./chunk-LQR3CHMH.js";
21
+ } from "./chunk-YIAUEFUY.js";
22
22
  import {
23
23
  CantParseJSONFile,
24
24
  cmd,
@@ -11455,14 +11455,6 @@ function stripDuplicateSlashes(path2) {
11455
11455
  function getServiceOutputDir(outputDir, service) {
11456
11456
  return join4(outputDir, "services", service.name);
11457
11457
  }
11458
- async function relocateRootBuildOutputToService(args) {
11459
- const { outputDir, service, workPath } = args;
11460
- await relocateBuildOutputApiEntries(
11461
- outputDir,
11462
- getServiceOutputDir(outputDir, service),
11463
- workPath
11464
- );
11465
- }
11466
11458
  async function writeBuildResultV2(args) {
11467
11459
  const {
11468
11460
  repoRootPath,
@@ -12000,8 +11992,7 @@ export {
12000
11992
  getStaticServiceSchedules,
12001
11993
  OUTPUT_DIR,
12002
11994
  writeBuildResult,
12003
- isLambda,
12004
- relocateRootBuildOutputToService
11995
+ isLambda
12005
11996
  };
12006
11997
  /*! Bundled license information:
12007
11998
 
@@ -6,7 +6,7 @@ const __filename = __fileURLToPath(import.meta.url);
6
6
  const __dirname = __dirname_(__filename);
7
7
  import {
8
8
  STANDARD_ENVIRONMENTS
9
- } from "./chunk-LQR3CHMH.js";
9
+ } from "./chunk-YIAUEFUY.js";
10
10
  import {
11
11
  getCommandName,
12
12
  require_lib
@@ -10,10 +10,10 @@ import {
10
10
  } from "./chunk-LJ5WXXG6.js";
11
11
  import {
12
12
  getLocalPathConfig
13
- } from "./chunk-4BFK3C7V.js";
13
+ } from "./chunk-6H2YVMJJ.js";
14
14
  import {
15
15
  getScope
16
- } from "./chunk-G3NXHUFT.js";
16
+ } from "./chunk-25XEQWUS.js";
17
17
  import {
18
18
  VERCEL_DIR_PROJECT,
19
19
  VERCEL_DIR_README,
@@ -48,7 +48,7 @@ import {
48
48
  selectAndParseRemoteUrl,
49
49
  selectOrg,
50
50
  writeServicesConfig
51
- } from "./chunk-LQR3CHMH.js";
51
+ } from "./chunk-YIAUEFUY.js";
52
52
  import {
53
53
  buildCommandWithGlobalFlags,
54
54
  outputAgentError,