@emend-ai/utim 1.45.1 → 1.45.5
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/utim.js +59 -11
- package/package.json +1 -1
package/bin/utim.js
CHANGED
|
@@ -78,17 +78,46 @@ function isUtimInstalled(python) {
|
|
|
78
78
|
// ── Run pip install with given extra flags — always show output ───────────────
|
|
79
79
|
function runPip(python, extraFlags) {
|
|
80
80
|
try {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
{
|
|
85
|
-
stdio: '
|
|
86
|
-
shell:
|
|
81
|
+
if (isWin) {
|
|
82
|
+
// On Windows: spawn in a new Command Prompt window and block until it is closed.
|
|
83
|
+
const cmdStr = `title UTIM Setup & echo ======================================== & echo Installing UTIM Python engine and dependencies... & echo ======================================== & "${python}" -m pip install --upgrade ${extraFlags.join(' ')} utim-cli & echo ======================================== & echo Installation complete. You can close this window. & pause`;
|
|
84
|
+
spawnSync('cmd.exe', ['/c', 'start', '/wait', 'cmd.exe', '/c', cmdStr], {
|
|
85
|
+
stdio: 'ignore',
|
|
86
|
+
shell: true,
|
|
87
87
|
windowsHide: false,
|
|
88
|
-
|
|
88
|
+
});
|
|
89
|
+
// After the popup window closes, verify if the pip package was actually installed
|
|
90
|
+
return isUtimInstalled(python);
|
|
91
|
+
} else if (isMac) {
|
|
92
|
+
// On macOS: use osascript to run it in a new Terminal window.
|
|
93
|
+
const lockFile = require('path').join(os.tmpdir(), `utim_install_${Date.now()}.lock`);
|
|
94
|
+
fs.writeFileSync(lockFile, 'running');
|
|
95
|
+
const installCmd = `echo "Installing UTIM Python engine..."; "${python}" -m pip install --upgrade ${extraFlags.join(' ')} utim-cli; rm -f "${lockFile}"; exit`;
|
|
96
|
+
const osaScript = `tell application "Terminal" to do script "${installCmd.replace(/"/g, '\\"')}"`;
|
|
97
|
+
|
|
98
|
+
spawnSync('osascript', ['-e', osaScript], { stdio: 'ignore' });
|
|
99
|
+
|
|
100
|
+
// Poll for lockfile deletion (timeout after 5 minutes)
|
|
101
|
+
let elapsed = 0;
|
|
102
|
+
while (fs.existsSync(lockFile) && elapsed < 300) {
|
|
103
|
+
spawnSync('sleep', ['1']);
|
|
104
|
+
elapsed++;
|
|
89
105
|
}
|
|
90
|
-
|
|
91
|
-
|
|
106
|
+
try { fs.unlinkSync(lockFile); } catch (_) {}
|
|
107
|
+
return isUtimInstalled(python);
|
|
108
|
+
} else {
|
|
109
|
+
// Linux / Termux fallback: run in current terminal
|
|
110
|
+
const r = spawnSync(
|
|
111
|
+
python,
|
|
112
|
+
['-m', 'pip', 'install', '--upgrade', ...extraFlags, 'utim-cli'],
|
|
113
|
+
{
|
|
114
|
+
stdio: 'inherit',
|
|
115
|
+
shell: false,
|
|
116
|
+
timeout: 300000,
|
|
117
|
+
}
|
|
118
|
+
);
|
|
119
|
+
return r.status === 0;
|
|
120
|
+
}
|
|
92
121
|
} catch (_) {
|
|
93
122
|
return false;
|
|
94
123
|
}
|
|
@@ -99,12 +128,31 @@ function installEngine(python) {
|
|
|
99
128
|
// Termux: install prebuilt system packages first to skip pydantic-core compilation
|
|
100
129
|
if (isTermux) {
|
|
101
130
|
process.stderr.write(
|
|
102
|
-
'\n💡 Termux:
|
|
131
|
+
'\n💡 Termux: adding Termux User Repository (tur-repo) to find prebuilt python-pydantic...\n\n'
|
|
103
132
|
);
|
|
104
|
-
|
|
133
|
+
// Register tur-repo first (contains prebuilt python-pydantic)
|
|
134
|
+
spawnSync('pkg', ['install', '-y', 'tur-repo'], { stdio: 'inherit', shell: false });
|
|
135
|
+
|
|
136
|
+
process.stderr.write(
|
|
137
|
+
'\n💡 Termux: installing prebuilt system cryptography and pydantic packages...\n\n'
|
|
138
|
+
);
|
|
139
|
+
const r1 = spawnSync('pkg', ['install', '-y', 'python-cryptography', 'python-pydantic'], {
|
|
105
140
|
stdio: 'inherit',
|
|
106
141
|
shell: false,
|
|
107
142
|
});
|
|
143
|
+
|
|
144
|
+
// Fallback: If prebuilt system packages fail to install, install Rust compiler toolchain
|
|
145
|
+
// so pip can compile pydantic-core and cryptography from source
|
|
146
|
+
if (r1.status !== 0) {
|
|
147
|
+
process.stderr.write(
|
|
148
|
+
'\n💡 Prebuilt package setup failed. Installing build dependencies (rust, clang) to compile from source...\n\n'
|
|
149
|
+
);
|
|
150
|
+
spawnSync('pkg', ['install', '-y', 'clang', 'rust', 'make', 'libfft-dev', 'libffi-dev', 'openssl-dev'], {
|
|
151
|
+
stdio: 'inherit',
|
|
152
|
+
shell: false,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
108
156
|
spawnSync(python, ['-m', 'pip', 'install', '--upgrade', 'pip', 'setuptools', 'wheel'], {
|
|
109
157
|
stdio: 'pipe',
|
|
110
158
|
shell: false,
|