zames_pro 2.95.5 → 2.95.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [2.95.6] - 2026-11-05
11
+
12
+ ### Added
13
+
14
+ - **compact:** carry the todo checklist and the /goal condition into the new chat
15
+ - **site:** a generated changelog page and one source for RU/EN layout strings
16
+
17
+ ### Fixed
18
+
19
+ - **changelog:** keep a drafted group heading off the previous bullet
20
+
10
21
  ## [2.95.5] - 2026-11-05
11
22
 
12
23
  ### Added
package/README.md CHANGED
@@ -72,7 +72,7 @@ and runs right after it, in the same chat. `Esc` aborts the current generation,
72
72
  - [Why zames?](#why-zames) · [Requirements](#requirements) · [Signing in](#signing-in)
73
73
  - [Switching providers (DeepSeek / Qwen / GLM)](#switching-providers-deepseek--qwen--glm)
74
74
  - [Installation](#installation) · [Usage](#usage) · [FAQ](#faq)
75
- - Reference: [Commands and tools](docs/commands.md) · [MCP](docs/mcp.md) · [Configuration and themes](docs/configuration.md) · [Troubleshooting](docs/troubleshooting.md)
75
+ - Reference: [Commands and tools](docs/commands.md) · [MCP](docs/mcp.md) · [Configuration and themes](docs/configuration.md) · [Troubleshooting](docs/troubleshooting.md) · [Changelog](https://viqto0r.github.io/zames_pro/changelog.html)
76
76
  - [Keywords and alternatives](#keywords-and-alternatives) · [Links](#links) · [License](#license)
77
77
 
78
78
  ## How it works
@@ -534,7 +534,7 @@ zames # один раз войти, дальше прост
534
534
  - [Почему zames?](#почему-zames) · [Требования](#требования) · [Вход в аккаунт](#вход-в-аккаунт)
535
535
  - [Переключение провайдера (DeepSeek / Qwen / GLM)](#переключение-провайдера-deepseek--qwen--glm)
536
536
  - [Установка](#установка) · [Использование](#использование) · [FAQ](#faq)
537
- - Справочник: [Команды и инструменты](docs/commands-ru.md) · [MCP](docs/mcp-ru.md) · [Конфигурация и темы](docs/configuration-ru.md) · [Troubleshooting](docs/troubleshooting-ru.md)
537
+ - Справочник: [Команды и инструменты](docs/commands-ru.md) · [MCP](docs/mcp-ru.md) · [Конфигурация и темы](docs/configuration-ru.md) · [Troubleshooting](docs/troubleshooting-ru.md) · [История изменений](https://viqto0r.github.io/zames_pro/changelog-ru.html)
538
538
  - [Ключевые слова и аналоги](#ключевые-слова-и-аналоги) · [Ссылки](#ссылки) · [Лицензия](#лицензия)
539
539
 
540
540
  ## Как это работает
package/dist/changelog.js CHANGED
@@ -97,13 +97,25 @@ export function syncUnreleased(changelog, body) {
97
97
  // carries several groups (`## Added` … `## Fixed`) without a blank line
98
98
  // between them, the next group used to stay glued to the last bullet
99
99
  // (`- a### Fixed`) — it was not a heading at all, so the item vanished
100
- // from the rendered changelog.
101
- .replace(/([^\n])\n?(?=## )/g, '$1' + nl + nl)
100
+ // from the rendered changelog. The lookahead is what keeps a CONTINUATION
101
+ // line of a multi-line bullet in place: gluing on `\n` as well joined the
102
+ // indent line to the next bullet and truncated the note.
103
+ // The draft's groups are still `## ` at this point (they become `### `
104
+ // below), and the FIRST group is already preceded by the blank line of
105
+ // the draft — so a group always starts a line, and this rule only has to
106
+ // punch in the missing blank line after a bullet.
107
+ .replace(/([^\n])(?=## )/g, '$1' + nl + nl)
102
108
  .trim()
103
109
  // The draft renders groups as `## Added` (top-level), but INSIDE the file
104
110
  // a version's groups are `### Added` (a subsection of the version heading).
105
- // `## [` (the next version) is left alone.
106
- .replace(/^## (?!\[)/gm, '### ');
111
+ // `## [` (the next version) is left alone. The FIRST group follows the
112
+ // version heading directly (no bullet before it), so the blank-line rule
113
+ // above never fired for it — `## [Unreleased]` came out as a bare `#`
114
+ // followed by `# Added`. The heading owns a blank line, always.
115
+ .replace(/^## (?!\[)/gm, '### ')
116
+ // One blank line between the version heading and its first group, not
117
+ // the three the rules above can stack up.
118
+ .replace(/^\n+(?=### )/gm, '');
107
119
  const section = cleanBody ? nl + nl + cleanBody + nl : nl;
108
120
  return changelog.slice(0, afterAnchor) + section + tail;
109
121
  }
package/dist/commands.js CHANGED
@@ -512,20 +512,80 @@ export function isUsableCompactSummary(text) {
512
512
  return false;
513
513
  return true;
514
514
  }
515
+ function todoMark(s) {
516
+ return s === 'completed' ? '[x]' : s === 'in_progress' ? '[~]' : '[ ]';
517
+ }
518
+ /** The TODO block carried into the new chat. Empty when there are no tasks. */
519
+ export function renderCompactTodos(todos = []) {
520
+ const items = Array.isArray(todos) ? todos : [];
521
+ if (!items.length)
522
+ return '';
523
+ const lines = items.map((x, i) => String(i + 1) +
524
+ '. ' +
525
+ todoMark(String(x.status)) +
526
+ ' ' +
527
+ String(x.content));
528
+ const done = items.filter((x) => x.status === 'completed').length;
529
+ return ('## Task checklist (carried over by the agent, still in force)' +
530
+ NL +
531
+ 'This list is SESSION state: it survived the compaction unchanged. ' +
532
+ 'Do NOT recreate it from the summary — keep it up to date with ' +
533
+ 'TodoWrite instead.' +
534
+ NL +
535
+ 'Todo list (' +
536
+ String(done) +
537
+ '/' +
538
+ String(items.length) +
539
+ ' done):' +
540
+ NL +
541
+ lines.join(NL));
542
+ }
543
+ /** The goal block carried into the new chat. Empty when no goal is set. */
544
+ export function renderCompactGoal(goal) {
545
+ const g = String(goal?.goal ?? '').trim();
546
+ if (!g)
547
+ return '';
548
+ const head = goal?.isCondition
549
+ ? '## Completion goal (carried over, still in force)'
550
+ : '## Session goal (carried over, still in force)';
551
+ return (head +
552
+ NL +
553
+ 'This goal is still active in this session; the compaction did not ' +
554
+ 'cancel it. Keep working toward it.' +
555
+ NL +
556
+ NL +
557
+ g);
558
+ }
559
+ /**
560
+ * Re-pin the SESSION state after a compaction. The chat is new, but the todo
561
+ * store and the /goal file live in the process and on disk, so they survive —
562
+ * only the model's KNOWLEDGE of them does not. Sent as its own message right
563
+ * after the carryover, so it reads as current state, not as history.
564
+ */
565
+ export function buildCompactToolResult(todos = [], goal = null) {
566
+ return [renderCompactTodos(todos), renderCompactGoal(goal)]
567
+ .filter(Boolean)
568
+ .join(NL + NL);
569
+ }
515
570
  /**
516
571
  * Wrap the model's summary into the text posted as the first message of the
517
572
  * NEW chat. The system prompt is sent separately (sendSystemPrompt), so here
518
573
  * we only mark the block as a carried-over context and add the operator's
519
- * original goal so the model does not lose it.
574
+ * original task. The todo checklist and the /goal condition are appended too:
575
+ * they are session state the model-written summary is not guaranteed to keep.
520
576
  */
521
- export function buildCompactCarryover(summary, task) {
577
+ export function buildCompactCarryover(summary, task, todos = [], goal = null) {
522
578
  const body = String(summary ?? '').trim();
523
- const goal = String(task ?? '').trim();
579
+ const goalText = String(task ?? '').trim();
524
580
  let out = 'Context carried over from a previous chat (compacted). ' +
525
581
  'Treat it as the history of our work so far and continue from the current state.';
526
582
  out += NL + NL + body;
527
- if (goal) {
528
- out += NL + NL + 'Original task: ' + goal;
583
+ if (goalText) {
584
+ out += NL + NL + 'Original task: ' + goalText;
585
+ }
586
+ for (const extra of [renderCompactTodos(todos), renderCompactGoal(goal)]) {
587
+ if (extra)
588
+ out += NL + NL + extra;
529
589
  }
530
590
  return out;
531
591
  }
package/dist/compact.js CHANGED
@@ -16,7 +16,7 @@ export const COMPACT_FALLBACK_LIMIT = 40;
16
16
  * The caller owns the browser and the throttle; this function only sends.
17
17
  */
18
18
  export async function performCompact(opts) {
19
- const { browser, workdir, locale, task, transcript = null, ui = null, buildSystemPrompt, tools, answerTimeoutMs, fallbackLimit = COMPACT_FALLBACK_LIMIT, skipUiLock = false, quiet = false, selfImprovement = false, contextExhausted = false, } = opts;
19
+ const { browser, workdir, locale, task, transcript = null, ui = null, buildSystemPrompt, tools, answerTimeoutMs, fallbackLimit = COMPACT_FALLBACK_LIMIT, skipUiLock = false, quiet = false, selfImprovement = false, contextExhausted = false, todos = [], goal = null, } = opts;
20
20
  const t = translate(locale);
21
21
  // The active provider's LABEL for operator-facing text: performCompact is
22
22
  // shared by every backend, so it cannot hardcode "DeepSeek". `providerArg`
@@ -189,7 +189,14 @@ export async function performCompact(opts) {
189
189
  timeout: 60_000,
190
190
  agent: false,
191
191
  });
192
- await browser.ask(buildCompactCarryover(summary, task), {
192
+ // The checklist and the goal are SESSION state (todoStore /
193
+ // .zames-goal), not chat state: they survive a compaction by themselves,
194
+ // but the model must be told they are still in force, otherwise it
195
+ // re-creates the tasks or treats the goal as gone because the summary
196
+ // does not mention it. They ride INSIDE the carryover, not as a separate
197
+ // turn: an extra send is another rate-limit pause AND every extra
198
+ // message of the new chat is another turn the model may answer.
199
+ await browser.ask(buildCompactCarryover(summary, task, todos, goal), {
193
200
  timeout: 60_000,
194
201
  agent: false,
195
202
  });
package/dist/index.js CHANGED
@@ -1302,6 +1302,8 @@ async function main() {
1302
1302
  skipUiLock: true,
1303
1303
  selfImprovement: devMode,
1304
1304
  contextExhausted: true,
1305
+ todos: getTodos(todoStore),
1306
+ goal: sessionGoal ? { goal: sessionGoal, isCondition: true } : null,
1305
1307
  });
1306
1308
  if (!res.ok)
1307
1309
  return false;
@@ -3125,6 +3127,8 @@ async function main() {
3125
3127
  answerTimeoutMs: providerAnswerTimeoutMs(),
3126
3128
  fallbackLimit: COMPACT_FALLBACK_LIMIT,
3127
3129
  selfImprovement: devMode,
3130
+ todos: getTodos(todoStore),
3131
+ goal: sessionGoal ? { goal: sessionGoal, isCondition: true } : null,
3128
3132
  });
3129
3133
  if (res.ok) {
3130
3134
  currentChatId = res.chatId;
@@ -4730,6 +4734,10 @@ async function main() {
4730
4734
  quiet: true,
4731
4735
  skipUiLock: true,
4732
4736
  selfImprovement: devMode,
4737
+ todos: getTodos(todoStore),
4738
+ goal: sessionGoal
4739
+ ? { goal: sessionGoal, isCondition: true }
4740
+ : null,
4733
4741
  });
4734
4742
  if (res.ok) {
4735
4743
  currentChatId = res.chatId;
package/llms-full.txt CHANGED
@@ -57,7 +57,7 @@ and runs right after it, in the same chat. `Esc` aborts the current generation,
57
57
  - [Why zames?](#why-zames) · [Requirements](#requirements) · [Signing in](#signing-in)
58
58
  - [Switching providers (DeepSeek / Qwen / GLM)](#switching-providers-deepseek--qwen--glm)
59
59
  - [Installation](#installation) · [Usage](#usage) · [FAQ](#faq)
60
- - Reference: [Commands and tools](docs/commands.md) · [MCP](docs/mcp.md) · [Configuration and themes](docs/configuration.md) · [Troubleshooting](docs/troubleshooting.md)
60
+ - Reference: [Commands and tools](docs/commands.md) · [MCP](docs/mcp.md) · [Configuration and themes](docs/configuration.md) · [Troubleshooting](docs/troubleshooting.md) · [Changelog](https://viqto0r.github.io/zames_pro/changelog.html)
61
61
  - [Keywords and alternatives](#keywords-and-alternatives) · [Links](#links) · [License](#license)
62
62
 
63
63
  ## How it works
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zames_pro",
3
- "version": "2.95.5",
3
+ "version": "2.95.6",
4
4
  "description": "Terminal coding agent that drives a real browser to chat with DeepSeek, Qwen or GLM — no API key required. Reads and edits files, runs commands, commits to git, like Claude Code / Codex CLI.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -44,6 +44,8 @@
44
44
  "render-how": "tsx scripts/render-how-it-works.mts",
45
45
  "build:readme": "tsx scripts/build-readme.mts",
46
46
  "build:llms": "tsx scripts/build-llms.mts",
47
+ "build:changelog": "tsx scripts/build-changelog.mts",
48
+ "build:site-data": "tsx scripts/build-site-data.mts",
47
49
  "postinstall": "node scripts/postinstall.mjs",
48
50
  "prepare": "husky",
49
51
  "glm-smoke": "tsx scripts/glm-smoke.mts",
@@ -170,5 +172,10 @@
170
172
  "funding": {
171
173
  "type": "github",
172
174
  "url": "https://github.com/sponsors/Viqto0r"
175
+ },
176
+ "overrides": {
177
+ "@typescript-eslint/typescript-estree": {
178
+ "minimatch": "^11.0.4"
179
+ }
173
180
  }
174
181
  }