zames_pro 2.82.138 → 2.82.140

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/CHANGELOG.md CHANGED
@@ -7,6 +7,96 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [2.82.140] - 2026-10-25
11
+
12
+ ### Fixed
13
+
14
+ - **scheduler:** stop the ticker on exit; correct the abort help line
15
+ - **config:** say when a project config overrides the home one
16
+
17
+ ## [2.82.139] - 2026-10-25
18
+
19
+ ### Changed
20
+
21
+ - docs(test/security-sandbox): drop the backlog priority label
22
+ - docs(test): remove the last backlog ids (I2, U2/U3)
23
+ - docs(test/extra-tools): drop a backlog id from a section header
24
+ - docs(test/cancel-ask): stop quoting a stale watchdog deadline
25
+ - docs(test/send-runtime-block-lift): fix a header that contradicted its own fix
26
+ - docs(test/tui-hints-locale): wrap two over-long comment lines
27
+ - docs(test/tui-hints-locale): wrap the over-long note
28
+ - docs(test): translate leftover Russian comments
29
+ - docs(test/readme-built): say why a second readme is forbidden
30
+ - docs(test/readme-built): say why a second readme is forbidden
31
+ - docs(test/agent-loop): state why the first send is not an agent turn
32
+ - docs(test/statusline-cap): untangle the settle-vs-exit note
33
+ - docs(test/i18n-unused): drop the shouting prefix
34
+ - docs(test/legacy-paste-marker): drop a time-relative word
35
+ - docs(test): replace first-person narration with the subject
36
+ - docs(test/continue-button): drop the first-person narration
37
+ - docs(test/auto-compact): drop a pointer to the fixture value
38
+ - docs(test/run-task): drop the refactor history from the header
39
+ - docs(test/attach-flow-shared): keep only the why of the fake clock
40
+ - docs(test/send-telemetry-nan-block): drop a case that lives in another test
41
+ - docs(test/wsl): state the real reason instead of the CI setup
42
+ - docs(test/agent-loop-robust): name the retry budget constant
43
+ - docs(test/diff-large-file): stop quoting a removed source comment
44
+ - docs(test/auth-login): trim a comment that restated its asserts
45
+ - docs(agents): remove the last backlog ids from the root instructions
46
+ - docs(scripts): remove backlog ids from scenario comments
47
+ - docs(test/generation-incomplete): stop quoting a stale watchdog value
48
+ - docs(test/cancel-ask): drop the runner version from the keep-alive note
49
+ - docs(test/cli-flags): name the skip-list constant
50
+ - docs(test/continue-button): name the real continue constant
51
+ - docs(test/finished-answer-plain-json): name the real constants
52
+ - docs(test/tool-name-resolution): drop the meta clause
53
+ - docs(test/mcp-truncate-surrogate): finish the meta-narration cleanup
54
+ - docs(test): drop meta-narration from test comments
55
+ - docs(test/log-window): state the bug instead of narrating the test
56
+ - docs(readme): mention /rewind next to /undo
57
+ - docs(llms): regenerate llms-full.txt after the readme fixes
58
+ - docs(readme): clarify the per-provider context window sentence
59
+ - docs(readme): the Qwen send pause is 4 s, not 1 s
60
+ - docs(readme): the context percentage is per provider, not always 1M
61
+ - docs(readme): complete the CLI options block
62
+ - docs(readme): list BashOutput and AskUser among the tools
63
+ - docs(readme): make the slash-command list match SLASH_COMMANDS
64
+ - docs(scripts): fix a typo in the build-readme usage line
65
+ - docs(test/agent-loop-robust): fix a section header that contradicted the code
66
+ - docs(test/i18n-unused): tighten the vacuously-green note
67
+ - docs(test/attach-flow): drop a what-comment
68
+ - docs(test/browser-login): drop a duplicated probe walkthrough
69
+ - docs(scripts): document the postinstall contract
70
+ - docs(test/agent-facing-english): point at the split i18n catalog
71
+ - docs(test): remove backlog ids missed by the first sweep
72
+ - docs(developing): refresh module sizes and drop backlog ids
73
+ - docs(agents): drop backlog ids from the module map
74
+ - docs(agents): the providers are three, with three profiles
75
+ - docs(contributing): fix the provider list and the dev-mode description
76
+ - docs(citation): sync the version and keep CITATION.cff updated on release
77
+ - docs(readme): mention GLM in the provider section
78
+ - docs(readme): fix three default/config facts (mouseScroll, telemetry, config write target)
79
+ - docs(readme): state the real Node.js requirement (>= 22)
80
+ - docs(design-notes): replace a backlog id with the actual reason
81
+ - docs(scripts): translate a Russian header and drop backlog ids
82
+ - docs(test/xml): prune and fix stale comments
83
+ - docs(test/subagent): prune stale comments
84
+ - docs(test/ssrf): prune stale comments
85
+ - docs(test/skill): prune and fix stale comments
86
+ - docs(test/mcp): prune stale comments and translate a leftover Russian note
87
+ - docs(test/i18n): repair a corrupted word and prune stale comments
88
+ - docs(test/glm): prune and fix stale comments
89
+ - docs(test/editor): drop remaining backlog ids
90
+ - docs(test/editor): prune and fix stale comments
91
+ - docs(test/context): prune and fix stale comments
92
+ - docs(test/config): prune and fix stale comments
93
+ - docs(test/cli): prune and fix stale comments
94
+ - docs(test/browser): prune and fix stale comments
95
+ - docs(test/backlog): prune and fix stale comments
96
+ - docs(test/answer-parse): prune and fix stale comments
97
+ - docs(test/agent-loop): prune and fix stale comments
98
+ - docs: add a text-audit protocol for an unattended loop run
99
+
10
100
  ## [2.82.138] - 2026-10-25
11
101
 
12
102
  ### Changed
package/README.md CHANGED
@@ -13,7 +13,7 @@
13
13
  <a href="https://www.npmjs.com/package/zames_pro"><img src="https://img.shields.io/npm/dm/zames_pro.svg" alt="npm downloads"></a>
14
14
  <a href="https://github.com/Viqto0r/zames_pro/actions/workflows/test.yml"><img src="https://github.com/Viqto0r/zames_pro/actions/workflows/test.yml/badge.svg" alt="tests"></a>
15
15
  <a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
16
- <a href="package.json"><img src="https://img.shields.io/badge/node-%3E%3D20-brightgreen.svg" alt="Node.js"></a>
16
+ <a href="package.json"><img src="https://img.shields.io/badge/node-%3E%3D22-brightgreen.svg" alt="Node.js"></a>
17
17
  <a href="https://www.typescriptlang.org/"><img src="https://img.shields.io/badge/TypeScript-strict-3178c6.svg" alt="TypeScript"></a>
18
18
  <a href="CONTRIBUTING.md"><img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs welcome"></a>
19
19
  </p>
