adhdev 0.1.4 → 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 +275 -13
- 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 = [
|
|
@@ -220,8 +220,8 @@ var EXTENSION_CATALOG = [
|
|
|
220
220
|
category: "bridge",
|
|
221
221
|
icon: "\u{1F309}",
|
|
222
222
|
recommended: true,
|
|
223
|
-
vsixUrl: "https://
|
|
224
|
-
//
|
|
223
|
+
vsixUrl: "https://adhf.dev/releases/bridge/latest.vsix"
|
|
224
|
+
// 웹사이트에서 정적 서빙
|
|
225
225
|
},
|
|
226
226
|
// AI Agent extensions
|
|
227
227
|
{
|
|
@@ -350,7 +350,25 @@ async function installExtension(ide, extension) {
|
|
|
350
350
|
});
|
|
351
351
|
});
|
|
352
352
|
}
|
|
353
|
-
|
|
353
|
+
if (extension.category === "bridge") {
|
|
354
|
+
return {
|
|
355
|
+
extensionId: extension.id,
|
|
356
|
+
marketplaceId: extension.marketplaceId,
|
|
357
|
+
success: false,
|
|
358
|
+
alreadyInstalled: false,
|
|
359
|
+
error: "VSIX download failed. Check your internet connection and try again."
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
} catch (e) {
|
|
363
|
+
if (extension.category === "bridge") {
|
|
364
|
+
return {
|
|
365
|
+
extensionId: extension.id,
|
|
366
|
+
marketplaceId: extension.marketplaceId,
|
|
367
|
+
success: false,
|
|
368
|
+
alreadyInstalled: false,
|
|
369
|
+
error: `VSIX download error: ${e?.message || "Unknown error"}`
|
|
370
|
+
};
|
|
371
|
+
}
|
|
354
372
|
}
|
|
355
373
|
}
|
|
356
374
|
return new Promise((resolve) => {
|
|
@@ -754,15 +772,15 @@ async function loginFlow() {
|
|
|
754
772
|
async function injectTokenToIDE(ide, connectionToken) {
|
|
755
773
|
if (!ide.cliCommand) return;
|
|
756
774
|
try {
|
|
757
|
-
const
|
|
775
|
+
const os2 = await import("os");
|
|
758
776
|
const fs = await import("fs");
|
|
759
777
|
const path = await import("path");
|
|
760
|
-
const
|
|
761
|
-
const home =
|
|
778
|
+
const platform3 = os2.platform();
|
|
779
|
+
const home = os2.homedir();
|
|
762
780
|
const getSettingsPath = (appName2) => {
|
|
763
|
-
if (
|
|
781
|
+
if (platform3 === "darwin") {
|
|
764
782
|
return path.join(home, "Library", "Application Support", appName2, "User", "settings.json");
|
|
765
|
-
} else if (
|
|
783
|
+
} else if (platform3 === "win32") {
|
|
766
784
|
return path.join(process.env.APPDATA || path.join(home, "AppData", "Roaming"), appName2, "User", "settings.json");
|
|
767
785
|
} else {
|
|
768
786
|
return path.join(home, ".config", appName2, "User", "settings.json");
|
|
@@ -835,12 +853,256 @@ async function addExtensionsFlow() {
|
|
|
835
853
|
console.log(import_chalk.default.green("\n\u2713 Extensions added!"));
|
|
836
854
|
}
|
|
837
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
|
+
|
|
838
1049
|
// src/index.ts
|
|
839
1050
|
var program = new import_commander.Command();
|
|
840
|
-
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");
|
|
841
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) => {
|
|
842
1053
|
await runWizard({ force: options.force });
|
|
843
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
|
+
});
|
|
844
1106
|
program.command("status").description("Show current ADHDev setup status").action(() => {
|
|
845
1107
|
const config = loadConfig();
|
|
846
1108
|
console.log(import_chalk2.default.bold("\n\u{1F309} ADHDev Status\n"));
|