zames_pro 2.96.3 → 2.96.4

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,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [2.96.4] - 2026-11-06
11
+
12
+ ### Fixed
13
+
14
+ - **tui:** keep a tall suggestion popup from overflowing the layout
15
+ - **scheduler:** scan cron in UTC so a DST fall-back hour is not skipped
16
+ - **context:** parse a YAML block list of command arguments
17
+ - **provider-fallback:** probe a guest-capable provider without the guest flag
18
+ - **cli:** accept the --flag=value spelling of a value flag
19
+
10
20
  ## [2.96.3] - 2026-11-06
11
21
 
12
22
  ### Fixed
package/dist/cli-args.js CHANGED
@@ -22,6 +22,14 @@ export const SKIP_VALUE_FLAGS = [
22
22
  export function createCliArgs(argv) {
23
23
  const args = Array.isArray(argv) ? argv : [];
24
24
  const getArg = (flag, fallback = null) => {
25
+ // `--task=fix it` is the common shell spelling: the SEPARATE form below
26
+ // never matched it, so the value was dropped from the task text and the
27
+ // operator's prompt vanished. Check the `=` form first.
28
+ const eq = flag + '=';
29
+ const joined = args.find((a) => a.startsWith(eq));
30
+ if (joined !== undefined && joined.length > eq.length) {
31
+ return joined.slice(eq.length);
32
+ }
25
33
  const i = args.indexOf(flag);
26
34
  // Truthiness, not `!== undefined`: an EMPTY value (`--task ''`) must
27
35
  // fall back too - an empty task is not a task. A following FLAG is not
package/dist/context.js CHANGED
@@ -332,11 +332,15 @@ function parseFrontmatter(raw) {
332
332
  const userInvokable = typeof out['user-invokable'] === 'string'
333
333
  ? out['user-invokable'].toLowerCase() !== 'false'
334
334
  : undefined;
335
+ // A YAML BLOCK LIST (`arguments:` + ` - env`) folds into one string with
336
+ // the list markers, so splitting on whitespace produced `['-', 'env']`: every
337
+ // declared name was 'missing' and the command was refused. Strip the markers
338
+ // first; the inline form (`arguments: env mode`) still works.
335
339
  const argumentsList = typeof out['arguments'] === 'string'
336
340
  ? out['arguments']
337
341
  .split(/[,\s]+/)
338
342
  .map((s) => s.trim())
339
- .filter(Boolean)
343
+ .filter((s) => s && s !== '-')
340
344
  : undefined;
341
345
  return {
342
346
  name: out.name,
@@ -26,7 +26,10 @@ export async function pickFallbackProvider(active, candidates, probeLogin, hasMa
26
26
  continue;
27
27
  // A live GUEST session is not a fallback (it dies in a few turns), but the
28
28
  // provider is still authorizable — signing in makes it a candidate.
29
- if (c.guestAllowed && c.guestSession !== false) {
29
+ // `guestSession` is OPTIONAL: an older caller that predates the field
30
+ // leaves it undefined, and reading that as "a guest" silently refused to
31
+ // fall back to a signed-in provider with a live session.
32
+ if (c.guestAllowed && c.guestSession === true) {
30
33
  authorizable.push(c.id);
31
34
  continue;
32
35
  }
package/dist/scheduler.js CHANGED
@@ -157,18 +157,24 @@ export function nextCronTime(expr, fromMs) {
157
157
  const c = parseCron(expr);
158
158
  if (!c)
159
159
  return null;
160
- const d = new Date(fromMs);
161
- d.setSeconds(0, 0);
162
- d.setMinutes(d.getMinutes() + 1);
160
+ // The scan steps in UTC MILLISECONDS, not local minutes: on the autumn DST
161
+ // FALL-BACK an hour repeats, and `setMinutes(getMinutes()+1)` visits every
162
+ // wall-clock minute TWICE (then jumps over the second occurrence), so a
163
+ // 02:45 job created after the first 02:45 fired the NEXT DAY. A fixed
164
+ // 60-second step visits every real minute exactly once; the field checks
165
+ // still use the LOCAL getters, so the wall-clock match is unchanged.
166
+ const step = 60_000;
167
+ let t = Math.floor(fromMs / step) * step + step;
163
168
  const limit = fromMs + 4 * 366 * 24 * 60 * 60 * 1000;
164
- while (d.getTime() <= limit) {
169
+ while (t <= limit) {
170
+ const d = new Date(t);
165
171
  if (c.minute.has(d.getMinutes()) &&
166
172
  c.hour.has(d.getHours()) &&
167
173
  c.month.has(d.getMonth() + 1) &&
168
174
  dayMatches(c, d)) {
169
- return d.getTime();
175
+ return t;
170
176
  }
171
- d.setMinutes(d.getMinutes() + 1);
177
+ t += step;
172
178
  }
173
179
  return null;
174
180
  }
@@ -20,8 +20,15 @@ export function fullScreenLayout(input) {
20
20
  // width — and the pure helper stays consistent with what it renders.
21
21
  const cols = Math.max(1, Math.floor(input.cols) || 80);
22
22
  const box = inputBoxRows(input.prompt, input.buf, input.cursor, cols, input.borderCols ?? 2);
23
- const suggestRows = Math.max(0, Math.floor(input.suggestRows) || 0);
24
- const panelRows = HEADER_ROWS + STATUS_ROWS + box + suggestRows + HINT_ROWS;
23
+ const wanted = Math.max(0, Math.floor(input.suggestRows) || 0);
24
+ // The layout must FIT the terminal: with a tall popup (a project with many
25
+ // custom commands) the reserved rows exceeded `termRows`, `logHeight` was
26
+ // clamped to 1 and the panel still overflowed — the input rows were pushed
27
+ // below the screen. The popup gives way first (it is a hint list), the log
28
+ // keeps at least one row.
29
+ const fixed = HEADER_ROWS + STATUS_ROWS + box + HINT_ROWS;
30
+ const suggestRows = Math.max(0, Math.min(wanted, termRows - fixed - 1));
31
+ const panelRows = fixed + suggestRows;
25
32
  const logHeight = Math.max(1, termRows - panelRows);
26
33
  // The caret counts the SAME viewport the reservation uses.
27
34
  // The suggestion popup is drawn ABOVE the box and the box does NOT move, so
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zames_pro",
3
- "version": "2.96.3",
3
+ "version": "2.96.4",
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": {