adhdev 0.1.6 → 0.1.7

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 +254 -10
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -162,18 +162,18 @@ function checkPathExists(paths) {
162
162
  return null;
163
163
  }
164
164
  async function detectIDEs() {
165
- const os = (0, import_os.platform)();
165
+ const os2 = (0, import_os.platform)();
166
166
  const results = [];
167
167
  for (const def of IDE_DEFINITIONS) {
168
168
  const cliPath = findCliCommand(def.cli);
169
- const appPath = checkPathExists(def.paths[os] || []);
169
+ const appPath = checkPathExists(def.paths[os2] || []);
170
170
  const installed = !!(cliPath || appPath);
171
171
  let resolvedCli = cliPath;
172
- if (!resolvedCli && appPath && os === "darwin") {
172
+ if (!resolvedCli && appPath && os2 === "darwin") {
173
173
  const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
174
174
  if ((0, import_fs.existsSync)(bundledCli)) resolvedCli = bundledCli;
175
175
  }
176
- if (!resolvedCli && appPath && os === "win32") {
176
+ if (!resolvedCli && appPath && os2 === "win32") {
177
177
  const { dirname } = await import("path");
178
178
  const appDir = dirname(appPath);
179
179
  const candidates = [
@@ -772,15 +772,15 @@ async function loginFlow() {
772
772
  async function injectTokenToIDE(ide, connectionToken) {
773
773
  if (!ide.cliCommand) return;
774
774
  try {
775
- const os = await import("os");
775
+ const os2 = await import("os");
776
776
  const fs = await import("fs");
777
777
  const path = await import("path");
778
- const platform2 = os.platform();
779
- const home = os.homedir();
778
+ const platform3 = os2.platform();
779
+ const home = os2.homedir();
780
780
  const getSettingsPath = (appName2) => {
781
- if (platform2 === "darwin") {
781
+ if (platform3 === "darwin") {
782
782
  return path.join(home, "Library", "Application Support", appName2, "User", "settings.json");
783
- } else if (platform2 === "win32") {
783
+ } else if (platform3 === "win32") {
784
784
  return path.join(process.env.APPDATA || path.join(home, "AppData", "Roaming"), appName2, "User", "settings.json");
785
785
  } else {
786
786
  return path.join(home, ".config", appName2, "User", "settings.json");
@@ -853,12 +853,256 @@ async function addExtensionsFlow() {
853
853
  console.log(import_chalk.default.green("\n\u2713 Extensions added!"));
854
854
  }
855
855
 
856
+ // src/launch.ts
857
+ var import_child_process3 = require("child_process");
858
+ var net = __toESM(require("net"));
859
+ var os = __toESM(require("os"));
860
+ var CDP_PORTS = {
861
+ cursor: 9333,
862
+ antigravity: 9335,
863
+ vscode: 9229,
864
+ windsurf: 9337,
865
+ "vscode-insiders": 9231,
866
+ vscodium: 9233
867
+ };
868
+ var MAC_APP_NAMES = {
869
+ cursor: "Cursor",
870
+ antigravity: "Antigravity",
871
+ vscode: "Visual Studio Code",
872
+ windsurf: "Windsurf",
873
+ "vscode-insiders": "Visual Studio Code - Insiders",
874
+ vscodium: "VSCodium"
875
+ };
876
+ async function findFreePort(startPort) {
877
+ return new Promise((resolve) => {
878
+ const server = net.createServer();
879
+ server.unref();
880
+ server.on("error", () => resolve(findFreePort(startPort + 1)));
881
+ server.listen(startPort, "127.0.0.1", () => {
882
+ server.close(() => resolve(startPort));
883
+ });
884
+ });
885
+ }
886
+ async function isPortInUse(port) {
887
+ 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);
897
+ });
898
+ socket.on("error", () => {
899
+ socket.destroy();
900
+ resolve(false);
901
+ });
902
+ socket.connect(port, "127.0.0.1");
903
+ });
904
+ }
905
+ function isIdeRunning(ideId) {
906
+ const platform3 = os.platform();
907
+ const appName = MAC_APP_NAMES[ideId];
908
+ if (!appName) return false;
909
+ try {
910
+ if (platform3 === "darwin") {
911
+ const result = (0, import_child_process3.execSync)(`pgrep -f "${appName}" 2>/dev/null`, { encoding: "utf-8" });
912
+ return result.trim().length > 0;
913
+ } 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);
916
+ } else {
917
+ const result = (0, import_child_process3.execSync)(`pgrep -f "${ideId}" 2>/dev/null`, { encoding: "utf-8" });
918
+ return result.trim().length > 0;
919
+ }
920
+ } catch {
921
+ return false;
922
+ }
923
+ }
924
+ async function launchWithCdp(options = {}) {
925
+ const platform3 = os.platform();
926
+ let targetIde;
927
+ const ides = await detectIDEs();
928
+ if (options.ideId) {
929
+ targetIde = ides.find((i) => i.id === options.ideId && i.installed);
930
+ if (!targetIde) {
931
+ return {
932
+ success: false,
933
+ ideId: options.ideId,
934
+ ideName: options.ideId,
935
+ port: 0,
936
+ alreadyRunning: false,
937
+ cdpAlreadyActive: false,
938
+ error: `IDE '${options.ideId}' not found or not installed`
939
+ };
940
+ }
941
+ } else {
942
+ const config = loadConfig();
943
+ if (config.selectedIde) {
944
+ targetIde = ides.find((i) => i.id === config.selectedIde && i.installed);
945
+ }
946
+ if (!targetIde) {
947
+ targetIde = ides.find((i) => i.installed);
948
+ }
949
+ if (!targetIde) {
950
+ return {
951
+ success: false,
952
+ ideId: "unknown",
953
+ ideName: "Unknown",
954
+ port: 0,
955
+ alreadyRunning: false,
956
+ cdpAlreadyActive: false,
957
+ error: "No IDE found. Install VS Code, Cursor, or Antigravity first."
958
+ };
959
+ }
960
+ }
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
+ };
973
+ }
974
+ const alreadyRunning = isIdeRunning(targetIde.id);
975
+ const port = await findFreePort(requestedPort);
976
+ try {
977
+ if (platform3 === "darwin") {
978
+ await launchMacOS(targetIde, port, options.workspace, options.newWindow);
979
+ } else if (platform3 === "win32") {
980
+ await launchWindows(targetIde, port, options.workspace, options.newWindow);
981
+ } else {
982
+ await launchLinux(targetIde, port, options.workspace, options.newWindow);
983
+ }
984
+ return {
985
+ success: true,
986
+ ideId: targetIde.id,
987
+ ideName: targetIde.displayName,
988
+ port,
989
+ alreadyRunning,
990
+ cdpAlreadyActive: false
991
+ };
992
+ } catch (e) {
993
+ return {
994
+ success: false,
995
+ ideId: targetIde.id,
996
+ ideName: targetIde.displayName,
997
+ port,
998
+ alreadyRunning,
999
+ cdpAlreadyActive: false,
1000
+ error: e?.message || String(e)
1001
+ };
1002
+ }
1003
+ }
1004
+ 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
+ }
1016
+ const args = ["--remote-debugging-port=" + port];
1017
+ if (newWindow) args.push("--new-window");
1018
+ 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();
1022
+ }
1023
+ async function launchWindows(ide, port, workspace, newWindow) {
1024
+ const cli = ide.cliCommand;
1025
+ if (!cli) {
1026
+ throw new Error(`No CLI command for ${ide.displayName}. Please add it to PATH.`);
1027
+ }
1028
+ const args = ["--remote-debugging-port=" + port];
1029
+ if (newWindow) args.push("--new-window");
1030
+ if (workspace) args.push(workspace);
1031
+ (0, import_child_process3.spawn)(cli, args, {
1032
+ detached: true,
1033
+ stdio: "ignore",
1034
+ shell: true
1035
+ // Windows에서 .cmd 파일 실행 위해
1036
+ }).unref();
1037
+ }
1038
+ async function launchLinux(ide, port, workspace, newWindow) {
1039
+ const cli = ide.cliCommand;
1040
+ if (!cli) {
1041
+ throw new Error(`No CLI command for ${ide.displayName}. Make sure it's in PATH.`);
1042
+ }
1043
+ const args = ["--remote-debugging-port=" + port];
1044
+ if (newWindow) args.push("--new-window");
1045
+ if (workspace) args.push(workspace);
1046
+ (0, import_child_process3.spawn)(cli, args, { detached: true, stdio: "ignore" }).unref();
1047
+ }
1048
+
856
1049
  // src/index.ts
857
1050
  var program = new import_commander.Command();
858
- program.name("adhdev").description("\u{1F309} ADHDev \u2014 Agent Dashboard Hub for your IDE").version("0.1.0");
1051
+ program.name("adhdev").description("\u{1F309} ADHDev \u2014 Agent Dashboard Hub for your IDE").version("0.1.6");
859
1052
  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) => {
860
1053
  await runWizard({ force: options.force });
861
1054
  });
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) => {
1056
+ const ora2 = await import("ora");
1057
+ const spinner = ora2.default("Detecting IDE...").start();
1058
+ try {
1059
+ const result = await launchWithCdp({
1060
+ ideId: ideArg,
1061
+ port: options.port ? parseInt(options.port) : void 0,
1062
+ workspace: options.workspace,
1063
+ newWindow: options.newWindow
1064
+ });
1065
+ spinner.stop();
1066
+ if (!result.success) {
1067
+ console.log(import_chalk2.default.red(`
1068
+ \u2717 ${result.error}
1069
+ `));
1070
+ console.log(import_chalk2.default.gray(" Available IDEs:"));
1071
+ const ides = await detectIDEs();
1072
+ ides.forEach((ide) => {
1073
+ if (ide.installed) {
1074
+ console.log(` ${import_chalk2.default.green("\u2713")} ${ide.icon} ${import_chalk2.default.bold(ide.id)} \u2014 ${ide.displayName}`);
1075
+ }
1076
+ });
1077
+ console.log(import_chalk2.default.gray(`
1078
+ Usage: adhdev launch <ide-id> [--port <port>]
1079
+ `));
1080
+ process.exit(1);
1081
+ }
1082
+ console.log();
1083
+ console.log(import_chalk2.default.bold(" \u{1F680} IDE Launched with CDP\n"));
1084
+ console.log(` ${import_chalk2.default.bold("IDE:")} ${result.ideName}`);
1085
+ 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")}`);
1093
+ }
1094
+ console.log();
1095
+ console.log(import_chalk2.default.gray(" Bridge extension will auto-connect to CDP."));
1096
+ console.log(import_chalk2.default.gray(` Test: curl http://127.0.0.1:${result.port}/json/version
1097
+ `));
1098
+ } catch (e) {
1099
+ spinner.stop();
1100
+ console.log(import_chalk2.default.red(`
1101
+ \u2717 Launch failed: ${e?.message || e}
1102
+ `));
1103
+ process.exit(1);
1104
+ }
1105
+ });
862
1106
  program.command("status").description("Show current ADHDev setup status").action(() => {
863
1107
  const config = loadConfig();
864
1108
  console.log(import_chalk2.default.bold("\n\u{1F309} ADHDev Status\n"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adhdev",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "ADHDev CLI — Detect, install and configure your IDE + AI agent extensions",
5
5
  "main": "dist/index.js",
6
6
  "bin": {