adhdev 0.1.7 → 0.1.9

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 (2) hide show
  1. package/dist/index.js +291 -91
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -553,19 +553,47 @@ async function quickSetup() {
553
553
  spinner.stop();
554
554
  if (installedIDEs.length === 0) {
555
555
  console.log(import_chalk.default.red("\u2717 No supported IDE with CLI found."));
556
- console.log(import_chalk.default.gray(" Supported: VS Code, Cursor, Antigravity, Windsurf"));
556
+ console.log(import_chalk.default.gray(" Supported: VS Code, Cursor, Antigravity, Windsurf, VSCodium"));
557
557
  return;
558
558
  }
559
- const selectedIDE = installedIDEs[0];
560
- console.log(import_chalk.default.green(`\u2713 Found: ${selectedIDE.icon} ${selectedIDE.displayName} ${selectedIDE.version ? `v${selectedIDE.version}` : ""}`));
561
- const bridgeExt = EXTENSION_CATALOG.find((e) => e.category === "bridge");
562
- const installSpinner = (0, import_ora.default)("Installing ADHDev Bridge extension...").start();
563
- const result = await installExtension(selectedIDE, bridgeExt);
564
- if (result.success) {
565
- installSpinner.succeed(result.alreadyInstalled ? "ADHDev Bridge already installed \u2713" : "ADHDev Bridge installed \u2713");
559
+ console.log(import_chalk.default.green(`Found ${installedIDEs.length} IDE(s):
560
+ `));
561
+ installedIDEs.forEach((ide) => {
562
+ const version = ide.version ? import_chalk.default.gray(` v${ide.version}`) : "";
563
+ console.log(` ${import_chalk.default.green("\u2713")} ${ide.icon} ${import_chalk.default.bold(ide.displayName)}${version}`);
564
+ });
565
+ console.log();
566
+ let selectedIDEs;
567
+ if (installedIDEs.length === 1) {
568
+ selectedIDEs = installedIDEs;
569
+ console.log(import_chalk.default.gray(` Auto-selected: ${installedIDEs[0].displayName}
570
+ `));
566
571
  } else {
567
- installSpinner.fail(`Installation failed: ${result.error}`);
568
- return;
572
+ const { selectedIdeIds } = await import_inquirer.default.prompt([
573
+ {
574
+ type: "checkbox",
575
+ name: "selectedIdeIds",
576
+ message: "Select IDEs to set up (Space to toggle, Enter to confirm):",
577
+ choices: installedIDEs.map((ide) => ({
578
+ name: `${ide.icon} ${ide.displayName}${ide.version ? import_chalk.default.gray(` v${ide.version}`) : ""}`,
579
+ value: ide.id,
580
+ checked: true
581
+ // 기본 모두 선택
582
+ })),
583
+ validate: (input) => input.length > 0 ? true : "Select at least one IDE"
584
+ }
585
+ ]);
586
+ selectedIDEs = installedIDEs.filter((i) => selectedIdeIds.includes(i.id));
587
+ }
588
+ const bridgeExt = EXTENSION_CATALOG.find((e) => e.category === "bridge");
589
+ for (const ide of selectedIDEs) {
590
+ const installSpinner = (0, import_ora.default)(`Installing ADHDev Bridge \u2192 ${ide.displayName}...`).start();
591
+ const result = await installExtension(ide, bridgeExt);
592
+ if (result.success) {
593
+ installSpinner.succeed(result.alreadyInstalled ? `${ide.icon} ${ide.displayName} \u2014 Bridge already installed \u2713` : `${ide.icon} ${ide.displayName} \u2014 Bridge installed \u2713`);
594
+ } else {
595
+ installSpinner.fail(`${ide.icon} ${ide.displayName} \u2014 Failed: ${result.error}`);
596
+ }
569
597
  }
570
598
  console.log(DIVIDER);
571
599
  const loginResult = await loginFlow();
@@ -573,9 +601,12 @@ async function quickSetup() {
573
601
  console.log(import_chalk.default.yellow("\u26A0 Setup completed without login. You can login later with `adhdev setup`."));
574
602
  }
575
603
  if (loginResult?.connectionToken) {
576
- await injectTokenToIDE(selectedIDE, loginResult.connectionToken);
604
+ for (const ide of selectedIDEs) {
605
+ await injectTokenToIDE(ide, loginResult.connectionToken);
606
+ }
577
607
  }
578
- markSetupComplete(selectedIDE.id, ["adhdev"]);
608
+ const primaryIde = selectedIDEs[0];
609
+ markSetupComplete(primaryIde.id, ["adhdev"]);
579
610
  if (loginResult) {
580
611
  updateConfig({
581
612
  connectionToken: loginResult.connectionToken,
@@ -585,10 +616,15 @@ async function quickSetup() {
585
616
  }
586
617
  console.log(DIVIDER);
587
618
  console.log(import_chalk.default.bold("\n\u{1F389} Setup Complete!\n"));
588
- console.log(` ${import_chalk.default.bold("IDE:")} ${selectedIDE.icon} ${selectedIDE.displayName}`);
619
+ if (selectedIDEs.length === 1) {
620
+ console.log(` ${import_chalk.default.bold("IDE:")} ${selectedIDEs[0].icon} ${selectedIDEs[0].displayName}`);
621
+ } else {
622
+ console.log(` ${import_chalk.default.bold("IDEs:")} ${selectedIDEs.map((i) => `${i.icon} ${i.displayName}`).join(", ")}`);
623
+ }
589
624
  console.log(` ${import_chalk.default.bold("User:")} ${loginResult?.email || "not logged in"}`);
590
625
  console.log(` ${import_chalk.default.bold("Status:")} ${import_chalk.default.green("Ready to connect")}`);
591
626
  console.log();
627
+ await suggestGlobalInstall();
592
628
  }
593
629
  async function customSetup() {
594
630
  console.log(import_chalk.default.bold("\n\u{1F4CD} Step 1/4 \u2014 Detecting installed IDEs...\n"));
@@ -852,20 +888,74 @@ async function addExtensionsFlow() {
852
888
  });
853
889
  console.log(import_chalk.default.green("\n\u2713 Extensions added!"));
854
890
  }
891
+ async function suggestGlobalInstall() {
892
+ const { execSync: execSyncLocal } = await import("child_process");
893
+ let isGloballyInstalled = false;
894
+ try {
895
+ const result = execSyncLocal("adhdev --version", {
896
+ encoding: "utf-8",
897
+ timeout: 5e3,
898
+ stdio: ["pipe", "pipe", "pipe"]
899
+ });
900
+ isGloballyInstalled = result.trim().length > 0;
901
+ } catch {
902
+ isGloballyInstalled = false;
903
+ }
904
+ if (isGloballyInstalled) return;
905
+ console.log(import_chalk.default.cyan(DIVIDER));
906
+ console.log(import_chalk.default.bold("\n\u{1F4A1} Install ADHDev CLI globally?\n"));
907
+ console.log(import_chalk.default.gray(" The `adhdev` command lets you:"));
908
+ console.log(import_chalk.default.gray(" \u2022 Launch IDE with CDP debugging (adhdev launch cursor)"));
909
+ console.log(import_chalk.default.gray(" \u2022 Relaunch IDE from the extension"));
910
+ console.log(import_chalk.default.gray(" \u2022 Check status anytime (adhdev status)"));
911
+ console.log();
912
+ const { doInstall } = await import_inquirer.default.prompt([
913
+ {
914
+ type: "confirm",
915
+ name: "doInstall",
916
+ message: `Install globally? (npm install -g adhdev)`,
917
+ default: true
918
+ }
919
+ ]);
920
+ if (!doInstall) {
921
+ console.log(import_chalk.default.gray("\n You can install later: npm install -g adhdev\n"));
922
+ return;
923
+ }
924
+ const installSpinner = (0, import_ora.default)("Installing adhdev globally...").start();
925
+ try {
926
+ execSyncLocal("npm install -g adhdev", {
927
+ encoding: "utf-8",
928
+ timeout: 6e4,
929
+ stdio: ["pipe", "pipe", "pipe"]
930
+ });
931
+ installSpinner.succeed("adhdev CLI installed globally \u2713");
932
+ console.log(import_chalk.default.gray(" Try: adhdev launch cursor"));
933
+ console.log();
934
+ } catch (e) {
935
+ installSpinner.fail("Global install failed");
936
+ console.log(import_chalk.default.yellow(` Error: ${e?.message?.split("\n")[0] || "Unknown"}`));
937
+ console.log(import_chalk.default.gray(" Try manually: npm install -g adhdev"));
938
+ const os2 = await import("os");
939
+ if (os2.platform() === "win32") {
940
+ console.log(import_chalk.default.gray(" On Windows, you may need to run PowerShell as Administrator"));
941
+ }
942
+ console.log();
943
+ }
944
+ }
855
945
 
856
946
  // src/launch.ts
857
947
  var import_child_process3 = require("child_process");
858
948
  var net = __toESM(require("net"));
859
949
  var os = __toESM(require("os"));
860
950
  var CDP_PORTS = {
861
- cursor: 9333,
862
- antigravity: 9335,
863
- vscode: 9229,
864
- windsurf: 9337,
865
- "vscode-insiders": 9231,
866
- vscodium: 9233
951
+ cursor: [9333, 9334],
952
+ antigravity: [9335, 9336],
953
+ vscode: [9229, 9230],
954
+ windsurf: [9337, 9338],
955
+ "vscode-insiders": [9231, 9232],
956
+ vscodium: [9233, 9234]
867
957
  };
868
- var MAC_APP_NAMES = {
958
+ var MAC_APP_IDENTIFIERS = {
869
959
  cursor: "Cursor",
870
960
  antigravity: "Antigravity",
871
961
  vscode: "Visual Studio Code",
@@ -873,46 +963,120 @@ var MAC_APP_NAMES = {
873
963
  "vscode-insiders": "Visual Studio Code - Insiders",
874
964
  vscodium: "VSCodium"
875
965
  };
876
- async function findFreePort(startPort) {
966
+ var WIN_PROCESS_NAMES = {
967
+ cursor: "Cursor.exe",
968
+ antigravity: "Antigravity.exe",
969
+ vscode: "Code.exe",
970
+ windsurf: "Windsurf.exe",
971
+ "vscode-insiders": "Code - Insiders.exe",
972
+ vscodium: "VSCodium.exe"
973
+ };
974
+ async function findFreePort(ports) {
975
+ for (const port2 of ports) {
976
+ const free = await checkPortFree(port2);
977
+ if (free) return port2;
978
+ }
979
+ let port = ports[1] + 1;
980
+ while (port < ports[1] + 10) {
981
+ if (await checkPortFree(port)) return port;
982
+ port++;
983
+ }
984
+ throw new Error("No free port found");
985
+ }
986
+ function checkPortFree(port) {
877
987
  return new Promise((resolve) => {
878
988
  const server = net.createServer();
879
989
  server.unref();
880
- server.on("error", () => resolve(findFreePort(startPort + 1)));
881
- server.listen(startPort, "127.0.0.1", () => {
882
- server.close(() => resolve(startPort));
990
+ server.on("error", () => resolve(false));
991
+ server.listen(port, "127.0.0.1", () => {
992
+ server.close(() => resolve(true));
883
993
  });
884
994
  });
885
995
  }
886
- async function isPortInUse(port) {
996
+ async function isCdpActive(port) {
887
997
  return new Promise((resolve) => {
888
- const socket = new net.Socket();
889
- socket.setTimeout(1e3);
890
- socket.on("connect", () => {
891
- socket.destroy();
892
- resolve(true);
893
- });
894
- socket.on("timeout", () => {
895
- socket.destroy();
896
- resolve(false);
998
+ const req = require("http").get(`http://127.0.0.1:${port}/json/version`, {
999
+ timeout: 2e3
1000
+ }, (res) => {
1001
+ let data = "";
1002
+ res.on("data", (c) => data += c);
1003
+ res.on("end", () => {
1004
+ try {
1005
+ const info = JSON.parse(data);
1006
+ resolve(!!info["WebKit-Version"] || !!info["Browser"]);
1007
+ } catch {
1008
+ resolve(false);
1009
+ }
1010
+ });
897
1011
  });
898
- socket.on("error", () => {
899
- socket.destroy();
1012
+ req.on("error", () => resolve(false));
1013
+ req.on("timeout", () => {
1014
+ req.destroy();
900
1015
  resolve(false);
901
1016
  });
902
- socket.connect(port, "127.0.0.1");
903
1017
  });
904
1018
  }
1019
+ async function killIdeProcess(ideId) {
1020
+ const platform3 = os.platform();
1021
+ const appName = MAC_APP_IDENTIFIERS[ideId];
1022
+ const winProcess = WIN_PROCESS_NAMES[ideId];
1023
+ try {
1024
+ if (platform3 === "darwin" && appName) {
1025
+ try {
1026
+ (0, import_child_process3.execSync)(`osascript -e 'tell application "${appName}" to quit' 2>/dev/null`, {
1027
+ timeout: 5e3
1028
+ });
1029
+ } catch {
1030
+ try {
1031
+ (0, import_child_process3.execSync)(`pkill -f "${appName}" 2>/dev/null`);
1032
+ } catch {
1033
+ }
1034
+ }
1035
+ } else if (platform3 === "win32" && winProcess) {
1036
+ try {
1037
+ (0, import_child_process3.execSync)(`taskkill /IM "${winProcess}" /F 2>nul`, { timeout: 5e3 });
1038
+ } catch {
1039
+ }
1040
+ } else {
1041
+ try {
1042
+ (0, import_child_process3.execSync)(`pkill -f "${ideId}" 2>/dev/null`);
1043
+ } catch {
1044
+ }
1045
+ }
1046
+ for (let i = 0; i < 30; i++) {
1047
+ await new Promise((r) => setTimeout(r, 500));
1048
+ if (!isIdeRunning(ideId)) return true;
1049
+ }
1050
+ if (platform3 === "darwin" && appName) {
1051
+ try {
1052
+ (0, import_child_process3.execSync)(`pkill -9 -f "${appName}" 2>/dev/null`);
1053
+ } catch {
1054
+ }
1055
+ } else if (platform3 === "win32" && winProcess) {
1056
+ try {
1057
+ (0, import_child_process3.execSync)(`taskkill /IM "${winProcess}" /F 2>nul`);
1058
+ } catch {
1059
+ }
1060
+ }
1061
+ await new Promise((r) => setTimeout(r, 2e3));
1062
+ return !isIdeRunning(ideId);
1063
+ } catch {
1064
+ return false;
1065
+ }
1066
+ }
905
1067
  function isIdeRunning(ideId) {
906
1068
  const platform3 = os.platform();
907
- const appName = MAC_APP_NAMES[ideId];
908
- if (!appName) return false;
909
1069
  try {
910
1070
  if (platform3 === "darwin") {
1071
+ const appName = MAC_APP_IDENTIFIERS[ideId];
1072
+ if (!appName) return false;
911
1073
  const result = (0, import_child_process3.execSync)(`pgrep -f "${appName}" 2>/dev/null`, { encoding: "utf-8" });
912
1074
  return result.trim().length > 0;
913
1075
  } else if (platform3 === "win32") {
914
- const result = (0, import_child_process3.execSync)(`tasklist /FI "IMAGENAME eq ${ideId}.exe" /NH 2>nul`, { encoding: "utf-8" });
915
- return result.includes(ideId);
1076
+ const winProc = WIN_PROCESS_NAMES[ideId];
1077
+ if (!winProc) return false;
1078
+ const result = (0, import_child_process3.execSync)(`tasklist /FI "IMAGENAME eq ${winProc}" /NH 2>nul`, { encoding: "utf-8" });
1079
+ return result.includes(winProc);
916
1080
  } else {
917
1081
  const result = (0, import_child_process3.execSync)(`pgrep -f "${ideId}" 2>/dev/null`, { encoding: "utf-8" });
918
1082
  return result.trim().length > 0;
@@ -921,6 +1085,22 @@ function isIdeRunning(ideId) {
921
1085
  return false;
922
1086
  }
923
1087
  }
1088
+ function detectCurrentWorkspace(ideId) {
1089
+ const platform3 = os.platform();
1090
+ if (platform3 !== "darwin") return void 0;
1091
+ try {
1092
+ const appName = MAC_APP_IDENTIFIERS[ideId];
1093
+ if (!appName) return void 0;
1094
+ const result = (0, import_child_process3.execSync)(
1095
+ `lsof -c "${appName}" 2>/dev/null | grep cwd | head -1 | awk '{print $NF}'`,
1096
+ { encoding: "utf-8", timeout: 3e3 }
1097
+ );
1098
+ const dir = result.trim();
1099
+ if (dir && dir !== "/") return dir;
1100
+ } catch {
1101
+ }
1102
+ return void 0;
1103
+ }
924
1104
  async function launchWithCdp(options = {}) {
925
1105
  const platform3 = os.platform();
926
1106
  let targetIde;
@@ -933,8 +1113,8 @@ async function launchWithCdp(options = {}) {
933
1113
  ideId: options.ideId,
934
1114
  ideName: options.ideId,
935
1115
  port: 0,
936
- alreadyRunning: false,
937
- cdpAlreadyActive: false,
1116
+ action: "failed",
1117
+ message: "",
938
1118
  error: `IDE '${options.ideId}' not found or not installed`
939
1119
  };
940
1120
  }
@@ -952,42 +1132,66 @@ async function launchWithCdp(options = {}) {
952
1132
  ideId: "unknown",
953
1133
  ideName: "Unknown",
954
1134
  port: 0,
955
- alreadyRunning: false,
956
- cdpAlreadyActive: false,
1135
+ action: "failed",
1136
+ message: "",
957
1137
  error: "No IDE found. Install VS Code, Cursor, or Antigravity first."
958
1138
  };
959
1139
  }
960
1140
  }
961
- const defaultPort = CDP_PORTS[targetIde.id] || 9333;
962
- const requestedPort = options.port || defaultPort;
963
- const cdpAlreadyActive = await isPortInUse(requestedPort);
964
- if (cdpAlreadyActive) {
965
- return {
966
- success: true,
967
- ideId: targetIde.id,
968
- ideName: targetIde.displayName,
969
- port: requestedPort,
970
- alreadyRunning: true,
971
- cdpAlreadyActive: true
972
- };
1141
+ const portPair = CDP_PORTS[targetIde.id] || [9333, 9334];
1142
+ for (const port2 of portPair) {
1143
+ if (await isCdpActive(port2)) {
1144
+ return {
1145
+ success: true,
1146
+ ideId: targetIde.id,
1147
+ ideName: targetIde.displayName,
1148
+ port: port2,
1149
+ action: "reused",
1150
+ message: `CDP already active on port ${port2}`
1151
+ };
1152
+ }
973
1153
  }
974
1154
  const alreadyRunning = isIdeRunning(targetIde.id);
975
- const port = await findFreePort(requestedPort);
1155
+ const workspace = options.workspace || (alreadyRunning ? detectCurrentWorkspace(targetIde.id) : void 0);
1156
+ if (alreadyRunning) {
1157
+ const killed = await killIdeProcess(targetIde.id);
1158
+ if (!killed) {
1159
+ return {
1160
+ success: false,
1161
+ ideId: targetIde.id,
1162
+ ideName: targetIde.displayName,
1163
+ port: 0,
1164
+ action: "failed",
1165
+ message: "",
1166
+ error: `Could not stop ${targetIde.displayName}. Close it manually and try again.`
1167
+ };
1168
+ }
1169
+ await new Promise((r) => setTimeout(r, 3e3));
1170
+ }
1171
+ const port = await findFreePort(portPair);
976
1172
  try {
977
1173
  if (platform3 === "darwin") {
978
- await launchMacOS(targetIde, port, options.workspace, options.newWindow);
1174
+ await launchMacOS(targetIde, port, workspace, options.newWindow);
979
1175
  } else if (platform3 === "win32") {
980
- await launchWindows(targetIde, port, options.workspace, options.newWindow);
1176
+ await launchWindows(targetIde, port, workspace, options.newWindow);
981
1177
  } else {
982
- await launchLinux(targetIde, port, options.workspace, options.newWindow);
1178
+ await launchLinux(targetIde, port, workspace, options.newWindow);
1179
+ }
1180
+ let cdpReady = false;
1181
+ for (let i = 0; i < 30; i++) {
1182
+ await new Promise((r) => setTimeout(r, 500));
1183
+ if (await isCdpActive(port)) {
1184
+ cdpReady = true;
1185
+ break;
1186
+ }
983
1187
  }
984
1188
  return {
985
1189
  success: true,
986
1190
  ideId: targetIde.id,
987
1191
  ideName: targetIde.displayName,
988
1192
  port,
989
- alreadyRunning,
990
- cdpAlreadyActive: false
1193
+ action: alreadyRunning ? "restarted" : "started",
1194
+ message: cdpReady ? `${targetIde.displayName} launched with CDP on port ${port}` : `${targetIde.displayName} launched (CDP may take a moment to initialize)`
991
1195
  };
992
1196
  } catch (e) {
993
1197
  return {
@@ -995,30 +1199,25 @@ async function launchWithCdp(options = {}) {
995
1199
  ideId: targetIde.id,
996
1200
  ideName: targetIde.displayName,
997
1201
  port,
998
- alreadyRunning,
999
- cdpAlreadyActive: false,
1202
+ action: "failed",
1203
+ message: "",
1000
1204
  error: e?.message || String(e)
1001
1205
  };
1002
1206
  }
1003
1207
  }
1004
1208
  async function launchMacOS(ide, port, workspace, newWindow) {
1005
- const appName = MAC_APP_NAMES[ide.id];
1006
- if (!appName) {
1007
- if (ide.cliCommand) {
1008
- const args2 = ["--remote-debugging-port=" + port];
1009
- if (newWindow) args2.push("--new-window");
1010
- if (workspace) args2.push(workspace);
1011
- (0, import_child_process3.spawn)(ide.cliCommand, args2, { detached: true, stdio: "ignore" }).unref();
1012
- return;
1013
- }
1014
- throw new Error(`No app name or CLI for ${ide.displayName}`);
1015
- }
1209
+ const appName = MAC_APP_IDENTIFIERS[ide.id];
1016
1210
  const args = ["--remote-debugging-port=" + port];
1017
1211
  if (newWindow) args.push("--new-window");
1018
1212
  if (workspace) args.push(workspace);
1019
- const openArgs = ["-a", appName, "--args", ...args];
1020
- if (newWindow) openArgs.splice(1, 0, "-n");
1021
- (0, import_child_process3.spawn)("open", openArgs, { detached: true, stdio: "ignore" }).unref();
1213
+ if (appName) {
1214
+ const openArgs = ["-a", appName, "--args", ...args];
1215
+ (0, import_child_process3.spawn)("open", openArgs, { detached: true, stdio: "ignore" }).unref();
1216
+ } else if (ide.cliCommand) {
1217
+ (0, import_child_process3.spawn)(ide.cliCommand, args, { detached: true, stdio: "ignore" }).unref();
1218
+ } else {
1219
+ throw new Error(`No app identifier or CLI for ${ide.displayName}`);
1220
+ }
1022
1221
  }
1023
1222
  async function launchWindows(ide, port, workspace, newWindow) {
1024
1223
  const cli = ide.cliCommand;
@@ -1032,7 +1231,6 @@ async function launchWindows(ide, port, workspace, newWindow) {
1032
1231
  detached: true,
1033
1232
  stdio: "ignore",
1034
1233
  shell: true
1035
- // Windows에서 .cmd 파일 실행 위해
1036
1234
  }).unref();
1037
1235
  }
1038
1236
  async function launchLinux(ide, port, workspace, newWindow) {
@@ -1048,17 +1246,16 @@ async function launchLinux(ide, port, workspace, newWindow) {
1048
1246
 
1049
1247
  // src/index.ts
1050
1248
  var program = new import_commander.Command();
1051
- program.name("adhdev").description("\u{1F309} ADHDev \u2014 Agent Dashboard Hub for your IDE").version("0.1.6");
1249
+ program.name("adhdev").description("\u{1F309} ADHDev \u2014 Agent Dashboard Hub for your IDE").version("0.1.9");
1052
1250
  program.command("setup", { isDefault: true }).description("Run the interactive setup wizard").option("-f, --force", "Force re-run setup even if already configured").action(async (options) => {
1053
1251
  await runWizard({ force: options.force });
1054
1252
  });
1055
- program.command("launch [ide]").description("Launch IDE with Chrome DevTools Protocol (CDP) debugging port").option("-p, --port <port>", "CDP port number (default: auto per IDE)").option("-w, --workspace <path>", "Workspace/folder to open").option("-n, --new-window", "Open in a new window").action(async (ideArg, options) => {
1253
+ program.command("launch [ide]").description("Launch or relaunch IDE with CDP debugging port (kills existing process first)").option("-w, --workspace <path>", "Workspace/folder to open").option("-n, --new-window", "Open in a new window").action(async (ideArg, options) => {
1056
1254
  const ora2 = await import("ora");
1057
1255
  const spinner = ora2.default("Detecting IDE...").start();
1058
1256
  try {
1059
1257
  const result = await launchWithCdp({
1060
1258
  ideId: ideArg,
1061
- port: options.port ? parseInt(options.port) : void 0,
1062
1259
  workspace: options.workspace,
1063
1260
  newWindow: options.newWindow
1064
1261
  });
@@ -1075,7 +1272,7 @@ program.command("launch [ide]").description("Launch IDE with Chrome DevTools Pro
1075
1272
  }
1076
1273
  });
1077
1274
  console.log(import_chalk2.default.gray(`
1078
- Usage: adhdev launch <ide-id> [--port <port>]
1275
+ Usage: adhdev launch <ide-id>
1079
1276
  `));
1080
1277
  process.exit(1);
1081
1278
  }
@@ -1083,13 +1280,16 @@ program.command("launch [ide]").description("Launch IDE with Chrome DevTools Pro
1083
1280
  console.log(import_chalk2.default.bold(" \u{1F680} IDE Launched with CDP\n"));
1084
1281
  console.log(` ${import_chalk2.default.bold("IDE:")} ${result.ideName}`);
1085
1282
  console.log(` ${import_chalk2.default.bold("CDP:")} ${import_chalk2.default.cyan(`ws://127.0.0.1:${result.port}`)}`);
1086
- if (result.cdpAlreadyActive) {
1087
- console.log(` ${import_chalk2.default.bold("Status:")} ${import_chalk2.default.yellow("CDP already active (reusing)")}`);
1088
- } else if (result.alreadyRunning) {
1089
- console.log(` ${import_chalk2.default.bold("Status:")} ${import_chalk2.default.yellow("\u26A0 IDE was already running without CDP")}`);
1090
- console.log(import_chalk2.default.gray(" Close and reopen, or use the extension's relaunch command"));
1091
- } else {
1092
- console.log(` ${import_chalk2.default.bold("Status:")} ${import_chalk2.default.green("\u2713 Started fresh with CDP")}`);
1283
+ switch (result.action) {
1284
+ case "reused":
1285
+ console.log(` ${import_chalk2.default.bold("Action:")} ${import_chalk2.default.yellow("CDP already active \u2014 reusing existing session")}`);
1286
+ break;
1287
+ case "restarted":
1288
+ console.log(` ${import_chalk2.default.bold("Action:")} ${import_chalk2.default.green("\u2713 Killed existing process \u2192 Restarted with CDP")}`);
1289
+ break;
1290
+ case "started":
1291
+ console.log(` ${import_chalk2.default.bold("Action:")} ${import_chalk2.default.green("\u2713 Started fresh with CDP")}`);
1292
+ break;
1093
1293
  }
1094
1294
  console.log();
1095
1295
  console.log(import_chalk2.default.gray(" Bridge extension will auto-connect to CDP."));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adhdev",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "description": "ADHDev CLI — Detect, install and configure your IDE + AI agent extensions",
5
5
  "main": "dist/index.js",
6
6
  "bin": {