zames_pro 2.66.0 → 2.67.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +189 -106
- package/README.md +484 -0
- package/README.ru.md +469 -0
- package/dist/attachments.js +0 -17
- package/dist/context.js +0 -3
- package/dist/extraTools.js +10 -11
- package/dist/fsutil.js +38 -1
- package/dist/gitTools.js +83 -26
- package/dist/index.js +18 -18
- package/dist/input.js +134 -30
- package/dist/mcp.js +49 -10
- package/dist/permissions.js +40 -1
- package/dist/run-task.js +6 -0
- package/dist/sandbox.js +49 -0
- package/dist/scheduler.js +8 -1
- package/dist/self-review.js +37 -17
- package/dist/shell.js +74 -32
- package/dist/tools.js +40 -20
- package/dist/transcript.js +15 -2
- package/dist/web.js +73 -33
- package/package.json +2 -1
- package/scripts/build-readme.mts +129 -0
- package/scripts/coverage-gate.mjs +4 -0
- package/scripts/release.mts +12 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,92 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [2.67.0] - 2026-10-08
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **agent:** one-shot exit code, recursive self-review, MCP dedupe/truncate/plan-filter, transcript flush (N3/N4/N5/N9/N20/N21)
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- **input:** CSI-u Delete, visual-row Up/Down, ESC disambiguation, Ctrl+L/PageUp (N27/N28/N29/N30)
|
|
19
|
+
- **security:** close shell-injection, symlink-escape and SSRF-redirect holes (N1/N2/N6/N7/N17/N18/N19/N22/N23)
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- **tools:** Edit/MultiEdit no longer corrupt dollar patterns (`$&`, `$$`, `$1`)
|
|
24
|
+
in `new_string` — the replacement now uses the functional form instead of a
|
|
25
|
+
string replacer.
|
|
26
|
+
- **tools:** Grep and findstr are run through `execFile` with an argument
|
|
27
|
+
array instead of a shell string, so a `$(...)` pattern is no longer executed
|
|
28
|
+
as a command.
|
|
29
|
+
- **git:** GitShow/GitDiff/GitAdd/GitPush/GitCommit now use `execFile`; `ref`
|
|
30
|
+
and `path` are validated (a leading `-` is rejected) — command/option
|
|
31
|
+
injection through the arguments of read-only tools is closed.
|
|
32
|
+
- **sandbox:** file tools resolve the real path (`fs.realpath`) and reject a
|
|
33
|
+
symlink pointing outside the working directory.
|
|
34
|
+
- **shell:** `assertCommandInsideRoot` expands `~`/`$HOME`, sees a `cd` inside
|
|
35
|
+
a subshell/backticks and rejects `eval` with `cd`.
|
|
36
|
+
- **plan mode:** MCP tools are now filtered for read-only too (mutating verbs
|
|
37
|
+
are dropped).
|
|
38
|
+
- **self-review:** the snapshot and diff/apply walk src/ subdirectories
|
|
39
|
+
recursively (`i18n/`, `input/`) — they used to be silently missing from the
|
|
40
|
+
snapshot.
|
|
41
|
+
- **one-shot `--task`:** on an agent error / iteration limit / watchdog the
|
|
42
|
+
process now exits with code 1 instead of 0.
|
|
43
|
+
- **input:** Ctrl+Delete and Delete now work under the CSI-u (kitty) protocol:
|
|
44
|
+
`CSI 3;5u`/`3;3u`/`3u`.
|
|
45
|
+
- **input:** Up/Down move the cursor across VISUAL rows of a wrapped line, not
|
|
46
|
+
only across logical lines.
|
|
47
|
+
- **input:** a lone ESC no longer aborts the generation when a control
|
|
48
|
+
sequence arrives in two chunks — a short timeout disambiguation.
|
|
49
|
+
- **input:** Ctrl+L clears the screen and PageUp/PageDown page the suggestion
|
|
50
|
+
list; an unknown control sequence is logged in debug instead of being
|
|
51
|
+
swallowed silently.
|
|
52
|
+
- **MCP:** duplicate tool names are disambiguated with a numeric suffix so the
|
|
53
|
+
second tool is not silently unreachable.
|
|
54
|
+
- **MCP:** a tool result is truncated with an explicit marker — a single call
|
|
55
|
+
(browser_snapshot and the like) no longer floods the context.
|
|
56
|
+
- **transcript:** `close()` waits for the flush (it returns a promise) so the
|
|
57
|
+
final events reach the file on the exit paths.
|
|
58
|
+
- **web:** `WebFetch` re-validates every redirect hop against the SSRF guard
|
|
59
|
+
and checks the final URL of a headless render.
|
|
60
|
+
- **permissions:** a `path` rule now also matches the file headers of an
|
|
61
|
+
`ApplyPatch` and path-looking arguments of MCP tools.
|
|
62
|
+
- **scheduler:** `nextCronTime` parses the cron expression once instead of on
|
|
63
|
+
every scanned minute.
|
|
64
|
+
- **git:** `formatGitContext` picks a code fence longer than any backtick run
|
|
65
|
+
in the preview, so a filename with backticks cannot break the markdown.
|
|
66
|
+
- **fsutil:** secrets and state are written with 0600 permissions;
|
|
67
|
+
`writeFileAtomic` fsyncs the file before rename (and the directory after)
|
|
68
|
+
for durability on a power loss.
|
|
69
|
+
|
|
70
|
+
### Changed
|
|
71
|
+
|
|
72
|
+
- **docs:** SECURITY.md updated for the permissions policy, the symlink guard
|
|
73
|
+
and the plan-mode MCP caveat; DEVELOPING.md module sizes refreshed.
|
|
74
|
+
- **cleanup:** removed the dead exports `listConfiguredServers`,
|
|
75
|
+
`builtinSkills` and `findFileByName`.
|
|
76
|
+
- **tests:** the MCP result cap, `htmlToText` and the DuckDuckGo parser are
|
|
77
|
+
now covered, and `web.ts`/`spinner.ts` gained coverage floors.
|
|
78
|
+
|
|
79
|
+
### Security
|
|
80
|
+
|
|
81
|
+
- Shared `shellQuote` helper for arguments passed to the shell (single quotes
|
|
82
|
+
with internal quotes doubled).
|
|
83
|
+
|
|
84
|
+
## [2.66.1] - 2026-10-07
|
|
85
|
+
|
|
86
|
+
### Changed
|
|
87
|
+
|
|
88
|
+
- README: the Russian translation is now folded into `<details>` directly in
|
|
89
|
+
`README.md`, so it can be read on the npm page without leaving GitHub. npm
|
|
90
|
+
renders the readme with the same GitHub Flavored Markdown as GitHub, and a
|
|
91
|
+
separate `README.ru.md` is not visible on the npm page (npm has one readme
|
|
92
|
+
per package). Both language versions are assembled from
|
|
93
|
+
`docs/readme.{en,ru}.md` by `npm run build:readme`;
|
|
94
|
+
`test/readme-built.test.ts` guards against drift.
|
|
95
|
+
|
|
10
96
|
## [2.66.0] - 2026-10-07
|
|
11
97
|
|
|
12
98
|
### Added
|
|
@@ -25,151 +111,148 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
25
111
|
|
|
26
112
|
### Fixed
|
|
27
113
|
|
|
28
|
-
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
- Ctrl+Delete / Ctrl+Backspace (
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
(Alt/Ctrl+Backspace)
|
|
37
|
-
|
|
38
|
-
-
|
|
39
|
-
|
|
40
|
-
(
|
|
41
|
-
|
|
42
|
-
- `/new`
|
|
43
|
-
|
|
44
|
-
|
|
114
|
+
- Long preview lines no longer create a horizontal scrollbar in the terminal:
|
|
115
|
+
`toolCall`/`toolResult` (LineEditor and spinner) now clip the preview by the
|
|
116
|
+
VISIBLE terminal width (`truncateToWidth`) instead of by character count. A
|
|
117
|
+
long command/result used to print wider than the screen.
|
|
118
|
+
- Ctrl+Delete / Ctrl+Backspace (and Alt+Delete / Alt+Backspace) now delete a
|
|
119
|
+
word in the input line. These escape sequences used to fall through the
|
|
120
|
+
generic key skip and did nothing. Supported variants: `ESC[3;5~` (xterm
|
|
121
|
+
Ctrl+Delete), `ESC[3;3~` (Alt+Delete), `ESC DEL`/`ESC 8`
|
|
122
|
+
(Alt/Ctrl+Backspace) and the kitty protocol `ESC[127;5u` / `ESC[127;3u`.
|
|
123
|
+
New `_deleteWordRight()` method + `test/editor-word-delete.test.ts`.
|
|
124
|
+
- The `/config` menu now keeps the SELECTED item on screen: the window is
|
|
125
|
+
built "backwards" from the cursor, taking into account the rows the group
|
|
126
|
+
headings occupy (previously an index-based `scrollTop` could push the
|
|
127
|
+
selected row below the window).
|
|
128
|
+
- `/new` resets the context counter: `_lastTokenUsage` accumulates PER CHAT,
|
|
129
|
+
and without a reset an empty chat kept showing the old `ctx: 302k · 30%`
|
|
130
|
+
until the first send. Test in `test/newchat-verify.test.ts`.
|
|
45
131
|
|
|
46
132
|
## [2.65.0] - 2026-10-07
|
|
47
133
|
|
|
48
134
|
### Changed
|
|
49
135
|
|
|
50
|
-
- README
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
`logo
|
|
59
|
-
сгенерирован). `logo.jpg` удалён и из списка `files` в package.json.
|
|
136
|
+
- The README screenshot `docs/demo.png` was regenerated in English (it used to
|
|
137
|
+
be in Russian). The reproducible generator `npm run render-demo`
|
|
138
|
+
(`scripts/render-demo.mjs`) renders the real editor layout and theme palette
|
|
139
|
+
through headless Chromium with an isolated profile.
|
|
140
|
+
- README: the ASCII "how it works" diagram was replaced by a Mermaid diagram
|
|
141
|
+
(the arrows no longer "float") plus a textual description in words.
|
|
142
|
+
- Removed unused files: `logo.jpg` (only `logo-small.jpg` is used in the
|
|
143
|
+
README) and the `docs/demo.tape` draft (the VHS render was never generated).
|
|
144
|
+
`logo.jpg` was also removed from the `files` list in package.json.
|
|
60
145
|
|
|
61
146
|
### Fixed
|
|
62
147
|
|
|
63
|
-
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
-
|
|
69
|
-
|
|
70
|
-
(`randomThinkingPhrase()`
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
(лишний обратный апостроф) в `src/config-menu.ts`.
|
|
148
|
+
- Terminal repaint after a window resize: the relative erase `ESC[n A` after a
|
|
149
|
+
size change landed on a stale row (the terminal re-flowed the wraps), so the
|
|
150
|
+
status/input were drawn in the wrong place. After a resize the block is
|
|
151
|
+
re-pinned to the bottom (home + padding), and the scrollback history is kept.
|
|
152
|
+
Test in `test/terminal-drift.test.ts`.
|
|
153
|
+
- A live language change (`/config lang`) did not reach two "created once"
|
|
154
|
+
objects: the thinking-phrase spinner took the default language
|
|
155
|
+
(`randomThinkingPhrase()` instead of `randomThinkingPhrase(this.locale)`),
|
|
156
|
+
and `DeepSeekBrowser` printed its notices (`ds.*`) in the language fixed at
|
|
157
|
+
startup. So with an English UI Russian thinking/notice phrases surfaced.
|
|
158
|
+
Added `DeepSeekBrowser.setLocale()`, called from `setConfigRuntime`.
|
|
159
|
+
- The `/config` menu is now drawn as a WINDOW sized to the terminal height
|
|
160
|
+
(previously the whole list of 49 fields was printed as one block). On a short
|
|
161
|
+
terminal the block scrolled off the top, so restoring the cursor with
|
|
162
|
+
`ESC[lastRows A` landed on the wrong row and arrow navigation "did not
|
|
163
|
+
scroll" the list. Also fixed a dead ANSI-strip regex (a stray backtick) in
|
|
164
|
+
`src/config-menu.ts`.
|
|
81
165
|
|
|
82
166
|
## [2.64.1] - 2026-10-07
|
|
83
167
|
|
|
84
168
|
### Changed
|
|
85
169
|
|
|
86
|
-
- README:
|
|
87
|
-
|
|
88
|
-
|
|
170
|
+
- README: added a terminal session screenshot (`docs/demo.png`) under the
|
|
171
|
+
header so the interface is visible immediately; a reproducible VHS demo
|
|
172
|
+
script (`docs/demo.tape`) for a future GIF.
|
|
89
173
|
|
|
90
174
|
## [2.64.0] - 2026-10-06
|
|
91
175
|
|
|
92
176
|
### Added
|
|
93
177
|
|
|
94
|
-
-
|
|
95
|
-
`npm run changelog:draft [ref]`
|
|
96
|
-
|
|
178
|
+
- A CHANGELOG draft generator from conventional commits (BACKLOG D2):
|
|
179
|
+
`npm run changelog:draft [ref]` prints a ready "Unreleased" block from the
|
|
180
|
+
commits after the last tag (or the given ref). Pure module
|
|
97
181
|
`src/changelog.ts` (`parseConventionalCommit` / `groupCommits` /
|
|
98
|
-
`renderChangelogDraft`,
|
|
99
|
-
|
|
182
|
+
`renderChangelogDraft`, unit-tested). The `CHANGELOG.md` file is NOT
|
|
183
|
+
overwritten automatically — the draft is reviewed by hand.
|
|
100
184
|
|
|
101
185
|
### Changed
|
|
102
186
|
|
|
103
|
-
-
|
|
104
|
-
|
|
105
|
-
(`resolveAttachPath` / `inlineAtRefs`) —
|
|
106
|
-
|
|
187
|
+
- Refactor (BACKLOG C3, step 1): attachment path resolution and `@file`
|
|
188
|
+
reference inlining were moved out of `src/index.ts` into
|
|
189
|
+
`src/attach-refs.ts` (`resolveAttachPath` / `inlineAtRefs`) — now a separate
|
|
190
|
+
testable module.
|
|
107
191
|
|
|
108
192
|
## [2.63.1] - 2026-10-06
|
|
109
193
|
|
|
110
194
|
### Fixed
|
|
111
195
|
|
|
112
|
-
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
196
|
+
- Timer flicker in the pre-send pause status: `sendPause()` (both `LineEditor`
|
|
197
|
+
and the non-TTY `SpinnerUI`) repainted the status WITHOUT the
|
|
198
|
+
"elapsed"/task-badge tail, while the animation tick drew it WITH it — once a
|
|
199
|
+
second the `· 1m 50s` label disappeared and reappeared. The update now builds
|
|
200
|
+
the same tail as the tick. Regression test in test/compact-statusline.test.ts.
|
|
117
201
|
|
|
118
202
|
### Changed
|
|
119
203
|
|
|
120
|
-
- README:
|
|
121
|
-
|
|
122
|
-
- Dependabot:
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
204
|
+
- README: centered header, larger logo (640px asset, 430px display), a "How
|
|
205
|
+
it works" diagram, a table of contents and a Links section.
|
|
206
|
+
- Dependabot: major updates are ignored (`semver-major`), monthly schedule,
|
|
207
|
+
auto-merge only for patch/minor and only for bot PRs (author and branch
|
|
208
|
+
checks); auto-merge workflow. The `master` branch is protected by a ruleset:
|
|
209
|
+
PR required, required check is the stable `ci` job.
|
|
126
210
|
|
|
127
211
|
## [2.63.0] - 2026-10-06
|
|
128
212
|
|
|
129
213
|
### Added
|
|
130
214
|
|
|
131
|
-
-
|
|
132
|
-
`.zames/permissions.json` (`default` + `rules`
|
|
133
|
-
`path`
|
|
134
|
-
|
|
135
|
-
`onAskPermission` (
|
|
136
|
-
|
|
137
|
-
(test/permissions.test.ts, test/permissions-loop.test.ts).
|
|
138
|
-
|
|
139
|
-
-
|
|
140
|
-
`argument-hint:`
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
215
|
+
- Real action approvals (BACKLOG C1): an approval policy in
|
|
216
|
+
`.zames/permissions.json` (`default` + `rules` with regexp on
|
|
217
|
+
`tool`/`command`/`path` and an `allow`|`deny`|`ask` action). Evaluated in
|
|
218
|
+
`agent-loop.ts` BEFORE every tool: `deny` blocks the call, `ask` prompts the
|
|
219
|
+
operator via `onAskPermission` (in a TTY — an interactive prompt above the
|
|
220
|
+
input line, in non-TTY — denied). New pure module `src/permissions.ts` +
|
|
221
|
+
tests (test/permissions.test.ts, test/permissions-loop.test.ts).
|
|
222
|
+
|
|
223
|
+
- Custom commands: arguments and hints (BACKLOG B7). Frontmatter
|
|
224
|
+
`argument-hint:` is shown in the "/" list and in `/help` (not inserted into
|
|
225
|
+
the input line), and `arguments:` declares mandatory positional arguments.
|
|
226
|
+
`$1 $2`, named `$name` and the previous `{{args}}`/`$ARGUMENTS` are
|
|
227
|
+
substituted into the command body. If the required arguments are missing the
|
|
228
|
+
command is not sent to the chat and a hint is printed. New pure helpers
|
|
145
229
|
`splitCommandArgs()` / `expandCommandArgs()` / `missingCommandArgs()`
|
|
146
|
-
(src/commands.ts,
|
|
147
|
-
|
|
148
|
-
- Path-scoped
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
`## Scoped instructions (...)` —
|
|
153
|
-
|
|
154
|
-
`renderContextSection()` (src/context.ts, src/system-prompt.ts;
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
`src/path-token.ts` (чистый, покрыт тестами).
|
|
230
|
+
(src/commands.ts, unit-tested).
|
|
231
|
+
|
|
232
|
+
- Path-scoped rules (BACKLOG B6): nested `AGENTS.md`/`MEMORY.md` from the
|
|
233
|
+
subdirectories the task touches are pulled in automatically. The task text is
|
|
234
|
+
scanned for path tokens, the nearest instructions are read for the found
|
|
235
|
+
directories (and their ancestors below the working dir) and rendered as a
|
|
236
|
+
separate `## Scoped instructions (...)` section — explicitly marked as
|
|
237
|
+
applying only to those files. `loadProjectContext(workdir, touchPaths?)` and
|
|
238
|
+
`renderContextSection()` (src/context.ts, src/system-prompt.ts; unit-tested).
|
|
239
|
+
|
|
240
|
+
- `@file` references in a task (BACKLOG B5): `solve the task @src/browser.ts`
|
|
241
|
+
inlines the contents of the referenced file right into the task, saving a
|
|
242
|
+
separate agent turn to read it. `@path` is recognized at a word boundary (at
|
|
243
|
+
the start of a line or after a space/bracket/quote) with a file extension;
|
|
244
|
+
`user@host` and decorators (`@Component`) are not touched. Existing files are
|
|
245
|
+
inlined (60 KB per file, 200 KB total — beyond that a truncation marker),
|
|
246
|
+
missing ones stay as-is. Helper `extractAtFileRefs()` in `src/path-token.ts`
|
|
247
|
+
(pure, unit-tested).
|
|
165
248
|
|
|
166
249
|
### Changed
|
|
167
250
|
|
|
168
|
-
- `AGENTS.md`
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
disclosure —
|
|
172
|
-
|
|
251
|
+
- `AGENTS.md` trimmed (BACKLOG C2): the deep root-cause write-ups ("the agent
|
|
252
|
+
stopped", reading the answer from the DOM, send hooks, `LineEditor`,
|
|
253
|
+
attachments) and the terminal mechanics were moved to
|
|
254
|
+
`docs/DESIGN-NOTES.md` (progressive disclosure — not loaded into every task).
|
|
255
|
+
AGENTS.md keeps the acting rules plus a short summary with a pointer.
|
|
173
256
|
|
|
174
257
|
## [2.62.0]
|
|
175
258
|
|