@xingjisoft/neutrino 0.3.0 → 0.4.1

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.
Files changed (56) hide show
  1. package/README.md +33 -549
  2. package/assets/neutrino.ico +0 -0
  3. package/assets/neutrino.svg +7 -0
  4. package/assets/pro/backend_output_model.txt +5 -0
  5. package/assets/pro/claude-module-prompt.txt +65 -0
  6. package/assets/pro/common.txt +9 -0
  7. package/assets/pro/confirm_model.txt +5 -0
  8. package/assets/pro/front_output_model.txt +9 -0
  9. package/assets/pro/genimage_model.txt +1 -0
  10. package/assets/pro/main_model.txt +5 -0
  11. package/assets/pro/model-template.json +376 -0
  12. package/assets/pro/modeling_model.txt +5 -0
  13. package/assets/pro/plan_model.txt +8 -0
  14. package/assets/pro/thinking_model.txt +3 -0
  15. package/dist/agents.js +22 -3
  16. package/dist/app.js +199 -26
  17. package/dist/background.js +358 -0
  18. package/dist/bin.js +184 -44
  19. package/dist/browser.js +57 -0
  20. package/dist/config.js +174 -26
  21. package/dist/header.js +2 -1
  22. package/dist/index.js +1 -1
  23. package/dist/llm/approval.js +6 -2
  24. package/dist/llm/client.js +197 -28
  25. package/dist/llm/subagent.js +37 -1
  26. package/dist/llm/tools.js +3 -1
  27. package/dist/migration.js +33 -0
  28. package/dist/pro/agents.js +104 -0
  29. package/dist/pro/config.js +88 -0
  30. package/dist/pro/preflight.js +172 -0
  31. package/dist/screens/agentConversation.js +48 -5
  32. package/dist/screens/agentHistory.js +4 -2
  33. package/dist/screens/chat.js +14 -8
  34. package/dist/screens/modelSelect.js +15 -4
  35. package/dist/screens/settings.js +52 -9
  36. package/dist/screens/start.js +48 -15
  37. package/dist/state.js +1 -0
  38. package/dist/terminal/restore.js +3 -12
  39. package/dist/tray.js +138 -0
  40. package/dist/ui.js +58 -0
  41. package/dist/web/hub.js +26 -4
  42. package/dist/web/server.js +495 -74
  43. package/dist/web/service.js +135 -0
  44. package/dist/web/session.js +278 -25
  45. package/dist/web/settings.js +97 -24
  46. package/dist/web/terminalBridge.js +250 -0
  47. package/package.json +37 -37
  48. package/web/README.md +150 -16
  49. package/web/app.js +490 -25
  50. package/web/i18n.js +396 -345
  51. package/web/index.html +120 -15
  52. package/web/neutrino-pro.gif +0 -0
  53. package/web/neutrino.png +0 -0
  54. package/web/pro.js +184 -0
  55. package/web/settings.js +373 -247
  56. package/web/style.css +398 -0
package/README.md CHANGED
@@ -1,568 +1,52 @@
1
1
  # XINGJI Neutrino
2
2
 
3
- A CLI coding agent that lives in your terminal. Neutrino gives you an interactive chat interface backed by LLMs, with built-in tool use (running commands, reading and writing files) so it can help you work on real projects.
3
+ ↓ 详细内容点这里 Learn More ↓
4
4
 
5
- ## Features
5
+ [English](./README-en.md) | [简体中文](./README-en.md)
6
6
 
