@xaidenlabs/uso 1.1.80 → 1.1.82
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/README.md +45 -0
- package/bin/index.js +20 -0
- package/package.json +1 -1
- package/src/commands/agent.js +295 -0
- package/src/commands/init.js +16 -0
- package/src/commands/uninstall.js +69 -0
- package/src/platforms/wsl.js +49 -0
package/README.md
CHANGED
|
@@ -10,6 +10,7 @@ USO is a zero-friction CLI toolchain that installs, manages, and runs your entir
|
|
|
10
10
|
|
|
11
11
|
- [Installation](#installation)
|
|
12
12
|
- [Quick Start](#quick-start)
|
|
13
|
+
- [AI Agent (New)](#ai-agent-new)
|
|
13
14
|
- [Stealth WSL Mode (Windows)](#stealth-wsl-mode-windows)
|
|
14
15
|
- [Full Environment Setup](#full-environment-setup)
|
|
15
16
|
- [Granular Installation](#granular-installation)
|
|
@@ -66,6 +67,48 @@ uso dev
|
|
|
66
67
|
|
|
67
68
|
---
|
|
68
69
|
|
|
70
|
+
## AI Agent (New)
|
|
71
|
+
|
|
72
|
+
USO isn't just a command runner — it's an **Autonomous AI Agent** that can write code, build programs, debug errors, and deploy. Powered by ReAct (Reason + Act) architecture, the agent thinks step-by-step and uses tools to accomplish your goals.
|
|
73
|
+
|
|
74
|
+
### 1. Configure an LLM Provider
|
|
75
|
+
|
|
76
|
+
The agent needs an LLM to think. It supports four providers out of the box:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# Option A: Local & Free (Ollama)
|
|
80
|
+
# Install from ollama.com, then run:
|
|
81
|
+
ollama pull llama3.1:8b
|
|
82
|
+
|
|
83
|
+
# Option B: GitHub Models (Free with GitHub Account)
|
|
84
|
+
uso agent-config --github-token <your-github-pat>
|
|
85
|
+
|
|
86
|
+
# Option C: Gemini
|
|
87
|
+
uso agent-config --gemini-key <your-api-key>
|
|
88
|
+
|
|
89
|
+
# Option D: OpenAI
|
|
90
|
+
uso agent-config --openai-key <your-api-key>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### 2. Give it a Goal
|
|
94
|
+
|
|
95
|
+
Just tell the agent what you want to do. It will check your environment, plan a strategy, execute the commands, and automatically self-heal if any step fails.
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# General environment fixing
|
|
99
|
+
uso agent "Check my Solana development environment and fix any missing tools"
|
|
100
|
+
|
|
101
|
+
# Build and test cycle
|
|
102
|
+
uso agent "Build my program and run the tests. If tests fail, fix the errors."
|
|
103
|
+
|
|
104
|
+
# Deployment
|
|
105
|
+
uso agent "Deploy my staking program to devnet and airdrop SOL if I don't have enough."
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
The agent runs a continuous FSM loop (`plan` → `execute` → `validate` → `heal`), streaming its thoughts and actions directly to your terminal.
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
69
112
|
## Stealth WSL Mode (Windows Only)
|
|
70
113
|
|
|
71
114
|
**The recommended mode for Windows developers.** Stealth Mode deploys a hidden WSL2 Linux environment (the "Uso Engine") that runs all your tooling inside Linux while you stay in PowerShell.
|
|
@@ -397,6 +440,8 @@ npm uninstall -g @xaidenlabs/uso
|
|
|
397
440
|
| `uso init rust` | `uso install rust` | Install Rust only |
|
|
398
441
|
| `uso init solana` | `uso install solana` | Install Solana CLI only |
|
|
399
442
|
| `uso init anchor` | `uso install anchor` | Install Anchor Framework only |
|
|
443
|
+
| `uso agent <goal>` | — | Run the Autonomous AI Agent |
|
|
444
|
+
| `uso agent-config` | — | Configure Agent LLM providers |
|
|
400
445
|
| `uso doctor` | — | Diagnose environment |
|
|
401
446
|
| `uso verify` | — | End-to-end verification build |
|
|
402
447
|
| `uso create <name>` | — | Scaffold a new Anchor project |
|
package/bin/index.js
CHANGED
|
@@ -6,6 +6,7 @@ const { verify } = require('../src/commands/verify');
|
|
|
6
6
|
const { create } = require('../src/commands/create');
|
|
7
7
|
const { build, test, deploy, clean, unblock, airdrop, address, balance, validator, dev } = require('../src/commands/workflow');
|
|
8
8
|
const { uninstall } = require('../src/commands/uninstall');
|
|
9
|
+
const { agent, agentConfig } = require('../src/commands/agent');
|
|
9
10
|
|
|
10
11
|
program
|
|
11
12
|
.name('uso')
|
|
@@ -16,12 +17,14 @@ program
|
|
|
16
17
|
.command('init [component]')
|
|
17
18
|
.alias('install')
|
|
18
19
|
.description('Install Rust, Solana CLI, Anchor Framework, or specific component (rust, solana, anchor)')
|
|
20
|
+
.option('-g, --global', 'Compatibility flag (ignored). uso manages toolchain components, not npm packages')
|
|
19
21
|
.option('--wsl', 'Install in Stealth WSL Mode (Windows Only)')
|
|
20
22
|
.action(init);
|
|
21
23
|
|
|
22
24
|
program
|
|
23
25
|
.command('setup [component]')
|
|
24
26
|
.description('Alias for init (Install components)')
|
|
27
|
+
.option('-g, --global', 'Compatibility flag (ignored). uso manages toolchain components, not npm packages')
|
|
25
28
|
.option('--wsl', 'Install in Stealth WSL Mode (Windows Only)')
|
|
26
29
|
.action(init);
|
|
27
30
|
|
|
@@ -99,4 +102,21 @@ program
|
|
|
99
102
|
.description('Uninstall uso components (rust, solana, anchor) or all')
|
|
100
103
|
.action(uninstall);
|
|
101
104
|
|
|
105
|
+
program
|
|
106
|
+
.command('agent [goal...]')
|
|
107
|
+
.description('Start the AI Agent to accomplish a goal autonomously')
|
|
108
|
+
.option('--model <model>', 'LLM model to use (e.g., llama3.1:8b, gemini-2.0-flash, openai/gpt-4o)')
|
|
109
|
+
.option('--provider <provider>', 'Force a specific LLM provider (ollama, gemini, openai, github)')
|
|
110
|
+
.option('--max-loops <n>', 'Maximum reasoning iterations', '3')
|
|
111
|
+
.option('--verbose', 'Show full reasoning traces')
|
|
112
|
+
.action(agent);
|
|
113
|
+
|
|
114
|
+
program
|
|
115
|
+
.command('agent-config')
|
|
116
|
+
.description('Configure API keys and preferences for the AI Agent')
|
|
117
|
+
.option('--gemini-key <key>', 'Set Gemini API key')
|
|
118
|
+
.option('--openai-key <key>', 'Set OpenAI API key')
|
|
119
|
+
.option('--github-token <token>', 'Set GitHub Models PAT token')
|
|
120
|
+
.action(agentConfig);
|
|
121
|
+
|
|
102
122
|
program.parse(process.argv);
|
package/package.json
CHANGED
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
const os = require("os");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const chalk = require("chalk");
|
|
4
|
+
const { log, spinner } = require("../utils/logger");
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* `uso agent "<goal>"` — Run the AI Agent to accomplish a goal.
|
|
8
|
+
*
|
|
9
|
+
* This command handler:
|
|
10
|
+
* 1. Loads agent config from ~/.uso-agent.json
|
|
11
|
+
* 2. Resolves an LLM provider (Ollama → GitHub → Gemini → OpenAI)
|
|
12
|
+
* 3. Runs the ReAct FSM loop
|
|
13
|
+
* 4. Streams reasoning + actions to the terminal with styled output
|
|
14
|
+
*/
|
|
15
|
+
const agent = async (goalParts, options) => {
|
|
16
|
+
// Commander passes args differently depending on definition
|
|
17
|
+
const goalArray = Array.isArray(goalParts) ? goalParts : [goalParts];
|
|
18
|
+
const goal = goalArray.filter(Boolean).join(" ").trim();
|
|
19
|
+
|
|
20
|
+
if (!goal) {
|
|
21
|
+
log.error("❌ No goal provided.");
|
|
22
|
+
log.info('Usage: uso agent "Deploy my staking program to devnet"');
|
|
23
|
+
log.info(' uso agent "Check my environment and fix any issues"');
|
|
24
|
+
log.info(' uso agent "Build and test my program"');
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Dynamic import of uso-core (ESM from CJS)
|
|
29
|
+
let UsoAgent, loadAgentConfig;
|
|
30
|
+
try {
|
|
31
|
+
const core = require("../../packages/uso-core/dist/cjs/index.js");
|
|
32
|
+
UsoAgent = core.UsoAgent;
|
|
33
|
+
loadAgentConfig = core.loadAgentConfig;
|
|
34
|
+
} catch (err) {
|
|
35
|
+
log.error("❌ uso-core agent module not found.");
|
|
36
|
+
log.warn(
|
|
37
|
+
"Run 'cd packages/uso-core && npm run build' to compile the agent.",
|
|
38
|
+
);
|
|
39
|
+
log.warn(`Detail: ${err.message}`);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const config = loadAgentConfig();
|
|
44
|
+
|
|
45
|
+
// Override config from CLI flags
|
|
46
|
+
if (options.model) {
|
|
47
|
+
// Try to infer provider from model name
|
|
48
|
+
if (options.model.includes("/")) {
|
|
49
|
+
// GitHub Models format: "openai/gpt-4o-mini"
|
|
50
|
+
config.github = { ...config.github, model: options.model };
|
|
51
|
+
} else if (options.model.startsWith("gemini")) {
|
|
52
|
+
config.gemini = { ...config.gemini, model: options.model };
|
|
53
|
+
} else if (
|
|
54
|
+
options.model.startsWith("gpt") ||
|
|
55
|
+
options.model.startsWith("o1") ||
|
|
56
|
+
options.model.startsWith("o3")
|
|
57
|
+
) {
|
|
58
|
+
config.openai = { ...config.openai, model: options.model };
|
|
59
|
+
} else {
|
|
60
|
+
config.ollama = { ...config.ollama, model: options.model };
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const maxLoops = parseInt(options.maxLoops || "3", 10);
|
|
65
|
+
|
|
66
|
+
// ─── Banner ────────────────────────────────────────────────
|
|
67
|
+
console.log();
|
|
68
|
+
console.log(
|
|
69
|
+
chalk.bold.cyan(" ┌─────────────────────────────────────────┐"),
|
|
70
|
+
);
|
|
71
|
+
console.log(
|
|
72
|
+
chalk.bold.cyan(" │") +
|
|
73
|
+
chalk.bold.white(" USO Agent v1.0 ") +
|
|
74
|
+
chalk.bold.cyan("│"),
|
|
75
|
+
);
|
|
76
|
+
console.log(
|
|
77
|
+
chalk.bold.cyan(" │") +
|
|
78
|
+
chalk.dim(" Autonomous Solana DevOps Engine ") +
|
|
79
|
+
chalk.bold.cyan("│"),
|
|
80
|
+
);
|
|
81
|
+
console.log(
|
|
82
|
+
chalk.bold.cyan(" └─────────────────────────────────────────┘"),
|
|
83
|
+
);
|
|
84
|
+
console.log();
|
|
85
|
+
console.log(chalk.dim(" Goal: ") + chalk.white.bold(goal));
|
|
86
|
+
console.log(chalk.dim(" Max iterations: ") + chalk.yellow(maxLoops));
|
|
87
|
+
console.log();
|
|
88
|
+
|
|
89
|
+
// ─── FSM Callbacks (render to terminal) ────────────────────
|
|
90
|
+
const callbacks = {
|
|
91
|
+
onPhaseChange: (phase, state) => {
|
|
92
|
+
const phases = {
|
|
93
|
+
planning: "🧠 Planning",
|
|
94
|
+
executing: "⚡ Executing",
|
|
95
|
+
validating: "✅ Validating",
|
|
96
|
+
healing: "🔧 Self-Healing",
|
|
97
|
+
};
|
|
98
|
+
if (phases[phase]) {
|
|
99
|
+
console.log(chalk.dim(` ── ${phases[phase]} ──`));
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
onThought: (thought, state) => {
|
|
104
|
+
console.log(chalk.blue(" 💭 ") + chalk.italic(thought));
|
|
105
|
+
},
|
|
106
|
+
|
|
107
|
+
onToolCall: (toolName, params, state) => {
|
|
108
|
+
const paramStr = Object.keys(params).length > 0
|
|
109
|
+
? chalk.dim(` ${JSON.stringify(params).slice(0, 80)}`)
|
|
110
|
+
: "";
|
|
111
|
+
console.log(chalk.yellow(" 🔧 ") + chalk.bold(toolName) + paramStr);
|
|
112
|
+
},
|
|
113
|
+
|
|
114
|
+
onObservation: (observation, success, state) => {
|
|
115
|
+
const lines = observation.split("\n").slice(0, 10);
|
|
116
|
+
const color = success ? chalk.green : chalk.red;
|
|
117
|
+
const icon = success ? " ✅ " : " ❌ ";
|
|
118
|
+
|
|
119
|
+
for (const line of lines) {
|
|
120
|
+
if (line.trim()) {
|
|
121
|
+
console.log(color(icon + line.trim().slice(0, 120)));
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (observation.split("\n").length > 10) {
|
|
125
|
+
console.log(chalk.dim(" ... (output truncated)"));
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
|
|
129
|
+
onIteration: (iteration, maxIterations, state) => {
|
|
130
|
+
console.log(
|
|
131
|
+
chalk.dim(`\n ─── Iteration ${iteration}/${maxIterations} ───`),
|
|
132
|
+
);
|
|
133
|
+
},
|
|
134
|
+
|
|
135
|
+
onComplete: (summary, state) => {
|
|
136
|
+
console.log();
|
|
137
|
+
console.log(chalk.green.bold(" ✅ GOAL ACCOMPLISHED"));
|
|
138
|
+
console.log(chalk.green(" " + summary));
|
|
139
|
+
console.log();
|
|
140
|
+
},
|
|
141
|
+
|
|
142
|
+
onFailed: (reason, state) => {
|
|
143
|
+
console.log();
|
|
144
|
+
console.log(chalk.red.bold(" ❌ GOAL FAILED"));
|
|
145
|
+
console.log(chalk.red(" " + reason));
|
|
146
|
+
console.log();
|
|
147
|
+
},
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
// ─── Run Agent ─────────────────────────────────────────────
|
|
151
|
+
const spin = spinner("Resolving LLM provider...").start();
|
|
152
|
+
|
|
153
|
+
try {
|
|
154
|
+
const usoAgent = new UsoAgent(config);
|
|
155
|
+
|
|
156
|
+
// Resolve LLM first to show which provider is being used
|
|
157
|
+
const llmDiag = await usoAgent.diagnoseLlm();
|
|
158
|
+
const available = llmDiag.filter((d) => d.available);
|
|
159
|
+
|
|
160
|
+
if (available.length === 0) {
|
|
161
|
+
spin.fail("No LLM provider available.");
|
|
162
|
+
console.log();
|
|
163
|
+
log.error("The USO Agent needs at least one LLM to reason.");
|
|
164
|
+
console.log();
|
|
165
|
+
log.info("Options (pick any):");
|
|
166
|
+
log.info(" 1. Install Ollama (free, local): https://ollama.com");
|
|
167
|
+
log.info(" Then run: ollama pull llama3.1:8b");
|
|
168
|
+
log.info(
|
|
169
|
+
" 2. uso agent-config --github-token <your-github-pat>",
|
|
170
|
+
);
|
|
171
|
+
log.info(
|
|
172
|
+
" 3. uso agent-config --gemini-key <your-api-key>",
|
|
173
|
+
);
|
|
174
|
+
log.info(
|
|
175
|
+
" 4. uso agent-config --openai-key <your-api-key>",
|
|
176
|
+
);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
spin.succeed(
|
|
181
|
+
`LLM: ${chalk.bold(available[0].name)} ${chalk.dim(`(${available.length} provider${available.length > 1 ? "s" : ""} available)`)}`,
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
// Run the agent
|
|
185
|
+
const result = await usoAgent.run({
|
|
186
|
+
goal,
|
|
187
|
+
provider: options.provider,
|
|
188
|
+
maxIterations: maxLoops,
|
|
189
|
+
verbose: !!options.verbose,
|
|
190
|
+
callbacks,
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
// ─── Summary ───────────────────────────────────────────
|
|
194
|
+
console.log(chalk.dim(" ─────────────────────────────────────────"));
|
|
195
|
+
console.log(
|
|
196
|
+
chalk.dim(" Provider: ") + chalk.white(result.llmProvider),
|
|
197
|
+
);
|
|
198
|
+
console.log(
|
|
199
|
+
chalk.dim(" Iterations: ") +
|
|
200
|
+
chalk.white(`${result.totalIterations}/${maxLoops}`),
|
|
201
|
+
);
|
|
202
|
+
console.log(
|
|
203
|
+
chalk.dim(" Duration: ") +
|
|
204
|
+
chalk.white(`${(result.durationMs / 1000).toFixed(1)}s`),
|
|
205
|
+
);
|
|
206
|
+
console.log(
|
|
207
|
+
chalk.dim(" Status: ") +
|
|
208
|
+
(result.success
|
|
209
|
+
? chalk.green.bold("SUCCESS")
|
|
210
|
+
: chalk.red.bold("FAILED")),
|
|
211
|
+
);
|
|
212
|
+
console.log();
|
|
213
|
+
|
|
214
|
+
process.exitCode = result.success ? 0 : 1;
|
|
215
|
+
} catch (err) {
|
|
216
|
+
spin.fail("Agent failed to start.");
|
|
217
|
+
log.error(`Error: ${err.message}`);
|
|
218
|
+
process.exitCode = 1;
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* `uso agent-config` — Configure API keys and preferences.
|
|
224
|
+
*/
|
|
225
|
+
const agentConfig = async (options) => {
|
|
226
|
+
let setApiKey, loadAgentConfig, saveAgentConfig;
|
|
227
|
+
try {
|
|
228
|
+
const core = require("../../packages/uso-core/dist/cjs/index.js");
|
|
229
|
+
setApiKey = core.setApiKey;
|
|
230
|
+
loadAgentConfig = core.loadAgentConfig;
|
|
231
|
+
saveAgentConfig = core.saveAgentConfig;
|
|
232
|
+
} catch (err) {
|
|
233
|
+
log.error("❌ uso-core agent module not found.");
|
|
234
|
+
log.warn("Run 'cd packages/uso-core && npm run build' to compile.");
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Set API keys from flags
|
|
239
|
+
if (options.geminiKey) {
|
|
240
|
+
setApiKey("gemini", options.geminiKey);
|
|
241
|
+
log.success("✅ Gemini API key saved.");
|
|
242
|
+
}
|
|
243
|
+
if (options.openaiKey) {
|
|
244
|
+
setApiKey("openai", options.openaiKey);
|
|
245
|
+
log.success("✅ OpenAI API key saved.");
|
|
246
|
+
}
|
|
247
|
+
if (options.githubToken) {
|
|
248
|
+
setApiKey("github", options.githubToken);
|
|
249
|
+
log.success("✅ GitHub Models token saved.");
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Show current config
|
|
253
|
+
if (!options.geminiKey && !options.openaiKey && !options.githubToken) {
|
|
254
|
+
const config = loadAgentConfig();
|
|
255
|
+
console.log();
|
|
256
|
+
console.log(chalk.bold("USO Agent Configuration"));
|
|
257
|
+
console.log(chalk.dim("Config file: ~/.uso-agent.json"));
|
|
258
|
+
console.log();
|
|
259
|
+
console.log(chalk.bold("LLM Providers:"));
|
|
260
|
+
console.log(
|
|
261
|
+
` Ollama: model=${chalk.cyan(config.ollama?.model || "llama3.1:8b")} url=${chalk.dim(config.ollama?.baseUrl || "http://localhost:11434")}`,
|
|
262
|
+
);
|
|
263
|
+
console.log(
|
|
264
|
+
` GitHub: model=${chalk.cyan(config.github?.model || "openai/gpt-4o-mini")} token=${config.github?.token ? chalk.green("SET") : chalk.red("NOT SET")}`,
|
|
265
|
+
);
|
|
266
|
+
console.log(
|
|
267
|
+
` Gemini: model=${chalk.cyan(config.gemini?.model || "gemini-2.0-flash")} key=${config.gemini?.apiKey ? chalk.green("SET") : chalk.red("NOT SET")}`,
|
|
268
|
+
);
|
|
269
|
+
console.log(
|
|
270
|
+
` OpenAI: model=${chalk.cyan(config.openai?.model || "gpt-4o-mini")} key=${config.openai?.apiKey ? chalk.green("SET") : chalk.red("NOT SET")}`,
|
|
271
|
+
);
|
|
272
|
+
console.log();
|
|
273
|
+
console.log(chalk.bold("Agent Settings:"));
|
|
274
|
+
console.log(
|
|
275
|
+
` Max iterations: ${chalk.cyan(config.agent?.maxIterations || 3)}`,
|
|
276
|
+
);
|
|
277
|
+
console.log(
|
|
278
|
+
` Confirm destructive: ${chalk.cyan(config.agent?.confirmDestructive ?? true)}`,
|
|
279
|
+
);
|
|
280
|
+
console.log();
|
|
281
|
+
console.log(chalk.dim("Set API keys:"));
|
|
282
|
+
console.log(
|
|
283
|
+
chalk.dim(" uso agent-config --gemini-key <key>"),
|
|
284
|
+
);
|
|
285
|
+
console.log(
|
|
286
|
+
chalk.dim(" uso agent-config --openai-key <key>"),
|
|
287
|
+
);
|
|
288
|
+
console.log(
|
|
289
|
+
chalk.dim(" uso agent-config --github-token <token>"),
|
|
290
|
+
);
|
|
291
|
+
console.log();
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
module.exports = { agent, agentConfig };
|
package/src/commands/init.js
CHANGED
|
@@ -15,6 +15,22 @@ const { installWsl, installWslFeature } = require("../platforms/wsl");
|
|
|
15
15
|
const init = async (component, options) => {
|
|
16
16
|
const platform = os.platform();
|
|
17
17
|
|
|
18
|
+
if (options?.global) {
|
|
19
|
+
log.warn(
|
|
20
|
+
"⚠️ '-g/--global' is an npm flag and is ignored by 'uso install'.",
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (
|
|
25
|
+
typeof component === "string" &&
|
|
26
|
+
(component.startsWith("@") || component.includes("/"))
|
|
27
|
+
) {
|
|
28
|
+
log.error(`❌ '${component}' is not a valid uso component.`);
|
|
29
|
+
log.info("👉 Use one of: rust, solana, anchor");
|
|
30
|
+
log.info("👉 To install this CLI globally, run: npm install -g @xaidenlabs/uso");
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
18
34
|
// --- On Windows, ALWAYS use the WSL path ---
|
|
19
35
|
if (platform === "win32") {
|
|
20
36
|
const hasWslBinary = !!shell.which("wsl");
|
|
@@ -45,6 +45,64 @@ const commandExists = (command, stealth) => {
|
|
|
45
45
|
const wslPathExists = (wslPath, stealth) => {
|
|
46
46
|
const result = runInStealth(`[ -e "${wslPath}" ]`, stealth, true);
|
|
47
47
|
return result.code === 0;
|
|
48
|
+
<<<<<<< HEAD
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const getInstalledAvmVersions = (stealth) => {
|
|
52
|
+
const listResult = stealth.enabled
|
|
53
|
+
? runInStealth("avm list", stealth, true)
|
|
54
|
+
: shell.exec("avm list", { silent: true });
|
|
55
|
+
|
|
56
|
+
if (listResult.code !== 0) return [];
|
|
57
|
+
|
|
58
|
+
const versions = [];
|
|
59
|
+
for (const rawLine of listResult.stdout.split(/\r?\n/)) {
|
|
60
|
+
const line = rawLine.trim();
|
|
61
|
+
if (!line) continue;
|
|
62
|
+
|
|
63
|
+
// avm list output can contain markers like "* 0.30.1" or "0.30.1 (current)"
|
|
64
|
+
const match = line.match(/(\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?)/);
|
|
65
|
+
if (match) versions.push(match[1]);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return [...new Set(versions)];
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const isCargoPackageInstalled = (packageName, stealth) => {
|
|
72
|
+
const checkCmd = `cargo install --list | grep -q '^${packageName} v'`;
|
|
73
|
+
const result = stealth.enabled
|
|
74
|
+
? runInStealth(checkCmd, stealth, true)
|
|
75
|
+
: shell.exec(checkCmd, { silent: true });
|
|
76
|
+
return result.code === 0;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const uninstallAnchorComponents = (stealth) => {
|
|
80
|
+
if (commandExists("avm", stealth)) {
|
|
81
|
+
const versions = getInstalledAvmVersions(stealth);
|
|
82
|
+
if (versions.length > 0) {
|
|
83
|
+
for (const version of versions) {
|
|
84
|
+
runOrElevate(`avm uninstall ${version}`, `Uninstall Anchor (AVM ${version})`, stealth);
|
|
85
|
+
}
|
|
86
|
+
} else {
|
|
87
|
+
log.info("No AVM-managed Anchor versions found to remove.");
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (isCargoPackageInstalled("anchor-cli", stealth)) {
|
|
92
|
+
runOrElevate(
|
|
93
|
+
"cargo uninstall anchor-cli",
|
|
94
|
+
"Uninstall anchor-cli",
|
|
95
|
+
stealth,
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (isCargoPackageInstalled("avm", stealth)) {
|
|
100
|
+
runOrElevate("cargo uninstall avm", "Uninstall avm", stealth);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
log.success("Anchor removal steps completed.");
|
|
104
|
+
=======
|
|
105
|
+
>>>>>>> d47ca156cb2a252419c54c520c7fcd0f0c18c525
|
|
48
106
|
};
|
|
49
107
|
|
|
50
108
|
/**
|
|
@@ -136,6 +194,9 @@ const uninstall = async (component) => {
|
|
|
136
194
|
const anchorInstalled = commandExists("anchor", stealth);
|
|
137
195
|
if (anchorInstalled) {
|
|
138
196
|
log.info("Removing Anchor...");
|
|
197
|
+
<<<<<<< HEAD
|
|
198
|
+
uninstallAnchorComponents(stealth);
|
|
199
|
+
=======
|
|
139
200
|
// Try avm uninstall first if available
|
|
140
201
|
if (commandExists("avm", stealth)) {
|
|
141
202
|
runOrElevate(
|
|
@@ -151,6 +212,7 @@ const uninstall = async (component) => {
|
|
|
151
212
|
);
|
|
152
213
|
runOrElevate("cargo uninstall avm", "Uninstall avm", stealth);
|
|
153
214
|
log.success("Anchor removal steps completed.");
|
|
215
|
+
>>>>>>> d47ca156cb2a252419c54c520c7fcd0f0c18c525
|
|
154
216
|
} else {
|
|
155
217
|
log.success("✅ Anchor is not installed.");
|
|
156
218
|
}
|
|
@@ -253,6 +315,9 @@ const uninstall = async (component) => {
|
|
|
253
315
|
);
|
|
254
316
|
if (removeAnchor.toLowerCase() === "y") {
|
|
255
317
|
log.info("Removing Anchor...");
|
|
318
|
+
<<<<<<< HEAD
|
|
319
|
+
uninstallAnchorComponents(stealth);
|
|
320
|
+
=======
|
|
256
321
|
// Try avm uninstall first if available
|
|
257
322
|
if (commandExists("avm", stealth)) {
|
|
258
323
|
runOrElevate("avm uninstall latest", "Uninstall Anchor (AVM)", stealth);
|
|
@@ -264,6 +329,7 @@ const uninstall = async (component) => {
|
|
|
264
329
|
);
|
|
265
330
|
runOrElevate("cargo uninstall avm", "Uninstall avm", stealth);
|
|
266
331
|
log.success("Anchor removal steps completed.");
|
|
332
|
+
>>>>>>> d47ca156cb2a252419c54c520c7fcd0f0c18c525
|
|
267
333
|
}
|
|
268
334
|
}
|
|
269
335
|
|
|
@@ -331,6 +397,7 @@ const uninstall = async (component) => {
|
|
|
331
397
|
}
|
|
332
398
|
}
|
|
333
399
|
|
|
400
|
+
<<<<<<< HEAD
|
|
334
401
|
// 3.5 Remove WSL Distro (if stealth mode is active)
|
|
335
402
|
if (stealth.enabled && os.platform() === "win32") {
|
|
336
403
|
const removeWslDistro = await askQuestion(
|
|
@@ -360,6 +427,8 @@ const uninstall = async (component) => {
|
|
|
360
427
|
}
|
|
361
428
|
}
|
|
362
429
|
|
|
430
|
+
=======
|
|
431
|
+
>>>>>>> d47ca156cb2a252419c54c520c7fcd0f0c18c525
|
|
363
432
|
// 4. WALLET REMOVAL (DANGER)
|
|
364
433
|
const walletPath = path.join(os.homedir(), ".config", "solana", "id.json");
|
|
365
434
|
const wslWalletPath = "$HOME/.config/solana/id.json";
|
package/src/platforms/wsl.js
CHANGED
|
@@ -6,6 +6,7 @@ const fs = require("fs");
|
|
|
6
6
|
const os = require("os");
|
|
7
7
|
const { spawnSync } = require("child_process");
|
|
8
8
|
const chalk = require("chalk");
|
|
9
|
+
<<<<<<< HEAD
|
|
9
10
|
const WSL_DISTRO = "Ubuntu";
|
|
10
11
|
|
|
11
12
|
const progressHelpers = `
|
|
@@ -40,6 +41,8 @@ run_with_progress() {
|
|
|
40
41
|
return "$status"
|
|
41
42
|
}
|
|
42
43
|
`.replace(/\r\n/g, "\n");
|
|
44
|
+
=======
|
|
45
|
+
>>>>>>> d47ca156cb2a252419c54c520c7fcd0f0c18c525
|
|
43
46
|
|
|
44
47
|
/**
|
|
45
48
|
* Installs the WSL Windows Feature via an elevated PowerShell UAC prompt.
|
|
@@ -105,9 +108,13 @@ const installWsl = async () => {
|
|
|
105
108
|
// 2. Install Ubuntu silently (Branded as Uso Engine)
|
|
106
109
|
// We use 'wsl -d Ubuntu -e true' to check if it's installed and runnable.
|
|
107
110
|
// 'wsl -l -v' output is notoriously unreliable due to charset encoding (UTF-16) on Windows.
|
|
111
|
+
<<<<<<< HEAD
|
|
108
112
|
const checkDistro = shell.exec(`wsl -d ${WSL_DISTRO} -e true`, {
|
|
109
113
|
silent: true,
|
|
110
114
|
});
|
|
115
|
+
=======
|
|
116
|
+
const checkDistro = shell.exec("wsl -d Ubuntu -e true", { silent: true });
|
|
117
|
+
>>>>>>> d47ca156cb2a252419c54c520c7fcd0f0c18c525
|
|
111
118
|
|
|
112
119
|
// If exit code is 0, it's installed and working.
|
|
113
120
|
if (checkDistro.code !== 0) {
|
|
@@ -125,10 +132,14 @@ const installWsl = async () => {
|
|
|
125
132
|
};
|
|
126
133
|
|
|
127
134
|
// Attempt 1: Standard Install
|
|
135
|
+
<<<<<<< HEAD
|
|
128
136
|
let success = tryInstall(
|
|
129
137
|
["--install", "-d", WSL_DISTRO],
|
|
130
138
|
"Standard Install",
|
|
131
139
|
);
|
|
140
|
+
=======
|
|
141
|
+
let success = tryInstall(["--install", "-d", "Ubuntu"], "Standard Install");
|
|
142
|
+
>>>>>>> d47ca156cb2a252419c54c520c7fcd0f0c18c525
|
|
132
143
|
|
|
133
144
|
// Attempt 2: Update WSL Kernel (Fixes network/protocol issues)
|
|
134
145
|
if (!success) {
|
|
@@ -137,7 +148,11 @@ const installWsl = async () => {
|
|
|
137
148
|
);
|
|
138
149
|
spawnSync("wsl", ["--update"], { stdio: "inherit", shell: false });
|
|
139
150
|
success = tryInstall(
|
|
151
|
+
<<<<<<< HEAD
|
|
140
152
|
["--install", "-d", WSL_DISTRO],
|
|
153
|
+
=======
|
|
154
|
+
["--install", "-d", "Ubuntu"],
|
|
155
|
+
>>>>>>> d47ca156cb2a252419c54c520c7fcd0f0c18c525
|
|
141
156
|
"Install after Update",
|
|
142
157
|
);
|
|
143
158
|
}
|
|
@@ -146,7 +161,11 @@ const installWsl = async () => {
|
|
|
146
161
|
if (!success) {
|
|
147
162
|
log.warn("⚠️ Still failing. Trying --web-download (Bypasses Store)...");
|
|
148
163
|
success = tryInstall(
|
|
164
|
+
<<<<<<< HEAD
|
|
149
165
|
["--install", "-d", WSL_DISTRO, "--web-download"],
|
|
166
|
+
=======
|
|
167
|
+
["--install", "-d", "Ubuntu", "--web-download"],
|
|
168
|
+
>>>>>>> d47ca156cb2a252419c54c520c7fcd0f0c18c525
|
|
150
169
|
"Web Download Install",
|
|
151
170
|
);
|
|
152
171
|
}
|
|
@@ -159,13 +178,18 @@ const installWsl = async () => {
|
|
|
159
178
|
"\n👉 ACTION REQUIRED: Run this command manually in PowerShell as Administrator:",
|
|
160
179
|
);
|
|
161
180
|
console.log(
|
|
181
|
+
<<<<<<< HEAD
|
|
162
182
|
chalk.bold.yellow(` wsl --install -d ${WSL_DISTRO} --web-download`),
|
|
183
|
+
=======
|
|
184
|
+
chalk.bold.yellow(" wsl --install -d Ubuntu --web-download"),
|
|
185
|
+
>>>>>>> d47ca156cb2a252419c54c520c7fcd0f0c18c525
|
|
163
186
|
);
|
|
164
187
|
log.warn(
|
|
165
188
|
"\nOnce that completes successfully, run 'uso setup --wsl' again.",
|
|
166
189
|
);
|
|
167
190
|
return false;
|
|
168
191
|
}
|
|
192
|
+
<<<<<<< HEAD
|
|
169
193
|
|
|
170
194
|
const verifyInstall = shell.exec(`wsl -d ${WSL_DISTRO} -e true`, {
|
|
171
195
|
silent: true,
|
|
@@ -191,6 +215,19 @@ const installWsl = async () => {
|
|
|
191
215
|
// 3. Configure Internal Environment (Rust + Solana + Anchor)
|
|
192
216
|
// We create a shell script and run it inside WSL.
|
|
193
217
|
|
|
218
|
+
=======
|
|
219
|
+
log.success("✅ Uso Engine configured.");
|
|
220
|
+
} else {
|
|
221
|
+
log.success("✅ Uso Engine is ready.");
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// 2.5 Hide from Windows Terminal (Stealth Mode)
|
|
225
|
+
hideFromWindowsTerminal();
|
|
226
|
+
|
|
227
|
+
// 3. Configure Internal Environment (Rust + Solana + Anchor)
|
|
228
|
+
// We create a shell script and run it inside WSL.
|
|
229
|
+
|
|
230
|
+
>>>>>>> d47ca156cb2a252419c54c520c7fcd0f0c18c525
|
|
194
231
|
log.info("⚙️ Initializing Uso Engine environment...");
|
|
195
232
|
|
|
196
233
|
// --- PHASE 1: System Dependencies (as root, no sudo needed) ---
|
|
@@ -215,7 +252,11 @@ fi
|
|
|
215
252
|
|
|
216
253
|
const spin1 = spinner("Phase 1/2: Installing system dependencies...").start();
|
|
217
254
|
const rootRes = shell.exec(
|
|
255
|
+
<<<<<<< HEAD
|
|
218
256
|
`wsl -d ${WSL_DISTRO} -u root -e bash "${wslRootScriptPath}"`,
|
|
257
|
+
=======
|
|
258
|
+
`wsl -d Ubuntu -u root -e bash "${wslRootScriptPath}"`,
|
|
259
|
+
>>>>>>> d47ca156cb2a252419c54c520c7fcd0f0c18c525
|
|
219
260
|
);
|
|
220
261
|
fs.unlinkSync(rootScriptPath);
|
|
221
262
|
|
|
@@ -415,9 +456,13 @@ fi
|
|
|
415
456
|
const spin2 = spinner(
|
|
416
457
|
"Phase 2/2: Installing Rust, Solana, Anchor (this takes a while)...",
|
|
417
458
|
).start();
|
|
459
|
+
<<<<<<< HEAD
|
|
418
460
|
const userRes = shell.exec(
|
|
419
461
|
`wsl -d ${WSL_DISTRO} -e bash "${wslUserScriptPath}"`,
|
|
420
462
|
);
|
|
463
|
+
=======
|
|
464
|
+
const userRes = shell.exec(`wsl -d Ubuntu -e bash "${wslUserScriptPath}"`);
|
|
465
|
+
>>>>>>> d47ca156cb2a252419c54c520c7fcd0f0c18c525
|
|
421
466
|
fs.unlinkSync(userScriptPath);
|
|
422
467
|
|
|
423
468
|
if (userRes.code === 0) {
|
|
@@ -429,7 +474,11 @@ fi
|
|
|
429
474
|
|
|
430
475
|
// Always set stealth mode config — even partial setup enables routing
|
|
431
476
|
const configPath = path.join(os.homedir(), ".uso-config.json");
|
|
477
|
+
<<<<<<< HEAD
|
|
432
478
|
const config = { mode: "wsl", distro: WSL_DISTRO };
|
|
479
|
+
=======
|
|
480
|
+
const config = { mode: "wsl", distro: "Ubuntu" };
|
|
481
|
+
>>>>>>> d47ca156cb2a252419c54c520c7fcd0f0c18c525
|
|
433
482
|
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
434
483
|
|
|
435
484
|
log.success("✅ Stealth Mode Enabled. 'uso' commands will now run via WSL.");
|