adhdev 0.1.45 → 0.1.46
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 +635 -602
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -658,413 +658,6 @@ var init_provider_loader = __esm({
|
|
|
658
658
|
}
|
|
659
659
|
});
|
|
660
660
|
|
|
661
|
-
// src/cli-detector.ts
|
|
662
|
-
async function detectCLIs() {
|
|
663
|
-
const platform7 = os2.platform();
|
|
664
|
-
const whichCmd = platform7 === "win32" ? "where" : "which";
|
|
665
|
-
const results = [];
|
|
666
|
-
for (const cli of KNOWN_CLIS) {
|
|
667
|
-
try {
|
|
668
|
-
const pathResult = (0, import_child_process3.execSync)(`${whichCmd} ${cli.command} 2>/dev/null`, {
|
|
669
|
-
encoding: "utf-8",
|
|
670
|
-
timeout: 5e3,
|
|
671
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
672
|
-
}).trim().split("\n")[0];
|
|
673
|
-
if (!pathResult) throw new Error("Not found");
|
|
674
|
-
let version;
|
|
675
|
-
try {
|
|
676
|
-
const versionResult = (0, import_child_process3.execSync)(`${cli.command} --version 2>/dev/null`, {
|
|
677
|
-
encoding: "utf-8",
|
|
678
|
-
timeout: 5e3,
|
|
679
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
680
|
-
}).trim();
|
|
681
|
-
const match = versionResult.match(/(\d+\.\d+[\.\d]*)/);
|
|
682
|
-
version = match ? match[1] : versionResult.split("\n")[0].slice(0, 30);
|
|
683
|
-
} catch {
|
|
684
|
-
}
|
|
685
|
-
results.push({ ...cli, installed: true, version, path: pathResult });
|
|
686
|
-
} catch {
|
|
687
|
-
results.push({ ...cli, installed: false });
|
|
688
|
-
}
|
|
689
|
-
}
|
|
690
|
-
return results;
|
|
691
|
-
}
|
|
692
|
-
async function detectCLI(cliId) {
|
|
693
|
-
const normalizedId = cliId === "claude-cli" ? "claude-code" : cliId;
|
|
694
|
-
const all = await detectCLIs();
|
|
695
|
-
return all.find((c) => c.id === normalizedId && c.installed) || null;
|
|
696
|
-
}
|
|
697
|
-
var import_child_process3, os2, KNOWN_CLIS;
|
|
698
|
-
var init_cli_detector = __esm({
|
|
699
|
-
"src/cli-detector.ts"() {
|
|
700
|
-
"use strict";
|
|
701
|
-
import_child_process3 = require("child_process");
|
|
702
|
-
os2 = __toESM(require("os"));
|
|
703
|
-
KNOWN_CLIS = [
|
|
704
|
-
{ id: "gemini-cli", displayName: "Gemini CLI", icon: "\u264A", command: "gemini" },
|
|
705
|
-
{ id: "claude-code", displayName: "Claude Code", icon: "\u{1F916}", command: "claude" },
|
|
706
|
-
{ id: "codex-cli", displayName: "Codex CLI", icon: "\u{1F9E0}", command: "codex" }
|
|
707
|
-
];
|
|
708
|
-
}
|
|
709
|
-
});
|
|
710
|
-
|
|
711
|
-
// src/launch.ts
|
|
712
|
-
function getProviderLoader() {
|
|
713
|
-
if (!_providerLoader) {
|
|
714
|
-
_providerLoader = new ProviderLoader({ logFn: () => {
|
|
715
|
-
} });
|
|
716
|
-
_providerLoader.loadAll();
|
|
717
|
-
_providerLoader.registerToDetector();
|
|
718
|
-
}
|
|
719
|
-
return _providerLoader;
|
|
720
|
-
}
|
|
721
|
-
function getCdpPorts() {
|
|
722
|
-
return getProviderLoader().getCdpPortMap();
|
|
723
|
-
}
|
|
724
|
-
function getMacAppIdentifiers() {
|
|
725
|
-
return getProviderLoader().getMacAppIdentifiers();
|
|
726
|
-
}
|
|
727
|
-
function getWinProcessNames() {
|
|
728
|
-
return getProviderLoader().getWinProcessNames();
|
|
729
|
-
}
|
|
730
|
-
async function findFreePort(ports) {
|
|
731
|
-
for (const port2 of ports) {
|
|
732
|
-
const free = await checkPortFree(port2);
|
|
733
|
-
if (free) return port2;
|
|
734
|
-
}
|
|
735
|
-
let port = ports[1] + 1;
|
|
736
|
-
while (port < ports[1] + 10) {
|
|
737
|
-
if (await checkPortFree(port)) return port;
|
|
738
|
-
port++;
|
|
739
|
-
}
|
|
740
|
-
throw new Error("No free port found");
|
|
741
|
-
}
|
|
742
|
-
function checkPortFree(port) {
|
|
743
|
-
return new Promise((resolve5) => {
|
|
744
|
-
const server = net.createServer();
|
|
745
|
-
server.unref();
|
|
746
|
-
server.on("error", () => resolve5(false));
|
|
747
|
-
server.listen(port, "127.0.0.1", () => {
|
|
748
|
-
server.close(() => resolve5(true));
|
|
749
|
-
});
|
|
750
|
-
});
|
|
751
|
-
}
|
|
752
|
-
async function isCdpActive(port) {
|
|
753
|
-
return new Promise((resolve5) => {
|
|
754
|
-
const req = require("http").get(`http://127.0.0.1:${port}/json/version`, {
|
|
755
|
-
timeout: 2e3
|
|
756
|
-
}, (res) => {
|
|
757
|
-
let data = "";
|
|
758
|
-
res.on("data", (c) => data += c);
|
|
759
|
-
res.on("end", () => {
|
|
760
|
-
try {
|
|
761
|
-
const info = JSON.parse(data);
|
|
762
|
-
resolve5(!!info["WebKit-Version"] || !!info["Browser"]);
|
|
763
|
-
} catch {
|
|
764
|
-
resolve5(false);
|
|
765
|
-
}
|
|
766
|
-
});
|
|
767
|
-
});
|
|
768
|
-
req.on("error", () => resolve5(false));
|
|
769
|
-
req.on("timeout", () => {
|
|
770
|
-
req.destroy();
|
|
771
|
-
resolve5(false);
|
|
772
|
-
});
|
|
773
|
-
});
|
|
774
|
-
}
|
|
775
|
-
async function killIdeProcess(ideId) {
|
|
776
|
-
const plat = os3.platform();
|
|
777
|
-
const appName = getMacAppIdentifiers()[ideId];
|
|
778
|
-
const winProcesses = getWinProcessNames()[ideId];
|
|
779
|
-
try {
|
|
780
|
-
if (plat === "darwin" && appName) {
|
|
781
|
-
try {
|
|
782
|
-
(0, import_child_process4.execSync)(`osascript -e 'tell application "${appName}" to quit' 2>/dev/null`, {
|
|
783
|
-
timeout: 5e3
|
|
784
|
-
});
|
|
785
|
-
} catch {
|
|
786
|
-
try {
|
|
787
|
-
(0, import_child_process4.execSync)(`pkill -f "${appName}" 2>/dev/null`);
|
|
788
|
-
} catch {
|
|
789
|
-
}
|
|
790
|
-
}
|
|
791
|
-
} else if (plat === "win32" && winProcesses) {
|
|
792
|
-
for (const proc of winProcesses) {
|
|
793
|
-
try {
|
|
794
|
-
(0, import_child_process4.execSync)(`taskkill /IM "${proc}" /F 2>nul`, { timeout: 5e3 });
|
|
795
|
-
} catch {
|
|
796
|
-
}
|
|
797
|
-
}
|
|
798
|
-
try {
|
|
799
|
-
const exeName = winProcesses[0].replace(".exe", "");
|
|
800
|
-
(0, import_child_process4.execSync)(`powershell -Command "Get-Process -Name '${exeName}' -ErrorAction SilentlyContinue | Stop-Process -Force"`, {
|
|
801
|
-
timeout: 1e4
|
|
802
|
-
});
|
|
803
|
-
} catch {
|
|
804
|
-
}
|
|
805
|
-
} else {
|
|
806
|
-
try {
|
|
807
|
-
(0, import_child_process4.execSync)(`pkill -f "${ideId}" 2>/dev/null`);
|
|
808
|
-
} catch {
|
|
809
|
-
}
|
|
810
|
-
}
|
|
811
|
-
for (let i = 0; i < 30; i++) {
|
|
812
|
-
await new Promise((r) => setTimeout(r, 500));
|
|
813
|
-
if (!isIdeRunning(ideId)) return true;
|
|
814
|
-
}
|
|
815
|
-
if (plat === "darwin" && appName) {
|
|
816
|
-
try {
|
|
817
|
-
(0, import_child_process4.execSync)(`pkill -9 -f "${appName}" 2>/dev/null`);
|
|
818
|
-
} catch {
|
|
819
|
-
}
|
|
820
|
-
} else if (plat === "win32" && winProcesses) {
|
|
821
|
-
for (const proc of winProcesses) {
|
|
822
|
-
try {
|
|
823
|
-
(0, import_child_process4.execSync)(`taskkill /IM "${proc}" /F 2>nul`);
|
|
824
|
-
} catch {
|
|
825
|
-
}
|
|
826
|
-
}
|
|
827
|
-
}
|
|
828
|
-
await new Promise((r) => setTimeout(r, 2e3));
|
|
829
|
-
return !isIdeRunning(ideId);
|
|
830
|
-
} catch {
|
|
831
|
-
return false;
|
|
832
|
-
}
|
|
833
|
-
}
|
|
834
|
-
function isIdeRunning(ideId) {
|
|
835
|
-
const plat = os3.platform();
|
|
836
|
-
try {
|
|
837
|
-
if (plat === "darwin") {
|
|
838
|
-
const appName = getMacAppIdentifiers()[ideId];
|
|
839
|
-
if (!appName) return false;
|
|
840
|
-
const result = (0, import_child_process4.execSync)(`pgrep -f "${appName}" 2>/dev/null`, { encoding: "utf-8" });
|
|
841
|
-
return result.trim().length > 0;
|
|
842
|
-
} else if (plat === "win32") {
|
|
843
|
-
const winProcesses = getWinProcessNames()[ideId];
|
|
844
|
-
if (!winProcesses) return false;
|
|
845
|
-
for (const proc of winProcesses) {
|
|
846
|
-
try {
|
|
847
|
-
const result = (0, import_child_process4.execSync)(`tasklist /FI "IMAGENAME eq ${proc}" /NH 2>nul`, { encoding: "utf-8" });
|
|
848
|
-
if (result.includes(proc)) return true;
|
|
849
|
-
} catch {
|
|
850
|
-
}
|
|
851
|
-
}
|
|
852
|
-
try {
|
|
853
|
-
const exeName = winProcesses[0].replace(".exe", "");
|
|
854
|
-
const result = (0, import_child_process4.execSync)(
|
|
855
|
-
`powershell -Command "(Get-Process -Name '${exeName}' -ErrorAction SilentlyContinue).Count"`,
|
|
856
|
-
{ encoding: "utf-8", timeout: 5e3 }
|
|
857
|
-
);
|
|
858
|
-
return parseInt(result.trim()) > 0;
|
|
859
|
-
} catch {
|
|
860
|
-
}
|
|
861
|
-
return false;
|
|
862
|
-
} else {
|
|
863
|
-
const result = (0, import_child_process4.execSync)(`pgrep -f "${ideId}" 2>/dev/null`, { encoding: "utf-8" });
|
|
864
|
-
return result.trim().length > 0;
|
|
865
|
-
}
|
|
866
|
-
} catch {
|
|
867
|
-
return false;
|
|
868
|
-
}
|
|
869
|
-
}
|
|
870
|
-
function detectCurrentWorkspace(ideId) {
|
|
871
|
-
const plat = os3.platform();
|
|
872
|
-
if (plat === "darwin") {
|
|
873
|
-
try {
|
|
874
|
-
const appName = getMacAppIdentifiers()[ideId];
|
|
875
|
-
if (!appName) return void 0;
|
|
876
|
-
const result = (0, import_child_process4.execSync)(
|
|
877
|
-
`lsof -c "${appName}" 2>/dev/null | grep cwd | head -1 | awk '{print $NF}'`,
|
|
878
|
-
{ encoding: "utf-8", timeout: 3e3 }
|
|
879
|
-
);
|
|
880
|
-
const dir = result.trim();
|
|
881
|
-
if (dir && dir !== "/") return dir;
|
|
882
|
-
} catch {
|
|
883
|
-
}
|
|
884
|
-
} else if (plat === "win32") {
|
|
885
|
-
try {
|
|
886
|
-
const fs7 = require("fs");
|
|
887
|
-
const appNameMap = getMacAppIdentifiers();
|
|
888
|
-
const appName = appNameMap[ideId];
|
|
889
|
-
if (appName) {
|
|
890
|
-
const storagePath = path2.join(
|
|
891
|
-
process.env.APPDATA || path2.join(os3.homedir(), "AppData", "Roaming"),
|
|
892
|
-
appName,
|
|
893
|
-
"storage.json"
|
|
894
|
-
);
|
|
895
|
-
if (fs7.existsSync(storagePath)) {
|
|
896
|
-
const data = JSON.parse(fs7.readFileSync(storagePath, "utf-8"));
|
|
897
|
-
const workspaces = data?.openedPathsList?.workspaces3 || data?.openedPathsList?.entries || [];
|
|
898
|
-
if (workspaces.length > 0) {
|
|
899
|
-
const recent = workspaces[0];
|
|
900
|
-
const uri = typeof recent === "string" ? recent : recent?.folderUri;
|
|
901
|
-
if (uri?.startsWith("file:///")) {
|
|
902
|
-
return decodeURIComponent(uri.replace("file:///", ""));
|
|
903
|
-
}
|
|
904
|
-
}
|
|
905
|
-
}
|
|
906
|
-
}
|
|
907
|
-
} catch {
|
|
908
|
-
}
|
|
909
|
-
}
|
|
910
|
-
return void 0;
|
|
911
|
-
}
|
|
912
|
-
async function launchWithCdp(options = {}) {
|
|
913
|
-
const platform7 = os3.platform();
|
|
914
|
-
let targetIde;
|
|
915
|
-
const ides = await detectIDEs();
|
|
916
|
-
if (options.ideId) {
|
|
917
|
-
targetIde = ides.find((i) => i.id === options.ideId && i.installed);
|
|
918
|
-
if (!targetIde) {
|
|
919
|
-
return {
|
|
920
|
-
success: false,
|
|
921
|
-
ideId: options.ideId,
|
|
922
|
-
ideName: options.ideId,
|
|
923
|
-
port: 0,
|
|
924
|
-
action: "failed",
|
|
925
|
-
message: "",
|
|
926
|
-
error: `IDE '${options.ideId}' not found or not installed`
|
|
927
|
-
};
|
|
928
|
-
}
|
|
929
|
-
} else {
|
|
930
|
-
const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
931
|
-
const config = loadConfig2();
|
|
932
|
-
if (config.selectedIde) {
|
|
933
|
-
targetIde = ides.find((i) => i.id === config.selectedIde && i.installed);
|
|
934
|
-
}
|
|
935
|
-
if (!targetIde) {
|
|
936
|
-
targetIde = ides.find((i) => i.installed);
|
|
937
|
-
}
|
|
938
|
-
if (!targetIde) {
|
|
939
|
-
return {
|
|
940
|
-
success: false,
|
|
941
|
-
ideId: "unknown",
|
|
942
|
-
ideName: "Unknown",
|
|
943
|
-
port: 0,
|
|
944
|
-
action: "failed",
|
|
945
|
-
message: "",
|
|
946
|
-
error: "No IDE found. Install VS Code, Cursor, or Antigravity first."
|
|
947
|
-
};
|
|
948
|
-
}
|
|
949
|
-
}
|
|
950
|
-
const portPair = getCdpPorts()[targetIde.id] || [9333, 9334];
|
|
951
|
-
for (const port2 of portPair) {
|
|
952
|
-
if (await isCdpActive(port2)) {
|
|
953
|
-
return {
|
|
954
|
-
success: true,
|
|
955
|
-
ideId: targetIde.id,
|
|
956
|
-
ideName: targetIde.displayName,
|
|
957
|
-
port: port2,
|
|
958
|
-
action: "reused",
|
|
959
|
-
message: `CDP already active on port ${port2}`
|
|
960
|
-
};
|
|
961
|
-
}
|
|
962
|
-
}
|
|
963
|
-
const alreadyRunning = isIdeRunning(targetIde.id);
|
|
964
|
-
const workspace = options.workspace || (alreadyRunning ? detectCurrentWorkspace(targetIde.id) : void 0);
|
|
965
|
-
if (alreadyRunning) {
|
|
966
|
-
const killed = await killIdeProcess(targetIde.id);
|
|
967
|
-
if (!killed) {
|
|
968
|
-
return {
|
|
969
|
-
success: false,
|
|
970
|
-
ideId: targetIde.id,
|
|
971
|
-
ideName: targetIde.displayName,
|
|
972
|
-
port: 0,
|
|
973
|
-
action: "failed",
|
|
974
|
-
message: "",
|
|
975
|
-
error: `Could not stop ${targetIde.displayName}. Close it manually and try again.`
|
|
976
|
-
};
|
|
977
|
-
}
|
|
978
|
-
await new Promise((r) => setTimeout(r, 3e3));
|
|
979
|
-
}
|
|
980
|
-
const port = await findFreePort(portPair);
|
|
981
|
-
try {
|
|
982
|
-
if (platform7 === "darwin") {
|
|
983
|
-
await launchMacOS(targetIde, port, workspace, options.newWindow);
|
|
984
|
-
} else if (platform7 === "win32") {
|
|
985
|
-
await launchWindows(targetIde, port, workspace, options.newWindow);
|
|
986
|
-
} else {
|
|
987
|
-
await launchLinux(targetIde, port, workspace, options.newWindow);
|
|
988
|
-
}
|
|
989
|
-
let cdpReady = false;
|
|
990
|
-
for (let i = 0; i < 30; i++) {
|
|
991
|
-
await new Promise((r) => setTimeout(r, 500));
|
|
992
|
-
if (await isCdpActive(port)) {
|
|
993
|
-
cdpReady = true;
|
|
994
|
-
break;
|
|
995
|
-
}
|
|
996
|
-
}
|
|
997
|
-
return {
|
|
998
|
-
success: true,
|
|
999
|
-
ideId: targetIde.id,
|
|
1000
|
-
ideName: targetIde.displayName,
|
|
1001
|
-
port,
|
|
1002
|
-
action: alreadyRunning ? "restarted" : "started",
|
|
1003
|
-
message: cdpReady ? `${targetIde.displayName} launched with CDP on port ${port}` : `${targetIde.displayName} launched (CDP may take a moment to initialize)`
|
|
1004
|
-
};
|
|
1005
|
-
} catch (e) {
|
|
1006
|
-
return {
|
|
1007
|
-
success: false,
|
|
1008
|
-
ideId: targetIde.id,
|
|
1009
|
-
ideName: targetIde.displayName,
|
|
1010
|
-
port,
|
|
1011
|
-
action: "failed",
|
|
1012
|
-
message: "",
|
|
1013
|
-
error: e?.message || String(e)
|
|
1014
|
-
};
|
|
1015
|
-
}
|
|
1016
|
-
}
|
|
1017
|
-
async function launchMacOS(ide, port, workspace, newWindow) {
|
|
1018
|
-
const appName = getMacAppIdentifiers()[ide.id];
|
|
1019
|
-
const args = ["--remote-debugging-port=" + port];
|
|
1020
|
-
if (newWindow) args.push("--new-window");
|
|
1021
|
-
if (workspace) args.push(workspace);
|
|
1022
|
-
if (appName) {
|
|
1023
|
-
const openArgs = ["-a", appName, "--args", ...args];
|
|
1024
|
-
(0, import_child_process4.spawn)("open", openArgs, { detached: true, stdio: "ignore" }).unref();
|
|
1025
|
-
} else if (ide.cliCommand) {
|
|
1026
|
-
(0, import_child_process4.spawn)(ide.cliCommand, args, { detached: true, stdio: "ignore" }).unref();
|
|
1027
|
-
} else {
|
|
1028
|
-
throw new Error(`No app identifier or CLI for ${ide.displayName}`);
|
|
1029
|
-
}
|
|
1030
|
-
}
|
|
1031
|
-
async function launchWindows(ide, port, workspace, newWindow) {
|
|
1032
|
-
const cli = ide.cliCommand;
|
|
1033
|
-
if (!cli) {
|
|
1034
|
-
throw new Error(`No CLI command for ${ide.displayName}. Please add it to PATH.`);
|
|
1035
|
-
}
|
|
1036
|
-
const parts = [`"${cli}"`, `--remote-debugging-port=${port}`];
|
|
1037
|
-
if (newWindow) parts.push("--new-window");
|
|
1038
|
-
if (workspace) parts.push(`"${workspace}"`);
|
|
1039
|
-
const fullCmd = parts.join(" ");
|
|
1040
|
-
const { exec: execCmd } = require("child_process");
|
|
1041
|
-
execCmd(fullCmd, { windowsHide: true }, () => {
|
|
1042
|
-
});
|
|
1043
|
-
}
|
|
1044
|
-
async function launchLinux(ide, port, workspace, newWindow) {
|
|
1045
|
-
const cli = ide.cliCommand;
|
|
1046
|
-
if (!cli) {
|
|
1047
|
-
throw new Error(`No CLI command for ${ide.displayName}. Make sure it's in PATH.`);
|
|
1048
|
-
}
|
|
1049
|
-
const args = ["--remote-debugging-port=" + port];
|
|
1050
|
-
if (newWindow) args.push("--new-window");
|
|
1051
|
-
if (workspace) args.push(workspace);
|
|
1052
|
-
(0, import_child_process4.spawn)(cli, args, { detached: true, stdio: "ignore" }).unref();
|
|
1053
|
-
}
|
|
1054
|
-
var import_child_process4, net, os3, path2, _providerLoader;
|
|
1055
|
-
var init_launch = __esm({
|
|
1056
|
-
"src/launch.ts"() {
|
|
1057
|
-
"use strict";
|
|
1058
|
-
import_child_process4 = require("child_process");
|
|
1059
|
-
net = __toESM(require("net"));
|
|
1060
|
-
os3 = __toESM(require("os"));
|
|
1061
|
-
path2 = __toESM(require("path"));
|
|
1062
|
-
init_detector();
|
|
1063
|
-
init_provider_loader();
|
|
1064
|
-
_providerLoader = null;
|
|
1065
|
-
}
|
|
1066
|
-
});
|
|
1067
|
-
|
|
1068
661
|
// src/cli-bridge.ts
|
|
1069
662
|
var import_ws, CliBridgeConnection;
|
|
1070
663
|
var init_cli_bridge = __esm({
|
|
@@ -1552,6 +1145,363 @@ var init_local_server = __esm({
|
|
|
1552
1145
|
}
|
|
1553
1146
|
});
|
|
1554
1147
|
|
|
1148
|
+
// src/launch.ts
|
|
1149
|
+
function getProviderLoader() {
|
|
1150
|
+
if (!_providerLoader) {
|
|
1151
|
+
_providerLoader = new ProviderLoader({ logFn: () => {
|
|
1152
|
+
} });
|
|
1153
|
+
_providerLoader.loadAll();
|
|
1154
|
+
_providerLoader.registerToDetector();
|
|
1155
|
+
}
|
|
1156
|
+
return _providerLoader;
|
|
1157
|
+
}
|
|
1158
|
+
function getCdpPorts() {
|
|
1159
|
+
return getProviderLoader().getCdpPortMap();
|
|
1160
|
+
}
|
|
1161
|
+
function getMacAppIdentifiers() {
|
|
1162
|
+
return getProviderLoader().getMacAppIdentifiers();
|
|
1163
|
+
}
|
|
1164
|
+
function getWinProcessNames() {
|
|
1165
|
+
return getProviderLoader().getWinProcessNames();
|
|
1166
|
+
}
|
|
1167
|
+
async function findFreePort(ports) {
|
|
1168
|
+
for (const port2 of ports) {
|
|
1169
|
+
const free = await checkPortFree(port2);
|
|
1170
|
+
if (free) return port2;
|
|
1171
|
+
}
|
|
1172
|
+
let port = ports[1] + 1;
|
|
1173
|
+
while (port < ports[1] + 10) {
|
|
1174
|
+
if (await checkPortFree(port)) return port;
|
|
1175
|
+
port++;
|
|
1176
|
+
}
|
|
1177
|
+
throw new Error("No free port found");
|
|
1178
|
+
}
|
|
1179
|
+
function checkPortFree(port) {
|
|
1180
|
+
return new Promise((resolve5) => {
|
|
1181
|
+
const server = net.createServer();
|
|
1182
|
+
server.unref();
|
|
1183
|
+
server.on("error", () => resolve5(false));
|
|
1184
|
+
server.listen(port, "127.0.0.1", () => {
|
|
1185
|
+
server.close(() => resolve5(true));
|
|
1186
|
+
});
|
|
1187
|
+
});
|
|
1188
|
+
}
|
|
1189
|
+
async function isCdpActive(port) {
|
|
1190
|
+
return new Promise((resolve5) => {
|
|
1191
|
+
const req = require("http").get(`http://127.0.0.1:${port}/json/version`, {
|
|
1192
|
+
timeout: 2e3
|
|
1193
|
+
}, (res) => {
|
|
1194
|
+
let data = "";
|
|
1195
|
+
res.on("data", (c) => data += c);
|
|
1196
|
+
res.on("end", () => {
|
|
1197
|
+
try {
|
|
1198
|
+
const info = JSON.parse(data);
|
|
1199
|
+
resolve5(!!info["WebKit-Version"] || !!info["Browser"]);
|
|
1200
|
+
} catch {
|
|
1201
|
+
resolve5(false);
|
|
1202
|
+
}
|
|
1203
|
+
});
|
|
1204
|
+
});
|
|
1205
|
+
req.on("error", () => resolve5(false));
|
|
1206
|
+
req.on("timeout", () => {
|
|
1207
|
+
req.destroy();
|
|
1208
|
+
resolve5(false);
|
|
1209
|
+
});
|
|
1210
|
+
});
|
|
1211
|
+
}
|
|
1212
|
+
async function killIdeProcess(ideId) {
|
|
1213
|
+
const plat = os2.platform();
|
|
1214
|
+
const appName = getMacAppIdentifiers()[ideId];
|
|
1215
|
+
const winProcesses = getWinProcessNames()[ideId];
|
|
1216
|
+
try {
|
|
1217
|
+
if (plat === "darwin" && appName) {
|
|
1218
|
+
try {
|
|
1219
|
+
(0, import_child_process3.execSync)(`osascript -e 'tell application "${appName}" to quit' 2>/dev/null`, {
|
|
1220
|
+
timeout: 5e3
|
|
1221
|
+
});
|
|
1222
|
+
} catch {
|
|
1223
|
+
try {
|
|
1224
|
+
(0, import_child_process3.execSync)(`pkill -f "${appName}" 2>/dev/null`);
|
|
1225
|
+
} catch {
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
} else if (plat === "win32" && winProcesses) {
|
|
1229
|
+
for (const proc of winProcesses) {
|
|
1230
|
+
try {
|
|
1231
|
+
(0, import_child_process3.execSync)(`taskkill /IM "${proc}" /F 2>nul`, { timeout: 5e3 });
|
|
1232
|
+
} catch {
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
try {
|
|
1236
|
+
const exeName = winProcesses[0].replace(".exe", "");
|
|
1237
|
+
(0, import_child_process3.execSync)(`powershell -Command "Get-Process -Name '${exeName}' -ErrorAction SilentlyContinue | Stop-Process -Force"`, {
|
|
1238
|
+
timeout: 1e4
|
|
1239
|
+
});
|
|
1240
|
+
} catch {
|
|
1241
|
+
}
|
|
1242
|
+
} else {
|
|
1243
|
+
try {
|
|
1244
|
+
(0, import_child_process3.execSync)(`pkill -f "${ideId}" 2>/dev/null`);
|
|
1245
|
+
} catch {
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
for (let i = 0; i < 30; i++) {
|
|
1249
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
1250
|
+
if (!isIdeRunning(ideId)) return true;
|
|
1251
|
+
}
|
|
1252
|
+
if (plat === "darwin" && appName) {
|
|
1253
|
+
try {
|
|
1254
|
+
(0, import_child_process3.execSync)(`pkill -9 -f "${appName}" 2>/dev/null`);
|
|
1255
|
+
} catch {
|
|
1256
|
+
}
|
|
1257
|
+
} else if (plat === "win32" && winProcesses) {
|
|
1258
|
+
for (const proc of winProcesses) {
|
|
1259
|
+
try {
|
|
1260
|
+
(0, import_child_process3.execSync)(`taskkill /IM "${proc}" /F 2>nul`);
|
|
1261
|
+
} catch {
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
await new Promise((r) => setTimeout(r, 2e3));
|
|
1266
|
+
return !isIdeRunning(ideId);
|
|
1267
|
+
} catch {
|
|
1268
|
+
return false;
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
function isIdeRunning(ideId) {
|
|
1272
|
+
const plat = os2.platform();
|
|
1273
|
+
try {
|
|
1274
|
+
if (plat === "darwin") {
|
|
1275
|
+
const appName = getMacAppIdentifiers()[ideId];
|
|
1276
|
+
if (!appName) return false;
|
|
1277
|
+
const result = (0, import_child_process3.execSync)(`pgrep -f "${appName}" 2>/dev/null`, { encoding: "utf-8" });
|
|
1278
|
+
return result.trim().length > 0;
|
|
1279
|
+
} else if (plat === "win32") {
|
|
1280
|
+
const winProcesses = getWinProcessNames()[ideId];
|
|
1281
|
+
if (!winProcesses) return false;
|
|
1282
|
+
for (const proc of winProcesses) {
|
|
1283
|
+
try {
|
|
1284
|
+
const result = (0, import_child_process3.execSync)(`tasklist /FI "IMAGENAME eq ${proc}" /NH 2>nul`, { encoding: "utf-8" });
|
|
1285
|
+
if (result.includes(proc)) return true;
|
|
1286
|
+
} catch {
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
try {
|
|
1290
|
+
const exeName = winProcesses[0].replace(".exe", "");
|
|
1291
|
+
const result = (0, import_child_process3.execSync)(
|
|
1292
|
+
`powershell -Command "(Get-Process -Name '${exeName}' -ErrorAction SilentlyContinue).Count"`,
|
|
1293
|
+
{ encoding: "utf-8", timeout: 5e3 }
|
|
1294
|
+
);
|
|
1295
|
+
return parseInt(result.trim()) > 0;
|
|
1296
|
+
} catch {
|
|
1297
|
+
}
|
|
1298
|
+
return false;
|
|
1299
|
+
} else {
|
|
1300
|
+
const result = (0, import_child_process3.execSync)(`pgrep -f "${ideId}" 2>/dev/null`, { encoding: "utf-8" });
|
|
1301
|
+
return result.trim().length > 0;
|
|
1302
|
+
}
|
|
1303
|
+
} catch {
|
|
1304
|
+
return false;
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1307
|
+
function detectCurrentWorkspace(ideId) {
|
|
1308
|
+
const plat = os2.platform();
|
|
1309
|
+
if (plat === "darwin") {
|
|
1310
|
+
try {
|
|
1311
|
+
const appName = getMacAppIdentifiers()[ideId];
|
|
1312
|
+
if (!appName) return void 0;
|
|
1313
|
+
const result = (0, import_child_process3.execSync)(
|
|
1314
|
+
`lsof -c "${appName}" 2>/dev/null | grep cwd | head -1 | awk '{print $NF}'`,
|
|
1315
|
+
{ encoding: "utf-8", timeout: 3e3 }
|
|
1316
|
+
);
|
|
1317
|
+
const dir = result.trim();
|
|
1318
|
+
if (dir && dir !== "/") return dir;
|
|
1319
|
+
} catch {
|
|
1320
|
+
}
|
|
1321
|
+
} else if (plat === "win32") {
|
|
1322
|
+
try {
|
|
1323
|
+
const fs7 = require("fs");
|
|
1324
|
+
const appNameMap = getMacAppIdentifiers();
|
|
1325
|
+
const appName = appNameMap[ideId];
|
|
1326
|
+
if (appName) {
|
|
1327
|
+
const storagePath = path2.join(
|
|
1328
|
+
process.env.APPDATA || path2.join(os2.homedir(), "AppData", "Roaming"),
|
|
1329
|
+
appName,
|
|
1330
|
+
"storage.json"
|
|
1331
|
+
);
|
|
1332
|
+
if (fs7.existsSync(storagePath)) {
|
|
1333
|
+
const data = JSON.parse(fs7.readFileSync(storagePath, "utf-8"));
|
|
1334
|
+
const workspaces = data?.openedPathsList?.workspaces3 || data?.openedPathsList?.entries || [];
|
|
1335
|
+
if (workspaces.length > 0) {
|
|
1336
|
+
const recent = workspaces[0];
|
|
1337
|
+
const uri = typeof recent === "string" ? recent : recent?.folderUri;
|
|
1338
|
+
if (uri?.startsWith("file:///")) {
|
|
1339
|
+
return decodeURIComponent(uri.replace("file:///", ""));
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1344
|
+
} catch {
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1347
|
+
return void 0;
|
|
1348
|
+
}
|
|
1349
|
+
async function launchWithCdp(options = {}) {
|
|
1350
|
+
const platform7 = os2.platform();
|
|
1351
|
+
let targetIde;
|
|
1352
|
+
const ides = await detectIDEs();
|
|
1353
|
+
if (options.ideId) {
|
|
1354
|
+
targetIde = ides.find((i) => i.id === options.ideId && i.installed);
|
|
1355
|
+
if (!targetIde) {
|
|
1356
|
+
return {
|
|
1357
|
+
success: false,
|
|
1358
|
+
ideId: options.ideId,
|
|
1359
|
+
ideName: options.ideId,
|
|
1360
|
+
port: 0,
|
|
1361
|
+
action: "failed",
|
|
1362
|
+
message: "",
|
|
1363
|
+
error: `IDE '${options.ideId}' not found or not installed`
|
|
1364
|
+
};
|
|
1365
|
+
}
|
|
1366
|
+
} else {
|
|
1367
|
+
const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
1368
|
+
const config = loadConfig2();
|
|
1369
|
+
if (config.selectedIde) {
|
|
1370
|
+
targetIde = ides.find((i) => i.id === config.selectedIde && i.installed);
|
|
1371
|
+
}
|
|
1372
|
+
if (!targetIde) {
|
|
1373
|
+
targetIde = ides.find((i) => i.installed);
|
|
1374
|
+
}
|
|
1375
|
+
if (!targetIde) {
|
|
1376
|
+
return {
|
|
1377
|
+
success: false,
|
|
1378
|
+
ideId: "unknown",
|
|
1379
|
+
ideName: "Unknown",
|
|
1380
|
+
port: 0,
|
|
1381
|
+
action: "failed",
|
|
1382
|
+
message: "",
|
|
1383
|
+
error: "No IDE found. Install VS Code, Cursor, or Antigravity first."
|
|
1384
|
+
};
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
const portPair = getCdpPorts()[targetIde.id] || [9333, 9334];
|
|
1388
|
+
for (const port2 of portPair) {
|
|
1389
|
+
if (await isCdpActive(port2)) {
|
|
1390
|
+
return {
|
|
1391
|
+
success: true,
|
|
1392
|
+
ideId: targetIde.id,
|
|
1393
|
+
ideName: targetIde.displayName,
|
|
1394
|
+
port: port2,
|
|
1395
|
+
action: "reused",
|
|
1396
|
+
message: `CDP already active on port ${port2}`
|
|
1397
|
+
};
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
const alreadyRunning = isIdeRunning(targetIde.id);
|
|
1401
|
+
const workspace = options.workspace || (alreadyRunning ? detectCurrentWorkspace(targetIde.id) : void 0);
|
|
1402
|
+
if (alreadyRunning) {
|
|
1403
|
+
const killed = await killIdeProcess(targetIde.id);
|
|
1404
|
+
if (!killed) {
|
|
1405
|
+
return {
|
|
1406
|
+
success: false,
|
|
1407
|
+
ideId: targetIde.id,
|
|
1408
|
+
ideName: targetIde.displayName,
|
|
1409
|
+
port: 0,
|
|
1410
|
+
action: "failed",
|
|
1411
|
+
message: "",
|
|
1412
|
+
error: `Could not stop ${targetIde.displayName}. Close it manually and try again.`
|
|
1413
|
+
};
|
|
1414
|
+
}
|
|
1415
|
+
await new Promise((r) => setTimeout(r, 3e3));
|
|
1416
|
+
}
|
|
1417
|
+
const port = await findFreePort(portPair);
|
|
1418
|
+
try {
|
|
1419
|
+
if (platform7 === "darwin") {
|
|
1420
|
+
await launchMacOS(targetIde, port, workspace, options.newWindow);
|
|
1421
|
+
} else if (platform7 === "win32") {
|
|
1422
|
+
await launchWindows(targetIde, port, workspace, options.newWindow);
|
|
1423
|
+
} else {
|
|
1424
|
+
await launchLinux(targetIde, port, workspace, options.newWindow);
|
|
1425
|
+
}
|
|
1426
|
+
let cdpReady = false;
|
|
1427
|
+
for (let i = 0; i < 30; i++) {
|
|
1428
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
1429
|
+
if (await isCdpActive(port)) {
|
|
1430
|
+
cdpReady = true;
|
|
1431
|
+
break;
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
return {
|
|
1435
|
+
success: true,
|
|
1436
|
+
ideId: targetIde.id,
|
|
1437
|
+
ideName: targetIde.displayName,
|
|
1438
|
+
port,
|
|
1439
|
+
action: alreadyRunning ? "restarted" : "started",
|
|
1440
|
+
message: cdpReady ? `${targetIde.displayName} launched with CDP on port ${port}` : `${targetIde.displayName} launched (CDP may take a moment to initialize)`
|
|
1441
|
+
};
|
|
1442
|
+
} catch (e) {
|
|
1443
|
+
return {
|
|
1444
|
+
success: false,
|
|
1445
|
+
ideId: targetIde.id,
|
|
1446
|
+
ideName: targetIde.displayName,
|
|
1447
|
+
port,
|
|
1448
|
+
action: "failed",
|
|
1449
|
+
message: "",
|
|
1450
|
+
error: e?.message || String(e)
|
|
1451
|
+
};
|
|
1452
|
+
}
|
|
1453
|
+
}
|
|
1454
|
+
async function launchMacOS(ide, port, workspace, newWindow) {
|
|
1455
|
+
const appName = getMacAppIdentifiers()[ide.id];
|
|
1456
|
+
const args = ["--remote-debugging-port=" + port];
|
|
1457
|
+
if (newWindow) args.push("--new-window");
|
|
1458
|
+
if (workspace) args.push(workspace);
|
|
1459
|
+
if (appName) {
|
|
1460
|
+
const openArgs = ["-a", appName, "--args", ...args];
|
|
1461
|
+
(0, import_child_process3.spawn)("open", openArgs, { detached: true, stdio: "ignore" }).unref();
|
|
1462
|
+
} else if (ide.cliCommand) {
|
|
1463
|
+
(0, import_child_process3.spawn)(ide.cliCommand, args, { detached: true, stdio: "ignore" }).unref();
|
|
1464
|
+
} else {
|
|
1465
|
+
throw new Error(`No app identifier or CLI for ${ide.displayName}`);
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1468
|
+
async function launchWindows(ide, port, workspace, newWindow) {
|
|
1469
|
+
const cli = ide.cliCommand;
|
|
1470
|
+
if (!cli) {
|
|
1471
|
+
throw new Error(`No CLI command for ${ide.displayName}. Please add it to PATH.`);
|
|
1472
|
+
}
|
|
1473
|
+
const parts = [`"${cli}"`, `--remote-debugging-port=${port}`];
|
|
1474
|
+
if (newWindow) parts.push("--new-window");
|
|
1475
|
+
if (workspace) parts.push(`"${workspace}"`);
|
|
1476
|
+
const fullCmd = parts.join(" ");
|
|
1477
|
+
const { exec: execCmd } = require("child_process");
|
|
1478
|
+
execCmd(fullCmd, { windowsHide: true }, () => {
|
|
1479
|
+
});
|
|
1480
|
+
}
|
|
1481
|
+
async function launchLinux(ide, port, workspace, newWindow) {
|
|
1482
|
+
const cli = ide.cliCommand;
|
|
1483
|
+
if (!cli) {
|
|
1484
|
+
throw new Error(`No CLI command for ${ide.displayName}. Make sure it's in PATH.`);
|
|
1485
|
+
}
|
|
1486
|
+
const args = ["--remote-debugging-port=" + port];
|
|
1487
|
+
if (newWindow) args.push("--new-window");
|
|
1488
|
+
if (workspace) args.push(workspace);
|
|
1489
|
+
(0, import_child_process3.spawn)(cli, args, { detached: true, stdio: "ignore" }).unref();
|
|
1490
|
+
}
|
|
1491
|
+
var import_child_process3, net, os2, path2, _providerLoader;
|
|
1492
|
+
var init_launch = __esm({
|
|
1493
|
+
"src/launch.ts"() {
|
|
1494
|
+
"use strict";
|
|
1495
|
+
import_child_process3 = require("child_process");
|
|
1496
|
+
net = __toESM(require("net"));
|
|
1497
|
+
os2 = __toESM(require("os"));
|
|
1498
|
+
path2 = __toESM(require("path"));
|
|
1499
|
+
init_detector();
|
|
1500
|
+
init_provider_loader();
|
|
1501
|
+
_providerLoader = null;
|
|
1502
|
+
}
|
|
1503
|
+
});
|
|
1504
|
+
|
|
1555
1505
|
// src/daemon-cdp.ts
|
|
1556
1506
|
var import_ws3, http, DaemonCdpManager;
|
|
1557
1507
|
var init_daemon_cdp = __esm({
|
|
@@ -2370,14 +2320,14 @@ var require_lib = __commonJS({
|
|
|
2370
2320
|
});
|
|
2371
2321
|
|
|
2372
2322
|
// src/daemon-p2p.ts
|
|
2373
|
-
var fs2, path3,
|
|
2323
|
+
var fs2, path3, os3, logFile, log, DaemonP2PSender;
|
|
2374
2324
|
var init_daemon_p2p = __esm({
|
|
2375
2325
|
"src/daemon-p2p.ts"() {
|
|
2376
2326
|
"use strict";
|
|
2377
2327
|
fs2 = __toESM(require("fs"));
|
|
2378
2328
|
path3 = __toESM(require("path"));
|
|
2379
|
-
|
|
2380
|
-
logFile = path3.join(
|
|
2329
|
+
os3 = __toESM(require("os"));
|
|
2330
|
+
logFile = path3.join(os3.tmpdir(), "adhdev_daemon_p2p.log");
|
|
2381
2331
|
log = (msg) => {
|
|
2382
2332
|
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] [P2P] ${msg}`;
|
|
2383
2333
|
console.log(line);
|
|
@@ -2499,7 +2449,7 @@ var init_daemon_p2p = __esm({
|
|
|
2499
2449
|
async fetchTurnCredentials() {
|
|
2500
2450
|
try {
|
|
2501
2451
|
const serverUrl = "https://api.adhf.dev";
|
|
2502
|
-
const configPath = path3.join(
|
|
2452
|
+
const configPath = path3.join(os3.homedir(), ".adhdev", "config.json");
|
|
2503
2453
|
let token = "";
|
|
2504
2454
|
try {
|
|
2505
2455
|
const config = JSON.parse(fs2.readFileSync(configPath, "utf-8"));
|
|
@@ -3078,14 +3028,14 @@ var init_scaffold_template = __esm({
|
|
|
3078
3028
|
});
|
|
3079
3029
|
|
|
3080
3030
|
// src/daemon/dev-server.ts
|
|
3081
|
-
var http2, fs3, path4,
|
|
3031
|
+
var http2, fs3, path4, os4, DEV_SERVER_PORT, DevServer;
|
|
3082
3032
|
var init_dev_server = __esm({
|
|
3083
3033
|
"src/daemon/dev-server.ts"() {
|
|
3084
3034
|
"use strict";
|
|
3085
3035
|
http2 = __toESM(require("http"));
|
|
3086
3036
|
fs3 = __toESM(require("fs"));
|
|
3087
3037
|
path4 = __toESM(require("path"));
|
|
3088
|
-
|
|
3038
|
+
os4 = __toESM(require("os"));
|
|
3089
3039
|
init_scaffold_template();
|
|
3090
3040
|
DEV_SERVER_PORT = 19280;
|
|
3091
3041
|
DevServer = class _DevServer {
|
|
@@ -3508,7 +3458,7 @@ var init_dev_server = __esm({
|
|
|
3508
3458
|
return;
|
|
3509
3459
|
}
|
|
3510
3460
|
const builtinDir = path4.resolve(__dirname, "../providers/_builtin");
|
|
3511
|
-
const userDir = path4.join(
|
|
3461
|
+
const userDir = path4.join(os4.homedir(), ".adhdev", "providers");
|
|
3512
3462
|
const possiblePaths = [
|
|
3513
3463
|
path4.join(userDir, type, "provider.js"),
|
|
3514
3464
|
path4.join(builtinDir, "ide", type, "provider.js"),
|
|
@@ -3533,7 +3483,7 @@ var init_dev_server = __esm({
|
|
|
3533
3483
|
return;
|
|
3534
3484
|
}
|
|
3535
3485
|
const builtinDir = path4.resolve(__dirname, "../providers/_builtin");
|
|
3536
|
-
const userDir = path4.join(
|
|
3486
|
+
const userDir = path4.join(os4.homedir(), ".adhdev", "providers");
|
|
3537
3487
|
const possiblePaths = [
|
|
3538
3488
|
path4.join(userDir, type, "provider.js"),
|
|
3539
3489
|
path4.join(builtinDir, "ide", type, "provider.js"),
|
|
@@ -3571,7 +3521,7 @@ var init_dev_server = __esm({
|
|
|
3571
3521
|
return;
|
|
3572
3522
|
}
|
|
3573
3523
|
const builtinDir = path4.resolve(__dirname, "../providers/_builtin");
|
|
3574
|
-
const userDir = path4.join(
|
|
3524
|
+
const userDir = path4.join(os4.homedir(), ".adhdev", "providers");
|
|
3575
3525
|
const possiblePaths = [
|
|
3576
3526
|
path4.join(userDir, type, "provider.js"),
|
|
3577
3527
|
path4.join(builtinDir, "ide", type, "provider.js"),
|
|
@@ -3694,7 +3644,7 @@ var init_dev_server = __esm({
|
|
|
3694
3644
|
const template = this.generateTemplate(type, name, category, { cdpPorts, cli, processName, installPath, binary, extensionId });
|
|
3695
3645
|
let targetDir;
|
|
3696
3646
|
if (location === "user") {
|
|
3697
|
-
targetDir = path4.join(
|
|
3647
|
+
targetDir = path4.join(os4.homedir(), ".adhdev", "providers", type);
|
|
3698
3648
|
} else {
|
|
3699
3649
|
const builtinDir = path4.resolve(__dirname, "../providers/_builtin");
|
|
3700
3650
|
targetDir = path4.join(builtinDir, category, type);
|
|
@@ -4184,14 +4134,14 @@ var init_daemon_cdp_devtools = __esm({
|
|
|
4184
4134
|
});
|
|
4185
4135
|
|
|
4186
4136
|
// src/daemon-commands.ts
|
|
4187
|
-
var fs4, path5,
|
|
4137
|
+
var fs4, path5, os5, DaemonCommandHandler;
|
|
4188
4138
|
var init_daemon_commands = __esm({
|
|
4189
4139
|
"src/daemon-commands.ts"() {
|
|
4190
4140
|
"use strict";
|
|
4191
4141
|
init_daemon_cdp_devtools();
|
|
4192
4142
|
fs4 = __toESM(require("fs"));
|
|
4193
4143
|
path5 = __toESM(require("path"));
|
|
4194
|
-
|
|
4144
|
+
os5 = __toESM(require("os"));
|
|
4195
4145
|
init_config();
|
|
4196
4146
|
DaemonCommandHandler = class {
|
|
4197
4147
|
ctx;
|
|
@@ -4935,7 +4885,7 @@ var init_daemon_commands = __esm({
|
|
|
4935
4885
|
return this.handleFileList(args);
|
|
4936
4886
|
}
|
|
4937
4887
|
resolveSafePath(requestedPath) {
|
|
4938
|
-
const home =
|
|
4888
|
+
const home = os5.homedir();
|
|
4939
4889
|
let resolved;
|
|
4940
4890
|
if (requestedPath.startsWith("~")) {
|
|
4941
4891
|
resolved = path5.join(home, requestedPath.slice(1));
|
|
@@ -4958,7 +4908,7 @@ var init_daemon_commands = __esm({
|
|
|
4958
4908
|
const config = loadConfig();
|
|
4959
4909
|
const cliRecent = config.recentCliWorkspaces || [];
|
|
4960
4910
|
try {
|
|
4961
|
-
const storageDir = path5.join(
|
|
4911
|
+
const storageDir = path5.join(os5.homedir(), "Library", "Application Support");
|
|
4962
4912
|
const candidates = ["Cursor", "Code", "VSCodium"];
|
|
4963
4913
|
for (const app of candidates) {
|
|
4964
4914
|
const stateFile = path5.join(storageDir, app, "User", "globalStorage", "state.vscdb");
|
|
@@ -5539,11 +5489,11 @@ var init_agent_stream = __esm({
|
|
|
5539
5489
|
});
|
|
5540
5490
|
|
|
5541
5491
|
// src/daemon-status.ts
|
|
5542
|
-
var
|
|
5492
|
+
var os6, path6, DaemonStatusReporter;
|
|
5543
5493
|
var init_daemon_status = __esm({
|
|
5544
5494
|
"src/daemon-status.ts"() {
|
|
5545
5495
|
"use strict";
|
|
5546
|
-
|
|
5496
|
+
os6 = __toESM(require("os"));
|
|
5547
5497
|
path6 = __toESM(require("path"));
|
|
5548
5498
|
init_config();
|
|
5549
5499
|
DaemonStatusReporter = class {
|
|
@@ -5694,15 +5644,15 @@ var init_daemon_status = __esm({
|
|
|
5694
5644
|
daemonMode: true,
|
|
5695
5645
|
machineNickname: loadConfig().machineNickname || null,
|
|
5696
5646
|
machine: {
|
|
5697
|
-
hostname:
|
|
5698
|
-
platform:
|
|
5699
|
-
release:
|
|
5700
|
-
arch:
|
|
5701
|
-
cpus:
|
|
5702
|
-
totalMem:
|
|
5703
|
-
freeMem:
|
|
5704
|
-
loadavg:
|
|
5705
|
-
uptime:
|
|
5647
|
+
hostname: os6.hostname(),
|
|
5648
|
+
platform: os6.platform(),
|
|
5649
|
+
release: os6.release(),
|
|
5650
|
+
arch: os6.arch(),
|
|
5651
|
+
cpus: os6.cpus().length,
|
|
5652
|
+
totalMem: os6.totalmem(),
|
|
5653
|
+
freeMem: os6.freemem(),
|
|
5654
|
+
loadavg: os6.loadavg(),
|
|
5655
|
+
uptime: os6.uptime()
|
|
5706
5656
|
},
|
|
5707
5657
|
managedIdes,
|
|
5708
5658
|
managedClis,
|
|
@@ -5738,7 +5688,7 @@ var init_daemon_status = __esm({
|
|
|
5738
5688
|
activeChat: managedClis[0]?.activeChat || managedIdes[0]?.activeChat || null,
|
|
5739
5689
|
agentStreams: managedIdes.flatMap((ide) => ide.agentStreams || []),
|
|
5740
5690
|
connectedExtensions: extSummary.connectedIdes,
|
|
5741
|
-
system: { platform:
|
|
5691
|
+
system: { platform: os6.platform(), hostname: os6.hostname() }
|
|
5742
5692
|
};
|
|
5743
5693
|
const p2pSent = this.sendP2PPayload(payload);
|
|
5744
5694
|
if (p2pSent) {
|
|
@@ -5751,11 +5701,11 @@ var init_daemon_status = __esm({
|
|
|
5751
5701
|
daemonMode: true,
|
|
5752
5702
|
machineNickname: payload.machineNickname,
|
|
5753
5703
|
machine: {
|
|
5754
|
-
hostname:
|
|
5755
|
-
platform:
|
|
5756
|
-
arch:
|
|
5757
|
-
cpus:
|
|
5758
|
-
totalMem:
|
|
5704
|
+
hostname: os6.hostname(),
|
|
5705
|
+
platform: os6.platform(),
|
|
5706
|
+
arch: os6.arch(),
|
|
5707
|
+
cpus: os6.cpus().length,
|
|
5708
|
+
totalMem: os6.totalmem()
|
|
5759
5709
|
},
|
|
5760
5710
|
managedIdes: managedIdes.map((ide) => ({
|
|
5761
5711
|
ideType: ide.ideType,
|
|
@@ -5814,20 +5764,20 @@ function stripAnsi(str) {
|
|
|
5814
5764
|
return str.replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, "").replace(/\x1B\][^\x07]*\x07/g, "").replace(/\x1B\][^\x1B]*\x1B\\/g, "");
|
|
5815
5765
|
}
|
|
5816
5766
|
function findBinary(name) {
|
|
5817
|
-
const isWin =
|
|
5767
|
+
const isWin = os7.platform() === "win32";
|
|
5818
5768
|
try {
|
|
5819
5769
|
const cmd = isWin ? `where ${name}` : `which ${name}`;
|
|
5820
|
-
return (0,
|
|
5770
|
+
return (0, import_child_process4.execSync)(cmd, { encoding: "utf-8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] }).trim().split("\n")[0].trim();
|
|
5821
5771
|
} catch {
|
|
5822
5772
|
return isWin ? `${name}.cmd` : name;
|
|
5823
5773
|
}
|
|
5824
5774
|
}
|
|
5825
|
-
var
|
|
5775
|
+
var os7, import_child_process4, pty, ProviderCliAdapter;
|
|
5826
5776
|
var init_provider_cli_adapter = __esm({
|
|
5827
5777
|
"src/cli-adapters/provider-cli-adapter.ts"() {
|
|
5828
5778
|
"use strict";
|
|
5829
|
-
|
|
5830
|
-
|
|
5779
|
+
os7 = __toESM(require("os"));
|
|
5780
|
+
import_child_process4 = require("child_process");
|
|
5831
5781
|
try {
|
|
5832
5782
|
pty = require("node-pty");
|
|
5833
5783
|
} catch {
|
|
@@ -5839,7 +5789,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
5839
5789
|
this.provider = provider2;
|
|
5840
5790
|
this.cliType = provider2.type;
|
|
5841
5791
|
this.cliName = provider2.name;
|
|
5842
|
-
this.workingDir = workingDir.startsWith("~") ? workingDir.replace(/^~/,
|
|
5792
|
+
this.workingDir = workingDir.startsWith("~") ? workingDir.replace(/^~/, os7.homedir()) : workingDir;
|
|
5843
5793
|
const t = provider2.timeouts || {};
|
|
5844
5794
|
this.timeouts = {
|
|
5845
5795
|
ptyFlush: t.ptyFlush ?? 50,
|
|
@@ -5897,7 +5847,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
5897
5847
|
if (!pty) throw new Error("node-pty is not installed");
|
|
5898
5848
|
const { spawn: spawnConfig } = this.provider;
|
|
5899
5849
|
const binaryPath = findBinary(spawnConfig.command);
|
|
5900
|
-
const isWin =
|
|
5850
|
+
const isWin = os7.platform() === "win32";
|
|
5901
5851
|
const allArgs = [...spawnConfig.args, ...this.extraArgs];
|
|
5902
5852
|
console.log(`[${this.cliType}] Spawning in ${this.workingDir}`);
|
|
5903
5853
|
let shellCmd;
|
|
@@ -6137,14 +6087,64 @@ var init_provider_cli_adapter = __esm({
|
|
|
6137
6087
|
}
|
|
6138
6088
|
});
|
|
6139
6089
|
|
|
6090
|
+
// src/cli-detector.ts
|
|
6091
|
+
async function detectCLIs() {
|
|
6092
|
+
const platform7 = os8.platform();
|
|
6093
|
+
const whichCmd = platform7 === "win32" ? "where" : "which";
|
|
6094
|
+
const results = [];
|
|
6095
|
+
for (const cli of KNOWN_CLIS) {
|
|
6096
|
+
try {
|
|
6097
|
+
const pathResult = (0, import_child_process5.execSync)(`${whichCmd} ${cli.command} 2>/dev/null`, {
|
|
6098
|
+
encoding: "utf-8",
|
|
6099
|
+
timeout: 5e3,
|
|
6100
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
6101
|
+
}).trim().split("\n")[0];
|
|
6102
|
+
if (!pathResult) throw new Error("Not found");
|
|
6103
|
+
let version;
|
|
6104
|
+
try {
|
|
6105
|
+
const versionResult = (0, import_child_process5.execSync)(`${cli.command} --version 2>/dev/null`, {
|
|
6106
|
+
encoding: "utf-8",
|
|
6107
|
+
timeout: 5e3,
|
|
6108
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
6109
|
+
}).trim();
|
|
6110
|
+
const match = versionResult.match(/(\d+\.\d+[\.\d]*)/);
|
|
6111
|
+
version = match ? match[1] : versionResult.split("\n")[0].slice(0, 30);
|
|
6112
|
+
} catch {
|
|
6113
|
+
}
|
|
6114
|
+
results.push({ ...cli, installed: true, version, path: pathResult });
|
|
6115
|
+
} catch {
|
|
6116
|
+
results.push({ ...cli, installed: false });
|
|
6117
|
+
}
|
|
6118
|
+
}
|
|
6119
|
+
return results;
|
|
6120
|
+
}
|
|
6121
|
+
async function detectCLI(cliId) {
|
|
6122
|
+
const normalizedId = cliId === "claude-cli" ? "claude-code" : cliId;
|
|
6123
|
+
const all = await detectCLIs();
|
|
6124
|
+
return all.find((c) => c.id === normalizedId && c.installed) || null;
|
|
6125
|
+
}
|
|
6126
|
+
var import_child_process5, os8, KNOWN_CLIS;
|
|
6127
|
+
var init_cli_detector = __esm({
|
|
6128
|
+
"src/cli-detector.ts"() {
|
|
6129
|
+
"use strict";
|
|
6130
|
+
import_child_process5 = require("child_process");
|
|
6131
|
+
os8 = __toESM(require("os"));
|
|
6132
|
+
KNOWN_CLIS = [
|
|
6133
|
+
{ id: "gemini-cli", displayName: "Gemini CLI", icon: "\u264A", command: "gemini" },
|
|
6134
|
+
{ id: "claude-code", displayName: "Claude Code", icon: "\u{1F916}", command: "claude" },
|
|
6135
|
+
{ id: "codex-cli", displayName: "Codex CLI", icon: "\u{1F9E0}", command: "codex" }
|
|
6136
|
+
];
|
|
6137
|
+
}
|
|
6138
|
+
});
|
|
6139
|
+
|
|
6140
6140
|
// src/daemon-cli.ts
|
|
6141
|
-
var os9, path7,
|
|
6141
|
+
var os9, path7, import_chalk, DaemonCliManager;
|
|
6142
6142
|
var init_daemon_cli = __esm({
|
|
6143
6143
|
"src/daemon-cli.ts"() {
|
|
6144
6144
|
"use strict";
|
|
6145
6145
|
os9 = __toESM(require("os"));
|
|
6146
6146
|
path7 = __toESM(require("path"));
|
|
6147
|
-
|
|
6147
|
+
import_chalk = __toESM(require("chalk"));
|
|
6148
6148
|
init_provider_cli_adapter();
|
|
6149
6149
|
init_cli_detector();
|
|
6150
6150
|
init_config();
|
|
@@ -6169,10 +6169,10 @@ var init_daemon_cli = __esm({
|
|
|
6169
6169
|
const normalizedType = typeMap[cliType] || cliType;
|
|
6170
6170
|
const provider2 = this.providerLoader.get(normalizedType);
|
|
6171
6171
|
if (provider2 && provider2.category === "cli" && provider2.patterns && provider2.spawn) {
|
|
6172
|
-
console.log(
|
|
6172
|
+
console.log(import_chalk.default.cyan(` \u{1F4E6} Using provider: ${provider2.name} (${provider2.type})`));
|
|
6173
6173
|
return new ProviderCliAdapter(provider2, workingDir, cliArgs);
|
|
6174
6174
|
}
|
|
6175
|
-
console.log(
|
|
6175
|
+
console.log(import_chalk.default.yellow(` \u26A0 No CLI provider for '${cliType}', falling back to generic`));
|
|
6176
6176
|
const fallbackProvider = this.providerLoader.get("gemini-cli");
|
|
6177
6177
|
if (fallbackProvider) {
|
|
6178
6178
|
return new ProviderCliAdapter(fallbackProvider, workingDir, cliArgs);
|
|
@@ -6187,10 +6187,10 @@ var init_daemon_cli = __esm({
|
|
|
6187
6187
|
if (!cliInfo) throw new Error(`${cliType} not found`);
|
|
6188
6188
|
const key = this.getCliKey(cliType, resolvedDir);
|
|
6189
6189
|
if (this.adapters.has(key)) {
|
|
6190
|
-
console.log(
|
|
6190
|
+
console.log(import_chalk.default.yellow(` \u26A1 CLI ${cliType} already running in ${resolvedDir}`));
|
|
6191
6191
|
return;
|
|
6192
6192
|
}
|
|
6193
|
-
console.log(
|
|
6193
|
+
console.log(import_chalk.default.yellow(` \u26A1 Starting CLI ${cliType} in ${resolvedDir}...`));
|
|
6194
6194
|
const adapter = this.createAdapter(cliType, resolvedDir, cliArgs);
|
|
6195
6195
|
await adapter.spawn();
|
|
6196
6196
|
const bridge = this.deps.getBridge();
|
|
@@ -6205,7 +6205,7 @@ var init_daemon_cli = __esm({
|
|
|
6205
6205
|
if (this.adapters.get(key) === adapter) {
|
|
6206
6206
|
this.adapters.delete(key);
|
|
6207
6207
|
this.deps.removeAgentTracking(key);
|
|
6208
|
-
console.log(
|
|
6208
|
+
console.log(import_chalk.default.yellow(` \u{1F9F9} Auto-cleaned stopped CLI: ${adapter.cliType}`));
|
|
6209
6209
|
this.deps.onStatusChange();
|
|
6210
6210
|
}
|
|
6211
6211
|
}, 3e3);
|
|
@@ -6217,7 +6217,7 @@ var init_daemon_cli = __esm({
|
|
|
6217
6217
|
});
|
|
6218
6218
|
}
|
|
6219
6219
|
this.adapters.set(key, adapter);
|
|
6220
|
-
console.log(
|
|
6220
|
+
console.log(import_chalk.default.green(` \u2713 CLI started: ${cliInfo.displayName} v${cliInfo.version || "unknown"} in ${resolvedDir}`));
|
|
6221
6221
|
try {
|
|
6222
6222
|
addCliHistory({ cliType, dir: resolvedDir, cliArgs });
|
|
6223
6223
|
} catch (e) {
|
|
@@ -6231,7 +6231,7 @@ var init_daemon_cli = __esm({
|
|
|
6231
6231
|
adapter.shutdown();
|
|
6232
6232
|
this.adapters.delete(key);
|
|
6233
6233
|
this.deps.removeAgentTracking(key);
|
|
6234
|
-
console.log(
|
|
6234
|
+
console.log(import_chalk.default.yellow(` \u{1F6D1} CLI Agent stopped: ${adapter.cliType} in ${adapter.workingDir}`));
|
|
6235
6235
|
this.deps.onStatusChange();
|
|
6236
6236
|
}
|
|
6237
6237
|
}
|
|
@@ -6265,15 +6265,15 @@ var init_daemon_cli = __esm({
|
|
|
6265
6265
|
await this.startSession(cliType, dir, args?.cliArgs);
|
|
6266
6266
|
try {
|
|
6267
6267
|
const config = loadConfig();
|
|
6268
|
-
console.log(
|
|
6268
|
+
console.log(import_chalk.default.cyan(` \u{1F4C2} Saving recent workspace: ${dir}`));
|
|
6269
6269
|
const recent = config.recentCliWorkspaces || [];
|
|
6270
6270
|
if (!recent.includes(dir)) {
|
|
6271
6271
|
const updated = [dir, ...recent].slice(0, 10);
|
|
6272
6272
|
saveConfig({ ...config, recentCliWorkspaces: updated });
|
|
6273
|
-
console.log(
|
|
6273
|
+
console.log(import_chalk.default.green(` \u2713 Recent workspace saved: ${dir}`));
|
|
6274
6274
|
}
|
|
6275
6275
|
} catch (e) {
|
|
6276
|
-
console.error(
|
|
6276
|
+
console.error(import_chalk.default.red(` \u2717 Failed to save recent workspace: ${e}`));
|
|
6277
6277
|
}
|
|
6278
6278
|
}
|
|
6279
6279
|
return { success: true, cliType, dir, id: key };
|
|
@@ -6294,7 +6294,7 @@ var init_daemon_cli = __esm({
|
|
|
6294
6294
|
break;
|
|
6295
6295
|
}
|
|
6296
6296
|
}
|
|
6297
|
-
if (!found) console.log(
|
|
6297
|
+
if (!found) console.log(import_chalk.default.yellow(` \u26A0 No adapter found for ${cliType} (key: ${key})`));
|
|
6298
6298
|
}
|
|
6299
6299
|
return { success: true, cliType, dir, stopped: true };
|
|
6300
6300
|
}
|
|
@@ -7099,7 +7099,7 @@ function stopDaemon() {
|
|
|
7099
7099
|
return false;
|
|
7100
7100
|
}
|
|
7101
7101
|
}
|
|
7102
|
-
var os12, fs6, path9, crypto2,
|
|
7102
|
+
var os12, fs6, path9, crypto2, import_chalk2, DANGEROUS_PATTERNS, AdhdevDaemon;
|
|
7103
7103
|
var init_adhdev_daemon = __esm({
|
|
7104
7104
|
"src/adhdev-daemon.ts"() {
|
|
7105
7105
|
"use strict";
|
|
@@ -7123,7 +7123,7 @@ var init_adhdev_daemon = __esm({
|
|
|
7123
7123
|
fs6 = __toESM(require("fs"));
|
|
7124
7124
|
path9 = __toESM(require("path"));
|
|
7125
7125
|
crypto2 = __toESM(require("crypto"));
|
|
7126
|
-
|
|
7126
|
+
import_chalk2 = __toESM(require("chalk"));
|
|
7127
7127
|
DANGEROUS_PATTERNS = [
|
|
7128
7128
|
/\brm\s+(-[a-z]*f|-[a-z]*r|--force|--recursive)/i,
|
|
7129
7129
|
/\bsudo\b/i,
|
|
@@ -7175,22 +7175,22 @@ var init_adhdev_daemon = __esm({
|
|
|
7175
7175
|
this.localPort = options.localPort || DEFAULT_DAEMON_PORT;
|
|
7176
7176
|
const workingDir = options.workingDir || process.cwd();
|
|
7177
7177
|
if (isDaemonRunning()) {
|
|
7178
|
-
console.log(
|
|
7179
|
-
console.log(
|
|
7178
|
+
console.log(import_chalk2.default.yellow("\n\u26A0 ADHDev Daemon is already running."));
|
|
7179
|
+
console.log(import_chalk2.default.gray(` Stop with: adhdev daemon:stop
|
|
7180
7180
|
`));
|
|
7181
7181
|
return;
|
|
7182
7182
|
}
|
|
7183
7183
|
writeDaemonPid(process.pid);
|
|
7184
7184
|
const config = loadConfig();
|
|
7185
7185
|
if (!config.connectionToken) {
|
|
7186
|
-
console.log(
|
|
7187
|
-
console.log(
|
|
7186
|
+
console.log(import_chalk2.default.red("\n\u2717 No connection token found."));
|
|
7187
|
+
console.log(import_chalk2.default.gray(" Run `adhdev setup` first.\n"));
|
|
7188
7188
|
process.exit(1);
|
|
7189
7189
|
}
|
|
7190
7190
|
this.localServer = new LocalServer({
|
|
7191
7191
|
port: this.localPort,
|
|
7192
7192
|
onExtensionConnected: (ext) => {
|
|
7193
|
-
console.log(
|
|
7193
|
+
console.log(import_chalk2.default.green(` \u{1F4CE} Extension connected: ${ext.ideType} v${ext.ideVersion}`));
|
|
7194
7194
|
this.localServer?.notifyServerState(
|
|
7195
7195
|
this.bridge?.isConnected() || false,
|
|
7196
7196
|
config.serverUrl
|
|
@@ -7198,7 +7198,7 @@ var init_adhdev_daemon = __esm({
|
|
|
7198
7198
|
setTimeout(() => this.statusReporter?.throttledReport(), 500);
|
|
7199
7199
|
},
|
|
7200
7200
|
onExtensionDisconnected: (ext) => {
|
|
7201
|
-
console.log(
|
|
7201
|
+
console.log(import_chalk2.default.yellow(` \u{1F4CE} Extension disconnected: ${ext.ideType}`));
|
|
7202
7202
|
setTimeout(() => this.statusReporter?.throttledReport(), 500);
|
|
7203
7203
|
},
|
|
7204
7204
|
onExtensionStatus: () => {
|
|
@@ -7206,7 +7206,7 @@ var init_adhdev_daemon = __esm({
|
|
|
7206
7206
|
},
|
|
7207
7207
|
onExtensionEvent: (ext, event, data) => {
|
|
7208
7208
|
if (event === "token_updated" && data.token) {
|
|
7209
|
-
console.log(
|
|
7209
|
+
console.log(import_chalk2.default.green(` \u{1F511} Token updated from Extension (${ext.ideType})`));
|
|
7210
7210
|
const cfg = loadConfig();
|
|
7211
7211
|
cfg.connectionToken = data.token;
|
|
7212
7212
|
saveConfig(cfg);
|
|
@@ -7214,7 +7214,7 @@ var init_adhdev_daemon = __esm({
|
|
|
7214
7214
|
this.bridge.disconnect();
|
|
7215
7215
|
this.bridge.token = data.token;
|
|
7216
7216
|
this.bridge.connect().catch((e) => {
|
|
7217
|
-
console.error(
|
|
7217
|
+
console.error(import_chalk2.default.red(` \u2717 Reconnect failed: ${e.message}`));
|
|
7218
7218
|
});
|
|
7219
7219
|
}
|
|
7220
7220
|
}
|
|
@@ -7234,7 +7234,7 @@ var init_adhdev_daemon = __esm({
|
|
|
7234
7234
|
try {
|
|
7235
7235
|
await this.localServer.start();
|
|
7236
7236
|
} catch (err) {
|
|
7237
|
-
console.error(
|
|
7237
|
+
console.error(import_chalk2.default.red(`
|
|
7238
7238
|
\u2717 Failed to start local server: ${err.message}`));
|
|
7239
7239
|
removeDaemonPid();
|
|
7240
7240
|
process.exit(1);
|
|
@@ -7270,7 +7270,7 @@ var init_adhdev_daemon = __esm({
|
|
|
7270
7270
|
});
|
|
7271
7271
|
this.p2p = new DaemonP2PSender(this.bridge);
|
|
7272
7272
|
if (this.p2p.isAvailable) {
|
|
7273
|
-
console.log(
|
|
7273
|
+
console.log(import_chalk2.default.green(" \u{1F517} P2P available (node-datachannel)"));
|
|
7274
7274
|
this.p2p.onInput(async (event) => {
|
|
7275
7275
|
if (!this.commandHandler) throw new Error("No command handler");
|
|
7276
7276
|
return this.commandHandler.handle("cdp_remote_action", event);
|
|
@@ -7345,16 +7345,16 @@ var init_adhdev_daemon = __esm({
|
|
|
7345
7345
|
}
|
|
7346
7346
|
}, 200);
|
|
7347
7347
|
} else {
|
|
7348
|
-
console.log(
|
|
7348
|
+
console.log(import_chalk2.default.gray(" \u26A0 P2P unavailable \u2014 using server relay"));
|
|
7349
7349
|
}
|
|
7350
7350
|
this.registerServerHandlers();
|
|
7351
7351
|
this.bridge.onStateChange((state) => {
|
|
7352
7352
|
if (state === "connected") {
|
|
7353
|
-
console.log(
|
|
7353
|
+
console.log(import_chalk2.default.green(" \u{1F4E1} Connected to ADHDev server"));
|
|
7354
7354
|
this.localServer?.notifyServerState(true, config.serverUrl);
|
|
7355
7355
|
this.statusReporter?.sendUnifiedStatusReport();
|
|
7356
7356
|
} else if (state === "disconnected") {
|
|
7357
|
-
console.log(
|
|
7357
|
+
console.log(import_chalk2.default.yellow(" \u26A0 Server disconnected, will reconnect..."));
|
|
7358
7358
|
this.localServer?.notifyServerState(false, config.serverUrl);
|
|
7359
7359
|
}
|
|
7360
7360
|
});
|
|
@@ -7390,16 +7390,16 @@ var init_adhdev_daemon = __esm({
|
|
|
7390
7390
|
}
|
|
7391
7391
|
printBanner(options, serverUrl) {
|
|
7392
7392
|
console.log();
|
|
7393
|
-
console.log(
|
|
7394
|
-
console.log(` ${
|
|
7395
|
-
console.log(` ${
|
|
7393
|
+
console.log(import_chalk2.default.bold(" \u{1F309} ADHDev Daemon"));
|
|
7394
|
+
console.log(` ${import_chalk2.default.bold("Local:")} ws://127.0.0.1:${this.localPort}/ipc`);
|
|
7395
|
+
console.log(` ${import_chalk2.default.bold("Server:")} ${serverUrl}`);
|
|
7396
7396
|
const cdpStatus = this.cdpManagers.size > 0 ? `\u2705 ${[...this.cdpManagers.entries()].map(([k, m]) => `${k}:${m.getPort()}`).join(", ")}` : "\u274C not connected";
|
|
7397
|
-
console.log(` ${
|
|
7398
|
-
console.log(` ${
|
|
7399
|
-
console.log(` ${
|
|
7397
|
+
console.log(` ${import_chalk2.default.bold("CDP:")} ${cdpStatus}`);
|
|
7398
|
+
console.log(` ${import_chalk2.default.bold("P2P:")} ${this.p2p?.isAvailable ? "\u2705 available" : "\u274C unavailable"}`);
|
|
7399
|
+
console.log(` ${import_chalk2.default.bold("Providers:")} ${this.providerLoader.getAll().length > 0 ? `\u2705 ${this.providerLoader.getAll().map((p) => p.type).join(", ")}` : "\u274C not loaded"}`);
|
|
7400
7400
|
console.log();
|
|
7401
|
-
console.log(
|
|
7402
|
-
console.log(
|
|
7401
|
+
console.log(import_chalk2.default.gray(" Extensions can connect to the local server."));
|
|
7402
|
+
console.log(import_chalk2.default.gray(" Press Ctrl+C to stop.\n"));
|
|
7403
7403
|
}
|
|
7404
7404
|
// ─── 서버 명령 핸들러 ───────────────────────────
|
|
7405
7405
|
registerServerHandlers() {
|
|
@@ -7484,9 +7484,9 @@ var init_adhdev_daemon = __esm({
|
|
|
7484
7484
|
}
|
|
7485
7485
|
}
|
|
7486
7486
|
async handleCommand(msg, cmd, args) {
|
|
7487
|
-
console.log(
|
|
7487
|
+
console.log(import_chalk2.default.magenta(` \u2699 Command: ${cmd}`));
|
|
7488
7488
|
if (cmd.startsWith("agent_stream") && args?._targetInstance) {
|
|
7489
|
-
console.log(
|
|
7489
|
+
console.log(import_chalk2.default.yellow(` \u{1F3AF} Target: ${args._targetType}:${args._targetInstance.split("_")[0]} agent=${args.agentType || ""}`));
|
|
7490
7490
|
}
|
|
7491
7491
|
try {
|
|
7492
7492
|
switch (cmd) {
|
|
@@ -7539,7 +7539,7 @@ var init_adhdev_daemon = __esm({
|
|
|
7539
7539
|
this.sendResult(msg, false, { error: `Command handler not initialized: ${cmd}` });
|
|
7540
7540
|
}
|
|
7541
7541
|
} catch (e) {
|
|
7542
|
-
console.error(
|
|
7542
|
+
console.error(import_chalk2.default.red(` \u2717 Command failed: ${e.message}`));
|
|
7543
7543
|
this.sendResult(msg, false, { error: e.message });
|
|
7544
7544
|
}
|
|
7545
7545
|
}
|
|
@@ -7605,15 +7605,15 @@ var init_adhdev_daemon = __esm({
|
|
|
7605
7605
|
console.log(`[launch_ide] target=${ideKey || "auto"}`);
|
|
7606
7606
|
const result = await launchWithCdp(launchArgs);
|
|
7607
7607
|
if (result.success && result.port && result.ideId && !this.cdpManagers.has(result.ideId)) {
|
|
7608
|
-
console.log(
|
|
7608
|
+
console.log(import_chalk2.default.cyan(`[launch_ide] Connecting CDP for ${result.ideId} on port ${result.port}...`));
|
|
7609
7609
|
const manager = new DaemonCdpManager(result.port, (msg) => {
|
|
7610
7610
|
console.log(`[CDP:${result.ideId}] ${msg}`);
|
|
7611
7611
|
});
|
|
7612
7612
|
const connected = await manager.connect();
|
|
7613
7613
|
if (connected) {
|
|
7614
7614
|
this.cdpManagers.set(result.ideId, manager);
|
|
7615
|
-
console.log(
|
|
7616
|
-
console.log(
|
|
7615
|
+
console.log(import_chalk2.default.green(` \u{1F50D} CDP connected: ${result.ideId} (port ${result.port})`));
|
|
7616
|
+
console.log(import_chalk2.default.green(` \u{1F4E1} CDP: ${this.cdpManagers.size} IDE(s) connected`));
|
|
7617
7617
|
}
|
|
7618
7618
|
}
|
|
7619
7619
|
this.startAgentStreamPolling();
|
|
@@ -7650,7 +7650,7 @@ var init_adhdev_daemon = __esm({
|
|
|
7650
7650
|
async stop() {
|
|
7651
7651
|
if (!this.running) return;
|
|
7652
7652
|
this.running = false;
|
|
7653
|
-
console.log(
|
|
7653
|
+
console.log(import_chalk2.default.yellow("\n Shutting down ADHDev Daemon..."));
|
|
7654
7654
|
this.cliManager.shutdownAll();
|
|
7655
7655
|
this.instanceManager.disposeAll();
|
|
7656
7656
|
if (this.statusReporter) {
|
|
@@ -7670,7 +7670,7 @@ var init_adhdev_daemon = __esm({
|
|
|
7670
7670
|
this.localServer?.stop();
|
|
7671
7671
|
this.bridge?.disconnect();
|
|
7672
7672
|
removeDaemonPid();
|
|
7673
|
-
console.log(
|
|
7673
|
+
console.log(import_chalk2.default.green(" \u2713 ADHDev Daemon stopped.\n"));
|
|
7674
7674
|
process.exit(0);
|
|
7675
7675
|
}
|
|
7676
7676
|
// ─── CDP 관리 ───────────────────────────────────
|
|
@@ -7753,7 +7753,7 @@ var init_adhdev_daemon = __esm({
|
|
|
7753
7753
|
const actualPort = manager.getPort();
|
|
7754
7754
|
const actualIde = Object.entries(cdpPortMap).find(([, p]) => p === actualPort)?.[0] || ide;
|
|
7755
7755
|
this.cdpManagers.set(actualIde, manager);
|
|
7756
|
-
console.log(
|
|
7756
|
+
console.log(import_chalk2.default.green(` \u{1F50D} CDP connected: ${actualIde} (port ${actualPort})`));
|
|
7757
7757
|
if (this.ideType === "unknown") {
|
|
7758
7758
|
this.ideType = actualIde;
|
|
7759
7759
|
}
|
|
@@ -7776,7 +7776,7 @@ var init_adhdev_daemon = __esm({
|
|
|
7776
7776
|
}
|
|
7777
7777
|
}
|
|
7778
7778
|
if (this.cdpManagers.size > 0) {
|
|
7779
|
-
console.log(
|
|
7779
|
+
console.log(import_chalk2.default.green(` \u{1F4E1} CDP: ${this.cdpManagers.size} IDE(s) connected`));
|
|
7780
7780
|
this.cdpDiscoveryTimer = setInterval(async () => {
|
|
7781
7781
|
for (const m of this.cdpManagers.values()) {
|
|
7782
7782
|
if (m.isConnected) {
|
|
@@ -7785,8 +7785,8 @@ var init_adhdev_daemon = __esm({
|
|
|
7785
7785
|
}
|
|
7786
7786
|
}, 3e4);
|
|
7787
7787
|
} else {
|
|
7788
|
-
console.log(
|
|
7789
|
-
console.log(
|
|
7788
|
+
console.log(import_chalk2.default.yellow(` \u26A0 CDP not available \u2014 tried ports: ${portsToTry.map((p) => `${p.ide}:${p.port}`).join(", ")}`));
|
|
7789
|
+
console.log(import_chalk2.default.yellow(` IDE may need relaunch with --remote-debugging-port`));
|
|
7790
7790
|
}
|
|
7791
7791
|
}
|
|
7792
7792
|
};
|
|
@@ -7798,7 +7798,7 @@ var import_commander = require("commander");
|
|
|
7798
7798
|
var import_chalk4 = __toESM(require("chalk"));
|
|
7799
7799
|
|
|
7800
7800
|
// src/wizard.ts
|
|
7801
|
-
var
|
|
7801
|
+
var import_chalk3 = __toESM(require("chalk"));
|
|
7802
7802
|
var import_inquirer = __toESM(require("inquirer"));
|
|
7803
7803
|
var import_ora = __toESM(require("ora"));
|
|
7804
7804
|
var import_open = __toESM(require("open"));
|
|
@@ -8004,27 +8004,17 @@ async function installExtensions(ide, extensions, onProgress) {
|
|
|
8004
8004
|
function getAIExtensions() {
|
|
8005
8005
|
return EXTENSION_CATALOG.filter((e) => e.category === "ai-agent");
|
|
8006
8006
|
}
|
|
8007
|
-
function launchIDE(ide, workspacePath) {
|
|
8008
|
-
if (!ide.cliCommand) return false;
|
|
8009
|
-
try {
|
|
8010
|
-
const args = workspacePath ? `"${workspacePath}"` : "";
|
|
8011
|
-
(0, import_child_process2.exec)(`"${ide.cliCommand}" ${args}`, { timeout: 1e4 });
|
|
8012
|
-
return true;
|
|
8013
|
-
} catch {
|
|
8014
|
-
return false;
|
|
8015
|
-
}
|
|
8016
|
-
}
|
|
8017
8007
|
|
|
8018
8008
|
// src/wizard.ts
|
|
8019
8009
|
init_config();
|
|
8020
8010
|
var SERVER_URL = "https://api.adhf.dev";
|
|
8021
8011
|
var LOGO = `
|
|
8022
|
-
${
|
|
8023
|
-
${
|
|
8024
|
-
${
|
|
8025
|
-
${
|
|
8012
|
+
${import_chalk3.default.cyan("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557")}
|
|
8013
|
+
${import_chalk3.default.cyan("\u2551")} ${import_chalk3.default.bold.white("\u{1F309} ADHDev Setup Wizard")} ${import_chalk3.default.cyan("\u2551")}
|
|
8014
|
+
${import_chalk3.default.cyan("\u2551")} ${import_chalk3.default.gray("Agent Dashboard Hub for your IDE")} ${import_chalk3.default.cyan("\u2551")}
|
|
8015
|
+
${import_chalk3.default.cyan("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D")}
|
|
8026
8016
|
`;
|
|
8027
|
-
var DIVIDER =
|
|
8017
|
+
var DIVIDER = import_chalk3.default.gray("\u2500".repeat(44));
|
|
8028
8018
|
async function runWizard(options = {}) {
|
|
8029
8019
|
const loader = new ProviderLoader({ logFn: () => {
|
|
8030
8020
|
} });
|
|
@@ -8033,11 +8023,11 @@ async function runWizard(options = {}) {
|
|
|
8033
8023
|
console.log(LOGO);
|
|
8034
8024
|
if (isSetupComplete() && !options.force) {
|
|
8035
8025
|
const config = loadConfig();
|
|
8036
|
-
console.log(
|
|
8026
|
+
console.log(import_chalk3.default.green("\u2713") + " ADHDev is already set up!");
|
|
8037
8027
|
const ides = config.configuredIdes?.length ? config.configuredIdes.join(", ") : config.selectedIde || "none";
|
|
8038
|
-
console.log(
|
|
8039
|
-
console.log(
|
|
8040
|
-
console.log(
|
|
8028
|
+
console.log(import_chalk3.default.gray(` IDEs: ${ides}`));
|
|
8029
|
+
console.log(import_chalk3.default.gray(` User: ${config.userEmail || "not logged in"}`));
|
|
8030
|
+
console.log(import_chalk3.default.gray(` Extensions: ${config.installedExtensions.length} installed`));
|
|
8041
8031
|
console.log();
|
|
8042
8032
|
const { action } = await import_inquirer.default.prompt([
|
|
8043
8033
|
{
|
|
@@ -8045,6 +8035,7 @@ async function runWizard(options = {}) {
|
|
|
8045
8035
|
name: "action",
|
|
8046
8036
|
message: "What would you like to do?",
|
|
8047
8037
|
choices: [
|
|
8038
|
+
{ name: "\u{1F680} Start Daemon (connect IDEs & monitor agents)", value: "start-daemon" },
|
|
8048
8039
|
{ name: "\u{1F504} Reconfigure (run setup again)", value: "reconfigure" },
|
|
8049
8040
|
{ name: "\u{1F527} Install/Update CLI (adhdev command)", value: "install-cli" },
|
|
8050
8041
|
{ name: "\u{1F510} Re-login", value: "relogin" },
|
|
@@ -8053,6 +8044,10 @@ async function runWizard(options = {}) {
|
|
|
8053
8044
|
}
|
|
8054
8045
|
]);
|
|
8055
8046
|
if (action === "exit") return;
|
|
8047
|
+
if (action === "start-daemon") {
|
|
8048
|
+
await startDaemonFlow();
|
|
8049
|
+
return;
|
|
8050
|
+
}
|
|
8056
8051
|
if (action === "relogin") {
|
|
8057
8052
|
await loginFlow();
|
|
8058
8053
|
return;
|
|
@@ -8068,9 +8063,9 @@ async function runWizard(options = {}) {
|
|
|
8068
8063
|
name: "mode",
|
|
8069
8064
|
message: "Setup mode:",
|
|
8070
8065
|
choices: [
|
|
8071
|
-
{ name: `\u{1F680} ${
|
|
8072
|
-
{ name: `\u2699\uFE0F ${
|
|
8073
|
-
{ name: `\u{1F527} ${
|
|
8066
|
+
{ name: `\u{1F680} ${import_chalk3.default.bold("Quick Setup")} \u2014 Auto-detect IDEs, install bridge, login ${import_chalk3.default.gray("(recommended)")}`, value: "quick" },
|
|
8067
|
+
{ name: `\u2699\uFE0F ${import_chalk3.default.bold("Custom Setup")} \u2014 Choose IDE, AI extensions, and more`, value: "custom" },
|
|
8068
|
+
{ name: `\u{1F527} ${import_chalk3.default.bold("CLI Only")} \u2014 Install adhdev command globally`, value: "cli-only" }
|
|
8074
8069
|
]
|
|
8075
8070
|
}
|
|
8076
8071
|
]);
|
|
@@ -8083,27 +8078,27 @@ async function runWizard(options = {}) {
|
|
|
8083
8078
|
}
|
|
8084
8079
|
}
|
|
8085
8080
|
async function quickSetup() {
|
|
8086
|
-
console.log(
|
|
8081
|
+
console.log(import_chalk3.default.bold("\n\u{1F680} Quick Setup\n"));
|
|
8087
8082
|
const spinner = (0, import_ora.default)("Detecting installed IDEs...").start();
|
|
8088
8083
|
const ides = await detectIDEs();
|
|
8089
8084
|
const installedIDEs = ides.filter((i) => i.installed && i.cliCommand);
|
|
8090
8085
|
spinner.stop();
|
|
8091
8086
|
if (installedIDEs.length === 0) {
|
|
8092
|
-
console.log(
|
|
8093
|
-
console.log(
|
|
8087
|
+
console.log(import_chalk3.default.red("\u2717 No supported IDE with CLI found."));
|
|
8088
|
+
console.log(import_chalk3.default.gray(" Supported: VS Code, Cursor, Antigravity, Windsurf, VSCodium"));
|
|
8094
8089
|
return;
|
|
8095
8090
|
}
|
|
8096
|
-
console.log(
|
|
8091
|
+
console.log(import_chalk3.default.green(`Found ${installedIDEs.length} IDE(s):
|
|
8097
8092
|
`));
|
|
8098
8093
|
installedIDEs.forEach((ide) => {
|
|
8099
|
-
const version = ide.version ?
|
|
8100
|
-
console.log(` ${
|
|
8094
|
+
const version = ide.version ? import_chalk3.default.gray(` v${ide.version}`) : "";
|
|
8095
|
+
console.log(` ${import_chalk3.default.green("\u2713")} ${ide.icon} ${import_chalk3.default.bold(ide.displayName)}${version}`);
|
|
8101
8096
|
});
|
|
8102
8097
|
console.log();
|
|
8103
8098
|
let selectedIDEs;
|
|
8104
8099
|
if (installedIDEs.length === 1) {
|
|
8105
8100
|
selectedIDEs = installedIDEs;
|
|
8106
|
-
console.log(
|
|
8101
|
+
console.log(import_chalk3.default.gray(` Auto-selected: ${installedIDEs[0].displayName}
|
|
8107
8102
|
`));
|
|
8108
8103
|
} else {
|
|
8109
8104
|
const { selectedIdeIds } = await import_inquirer.default.prompt([
|
|
@@ -8112,7 +8107,7 @@ async function quickSetup() {
|
|
|
8112
8107
|
name: "selectedIdeIds",
|
|
8113
8108
|
message: "Select IDEs to set up (Space to toggle, Enter to confirm):",
|
|
8114
8109
|
choices: installedIDEs.map((ide) => ({
|
|
8115
|
-
name: `${ide.icon} ${ide.displayName}${ide.version ?
|
|
8110
|
+
name: `${ide.icon} ${ide.displayName}${ide.version ? import_chalk3.default.gray(` v${ide.version}`) : ""}`,
|
|
8116
8111
|
value: ide.id,
|
|
8117
8112
|
checked: true
|
|
8118
8113
|
// 기본 모두 선택
|
|
@@ -8135,7 +8130,7 @@ async function quickSetup() {
|
|
|
8135
8130
|
console.log(DIVIDER);
|
|
8136
8131
|
const loginResult = await loginFlow();
|
|
8137
8132
|
if (!loginResult) {
|
|
8138
|
-
console.log(
|
|
8133
|
+
console.log(import_chalk3.default.yellow("\u26A0 Setup completed without login. You can login later with `adhdev setup`."));
|
|
8139
8134
|
}
|
|
8140
8135
|
if (loginResult?.connectionToken) {
|
|
8141
8136
|
for (const ide of selectedIDEs) {
|
|
@@ -8152,57 +8147,59 @@ async function quickSetup() {
|
|
|
8152
8147
|
});
|
|
8153
8148
|
}
|
|
8154
8149
|
console.log(DIVIDER);
|
|
8155
|
-
console.log(
|
|
8150
|
+
console.log(import_chalk3.default.bold("\n\u{1F389} Setup Complete!\n"));
|
|
8156
8151
|
if (selectedIDEs.length === 1) {
|
|
8157
|
-
console.log(` ${
|
|
8152
|
+
console.log(` ${import_chalk3.default.bold("IDE:")} ${selectedIDEs[0].icon} ${selectedIDEs[0].displayName}`);
|
|
8158
8153
|
} else {
|
|
8159
|
-
console.log(` ${
|
|
8154
|
+
console.log(` ${import_chalk3.default.bold("IDEs:")} ${selectedIDEs.map((i) => `${i.icon} ${i.displayName}`).join(", ")}`);
|
|
8160
8155
|
}
|
|
8161
|
-
console.log(` ${
|
|
8162
|
-
console.log(` ${
|
|
8156
|
+
console.log(` ${import_chalk3.default.bold("User:")} ${loginResult?.email || "not logged in"}`);
|
|
8157
|
+
console.log(` ${import_chalk3.default.bold("Status:")} ${import_chalk3.default.green("Ready to connect")}`);
|
|
8163
8158
|
console.log();
|
|
8164
|
-
console.log(
|
|
8165
|
-
console.log(
|
|
8166
|
-
console.log(
|
|
8167
|
-
console.log(
|
|
8168
|
-
console.log(
|
|
8159
|
+
console.log(import_chalk3.default.gray(" Commands:"));
|
|
8160
|
+
console.log(import_chalk3.default.gray(" adhdev daemon \u2014 Start daemon (IDE monitor + agent hub)"));
|
|
8161
|
+
console.log(import_chalk3.default.gray(" adhdev launch cursor \u2014 Launch IDE with CDP"));
|
|
8162
|
+
console.log(import_chalk3.default.gray(" adhdev launch gemini \u2014 Start CLI agent via daemon"));
|
|
8163
|
+
console.log(import_chalk3.default.gray(" adhdev status \u2014 Check setup status"));
|
|
8164
|
+
console.log(import_chalk3.default.gray(" adhdev setup \u2014 Reconfigure"));
|
|
8169
8165
|
console.log();
|
|
8170
8166
|
await installCliOnly();
|
|
8167
|
+
await startDaemonFlow();
|
|
8171
8168
|
}
|
|
8172
8169
|
async function customSetup() {
|
|
8173
|
-
console.log(
|
|
8170
|
+
console.log(import_chalk3.default.bold("\n\u{1F4CD} Step 1/4 \u2014 Detecting installed IDEs...\n"));
|
|
8174
8171
|
const spinner = (0, import_ora.default)("Scanning your system...").start();
|
|
8175
8172
|
const ides = await detectIDEs();
|
|
8176
8173
|
const installedIDEs = ides.filter((i) => i.installed);
|
|
8177
8174
|
spinner.stop();
|
|
8178
8175
|
if (installedIDEs.length === 0) {
|
|
8179
|
-
console.log(
|
|
8176
|
+
console.log(import_chalk3.default.yellow("\u26A0 No supported IDEs found."));
|
|
8180
8177
|
return;
|
|
8181
8178
|
}
|
|
8182
|
-
console.log(
|
|
8179
|
+
console.log(import_chalk3.default.green(`Found ${installedIDEs.length} IDE(s):
|
|
8183
8180
|
`));
|
|
8184
8181
|
installedIDEs.forEach((ide) => {
|
|
8185
|
-
const version = ide.version ?
|
|
8186
|
-
const cli = ide.cliCommand ?
|
|
8187
|
-
console.log(` ${ide.icon} ${
|
|
8182
|
+
const version = ide.version ? import_chalk3.default.gray(` v${ide.version}`) : "";
|
|
8183
|
+
const cli = ide.cliCommand ? import_chalk3.default.gray(` (CLI: \u2713)`) : import_chalk3.default.yellow(` (CLI: \u2717 manual install)`);
|
|
8184
|
+
console.log(` ${ide.icon} ${import_chalk3.default.bold(ide.displayName)}${version}${cli}`);
|
|
8188
8185
|
});
|
|
8189
8186
|
console.log();
|
|
8190
8187
|
console.log(DIVIDER);
|
|
8191
|
-
console.log(
|
|
8188
|
+
console.log(import_chalk3.default.bold("\n\u{1F4CD} Step 2/4 \u2014 Select your primary IDE\n"));
|
|
8192
8189
|
const { selectedIdeId } = await import_inquirer.default.prompt([
|
|
8193
8190
|
{
|
|
8194
8191
|
type: "list",
|
|
8195
8192
|
name: "selectedIdeId",
|
|
8196
8193
|
message: "Which IDE?",
|
|
8197
8194
|
choices: installedIDEs.map((ide) => ({
|
|
8198
|
-
name: `${ide.icon} ${ide.displayName}${ide.version ?
|
|
8195
|
+
name: `${ide.icon} ${ide.displayName}${ide.version ? import_chalk3.default.gray(` v${ide.version}`) : ""}`,
|
|
8199
8196
|
value: ide.id
|
|
8200
8197
|
}))
|
|
8201
8198
|
}
|
|
8202
8199
|
]);
|
|
8203
8200
|
const selectedIDE = installedIDEs.find((i) => i.id === selectedIdeId);
|
|
8204
8201
|
console.log(DIVIDER);
|
|
8205
|
-
console.log(
|
|
8202
|
+
console.log(import_chalk3.default.bold("\n\u{1F4CD} Step 3/4 \u2014 Choose AI extensions\n"));
|
|
8206
8203
|
const aiExtensions = getAIExtensions();
|
|
8207
8204
|
const { selectedExtIds } = await import_inquirer.default.prompt([
|
|
8208
8205
|
{
|
|
@@ -8210,7 +8207,7 @@ async function customSetup() {
|
|
|
8210
8207
|
name: "selectedExtIds",
|
|
8211
8208
|
message: "Select AI extensions:",
|
|
8212
8209
|
choices: aiExtensions.map((ext) => ({
|
|
8213
|
-
name: `${ext.icon} ${ext.displayName} \u2014 ${
|
|
8210
|
+
name: `${ext.icon} ${ext.displayName} \u2014 ${import_chalk3.default.gray(ext.description)}`,
|
|
8214
8211
|
value: ext.id,
|
|
8215
8212
|
checked: ext.recommended
|
|
8216
8213
|
}))
|
|
@@ -8219,20 +8216,20 @@ async function customSetup() {
|
|
|
8219
8216
|
const bridgeExt = EXTENSION_CATALOG.find((e) => e.category === "bridge");
|
|
8220
8217
|
const selectedAIExts = aiExtensions.filter((e) => selectedExtIds.includes(e.id));
|
|
8221
8218
|
const allExtensions = [bridgeExt, ...selectedAIExts];
|
|
8222
|
-
console.log(
|
|
8219
|
+
console.log(import_chalk3.default.bold("\n\u{1F4CD} Step 4/4 \u2014 Installing extensions\n"));
|
|
8223
8220
|
if (selectedIDE.cliCommand) {
|
|
8224
8221
|
await installExtensions(
|
|
8225
8222
|
selectedIDE,
|
|
8226
8223
|
allExtensions,
|
|
8227
8224
|
(current, total, ext, result) => {
|
|
8228
|
-
const status = result.alreadyInstalled ?
|
|
8225
|
+
const status = result.alreadyInstalled ? import_chalk3.default.blue("already installed") : result.success ? import_chalk3.default.green("installed \u2713") : import_chalk3.default.red(`failed \u2717`);
|
|
8229
8226
|
console.log(` [${current}/${total}] ${ext.icon} ${ext.displayName} \u2014 ${status}`);
|
|
8230
8227
|
}
|
|
8231
8228
|
);
|
|
8232
8229
|
} else {
|
|
8233
|
-
console.log(
|
|
8230
|
+
console.log(import_chalk3.default.yellow("\u26A0 No CLI \u2014 install manually:"));
|
|
8234
8231
|
allExtensions.forEach((ext) => {
|
|
8235
|
-
console.log(
|
|
8232
|
+
console.log(import_chalk3.default.gray(` ${ext.icon} ${ext.displayName}: ${ext.marketplaceId}`));
|
|
8236
8233
|
});
|
|
8237
8234
|
}
|
|
8238
8235
|
console.log(DIVIDER);
|
|
@@ -8249,34 +8246,17 @@ async function customSetup() {
|
|
|
8249
8246
|
});
|
|
8250
8247
|
}
|
|
8251
8248
|
console.log(DIVIDER);
|
|
8252
|
-
console.log(
|
|
8253
|
-
console.log(` ${
|
|
8254
|
-
console.log(` ${
|
|
8255
|
-
console.log(` ${
|
|
8256
|
-
console.log(` ${
|
|
8249
|
+
console.log(import_chalk3.default.bold("\n\u{1F389} Setup Complete!\n"));
|
|
8250
|
+
console.log(` ${import_chalk3.default.bold("IDE:")} ${selectedIDE.icon} ${selectedIDE.displayName}`);
|
|
8251
|
+
console.log(` ${import_chalk3.default.bold("Extensions:")} ${allExtensions.length} installed`);
|
|
8252
|
+
console.log(` ${import_chalk3.default.bold("User:")} ${loginResult?.email || "not logged in"}`);
|
|
8253
|
+
console.log(` ${import_chalk3.default.bold("Status:")} ${import_chalk3.default.green("Ready to connect")}`);
|
|
8257
8254
|
console.log();
|
|
8258
|
-
|
|
8259
|
-
|
|
8260
|
-
type: "confirm",
|
|
8261
|
-
name: "shouldLaunch",
|
|
8262
|
-
message: `Launch ${selectedIDE.displayName} now?`,
|
|
8263
|
-
default: true
|
|
8264
|
-
}
|
|
8265
|
-
]);
|
|
8266
|
-
if (shouldLaunch) {
|
|
8267
|
-
const launched = launchIDE(selectedIDE);
|
|
8268
|
-
if (launched) {
|
|
8269
|
-
console.log(import_chalk.default.green(`
|
|
8270
|
-
\u2713 ${selectedIDE.displayName} is starting...`));
|
|
8271
|
-
} else {
|
|
8272
|
-
console.log(import_chalk.default.yellow(`
|
|
8273
|
-
\u26A0 Could not launch automatically.`));
|
|
8274
|
-
}
|
|
8275
|
-
}
|
|
8276
|
-
console.log(import_chalk.default.gray("\nThank you for using ADHDev! \u{1F309}\n"));
|
|
8255
|
+
await startDaemonFlow();
|
|
8256
|
+
console.log(import_chalk3.default.gray("\nThank you for using ADHDev! \u{1F309}\n"));
|
|
8277
8257
|
}
|
|
8278
8258
|
async function loginFlow() {
|
|
8279
|
-
console.log(
|
|
8259
|
+
console.log(import_chalk3.default.bold("\n\u{1F510} Login to ADHDev\n"));
|
|
8280
8260
|
const { wantLogin } = await import_inquirer.default.prompt([
|
|
8281
8261
|
{
|
|
8282
8262
|
type: "confirm",
|
|
@@ -8306,17 +8286,17 @@ async function loginFlow() {
|
|
|
8306
8286
|
return null;
|
|
8307
8287
|
}
|
|
8308
8288
|
console.log();
|
|
8309
|
-
console.log(
|
|
8310
|
-
console.log(
|
|
8311
|
-
console.log(
|
|
8289
|
+
console.log(import_chalk3.default.cyan(" \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510"));
|
|
8290
|
+
console.log(import_chalk3.default.cyan(" \u2502") + ` Your code: ${import_chalk3.default.bold.white(userCode)} ` + import_chalk3.default.cyan("\u2502"));
|
|
8291
|
+
console.log(import_chalk3.default.cyan(" \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518"));
|
|
8312
8292
|
console.log();
|
|
8313
|
-
console.log(
|
|
8293
|
+
console.log(import_chalk3.default.gray(` Opening: ${verificationUrl}`));
|
|
8314
8294
|
console.log();
|
|
8315
8295
|
try {
|
|
8316
8296
|
await (0, import_open.default)(verificationUrl);
|
|
8317
|
-
console.log(
|
|
8297
|
+
console.log(import_chalk3.default.green(" \u2713 Browser opened \u2014 please sign in and approve"));
|
|
8318
8298
|
} catch {
|
|
8319
|
-
console.log(
|
|
8299
|
+
console.log(import_chalk3.default.yellow(` \u26A0 Could not open browser. Visit: ${verificationUrl}`));
|
|
8320
8300
|
}
|
|
8321
8301
|
const pollSpinner = (0, import_ora.default)("Waiting for authentication...").start();
|
|
8322
8302
|
const startTime = Date.now();
|
|
@@ -8335,7 +8315,7 @@ async function loginFlow() {
|
|
|
8335
8315
|
}
|
|
8336
8316
|
const data = await res.json();
|
|
8337
8317
|
if (data.status === "completed" && data.connectionToken) {
|
|
8338
|
-
pollSpinner.succeed(`Authenticated as ${
|
|
8318
|
+
pollSpinner.succeed(`Authenticated as ${import_chalk3.default.bold(data.user?.email || "user")}`);
|
|
8339
8319
|
return {
|
|
8340
8320
|
connectionToken: data.connectionToken,
|
|
8341
8321
|
email: data.user?.email,
|
|
@@ -8385,10 +8365,62 @@ async function injectTokenToIDE(ide, connectionToken) {
|
|
|
8385
8365
|
settings["adhdev.connectionToken"] = connectionToken;
|
|
8386
8366
|
settings["adhdev.autoConnect"] = true;
|
|
8387
8367
|
fs7.writeFileSync(settingsPath, JSON.stringify(settings, null, 4), "utf-8");
|
|
8388
|
-
console.log(
|
|
8368
|
+
console.log(import_chalk3.default.green(" \u2713 Connection token saved to IDE settings"));
|
|
8369
|
+
} catch (e) {
|
|
8370
|
+
console.log(import_chalk3.default.yellow(` \u26A0 Could not inject token: ${e.message}`));
|
|
8371
|
+
console.log(import_chalk3.default.gray(` You can set it manually: adhdev.connectionToken = ${connectionToken}`));
|
|
8372
|
+
}
|
|
8373
|
+
}
|
|
8374
|
+
async function startDaemonFlow() {
|
|
8375
|
+
const { isDaemonRunning: isDaemonRunning2 } = await Promise.resolve().then(() => (init_adhdev_daemon(), adhdev_daemon_exports));
|
|
8376
|
+
if (isDaemonRunning2()) {
|
|
8377
|
+
console.log(import_chalk3.default.green(" \u2713 Daemon is already running"));
|
|
8378
|
+
console.log(import_chalk3.default.gray(" Dashboard: https://app.adhf.dev/dashboard\n"));
|
|
8379
|
+
return;
|
|
8380
|
+
}
|
|
8381
|
+
const { startDaemon } = await import_inquirer.default.prompt([
|
|
8382
|
+
{
|
|
8383
|
+
type: "confirm",
|
|
8384
|
+
name: "startDaemon",
|
|
8385
|
+
message: "Start ADHDev Daemon now? (IDE monitor + agent hub)",
|
|
8386
|
+
default: true
|
|
8387
|
+
}
|
|
8388
|
+
]);
|
|
8389
|
+
if (!startDaemon) {
|
|
8390
|
+
console.log(import_chalk3.default.gray(" Start later: adhdev daemon\n"));
|
|
8391
|
+
return;
|
|
8392
|
+
}
|
|
8393
|
+
const daemonSpinner = (0, import_ora.default)("Starting daemon...").start();
|
|
8394
|
+
try {
|
|
8395
|
+
const { AdhdevDaemon: AdhdevDaemon2 } = await Promise.resolve().then(() => (init_adhdev_daemon(), adhdev_daemon_exports));
|
|
8396
|
+
const daemon = new AdhdevDaemon2();
|
|
8397
|
+
const { execSync: execSync6 } = await import("child_process");
|
|
8398
|
+
const os13 = await import("os");
|
|
8399
|
+
const path10 = await import("path");
|
|
8400
|
+
const logPath = path10.join(os13.homedir(), ".adhdev", "daemon.log");
|
|
8401
|
+
try {
|
|
8402
|
+
execSync6(`nohup adhdev daemon > "${logPath}" 2>&1 &`, {
|
|
8403
|
+
timeout: 3e3,
|
|
8404
|
+
stdio: "ignore"
|
|
8405
|
+
});
|
|
8406
|
+
} catch {
|
|
8407
|
+
daemon.start({ localPort: 19222, foreground: false }).catch(() => {
|
|
8408
|
+
});
|
|
8409
|
+
}
|
|
8410
|
+
await new Promise((r) => setTimeout(r, 2e3));
|
|
8411
|
+
if (isDaemonRunning2()) {
|
|
8412
|
+
daemonSpinner.succeed("Daemon started");
|
|
8413
|
+
console.log(import_chalk3.default.gray(" Dashboard: https://app.adhf.dev/dashboard"));
|
|
8414
|
+
console.log(import_chalk3.default.gray(` Logs: ${logPath}`));
|
|
8415
|
+
} else {
|
|
8416
|
+
daemonSpinner.succeed("Daemon starting in background");
|
|
8417
|
+
console.log(import_chalk3.default.gray(" Dashboard: https://app.adhf.dev/dashboard"));
|
|
8418
|
+
console.log(import_chalk3.default.gray(` Logs: ${logPath}`));
|
|
8419
|
+
}
|
|
8420
|
+
console.log();
|
|
8389
8421
|
} catch (e) {
|
|
8390
|
-
|
|
8391
|
-
console.log(
|
|
8422
|
+
daemonSpinner.fail(`Daemon start failed: ${e?.message || "Unknown"}`);
|
|
8423
|
+
console.log(import_chalk3.default.gray(" Manual: adhdev daemon\n"));
|
|
8392
8424
|
}
|
|
8393
8425
|
}
|
|
8394
8426
|
async function installCliOnly() {
|
|
@@ -8405,14 +8437,15 @@ async function installCliOnly() {
|
|
|
8405
8437
|
} catch {
|
|
8406
8438
|
}
|
|
8407
8439
|
const isNpx = process.env.npm_execpath?.includes("npx") || process.argv[1]?.includes("npx") || process.argv[1]?.includes("_npx");
|
|
8408
|
-
console.log(
|
|
8409
|
-
console.log(
|
|
8410
|
-
console.log(
|
|
8411
|
-
console.log(
|
|
8412
|
-
console.log(
|
|
8440
|
+
console.log(import_chalk3.default.bold("\n\u{1F527} ADHDev CLI\n"));
|
|
8441
|
+
console.log(import_chalk3.default.gray(" The `adhdev` command lets you:"));
|
|
8442
|
+
console.log(import_chalk3.default.gray(" \u2022 Start daemon \u2014 IDE monitor + agent hub (adhdev daemon)"));
|
|
8443
|
+
console.log(import_chalk3.default.gray(" \u2022 Launch IDE with CDP (adhdev launch cursor)"));
|
|
8444
|
+
console.log(import_chalk3.default.gray(" \u2022 Start CLI agents (adhdev launch gemini)"));
|
|
8445
|
+
console.log(import_chalk3.default.gray(" \u2022 Check status (adhdev status)"));
|
|
8413
8446
|
console.log();
|
|
8414
8447
|
if (currentVersion) {
|
|
8415
|
-
console.log(
|
|
8448
|
+
console.log(import_chalk3.default.green(` \u2713 Currently installed: v${currentVersion}`));
|
|
8416
8449
|
if (!isNpx) {
|
|
8417
8450
|
const { doUpdate } = await import_inquirer.default.prompt([{
|
|
8418
8451
|
type: "confirm",
|
|
@@ -8422,10 +8455,10 @@ async function installCliOnly() {
|
|
|
8422
8455
|
}]);
|
|
8423
8456
|
if (!doUpdate) return;
|
|
8424
8457
|
} else {
|
|
8425
|
-
console.log(
|
|
8458
|
+
console.log(import_chalk3.default.gray(" Updating to latest..."));
|
|
8426
8459
|
}
|
|
8427
8460
|
} else {
|
|
8428
|
-
console.log(
|
|
8461
|
+
console.log(import_chalk3.default.yellow(" \u2717 Not installed globally"));
|
|
8429
8462
|
if (!isNpx) {
|
|
8430
8463
|
const { doInstall } = await import_inquirer.default.prompt([{
|
|
8431
8464
|
type: "confirm",
|
|
@@ -8434,11 +8467,11 @@ async function installCliOnly() {
|
|
|
8434
8467
|
default: true
|
|
8435
8468
|
}]);
|
|
8436
8469
|
if (!doInstall) {
|
|
8437
|
-
console.log(
|
|
8470
|
+
console.log(import_chalk3.default.gray("\n You can install later: npm install -g adhdev\n"));
|
|
8438
8471
|
return;
|
|
8439
8472
|
}
|
|
8440
8473
|
} else {
|
|
8441
|
-
console.log(
|
|
8474
|
+
console.log(import_chalk3.default.gray(" Installing globally..."));
|
|
8442
8475
|
}
|
|
8443
8476
|
}
|
|
8444
8477
|
const installSpinner = (0, import_ora.default)("Installing adhdev CLI...").start();
|
|
@@ -8458,17 +8491,17 @@ async function installCliOnly() {
|
|
|
8458
8491
|
} catch {
|
|
8459
8492
|
}
|
|
8460
8493
|
installSpinner.succeed(`adhdev CLI ${currentVersion ? "updated" : "installed"} \u2713 (v${newVersion})`);
|
|
8461
|
-
console.log(
|
|
8462
|
-
console.log(
|
|
8494
|
+
console.log(import_chalk3.default.gray(" Try: adhdev daemon"));
|
|
8495
|
+
console.log(import_chalk3.default.gray(" adhdev status"));
|
|
8463
8496
|
console.log();
|
|
8464
8497
|
} catch (e) {
|
|
8465
8498
|
installSpinner.fail("Install failed");
|
|
8466
|
-
console.log(
|
|
8499
|
+
console.log(import_chalk3.default.yellow(` Error: ${e?.message?.split("\n")[0] || "Unknown"}`));
|
|
8467
8500
|
const osModule = await import("os");
|
|
8468
8501
|
if (osModule.platform() === "win32") {
|
|
8469
|
-
console.log(
|
|
8502
|
+
console.log(import_chalk3.default.gray(" On Windows, run PowerShell as Administrator"));
|
|
8470
8503
|
}
|
|
8471
|
-
console.log(
|
|
8504
|
+
console.log(import_chalk3.default.gray(" Manual: npm install -g adhdev@latest"));
|
|
8472
8505
|
console.log();
|
|
8473
8506
|
}
|
|
8474
8507
|
}
|
|
@@ -8505,10 +8538,10 @@ _cliProviderLoader.loadAll();
|
|
|
8505
8538
|
_cliProviderLoader.registerToDetector();
|
|
8506
8539
|
var program = new import_commander.Command();
|
|
8507
8540
|
program.name("adhdev").description("\u{1F309} ADHDev \u2014 Agent Dashboard Hub for your IDE").version(pkgVersion);
|
|
8508
|
-
program.command("setup").description("Run the interactive setup wizard").option("-f, --force", "Force re-run setup even if already configured").action(async (options) => {
|
|
8541
|
+
program.command("setup").description("Run the interactive setup wizard (detect IDEs, install bridge, login)").option("-f, --force", "Force re-run setup even if already configured").action(async (options) => {
|
|
8509
8542
|
await runWizard({ force: options.force });
|
|
8510
8543
|
});
|
|
8511
|
-
program.command("launch [target]").description("Launch IDE with CDP or start CLI agent (
|
|
8544
|
+
program.command("launch [target]").description("Launch IDE with CDP or start CLI agent (e.g. cursor, gemini, claude)").option("-w, --workspace <path>", "Workspace/folder to open").option("-n, --new-window", "Open in a new window").option("-d, --dir <path>", "Working directory for CLI agent", process.cwd()).action(async (targetArg, options) => {
|
|
8512
8545
|
const CLI_ALIASES = {
|
|
8513
8546
|
"claude": "claude-code",
|
|
8514
8547
|
"claude-code": "claude-code",
|
|
@@ -8753,7 +8786,7 @@ program.command("reset").description("Reset ADHDev configuration").action(async
|
|
|
8753
8786
|
console.log(import_chalk4.default.gray(" Run `adhdev setup` to reconfigure.\n"));
|
|
8754
8787
|
}
|
|
8755
8788
|
});
|
|
8756
|
-
program.command("daemon").description("Start ADHDev Daemon \u2014 unified
|
|
8789
|
+
program.command("daemon").description("\u{1F680} Start ADHDev Daemon \u2014 unified hub for IDE monitoring, agent management, and remote control").option("-p, --port <port>", "Local WS server port", "19222").option("--server <url>", "Override server URL for testing").option("--dev", "Enable Dev Mode \u2014 HTTP API on :19280 for script debugging").action(async (options) => {
|
|
8757
8790
|
const { AdhdevDaemon: AdhdevDaemon2 } = await Promise.resolve().then(() => (init_adhdev_daemon(), adhdev_daemon_exports));
|
|
8758
8791
|
const daemon = new AdhdevDaemon2();
|
|
8759
8792
|
await daemon.start({
|