@@ -96,8 +96,8 @@ Key pieces:
96
96
  - **A persistent per-provider profile** (`~/.zames/profile` for DeepSeek,
97
97
  `~/.zames/qwen-profile` for Qwen) keeps you signed in; the headless
98
98
  User-Agent is patched so the site's CDN does not 403 the login.
99
- - **A send throttle** (15 s on DeepSeek, ~1 s on Qwen, which tolerates rapid
100
- sends; GLM uses an adaptive pause that starts at 0) keeps the web chat's rate
99
+ - **A send throttle** (15 s on DeepSeek, 4 s on Qwen, which tolerates a faster
100
+ pace; GLM uses an adaptive pause that starts at 0) keeps the web chat's rate
101
101
  limit happy during long tool-heavy runs.
102
102
  - **The agent is sandboxed** to the directory it was started in — no tool can
103
103
  read or write above it.
@@ -115,7 +115,8 @@ Key pieces:
115
115
 
116
116
  - **Tools like Claude Code / Codex** — `Read`, `Write`, `Edit`, `Bash`,
117
117
  `Glob`, `Grep`, plus `MultiEdit`, `ApplyPatch`, `LS`, `TodoWrite`, git and web
118
- tools. Every edit is backed by `/undo`.
118
+ tools. Every edit is backed by `/undo`, and `/rewind` restores the whole
119
+ working tree from a checkpoint.
119
120
  - **Runs while you keep typing** — queue messages during a task; they run right
120
121
  after it, in the same chat (like typing during generation on the web).
121
122
  - **Plan mode** — `/plan` (or `--plan`) drops all mutating tools, so the agent
@@ -148,7 +149,7 @@ Key pieces:
148
149
 
149
150
  ## Requirements
150
151
 
151
- - Node.js >= 20
152
+ - Node.js >= 22
152
153
  - An account on the chat you want to use — **DeepSeek** (`chat.deepseek.com`,
153
154
  the default), **Qwen** (`chat.qwen.ai`) or **GLM** (`chat.z.ai`). Qwen also
154
155
  works in guest mode for a few messages. On first launch zames asks for your login in the terminal
@@ -194,8 +195,8 @@ Credentials and toggles can also be edited from `/config`
194
195
 
195
196
  ## Switching providers (DeepSeek / Qwen / GLM)
196
197
 
197
- zames can drive either **DeepSeek** (`chat.deepseek.com`, the default) or
198
- **Qwen** (`chat.qwen.ai`):
198
+ zames can drive **DeepSeek** (`chat.deepseek.com`, the default), **Qwen**
199
+ (`chat.qwen.ai`) or **GLM** (`chat.z.ai`):
199
200
 
200
201
  ```bash
201
202
  /provider qwen # switch to Qwen (persisted) — applied live, no restart
@@ -209,9 +210,10 @@ zames can drive either **DeepSeek** (`chat.deepseek.com`, the default) or
209
210
  Notes:
210
211
 
211
212
  - The switch is **live**: zames closes the current backend and opens the other
212
- one in place, so no restart is needed. The two backends use **separate
213
+ one in place, so no restart is needed. The backends use **separate
213
214
  persistent profiles** (`~/.zames/profile` for DeepSeek, `~/.zames/qwen-profile`
214
- for Qwen), so switching never signs the other one out.
215
+ for Qwen, `~/.zames/glm-profile` for GLM), so switching never signs the other
216
+ one out.
215
217
  - A chat id belongs to ONE backend, so the new provider opens a **fresh chat**.
216
218
  If the previous chat had messages they are summarized and posted as a
217
219
  handoff with the next task; an empty chat is switched silently.
@@ -230,10 +232,10 @@ Notes:
230
232
  solved programmatically). zames therefore launches GLM headed by default and
231
233
  prints a note about it; `--headless` still forces headless (sends will hit
232
234
  the captcha). `--headed` is accepted everywhere.
233
- - **Send telemetry**: every send is recorded in
235
+ - **Send telemetry** (off by default): when enabled, every send is recorded in
234
236
  `~/.zames/logs/sends-<provider>.jsonl` (timing, mode flags, the outcome and
235
- the server error — never the prompt or the answer). Turn it off with
236
- `/config set browser.sendTelemetry false`. `/limits` shows the recent sends
237
+ the server error — never the prompt or the answer). Turn it on with
238
+ `/config set browser.sendTelemetry true`. `/limits` shows the recent sends
237
239
  and the current pause. GLM additionally uses an **adaptive pause**: it starts
238
240
  at 0 and backs off from a REAL rate limit.
239
241
  - **Warning**: automating a web chat may violate the service's terms of use and
@@ -295,11 +297,11 @@ The prompt is a small line editor with persistent history:
295
297
  Full-screen mode adds dialog navigation, so a long answer can be read and
296
298
  selected without leaving the terminal:
297
299
 
298
- - `ui.mouseScroll=false` (default) — the terminal owns the mouse: normal text
299
- selection works and the wheel is inert (it never scrolls the input history —
300
- history is arrow keys only).
301
- - `ui.mouseScroll=true` — the app consumes the wheel and scrolls the dialog;
302
- selecting text then needs `Shift`+click (the TUI convention).
300
+ - `ui.mouseScroll=true` (default) — the app consumes the wheel and scrolls the
301
+ dialog; selecting text then needs `Shift`+click (the TUI convention). The
302
+ wheel never scrolls the input history — history is arrow keys only.
303
+ - `ui.mouseScroll=false` — the terminal owns the mouse again: normal text
304
+ selection works and the wheel is inert.
303
305
  - `PgUp` / `PgDn` — move up/down the dialog half a screen.
304
306
  - `Home` / `End` — jump to the very top / bottom of the dialog (only while the
305
307
  input line is empty; with text typed they move the caret as usual).
@@ -336,8 +338,11 @@ instead of staying silent.
336
338
  zames --task <task text>
337
339
  zames --chat <id>
338
340
  zames --new-chat
341
+ zames --resume-last
339
342
  zames --resend-prompt
340
343
  zames --dir <path>
344
+ zames --provider <deepseek|qwen|glm>
345
+ zames --max-iter <n>
341
346
  zames --headless
342
347
  zames --headed
343
348
  zames --plan
@@ -368,15 +373,19 @@ zames --task "..." --output-format jsonl \
368
373
 
369
374
  The agent has the same style of tools as Claude Code / Codex CLI:
370
375
 
371
- - **File tools** — `Read`, `Write`, `Edit`, `Bash`, `Glob`, `Grep`. `Read`
372
- returns raw content by default; pass `numbered=true` to get `cat -n`-style
373
- line numbers (for reference only — do not paste them into `Edit`).
376
+ - **File tools** — `Read`, `Write`, `Edit`, `Bash`, `BashOutput`, `Glob`,
377
+ `Grep`. `Read` returns raw content by default; pass `numbered=true` to get
378
+ `cat -n`-style line numbers (for reference only — do not paste them into
379
+ `Edit`). `Bash` takes `run_in_background`; `BashOutput` then polls or kills
380
+ that process.
374
381
  - **Extra tools** — `LS` (list a directory), `MultiEdit` (several edits to one
375
382
  file applied atomically), `TodoWrite` (session task checklist), `ApplyPatch`
376
383
  (multi-file patch in Codex's V4A format: `*** Begin Patch` … `*** End Patch`).
377
384
  - **Git** — `GitStatus`, `GitDiff`, `GitLog`, `GitShow`, `GitBranchList`,
378
385
  `GitAdd`, `GitCommit`, `GitPush`.
379
386
  - **Web** — `WebFetch`, `WebSearch`.
387
+ - **Operator** — `AskUser` (a modal question with options; skipped in plan
388
+ mode so a plan is never interrupted).
380
389
  - **Service** — `respond` (final answer to the operator, ends the task).
381
390
 
382
391
  All file tools stay inside the working directory (sandbox). `Write`/`Edit` and
@@ -384,11 +393,12 @@ All file tools stay inside the working directory (sandbox). `Write`/`Edit` and
384
393
 
385
394
  ## Slash commands
386
395
 
387
- Type / in the prompt for hints (Tab completes). Besides the session and
388
- config commands (/new, /chats, /resume, /cd, /status, /config,
389
- /undo, /transcript, /mcp, /skills, /memory, /init, /reload,
390
- /debug-dom, /help, /exit) there are a few that mirror Claude Code /
391
- Codex CLI:
396
+ Type / in the prompt for hints (Tab completes) — that list is always complete,
397
+ `/help <command>` describes any single one. Besides the session and config
398
+ commands (/new or /clear, /sessions, /chats, /resume-id, /last, /chat, /cd,
399
+ /pwd, /status, /config, /undo, /undo-list, /rewind, /rewind-list, /transcript,
400
+ /tasks, /mcp, /skills, /memory, /remember, /init, /reload, /debug-dom, /help,
401
+ /exit) there are a few that mirror Claude Code / Codex CLI:
392
402
 
393
403
  - /diff [--staged] — show the working-tree git diff (--staged for the index).
394
404
  - /diffstat — a one-line change summary (`git diff --stat`).
@@ -450,11 +460,12 @@ tests`). /cron "<min> <hour> <dom> <month> <dow>" <task> — run on a schedule.
450
460
  current task.
