Changelog
Every zames_pro release in order: what was added, fixed and changed — from the latest release back to the first one.
Every zames_pro release: the newest on top, older versions expandable, and the version list at the start of the page jumps straight to one. (releases: 319)
Unreleased
Unreleased
Fixed
- prompt: do not echo a newline when Ctrl+C aborts the prompt
- tui: show a rejected config value in the error colour
- tui: remove the key-debug stdin listener on dispose
- tui: measure hint chips in visible columns
v2.96.23
v2.96.23
Fixed
- tui: read the log scroll bound live in full-screen mode
- tui: localize the elapsed timer in the status bar
- config: expose browser.fallbackProviders in /config as a comma-separated string
- security: write the auth marker 0600 via the atomic writer
- release: stamp date-released in CITATION.cff on every release
v2.96.22
v2.96.22
Added
- site: fold the changelog jump list by year and link it from the header
v2.96.21
v2.96.21
Fixed
- undo: give the store its own history dir so tests stop racing the shared index
- sessions: keep a __proto__ workdir as an own index key
- commands: pick a placeholder separator the command body does not contain
Changed
- drop the child-process undo test (it re-broke the suite)
v2.96.20
v2.96.20
Fixed
- cost: flatten the transcript path and start time of the report
- diff: clamp the preview bound and never print a leading blank line
- changelog: anchor the Unreleased rewrite on a real heading
- backlog: a fenced heading inside an archive does not block the collapse
- backlog: an id inside a fenced block does not advance the counter
v2.96.19
v2.96.19
Fixed
- provider: flatten an unknown provider label in the /model refusal
- loop: split the interval from the task on any whitespace
- scheduler: reject a cron day-of-month the month never has
- jobs: accept any whitespace after the remove verb
- context-limit: flatten the provider and error text of the live notices
v2.96.18
v2.96.18
Fixed
- resume: flatten the provider names in the refusal message
- queue: a null queue entry no longer crashes the listing
- context: a context file with no content no longer crashes the report
- limits: flatten the telemetry path in the empty-state message
- info: flatten the transcript path printed by /transcript
v2.96.17
v2.96.17
Fixed
- tool-summary: a timeout or a later Error line marks the call failed
- diff: normalize line endings so CRLF is not a whole-file change
- diagnostics: honour a cap smaller than the truncation marker
- path-token: an all-digit extension is a version, not an @file reference
- attach: sniff the content when the stored mime is generic
v2.96.16
v2.96.16
Fixed
- attach-refs: widen the @file fence past the file's own backticks
- attachments: an all-digit extension is a version, not a file name
- tui: count suggestion rows at the popup box width
- tui: place the caret by the actual border style, not a constant
- tui: carry a partial CSI from its ESC, not only mid-parameter
v2.96.15
v2.96.15
Fixed
- tui: clip the full-screen header title so it stays one row
- tui: window the theme picker list to the terminal height
- tui: keep the hint bar to one row by clipping it to the width
- login: reject a password made only of whitespace
- tui: submit a secret prompt verbatim instead of trimming it
v2.96.14
v2.96.14
Fixed
- tui: split a long word in the ask-question box instead of overflowing it
- tui: strip terminal control sequences from a select-list title
- config-menu: shrink the list budget while the theme preview is open
- tui: clamp the full-screen panel so a short terminal is never overflowed
- layout: a non-positive truncation budget yields nothing, not one column over
v2.96.13
v2.96.13
Fixed
- config-menu: measure a row with the shared charWidth rule
- tui: a zero-height log pane windows to one row, not the whole log
- tui: forward Delete does not shorten a value in an end-anchored prompt
- tui: a prompt never inserts the raw DEL byte as text
- doctor: omit an unmeasurable system-prompt size instead of reporting NaN
v2.96.12
v2.96.12
Fixed
- context: omit a non-finite system-prompt size from the report
- i18n: pass the snapshot path under the param the template names
- dev-watch: match the hot list by path so a namesake module is not silenced
- permissions: match a path rule against the arguments of a shell command
- config-menu: decode the terminal stream with one StringDecoder
v2.96.11
v2.96.11
Fixed
- prompt: delete a whole code point in the forward-Delete branch
- completion-check: treat extension-less build files as runnable artifacts
- login: classify a guest page with a captcha as a challenge
- compact: keep the message count in an empty-fallback reason
- restore-history: decode every JSON escape in one pass so a doubled backslash keeps the next escape
v2.96.10
v2.96.10
Fixed
- export: keep a tool result on one line and mark a clipped one
- config: validate a live store value before writing it
- config: an unknown language is rejected instead of silently defaulted
- config: a password keeps its spaces when set from the command line
- transcript: cap the session label so the file name fits the filesystem
v2.96.9
v2.96.9
Fixed
- statusline: a backgrounded child no longer holds the badge until the timeout
- resume: a junk session record is skipped instead of crashing /sessions
- model: a model id with a newline is flattened to one line
- context-limit: a non-finite retry budget gives up instead of retrying forever
- spinner: a dots-only phrase keeps a label instead of going empty
v2.96.8
v2.96.8
Fixed
- ui-health: report a capability listed twice only once
- tui: a throwing store subscriber no longer starves the others
- undo: list(0) returns no rows instead of the whole history
- shell: a cd inside a nested shell is checked by the sandbox
- sandbox: a dangling symlink cannot let a write escape the root
v2.96.7
v2.96.7
Fixed
- tui: a raw DEL byte is not inserted into the input line
- tui: Down after editing a recalled entry moves to the next entry
- tui: Up/Down keep the visual column on wide-glyph wrapped lines
- goal: a quoted verdict example no longer wins over the real verdict
- input: hold only a partial paste marker, not a lone ESC
v2.96.6
v2.96.6
Fixed
- input: drop a dangling ZWJ when a truncation cuts an emoji sequence
- input: count a ZWJ emoji sequence as one glyph in the layout
- tui: ZAMES_NO_BG=0 no longer disables the themed background
- markdown: an unknown code-fence language falls back to plain text
- web: decode an escaped HTML entity only once
v2.96.5
v2.96.5
Fixed
- web: tolerate whitespace around = in a DuckDuckGo result attribute
- web: recognise x-zip and x-msdownload as binary content
- web: drop the page head and keep <pre> code intact when converting HTML
- web: share one in-flight headless context between concurrent fetches
- scheduler: never scan cron forever on a non-finite fromMs
v2.96.4
v2.96.4
Fixed
- tui: keep a tall suggestion popup from overflowing the layout
- scheduler: scan cron in UTC so a DST fall-back hour is not skipped
- context: parse a YAML block list of command arguments
- provider-fallback: probe a guest-capable provider without the guest flag
- cli: accept the --flag=value spelling of a value flag
v2.96.3
v2.96.3
Fixed
- banner: keep a banner field on one line inside the box
- scheduler: reschedule a job whose nextAt is not finite
- goal: keep a condition from injecting its own verdict block
- compact: keep operator and summary text out of the carryover headings
- release: sync the changelog and rebuild its pages inside a release
v2.96.2
v2.96.2
Fixed
- info: keep a /chat and /pwd value on one line
- status: flatten a status/doctor value and drop a broken count
- limits: never render a negative or NaN counter in /limits
- restore-history: keep a plain answer that opens with 'thinking for'
- commands: keep a project file/skill/command name on one /context row
v2.96.1
v2.96.1
Fixed
- release-policy: one pair of parens in the BREAKING note
- changelog: a group heading must start a line, not sit inside a bullet
- backlog: ignore a fenced section header when appending
- dev-watch: follow index.ts's hot-reloadable list (restore-history, input/layout)
- shell: block a recursive rm of ./ and ../ (trailing slash)
v2.96.0
v2.96.0
Added
- loop: dev-only /loop improvement cycles with a release policy
Fixed
- extraTools: apply an insertion-only ApplyPatch hunk from its @@ header
- dev: keep the unparsed-call dump directory bounded
v2.95.6
v2.95.6
Added
- compact: carry the todo checklist and the /goal condition into the new chat
- site: a generated changelog page and one source for RU/EN layout strings
Fixed
- changelog: keep a drafted group heading off the previous bullet
v2.95.5
v2.95.5
Added
- site: a 404 page, hreflang alternates and cache-busted assets
Fixed
- tui: keep the AskUser question and answer in the log
- changelog: keep a manual Unreleased note inside its group
- site: stop the landing title repeating the site name in og:title
- site: give the social preview its own static image
Changed
- tui: paint the AskUser question in the tool color
- drop dead provider-unification modules and stale doc text
- site: a deeper palette, bigger type and calmer cards
v2.95.4
v2.95.4
Fixed
- site: stop the copy buttons from covering or scrolling away
- site: give the hero copy button its shared look and drop demo artifacts
v2.95.3
v2.95.3
Fixed
- deepseek: an appended answer is not a dead turn
- slow start
v2.95.2
v2.95.2
Changed
- fix-deepseek-head-only
- test: pin the streamed-answer head snapshot (the resend loop)
- docs: theme gallery, mobile menu and code copy buttons
v2.95.1
v2.95.1
Fixed
- loop: skip the stall path for a stale BashOutput poll
v2.95.0
v2.95.0
Added
- prompt: send throwaway files to <project>/tmp
v2.94.7
v2.94.7
Fixed
- deepseek: recognise the server-busy notice from the SSE body
v2.94.6
v2.94.6
Fixed
- ui: clear the generating badge as soon as an answer comes back
v2.94.5
v2.94.5
Changed
- deepseek: cut the send-start deadline from 50s to 22s
v2.94.4
v2.94.4
Fixed
- deepseek: never resend a truncated turn while an answer is captured
Changed
- format ask-deadline test
v2.94.3
v2.94.3
Fixed
- deepseek: the watchdog deadline must exceed the answer timeout
v2.94.2
v2.94.2
Fixed
- dev: write the unparsed-call dump into the project workdir
v2.94.1
v2.94.1
Fixed
- dev: dump an unparsed call in the watchdog branch too
v2.94.0
v2.94.0
Added
- dev: dump unrecognized tool calls and hot-reload the parser
v2.93.0
v2.93.0
Fixed
- deepseek: recognize every tool-call shape the chat returns
v2.92.0
v2.92.0
Changed
- Internal improvements.
v2.91.0
v2.91.0
Added
- retry: infinite incremental retries with escalating backoff
Fixed
- qwen,glm: headless login probe and headed runs
- ui: same no-flicker phase rule for qwen and glm
v2.90.18
v2.90.18
Fixed
- self-healing live interaction with the chat
- restore: drop the loop's timeout nudge
- deepseek: do not read a protocol marker mentioned in our own text
- restore: keep the loop's timeout nudge out of the restored dialogue
- browser: stop misreading a completed turn as truncated
Changed
- drop the _netTurnBody and restore-nudge changes
v2.90.17
v2.90.17
Fixed
- self-healing live interaction with the chat
- restore: drop the loop's timeout nudge
- deepseek: do not read a protocol marker mentioned in our own text
- restore: keep the loop's timeout nudge out of the restored dialogue
- browser: stop misreading a completed turn as truncated
Changed
- drop the _netTurnBody and restore-nudge changes
v2.90.16
v2.90.16
Fixed
- browser: apply the sanitized headless UA to the relaunch explicitly
v2.90.15
v2.90.15
Changed
- test(browser): pin the headless user-agent sanitizer contract
v2.90.14
v2.90.14
Fixed
- sandbox: block a recursive rm of an absolute or outside path
v2.90.13
v2.90.13
Fixed
- apply-patch: start each hunk search where the previous one ended
v2.90.12
v2.90.12
Fixed
- input: keep the legacy reverse-search position when the query is refined
v2.90.11
v2.90.11
Fixed
- input: stop legacy word movement and deletion at a newline
v2.90.10
v2.90.10
Fixed
- commands: never cut a restored message in the middle of a surrogate pair
v2.90.9
v2.90.9
Fixed
- ui: strip OSC escapes when measuring the banner and config-menu width
v2.90.8
v2.90.8
Fixed
- tui: copy an OSC escape whole and do not count its body as visible width
v2.90.7
v2.90.7
Fixed
- handoff: a legacy GLM handoff no longer claims Qwen wrote it
v2.90.6
v2.90.6
Fixed
- tui: keep the reverse-search position when the query is refined
v2.90.5
v2.90.5
Fixed
- commands: keep an explicitly empty quoted argument as a supplied position
v2.90.4
v2.90.4
Fixed
- ui: safeJson(undefined) returns a string, not the value undefined
v2.90.3
v2.90.3
Fixed
- ui: keep a tool detail on a negative clip budget instead of a lone ellipsis
v2.90.2
v2.90.2
Fixed
- web: treat the IPv4-translated ::ffff:0:a.b.c.d literal as private
v2.90.1
v2.90.1
Fixed
- tui: fit the turn rule and agent answers to the pane width, not the terminal
v2.90.0
v2.90.0
Added
- ui: use the full terminal width instead of capping the content at 100 columns
- doctor: wire the prompt size, password store and swallowed tags into /doctor
- tui: keep a gutter on both sides so the UI is not flush with the terminal edges
- first-run: ask for language and provider once, before the input loop
- provider: continue a task on an authorized fallback provider
- browser: count swallowed failures instead of silent catches
- config: add the password store and fallback provider settings
- commands: introduce the slash-command registry and its five groups
- browser: model the ask phase decision as a pure state machine
- browser: share the send slot and the ask retry policy
- browser: share the helpers and the error families across providers
- dev: warn about every non-reloadable module, not just browser.ts
- doctor: report where the provider password is stored
- doctor: report the system prompt size against its budget
- config: choose the password store
- first-run: add the wizard step logic
- provider: add the fallback decision
- prompt: pin the system prompt budget
- swallow: count swallowed exceptions
- i18n: default to English on the first run
- agent-loop: nudge once when a code edit was never verified
Fixed
- input: the wrap break space belongs to neither row (no stray indent)
- tui: count the gutter in the caret column so it sits after the typed text
- tui: stop the ora spinner from fighting the TUI (53 MB/s redraw storm)
- tui: put the caret on the input row when the suggestion popup is open
- tui: run /tasks live while the agent works instead of queueing it
- tui: draw the operator bar on every row of a multi-line message
- first-run: run the wizard before the browser so its provider is the one launched
- first-run: read the language as a word, not a y/N dialog
- browser: keep the resumed chat open across a restart and a page relaunch
Changed
- commands: dispatch the dev-only group through the registry
- commands: dispatch the scheduler and context group through the registry
- commands: dispatch the git, undo and rewind group through the registry
- commands: dispatch the session and chat group through the registry
- commands: dispatch the informational group through the registry
- i18n: drop the browser-only reload hint superseded by the generic one
v2.89.0
v2.89.0
Added
- config: two-level /config menu with groups and sections
- config: diagnostics settings (post-edit check command, timeout, output cap) are now editable from
/config
v2.88.2
v2.88.2
Changed
- docs: no manual step — the agent owns every file and every release action
v2.88.1
v2.88.1
Changed
- docs: restore the demo.png reference in README; document the note files
v2.88.0
v2.88.0
Added
- ui: switch the theme while the agent is generating
v2.87.0
v2.87.0
Added
- ui: light palettes, themed task badge, readable config menu on light themes
v2.86.1
v2.86.1
Fixed
- ui: the operator bar on every row, screenshots for all themes
v2.86.0
v2.86.0
Added
- ui: 10 more palettes, no sample dump after picking, picker smoke
v2.85.0
v2.85.0
Added
- ui: theme the window background, keep the unsent draft, drop the extra prompt caret
v2.84.0
v2.84.0
Added
- ui: theme previews, 6 more palettes, inline /config preview
v2.83.4
v2.83.4
Fixed
- ui: theme the input text, the status row and the input frame
v2.83.2
v2.83.2
Fixed
- ui: repaint the model answer and the code highlighting on a theme switch
v2.83.1
v2.83.1
Added
- ui: /theme pick list with live preview
v2.83.0
v2.83.0
Added
- ui: selectable terminal color themes
v2.82.142
v2.82.142
Fixed
- release: bump package-lock.json root versions too
v2.82.141
v2.82.141
Fixed
- i18n: /rewind help names --yes and the default point
- i18n: /web help lists the /websearch alias
- i18n: /config help lists its subcommand aliases
- i18n: /queue help lists its list/clear aliases
- i18n: /goal help lists the off and on forms
- i18n: json and jsonl are the same event stream
- i18n: the /loop floor is not a 15s provider throttle
- help: list the /session and /usage aliases
- i18n: drop the duplicate backslash newline hint
- tui: enable the kitty keyboard protocol so Shift+Enter works
- i18n: drop the duplicate status.review_none key
- i18n: /status says MCP tools is a count, not a list
- i18n: the empty-screen hint names a working newline key
- prompt: say that plan mode also hides mutating MCP tools
- prompt: list every *_base64 escape hatch
- i18n: plan mode lists every dropped tool, MCP included
- prompt: decode the terminal bytes across reads, not per read
- i18n: the clipboard hint names the real Wayland and Windows tools
- i18n: the doctor auth row describes the sign-in marker it actually reads
- i18n: the Qwen guest notice says /provider login opens the window itself
- i18n: each full-screen key hint names its own mouse mode
- i18n: the TUI key hint does not advertise a wheel that is off
- i18n: Esc in the AskUser modal means no answer, not dismiss
- i18n: keep prompt.answer_language English in both locales
- mcp: localize the floating-version warning
- browser: localize the send-pause fallback line
- browser: DeepSeek login notices go through the UI hook
- compact: fill the {provider} placeholder in compact.start
- i18n: AskUser free-text mode explains how to send
- llms: generated header says GLM runs headed too
- i18n: suggestion hint says Ctrl+N/P select, not scroll
- i18n: startup hint shows Ctrl+V for clipboard images too
- i18n: /last says there is no session for THIS directory
- i18n: drop the unverified ~10 messages/day guest quota claim
- i18n: keep the agent-facing ONLY TOOL CALLS block English in both locales
- i18n: MCP hint lists the .mcp.json path too
- i18n: help shows the real clipboard paste binding (Ctrl+V)
- i18n: GLM guest_limit message says the quota is exhausted
- i18n: deepseek send_no_start states the real ~50s budget
- i18n: describe both mouseScroll states and the real default
- i18n: translate the English /status labels into Russian
Changed
- i18n: drop the duplicate doctor.unknown and msg.not_dir keys
v2.82.140
v2.82.140
Fixed
- scheduler: stop the ticker on exit; correct the abort help line
- config: say when a project config overrides the home one
v2.82.139
v2.82.139
Changed
- docs(test/security-sandbox): drop the backlog priority label
- docs(test): remove the last backlog ids (I2, U2/U3)
- docs(test/extra-tools): drop a backlog id from a section header
- docs(test/cancel-ask): stop quoting a stale watchdog deadline
- docs(test/send-runtime-block-lift): fix a header that contradicted its own fix
- docs(test/tui-hints-locale): wrap two over-long comment lines
- docs(test/tui-hints-locale): wrap the over-long note
- docs(test): translate leftover Russian comments
- docs(test/readme-built): say why a second readme is forbidden
- docs(test/readme-built): say why a second readme is forbidden
- docs(test/agent-loop): state why the first send is not an agent turn
- docs(test/statusline-cap): untangle the settle-vs-exit note
- docs(test/i18n-unused): drop the shouting prefix
- docs(test/legacy-paste-marker): drop a time-relative word
- docs(test): replace first-person narration with the subject
- docs(test/continue-button): drop the first-person narration
- docs(test/auto-compact): drop a pointer to the fixture value
- docs(test/run-task): drop the refactor history from the header
- docs(test/attach-flow-shared): keep only the why of the fake clock
- docs(test/send-telemetry-nan-block): drop a case that lives in another test
- docs(test/wsl): state the real reason instead of the CI setup
- docs(test/agent-loop-robust): name the retry budget constant
- docs(test/diff-large-file): stop quoting a removed source comment
- docs(test/auth-login): trim a comment that restated its asserts
- docs(agents): remove the last backlog ids from the root instructions
- docs(scripts): remove backlog ids from scenario comments
- docs(test/generation-incomplete): stop quoting a stale watchdog value
- docs(test/cancel-ask): drop the runner version from the keep-alive note
- docs(test/cli-flags): name the skip-list constant
- docs(test/continue-button): name the real continue constant
- docs(test/finished-answer-plain-json): name the real constants
- docs(test/tool-name-resolution): drop the meta clause
- docs(test/mcp-truncate-surrogate): finish the meta-narration cleanup
- docs(test): drop meta-narration from test comments
- docs(test/log-window): state the bug instead of narrating the test
- docs(readme): mention /rewind next to /undo
- docs(llms): regenerate llms-full.txt after the readme fixes
- docs(readme): clarify the per-provider context window sentence
- docs(readme): the Qwen send pause is 4 s, not 1 s
- docs(readme): the context percentage is per provider, not always 1M
- docs(readme): complete the CLI options block
- docs(readme): list BashOutput and AskUser among the tools
- docs(readme): make the slash-command list match SLASH_COMMANDS
- docs(scripts): fix a typo in the build-readme usage line
- docs(test/agent-loop-robust): fix a section header that contradicted the code
- docs(test/i18n-unused): tighten the vacuously-green note
- docs(test/attach-flow): drop a what-comment
- docs(test/browser-login): drop a duplicated probe walkthrough
- docs(scripts): document the postinstall contract
- docs(test/agent-facing-english): point at the split i18n catalog
- docs(test): remove backlog ids missed by the first sweep
- docs(developing): refresh module sizes and drop backlog ids
- docs(agents): drop backlog ids from the module map
- docs(agents): the providers are three, with three profiles
- docs(contributing): fix the provider list and the dev-mode description
- docs(citation): sync the version and keep CITATION.cff updated on release
- docs(readme): mention GLM in the provider section
- docs(readme): fix three default/config facts (mouseScroll, telemetry, config write target)
- docs(readme): state the real Node.js requirement (>= 22)
- docs(design-notes): replace a backlog id with the actual reason
- docs(scripts): translate a Russian header and drop backlog ids
- docs(test/xml): prune and fix stale comments
- docs(test/subagent): prune stale comments
- docs(test/ssrf): prune stale comments
- docs(test/skill): prune and fix stale comments
- docs(test/mcp): prune stale comments and translate a leftover Russian note
- docs(test/i18n): repair a corrupted word and prune stale comments
- docs(test/glm): prune and fix stale comments
- docs(test/editor): drop remaining backlog ids
- docs(test/editor): prune and fix stale comments
- docs(test/context): prune and fix stale comments
- docs(test/config): prune and fix stale comments
- docs(test/cli): prune and fix stale comments
- docs(test/browser): prune and fix stale comments
- docs(test/backlog): prune and fix stale comments
- docs(test/answer-parse): prune and fix stale comments
- docs(test/agent-loop): prune and fix stale comments
- docs: add a text-audit protocol for an unattended loop run
v2.82.138
v2.82.138
Changed
- docs(types): fix a stale provider count
- docs(tui/widgets): prune a section divider
- docs(tui): prune section dividers
- docs(system-prompt): drop a backlog-id reference
- docs(statusline): prune and fix stale comments
- docs(status-command): prune and fix stale comments
- docs(spinner): prune and fix stale comments
- docs(shell): prune and fix stale comments
- docs(sessions): prune and fix stale comments
- docs(send-throttle): prune and fix stale comments
- docs(send-telemetry): prune and fix stale comments
- docs(send-runtime): prune and fix stale comments
- docs(self-review): prune section dividers
- docs(run-task): prune and fix stale comments
- docs(qwen-ui): prune and fix stale comments
- docs(qwen-net-capture): prune and fix stale comments
- docs(qwen-chats): prune and fix stale comments
- docs(qwen-browser): prune section dividers
- docs(prompt): prune and fix stale comments
- docs(permissions): prune and fix stale comments
- docs(path-token): prune and fix stale comments
- docs(net-capture): prune and fix stale comments
- docs(mcp): prune and fix stale comments
- docs(markdown): prune and fix stale comments
- docs(limits-command): prune and fix stale comments
- docs(input/suggest): prune and fix stale comments
- docs(input/layout): drop a backlog-id reference
- docs(input): prune backlog ids and section dividers
- docs(index): prune section dividers
- docs(i18n): prune and fix stale comments
- docs(i18n): drop backlog-id references from common.ts comments
- docs(goal): prune and fix stale comments
- docs(glm-ui): prune and fix stale comments
- docs(glm-net-capture): prune and fix stale comments
- docs(glm-chats): prune and fix stale comments
- docs(glm-browser): prune and fix stale comments
- docs(glm-browser): prune and fix stale comments
- docs(gitTools): prune and fix stale comments
- docs(fsutil): prune and fix stale comments
- docs(extraTools): prune and fix stale comments
- docs(diff): prune and fix stale comments
- docs(diagnostics): prune and fix stale comments
- docs(deepseek-ui): prune and fix stale comments
- docs(config): prune and fix stale comments
- docs(config-menu): prune and fix stale comments
- docs(config-live): prune and fix stale comments
- docs(config-commands): prune and fix stale comments
- docs(config-command): prune and fix stale comments
- docs(commands): prune and fix stale comments
- docs(code-blocks): prune and fix stale comments
- docs(cli-args): prune and fix stale comments
- docs(checkpoint): prune and fix stale comments
- docs(changelog): prune and fix stale comments
- docs(browser): prune and fix stale comments
- docs(browser-pure): prune and fix stale comments
- docs(browser-login): prune and fix stale comments
- docs(browser-dom): prune and fix stale comments
- docs(browser-chats): prune and fix stale comments
- docs(banner): prune and fix stale comments
- docs(backlog): prune and fix stale comments
- docs(attachments): prune and fix stale comments
- docs(attach-refs): prune and fix stale comments
- docs(attach-flow): prune and fix stale comments
- docs(answer-parse): prune and fix stale comments
- docs(agent-loop): prune and fix stale comments
v2.82.137
v2.82.137
Changed
- docs: drop backlog-id references from source comments
v2.82.136
v2.82.136
Fixed
- spinner: a live language switch reaches the non-TTY spinner
v2.82.135
v2.82.135
Changed
- tui: one pure helper owns the full-screen layout arithmetic
v2.82.134
v2.82.134
Fixed
- input: the legacy editor forgets a deleted paste body too
v2.82.133
v2.82.133
Fixed
- tui,glm: a deleted paste body is forgotten; a message id is not a chat id
v2.82.132
v2.82.132
Fixed
- backlog: a heading with no text after the id keeps a usable title
v2.82.131
v2.82.131
Fixed
- status: a negative MCP tool count is not printed
v2.82.130
v2.82.130
Fixed
- goal: a prose answer mentioning DSML still yields its verdict
v2.82.129
v2.82.129
Fixed
- tui: a compact token count never renders 1000k or 1000.0M
v2.82.128
v2.82.128
Fixed
- qwen: a negative usage count is not a context size
v2.82.127
v2.82.127
Changed
- Internal improvements.
v2.82.126
v2.82.126
Fixed
- resume: an answer that merely mentions DSML is not dropped
v2.82.125
v2.82.125
Fixed
- doctor: a value with a newline cannot fake a doctor row
v2.82.124
v2.82.124
Fixed
- mcp: a schema property named proto becomes a real parameter
v2.82.123
v2.82.123
Fixed
- mcp: a duplicate tool rename does not steal a later tool name
v2.82.122
v2.82.122
Fixed
- context: a file that does not fit the pool does not drop the rest
v2.82.121
v2.82.121
Fixed
- tui: the input history stores the expanded paste, not its marker
v2.82.120
v2.82.120
Fixed
- diff: a huge file no longer exhausts memory in the diff
v2.82.119
v2.82.119
Fixed
- throttle: cap a huge Retry-After so the agent is not frozen
v2.82.118
v2.82.118
Fixed
- subagent: an empty report is not passed on as a successful result
v2.82.117
v2.82.117
Fixed
- commands: operator text cannot spoof a queued-message boundary
v2.82.116
v2.82.116
Fixed
- attachments: wait for the upload chip by exact file name
v2.82.115
v2.82.115
Fixed
- hooks: a big Write is not blocked by a hook's env size limit
v2.82.114
v2.82.114
Fixed
- scheduler: a multi-line job task cannot fake a /jobs line
v2.82.113
v2.82.113
Fixed
- status: a multi-line goal cannot fake a /status line
v2.82.112
v2.82.112
Fixed
- ui-health: a capability with no selectors is not reported missing
v2.82.111
v2.82.111
Fixed
- cost: a tool name with a newline cannot break the /cost report
v2.82.110
v2.82.110
Fixed
- commands: a dollar token inside a custom-command argument is not expanded twice
v2.82.109
v2.82.109
Fixed
- tui: a failure phrase inside the output does not mark the call failed
v2.82.108
v2.82.108
Fixed
- diagnostics: a mid-line tsc error is not hidden by a zero banner
v2.82.107
v2.82.107
Fixed
- prompt: a multi-line skill description cannot inject a prompt section
v2.82.106
v2.82.106
Fixed
- goal: a tool call mentioning VERDICT: MET does not clear the goal
v2.82.105
v2.82.105
Fixed
- tui: keep a colour reset when truncating styled text
v2.82.104
v2.82.104
Fixed
- fsutil: write through a dangling symlink instead of replacing it
v2.82.103
v2.82.103
Fixed
- code-blocks: a fence with a backtick in its info still opens a block
v2.82.102
v2.82.102
Fixed
- attachments: recognize non-Latin and punctuated file names
v2.82.101
v2.82.101
Fixed
- commands: a non-string respond message is not shown as the answer
v2.82.100
v2.82.100
Fixed
- i18n: localize the untitled label of a scraped chat row
v2.82.99
v2.82.99
Fixed
- send-runtime: record the block duration on the successful retry
v2.82.98
v2.82.98
Fixed
- checkpoint: a tar spawn error is reported, not thrown
v2.82.97
v2.82.97
Fixed
- qwen: restore dialogue order from an ISO history timestamp
v2.82.96
v2.82.96
Fixed
- telemetry: keep the average block duration finite in /limits
v2.82.95
v2.82.95
Fixed
- mcp: use toolResult when content carries nothing usable
v2.82.94
v2.82.94
Fixed
- web: WebFetch cap does not split a surrogate pair
v2.82.93
v2.82.93
Fixed
- web: collapse a duplicated search result URL
v2.82.92
v2.82.92
Fixed
- goal: collapse whitespace in the evaluator reason
v2.82.91
v2.82.91
Fixed
- goal: a goal cannot inject a second Current task section
v2.82.90
v2.82.90
Fixed
- commands: a dynamic hint name is normalized to a slash command
v2.82.89
v2.82.89
Fixed
- self-review: collapse whitespace in the focus text
v2.82.88
v2.82.88
Fixed
- cost: a non-finite elapsed no longer makes the duration Infinity
v2.82.87
v2.82.87
Fixed
- export: do not split a surrogate pair when clipping a tool result
v2.82.86
v2.82.86
Fixed
- review: collapse whitespace in the review focus text
v2.82.85
v2.82.85
Fixed
- undo: never print Invalid Date in /undo-list and /checkpoints
v2.82.84
v2.82.84
Fixed
- cost: never print a negative context token count
v2.82.83
v2.82.83
Fixed
- diagnostics: a zero banner no longer hides a real error line
v2.82.82
v2.82.82
Fixed
- backlog: collapse whitespace in an item title
v2.82.81
v2.82.81
Fixed
- config: a null section no longer wipes its defaults
v2.82.80
v2.82.80
Fixed
- history: trim the role before comparing it (all three providers)
v2.82.79
v2.82.79
Fixed
- glm: keep a duplicated chat id once in the chat list
v2.82.78
v2.82.78
Fixed
- qwen: keep a duplicated chat id once in the chat list
v2.82.77
v2.82.77
Fixed
- scheduler: a zero-interval loop no longer fires on every tick
v2.82.76
v2.82.76
Fixed
- login: askPassword Backspace deletes a whole code point
v2.82.75
v2.82.75
Fixed
- xml: keep an escaped quote inside an invoke attribute value
v2.82.74
v2.82.74
Fixed
- commands: collapse dynamic slash hints that differ only by case
v2.82.73
v2.82.73
Fixed
- telemetry: do not average a missing block duration as zero
v2.82.72
v2.82.72
Fixed
- config: reject a non-finite live timing value and re-derive the deadline
v2.82.71
v2.82.71
Fixed
- prompt: Backspace deletes a whole code point in promptOnce
v2.82.70
v2.82.70
Fixed
- transcript: keep a capped line valid JSON so the event is not lost
v2.82.69
v2.82.69
Fixed
- attachments: keep the extension when a temp name is capped
v2.82.68
v2.82.68
Fixed
- tools: do not drop read-only MCP tools from plan mode
v2.82.67
v2.82.67
Fixed
- tui: Up/Down in a wrapped input keeps the visual column
v2.82.66
v2.82.66
Fixed
- tui: append a space when Tab completion lands on a full command name
v2.82.65
v2.82.65
Fixed
- attachments: show gigabytes and never a non-finite size
v2.82.64
v2.82.64
Fixed
- attachments: never render a size as 1024.0 KB
v2.82.63
v2.82.63
Fixed
- tui: truncateToWidth never cuts inside an ANSI escape
v2.82.62
v2.82.62
Fixed
- attachments: do not inline a binary @file reference as text
v2.82.61
v2.82.61
Fixed
- tools: Glob cannot report files outside the project root
v2.82.60
v2.82.60
Fixed
- permissions: scan nested path arguments for every tool, not only MCP
v2.82.59
v2.82.59
Fixed
- commands: /diffstat hides the padded no-output sentinel
v2.82.58
v2.82.58
Fixed
- commands: keep a long answer in the restored dialogue instead of dropping it
v2.82.57
v2.82.57
Fixed
- shell: strip every quote from a cd target before the sandbox check
v2.82.56
v2.82.56
Fixed
- tool-summary: mark an MCP failure as an error, not a success
- tools: answer Read failures in the tool's own words
- paste: never swap the bodies of two same-size pastes
v2.82.55
v2.82.55
Fixed
- deepseek: require a boundary around HTTP status codes in the busy matcher
- toolcall: require an attribute boundary before the tool name
v2.82.54
v2.82.54
Fixed
- telemetry: measure a rate-limit block once, at the lift
- hooks: load the config before firing the Stop hook
- history: match fragment types case-insensitively in every parser
v2.82.53
v2.82.53
Fixed
- glm: keep a message without a timestamp in dialogue order
- qwen: keep a message without a timestamp in dialogue order
- rewind: resolve a full checkpoint stamp against the whole index
v2.82.52
v2.82.52
Fixed
- config: tolerate an unparsable config file when writing
- tui: use the shared width table when estimating log rows
Changed
- tui: derive the input box width from the shared helper
v2.82.51
v2.82.51
Added
- seo: make the project findable by search engines and AI crawlers
- scripts: glm-warmup opens a visible z.ai window to pass the captcha once
Fixed
- subagent: do not log subagent_start twice per Task call
- web: parse DuckDuckGo results whose attributes are single-quoted
- mcp: keep a schema whose type is a list in the tool description
- attach: honour the @ref total budget instead of inlining a whole file over it
- context: clip AGENTS.md/MEMORY.md without splitting a surrogate pair
- loop: a plain-text answer is re-asked with a real reason, watchdog retry no longer resends the task
- tools: reject a non-string path instead of writing [object Object]
Changed
- comments: drop dead backlog ids from source comments
v2.82.50
v2.82.50
Fixed
- i18n: a prototype member is not a translation
- path-token: split semicolon-separated @file lists
- tui: keep a tall log entry inside the viewport when scrolling
- resume: refuse a session owned by another provider
- tui: skip OSC sequences when measuring log rows
- layout: wrapToWidth keeps every line within the width
- tools: trim allowed-tools entries before matching
- config: getByPath must not walk the prototype chain
- context: strip a BOM before parsing the frontmatter
- telemetry: a provider id must not escape the log directory
- throttle: a non-finite retryAfterMs must not block forever
- auth: do not migrate a legacy GLM marker to deepseek
- qwen: accept a bare array under chat.history
- qwen: a quota_limit mention inside an answer is not a rate limit
- glm: a quota phrase inside an answer is not a quota error
- glm: order the restored dialogue by an ISO timestamp too
- attach: a throwing preview lookup must not abort the attach
- handoff: clear the side handoff files too
- loop: resolve a padded or upper-cased tool name
- mcp: honour a profile flag given inside the command
- config: re-derive the ask deadline when the answer timeout changes live
- diff: compare lines with an LCS instead of by position
- goal: a verdict must not match the head of a word
- telemetry: ignore a send event dated in the future
- tui: show a sandbox refusal as a failed tool call
- config: the list does not mask a whitespace-only password
- attach: never treat a URL as a local file path
- chats: reject a negative accumulated_token_usage on restore
- qwen: never return a thinking-phase object as the answer
- glm: reject a negative token usage
- undo: tolerate a corrupt undo index
- permissions: match a command rule in nested MCP args
- status: fall back to the default context window on an invalid limit
- input: count blank lines at the end of a paste
v2.82.49
v2.82.49
Fixed
- goal: /goal on no longer overwrites the goal text
v2.82.48
v2.82.48
Fixed
- sessions: cap the stored todo checklist
v2.82.47
v2.82.47
Fixed
- checkpoint: take the pre-rewind backup after a successful extract
v2.82.46
v2.82.46
Fixed
- undo: report no backup for an unreadable target
v2.82.45
v2.82.45
Fixed
- net-log: rotate only real dumps, never a foreign txt
v2.82.44
v2.82.44
Fixed
- transcript: rotate by timestamp, not by the workdir label
v2.82.43
v2.82.43
Fixed
- telemetry: record the block start with the adaptive throttle off
v2.82.42
v2.82.42
Fixed
- throttle: let a forced Retry-After wait expire
v2.82.41
v2.82.41
Fixed
- telemetry: accept a stringified blockMs in the average
v2.82.40
v2.82.40
Fixed
- transcript: cap a single logged payload
v2.82.39
v2.82.39
Fixed
- config: do not mask a whitespace-only password
v2.82.38
v2.82.38
Fixed
- config: dispatch /config subcommands after the command name
v2.82.37
v2.82.37
Fixed
- config: give hotReload a default so it can be reset
v2.82.36
v2.82.36
Fixed
- handoff: keep a pending handoff of another workdir
v2.82.35
v2.82.35
Fixed
- checkpoint: rebuild the index when index.json is corrupt
v2.82.34
v2.82.34
Fixed
- undo: report no backup when retention is zero
v2.82.33
v2.82.33
Fixed
- sessions: show a distant future timestamp as future, not now
v2.82.32
v2.82.32
Fixed
- git: split a comma-separated paths argument
v2.82.31
v2.82.31
Fixed
- mcp: keep a string content block whole
v2.82.30
v2.82.30
Fixed
- statusline: kill the whole process group on timeout
v2.82.29
v2.82.29
Fixed
- subagent: log the sub-task description with the run
v2.82.28
v2.82.28
Fixed
- scheduler: render a zero interval as 0s, not 0h
v2.82.27
v2.82.27
Fixed
- attachments: reject a data URL with an empty payload
v2.82.26
v2.82.26
Fixed
- context: split a comma-separated @file list into references
v2.82.25
v2.82.25
Fixed
- context: pull scoped AGENTS.md for a file path in the task
v2.82.24
v2.82.24
Fixed
- permissions: drop a rule with an unknown condition key
v2.82.23
v2.82.23
Fixed
- shell: normalize the runFile timeout instead of throwing
v2.82.22
v2.82.22
Fixed
- web: keep table cells apart in htmlToText
v2.82.21
v2.82.21
Fixed
- glm: unwrap nested pagination wrappers in the chat list
v2.82.20
v2.82.20
Fixed
- qwen: unwrap a paginated chat-list wrapper
v2.82.19
v2.82.19
Fixed
- glm: unwrap a nested chats wrapper in the chat list
Changed
- glm: drop guessed role fields from the history parser
v2.82.18
v2.82.18
Fixed
- ci: merge cache-busted coverage rows so the gate stops failing
v2.82.17
v2.82.17
Fixed
- glm: drop system/tool turns and read fragments on resume
v2.82.16
v2.82.16
Fixed
- glm: read feature flags given as an object map
v2.82.15
v2.82.15
Fixed
- glm: probe the send button so a missing one is a critical UI failure
v2.82.14
v2.82.14
Fixed
- glm: read token usage inside the chat:completion envelope
v2.82.13
v2.82.13
Fixed
- qwen: parse a bare-array history reply on resume
v2.82.12
v2.82.12
Fixed
- qwen: find an answer nested in a JSON envelope
v2.82.11
v2.82.11
Fixed
- commands: advertise /limits in the slash-command hints
v2.82.10
v2.82.10
Fixed
- glm: unwrap the chat:completion envelope in a non-streamed JSON reply
v2.82.9
v2.82.9
Fixed
- tui: wordRight stops at a newline instead of jumping to the next line
v2.82.8
v2.82.8
Fixed
- mcp: --isolated=false no longer counts as an isolated profile
v2.82.7
v2.82.7
Fixed
- queue: a truncated queued message keeps no lone surrogate
v2.82.6
v2.82.6
Fixed
- config: a numeric setting rejects a fractional value
v2.82.5
v2.82.5
Fixed
- cost: a non-finite duration renders as zero, not NaNs
v2.82.4
v2.82.4
Fixed
- telemetry: a non-finite blockMs does not poison the /limits average
v2.82.3
v2.82.3
Fixed
- answer-parse: a line-boundary cut never keeps a lone surrogate
v2.82.2
v2.82.2
Fixed
- banner: a zero content width still renders the real fields
v2.82.1
v2.82.1
Fixed
- shell: an empty command answers instead of throwing
v2.82.0
v2.82.0
Fixed
- compact: recover from an exhausted chat context on every provider
v2.81.23
v2.81.23
Fixed
- resume: a respond message carrying the safety block is hidden
v2.81.22
v2.81.22
Fixed
- parser: a tool call whose args are a JSON string is recognized
v2.81.21
v2.81.21
Fixed
- extra-tools: ApplyPatch Add File refuses to overwrite an existing file
v2.81.20
v2.81.20
Fixed
- extra-tools: MultiEdit without new_string no longer deletes text
v2.81.19
v2.81.19
Fixed
- tools: Edit without new_string no longer deletes the text
v2.81.18
v2.81.18
Fixed
- tools: Write without content no longer truncates a file
v2.81.17
v2.81.17
Fixed
- tools: Read past EOF explains the empty window
v2.81.16
v2.81.16
Fixed
- i18n: /cost describes the context counter neutrally
v2.81.15
v2.81.15
Fixed
- web: a search result without a snippet no longer borrows the next one
v2.81.14
v2.81.14
Fixed
- glm: an answer that mentions the captcha is not the captcha
v2.81.13
v2.81.13
Fixed
- qwen: the chat list accepts a bare array
v2.81.12
v2.81.12
Fixed
- backlog: a priority on its own line is still the priority
v2.81.11
v2.81.11
Fixed
- commands: unescapeJsonString never leaves a lone surrogate
v2.81.10
v2.81.10
Fixed
- qwen: the restored dialogue drops a SYSTEM turn
v2.81.9
v2.81.9
Fixed
- commands: a failed attachment only rewrites its own whole path
v2.81.8
v2.81.8
Fixed
- net-capture: a lone closing bracket is not a finished answer
v2.81.7
v2.81.7
Changed
- docs(diagram): how-it-works shows all three chat backends
v2.81.6
v2.81.6
Fixed
- tui: undo restores the paste body, not just its marker
v2.81.5
v2.81.5
Changed
- docs(readme): mention GLM everywhere DeepSeek and Qwen were listed
v2.81.4
v2.81.4
Fixed
- web: SSRF guard blocks metadata/kubernetes service aliases
v2.81.3
v2.81.3
Fixed
- context: allowed-tools accepts a space-separated list
v2.81.2
v2.81.2
Fixed
- tools: read-only mode drops concatenated/camelCase MCP writers
v2.81.1
v2.81.1
Added
- send telemetry is opt-in (on automatically in dev)
Fixed
- config: mask a password in the /config set confirmation
Changed
- apply prettier to the GLM provider and send runtime
v2.81.0
v2.81.0
Added
- auto-compact by default, GLM reasoning effort low
- glm: tell the model it runs on the operator's machine; fix the runtime rewrite URL match
- glm: neutralise z.ai's agent runtime so zames tools actually run
- glm: run with a visible browser by default (the site blocks headless)
- glm: thinking is always on and cannot be toggled off
- glm: verify mode flags and attach files through the upload button
- send telemetry for all providers and adaptive throttle (enabled for GLM)
- GLM (chat.z.ai) provider with anonymized recon fixtures
- browser-based login (auto-login first, headed window fallback, headless after)
Fixed
- glm: force web search off and report a busy page instead of a missing button
- glm: no web-search noise, quota fails fast, the model is told not to browse
- glm: the smoke sends the system-prompt into the same chat; the mode check reads the rewritten body
- glm: a signed-in session is not reported as a guest
- drop the unused headless flag
- glm: word the mode warning accurately (the smoke passed with it on)
- persist the sign-in session cookie so it survives a restart
- a successful auto-login saves the credentials it used
- per-provider credentials are writable (missing from the config schema)
- DeepSeek signs in through the browser window before the terminal form
- the TUI login fallback prefills the active provider's credentials
- doctor renders the display row and the adaptive pause
- glm: report the slider captcha instead of a silent no-answer
- handoff label and live config for more than two providers
- per-provider auth marker, credentials and shared headless-UA cache
Changed
- provider capabilities instead of qwen-only checks
v2.80.8
v2.80.8
Changed
- Internal improvements.
v2.80.7
v2.80.7
Fixed
- stop filling the disk with temp dirs, coverage dumps and unbounded logs
- word delete and word-left stop at a newline
v2.80.6
v2.80.6
Fixed
- stop filling the disk with temp dirs, coverage dumps and unbounded logs
- word delete and word-left stop at a newline
v2.80.5
v2.80.5
Fixed
- a JSON array line in a transcript is not an event
v2.80.4
v2.80.4
Fixed
- parse a bare id-keyed Qwen chat list map
v2.80.3
v2.80.3
Fixed
- a malformed uddg escape does not abort the web search
v2.80.2
v2.80.2
Fixed
- wrapToWidth keeps the indentation and inner spaces of a line
- undo: derive the backup name hash with sha1 instead of a path prefix
v2.80.1
v2.80.1
Fixed
- context: strip a leading BOM before the SKILL.md frontmatter
- statusline: clip a long status badge to one short row
- diagnostics: keep the summary inside maxChars
v2.80.0
v2.80.0
Fixed
- commands: keep an unsupplied position as written in a custom command
- subagent: count a subagent run only once it actually starts
- attach: do not cut an inlined @file inside a surrogate pair
- checkpoint: a bare out-of-range rewind index no longer matches a stamp prefix
- git: split a space-separated paths argument in GitAdd
- mcp: keep an MCP tool result inside its size cap
- hooks: never cut a hook denial or notice inside a surrogate pair
- sessions: escape a literal underscore in the session file name
v2.79.0
v2.79.0
Fixed
- qwen: match the history 'from' role case-insensitively and accept human
- browser-chats: match the history role case-insensitively and drop service turns
- extratools: apply multi-hunk ApplyPatch updates and honour @@ line numbers
- web: drop non-http(s) links from WebSearch results
- web: judge 6to4 and Teredo addresses by the embedded IPv4
- permissions: match path rules against arrays and nested MCP args
- scheduler: reject empty and malformed cron field tokens
- qwen: read numeric and map-keyed ids in the chat list
- xml-toolcall: a stray brace before inline JSON no longer eats the args
- xml-toolcall: keep a </parameter> literal inside a parameter value
- qwen: detect a finished status carried on the choice, not only the delta
- config: reject an empty value for a number setting
- goal: an echoed label set is not the evaluator verdict
- input: expand each paste into its own marker occurrence
- compact: a summary that mentions DSML in prose is usable
v2.78.3
v2.78.3
Fixed
- answer-parse: a report narrating completed steps is not unfinished work
- net-capture: a short complete answer is not a finished-without-answer turn
- git: keep the empty-output sentinel out of the git context
- tools: make Read offset/limit 1-based like every line-numbered tool
- shell: scan a glued cd target (cd../.. escaped the sandbox)
- web: drop an unclosed script/style body in htmlToText
- diagnostics: recognize a coloured/timestamped clean banner
- permissions: fail closed on a rule with an invalid regex
- transcript: sanitize the session name in the file name
- backlog: strip a CR from a note title
- shell: escalate to SIGKILL when a killed job traps SIGTERM
- input: Tab on an empty buffer inserted a guessed command
v2.78.2
v2.78.2
Fixed
- goal: clampGoalCondition does not cut a surrogate pair
- web: judge the expanded IPv6 form in the SSRF guard
- permissions: match a command rule against an avv array
- scheduler: OR a restricted day-of-month and day-of-week
- qwen: guest-limit classifier ignores a normal answer
- net-capture: read a top-level accumulated_token_usage pair
- tools: Read does not clip a surrogate pair in half
- tool-summary: do not cut a surrogate pair in the log line
- shell: do not start a background trim on a lone surrogate
- sandbox: match eval at a command position, not as a substring
- goal: parse the spaced and hyphenated NOT MET verdict
- hooks: cap the combined PostToolUse and lifecycle output
- fsutil: write atomic files through a symlink, not over it
- mcp: sanitize the server half of a qualified tool name
- statusline: settle on our own stdout end, not on the pipe closing
- provider: match the handoff workdir by real path, not by string
- checkpoint: retention deletes same-millisecond sibling archives
- undo: a missing backup file no longer wedges the undo history
- sessions: a stale internal id no longer hides the saved session
- attach: keep @file references inside the sandbox root
v2.78.1
v2.78.1
Fixed
- permissions: match a command rule against every plausible command key
- hooks: cap a PreToolUse denial so it cannot flood the tool result
- diagnostics: treat a zero-error watch banner as clean
- statusline: cap the hook output so a chatty command cannot flood the row
v2.78.0
v2.78.0
Added
- skills: ship the methodology skills inside the package
Fixed
- fsutil: remove the temp file when an atomic write fails
v2.77.1
v2.77.1
Fixed
- backlog: only collapse real archive blocks, not notes that mention details
- qwen: do not read a retry phrase in the answer as a rate limit
- web: block IPv4-compatible IPv6 addresses in the SSRF guard
- sessions: cap the input history when loading it
- sessions: keep chat ids with unsafe characters in separate files
v2.77.0
v2.77.0
Added
- scheduler: start the first /loop tick immediately
Fixed
- diff: show no-changes text instead of the git runner sentinel
- config: refuse prototype-polluting segments in setByPath
- net: read the context counter from history_messages and OpenAI usage
- agent-loop: do not flag a report that explains the work as unfinished
- agent-loop: stop treating prose that mentions invoke/parameter as a tool call
- backlog: ignore headings inside fenced code blocks
- subagent: keep the SubagentStop hook output when the run fails
- goal: parse a markdown-formatted evaluator verdict
- qwen: skip the thinking phase when restoring a chat from content_list
- changelog: keep drafted group headings on their own line
- tui: decode modified and release wheel reports correctly
- shell: normalize an invalid Bash timeout instead of crashing the tool
- cost: keep per-tool stats safe for proto/constructor tool names
- tui: mark blocked/aborted tool calls as errors in the result icon
- mcp: do not split a surrogate pair when truncating an MCP result
- context: discover skills at the documented 3 levels deep
- commands: /diffstat accepts --staged like /diff
- commands: /add-dir expands a leading ~ to the home directory
- scheduler: accept the N/step cron form
- scheduler: reject a /loop interval that overflows the 32-bit timer
- diagnostics: never cut the check output inside a surrogate pair
- web: close two SSRF-guard bypasses in WebFetch
- scheduler: flag a job whose next fire could not be computed
- subagent: cap a report without splitting a surrogate pair
- qwen: a retry wait cut short by Esc must stop the retry chain
- tui: a bracketed paste split across reads must not leak its end marker
- agent-loop: do not cut a tool result inside a surrogate pair
- web: a broken numeric HTML entity must not fail the whole WebFetch
- scheduler: keep a scheduled message's jobId through the queue merge; explain an unrecognized /loop interval
- tui: localize the Ink dialog key-hint bars
- i18n: drop the dead /resume <n> hint from /sessions and the docs
v2.76.0
v2.76.0
Added
- bake methodology skills in, localize skill hints, fix Ctrl+Del and scroll-to-bottom
v2.75.6
v2.75.6
Added
- tools: AskUser — a modal question with options (and a free-text escape)
- skills: tell the model to check and read a matching skill before a non-trivial task
Fixed
- deepseek: retry a FINISHED turn with only a truncated RESPONSE head
- tui: default ui.mouseScroll back to true (wheel scrolls the log)
- tui: default ui.mouseScroll back to false so native selection works
Changed
- prune dead code, untrack one-off TUI probes, ship only postinstall
- tui: drop the unused onCopy/hint affordance from CodeBlock
- tui: drop the code-block copy feature (Ctrl+Y / /copy-code)
v2.75.5
v2.75.5
Fixed
- i18n: clearer TUI key hints; localize the scrolled status; add sched-smoke
v2.75.4
v2.75.4
Added
- qwen: per-model context window for the status bar and auto-compact
Changed
- test: format qwen-context test with prettier
v2.75.3
v2.75.3
Fixed
- markdown: always apply the theme in rendered answers; rename logo-small.jpg to logo.jpg
v2.75.2
v2.75.2
Changed
- batch read-only tool calls and skip redundant checkpoints
v2.75.1
v2.75.1
Added
- remove /resume; Ctrl+Delete always deletes the word BEFORE the cursor
- tui: drop the working directory from the prompt
- tui: persistent key hint under the input box
Fixed
- stop advertising the removed /resume and make the i18n guard real
- tui: Ctrl+Delete works in VSCode (it sends ESC d)
- tui: Ctrl+Delete deletes the word BEFORE the cursor
v2.75.0
v2.75.0
Added
- tui: show a one-time hint about mouse selection
- tui: Home/End jump to the top/bottom of the dialog
- tui: mouse wheel scrolls the dialog by default
Fixed
- tui: the status row keeps its height (inline caret on the input row)
- tui: the status bar never wraps to a second line
- tui: the caret lands correctly in a CJK buffer
- tui: responsive dividers and wrapping-aware menu window
- tui: log scroll reads the LIVE offset (no stale closure)
- tui: Ctrl+Delete works (kitty CSI-u) and deletes left at end of line
- tui: the mouse wheel no longer scrolls the input history (for good)
- attachments: keep the items array identity across reset()
- tui: the config menu now redraws on change and fits the terminal
- tui: reserve the real number of rows for a wrapping suggest popup
- tui: exact badge width (T0.7) and honor NO_COLOR (T0.11)
- tui: deliver the FULL pasted text to the agent, not the [Pasted lines#N] marker
- tui: separate SELECT/SCROLL mouse modes and stop the header wrapping the panel
v2.74.0
v2.74.0
Added
- tui: interactive /chats and /sessions list menus
- tui: task progress bar and tool-result outcome icons (TUI-12)
- tui: in-TUI login and one-time-code forms (TUI-10)
- tui: copy code blocks (Ctrl+Y / /copy-code) and a CodeBlock widget
- tui: Ink-based terminal UI with full-screen mode, rich menus and mouse scrolling
- goal: completion-condition semantics with evaluator; make /config live
Fixed
- tui: the mouse wheel now scrolls the DIALOG (not the input history)
- tui: window the full-screen log by rendered ROW, not by entry
- tui: split-safe wheel parser, empty-log hint, selection-aware suggest window
- tui: real visual-row input box height, Ctrl+J, and wheel-vs-history
- tui: multi-line input, growing input box, optional mouse scroll
Changed
- tui: drop the task progress bar — keep just the "tasks: n/m" text
- tui: distinct color and a divider for operator messages
v2.73.11
v2.73.11
Fixed
- drop the duplicate render-how script; sync package-lock version
v2.73.10
v2.73.10
Fixed
- tools: reject invalid base64 instead of writing garbage
v2.73.9
v2.73.9
Fixed
- qwen: raise the default send pause to 4s (rate limit is real)
- qwen: read the real history shape (map) + handle quota_limit
- cli: honor --provider <id>; stop blocking bash -c in the sandbox
v2.73.8
v2.73.8
Fixed
- bound qwen net body, share attach flow, count transcript backpressure, buffer split paste
- lose fewer tool args, unstick the arg-error loop, harden launch
v2.73.7
v2.73.7
Changed
- docs(readme): fix the crooked back-edge arrowheads
v2.73.6
v2.73.6
Changed
- docs(readme): generalize the last DeepSeek-only mentions to both providers
v2.73.5
v2.73.5
Changed
- docs(readme): route the how-it-works back-edges below the boxes
v2.73.4
v2.73.4
Changed
- docs(readme): restore mermaid-style diagram with Qwen, finish provider-neutral prose
v2.73.3
v2.73.3
Fixed
- harden SSRF guard, sandbox, git args, mcp lifecycle and editor
v2.73.2
v2.73.2
Changed
- docs(readme): document Qwen everywhere and refresh the diagram
v2.73.1
v2.73.1
Fixed
- qwen: live provider switch, verified send, server-busy handling
v2.73.0
v2.73.0
Added
- qwen: a second chat provider (
chat.qwen.ai), selectable with/provider <deepseek|qwen>, so the operator can switch models without leaving zames. Addssrc/qwen-ui.ts(selectors),src/qwen-net-capture.ts(phase-aware SSE parser),src/qwen-browser.ts(QwenBrowser), a separate persistent profile (~/.zames/qwen-profile),/modelto list/pick a Qwen model, and file attachments via the mode menu's "Upload attachment" item. - provider: switching
/providermid-session now carries the conversation over: the current chat is summarized (on the old backend) and persisted as a handoff (src/provider-handoff.ts); the next launch posts it as the first message of the new provider's chat, so context is not lost. Falls back to a local history dump when the model summary is unusable. Unit-tested. - provider: a
PROVIDERSregistry (src/providers.ts) is the SINGLE source of truth (ids, labels,/chatURL prefix), so adding a backend (ChatGPT, Gemini, …) is a data change plus the provider's own modules — not a dozen ternaries./provideraccepts any registered id; the config enum, the{provider}label and/doctorread from the registry. Unit-tested (test/providers.test.ts). - provider: a
ChatProviderinterface (src/types.ts) both backends implement; the agent loop only depends onBrowserLikeand never sees a concrete class. Operator notices (ds.answer_timeout,ds.tool_retry, …) now use a{provider}label so they never say "DeepSeek" while driving Qwen.
Changed
- ui: the status line shows a provider badge ([Qwen]/[DeepSeek]) so the active backend is always visible in a multi-provider session.
- qwen:
listChats/fetchChatMessagesnow use Qwen's OWN API (GET /api/v2/chats/?page=1&exclude_project=trueandGET /api/v2/chats/<id>?direction=up&limit=N) with the DOM scrape as a fallback, so/chatsand/resumework on a signed-in account (verified live: 9 chats with titles, 20 messages). Parsers are pure + tested. - qwen: password login (
_autoLogin) fixed to the verified order (email -> "Log in with a password" -> password -> submit); the email-CODE flow needs the operator to read the mail, so a saved password is preferred. Verified live. - qwen: the context counter now uses
input_tokens(the prompt size) — the true "used context" — instead oftotal_tokens(which adds the answer), so the status bar matches DeepSeek's semantics. - qwen: thinking / web search are mapped onto Qwen's own UI: deepThinking ON selects the "Thinking" mode (OFF → "Fast") in the
.qwen-thinking-selectordropdown, and webSearch toggles the "Web search" item in the "+" mode menu./thinkingand/webtherefore work on Qwen too. - qwen: no 15 s send throttle — a live experiment (4 back-to-back sends at 0 ms gap) hit no rate limit, so
qwen.minSendIntervalMsdefaults to 1000 ms. The agent-loop watchdog deadline is derived from the Qwen answer timeout (a cold guest turn can take minutes), not the DeepSeek 240 s default. - provider: sessions are tagged with the ACTIVE provider (
saveSession({…, provider})), so/resume//last/auto-restore only ever reopen a chat in the backend that created it (a chat id is meaningless to the other one).loadLastSession(workdir, provider)filters accordingly. - qwen: the restored-dialogue scraper moved to a PURE
src/qwen-chats.ts(mirroringbrowser-chats.ts) and now keeps only the OUTERMOST message container — the broad[class*="message"]chain matched an outer and an inner block, so every turn printed twice.listChatsopens the sidebar first and matches/c/<id>links. Compact / auto-compact use the active provider's own answer timeout (providerAnswerTimeoutMs()), not DeepSeek's.
Fixed
- qwen: recover from a lost page/context mid-run (relaunch + re-login, and re-navigate to the chat if the input is gone) instead of failing every retry.
- qwen: the guest daily limit (
getstsToken→RateLimited) fails fast with a "sign in" message instead of a 20-minute rate-limit wait. - qwen: the real sign-in flow is email → one-time code from the letter (not email+password):
_promptAndLogin()now sends the email, asks the operator for the code in the terminal, submits it, and verifies the session from the page (guest header CTAs absent)./provider loginre-runs it. - qwen: a longer send-button wait when files are attached (the upload keeps the button disabled).
v2.72.9
v2.72.9
Fixed
- release: do not duplicate the Unreleased body into the version section
- context: raise the context budget and split agents/memory pools
- browser: handle the DeepSeek email MFA dialog on login
- subagent: fail safe when the parent chat id is unknown
- tools: honor a skill's allowed-tools frontmatter
- context: keep newest MEMORY.md notes and write facts to the project memory
v2.72.8
v2.72.8
Fixed
- browser: also treat generation_timeout as a truncated turn
- browser: also treat generation_timeout as a truncated turn
v2.72.7
v2.72.7
Fixed
- ui: show a queued-message banner for EVERY queued message
- ui: show a queued-message banner for EVERY queued message
v2.72.6
v2.72.6
Fixed
- browser: detect the property form of quasi_status (Stopped/FINISHED hang)
- browser: detect the property form of quasi_status (Stopped/FINISHED hang)
v2.72.5
v2.72.5
Changed
- input: extract the pure slash-command suggestion logic into input/suggest.ts (C3)
- input: extract the pure slash-command suggestion logic into input/suggest.ts (C3)
v2.72.4
v2.72.4
Changed
- index: extract the pure /config rendering into config-commands.ts (C3)
- index: extract the pure /config rendering into config-commands.ts (C3)
v2.72.3
v2.72.3
Changed
- index: extract the paste-aware terminal reader into src/prompt.ts
- index: extract the paste-aware terminal reader into src/prompt.ts
v2.72.2
v2.72.2
Added
- self-smoke: add --reuse-profile and a bounded, explicit login failure (exit 2)
- self-smoke: add --reuse-profile and a bounded, explicit login failure (exit 2)
v2.72.1
v2.72.1
Changed
- browser: move cleanAnswer into browser-pure.ts (C3)
- browser: extract the element-level DOM callbacks into browser-dom.ts (C3)
- browser: extract the headless UA reader callback (C3)
- browser: extract the login-submit, UA-scan and busy-title callbacks (C3)
- browser: extract the in-page DOM callbacks into browser-dom.ts (C3)
- answer-parse: import the parser directly, drop the agent-loop re-export (C3b)
- browser: move cleanAnswer into browser-pure.ts (C3)
- browser: extract the element-level DOM callbacks into browser-dom.ts (C3)
- browser: extract the headless UA reader callback (C3)
- browser: extract the login-submit, UA-scan and busy-title callbacks (C3)
- browser: extract the in-page DOM callbacks into browser-dom.ts (C3)
- answer-parse: import the parser directly, drop the agent-loop re-export (C3b)
v2.72.0
v2.72.0
Added
- close the open BACKLOG items (N31-N38, D2) and type the helper scripts
- close the open BACKLOG items (N31-N38, D2) and type the helper scripts
Fixed
- agent-loop: honor the abort contract in the parallel read-only batch
- changelog: normalize the Unreleased group headings to ### and document changelog:sync
- subagent: harden the runner guards and keep the parent UI alive
- subagent: harden the runner guards and keep the parent UI alive
Changed
- rename agent-loop-pure.ts to answer-parse.ts
- browser: extract the chat DOM scrapers and the history parser (C3)
- extract the pure halves of browser/agent-loop and the CLI parser (C3)
v2.71.0
v2.71.0
Added
- subagent: add the Task tool, enable subagents by default and instruct the model when to delegate
v2.70.0
v2.70.0
Added
- browser: centralize DeepSeek UI constants and add a UI health probe
v2.69.0
v2.69.0
Changed
- ui: ONE content width for every block, from a new single source of truth
src/width.ts. The model answers, the echo of the operator text, the tool previews, the service warnings and the divider now all stop at the same margin (min(ui.answerWidth, terminal - 1), capped at 100 by default). Before, answers and the divider were capped at 100 while the echoed operator text and warnings ran to the full terminal width — the mismatch looked ragged after a resize. - config:
ui.answerWidthnow sets the SHARED content width (label updated).0= auto (terminal width, capped at 100).
v2.68.1
v2.68.1
Fixed
- ui: long service messages (send failures, rate limits) are now word-wrapped to the same margin as the tool previews (
cols - 1). Before, they were printed at the full terminal width and the terminal wrapped them mid-word, so some lines ran to the edge and some stopped short. Applies toLineEditor.warning()and the non-TTY spinner.
v2.68.0
v2.68.0
Changed
- git: every git invocation (GitStatus/GitLog/GitBranchList/GitAdd/ GitCommit and the
/diff,/diffstat,/doctorhelpers) now goes throughrunGitArgs()(execFilewith an argument array, no shell). The last shell-string variant (runGit) is gone, so no git argument can ever be interpreted by a shell.diffGitArgs()now returns an array. - cleanup: removed the dead
shellQuoteexport (nothing used it after the move toexecFile). - build:
prepublishOnlynow runsbuild:readmebeforebuild, so a published README.md can never drift fromdocs/readme.*.md.
v2.67.4
v2.67.4
Fixed
- readme:
npm run build:readmegenerated aREADME.ru.mdagain even though it is no longer published (removed fromfiles[]in 2.67.1) and a test asserted it must not exist — so a local build wrote an untracked file and could trip the drift test. The generator now writes ONLYREADME.md.
v2.67.3
v2.67.3
Fixed
- input: a terminal resize no longer clears the whole viewport. The 2.67.2 fix removed the duplicate footer by clearing the screen (
ESC[2J), but that pushed the history above into the scrollback and left a blank gap between the input line and the text the operator was reading. The block is now erased with a RELATIVE move (the cursor row within the block), which lands on the block top row after a reflow and clears ONLY our own rows — the history above stays visible and in place.
v2.67.2
v2.67.2
Fixed
- input: a terminal resize no longer leaves a DUPLICATE of the status/ input block on screen. After a resize the terminal re-flows the lines above the block, so the old code re-pinned by padding to the bottom and scrolled the previous copy of the block back into view. The repaint now clears the visible viewport (
ESC[2J) before re-pinning; this clears the SCREEN, not the scrollback, so the history above is preserved.
v2.67.1
v2.67.1
Changed
- web: the headless renderer reuses ONE BrowserContext for every
WebFetchwithrender=true(it used to build a fresh context per call); the page is closed after each fetch and the context incloseWeb(). - docs:
npm run self-smokeis now documented as a REQUIRED manual pre-release step in DEVELOPING.md — it is the only gate that catches an integration regression (login, send, attachments) and needs live creds, so it stays out of CI. - packaging:
README.ru.mdis no longer generated or published. The Russian translation already lives inside README.md as a<details>block (visible on npm), and the language switcher is now an in-page#readme-ruanchor — the second ~15 KB file only duplicated it and could drift.
v2.67.0
v2.67.0
Fixed
- tools: Edit/MultiEdit no longer corrupt dollar patterns (
$&,$$,$1) innew_string— the replacement now uses the functional form instead of a string replacer. - tools: Grep and findstr are run through
execFilewith an argument array instead of a shell string, so a$(...)pattern is no longer executed as a command. - git: GitShow/GitDiff/GitAdd/GitPush/GitCommit now use
execFile;refandpathare validated (a leading-is rejected) — command/option injection through the arguments of read-only tools is closed. - sandbox: file tools resolve the real path (
fs.realpath) and reject a symlink pointing outside the working directory. - shell:
assertCommandInsideRootexpands~/$HOME, sees acdinside a subshell/backticks and rejectsevalwithcd. - plan mode: MCP tools are now filtered for read-only too (mutating verbs are dropped).
- self-review: the snapshot and diff/apply walk src/ subdirectories recursively (
i18n/,input/) — they used to be silently missing from the snapshot. - one-shot
--task: on an agent error / iteration limit / watchdog the process now exits with code 1 instead of 0. - input: Ctrl+Delete and Delete now work under the CSI-u (kitty) protocol:
CSI 3;5u/3;3u/3u. - input: Up/Down move the cursor across VISUAL rows of a wrapped line, not only across logical lines.
- input: a lone ESC no longer aborts the generation when a control sequence arrives in two chunks — a short timeout disambiguation.
- input: Ctrl+L clears the screen and PageUp/PageDown page the suggestion list; an unknown control sequence is logged in debug instead of being swallowed silently.
- MCP: duplicate tool names are disambiguated with a numeric suffix so the second tool is not silently unreachable.
- MCP: a tool result is truncated with an explicit marker — a single call (browser_snapshot and the like) no longer floods the context.
- transcript:
close()waits for the flush (it returns a promise) so the final events reach the file on the exit paths. - web:
WebFetchre-validates every redirect hop against the SSRF guard and checks the final URL of a headless render. - permissions: a
pathrule now also matches the file headers of anApplyPatchand path-looking arguments of MCP tools. - scheduler:
nextCronTimeparses the cron expression once instead of on every scanned minute. - git:
formatGitContextpicks a code fence longer than any backtick run in the preview, so a filename with backticks cannot break the markdown. - fsutil: secrets and state are written with 0600 permissions;
writeFileAtomicfsyncs the file before rename (and the directory after) for durability on a power loss.
Changed
- docs: SECURITY.md updated for the permissions policy, the symlink guard and the plan-mode MCP caveat; DEVELOPING.md module sizes refreshed.
- cleanup: removed the dead exports
listConfiguredServers,builtinSkillsandfindFileByName. - tests: the MCP result cap,
htmlToTextand the DuckDuckGo parser are now covered, andweb.ts/spinner.tsgained coverage floors.
Security
- Shared
shellQuotehelper for arguments passed to the shell (single quotes with internal quotes doubled).
v2.66.1
v2.66.1
Changed
- README: the Russian translation is now folded into
<details>directly inREADME.md, so it can be read on the npm page without leaving GitHub. npm renders the readme with the same GitHub Flavored Markdown as GitHub, and a separateREADME.ru.mdis not visible on the npm page (npm has one readme per package). Both language versions are assembled fromdocs/readme.{en,ru}.mdbynpm run build:readme;test/readme-built.test.tsguards against drift.
v2.66.0
v2.66.0
Added
- release: add scripts/release.mts for one-command release prep (G4)
- reload: include commands, run-task and attach-refs in hot-reload (G2)
Changed
- apply prettier to files touched by G2/F1
v2.65.1
v2.65.1
Other
- Long preview lines no longer create a horizontal scrollbar in the terminal:
toolCall/toolResult(LineEditor and spinner) now clip the preview by the VISIBLE terminal width (truncateToWidth) instead of by character count. A long command/result used to print wider than the screen. - Ctrl+Delete / Ctrl+Backspace (and Alt+Delete / Alt+Backspace) now delete a word in the input line. These escape sequences used to fall through the generic key skip and did nothing. Supported variants:
ESC[3;5~(xterm Ctrl+Delete),ESC[3;3~(Alt+Delete),ESC DEL/ESC 8(Alt/Ctrl+Backspace) and the kitty protocolESC[127;5u/ESC[127;3u. New_deleteWordRight()method +test/editor-word-delete.test.ts. - The
/configmenu now keeps the SELECTED item on screen: the window is built "backwards" from the cursor, taking into account the rows the group headings occupy (previously an index-basedscrollTopcould push the selected row below the window). /newresets the context counter:_lastTokenUsageaccumulates PER CHAT, and without a reset an empty chat kept showing the oldctx: 302k · 30%until the first send. Test intest/newchat-verify.test.ts.
v2.65.0
v2.65.0
Changed
- The README screenshot
docs/demo.pngwas regenerated in English (it used to be in Russian). The reproducible generatornpm run render-demo(scripts/render-demo.mjs) renders the real editor layout and theme palette through headless Chromium with an isolated profile. - README: the ASCII "how it works" diagram was replaced by a Mermaid diagram (the arrows no longer "float") plus a textual description in words.
- Removed unused files:
logo.jpg(onlylogo-small.jpgis used in the README) and thedocs/demo.tapedraft (the VHS render was never generated).logo.jpgwas also removed from thefileslist in package.json. - Terminal repaint after a window resize: the relative erase
ESC[n Aafter a size change landed on a stale row (the terminal re-flowed the wraps), so the status/input were drawn in the wrong place. After a resize the block is re-pinned to the bottom (home + padding), and the scrollback history is kept. Test intest/terminal-drift.test.ts. - A live language change (
/config lang) did not reach two "created once" objects: the thinking-phrase spinner took the default language (randomThinkingPhrase()instead ofrandomThinkingPhrase(this.locale)), andDeepSeekBrowserprinted its notices (ds.*) in the language fixed at startup. So with an English UI Russian thinking/notice phrases surfaced. AddedDeepSeekBrowser.setLocale(), called fromsetConfigRuntime. - The
/configmenu is now drawn as a WINDOW sized to the terminal height (previously the whole list of 49 fields was printed as one block). On a short terminal the block scrolled off the top, so restoring the cursor withESC[lastRows Alanded on the wrong row and arrow navigation "did not scroll" the list. Also fixed a dead ANSI-strip regex (a stray backtick) insrc/config-menu.ts.
v2.64.1
v2.64.1
Changed
- README: added a terminal session screenshot (
docs/demo.png) under the header so the interface is visible immediately; a reproducible VHS demo script (docs/demo.tape) for a future GIF.
v2.64.0
v2.64.0
Added
- A CHANGELOG draft generator from conventional commits (BACKLOG D2):
npm run changelog:draft [ref]prints a ready "Unreleased" block from the commits after the last tag (or the given ref). Pure modulesrc/changelog.ts(parseConventionalCommit/groupCommits/renderChangelogDraft, unit-tested). TheCHANGELOG.mdfile is NOT overwritten automatically — the draft is reviewed by hand.
Changed
- Refactor (BACKLOG C3, step 1): attachment path resolution and
@filereference inlining were moved out ofsrc/index.tsintosrc/attach-refs.ts(resolveAttachPath/inlineAtRefs) — now a separate testable module.
v2.63.1
v2.63.1
Other
- Timer flicker in the pre-send pause status:
sendPause()(bothLineEditorand the non-TTYSpinnerUI) repainted the status WITHOUT the "elapsed"/task-badge tail, while the animation tick drew it WITH it — once a second the· 1m 50slabel disappeared and reappeared. The update now builds the same tail as the tick. Regression test in test/compact-statusline.test.ts.
Changed
- README: centered header, larger logo (640px asset, 430px display), a "How it works" diagram, a table of contents and a Links section.
- Dependabot: major updates are ignored (
semver-major), monthly schedule, auto-merge only for patch/minor and only for bot PRs (author and branch checks); auto-merge workflow. Themasterbranch is protected by a ruleset: PR required, required check is the stablecijob.
v2.63.0
v2.63.0
Added
- Real action approvals (BACKLOG C1): an approval policy in
.zames/permissions.json(default+ruleswith regexp ontool/command/pathand anallow|deny|askaction). Evaluated inagent-loop.tsBEFORE every tool:denyblocks the call,askprompts the operator viaonAskPermission(in a TTY — an interactive prompt above the input line, in non-TTY — denied). New pure modulesrc/permissions.ts+ tests (test/permissions.test.ts, test/permissions-loop.test.ts). - Custom commands: arguments and hints (BACKLOG B7). Frontmatter
argument-hint:is shown in the "/" list and in/help(not inserted into the input line), andarguments:declares mandatory positional arguments.$1 $2, named$nameand the previous/$ARGUMENTSare substituted into the command body. If the required arguments are missing the command is not sent to the chat and a hint is printed. New pure helperssplitCommandArgs()/expandCommandArgs()/missingCommandArgs()(src/commands.ts, unit-tested). - Path-scoped rules (BACKLOG B6): nested
AGENTS.md/MEMORY.mdfrom the subdirectories the task touches are pulled in automatically. The task text is scanned for path tokens, the nearest instructions are read for the found directories (and their ancestors below the working dir) and rendered as a separate## Scoped instructions (...)section — explicitly marked as applying only to those files.loadProjectContext(workdir, touchPaths?)andrenderContextSection()(src/context.ts, src/system-prompt.ts; unit-tested). @filereferences in a task (BACKLOG B5):solve the task @src/browser.tsinlines the contents of the referenced file right into the task, saving a separate agent turn to read it.@pathis recognized at a word boundary (at the start of a line or after a space/bracket/quote) with a file extension;user@hostand decorators (@Component) are not touched. Existing files are inlined (60 KB per file, 200 KB total — beyond that a truncation marker), missing ones stay as-is. HelperextractAtFileRefs()insrc/path-token.ts(pure, unit-tested).
Changed
AGENTS.mdtrimmed (BACKLOG C2): the deep root-cause write-ups ("the agent stopped", reading the answer from the DOM, send hooks,LineEditor, attachments) and the terminal mechanics were moved todocs/DESIGN-NOTES.md(progressive disclosure — not loaded into every task). AGENTS.md keeps the acting rules plus a short summary with a pointer.
v2.62.0
v2.62.0
Added
- Checkpoints / rewind (BACKLOG B3): at the start of every task the working tree is snapshotted into a tarball under
~/.zames/checkpoints/, and/rewind [n]rolls it back in one step (with a confirmation prompt and an automaticpre-rewindbackup of the current state, so the rewind itself is reversible)./rewind-listshows the recent checkpoints.node_modules,.git,distandtmpare never snapshotted or deleted. Unlike a manual git stash, this works in a non-git directory and never touches the operator's index. New modulesrc/checkpoint.ts(pure helpers +CheckpointStore, unit-tested); configurable viacheckpoint.enabled/checkpoint.maxBackups(default 50) in/config.
v2.61.0
v2.61.0
Added
/backlog <text>— record an improvement idea inBACKLOG.mdwithout implementing it. Deterministic: a freshN<n>id under the matchingP0..P3section; an optional leadingP0..P3picks the section, the first line is the title, the rest the body./backlog collapseprunes the archived blocks.- BACKLOG.md maintenance (
src/backlog.ts, pure/tested):/improvenow auto-prunes a finished item's archived<details>copy after a successful run (the### X. [x] ... donesummary line is kept), and a startup warning fires when BACKLOG.md exceeds 500 lines / 60 KB. The collapser tolerates an UNCLOSED<details>(a real file had one). - Dev-mode self-improvement note: in
--devthe system prompt tells the model it may append ONE short BACKLOG.md bullet when it spots an improvement outside the current task (off in a normal run).
Changed
- Self-development commands (
/improve,/backlog,/self-review,/self-fix,/self-done,/self-list,/self-diff,/self-apply) are now DEV-ONLY: they are hidden from/helpand the «/» hints, and rejected by the main loop, unless the operator runs in dev mode (--devorconfig.hotReload). A regular package install no longer advertises them, and a hand-typed/improvecan no longer edit an unrelated project's BACKLOG.md. The list isDEV_ONLY_COMMANDS/isDevOnlyCommand()insrc/commands.ts(pure, tested).
v2.60.0
v2.60.0
Added
- PreToolUse / PostToolUse hooks (see
src/hooks.ts): a project policy can attach an external script to every tool call via.zames/hooks.json({ "PreToolUse": [{matcher, command}], "PostToolUse": [...] }). A PreToolUse hook that exits non-zero BLOCKS the call (its output becomes the tool result); a PostToolUse hook's stdout is appended to the result. Hooks are best-effort: a missing/malformed config, a crash or a 10s timeout never fails the agent loop.
v2.59.0
v2.59.0
Added
/improve [id]— a backlog-driven self-improvement loop. It picks the next open item fromBACKLOG.md(highest priority, or an explicit id), runs the standard task loop on it (implement, typecheck/lint/test, mark the item done, add a CHANGELOG entry) and leaves the changes uncommitted for review. This is the reproducible hand-off path for a fresh agent.
v2.58.0
v2.58.0
Added
--output-format json|jsonlfor one-shot runs: transcript events are streamed as JSON lines on stdout (human text goes to stderr), so zames pipes intojqand CI pipelines.Transcriptgained anonLinemirror.- Loop detection: four identical tool calls in a row trigger a nudge to change approach instead of repeating the same call forever.
- MCP configs pinned to
@latest/@nextnow warn (in/mcpand at startup) so the tool set does not silently change between runs. /helpis grouped into sections (session / workspace / git / agent / context / files) instead of one long list.Grepaccepts a comma-separatedincludelist.- System prompt: a "Choosing the right tool" section (Edit vs MultiEdit vs ApplyPatch, Grep vs Glob vs LS, Git tools vs Bash).
Changed
coverage-gateenforces floors for 8 more modules and prints the lowest-covered modules in the CI log.- README: Why zames?, an FAQ and a machine-readable-output section.
- Dependabot config for npm and GitHub Actions.
v2.57.1
v2.57.1
Changed
- CI workflows use actions/checkout@v5 and actions/setup-node@v5 (the v4 actions run on the deprecated Node 20 runtime and showed up as an annotation on every run).
Added
- README badges (npm version/downloads, CI status, license, Node, PRs) and a Features section, so the GitHub landing page and the npm page show what the project is at a glance.
- Community files: issue forms (bug report, feature request), a PR template and CODE_OF_CONDUCT.md.
- package.json: a fuller description and more keywords (npm search), and CHANGELOG.md is now included in the published files.
v2.57.0
v2.57.0
Added
- Plan mode (read-only): start with --plan or toggle with /plan [on|off]. In this mode mutating tools (Write/Edit/MultiEdit/ApplyPatch/Bash, GitAdd/ GitCommit/GitPush) are removed from the tool set entirely, so the agent can investigate without touching the tree.
- src/fsutil.ts - one shared atomic writer (writeFileAtomic/writeJsonAtomic).
Changed
- config, sessions and undo now share the single atomic writer (the temp-file+rename logic used to be copy-pasted in three places).
- BACKLOG.md is now git-ignored and untracked: it is the agent's own improvement-notes file, rewritten constantly, and used to be published with the package.
- GitPush validates the branch name before building the shell command, so a model-supplied branch cannot smuggle shell metacharacters.
- SECURITY.md no longer promises a /permissions command / alwaysConfirm list that was removed in 2.55.0; AGENTS.md cleaned of the same dead refs.
v2.56.0
v2.56.0
Added
/context— show what is loaded into the prompt (AGENTS.md, MEMORY.md, skills, custom commands) plus the system-prompt size./retry— resend the last task into the same chat (handy after a truncated or empty answer)./rename <title>— set the current session title (shown in/sessions)./diffstat— a one-linegit diff --statchange summary./copy— copy the last assistant answer to the OS clipboard (wl-copy / xclip / xsel / pbcopy / clip).GitShowandGitBranchListgit tools (read-only).- The status line now shows the elapsed time of the current phase ("45s", "2m 05s") in BOTH the LineEditor and the non-TTY spinner, and the spinner shows the same "tasks: 2/5" badge the editor does.
- A one-time hint when the context reaches ~80% while auto-compact is off, pointing at
/compact. - Tests: dead-i18n-key guard, agent-facing-no-Cyrillic guard, CLI flag consistency, binary content-type handling for
WebFetch.
Changed
WebFetchreturns a short human note for binary content types (PDF, images, archives, ...) instead of dumping raw bytes into the model context.npm run buildnow wipesdist/first (scripts/clean-dist.mjs), so a removed source file no longer leaves an orphan.jsin the package./undofailure reasons are localized:src/undo.tsreturned hardcoded Russian strings that showed up in an English UI. It now returns machine codes ('empty' / 'disabled') localized by the caller.- Removed the dead
--projectflag (it only swallowed the following argument) and the no-op--calibrateflag together with their help/i18n entries. - Removed the orphaned
confirm.hint/confirm.ask_labeli18n keys left by the confirm-subsystem removal. - README Node requirement aligned with
engines/.nvmrc(>= 20). GitBranchListquotes its--formatargument so the POSIX shell does not choke on the parentheses/brackets in the format string.
v2.55.0
v2.55.0
Added
!commandin the prompt runs a shell command directly, bypassing the model (like Claude Code's bash mode). The same sandbox guard as theBashtool applies, so a direct command cannot leave the project./remember <text>appends a durable note to the projectMEMORY.md, so a fact worth keeping across sessions is written to disk instead of living only in the chat./skills,/memory,/remember,/initand/mcpare now listed in the/helpoutput (they were only in the «/» completion list before).
Changed
- The shell runner moved to
src/shell.ts, shared by theBashtool and the new!commandescape (one sandbox guard, one abort wiring). /self-reviewnow copies root configs (package.json,eslint.config.js,tsconfig*.json,.prettierrc) andscripts/**into a read-only_context/folder of the snapshot, so the reviewer can read them. The editable set (diff/apply) stays.ts-only.package.jsongainedpackageManager: npm@11.19.0.- The status line no longer prefixes a running-tool indicator with the previous answer's "done" phase (e.g.
✓ done: running Bash):toolCall()clears the send-phase state before starting the tool animation.
Removed
- The never-wired tool-confirmation subsystem:
src/confirm.ts(ConfirmManager/formatDiffPreview) was fully implemented and tested but never called by the runtime, soconfirmation.write/edit/bash,alwaysConfirmand the/permissionscommand did nothing. Removed the module, its tests, the config keys, the/permissionscommand and the related i18n strings.
v2.54.0
v2.54.0
Added
- New unit tests for previously uncovered modules:
diff.ts(unified/color diff),spinner.ts(ellipsis/dots/UI surface),confirm.ts(confirmation logic + alwaysConfirm fallback) andmarkdown.ts(rendering of headings, lists, code, tables). WebFetchnow blocks private/loopback/link-local addresses (SSRF guard, including cloud metadata169.254.169.254) and retries transient network errors and 5xx responses with exponential backoff.- CI prints per-file test coverage (
node --experimental-test-coverage) so untested modules are visible in the log (informational, does not fail).
Changed
- The
pre-pushgit hook no longer runs the full test suite (it was fragile and timed out on tag pushes); tests stay inpre-commitand CI.
v2.53.1
v2.53.1
Other
require('fs')in ESM modules (src/attachments.ts,src/self-review.ts) threwReferenceErrorat runtime: WSL clipboard detection always returnedfalseand/self-reviewfound no sources when run from the builtdist/.- Config, session and undo index writes are now atomic (temp file + rename), so a crash or Ctrl+C mid-write can no longer corrupt
~/.zames/config.jsonor a saved session.
Changed
- Removed the unused
markeddependency (Markdown is rendered bymarkdansi). - CI installs dependencies with
npm cifor reproducible builds. - The i18n test now validates the whole
CATALOGinstead of a small sample. - Added
.nvmrc(Node 24).
v2.53.0
v2.53.0
Added
- Session banner warns when no saved DeepSeek session exists.
--no-colorflag (explicitNO_COLOR).