zames_pro 2.82.140 → 2.82.142

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/CHANGELOG.md +56 -0
  2. package/README.md +68 -42
  3. package/SECURITY.md +6 -3
  4. package/dist/attachments.js +4 -7
  5. package/dist/backlog.js +2 -2
  6. package/dist/browser-pure.js +2 -2
  7. package/dist/browser.js +8 -2
  8. package/dist/commands.js +7 -3
  9. package/dist/compact.js +7 -2
  10. package/dist/config.js +1 -1
  11. package/dist/context.js +27 -9
  12. package/dist/glm-browser.js +1 -1
  13. package/dist/glm-net-capture.js +1 -1
  14. package/dist/glm-ui.js +0 -20
  15. package/dist/hooks.js +1 -1
  16. package/dist/i18n/common.js +16 -11
  17. package/dist/i18n/config.js +2 -2
  18. package/dist/i18n/deepseek.js +2 -2
  19. package/dist/i18n/doctor.js +9 -5
  20. package/dist/i18n/glm.js +2 -2
  21. package/dist/i18n/help.js +126 -117
  22. package/dist/i18n/mcp.js +11 -5
  23. package/dist/i18n/prompt.js +9 -3
  24. package/dist/i18n/qwen.js +2 -2
  25. package/dist/i18n/self-review.js +4 -0
  26. package/dist/i18n/spinner.js +13 -8
  27. package/dist/index.js +8 -5
  28. package/dist/mcp.js +6 -3
  29. package/dist/prompt.js +16 -1
  30. package/dist/qwen-browser.js +1 -1
  31. package/dist/qwen-ui.js +0 -2
  32. package/dist/run-task.js +1 -1
  33. package/dist/scheduler.js +1 -1
  34. package/dist/sessions.js +1 -1
  35. package/dist/spinner.js +1 -1
  36. package/dist/status-command.js +6 -2
  37. package/dist/statusline.js +2 -2
  38. package/dist/subagent.js +3 -3
  39. package/dist/system-prompt.js +9 -1
  40. package/dist/tui/AskQuestion.js +1 -1
  41. package/dist/tui/FullScreenApp.js +4 -15
  42. package/dist/tui/LogView.js +1 -1
  43. package/dist/tui/TuiEditor.js +7 -0
  44. package/dist/tui/edit.js +1 -1
  45. package/dist/tui/layout.js +1 -1
  46. package/dist/tui/widgets.js +1 -25
  47. package/dist/web.js +1 -1
  48. package/dist/width.js +1 -1
  49. package/llms-full.txt +35 -22
  50. package/llms.txt +4 -2
  51. package/package.json +2 -2
  52. package/skills/systematic-debugging/SKILL.md +7 -0
  53. package/skills/test-driven-development/SKILL.md +5 -0
  54. package/skills/verification-before-completion/SKILL.md +5 -0
  55. package/skills/writing-plans/SKILL.md +12 -0
  56. package/dist/code-blocks.js +0 -54
package/CHANGELOG.md CHANGED
@@ -7,6 +7,62 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [2.82.142] - 2026-10-27
11
+
12
+ ### Fixed
13
+
14
+ - **release:** bump package-lock.json root versions too
15
+
16
+ ## [2.82.141] - 2026-10-26
17
+
18
+ ### Fixed
19
+
20
+ - **i18n:** /rewind help names --yes and the default point
21
+ - **i18n:** /web help lists the /websearch alias
22
+ - **i18n:** /config help lists its subcommand aliases
23
+ - **i18n:** /queue help lists its list/clear aliases
24
+ - **i18n:** /goal help lists the off and on forms
25
+ - **i18n:** json and jsonl are the same event stream
26
+ - **i18n:** the /loop floor is not a 15s provider throttle
27
+ - **help:** list the /session and /usage aliases
28
+ - **i18n:** drop the duplicate backslash newline hint
29
+ - **tui:** enable the kitty keyboard protocol so Shift+Enter works
30
+ - **i18n:** drop the duplicate status.review_none key
31
+ - **i18n:** /status says MCP tools is a count, not a list
32
+ - **i18n:** the empty-screen hint names a working newline key
33
+ - **prompt:** say that plan mode also hides mutating MCP tools
34
+ - **prompt:** list every *_base64 escape hatch
35
+ - **i18n:** plan mode lists every dropped tool, MCP included
36
+ - **prompt:** decode the terminal bytes across reads, not per read
37
+ - **i18n:** the clipboard hint names the real Wayland and Windows tools
38
+ - **i18n:** the doctor auth row describes the sign-in marker it actually reads
39
+ - **i18n:** the Qwen guest notice says /provider login opens the window itself
40
+ - **i18n:** each full-screen key hint names its own mouse mode
41
+ - **i18n:** the TUI key hint does not advertise a wheel that is off
42
+ - **i18n:** Esc in the AskUser modal means no answer, not dismiss
43
+ - **i18n:** keep prompt.answer_language English in both locales
44
+ - **mcp:** localize the floating-version warning
45
+ - **browser:** localize the send-pause fallback line
46
+ - **browser:** DeepSeek login notices go through the UI hook
47
+ - **compact:** fill the {provider} placeholder in compact.start
48
+ - **i18n:** AskUser free-text mode explains how to send
49
+ - **llms:** generated header says GLM runs headed too
50
+ - **i18n:** suggestion hint says Ctrl+N/P select, not scroll
51
+ - **i18n:** startup hint shows Ctrl+V for clipboard images too
52
+ - **i18n:** /last says there is no session for THIS directory
53
+ - **i18n:** drop the unverified ~10 messages/day guest quota claim
54
+ - **i18n:** keep the agent-facing ONLY TOOL CALLS block English in both locales
55
+ - **i18n:** MCP hint lists the .mcp.json path too
56
+ - **i18n:** help shows the real clipboard paste binding (Ctrl+V)
57
+ - **i18n:** GLM guest_limit message says the quota is exhausted
58
+ - **i18n:** deepseek send_no_start states the real ~50s budget
59
+ - **i18n:** describe both mouseScroll states and the real default
60
+ - **i18n:** translate the English /status labels into Russian
61
+
62
+ ### Changed
63
+
64
+ - **i18n:** drop the duplicate doctor.unknown and msg.not_dir keys
65
+
10
66
  ## [2.82.140] - 2026-10-25