7
- - **Interactive terminal UI** — logo screen, chat, model select, history, and settings screens.
8
- - **Full mouse support** — hover to highlight, click to select/open/position the cursor, wheel to scroll, right-click to go back (like OpenCode).
9
- - **Select & copy** — drag the mouse over any text (agent output, the input box, menus, …) to select it; releasing the button copies the selection to the clipboard (via OSC 52, with a native fallback). Holding the drag against the top or bottom edge of the log scrolls it, so one selection can run for as long as the whole conversation.
10
- - **Paste-friendly input** — like OpenCode, a pasted block has its newlines turned into spaces so it stays one line, and only a manually typed `Enter` submits the message.
11
- - **Faithful log rendering** — text in the chat log keeps its indentation, blank lines and column alignment; when a long tool-output line wraps, continuation lines stay indented instead of snapping back to the left margin.
12
- - **Scrollable context log** — a vertical scrollbar is drawn on the right edge of the chat (and the agent-conversation viewer) whenever the conversation is taller than the view. Scroll with the wheel, `PgUp`/`PgDn` or `↑`/`↓`, or grab the scrollbar with the mouse and drag it like in a GUI.
13
- - **LLM providers** — ships with DeepSeek, OpenAI, and Anthropic presets; works with any OpenAI-compatible endpoint.
14
- - **Tool calling** — the agent can run shell commands, read files, write files, and list directories in your working directory.
15
- - **Streaming responses** — token-by-token output with pause/resume (`ESC ESC`).
16
- - **Intensity control** — tune `temperature`/`top_p` from `Low` to `Ultra`.
17
- - **Session history** — messages are saved before a turn starts, streamed replies are checkpointed every second, and tool calls/results are saved immediately. The history screen lists conversations started in the current working directory. Failed saves are shown in the terminal and browser UI.
18
- - **Auto-folding turns** — once a turn finishes, the work behind the reply (the thinking and the tool calls) folds into one summary line in both the terminal and the browser, while the answer itself always stays on screen. Click the line to read the whole round again; a turn with little to hide, or a long answer on its own, stays open. A turn stopped with `ESC ESC` is paused, not finished, so it stays open. Nothing is dropped: the transcript, the saved session and the model's context keep every message.
19
- - **Complete conversation history** — context compression keeps every original message and tool result on disk. The earlier portion starts collapsed in the terminal and browser; click **Earlier conversation** to expand it, including in reopened history. Model requests use a separate summary plus recent messages.
20
- - **Plan-first turns** — before a request is answered, a planner agent splits it into ordered, independent steps ("model the case from box.png", "animate the camera: push in, orbit, pull back"), and the worker then executes those steps one at a time, top to bottom. Every step is a concrete deliverable, so later work is explicit instead of one vague instruction. See [Plan-first turns](#plan-first-turns).
21
- - **The step card** — click `ⓘ` in the chat header (or press `Ctrl+P`) to open the info card in the top-right corner. It lists the plan as a vertical timeline of nodes: the step being worked on is highlighted, steps still to come are lit, and finished steps are drawn dark with a tick. The same card shows prompt/completion/total token counts when no plan is running.
22
- - **Sub-agents** — independent work can be handed to a sub-agent: a second agent loop with its own context, its own tool calls and the same approval gate. Only its report comes back, so a survey that reads thirty files does not fill the conversation with thirty files. See [Sub-agents](#sub-agents).
23
- - **Agent history browser** — view past sessions from other CLI agents (Claude Code, Codex, OpenCode) directly from the history screen.
24
- - **Approval gate** — risky commands and paths outside the working directory need your sign-off. The header turns orange and reads **Request Approval**; press `Y` or `N`. Delete-class commands always ask, unless you explicitly granted full trust, and there is an opt-in reviewer agent for automatic decisions.
25
- - **Browser UI on by default** — every `neutrino` launch also mounts a local website at <http://127.0.0.1:8765> that lists every saved conversation grouped by working directory, streams the running one in real time, and lets you pause/resume it, send messages, start new conversations, open or create working directories, switch provider/model/intensity, edit every terminal setting, and switch the interface between English and 简体中文. Use `--port`/`--host` to move it, `--lan` to share it, or `--no-web` to keep the terminal only.
7
+ ## 什么是 Neutrino ?
26
8
 
27
- ## Requirements
9
+ Neutrino 是由 XINGJI 工作室开发的一款跨生态跨平台的全新架构 Agent。
28
10
 
29
- - Node.js **>= 18.0.0**
30
- - An interactive terminal (TTY)
11
+ ## Neutrino 有什么特点?
31
12
 
32
- ## Installation
13
+ - 提供 Web 控制台,对手机端进行特别优化,提供与 CLI 界面**一样甚至更好**的操作体验。
14
+ - Pro 模式 使用全新自研 “站中间串两边” 架构,把任务分割给各个最适合的模型,降低成本并提升一次通过率,免去繁杂的描述和拆分挑选,**真正做到一句话一次性做到最好**!
15
+ - OpenCode 的思考强度切换简直是一坨史,但Neutrino不存在这个问题。**你想要什么强度就用什么强度。**
16
+ - 配置文件条目清晰,想怎么用就怎么用,相比于 OpenCode 更加方便。
17
+ - 更严谨更方便的自动审批系统,**一键切换**,多智能体评审,保证数据安全。
18
+ - 超级轻量,总代码量仅 3 万行。
19
+ - 兼容 ClaudeCode、OpenCode、Codex 等多种 Agent 的对话格式,无缝迁移。
20
+ - 1000 万以内最好的 Agent!(绝对没有嘲讽某公司的意思)
33
21
 
34
- ```sh
35
- npm install -g @xingjisoft/neutrino
36
- ```
37
-
38
- Or run from source:
39
-
40
- ```sh
41
- git clone <repo-url> neutrino
42
- cd neutrino
43
- npm install
44
- npm run build
45
- npm link
46
- ```
47
-
48
- ## Usage
49
-
50
- ```sh
51
- neutrino
52
- ```
53
-
54
- Type a message on the start screen and press `Enter` to begin a new chat.
55
- The browser UI is mounted at <http://127.0.0.1:8765> at the same time; see
56
- [Web UI](#web-ui) below for `--port`, `--lan` and `--no-web`.
57
-
58
- ### Keys
59
-
60
- | Keys | Action |
61
- | --- | --- |
62
- | `Enter` | Send message / confirm (only a manually typed Enter sends) |
63
- | `←`/`→`, `↑`/`↓` | Move focus / navigate |
64
- | `Ctrl+E` | Open model config |
65
- | `Ctrl+B` | Back to menu (from chat) |
66
- | `Ctrl+L` | Clear conversation (from chat) |
67
- | `Esc Esc` | Pause / resume streaming (a paused turn stays open: only a finished reply folds) |
68
- | `Esc` | Clear an active selection |
69
- | `PgUp` / `PgDn` | Scroll chat history |
70
- | `Ctrl+C` | Do nothing while text is selected; otherwise pause the running conversation or show the exit hint at the top |
71
- | `Ctrl+C` × 3 | Quit after three consecutive presses, no more than 1.5 seconds apart (another key, paste, click or scroll resets the count) |
72
- | `Ctrl+Shift+C` | Quit immediately (requires the terminal to forward the shortcut) |
73
- | `Ctrl+A` | Toggle Request Approval / Auto Approval in a conversation |
74
- | `Ctrl+P` | Toggle the plan / token info card in the top-right corner |
75
- | `Y` | Approve the pending request (while the approval card is up) |
76
- | `N` / `Esc` | Deny the pending request |
77
- | `Ctrl+Q` | Quit |
78
-
79
- ### Mouse
80
-
81
- | Action | Effect |
82
- | --- | --- |
83
- | Hover over an item | Highlight / select it in lists and menus |
84
- | Click an item | Select and confirm (open a screen, load a session, apply a setting…) |
85
- | Click the input box | Focus it and place the cursor at the clicked position |
86
- | Click a folded turn | Expand the complete round, or fold it again |
87
- | Click `⚙ tool` | Expand or collapse a tool call's output |
88
- | Click and drag | Select text under the rectangle; releasing copies it to the clipboard |
89
- | Drag onto the first/last row of the log | Scroll the log a line at a time (faster the longer you hold it) and keep growing the selection past the screen |
90
- | Click the header (left of `ⓘ`) | Open the model selector |
91
- | Click `ⓘ` (chat header) | Toggle the plan / token info card |
92
- | Drag the scrollbar | Grab the thumb on the right edge of the chat/log and drag it to scroll |
93
- | Scroll wheel | Scroll the chat/log, or move through lists |
94
- | Right-click | Go back (like `Esc`) |
95
-
96
- The selection highlight is drawn over whatever is on screen, so it works uniformly on the chat log, the input box and every menu. Selected text is copied with trailing whitespace trimmed per line (shell-style), so it can be pasted straight back into a terminal. UI chrome (such as the scrollbar) is skipped when copying and highlighting, so a copy never picks up the bar or the padding in front of it.
97
-
98
- A drag that scrolls keeps its starting point anchored to the line it began on,
99
- not to the row it began on: the mark stays on the edge that is scrolling, the
100
- highlight stops at the log's edge instead of spilling into the header or the
101
- input box, and the copy includes the lines that scrolled out of view. Scroll back
102
- and the selection shrinks again; press `Esc` to drop it.
103
-
104
- ## Plan-first turns
105
-
106
- A request is answered in two passes. A **planner agent** first turns the message
107
- into an ordered list of independent steps; a **worker agent** then executes
108
- exactly one step per pass, from the top down. Each step names one deliverable, so
109
- a long request stops being a single vague instruction and becomes a sequence of
110
- concrete, verifiable ones. The plan is written into the conversation as a
111
- message and saved with the session, so the steps of a reopened conversation are
112
- still there.
113
-
114
- The steps are also listed in the `ⓘ` card in the top-right corner of the chat —
115
- click it, or press `Ctrl+P`:
116
-
117
- - nodes run top to bottom in execution order, joined by a connector,
118
- - the step being worked on is the highlighted row,
119
- - steps still to come are lit, and
120
- - finished steps are drawn dark with a tick; a failed one is marked in red.
121
-
122
- The card opens by itself as soon as a plan is written, and closing it loses
123
- nothing: `Ctrl+P` brings it back. On a short terminal the card shows a window
124
- around the running step and counts the steps above and below it.
125
-
126
- A step that fails stops the plan: the remaining steps stay pending and the next
127
- message can re-plan them. A turn paused with `Esc Esc` stops the plan and marks
128
- it **stopped**, so no step keeps looking live. When no usable plan comes back —
129
- a single-action request, a provider error, an answer that is not a plan — the
130
- turn runs in one pass exactly as before, so planning is never a new way to fail.
131
-
132
- **Simple requests are not planned at all.** Planning costs a model round-trip
133
- before any work starts, and for "把这个变量改名" that round-trip is pure friction.
134
- A request is planned only when it shows a reason to be split:
135
-
136
- | Signal | Example |
137
- | --- | --- |
138
- | More than one thing to do | `先改配置,再更新文档`, `运行测试,并且把报错修掉` |
139
- | Its own structure | a numbered or bulleted list |
140
- | It reads as a brief | longer than about 180 columns |
141
- | It asks for a plan | `列个计划`, `plan`, `steps` |
142
-
143
- Everything else runs in one pass: no planner call, no plan card, and the agent
144
- still names the steps it is taking inside its own answer. The check lives in
145
- `needsPlan()` in `src/llm/plan.ts`.
146
-
147
- The prompts are files, not code: [`assets/planner.txt`](./assets/planner.txt)
148
- says how steps are written, [`assets/step.txt`](./assets/step.txt) is the
149
- instruction for each step, and [`assets/prompt.txt`](./assets/prompt.txt) is the
150
- worker's base system prompt. Turn planning off for one run with
151
- `NEUTRINO_PLAN=off`, or permanently with `"plan_first": false` in `config.json`.
152
-
153
- ## Sub-agents
154
-
155
- The agent can hand one self-contained sub-task to a **sub-agent**: a second agent
156
- loop with its own transcript, its own tool calls and the same working directory.
157
- Only its final report comes back — the files it read and the commands it ran
158
- never enter the main conversation. That is the point: surveying a large codebase
159
- or probing how a command behaves costs many messages, and the parent needs the
160
- conclusion, not the transcript. The child's tokens still count in the
161
- conversation's usage.
162
-
163
- - The parent calls the `delegate` tool with a complete task and, optionally, a
164
- little context. The sub-agent cannot see the conversation and cannot ask the
165
- user, so a task that refers to "the file above" fails; the system prompt tells
166
- the model to write a brief that stands alone.
167
- - Its tool calls go through the **same approval gate**: a risky call parks the
168
- turn and shows the usual card (the header turns orange, the browser shows its
169
- banner). Denying it tells the sub-agent not to retry unchanged, and the parent
170
- receives the refusal in the report.
171
- - Delegation is one level deep — `delegate` is not in a sub-agent's toolset — so
172
- the work always has one owner and one pause button.
173
- - While it runs, the terminal status line and the browser badge name the current
174
- phase (`Sub-agent — read_file`), and the `delegate` tool block shows the task
175
- it was given. The report replaces that marker when it arrives, as the result of
176
- the tool call.
177
- - The round limit (12) bounds a child that never finishes; the parent then gets
178
- the partial report, clearly marked as partial. A paused turn aborts the
179
- sub-agent and says so in the tool result.
180
-
181
- The sub-agent's prompt is a file too: [`assets/subagent.txt`](./assets/subagent.txt).
182
-
183
- ## Configuration
184
-
185
- Settings are stored under `~/.neutrino/`:
186
-
187
- - `model.json` — provider and model definitions (edit to add your own endpoints).
188
- DeepSeek-style thinking endpoints get `reasoning_content` sent back on their
189
- assistant messages automatically; a differently named endpoint can opt in
190
- with `"reasoning": true` (or opt out with `false`).
191
- - `config.json` — app configuration (selected provider/model/intensity, theme,
192
- language, approval mode, `auto_approve_extreme_risk`, `sound_alerts`,
193
- `web_console`, `web_workspaces`). `language` (`en` or `zh`) is the browser
194
- console's interface language; the terminal UI itself stays English.
195
- - `session/` — saved conversation sessions, one JSON file per session.
196
-
197
- Set your API key in the model select screen or directly in `model.json`.
198
-
199
- A few environment variables override flags:
200
-
201
- | Variable | Effect |
202
- | --- | --- |
203
- | `NEUTRINO_WEB_PORT` | Web UI port: like `--port` in either mode, and it mounts the UI even when `web_console` is off. |
204
- | `NEUTRINO_WEB_HOST` | Interface to bind, like `--host`; also mounts the UI when `web_console` is off. |
205
- | `NEUTRINO_NETWORK_ATTEMPTS` | Total tries for a model request that keeps dropping (default 7). |
206
- | `NEUTRINO_RETRY_DELAY_MS` | Wait before the first retry in ms; each retry doubles it (default 5000). |
207
- | `NEUTRINO_PLAN` | `off` answers a request in one pass without planning it (overrides `plan_first`); `on` forces planning. |
208
-
209
- ### Approvals
210
-
211
- Every tool call is classified before it runs.
212
-
213
- | Class | Examples | Default behaviour |
214
- | --- | --- | --- |
215
- | Routine | `npm run build`, `git status`, reading or writing inside the project | Runs without asking |
216
- | High | `sudo`, `chmod`, package installs, `git push`, `curl`, inline `python -c`, any path outside the working directory | Asks the user |
217
- | Extreme | Delete-class: `rm`, `del`, `shred`, `mkfs`, `git clean -f`, `git reset --hard`, `find -delete`, `DROP TABLE`, … | Always asks the user |
218
-
219
- While a call waits for an answer the top bar turns orange and reads
220
- **Request Approval**, and an orange card floats above the input box with the
221
- command, **why the agent says it needs it**, why it was flagged, and
222
- `[ Y ] Approve` / `[ N ] Deny`. Approving runs the call; denying returns a note
223
- to the model so it can pick another route instead of retrying.
224
-
225
- Every tool call carries a `reason` argument, and a call that needs approval but
226
- states none does not run: the gate refuses it before you are interrupted or a
227
- reviewer is paid for, and the model is told to resend the same call with a
228
- reason. The reason is the agent's own claim, shown apart from the arguments.
229
- A vague, imperfect or seemingly unrelated reason is not itself a safety hazard;
230
- reviewers judge the actual call's consequences and explicit user restrictions.
231
-
232
- Two phrases in your message change the policy for that conversation:
233
-
234
- | Phrase in the prompt | Effect |
235
- | --- | --- |
236
- | `无需审批` | High-risk calls run without asking. Delete-class calls still ask. |
237
- | `我已知悉风险,同意给予完整权限,无需任何审批` | Nothing asks, including delete-class calls. |
238
-
239
- The one-row **Request Approval / Auto Approval** button above the main menu's
240
- version label sets and remembers the default for new conversations. Each terminal
241
- conversation has its own button above the input (or **Ctrl+A**), and each browser
242
- conversation has a switch in its controls. The conversation's choice is saved
243
- with its history and synced between terminal and browser. Writing `自动审批` or
244
- `自动批准` in a prompt no longer enables automatic review.
245
-
246
- With **Auto Approval** enabled, each pending tool call receives **two independent
247
- safety reviews**. A review round passes when its average safety score is at least
248
- 60/100 and no concrete safety hazard or failed review blocks it. Task relevance
249
- has zero weight and no ordinary minimum: even a score of 0 does not by itself
250
- prevent a safe call from running, and doubts about purpose must not lower safety.
251
-
252
- Only an extreme, obvious task mismatch can veto on relevance: both reviewers
253
- must independently mark it, give a relevance score of at most 5/100, and provide
254
- specific evidence comparing the task and proposed action. One suspicion, weak
255
- justification, or uncertainty about the task is insufficient.
256
-
257
- The policy favors ordinary implementation and verification steps, including
258
- scoped edits, dependency installation, public network checks and temporary test
259
- files. Concrete serious hazards and explicit user prohibitions block approval;
260
- a failed, timed-out or malformed review also prevents automatic execution.
261
- Every assessment and the safety result are included in the decision, per round
262
- for delete-class calls.
263
-
264
- Each turn captures its literal user request and earlier user messages separately
265
- from summaries and tool output, so short follow-ups keep their task context.
266
- Queued messages take effect on the next turn. Denied tool results include the
267
- reviewed user request and recent user requests for diagnosis.
268
-
269
- Automatic approval of delete-class commands is behind a switch in **Settings →
270
- Extreme-risk auto-approval**, which is **off by default**: while it is off,
271
- delete-class calls always go to a human even in **Auto Approval** mode.
272
-
273
- With the switch on, a delete-class call is reviewed **three separate times**.
274
- Each round is the usual pair of independent reviewers; the rounds run one after
275
- another and no round is told what an earlier one concluded. Every round is
276
- judged on its own scores and the call only runs if **all three** approve, so the
277
- first round that denies or fails ends the sequence: a deletion never gets a
278
- second chance to pass. The switches are layered, so turning **Auto Approval**
279
- off still sends every delete-class request to you. The reviewer model defaults
280
- to the chat model and can be changed in **Settings → Approval reviewer model**.
281
-
282
- ### Sound alerts
283
-
284
- A short cue plays when a turn finishes and when an approval request appears, in
285
- both the terminal and the web UI, so a long task or a blocking approval is
286
- noticeable from another window. Approval requests ring twice; finished turns
287
- ring once. Toggle it in **Settings → Sound alerts** (TUI or web), or set
288
- `"sound_alerts": false` in `config.json`.
289
-
290
- Browsers refuse to start audio before a user gesture, so the web UI stays silent
291
- until the page has been clicked or a key has been pressed at least once.
292
-
293
- ### Browsing other agents' history
294
-
295
- From the history screen, select **Open other Agent's history** to view past sessions recorded by other CLI agents installed on your machine:
296
-
297
- - **Claude Code** — reads `~/.claude/projects/**/*.jsonl`.
298
- - **Codex** — reads `~/.codex/sessions` and `~/.codex/archived_sessions`.
299
- - **OpenCode** — reads the local SQLite database (`opencode.db`) via `node:sqlite` (requires Node.js **22.13+**; silently unavailable on older versions).
22
+ ## 相比于 OpenCode 的优势
300
23
 
301
- Only sessions that were started in the current working directory are listed, so the history stays focused on the project you are in. These sessions are read-only; you can open them for review but not edit or delete.
24
+ - 可以方便自由地随意调整思考强度。
25
+ - 提供更好的 Web 控制台,为手机端特别优化,不管什么手机什么设备,无需下载随时随地只要有网就能远控!
26
+ - 进行特殊优化,**更省钱!**(OpenCode 用啥都贵)
27
+ - 更简单严谨的自动审批系统,解放双手的同时保证你的数据安全,全自动审批一切命令(可以在设置中调整,要求高危命令人工审批),无需人工干涉。
28
+ - 更好的自动重试系统。
29
+ - 我们是小团队,你的建议我们全部都能收到!
30
+ - Pro 模式真正做到一句话一次性做到最好!目前主流 Agent **全部** 没有这个功能!(因为主流 Agent 基本都是 AI 厂商的,总不能自家 Agent 用自己竞争对手的东西吧)
31
+ - 配置文件简洁易懂,想咋改就咋改。
302
32
 
303
- ## Web UI
33
+ ## 安装方式
304
34
 
305
- Neutrino mounts a small website at <http://127.0.0.1:8765> whenever the
306
- terminal UI starts. It groups every saved conversation by working directory
307
- (showing the five newest per path with the rest collapsed), folds the work of
308
- every finished turn into one summary line that opens on a click while the reply
309
- stays on screen, streams a running conversation live, and lets you pause or
310
- resume it and send new messages from the browser. Conversation text is rendered
311
- as markdown — headings, lists (including tasks and nesting), tables, block
312
- quotes, fenced code, emphasis, links and images — while raw HTML stays inert and
313
- only safe link/image schemes become clickable.
35
+ npm 一键安装:
314
36
 
315
- **New conversation** in the sidebar starts a chat that has no transcript yet.
316
- Its dialog chooses the working directory and the provider, model and thinking
317
- level for the first turn. **Browse…** opens the server's folder picker, where you
318
- can walk the filesystem, create a folder, and use it as the conversation's
319
- working directory. Opened folders are remembered under **Working directories**
320
- (the folder button above the list), which scopes the sidebar to that project and
321
- lets you start a new chat there; you can always return to **All directories**.
322
-
323
- A saved transcript opens read-only, because nothing is running for it. Press
324
- **Continue here** (or simply type in the composer) and the server resumes it
325
- in-process — same model, working directory and token counters — so you can keep
326
- chatting from the browser with no terminal attached. Turns are written back to
327
- the same session file. **Clear** starts a fresh conversation in the same folder
328
- (the previous transcript stays saved), **Delete** removes a saved transcript,
329
- and **Other agents** lists read-only sessions that Claude Code, Codex or
330
- OpenCode recorded in that folder.
331
-
332
- Use the selectors above a conversation to change its provider, model or
333
- intensity, then press **Apply to conversation** (pause an active turn first).
334
- The **Settings** (gear) button in the sidebar edits defaults for new conversations,
335
- the interface language, plan-first turns, the default approval mode, context
336
- compression and approval settings. Conversation choices are saved with the
337
- transcript and do not overwrite the defaults. Configured models and keys are
338
- shared with the terminal; keys stay on the server.
339
-
340
- The interface language can be switched in the sidebar footer or in
341
- **Settings → Interface**: English and 简体中文 are supported. The change applies
342
- immediately without a reload, survives restarts in `config.json`, and is shared
343
- by every browser. The terminal UI itself is not translated.
344
-
345
- The `ⓘ` button in a conversation header opens the same plan/token card as
346
- `Ctrl+P` in the terminal: the steps of a planned turn with their live statuses,
347
- and the prompt/completion/total token counts when no plan is running.
348
-
349
- Context auto-compression starts at 80% of the current model's context window.
350
- Models default to 1,000,000 tokens (compression at 800,000). Adjust the model
351
- context window in terminal Settings or select the provider/model in Web Settings
352
- and enter its capacity in tokens. This is saved per provider/model and applies
353
- to future turns in active conversations. The legacy fixed
354
- `context_compress_threshold` setting is no longer used.
355
-
356
- ```sh
357
- # The terminal UI now brings the web UI up with it
358
- neutrino
359
-
360
- # Pick a different port or interface
361
- neutrino --port 9000
362
- neutrino --host 100.64.0.7
363
-
364
- # Or serve only the saved history, with no terminal
365
- neutrino web --port 8765
366
- ```
367
-
368
- Then open <http://127.0.0.1:8765>. The site itself lives in [`web/`](./web) and
369
- needs no build step; see [`web/README.md`](./web/README.md) for the API.
370
-
371
- The console is on by default; turn it off for one run with `--no-web`, or
372
- permanently in the terminal's **Settings → Web console**. The `--web-port` flag
373
- is still accepted as an alias for `--port`. If the default port is already taken
374
- (usually by another Neutrino instance), the terminal UI starts anyway and prints
375
- how to choose another port.
376
-
377
- ### Reaching it from another device
378
-
379
- The server binds to loopback, so only this machine can open it. To use it from a
380
- phone, a tablet or another box on your LAN or VPN, bind an interface others can
381
- see:
382
-
383
- ```sh
384
- neutrino --lan # TUI + web UI on every interface (0.0.0.0)
385
- neutrino --host 100.64.0.7 # TUI + web UI on one specific address
386
- neutrino web --port 8765 --lan # headless web UI on every interface
387
- ```
388
-
389
- `--lan` is shorthand for `--host 0.0.0.0`; the two cannot be combined.
390
-
391
- Startup prints every address that works, so you can copy the one matching the
392
- device you are on:
393
-
394
- ```
395
- Neutrino web UI listening on 0.0.0.0:8765
396
- Open the address that matches your device:
397
- http://100.105.130.25:8765/
398
- http://192.168.1.211:8765/
399
- http://127.0.0.1:8765/
400
- ```
401
-
402
- Open the address and sign in with your permanent Web password. The initial
403
- password is **`114514`**. Change it in the browser's **Settings → Web access**
404
- or in the terminal's **Settings → Web password**. It is saved as a salted hash
405
- in `~/.neutrino/config.json` and survives restarts. While the site is running,
406
- its address is also shown in the terminal header and in the terminal's
407
- **Settings → Web console** row, which can start or stop it without a restart.
408
-
409
- For automatic login, open `http://<host>:8765/?pwd=114514`. The page checks the
410
- password, remembers the login, and removes `pwd` from the address bar. If it is
411
- incorrect, the password login dialog lets you try again. URL-encode special
412
- characters in your password.
413
-
414
- The browser remembers your login in an HttpOnly cookie for up to one year,
415
- including across server restarts. Changing the password signs out other
416
- browsers; the browser that saves the new password stays signed in. Addresses
417
- and startup output never contain your password or session credentials.
418
-
419
- - **`--no-auth`** explicitly disables password login.
420
- - Static files and the login endpoint remain public; all conversation and
421
- settings APIs require a login, including when accessed through localhost.
422
- - **Firewall:** the first bind to `0.0.0.0` triggers an allow prompt on Windows
423
- and macOS. Allow it for private networks, and check that your WLAN is not
424
- marked "public", where incoming connections are blocked anyway.
425
- - **`127.0.0.1` is still the default interface.** The console starts with the
426
- terminal UI, but it is not a network service until you pass `--host`/`--lan`.
427
-
428
- ## Built-in tools
429
-
430
- The agent can call the following tools during a conversation:
431
-
432
- - `run_command` — execute a shell command (120s timeout, output capped).
433
- - `read_file` — read a text file (capped at 200KB).
434
- - `write_file` — write content to a file.
435
- - `list_files` — list directory contents.
436
- - `delegate` — hand one self-contained sub-task to a sub-agent and return its report.
437
-
438
- Every tool takes an additional `reason` argument: one sentence saying what the
439
- call is for and why it is needed now. It is what the approval card shows and what
440
- reviewers check the arguments against, so it is required even for calls that
441
- usually run without asking.
442
-
443
- ## Development
444
-
445
- ```sh
446
- npm run build # compile TypeScript to dist/
447
- npm test # build, then run every test below
448
- ```
449
-
450
- Individual tests:
451
-
452
- ```sh
453
- node scripts/test-paste.mjs # verify pasted newlines are flattened to spaces
454
- node scripts/test-mouse.mjs # verify mouse escape-sequence parsing
455
- node scripts/test-cursor.mjs # verify click-to-position-cursor math
456
- node scripts/test-selection.mjs # verify selection highlighting & text extraction
457
- node scripts/test-drag-scroll.mjs # verify drag-select auto-scroll: edge scrolling, cross-screen copy
458
- node scripts/test-copy.mjs # verify a copy never includes the scrollbar or trailing padding
459
- node scripts/test-scrollbar.mjs # verify the conversation scrollbar size/position and drag maths
460
- node scripts/test-markdown.mjs # verify markdown/table rendering (incl. ragged rows)
461
- node scripts/test-wrap.mjs # verify indentation & spacing are preserved when wrapping
462
- node scripts/test-render.mjs # fuzz the diff renderer + render the chat screen,
463
- # asserting no stale/residual cells are left behind
464
- node scripts/test-sanitize.mjs # verify ANSI/control codes never reach the screen
465
- node scripts/test-drift.mjs # verify the input area self-heals after terminal drift
466
- node scripts/test-fetch.mjs # verify streamed requests release aborts, retry drops and the 7-attempt backoff
467
- node scripts/test-compact.mjs # verify context-compression planning
468
- node scripts/test-history-fold.mjs # verify full-history retention, folding and resume
469
- node scripts/test-web-history.mjs # verify browser history disclosures and streaming state
470
- node scripts/test-web-default.mjs # verify the web console starts and toggles by default
471
- node scripts/test-turn-fold.mjs # verify folded turns keep their reply and every message
472
- node scripts/test-plan.mjs # verify plan-first turns, step order, the step card and the fallback
473
- node scripts/test-subagent.mjs # verify delegation: isolation, approvals, abort, round limits
474
- node scripts/test-tools.mjs # verify tool-output folding
475
- node scripts/test-web.mjs # verify the web server, API, SSE stream and path-traversal guards
476
- node scripts/test-web-settings.mjs # verify model switching, persistence, browser controls and defaults
477
- node scripts/test-web-settings-http.mjs # verify authenticated settings and model changes over HTTP
478
- node scripts/test-web-markdown.mjs # verify the browser markdown renderer and its XSS boundaries
479
- node scripts/test-web-i18n.mjs # verify every console label has a Chinese translation and placeholders survive
480
- node scripts/test-web-workspaces.mjs # verify folder browsing/creation, new conversations, clear/delete and other-agent history
37
+ ``` bash
38
+ npm install -g @xingjisoft/neutrino
481
39
  ```
482
40
 
483
- ### Rendering model
484
-
485
- The screen is drawn into a `Buffer` of cells which is diffed against the previous frame, so only changed rows are emitted. Rows are erased to the end of the line before being repainted, and the buffer keeps double-width glyphs consistent (writing over one half of a wide character blanks the other half). Together these guarantee that a repainted row can never leave a stale cell behind.
486
-
487
- Because only *changed* rows are emitted, a row whose contents happen to be identical from one frame to the next is never rewritten — so if the terminal shifts its own contents behind our back (ConPTY reflowing the buffer mid-resize, a size-race repaint, a stray scroll) that row would stay stale. Two defences cover this: the persistent chrome (input box, tabs, key hints) is repainted on every frame via `Screen.alwaysRepaintRows()`, and the app periodically re-emits the whole cached frame (`Renderer.repaint()`) as a safety net. Both are no-ops when nothing drifted.
488
-
489
- ### Text hygiene
490
-
491
- A cell's glyph is copied straight into the output stream, so a cell holding a *control* character becomes a command the terminal executes — an ESC sequence can move the cursor, clear the screen or leave the alternate buffer, and a TAB shifts the rest of the row. Tool output (ANSI colours from `ls --color`, `git`, `npm`, progress bars, …), file contents and pasted text all carry such bytes, so they are neutralised in three places:
492
-
493
- 1. `src/sanitize.ts` — `sanitizeText()` removes whole escape sequences (not just the ESC byte, which would leave `[31m` behind as literal text), expands tabs so measured widths match what the terminal draws, and drops any remaining control code. It is applied where untrusted text enters the display (chat messages, tool results, pasted input).
494
- 2. `Buffer` — writing a control character stores a space instead, preserving the column width the caller measured, so no cell can ever hold one.
495
- 3. `Renderer` — a last-resort check when emitting a row, so the byte stream cannot carry a control code even if a cell were populated another way.
496
-
497
- ### Network resilience
498
-
499
- Model responses arrive over a streamed connection that can drop at any point. A single blip must not end the session — a turn is minutes of work, and a proxy that resets an idle socket says nothing about the user's task — so a failed request is retried before anything is given up:
500
-
501
- | Attempt | Wait before it |
502
- | --- | --- |
503
- | 1 | — |
504
- | 2 | 5s |
505
- | 3 | 10s |
506
- | 4 | 20s |
507
- | 5 | 40s |
508
- | 6 | 80s |
509
- | 7 | 2m 40s |
41
+ ## 使用小技巧
510
42
 
511
- That is seven tries and roughly five minutes in total, doubling every time: a link that is merely flaky recovers long before the budget is spent, while a link that is genuinely down is not hammered. `NEUTRINO_NETWORK_ATTEMPTS` and `NEUTRINO_RETRY_DELAY_MS` tune both numbers. The policy lives in `src/llm/retry.ts`.
43
+ - Web 控制台配合 Tailscale 等软件,可以直接实现外网安全远控!而且无需下载,打开即用!
44
+ - 支持后台常驻(默认关闭):在 Web 控制台或终端设置中切换后立即生效,开启时关闭终端也不会中断已开始的浏览器任务。也可以用 `neutrino background start|stop|status|open` 管理后台控制台。
512
45
 
513
- What counts as worth retrying:
46
+ ---
514
47
 
515
- - **Connection failures** — a reset (`ECONNRESET`), a refused or unreachable socket, `EPIPE`, DNS (`EAI_AGAIN`), a connect timeout, and undici's `UND_ERR_*` codes.
516
- - **A stream that dies before the first byte** — the server or a proxy closed the connection mid-flight (`TypeError: terminated`, `other side closed`, `socket hang up`, …). Nothing has reached the user, so the request is simply re-issued.
517
- - **A transient HTTP status** — 408/425, 429 and 5xx (502/503/504 from a load balancer, 529 "overloaded"). A bad request is different: 400/401/403/404/422 surface on the first answer, because re-sending them only delays the real message.
518
- - **A stream that dies after output has started** is *not* retried: replaying it would duplicate the reply, so the error is surfaced with the real reason expanded out of the `error.cause` chain (`fetch failed` alone says nothing useful) and the partial text is kept.
519
-
520
- A retry can leave the stream silent for up to 160s, so it is never silent *about* being silent: the terminal status line and the web badge name the attempt and the delay ("Network hiccup — retrying in 40s (attempt 4/7)"). The wait is also polled, so pausing the turn, sending a newer message or quitting drops it immediately instead of sitting out the backoff.
521
-
522
- Any stream the consumer walks away from (pause, or a newer turn taking over) always has its body cancelled, so sockets are not leaked.
523
-
524
- ### Crash safety
525
-
526
- The TUI takes over the terminal: raw mode, the alternate screen and mouse
527
- reporting. If the process ever dies without undoing those, the shell inherits a
528
- terminal that types `[<b>;<x>;<y>M` mouse reports at every cursor move.
529
-
530
- So the teardown sequence is registered three ways — normal quit, a
531
- `process.on("exit")` hook that writes synchronously to fd 1, and
532
- `uncaughtException` / `unhandledRejection` handlers. Normal quit uses the same
533
- synchronous teardown, so pending frame output cannot swallow the cleanup.
534
- Catchable exits also flush the latest conversation snapshot, including a partial
535
- reply. Uncaught errors are appended to `~/.neutrino/crash.log` and exit with
536
- status 1. SIGHUP and Windows Ctrl+Break also restore and checkpoint before exit.
537
-
538
- Session snapshots are written to a temporary file in the session directory,
539
- synced, then atomically renamed over the previous snapshot. A failed write
540
- preserves the previous history, reports an error in the UI and crash log, and
541
- is retried at the next checkpoint. Partial replies are replaced by the completed
542
- reply in the saved snapshot, so reopening history does not duplicate them.
543
-
544
- Key handlers and the render loop are also wrapped: they run inside `stdin`
545
- callbacks and timers, where a throw is an uncaught exception that used to end
546
- the session. A failed frame is now retried, and only a screen that cannot be
547
- drawn at all stops the app.
548
-
549
- An uncatchable kill (SIGKILL, TerminateProcess or a runtime/OS failure) cannot
550
- run cleanup. Already-written snapshots survive; with a writable disk, streamed
551
- output since the last one-second checkpoint may be lost. If a shell is stuck
552
- in mouse mode, run this in Bash:
553
-
554
- ```sh
555
- printf '\033[?2004l\033[?1000l\033[?1002l\033[?1003l\033[?1006l\033[?1015l\033[?25h\033[0m\033[?1049l'
556
- stty sane
557
- ```
558
-
559
- In PowerShell:
560
-
561
- ```powershell
562
- $esc = [char]27
563
- [Console]::Write("${esc}[?2004l${esc}[?1000l${esc}[?1002l${esc}[?1003l${esc}[?1006l${esc}[?1015l${esc}[?25h${esc}[0m${esc}[?1049l")
564
- ```
48
+ 欢迎各位大佬提供建议!
565
49
 
566
- ## License
50
+ ---
567
51
 
568
- Apache-2.0. See [LICENSE](./LICENSE).
52
+ Copymiddle(O) XINGJI Interactive Software 2017-2026 Some rights reserved.
Binary file
@@ -0,0 +1,7 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" role="img" aria-label="Neutrino">
2
+ <rect width="32" height="32" rx="7" fill="#151517"/>
3
+ <g fill="none" stroke="#f9fafb" stroke-width="1.9" stroke-linecap="round">
4
+ <ellipse cx="16" cy="16" rx="12.5" ry="5.1" transform="rotate(-30 16 16)"/>
5
+ <circle cx="16" cy="16" r="4.1"/>
6
+ </g>
7
+ </svg>
@@ -0,0 +1,5 @@
1
+ You are Neutrino Pro's backend and general coding specialist. Implement non-frontend code, APIs, storage, CLI behavior, integration, build logic and tests in the existing project's style. Read the relevant interfaces and callers before changing behavior.
2
+
3
+ Preserve type and data contracts, handle validation and failures explicitly, and avoid leaking credentials through errors or logs. Consider concurrency, cancellation and persistence when they affect the task. Keep filesystem and process operations scoped to the requested work and route tool execution through the shared approval gate.
4
+
5
+ Use focused tests that exercise observable behavior. Report changed files, any contract changes and actual verification results. Consult thinking_model for difficult diagnosis or algorithms, modeling_model for schemas/domain models, and front_output_model for interface changes. Keep those delegated tasks concrete and integrate their outputs before reporting completion.