reasonix 0.4.21 → 0.4.23
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 +303 -293
- package/dist/cli/index.js +634 -43
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +287 -4
- package/dist/index.js +416 -82
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,8 +6,9 @@
|
|
|
6
6
|
[](https://www.npmjs.com/package/reasonix)
|
|
7
7
|
[](./package.json)
|
|
8
8
|
|
|
9
|
-
**A DeepSeek-native AI coding
|
|
10
|
-
first-class. No
|
|
9
|
+
**A DeepSeek-native AI coding agent in your terminal.** Edits files as
|
|
10
|
+
reviewable SEARCH/REPLACE blocks. Ink TUI. MCP first-class. No
|
|
11
|
+
LangChain.
|
|
11
12
|
|
|
12
13
|
---
|
|
13
14
|
|
|
@@ -16,60 +17,27 @@ first-class. No LangChain.
|
|
|
16
17
|
**1. Get a DeepSeek API key.** Free credit on signup:
|
|
17
18
|
<https://platform.deepseek.com/api_keys>
|
|
18
19
|
|
|
19
|
-
**2.
|
|
20
|
-
|
|
21
|
-
```bash
|
|
22
|
-
npx reasonix
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
First run walks you through a 30-second wizard:
|
|
26
|
-
|
|
27
|
-
- paste your API key (saved to `~/.reasonix/config.json`)
|
|
28
|
-
- pick a preset — `fast` (cheap chat, default), `smart` (+R1 reasoning), `max` (+self-consistency branching)
|
|
29
|
-
- multi-select MCP servers from a catalog (filesystem, memory, github, puppeteer, …)
|
|
30
|
-
|
|
31
|
-
Every run after that drops you straight into chat.
|
|
32
|
-
|
|
33
|
-
**3. Inside the chat.** Type anything and hit Enter. Type `/help` to see
|
|
34
|
-
every command. The status bar at the top shows cache hit %, cost so far,
|
|
35
|
-
balance, and context usage. Press `Esc` to cancel whatever is running.
|
|
36
|
-
|
|
37
|
-
```
|
|
38
|
-
reasonix › explain what this project does
|
|
39
|
-
assistant
|
|
40
|
-
…streams R1 reasoning into a dim preview, then writes the answer…
|
|
41
|
-
status bar: cache hit 92% · cost $0.001 · ctx 8k/131k (6%) · balance 12.34 CNY
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
Requires Node ≥ 18. Works on macOS, Linux, Windows (Git Bash + PowerShell).
|
|
45
|
-
|
|
46
|
-
---
|
|
47
|
-
|
|
48
|
-
## Using `reasonix code` — your terminal pair programmer
|
|
49
|
-
|
|
50
|
-
Scoped to the directory you launch from. The model has native
|
|
51
|
-
`read_file` / `write_file` / `edit_file` / `list_directory` /
|
|
52
|
-
`search_files` / `directory_tree` / `get_file_info` /
|
|
53
|
-
`create_directory` / `move_file` tools, all sandboxed — any path that
|
|
54
|
-
resolves outside the launch root (including `..` and symlink escapes)
|
|
55
|
-
is refused.
|
|
20
|
+
**2. Point it at a project.** No install needed.
|
|
56
21
|
|
|
57
22
|
```bash
|
|
58
23
|
cd my-project
|
|
59
24
|
npx reasonix code
|
|
60
25
|
```
|
|
61
26
|
|
|
62
|
-
|
|
27
|
+
First run walks you through a 30-second wizard (paste API key → pick
|
|
28
|
+
preset → multi-select MCP servers). Every run after that drops you
|
|
29
|
+
straight in.
|
|
30
|
+
|
|
31
|
+
**3. Ask it to edit.** The model proposes edits as SEARCH/REPLACE
|
|
32
|
+
blocks — nothing hits disk until you `/apply`.
|
|
63
33
|
|
|
64
34
|
```
|
|
65
|
-
reasonix code › users.ts 里 findByEmail
|
|
35
|
+
reasonix code › users.ts 里 findByEmail 对大小写敏感导致登录失败,帮我改
|
|
66
36
|
|
|
67
37
|
assistant
|
|
68
|
-
▸ R1 reasoning · 1243 chars of thought
|
|
69
38
|
▸ tool<search_files> → src/users.ts, src/users.test.ts
|
|
70
39
|
▸ tool<read_file> → (src/users.ts, 412 chars)
|
|
71
|
-
▸
|
|
72
|
-
▸ 找到了。findByEmail 直接用 === 比对。我把查询和存储都规范化为小写,并补上一条测试。
|
|
40
|
+
▸ 找到了。findByEmail 直接用 === 比对。改成小写规范化并补一条测试。
|
|
73
41
|
|
|
74
42
|
src/users.ts
|
|
75
43
|
<<<<<<< SEARCH
|
|
@@ -79,49 +47,34 @@ src/users.ts
|
|
|
79
47
|
return users.find(u => u.email.toLowerCase() === needle);
|
|
80
48
|
>>>>>>> REPLACE
|
|
81
49
|
|
|
82
|
-
|
|
83
|
-
<<<<<<< SEARCH
|
|
84
|
-
it("finds by email", () => {
|
|
85
|
-
expect(findByEmail("a@b.com")).toBeDefined();
|
|
86
|
-
});
|
|
87
|
-
=======
|
|
88
|
-
it("finds by email", () => {
|
|
89
|
-
expect(findByEmail("a@b.com")).toBeDefined();
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
it("is case-insensitive", () => {
|
|
93
|
-
expect(findByEmail("A@B.COM")).toBeDefined();
|
|
94
|
-
});
|
|
95
|
-
>>>>>>> REPLACE
|
|
50
|
+
▸ 1 pending edit across 1 file — /apply to write · /discard to drop
|
|
96
51
|
|
|
97
|
-
|
|
52
|
+
reasonix code › /apply
|
|
53
|
+
▸ ✓ applied src/users.ts
|
|
98
54
|
```
|
|
99
55
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
- `/apply` — commit the pending blocks. You'll see `✓ applied
|
|
104
|
-
src/users.ts` and `✓ applied src/users.test.ts`. A snapshot of the
|
|
105
|
-
pre-edit file is kept so `/undo` can roll back.
|
|
106
|
-
- `/discard` — throw the blocks away without writing.
|
|
107
|
-
- Keep chatting — ask for adjustments. Say "also cover the empty
|
|
108
|
-
string case" and the model proposes another block set.
|
|
56
|
+
Requires Node ≥ 20.10. macOS, Linux, Windows (PowerShell / Git Bash /
|
|
57
|
+
Windows Terminal). Press `Esc` anytime to abort; `/help` for the full
|
|
58
|
+
command list.
|
|
109
59
|
|
|
110
|
-
|
|
60
|
+
---
|
|
111
61
|
|
|
112
|
-
|
|
113
|
-
reasonix code › /commit "fix: findByEmail case-insensitive"
|
|
114
|
-
▸ git add -A && git commit -m "fix: findByEmail case-insensitive"
|
|
115
|
-
[main a1b2c3d] fix: findByEmail case-insensitive
|
|
116
|
-
```
|
|
62
|
+
## `reasonix code` — pair programmer in your terminal
|
|
117
63
|
|
|
118
|
-
|
|
64
|
+
Scoped to the directory you launch from. The model has native
|
|
65
|
+
`read_file` / `write_file` / `edit_file` / `list_directory` /
|
|
66
|
+
`search_files` / `directory_tree` / `get_file_info` /
|
|
67
|
+
`create_directory` / `move_file` tools, all sandboxed — any path that
|
|
68
|
+
resolves outside the launch root (including `..` and symlink escapes)
|
|
69
|
+
is refused. Plus `run_command` with a read-only allowlist; anything
|
|
70
|
+
state-mutating (`npm install`, `git commit`, …) is gated behind a
|
|
71
|
+
confirmation picker.
|
|
119
72
|
|
|
120
73
|
### Walkthrough: explore before editing
|
|
121
74
|
|
|
122
75
|
For "what does this code do?" questions the model uses the read-side
|
|
123
|
-
tools and replies in prose — no SEARCH/REPLACE blocks, no file
|
|
124
|
-
Ask to change something only when you mean it:
|
|
76
|
+
tools and replies in prose — no SEARCH/REPLACE blocks, no file
|
|
77
|
+
writes. Ask to change something only when you mean it:
|
|
125
78
|
|
|
126
79
|
```
|
|
127
80
|
reasonix code › 这个项目的路由是怎么组织的?
|
|
@@ -132,23 +85,10 @@ assistant
|
|
|
132
85
|
nested routes 写子路径,最后 …
|
|
133
86
|
```
|
|
134
87
|
|
|
135
|
-
If
|
|
136
|
-
|
|
137
|
-
error and retries
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
### Things to try
|
|
141
|
-
|
|
142
|
-
- `/tool 1` — dump the last tool call's full output (when the 400-char
|
|
143
|
-
inline clip isn't enough).
|
|
144
|
-
- `/think` — see the model's full R1 reasoning for the last turn
|
|
145
|
-
(reasoner preset only).
|
|
146
|
-
- `/memory` — show the project's `REASONIX.md` (see below).
|
|
147
|
-
- `/plan` — toggle read-only plan mode (see below).
|
|
148
|
-
- `/undo` — roll back the last applied edit batch.
|
|
149
|
-
- `/new` — start fresh in the same directory without losing the
|
|
150
|
-
session file.
|
|
151
|
-
- Drop `--no-session` for an ephemeral session that doesn't persist.
|
|
88
|
+
If an `edit_file` SEARCH block doesn't match the file byte-for-byte,
|
|
89
|
+
the edit is refused loudly rather than fuzzy-matched. The model sees
|
|
90
|
+
the error and retries — silent wrong edits are worse than visible
|
|
91
|
+
rejections.
|
|
152
92
|
|
|
153
93
|
### Plan mode — review before executing
|
|
154
94
|
|
|
@@ -179,24 +119,58 @@ Swap JWT middleware for session cookies, keep user table intact.
|
|
|
179
119
|
Cancel
|
|
180
120
|
```
|
|
181
121
|
|
|
182
|
-
**Approve** exits plan mode and the model starts executing.
|
|
183
|
-
**Refine** keeps the model exploring and asking for an updated plan.
|
|
184
|
-
**Cancel** drops it and asks you what you actually want.
|
|
185
|
-
|
|
186
|
-
Small fixes skip this — the model goes straight to `edit_file`.
|
|
187
|
-
|
|
188
122
|
**Force it** with `/plan` — enters an explicit read-only phase where
|
|
189
123
|
the model *must* submit a plan before any edit or non-allowlisted
|
|
190
|
-
shell call will execute. Use
|
|
191
|
-
|
|
192
|
-
|
|
124
|
+
shell call will execute. Use for high-stakes changes you want to
|
|
125
|
+
audit before the model touches disk. `/plan off` or picker
|
|
126
|
+
Approve/Cancel exits.
|
|
127
|
+
|
|
128
|
+
### `/commit` — stage + commit in one step
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
reasonix code › /commit "fix: findByEmail case-insensitive"
|
|
132
|
+
▸ git add -A && git commit -m "fix: findByEmail case-insensitive"
|
|
133
|
+
[main a1b2c3d] fix: findByEmail case-insensitive
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Things to try
|
|
137
|
+
|
|
138
|
+
- `/tool 1` — dump the last tool call's full output (when the 400-char
|
|
139
|
+
inline clip isn't enough).
|
|
140
|
+
- `/think` — see the model's full R1 reasoning for the last turn
|
|
141
|
+
(reasoner preset only).
|
|
142
|
+
- `/undo` — roll back the last applied edit batch.
|
|
143
|
+
- `/new` — start fresh in the same directory without losing the
|
|
144
|
+
session file.
|
|
145
|
+
- `npx reasonix code --preset max` — R1 + 3-way self-consistency
|
|
146
|
+
branching for gnarly refactors.
|
|
147
|
+
- `npx reasonix code src/` — narrower sandbox (only `src/` is
|
|
148
|
+
writable).
|
|
149
|
+
- `npx reasonix code --no-session` — ephemeral; nothing saved.
|
|
150
|
+
|
|
151
|
+
### Staying current
|
|
152
|
+
|
|
153
|
+
The panel header shows the running version next to `Reasonix` (e.g.
|
|
154
|
+
`Reasonix v0.4.22 · model …`). A quiet 24-hour background check against
|
|
155
|
+
the npm registry surfaces a yellow `update: X.Y.Z` on the right side
|
|
156
|
+
of the same row when a newer version has been published. No blocking,
|
|
157
|
+
no nagging — the check runs once per day max and is silent on failure
|
|
158
|
+
(offline, firewall, etc.).
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
reasonix update # print current vs latest, run `npm i -g reasonix@latest`
|
|
162
|
+
reasonix update --dry-run # print the plan without running anything
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Running via `npx`? The command detects that and prints a
|
|
166
|
+
cache-refresh hint instead — npx picks up the newest version on
|
|
167
|
+
its next invocation automatically.
|
|
193
168
|
|
|
194
|
-
### Project
|
|
169
|
+
### Project conventions — `REASONIX.md`
|
|
195
170
|
|
|
196
171
|
Drop a `REASONIX.md` in the project root and its contents are pinned
|
|
197
|
-
into the
|
|
198
|
-
|
|
199
|
-
glossary, or things the model keeps forgetting:
|
|
172
|
+
into the system prompt every launch. Committable team memory — house
|
|
173
|
+
conventions, domain glossary, things the model keeps forgetting:
|
|
200
174
|
|
|
201
175
|
```bash
|
|
202
176
|
cat > REASONIX.md <<'EOF'
|
|
@@ -210,7 +184,7 @@ EOF
|
|
|
210
184
|
Re-launch (or `/new`) to pick it up; the prefix is hashed once per
|
|
211
185
|
session to keep the DeepSeek cache warm. `/memory` prints what's
|
|
212
186
|
currently pinned. `REASONIX_MEMORY=off` disables every memory source
|
|
213
|
-
|
|
187
|
+
for CI / offline repro.
|
|
214
188
|
|
|
215
189
|
### User memory — `~/.reasonix/memory/`
|
|
216
190
|
|
|
@@ -218,15 +192,16 @@ A second, **private per-user** memory layer lives under your home
|
|
|
218
192
|
directory. Unlike `REASONIX.md` it's never committed, and the model
|
|
219
193
|
can write to it itself via the `remember` tool. Two scopes:
|
|
220
194
|
|
|
221
|
-
- `~/.reasonix/memory/global/` — cross-project (your preferences,
|
|
222
|
-
|
|
223
|
-
|
|
195
|
+
- `~/.reasonix/memory/global/` — cross-project (your preferences,
|
|
196
|
+
tooling).
|
|
197
|
+
- `~/.reasonix/memory/<project-hash>/` — scoped to one sandbox root
|
|
198
|
+
in `reasonix code` (decisions, local facts, per-repo shortcuts).
|
|
224
199
|
|
|
225
|
-
Each scope keeps an always-loaded `MEMORY.md` index of one-liners
|
|
226
|
-
zero or more `<name>.md` detail files (loaded on demand via
|
|
200
|
+
Each scope keeps an always-loaded `MEMORY.md` index of one-liners
|
|
201
|
+
plus zero or more `<name>.md` detail files (loaded on demand via
|
|
227
202
|
`recall_memory`). Writes land immediately; pinning into the system
|
|
228
|
-
prompt takes effect on next `/new` or launch so the cache prefix
|
|
229
|
-
stable for the current session.
|
|
203
|
+
prompt takes effect on next `/new` or launch so the cache prefix
|
|
204
|
+
stays stable for the current session.
|
|
230
205
|
|
|
231
206
|
```
|
|
232
207
|
reasonix code › 我用 bun 而不是 npm,请以后都用 bun 跑构建
|
|
@@ -234,142 +209,201 @@ reasonix code › 我用 bun 而不是 npm,请以后都用 bun 跑构建
|
|
|
234
209
|
assistant
|
|
235
210
|
▸ tool<remember> → project/bun_build saved
|
|
236
211
|
"Build command on this machine is `bun run build`"
|
|
237
|
-
|
|
238
|
-
reasonix code › /memory list
|
|
239
|
-
project/project bun_build Build command on this machine is `bun run build`
|
|
240
212
|
```
|
|
241
213
|
|
|
242
|
-
**Slash
|
|
214
|
+
**Slash**: `/memory` · `/memory list` · `/memory show <name>` ·
|
|
215
|
+
`/memory forget <name>` · `/memory clear <scope> confirm`.
|
|
216
|
+
**Model tools**: `remember(type, scope, name, description, content)` ·
|
|
217
|
+
`forget(scope, name)` · `recall_memory(scope, name)`.
|
|
243
218
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
- `/memory show <name>` — dump one file's full body
|
|
247
|
-
- `/memory forget <name>` — delete one memory (no LLM turn)
|
|
248
|
-
- `/memory clear <global|project> confirm` — wipe a scope (typed literal)
|
|
219
|
+
Project scope is only available inside `reasonix code` (needs a real
|
|
220
|
+
sandbox root to hash); plain `reasonix` gets the global scope only.
|
|
249
221
|
|
|
250
|
-
|
|
222
|
+
### Skills — user-authored prompt packs
|
|
251
223
|
|
|
252
|
-
|
|
253
|
-
-
|
|
254
|
-
|
|
224
|
+
Skills are prose instruction blocks you drop on disk. Reasonix pins
|
|
225
|
+
their names + one-line descriptions into the system prompt; the
|
|
226
|
+
model can call `run_skill({name: "..."})` on its own when a match
|
|
227
|
+
fits, or you can type `/skill <name> [args]` to run one manually.
|
|
255
228
|
|
|
256
|
-
|
|
257
|
-
a real sandbox root to hash); plain `reasonix` / `reasonix chat` gets
|
|
258
|
-
the global scope only.
|
|
229
|
+
Two scopes, same layout as user memory:
|
|
259
230
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
231
|
+
- `<project>/.reasonix/skills/` — per-project skills (commit them to
|
|
232
|
+
share with your team, or add to `.gitignore` for personal drafts).
|
|
233
|
+
- `~/.reasonix/skills/` — global skills available everywhere.
|
|
234
|
+
|
|
235
|
+
Either layout works: `<name>/SKILL.md` (preferred — can bundle
|
|
236
|
+
additional assets alongside) or flat `<name>.md`.
|
|
265
237
|
|
|
238
|
+
```markdown
|
|
239
|
+
---
|
|
240
|
+
name: review
|
|
241
|
+
description: Review uncommitted changes and flag risks
|
|
266
242
|
---
|
|
267
243
|
|
|
268
|
-
|
|
244
|
+
Run `git diff` on staged and unstaged changes. Summarize what each
|
|
245
|
+
hunk does, call out potential regressions, and list files that might
|
|
246
|
+
need additional tests. Don't propose edits unless I ask.
|
|
247
|
+
```
|
|
269
248
|
|
|
270
|
-
|
|
271
|
-
drafting, Q&A, schema design, architecture discussions, or driving
|
|
272
|
-
your own MCP servers. Sessions persist per name under
|
|
273
|
-
`~/.reasonix/sessions/`.
|
|
249
|
+
Use it:
|
|
274
250
|
|
|
275
|
-
```bash
|
|
276
|
-
npx reasonix # uses saved config + wizard-selected MCP
|
|
277
|
-
npx reasonix --preset smart # one-shot override
|
|
278
|
-
npx reasonix --session design # named session
|
|
279
|
-
npx reasonix --session design # resume it later — history intact
|
|
280
251
|
```
|
|
252
|
+
reasonix code › /skill review
|
|
253
|
+
▸ running skill: review
|
|
254
|
+
assistant
|
|
255
|
+
▸ tool<run_command> → git diff --cached
|
|
256
|
+
▸ 3 改动,1 个需要回归测试 …
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
Or let the model pick autonomously — because the skill's name +
|
|
260
|
+
description are pinned in the prefix, asking "帮我看下未提交的改动有没
|
|
261
|
+
有风险" triggers `run_skill({name: "review"})` without you typing the
|
|
262
|
+
slash command.
|
|
263
|
+
|
|
264
|
+
**Slash**: `/skill` (list) · `/skill show <name>` · `/skill <name>
|
|
265
|
+
[args]` (inject body as user turn).
|
|
266
|
+
|
|
267
|
+
**Deliberately not tied** to any other client's directory convention
|
|
268
|
+
(`.claude/skills`, etc.) — Reasonix is model-agnostic at the
|
|
269
|
+
conversation layer. Any SKILL.md you author works; the body is
|
|
270
|
+
prose, so skills authored for other tools usually port over unchanged
|
|
271
|
+
(Reasonix's tool names differ — `filesystem` / `shell` / `web` — but
|
|
272
|
+
the model reads the instructions and picks our equivalents).
|
|
281
273
|
|
|
282
|
-
###
|
|
274
|
+
### Hooks — automate around tool calls and turns
|
|
283
275
|
|
|
276
|
+
Drop a `settings.json` under `.reasonix/` (project or `~/`) and
|
|
277
|
+
Reasonix will fire shell commands at four well-known points in
|
|
278
|
+
the loop: before a tool runs, after a tool returns, before your
|
|
279
|
+
prompt reaches the model, and after the turn ends.
|
|
280
|
+
|
|
281
|
+
```json
|
|
282
|
+
// <project>/.reasonix/settings.json ← committable
|
|
283
|
+
// ~/.reasonix/settings.json ← per-user
|
|
284
|
+
{
|
|
285
|
+
"hooks": {
|
|
286
|
+
"PreToolUse": [{ "match": "edit_file|write_file", "command": "bun scripts/guard.ts" }],
|
|
287
|
+
"PostToolUse": [{ "match": "edit_file", "command": "biome format --write" }],
|
|
288
|
+
"UserPromptSubmit": [{ "command": "echo $(date +%s) >> ~/.reasonix/prompts.log" }],
|
|
289
|
+
"Stop": [{ "command": "bun test --run", "timeout": 60000 }]
|
|
290
|
+
}
|
|
291
|
+
}
|
|
284
292
|
```
|
|
285
|
-
reasonix › /preset smart
|
|
286
|
-
▸ switched to smart · model deepseek-reasoner · harvest on · branch off
|
|
287
293
|
|
|
288
|
-
|
|
289
|
-
|
|
294
|
+
Each hook is a shell command. Reasonix invokes it with stdin = a
|
|
295
|
+
JSON envelope describing the event:
|
|
290
296
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
‹ hypotheses (2): SharedPreferences 存计数 · lastShownAt 时间戳
|
|
295
|
-
‹ uncertainties (1): 用户换设备后重置的策略
|
|
296
|
-
|
|
297
|
-
建议数据模型:
|
|
298
|
-
lastShownAt: DateTime
|
|
299
|
-
consecutiveShows: int (0..3)
|
|
300
|
-
sleepUntil: DateTime?
|
|
301
|
-
…
|
|
297
|
+
```json
|
|
298
|
+
{ "event": "PreToolUse", "cwd": "/path/to/project",
|
|
299
|
+
"toolName": "edit_file", "toolArgs": { "path": "src/x.ts", "..." } }
|
|
302
300
|
```
|
|
303
301
|
|
|
304
|
-
|
|
305
|
-
model / flags / context use; `/retry` re-samples the same prompt with
|
|
306
|
-
a fresh random seed (useful when the first answer missed something).
|
|
302
|
+
Exit code drives the decision:
|
|
307
303
|
|
|
308
|
-
|
|
304
|
+
- **0** — pass; loop continues normally
|
|
305
|
+
- **2** — block (only on `PreToolUse` / `UserPromptSubmit`); the
|
|
306
|
+
hook's stderr becomes the synthetic tool result the model sees,
|
|
307
|
+
or the prompt is dropped entirely
|
|
308
|
+
- **anything else** — warn; loop continues, stderr renders as a
|
|
309
|
+
yellow row inline
|
|
309
310
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
--mcp "fs=npx -y @modelcontextprotocol/server-filesystem /tmp/scratch" \
|
|
315
|
-
--mcp "kb=https://mcp.example.com/sse"
|
|
316
|
-
```
|
|
311
|
+
`match` is anchored regex on the tool name; `*` or omitted matches
|
|
312
|
+
every tool. Project hooks fire before global hooks. Default
|
|
313
|
+
timeouts: 5s for blocking events, 30s for logging events; per-hook
|
|
314
|
+
`timeout` overrides.
|
|
317
315
|
|
|
318
|
-
|
|
316
|
+
**Slash**: `/hooks` (list active hooks) · `/hooks reload` (re-read
|
|
317
|
+
`settings.json` from disk without losing your session).
|
|
319
318
|
|
|
320
|
-
|
|
321
|
-
reasonix › /mcp
|
|
322
|
-
▸ fs (stdio, 11 tools) fs_read_file · fs_list_directory · fs_write_file · …
|
|
323
|
-
▸ kb (sse, 4 tools) kb_search · kb_get · kb_list_collections · kb_stat
|
|
319
|
+
### Staying current from inside the TUI
|
|
324
320
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
321
|
+
`/update` inside a running session shows your current version, the
|
|
322
|
+
last-resolved latest version (from the quiet 24h background check),
|
|
323
|
+
and the shell command to run. The slash does *not* spawn
|
|
324
|
+
`npm install` — stdio:inherit into a running Ink renderer corrupts
|
|
325
|
+
the display. Exit the session and run `reasonix update` in a
|
|
326
|
+
fresh shell when you actually want to install.
|
|
327
|
+
|
|
328
|
+
---
|
|
329
|
+
|
|
330
|
+
## `reasonix` — also works as general chat
|
|
331
|
+
|
|
332
|
+
Same TUI, no filesystem tools unless you opt in via MCP. Good for
|
|
333
|
+
drafting, Q&A, schema design, architecture discussions, or driving
|
|
334
|
+
your own MCP servers. Sessions persist per name under
|
|
335
|
+
`~/.reasonix/sessions/`.
|
|
336
|
+
|
|
337
|
+
```bash
|
|
338
|
+
npx reasonix # uses saved config + wizard-selected MCP
|
|
339
|
+
npx reasonix --preset smart # reasoner + R1 harvest for this run
|
|
340
|
+
npx reasonix --session design # named session — resume later with --session design
|
|
331
341
|
```
|
|
332
342
|
|
|
333
|
-
|
|
334
|
-
plumbing as native tools, including the 32k result cap and live
|
|
335
|
-
progress-notification rendering.
|
|
343
|
+
Bridge your own MCP servers on the fly:
|
|
336
344
|
|
|
337
|
-
|
|
345
|
+
```bash
|
|
346
|
+
npx reasonix \
|
|
347
|
+
--mcp "fs=npx -y @modelcontextprotocol/server-filesystem /tmp/safe" \
|
|
348
|
+
--mcp "kb=https://mcp.example.com/sse"
|
|
349
|
+
```
|
|
338
350
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
| Exploring a project without writing files | `reasonix code` (it only writes on `/apply`) |
|
|
343
|
-
| Design / architecture / research chat | `reasonix` |
|
|
344
|
-
| Driving your own MCP servers | `reasonix --mcp "..."` |
|
|
345
|
-
| One-shot question, no TUI | `reasonix run "..."` |
|
|
346
|
-
| Reproducing a prior session / benchmark | `reasonix replay path.jsonl` |
|
|
351
|
+
MCP tools go through the same Cache-First + repair + context-safety
|
|
352
|
+
plumbing as native tools — 32k result cap, live progress-notification
|
|
353
|
+
rendering, retries.
|
|
347
354
|
|
|
348
355
|
---
|
|
349
356
|
|
|
350
357
|
## Commands inside the session
|
|
351
358
|
|
|
359
|
+
**Core**
|
|
360
|
+
|
|
352
361
|
| command | what it does |
|
|
353
362
|
|---|---|
|
|
354
|
-
| `/help` | full command reference with hints |
|
|
363
|
+
| `/help` · `/?` | full command reference with hints |
|
|
355
364
|
| `/status` | current model · flags · context · session |
|
|
365
|
+
| `/new` · `/reset` | fresh conversation in the same session |
|
|
366
|
+
| `/clear` | clear visible scrollback only (log kept) |
|
|
367
|
+
| `/retry` | truncate and resend your last message (fresh sample) |
|
|
368
|
+
| `/exit` · `/quit` | quit |
|
|
369
|
+
|
|
370
|
+
**Model**
|
|
371
|
+
|
|
372
|
+
| command | what it does |
|
|
373
|
+
|---|---|
|
|
356
374
|
| `/preset <fast\|smart\|max>` | one-tap bundle (model + harvest + branch) |
|
|
357
375
|
| `/model <id>` | switch DeepSeek model (`deepseek-chat`, `deepseek-reasoner`) |
|
|
358
376
|
| `/harvest [on\|off]` | toggle R1 plan-state extraction |
|
|
359
377
|
| `/branch <N\|off>` | run N parallel samples per turn, pick best (N ≥ 2) |
|
|
378
|
+
| `/think` | dump the last turn's full R1 reasoning |
|
|
379
|
+
|
|
380
|
+
**Context & tools**
|
|
381
|
+
|
|
382
|
+
| command | what it does |
|
|
383
|
+
|---|---|
|
|
360
384
|
| `/mcp` | list attached MCP servers and their tools |
|
|
361
385
|
| `/tool [N]` | dump the Nth tool call's full output (1 = latest) |
|
|
362
|
-
| `/think` | dump the last turn's full R1 reasoning |
|
|
363
|
-
| `/retry` | truncate and resend your last message (fresh sample) |
|
|
364
386
|
| `/compact [cap]` | shrink oversized tool results in the log |
|
|
387
|
+
|
|
388
|
+
**Memory & skills**
|
|
389
|
+
|
|
390
|
+
| command | what it does |
|
|
391
|
+
|---|---|
|
|
392
|
+
| `/memory` | show pinned memory (REASONIX.md + ~/.reasonix/memory) |
|
|
393
|
+
| `/memory list` · `show <name>` · `forget <name>` · `clear <scope> confirm` | manage the store |
|
|
394
|
+
| `/skill` · `/skill list` | list discovered skills (project + global) |
|
|
395
|
+
| `/skill show <name>` | dump one skill's body |
|
|
396
|
+
| `/skill <name> [args]` | run a skill (inject body as user turn) |
|
|
397
|
+
|
|
398
|
+
**Sessions**
|
|
399
|
+
|
|
400
|
+
| command | what it does |
|
|
401
|
+
|---|---|
|
|
365
402
|
| `/sessions` | list saved sessions (current marked with `▸`) |
|
|
366
403
|
| `/forget` | delete the current session from disk |
|
|
367
|
-
| `/new` (alias `/reset`) | start a fresh conversation in the same session |
|
|
368
|
-
| `/clear` | clear visible scrollback only (log kept) |
|
|
369
404
|
| `/setup` | reconfigure (exit and run `reasonix setup`) |
|
|
370
|
-
| `/exit` | quit |
|
|
371
405
|
|
|
372
|
-
|
|
406
|
+
**Code mode only** (`reasonix code`)
|
|
373
407
|
|
|
374
408
|
| command | what it does |
|
|
375
409
|
|---|---|
|
|
@@ -377,32 +411,36 @@ Additional commands in `reasonix code`:
|
|
|
377
411
|
| `/discard` | drop the pending edit blocks without writing |
|
|
378
412
|
| `/undo` | roll back the last applied edit batch |
|
|
379
413
|
| `/commit "msg"` | `git add -A && git commit -m "msg"` |
|
|
414
|
+
| `/plan [on\|off]` | toggle read-only plan mode |
|
|
415
|
+
| `/apply-plan` | force-approve a pending plan |
|
|
380
416
|
|
|
381
|
-
**Keyboard
|
|
417
|
+
**Keyboard**
|
|
382
418
|
|
|
383
419
|
- `Enter` — submit
|
|
384
|
-
- `Shift+Enter` / `Ctrl+J` — newline (multi-line paste also supported;
|
|
385
|
-
|
|
420
|
+
- `Shift+Enter` / `Ctrl+J` — newline (multi-line paste also supported;
|
|
421
|
+
`\` + Enter as a portable fallback)
|
|
422
|
+
- `↑` / `↓` — walk prompt history while idle; navigate slash-autocomplete
|
|
386
423
|
- `Tab` / `Enter` on a `/foo` prefix — accept the highlighted suggestion
|
|
387
|
-
- `Esc` — abort the current turn (stops the API call, cancels any
|
|
424
|
+
- `Esc` — abort the current turn (stops the API call, cancels any
|
|
425
|
+
in-flight tool, rejects pending MCP requests)
|
|
388
426
|
- `y` / `n` on confirm prompts — hotkey accept / reject
|
|
389
427
|
|
|
390
428
|
---
|
|
391
429
|
|
|
392
430
|
## Sessions and safety nets
|
|
393
431
|
|
|
394
|
-
- Sessions live as JSONL under `~/.reasonix/sessions/<name>.jsonl`
|
|
395
|
-
directory for `reasonix code`). Every message appended
|
|
396
|
-
never loses context.
|
|
432
|
+
- Sessions live as JSONL under `~/.reasonix/sessions/<name>.jsonl`
|
|
433
|
+
(per directory for `reasonix code`). Every message appended
|
|
434
|
+
atomically; `Ctrl+C` never loses context.
|
|
397
435
|
- Tool results are capped at 32k chars per call. Oversized sessions
|
|
398
436
|
self-heal on load (shrinks + rewrites the file).
|
|
399
437
|
- Malformed `assistant.tool_calls` / `tool` pairing is validated on
|
|
400
438
|
every outgoing API call so a corrupted session can't keep 400ing.
|
|
401
|
-
- Context gauge turns yellow at 50%, red at 80% with a `/compact`
|
|
402
|
-
Approaching the 131k window triggers an automatic
|
|
403
|
-
before falling back to a forced summary.
|
|
404
|
-
- The
|
|
405
|
-
|
|
439
|
+
- Context gauge turns yellow at 50%, red at 80% with a `/compact`
|
|
440
|
+
nudge. Approaching the 131k window triggers an automatic
|
|
441
|
+
compaction attempt before falling back to a forced summary.
|
|
442
|
+
- The `reasonix code` sandbox refuses any path that resolves outside
|
|
443
|
+
the launch directory, including symlink escape and `..` traversal.
|
|
406
444
|
|
|
407
445
|
### Troubleshooting: duplicate rows / ghost rendering
|
|
408
446
|
|
|
@@ -416,18 +454,12 @@ If you hit this, run with plain mode:
|
|
|
416
454
|
|
|
417
455
|
```bash
|
|
418
456
|
REASONIX_UI=plain npx reasonix code
|
|
419
|
-
# or
|
|
420
|
-
REASONIX_UI=plain npx reasonix
|
|
421
457
|
```
|
|
422
458
|
|
|
423
|
-
Plain mode suppresses
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
Ink's `<Static>` append path.
|
|
428
|
-
|
|
429
|
-
Windows Terminal, PowerShell 7 in Windows Terminal, and WezTerm
|
|
430
|
-
don't need this opt-out.
|
|
459
|
+
Plain mode suppresses live/animated rows and disables the internal
|
|
460
|
+
tick timer. You lose the streaming preview and spinners but gain
|
|
461
|
+
stable scrollback. Windows Terminal, PowerShell 7 in Windows
|
|
462
|
+
Terminal, and WezTerm don't need this opt-out.
|
|
431
463
|
|
|
432
464
|
---
|
|
433
465
|
|
|
@@ -439,19 +471,11 @@ something the model wasn't trained on (new releases, current events,
|
|
|
439
471
|
obscure APIs), it decides to call `web_search` on its own; if a
|
|
440
472
|
snippet isn't enough it follows up with `web_fetch`.
|
|
441
473
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
▸ 3.19 主要新增了 …
|
|
448
|
-
```
|
|
449
|
-
|
|
450
|
-
Backed by **Mojeek**'s public search page — an independent web index,
|
|
451
|
-
no API key, no signup, bot-friendly. Coverage on niche or very recent
|
|
452
|
-
queries can be thinner than Google/Bing, but it's reliable from
|
|
453
|
-
scripts and doesn't gate on cookies or sessions. (DDG was the original
|
|
454
|
-
backend but it started serving anti-bot pages in 2026.)
|
|
474
|
+
Backed by **Mojeek**'s public search page — an independent web
|
|
475
|
+
index, bot-friendly, no cookies/sessions. Coverage on niche or very
|
|
476
|
+
recent queries can be thinner than Google/Bing, but it's reliable
|
|
477
|
+
from scripts. (DDG was the original backend but started serving
|
|
478
|
+
anti-bot pages in 2026.)
|
|
455
479
|
|
|
456
480
|
**Turn it off** (offline mode / privacy / CI):
|
|
457
481
|
|
|
@@ -461,37 +485,11 @@ backend but it started serving anti-bot pages in 2026.)
|
|
|
461
485
|
```
|
|
462
486
|
|
|
463
487
|
```bash
|
|
464
|
-
|
|
465
|
-
REASONIX_SEARCH=off npx reasonix
|
|
488
|
+
REASONIX_SEARCH=off npx reasonix code
|
|
466
489
|
```
|
|
467
490
|
|
|
468
|
-
**Bring your own
|
|
469
|
-
|
|
470
|
-
manually:
|
|
471
|
-
|
|
472
|
-
```ts
|
|
473
|
-
import { ToolRegistry } from "reasonix";
|
|
474
|
-
// Register your own `web_search` / `web_fetch` on a ToolRegistry,
|
|
475
|
-
// then pass it to CacheFirstLoop (or `reasonix chat --no-config`
|
|
476
|
-
// with seedTools via library API).
|
|
477
|
-
```
|
|
478
|
-
|
|
479
|
-
Inside the session:
|
|
480
|
-
|
|
481
|
-
```
|
|
482
|
-
reasonix › Flutter 3.19 引入了什么新的 Navigator API?
|
|
483
|
-
assistant
|
|
484
|
-
▸ tool<web_search> → query: "Flutter 3.19 new Navigator API"
|
|
485
|
-
answer: Flutter 3.19 introduces the NavigatorObserver changes …
|
|
486
|
-
1. Flutter 3.19 Release Notes — https://docs.flutter.dev/…
|
|
487
|
-
2. What's new in Flutter 3.19 — https://medium.com/…
|
|
488
|
-
▸ tool<web_fetch> → https://docs.flutter.dev/release/release-notes/3-19-0
|
|
489
|
-
(full page text, clipped at 32k)
|
|
490
|
-
▸ 3.19 新增了 …
|
|
491
|
-
```
|
|
492
|
-
|
|
493
|
-
For advanced / self-hosted search (Kagi, SearXNG, internal caches)
|
|
494
|
-
implement the `WebSearchProvider` interface and call
|
|
491
|
+
**Bring your own** (Kagi, SearXNG, internal caches): implement the
|
|
492
|
+
`WebSearchProvider` interface and call
|
|
495
493
|
`registerWebTools(registry, { provider })` yourself, or bridge an
|
|
496
494
|
existing MCP search server via `--mcp`.
|
|
497
495
|
|
|
@@ -499,14 +497,14 @@ existing MCP search server via `--mcp`.
|
|
|
499
497
|
|
|
500
498
|
## MCP — bring your own tools
|
|
501
499
|
|
|
502
|
-
Any [MCP](https://spec.modelcontextprotocol.io/) server works.
|
|
503
|
-
lets you pick from a catalog, or drive it by flag:
|
|
500
|
+
Any [MCP](https://spec.modelcontextprotocol.io/) server works. The
|
|
501
|
+
wizard lets you pick from a catalog, or drive it by flag:
|
|
504
502
|
|
|
505
503
|
```bash
|
|
506
504
|
# stdio (local subprocess)
|
|
507
505
|
npx reasonix --mcp "fs=npx -y @modelcontextprotocol/server-filesystem /tmp/safe"
|
|
508
506
|
|
|
509
|
-
# multiple
|
|
507
|
+
# multiple at once
|
|
510
508
|
npx reasonix \
|
|
511
509
|
--mcp "fs=npx -y @modelcontextprotocol/server-filesystem /tmp/safe" \
|
|
512
510
|
--mcp "demo=npx tsx examples/mcp-server-demo.ts"
|
|
@@ -515,21 +513,22 @@ npx reasonix \
|
|
|
515
513
|
npx reasonix --mcp "kb=https://mcp.example.com/sse"
|
|
516
514
|
```
|
|
517
515
|
|
|
518
|
-
`reasonix mcp list` shows the curated catalog. `reasonix mcp inspect
|
|
519
|
-
connects once and dumps the server's tools / resources /
|
|
520
|
-
starting a chat. Progress notifications from
|
|
521
|
-
spec) render live as a progress bar
|
|
516
|
+
`reasonix mcp list` shows the curated catalog. `reasonix mcp inspect
|
|
517
|
+
<spec>` connects once and dumps the server's tools / resources /
|
|
518
|
+
prompts without starting a chat. Progress notifications from
|
|
519
|
+
long-running tools (2025-03-26 spec) render live as a progress bar
|
|
520
|
+
in the spinner.
|
|
522
521
|
|
|
523
|
-
Supported transports: **stdio** (local command) and **HTTP+SSE**
|
|
524
|
-
MCP 2024-11-05 spec).
|
|
522
|
+
Supported transports: **stdio** (local command) and **HTTP+SSE**
|
|
523
|
+
(remote, MCP 2024-11-05 spec).
|
|
525
524
|
|
|
526
525
|
---
|
|
527
526
|
|
|
528
527
|
## CLI reference
|
|
529
528
|
|
|
530
529
|
```bash
|
|
531
|
-
npx reasonix # chat (uses saved config)
|
|
532
530
|
npx reasonix code [path] # coding mode scoped to path (default: cwd)
|
|
531
|
+
npx reasonix # chat (uses saved config)
|
|
533
532
|
npx reasonix setup # reconfigure the wizard
|
|
534
533
|
npx reasonix chat --session work # named session
|
|
535
534
|
npx reasonix chat --no-session # ephemeral
|
|
@@ -561,6 +560,9 @@ Env vars (win over config):
|
|
|
561
560
|
```bash
|
|
562
561
|
export DEEPSEEK_API_KEY=sk-...
|
|
563
562
|
export DEEPSEEK_BASE_URL=https://... # optional alternate endpoint
|
|
563
|
+
export REASONIX_MEMORY=off # disable REASONIX.md + user memory
|
|
564
|
+
export REASONIX_SEARCH=off # disable web_search / web_fetch
|
|
565
|
+
export REASONIX_UI=plain # disable live rows (ghosting workaround)
|
|
564
566
|
```
|
|
565
567
|
|
|
566
568
|
---
|
|
@@ -606,13 +608,14 @@ for await (const ev of loop.step("What is 17 + 25?")) {
|
|
|
606
608
|
console.log(loop.stats.summary());
|
|
607
609
|
```
|
|
608
610
|
|
|
609
|
-
`ChatOptions.seedTools` accepts a pre-built `ToolRegistry` for
|
|
610
|
-
who want the `reasonix code` loop wiring without the CLI
|
|
611
|
-
See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for
|
|
611
|
+
`ChatOptions.seedTools` accepts a pre-built `ToolRegistry` for
|
|
612
|
+
callers who want the `reasonix code` loop wiring without the CLI
|
|
613
|
+
wrapper. See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for
|
|
614
|
+
internals.
|
|
612
615
|
|
|
613
616
|
---
|
|
614
617
|
|
|
615
|
-
##
|
|
618
|
+
## Benchmarks — verify the cache-hit claim yourself
|
|
616
619
|
|
|
617
620
|
Every abstraction here earns its weight against a DeepSeek-specific
|
|
618
621
|
property — dirt-cheap tokens, R1 reasoning traces, automatic prefix
|
|
@@ -626,11 +629,10 @@ caching, JSON mode. Generic wrappers leave these on the table.
|
|
|
626
629
|
| Scavenge tool calls leaked into `<think>` | yes | no |
|
|
627
630
|
| Call-storm breaker on identical-arg repeats | yes | no |
|
|
628
631
|
| Live cache-hit / cost / vs-Claude panel | yes | no |
|
|
629
|
-
| First-run config prompt + Markdown TUI | yes | no |
|
|
630
632
|
|
|
631
633
|
On the same τ-bench-lite workload — 8 multi-turn tool-use tasks × 3
|
|
632
|
-
repeats = 48 runs per side, live DeepSeek `deepseek-chat`, sole
|
|
633
|
-
prefix stability:
|
|
634
|
+
repeats = 48 runs per side, live DeepSeek `deepseek-chat`, sole
|
|
635
|
+
variable prefix stability:
|
|
634
636
|
|
|
635
637
|
| metric | baseline (cache-hostile) | Reasonix | delta |
|
|
636
638
|
|---|---:|---:|---:|
|
|
@@ -638,7 +640,7 @@ prefix stability:
|
|
|
638
640
|
| cost / task | $0.002599 | $0.001579 | **−39%** |
|
|
639
641
|
| pass rate | 96% (23/24) | **100% (24/24)** | — |
|
|
640
642
|
|
|
641
|
-
**
|
|
643
|
+
**Reproduce without spending an API credit:**
|
|
642
644
|
|
|
643
645
|
```bash
|
|
644
646
|
git clone https://github.com/esengine/reasonix.git && cd reasonix && npm install
|
|
@@ -654,8 +656,10 @@ model call; baseline's churns on every turn. The cache delta is
|
|
|
654
656
|
*mechanically* attributable to log stability, not to a different
|
|
655
657
|
system prompt.
|
|
656
658
|
|
|
657
|
-
Full 48-run report:
|
|
658
|
-
|
|
659
|
+
Full 48-run report:
|
|
660
|
+
[`benchmarks/tau-bench/report.md`](./benchmarks/tau-bench/report.md).
|
|
661
|
+
Reproduce with your own API key: `npx tsx
|
|
662
|
+
benchmarks/tau-bench/runner.ts --repeats 3`.
|
|
659
663
|
|
|
660
664
|
MCP reference runs (one single prefix hash across all 5 turns even
|
|
661
665
|
with two concurrent MCP subprocesses):
|
|
@@ -670,10 +674,16 @@ with two concurrent MCP subprocesses):
|
|
|
670
674
|
|
|
671
675
|
## Non-goals
|
|
672
676
|
|
|
673
|
-
- Multi-agent orchestration (use LangGraph).
|
|
674
|
-
-
|
|
675
|
-
|
|
676
|
-
-
|
|
677
|
+
- **Multi-agent orchestration / sub-agents** (use LangGraph).
|
|
678
|
+
- **Workflow DSL / DAG scheduler / parallel-branch engine** — skills
|
|
679
|
+
are prose; the model sequences via the normal tool-use loop.
|
|
680
|
+
Keeps single-loop + append-only + cache-first invariants intact.
|
|
681
|
+
- **Multi-provider abstraction** (use LiteLLM). Reasonix is
|
|
682
|
+
DeepSeek-only on purpose — every pillar (cache-first loop, R1
|
|
683
|
+
harvesting, tool-call repair) is tuned against DeepSeek-specific
|
|
684
|
+
behavior and economics. Coupling to one backend is the feature.
|
|
685
|
+
- **RAG / vector stores** (use LlamaIndex).
|
|
686
|
+
- **Web UI / SaaS.**
|
|
677
687
|
|
|
678
688
|
Reasonix does DeepSeek, deeply.
|
|
679
689
|
|
|
@@ -685,9 +695,9 @@ Reasonix does DeepSeek, deeply.
|
|
|
685
695
|
git clone https://github.com/esengine/reasonix.git
|
|
686
696
|
cd reasonix
|
|
687
697
|
npm install
|
|
688
|
-
npm run dev
|
|
698
|
+
npm run dev code # run CLI from source via tsx
|
|
689
699
|
npm run build # tsup to dist/
|
|
690
|
-
npm test # vitest (
|
|
700
|
+
npm test # vitest (648 tests)
|
|
691
701
|
npm run lint # biome
|
|
692
702
|
npm run typecheck # tsc --noEmit
|
|
693
703
|
```
|