zames_pro 2.82.136 → 2.82.137

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,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [2.82.137] - 2026-10-24
11
+
12
+ ### Changed
13
+
14
+ - docs: drop backlog-id references from source comments
15
+
10
16
  ## [2.82.136] - 2026-10-24
11
17
 
12
18
  ### Fixed
@@ -14,7 +14,7 @@ export async function runAgentLoop({ browser, tools, task, workdir, maxIteration
14
14
  // `undefined` means "read .zames/hooks.json"; an explicit null disables
15
15
  // hooks entirely.
16
16
  const hookConfig = hooks === undefined ? loadHooks(workdir) : (hooks ?? {});
17
- // Same for the approval policy (C1): read `.zames/permissions.json` once.
17
+ // Same for the approval policy: read `.zames/permissions.json` once.
18
18
  const permissionPolicy = permissions === undefined ? loadPermissions(workdir) : permissions;
19
19
  // UI callbacks must NEVER break the agent loop. A rendering error (a huge
20
20
  // tool result, a broken markdown frame, a closed terminal) used to throw
@@ -81,7 +81,7 @@ export async function runAgentLoop({ browser, tools, task, workdir, maxIteration
81
81
  if (freshChat) {
82
82
  await browser.newChat();
83
83
  transcript?.log('new_chat');
84
- // SessionStart hook (N32): a fresh chat is the start of a session, so a
84
+ // SessionStart hook: a fresh chat is the start of a session, so a
85
85
  // hook can inject context or set up state. Best-effort, output is logged.
86
86
  try {
87
87
  const out = await runLifecycleHooks(hookConfig, 'SessionStart', workdir);
@@ -118,7 +118,7 @@ export async function runAgentLoop({ browser, tools, task, workdir, maxIteration
118
118
  let context;
119
119
  try {
120
120
  // Pass the task text so nested AGENTS.md/MEMORY.md for the directories
121
- // this task actually touches are pulled in (B6, path-scoped rules).
121
+ // this task actually touches are pulled in (path-scoped rules).
122
122
  context = await loadProjectContext(workdir, [task]);
123
123
  }
124
124
  catch {
@@ -280,7 +280,7 @@ export async function runAgentLoop({ browser, tools, task, workdir, maxIteration
280
280
  let lastAutoCompactTokens = -1;
281
281
  // Set when an auto-compact returned the SAME chat id it started in — i.e.
282
282
  // the "fresh chat" never opened and the compaction did nothing. Without this
283
- // guard a broken newChat() (see B2) made the loop compact on EVERY tool call
283
+ // guard a broken newChat() made the loop compact on EVERY tool call
284
284
  // while the context kept growing. Defense in depth: the root cause is fixed,
285
285
  // but a future regression must not turn into an endless "compacting" loop.
286
286
  let autoCompactDisabled = false;
@@ -314,7 +314,7 @@ export async function runAgentLoop({ browser, tools, task, workdir, maxIteration
314
314
  // 300s rate-limit wait or the finish loop) while the next iteration
315
315
  // started a SECOND ask() against the same page — two sends / two Continue
316
316
  // clicks.
317
- // UserPromptSubmit hook (N32): runs right before the prompt is sent. Its
317
+ // UserPromptSubmit hook: runs right before the prompt is sent. Its
318
318
  // stdout is appended to the outgoing message as extra context, mirroring
319
319
  // Claude Code. Best-effort — a hook failure never blocks the send.
320
320
  try {
@@ -787,7 +787,7 @@ export async function runAgentLoop({ browser, tools, task, workdir, maxIteration
787
787
  'repeat the identical call.';
788
788
  continue;
789
789
  }
790
- // N34: several READ-ONLY calls in one batch are independent, so run them
790
+ // Several READ-ONLY calls in one batch are independent, so run them
791
791
  // concurrently instead of one-by-one (the model often emits 4-6 Reads in a
792
792
  // single answer and each awaited round-trip added latency). The fast path
793
793
  // is deliberately NARROW: it is taken only when EVERY call is a known
@@ -1016,7 +1016,7 @@ export async function runAgentLoop({ browser, tools, task, workdir, maxIteration
1016
1016
  results.push({ tool: call.tool, result: blocked });
1017
1017
  continue;
1018
1018
  }
1019
- // Approval policy (C1): a `deny` rule blocks the call (like a PreToolUse
1019
+ // Approval policy: a `deny` rule blocks the call (like a PreToolUse
1020
1020
  // denial); an `ask` rule prompts the operator. Hooks stay authoritative
1021
1021
  // for programmatic guards — this is the human-in-the-loop layer.
1022
1022
  const decision = decidePermission(permissionPolicy, call.tool, call.args);
@@ -1065,7 +1065,7 @@ export async function runAgentLoop({ browser, tools, task, workdir, maxIteration
1065
1065
  const poll = setInterval(syncToolAbort, 100);
1066
1066
  if (typeof poll.unref === 'function')
1067
1067
  poll.unref();
1068
- // Time the tool (T-D3): the transcript carries durationMs so /cost can
1068
+ // Time the tool: the transcript carries durationMs so /cost can
1069
1069
  // show where the time goes (frequent Read→Edit cycles vs slow Bash).
1070
1070
  const toolStart = Date.now();
1071
1071
  try {
@@ -1089,7 +1089,7 @@ export async function runAgentLoop({ browser, tools, task, workdir, maxIteration
1089
1089
  [PostToolUse hook]
1090
1090
  ${post}`;
1091
1091
  }
1092
- // N38: after a file-mutating tool, run the project's own check and
1092
+ // After a file-mutating tool, run the project's own check and
1093
1093
  // append its summary, so a type error reaches the model immediately
1094
1094
  // instead of costing a whole round-trip. Best-effort and capped.
1095
1095
  if (shouldRunDiagnostics(diagnostics, call.tool)) {
package/dist/changelog.js CHANGED
@@ -80,7 +80,7 @@ export function renderChangelogDraft(groups) {
80
80
  }
81
81
  /**
82
82
  * Replace the body between `## [Unreleased]` and the next `## [` heading with
83
- * a freshly drafted body (D2). PURE so a test can pin the exact behavior.
83
+ * a freshly drafted body. PURE so a test can pin the exact behavior.
84
84
  *
85
85
  * When `body` is empty the existing Unreleased section is CLEARED to just the
86
86
  * heading (no stray blank content). A changelog without an Unreleased heading
package/dist/commands.js CHANGED
@@ -238,7 +238,7 @@ export function renderCost(stats, transcriptFile, tokenUsage = null, t = transla
238
238
  for (const [name, n] of top)
239
239
  lines.push(' ' + nameLine(name) + ': ' + n);
240
240
  }
241
- // T-D3: where the time went. Sort by total ms, show the top tools with the
241
+ // Where the time went. Sort by total ms, show the top tools with the
242
242
  // count and a human duration, so Read→Edit cycles and slow Bash calls are
243
243
  // visible at a glance.
244
244
  const byTime = Object.entries(stats.toolTime || {})
package/dist/compact.js CHANGED
@@ -43,7 +43,7 @@ export async function performCompact(opts) {
43
43
  try {
44
44
  if (!quiet)
45
45
  log(t('compact.start'));
46
- // PreCompact hook (N32): runs BEFORE the chat is summarized/rewritten, so
46
+ // PreCompact hook: runs BEFORE the chat is summarized/rewritten, so
47
47
  // a hook can persist state or notify. Best-effort.
48
48
  try {
49
49
  const out = await runLifecycleHooks(loadHooks(workdir), 'PreCompact', workdir, { chatId: currentChatId });
package/dist/config.js CHANGED
@@ -135,7 +135,7 @@ export const DEFAULTS = {
135
135
  contextLimit: 1_000_000,
136
136
  // 0 = auto: terminal width, capped at 100 columns (the historical width).
137
137
  answerWidth: 0,
138
- // N37 statusLine hook. Off by default; edit config.json to set a command.
138
+ // statusLine hook. Off by default; edit config.json to set a command.
139
139
  statusLineCommand: '',
140
140
  statusLineIntervalMs: 10_000,
141
141
  // Use the Ink/React TUI for the input area (the rich editor). Set to false
package/dist/index.js CHANGED
@@ -257,7 +257,7 @@ const RELOADABLE = [
257
257
  'config',
258
258
  'fsutil',
259
259
  'backlog',
260
- // C3 modules index.ts now calls through the mod bag (G2): without this a
260
+ // Modules index.ts now calls through the mod bag: without this a
261
261
  // /reload silently kept the OLD commands/run-task/attach-refs until a restart.
262
262
  // 'input/layout' is NOT listed: its only live consumers are input.ts (the
263
263
  // long-lived LineEditor, itself not reloadable) and spinner.ts, which already
@@ -594,7 +594,7 @@ async function refreshDynamicCommands(workdir) {
594
594
  }
595
595
  const cmds = await loadCommands(workdir);
596
596
  for (const c of cmds) {
597
- // B7: carry the declared argument hint as a separate field so the hint is
597
+ // Carry the declared argument hint as a separate field so the hint is
598
598
  // SHOWN in the suggest list but never inserted into the input line.
599
599
  out.push({
600
600
  name: '/' + c.name,
@@ -619,7 +619,7 @@ async function expandSlashTarget(workdir, name, rest) {
619
619
  const commands = await loadCommands(workdir);
620
620
  const cmd = commands.find((c) => c.name.toLowerCase() === name.toLowerCase());
621
621
  if (cmd) {
622
- // B7: refuse to run when declared positional arguments are missing.
622
+ // Refuse to run when declared positional arguments are missing.
623
623
  const missing = mod.commands.missingCommandArgs(cmd.arguments, rest);
624
624
  if (missing.length)
625
625
  return { missing };
@@ -1410,7 +1410,7 @@ async function main() {
1410
1410
  let reviewMode = null;
1411
1411
  process.on('SIGINT', async () => {
1412
1412
  running = false;
1413
- // Kill any background processes (N33) so no dev-server outlives the agent.
1413
+ // Kill any background processes so no dev-server outlives the agent.
1414
1414
  killAllBackground();
1415
1415
  await browser.close().catch(() => { });
1416
1416
  // Close the lazy headless browser from web.js, otherwise it would stay
@@ -1468,7 +1468,7 @@ async function main() {
1468
1468
  // swap. Assigned where the editor is built (see the login wiring below);
1469
1469
  // a no-op until then so /provider before setup is harmless.
1470
1470
  let wireLoginCallbacks = () => { };
1471
- // N37 statusLine hook timer (cleared on exit).
1471
+ // statusLine hook timer (cleared on exit).
1472
1472
  let statusLineTimer = null;
1473
1473
  let waiter = null;
1474
1474
  const takeInput = () => {
@@ -1619,7 +1619,7 @@ async function main() {
1619
1619
  };
1620
1620
  };
1621
1621
  wireLoginCallbacks(browser);
1622
- // N37 statusLine hook: run the configured command on its own timer (never
1622
+ // statusLine hook: run the configured command on its own timer (never
1623
1623
  // per-render — a spawn would block typing) and show its first stdout line
1624
1624
  // in the status line. Off when ui.statusLineCommand is empty.
1625
1625
  if (config.ui.statusLineCommand) {
@@ -4065,7 +4065,7 @@ async function main() {
4065
4065
  }
4066
4066
  }
4067
4067
  }
4068
- // B7: a custom command with mandatory `arguments:` refuses to run until the
4068
+ // A custom command with mandatory `arguments:` refuses to run until the
4069
4069
  // operator supplies them (by position).
4070
4070
  if (missingArgs) {
4071
4071
  console.error(theme.error(t('msg.missing_args', { v: missingArgs.join(', ') })));
@@ -4081,7 +4081,7 @@ async function main() {
4081
4081
  : expandedTask !== null
4082
4082
  ? expandedTask
4083
4083
  : trimmed;
4084
- // B5: inline any `@path` references into the task so the agent does not
4084
+ // Inline any `@path` references into the task so the agent does not
4085
4085
  // spend a round-trip reading a file the operator already pointed at. Only
4086
4086
  // existing files are inlined; a bare `@name` in prose is left untouched.
4087
4087
  let finalTaskText = taskText;
package/dist/input.js CHANGED
@@ -173,7 +173,7 @@ export class LineEditor {
173
173
  // A callback the editor calls before every render to read the agent's
174
174
  // current task-list summary ("tasks: 2/5"), empty when there is no list.
175
175
  onTasksQuery;
176
- // Extra status text produced by an external command (N37 statusLine hook).
176
+ // Extra status text produced by an external command (the statusLine hook).
177
177
  // Set via setStatusLine(); shown before the queue/tasks badges. Kept as a
178
178
  // plain field because the CALLER runs the command on its own timer (a
179
179
  // per-render spawn would block typing).
@@ -361,7 +361,7 @@ export class LineEditor {
361
361
  return '';
362
362
  }
363
363
  }
364
- // The statusLine hook text (N37), shown before the queue/tasks badges.
364
+ // The statusLine hook text, shown before the queue/tasks badges.
365
365
  // A trailing space separates it from whatever follows; empty hides it.
366
366
  _statusLineBadge() {
367
367
  return this.statusLine ? theme.system(this.statusLine) + ' ' : '';
@@ -605,7 +605,7 @@ export class LineEditor {
605
605
  }
606
606
  // Update the context window size (from config.ui.contextLimit). The next
607
607
  // render recomputes the percentage and its color with the new limit.
608
- // Set the statusLine hook text (N37). The caller runs the command on its
608
+ // Set the statusLine hook text. The caller runs the command on its
609
609
  // own timer; this only stores + repaints. An empty string hides the badge.
610
610
  setStatusLine(text) {
611
611
  const t = String(text || '').trim();
package/dist/run-task.js CHANGED
@@ -5,7 +5,7 @@ import { formatCompactTokens, pasteReplacement, expandPastes } from './input.js'
5
5
  import { DEFAULT_LOCALE } from './i18n.js';
6
6
  import { providerAskDeadlineMs } from './config.js';
7
7
  // Ask the operator to approve a tool call flagged by an `ask` permission rule
8
- // (C1). While the LineEditor owns the terminal it must be paused first, or the
8
+ // While the LineEditor owns the terminal it must be paused first, or the
9
9
  // confirmation prompt and the input line fight for the same keys. A non-TTY run
10
10
  // has no way to answer, so it DENIES (never silently allows a guarded call).
11
11
  export async function askOperatorConfirm(editor, question, t,
@@ -332,7 +332,7 @@ export async function runTask(deps, browser, tools, taskText, workdir, opts, att
332
332
  // Set when the loop ends without a real answer (iteration limit / watchdog)
333
333
  // so the one-shot mode can exit non-zero. See N5.
334
334
  let failure = null;
335
- // N31: the machine-readable reason for the last task's outcome.
335
+ // The machine-readable reason for the last task's outcome.
336
336
  let outcomeKind = 'ok';
337
337
  // How many auto-continue turns a completion goal has already spent.
338
338
  let goalTurns = 0;
@@ -389,7 +389,7 @@ export async function runTask(deps, browser, tools, taskText, workdir, opts, att
389
389
  },
390
390
  onWarning: (msg) => ui.warning(msg),
391
391
  onAskPermission: async (info) => {
392
- // C1: a rule with action "ask". Show the reason and wait for the
392
+ // A rule with action "ask". Show the reason and wait for the
393
393
  // operator. In non-TTY this denies.
394
394
  ui.warning(t('perm.ask', { tool: info.tool, reason: info.reason }));
395
395
  const ok = await askOperatorConfirm(editor || null, t('perm.confirm'), t, locale);
@@ -440,7 +440,7 @@ export async function runTask(deps, browser, tools, taskText, workdir, opts, att
440
440
  }
441
441
  }
442
442
  : onAskUser,
443
- // N38: the check command appended to a tool result after an edit
443
+ // The check command appended to a tool result after an edit
444
444
  // (off by default; config.diagnostics).
445
445
  diagnostics: deps.config.diagnostics,
446
446
  });
@@ -452,7 +452,7 @@ export async function runTask(deps, browser, tools, taskText, workdir, opts, att
452
452
  ui.warning(outcome);
453
453
  transcript?.log('agent_no_answer', { outcome });
454
454
  failure = outcome;
455
- // N31: a machine-readable reason so `--output-format jsonl` consumers
455
+ // A machine-readable reason so `--output-format jsonl` consumers
456
456
  // (CI) can tell a real error from an exhausted limit / watchdog.
457
457
  outcomeKind = outcome.startsWith('Iteration limit reached')
458
458
  ? 'iteration_limit'
@@ -570,7 +570,7 @@ export async function runTask(deps, browser, tools, taskText, workdir, opts, att
570
570
  sendSystemPrompt: false,
571
571
  };
572
572
  }
573
- // Stop hook (N32): the whole task (including drained queue messages) is
573
+ // Stop hook: the whole task (including drained queue messages) is
574
574
  // done. A cleanup/notification hook runs here. Best-effort.
575
575
  try {
576
576
  // LOAD the config: `undefined` here made every Stop hook a no-op — the
@@ -584,7 +584,7 @@ export async function runTask(deps, browser, tools, taskText, workdir, opts, att
584
584
  ui.warning(out);
585
585
  }
586
586
  catch { }
587
- // N31: a single terminal event carrying the reason, so a jsonl consumer
587
+ // A single terminal event carrying the reason, so a jsonl consumer
588
588
  // does not have to guess from the exit code alone.
589
589
  transcript?.log('task_result', {
590
590
  ok: !failure,
@@ -1,5 +1,5 @@
1
1
  import { spawn } from 'node:child_process';
2
- // N37 statusLine hook. When `ui.statusLineCommand` is set, zames runs it on a
2
+ // statusLine hook. When `ui.statusLineCommand` is set, zames runs it on a
3
3
  // timer with a JSON status object on stdin and shows the FIRST line of its
4
4
  // stdout in the status line (like Claude Code). The command is deliberately
5
5
  // run OUT of the render path: a per-render spawn would block typing, so the
package/dist/subagent.js CHANGED
@@ -178,7 +178,7 @@ export function createSubagentRunner(opts) {
178
178
  browser.onSendState = savedHooks.onSendState;
179
179
  browser.onNotice = savedHooks.onNotice;
180
180
  }
181
- // SubagentStop hook (N32): fires after the nested loop finishes, so a hook
181
+ // SubagentStop hook: fires after the nested loop finishes, so a hook
182
182
  // can clean up or notify. Best-effort; its stdout is appended to the report.
183
183
  let hookOut = '';
184
184
  try {
package/dist/tools.js CHANGED
@@ -104,7 +104,7 @@ export function createTools(workdir, { undo, todos, readOnly = false, subagents
104
104
  },
105
105
  fn: async ({ path: p, offset, limit, numbered }) => {
106
106
  const file = safe(req(p, 'path'));
107
- // Binary guard (N35): reading an image/archive as utf-8 produced
107
+ // Binary guard: reading an image/archive as utf-8 produced
108
108
  // mojibake the model tried to reason about. Detect a binary buffer
109
109
  // BEFORE decoding and answer with useful metadata instead.
110
110
  // A read FAILURE (a missing file, a directory, EACCES) is answered in
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zames_pro",
3
- "version": "2.82.136",
3
+ "version": "2.82.137",
4
4
  "description": "Terminal coding agent that drives a real browser to chat with DeepSeek, Qwen and other web LLMs — no API key required. Reads and edits files, runs commands, commits to git, like Claude Code / Codex CLI.",
5
5
  "type": "module",
6
6
  "bin": {