zames_pro 2.20.0 → 2.21.2
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 +20 -12
- package/dist/attachments.js +80 -17
- package/dist/browser.js +55 -12
- package/dist/commands.js +7 -2
- package/dist/config-menu.js +3 -1
- package/dist/config.js +157 -23
- package/dist/context.js +68 -13
- package/dist/extraTools.js +8 -2
- package/dist/i18n.js +745 -187
- package/dist/index.js +37 -16
- package/dist/input.js +144 -22
- package/dist/mcp.js +16 -4
- package/dist/path-token.js +4 -3
- package/dist/self-review.js +6 -6
- package/dist/spinner.js +8 -2
- package/dist/system-prompt.js +19 -5
- package/dist/tools.js +2 -6
- package/dist/web.js +1 -1
- package/dist/xml-toolcall.js +10 -5
- package/package.json +13 -2
- package/scripts/eslint-ts6.mjs +51 -0
package/dist/context.js
CHANGED
|
@@ -10,7 +10,14 @@ function clipIf(name, content, budget) {
|
|
|
10
10
|
if (cleaned.length <= budget)
|
|
11
11
|
return cleaned;
|
|
12
12
|
const keep = Math.max(0, budget - 120);
|
|
13
|
-
return cleaned.slice(0, keep) +
|
|
13
|
+
return (cleaned.slice(0, keep) +
|
|
14
|
+
NL +
|
|
15
|
+
NL +
|
|
16
|
+
'[... ' +
|
|
17
|
+
name +
|
|
18
|
+
' truncated (' +
|
|
19
|
+
(cleaned.length - keep) +
|
|
20
|
+
' chars omitted) ...]');
|
|
14
21
|
}
|
|
15
22
|
async function readIfFile(p, budget) {
|
|
16
23
|
try {
|
|
@@ -53,7 +60,12 @@ function dirChainFromRoot(from) {
|
|
|
53
60
|
}
|
|
54
61
|
return out;
|
|
55
62
|
}
|
|
56
|
-
const PROJECT_SKILL_DIRS = [
|
|
63
|
+
const PROJECT_SKILL_DIRS = [
|
|
64
|
+
'.zames/skills',
|
|
65
|
+
'.claude/skills',
|
|
66
|
+
'.agents/skills',
|
|
67
|
+
'skills',
|
|
68
|
+
];
|
|
57
69
|
function parseFrontmatter(raw) {
|
|
58
70
|
const norm = raw.replace(CRLF_RE, NL);
|
|
59
71
|
if (!norm.startsWith('---'))
|
|
@@ -77,7 +89,8 @@ function parseFrontmatter(raw) {
|
|
|
77
89
|
lastKey = key;
|
|
78
90
|
continue;
|
|
79
91
|
}
|
|
80
|
-
if ((val.startsWith('"') && val.endsWith('"')) ||
|
|
92
|
+
if ((val.startsWith('"') && val.endsWith('"')) ||
|
|
93
|
+
(val.startsWith("'") && val.endsWith("'"))) {
|
|
81
94
|
val = val.slice(1, -1);
|
|
82
95
|
}
|
|
83
96
|
out[key] = val;
|
|
@@ -88,12 +101,20 @@ function parseFrontmatter(raw) {
|
|
|
88
101
|
}
|
|
89
102
|
}
|
|
90
103
|
const allowedTools = typeof out['allowed-tools'] === 'string'
|
|
91
|
-
? out['allowed-tools']
|
|
104
|
+
? out['allowed-tools']
|
|
105
|
+
.split(/,/)
|
|
106
|
+
.map((s) => s.trim())
|
|
107
|
+
.filter(Boolean)
|
|
92
108
|
: undefined;
|
|
93
109
|
const userInvokable = typeof out['user-invokable'] === 'string'
|
|
94
110
|
? out['user-invokable'].toLowerCase() !== 'false'
|
|
95
111
|
: undefined;
|
|
96
|
-
return {
|
|
112
|
+
return {
|
|
113
|
+
name: out.name,
|
|
114
|
+
description: out.description,
|
|
115
|
+
allowedTools,
|
|
116
|
+
userInvokable,
|
|
117
|
+
};
|
|
97
118
|
}
|
|
98
119
|
export function skillBody(raw) {
|
|
99
120
|
const norm = raw.replace(CRLF_RE, NL);
|
|
@@ -132,8 +153,14 @@ export async function loadSkills(workdir) {
|
|
|
132
153
|
for (const rel of PROJECT_SKILL_DIRS) {
|
|
133
154
|
roots.push({ dir: path.join(workdir, rel), source: 'project' });
|
|
134
155
|
}
|
|
135
|
-
roots.push({
|
|
136
|
-
|
|
156
|
+
roots.push({
|
|
157
|
+
dir: path.join(os.homedir(), '.zames', 'skills'),
|
|
158
|
+
source: 'global',
|
|
159
|
+
});
|
|
160
|
+
roots.push({
|
|
161
|
+
dir: path.join(os.homedir(), '.claude', 'skills'),
|
|
162
|
+
source: 'global',
|
|
163
|
+
});
|
|
137
164
|
for (const root of roots) {
|
|
138
165
|
const files = await findSkillFiles(root.dir);
|
|
139
166
|
for (const f of files) {
|
|
@@ -150,13 +177,25 @@ export async function loadSkills(workdir) {
|
|
|
150
177
|
continue;
|
|
151
178
|
seen.add(key);
|
|
152
179
|
const description = (fm.description || '').replace(/\s+/g, ' ').trim();
|
|
153
|
-
found.push({
|
|
180
|
+
found.push({
|
|
181
|
+
name,
|
|
182
|
+
description,
|
|
183
|
+
path: f,
|
|
184
|
+
dir,
|
|
185
|
+
allowedTools: fm.allowedTools,
|
|
186
|
+
source: root.source,
|
|
187
|
+
userInvokable: fm.userInvokable !== false,
|
|
188
|
+
});
|
|
154
189
|
}
|
|
155
190
|
}
|
|
156
191
|
found.sort((a, b) => a.name.localeCompare(b.name));
|
|
157
192
|
return found;
|
|
158
193
|
}
|
|
159
|
-
const PROJECT_COMMAND_DIRS = [
|
|
194
|
+
const PROJECT_COMMAND_DIRS = [
|
|
195
|
+
'.zames/commands',
|
|
196
|
+
'.claude/commands',
|
|
197
|
+
'.agents/commands',
|
|
198
|
+
];
|
|
160
199
|
async function loadCommandsFromDir(dir) {
|
|
161
200
|
const out = [];
|
|
162
201
|
let entries;
|
|
@@ -180,7 +219,12 @@ async function loadCommandsFromDir(dir) {
|
|
|
180
219
|
const name = path.basename(e, '.md').trim();
|
|
181
220
|
if (!name)
|
|
182
221
|
continue;
|
|
183
|
-
out.push({
|
|
222
|
+
out.push({
|
|
223
|
+
name,
|
|
224
|
+
description: (fm.description || '').replace(/\s+/g, ' ').trim(),
|
|
225
|
+
path: full,
|
|
226
|
+
body: skillBody(raw),
|
|
227
|
+
});
|
|
184
228
|
}
|
|
185
229
|
return out;
|
|
186
230
|
}
|
|
@@ -205,7 +249,10 @@ export async function loadCommands(workdir) {
|
|
|
205
249
|
async function loadAgentsChain(workdir) {
|
|
206
250
|
const out = [];
|
|
207
251
|
const seen = new Set();
|
|
208
|
-
for (const p of [
|
|
252
|
+
for (const p of [
|
|
253
|
+
path.join(os.homedir(), '.zames', 'AGENTS.md'),
|
|
254
|
+
path.join(os.homedir(), '.claude', 'CLAUDE.md'),
|
|
255
|
+
]) {
|
|
209
256
|
const f = await readIfFile(p, MAX_FILE_BASE);
|
|
210
257
|
if (f && !seen.has(f.path)) {
|
|
211
258
|
seen.add(f.path);
|
|
@@ -228,7 +275,10 @@ async function loadAgentsChain(workdir) {
|
|
|
228
275
|
async function loadMemoryChain(workdir) {
|
|
229
276
|
const out = [];
|
|
230
277
|
const seen = new Set();
|
|
231
|
-
for (const p of [
|
|
278
|
+
for (const p of [
|
|
279
|
+
path.join(os.homedir(), '.zames', 'MEMORY.md'),
|
|
280
|
+
path.join(os.homedir(), '.claude', 'MEMORY.md'),
|
|
281
|
+
]) {
|
|
232
282
|
const f = await readIfFile(p, MAX_FILE_BASE);
|
|
233
283
|
if (f && !seen.has(f.path)) {
|
|
234
284
|
seen.add(f.path);
|
|
@@ -266,5 +316,10 @@ export async function loadProjectContext(workdir) {
|
|
|
266
316
|
}
|
|
267
317
|
return kept;
|
|
268
318
|
};
|
|
269
|
-
return {
|
|
319
|
+
return {
|
|
320
|
+
agents: withinBudget(agents),
|
|
321
|
+
memory: withinBudget(memory),
|
|
322
|
+
skills,
|
|
323
|
+
commands,
|
|
324
|
+
};
|
|
270
325
|
}
|
package/dist/extraTools.js
CHANGED
|
@@ -73,7 +73,10 @@ export function parsePatch(text) {
|
|
|
73
73
|
if (!file)
|
|
74
74
|
return { ops: [], error: 'Patch header has an empty path.' };
|
|
75
75
|
if (path.isAbsolute(file) || /(^|[\\/])\.\.([\\/]|$)/.test(file)) {
|
|
76
|
-
return {
|
|
76
|
+
return {
|
|
77
|
+
ops: [],
|
|
78
|
+
error: 'Patch path must stay inside the project: ' + file,
|
|
79
|
+
};
|
|
77
80
|
}
|
|
78
81
|
current = { op: kind, file, lines: [] };
|
|
79
82
|
ops.push(current);
|
|
@@ -120,7 +123,10 @@ export function applyUpdateHunk(content, hunkLines) {
|
|
|
120
123
|
}
|
|
121
124
|
}
|
|
122
125
|
if (!oldLines.length) {
|
|
123
|
-
return {
|
|
126
|
+
return {
|
|
127
|
+
ok: false,
|
|
128
|
+
error: 'Hunk has no context or removed lines to anchor on.',
|
|
129
|
+
};
|
|
124
130
|
}
|
|
125
131
|
const norm = (s, mode) => {
|
|
126
132
|
if (mode === 'exact')
|