@emend-ai/utim 1.46.27 → 1.46.30

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
@@ -1,82 +1,161 @@
1
- # UTIM CLI Agent: Enterprise Coder Assistant
2
-
3
- UTIM is an agentic developer CLI assistant designed to automate coding tasks directly inside your local terminal, featuring robust safety controls, self-healing quality gates, and local-first semantic memory.
4
-
5
- ---
6
-
7
- ## 🚀 Quick Start
8
-
9
- ### 1. Installation
10
- Install the package from your local source directory:
11
-
12
- ```bash
13
- # Basic installation
14
- pip install .
15
-
16
- # Recommended: Full installation (includes semantic vector RAG & web search)
17
- pip install ".[full]"
18
- ```
19
-
20
- ### 2. Provider & Model Configuration
21
- Start the chat session:
22
- ```bash
23
- utim
24
- ```
25
- On first run, UTIM checks for `.utim/config.json`. If it does not exist, it runs a provider and model configuration wizard. You can configure:
26
- - **Default Providers**: OpenRouter, OpenAI, custom servers, etc.
27
- - **Model Picker**: Press `Ctrl+M` in the chat terminal at any time to configure, pick, add, or delete LLMs.
28
-
29
- ---
30
-
31
- ## ⚡ Main CLI Commands
32
-
33
- - **`utim`**: Starts the interactive chat terminal (TUI).
34
- - **`utim task "<prompt>"`**: Executes a single task autonomously from the command line and exits. In an interactive terminal (`stdin` is a TTY) file writes and commands prompt for confirmation; when piped/scripted they run in auto-accept mode.
35
- - **`utim --dry-run`**: Starts the session in **Dry-Run Mode** (all code modifications and shell commands are simulated, not written/executed).
36
- - **`utim --sandbox`**: Runs all mutating shell command proposals in the intelligent local sandbox (untrusted commands will block until approved).
37
- - **`utim doctor`** / **`utim init`** / **`utim reset`**: Administrative commands for state diagnosis, initialization, and factory resets.
38
-
39
- ---
40
-
41
- ## 🛠️ In-Chat Slash Commands
42
-
43
- Inside the interactive chat terminal, type these slash commands for direct workspace control:
44
-
45
- - **`/undo`**: Reverts the last assistant action, restoring files to their exact "before" state and rolling back messages.
46
- - **`/redo`**: Re-applies the last undone turn, re-writing files and restoring conversation logs.
47
- - **`/rewind <turn_index>`**: Rolls back the entire session to a specific conversation turn.
48
- - **`/doctor`**: Run diagnostics on environment variables, Python version, dependencies, API model connections, and MCP server status.
49
- - **`/report`**: Generates a support bundle under `.utim_tmp/report_bundle.zip` (automatically redacts secrets, passwords, or personal names/files).
50
- - **`/reset`**: Wipes the current chat history without deleting persistent local vector memory.
51
-
52
- ---
53
-
54
- ## 🧠 Architecture & How it Works
55
-
56
- 1. **Local Memory (`.utim/memory.json` & ChromaDB)**:
57
- - Global user preferences, rules, and facts are synced to a semantic vector database (`.utim_tmp/vector_db`).
58
- - Relevant memories are dynamically fetched via semantic similarity (RAG) and injected into the system prompt context, preventing prompt bloating.
59
- 2. **Undo/Redo Stack & Session State**:
60
- - Every file change (writes, batch string edits, moves, deletions) computes a diff snapshot.
61
- - The entire stack is serialized dynamically to `.utim/session_state.json`. You can close your shell, shut down your computer, and resume later with intact rollback features.
62
- 3. **Workspace Boundary & Safety Controls**:
63
- - Prior to writing files, UTIM performs **Pre-Commit Syntax Checks** (AST compilation for Python, JSON loads, JS/TS checks).
64
- - If tests are available (`pytest`, `npm test`, etc.), UTIM runs them in a background **Regression testing loop**, prompting the model to self-heal code errors if assertions fail.
65
- - **Interactive TUI mode** (`utim`): every file mutation shows an interactive diff dialog; the developer accepts, edits, or rejects individual hunks before they are applied.
66
- - **CLI task mode** (`utim task`): when running in a real terminal, destructive operations (`rm`, package installs, `>` redirects) prompt for `y/n` confirmation. When stdin is piped/non-interactive all edits are auto-accepted.
67
- - **Sandbox mode** (`utim --sandbox`): classifies every terminal command as safe or risky and blocks risky commands until explicitly approved.
68
-
69
- ---
70
-
71
- ## ⚠️ What this Tool Can and Cannot Do
72
-
73
- ### Can Do:
74
- - Read, write, and patch codebases safely.
75
- - Install and coordinate custom MCP (Model Context Protocol) servers.
76
- - Self-heal syntax and test errors before files are written.
77
- - Revert any file modification instantly.
78
-
79
- ### Cannot Do:
80
- - **No Remote Code Execution**: Runs locally on your machine.
81
- - **Unverified Sensitive Reads Blocked**: Reading files or memory matching sensitive keys (like passwords, secret codes, or personal data) is blocked unless verified via your configured verification code.
82
- - **No Auto-Deletions**: Any command that deletes files outside the working directory is blocked automatically.
1
+ # UTIM CLI Agent: Enterprise Coder Assistant
2
+
3
+ UTIM is an agentic developer CLI assistant designed to automate coding tasks directly inside your local terminal, featuring robust safety controls, self-healing quality gates, and local-first semantic memory.
4
+
5
+ ---
6
+
7
+ ## 🚀 Quick Start
8
+
9
+ ### 1. Installation
10
+ Install the package from your local source directory:
11
+
12
+ ```bash
13
+ # Basic installation
14
+ pip install .
15
+
16
+ # Recommended: Full installation (includes semantic vector RAG & web search)
17
+ pip install ".[full]"
18
+ ```
19
+
20
+ ### 2. Provider & Model Configuration
21
+ Start the chat session:
22
+ ```bash
23
+ utim
24
+ ```
25
+ On first run, UTIM checks for `.utim/config.json`. If it does not exist, it runs a provider and model configuration wizard. You can configure:
26
+ - **Default Providers**: OpenRouter, OpenAI, custom servers, etc.
27
+ - **Model Picker**: Press `Ctrl+M` in the chat terminal at any time to configure, pick, add, or delete LLMs.
28
+
29
+ ---
30
+
31
+ ## ⚡ Main CLI Commands
32
+
33
+ - **`utim`**: Starts the interactive chat terminal (TUI).
34
+ - **`utim task "<prompt>"`**: Executes a single task autonomously from the command line and exits. In an interactive terminal (`stdin` is a TTY) file writes and commands prompt for confirmation; when piped/scripted they run in auto-accept mode.
35
+ - **`utim --dry-run`**: Starts the session in **Dry-Run Mode** (all code modifications and shell commands are simulated, not written/executed).
36
+ - **`utim --sandbox`**: Runs all mutating shell command proposals in the intelligent local sandbox (untrusted commands will block until approved).
37
+ - **`utim doctor`** / **`utim init`** / **`utim reset`**: Administrative commands for state diagnosis, initialization, and factory resets.
38
+
39
+ ---
40
+
41
+ ## 🛠️ In-Chat Slash Commands
42
+
43
+ Inside the interactive chat terminal, type these slash commands for direct workspace control:
44
+
45
+ - **`/undo`**: Reverts the last assistant action, restoring files to their exact "before" state and rolling back messages.
46
+ - **`/redo`**: Re-applies the last undone turn, re-writing files and restoring conversation logs.
47
+ - **`/rewind <turn_index>`**: Rolls back the entire session to a specific conversation turn.
48
+ - **`/doctor`**: Run diagnostics on environment variables, Python version, dependencies, API model connections, and MCP server status.
49
+ - **`/report`**: Generates a support bundle under `.utim_tmp/report_bundle.zip` (automatically redacts secrets, passwords, or personal names/files).
50
+ - **`/reset`**: Wipes the current chat history without deleting persistent local vector memory.
51
+
52
+ ---
53
+
54
+ ## 🧠 Architecture & How it Works
55
+
56
+ 1. **Local Memory (`.utim/memory.json` & ChromaDB)**:
57
+ - Global user preferences, rules, and facts are synced to a semantic vector database (`.utim_tmp/vector_db`).
58
+ - Relevant memories are dynamically fetched via semantic similarity (RAG) and injected into the system prompt context, preventing prompt bloating.
59
+ 2. **Undo/Redo Stack & Session State**:
60
+ - Every file change (writes, batch string edits, moves, deletions) computes a diff snapshot.
61
+ - The entire stack is serialized dynamically to `.utim/session_state.json`. You can close your shell, shut down your computer, and resume later with intact rollback features.
62
+ 3. **Workspace Boundary & Safety Controls**:
63
+ - Prior to writing files, UTIM performs **Pre-Commit Syntax Checks** (AST compilation for Python, JSON loads, JS/TS checks).
64
+ - If tests are available (`pytest`, `npm test`, etc.), UTIM runs them in a background **Regression testing loop**, prompting the model to self-heal code errors if assertions fail.
65
+ - **Interactive TUI mode** (`utim`): every file mutation shows an interactive diff dialog; the developer accepts, edits, or rejects individual hunks before they are applied.
66
+ - **CLI task mode** (`utim task`): when running in a real terminal, destructive operations (`rm`, package installs, `>` redirects) prompt for `y/n` confirmation. When stdin is piped/non-interactive all edits are auto-accepted.
67
+ - **Sandbox mode** (`utim --sandbox`): classifies every terminal command as safe or risky and blocks risky commands until explicitly approved.
68
+
69
+ ---
70
+
71
+ ## ⚠️ What this Tool Can and Cannot Do
72
+
73
+ ### Can Do:
74
+ - Read, write, and patch codebases safely.
75
+ - Install and coordinate custom MCP (Model Context Protocol) servers.
76
+ - Self-heal syntax and test errors before files are written.
77
+ - Revert any file modification instantly.
78
+
79
+ ### Cannot Do:
80
+ - **No Remote Code Execution**: Runs locally on your machine.
81
+ - **Unverified Sensitive Reads Blocked**: Reading files or memory matching sensitive keys (like passwords, secret codes, or personal data) is blocked unless verified via your configured verification code.
82
+ - **No Auto-Deletions**: Any command that deletes files outside the working directory is blocked automatically.
83
+
84
+ ---
85
+
86
+ ## 📋 Compatibility Matrix
87
+
88
+ | Component | Minimum Version | Recommended Version | Notes |
89
+ |-----------|-----------------|---------------------|-------|
90
+ | **Python** | 3.10 | 3.11+ | 3.10 required for asyncio features |
91
+ | **pip** | 21.0 | 23.0+ | For modern dependency resolution |
92
+ | **Node.js** | 18.0 | 20.0+ | Only if using MCP servers |
93
+ | **Operating System** | | | |
94
+ | - Windows | 10 (1903+) | 11 | PowerShell or CMD required |
95
+ | - macOS | 11 (Big Sur) | 14 (Sonoma) | Terminal.app or iTerm2 |
96
+ | - Linux | Ubuntu 20.04 | Ubuntu 22.04+ | Any modern distro with bash |
97
+ | **Terminals** | | | |
98
+ | - Windows Terminal | 1.0 | 1.19+ | Full color support |
99
+ | - iTerm2 | 3.4+ | 3.5+ | Recommended on macOS |
100
+ | - VS Code Terminal | 1.70+ | 1.85+ | Full support |
101
+ | **Required Tools** | | | |
102
+ | - git | 2.30 | 2.40+ | For undo/redo and diffs |
103
+ | - Docker | 20.10 | 24.0+ | Optional, for sandbox mode |
104
+
105
+ ### Supported LLM Providers
106
+
107
+ | Provider | API Type | Models Supported |
108
+ |----------|----------|------------------|
109
+ | OpenRouter | REST | Claude, GPT, Gemini, Mistral, etc. |
110
+ | OpenAI | REST | GPT-4o, GPT-4 Turbo, GPT-3.5 |
111
+ | Anthropic | REST | Claude 3.5, 3, 2 |
112
+ | Google AI | REST | Gemini 1.5 Pro/Flash |
113
+ | Azure OpenAI | REST | GPT-4, GPT-3.5 |
114
+ | Ollama | Local | Llama 3, Mistral, CodeLlama |
115
+ | Custom Server | REST | Any OpenAI-compatible API |
116
+
117
+ ---
118
+
119
+ ## 📄 Related Documentation
120
+
121
+ - [📖 Full Documentation](https://utim.dev/docs)
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
124
+ - [📊 SLA & Support](SLA.md)
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.27",
4
- "description": "UTIM Universal Terminal Intelligence Manager. An agentic AI coding assistant for your terminal.",
3
+ "version": "1.46.30",
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,