@xaidenlabs/uso 1.1.65 → 1.1.68
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/package.json +36 -36
- package/src/commands/doctor.js +202 -126
- package/src/commands/uninstall.js +374 -199
- package/src/commands/workflow.js +443 -356
- package/src/platforms/linux.js +22 -6
- package/src/platforms/wsl.js +286 -195
package/package.json
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@xaidenlabs/uso",
|
|
3
|
-
"version": "1.1.
|
|
4
|
-
"description": "Universal Solana Development Toolchain. Native or Stealth WSL Mode. Build, test, and deploy without the friction.",
|
|
5
|
-
"bin": {
|
|
6
|
-
"uso": "bin/index.js"
|
|
7
|
-
},
|
|
8
|
-
"files": [
|
|
9
|
-
"bin",
|
|
10
|
-
"src",
|
|
11
|
-
"templates",
|
|
12
|
-
"anchor_program",
|
|
13
|
-
"anchor_project"
|
|
14
|
-
],
|
|
15
|
-
"scripts": {
|
|
16
|
-
"test": "echo \"Error: no test specified\" && exit 1"
|
|
17
|
-
},
|
|
18
|
-
"keywords": [
|
|
19
|
-
"solana",
|
|
20
|
-
"anchor",
|
|
21
|
-
"web3",
|
|
22
|
-
"rust",
|
|
23
|
-
"install",
|
|
24
|
-
"setup",
|
|
25
|
-
"developer-tools"
|
|
26
|
-
],
|
|
27
|
-
"author": "Xaiden Labs",
|
|
28
|
-
"license": "ISC",
|
|
29
|
-
"type": "commonjs",
|
|
30
|
-
"dependencies": {
|
|
31
|
-
"chalk": "^4.1.2",
|
|
32
|
-
"commander": "^14.0.3",
|
|
33
|
-
"ora": "^5.4.1",
|
|
34
|
-
"shelljs": "^0.10.0"
|
|
35
|
-
}
|
|
36
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@xaidenlabs/uso",
|
|
3
|
+
"version": "1.1.68",
|
|
4
|
+
"description": "Universal Solana Development Toolchain. Native or Stealth WSL Mode. Build, test, and deploy without the friction.",
|
|
5
|
+
"bin": {
|
|
6
|
+
"uso": "bin/index.js"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
"bin",
|
|
10
|
+
"src",
|
|
11
|
+
"templates",
|
|
12
|
+
"anchor_program",
|
|
13
|
+
"anchor_project"
|
|
14
|
+
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"solana",
|
|
20
|
+
"anchor",
|
|
21
|
+
"web3",
|
|
22
|
+
"rust",
|
|
23
|
+
"install",
|
|
24
|
+
"setup",
|
|
25
|
+
"developer-tools"
|
|
26
|
+
],
|
|
27
|
+
"author": "Xaiden Labs",
|
|
28
|
+
"license": "ISC",
|
|
29
|
+
"type": "commonjs",
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"chalk": "^4.1.2",
|
|
32
|
+
"commander": "^14.0.3",
|
|
33
|
+
"ora": "^5.4.1",
|
|
34
|
+
"shelljs": "^0.10.0"
|
|
35
|
+
}
|
|
36
|
+
}
|
package/src/commands/doctor.js
CHANGED
|
@@ -1,167 +1,243 @@
|
|
|
1
|
-
const shell = require(
|
|
2
|
-
const os = require(
|
|
3
|
-
const path = require(
|
|
4
|
-
const fs = require(
|
|
5
|
-
const { log } = require(
|
|
1
|
+
const shell = require("shelljs");
|
|
2
|
+
const os = require("os");
|
|
3
|
+
const path = require("path");
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const { log } = require("../utils/logger");
|
|
6
|
+
const { isStealthMode } = require("../utils/stealth");
|
|
7
|
+
const { runWsl } = require("../utils/wsl-bridge");
|
|
8
|
+
|
|
9
|
+
const getStealthContext = () => {
|
|
10
|
+
if (os.platform() !== "win32") return { enabled: false, distro: "Ubuntu" };
|
|
11
|
+
return isStealthMode();
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const runVersionCheck = (tool, stealth) => {
|
|
15
|
+
if (stealth.enabled) {
|
|
16
|
+
// Mirror the init/workflow environment inside WSL.
|
|
17
|
+
const envSetup =
|
|
18
|
+
'source $HOME/.cargo/env 2>/dev/null; export PATH="$HOME/.local/share/solana/install/active_release/bin:$HOME/.avm/bin:$PATH"';
|
|
19
|
+
return runWsl(`${envSetup} && ${tool} --version`, {
|
|
20
|
+
distro: stealth.distro,
|
|
21
|
+
execOpts: { silent: true },
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return shell.exec(`${tool} --version`, { silent: true });
|
|
26
|
+
};
|
|
6
27
|
|
|
7
28
|
const checkGit = (silent = false) => {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
29
|
+
const installed = !!shell.which("git");
|
|
30
|
+
if (!silent) {
|
|
31
|
+
if (installed) log.success("✅ Git installed");
|
|
32
|
+
else log.error("❌ Git not found");
|
|
33
|
+
}
|
|
34
|
+
return installed;
|
|
14
35
|
};
|
|
15
36
|
|
|
16
37
|
const checkWsl = (silent = false) => {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
38
|
+
// Only relevant on Windows
|
|
39
|
+
if (os.platform() !== "win32") return true;
|
|
40
|
+
|
|
41
|
+
// 1. Check wsl.exe exists
|
|
42
|
+
const hasWslBinary = !!shell.which("wsl");
|
|
43
|
+
if (!hasWslBinary) {
|
|
44
|
+
if (!silent) {
|
|
45
|
+
log.error("❌ WSL not installed");
|
|
46
|
+
log.warn(
|
|
47
|
+
" 👉 Run 'uso install' to automatically install WSL (admin permission required).",
|
|
48
|
+
);
|
|
28
49
|
}
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
29
52
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
53
|
+
// 2. Check WSL feature is active
|
|
54
|
+
const statusCheck = shell.exec("wsl --status", { silent: true });
|
|
55
|
+
if (statusCheck.code !== 0) {
|
|
56
|
+
if (!silent) {
|
|
57
|
+
log.warn(
|
|
58
|
+
"⚠️ WSL is installed but not fully configured (restart may be pending).",
|
|
59
|
+
);
|
|
60
|
+
log.warn(" 👉 Try restarting your PC, then run 'uso install' again.");
|
|
38
61
|
}
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
39
64
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
return false;
|
|
65
|
+
// 3. Check Ubuntu distro is ready
|
|
66
|
+
const ubuntuCheck = shell.exec("wsl -d Ubuntu -e true", { silent: true });
|
|
67
|
+
if (ubuntuCheck.code !== 0) {
|
|
68
|
+
if (!silent) {
|
|
69
|
+
log.warn("⚠️ WSL installed but Ubuntu distro is not yet set up.");
|
|
70
|
+
log.warn(" 👉 Run 'uso install' to finish the setup.");
|
|
48
71
|
}
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
49
74
|
|
|
50
|
-
|
|
51
|
-
|
|
75
|
+
if (!silent) log.success("✅ WSL installed and Ubuntu ready");
|
|
76
|
+
return true;
|
|
52
77
|
};
|
|
53
78
|
|
|
54
79
|
const checkRust = (silent = false) => {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
80
|
+
const stealth = getStealthContext();
|
|
81
|
+
const rustc = runVersionCheck("rustc", stealth);
|
|
82
|
+
const installed = rustc.code === 0;
|
|
83
|
+
if (!silent) {
|
|
84
|
+
if (installed) {
|
|
85
|
+
const scope = stealth.enabled ? " via WSL" : "";
|
|
86
|
+
log.success(`✅ Rust installed${scope} (${rustc.stdout.trim()})`);
|
|
87
|
+
} else {
|
|
88
|
+
const scope = stealth.enabled ? " in WSL environment" : "";
|
|
89
|
+
log.error(`❌ Rust not found${scope}`);
|
|
60
90
|
}
|
|
61
|
-
|
|
91
|
+
}
|
|
92
|
+
return installed;
|
|
62
93
|
};
|
|
63
94
|
|
|
64
95
|
const checkSolana = (silent = false) => {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
96
|
+
const stealth = getStealthContext();
|
|
97
|
+
|
|
98
|
+
if (stealth.enabled) {
|
|
99
|
+
const solanaWsl = runVersionCheck("solana", stealth);
|
|
100
|
+
const installed = solanaWsl.code === 0;
|
|
101
|
+
if (!silent) {
|
|
102
|
+
if (installed)
|
|
103
|
+
log.success(
|
|
104
|
+
`✅ Solana CLI installed via WSL (${solanaWsl.stdout.trim()})`,
|
|
105
|
+
);
|
|
106
|
+
else log.error("❌ Solana CLI not found in WSL environment");
|
|
70
107
|
}
|
|
108
|
+
return installed;
|
|
109
|
+
}
|
|
71
110
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
111
|
+
// 1. Try PATH first
|
|
112
|
+
let solana = shell.exec("solana --version", { silent: true });
|
|
113
|
+
if (solana.code === 0) {
|
|
114
|
+
if (!silent)
|
|
115
|
+
log.success(`✅ Solana CLI installed (${solana.stdout.trim()})`);
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// 2. Try default Windows path if on Windows
|
|
120
|
+
if (os.platform() === "win32") {
|
|
121
|
+
const home = os.homedir();
|
|
122
|
+
// Modern path (Agave/Solana)
|
|
123
|
+
const defaultPath = path.join(
|
|
124
|
+
home,
|
|
125
|
+
".local",
|
|
126
|
+
"share",
|
|
127
|
+
"solana",
|
|
128
|
+
"install",
|
|
129
|
+
"active_release",
|
|
130
|
+
"bin",
|
|
131
|
+
"solana.exe",
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
if (fs.existsSync(defaultPath)) {
|
|
135
|
+
if (!silent)
|
|
136
|
+
log.success(`✅ Solana CLI installed (Found at ${defaultPath})`);
|
|
137
|
+
// Optionally we could try to get version from it, but existence is enough to skip install
|
|
138
|
+
return true;
|
|
83
139
|
}
|
|
140
|
+
}
|
|
84
141
|
|
|
85
|
-
|
|
86
|
-
|
|
142
|
+
if (!silent) log.error("❌ Solana CLI not found");
|
|
143
|
+
return false;
|
|
87
144
|
};
|
|
88
145
|
|
|
89
146
|
const checkAnchor = (silent = false) => {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
147
|
+
const stealth = getStealthContext();
|
|
148
|
+
const anchor = runVersionCheck("anchor", stealth);
|
|
149
|
+
const installed = anchor.code === 0;
|
|
150
|
+
if (!silent) {
|
|
151
|
+
if (installed) {
|
|
152
|
+
const scope = stealth.enabled ? " via WSL" : "";
|
|
153
|
+
log.success(`✅ Anchor installed${scope} (${anchor.stdout.trim()})`);
|
|
154
|
+
} else {
|
|
155
|
+
const scope = stealth.enabled ? " in WSL environment" : "";
|
|
156
|
+
log.error(`❌ Anchor not found${scope}`);
|
|
95
157
|
}
|
|
96
|
-
|
|
158
|
+
}
|
|
159
|
+
return installed;
|
|
97
160
|
};
|
|
98
161
|
|
|
99
162
|
const checkCppTools = (silent = false) => {
|
|
100
|
-
|
|
163
|
+
if (os.platform() !== "win32") return true; // Not needed on others
|
|
101
164
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
165
|
+
// 1. Check PATH
|
|
166
|
+
const hasCl = !!shell.which("cl");
|
|
167
|
+
if (hasCl) {
|
|
168
|
+
if (!silent) log.success("✅ C++ Build Tools (cl.exe) found in PATH");
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// 2. Check via vswhere
|
|
173
|
+
const programFiles =
|
|
174
|
+
process.env["ProgramFiles(x86)"] || process.env["ProgramFiles"];
|
|
175
|
+
const vswherePath = path.join(
|
|
176
|
+
programFiles,
|
|
177
|
+
"Microsoft Visual Studio",
|
|
178
|
+
"Installer",
|
|
179
|
+
"vswhere.exe",
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
if (fs.existsSync(vswherePath)) {
|
|
183
|
+
// Use quotes around * to prevent shell globbing issues
|
|
184
|
+
// We look for ANY product that installs VC tools.
|
|
185
|
+
// We relax the requirement to just 'installationPath' to confirm VS is present,
|
|
186
|
+
// as 'Desktop development with C++' is the standard workload.
|
|
187
|
+
// But to be safe, we should check for the VC component if possible.
|
|
188
|
+
// Tests showed that -products * returned the install path successfully.
|
|
189
|
+
|
|
190
|
+
const cmd = `"${vswherePath}" -latest -products "*" -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath`;
|
|
191
|
+
const result = shell.exec(cmd, { silent: true });
|
|
192
|
+
|
|
193
|
+
if (result.code === 0 && result.stdout.trim().length > 0) {
|
|
194
|
+
if (!silent) log.success("✅ C++ Build Tools detected (via vswhere).");
|
|
195
|
+
return true;
|
|
107
196
|
}
|
|
108
197
|
|
|
109
|
-
//
|
|
110
|
-
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
if (fs.existsSync(vswherePath)) {
|
|
114
|
-
// Use quotes around * to prevent shell globbing issues
|
|
115
|
-
// We look for ANY product that installs VC tools.
|
|
116
|
-
// We relax the requirement to just 'installationPath' to confirm VS is present,
|
|
117
|
-
// as 'Desktop development with C++' is the standard workload.
|
|
118
|
-
// But to be safe, we should check for the VC component if possible.
|
|
119
|
-
// Tests showed that -products * returned the install path successfully.
|
|
120
|
-
|
|
121
|
-
const cmd = `"${vswherePath}" -latest -products "*" -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath`;
|
|
122
|
-
const result = shell.exec(cmd, { silent: true });
|
|
123
|
-
|
|
124
|
-
if (result.code === 0 && result.stdout.trim().length > 0) {
|
|
125
|
-
if (!silent) log.success("✅ C++ Build Tools detected (via vswhere).");
|
|
126
|
-
return true;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// Fallback: Check for just the workload, or even just the existence of VS Build Tools
|
|
130
|
-
// usage: vswhere -latest -products * -requires Microsoft.VisualStudio.Workload.VCTools
|
|
131
|
-
const cmd2 = `"${vswherePath}" -latest -products "*" -requires Microsoft.VisualStudio.Workload.VCTools -property installationPath`;
|
|
132
|
-
const result2 = shell.exec(cmd2, { silent: true });
|
|
133
|
-
|
|
134
|
-
if (result2.code === 0 && result2.stdout.trim().length > 0) {
|
|
135
|
-
if (!silent) log.success("✅ C++ Build Tools detected (via vswhere workload).");
|
|
136
|
-
return true;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
198
|
+
// Fallback: Check for just the workload, or even just the existence of VS Build Tools
|
|
199
|
+
// usage: vswhere -latest -products * -requires Microsoft.VisualStudio.Workload.VCTools
|
|
200
|
+
const cmd2 = `"${vswherePath}" -latest -products "*" -requires Microsoft.VisualStudio.Workload.VCTools -property installationPath`;
|
|
201
|
+
const result2 = shell.exec(cmd2, { silent: true });
|
|
139
202
|
|
|
140
|
-
if (
|
|
141
|
-
|
|
142
|
-
log.
|
|
203
|
+
if (result2.code === 0 && result2.stdout.trim().length > 0) {
|
|
204
|
+
if (!silent)
|
|
205
|
+
log.success("✅ C++ Build Tools detected (via vswhere workload).");
|
|
206
|
+
return true;
|
|
143
207
|
}
|
|
144
|
-
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (!silent) {
|
|
211
|
+
log.warn("⚠️ C++ Build Tools (cl.exe) not found.");
|
|
212
|
+
log.warn(" Rust requires 'Desktop development with C++' to compile.");
|
|
213
|
+
}
|
|
214
|
+
return false;
|
|
145
215
|
};
|
|
146
216
|
|
|
147
217
|
const doctor = async () => {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
218
|
+
const platform = os.platform();
|
|
219
|
+
const stealth = getStealthContext();
|
|
220
|
+
log.header(`🩺 Running Doctor for ${platform}...`);
|
|
221
|
+
if (platform === "win32" && stealth.enabled) {
|
|
222
|
+
log.info(
|
|
223
|
+
`🐧 Stealth Mode active (WSL distro: ${stealth.distro}). Checking toolchain inside WSL.`,
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
checkGit();
|
|
228
|
+
if (platform === "win32") checkWsl();
|
|
229
|
+
checkRust();
|
|
230
|
+
checkSolana();
|
|
231
|
+
checkAnchor();
|
|
232
|
+
checkCppTools();
|
|
157
233
|
};
|
|
158
234
|
|
|
159
235
|
module.exports = {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
236
|
+
doctor,
|
|
237
|
+
checkGit,
|
|
238
|
+
checkWsl,
|
|
239
|
+
checkRust,
|
|
240
|
+
checkSolana,
|
|
241
|
+
checkAnchor,
|
|
242
|
+
checkCppTools,
|
|
167
243
|
};
|