zames_pro 2.82.134 → 2.82.136
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 +12 -0
- package/dist/index.js +3 -0
- package/dist/spinner.js +15 -4
- package/dist/tui/FullScreenApp.js +16 -26
- package/dist/tui/layout.js +32 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [2.82.136] - 2026-10-24
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **spinner:** a live language switch reaches the non-TTY spinner
|
|
15
|
+
|
|
16
|
+
## [2.82.135] - 2026-10-24
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- **tui:** one pure helper owns the full-screen layout arithmetic
|
|
21
|
+
|
|
10
22
|
## [2.82.134] - 2026-10-24
|
|
11
23
|
|
|
12
24
|
### Fixed
|
package/dist/index.js
CHANGED
|
@@ -1903,6 +1903,9 @@ async function main() {
|
|
|
1903
1903
|
// DeepSeek-side message printed later would still come out in the OLD
|
|
1904
1904
|
// language until a restart.
|
|
1905
1905
|
browser.setLocale(value);
|
|
1906
|
+
// A NON-TTY run has no editor: its only UI is the spinner, which must
|
|
1907
|
+
// follow the switch too (it is created per command from the locale).
|
|
1908
|
+
mod.createSpinner(value).setLocale?.(value);
|
|
1906
1909
|
if (editor) {
|
|
1907
1910
|
editor.setLocale(value);
|
|
1908
1911
|
editor.setCommands(buildSlashCommands());
|
package/dist/spinner.js
CHANGED
|
@@ -63,7 +63,11 @@ export function createSpinner(locale = 'ru') {
|
|
|
63
63
|
};
|
|
64
64
|
// Hint in the status line: while the agent works the terminal is live,
|
|
65
65
|
// so you can type the next message. Without it this is not obvious.
|
|
66
|
-
|
|
66
|
+
// RE-DERIVED on a locale switch: `/config lang` changes the language live,
|
|
67
|
+
// and a constant built once at construction kept the OLD language (and even
|
|
68
|
+
// the old locale's separator) until a restart.
|
|
69
|
+
let localeNow = locale;
|
|
70
|
+
let HINT = theme.dim(' · ' + translate(localeNow)('spinner.hint'));
|
|
67
71
|
// Run the animated status line: a brown base text plus a growing/shrinking
|
|
68
72
|
// "running" dot sequence. Shared by the thinking spinner and the send-pause
|
|
69
73
|
// indicator, so the pause is animated too (before, it was a static line and
|
|
@@ -128,6 +132,13 @@ export function createSpinner(locale = 'ru') {
|
|
|
128
132
|
spinner.text = theme.prompt('✎ ') + pending + HINT;
|
|
129
133
|
};
|
|
130
134
|
return {
|
|
135
|
+
// `/config lang` switches the language live; the legacy LineEditor and the
|
|
136
|
+
// TUI adapter both expose setLocale, and index.ts calls it on EVERY editor.
|
|
137
|
+
// Without it the non-TTY spinner kept its old-language hint until restart.
|
|
138
|
+
setLocale: (l) => {
|
|
139
|
+
localeNow = l;
|
|
140
|
+
HINT = theme.dim(' · ' + translate(localeNow)('spinner.hint'));
|
|
141
|
+
},
|
|
131
142
|
get onTasksQuery() {
|
|
132
143
|
return onTasksQuery;
|
|
133
144
|
},
|
|
@@ -148,7 +159,7 @@ export function createSpinner(locale = 'ru') {
|
|
|
148
159
|
sendPause: (seconds) => {
|
|
149
160
|
if (pending)
|
|
150
161
|
return;
|
|
151
|
-
const label = translate(
|
|
162
|
+
const label = translate(localeNow)('spinner.pause', { n: seconds });
|
|
152
163
|
// Update only the base text while the dot animation is already running,
|
|
153
164
|
// so the countdown refreshes without resetting the dots.
|
|
154
165
|
if (animating && dotTimer && spinner) {
|
|
@@ -179,7 +190,7 @@ export function createSpinner(locale = 'ru') {
|
|
|
179
190
|
// long time): the operator must see that work is in progress.
|
|
180
191
|
if (pending)
|
|
181
192
|
return;
|
|
182
|
-
startAnimated(translate(
|
|
193
|
+
startAnimated(translate(localeNow)('spinner.running_tool', { name }));
|
|
183
194
|
},
|
|
184
195
|
toolResult: (result) => {
|
|
185
196
|
stop();
|
|
@@ -194,7 +205,7 @@ export function createSpinner(locale = 'ru') {
|
|
|
194
205
|
const rendered = renderMarkdown(msg);
|
|
195
206
|
// Model answer marker: helps visually separate it from the user's input
|
|
196
207
|
// (which is highlighted by the prompt with a golden arrow).
|
|
197
|
-
console.log(NL + theme.assistant(translate(
|
|
208
|
+
console.log(NL + theme.assistant(translate(localeNow)('editor.answer')) + NL);
|
|
198
209
|
console.log(rendered);
|
|
199
210
|
console.log(theme.dim(divider()) + NL);
|
|
200
211
|
},
|
|
@@ -18,7 +18,8 @@ import { InputLine } from './InputLine.js';
|
|
|
18
18
|
import { contentWidth } from '../width.js';
|
|
19
19
|
import { translate } from '../i18n.js';
|
|
20
20
|
import { suggestRowCount } from '../input/suggest.js';
|
|
21
|
-
import {
|
|
21
|
+
import { truncateToWidth, visLen } from '../input/layout.js';
|
|
22
|
+
import { fullScreenLayout } from './layout.js';
|
|
22
23
|
import { useMouseWheel } from './useMouseWheel.js';
|
|
23
24
|
/** The header bar: title, version, working directory. */
|
|
24
25
|
function Header({ store }) {
|
|
@@ -49,27 +50,20 @@ export function FullScreenApp({ store, inputProps, }) {
|
|
|
49
50
|
const state = useSyncExternalStore(store.subscribe, store.getSnapshot);
|
|
50
51
|
const { rows } = useWindowSize();
|
|
51
52
|
const termRows = rows || 24;
|
|
52
|
-
//
|
|
53
|
-
//
|
|
54
|
-
//
|
|
55
|
-
|
|
56
|
-
const STATUS_ROWS = 1;
|
|
53
|
+
// ONE pure helper owns the panel arithmetic, so the reserved rows and the
|
|
54
|
+
// caret row can never drift apart (the component used to compute them
|
|
55
|
+
// separately and the caret landed below the input box when the panel filled
|
|
56
|
+
// the terminal).
|
|
57
57
|
const cols = Math.max(1, useWindowSize().columns || 80);
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
// of the fixed panel height, so the log viewport shrinks by one row instead
|
|
68
|
-
// of the panel overflowing; `cursorTop` (measured from the top) is NOT
|
|
69
|
-
// affected, so the caret cannot move.
|
|
70
|
-
const HINT_ROWS = 1;
|
|
71
|
-
const panelRows = HEADER_ROWS + STATUS_ROWS + INPUT_BOX_ROWS + suggestRows + HINT_ROWS;
|
|
72
|
-
const logHeight = Math.max(1, termRows - panelRows);
|
|
58
|
+
const fsLayout = fullScreenLayout({
|
|
59
|
+
termRows,
|
|
60
|
+
cols,
|
|
61
|
+
prompt: state.prompt,
|
|
62
|
+
buf: state.edit.buf,
|
|
63
|
+
cursor: state.edit.cursor,
|
|
64
|
+
suggestRows: suggestRowCount(state.edit.buf, state.commands, cols),
|
|
65
|
+
});
|
|
66
|
+
const logHeight = fsLayout.logHeight;
|
|
73
67
|
// Window the log BY RENDERED ROW: a long wrapped answer can be taller than
|
|
74
68
|
// one entry, and an entry-count window either overflowed the panel or left
|
|
75
69
|
// it half empty. `scroll` is measured in ROWS here (0 = newest at the
|
|
@@ -129,11 +123,7 @@ export function FullScreenApp({ store, inputProps, }) {
|
|
|
129
123
|
// after everything above: header + as many log rows as fit + the
|
|
130
124
|
// suggestion popup + status. `cursorTop` counts the rows ABOVE the
|
|
131
125
|
// input rows; the box border row is added by InputLine.
|
|
132
|
-
cursorTop:
|
|
133
|
-
Math.max(1, termRows - panelRows) +
|
|
134
|
-
suggestRows +
|
|
135
|
-
STATUS_ROWS +
|
|
136
|
-
1, prompt: state.prompt, locale: state.locale, commands: state.commands, locked: state.locked }), _jsx(Text, { color: "#5b616e", wrap: "truncate", children: ' ' +
|
|
126
|
+
cursorTop: fsLayout.cursorTop, prompt: state.prompt, locale: state.locale, commands: state.commands, locked: state.locked }), _jsx(Text, { color: "#5b616e", wrap: "truncate", children: ' ' +
|
|
137
127
|
translate(state.locale)(state.mouseScroll ? 'editor.keys_hint' : 'editor.keys_hint_select') })] }));
|
|
138
128
|
}
|
|
139
129
|
void contentWidth;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// PURE layout arithmetic for the FULL-SCREEN TUI. The component used to compute
|
|
2
|
+
// the panel height and the caret row separately; when the panel already fills
|
|
3
|
+
// the terminal the two disagreed by a row and the caret landed BELOW the input
|
|
4
|
+
// box. One function now owns the numbers, so the reserved rows and the caret
|
|
5
|
+
// can never drift apart.
|
|
6
|
+
import { inputBoxRows } from '../input/layout.js';
|
|
7
|
+
/** Rows of the fixed header: the title row + the divider. */
|
|
8
|
+
export const HEADER_ROWS = 2;
|
|
9
|
+
/** Rows of the status bar above the input box. */
|
|
10
|
+
export const STATUS_ROWS = 1;
|
|
11
|
+
/** Rows of the key hint UNDER the input box. */
|
|
12
|
+
export const HINT_ROWS = 1;
|
|
13
|
+
export function fullScreenLayout(input) {
|
|
14
|
+
const termRows = Math.max(1, Math.floor(input.termRows) || 24);
|
|
15
|
+
const cols = Math.max(1, Math.floor(input.cols) || 80);
|
|
16
|
+
const box = inputBoxRows(input.prompt, input.buf, input.cursor, cols);
|
|
17
|
+
const suggestRows = Math.max(0, Math.floor(input.suggestRows) || 0);
|
|
18
|
+
const panelRows = HEADER_ROWS + STATUS_ROWS + box + suggestRows + HINT_ROWS;
|
|
19
|
+
const logHeight = Math.max(1, termRows - panelRows);
|
|
20
|
+
// The caret counts the SAME viewport the reservation uses.
|
|
21
|
+
const cursorTop = HEADER_ROWS + logHeight + suggestRows + STATUS_ROWS + 1;
|
|
22
|
+
return {
|
|
23
|
+
headerRows: HEADER_ROWS,
|
|
24
|
+
statusRows: STATUS_ROWS,
|
|
25
|
+
hintRows: HINT_ROWS,
|
|
26
|
+
inputBoxRows: box,
|
|
27
|
+
suggestRows,
|
|
28
|
+
panelRows,
|
|
29
|
+
logHeight,
|
|
30
|
+
cursorTop,
|
|
31
|
+
};
|
|
32
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zames_pro",
|
|
3
|
-
"version": "2.82.
|
|
3
|
+
"version": "2.82.136",
|
|
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": {
|