451
461
 
452
462
  The token context is also shown live: the status line above the input has the
453
- spinner/text on the left and the context on the right (e.g. `125k · 13%`,
454
- percent of a 1M context). It is COLORED by fill level: green below 50%,
455
- yellow 50-80%, red above 80%. It comes from the provider's own token
456
- counter (DeepSeek's `accumulated_token_usage`, Qwen's `input_tokens`, GLM's
457
- `prompt_tokens`) and is
463
+ spinner/text on the left and the context on the right (e.g. `125k · 13%`). The
464
+ percentage is of the ACTIVE provider's window — 1M for DeepSeek, a per-model
465
+ value for Qwen and GLM (`qwen.contextLimit` / `glm.contextLimit`) — and it is
466
+ COLORED by fill level: green below 50%, yellow 50-80%, red above 80%.
467
+ It comes from the provider's own token counter (DeepSeek's
468
+ `accumulated_token_usage`, Qwen's `input_tokens`, GLM's `prompt_tokens`) and is
458
469
  hidden until the first answer delivers it.
459
470
 
460
471
  ## Project context, skills and memory
@@ -587,8 +598,9 @@ Examples:
587
598
  /config lang en
588
599
  ```
589
600
 
590
- Changes are written to the project `.zamesrc.json` and applied right away
591
- (where possible without a restart).
601
+ Changes are written to the HOME config (`~/.zames/config.json`), NOT to the
602
+ project `.zamesrc.json` — a personal toggle must not leak into git — and applied
603
+ right away (where possible without a restart).
592
604
 
593
605
  ### Language
594
606
 
@@ -645,7 +657,7 @@ signed-in browser profile.
645
657
  **How do I install a terminal AI coding agent?**
646
658
 
647
659
  ```bash
648
- npm install -g zames_pro # Node.js >= 20; Chromium is fetched automatically
660
+ npm install -g zames_pro # Node.js >= 22; Chromium is fetched automatically
649
661
  cd your-project
650
662
  zames
