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/README.md +86 -5
- package/dist/cli.cjs +597 -26
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +604 -25
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -1562,8 +1562,8 @@ async function convertPulledFilesForTarget(target, directories) {
|
|
|
1562
1562
|
const skillPath = (0, import_node_path6.join)(skillsDir, skillDir);
|
|
1563
1563
|
const skillMdPath = (0, import_node_path6.join)(skillPath, "SKILL.md");
|
|
1564
1564
|
const skillMdcPath = (0, import_node_path6.join)(skillPath, "SKILL.mdc");
|
|
1565
|
-
const { existsSync:
|
|
1566
|
-
if (
|
|
1565
|
+
const { existsSync: existsSync4 } = await import("fs");
|
|
1566
|
+
if (existsSync4(skillMdPath)) {
|
|
1567
1567
|
const content = readFile(skillMdPath);
|
|
1568
1568
|
writeFile(skillMdcPath, content);
|
|
1569
1569
|
const { rmSync: rmSync2 } = await import("fs");
|
|
@@ -2060,17 +2060,305 @@ var import_citty6 = require("citty");
|
|
|
2060
2060
|
var p8 = __toESM(require("@clack/prompts"), 1);
|
|
2061
2061
|
var import_picocolors8 = __toESM(require("picocolors"), 1);
|
|
2062
2062
|
var import_node_child_process = require("child_process");
|
|
2063
|
-
var
|
|
2063
|
+
var import_node_path10 = require("path");
|
|
2064
2064
|
var import_node_url2 = require("url");
|
|
2065
|
+
var import_node_fs3 = require("fs");
|
|
2066
|
+
|
|
2067
|
+
// src/utils/alias.ts
|
|
2065
2068
|
var import_node_fs2 = require("fs");
|
|
2069
|
+
var import_node_os = require("os");
|
|
2070
|
+
var import_node_path9 = require("path");
|
|
2071
|
+
var CURSOR_KIT_DIR = ".cursor-kit";
|
|
2072
|
+
var ALIASES_FILE = "aliases.json";
|
|
2073
|
+
function getAliasConfigDir() {
|
|
2074
|
+
return (0, import_node_path9.join)((0, import_node_os.homedir)(), CURSOR_KIT_DIR);
|
|
2075
|
+
}
|
|
2076
|
+
function getAliasConfigPath() {
|
|
2077
|
+
return (0, import_node_path9.join)(getAliasConfigDir(), ALIASES_FILE);
|
|
2078
|
+
}
|
|
2079
|
+
function ensureConfigDir() {
|
|
2080
|
+
const configDir = getAliasConfigDir();
|
|
2081
|
+
if (!(0, import_node_fs2.existsSync)(configDir)) {
|
|
2082
|
+
(0, import_node_fs2.mkdirSync)(configDir, { recursive: true });
|
|
2083
|
+
}
|
|
2084
|
+
}
|
|
2085
|
+
function loadAliasConfig() {
|
|
2086
|
+
const configPath = getAliasConfigPath();
|
|
2087
|
+
if (!(0, import_node_fs2.existsSync)(configPath)) {
|
|
2088
|
+
return { aliases: {} };
|
|
2089
|
+
}
|
|
2090
|
+
try {
|
|
2091
|
+
const content = (0, import_node_fs2.readFileSync)(configPath, "utf-8");
|
|
2092
|
+
return JSON.parse(content);
|
|
2093
|
+
} catch {
|
|
2094
|
+
return { aliases: {} };
|
|
2095
|
+
}
|
|
2096
|
+
}
|
|
2097
|
+
function saveAliasConfig(config) {
|
|
2098
|
+
ensureConfigDir();
|
|
2099
|
+
const configPath = getAliasConfigPath();
|
|
2100
|
+
(0, import_node_fs2.writeFileSync)(configPath, JSON.stringify(config, null, 2), "utf-8");
|
|
2101
|
+
}
|
|
2102
|
+
function getInstanceDataDir(instanceName) {
|
|
2103
|
+
return (0, import_node_path9.join)(
|
|
2104
|
+
(0, import_node_os.homedir)(),
|
|
2105
|
+
"Library",
|
|
2106
|
+
"Application Support",
|
|
2107
|
+
instanceName.replace(/ /g, "")
|
|
2108
|
+
);
|
|
2109
|
+
}
|
|
2110
|
+
function getInstanceAppPath(instanceName) {
|
|
2111
|
+
return (0, import_node_path9.join)((0, import_node_os.homedir)(), "Applications", `${instanceName}.app`);
|
|
2112
|
+
}
|
|
2113
|
+
function generateScriptContent(instanceName) {
|
|
2114
|
+
const dataDir = getInstanceDataDir(instanceName);
|
|
2115
|
+
const appPath = getInstanceAppPath(instanceName);
|
|
2116
|
+
return `#!/usr/bin/env bash
|
|
2117
|
+
# Generated by cursor-kit for instance: ${instanceName}
|
|
2118
|
+
# This script opens the specified directory (or current directory) in the Cursor instance
|
|
2119
|
+
|
|
2120
|
+
set -euo pipefail
|
|
2121
|
+
|
|
2122
|
+
DIR="\${1:-.}"
|
|
2123
|
+
|
|
2124
|
+
# Resolve to absolute path if relative
|
|
2125
|
+
if [[ "$DIR" != /* ]]; then
|
|
2126
|
+
DIR="$(cd "$DIR" 2>/dev/null && pwd)"
|
|
2127
|
+
fi
|
|
2128
|
+
|
|
2129
|
+
DATA_DIR="${dataDir}"
|
|
2130
|
+
APP_PATH="${appPath}"
|
|
2131
|
+
|
|
2132
|
+
if [ ! -d "$APP_PATH" ]; then
|
|
2133
|
+
echo "Error: Cursor instance not found at $APP_PATH" >&2
|
|
2134
|
+
echo "The instance may have been removed. Run 'cursor-kit instance -l' to see available instances." >&2
|
|
2135
|
+
exit 1
|
|
2136
|
+
fi
|
|
2137
|
+
|
|
2138
|
+
open -n "$APP_PATH" --args --user-data-dir "$DATA_DIR" "$DIR"
|
|
2139
|
+
`;
|
|
2140
|
+
}
|
|
2141
|
+
function generateShellFunction(aliasName, instanceName) {
|
|
2142
|
+
const dataDir = getInstanceDataDir(instanceName);
|
|
2143
|
+
const appPath = getInstanceAppPath(instanceName);
|
|
2144
|
+
return `
|
|
2145
|
+
# cursor-kit alias: ${aliasName} -> ${instanceName}
|
|
2146
|
+
${aliasName}() {
|
|
2147
|
+
local DIR="\${1:-.}"
|
|
2148
|
+
if [[ "$DIR" != /* ]]; then
|
|
2149
|
+
DIR="$(cd "$DIR" 2>/dev/null && pwd)"
|
|
2150
|
+
fi
|
|
2151
|
+
local DATA_DIR="${dataDir}"
|
|
2152
|
+
local APP_PATH="${appPath}"
|
|
2153
|
+
if [ ! -d "$APP_PATH" ]; then
|
|
2154
|
+
echo "Error: Cursor instance not found at $APP_PATH" >&2
|
|
2155
|
+
return 1
|
|
2156
|
+
fi
|
|
2157
|
+
open -n "$APP_PATH" --args --user-data-dir "$DATA_DIR" "$DIR"
|
|
2158
|
+
}
|
|
2159
|
+
# end cursor-kit alias: ${aliasName}
|
|
2160
|
+
`;
|
|
2161
|
+
}
|
|
2162
|
+
function detectShellConfigPath() {
|
|
2163
|
+
const home = (0, import_node_os.homedir)();
|
|
2164
|
+
const shell = process.env.SHELL ?? "/bin/zsh";
|
|
2165
|
+
if (shell.includes("zsh")) {
|
|
2166
|
+
return (0, import_node_path9.join)(home, ".zshrc");
|
|
2167
|
+
}
|
|
2168
|
+
if (shell.includes("bash")) {
|
|
2169
|
+
const bashProfile = (0, import_node_path9.join)(home, ".bash_profile");
|
|
2170
|
+
if ((0, import_node_fs2.existsSync)(bashProfile)) {
|
|
2171
|
+
return bashProfile;
|
|
2172
|
+
}
|
|
2173
|
+
return (0, import_node_path9.join)(home, ".bashrc");
|
|
2174
|
+
}
|
|
2175
|
+
return (0, import_node_path9.join)(home, ".zshrc");
|
|
2176
|
+
}
|
|
2177
|
+
function getHomeBinDir() {
|
|
2178
|
+
return (0, import_node_path9.join)((0, import_node_os.homedir)(), "bin");
|
|
2179
|
+
}
|
|
2180
|
+
function getUsrLocalBinDir() {
|
|
2181
|
+
return "/usr/local/bin";
|
|
2182
|
+
}
|
|
2183
|
+
function ensureBinDir(binDir) {
|
|
2184
|
+
if (!(0, import_node_fs2.existsSync)(binDir)) {
|
|
2185
|
+
(0, import_node_fs2.mkdirSync)(binDir, { recursive: true });
|
|
2186
|
+
}
|
|
2187
|
+
}
|
|
2188
|
+
function createExecutableScript(aliasName, instanceName, targetDir) {
|
|
2189
|
+
ensureBinDir(targetDir);
|
|
2190
|
+
const scriptPath = (0, import_node_path9.join)(targetDir, aliasName);
|
|
2191
|
+
const scriptContent = generateScriptContent(instanceName);
|
|
2192
|
+
(0, import_node_fs2.writeFileSync)(scriptPath, scriptContent, "utf-8");
|
|
2193
|
+
(0, import_node_fs2.chmodSync)(scriptPath, 493);
|
|
2194
|
+
return scriptPath;
|
|
2195
|
+
}
|
|
2196
|
+
function createShellAlias(aliasName, instanceName, shellConfigPath) {
|
|
2197
|
+
const functionContent = generateShellFunction(aliasName, instanceName);
|
|
2198
|
+
if (!(0, import_node_fs2.existsSync)(shellConfigPath)) {
|
|
2199
|
+
(0, import_node_fs2.writeFileSync)(shellConfigPath, "", "utf-8");
|
|
2200
|
+
}
|
|
2201
|
+
const existingContent = (0, import_node_fs2.readFileSync)(shellConfigPath, "utf-8");
|
|
2202
|
+
if (existingContent.includes(`# cursor-kit alias: ${aliasName}`)) {
|
|
2203
|
+
removeShellAlias(aliasName, shellConfigPath);
|
|
2204
|
+
}
|
|
2205
|
+
(0, import_node_fs2.appendFileSync)(shellConfigPath, functionContent, "utf-8");
|
|
2206
|
+
}
|
|
2207
|
+
function removeShellAlias(aliasName, shellConfigPath) {
|
|
2208
|
+
if (!(0, import_node_fs2.existsSync)(shellConfigPath)) {
|
|
2209
|
+
return false;
|
|
2210
|
+
}
|
|
2211
|
+
const content = (0, import_node_fs2.readFileSync)(shellConfigPath, "utf-8");
|
|
2212
|
+
const startMarker = `# cursor-kit alias: ${aliasName}`;
|
|
2213
|
+
const endMarker = `# end cursor-kit alias: ${aliasName}`;
|
|
2214
|
+
const startIndex = content.indexOf(startMarker);
|
|
2215
|
+
if (startIndex === -1) {
|
|
2216
|
+
return false;
|
|
2217
|
+
}
|
|
2218
|
+
const endIndex = content.indexOf(endMarker);
|
|
2219
|
+
if (endIndex === -1) {
|
|
2220
|
+
return false;
|
|
2221
|
+
}
|
|
2222
|
+
const before = content.slice(0, startIndex);
|
|
2223
|
+
const after = content.slice(endIndex + endMarker.length);
|
|
2224
|
+
const newContent = (before + after).replace(/\n{3,}/g, "\n\n");
|
|
2225
|
+
(0, import_node_fs2.writeFileSync)(shellConfigPath, newContent, "utf-8");
|
|
2226
|
+
return true;
|
|
2227
|
+
}
|
|
2228
|
+
function removeExecutableScript(scriptPath) {
|
|
2229
|
+
if (!(0, import_node_fs2.existsSync)(scriptPath)) {
|
|
2230
|
+
return false;
|
|
2231
|
+
}
|
|
2232
|
+
try {
|
|
2233
|
+
(0, import_node_fs2.unlinkSync)(scriptPath);
|
|
2234
|
+
return true;
|
|
2235
|
+
} catch {
|
|
2236
|
+
return false;
|
|
2237
|
+
}
|
|
2238
|
+
}
|
|
2239
|
+
function createAlias(options) {
|
|
2240
|
+
const { aliasName, instanceName, storageLocation } = options;
|
|
2241
|
+
try {
|
|
2242
|
+
let scriptPath;
|
|
2243
|
+
let shellConfigPath;
|
|
2244
|
+
switch (storageLocation) {
|
|
2245
|
+
case "shell-config": {
|
|
2246
|
+
shellConfigPath = detectShellConfigPath();
|
|
2247
|
+
createShellAlias(aliasName, instanceName, shellConfigPath);
|
|
2248
|
+
break;
|
|
2249
|
+
}
|
|
2250
|
+
case "usr-local-bin": {
|
|
2251
|
+
scriptPath = createExecutableScript(
|
|
2252
|
+
aliasName,
|
|
2253
|
+
instanceName,
|
|
2254
|
+
getUsrLocalBinDir()
|
|
2255
|
+
);
|
|
2256
|
+
break;
|
|
2257
|
+
}
|
|
2258
|
+
case "home-bin": {
|
|
2259
|
+
scriptPath = createExecutableScript(
|
|
2260
|
+
aliasName,
|
|
2261
|
+
instanceName,
|
|
2262
|
+
getHomeBinDir()
|
|
2263
|
+
);
|
|
2264
|
+
break;
|
|
2265
|
+
}
|
|
2266
|
+
}
|
|
2267
|
+
const config = loadAliasConfig();
|
|
2268
|
+
config.aliases[aliasName] = {
|
|
2269
|
+
instanceName,
|
|
2270
|
+
aliasName,
|
|
2271
|
+
storageLocation,
|
|
2272
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2273
|
+
scriptPath
|
|
2274
|
+
};
|
|
2275
|
+
saveAliasConfig(config);
|
|
2276
|
+
return { success: true, scriptPath, shellConfigPath };
|
|
2277
|
+
} catch (error) {
|
|
2278
|
+
return {
|
|
2279
|
+
success: false,
|
|
2280
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
2281
|
+
};
|
|
2282
|
+
}
|
|
2283
|
+
}
|
|
2284
|
+
function removeAlias(aliasName) {
|
|
2285
|
+
const config = loadAliasConfig();
|
|
2286
|
+
const entry = config.aliases[aliasName];
|
|
2287
|
+
if (!entry) {
|
|
2288
|
+
return false;
|
|
2289
|
+
}
|
|
2290
|
+
let removed = false;
|
|
2291
|
+
switch (entry.storageLocation) {
|
|
2292
|
+
case "shell-config": {
|
|
2293
|
+
const shellConfigPath = detectShellConfigPath();
|
|
2294
|
+
removed = removeShellAlias(aliasName, shellConfigPath);
|
|
2295
|
+
break;
|
|
2296
|
+
}
|
|
2297
|
+
case "usr-local-bin": {
|
|
2298
|
+
const scriptPath = (0, import_node_path9.join)(getUsrLocalBinDir(), aliasName);
|
|
2299
|
+
removed = removeExecutableScript(scriptPath);
|
|
2300
|
+
break;
|
|
2301
|
+
}
|
|
2302
|
+
case "home-bin": {
|
|
2303
|
+
const scriptPath = (0, import_node_path9.join)(getHomeBinDir(), aliasName);
|
|
2304
|
+
removed = removeExecutableScript(scriptPath);
|
|
2305
|
+
break;
|
|
2306
|
+
}
|
|
2307
|
+
}
|
|
2308
|
+
delete config.aliases[aliasName];
|
|
2309
|
+
saveAliasConfig(config);
|
|
2310
|
+
return removed;
|
|
2311
|
+
}
|
|
2312
|
+
function getAliasForInstance(instanceName) {
|
|
2313
|
+
const config = loadAliasConfig();
|
|
2314
|
+
for (const entry of Object.values(config.aliases)) {
|
|
2315
|
+
if (entry.instanceName === instanceName) {
|
|
2316
|
+
return entry;
|
|
2317
|
+
}
|
|
2318
|
+
}
|
|
2319
|
+
return null;
|
|
2320
|
+
}
|
|
2321
|
+
function aliasExists(aliasName) {
|
|
2322
|
+
const config = loadAliasConfig();
|
|
2323
|
+
return aliasName in config.aliases;
|
|
2324
|
+
}
|
|
2325
|
+
function generateAliasName(instanceName) {
|
|
2326
|
+
return instanceName.toLowerCase().replace(/^cursor\s*/i, "cursor-").replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
2327
|
+
}
|
|
2328
|
+
function getStorageLocationLabel(location) {
|
|
2329
|
+
switch (location) {
|
|
2330
|
+
case "shell-config":
|
|
2331
|
+
return "Shell config (~/.zshrc or ~/.bashrc)";
|
|
2332
|
+
case "usr-local-bin":
|
|
2333
|
+
return "/usr/local/bin (system-wide)";
|
|
2334
|
+
case "home-bin":
|
|
2335
|
+
return "~/bin (user-local)";
|
|
2336
|
+
}
|
|
2337
|
+
}
|
|
2338
|
+
function isHomeBinInPath() {
|
|
2339
|
+
const pathEnv = process.env.PATH ?? "";
|
|
2340
|
+
const homeBin = getHomeBinDir();
|
|
2341
|
+
return pathEnv.split(":").some((p9) => p9 === homeBin || p9 === "~/bin" || p9 === "$HOME/bin");
|
|
2342
|
+
}
|
|
2343
|
+
function getPathSetupInstructions() {
|
|
2344
|
+
const shell = process.env.SHELL ?? "/bin/zsh";
|
|
2345
|
+
const configFile = shell.includes("zsh") ? "~/.zshrc" : "~/.bashrc";
|
|
2346
|
+
return `Add the following to your ${configFile}:
|
|
2347
|
+
|
|
2348
|
+
export PATH="$HOME/bin:$PATH"
|
|
2349
|
+
|
|
2350
|
+
Then restart your terminal or run: source ${configFile}`;
|
|
2351
|
+
}
|
|
2352
|
+
|
|
2353
|
+
// src/commands/instance.ts
|
|
2066
2354
|
function getBinPath() {
|
|
2067
|
-
const currentDir = (0,
|
|
2355
|
+
const currentDir = (0, import_node_path10.dirname)((0, import_node_url2.fileURLToPath)(importMetaUrl));
|
|
2068
2356
|
const possiblePaths = [
|
|
2069
|
-
(0,
|
|
2070
|
-
(0,
|
|
2357
|
+
(0, import_node_path10.join)(currentDir, "..", "..", "bin"),
|
|
2358
|
+
(0, import_node_path10.join)(currentDir, "..", "bin")
|
|
2071
2359
|
];
|
|
2072
2360
|
for (const binPath of possiblePaths) {
|
|
2073
|
-
if ((0,
|
|
2361
|
+
if ((0, import_node_fs3.existsSync)(binPath)) {
|
|
2074
2362
|
return binPath;
|
|
2075
2363
|
}
|
|
2076
2364
|
}
|
|
@@ -2078,19 +2366,24 @@ function getBinPath() {
|
|
|
2078
2366
|
}
|
|
2079
2367
|
function ensureExecutable(scriptPath) {
|
|
2080
2368
|
try {
|
|
2081
|
-
(0,
|
|
2369
|
+
(0, import_node_fs3.chmodSync)(scriptPath, 493);
|
|
2082
2370
|
} catch {
|
|
2083
2371
|
}
|
|
2084
2372
|
}
|
|
2085
2373
|
function getExistingInstances() {
|
|
2086
|
-
const userAppsDir = (0,
|
|
2087
|
-
if (!(0,
|
|
2374
|
+
const userAppsDir = (0, import_node_path10.join)(process.env.HOME ?? "", "Applications");
|
|
2375
|
+
if (!(0, import_node_fs3.existsSync)(userAppsDir)) return [];
|
|
2088
2376
|
try {
|
|
2089
|
-
const apps = (0,
|
|
2090
|
-
return apps.filter((app) => app.startsWith("Cursor") && app.endsWith(".app") && app !== "Cursor.app").map((app) =>
|
|
2091
|
-
name
|
|
2092
|
-
|
|
2093
|
-
|
|
2377
|
+
const apps = (0, import_node_fs3.readdirSync)(userAppsDir);
|
|
2378
|
+
return apps.filter((app) => app.startsWith("Cursor") && app.endsWith(".app") && app !== "Cursor.app").map((app) => {
|
|
2379
|
+
const name = app.replace(".app", "");
|
|
2380
|
+
const aliasEntry = getAliasForInstance(name);
|
|
2381
|
+
return {
|
|
2382
|
+
name,
|
|
2383
|
+
path: (0, import_node_path10.join)(userAppsDir, app),
|
|
2384
|
+
alias: aliasEntry?.aliasName
|
|
2385
|
+
};
|
|
2386
|
+
});
|
|
2094
2387
|
} catch {
|
|
2095
2388
|
return [];
|
|
2096
2389
|
}
|
|
@@ -2109,6 +2402,180 @@ function runScript(scriptPath, args) {
|
|
|
2109
2402
|
});
|
|
2110
2403
|
});
|
|
2111
2404
|
}
|
|
2405
|
+
async function promptAliasCreation(instanceName, providedAlias, providedLocation, skipConfirmation) {
|
|
2406
|
+
if (!skipConfirmation) {
|
|
2407
|
+
const shouldCreateAlias = await p8.confirm({
|
|
2408
|
+
message: "Would you like to create a shell alias for this instance?",
|
|
2409
|
+
initialValue: true
|
|
2410
|
+
});
|
|
2411
|
+
if (p8.isCancel(shouldCreateAlias) || !shouldCreateAlias) {
|
|
2412
|
+
return null;
|
|
2413
|
+
}
|
|
2414
|
+
}
|
|
2415
|
+
let aliasName;
|
|
2416
|
+
const suggestedAlias = generateAliasName(instanceName);
|
|
2417
|
+
if (providedAlias) {
|
|
2418
|
+
aliasName = providedAlias;
|
|
2419
|
+
} else {
|
|
2420
|
+
const aliasResult = await p8.text({
|
|
2421
|
+
message: "Enter alias name:",
|
|
2422
|
+
placeholder: suggestedAlias,
|
|
2423
|
+
initialValue: suggestedAlias,
|
|
2424
|
+
validate: (value) => {
|
|
2425
|
+
if (!value.trim()) return "Alias name is required";
|
|
2426
|
+
if (!/^[a-z0-9-]+$/.test(value)) return "Alias must contain only lowercase letters, numbers, and hyphens";
|
|
2427
|
+
if (aliasExists(value)) return `Alias "${value}" already exists`;
|
|
2428
|
+
return void 0;
|
|
2429
|
+
}
|
|
2430
|
+
});
|
|
2431
|
+
if (p8.isCancel(aliasResult)) {
|
|
2432
|
+
return null;
|
|
2433
|
+
}
|
|
2434
|
+
aliasName = aliasResult;
|
|
2435
|
+
}
|
|
2436
|
+
let location;
|
|
2437
|
+
if (providedLocation && ["shell-config", "usr-local-bin", "home-bin"].includes(providedLocation)) {
|
|
2438
|
+
location = providedLocation;
|
|
2439
|
+
} else {
|
|
2440
|
+
const locationResult = await p8.select({
|
|
2441
|
+
message: "Where should the alias be stored?",
|
|
2442
|
+
options: [
|
|
2443
|
+
{
|
|
2444
|
+
value: "shell-config",
|
|
2445
|
+
label: "Shell config",
|
|
2446
|
+
hint: detectShellConfigPath()
|
|
2447
|
+
},
|
|
2448
|
+
{
|
|
2449
|
+
value: "home-bin",
|
|
2450
|
+
label: "~/bin",
|
|
2451
|
+
hint: "User-local executable scripts"
|
|
2452
|
+
},
|
|
2453
|
+
{
|
|
2454
|
+
value: "usr-local-bin",
|
|
2455
|
+
label: "/usr/local/bin",
|
|
2456
|
+
hint: "System-wide (may require sudo)"
|
|
2457
|
+
}
|
|
2458
|
+
]
|
|
2459
|
+
});
|
|
2460
|
+
if (p8.isCancel(locationResult)) {
|
|
2461
|
+
return null;
|
|
2462
|
+
}
|
|
2463
|
+
location = locationResult;
|
|
2464
|
+
}
|
|
2465
|
+
return { aliasName, location };
|
|
2466
|
+
}
|
|
2467
|
+
async function handleAliasCreation(instanceName, aliasName, location) {
|
|
2468
|
+
const result = createAlias({
|
|
2469
|
+
aliasName,
|
|
2470
|
+
instanceName,
|
|
2471
|
+
storageLocation: location
|
|
2472
|
+
});
|
|
2473
|
+
if (!result.success) {
|
|
2474
|
+
printWarning(`Failed to create alias: ${result.error}`);
|
|
2475
|
+
return false;
|
|
2476
|
+
}
|
|
2477
|
+
console.log();
|
|
2478
|
+
printSuccess(`Alias ${highlight(aliasName)} created!`);
|
|
2479
|
+
console.log(import_picocolors8.default.dim(` \u2514\u2500 Location: ${getStorageLocationLabel(location)}`));
|
|
2480
|
+
if (location === "home-bin" && !isHomeBinInPath()) {
|
|
2481
|
+
console.log();
|
|
2482
|
+
printWarning("~/bin is not in your PATH");
|
|
2483
|
+
console.log(import_picocolors8.default.dim(getPathSetupInstructions()));
|
|
2484
|
+
}
|
|
2485
|
+
if (location === "shell-config") {
|
|
2486
|
+
console.log();
|
|
2487
|
+
console.log(import_picocolors8.default.dim(" Restart your terminal or run:"));
|
|
2488
|
+
console.log(import_picocolors8.default.dim(` source ${detectShellConfigPath()}`));
|
|
2489
|
+
}
|
|
2490
|
+
console.log();
|
|
2491
|
+
console.log(import_picocolors8.default.dim(" Usage:"));
|
|
2492
|
+
console.log(import_picocolors8.default.dim(` ${aliasName} . # Open current directory`));
|
|
2493
|
+
console.log(import_picocolors8.default.dim(` ${aliasName} /path/to/dir # Open specific directory`));
|
|
2494
|
+
return true;
|
|
2495
|
+
}
|
|
2496
|
+
async function handleAliasRemoval(instanceName) {
|
|
2497
|
+
const aliasEntry = getAliasForInstance(instanceName);
|
|
2498
|
+
if (!aliasEntry) {
|
|
2499
|
+
return;
|
|
2500
|
+
}
|
|
2501
|
+
const shouldRemove = await p8.confirm({
|
|
2502
|
+
message: `Remove associated alias "${aliasEntry.aliasName}"?`,
|
|
2503
|
+
initialValue: true
|
|
2504
|
+
});
|
|
2505
|
+
if (p8.isCancel(shouldRemove) || !shouldRemove) {
|
|
2506
|
+
return;
|
|
2507
|
+
}
|
|
2508
|
+
const removed = removeAlias(aliasEntry.aliasName);
|
|
2509
|
+
if (removed) {
|
|
2510
|
+
printSuccess(`Alias ${highlight(aliasEntry.aliasName)} removed`);
|
|
2511
|
+
} else {
|
|
2512
|
+
printWarning(`Could not remove alias ${aliasEntry.aliasName}`);
|
|
2513
|
+
}
|
|
2514
|
+
}
|
|
2515
|
+
async function handleAliasAction(instanceName, providedAlias, providedLocation) {
|
|
2516
|
+
const existingAlias = getAliasForInstance(instanceName);
|
|
2517
|
+
if (existingAlias) {
|
|
2518
|
+
console.log();
|
|
2519
|
+
printInfo(`Instance ${highlight(instanceName)} already has alias: ${highlight(existingAlias.aliasName)}`);
|
|
2520
|
+
console.log(import_picocolors8.default.dim(` \u2514\u2500 Location: ${getStorageLocationLabel(existingAlias.storageLocation)}`));
|
|
2521
|
+
console.log();
|
|
2522
|
+
const updateChoice = await p8.select({
|
|
2523
|
+
message: "What would you like to do?",
|
|
2524
|
+
options: [
|
|
2525
|
+
{
|
|
2526
|
+
value: "update",
|
|
2527
|
+
label: "Update alias",
|
|
2528
|
+
hint: "Change alias name or location"
|
|
2529
|
+
},
|
|
2530
|
+
{
|
|
2531
|
+
value: "remove",
|
|
2532
|
+
label: "Remove alias",
|
|
2533
|
+
hint: "Delete the existing alias"
|
|
2534
|
+
},
|
|
2535
|
+
{
|
|
2536
|
+
value: "keep",
|
|
2537
|
+
label: "Keep current alias",
|
|
2538
|
+
hint: "No changes"
|
|
2539
|
+
}
|
|
2540
|
+
]
|
|
2541
|
+
});
|
|
2542
|
+
if (p8.isCancel(updateChoice) || updateChoice === "keep") {
|
|
2543
|
+
p8.outro(import_picocolors8.default.dim("No changes made"));
|
|
2544
|
+
return;
|
|
2545
|
+
}
|
|
2546
|
+
if (updateChoice === "remove") {
|
|
2547
|
+
const removed = removeAlias(existingAlias.aliasName);
|
|
2548
|
+
if (removed) {
|
|
2549
|
+
console.log();
|
|
2550
|
+
printSuccess(`Alias ${highlight(existingAlias.aliasName)} removed`);
|
|
2551
|
+
console.log();
|
|
2552
|
+
p8.outro(import_picocolors8.default.green("\u2728 Done!"));
|
|
2553
|
+
} else {
|
|
2554
|
+
printWarning(`Could not remove alias ${existingAlias.aliasName}`);
|
|
2555
|
+
p8.outro(import_picocolors8.default.yellow("Check file permissions"));
|
|
2556
|
+
}
|
|
2557
|
+
return;
|
|
2558
|
+
}
|
|
2559
|
+
removeAlias(existingAlias.aliasName);
|
|
2560
|
+
}
|
|
2561
|
+
const aliasConfig = await promptAliasCreation(
|
|
2562
|
+
instanceName,
|
|
2563
|
+
providedAlias,
|
|
2564
|
+
providedLocation,
|
|
2565
|
+
true
|
|
2566
|
+
);
|
|
2567
|
+
if (!aliasConfig) {
|
|
2568
|
+
p8.outro(import_picocolors8.default.dim("Alias creation cancelled"));
|
|
2569
|
+
return;
|
|
2570
|
+
}
|
|
2571
|
+
const success = await handleAliasCreation(instanceName, aliasConfig.aliasName, aliasConfig.location);
|
|
2572
|
+
if (success) {
|
|
2573
|
+
console.log();
|
|
2574
|
+
p8.outro(import_picocolors8.default.green("\u2728 Done!"));
|
|
2575
|
+
} else {
|
|
2576
|
+
p8.outro(import_picocolors8.default.yellow("Alias creation failed"));
|
|
2577
|
+
}
|
|
2578
|
+
}
|
|
2112
2579
|
var instanceCommand = (0, import_citty6.defineCommand)({
|
|
2113
2580
|
meta: {
|
|
2114
2581
|
name: "instance",
|
|
@@ -2118,7 +2585,7 @@ var instanceCommand = (0, import_citty6.defineCommand)({
|
|
|
2118
2585
|
action: {
|
|
2119
2586
|
type: "string",
|
|
2120
2587
|
alias: "a",
|
|
2121
|
-
description: "Action: 'create', 'reinstall', or '
|
|
2588
|
+
description: "Action: 'create', 'reinstall', 'remove', or 'alias'"
|
|
2122
2589
|
},
|
|
2123
2590
|
name: {
|
|
2124
2591
|
type: "string",
|
|
@@ -2130,6 +2597,20 @@ var instanceCommand = (0, import_citty6.defineCommand)({
|
|
|
2130
2597
|
alias: "l",
|
|
2131
2598
|
description: "List existing Cursor instances",
|
|
2132
2599
|
default: false
|
|
2600
|
+
},
|
|
2601
|
+
alias: {
|
|
2602
|
+
type: "string",
|
|
2603
|
+
alias: "A",
|
|
2604
|
+
description: "Shell alias name for the instance (e.g. 'cursor-work')"
|
|
2605
|
+
},
|
|
2606
|
+
aliasLocation: {
|
|
2607
|
+
type: "string",
|
|
2608
|
+
description: "Alias storage location: 'shell-config', 'usr-local-bin', or 'home-bin'"
|
|
2609
|
+
},
|
|
2610
|
+
skipAlias: {
|
|
2611
|
+
type: "boolean",
|
|
2612
|
+
description: "Skip alias creation prompt",
|
|
2613
|
+
default: false
|
|
2133
2614
|
}
|
|
2134
2615
|
},
|
|
2135
2616
|
async run({ args }) {
|
|
@@ -2153,7 +2634,8 @@ var instanceCommand = (0, import_citty6.defineCommand)({
|
|
|
2153
2634
|
console.log(import_picocolors8.default.bold(import_picocolors8.default.cyan(" \u{1F5A5} Cursor Instances")) + import_picocolors8.default.dim(` (${instances.length})`));
|
|
2154
2635
|
console.log();
|
|
2155
2636
|
for (const instance of instances) {
|
|
2156
|
-
|
|
2637
|
+
const aliasInfo = instance.alias ? import_picocolors8.default.dim(` (alias: ${import_picocolors8.default.cyan(instance.alias)})`) : "";
|
|
2638
|
+
console.log(` ${import_picocolors8.default.green("\u25CF")} ${highlight(instance.name)}${aliasInfo}`);
|
|
2157
2639
|
console.log(import_picocolors8.default.dim(` \u2514\u2500 ${instance.path}`));
|
|
2158
2640
|
}
|
|
2159
2641
|
}
|
|
@@ -2162,13 +2644,55 @@ var instanceCommand = (0, import_citty6.defineCommand)({
|
|
|
2162
2644
|
p8.outro(import_picocolors8.default.dim(`Total: ${instances.length} instance${instances.length !== 1 ? "s" : ""}`));
|
|
2163
2645
|
return;
|
|
2164
2646
|
}
|
|
2647
|
+
const existingInstances = getExistingInstances();
|
|
2648
|
+
if (args.action === "alias") {
|
|
2649
|
+
if (existingInstances.length === 0) {
|
|
2650
|
+
console.log();
|
|
2651
|
+
printInfo("No custom Cursor instances found.");
|
|
2652
|
+
console.log(import_picocolors8.default.dim(" Create an instance first with: ") + highlight("cursor-kit instance -a create"));
|
|
2653
|
+
console.log();
|
|
2654
|
+
p8.outro(import_picocolors8.default.dim("Nothing to do"));
|
|
2655
|
+
return;
|
|
2656
|
+
}
|
|
2657
|
+
let instanceName2;
|
|
2658
|
+
if (args.name) {
|
|
2659
|
+
const found = existingInstances.find((i) => i.name === args.name);
|
|
2660
|
+
if (!found) {
|
|
2661
|
+
printWarning(`Instance "${args.name}" not found.`);
|
|
2662
|
+
console.log(import_picocolors8.default.dim(" Available instances:"));
|
|
2663
|
+
for (const inst of existingInstances) {
|
|
2664
|
+
console.log(import_picocolors8.default.dim(` \u2022 ${inst.name}`));
|
|
2665
|
+
}
|
|
2666
|
+
console.log();
|
|
2667
|
+
p8.outro(import_picocolors8.default.dim("Nothing to do"));
|
|
2668
|
+
return;
|
|
2669
|
+
}
|
|
2670
|
+
instanceName2 = args.name;
|
|
2671
|
+
} else {
|
|
2672
|
+
const instanceResult = await p8.select({
|
|
2673
|
+
message: "Select instance to manage alias:",
|
|
2674
|
+
options: existingInstances.map((inst) => ({
|
|
2675
|
+
value: inst.name,
|
|
2676
|
+
label: inst.alias ? `${inst.name} (alias: ${inst.alias})` : inst.name,
|
|
2677
|
+
hint: inst.alias ? "Has alias" : "No alias"
|
|
2678
|
+
}))
|
|
2679
|
+
});
|
|
2680
|
+
if (p8.isCancel(instanceResult)) {
|
|
2681
|
+
p8.cancel("Operation cancelled");
|
|
2682
|
+
process.exit(0);
|
|
2683
|
+
}
|
|
2684
|
+
instanceName2 = instanceResult;
|
|
2685
|
+
}
|
|
2686
|
+
await handleAliasAction(instanceName2, args.alias, args.aliasLocation);
|
|
2687
|
+
return;
|
|
2688
|
+
}
|
|
2165
2689
|
const s = p8.spinner();
|
|
2166
2690
|
s.start("Checking prerequisites...");
|
|
2167
2691
|
const binPath = getBinPath();
|
|
2168
|
-
const createScript = (0,
|
|
2169
|
-
const removeScript = (0,
|
|
2170
|
-
const reinstallScript = (0,
|
|
2171
|
-
const scriptsExist = (0,
|
|
2692
|
+
const createScript = (0, import_node_path10.join)(binPath, "cursor-new-instance");
|
|
2693
|
+
const removeScript = (0, import_node_path10.join)(binPath, "cursor-remove-instance");
|
|
2694
|
+
const reinstallScript = (0, import_node_path10.join)(binPath, "cursor-reinstall-instance.sh");
|
|
2695
|
+
const scriptsExist = (0, import_node_fs3.existsSync)(createScript) && (0, import_node_fs3.existsSync)(removeScript) && (0, import_node_fs3.existsSync)(reinstallScript);
|
|
2172
2696
|
if (!scriptsExist) {
|
|
2173
2697
|
s.stop("Prerequisites check failed");
|
|
2174
2698
|
console.log();
|
|
@@ -2179,7 +2703,7 @@ var instanceCommand = (0, import_citty6.defineCommand)({
|
|
|
2179
2703
|
process.exit(1);
|
|
2180
2704
|
}
|
|
2181
2705
|
const originalCursor = "/Applications/Cursor.app";
|
|
2182
|
-
if (!(0,
|
|
2706
|
+
if (!(0, import_node_fs3.existsSync)(originalCursor)) {
|
|
2183
2707
|
s.stop("Prerequisites check failed");
|
|
2184
2708
|
console.log();
|
|
2185
2709
|
printWarning("Cursor.app not found in /Applications");
|
|
@@ -2189,7 +2713,6 @@ var instanceCommand = (0, import_citty6.defineCommand)({
|
|
|
2189
2713
|
process.exit(1);
|
|
2190
2714
|
}
|
|
2191
2715
|
s.stop("Prerequisites verified");
|
|
2192
|
-
const existingInstances = getExistingInstances();
|
|
2193
2716
|
let action;
|
|
2194
2717
|
let instanceName;
|
|
2195
2718
|
if (args.action && ["create", "remove", "reinstall"].includes(args.action)) {
|
|
@@ -2203,6 +2726,11 @@ var instanceCommand = (0, import_citty6.defineCommand)({
|
|
|
2203
2726
|
label: "Create new instance",
|
|
2204
2727
|
hint: "Clone Cursor with separate identity"
|
|
2205
2728
|
},
|
|
2729
|
+
{
|
|
2730
|
+
value: "alias",
|
|
2731
|
+
label: "Manage alias",
|
|
2732
|
+
hint: existingInstances.length > 0 ? "Add or update shell alias for instance" : "No instances available"
|
|
2733
|
+
},
|
|
2206
2734
|
{
|
|
2207
2735
|
value: "reinstall",
|
|
2208
2736
|
label: "Reinstall instance",
|
|
@@ -2220,6 +2748,30 @@ var instanceCommand = (0, import_citty6.defineCommand)({
|
|
|
2220
2748
|
process.exit(0);
|
|
2221
2749
|
}
|
|
2222
2750
|
action = actionResult;
|
|
2751
|
+
if (action === "alias") {
|
|
2752
|
+
if (existingInstances.length === 0) {
|
|
2753
|
+
console.log();
|
|
2754
|
+
printInfo("No custom Cursor instances found.");
|
|
2755
|
+
console.log(import_picocolors8.default.dim(" Create an instance first."));
|
|
2756
|
+
console.log();
|
|
2757
|
+
p8.outro(import_picocolors8.default.dim("Nothing to do"));
|
|
2758
|
+
return;
|
|
2759
|
+
}
|
|
2760
|
+
const instanceResult = await p8.select({
|
|
2761
|
+
message: "Select instance to manage alias:",
|
|
2762
|
+
options: existingInstances.map((inst) => ({
|
|
2763
|
+
value: inst.name,
|
|
2764
|
+
label: inst.alias ? `${inst.name} (alias: ${inst.alias})` : inst.name,
|
|
2765
|
+
hint: inst.alias ? "Has alias" : "No alias"
|
|
2766
|
+
}))
|
|
2767
|
+
});
|
|
2768
|
+
if (p8.isCancel(instanceResult)) {
|
|
2769
|
+
p8.cancel("Operation cancelled");
|
|
2770
|
+
process.exit(0);
|
|
2771
|
+
}
|
|
2772
|
+
await handleAliasAction(instanceResult, args.alias, args.aliasLocation);
|
|
2773
|
+
return;
|
|
2774
|
+
}
|
|
2223
2775
|
}
|
|
2224
2776
|
if (args.name) {
|
|
2225
2777
|
instanceName = args.name;
|
|
@@ -2229,7 +2781,7 @@ var instanceCommand = (0, import_citty6.defineCommand)({
|
|
|
2229
2781
|
message: `Select instance to ${actionLabel2}:`,
|
|
2230
2782
|
options: existingInstances.map((inst) => ({
|
|
2231
2783
|
value: inst.name,
|
|
2232
|
-
label: inst.name,
|
|
2784
|
+
label: inst.alias ? `${inst.name} (alias: ${inst.alias})` : inst.name,
|
|
2233
2785
|
hint: inst.path
|
|
2234
2786
|
}))
|
|
2235
2787
|
});
|
|
@@ -2277,12 +2829,16 @@ var instanceCommand = (0, import_citty6.defineCommand)({
|
|
|
2277
2829
|
console.log(` ${import_picocolors8.default.dim("Bundle ID:")} ${import_picocolors8.default.dim("com.cursor.")}${highlight(slug)}`);
|
|
2278
2830
|
console.log(` ${import_picocolors8.default.dim("Location:")} ${import_picocolors8.default.dim("~/Applications/")}${highlight(instanceName + ".app")}`);
|
|
2279
2831
|
if (action === "reinstall") {
|
|
2280
|
-
const dataDir = (0,
|
|
2832
|
+
const dataDir = (0, import_node_path10.join)(process.env.HOME ?? "", "Library", "Application Support", instanceName.replace(/ /g, ""));
|
|
2281
2833
|
console.log(` ${import_picocolors8.default.dim("Data:")} ${import_picocolors8.default.green("\u2713")} ${import_picocolors8.default.dim("Preserved at")} ${import_picocolors8.default.dim(dataDir)}`);
|
|
2282
2834
|
}
|
|
2283
2835
|
} else {
|
|
2284
|
-
const targetPath = (0,
|
|
2836
|
+
const targetPath = (0, import_node_path10.join)(process.env.HOME ?? "", "Applications", `${instanceName}.app`);
|
|
2285
2837
|
console.log(` ${import_picocolors8.default.dim("Path:")} ${import_picocolors8.default.dim(targetPath)}`);
|
|
2838
|
+
const aliasEntry = getAliasForInstance(instanceName);
|
|
2839
|
+
if (aliasEntry) {
|
|
2840
|
+
console.log(` ${import_picocolors8.default.dim("Alias:")} ${import_picocolors8.default.yellow(aliasEntry.aliasName)} ${import_picocolors8.default.dim("(will be removed)")}`);
|
|
2841
|
+
}
|
|
2286
2842
|
}
|
|
2287
2843
|
console.log();
|
|
2288
2844
|
printDivider();
|
|
@@ -2307,6 +2863,20 @@ var instanceCommand = (0, import_citty6.defineCommand)({
|
|
|
2307
2863
|
if (exitCode === 0) {
|
|
2308
2864
|
if (action === "create") {
|
|
2309
2865
|
printSuccess(`Instance ${highlight(instanceName)} created successfully!`);
|
|
2866
|
+
if (!args.skipAlias) {
|
|
2867
|
+
console.log();
|
|
2868
|
+
const aliasConfig = await promptAliasCreation(
|
|
2869
|
+
instanceName,
|
|
2870
|
+
args.alias,
|
|
2871
|
+
args.aliasLocation
|
|
2872
|
+
);
|
|
2873
|
+
if (aliasConfig) {
|
|
2874
|
+
await handleAliasCreation(instanceName, aliasConfig.aliasName, aliasConfig.location);
|
|
2875
|
+
}
|
|
2876
|
+
} else if (args.alias) {
|
|
2877
|
+
const location = args.aliasLocation ?? "shell-config";
|
|
2878
|
+
await handleAliasCreation(instanceName, args.alias, location);
|
|
2879
|
+
}
|
|
2310
2880
|
console.log();
|
|
2311
2881
|
console.log(import_picocolors8.default.dim(" Next steps:"));
|
|
2312
2882
|
console.log(import_picocolors8.default.dim(" \u2022 The new instance should launch automatically"));
|
|
@@ -2320,6 +2890,7 @@ var instanceCommand = (0, import_citty6.defineCommand)({
|
|
|
2320
2890
|
console.log(import_picocolors8.default.dim(" \u2022 Relaunched with your preserved data"));
|
|
2321
2891
|
console.log(import_picocolors8.default.dim(" \u2022 Ready to use with your existing account"));
|
|
2322
2892
|
} else {
|
|
2893
|
+
await handleAliasRemoval(instanceName);
|
|
2323
2894
|
printSuccess(`Instance ${highlight(instanceName)} removed successfully!`);
|
|
2324
2895
|
}
|
|
2325
2896
|
console.log();
|