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.
- package/dist/index.js +254 -10
- 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
|
|
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[
|
|
169
|
+
const appPath = checkPathExists(def.paths[os2] || []);
|
|
170
170
|
const installed = !!(cliPath || appPath);
|
|
171
171
|
let resolvedCli = cliPath;
|
|
172
|
-
if (!resolvedCli && appPath &&
|
|
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 &&
|
|
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
|
|
775
|
+
const os2 = await import("os");
|
|
776
776
|
const fs = await import("fs");
|
|
777
777
|
const path = await import("path");
|
|
778
|
-
const
|
|
779
|
-
const home =
|
|
778
|
+
const platform3 = os2.platform();
|
|
779
|
+
const home = os2.homedir();
|
|
780
780
|
const getSettingsPath = (appName2) => {
|
|
781
|
-
if (
|
|
781
|
+
if (platform3 === "darwin") {
|
|
782
782
|
return path.join(home, "Library", "Application Support", appName2, "User", "settings.json");
|
|
783
|
-
} else if (
|
|
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.
|
|
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"));
|