651
663
  ```
@@ -777,9 +789,9 @@ zames не вызывает API модели. Он запускает headless C
777
789
  `~/.zames/qwen-profile` у Qwen, `~/.zames/glm-profile` у GLM) держит вас
778
790
  залогиненным; User-Agent
779
791
  headless-браузера подменяется, чтобы CDN сайта не отдавал 403 на вход.
780
- - **Троттлинг отправки** (15 с у DeepSeek, ~1 с у Qwen, который спокойно
781
- переносит частые отправки; у GLM — адаптивная пауза с нуля) щадит рейт-лимит
782
- веб-чата во время долгих прогонов с инструментами.
792
+ - **Троттлинг отправки** (15 с у DeepSeek, 4 с у Qwen, который спокойно
793
+ переносит более частый темп; у GLM — адаптивная пауза с нуля) щадит
794
+ рейт-лимит веб-чата во время долгих прогонов с инструментами.
783
795
  - **Агент запесочен** в директорию запуска — ни один инструмент не может
784
796
  читать или писать выше неё.
785
797
 
@@ -796,7 +808,8 @@ zames не вызывает API модели. Он запускает headless C
796
808
 
797
809
  - **Инструменты как в Claude Code / Codex** — `Read`, `Write`, `Edit`, `Bash`,
798
810
  `Glob`, `Grep`, плюс `MultiEdit`, `ApplyPatch`, `LS`, `TodoWrite`, git- и
799
- веб-инструменты. Каждая правка подкреплена `/undo`.
811
+ веб-инструменты. Каждая правка подкреплена `/undo`, а `/rewind` возвращает
812
+ всё рабочее дерево к чекпойнту.
800
813
  - **Работает, пока вы печатаете** — сообщения, набранные во время задачи,
801
814
  встают в очередь и уходят сразу после неё, в тот же чат (как набор текста
802
815
  во время генерации на сайте).
@@ -832,7 +845,7 @@ zames не вызывает API модели. Он запускает headless C
832
845
 
833
846
  ## Требования
834
847
 
835
- - Node.js >= 20
848
+ - Node.js >= 22
836
849
  - Аккаунт в нужном чате — **DeepSeek** (`chat.deepseek.com`, по умолчанию),
837
850
  **Qwen** (`chat.qwen.ai`) или **GLM** (`chat.z.ai`). Qwen также работает в
838
851
  гостевом режиме на несколько сообщений. При первом запуске zames спросит логин в терминале (и сохранит его
@@ -911,10 +924,10 @@ zames умеет работать с **DeepSeek** (`chat.deepseek.com`, по у
911
924
  программно её не пройти). Поэтому zames запускает GLM с окном по умолчанию и
912
925
  пишет об этом при старте; `--headless` по-прежнему форсирует headless
913
926
  (отправки будут упираться в капчу). `--headed` работает везде.
914
- - **Телеметрия отправок**: каждая отправка пишется в
915
- `~/.zames/logs/sends-<provider>.jsonl` (тайминги, флаги режимов, исход и
916
- ошибка сервера — без промптов и ответов). Отключается через
917
- `/config set browser.sendTelemetry false`. Команда `/limits` показывает
927
+ - **Телеметрия отправок** (по умолчанию выключена): когда включена, каждая
928
+ отправка пишется в `~/.zames/logs/sends-<provider>.jsonl` (тайминги, флаги
929
+ режимов, исход и ошибка сервера — без промптов и ответов). Включается через
930
+ `/config set browser.sendTelemetry true`. Команда `/limits` показывает
918
931
  последние отправки и текущую паузу. У GLM вдобавок **адаптивная пауза**: она
919
932
  начинается с 0 и растёт только после НАСТОЯЩЕГО лимита.
920
933
  - **Предупреждение**: автоматизация веб-чата может нарушать условия
@@ -978,11 +991,11 @@ zames
978
991
  В полноэкранном режиме добавляется навигация по диалогу, чтобы длинный ответ
979
992
  можно было прочитать и выделить не покидая терминал:
980
993
 
981
- - `ui.mouseScroll=false` (по умолчанию) — терминал владеет мышью: обычное
982
- выделение текста работает, колесо инертно (и никогда не листает историю
983
- ввода — история только стрелками).
984
- - `ui.mouseScroll=true` — приложение перехватывает колесо и скроллит диалог;
985
- выделение текста тогда — `Shift`+клик (стандарт TUI).
994
+ - `ui.mouseScroll=true` (по умолчанию) — приложение перехватывает колесо и
995
+ скроллит диалог; выделение текста тогда — `Shift`+клик (стандарт TUI). Колесо
996
+ никогда не листает историю ввода — история только стрелками.
997
+ - `ui.mouseScroll=false` — мышью снова владеет терминал: обычное выделение
998
+ текста работает, колесо инертно.
986
999
  - `PgUp` / `PgDn` — вверх/вниз по диалогу на пол-экрана.
987
1000
  - `Home` / `End` — прыжок в самый верх / низ диалога (только когда строка ввода
988
1001
  пуста; при набранном тексте они двигают курсор, как обычно).
@@ -1020,8 +1033,11 @@ base64-блок с узнаваемой сигнатурой изображен
1020
1033
  zames --task <текст задачи>
1021
1034
  zames --chat <id>
1022
1035
  zames --new-chat
1036
+ zames --resume-last
1023
1037
  zames --resend-prompt
1024
1038
  zames --dir <path>
1039
+ zames --provider <deepseek|qwen|glm>
1040
+ zames --max-iter <n>
1025
1041
  zames --headless
1026
1042
  zames --headed
1027
1043
  zames --plan
@@ -1052,16 +1068,19 @@ zames --task "..." --output-format jsonl \
1052
1068
 
1053
1069
  У агента тот же стиль инструментов, что в Claude Code / Codex CLI:
1054
1070
 
1055
- - **Файловые** — `Read`, `Write`, `Edit`, `Bash`, `Glob`, `Grep`. `Read` по
1056
- умолчанию отдаёт сырое содержимое; передайте `numbered=true`, чтобы получить
1057
- нумерацию строк в стиле `cat -n` (только для справки — не вставляйте её в
1058
- `Edit`).
1071
+ - **Файловые** — `Read`, `Write`, `Edit`, `Bash`, `BashOutput`, `Glob`,
1072
+ `Grep`. `Read` по умолчанию отдаёт сырое содержимое; передайте
1073
+ `numbered=true`, чтобы получить нумерацию строк в стиле `cat -n` (только для
1074
+ справки — не вставляйте её в `Edit`). `Bash` принимает `run_in_background`,
1075
+ а `BashOutput` затем опрашивает или убивает этот процесс.
1059
1076
  - **Дополнительные** — `LS` (список директории), `MultiEdit` (несколько правок
1060
1077
  одного файла атомарно), `TodoWrite` (чек-лист задач сессии), `ApplyPatch`
1061
1078
  (мультифайловый патч в формате V4A от Codex: `*** Begin Patch` … `*** End Patch`).
1062
1079
  - **Git** — `GitStatus`, `GitDiff`, `GitLog`, `GitShow`, `GitBranchList`,
1063
1080
  `GitAdd`, `GitCommit`, `GitPush`.
1064
1081
  - **Web** — `WebFetch`, `WebSearch`.
1082
+ - **Оператор** — `AskUser` (модальный вопрос с вариантами; в режиме плана не
1083
+ предлагается, чтобы не прерывать план).
1065
1084
  - **Служебный** — `respond` (финальный ответ оператору, завершает задачу).
1066
1085
 
1067
1086
  Все файловые инструменты остаются внутри рабочей директории (песочница).
@@ -1070,10 +1089,12 @@ zames --task "..." --output-format jsonl \
1070
1089
 
1071
1090
  ## Слэш-команды
1072
1091
 
1073
- Введите / в промпте для подсказок (Tab дополняет). Кроме команд сессии и
1074
- конфига (/new, /chats, /resume, /cd, /status, /config, /undo, /transcript,
1075
- /mcp, /skills, /memory, /init, /reload, /debug-dom, /help, /exit) есть
1076
- несколько в духе Claude Code / Codex CLI:
1092
+ Введите / в промпте для подсказок (Tab дополняет) — этот список всегда полный,
1093
+ а `/help <команда>` описывает любую одну из них. Кроме команд сессии и конфига
1094
+ (/new или /clear, /sessions, /chats, /resume-id, /last, /chat, /cd, /pwd,
1095
+ /status, /config, /undo, /undo-list, /rewind, /rewind-list, /transcript,
1096
+ /tasks, /mcp, /skills, /memory, /remember, /init, /reload, /debug-dom, /help,
1097
+ /exit) есть несколько в духе Claude Code / Codex CLI:
1077
1098
 
1078
1099
  - /diff [--staged] — показать git-диф рабочего дерева (--staged для индекса).
1079
1100
  - /diffstat — сводка изменений одной строкой (`git diff --stat`).
@@ -1136,11 +1157,12 @@ zames --task "..." --output-format jsonl \
1136
1157
  текущей задачи.
1137
1158
 
1138
1159
  Контекст в токенах показывается и вживую: в строке статуса над вводом слева
1139
- спиннер/текст, справа — контекст (например, `125k · 13%`, процент от 1M
1140
- контекста). Он ОКРАШЕН по уровню заполнения: зелёный ниже 50%, жёлтый 50-80%,
1141
- красный выше 80%. Значение приходит из счётчика токенов провайдера (у DeepSeek —
1142
- `accumulated_token_usage`, у Qwen — `input_tokens`, у GLM — `prompt_tokens`) и
1143
- скрыто до первого ответа.
1160
+ спиннер/текст, справа — контекст (например, `125k · 13%`). Процент считается от
1161
+ окна АКТИВНОГО провайдера — 1M у DeepSeek, у Qwen и GLM — своё значение на
1162
+ модель (`qwen.contextLimit` / `glm.contextLimit`). Он ОКРАШЕН по уровню
1163
+ заполнения: зелёный ниже 50%, жёлтый 50-80%, красный выше 80%. Значение
1164
+ приходит из счётчика токенов провайдера (у DeepSeek — `accumulated_token_usage`,
1165
+ у Qwen — `input_tokens`, у GLM — `prompt_tokens`) и скрыто до первого ответа.
1144
1166
 
1145
1167
  ## Контекст проекта, навыки и память
1146
1168
 
@@ -1272,8 +1294,9 @@ enum переключаются на месте; числа и строки от
1272
1294
  /config lang en
1273
1295
  ```