11
67
 
12
68
  ### Fixed
package/README.md CHANGED
@@ -127,7 +127,9 @@ Key pieces:
127
127
  - **Subagents** — the `Task` tool delegates a self-contained sub-task to an
128
128
  agent in its own separate chat (isolated context), which returns only a
129
129
  report, so heavy research does not flood the main context. On by default;
130
- tune with `browser.subagents` / `browser.maxSubagents`.
130
+ `browser.subagents` turns it off and `browser.maxSubagents` caps the runs
131
+ per TASK (default 3). Calls are sequential, not parallel, and the subtype
132
+ matters: `explore` is read-only, `general` may edit files.
131
133
  - **MCP support** — plug in external tool servers (e.g. `@playwright/mcp`).
132
134
  - **Scheduling** — `/loop`, `/cron` and `/jobs` repeat tasks on a timer.
133
135
  - **Bilingual UI** — Russian / English (`/config lang`).
@@ -287,8 +289,12 @@ The prompt is a small line editor with persistent history:
287
289
  - `Ctrl+_` — undo the last edit in the input line (a fat-fingered `Ctrl+U` /
288
290
  `Ctrl+K` is recoverable).
289
291
  - `Ctrl+U` — clear the line, `Ctrl+K` — delete to end of line, `Ctrl+W` —
