wormclaude 1.0.144 → 1.0.145
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/inlinetools.js +85 -4
- package/dist/theme.js +1 -1
- package/dist/tui.js +4 -1
- package/package.json +1 -1
package/dist/inlinetools.js
CHANGED
|
@@ -128,6 +128,72 @@ function toToolCall(obj, i) {
|
|
|
128
128
|
function looksLikeCall(o) {
|
|
129
129
|
return !!o && typeof o === 'object' && (typeof o.name === 'string' || typeof o.tool === 'string' || (o.function && typeof o.function === 'object'));
|
|
130
130
|
}
|
|
131
|
+
// Sarmasız (wrapper'sız) üst-düzey JSON için SIKI kontrol: yalnız adı BİLİNEN bir araç olan
|
|
132
|
+
// veya `function`/`arguments` yapısı taşıyan nesne çağrıdır. Aksi halde `package.json` gibi
|
|
133
|
+
// `"name"` içeren GERÇEK dosya içerikleri yanlışlıkla araç çağrısı sanılırdı (latent bug).
|
|
134
|
+
const _KNOWN_TOOL_RE = /^(?:Bash|PowerShell|Read|Write|Edit|Glob|Grep|WebFetch|WebSearch|Sleep|TaskOutput|AskUserQuestion)$/;
|
|
135
|
+
function looksLikeKnownCall(o) {
|
|
136
|
+
if (!o || typeof o !== 'object')
|
|
137
|
+
return false;
|
|
138
|
+
if (o.function && typeof o.function === 'object')
|
|
139
|
+
return true;
|
|
140
|
+
const nm = o.name || o.tool || o.tool_name;
|
|
141
|
+
if (typeof nm !== 'string' || !_KNOWN_TOOL_RE.test(nm))
|
|
142
|
+
return false;
|
|
143
|
+
// Bilinen ad + bir argüman anahtarı (çıplak `{"name":"Read"}` da geçerli olabilir → ad yeter).
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
// ---- DOSYA-BLOĞU KURTARMA (build paste-vs-write) -----------------------------
|
|
147
|
+
// Model bir build görevinde Write çağırmak yerine ```kod bloğu YAPIŞTIRABİLİR ve
|
|
148
|
+
// dosya hiç oluşmaz. Bunu kurtarıyoruz — AMA yalnız blok AÇIKÇA bir dosya adıyla
|
|
149
|
+
// etiketliyse (`index.html`, **app.py**, `# server.py`, `Dosya: x.css`…). Etiket
|
|
150
|
+
// yoksa (saf "kod göster" / örnek) DOKUNMAYIZ. Recovered Write yine onay ister →
|
|
151
|
+
// kullanıcı sadece görmek istediyse reddeder (güvenli).
|
|
152
|
+
const _CODE_EXT = 'py|js|jsx|ts|tsx|html?|htm|css|scss|sass|less|json|jsonc|sh|bash|zsh|go|rs|java|kt|c|cc|cpp|cxx|h|hpp|rb|php|sql|ya?ml|toml|ini|env|xml|svg|vue|svelte|astro|md|markdown|txt|dockerfile|makefile|cs|swift|dart|lua|pl|r|m|mjs|cjs|tf|gradle|bat|ps1';
|
|
153
|
+
const _ECHO_FILE_LANGS = /^(plaintext|plain|text|txt|http|https|console|output|log|raw|diff|patch)$/i;
|
|
154
|
+
// Dosya-adı token'ı: `path/to/file.ext` veya `file.ext` (gerçek kod uzantısı şart).
|
|
155
|
+
const _FNAME = '(?:[\\w./\\\\-]+\\.(?:' + _CODE_EXT + ')|Dockerfile|Makefile|\\.(?:env|gitignore|babelrc)[\\w.-]*)';
|
|
156
|
+
// Etiket biçimleri — fence'ten HEMEN önce (≤2 satır), aynı paragraf:
|
|
157
|
+
// `file.ext` | **file.ext** | ## file.ext | File:/Dosya:/Filename: file.ext | file.ext:
|
|
158
|
+
const _LABEL_RE = new RegExp('(?:^|\\n)[ \\t>*#`\\-]*' +
|
|
159
|
+
'(?:(?:file|dosya|filename|dosya adı|path|yol)\\s*[:=]\\s*)?' +
|
|
160
|
+
'["`*\\[(]*\\s*(' + _FNAME + ')\\s*["`*\\])]*\\s*:?[ \\t]*' + // **bold**/`tick`/[bracket] çoklu sarmal
|
|
161
|
+
'(?:\\([^)\\n]*\\))?[ \\t]*' + // "index.html (ana sayfa)" gibi parantez-not
|
|
162
|
+
'\\r?\\n(?:[ \\t]*\\r?\\n)?' + // araya en çok bir boş satır
|
|
163
|
+
'```([a-zA-Z0-9_+-]*)[ \\t]*\\r?\\n([\\s\\S]*?)```', 'gi');
|
|
164
|
+
/** Metindeki dosya-adı etiketli kod bloklarını bulur (span'larıyla). Konservatif:
|
|
165
|
+
* gerçek kod uzantısı + echo-olmayan dil + ≥2 satır/≥40 karakter gövde şart. */
|
|
166
|
+
export function findFileBlocks(text) {
|
|
167
|
+
const t = text || '';
|
|
168
|
+
const out = [];
|
|
169
|
+
const seen = new Set();
|
|
170
|
+
let m;
|
|
171
|
+
_LABEL_RE.lastIndex = 0;
|
|
172
|
+
while ((m = _LABEL_RE.exec(t)) !== null) {
|
|
173
|
+
const file = m[1].trim();
|
|
174
|
+
const lang = (m[2] || '').trim();
|
|
175
|
+
const body = m[3] || '';
|
|
176
|
+
if (_ECHO_FILE_LANGS.test(lang))
|
|
177
|
+
continue; // komut/çıktı bloğu — dosya değil
|
|
178
|
+
const nonEmpty = body.split('\n').filter((l) => l.trim()).length;
|
|
179
|
+
if (body.trim().length < 15 && nonEmpty < 2)
|
|
180
|
+
continue; // önemsiz snippet (`a=1` gibi) — etiket asıl sinyal
|
|
181
|
+
const key = file + '|' + body.length;
|
|
182
|
+
if (seen.has(key))
|
|
183
|
+
continue;
|
|
184
|
+
seen.add(key);
|
|
185
|
+
out.push({ file, content: body.replace(/\s+$/, '') + '\n', start: m.index, end: m.index + m[0].length });
|
|
186
|
+
}
|
|
187
|
+
return out;
|
|
188
|
+
}
|
|
189
|
+
/** Dosya-bloklarını Write çağrılarına çevirir (yapısal/inline tool-call YOKKEN son çare). */
|
|
190
|
+
export function recoverFileBlocks(text) {
|
|
191
|
+
return findFileBlocks(text).map((b, i) => ({
|
|
192
|
+
id: `fileblock_${i}`,
|
|
193
|
+
name: 'Write',
|
|
194
|
+
args: JSON.stringify({ file_path: b.file, content: b.content }),
|
|
195
|
+
}));
|
|
196
|
+
}
|
|
131
197
|
/** Metindeki üst-düzey {…} JSON nesnelerini (string/escape duyarlı) çıkarır.
|
|
132
198
|
* Model çağrıları sarmasız ve BİRDEN FAZLA nesne olarak dökebilir: {…}{…} veya {…}\n{…}
|
|
133
199
|
* (abliterated coder davranışı). Her üst-düzey nesneyi ayrı parça olarak döndürür. */
|
|
@@ -169,7 +235,8 @@ function extractTopLevelJsonObjects(text) {
|
|
|
169
235
|
export function recoverInlineToolCalls(text) {
|
|
170
236
|
const t = (text || '').trim();
|
|
171
237
|
// JSON/prose/ToolName{…}/ToolName(…) çağrısı yoksa erken çık.
|
|
172
|
-
|
|
238
|
+
// (Kod fence'i varsa çıkma — dosya-adı etiketli blok olabilir, adım 7 karar verir.)
|
|
239
|
+
if (!t || (!t.includes('"name"') && !t.includes('"tool"') && !t.includes('"function"') && !/AskUserQuestion/i.test(t) && !TOOL_PREFIX_RE.test(t) && !TOOL_PAREN_RE.test(t) && !t.includes('```')))
|
|
173
240
|
return [];
|
|
174
241
|
const out = [];
|
|
175
242
|
const seen = new Set();
|
|
@@ -193,7 +260,9 @@ export function recoverInlineToolCalls(text) {
|
|
|
193
260
|
if (!out.length) {
|
|
194
261
|
for (const m of t.matchAll(/```(?:json|tool_call|tool|function)?\s*([\s\S]*?)```/gi)) {
|
|
195
262
|
const o = safeJsonParse(m[1].trim(), null);
|
|
196
|
-
|
|
263
|
+
// SIKI: ```json içine konmuş GERÇEK dosya (`{"name":"app",...}`) tool-call sanılmasın;
|
|
264
|
+
// sarmalı tool-call'lar zaten bilinen araç adı (Write/Bash…) kullanır → step 7 dosyayı alır.
|
|
265
|
+
if (looksLikeKnownCall(o))
|
|
197
266
|
push(o);
|
|
198
267
|
}
|
|
199
268
|
}
|
|
@@ -202,8 +271,8 @@ export function recoverInlineToolCalls(text) {
|
|
|
202
271
|
if (!out.length) {
|
|
203
272
|
for (const frag of extractTopLevelJsonObjects(t)) {
|
|
204
273
|
const o = safeJsonParse(frag, null);
|
|
205
|
-
if (
|
|
206
|
-
push(o);
|
|
274
|
+
if (looksLikeKnownCall(o))
|
|
275
|
+
push(o); // SIKI: package.json gibi dosyaları çağrı sanma
|
|
207
276
|
}
|
|
208
277
|
}
|
|
209
278
|
// 4) AskUserQuestion'ı JSON yerine DÜZ-METİN (prose) yazan model (abliterated):
|
|
@@ -265,6 +334,18 @@ export function recoverInlineToolCalls(text) {
|
|
|
265
334
|
}
|
|
266
335
|
}
|
|
267
336
|
}
|
|
337
|
+
// 7) SON ÇARE: hiç çağrı kurtarılamadıysa, dosya-adı etiketli ```kod bloklarını
|
|
338
|
+
// Write'a çevir (model build'de Write yerine kod yapıştırınca dosya kaybolmasın).
|
|
339
|
+
// Adım 7, gerçek tool-call YOKKEN çalışır → "kod göster"i bozmaz (etiket gerekir).
|
|
340
|
+
if (!out.length) {
|
|
341
|
+
for (const tc of recoverFileBlocks(t)) {
|
|
342
|
+
const k = tc.name + '|' + tc.args;
|
|
343
|
+
if (!seen.has(k)) {
|
|
344
|
+
seen.add(k);
|
|
345
|
+
out.push(tc);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
268
349
|
return out;
|
|
269
350
|
}
|
|
270
351
|
/** Modelin komut/çıktıyı TEKRAR yazdığı kod-bloklarını siler (```plaintext/bash/http/console…).
|
package/dist/theme.js
CHANGED
package/dist/tui.js
CHANGED
|
@@ -445,7 +445,10 @@ export async function runTui() {
|
|
|
445
445
|
if (allowAll.has(c.name))
|
|
446
446
|
return resolve('allow');
|
|
447
447
|
// Claude tarzı: Write/Edit'te YAZMADAN ÖNCE dosya içeriğini göster, sonra onay iste.
|
|
448
|
-
|
|
448
|
+
// İSTİSNA: kurtarılan dosya-bloğu (id `fileblock_`) içeriği zaten akışta prose olarak
|
|
449
|
+
// gösterildi → fileprev'i ATLA, yoksa aynı kod iki kez basılır.
|
|
450
|
+
const _recoveredBlock = typeof c.id === 'string' && c.id.startsWith('fileblock_');
|
|
451
|
+
if (!_recoveredBlock && ((c.name === 'Write' && args?.content != null) || (c.name === 'Edit' && args?.new_string != null))) {
|
|
449
452
|
const _content = String(c.name === 'Write' ? args.content : args.new_string);
|
|
450
453
|
printItem({ kind: 'fileprev', file: relWs(args.file_path), lines: _content.split('\n') });
|
|
451
454
|
}
|