1274
1296
 
1275
- Изменения пишутся в проектный `.zamesrc.json` и применяются сразу (где это
1276
- возможно без перезапуска).
1297
+ Изменения пишутся в домашний конфиг (`~/.zames/config.json`), а НЕ в проектный
1298
+ `.zamesrc.json` — личный переключатель не должен попадать в git, — и применяются
1299
+ сразу (где это возможно без перезапуска).
1277
1300
 
1278
1301
  ### Язык
1279
1302
 
@@ -1332,7 +1355,7 @@ reasoning-модель при включённом «Deep thinking»). В Qwen
1332
1355
  **Как установить терминальный AI coding-агент?**
1333
1356
 
1334
1357
  ```bash
1335
- npm install -g zames_pro # Node.js >= 20; Chromium скачается автоматически
1358
+ npm install -g zames_pro # Node.js >= 22; Chromium скачается автоматически
1336
1359
  cd your-project
1337
1360
  zames
1338
1361
  ```
@@ -15,8 +15,22 @@ import { configGetValue, configValueHint } from './config-commands.js';
15
15
  * blindly from the main loop and from the live mid-run interception.
16
16
  */
17
17
  export async function handleConfigCommand(input, deps) {
18
- const { t, print, printErr, getValue, setValue, resetField, showList, openMenu, currentLocale, normalizeLocale, localeDisplayName, homeConfigPath, projectConfigPath, } = deps;
18
+ const { t, print, printErr, getValue, setValue, resetField, showList, openMenu, currentLocale, normalizeLocale, localeDisplayName, homeConfigPath, projectConfigPath, shadowedKeys, } = deps;
19
19
  const schema = deps.schema;
20
+ // A HOME write is not always the value the next launch reads: the project
21
+ // `.zamesrc.json` is merged last, so a key present in both wins from the
22
+ // project file. Without this line the operator saw "saved" and then the OLD
23
+ // value after a restart (the stale `ui.locale: en` bug).
24
+ const warnShadowed = (key) => {
25
+ if (!shadowedKeys)
26
+ return;
27
+ if (!shadowedKeys().includes(key))
28
+ return;
29
+ printErr(theme.warn(t('cfg.shadowed', {
30
+ file: projectConfigPath,
31
+ keys: key,
32
+ })));
33
+ };
20
34
  // Accept BOTH spellings: the main loop passes the whole typed line
21
35
  // (`/config get ui.locale`), while tests and other callers pass the text
22
36
  // after the command (`get ui.locale`). Reading parts[1] blindly made the
@@ -60,6 +74,7 @@ export async function handleConfigCommand(input, deps) {
60
74
  return;
61
75
  }
62
76
  print(theme.assistant(t('cfg.lang_set', { v: localeDisplayName(loc) })));
77
+ warnShadowed('ui.locale');
63
78
  return;
64
79
  }
65
80
  if (sub === 'get') {
@@ -105,6 +120,7 @@ export async function handleConfigCommand(input, deps) {
105
120
  value: configGetValue(key, getValue(key), t),
106
121
  file: homeConfigPath,
107
122
  })));
123
+ warnShadowed(key);
108
124
  return;
109
125
  }
