@xaidenlabs/uso 1.1.39 โ†’ 1.1.41

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/bin/index.js CHANGED
@@ -4,7 +4,7 @@ const { init } = require('../src/commands/init');
4
4
  const { doctor } = require('../src/commands/doctor');
5
5
  const { verify } = require('../src/commands/verify');
6
6
  const { create } = require('../src/commands/create');
7
- const { build, test, deploy, clean, unblock, airdrop, validator } = require('../src/commands/workflow');
7
+ const { build, test, deploy, clean, unblock, airdrop, validator, dev } = require('../src/commands/workflow');
8
8
  const { uninstall } = require('../src/commands/uninstall');
9
9
 
10
10
  program
@@ -62,6 +62,11 @@ program
62
62
  .description('Scaffold a new Solana project with Next.js frontend')
63
63
  .action(create);
64
64
 
65
+ program
66
+ .command('dev')
67
+ .description('Start developer mode (Validator + Watcher)')
68
+ .action(dev);
69
+
65
70
  program
66
71
  .command('clean')
67
72
  .description('Clean the project (wraps "anchor clean")')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xaidenlabs/uso",
3
- "version": "1.1.39",
3
+ "version": "1.1.41",
4
4
  "description": "Universal Solana Orchestrator - A one-command setup tool for Solana and Anchor development environments on Windows, macOS, and Linux.",
