zames_pro 2.6.0 → 2.7.0
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/dist/agent-loop.js +118 -82
- package/dist/browser.js +40 -41
- package/dist/config-menu.js +25 -25
- package/dist/config.js +5 -5
- package/dist/gitTools.js +4 -4
- package/dist/i18n.js +11 -7
- package/dist/index.js +153 -150
- package/dist/input.js +82 -77
- package/dist/markdown.js +1 -1
- package/dist/net-capture.js +20 -20
- package/dist/self-review.js +16 -16
- package/dist/sessions.js +11 -11
- package/dist/spinner.js +20 -16
- package/dist/system-prompt.js +23 -0
- package/dist/theme.js +26 -26
- package/dist/tools.js +9 -9
- package/dist/transcript.js +2 -2
- package/dist/types.js +2 -2
- package/dist/web.js +16 -16
- package/dist/xml-toolcall.js +14 -14
- package/package.json +1 -1
package/dist/config-menu.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
//
|
|
1
|
+
// Interactive settings menu for the /config command.
|
|
2
2
|
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
3
|
+
// The menu renders a list of parameters grouped by sections and lets you
|
|
4
|
+
// change them with the arrow keys: boolean/enum toggle in place, number/string
|
|
5
|
+
// prompt for input. All strings come from i18n (cfg.*), so the menu is
|
|
6
|
+
// fully localized.
|
|
7
7
|
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
8
|
+
// The module doesn't know about config.ts directly (except for the schema
|
|
9
|
+
// types): the caller reads and writes values through callbacks. This makes the
|
|
10
|
+
// menu easy to test and reuse.
|
|
11
11
|
import { theme } from './theme.js';
|
|
12
12
|
const ESC = String.fromCharCode(27);
|
|
13
|
-
//
|
|
13
|
+
// Strip ANSI sequences to compute the visible length of a line.
|
|
14
14
|
function stripAnsi(s) {
|
|
15
15
|
return s.replace(/\x1b\[[0-9;?]*[A-Za-z]/g, '');
|
|
16
16
|
}
|
|
@@ -25,9 +25,9 @@ function groupLabel(field, t) {
|
|
|
25
25
|
return t(field.groupKey);
|
|
26
26
|
}
|
|
27
27
|
/**
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
28
|
+
* Show the interactive menu. Returns a promise that resolves when the
|
|
29
|
+
* user exits (q/Esc/Ctrl+C). In a non-TTY it throws — the caller
|
|
30
|
+
* must show a text list.
|
|
31
31
|
*/
|
|
32
32
|
export function runConfigMenu(opts) {
|
|
33
33
|
const input = opts.input || process.stdin;
|
|
@@ -45,9 +45,9 @@ export function runConfigMenu(opts) {
|
|
|
45
45
|
const wasRaw = input.isRaw;
|
|
46
46
|
input.setRawMode(true);
|
|
47
47
|
input.resume();
|
|
48
|
-
output.write(ESC + '[?25l'); //
|
|
49
|
-
//
|
|
50
|
-
//
|
|
48
|
+
output.write(ESC + '[?25l'); // hide the cursor while rendering
|
|
49
|
+
// Menu rendering: lines go top to bottom, and we return the cursor to the
|
|
50
|
+
// start of the block via relative moves so we don't spawn blank lines.
|
|
51
51
|
let lastRows = 0;
|
|
52
52
|
const render = () => {
|
|
53
53
|
const lines = [];
|
|
@@ -81,9 +81,9 @@ export function runConfigMenu(opts) {
|
|
|
81
81
|
lines.push('');
|
|
82
82
|
lines.push(theme.dim(t('cfg.menu.hint')));
|
|
83
83
|
}
|
|
84
|
-
//
|
|
85
|
-
// (
|
|
86
|
-
//
|
|
84
|
+
// Erase the previous block and print the new one. We count VISUAL lines
|
|
85
|
+
// (accounting for wrapping by terminal width), otherwise on narrow
|
|
86
|
+
// terminals you get "garbage" from unerased tails.
|
|
87
87
|
const cols = output.columns || 80;
|
|
88
88
|
const rowsOf = (s) => {
|
|
89
89
|
const len = stripAnsi(s).length;
|
|
@@ -106,7 +106,7 @@ export function runConfigMenu(opts) {
|
|
|
106
106
|
input.removeListener('data', onData);
|
|
107
107
|
if (input.setRawMode)
|
|
108
108
|
input.setRawMode(wasRaw || false);
|
|
109
|
-
output.write(ESC + '[?25h'); //
|
|
109
|
+
output.write(ESC + '[?25h'); // restore the cursor
|
|
110
110
|
if (resolveDone)
|
|
111
111
|
resolveDone();
|
|
112
112
|
};
|
|
@@ -146,15 +146,15 @@ export function runConfigMenu(opts) {
|
|
|
146
146
|
message = null;
|
|
147
147
|
return;
|
|
148
148
|
}
|
|
149
|
-
// number/string —
|
|
149
|
+
// number/string — prompt for input.
|
|
150
150
|
editing = true;
|
|
151
151
|
editBuf = get(f.path) === undefined ? '' : String(get(f.path));
|
|
152
152
|
};
|
|
153
153
|
const onData = (buf) => {
|
|
154
154
|
const s = buf.toString('utf-8');
|
|
155
155
|
if (editing) {
|
|
156
|
-
//
|
|
157
|
-
//
|
|
156
|
+
// Process input character by character: the terminal may send several
|
|
157
|
+
// bytes at once (paste, auto-repeat), Enter is 0x0d/0x0a, backspace is 0x7f.
|
|
158
158
|
for (const ch of s) {
|
|
159
159
|
if (ch === '\r' || ch === '\n') {
|
|
160
160
|
commitEdit();
|
|
@@ -180,9 +180,9 @@ export function runConfigMenu(opts) {
|
|
|
180
180
|
render();
|
|
181
181
|
return;
|
|
182
182
|
}
|
|
183
|
-
//
|
|
184
|
-
//
|
|
185
|
-
// escape
|
|
183
|
+
// The terminal may send several keys in one packet (fast typing,
|
|
184
|
+
// auto-repeat, automation). We parse the buffer into tokens: first
|
|
185
|
+
// escape sequences (arrows), then single characters.
|
|
186
186
|
let i = 0;
|
|
187
187
|
while (i < s.length) {
|
|
188
188
|
if (s.startsWith('\x1b[A', i)) {
|
package/dist/config.js
CHANGED
|
@@ -157,8 +157,8 @@ export function configPathFor(scope) {
|
|
|
157
157
|
return scope === 'project' ? PROJECT_CONFIG : HOME_CONFIG;
|
|
158
158
|
}
|
|
159
159
|
/**
|
|
160
|
-
*
|
|
161
|
-
*
|
|
160
|
+
* Read only the specified config file (without merging with defaults), so that
|
|
161
|
+
* writing does not "freeze" all defaults into the user's file.
|
|
162
162
|
*/
|
|
163
163
|
export function readConfigFile(file) {
|
|
164
164
|
try {
|
|
@@ -176,8 +176,8 @@ export function readConfigFile(file) {
|
|
|
176
176
|
return {};
|
|
177
177
|
}
|
|
178
178
|
/**
|
|
179
|
-
*
|
|
180
|
-
*
|
|
179
|
+
* Write a setting value to the file. Returns the final object that was
|
|
180
|
+
* written. The value is first validated against the schema.
|
|
181
181
|
*/
|
|
182
182
|
export function writeConfigValue(scope, key, raw) {
|
|
183
183
|
const field = getConfigField(key);
|
|
@@ -191,7 +191,7 @@ export function writeConfigValue(scope, key, raw) {
|
|
|
191
191
|
fs.writeFileSync(file, JSON.stringify(data, null, 2) + '\n', 'utf-8');
|
|
192
192
|
return { value, file };
|
|
193
193
|
}
|
|
194
|
-
/**
|
|
194
|
+
/** Reset a setting to the default (remove the key from the file). */
|
|
195
195
|
export function resetConfigValue(scope, key) {
|
|
196
196
|
const field = getConfigField(key);
|
|
197
197
|
if (!field)
|
package/dist/gitTools.js
CHANGED
|
@@ -36,8 +36,8 @@ export function runGit(cmd, cwd, timeout = 15_000) {
|
|
|
36
36
|
});
|
|
37
37
|
});
|
|
38
38
|
}
|
|
39
|
-
//
|
|
40
|
-
//
|
|
39
|
+
// Safely quotes paths/arguments for passing to the shell.
|
|
40
|
+
// String or array -> a string with double quotes and escaping.
|
|
41
41
|
function quoteArgs(input) {
|
|
42
42
|
const list = Array.isArray(input) ? input : [input];
|
|
43
43
|
return list
|
|
@@ -46,7 +46,7 @@ function quoteArgs(input) {
|
|
|
46
46
|
.map((v) => JSON.stringify(v))
|
|
47
47
|
.join(' ');
|
|
48
48
|
}
|
|
49
|
-
//
|
|
49
|
+
// Checks whether the directory is a git repository and gathers the context.
|
|
50
50
|
export async function getGitContext(workdir) {
|
|
51
51
|
const probe = await runGit('git rev-parse --is-inside-work-tree', workdir, 5000);
|
|
52
52
|
if (probe.trim() !== 'true')
|
|
@@ -175,7 +175,7 @@ export function createGitTools(workdir) {
|
|
|
175
175
|
if (!msg.trim()) {
|
|
176
176
|
return 'Ошибка: message пустой.';
|
|
177
177
|
}
|
|
178
|
-
//
|
|
178
|
+
// We stage everything only if the index is empty (as the description promises).
|
|
179
179
|
const staged = await runGit('git diff --cached --name-only', workdir, 10_000);
|
|
180
180
|
const hasStaged = !/^\s*/.test(staged) &&
|
|
181
181
|
staged.trim() !== '(команда выполнена, вывода нет)';
|
package/dist/i18n.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// Localization (i18n).
|
|
2
2
|
//
|
|
3
|
-
//
|
|
4
|
-
// *
|
|
5
|
-
// *
|
|
6
|
-
// *
|
|
3
|
+
// Goals:
|
|
4
|
+
// * change the interface language (help, service messages);
|
|
5
|
+
// * the agent's answer language — via the system-prompt;
|
|
6
|
+
// * the agent's answer language for a plain language.
|
|
7
7
|
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
8
|
+
// Strategy: a single key->translation map. New keys are easy to add.
|
|
9
|
+
// Russian texts (ru) are the default, English (en) is the alternative.
|
|
10
10
|
export const DEFAULT_LOCALE = 'ru';
|
|
11
11
|
export const LOCALES = [
|
|
12
12
|
{ code: 'ru', name: 'Русский', englishName: 'Russian' },
|
|
@@ -25,7 +25,7 @@ export function normalizeLocale(v) {
|
|
|
25
25
|
return 'en';
|
|
26
26
|
return DEFAULT_LOCALE;
|
|
27
27
|
}
|
|
28
|
-
//
|
|
28
|
+
// String catalog. Key -> { ru, en }. If a key is missing — we return the key itself.
|
|
29
29
|
const CATALOG = {
|
|
30
30
|
'app.tagline': {
|
|
31
31
|
ru: 'агент поверх chat.deepseek.com через Playwright',
|
|
@@ -135,6 +135,10 @@ const CATALOG = {
|
|
|
135
135
|
'msg.queued': { ru: '📨 В очередь ({n}): ', en: '📨 Queued ({n}): ' },
|
|
136
136
|
'msg.from_queue': { ru: '▶ Из очереди: ', en: '▶ From queue: ' },
|
|
137
137
|
'msg.agent_error': { ru: '✖ Ошибка агента:', en: '✖ Agent error:' },
|
|
138
|
+
'msg.suspicious_stop': {
|
|
139
|
+
ru: 'агент, похоже, остановился, не распознав вызов инструмента. Ответ сохранён в транскрипте (событие suspicious_final). Можно попросить продолжить или переотправить задачу.',
|
|
140
|
+
en: 'the agent seems to have stopped without recognizing a tool call. The response is saved in the transcript (suspicious_final event). You can ask it to continue or resend the task.',
|
|
141
|
+
},
|
|
138
142
|
'msg.critical': { ru: 'Критическая ошибка:', en: 'Critical error:' },
|
|
139
143
|
'msg.not_dir': { ru: 'Не директория: {v}', en: 'Not a directory: {v}' },
|
|
140
144
|
'prompt.review': { ru: 'REVIEW', en: 'REVIEW' },
|