@xaidenlabs/uso 1.1.1 → 1.1.2
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
CHANGED
package/src/commands/workflow.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
const shell = require('shelljs');
|
|
2
2
|
const os = require('os');
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
3
5
|
const { log, spinner } = require('../utils/logger');
|
|
4
6
|
|
|
5
7
|
const runProxyCommand = async (command, args = []) => {
|
|
@@ -26,23 +28,116 @@ const runProxyCommand = async (command, args = []) => {
|
|
|
26
28
|
|
|
27
29
|
if (isPrivilegeError && os.platform() === 'win32') {
|
|
28
30
|
log.warn("⚠️ Windows requires Administrator privileges for this operation.");
|
|
29
|
-
log.info("🔑 Requesting elevated access
|
|
31
|
+
log.info("🔑 Requesting elevated access...\n");
|
|
30
32
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const elevatedRun = shell.exec(elevateCmd);
|
|
34
|
-
|
|
35
|
-
if (elevatedRun.code === 0) {
|
|
36
|
-
log.success(`✅ '${command}' completed successfully (elevated).`);
|
|
37
|
-
} else {
|
|
38
|
-
log.error(`❌ '${command}' failed even with elevated privileges.`);
|
|
39
|
-
log.warn("👉 Try running your terminal as Administrator manually.");
|
|
40
|
-
}
|
|
33
|
+
await runElevatedWithProgress(command, args);
|
|
41
34
|
} else {
|
|
42
35
|
log.error(`❌ '${command}' failed.`);
|
|
43
36
|
}
|
|
44
37
|
};
|
|
45
38
|
|
|
39
|
+
/**
|
|
40
|
+
* Runs the anchor command in a HIDDEN elevated PowerShell window,
|
|
41
|
+
* redirecting all output to a temp log file. The user's terminal
|
|
42
|
+
* shows a spinner that tails the log file in real-time.
|
|
43
|
+
*/
|
|
44
|
+
const runElevatedWithProgress = (command, args = []) => {
|
|
45
|
+
return new Promise((resolve) => {
|
|
46
|
+
const tmpDir = os.tmpdir();
|
|
47
|
+
const logFile = path.join(tmpDir, `uso-elevated-${Date.now()}.log`);
|
|
48
|
+
const doneFile = path.join(tmpDir, `uso-elevated-${Date.now()}.done`);
|
|
49
|
+
const cwd = process.cwd();
|
|
50
|
+
|
|
51
|
+
// Write an empty log file so we can start reading immediately
|
|
52
|
+
fs.writeFileSync(logFile, '', 'utf8');
|
|
53
|
+
|
|
54
|
+
// Build the elevated command:
|
|
55
|
+
// 1. cd into the user's project directory
|
|
56
|
+
// 2. Run anchor <command>
|
|
57
|
+
// 3. Write exit code to a .done file so we know it finished
|
|
58
|
+
// 4. All stdout/stderr piped to the log file
|
|
59
|
+
const anchorCmd = `anchor ${command} ${args.join(' ')}`;
|
|
60
|
+
const innerScript = `
|
|
61
|
+
Set-Location '${cwd.replace(/'/g, "''")}';
|
|
62
|
+
$output = & cmd /c '${anchorCmd} 2>&1';
|
|
63
|
+
$output | Out-File -FilePath '${logFile.replace(/\\/g, '\\\\')}' -Encoding utf8 -Append;
|
|
64
|
+
$LASTEXITCODE | Out-File -FilePath '${doneFile.replace(/\\/g, '\\\\')}' -Encoding utf8;
|
|
65
|
+
`.replace(/\n/g, ' ').trim();
|
|
66
|
+
|
|
67
|
+
// Launch hidden elevated process
|
|
68
|
+
const elevateCmd = `powershell -Command "Start-Process powershell -ArgumentList '-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', '${innerScript.replace(/'/g, "''")}' -Verb RunAs -WindowStyle Hidden"`;
|
|
69
|
+
|
|
70
|
+
// This triggers the UAC prompt (that one still shows — it's Windows security, can't bypass it)
|
|
71
|
+
const elevateResult = shell.exec(elevateCmd, { silent: true });
|
|
72
|
+
|
|
73
|
+
if (elevateResult.code !== 0) {
|
|
74
|
+
log.error("❌ Failed to launch elevated process. Was the UAC prompt declined?");
|
|
75
|
+
resolve();
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Now poll the log file and show progress
|
|
80
|
+
const spin = spinner('Building with elevated privileges...').start();
|
|
81
|
+
let lastSize = 0;
|
|
82
|
+
let lastLine = '';
|
|
83
|
+
|
|
84
|
+
const pollInterval = setInterval(() => {
|
|
85
|
+
try {
|
|
86
|
+
// Check if process finished
|
|
87
|
+
if (fs.existsSync(doneFile)) {
|
|
88
|
+
clearInterval(pollInterval);
|
|
89
|
+
|
|
90
|
+
const exitCode = fs.readFileSync(doneFile, 'utf8').trim();
|
|
91
|
+
const fullLog = fs.readFileSync(logFile, 'utf8');
|
|
92
|
+
|
|
93
|
+
// Cleanup temp files
|
|
94
|
+
try { fs.unlinkSync(logFile); } catch (e) { /* ignore */ }
|
|
95
|
+
try { fs.unlinkSync(doneFile); } catch (e) { /* ignore */ }
|
|
96
|
+
|
|
97
|
+
if (exitCode === '0') {
|
|
98
|
+
spin.succeed(`'${command}' completed successfully (elevated).`);
|
|
99
|
+
} else {
|
|
100
|
+
spin.fail(`'${command}' failed (elevated, exit code: ${exitCode}).`);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Print the captured output
|
|
104
|
+
if (fullLog.trim()) {
|
|
105
|
+
console.log('\n' + fullLog.trim());
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
resolve();
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Read new content from log file for progress
|
|
113
|
+
const stats = fs.statSync(logFile);
|
|
114
|
+
if (stats.size > lastSize) {
|
|
115
|
+
const content = fs.readFileSync(logFile, 'utf8');
|
|
116
|
+
const lines = content.trim().split('\n').filter(l => l.trim());
|
|
117
|
+
if (lines.length > 0) {
|
|
118
|
+
lastLine = lines[lines.length - 1].trim();
|
|
119
|
+
// Show the last meaningful line as spinner text
|
|
120
|
+
const displayLine = lastLine.length > 70 ? lastLine.substring(0, 67) + '...' : lastLine;
|
|
121
|
+
spin.text = displayLine;
|
|
122
|
+
}
|
|
123
|
+
lastSize = stats.size;
|
|
124
|
+
}
|
|
125
|
+
} catch (e) {
|
|
126
|
+
// File might not exist yet or be locked, just keep polling
|
|
127
|
+
}
|
|
128
|
+
}, 500);
|
|
129
|
+
|
|
130
|
+
// Safety timeout: 10 minutes max
|
|
131
|
+
setTimeout(() => {
|
|
132
|
+
if (!fs.existsSync(doneFile)) {
|
|
133
|
+
clearInterval(pollInterval);
|
|
134
|
+
spin.fail("Timed out waiting for elevated process (10 min).");
|
|
135
|
+
resolve();
|
|
136
|
+
}
|
|
137
|
+
}, 10 * 60 * 1000);
|
|
138
|
+
});
|
|
139
|
+
};
|
|
140
|
+
|
|
46
141
|
const build = () => runProxyCommand('build');
|
|
47
142
|
const test = () => runProxyCommand('test');
|
|
48
143
|
const deploy = () => runProxyCommand('deploy');
|