wormclaude 1.0.90 → 1.0.92

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
@@ -3,6 +3,7 @@
3
3
  // Ölçüm: usage (token) bilgisini 'done' olayında döndürür (billing için).
4
4
  import { loadStored, DEFAULT_BASE_URL } from './auth.js';
5
5
  import { StreamingToolCallParser } from './streamparser.js';
6
+ import { recoverInlineToolCalls } from './inlinetools.js';
6
7
  import { safeJsonStringify } from './safejson.js';
7
8
  import { getTrace, getSession } from './telemetry.js';
8
9
  export function loadConfig() {
@@ -186,6 +187,7 @@ export async function* streamChat(messages, tools, config, signal) {
186
187
  let buf = '';
187
188
  const toolParser = new StreamingToolCallParser();
188
189
  let usage;
190
+ let fullText = ''; // model metne araç çağrısı gömerse sonda kurtarmak için
189
191
  while (true) {
190
192
  if (ac.signal.aborted && !timedOut) {
191
193
  try {
@@ -239,8 +241,10 @@ export async function* streamChat(messages, tools, config, signal) {
239
241
  const delta = j.choices?.[0]?.delta;
240
242
  if (!delta)
241
243
  continue;
242
- if (delta.content)
244
+ if (delta.content) {
245
+ fullText += delta.content;
243
246
  yield { type: 'text', text: delta.content };
247
+ }
244
248
  if (delta.tool_calls) {
245
249
  for (const tc of delta.tool_calls) {
246
250
  const idx = tc.index ?? 0;
@@ -252,10 +256,16 @@ export async function* streamChat(messages, tools, config, signal) {
252
256
  clearTimer(); // akış normal bitti → zamanlayıcı + dinleyici temizle
253
257
  // Tamamlanan çağrıları sağlam biçimde topla; args'ı GEÇERLİ JSON string olarak emit et
254
258
  // (tools.ts tarafındaki JSON.parse artık asla patlamaz — onarım burada yapıldı).
255
- const toolCalls = toolParser.getCompleted().map((c) => ({
259
+ let toolCalls = toolParser.getCompleted().map((c) => ({
256
260
  id: c.id,
257
261
  name: c.name,
258
262
  args: safeJsonStringify(c.args),
259
263
  }));
264
+ // Yedek: upstream yapısal tool_call vermediyse modelin metne gömdüğü çağrıyı kurtar.
265
+ if (toolCalls.length === 0 && fullText) {
266
+ const recovered = recoverInlineToolCalls(fullText);
267
+ if (recovered.length)
268
+ toolCalls = recovered;
269
+ }
260
270
  yield { type: 'done', toolCalls, usage };
261
271
  }
package/dist/cli.js CHANGED
@@ -5,6 +5,7 @@ import TextInput from 'ink-text-input';
5
5
  import * as path from 'node:path';
6
6
  import { theme, VERSION } from './theme.js';
7
7
  import { loadConfig, streamChat, fetchAccount } from './api.js';
8
+ import { stripInlineToolCalls } from './inlinetools.js';
8
9
  import { newTrace, flushTelemetry } from './telemetry.js';
9
10
  import { tier } from './program.js';
10
11
  import { allToolSchemas, executeToolCalls, executeTool, toolLabel, setToolConfig } from './tools.js';
@@ -722,6 +723,10 @@ function App() {
722
723
  setStreaming('');
723
724
  // Sızan özel-token / tool-call markup'ını bir kez temizle (hem geçmiş hem gösterim için).
724
725
  assistantText = cleanModelText(assistantText);
726
+ // Model araç çağrısını metne gömdüyse (inline kurtarma) → o JSON bloğunu gösterim+geçmişten çıkar.
727
+ if (toolCalls.some((t) => t.id?.startsWith('inline_'))) {
728
+ assistantText = stripInlineToolCalls(assistantText);
729
+ }
725
730
  // Reactive compact: bağlam taştıysa bir kez özetle ve turu tekrar dene
726
731
  if (gotCtxError && !reactiveRetried) {
727
732
  reactiveRetried = true;
package/dist/commands.js CHANGED
@@ -15,7 +15,7 @@ import { isLearnEnabled, setLearnEnabled, getLearnFile, getLearnCount } from './
15
15
  import { saveMemoryFact, getMemoryPath, loadMemoryContext } from './memory.js';
16
16
  import { fetchAccount, getVerifyStatus, submitVerification } from './api.js';
17
17
  import { programText, tier } from './program.js';
18
- import { runPentest } from './pentest.js';
18
+ import { runPentest, fetchPtTools } from './pentest.js';
19
19
  export const COMMANDS = [
20
20
  { name: '/help', desc: 'komutları ve ipuçlarını göster' },
21
21
  { name: '/clear', desc: 'sohbeti ve geçmişi temizle' },
@@ -748,14 +748,26 @@ export async function runSlashCommand(input, ctx) {
748
748
  await pentestCmd(sub, m.join(' '), ctx);
749
749
  return true;
750
750
  }
751
- ctx.note('Güvenlik tarama skill\'leri (seviye 3+ · motor sunucuda gizli):\n' +
752
- ' /skill xss <url> reflected XSS\n' +
753
- ' /skill sqli <url> SQL injection (error/boolean/time)\n' +
754
- ' /skill recon <alan> alt-alan + başlık + ifşa\n' +
755
- ' /skill <şablon-id> <hedef> sunucudaki özel şablonlar (.md)\n' +
756
- 'Çalıştırmak için sonuna "run" ekle:\n' +
757
- ' /skill xss https://site/p?id=1 run\n' +
758
- '(kısa yol: /xss /sqli /recon)');
751
+ // Canlı liste: dahili komutlar + admin'in eklediği özel şablonlar
752
+ const t = await fetchPtTools(ctx.config);
753
+ const lines = ['🛡️ Güvenlik tarama skill\'leri (motor sunucuda gizli):'];
754
+ if (t && !t.eligible) {
755
+ lines.push(` Seviyen ${t.trust} gerekli: ${t.min_trust}+. Başvuru: /dogrula`);
756
+ }
757
+ else if (t) {
758
+ lines.push(` Aylık kota: ${t.used}/${t.quota}`);
759
+ }
760
+ lines.push(' Dahili:');
761
+ const builtins = (t && t.tools) || { xss: 'reflected XSS', sqli: 'SQL injection', recon: 'keşif + ifşa' };
762
+ for (const [id, name] of Object.entries(builtins))
763
+ lines.push(` /skill ${id} <hedef> run ${name}`);
764
+ if (t && (t.templates || []).length) {
765
+ lines.push(' Özel şablonlar (admin):');
766
+ for (const tm of t.templates)
767
+ lines.push(` /skill ${tm.id} <hedef> run ${tm.name || ''}${tm.severity ? ' [' + tm.severity + ']' : ''}`);
768
+ }
769
+ lines.push('Örnek: /skill xss https://site/p?id=1 run · kısa yol: /xss /sqli /recon');
770
+ ctx.note(lines.join('\n'));
759
771
  return true;
760
772
  }
761
773
  case '/export': {
@@ -0,0 +1,87 @@
1
+ // Model bazen araç çağrısını yapısal `tool_calls` yerine düz METİN (content) içine gömer
2
+ // (yerel/abliterated modellerde sık). Tanınan biçimler:
3
+ // <tool_call>{"name":"Glob","arguments":{...}}</tool_call>
4
+ // ```json\n{"name":"Glob","arguments":{...}}\n```
5
+ // (tüm mesaj) {"name":"Glob","arguments":{...}}
6
+ // OpenAI: {"type":"function","function":{"name":...,"arguments":"{...}"}}
7
+ // Bu modül o gömülü çağrıları kurtarır — upstream yapısal tool_call vermediğinde YEDEK.
8
+ import { safeJsonParse } from './safejson.js';
9
+ const ARG_KEYS = ['arguments', 'parameters', 'input', 'args', 'params'];
10
+ function toToolCall(obj, i) {
11
+ if (!obj || typeof obj !== 'object')
12
+ return null;
13
+ const src = obj.function && typeof obj.function === 'object' ? obj.function : obj;
14
+ const name = src.name || obj.name || obj.tool || obj.tool_name;
15
+ if (!name || typeof name !== 'string')
16
+ return null;
17
+ let args = undefined;
18
+ if (src.arguments !== undefined)
19
+ args = src.arguments;
20
+ else
21
+ for (const k of ARG_KEYS) {
22
+ if (obj[k] !== undefined) {
23
+ args = obj[k];
24
+ break;
25
+ }
26
+ }
27
+ if (typeof args === 'string')
28
+ args = safeJsonParse(args, {});
29
+ if (args === undefined || args === null)
30
+ args = {};
31
+ return { id: `inline_${i}`, name, args: JSON.stringify(args) };
32
+ }
33
+ function looksLikeCall(o) {
34
+ return !!o && typeof o === 'object' && (typeof o.name === 'string' || typeof o.tool === 'string' || (o.function && typeof o.function === 'object'));
35
+ }
36
+ /** Metindeki gömülü araç çağrılarını kurtarır. Gürültüden kaçınmak için yalnız açık sarmalları
37
+ * (<tool_call>, ```json) veya mesajın TAMAMI tek JSON çağrısıysa onu alır. */
38
+ export function recoverInlineToolCalls(text) {
39
+ const t = (text || '').trim();
40
+ if (!t || (!t.includes('"name"') && !t.includes('"tool"') && !t.includes('"function"')))
41
+ return [];
42
+ const out = [];
43
+ const seen = new Set();
44
+ const push = (o) => {
45
+ const tc = toToolCall(o, out.length);
46
+ if (!tc)
47
+ return;
48
+ const k = tc.name + '|' + tc.args;
49
+ if (!seen.has(k)) {
50
+ seen.add(k);
51
+ out.push(tc);
52
+ }
53
+ };
54
+ // 1) <tool_call>...</tool_call> (Hermes/Qwen)
55
+ for (const m of t.matchAll(/<tool_call>\s*([\s\S]*?)\s*<\/tool_call>/gi)) {
56
+ const o = safeJsonParse(m[1].trim(), null);
57
+ if (looksLikeCall(o))
58
+ push(o);
59
+ }
60
+ // 2) ```json / ```tool_call ... ``` (kod-bloğuna gömülü)
61
+ if (!out.length) {
62
+ for (const m of t.matchAll(/```(?:json|tool_call|tool|function)?\s*([\s\S]*?)```/gi)) {
63
+ const o = safeJsonParse(m[1].trim(), null);
64
+ if (looksLikeCall(o))
65
+ push(o);
66
+ }
67
+ }
68
+ // 3) Mesajın TAMAMI tek JSON çağrısı (sarmasız)
69
+ if (!out.length && t.startsWith('{') && t.endsWith('}')) {
70
+ const o = safeJsonParse(t, null);
71
+ if (looksLikeCall(o))
72
+ push(o);
73
+ }
74
+ return out;
75
+ }
76
+ /** Kurtarılan çağrı bloklarını GÖRÜNTÜ/geçmiş metninden temizler (çirkin JSON kalmasın). */
77
+ export function stripInlineToolCalls(text) {
78
+ let s = text || '';
79
+ s = s.replace(/<tool_call>[\s\S]*?<\/tool_call>/gi, '');
80
+ s = s.replace(/```(?:json|tool_call|tool|function)?\s*\{[\s\S]*?\}\s*```/gi, (blk) => {
81
+ return /"(name|tool|function)"/.test(blk) ? '' : blk; // yalnız çağrı-bloklarını sil
82
+ });
83
+ const tr = s.trim();
84
+ if (tr.startsWith('{') && tr.endsWith('}') && /"(name|tool|function)"/.test(tr))
85
+ return '';
86
+ return s.trim();
87
+ }
package/dist/pentest.js CHANGED
@@ -1,4 +1,19 @@
1
1
  const MAX_BODY = 262_144; // 256 KB cevap gövdesi üst sınırı
2
+ // Kullanılabilir tarama skill'leri + kota durumu (dahili + admin şablonları) — keşif için.
3
+ export async function fetchPtTools(config) {
4
+ try {
5
+ const r = await fetch(`${config.baseUrl}/pentest/tools`, {
6
+ headers: { ...(config.apiKey ? { Authorization: `Bearer ${config.apiKey}` } : {}) },
7
+ signal: AbortSignal.timeout(10000),
8
+ });
9
+ if (!r.ok)
10
+ return null;
11
+ return await r.json();
12
+ }
13
+ catch {
14
+ return null;
15
+ }
16
+ }
2
17
  async function postJson(config, p, body, timeoutMs) {
3
18
  try {
4
19
  const r = await fetch(`${config.baseUrl}${p}`, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wormclaude",
3
- "version": "1.0.90",
3
+ "version": "1.0.92",
4
4
  "description": "WormClaude CLI - uncensored security+code assistant (ink TUI, Claude-style)",
5
5
  "type": "module",
6
6
  "bin": {