zames_pro 2.49.4 → 2.50.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/README.md +1 -1
- package/dist/i18n.js +62 -2
- package/dist/index.js +2 -1
- package/dist/self-review.js +44 -34
- package/logo.jpg +0 -0
- package/package.json +2 -2
- package/logo.png +0 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# zames_pro
|
|
2
2
|
|
|
3
|
-

|
|
4
4
|
|
|
5
5
|
A terminal coding agent that works on top of [chat.deepseek.com](https://chat.deepseek.com/) through Playwright.
|
|
6
6
|
In spirit it is similar to Claude Code / Codex CLI: it starts in the current
|
package/dist/i18n.js
CHANGED
|
@@ -446,8 +446,8 @@ const CATALOG = {
|
|
|
446
446
|
'help.files.config': { ru: 'Конфиг:', en: 'Config:' },
|
|
447
447
|
// ---------- spinner ----------
|
|
448
448
|
'spinner.phrases': {
|
|
449
|
-
ru: '
|
|
450
|
-
en: '
|
|
449
|
+
ru: 'Анализирую запрос…|Изучаю контекст…|Планирую решение…|Обрабатываю данные…|Формулирую ответ…|Проверяю детали…|Собираю информацию…|Обдумываю варианты…|Структурирую мысли…|Готовлю решение…|Анализирую код…|Уточняю детали…|Выполняю вычисления…|Систематизирую данные…|Прорабатываю задачу…|Проверяю логику…|Оптимизирую подход…|Формирую выводы…',
|
|
450
|
+
en: 'Analyzing the request…|Reviewing the context…|Planning the solution…|Processing the data…|Formulating the answer…|Checking the details…|Gathering information…|Weighing the options…|Structuring the thoughts…|Preparing the solution…|Analyzing the code…|Clarifying the details…|Running the computation…|Organizing the data…|Working through the task…|Verifying the logic…|Optimizing the approach…|Forming conclusions…',
|
|
451
451
|
},
|
|
452
452
|
'spinner.hint': { ru: 'Esc — стоп', en: 'Esc — stop' },
|
|
453
453
|
'spinner.pause': {
|
|
@@ -814,6 +814,66 @@ const CATALOG = {
|
|
|
814
814
|
ru: 'Использование: /self-apply <name>',
|
|
815
815
|
en: 'Usage: /self-apply <name>',
|
|
816
816
|
},
|
|
817
|
+
'self.no_src': {
|
|
818
|
+
ru: 'Самообзор отменён: в {dir} нет .ts файлов. Проверь, что src/ не пуст и ты запускаешь агента из корня проекта.',
|
|
819
|
+
en: 'Self-review aborted: no .ts files in {dir}. Check that src/ is not empty and you run the agent from the project root.',
|
|
820
|
+
},
|
|
821
|
+
'self.no_src_err': {
|
|
822
|
+
ru: 'SRC_DIR пуст — нечего ревьюить',
|
|
823
|
+
en: 'SRC_DIR is empty - nothing to review',
|
|
824
|
+
},
|
|
825
|
+
'self.snapshot': { ru: '📸 Снапшот: {dir}', en: '📸 Snapshot: {dir}' },
|
|
826
|
+
'self.files': { ru: 'Файлов: {n} — {list}', en: 'Files: {n} — {list}' },
|
|
827
|
+
'self.starting': {
|
|
828
|
+
ru: 'Начинаю самообзор...',
|
|
829
|
+
en: 'Starting self-review...',
|
|
830
|
+
},
|
|
831
|
+
'self.report': { ru: '📋 Отчёт:', en: '📋 Report:' },
|
|
832
|
+
'self.report_empty': { ru: '(пусто)', en: '(empty)' },
|
|
833
|
+
'self.report_path': { ru: 'Отчёт: {v}', en: 'Report: {v}' },
|
|
834
|
+
'self.snapshot_path': { ru: 'Снапшот: {v}', en: 'Snapshot: {v}' },
|
|
835
|
+
'self.changed': {
|
|
836
|
+
ru: 'Изменено: {n} файл(ов): {list}',
|
|
837
|
+
en: 'Changed: {n} file(s): {list}',
|
|
838
|
+
},
|
|
839
|
+
'self.changed_none': {
|
|
840
|
+
ru: 'Изменено: (ничего — только отчёт)',
|
|
841
|
+
en: 'Changed: (nothing - report only)',
|
|
842
|
+
},
|
|
843
|
+
'self.next': { ru: 'Дальше:', en: 'Next:' },
|
|
844
|
+
'self.diff_hint': {
|
|
845
|
+
ru: ' /self-diff {name} — посмотреть различия',
|
|
846
|
+
en: ' /self-diff {name} — view the diff',
|
|
847
|
+
},
|
|
848
|
+
'self.apply_hint': {
|
|
849
|
+
ru: ' /self-apply {name} — применить к живому src/',
|
|
850
|
+
en: ' /self-apply {name} — apply to the live src/',
|
|
851
|
+
},
|
|
852
|
+
'self.no_diff': { ru: 'Различий нет.', en: 'No differences.' },
|
|
853
|
+
'self.apply_no_ts': {
|
|
854
|
+
ru: 'В снапшоте {dir} нет .ts файлов. Apply отменён, чтобы не стирать src/.',
|
|
855
|
+
en: 'Snapshot {dir} has no .ts files. Apply aborted to avoid wiping src/.',
|
|
856
|
+
},
|
|
857
|
+
'self.applied': {
|
|
858
|
+
ru: '✅ Применено: {n} файл(ов)',
|
|
859
|
+
en: '✅ Applied: {n} file(s)',
|
|
860
|
+
},
|
|
861
|
+
'self.backup': { ru: 'Бэкап: {dir}', en: 'Backup: {dir}' },
|
|
862
|
+
'self.restart_hint': {
|
|
863
|
+
ru: 'Перезапусти агента, чтобы изменения вступили в силу.',
|
|
864
|
+
en: 'Restart the agent for the changes to take effect.',
|
|
865
|
+
},
|
|
866
|
+
'self.no_snapshots': { ru: 'Снапшотов нет.', en: 'No snapshots.' },
|
|
867
|
+
'self.list_title': {
|
|
868
|
+
ru: 'Снапшоты самообзора:',
|
|
869
|
+
en: 'Self-review snapshots:',
|
|
870
|
+
},
|
|
871
|
+
'self.list_changed': { ru: '[{n} изменено]', en: '[{n} changed]' },
|
|
872
|
+
'self.list_unchanged': { ru: '[без правок]', en: '[no changes]' },
|
|
873
|
+
'self.list_commands': {
|
|
874
|
+
ru: 'Команды: /self-diff <name>, /self-apply <name>',
|
|
875
|
+
en: 'Commands: /self-diff <name>, /self-apply <name>',
|
|
876
|
+
},
|
|
817
877
|
'self.fix_hint': {
|
|
818
878
|
ru: '\n💡 Режим ревью по снапшоту {name}. Пиши агенту задачу или /self-done.\n',
|
|
819
879
|
en: '\n💡 Review mode on snapshot {name}. Send the agent a task or /self-done.\n',
|
package/dist/index.js
CHANGED
|
@@ -2149,6 +2149,7 @@ async function main() {
|
|
|
2149
2149
|
config,
|
|
2150
2150
|
focus: focus || undefined,
|
|
2151
2151
|
transcript,
|
|
2152
|
+
locale: currentLocale,
|
|
2152
2153
|
});
|
|
2153
2154
|
// Switch to review mode:
|
|
2154
2155
|
// - working directory = snapshot
|
|
@@ -2262,7 +2263,7 @@ async function main() {
|
|
|
2262
2263
|
}
|
|
2263
2264
|
if (lower === '/self-list') {
|
|
2264
2265
|
try {
|
|
2265
|
-
await mod.selfList({ config });
|
|
2266
|
+
await mod.selfList({ config, locale: currentLocale });
|
|
2266
2267
|
}
|
|
2267
2268
|
catch (e) {
|
|
2268
2269
|
console.error(theme.error(t('msg.error')), e.message);
|
package/dist/self-review.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
2
|
import fs from 'fs/promises';
|
|
3
3
|
import { theme } from './theme.js';
|
|
4
|
+
import { translate, DEFAULT_LOCALE } from './i18n.js';
|
|
4
5
|
import { fileURLToPath } from 'url';
|
|
5
6
|
import { ZAMES_HOME } from './config.js';
|
|
6
7
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
@@ -22,6 +23,12 @@ function resolveSrcDir() {
|
|
|
22
23
|
}
|
|
23
24
|
const SRC_DIR = resolveSrcDir();
|
|
24
25
|
const SNAP_ROOT = path.join(ZAMES_HOME, 'snapshots');
|
|
26
|
+
// Localization for everything the OPERATOR sees. The locale is passed in from
|
|
27
|
+
// the caller (src/index.ts holds currentLocale); without it we fall back to the
|
|
28
|
+
// default so a direct call never breaks.
|
|
29
|
+
function translator(locale) {
|
|
30
|
+
return translate(locale || DEFAULT_LOCALE);
|
|
31
|
+
}
|
|
25
32
|
// Dynamic import of the logic with a timestamp — so that on /reload (or
|
|
26
33
|
// auto-reload) self-review uses FRESH tools/agent-loop, not the ones cached on
|
|
27
34
|
// first load. Otherwise reload wouldn't reach self-review's dependencies.
|
|
@@ -54,7 +61,8 @@ async function copyDirJsFiles(from, to) {
|
|
|
54
61
|
return copied;
|
|
55
62
|
}
|
|
56
63
|
// ---------- /self-review ----------
|
|
57
|
-
export async function selfReview({ browser, focus, transcript, }) {
|
|
64
|
+
export async function selfReview({ browser, focus, transcript, locale, }) {
|
|
65
|
+
const t = translator(locale);
|
|
58
66
|
const stamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
59
67
|
const snapRoot = path.join(SNAP_ROOT);
|
|
60
68
|
const snapDir = path.join(snapRoot, `run-${stamp}`);
|
|
@@ -62,9 +70,8 @@ export async function selfReview({ browser, focus, transcript, }) {
|
|
|
62
70
|
await ensureDir(snapDir);
|
|
63
71
|
const copied = await copyDirJsFiles(SRC_DIR, snapDir);
|
|
64
72
|
if (copied.length === 0) {
|
|
65
|
-
console.error(theme.error(
|
|
66
|
-
|
|
67
|
-
throw new Error('SRC_DIR пуст — нечего ревьюить');
|
|
73
|
+
console.error(theme.error('\n✖ ' + t('self.no_src', { dir: SRC_DIR })));
|
|
74
|
+
throw new Error(t('self.no_src_err'));
|
|
68
75
|
}
|
|
69
76
|
// Copy package.json for context — so the agent sees the dependencies
|
|
70
77
|
try {
|
|
@@ -72,9 +79,9 @@ export async function selfReview({ browser, focus, transcript, }) {
|
|
|
72
79
|
await fs.writeFile(path.join(snapDir, 'package.json'), pkg, 'utf-8');
|
|
73
80
|
}
|
|
74
81
|
catch { }
|
|
75
|
-
console.log(theme.system(
|
|
76
|
-
console.log(theme.system(
|
|
77
|
-
console.log(theme.system('
|
|
82
|
+
console.log(theme.system('\n' + t('self.snapshot', { dir: snapDir })));
|
|
83
|
+
console.log(theme.system(t('self.files', { n: copied.length, list: copied.join(', ') })));
|
|
84
|
+
console.log(theme.system(t('self.starting') + '\n'));
|
|
78
85
|
const taskPrompt = buildReviewPrompt({ focus, snapDir });
|
|
79
86
|
const { createTools, runAgentLoop } = await loadFresh();
|
|
80
87
|
const tools = createTools(snapDir, { undo: null });
|
|
@@ -94,42 +101,43 @@ export async function selfReview({ browser, focus, transcript, }) {
|
|
|
94
101
|
console.log(theme.warn(`🔧 ${name}`), theme.system(preview));
|
|
95
102
|
},
|
|
96
103
|
onToolResult: (r) => {
|
|
97
|
-
const
|
|
98
|
-
console.log(theme.system(` → ${
|
|
104
|
+
const text = typeof r === 'string' ? r : JSON.stringify(r);
|
|
105
|
+
console.log(theme.system(` → ${text.slice(0, 200).replace(/\n/g, ' ↵ ')}\n`));
|
|
99
106
|
},
|
|
100
107
|
onAssistantMessage: (msg) => {
|
|
101
108
|
finalMessage = msg;
|
|
102
|
-
console.log(theme.assistant('\n
|
|
109
|
+
console.log(theme.assistant('\n' + t('self.report') + '\n'));
|
|
103
110
|
console.log(msg);
|
|
104
111
|
console.log();
|
|
105
112
|
},
|
|
106
113
|
});
|
|
107
114
|
// Save the report
|
|
108
115
|
const reportPath = path.join(snapDir, '_report.md');
|
|
109
|
-
await fs.writeFile(reportPath, finalMessage || '
|
|
116
|
+
await fs.writeFile(reportPath, finalMessage || t('self.report_empty'), 'utf-8');
|
|
110
117
|
// Compute what changed
|
|
111
118
|
const changed = await diffFiles(SRC_DIR, snapDir);
|
|
112
119
|
console.log(theme.system('─'.repeat(60)));
|
|
113
|
-
console.log(theme.system(
|
|
114
|
-
console.log(theme.system(
|
|
120
|
+
console.log(theme.system(t('self.report_path', { v: reportPath })));
|
|
121
|
+
console.log(theme.system(t('self.snapshot_path', { v: snapDir })));
|
|
115
122
|
if (changed.length) {
|
|
116
|
-
console.log(theme.assistant(
|
|
123
|
+
console.log(theme.assistant(t('self.changed', { n: changed.length, list: changed.join(', ') })));
|
|
117
124
|
}
|
|
118
125
|
else {
|
|
119
|
-
console.log(theme.system(
|
|
126
|
+
console.log(theme.system(t('self.changed_none')));
|
|
120
127
|
}
|
|
121
|
-
console.log(theme.user(
|
|
122
|
-
console.log(theme.user(
|
|
123
|
-
console.log(theme.user(
|
|
128
|
+
console.log(theme.user('\n' + t('self.next')));
|
|
129
|
+
console.log(theme.user(t('self.diff_hint', { name: path.basename(snapDir) })));
|
|
130
|
+
console.log(theme.user(t('self.apply_hint', { name: path.basename(snapDir) })));
|
|
124
131
|
console.log();
|
|
125
132
|
return { snapDir, reportPath, changed };
|
|
126
133
|
}
|
|
127
134
|
// ---------- /self-diff ----------
|
|
128
|
-
export async function selfDiff({ name, }) {
|
|
135
|
+
export async function selfDiff({ name, locale, }) {
|
|
136
|
+
const t = translator(locale);
|
|
129
137
|
const snapDir = path.join(SNAP_ROOT, name);
|
|
130
138
|
const snapStat = await fs.stat(snapDir).catch(() => null);
|
|
131
139
|
if (!snapStat)
|
|
132
|
-
throw new Error(
|
|
140
|
+
throw new Error(t('self.snapshot_not_found', { dir: snapDir }));
|
|
133
141
|
const { unifiedDiff, colorDiff } = await import('./diff.js');
|
|
134
142
|
const files = await fs.readdir(snapDir);
|
|
135
143
|
let anyDiff = false;
|
|
@@ -150,15 +158,16 @@ export async function selfDiff({ name, }) {
|
|
|
150
158
|
console.log(colorDiff(diff));
|
|
151
159
|
}
|
|
152
160
|
if (!anyDiff) {
|
|
153
|
-
console.log(theme.system('
|
|
161
|
+
console.log(theme.system(t('self.no_diff')));
|
|
154
162
|
}
|
|
155
163
|
}
|
|
156
164
|
// ---------- /self-apply ----------
|
|
157
|
-
export async function selfApply({ name, }) {
|
|
165
|
+
export async function selfApply({ name, locale, }) {
|
|
166
|
+
const t = translator(locale);
|
|
158
167
|
const snapDir = path.join(SNAP_ROOT, name);
|
|
159
168
|
const snapStat = await fs.stat(snapDir).catch(() => null);
|
|
160
169
|
if (!snapStat)
|
|
161
|
-
throw new Error(
|
|
170
|
+
throw new Error(t('self.snapshot_not_found', { dir: snapDir }));
|
|
162
171
|
// Back up the current src before overwriting
|
|
163
172
|
const stamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
164
173
|
const backupDir = path.join(SNAP_ROOT, `backup-before-apply-${stamp}`);
|
|
@@ -166,7 +175,7 @@ export async function selfApply({ name, }) {
|
|
|
166
175
|
const files = await fs.readdir(snapDir);
|
|
167
176
|
const jsFiles = files.filter((f) => f.endsWith('.ts'));
|
|
168
177
|
if (jsFiles.length === 0) {
|
|
169
|
-
throw new Error(
|
|
178
|
+
throw new Error(t('self.apply_no_ts', { dir: snapDir }));
|
|
170
179
|
}
|
|
171
180
|
const applied = [];
|
|
172
181
|
for (const f of jsFiles) {
|
|
@@ -174,28 +183,29 @@ export async function selfApply({ name, }) {
|
|
|
174
183
|
await fs.writeFile(path.join(SRC_DIR, f), data, 'utf-8');
|
|
175
184
|
applied.push(f);
|
|
176
185
|
}
|
|
177
|
-
console.log(theme.assistant(
|
|
186
|
+
console.log(theme.assistant('\n' + t('self.applied', { n: applied.length })));
|
|
178
187
|
console.log(theme.system(applied.join(', ')));
|
|
179
|
-
console.log(theme.system(
|
|
180
|
-
console.log(theme.warn(
|
|
188
|
+
console.log(theme.system(t('self.backup', { dir: backupDir })));
|
|
189
|
+
console.log(theme.warn('\n' + t('self.restart_hint') + '\n'));
|
|
181
190
|
}
|
|
182
191
|
// ---------- /self-list ----------
|
|
183
|
-
export async function selfList({
|
|
192
|
+
export async function selfList({ locale, } = {}) {
|
|
193
|
+
const t = translator(locale);
|
|
184
194
|
const snapRoot = path.join(SNAP_ROOT);
|
|
185
195
|
let entries;
|
|
186
196
|
try {
|
|
187
197
|
entries = await fs.readdir(snapRoot);
|
|
188
198
|
}
|
|
189
199
|
catch {
|
|
190
|
-
console.log(theme.system('
|
|
200
|
+
console.log(theme.system(t('self.no_snapshots')));
|
|
191
201
|
return;
|
|
192
202
|
}
|
|
193
203
|
if (!entries.length) {
|
|
194
|
-
console.log(theme.system('
|
|
204
|
+
console.log(theme.system(t('self.no_snapshots')));
|
|
195
205
|
return;
|
|
196
206
|
}
|
|
197
207
|
entries.sort();
|
|
198
|
-
console.log(theme.system('
|
|
208
|
+
console.log(theme.system(t('self.list_title')));
|
|
199
209
|
for (const e of entries) {
|
|
200
210
|
const full = path.join(snapRoot, e);
|
|
201
211
|
const stat = await fs.stat(full).catch(() => null);
|
|
@@ -208,13 +218,13 @@ export async function selfList({ config: _config, } = {}) {
|
|
|
208
218
|
.catch(() => false);
|
|
209
219
|
const changedCount = (await diffFiles(SRC_DIR, full)).length;
|
|
210
220
|
const tag = changedCount
|
|
211
|
-
? theme.assistant(
|
|
212
|
-
: theme.system('
|
|
221
|
+
? theme.assistant(t('self.list_changed', { n: changedCount }))
|
|
222
|
+
: theme.system(t('self.list_unchanged'));
|
|
213
223
|
const rep = hasReport ? theme.user('📋') : ' ';
|
|
214
224
|
console.log(` ${rep} ${e} ${tag}`);
|
|
215
225
|
}
|
|
216
226
|
console.log();
|
|
217
|
-
console.log(theme.system('
|
|
227
|
+
console.log(theme.system(t('self.list_commands') + '\n'));
|
|
218
228
|
}
|
|
219
229
|
// ---------- helpers ----------
|
|
220
230
|
async function diffFiles(origDir, newDir) {
|
package/logo.jpg
ADDED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zames_pro",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.50.0",
|
|
4
4
|
"description": "Terminal coding agent over chat.deepseek.com via Playwright",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"scripts",
|
|
12
12
|
"README.md",
|
|
13
13
|
"LICENSE",
|
|
14
|
-
"logo.
|
|
14
|
+
"logo.jpg"
|
|
15
15
|
],
|
|
16
16
|
"scripts": {
|
|
17
17
|
"start": "node ./dist/index.js",
|
package/logo.png
DELETED
|
Binary file
|