cursor-kit-cli 1.5.0 → 1.6.0-beta.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/cli.js CHANGED
@@ -1535,8 +1535,8 @@ async function convertPulledFilesForTarget(target, directories) {
1535
1535
  const skillPath = join6(skillsDir, skillDir);
1536
1536
  const skillMdPath = join6(skillPath, "SKILL.md");
1537
1537
  const skillMdcPath = join6(skillPath, "SKILL.mdc");
1538
- const { existsSync: existsSync3 } = await import("fs");
1539
- if (existsSync3(skillMdPath)) {
1538
+ const { existsSync: existsSync4 } = await import("fs");
1539
+ if (existsSync4(skillMdPath)) {
1540
1540
  const content = readFile(skillMdPath);
1541
1541
  writeFile(skillMdcPath, content);
1542
1542
  const { rmSync: rmSync2 } = await import("fs");
@@ -2033,17 +2033,313 @@ import { defineCommand as defineCommand6 } from "citty";
2033
2033
  import * as p8 from "@clack/prompts";
2034
2034
  import pc8 from "picocolors";
2035
2035
  import { spawn } from "child_process";
2036
- import { join as join9, dirname as dirname3 } from "path";
2036
+ import { join as join10, dirname as dirname3 } from "path";
2037
2037
  import { fileURLToPath as fileURLToPath2 } from "url";
2038
- import { existsSync as existsSync2, chmodSync, readdirSync as readdirSync2 } from "fs";
2038
+ import { existsSync as existsSync3, chmodSync as chmodSync2, readdirSync as readdirSync2 } from "fs";
2039
+
2040
+ // src/utils/alias.ts
2041
+ import {
2042
+ appendFileSync,
2043
+ chmodSync,
2044
+ existsSync as existsSync2,
2045
+ mkdirSync as mkdirSync2,
2046
+ readFileSync as readFileSync2,
2047
+ unlinkSync,
2048
+ writeFileSync as writeFileSync2
2049
+ } from "fs";
2050
+ import { homedir } from "os";
2051
+ import { join as join9 } from "path";
2052
+ var CURSOR_KIT_DIR = ".cursor-kit";
2053
+ var ALIASES_FILE = "aliases.json";
2054
+ function getAliasConfigDir() {
2055
+ return join9(homedir(), CURSOR_KIT_DIR);
2056
+ }
2057
+ function getAliasConfigPath() {
2058
+ return join9(getAliasConfigDir(), ALIASES_FILE);
2059
+ }
2060
+ function ensureConfigDir() {
2061
+ const configDir = getAliasConfigDir();
2062
+ if (!existsSync2(configDir)) {
2063
+ mkdirSync2(configDir, { recursive: true });
2064
+ }
2065
+ }
2066
+ function loadAliasConfig() {
2067
+ const configPath = getAliasConfigPath();
2068
+ if (!existsSync2(configPath)) {
2069
+ return { aliases: {} };
2070
+ }
2071
+ try {
2072
+ const content = readFileSync2(configPath, "utf-8");
2073
+ return JSON.parse(content);
2074
+ } catch {
2075
+ return { aliases: {} };
2076
+ }
2077
+ }
2078
+ function saveAliasConfig(config) {
2079
+ ensureConfigDir();
2080
+ const configPath = getAliasConfigPath();
2081
+ writeFileSync2(configPath, JSON.stringify(config, null, 2), "utf-8");
2082
+ }
2083
+ function getInstanceDataDir(instanceName) {
2084
+ return join9(
2085
+ homedir(),
2086
+ "Library",
2087
+ "Application Support",
2088
+ instanceName.replace(/ /g, "")
2089
+ );
2090
+ }
2091
+ function getInstanceAppPath(instanceName) {
2092
+ return join9(homedir(), "Applications", `${instanceName}.app`);
2093
+ }
2094
+ function generateScriptContent(instanceName) {
2095
+ const dataDir = getInstanceDataDir(instanceName);
2096
+ const appPath = getInstanceAppPath(instanceName);
2097
+ return `#!/usr/bin/env bash
2098
+ # Generated by cursor-kit for instance: ${instanceName}
2099
+ # This script opens the specified directory (or current directory) in the Cursor instance
2100
+
2101
+ set -euo pipefail
2102
+
2103
+ DIR="\${1:-.}"
2104
+
2105
+ # Resolve to absolute path if relative
2106
+ if [[ "$DIR" != /* ]]; then
2107
+ DIR="$(cd "$DIR" 2>/dev/null && pwd)"
2108
+ fi
2109
+
2110
+ DATA_DIR="${dataDir}"
2111
+ APP_PATH="${appPath}"
2112
+
2113
+ if [ ! -d "$APP_PATH" ]; then
2114
+ echo "Error: Cursor instance not found at $APP_PATH" >&2
2115
+ echo "The instance may have been removed. Run 'cursor-kit instance -l' to see available instances." >&2
2116
+ exit 1
2117
+ fi
2118
+
2119
+ open -n "$APP_PATH" --args --user-data-dir "$DATA_DIR" "$DIR"
2120
+ `;
2121
+ }
2122
+ function generateShellFunction(aliasName, instanceName) {
2123
+ const dataDir = getInstanceDataDir(instanceName);
2124
+ const appPath = getInstanceAppPath(instanceName);
2125
+ return `
2126
+ # cursor-kit alias: ${aliasName} -> ${instanceName}
2127
+ ${aliasName}() {
2128
+ local DIR="\${1:-.}"
2129
+ if [[ "$DIR" != /* ]]; then
2130
+ DIR="$(cd "$DIR" 2>/dev/null && pwd)"
2131
+ fi
2132
+ local DATA_DIR="${dataDir}"
2133
+ local APP_PATH="${appPath}"
2134
+ if [ ! -d "$APP_PATH" ]; then
2135
+ echo "Error: Cursor instance not found at $APP_PATH" >&2
2136
+ return 1
2137
+ fi
2138
+ open -n "$APP_PATH" --args --user-data-dir "$DATA_DIR" "$DIR"
2139
+ }
2140
+ # end cursor-kit alias: ${aliasName}
2141
+ `;
2142
+ }
2143
+ function detectShellConfigPath() {
2144
+ const home = homedir();
2145
+ const shell = process.env.SHELL ?? "/bin/zsh";
2146
+ if (shell.includes("zsh")) {
2147
+ return join9(home, ".zshrc");
2148
+ }
2149
+ if (shell.includes("bash")) {
2150
+ const bashProfile = join9(home, ".bash_profile");
2151
+ if (existsSync2(bashProfile)) {
2152
+ return bashProfile;
2153
+ }
2154
+ return join9(home, ".bashrc");
2155
+ }
2156
+ return join9(home, ".zshrc");
2157
+ }
2158
+ function getHomeBinDir() {
2159
+ return join9(homedir(), "bin");
2160
+ }
2161
+ function getUsrLocalBinDir() {
2162
+ return "/usr/local/bin";
2163
+ }
2164
+ function ensureBinDir(binDir) {
2165
+ if (!existsSync2(binDir)) {
2166
+ mkdirSync2(binDir, { recursive: true });
2167
+ }
2168
+ }
2169
+ function createExecutableScript(aliasName, instanceName, targetDir) {
2170
+ ensureBinDir(targetDir);
2171
+ const scriptPath = join9(targetDir, aliasName);
2172
+ const scriptContent = generateScriptContent(instanceName);
2173
+ writeFileSync2(scriptPath, scriptContent, "utf-8");
2174
+ chmodSync(scriptPath, 493);
2175
+ return scriptPath;
2176
+ }
2177
+ function createShellAlias(aliasName, instanceName, shellConfigPath) {
2178
+ const functionContent = generateShellFunction(aliasName, instanceName);
2179
+ if (!existsSync2(shellConfigPath)) {
2180
+ writeFileSync2(shellConfigPath, "", "utf-8");
2181
+ }
2182
+ const existingContent = readFileSync2(shellConfigPath, "utf-8");
2183
+ if (existingContent.includes(`# cursor-kit alias: ${aliasName}`)) {
2184
+ removeShellAlias(aliasName, shellConfigPath);
2185
+ }
2186
+ appendFileSync(shellConfigPath, functionContent, "utf-8");
2187
+ }
2188
+ function removeShellAlias(aliasName, shellConfigPath) {
2189
+ if (!existsSync2(shellConfigPath)) {
2190
+ return false;
2191
+ }
2192
+ const content = readFileSync2(shellConfigPath, "utf-8");
2193
+ const startMarker = `# cursor-kit alias: ${aliasName}`;
2194
+ const endMarker = `# end cursor-kit alias: ${aliasName}`;
2195
+ const startIndex = content.indexOf(startMarker);
2196
+ if (startIndex === -1) {
2197
+ return false;
2198
+ }
2199
+ const endIndex = content.indexOf(endMarker);
2200
+ if (endIndex === -1) {
2201
+ return false;
2202
+ }
2203
+ const before = content.slice(0, startIndex);
2204
+ const after = content.slice(endIndex + endMarker.length);
2205
+ const newContent = (before + after).replace(/\n{3,}/g, "\n\n");
2206
+ writeFileSync2(shellConfigPath, newContent, "utf-8");
2207
+ return true;
2208
+ }
2209
+ function removeExecutableScript(scriptPath) {
2210
+ if (!existsSync2(scriptPath)) {
2211
+ return false;
2212
+ }
2213
+ try {
2214
+ unlinkSync(scriptPath);
2215
+ return true;
2216
+ } catch {
2217
+ return false;
2218
+ }
2219
+ }
2220
+ function createAlias(options) {
2221
+ const { aliasName, instanceName, storageLocation } = options;
2222
+ try {
2223
+ let scriptPath;
2224
+ let shellConfigPath;
2225
+ switch (storageLocation) {
2226
+ case "shell-config": {
2227
+ shellConfigPath = detectShellConfigPath();
2228
+ createShellAlias(aliasName, instanceName, shellConfigPath);
2229
+ break;
2230
+ }
2231
+ case "usr-local-bin": {
2232
+ scriptPath = createExecutableScript(
2233
+ aliasName,
2234
+ instanceName,
2235
+ getUsrLocalBinDir()
2236
+ );
2237
+ break;
2238
+ }
2239
+ case "home-bin": {
2240
+ scriptPath = createExecutableScript(
2241
+ aliasName,
2242
+ instanceName,
2243
+ getHomeBinDir()
2244
+ );
2245
+ break;
2246
+ }
2247
+ }
2248
+ const config = loadAliasConfig();
2249
+ config.aliases[aliasName] = {
2250
+ instanceName,
2251
+ aliasName,
2252
+ storageLocation,
2253
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
2254
+ scriptPath
2255
+ };
2256
+ saveAliasConfig(config);
2257
+ return { success: true, scriptPath, shellConfigPath };
2258
+ } catch (error) {
2259
+ return {
2260
+ success: false,
2261
+ error: error instanceof Error ? error.message : "Unknown error"
2262
+ };
2263
+ }
2264
+ }
2265
+ function removeAlias(aliasName) {
2266
+ const config = loadAliasConfig();
2267
+ const entry = config.aliases[aliasName];
2268
+ if (!entry) {
2269
+ return false;
2270
+ }
2271
+ let removed = false;
2272
+ switch (entry.storageLocation) {
2273
+ case "shell-config": {
2274
+ const shellConfigPath = detectShellConfigPath();
2275
+ removed = removeShellAlias(aliasName, shellConfigPath);
2276
+ break;
2277
+ }
2278
+ case "usr-local-bin": {
2279
+ const scriptPath = join9(getUsrLocalBinDir(), aliasName);
2280
+ removed = removeExecutableScript(scriptPath);
2281
+ break;
2282
+ }
2283
+ case "home-bin": {
2284
+ const scriptPath = join9(getHomeBinDir(), aliasName);
2285
+ removed = removeExecutableScript(scriptPath);
2286
+ break;
2287
+ }
2288
+ }
2289
+ delete config.aliases[aliasName];
2290
+ saveAliasConfig(config);
2291
+ return removed;
2292
+ }
2293
+ function getAliasForInstance(instanceName) {
2294
+ const config = loadAliasConfig();
2295
+ for (const entry of Object.values(config.aliases)) {
2296
+ if (entry.instanceName === instanceName) {
2297
+ return entry;
2298
+ }
2299
+ }
2300
+ return null;
2301
+ }
2302
+ function aliasExists(aliasName) {
2303
+ const config = loadAliasConfig();
2304
+ return aliasName in config.aliases;
2305
+ }
2306
+ function generateAliasName(instanceName) {
2307
+ return instanceName.toLowerCase().replace(/^cursor\s*/i, "cursor-").replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "").replace(/-+/g, "-").replace(/^-|-$/g, "");
2308
+ }
2309
+ function getStorageLocationLabel(location) {
2310
+ switch (location) {
2311
+ case "shell-config":
2312
+ return "Shell config (~/.zshrc or ~/.bashrc)";
2313
+ case "usr-local-bin":
2314
+ return "/usr/local/bin (system-wide)";
2315
+ case "home-bin":
2316
+ return "~/bin (user-local)";
2317
+ }
2318
+ }
2319
+ function isHomeBinInPath() {
2320
+ const pathEnv = process.env.PATH ?? "";
2321
+ const homeBin = getHomeBinDir();
2322
+ return pathEnv.split(":").some((p9) => p9 === homeBin || p9 === "~/bin" || p9 === "$HOME/bin");
2323
+ }
2324
+ function getPathSetupInstructions() {
2325
+ const shell = process.env.SHELL ?? "/bin/zsh";
2326
+ const configFile = shell.includes("zsh") ? "~/.zshrc" : "~/.bashrc";
2327
+ return `Add the following to your ${configFile}:
2328
+
2329
+ export PATH="$HOME/bin:$PATH"
2330
+
2331
+ Then restart your terminal or run: source ${configFile}`;
2332
+ }
2333
+
2334
+ // src/commands/instance.ts
2039
2335
  function getBinPath() {
2040
2336
  const currentDir = dirname3(fileURLToPath2(import.meta.url));
2041
2337
  const possiblePaths = [
2042
- join9(currentDir, "..", "..", "bin"),
2043
- join9(currentDir, "..", "bin")
2338
+ join10(currentDir, "..", "..", "bin"),
2339
+ join10(currentDir, "..", "bin")
2044
2340
  ];
2045
2341
  for (const binPath of possiblePaths) {
2046
- if (existsSync2(binPath)) {
2342
+ if (existsSync3(binPath)) {
2047
2343
  return binPath;
2048
2344
  }
2049
2345
  }
@@ -2051,19 +2347,24 @@ function getBinPath() {
2051
2347
  }
2052
2348
  function ensureExecutable(scriptPath) {
2053
2349
  try {
2054
- chmodSync(scriptPath, 493);
2350
+ chmodSync2(scriptPath, 493);
2055
2351
  } catch {
2056
2352
  }
2057
2353
  }
2058
2354
  function getExistingInstances() {
2059
- const userAppsDir = join9(process.env.HOME ?? "", "Applications");
2060
- if (!existsSync2(userAppsDir)) return [];
2355
+ const userAppsDir = join10(process.env.HOME ?? "", "Applications");
2356
+ if (!existsSync3(userAppsDir)) return [];
2061
2357
  try {
2062
2358
  const apps = readdirSync2(userAppsDir);
2063
- return apps.filter((app) => app.startsWith("Cursor") && app.endsWith(".app") && app !== "Cursor.app").map((app) => ({
2064
- name: app.replace(".app", ""),
2065
- path: join9(userAppsDir, app)
2066
- }));
2359
+ return apps.filter((app) => app.startsWith("Cursor") && app.endsWith(".app") && app !== "Cursor.app").map((app) => {
2360
+ const name = app.replace(".app", "");
2361
+ const aliasEntry = getAliasForInstance(name);
2362
+ return {
2363
+ name,
2364
+ path: join10(userAppsDir, app),
2365
+ alias: aliasEntry?.aliasName
2366
+ };
2367
+ });
2067
2368
  } catch {
2068
2369
  return [];
2069
2370
  }
@@ -2082,6 +2383,180 @@ function runScript(scriptPath, args) {
2082
2383
  });
2083
2384
  });
2084
2385
  }
2386
+ async function promptAliasCreation(instanceName, providedAlias, providedLocation, skipConfirmation) {
2387
+ if (!skipConfirmation) {
2388
+ const shouldCreateAlias = await p8.confirm({
2389
+ message: "Would you like to create a shell alias for this instance?",
2390
+ initialValue: true
2391
+ });
2392
+ if (p8.isCancel(shouldCreateAlias) || !shouldCreateAlias) {
2393
+ return null;
2394
+ }
2395
+ }
2396
+ let aliasName;
2397
+ const suggestedAlias = generateAliasName(instanceName);
2398
+ if (providedAlias) {
2399
+ aliasName = providedAlias;
2400
+ } else {
2401
+ const aliasResult = await p8.text({
2402
+ message: "Enter alias name:",
2403
+ placeholder: suggestedAlias,
2404
+ initialValue: suggestedAlias,
2405
+ validate: (value) => {
2406
+ if (!value.trim()) return "Alias name is required";
2407
+ if (!/^[a-z0-9-]+$/.test(value)) return "Alias must contain only lowercase letters, numbers, and hyphens";
2408
+ if (aliasExists(value)) return `Alias "${value}" already exists`;
2409
+ return void 0;
2410
+ }
2411
+ });
2412
+ if (p8.isCancel(aliasResult)) {
2413
+ return null;
2414
+ }
2415
+ aliasName = aliasResult;
2416
+ }
2417
+ let location;
2418
+ if (providedLocation && ["shell-config", "usr-local-bin", "home-bin"].includes(providedLocation)) {
2419
+ location = providedLocation;
2420
+ } else {
2421
+ const locationResult = await p8.select({
2422
+ message: "Where should the alias be stored?",
2423
+ options: [
2424
+ {
2425
+ value: "shell-config",
2426
+ label: "Shell config",
2427
+ hint: detectShellConfigPath()
2428
+ },
2429
+ {
2430
+ value: "home-bin",
2431
+ label: "~/bin",
2432
+ hint: "User-local executable scripts"
2433
+ },
2434
+ {
2435
+ value: "usr-local-bin",
2436
+ label: "/usr/local/bin",
2437
+ hint: "System-wide (may require sudo)"
2438
+ }
2439
+ ]
2440
+ });
2441
+ if (p8.isCancel(locationResult)) {
2442
+ return null;
2443
+ }
2444
+ location = locationResult;
2445
+ }
2446
+ return { aliasName, location };
2447
+ }
2448
+ async function handleAliasCreation(instanceName, aliasName, location) {
2449
+ const result = createAlias({
2450
+ aliasName,
2451
+ instanceName,
2452
+ storageLocation: location
2453
+ });
2454
+ if (!result.success) {
2455
+ printWarning(`Failed to create alias: ${result.error}`);
2456
+ return false;
2457
+ }
2458
+ console.log();
2459
+ printSuccess(`Alias ${highlight(aliasName)} created!`);
2460
+ console.log(pc8.dim(` \u2514\u2500 Location: ${getStorageLocationLabel(location)}`));
2461
+ if (location === "home-bin" && !isHomeBinInPath()) {
2462
+ console.log();
2463
+ printWarning("~/bin is not in your PATH");
2464
+ console.log(pc8.dim(getPathSetupInstructions()));
2465
+ }
2466
+ if (location === "shell-config") {
2467
+ console.log();
2468
+ console.log(pc8.dim(" Restart your terminal or run:"));
2469
+ console.log(pc8.dim(` source ${detectShellConfigPath()}`));
2470
+ }
2471
+ console.log();
2472
+ console.log(pc8.dim(" Usage:"));
2473
+ console.log(pc8.dim(` ${aliasName} . # Open current directory`));
2474
+ console.log(pc8.dim(` ${aliasName} /path/to/dir # Open specific directory`));
2475
+ return true;
2476
+ }
2477
+ async function handleAliasRemoval(instanceName) {
2478
+ const aliasEntry = getAliasForInstance(instanceName);
2479
+ if (!aliasEntry) {
2480
+ return;
2481
+ }
2482
+ const shouldRemove = await p8.confirm({
2483
+ message: `Remove associated alias "${aliasEntry.aliasName}"?`,
2484
+ initialValue: true
2485
+ });
2486
+ if (p8.isCancel(shouldRemove) || !shouldRemove) {
2487
+ return;
2488
+ }
2489
+ const removed = removeAlias(aliasEntry.aliasName);
2490
+ if (removed) {
2491
+ printSuccess(`Alias ${highlight(aliasEntry.aliasName)} removed`);
2492
+ } else {
2493
+ printWarning(`Could not remove alias ${aliasEntry.aliasName}`);
2494
+ }
2495
+ }
2496
+ async function handleAliasAction(instanceName, providedAlias, providedLocation) {
2497
+ const existingAlias = getAliasForInstance(instanceName);
2498
+ if (existingAlias) {
2499
+ console.log();
2500
+ printInfo(`Instance ${highlight(instanceName)} already has alias: ${highlight(existingAlias.aliasName)}`);
2501
+ console.log(pc8.dim(` \u2514\u2500 Location: ${getStorageLocationLabel(existingAlias.storageLocation)}`));
2502
+ console.log();
2503
+ const updateChoice = await p8.select({
2504
+ message: "What would you like to do?",
2505
+ options: [
2506
+ {
2507
+ value: "update",
2508
+ label: "Update alias",
2509
+ hint: "Change alias name or location"
2510
+ },
2511
+ {
2512
+ value: "remove",
2513
+ label: "Remove alias",
2514
+ hint: "Delete the existing alias"
2515
+ },
2516
+ {
2517
+ value: "keep",
2518
+ label: "Keep current alias",
2519
+ hint: "No changes"
2520
+ }
2521
+ ]
2522
+ });
2523
+ if (p8.isCancel(updateChoice) || updateChoice === "keep") {
2524
+ p8.outro(pc8.dim("No changes made"));
2525
+ return;
2526
+ }
2527
+ if (updateChoice === "remove") {
2528
+ const removed = removeAlias(existingAlias.aliasName);
2529
+ if (removed) {
2530
+ console.log();
2531
+ printSuccess(`Alias ${highlight(existingAlias.aliasName)} removed`);
2532
+ console.log();
2533
+ p8.outro(pc8.green("\u2728 Done!"));
2534
+ } else {
2535
+ printWarning(`Could not remove alias ${existingAlias.aliasName}`);
2536
+ p8.outro(pc8.yellow("Check file permissions"));
2537
+ }
2538
+ return;
2539
+ }
2540
+ removeAlias(existingAlias.aliasName);
2541
+ }
2542
+ const aliasConfig = await promptAliasCreation(
2543
+ instanceName,
2544
+ providedAlias,
2545
+ providedLocation,
2546
+ true
2547
+ );
2548
+ if (!aliasConfig) {
2549
+ p8.outro(pc8.dim("Alias creation cancelled"));
2550
+ return;
2551
+ }
2552
+ const success = await handleAliasCreation(instanceName, aliasConfig.aliasName, aliasConfig.location);
2553
+ if (success) {
2554
+ console.log();
2555
+ p8.outro(pc8.green("\u2728 Done!"));
2556
+ } else {
2557
+ p8.outro(pc8.yellow("Alias creation failed"));
2558
+ }
2559
+ }
2085
2560
  var instanceCommand = defineCommand6({
2086
2561
  meta: {
2087
2562
  name: "instance",
@@ -2091,7 +2566,7 @@ var instanceCommand = defineCommand6({
2091
2566
  action: {
2092
2567
  type: "string",
2093
2568
  alias: "a",
2094
- description: "Action: 'create', 'reinstall', or 'remove'"
2569
+ description: "Action: 'create', 'reinstall', 'remove', or 'alias'"
2095
2570
  },
2096
2571
  name: {
2097
2572
  type: "string",
@@ -2103,6 +2578,20 @@ var instanceCommand = defineCommand6({
2103
2578
  alias: "l",
2104
2579
  description: "List existing Cursor instances",
2105
2580
  default: false
2581
+ },
2582
+ alias: {
2583
+ type: "string",
2584
+ alias: "A",
2585
+ description: "Shell alias name for the instance (e.g. 'cursor-work')"
2586
+ },
2587
+ aliasLocation: {
2588
+ type: "string",
2589
+ description: "Alias storage location: 'shell-config', 'usr-local-bin', or 'home-bin'"
2590
+ },
2591
+ skipAlias: {
2592
+ type: "boolean",
2593
+ description: "Skip alias creation prompt",
2594
+ default: false
2106
2595
  }
2107
2596
  },
2108
2597
  async run({ args }) {
@@ -2126,7 +2615,8 @@ var instanceCommand = defineCommand6({
2126
2615
  console.log(pc8.bold(pc8.cyan(" \u{1F5A5} Cursor Instances")) + pc8.dim(` (${instances.length})`));
2127
2616
  console.log();
2128
2617
  for (const instance of instances) {
2129
- console.log(` ${pc8.green("\u25CF")} ${highlight(instance.name)}`);
2618
+ const aliasInfo = instance.alias ? pc8.dim(` (alias: ${pc8.cyan(instance.alias)})`) : "";
2619
+ console.log(` ${pc8.green("\u25CF")} ${highlight(instance.name)}${aliasInfo}`);
2130
2620
  console.log(pc8.dim(` \u2514\u2500 ${instance.path}`));
2131
2621
  }
2132
2622
  }
@@ -2135,13 +2625,55 @@ var instanceCommand = defineCommand6({
2135
2625
  p8.outro(pc8.dim(`Total: ${instances.length} instance${instances.length !== 1 ? "s" : ""}`));
2136
2626
  return;
2137
2627
  }
2628
+ const existingInstances = getExistingInstances();
2629
+ if (args.action === "alias") {
2630
+ if (existingInstances.length === 0) {
2631
+ console.log();
2632
+ printInfo("No custom Cursor instances found.");
2633
+ console.log(pc8.dim(" Create an instance first with: ") + highlight("cursor-kit instance -a create"));
2634
+ console.log();
2635
+ p8.outro(pc8.dim("Nothing to do"));
2636
+ return;
2637
+ }
2638
+ let instanceName2;
2639
+ if (args.name) {
2640
+ const found = existingInstances.find((i) => i.name === args.name);
2641
+ if (!found) {
2642
+ printWarning(`Instance "${args.name}" not found.`);
2643
+ console.log(pc8.dim(" Available instances:"));
2644
+ for (const inst of existingInstances) {
2645
+ console.log(pc8.dim(` \u2022 ${inst.name}`));
2646
+ }
2647
+ console.log();
2648
+ p8.outro(pc8.dim("Nothing to do"));
2649
+ return;
2650
+ }
2651
+ instanceName2 = args.name;
2652
+ } else {
2653
+ const instanceResult = await p8.select({
2654
+ message: "Select instance to manage alias:",
2655
+ options: existingInstances.map((inst) => ({
2656
+ value: inst.name,
2657
+ label: inst.alias ? `${inst.name} (alias: ${inst.alias})` : inst.name,
2658
+ hint: inst.alias ? "Has alias" : "No alias"
2659
+ }))
2660
+ });
2661
+ if (p8.isCancel(instanceResult)) {
2662
+ p8.cancel("Operation cancelled");
2663
+ process.exit(0);
2664
+ }
2665
+ instanceName2 = instanceResult;
2666
+ }
2667
+ await handleAliasAction(instanceName2, args.alias, args.aliasLocation);
2668
+ return;
2669
+ }
2138
2670
  const s = p8.spinner();
2139
2671
  s.start("Checking prerequisites...");
2140
2672
  const binPath = getBinPath();
2141
- const createScript = join9(binPath, "cursor-new-instance");
2142
- const removeScript = join9(binPath, "cursor-remove-instance");
2143
- const reinstallScript = join9(binPath, "cursor-reinstall-instance.sh");
2144
- const scriptsExist = existsSync2(createScript) && existsSync2(removeScript) && existsSync2(reinstallScript);
2673
+ const createScript = join10(binPath, "cursor-new-instance");
2674
+ const removeScript = join10(binPath, "cursor-remove-instance");
2675
+ const reinstallScript = join10(binPath, "cursor-reinstall-instance.sh");
2676
+ const scriptsExist = existsSync3(createScript) && existsSync3(removeScript) && existsSync3(reinstallScript);
2145
2677
  if (!scriptsExist) {
2146
2678
  s.stop("Prerequisites check failed");
2147
2679
  console.log();
@@ -2152,7 +2684,7 @@ var instanceCommand = defineCommand6({
2152
2684
  process.exit(1);
2153
2685
  }
2154
2686
  const originalCursor = "/Applications/Cursor.app";
2155
- if (!existsSync2(originalCursor)) {
2687
+ if (!existsSync3(originalCursor)) {
2156
2688
  s.stop("Prerequisites check failed");
2157
2689
  console.log();
2158
2690
  printWarning("Cursor.app not found in /Applications");
@@ -2162,7 +2694,6 @@ var instanceCommand = defineCommand6({
2162
2694
  process.exit(1);
2163
2695
  }
2164
2696
  s.stop("Prerequisites verified");
2165
- const existingInstances = getExistingInstances();
2166
2697
  let action;
2167
2698
  let instanceName;
2168
2699
  if (args.action && ["create", "remove", "reinstall"].includes(args.action)) {
@@ -2176,6 +2707,11 @@ var instanceCommand = defineCommand6({
2176
2707
  label: "Create new instance",
2177
2708
  hint: "Clone Cursor with separate identity"
2178
2709
  },
2710
+ {
2711
+ value: "alias",
2712
+ label: "Manage alias",
2713
+ hint: existingInstances.length > 0 ? "Add or update shell alias for instance" : "No instances available"
2714
+ },
2179
2715
  {
2180
2716
  value: "reinstall",
2181
2717
  label: "Reinstall instance",
@@ -2193,6 +2729,30 @@ var instanceCommand = defineCommand6({
2193
2729
  process.exit(0);
2194
2730
  }
2195
2731
  action = actionResult;
2732
+ if (action === "alias") {
2733
+ if (existingInstances.length === 0) {
2734
+ console.log();
2735
+ printInfo("No custom Cursor instances found.");
2736
+ console.log(pc8.dim(" Create an instance first."));
2737
+ console.log();
2738
+ p8.outro(pc8.dim("Nothing to do"));
2739
+ return;
2740
+ }
2741
+ const instanceResult = await p8.select({
2742
+ message: "Select instance to manage alias:",
2743
+ options: existingInstances.map((inst) => ({
2744
+ value: inst.name,
2745
+ label: inst.alias ? `${inst.name} (alias: ${inst.alias})` : inst.name,
2746
+ hint: inst.alias ? "Has alias" : "No alias"
2747
+ }))
2748
+ });
2749
+ if (p8.isCancel(instanceResult)) {
2750
+ p8.cancel("Operation cancelled");
2751
+ process.exit(0);
2752
+ }
2753
+ await handleAliasAction(instanceResult, args.alias, args.aliasLocation);
2754
+ return;
2755
+ }
2196
2756
  }
2197
2757
  if (args.name) {
2198
2758
  instanceName = args.name;
@@ -2202,7 +2762,7 @@ var instanceCommand = defineCommand6({
2202
2762
  message: `Select instance to ${actionLabel2}:`,
2203
2763
  options: existingInstances.map((inst) => ({
2204
2764
  value: inst.name,
2205
- label: inst.name,
2765
+ label: inst.alias ? `${inst.name} (alias: ${inst.alias})` : inst.name,
2206
2766
  hint: inst.path
2207
2767
  }))
2208
2768
  });
@@ -2250,12 +2810,16 @@ var instanceCommand = defineCommand6({
2250
2810
  console.log(` ${pc8.dim("Bundle ID:")} ${pc8.dim("com.cursor.")}${highlight(slug)}`);
2251
2811
  console.log(` ${pc8.dim("Location:")} ${pc8.dim("~/Applications/")}${highlight(instanceName + ".app")}`);
2252
2812
  if (action === "reinstall") {
2253
- const dataDir = join9(process.env.HOME ?? "", "Library", "Application Support", instanceName.replace(/ /g, ""));
2813
+ const dataDir = join10(process.env.HOME ?? "", "Library", "Application Support", instanceName.replace(/ /g, ""));
2254
2814
  console.log(` ${pc8.dim("Data:")} ${pc8.green("\u2713")} ${pc8.dim("Preserved at")} ${pc8.dim(dataDir)}`);
2255
2815
  }
2256
2816
  } else {
2257
- const targetPath = join9(process.env.HOME ?? "", "Applications", `${instanceName}.app`);
2817
+ const targetPath = join10(process.env.HOME ?? "", "Applications", `${instanceName}.app`);
2258
2818
  console.log(` ${pc8.dim("Path:")} ${pc8.dim(targetPath)}`);
2819
+ const aliasEntry = getAliasForInstance(instanceName);
2820
+ if (aliasEntry) {
2821
+ console.log(` ${pc8.dim("Alias:")} ${pc8.yellow(aliasEntry.aliasName)} ${pc8.dim("(will be removed)")}`);
2822
+ }
2259
2823
  }
2260
2824
  console.log();
2261
2825
  printDivider();
@@ -2280,6 +2844,20 @@ var instanceCommand = defineCommand6({
2280
2844
  if (exitCode === 0) {
2281
2845
  if (action === "create") {
2282
2846
  printSuccess(`Instance ${highlight(instanceName)} created successfully!`);
2847
+ if (!args.skipAlias) {
2848
+ console.log();
2849
+ const aliasConfig = await promptAliasCreation(
2850
+ instanceName,
2851
+ args.alias,
2852
+ args.aliasLocation
2853
+ );
2854
+ if (aliasConfig) {
2855
+ await handleAliasCreation(instanceName, aliasConfig.aliasName, aliasConfig.location);
2856
+ }
2857
+ } else if (args.alias) {
2858
+ const location = args.aliasLocation ?? "shell-config";
2859
+ await handleAliasCreation(instanceName, args.alias, location);
2860
+ }
2283
2861
  console.log();
2284
2862
  console.log(pc8.dim(" Next steps:"));
2285
2863
  console.log(pc8.dim(" \u2022 The new instance should launch automatically"));
@@ -2293,6 +2871,7 @@ var instanceCommand = defineCommand6({
2293
2871
  console.log(pc8.dim(" \u2022 Relaunched with your preserved data"));
2294
2872
  console.log(pc8.dim(" \u2022 Ready to use with your existing account"));
2295
2873
  } else {
2874
+ await handleAliasRemoval(instanceName);
2296
2875
  printSuccess(`Instance ${highlight(instanceName)} removed successfully!`);
2297
2876
  }
2298
2877
  console.log();