110
126
  if (sub === 'reset' || sub === 'unset') {
package/dist/config.js CHANGED
@@ -165,19 +165,72 @@ export const DEFAULTS = {
165
165
  };
166
166
  export function loadConfig() {
167
167
  const merged = JSON.parse(JSON.stringify(DEFAULTS));
168
- for (const file of [HOME_CONFIG, projectConfigPath()]) {
169
- try {
170
- const data = JSON.parse(fs.readFileSync(file, 'utf-8'));
171
- deepMerge(merged, data);
172
- }
173
- catch (e) {
174
- const err = e;
175
- if (err.code !== 'ENOENT') {
176
- console.error(`config: failed to read ${file}: ${err.message}`);
168
+ // Keys the PROJECT file overrides in the HOME file. Kept so the editor can
169
+ // say "your change was saved but the project file still wins" — a live
170
+ // symptom was `/config lang ru` answering "saved", then English after a
171
+ // restart, because a stale project `.zamesrc.json` pinned `ui.locale: en`.
172
+ shadowedKeys = [];
173
+ const homeData = readConfigObject(HOME_CONFIG);
174
+ const projectData = readConfigObject(projectConfigPath());
175
+ if (projectData) {
176
+ shadowedKeys = overriddenKeys(homeData, projectData);
177
+ }
178
+ for (const data of [homeData, projectData]) {
179
+ if (!data)
180
+ continue;
181
+ deepMerge(merged, data);
182
+ }
183
+ return merged;
184
+ }
185
+ /** Keys the lower-priority file also sets, from the last loadConfig(). */
186
+ let shadowedKeys = [];
187
+ export function shadowedConfigKeys() {
188
+ return shadowedKeys.slice();
189
+ }
190
+ /**
191
+ * Every leaf path ("ui.locale", "browser.auth.username") present in BOTH
192
+ * objects — i.e. a value the PROJECT config overrides over the HOME one.
193
+ * PURE so the precedence puzzle can be tested without touching the disk.
194
+ */
195
+ export function overriddenKeys(lower, higher) {
196
+ if (!lower || !higher)
197
+ return [];
198
+ const out = [];
199
+ const walk = (a, b, prefix) => {
200
+ for (const key of Object.keys(b)) {
201
+ if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
202
+ continue;
203
+ }
204
+ const path2 = prefix ? prefix + '.' + key : key;
205
+ const av = a[key];
206
+ const bv = b[key];
207
+ if (isPlainObject(av) && isPlainObject(bv)) {
208
+ walk(av, bv, path2);
209
+ }
210
+ else if (av !== undefined && !isPlainObject(bv)) {
211
+ out.push(path2);
177
212
  }
178
213
  }
214
+ };
215
+ walk(lower, higher, '');
216
+ return out.sort();
217
+ }
218
+ function isPlainObject(v) {
219
+ return !!v && typeof v === 'object' && !Array.isArray(v);
220
+ }
221
+ /** Parse one config file; null when it is missing or unreadable. */
222
+ function readConfigObject(file) {
223
+ try {
224
+ const data = JSON.parse(fs.readFileSync(file, 'utf-8'));
225
+ return isPlainObject(data) ? data : null;
226
+ }
227
+ catch (e) {
228
+ const err = e;
229
+ if (err.code !== 'ENOENT') {
230
+ console.error(`config: failed to read ${file}: ${err.message}`);
231
+ }
232
+ return null;
179
233
  }
180
- return merged;
181
234
  }
182
235
  // The agent-loop watchdog deadline per provider. The loop default (240s) is
183
236
  // tuned for DeepSeek; a Qwen GUEST turn regularly takes 7-8 minutes (cold
@@ -251,6 +251,13 @@ export const configMessages = {
251
251
  ru: 'Язык переключён на {v}.',
252
252
  en: 'Language switched to {v}.',
253
253
  },
254
+ // The project `.zamesrc.json` is merged AFTER the home config, so a key it
255
+ // also sets silently wins — the operator sees "saved", then the old value
256
+ // after a restart (a stale `ui.locale: en` looked like a lost setting).
257
+ 'cfg.shadowed': {
258
+ ru: '⚠ Проектный конфиг {file} переопределяет: {keys} — после перезапуска будет его значение. Уберите эти ключи из проектного файла.',
259
+ en: '⚠ The project config {file} overrides: {keys} — after a restart its value wins. Remove these keys from the project file.',
260
+ },
254
261
  'cfg.lang_usage': {
255
262
  ru: 'Использование: /config lang <ru|en>',
256
263
  en: 'Usage: /config lang <ru|en>',
package/dist/i18n/help.js CHANGED
@@ -94,8 +94,8 @@ export const helpMessages = {
94
94
  en: 'Ctrl+Shift+V image paste an image/file (saved to tmp)',
95
95
  },
96
96
  'help.key.esc': {
97
- ru: 'Esc, Ctrl+C прервать текущую генерацию',
98
- en: 'Esc, Ctrl+C abort current generation',
97
+ ru: 'Esc, Ctrl+C Esc — прервать генерацию; Ctrl+C — прервать инструмент, второй раз — весь прогон',
98
+ en: 'Esc, Ctrl+C Esc — abort generation; Ctrl+C — abort the tool, twice — the whole run',
99
99
  },
100
100
  'help.key.scroll': {
101
101
  ru: 'PgUp / PgDn вверх/вниз по диалогу (Home/End — в начало/конец) [full-screen]',
package/dist/index.js CHANGED
@@ -20,7 +20,7 @@ import { LineEditor } from './input.js';
20
20
  import { TuiEditor } from './tui/TuiEditor.js';
21
21
  import { promptOnce } from './prompt.js';
22
22
  import { parseImagePaste, extForMime, saveToTemp, guessMime, formatSize, readClipboardImageDetailed, sniffMime, readWindowsClipboardFiles, hasClipboardTool, writeClipboardText, contentHash, } from './attachments.js';
23
- import { loadConfig, DEFAULTS, CONFIG_PATHS, ZAMES_HOME, CONFIG_SCHEMA, getByPath, validateConfigValue, writeConfigValue, resetConfigValue, providerAskDeadlineMs, } from './config.js';
23
+ import { loadConfig, DEFAULTS, CONFIG_PATHS, ZAMES_HOME, CONFIG_SCHEMA, getByPath, validateConfigValue, writeConfigValue, resetConfigValue, providerAskDeadlineMs, shadowedConfigKeys, } from './config.js';
24
24
  import { runConfigMenu } from './config-menu.js';
25
25
  import { runConfigMenuInk } from './tui/run-config-menu.js';
26
26
  import { formatConfigList } from './config-commands.js';
@@ -126,6 +126,17 @@ let currentLocale = isLocale(config.ui?.locale)
126
126
  // Translation: reads currentLocale at call time, so a language change takes
127
127
  // effect immediately, without a restart (for lines printed afterwards).
128
128
  const t = (key, params) => translate(currentLocale)(key, params);
129
+ // A project `.zamesrc.json` wins over the HOME config, so a key it ALSO sets
130
+ // silently defeats `/config set` — the value looks saved and comes back stale
131
+ // after a restart (the reported "language resets to English" case). Say it at
132
+ // startup, before a task, instead of letting the operator hunt for it.
133
+ const shadowedAtStartup = shadowedConfigKeys();
134
+ if (shadowedAtStartup.length) {
135
+ console.error(theme.warn(t('cfg.shadowed', {
136
+ file: CONFIG_PATHS.PROJECT_CONFIG,
137
+ keys: shadowedAtStartup.join(', '),
138
+ })));
139
+ }
129
140
  // Headless is the default. --headed forces a visible window (useful for the
130
141
  // first sign-in or debugging the DOM). --headless keeps it explicit.
131
142
  // DeepSeek/Qwen run headless by default; GLM CANNOT: z.ai answers a headless
@@ -1349,10 +1360,23 @@ async function main() {
1349
1360
  // never bypassing the send throttle). Started lazily on the first job.
1350
1361
  const scheduler = new Scheduler();
1351
1362
  let scheduleTimer = null;
1363
+ // Ctrl+C on an idle agent EXITS the process. Without this latch a /loop job
1364
+ // whose task was interrupted (and every later fire) would be dropped into
1365
+ // the queue while nobody waits for it, and each tick printed "fired" into a
1366
+ // dying terminal. A loop is meant to outlive a single task, not the agent.
1367
+ let shuttingDown = false;
1368
+ const stopScheduleTicker = () => {
1369
+ if (scheduleTimer) {
1370
+ clearInterval(scheduleTimer);
1371
+ scheduleTimer = null;
1372
+ }
1373
+ };
1352
1374
  const startScheduleTicker = () => {
1353
1375
  if (scheduleTimer)
1354
1376
  return;
1355
1377
  scheduleTimer = setInterval(() => {
1378
+ if (shuttingDown)
1379
+ return;
1356
1380
  const due = scheduler.due(Date.now());
1357
1381
  for (const job of due) {
1358
1382
  // Do not pile MANY copies of the same job while the agent is busy: if
@@ -1403,6 +1427,8 @@ async function main() {
1403
1427
  let reviewMode = null;
1404
1428
  process.on('SIGINT', async () => {
1405
1429
  running = false;
1430
+ shuttingDown = true;
1431
+ stopScheduleTicker();
1406
1432
  // Kill any background processes so no dev-server outlives the agent.
1407
1433
  killAllBackground();
1408
1434
  await browser.close().catch(() => { });
@@ -1827,8 +1853,12 @@ async function main() {
1827
1853
  lastCtrlCAt = now;
1828
1854
  }
1829
1855
  else {
1830
- // Not busy — exit. We wake takeInput() so the loop finishes.
1856
+ // Not busy — exit. We wake takeInput() so the loop finishes. The
1857
+ // scheduler must stop too: a live /loop ticker keeps firing into the
1858
+ // queue while the process is shutting down.
1831
1859
  running = false;
1860
+ shuttingDown = true;
1861
+ stopScheduleTicker();
1832
1862
  if (waiter) {
1833
1863
  const r = waiter;
1834
1864
  waiter = null;
@@ -2160,6 +2190,7 @@ async function main() {
2160
2190
  schema: CONFIG_SCHEMA,
2161
2191
  homeConfigPath: CONFIG_PATHS.HOME_CONFIG,
2162
2192
  projectConfigPath: CONFIG_PATHS.PROJECT_CONFIG,
2193
+ shadowedKeys: shadowedConfigKeys,
2163
2194
  });
2164
2195
  }
2165
2196
  // Open a chat by its ChatInfo and print the restored dialogue. Shared by
package/llms-full.txt CHANGED
@@ -80,8 +80,8 @@ Key pieces:
80
80
  - **A persistent per-provider profile** (`~/.zames/profile` for DeepSeek,
81
81
  `~/.zames/qwen-profile` for Qwen) keeps you signed in; the headless
82
82
  User-Agent is patched so the site's CDN does not 403 the login.
83
- - **A send throttle** (15 s on DeepSeek, ~1 s on Qwen, which tolerates rapid
84
- sends; GLM uses an adaptive pause that starts at 0) keeps the web chat's rate
83
+ - **A send throttle** (15 s on DeepSeek, 4 s on Qwen, which tolerates a faster
84
+ pace; GLM uses an adaptive pause that starts at 0) keeps the web chat's rate
85
85
  limit happy during long tool-heavy runs.
86
86
  - **The agent is sandboxed** to the directory it was started in — no tool can
87
87
  read or write above it.
@@ -99,7 +99,8 @@ Key pieces:
99
99
 
100
100
  - **Tools like Claude Code / Codex** — `Read`, `Write`, `Edit`, `Bash`,
101
101
  `Glob`, `Grep`, plus `MultiEdit`, `ApplyPatch`, `LS`, `TodoWrite`, git and web
102
- tools. Every edit is backed by `/undo`.
102
+ tools. Every edit is backed by `/undo`, and `/rewind` restores the whole
103
+ working tree from a checkpoint.
103
104
  - **Runs while you keep typing** — queue messages during a task; they run right
104
105
  after it, in the same chat (like typing during generation on the web).
105
106
  - **Plan mode** — `/plan` (or `--plan`) drops all mutating tools, so the agent
@@ -132,7 +133,7 @@ Key pieces:
132
133
 
133
134
  ## Requirements
134
135
 
135
- - Node.js >= 20
136
+ - Node.js >= 22
136
137
  - An account on the chat you want to use — **DeepSeek** (`chat.deepseek.com`,
137
138
  the default), **Qwen** (`chat.qwen.ai`) or **GLM** (`chat.z.ai`). Qwen also
138
139
  works in guest mode for a few messages. On first launch zames asks for your login in the terminal
@@ -178,8 +179,8 @@ Credentials and toggles can also be edited from `/config`
178
179
 
179
180
  ## Switching providers (DeepSeek / Qwen / GLM)
180
181
 
181
- zames can drive either **DeepSeek** (`chat.deepseek.com`, the default) or
182
- **Qwen** (`chat.qwen.ai`):
182
+ zames can drive **DeepSeek** (`chat.deepseek.com`, the default), **Qwen**
183
+ (`chat.qwen.ai`) or **GLM** (`chat.z.ai`):
183
184
 
184
185
  ```bash
185
186
  /provider qwen # switch to Qwen (persisted) — applied live, no restart
@@ -193,9 +194,10 @@ zames can drive either **DeepSeek** (`chat.deepseek.com`, the default) or
193
194
  Notes:
194
195
 
195
196
  - The switch is **live**: zames closes the current backend and opens the other
196
- one in place, so no restart is needed. The two backends use **separate
197
+ one in place, so no restart is needed. The backends use **separate
197
198
  persistent profiles** (`~/.zames/profile` for DeepSeek, `~/.zames/qwen-profile`
198
- for Qwen), so switching never signs the other one out.
199
+ for Qwen, `~/.zames/glm-profile` for GLM), so switching never signs the other
200
+ one out.
199
201
  - A chat id belongs to ONE backend, so the new provider opens a **fresh chat**.
200
202
  If the previous chat had messages they are summarized and posted as a
201
203
  handoff with the next task; an empty chat is switched silently.
@@ -214,10 +216,10 @@ Notes:
214
216
  solved programmatically). zames therefore launches GLM headed by default and
215
217
  prints a note about it; `--headless` still forces headless (sends will hit
216
218
  the captcha). `--headed` is accepted everywhere.
217
- - **Send telemetry**: every send is recorded in
219
+ - **Send telemetry** (off by default): when enabled, every send is recorded in
218
220
  `~/.zames/logs/sends-<provider>.jsonl` (timing, mode flags, the outcome and
219
- the server error — never the prompt or the answer). Turn it off with
220
- `/config set browser.sendTelemetry false`. `/limits` shows the recent sends
221
+ the server error — never the prompt or the answer). Turn it on with
222
+ `/config set browser.sendTelemetry true`. `/limits` shows the recent sends
221
223
  and the current pause. GLM additionally uses an **adaptive pause**: it starts
222
224
  at 0 and backs off from a REAL rate limit.
223
225
  - **Warning**: automating a web chat may violate the service's terms of use and
@@ -279,11 +281,11 @@ The prompt is a small line editor with persistent history:
279
281
  Full-screen mode adds dialog navigation, so a long answer can be read and
280
282
  selected without leaving the terminal:
281
283
 
282
- - `ui.mouseScroll=false` (default) — the terminal owns the mouse: normal text
283
- selection works and the wheel is inert (it never scrolls the input history —
284
- history is arrow keys only).
285
- - `ui.mouseScroll=true` — the app consumes the wheel and scrolls the dialog;
286
- selecting text then needs `Shift`+click (the TUI convention).
284
+ - `ui.mouseScroll=true` (default) — the app consumes the wheel and scrolls the
285
+ dialog; selecting text then needs `Shift`+click (the TUI convention). The
286
+ wheel never scrolls the input history — history is arrow keys only.
287
+ - `ui.mouseScroll=false` — the terminal owns the mouse again: normal text
288
+ selection works and the wheel is inert.
287
289
  - `PgUp` / `PgDn` — move up/down the dialog half a screen.
288
290
  - `Home` / `End` — jump to the very top / bottom of the dialog (only while the
289
291
  input line is empty; with text typed they move the caret as usual).
@@ -320,8 +322,11 @@ instead of staying silent.
320
322
  zames --task <task text>
321
323
  zames --chat <id>
322
324
  zames --new-chat
325
+ zames --resume-last
323
326
  zames --resend-prompt
324
327
  zames --dir <path>
328
+ zames --provider <deepseek|qwen|glm>
329
+ zames --max-iter <n>
325
330
  zames --headless
326
331
  zames --headed
327
332
  zames --plan
@@ -352,15 +357,19 @@ zames --task "..." --output-format jsonl \
352
357
 
353
358
  The agent has the same style of tools as Claude Code / Codex CLI:
354
359
 
355
- - **File tools** — `Read`, `Write`, `Edit`, `Bash`, `Glob`, `Grep`. `Read`
356
- returns raw content by default; pass `numbered=true` to get `cat -n`-style
357
- line numbers (for reference only — do not paste them into `Edit`).
360
+ - **File tools** — `Read`, `Write`, `Edit`, `Bash`, `BashOutput`, `Glob`,
361
+ `Grep`. `Read` returns raw content by default; pass `numbered=true` to get
362
+ `cat -n`-style line numbers (for reference only — do not paste them into
363
+ `Edit`). `Bash` takes `run_in_background`; `BashOutput` then polls or kills
364
+ that process.
358
365
  - **Extra tools** — `LS` (list a directory), `MultiEdit` (several edits to one
359
366
  file applied atomically), `TodoWrite` (session task checklist), `ApplyPatch`
360
367
  (multi-file patch in Codex's V4A format: `*** Begin Patch` … `*** End Patch`).
361
368
  - **Git** — `GitStatus`, `GitDiff`, `GitLog`, `GitShow`, `GitBranchList`,
362
369
  `GitAdd`, `GitCommit`, `GitPush`.
363
370
  - **Web** — `WebFetch`, `WebSearch`.
371
+ - **Operator** — `AskUser` (a modal question with options; skipped in plan
372
+ mode so a plan is never interrupted).
364
373
  - **Service** — `respond` (final answer to the operator, ends the task).
365
374
 
366
375
  All file tools stay inside the working directory (sandbox). `Write`/`Edit` and
@@ -368,11 +377,12 @@ All file tools stay inside the working directory (sandbox). `Write`/`Edit` and
368
377
 
369
378
  ## Slash commands
370
379
 
371
- Type / in the prompt for hints (Tab completes). Besides the session and
372
- config commands (/new, /chats, /resume, /cd, /status, /config,
373
- /undo, /transcript, /mcp, /skills, /memory, /init, /reload,
374
- /debug-dom, /help, /exit) there are a few that mirror Claude Code /
375
- Codex CLI:
380
+ Type / in the prompt for hints (Tab completes) — that list is always complete,
381
+ `/help <command>` describes any single one. Besides the session and config
382
+ commands (/new or /clear, /sessions, /chats, /resume-id, /last, /chat, /cd,
383
+ /pwd, /status, /config, /undo, /undo-list, /rewind, /rewind-list, /transcript,
384
+ /tasks, /mcp, /skills, /memory, /remember, /init, /reload, /debug-dom, /help,
385
+ /exit) there are a few that mirror Claude Code / Codex CLI:
376
386
 
377
387
  - /diff [--staged] — show the working-tree git diff (--staged for the index).
378
388
  - /diffstat — a one-line change summary (`git diff --stat`).
@@ -434,11 +444,12 @@ tests`). /cron "<min> <hour> <dom> <month> <dow>" <task> — run on a schedule.
434
444
  current task.
435
445
 
436
446
  The token context is also shown live: the status line above the input has the
437
- spinner/text on the left and the context on the right (e.g. `125k · 13%`,
438
- percent of a 1M context). It is COLORED by fill level: green below 50%,
439
- yellow 50-80%, red above 80%. It comes from the provider's own token
440
- counter (DeepSeek's `accumulated_token_usage`, Qwen's `input_tokens`, GLM's
441
- `prompt_tokens`) and is
447
+ spinner/text on the left and the context on the right (e.g. `125k · 13%`). The
448
+ percentage is of the ACTIVE provider's window — 1M for DeepSeek, a per-model
449
+ value for Qwen and GLM (`qwen.contextLimit` / `glm.contextLimit`) — and it is
450
+ COLORED by fill level: green below 50%, yellow 50-80%, red above 80%.
451
+ It comes from the provider's own token counter (DeepSeek's
452
+ `accumulated_token_usage`, Qwen's `input_tokens`, GLM's `prompt_tokens`) and is
442
453
  hidden until the first answer delivers it.
443
454
 
444
455
  ## Project context, skills and memory
@@ -571,8 +582,9 @@ Examples:
571
582
  /config lang en
572
583
  ```
573
584
 
574
- Changes are written to the project `.zamesrc.json` and applied right away
575
- (where possible without a restart).
585
+ Changes are written to the HOME config (`~/.zames/config.json`), NOT to the
586
+ project `.zamesrc.json` — a personal toggle must not leak into git — and applied
587
+ right away (where possible without a restart).
576
588
 
577
589
  ### Language
578
590
 
@@ -629,7 +641,7 @@ signed-in browser profile.
629
641
  **How do I install a terminal AI coding agent?**
630
642
 
631
643
  ```bash
632
- npm install -g zames_pro # Node.js >= 20; Chromium is fetched automatically
644
+ npm install -g zames_pro # Node.js >= 22; Chromium is fetched automatically
633
645
  cd your-project
634
646
  zames
635
647
  ```
package/llms.txt CHANGED
@@ -20,7 +20,7 @@ LLM-friendly map of the project. Everything below is plain Markdown.
20
20
  - **Supported backends:** DeepSeek (`chat.deepseek.com`, default), Qwen
21
21
  (`chat.qwen.ai`), GLM (`chat.z.ai`). Live switch with
22
22
  `/provider <deepseek|qwen|glm>`; each backend keeps its own browser profile.
23
- - **Language / stack:** TypeScript (strict), Node.js >= 20, Playwright,
23
+ - **Language / stack:** TypeScript (strict), Node.js >= 22, Playwright,
24
24
  Ink/React TUI, MCP client.
25
25
  - **License:** MIT. **Not affiliated** with DeepSeek, Alibaba or Zhipu AI.
26
26
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zames_pro",
3
- "version": "2.82.138",
3
+ "version": "2.82.140",
4
4
  "description": "Terminal coding agent that drives a real browser to chat with DeepSeek, Qwen and other web LLMs — no API key required. Reads and edits files, runs commands, commits to git, like Claude Code / Codex CLI.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,3 +1,8 @@
1
+ // Post-install step: fetch the Chromium build Playwright drives and, on a
2
+ // Linux box that needs it, its system libraries. It runs BEFORE tsx is
3
+ // guaranteed to be installed, so it stays a plain .mjs script. Every failure
4
+ // is a WARNING, never a non-zero exit: a missing browser must not break
5
+ // `npm install`, and the warning names the manual command to run instead.
1
6
  import { spawnSync } from 'node:child_process'
2
7
 
3
8
  const NL = String.fromCharCode(10)