ucode-agent 1.26.2 → 1.28.0

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,399 +1,438 @@
1
- # ucode
2
-
3
- A coding agent that lives in your terminal. It reads your code, edits it, runs
4
- your commands, and keeps every conversation on disk. It runs on NVIDIA and
5
- Cohere models, all of them free.
6
-
7
- It opens on a quiet screen — the name, the place to type, and the version in the
8
- corner:
9
-
10
- ```
11
- ██╗ ██╗ ██████╗ ██████╗ ██████╗ ███████╗
12
- ██║ ██║██╔════╝██╔═══██╗██╔══██╗██╔════╝
13
- ██║ ██║██║ ██║ ██║██║ ██║█████╗
14
- ██║ ██║██║ ██║ ██║██║ ██║██╔══╝
15
- ╚██████╔╝╚██████╗╚██████╔╝██████╔╝███████╗
16
- ╚═════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝
17
-
18
-
19
- ╭──────────────────────────────────────────────────────────────────────────────╮
20
- │ › Ask anything… │
21
- │ │
22
- │ ◆ Build · North Mini Code 0% │
23
- ╰──────────────────────────────────────────────────────────────────────────────╯
24
-
25
-
26
- v1.2.0
27
- ```
28
-
29
- and once you are talking, each message you send is boxed in the same blue as
30
- the input, so your own words are easy to find in a long session:
31
-
32
- ```
33
- ╭──────────────────────────────────────────────────────────────────────────────────╮
34
- │ › build a notes dashboard │
35
- ╰──────────────────────────────────────────────────────────────────────────────────╯
36
- ● Writing index.html
37
- └ created · 148 lines
38
- 1 + <!doctype html>
39
- 2 + <html lang="en">
40
- … 146 more lines
41
- ● Running npm run dev
42
- └ ready · http://localhost:3000 · PID 4812
43
-
44
- ╭──────────────────────────────────────────────────────────────────────────────────╮
45
- │ › now add a dark mode toggle │
46
- │ │
47
- │ ◆ Build · North Mini Code 4% │
48
- ╰──────────────────────────────────────────────────────────────────────────────────╯
49
- ```
50
-
51
- The status sits inside the input box because it describes the thing you are
52
- typing into. Three facts, no more: the live mode, the answering model, and how
53
- full the context window is. The percentage turns amber at 75%, which is where
54
- older turns start being folded into a summary. While a turn is running the
55
- middle of that row carries the spinner and the way out of it, and hands the
56
- space straight back when it finishes.
57
-
58
- ## Install
59
-
60
- ```bash
61
- npm i -g ucode-agent
62
- ```
63
-
64
- Then put a key where it will survive upgrades:
65
-
66
- ```bash
67
- mkdir -p ~/.ucode
68
- echo "UCODE_API_KEY=sk-or-..." > ~/.ucode/.env
69
- ```
70
-
71
- Keys are free at [openrouter.ai/keys](https://openrouter.ai/keys). A `.env` in
72
- the project you are working on wins over that one, and a real environment
73
- variable wins over both.
74
-
75
- Then, in any project:
76
-
77
- ```bash
78
- ucode
79
- ```
80
-
81
- Needs Node 22 or newer.
82
-
83
- ## The models
84
-
85
- Five, and no picker full of names nobody recognises. NVIDIA and Cohere both
86
- serve capable models free, and both handle tool calling
87
- properly, which is the thing an agent actually depends on.
88
-
89
- | Model | Context | For |
90
- | --- | --- | --- |
91
- | Nemotron 3 Ultra | 1M | deepest reasoning, slowest to first token |
92
- | Nemotron 3.5 Lightning | 1M | the same enormous window, answers much sooner |
93
- | Nemotron 3 Super | 262k | strong all-rounder, quick to start |
94
- | Nemotron 3 Nano Omni | 256k | small, fast, reasoning tuned |
95
- | **North Mini Code** ★ | 256k | the default — built for code and interface work, quick to answer |
96
-
97
- `/model` shows them and switches. `ucode -m cohere/north-mini-code:free`
98
- starts on one.
99
-
100
- North Mini Code is the default: it is built for code and interfaces, which is most
101
- of what ucode is asked to do, and it answers far sooner than the big reasoning
102
- models. Switch to Ultra when a problem needs the million-token window more than
103
- the speed.
104
-
105
- **A busy model never stops a build.** Free endpoints are shared, and "too many
106
- requests" is routine. ucode waits it out with growing pauses, and if the model
107
- stays busy it carries on with the next one — North Mini Code, then Nemotron 3.5
108
- Lightning, Super, Ultra — from exactly where it was, and tells you it switched.
109
- If every model is busy at once it waits a minute and goes round again. Your
110
- chosen model gets another go a few minutes later.
111
-
112
- ## What it does
113
-
114
- **Twenty-one tools.** `create_app`, `read_file`, `read_files`, `write_file`,
115
- `batch_write`, `edit_file`, `multi_edit`, `edit_files`, `rename_symbol`,
116
- `find_symbol`, `outline`, `type_of`, `add_block`, `list_dir`, `glob`, `grep`,
117
- `run_command`, `run_commands`, `look_at_app`, `web_search`, `deploy`. Read-only
118
- calls run in parallel, and start the moment the model finishes writing them —
119
- while the rest of its reply is still arriving. Anything that writes runs on its
120
- own, in order.
121
-
122
- **It asks rather than guesses.** `type_of` opens a language service on the
123
- TypeScript the project itself has installed and gives back the exact signature,
124
- the JSDoc, and where a thing is defined — inferred types included. `find_symbol`
125
- answers "where is this declared", which is the question `grep` is usually being
126
- asked badly. `rename_symbol` renames by code shape, knowing where strings and
127
- comments begin, because a find-and-replace that matched too much is the most
128
- common broken edit.
129
-
130
- **It checks itself as it goes.** After a change: an incremental type check that
131
- answers in about a second rather than a cold minute, then the tests that reach
132
- the files just changed, then anything the running dev server has complained
133
- about since the last look. All three come back the way an error does, so the
134
- model fixes them without being told.
135
-
136
- **New apps are ready in seconds.** A starter installed once is kept and
137
- hard-linked into the next app — the same files under another name, so it costs
138
- no extra disk and skips the wait entirely.
139
-
140
- **Apps start from a ready-made starter.** Setting up Next.js and shadcn from
141
- nothing takes about four minutes — `create-next-app` and the shadcn CLI measured
142
- at 116s and 130s — plus a dozen model round trips. `create_app` copies ucode's
143
- starter instead: Next.js 16, TypeScript, Tailwind 4, shadcn/ui with 25 common
144
- components, light/dark mode, toasts and a considered theme, already known to
145
- build. The copy takes under a second, and its install runs in the background
146
- while the model writes the first components.
147
-
148
- **Built to be fast, and measured.** A traced build of a small Next.js app went
149
- from 17 minutes and 116 model steps to about 6 minutes and 25 steps, by fixing
150
- where the time actually went:
151
-
152
- - Edits return the file as it now stands, so the model does not re-read it.
153
- - Files written more than a few steps ago stop being re-sent in full; the
154
- conversation stays small, so every step answers faster.
155
- - A file-write whose JSON is malformed — a missing comma, an unescaped quote in
156
- the code, raw line breaks — is repaired instead of thrown away with all its
157
- output.
158
- - Every write is parsed on the spot, so a syntax error comes back in the same
159
- step rather than a minute later from a failed build.
160
- - A failed build that is missing a component or package says exactly which
161
- command fixes it.
162
- - The starter is the shadcn models already know (Radix), so the code they write
163
- compiles the first time.
164
-
165
- `UCODE_TRACE=1` writes every model call and tool, with its duration, to
166
- `~/.ucode/trace.jsonl`.
167
-
168
- **Deploy in one line.** Say "deploy it", or type `/deploy [folder]`, and the app
169
- goes live on Vercel. ucode picks a short project name that fits the app and is
170
- free (`food-iq`, else `food-iq-app`…), copies the app's `.env` keys to Vercel as
171
- encrypted variables, refuses code with a secret written into it (and says how to
172
- move it to a server route), and gives you the link. Deploying again updates the
173
- same link. Needs a token from vercel.com/account/tokens in `~/.ucode/.env` as
174
- `VERCEL_TOKEN=...`.
175
-
176
- **A look for every app.** `create_app` takes a design preset — ocean, grove,
177
- sunset, graphite, violet or citrus — each a full light and dark palette with its
178
- own font, so apps stop looking like the same default blue.
179
-
180
- **It notices when it is going round in circles.** The same failing edit, an edit
181
- that changes nothing, or a build failing on the same errors three times gets a
182
- firm, specific note; if that does not work, the turn moves to another model.
183
-
184
- **It never dies at the daily limit.** When the free daily limit runs out mid-build,
185
- ucode counts down to the reset and carries on by itself.
186
-
187
- **You can see it working.** The status row shows the current step with a light
188
- sweeping across it, the step count and the time, and each answer ends with
189
- `✓ Done in 6m 12s · 25 steps`. When a dev server comes up, the app opens in your
190
- browser (`UCODE_OPEN=0` turns that off).
191
-
192
- **`/stats` and `ucode doctor`.** `/stats` shows the session's time, steps, tokens,
193
- files and builds. `ucode doctor` (or `/doctor`) checks Node, npm, git, the API
194
- key and today's free requests left, the browser, the Vercel token and the
195
- version, with the fix for anything wrong.
196
-
197
- **Parallel workers.** When a build splits into parts that touch different files
198
- — the API route, the upload component, the results view — the model hands them
199
- to up to three workers that build at the same time, each line in the transcript
200
- tagged with the worker's name. File writes take turns so two never collide.
201
-
202
- **Installs that start early.** The moment a `package.json` with dependencies is
203
- written, its install starts in the background while the rest of the app is
204
- still being written. An install the model asks for later waits for that one
205
- instead of running twice, and anything run in that folder waits for it too.
206
-
207
- **It looks at what it built.** `look_at_app` opens the running app in a real
208
- browser — the Edge or Chrome already on your machine, so there is nothing extra
209
- to download — at 375px and 1440px. It reports console errors, failed requests,
210
- content that spills off a phone screen, broken images and unlabeled controls,
211
- saves screenshots to `.ucode/screenshots`, and has Nemotron Nano Omni review them
212
- the way a designer would. The model fixes what it finds before calling the app
213
- done. Both widths load at once, and the designer review — the slow part — runs
214
- on the first look at an app in each request and is skipped, not waited on, when
215
- the vision model is busy. The look after the fixes re-runs only the fast checks:
216
- a few seconds.
217
-
218
- **Errors fixed before you see them.** When the model says it is done, ucode
219
- type-checks every file it changed — `tsc --noEmit` for TypeScript projects,
220
- a syntax check for JavaScript and Python — and hands any errors back to fix,
221
- up to three rounds.
222
-
223
- **A plan you can see.** For longer jobs the model keeps a short checklist, shown
224
- as one line: `plan 2/5 ✓ Scaffold · ✓ Upload · ▸ Score dial · ○ Findings · ○ Polish`.
225
-
226
- **It knows the project before it asks.** Each turn starts with a map of every
227
- file and the names each code file exports, so the model goes straight to the
228
- right file instead of searching for it.
229
-
230
- **Project memory.** `UCODE.md` in a project — and `~/.ucode/UCODE.md` for how you
231
- like to work everywhere — is read at the start of every turn. `/remember <note>`
232
- adds a line to it.
233
-
234
- **Edits that never guess.** `edit_file` matches exactly once or it fails, and
235
- when it fails it says *why*. It tolerates what does not matter — tabs against
236
- spaces, a different indent depth, Windows line endings — and re-indents the
237
- replacement to fit the file, but a match found twice is still refused.
238
- `edit_files` changes several files in one call, and writes none of them if any
239
- edit fails.
240
-
241
- **Diffs with real line numbers.** Removed lines are numbered where they were,
242
- added lines where they now are. Numbers you can jump to, not decoration.
243
-
244
- **Live commentary.** `● Listing src`, `● Running npm test` — what it is doing,
245
- as it does it, named after the file or command rather than the tool.
246
-
247
- **Two modes.** Build edits and runs. Plan reads and researches with the writing
248
- tools withheld, which is stronger than asking a model nicely. `ctrl+b` swaps
249
- them; the chip inside the input box says which is live.
250
-
251
- **Sessions.** Everything is on disk under `~/.ucode/sessions`, saved after every
252
- step. `/resume` lists them with what each one was actually about, the ones from
253
- this folder first. Press `d` twice on one to delete it — the list stays open, so
254
- clearing out several is quick — or `/session delete 2,5`.
255
-
256
- **It updates itself.** Each launch checks npm in the background and, if there is
257
- a newer version, installs it while you work. The next launch is the new one.
258
- Set `UCODE_NO_UPDATE=1` to turn that off.
259
-
260
- **A context window that folds rather than forgets.** Past 75% the oldest turns
261
- are summarised instead of dropped, never cutting between a tool call and its
262
- result. The full history stays on disk regardless.
263
-
264
- **Screenshots.** Mention a `.png` in your message and it gets attached.
265
-
266
- ## Skills
267
-
268
- A skill is a folder with a `SKILL.md`: frontmatter, then instructions. Only the
269
- names and one-line descriptions go into the system prompt — a body is pulled in
270
- when it is wanted, so the prompt stays the same size however many you add.
271
-
272
- | Skill | For |
273
- | --- | --- |
274
- | `ui-ux` | interfaces: direction, tokens, layout, states, motion, accessibility |
275
- | `build-app` | going from nothing to something running, and proving it runs |
276
- | `debug` | finding the real cause instead of the first plausible one |
277
- | `code-review` | reviewing a change the way a careful colleague would |
278
- | `write-tests` | tests that fail for the right reason |
279
- | `ai-features` | model-backed features: prompts with rules, validated JSON, images, failure handling |
280
- | `security` | secrets, auth, ownership checks, injection, XSS, CSRF, SSRF, uploads |
281
- | `performance` | measure first, find the real bottleneck, prove the win with numbers |
282
- | `refactor` | change the shape of code without changing what it does |
283
-
284
- **Every skill loads itself** when the request calls for it — an app pulls in
285
- `ui-ux` and `build-app`, "it crashes" pulls in `debug`, an AI feature pulls in
286
- `ai-features`, an API key pulls in `security` — so the whole skill is in
287
- context before the model takes its first step. Waiting for the model to decide it needs design guidance means
288
- finding out it did not after the app is built.
289
-
290
- Add your own in `.ucode/skills/<name>/SKILL.md` inside a project. A project
291
- skill shadows a built-in of the same name. Give it an `auto:` line and it loads
292
- itself too:
293
-
294
- ```markdown
295
- ---
296
- name: house-style
297
- description: How we write services here.
298
- auto: endpoint, handler, migration
299
- ---
300
-
301
- Everything after the frontmatter is the instruction.
302
- ```
303
-
304
- ## Commands
305
-
306
- | | |
307
- | --- | --- |
308
- | `/help` | the list |
309
- | `/model` | show the models and switch — `/models` does the same |
310
- | `/resume` | pick up an earlier conversation — `/session`, `/sessions` too |
311
- | `/session delete 2,5` | delete saved conversations by number (or `d d` in the list) |
312
- | `/new` | save this one and start fresh |
313
- | `/remember <note>` | add a standing note to this project's `UCODE.md` |
314
- | `/skills` | what it knows how to do, and what is loaded |
315
- | `/search <query>` | look something up on the web |
316
- | `/copy` | last reply to the clipboard |
317
- | `/clear` | clear the screen, keep the conversation |
318
- | `/exit` | save and quit |
319
-
320
- `ctrl+b` plan/build · `esc` stops a running turn · `ctrl+d` quits ·
321
- `↑ ↓` scroll the conversation, or walk history once you are typing ·
322
- `tab` completes a command
323
-
324
- ## Options
325
-
326
- ```
327
- ucode [options]
328
-
329
- -m, --model <id> which model to use
330
- -C, --cwd <dir> work in another directory
331
- --plan start in plan mode
332
- --debug print stack traces when something breaks
333
- -v, --version print the version
334
- -h, --help the above
335
- ```
336
-
337
- ## Configuration
338
-
339
- | | |
340
- | --- | --- |
341
- | `~/.ucode/.env` | `UCODE_API_KEY`, and `TAVILY_API_KEY` for web search |
342
- | `~/.ucode/sessions/` | one JSON per conversation |
343
- | `.ucode/skills/` | skills belonging to a project |
344
- | `UCODE.md` | project memory, read every turn |
345
- | `~/.ucode/UCODE.md` | your own standing instructions, for every project |
346
-
347
- Environment overrides: `UCODE_MODEL`, `UCODE_WORKER_MODEL` (a faster model for
348
- parallel workers), `UCODE_WORKER_STEPS`, `UCODE_MAX_CONTEXT_TOKENS`,
349
- `UCODE_MAX_STEPS`, `UCODE_MAX_TOOL_OUTPUT`, `UCODE_REQUEST_TIMEOUT_MS`,
350
- `UCODE_BASE_URL`, `UCODE_NO_UPDATE`.
351
-
352
- Web search needs a Tavily key — free, 1000 searches a month, no card. Without
353
- one, ucode answers from what it knows and says that it could not check.
354
-
355
- ## How it is put together
356
-
357
- ```
358
- ucode.js the command: arguments in, Agent out
359
- src/core/loop.js the agent loop, the system prompt, the slash commands
360
- src/core/provider.js the only file that knows which provider answers
361
- src/core/history.js sessions on disk
362
- src/core/window.js folding a long conversation to fit
363
- src/core/skills.js loading skills, and deciding which load themselves
364
- src/core/context.js the project map and project memory
365
- src/core/failure.js one error shape: what, why, what next
366
- src/tools/ the twenty-one tools, plus their shared plumbing
367
- src/ui/screen.js the full-screen interface
368
- src/ui/plain.js the same interface for when there is no terminal
369
- src/ui/theme.js colour, boxes, and the string maths behind both
370
- ```
371
-
372
- Everything above `provider.js` speaks one small provider-neutral message
373
- format. Moving to another host means rewriting that one file.
374
-
375
- Every failure carries three things — what was attempted, what failed, and what
376
- to do next — so no screen ever has to fall back on a stack trace. Tool failures
377
- are handed to the model as text instead, which is why they read like
378
- instructions.
379
-
380
- ## Development
381
-
382
- ```bash
383
- git clone https://github.com/sppideey/ucode-agent
384
- cd ucode-agent
385
- npm install
386
- npm link # puts `ucode` on PATH, pointing at this checkout
387
- npm test
388
- ```
389
-
390
- `npm link` matters while developing: it symlinks the global command to your
391
- working copy, so an edit is live on the next launch. Running
392
- `npm i -g ucode-agent` replaces that with a frozen copy from the registry and
393
- your edits stop taking effect.
394
-
395
- The tests need no network and no framework — `node test/run.js` runs them all.
396
-
397
- ## Licence
398
-
399
- ISC. Made with ❤️ by om dixit.
1
+ # ucode
2
+
3
+ A coding agent that lives in your terminal. It reads your code, edits it, runs
4
+ your commands, and keeps every conversation on disk. It runs on NVIDIA and
5
+ Cohere models, all of them free.
6
+
7
+ It opens on a quiet screen — the name, the place to type, and the version in the
8
+ corner:
9
+
10
+ ```
11
+ ██╗ ██╗ ██████╗ ██████╗ ██████╗ ███████╗
12
+ ██║ ██║██╔════╝██╔═══██╗██╔══██╗██╔════╝
13
+ ██║ ██║██║ ██║ ██║██║ ██║█████╗
14
+ ██║ ██║██║ ██║ ██║██║ ██║██╔══╝
15
+ ╚██████╔╝╚██████╗╚██████╔╝██████╔╝███████╗
16
+ ╚═════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝
17
+
18
+
19
+ ╭──────────────────────────────────────────────────────────────────────────────╮
20
+ │ › Ask anything… │
21
+ │ │
22
+ │ ◆ Build · North Mini Code 0% │
23
+ ╰──────────────────────────────────────────────────────────────────────────────╯
24
+
25
+
26
+ v1.2.0
27
+ ```
28
+
29
+ and once you are talking, each message you send is boxed in the same blue as
30
+ the input, so your own words are easy to find in a long session:
31
+
32
+ ```
33
+ ╭──────────────────────────────────────────────────────────────────────────────────╮
34
+ │ › build a notes dashboard │
35
+ ╰──────────────────────────────────────────────────────────────────────────────────╯
36
+ ● Writing index.html
37
+ └ created · 148 lines
38
+ 1 + <!doctype html>
39
+ 2 + <html lang="en">
40
+ … 146 more lines
41
+ ● Running npm run dev
42
+ └ ready · http://localhost:3000 · PID 4812
43
+
44
+ ╭──────────────────────────────────────────────────────────────────────────────────╮
45
+ │ › now add a dark mode toggle │
46
+ │ │
47
+ │ ◆ Build · North Mini Code 4% │
48
+ ╰──────────────────────────────────────────────────────────────────────────────────╯
49
+ ```
50
+
51
+ The status sits inside the input box because it describes the thing you are
52
+ typing into. Three facts, no more: the live mode, the answering model, and how
53
+ full the context window is. The percentage turns amber at 75%, which is where
54
+ older turns start being folded into a summary. While a turn is running the
55
+ middle of that row carries the spinner and the way out of it, and hands the
56
+ space straight back when it finishes.
57
+
58
+ ## Install
59
+
60
+ ```bash
61
+ npm i -g ucode-agent
62
+ ```
63
+
64
+ Then put a key where it will survive upgrades:
65
+
66
+ ```bash
67
+ mkdir -p ~/.ucode
68
+ echo "UCODE_API_KEY=sk-or-..." > ~/.ucode/.env
69
+ ```
70
+
71
+ Keys are free at [openrouter.ai/keys](https://openrouter.ai/keys). A `.env` in
72
+ the project you are working on wins over that one, and a real environment
73
+ variable wins over both.
74
+
75
+ Then, in any project:
76
+
77
+ ```bash
78
+ ucode
79
+ ```
80
+
81
+ Needs Node 22 or newer.
82
+
83
+ ## The models
84
+
85
+ Five, and no picker full of names nobody recognises. NVIDIA and Cohere both
86
+ serve capable models free, and both handle tool calling
87
+ properly, which is the thing an agent actually depends on.
88
+
89
+ | Model | Context | For |
90
+ | --- | --- | --- |
91
+ | Nemotron 3 Ultra | 1M | deepest reasoning, slowest to first token |
92
+ | Nemotron 3.5 Lightning | 1M | the same enormous window, answers much sooner |
93
+ | Nemotron 3 Super | 262k | strong all-rounder, quick to start |
94
+ | Nemotron 3 Nano Omni | 256k | small, fast, reasoning tuned |
95
+ | **North Mini Code** ★ | 256k | the default — built for code and interface work, quick to answer |
96
+
97
+ `/model` shows them and switches. `ucode -m cohere/north-mini-code:free`
98
+ starts on one.
99
+
100
+ North Mini Code is the default: it is built for code and interfaces, which is most
101
+ of what ucode is asked to do, and it answers far sooner than the big reasoning
102
+ models. Switch to Ultra when a problem needs the million-token window more than
103
+ the speed.
104
+
105
+ **A busy model never stops a build.** Free endpoints are shared, and "too many
106
+ requests" is routine. ucode waits it out with growing pauses, and if the model
107
+ stays busy it carries on with the next one — North Mini Code, then Nemotron 3.5
108
+ Lightning, Super, Ultra — from exactly where it was, and tells you it switched.
109
+ If every model is busy at once it waits a minute and goes round again. Your
110
+ chosen model gets another go a few minutes later.
111
+
112
+ ## What it does
113
+
114
+ **Twenty-one tools.** `create_app`, `read_file`, `read_files`, `write_file`,
115
+ `batch_write`, `edit_file`, `multi_edit`, `edit_files`, `rename_symbol`,
116
+ `find_symbol`, `outline`, `type_of`, `add_block`, `list_dir`, `glob`, `grep`,
117
+ `run_command`, `run_commands`, `look_at_app`, `web_search`, `deploy`. Read-only
118
+ calls run in parallel, and start the moment the model finishes writing them —
119
+ while the rest of its reply is still arriving. Anything that writes runs on its
120
+ own, in order.
121
+
122
+ **It asks rather than guesses.** `type_of` opens a language service on the
123
+ TypeScript the project itself has installed and gives back the exact signature,
124
+ the JSDoc, and where a thing is defined — inferred types included. `find_symbol`
125
+ answers "where is this declared", which is the question `grep` is usually being
126
+ asked badly. `rename_symbol` renames by code shape, knowing where strings and
127
+ comments begin, because a find-and-replace that matched too much is the most
128
+ common broken edit.
129
+
130
+ **It checks itself as it goes.** After a change: an incremental type check that
131
+ answers in about a second rather than a cold minute, then the tests that reach
132
+ the files just changed, then anything the running dev server has complained
133
+ about since the last look. All three come back the way an error does, so the
134
+ model fixes them without being told.
135
+
136
+ **New apps are ready in seconds.** A starter installed once is kept and
137
+ hard-linked into the next app — the same files under another name, so it costs
138
+ no extra disk and skips the wait entirely.
139
+
140
+ **Apps start from a ready-made starter — and finish in the same call.**
141
+ `create_app` copies a starter that is already known to build, and takes the
142
+ app's files with it, so a one-page app is a single round trip: the starter
143
+ lands, the model's files are written over it, and the starter's own files come
144
+ back inside the result so there is nothing to read afterwards.
145
+
146
+ The default starter is `plain-html`: one page, one stylesheet, one module,
147
+ nothing to install and nothing to build. A tasks app, a game, a calculator or a
148
+ visualisation is finished before a framework would have finished installing.
149
+ `next-shadcn` is there for routes, a database or many screens — Next.js 16,
150
+ TypeScript, Tailwind 4, shadcn/ui with 25 components, light/dark, toasts and a
151
+ considered theme. Setting that up by hand is about four minutes
152
+ (`create-next-app` and the shadcn CLI measured at 116s and 130s) plus a dozen
153
+ round trips; the copy takes under a second, and its install runs in the
154
+ background while the model writes the first components.
155
+
156
+ **Built to be fast, and measured.** A traced build of a small Next.js app went
157
+ from 17 minutes and 116 model steps to about 6 minutes and 25 steps, by fixing
158
+ where the time actually went:
159
+
160
+ - Edits return the file as it now stands, so the model does not re-read it.
161
+ - Files written more than a few steps ago stop being re-sent in full; the
162
+ conversation stays small, so every step answers faster.
163
+ - A file-write whose JSON is malformed — a missing comma, an unescaped quote in
164
+ the code, raw line breaks — is repaired instead of thrown away with all its
165
+ output.
166
+ - Every write is parsed on the spot, so a syntax error comes back in the same
167
+ step rather than a minute later from a failed build.
168
+ - A failed build that is missing a component or package says exactly which
169
+ command fixes it.
170
+ - The starter is the shadcn models already know (Radix), so the code they write
171
+ compiles the first time.
172
+ - A new app goes out without the tools it has nothing to point at — no symbol
173
+ lookup, no rename, no type query in an empty folder — and an instruction pack
174
+ that loads itself sends its short form, with the full one a `load_skill`
175
+ away. Both are re-read by the provider on every step, so what is not in the
176
+ request is time off every one of them.
177
+ - Ready-made blocks for a page with no build step as well as for React: a list you
178
+ can add to, tick off, rename and remove, a filter row, a localStorage store, a
179
+ dialog, toasts, a theme toggle. Typing is the slowest part of a build, and each
180
+ block is a hundred lines nobody has to type.
181
+ - A nested argument written the wrong way — a JSON string, a { path: contents } map
182
+ — is read rather than refused. Each refusal was a round trip spent being told
183
+ something that could simply be parsed.
184
+ - A tool that was not offered is refused rather than quietly run, so withholding one
185
+ from a new project, or from plan mode, means what it says.
186
+ - The closing message is cut to eight lines. A build that ends with the request
187
+ read back and every feature ticked off is a status report nobody asked for,
188
+ and it is the last thing left on screen.
189
+
190
+ `UCODE_TRACE=1` writes every model call and tool, with its duration, to
191
+ `~/.ucode/trace.jsonl`.
192
+
193
+ Measured on "build me a simple todo app" — same prompt, same model, two traced
194
+ runs: **27 model calls, 8 failed tool calls, no finished app** before this round of
195
+ work; **14 model calls, no failures, a working app in under two minutes** after it.
196
+
197
+ **Deploy in one line.** Say "deploy it", or type `/deploy [folder]`, and the app
198
+ goes live on Vercel. ucode picks a short project name that fits the app and is
199
+ free (`food-iq`, else `food-iq-app`…), copies the app's `.env` keys to Vercel as
200
+ encrypted variables, refuses code with a secret written into it (and says how to
201
+ move it to a server route), and gives you the link. Deploying again updates the
202
+ same link. Needs a token from vercel.com/account/tokens in `~/.ucode/.env` as
203
+ `VERCEL_TOKEN=...`.
204
+
205
+ **A look for every app.** `create_app` takes a design preset — ocean, grove,
206
+ sunset, graphite, violet or citrus — each a full light and dark palette with its
207
+ own font, so apps stop looking like the same default blue.
208
+
209
+ **It notices when it is going round in circles.** The same failing edit, an edit
210
+ that changes nothing, or a build failing on the same errors three times gets a
211
+ firm, specific note; if that does not work, the turn moves to another model.
212
+
213
+ **It never dies at the daily limit.** When the free daily limit runs out mid-build,
214
+ ucode counts down to the reset and carries on by itself.
215
+
216
+ **You can see it working.** The status row shows the current step with a light
217
+ sweeping across it, the step count and the time, and each answer ends with
218
+ `✓ Done in 6m 12s · 25 steps`. When a dev server comes up, the app opens in your
219
+ browser (`UCODE_OPEN=0` turns that off).
220
+
221
+ **`/stats` and `ucode doctor`.** `/stats` shows the session's time, steps, tokens,
222
+ files and builds. `ucode doctor` (or `/doctor`) checks Node, npm, git, the API
223
+ key and today's free requests left, the browser, the Vercel token and the
224
+ version, with the fix for anything wrong.
225
+
226
+ **Parallel workers.** When a build splits into parts that touch different files
227
+ — the API route, the upload component, the results view — the model hands them
228
+ to up to three workers that build at the same time, each line in the transcript
229
+ tagged with the worker's name. File writes take turns so two never collide.
230
+
231
+ **Installs that start early.** The moment a `package.json` with dependencies is
232
+ written, its install starts in the background while the rest of the app is
233
+ still being written. An install the model asks for later waits for that one
234
+ instead of running twice, and anything run in that folder waits for it too.
235
+
236
+ **It looks at what it built.** `look_at_app` opens the running app in a real
237
+ browser — the Edge or Chrome already on your machine, so there is nothing extra
238
+ to download — at 375px and 1440px. It reports console errors, failed requests,
239
+ content that spills off a phone screen, broken images and unlabeled controls,
240
+ saves screenshots to `.ucode/screenshots`, and has Nemotron Nano Omni review them
241
+ the way a designer would. The model fixes what it finds before calling the app
242
+ done. Both widths load at once, and the designer review — the slow part — runs
243
+ on the first look at an app in each request and is skipped, not waited on, when
244
+ the vision model is busy. The look after the fixes re-runs only the fast checks:
245
+ a few seconds.
246
+
247
+ **Errors fixed before you see them.** When the model says it is done, ucode
248
+ type-checks every file it changed — `tsc --noEmit` for TypeScript projects,
249
+ a syntax check for JavaScript and Python — and hands any errors back to fix,
250
+ up to three rounds.
251
+
252
+ **A plan you can see.** For longer jobs the model keeps a short checklist, with
253
+ a bar across the top for how far along it is and one row per step, so the one in
254
+ progress is findable without reading the rest:
255
+
256
+ ```
257
+ ━━━━────── 2/5
258
+ ✓ Scaffold
259
+ ✓ Upload
260
+ ▸ Score dial
261
+ ○ Findings
262
+ ○ Polish
263
+ ```
264
+
265
+ **It knows the project before it asks.** Each turn starts with a map of every
266
+ file and the names each code file exports, so the model goes straight to the
267
+ right file instead of searching for it.
268
+
269
+ **Project memory.** `UCODE.md` in a project — and `~/.ucode/UCODE.md` for how you
270
+ like to work everywhere — is read at the start of every turn. `/remember <note>`
271
+ adds a line to it.
272
+
273
+ **Edits that never guess.** `edit_file` matches exactly once or it fails, and
274
+ when it fails it says *why*. It tolerates what does not matter — tabs against
275
+ spaces, a different indent depth, Windows line endings — and re-indents the
276
+ replacement to fit the file, but a match found twice is still refused.
277
+ `edit_files` changes several files in one call, and writes none of them if any
278
+ edit fails.
279
+
280
+ **Diffs with real line numbers.** Removed lines are numbered where they were,
281
+ added lines where they now are. Numbers you can jump to, not decoration.
282
+
283
+ **Live commentary.** `● Listing src`, `● Running npm test` — what it is doing,
284
+ as it does it, named after the file or command rather than the tool.
285
+
286
+ **Two modes.** Build edits and runs. Plan reads and researches with the writing
287
+ tools withheld, which is stronger than asking a model nicely. `ctrl+b` swaps
288
+ them; the chip inside the input box says which is live.
289
+
290
+ **Sessions.** Everything is on disk under `~/.ucode/sessions`, saved after every
291
+ step. `/resume` lists them with what each one was actually about, the ones from
292
+ this folder first. Press `d` twice on one to delete it — the list stays open, so
293
+ clearing out several is quick — or `/session delete 2,5`.
294
+
295
+ **It updates itself.** Each launch checks npm in the background and, if there is
296
+ a newer version, installs it while you work. The next launch is the new one.
297
+ Set `UCODE_NO_UPDATE=1` to turn that off.
298
+
299
+ **A context window that folds rather than forgets.** Past 75% the oldest turns
300
+ are summarised instead of dropped, never cutting between a tool call and its
301
+ result. The full history stays on disk regardless.
302
+
303
+ **Screenshots.** Mention a `.png` in your message and it gets attached.
304
+
305
+ ## Skills
306
+
307
+ A skill is a folder with a `SKILL.md`: frontmatter, then instructions. Only the
308
+ names and one-line descriptions go into the system prompt — a body is pulled in
309
+ when it is wanted, so the prompt stays the same size however many you add.
310
+
311
+ | Skill | For |
312
+ | --- | --- |
313
+ | `ui-ux` | interfaces: direction, tokens, layout, states, motion, accessibility |
314
+ | `build-app` | going from nothing to something running, and proving it runs |
315
+ | `debug` | finding the real cause instead of the first plausible one |
316
+ | `code-review` | reviewing a change the way a careful colleague would |
317
+ | `write-tests` | tests that fail for the right reason |
318
+ | `ai-features` | model-backed features: prompts with rules, validated JSON, images, failure handling |
319
+ | `security` | secrets, auth, ownership checks, injection, XSS, CSRF, SSRF, uploads |
320
+ | `performance` | measure first, find the real bottleneck, prove the win with numbers |
321
+ | `refactor` | change the shape of code without changing what it does |
322
+
323
+ **Every skill loads itself** when the request calls for it — an app pulls in
324
+ `ui-ux` and `build-app`, "it crashes" pulls in `debug`, an AI feature pulls in
325
+ `ai-features`, an API key pulls in `security` — so the whole skill is in
326
+ context before the model takes its first step. Waiting for the model to decide it needs design guidance means
327
+ finding out it did not after the app is built.
328
+
329
+ Add your own in `.ucode/skills/<name>/SKILL.md` inside a project. A project
330
+ skill shadows a built-in of the same name. Give it an `auto:` line and it loads
331
+ itself too:
332
+
333
+ ```markdown
334
+ ---
335
+ name: house-style
336
+ description: How we write services here.
337
+ auto: endpoint, handler, migration
338
+ ---
339
+
340
+ Everything after the frontmatter is the instruction.
341
+ ```
342
+
343
+ ## Commands
344
+
345
+ | | |
346
+ | --- | --- |
347
+ | `/help` | the list |
348
+ | `/model` | show the models and switch — `/models` does the same |
349
+ | `/resume` | pick up an earlier conversation — `/session`, `/sessions` too |
350
+ | `/session delete 2,5` | delete saved conversations by number (or `d d` in the list) |
351
+ | `/new` | save this one and start fresh |
352
+ | `/remember <note>` | add a standing note to this project's `UCODE.md` |
353
+ | `/skills` | what it knows how to do, and what is loaded |
354
+ | `/search <query>` | look something up on the web |
355
+ | `/copy` | last reply to the clipboard |
356
+ | `/clear` | clear the screen, keep the conversation |
357
+ | `/exit` | save and quit |
358
+
359
+ `ctrl+b` plan/build · `esc` stops a running turn · `ctrl+d` quits ·
360
+ `↑ ↓` scroll the conversation, or walk history once you are typing ·
361
+ `tab` completes a command
362
+
363
+ ## Options
364
+
365
+ ```
366
+ ucode [options]
367
+
368
+ -m, --model <id> which model to use
369
+ -C, --cwd <dir> work in another directory
370
+ --plan start in plan mode
371
+ --debug print stack traces when something breaks
372
+ -v, --version print the version
373
+ -h, --help the above
374
+ ```
375
+
376
+ ## Configuration
377
+
378
+ | | |
379
+ | --- | --- |
380
+ | `~/.ucode/.env` | `UCODE_API_KEY`, and `TAVILY_API_KEY` for web search |
381
+ | `~/.ucode/sessions/` | one JSON per conversation |
382
+ | `.ucode/skills/` | skills belonging to a project |
383
+ | `UCODE.md` | project memory, read every turn |
384
+ | `~/.ucode/UCODE.md` | your own standing instructions, for every project |
385
+
386
+ Environment overrides: `UCODE_MODEL`, `UCODE_WORKER_MODEL` (a faster model for
387
+ parallel workers), `UCODE_WORKER_STEPS`, `UCODE_MAX_CONTEXT_TOKENS`,
388
+ `UCODE_MAX_STEPS`, `UCODE_MAX_TOOL_OUTPUT`, `UCODE_REQUEST_TIMEOUT_MS`,
389
+ `UCODE_BASE_URL`, `UCODE_NO_UPDATE`.
390
+
391
+ Web search needs a Tavily key — free, 1000 searches a month, no card. Without
392
+ one, ucode answers from what it knows and says that it could not check.
393
+
394
+ ## How it is put together
395
+
396
+ ```
397
+ ucode.js the command: arguments in, Agent out
398
+ src/core/loop.js the agent loop, the system prompt, the slash commands
399
+ src/core/provider.js the only file that knows which provider answers
400
+ src/core/history.js sessions on disk
401
+ src/core/window.js folding a long conversation to fit
402
+ src/core/skills.js loading skills, and deciding which load themselves
403
+ src/core/context.js the project map and project memory
404
+ src/core/failure.js one error shape: what, why, what next
405
+ src/tools/ the twenty-one tools, plus their shared plumbing
406
+ src/ui/screen.js the full-screen interface
407
+ src/ui/plain.js the same interface for when there is no terminal
408
+ src/ui/theme.js colour, boxes, and the string maths behind both
409
+ ```
410
+
411
+ Everything above `provider.js` speaks one small provider-neutral message
412
+ format. Moving to another host means rewriting that one file.
413
+
414
+ Every failure carries three things — what was attempted, what failed, and what
415
+ to do next — so no screen ever has to fall back on a stack trace. Tool failures
416
+ are handed to the model as text instead, which is why they read like
417
+ instructions.
418
+
419
+ ## Development
420
+
421
+ ```bash
422
+ git clone https://github.com/sppideey/ucode-agent
423
+ cd ucode-agent
424
+ npm install
425
+ npm link # puts `ucode` on PATH, pointing at this checkout
426
+ npm test
427
+ ```
428
+
429
+ `npm link` matters while developing: it symlinks the global command to your
430
+ working copy, so an edit is live on the next launch. Running
431
+ `npm i -g ucode-agent` replaces that with a frozen copy from the registry and
432
+ your edits stop taking effect.
433
+
434
+ The tests need no network and no framework — `node test/run.js` runs them all.
435
+
436
+ ## Licence
437
+
438
+ ISC. Made with ❤️ by om dixit.