290
- delete the word before the cursor, `Ctrl+←`/`Ctrl+→` — move by words.
291
- - `\` + `Enter`, `Ctrl+J`, `Ctrl+Enter` or `Shift+Enter` — insert a newline.
292
+ delete the word before the cursor, `Ctrl+←`/`Ctrl+→` — move by words,
293
+ `Ctrl+Delete`/`Alt+Delete` — delete the word after the cursor.
294
+ - `\` + `Enter` and `Ctrl+J` — insert a newline; these two work in
295
+ every terminal. `Ctrl+Enter` and `Shift+Enter` do it too, but only where the
296
+ terminal implements the kitty keyboard protocol: without it the terminal
297
+ sends a PLAIN Enter for Shift+Enter and the message is sent.
292
298
  - `/` + `Tab` — slash-command hints and completion.
293
299
  - `!command` — run a shell command directly, bypassing the model (like
294
300
  Claude Code's bash mode). The same sandbox guard as the `Bash` tool applies,
@@ -302,9 +308,10 @@ selected without leaving the terminal:
302
308
  wheel never scrolls the input history — history is arrow keys only.
303
309
  - `ui.mouseScroll=false` — the terminal owns the mouse again: normal text
304
310
  selection works and the wheel is inert.
305
- - `PgUp` / `PgDn` — move up/down the dialog half a screen.
306
- - `Home` / `End` — jump to the very top / bottom of the dialog (only while the
307
- input line is empty; with text typed they move the caret as usual).
311
+ - the mouse wheel, `PgUp` / `PgDn` (half a screen) and `Home` / `End` (the very
312
+ top / bottom) scroll the dialog; the wheel needs `ui.mouseScroll=true` (the default), and
313
+ Home/End jump only while the input line is empty (with text typed they
314
+ move the caret as usual).
308
315
  - To copy a LARGE block, use `/export` (writes the whole session as Markdown)
309
316
  or the transcript file (`/transcript` shows the path) — the terminal's own
310
317
  drag-select cannot reach past one screen.
@@ -313,8 +320,8 @@ Set `NO_COLOR=1` to disable colors (a calm default palette is used otherwise).
313
320
 
314
321
  ### Images and files
315
322
 
316
- You can paste an image or a file into the input line (Ctrl+Shift+V / Shift+Insert
317
- or the terminal's own paste). zames saves it under `<project>/tmp` and shows a
323
+ You can paste an image or a file into the input line (Shift+Insert or the
324
+ terminal's own paste; for a FILE from the clipboard press Ctrl+V). zames saves it under `<project>/tmp` and shows a
318
325
  marker in the line - `[image#1]` for images, `[file#1]` for other files - then
319
326
  uploads the real file to the chat together with your message. These are the
320
327
  same formats the DeepSeek / Qwen / GLM web chat accepts (PNG, JPEG, GIF, WEBP, BMP,
@@ -384,6 +391,8 @@ The agent has the same style of tools as Claude Code / Codex CLI:
384
391
  - **Git** — `GitStatus`, `GitDiff`, `GitLog`, `GitShow`, `GitBranchList`,
385
392
  `GitAdd`, `GitCommit`, `GitPush`.
386
393
  - **Web** — `WebFetch`, `WebSearch`.
394
+ - **Subagents** — `Task` (delegate a self-contained sub-task to an agent in
395
+ its own chat; `explore` is read-only, `general` may edit; capped per task).
387
396
  - **Operator** — `AskUser` (a modal question with options; skipped in plan
388
397
  mode so a plan is never interrupted).
389
398
  - **Service** — `respond` (final answer to the operator, ends the task).
@@ -431,8 +440,9 @@ commands (/new or /clear, /sessions, /chats, /resume-id, /last, /chat, /cd,
431
440
  - /review [focus] [--staged] — ask the agent to review uncommitted changes
432
441
  and report findings (no code changes).
433
442
  - /plan [on|off] — plan (read-only) mode. While it is on, the mutating tools
434
- (Write/Edit/MultiEdit/ApplyPatch/Bash, GitAdd/GitCommit/GitPush) are removed
435
- from the tool set, so the agent can investigate without touching the tree.
443
+ (Write/Edit/MultiEdit/ApplyPatch/Bash/BashOutput, GitAdd/GitCommit/GitPush,
444
+ AskUser) are removed from the tool set, and so are MCP tools with a mutating
445
+ name, so the agent can investigate without touching the tree.
436
446
  Start in it with `--plan`.
437
447
  - /compact — ask the active backend to compress the current chat into a handover
438
448
  summary, then open a NEW chat, resend the system prompt and post the summary
@@ -440,9 +450,10 @@ commands (/new or /clear, /sessions, /chats, /resume-id, /last, /chat, /cd,
440
450
  - /goal <condition> — set a **completion condition** (Claude Code parity). The
441
451
  agent starts working toward it at once and keeps starting new turns until a
442
452
  separate evaluator model judges the condition met. The goal clears itself
443
- automatically when it is met (or judged impossible), or with `/goal clear`.
444
- The condition is stored in `<project>/.zames-goal` (git-ignored) and restored
445
- on the next launch. `/goal` with no argument shows the current state.
453
+ automatically when it is met (or judged impossible), or with `/goal clear`
454
+ (or its synonym `/goal off`). The condition is stored in `<project>/.zames-goal`
455
+ (git-ignored) and restored on the next launch. `/goal` with no argument — or
456
+ `/goal on` — shows the current state.
446
457
  - /loop <interval> <task> — repeat a task periodically (e.g. `/loop 10m run the
447
458
  tests`). /cron "<min> <hour> <dom> <month> <dow>" <task> — run on a schedule.
448
459
  /jobs [rm <id>|clear] lists and stops them. A fired job is put into the same
@@ -456,8 +467,9 @@ tests`). /cron "<min> <hour> <dom> <month> <dow>" <task> — run on a schedule.
456
467
  "Web search" item in the "+" menu.
457
468
  These (and /queue, /jobs, /goal, `/config <sub>`) can be used WHILE the agent
458
469
  is working — they do not touch the in-flight generation.
459
- - /queue [clear] — list or clear the messages waiting to be sent after the
460
- current task.
470
+ - /queue [list|ls|clear|c|clean] — list (`list`/`ls`) or clear
471
+ (`clear`/`c`/`clean`) the messages waiting to be sent after the current
472
+ task.
461
473
 
462
474
  The token context is also shown live: the status line above the input has the
463
475
  spinner/text on the left and the context on the right (e.g. `125k · 13%`). The
@@ -563,8 +575,7 @@ too):
563
575
 
564
576
  - **Memory** (`@modelcontextprotocol/server-memory`) — a local knowledge graph
565
577
  (9 tools) for durable facts across chats. NOTE: zames already has `MEMORY.md`
566
-
567
- * `AGENTS.md`; add this only if you want a queryable graph.
578
+ + `AGENTS.md`; add this only if you want a queryable graph.
568
579
 
569
580
  Keep the stack SMALL: every server loads its tool definitions into the model's
570
581
  context. Add one when you feel its absence, not before.
@@ -580,13 +591,14 @@ You can view and change settings without leaving the agent — use the
580
591
  toggle in place; numbers and strings open an input prompt.
581
592
 
582
593
  ```
583
- /config interactive settings menu
584
- /config list print all editable settings
594
+ /config interactive settings menu (alias: menu)
595
+ /config list print all editable settings (aliases: show, ls)
585
596
  /config get <path> show a setting
586
597
  /config set <path> <value> change a setting
587
- /config reset <path> reset a setting to its default
588
- /config path show config file paths
598
+ /config reset <path> reset a setting to its default (alias: unset)
599
+ /config path show config file paths (alias: paths)
589
600
  /config lang <ru|en> switch interface and agent language
601
+ (aliases: language, язык)
590
602
  ```
591
603
 
592
604
  Examples:
@@ -821,7 +833,10 @@ zames не вызывает API модели. Он запускает headless C
821
833
  - **Субагенты** — инструмент `Task` поручает самодостаточную подзадачу агенту
822
834
  в отдельном чате (изолированный контекст), который возвращает только отчёт,
823
835
  так что тяжёлая разведка не засоряет основной контекст. Включены по
824
- умолчанию; настраиваются через `browser.subagents` / `browser.maxSubagents`.
836
+ умолчанию; `browser.subagents` выключает их, а `browser.maxSubagents` ограничивает
837
+ число запусков на ОДНУ задачу (по умолчанию 3). Вызовы последовательные,
838
+ не параллельные, и подтип важен: `explore` только читает, `general` может
839
+ править файлы.
825
840
  - **Поддержка MCP** — подключение внешних серверов инструментов (например,
826
841
  `@playwright/mcp`).
827
842
  - **Планировщик** — `/loop`, `/cron` и `/jobs` повторяют задачи по таймеру.
@@ -980,9 +995,13 @@ zames
980
995
  - `Ctrl+_` — отменить последнюю правку строки ввода (случайно нажатые
981
996
  `Ctrl+U` / `Ctrl+K` можно вернуть).
982
997
  - `Ctrl+U` — очистить строку, `Ctrl+K` — удалить до конца строки, `Ctrl+W` —
983
- удалить слово перед курсором, `Ctrl+←`/`Ctrl+→` — переход по словам.
984
- - `\` + `Enter`, `Ctrl+J`, `Ctrl+Enter` или `Shift+Enter` — вставить новую
985
- строку.
998
+ удалить слово перед курсором, `Ctrl+←`/`Ctrl+→` — переход по словам,
999
+ `Ctrl+Delete`/`Alt+Delete` — удалить слово после курсора.
1000
+ - `\` + `Enter` и `Ctrl+J` — вставить новую строку; эти две
1001
+ работают в любом терминале. `Ctrl+Enter` и `Shift+Enter` тоже вставляют
1002
+ строку, но только там, где терминал поддерживает kitty-протокол
1003
+ клавиатуры: без него Shift+Enter приходит как обычный Enter, и
1004
+ сообщение отправляется.
986
1005
  - `/` + `Tab` — подсказки и автодополнение слэш-команд.
987
1006
  - `!команда` — выполнить shell-команду напрямую, минуя модель (как bash-режим
988
1007
  Claude Code). Действует та же песочница, что и для инструмента `Bash`, так
@@ -996,9 +1015,10 @@ zames
996
1015
  никогда не листает историю ввода — история только стрелками.
997
1016
  - `ui.mouseScroll=false` — мышью снова владеет терминал: обычное выделение
998
1017
  текста работает, колесо инертно.
999
- - `PgUp` / `PgDn` — вверх/вниз по диалогу на пол-экрана.
1000
- - `Home` / `End` — прыжок в самый верх / низ диалога (только когда строка ввода
1001
- пуста; при набранном тексте они двигают курсор, как обычно).
1018
+ - колесо мыши, `PgUp` / `PgDn` (пол-экрана) и `Home` / `End` (самый верх / низ)
1019
+ прокручивают диалог; колесо работает при `ui.mouseScroll=true` (по умолчанию), а
1020
+ Home/End прыгают только когда строка ввода пуста (при набранном тексте
1021
+ они двигают курсор, как обычно).
1002
1022
  - Чтобы скопировать БОЛЬШОЙ кусок, используйте `/export` (пишет всю сессию в
1003
1023
  Markdown) или файл транскрипта (`/transcript` покажет путь) — собственным
1004
1024
  выделением терминала за пределы одного экрана не выделить.
@@ -1008,8 +1028,8 @@ zames
1008
1028
 
1009
1029
  ### Картинки и файлы
1010
1030
 
1011
- В строку ввода можно вставить картинку или файл (Ctrl+Shift+V / Shift+Insert
1012
- или собственной вставкой терминала). zames сохраняет его в `<project>/tmp` и
1031
+ В строку ввода можно вставить картинку или файл (Shift+Insert или
1032
+ собственной вставкой терминала; файл из буфера обмена — по Ctrl+V). zames сохраняет его в `<project>/tmp` и
1013
1033
  показывает маркер в строке — `[image#1]` для картинок, `[file#1]` для прочих
1014
1034
  файлов — затем загружает реальный файл в чат вместе с вашим сообщением. Это те
1015
1035
  же форматы, что принимает веб-чат DeepSeek / Qwen / GLM (PNG, JPEG, GIF, WEBP, BMP,
@@ -1079,6 +1099,9 @@ zames --task "..." --output-format jsonl \
1079
1099
  - **Git** — `GitStatus`, `GitDiff`, `GitLog`, `GitShow`, `GitBranchList`,
1080
1100
  `GitAdd`, `GitCommit`, `GitPush`.
1081
1101
  - **Web** — `WebFetch`, `WebSearch`.
1102
+ - **Субагенты** — `Task` (делегировать самодостаточную подзадачу агенту в
1103
+ отдельном чате; `explore` только читает, `general` может править; число
1104
+ запусков на задачу ограничено).
1082
1105
  - **Оператор** — `AskUser` (модальный вопрос с вариантами; в режиме плана не
1083
1106
  предлагается, чтобы не прерывать план).
1084
1107
  - **Служебный** — `respond` (финальный ответ оператору, завершает задачу).
@@ -1127,9 +1150,10 @@ zames --task "..." --output-format jsonl \
1127
1150
  - /review [focus] [--staged] — попросить агента проверить незакоммиченные
1128
1151
  изменения и сообщить находки (без правок кода).
1129
1152
  - /plan [on|off] — режим плана (только чтение). Пока он включён, мутирующие
1130
- инструменты (Write/Edit/MultiEdit/ApplyPatch/Bash, GitAdd/GitCommit/GitPush)
1131
- убраны из набора, чтобы агент изучал код, не трогая дерево. Стартовать в нём
1132
- можно с `--plan`.
1153
+ инструменты (Write/Edit/MultiEdit/ApplyPatch/Bash/BashOutput,
1154
+ GitAdd/GitCommit/GitPush, AskUser) убраны из набора вместе с MCP-инструментами
1155
+ с мутирующим именем, чтобы агент изучал код, не трогая дерево. Стартовать в
1156
+ нём можно с `--plan`.
1133
1157
  - /compact — попросить активный бэкенд сжать текущий чат в передаточное резюме,
1134
1158
  затем открыть НОВЫЙ чат, заново отправить системный промпт и положить резюме как
1135
1159
  перенесённый контекст. Используйте, когда контекст разрастается.
@@ -1137,9 +1161,10 @@ zames --task "..." --output-format jsonl \
1137
1161
  сразу начинает работать над ним и продолжает запускать новые ходы, пока
1138
1162
  отдельная модель-оценщик не признает условие выполненным. Цель снимается
1139
1163
  автоматически при достижении (или если оценщик признал её недостижимой),
1140
- либо командой `/goal clear`. Условие хранится в `<project>/.zames-goal`
1141
- (git-ignored) и восстанавливается при следующем запуске. `/goal` без
1142
- аргумента показывает текущее состояние.
1164
+ либо командой `/goal clear` (синоним — `/goal off`). Условие
1165
+ хранится в `<project>/.zames-goal` (git-ignored) и восстанавливается при
1166
+ следующем запуске. `/goal` без аргумента — или `/goal on` —
1167
+ показывает текущее состояние.
1143
1168
  - /loop <interval> <task> — повторять задачу периодически (например,
1144
1169
  `/loop 10m run the tests`). /cron "<min> <hour> <dom> <month> <dow>" <task> —
1145
1170
  запуск по расписанию. /jobs [rm <id>|clear] перечисляет и останавливает их.
@@ -1153,8 +1178,8 @@ zames --task "..." --output-format jsonl \
1153
1178
  в меню «+».
1154
1179
  Их (а также /queue, /jobs, /goal, `/config <sub>`) можно использовать, ПОКА
1155
1180
  агент работает — они не трогают текущую генерацию.
1156
- - /queue [clear] — показать или очистить сообщения, ждущие отправки после
1157
- текущей задачи.
1181
+ - /queue [list|ls|clear|c|clean] — показать (`list`/`ls`) или очистить
1182
+ (`clear`/`c`/`clean`) сообщения, ждущие отправки после текущей задачи.
1158
1183
 
1159
1184
  Контекст в токенах показывается и вживую: в строке статуса над вводом слева
1160
1185
  спиннер/текст, справа — контекст (например, `125k · 13%`). Процент считается от
@@ -1276,13 +1301,14 @@ MCP-браузер и браузер агента подерутся за оди
1276
1301
  enum переключаются на месте; числа и строки открывают ввод.
1277
1302
 
1278
1303
  ```
1279
- /config интерактивное меню настроек
1280
- /config list показать все изменяемые настройки
1304
+ /config интерактивное меню настроек (алиас: menu)
1305
+ /config list показать все изменяемые настройки (алиасы: show, ls)
1281
1306
  /config get <path> показать настройку
1282
1307
  /config set <path> <value> изменить настройку
1283
- /config reset <path> сбросить настройку к дефолту
1284
- /config path показать пути файлов конфига
1308
+ /config reset <path> сбросить настройку к дефолту (алиас: unset)
1309
+ /config path показать пути файлов конфига (алиас: paths)
1285
1310
  /config lang <ru|en> переключить язык интерфейса и агента
1311
+ (алиасы: language, язык)
1286
1312
  ```
1287
1313
 
1288
1314
  Примеры:
package/SECURITY.md CHANGED
@@ -19,8 +19,8 @@ is not a sandbox:
19
19
  your user. Treat every task you give the agent as code you are willing to
20
20
  run.
21
21
  - The chat-provider credentials in `~/.zames/config.json` and the browser
22
- profiles (`~/.zames/profile`, `~/.zames/qwen-profile`) are sensitive. They
23
- never leave your machine. Files
22
+ profiles (`~/.zames/profile`, `~/.zames/qwen-profile`, `~/.zames/glm-profile`)
23
+ are sensitive. They never leave your machine. Files
24
24
  written by the agent's own state/config writers are created with `0600`
25
25
  permissions, but files created by your own tools or by `Bash` follow your
26
26
  umask.
@@ -40,7 +40,10 @@ is not a sandbox:
40
40
  tools from the model's tool set. Since this release it also drops MCP tools
41
41
  whose names look mutating (click/type/write/...); the classification is a
42
42
  heuristic deny-list, so treat plan mode as a strong hint rather than a hard
43
- guarantee for third-party MCP servers.
43
+ guarantee for third-party MCP servers. It is NOT a security boundary:
44
+ it only makes those tools INVISIBLE to the model for that task —
45
+ `.zames/permissions.json` is unchanged, no OS isolation is added, and a
46
+ server whose tool name the heuristic does not recognise is still offered.
44
47
  - `Write`/`Edit` and the multi-file tools keep a backup (`/undo`,
45
48
  `/undo-list`), but that is an undo safety net, not a security boundary. Give
46
49
  the agent only tasks you are willing to run.
@@ -6,7 +6,7 @@ import { createHash } from 'crypto';
6
6
  import { execFileSync } from 'child_process';
7
7
  import { extractPathToken } from './path-token.js';
8
8
  export { extractPathToken };
9
- export const IMAGE_EXTS = [
9
+ const IMAGE_EXTS = [
10
10
  '.png',
11
11
  '.jpg',
12
12
  '.jpeg',
@@ -16,7 +16,7 @@ export const IMAGE_EXTS = [
16
16
  '.svg',
17
17
  '.ico',
18
18
  ];
19
- export const MAX_ATTACHMENT_BYTES = 20 * 1024 * 1024;
19
+ const MAX_ATTACHMENT_BYTES = 20 * 1024 * 1024;
20
20
  // Stable content hash for de-duplicating identical attachments (a pasted image
21
21
  // is saved to a NEW temp file every time, so its path is not a stable identity).
22
22
  export function contentHash(data) {
@@ -286,7 +286,7 @@ export function hasClipboardTool() {
286
286
  }
287
287
  // True when the Windows filesystem is visible from here, i.e. a
288
288
  // powershell.exe call can reach the Windows clipboard.
289
- export function windowsReachable() {
289
+ function windowsReachable() {
290
290
  if (process.platform === 'win32')
291
291
  return true;
292
292
  if (process.platform !== 'linux')
@@ -410,9 +410,6 @@ export async function readClipboardImageDetailed() {
410
410
  }
411
411
  return { data: null, via: 'unsupported-platform' };
412
412
  }
413
- export async function readClipboardImage() {
414
- return (await readClipboardImageDetailed()).data;
415
- }
416
413
  function tryCommand(bin, args) {
417
414
  try {
418
415
  const out = execFileSync(bin, args, {
@@ -501,7 +498,7 @@ export function winPathToWsl(winPath) {
501
498
  return '/mnt/' + drive + '/' + rest;
502
499
  }
503
500
  // Run the embedded PowerShell script and return the clipboard image bytes.
504
- export async function readWindowsClipboardImage() {
501
+ async function readWindowsClipboardImage() {
505
502
  if (!isWsl())
506
503
  return null;
507
504
  const out = tryCommand('powershell.exe', [
package/dist/backlog.js CHANGED
@@ -13,8 +13,8 @@ const NL = String.fromCharCode(10);
13
13
  const NEW_ITEM_PREFIX = 'N';
14
14
  // Past these thresholds BACKLOG.md costs more tokens (on /improve) than it is
15
15
  // worth, so the operator is nudged to collapse it.
16
- export const BACKLOG_WARN_LINES = 500;
17
- export const BACKLOG_WARN_CHARS = 60_000;
16
+ const BACKLOG_WARN_LINES = 500;
17
+ const BACKLOG_WARN_CHARS = 60_000;
18
18
  // Parse a `/backlog <text>` note into the shape appendBacklogItem() wants. An
19
19
  // optional leading `P0..P3` token sets the priority; the first line becomes the
20
20
  // title and the rest the body. PURE so the operator's note is placed exactly as
@@ -214,7 +214,7 @@ export function sanitizeHeadlessUA(ua) {
214
214
  // reported "no session" for whichever provider had signed in second. A legacy
215
215
  // record without `providers` still reads: `{provider:'qwen'}` means Qwen and a
216
216
  // bare `{at}` means DeepSeek (the only writer before the second backend).
217
- export const AUTH_MARKER_FILE = path.join(os.homedir(), '.zames', 'auth.json');
217
+ const AUTH_MARKER_FILE = path.join(os.homedir(), '.zames', 'auth.json');
218
218
  /**
219
219
  * PURE: does the marker text say `provider` has a stored session? Legacy
220
220
  * shapes are honored (see the comment above AUTH_MARKER_FILE).
@@ -269,7 +269,7 @@ export function mergeAuthMarker(raw, provider, at) {
269
269
  return JSON.stringify({ providers }, null, 2);
270
270
  }
271
271
  // Best-effort: read the marker text from disk ('' when absent/unreadable).
272
- export async function readAuthMarker() {
272
+ async function readAuthMarker() {
273
273
  try {
274
274
  return await fs.readFile(AUTH_MARKER_FILE, 'utf-8');
275
275
  }
package/dist/browser.js CHANGED
@@ -616,7 +616,11 @@ export class DeepSeekBrowser {
616
616
  catch { }
617
617
  },
618
618
  persistSession: () => this._persistSessionIfNeeded(),
619
- notice: (key) => console.log(theme.system(this._t(key))),
619
+ // Route login notices through the SAME notice hook as every other
620
+ // message: a raw console.log is painted OVER by the LineEditor status
621
+ // line, so the operator saw a frozen spinner instead of "a browser
622
+ // window opened" / "login timed out" (see DESIGN-NOTES, onNotice).
623
+ notice: (key) => this._notice(this._t(key)),
620
624
  isAborted: () => this._abort,
621
625
  windowClosed: () => this._windowClosed,
622
626
  sleep: (ms) => new Promise((r) => setTimeout(r, ms)),
@@ -1932,7 +1936,9 @@ export class DeepSeekBrowser {
1932
1936
  catch { }
1933
1937
  }
1934
1938
  else {
1935
- console.error(theme.warn(`⏳ send pause ${secs}s`));
1939
+ // Fallback when no UI hook is wired (a direct ask() from a script):
1940
+ // localize it — the pause is operator-facing text.
1941
+ console.error(theme.warn(translate(this.locale)('spinner.pause', { n: String(secs) })));
1936
1942
  }
1937
1943
  };
1938
1944
  report(gap);
package/dist/commands.js CHANGED
@@ -161,7 +161,7 @@ export function parseTranscript(body) {
161
161
  }
162
162
  return out;
163
163
  }
164
- export const EN_DURATION_UNITS = { h: 'h', m: 'm', s: 's' };
164
+ const EN_DURATION_UNITS = { h: 'h', m: 'm', s: 's' };
165
165
  // Human-readable duration: "8s", "5m 12s", "1h 01m 01s". Seconds are padded
166
166
  // only when a larger unit is present, so a lone "45s" is not "45s" padded.
167
167
  export function formatDuration(ms, units = EN_DURATION_UNITS) {
@@ -336,7 +336,7 @@ export function renderDoctor(d, t = translate('en')) {
336
336
  : t('doctor.not_repo'));
337
337
  row(d.configOk, 'config', d.configOk
338
338
  ? t('doctor.loaded')
339
- : t('doctor.error', { v: d.configError || t('doctor.unknown') }));
339
+ : t('doctor.error', { v: d.configError || t('common.unknown') }));
340
340
  row(true, 'browser', d.browserChannel ? d.browserChannel : t('doctor.bundled'));
341
341
  row(!!d.authSaved, 'auth', d.authSaved ? t('doctor.auth_saved') : t('doctor.auth_none'));
342
342
  row(!!d.clipboardTool, 'clipboard', d.clipboardTool || t('doctor.clipboard_none'));
@@ -421,7 +421,7 @@ export const RESTORED_HISTORY_LIMIT = 20;
421
421
  * history) is far bigger and is filtered by the noise checks below; a real
422
422
  * answer above this size is shortened instead of being dropped.
423
423
  */
424
- export const RESTORED_MESSAGE_MAX = 100_000;
424
+ const RESTORED_MESSAGE_MAX = 100_000;
425
425
  /**
426
426
  * DeepSeek stores the assistant turn VERBATIM: either a raw tool-call JSON
427
427
  * ({"tool":"Read","args":{...}}, frequently dirty/truncated) or a `respond`
@@ -1203,6 +1203,8 @@ export const SLASH_COMMANDS = [
1203
1203
  { name: '/new', key: 'help.cmd.new' },
1204
1204
  { name: '/clear', key: 'help.cmd.new' },
1205
1205
  { name: '/sessions', key: 'help.cmd.sessions' },
1206
+ // ALIAS: /session is handled by the same branch in src/index.ts.
1207
+ { name: '/session', key: 'help.cmd.sessions' },
1206
1208
  { name: '/chats', key: 'help.cmd.chats' },
1207
1209
  { name: '/resume-id', key: 'help.cmd.resume_id' },
1208
1210
  { name: '/last', key: 'help.cmd.last' },
@@ -1223,6 +1225,8 @@ export const SLASH_COMMANDS = [
1223
1225
  { name: '/diff', key: 'help.cmd.diff' },
1224
1226
  { name: '/diffstat', key: 'help.cmd.diffstat' },
1225
1227
  { name: '/cost', key: 'help.cmd.cost' },
1228
+ // ALIAS: /usage takes the same branch as /cost.
1229
+ { name: '/usage', key: 'help.cmd.cost' },
1226
1230
  { name: '/limits', key: 'help.cmd.limits' },
1227
1231
  { name: '/export', key: 'help.cmd.export' },
1228
1232
  { name: '/doctor', key: 'help.cmd.doctor' },
package/dist/compact.js CHANGED
@@ -3,7 +3,7 @@ import { buildCompactPrompt, buildCompactCarryover, isUsableCompactSummary, trim
3
3
  import { loadHooks, runLifecycleHooks } from './hooks.js';
4
4
  const NL = String.fromCharCode(10);
5
5
  /** How many times the summary call is retried before the local fallback. */
6
- export const COMPACT_SUMMARY_ATTEMPTS = 3;
6
+ const COMPACT_SUMMARY_ATTEMPTS = 3;
7
7
  /** How many restored messages the local fallback keeps. */
8
8
  export const COMPACT_FALLBACK_LIMIT = 40;
9
9
  /**
@@ -17,6 +17,11 @@ export const COMPACT_FALLBACK_LIMIT = 40;
17
17
  export async function performCompact(opts) {
18
18
  const { browser, workdir, locale, task, transcript = null, ui = null, buildSystemPrompt, tools, answerTimeoutMs, fallbackLimit = COMPACT_FALLBACK_LIMIT, skipUiLock = false, quiet = false, selfImprovement = false, contextExhausted = false, } = opts;
19
19
  const t = translate(locale);
20
+ // The active provider's LABEL for operator-facing text: performCompact is
21
+ // shared by every backend, so it cannot hardcode "DeepSeek". `providerArg`
22
+ // comes from the caller (the same registry label the rest of the UI shows);
23
+ // the browser is only a fallback for direct callers and tests.
24
+ const providerLabel = opts.providerLabel || 'DeepSeek';
20
25
  const log = (msg) => {
21
26
  if (!quiet)
22
27
  console.error(msg);
@@ -42,7 +47,7 @@ export async function performCompact(opts) {
42
47
  ui.lock(t('msg.input_locked'));
43
48
  try {
44
49
  if (!quiet)
45
- log(t('compact.start'));
50
+ log(t('compact.start', { provider: providerLabel }));
46
51
  // PreCompact hook: runs BEFORE the chat is summarized/rewritten, so
47
52
  // a hook can persist state or notify. Best-effort.
48
53
  try {
package/dist/config.js CHANGED
@@ -748,7 +748,7 @@ function parseConfigValue(field, raw) {
748
748
  export function validateConfigValue(field, raw) {
749
749
  return parseConfigValue(field, raw);
750
750
  }
751
- export function configPathFor(scope) {
751
+ function configPathFor(scope) {
752
752
  return scope === 'project' ? projectConfigPath() : HOME_CONFIG;
753
753
  }
754
754
  /**
package/dist/context.js CHANGED
@@ -66,7 +66,7 @@ const BUILTIN_SKILLS = [
66
66
  // them out of the box; a project skill of the same name overrides them.
67
67
  {
68
68
  name: 'brainstorming',
69
- description: 'Use when the request is a GOAL, not a spec — "add X", "make it better", "integrate Y" — and it is unclear what "done" means.',
69
+ description: 'Use when the operator\'s request is a GOAL, not a spec — "add X", "make it better", "integrate Y" — and it is unclear what "done" means. Draws out the intent and plays it back before building.',
70
70
  body: 'When a request is a goal ("make scrolling feel right"), building ' +
71
71
  'immediately produces the wrong thing fast. First make the intent concrete.\n' +
72
72
  'Pin down: (a) the REAL outcome — what should be TRUE after that is not ' +
@@ -83,7 +83,7 @@ const BUILTIN_SKILLS = [
83
83
  },
84
84
  {
85
85
  name: 'writing-plans',
86
- description: 'Use when a task needs more than one or two tool calls — a multi-file change, a new feature, a refactor. Breaks it into small ordered steps with exact paths and a verification for each.',
86
+ description: 'Use when a task is large enough to need more than one or two tool calls — a multi-file change, a new feature, a refactor. Breaks the work into small ordered steps with exact paths and a verification for each.',
87
87
  body: 'A plan is a sequence of steps a careful engineer with NO project ' +
88
88
  'context could follow. Each step (2-5 minutes) names: the EXACT file ' +
89
89
  'path(s); the concrete edit; how to verify it (command, test name, ' +
@@ -97,11 +97,16 @@ const BUILTIN_SKILLS = [
97
97
  'plan instead of improvising; a 30-step plan means the task should be ' +
98
98
  'split. In zames the plan lives in your reasoning and, for a long task, ' +
99
99
  'in a TodoWrite list — one entry per step. Do not narrate it between tool ' +
100
- 'calls; the todo list IS the visible plan.',
100
+ 'calls; the todo list IS the visible plan. A plan is not a report: the ' +
101
+ 'operator sees ONLY the last respond, so keep the per-step evidence for ' +
102
+ 'that one message. Subagents do not parallelise the plan either — a Task ' +
103
+ 'call is a fresh isolated chat and zames has ONE browser and ONE send ' +
104
+ 'slot, so subagents are sequential and only keep a broad read-only ' +
105
+ 'investigation out of the main context.',
101
106
  },
102
107
  {
103
108
  name: 'test-driven-development',
104
- description: 'Use when writing or changing testable behaviour — a bug fix, a new function, a parser, a formatter. Write the failing test first, watch it fail, then make it pass.',
109
+ description: 'Use when writing or changing behaviour that can be tested — a bug fix, a new function, a parser, a formatter. Write the failing test first, watch it fail, then make it pass. Prevents tests that only pass because they were written against the finished code.',
105
110
  body: 'RED -> GREEN -> REFACTOR. The order is the point, not a formality.\n' +
106
111
  '1. RED — write the smallest test that expresses the new behaviour and ' +
107
112
  'RUN it. It must FAIL for the RIGHT reason ("not implemented", not a ' +
@@ -114,11 +119,16 @@ const BUILTIN_SKILLS = [
114
119
  'for ONE reason with a message that says what broke. In this project a ' +
115
120
  'bug fix ALWAYS gets a regression test reproducing the original bug. ' +
116
121
  'When a test needs fixing, ask whether the TEST or the CODE was wrong; ' +
117
- 'if the code was written before its test, rewrite it driven by the test.',
122
+ 'if the code was written before its test, rewrite it driven by the test.\n' +
123
+ 'A test that writes a temp dir or file cleans it up itself: in this repo ' +
124
+ 'always go through test/tmp-dir.ts (makeTmpDir(t, prefix) / ' +
125
+ 'makeTmpDirSync), which registers the t.after cleanup. On WSL a leaked ' +
126
+ 'os.tmpdir() entry lives inside ext4.vhdx and never returns its space to ' +
127
+ 'the Windows host, so an abandoned temp dir fragments the disk permanently.',
118
128
  },
119
129
  {
120
130
  name: 'systematic-debugging',
121
- description: 'Use when something is broken and the cause is not obvious — a failing test, a wrong result, a hang, a crash. Four phases: reproduce, isolate, hypothesize, fix.',
131
+ description: 'Use when something is broken and the cause is not obvious — a failing test, a wrong result, a hang, a crash. Four phases: reproduce, isolate, hypothesize, fix. Prevents guessing.',
122
132
  body: 'Do NOT start by editing code. Work the four phases in order; each ' +
123
133
  'produces an artifact you can point at.\n' +
124
134
  '1. REPRODUCE — get a command that FAILS the way the operator describes; ' +
@@ -127,7 +137,12 @@ const BUILTIN_SKILLS = [
127
137
  '2. ISOLATE — shrink to the smallest failing unit (bisect, stub, ' +
128
138
  'binary-search). Read the code the failing path ACTUALLY executes. Check ' +
129
139
  'the obvious first: wrong file, stale build, cached state, different ' +
130
- 'config, an error swallowed by a catch.\n' +
140
+ 'config, an error swallowed by a catch. In zames the evidence is already ' +
141
+ 'on disk: the transcript (~/.zames/logs/*.jsonl, /transcript prints this ' +
142
+ "run's path), the raw answer bodies in ~/.zames/net-log with " +
143
+ 'ZAMES_NET_DEBUG=1 (npm run dev sets it), and the per-send telemetry ' +
144
+ '(~/.zames/logs/sends-<provider>.jsonl, dev mode or ' +
145
+ 'browser.sendTelemetry). Read them BEFORE guessing.\n' +
131
146
  '3. HYPOTHESIZE — state it in one sentence and predict what you should ' +
132
147
  'see if it is right; test exactly that. One change at a time; prefer an ' +
133
148
  'observation (log, test assertion) over an edit. If the prediction is ' +
@@ -141,7 +156,7 @@ const BUILTIN_SKILLS = [
141
156
  },
142
157
  {
143
158
  name: 'verification-before-completion',
144
- description: 'Use BEFORE declaring a task done — a feature, a bug fix, a generated file. Forces you to run the verification you promised instead of trusting the code looks right.',
159
+ description: 'Use BEFORE declaring a task done or reporting success — a feature, a bug fix, a file you generated. Forces you to run the verification you promised instead of trusting that the code looks right.',
145
160
  body: '"It should work" is not done. Before reporting success, produce ' +
146
161
  'EVIDENCE from the real artifact, not from your intent.\n' +
147
162
  '1. Re-read the original request; tick every requirement (including the ' +
@@ -155,7 +170,10 @@ const BUILTIN_SKILLS = [
155
170
  'result — so the operator can reproduce it. "Tests pass" without the ' +
156
171
  'command is not evidence.\n' +
157
172
  'If you cannot run the verification, SAY SO explicitly and describe what ' +
158
- 'you did instead; never report "done" implying a check you did not run.',
173
+ 'you did instead; never report "done" implying a check you did not run.\n' +
174
+ 'In zames the report is ONE respond call: the operator reads only the ' +
175
+ 'LAST respond, so put the complete evidence there and never end a turn ' +
176
+ 'on a bare text update with work still pending.',
159
177
  },
160
178
  ];
161
179
  // Per-file budgets. AGENTS.md/MEMORY.md are hand-maintained and grow over
@@ -33,7 +33,7 @@ import { extractAnswer, extractTokenUsage, isFinishedWithoutAnswer, isRateLimitT
33
33
  import { SendRuntime } from './send-runtime.js';
34
34
  import { readGlmBodyFeatures, unsafeGlmModes, glmFlagsMismatch, } from './glm-flags.js';
35
35
  import { interactiveBrowserLogin, loginIsInteractive, canShowWindow, } from './browser-login.js';
36
- export const GLM_USER_DATA_DIR = path.join(os.homedir(), '.zames', 'glm-profile');
36
+ const GLM_USER_DATA_DIR = path.join(os.homedir(), '.zames', 'glm-profile');
37
37
  const MAX_NET_BODY = 64 * 1024;
38
38
  function capNetBody(body) {
39
39
  if (body.length <= MAX_NET_BODY)