@emend-ai/utim 1.46.28 → 1.46.31

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 CHANGED
@@ -119,6 +119,43 @@ Inside the interactive chat terminal, type these slash commands for direct works
119
119
  ## 📄 Related Documentation
120
120
 
121
121
  - [📖 Full Documentation](https://utim.dev/docs)
122
- - [🔒 Security Policy](SECURITY.md)
122
+ - [🔒 Security Policy](SECURITY.md) — vulnerability reporting, security@utim.dev
123
+ - [🗄️ Data Handling Reference](DATA_HANDLING.md) — what stays local, what goes to backend, what goes to model providers
123
124
  - [📊 SLA & Support](SLA.md)
124
125
  - [🛡️ Privacy Policy](landing/src/docs_md/privacy.md)
126
+
127
+ ## 📦 Installation Methods
128
+
129
+ ### npm (recommended — works without Python pre-installed)
130
+ ```bash
131
+ npm install -g @emend-ai/utim
132
+ ```
133
+
134
+ ### pip (from PyPI)
135
+ ```bash
136
+ pip install utim-cli
137
+ # Full install with optional features (web search, images, parsers)
138
+ pip install "utim-cli[full]"
139
+ ```
140
+
141
+ ### Source install (development)
142
+ ```bash
143
+ git clone https://github.com/emendai/utim.git
144
+ cd utim
145
+ pip install -e ".[full]"
146
+ ```
147
+
148
+ ### Smoke-test your install
149
+ ```bash
150
+ utim --version # Should print the current version
151
+ utim doctor # Runs diagnostics — all checks should pass
152
+ ```
153
+
154
+ See [INSTALLATION_VERIFICATION.md](INSTALLATION_VERIFICATION.md) for detailed verification steps and troubleshooting.
155
+
156
+ ## 🔢 Version
157
+
158
+ UTIM uses a single canonical version defined in [`utim_cli/_version.py`](utim_cli/_version.py).
159
+ Run `python scripts/sync_version.py` to propagate a version bump to all surfaces
160
+ (`package.json`, `pyproject.toml`, `CHANGELOG.md`) before releasing.
161
+
package/bin/utim.js CHANGED
@@ -18,6 +18,17 @@ const isTermux =
18
18
  (process.env.PREFIX && process.env.PREFIX.includes('com.termux')) ||
19
19
  fs.existsSync('/data/data/com.termux');
20
20
 
21
+ const path = require('path');
22
+ let versionPin = '';
23
+ try {
24
+ const pkg = require(path.join(__dirname, '..', 'package.json'));
25
+ if (pkg.version) {
26
+ versionPin = `==${pkg.version}`;
27
+ }
28
+ } catch (_) {}
29
+
30
+ const pipPackage = `utim-cli${versionPin}`;
31
+
21
32
  // ── Spinner (no-op when not a TTY) ───────────────────────────────────────────
22
33
  function createSpinner(text) {
23
34
  const frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
@@ -69,7 +80,18 @@ function isUtimInstalled(python) {
69
80
  shell: isWin,
70
81
  windowsHide: true,
71
82
  });
72
- return r.status === 0 && (r.stdout || '').includes('Name:');
83
+ if (r.status !== 0) return false;
84
+
85
+ // Enforce that installed version matches expectedVersion
86
+ if (versionPin) {
87
+ const expectedVersion = versionPin.replace('==', '').trim();
88
+ const stdoutStr = r.stdout || '';
89
+ const match = stdoutStr.match(/^Version:\s*([^\r\n]+)/m);
90
+ if (match && match[1].trim() !== expectedVersion) {
91
+ return false; // version mismatch, force update/reinstall
92
+ }
93
+ }
94
+ return (r.stdout || '').includes('Name:');
73
95
  } catch (_) {
74
96
  return false;
75
97
  }
@@ -80,7 +102,7 @@ function runPip(python, extraFlags) {
80
102
  try {
81
103
  if (isWin) {
82
104
  // 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`;
105
+ const cmdStr = `title UTIM Setup & echo ======================================== & echo Installing UTIM Python engine and dependencies... & echo ======================================== & "${python}" -m pip install ${extraFlags.join(' ')} ${pipPackage} & echo ======================================== & echo Installation complete. You can close this window. & pause`;
84
106
  spawnSync('cmd.exe', ['/c', 'start', '/wait', 'cmd.exe', '/c', cmdStr], {
85
107
  stdio: 'ignore',
86
108
  shell: true,
@@ -92,7 +114,7 @@ function runPip(python, extraFlags) {
92
114
  // On macOS: use osascript to run it in a new Terminal window.
93
115
  const lockFile = require('path').join(os.tmpdir(), `utim_install_${Date.now()}.lock`);
94
116
  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`;
117
+ const installCmd = `echo "Installing UTIM Python engine..."; "${python}" -m pip install ${extraFlags.join(' ')} ${pipPackage}; rm -f "${lockFile}"; exit`;
96
118
  const osaScript = `tell application "Terminal" to do script "${installCmd.replace(/"/g, '\\"')}"`;
97
119
 
98
120
  spawnSync('osascript', ['-e', osaScript], { stdio: 'ignore' });
@@ -113,10 +135,8 @@ function runPip(python, extraFlags) {
113
135
  // versions of pydantic-core from PyPI and trying to compile from source.
114
136
  // Instead, use --upgrade-strategy only-if-needed to keep the pre-compiled version.
115
137
  pipArgs.push('--upgrade-strategy', 'only-if-needed');
116
- } else {
117
- pipArgs.push('--upgrade');
118
138
  }
119
- pipArgs.push(...extraFlags, 'utim-cli');
139
+ pipArgs.push(...extraFlags, pipPackage);
120
140
 
121
141
  const r = spawnSync(python, pipArgs, {
122
142
  stdio: 'inherit',
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@emend-ai/utim",
3
- "version": "1.46.28",
4
- "description": "UTIM Universal Terminal Intelligence Manager. An agentic AI coding assistant for your terminal.",
3
+ "version": "1.46.31",
4
+ "description": "UTIM \u2013 Universal Terminal Intelligence Manager. An agentic AI coding assistant for your terminal.",
5
5
  "keywords": [
6
6
  "ai",
7
7
  "agent",
@@ -58,13 +58,25 @@ if (!python) {
58
58
  process.exit(0);
59
59
  }
60
60
 
61
+ // Read the version from package.json to pin the python engine version
62
+ const path = require('path');
63
+ let versionPin = '';
64
+ try {
65
+ const pkg = require(path.join(__dirname, '..', 'package.json'));
66
+ if (pkg.version) {
67
+ versionPin = `==${pkg.version}`;
68
+ }
69
+ } catch (_) {}
70
+
71
+ const pipPackage = `utim-cli${versionPin}`;
72
+
61
73
  // Silently pre-install in the background (pipe output, not inherit)
62
74
  // so the npm install output stays clean. Any failure is fine —
63
75
  // the launcher self-heals on first `utim` run.
64
76
  try {
65
77
  const r = spawnSync(
66
78
  python,
67
- ['-m', 'pip', 'install', '--upgrade', '--quiet', 'utim-cli'],
79
+ ['-m', 'pip', 'install', '--quiet', pipPackage],
68
80
  {
69
81
  stdio: 'pipe',
70
82
  shell: isWin,