@xaidenlabs/uso 1.1.40 → 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.40",
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"
@@ -266,6 +266,16 @@ const validator = async (args = []) => {
266
266
  Write-Host "⚠️ Could not set exclusions (User might not be Admin?)" -ForegroundColor Yellow;
267
267
  }
268
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
+
269
279
  Write-Host "🚀 Starting Validator: ${targetCmd}" -ForegroundColor Green;
270
280
 
271
281
  try {
@@ -328,3 +338,85 @@ module.exports = {
328
338
  airdrop,
329
339
  validator
330
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
+ };