5
5
  "bin": {
6
6
  "uso": "bin/index.js"
@@ -244,9 +244,55 @@ const validator = async (args = []) => {
244
244
  log.info(`๐Ÿš€ Spawning visible Administrator terminal for '${targetCmd}'...`);
245
245
  log.warn("๐Ÿ‘‰ A new window will appear. Keep it open to run the validator!");
246
246
 
247
- // Updated PowerShell command to keep window open and show errors if it crashes immediately
248
- // Using Read-Host is safer than ReadKey for nested quoting
249
- const psCmd = `powershell -Command "Start-Process powershell -ArgumentList '-NoExit', '-Command', '& ${targetCmd}; if ($LASTEXITCODE -ne 0) { Write-Host \\"โŒ Validator Crashed! Press Enter to exit...\\" -ForegroundColor Red; Read-Host }' -Verb RunAs"`;
247
+ // Robust Launch using EncodedCommand to avoid quoting hell and set CWD correctly
248
+ // 1. Set CWD (Critical: RunAs defaults to System32)
249
+ // 2. Add Exclusions (Critical: Fixes Access Denied on ledger files)
250
+ // 3. Run Validator
251
+ // 4. Pause on Error
252
+
253
+ const cwd = process.cwd();
254
+ const psScript = `
255
+ $ErrorActionPreference = 'Stop';
256
+ try { Set-Location -Path '${cwd}'; } catch { Write-Host "โš ๏ธ Could not set CWD. Keeping default." -ForegroundColor Yellow; }
257
+
258
+ Write-Host "๐Ÿ“‚ Working Directory: $(Get-Location)" -ForegroundColor Gray;
259
+
260
+ Write-Host "๐Ÿ›ก๏ธ Attempting to whitelist folder in Windows Defender..." -ForegroundColor Cyan;
261
+ try {
262
+ Add-MpPreference -ExclusionPath '${cwd}' -ErrorAction SilentlyContinue;
263
+ Add-MpPreference -ExclusionProcess "solana-test-validator" -ErrorAction SilentlyContinue;
264
+ Write-Host "โœ… Secured." -ForegroundColor Green;
265
+ } catch {
266
+ Write-Host "โš ๏ธ Could not set exclusions (User might not be Admin?)" -ForegroundColor Yellow;
267
+ }
268
+
269
+ Write-Host "๐Ÿ”“ Enabling Developer Mode for Symlinks..." -ForegroundColor Cyan;
270
+ $regPath = "HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\AppModelUnlock";
271
+ try {
272
+ New-Item -Path $regPath -Force -ErrorAction SilentlyContinue | Out-Null;
273
+ Set-ItemProperty -Path $regPath -Name "AllowDevelopmentWithoutDevLicense" -Value 1 -Type DWord -ErrorAction SilentlyContinue;
274
+ Write-Host "โœ… Developer Mode Enabled." -ForegroundColor Green;
275
+ } catch {
276
+ Write-Host "โš ๏ธ Could not enable Developer Mode (Registry Write Failed)." -ForegroundColor Yellow;
277
+ }
278
+
279
+ Write-Host "๐Ÿš€ Starting Validator: ${targetCmd}" -ForegroundColor Green;
280
+
281
+ try {
282
+ & ${targetCmd};
283
+ } catch {
284
+ Write-Host "โŒ Validator Execution Failed: $_" -ForegroundColor Red;
285
+ }
286
+
287
+ if ($LASTEXITCODE -ne 0) {
288
+ Write-Host "โŒ Validator Crashed (Exit Code: $LASTEXITCODE). Press Enter to exit..." -ForegroundColor Red;
289
+ Read-Host;
290
+ }
291
+ `.replace(/\n/g, ' ').replace(/\s+/g, ' ').trim();
292
+
293
+ const encoded = Buffer.from(psScript, 'utf16le').toString('base64');
294
+ const psCmd = `powershell -Command "Start-Process powershell -ArgumentList '-NoExit', '-EncodedCommand', '${encoded}' -Verb RunAs"`;
295
+
250
296
  shell.exec(psCmd);
251
297
 
252
298
  log.success("โœ… Validator launch sequence initiated.");
@@ -292,3 +338,85 @@ module.exports = {
292
338
  airdrop,
293
339
  validator
294
340
  };
341
+
342
+ const dev = async () => {
343
+ log.header("๐Ÿš€ Starting Development Environment...");
344
+
345
+ // 1. Check if validator is running
346
+ const isValidatorRunning = () => {
347
+ const res = shell.exec('netstat -an | findstr 8899', { silent: true });
348
+ return res.code === 0 && res.stdout.length > 0;
349
+ };
350
+
351
+ if (isValidatorRunning()) {
352
+ log.success("โœ… Validator is already running.");
353
+ } else {
354
+ log.info("โณ Spawning Validator...");
355
+ // Spawn validator (this will open the Admin window)
356
+ // We use [] args to start cleanly but persistently.
357
+ // If it fails, the user will see it in the new window.
358
+ await validator([]);
359
+
360
+ // Wait for validator to be ready
361
+ const spin = spinner('Waiting for Validator to respond...').start();
362
+ let retries = 30; // 15 seconds
363
+ while (retries > 0) {
364
+ if (isValidatorRunning()) {
365
+ spin.succeed("โœ… Validator is online.");
366
+ break;
367
+ }
368
+ await new Promise(r => setTimeout(r, 1000));
369
+ retries--;
370
+ }
371
+
372
+ if (retries === 0) {
373
+ spin.warn("โš ๏ธ Validator might be taking a while to start. Continuing to tests...");
374
+ }
375
+ }
376
+
377
+ log.info("๐Ÿงช Running initial tests...");
378
+ test(['--', '--skip-local-validator']);
379
+
380
+ log.header("๐Ÿ‘€ Watching for changes...");
381
+ log.info("๐Ÿ‘‰ Change any .rs or .ts file to re-run tests.");
382
+ log.info("๐Ÿ‘‰ Press Ctrl+C to exit.");
383
+
384
+ let debounce = false;
385
+ const runTests = () => {
386
+ if (debounce) return;
387
+ debounce = true;
388
+ setTimeout(() => debounce = false, 2000); // 2s debounce
389
+
390
+ console.clear();
391
+ log.header("๐Ÿ”„ Detected change. Re-running tests...");
392
+ test(['--', '--skip-local-validator']);
393
+ log.header("๐Ÿ‘€ Watching for changes...");
394
+ };
395
+
396
+ // Simple Watcher using fs.watch
397
+ const watchDirs = ['programs', 'tests'];
398
+ watchDirs.forEach(dir => {
399
+ const p = path.join(process.cwd(), dir);
400
+ if (fs.existsSync(p)) {
401
+ fs.watch(p, { recursive: true }, (eventType, filename) => {
402
+ if (filename && (filename.endsWith('.rs') || filename.endsWith('.ts'))) {
403
+ runTests();
404
+ }
405
+ });
406
+ }
407
+ });
408
+
409
+ // Keep process alive
410
+ setInterval(() => { }, 1000);
411
+ };
412
+
413
+ module.exports = {
414
+ build,
415
+ test,
416
+ deploy,
417
+ clean,
418
+ unblock,
419
+ airdrop,
420
+ validator,
421
+ dev
422
+ };