wormclaude 1.0.231 → 1.0.232

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/api.js CHANGED
@@ -80,18 +80,39 @@ function backoff(attempt) {
80
80
  const base = Math.min(BASE_DELAY_MS * 2 ** attempt, MAX_DELAY_MS);
81
81
  return base + Math.random() * 0.25 * base; // jitter %25
82
82
  }
83
+ // Retry-After header'ı ms'ye çevir (saniye VEYA HTTP-date). Sunucu "şu kadar bekle" derse
84
+ // kör backoff yerine onu onurla → 429/503'te ne erken hammer'la ne fazla bekle. Yoksa null.
85
+ function retryAfterMs(res) {
86
+ try {
87
+ const h = res.headers?.get?.('retry-after');
88
+ if (!h)
89
+ return null;
90
+ const secs = Number(h);
91
+ if (Number.isFinite(secs))
92
+ return Math.min(Math.max(0, secs * 1000), 60000);
93
+ const when = Date.parse(h);
94
+ if (!Number.isNaN(when))
95
+ return Math.min(Math.max(0, when - Date.now()), 60000);
96
+ }
97
+ catch { }
98
+ return null;
99
+ }
83
100
  const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
84
101
  // Sadece BAĞLANTI kurulurken retry edilir (stream başladıktan sonra retry edilmez
85
102
  // — aksi halde kısmi metin tekrar gelir). HTTP başlamadan önceki hatalar güvenli.
86
103
  async function fetchWithRetry(url, init) {
87
104
  let lastErr;
88
105
  for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
106
+ let waitMs = backoff(attempt);
89
107
  try {
90
108
  const res = await fetch(url, init);
91
109
  if (res.ok)
92
110
  return res;
93
111
  if (!RETRYABLE_STATUS.has(res.status) || attempt === MAX_RETRIES)
94
112
  return res;
113
+ const ra = retryAfterMs(res); // sunucu bekleme süresi verdiyse onu onurla
114
+ if (ra != null)
115
+ waitMs = ra;
95
116
  try {
96
117
  await res.body?.cancel();
97
118
  }
@@ -107,7 +128,7 @@ async function fetchWithRetry(url, init) {
107
128
  if (attempt === MAX_RETRIES)
108
129
  throw e;
109
130
  }
110
- await sleep(backoff(attempt));
131
+ await sleep(waitMs);
111
132
  }
112
133
  throw lastErr ?? new Error('retry exhausted');
113
134
  }
@@ -2,6 +2,36 @@
2
2
  // Qwen-14B + vLLM(hermes) parçalı JSON arg, index çakışması, ID'siz devam chunk'ı üretebilir.
3
3
  // Gemini streamingToolCallParser'dan uyarlandı; bizim {index, id?, name?, argChunk} delta'mıza göre sade.
4
4
  import { safeJsonParse } from './safejson.js';
5
+ // Yarım kalmış JSON'u onar: açık string'i kapat + string-dışı açık {/[ 'ları doğru sırada kapat.
6
+ // Stream son string arg'ı (ör. uzun file_path) yarıda keserse argümanlar {} olarak kaybolmasın.
7
+ function repairJson(buf) {
8
+ let s = buf, inStr = false, esc = false;
9
+ const stack = [];
10
+ for (const ch of s) {
11
+ if (inStr) {
12
+ if (esc)
13
+ esc = false;
14
+ else if (ch === '\\')
15
+ esc = true;
16
+ else if (ch === '"')
17
+ inStr = false;
18
+ continue;
19
+ }
20
+ if (ch === '"')
21
+ inStr = true;
22
+ else if (ch === '{')
23
+ stack.push('}');
24
+ else if (ch === '[')
25
+ stack.push(']');
26
+ else if (ch === '}' || ch === ']')
27
+ stack.pop();
28
+ }
29
+ if (inStr)
30
+ s += '"';
31
+ while (stack.length)
32
+ s += stack.pop();
33
+ return s;
34
+ }
5
35
  export class StreamingToolCallParser {
6
36
  buffers = new Map();
7
37
  depths = new Map();
@@ -88,6 +118,13 @@ export class StreamingToolCallParser {
88
118
  return { complete: true, value: JSON.parse(newBuffer) };
89
119
  }
90
120
  catch {
121
+ // Kapanmamış string onarımı: kapanış tırnağı stream'de düştüyse (inString) ekle + tekrar dene.
122
+ if (inString) {
123
+ try {
124
+ return { complete: true, value: JSON.parse(newBuffer + '"') };
125
+ }
126
+ catch { }
127
+ }
91
128
  return { complete: false };
92
129
  }
93
130
  }
@@ -100,8 +137,23 @@ export class StreamingToolCallParser {
100
137
  const m = this.meta.get(index);
101
138
  if (!m?.name)
102
139
  continue; // isimsiz parça → çağrı değil
103
- // Boş buffer = argümansız tool (ör. {}). safeJsonParse onarım dener, başarısızsa {} fallback.
104
- const args = buffer.trim() ? safeJsonParse(buffer, {}) : {};
140
+ // Boş buffer = argümansız tool (ör. {}). Dolu ise: JSON.parse (kapanmamış string ise
141
+ // kapatma-tırnağı ekle+dene) safeJsonParse fallback. Böylece stream son string arg'ı
142
+ // yarıda kesse bile argümanlar {} olarak kaybolmaz.
143
+ let args = {};
144
+ if (buffer.trim()) {
145
+ try {
146
+ args = JSON.parse(buffer);
147
+ }
148
+ catch {
149
+ try {
150
+ args = JSON.parse(repairJson(buffer));
151
+ } // string + açık brace'leri kapat
152
+ catch {
153
+ args = safeJsonParse(buffer, {});
154
+ }
155
+ }
156
+ }
105
157
  out.push({ id: m.id || `call_${index}`, name: m.name, args, index });
106
158
  }
107
159
  return out;
package/dist/theme.js CHANGED
@@ -16,4 +16,4 @@ export const theme = {
16
16
  synType: '#a78bfa', // tip/sınıf adları, sabitler
17
17
  synProp: '#e0e0e0', // özellik/anahtar adları
18
18
  };
19
- export const VERSION = '1.0.231';
19
+ export const VERSION = '1.0.232';
package/dist/tools.js CHANGED
@@ -874,7 +874,7 @@ async function execOne(call, hooks) {
874
874
  // 1) Girdi doğrulama
875
875
  const verr = validateToolInput(call.name, args);
876
876
  if (verr)
877
- return { ok: false, output: `Geçersiz girdi: ${verr}`, args };
877
+ return { ok: false, output: `INVALID_PARAMS for ${call.name}: ${verr}. Fix the arguments and call ${call.name} again with the correct parameters.`, args };
878
878
  // İNCELEME KİLİDİ: incele görevinde "nasıl kullanayım?" diye SORMA — açıklamayı üret.
879
879
  if (inspectLock && call.name === 'AskUserQuestion') {
880
880
  return { ok: false, output: 'This is an INSPECT/UNDERSTAND task — do NOT ask the user what to do with the files or how they want to use them. Just explain, in text, what the folder contains: the key files and their purpose, and what the project/collection is overall. Deliver that written explanation now.', args };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wormclaude",
3
- "version": "1.0.231",
3
+ "version": "1.0.232",
4
4
  "description": "WormClaude CLI - uncensored security+code assistant (ink TUI, Claude-style)",
5
5
  "type": "module",
6
6
  "bin": {