wormclaude 1.0.151 → 1.0.153

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
@@ -151,6 +151,7 @@ export async function* streamChat(messages, tools, config, signal) {
151
151
  method: 'POST',
152
152
  headers: {
153
153
  'Content-Type': 'application/json',
154
+ 'X-WormClaude-Client': 'cli', // gateway: CLI kullanımı abonelik kovasından düşer (çıplak API = API cüzdanı)
154
155
  ...(config.apiKey ? { Authorization: `Bearer ${config.apiKey}` } : {}),
155
156
  ...(getTrace() ? { 'X-WC-Trace': getTrace(), 'X-WC-Session': getSession() } : {}),
156
157
  },
package/dist/auth.js CHANGED
@@ -4,6 +4,9 @@ import * as path from 'node:path';
4
4
  import * as os from 'node:os';
5
5
  import * as readline from 'node:readline';
6
6
  import { spawn } from 'node:child_process';
7
+ import { getLang } from './i18n.js';
8
+ // Kullanıcıya gösterilen metin: VARSAYILAN İngilizce; yalnız dil 'tr' ise Türkçe.
9
+ const tt = (en, tr) => (getLang() === 'tr' ? tr : en);
7
10
  export const CONFIG_DIR = path.join(os.homedir(), '.wormclaude');
8
11
  export const CONFIG_PATH = path.join(CONFIG_DIR, 'config.json');
9
12
  // Müşteriler bunu değiştirmesin diye varsayılan public API.
@@ -36,24 +39,26 @@ export function clearStored() {
36
39
  export async function loginWithKey(rawKey) {
37
40
  const key = (rawKey || '').trim();
38
41
  if (!key) {
39
- process.stdout.write('\n Anahtar boş. Kullanım: wormclaude login --key <ANAHTAR>\n\n');
42
+ process.stdout.write('\n ' + tt('Empty key. Usage: wormclaude login --key <KEY>', 'Anahtar boş. Kullanım: wormclaude login --key <ANAHTAR>') + '\n\n');
40
43
  process.exit(1);
41
44
  }
42
45
  const base = process.env.WORMCLAUDE_BASE_URL || DEFAULT_BASE_URL;
43
- process.stdout.write(' Anahtar doğrulanıyor...');
46
+ process.stdout.write(' ' + tt('Validating key...', 'Anahtar doğrulanıyor...'));
44
47
  try {
45
48
  const r = await fetch(`${base}/account`, { headers: { Authorization: `Bearer ${key}` } });
46
49
  if (!r.ok) {
47
- process.stdout.write('\n\n \x1b[31m✗ Anahtar geçersiz\x1b[0m (HTTP ' + r.status + '). Web Ayarlar → API\'den doğru anahtarı kopyala.\n\n');
50
+ process.stdout.write('\n\n \x1b[31m' + tt('Invalid key', '✗ Anahtar geçersiz') + '\x1b[0m (HTTP ' + r.status + '). ' +
51
+ tt('Copy the correct key from web Settings → API.', 'Web Ayarlar → API\'den doğru anahtarı kopyala.') + '\n\n');
48
52
  process.exit(1);
49
53
  }
50
54
  }
51
55
  catch (e) {
52
- process.stdout.write('\n\n Sunucuya ulaşılamadı: ' + (e?.message || e) + '\n\n');
56
+ process.stdout.write('\n\n ' + tt('Could not reach the server: ', 'Sunucuya ulaşılamadı: ') + (e?.message || e) + '\n\n');
53
57
  process.exit(1);
54
58
  }
55
59
  saveStored({ baseUrl: base, apiKey: key, model: 'wormclaude-v2' });
56
- process.stdout.write('\n\n \x1b[32m✓ Giriş başarılı!\x1b[0m Artık `wormclaude` yazarak kullanabilirsiniz.\n\n');
60
+ process.stdout.write('\n\n \x1b[32m' + tt('Signed in!', '✓ Giriş başarılı!') + '\x1b[0m ' +
61
+ tt('You can now use `wormclaude`.', 'Artık `wormclaude` yazarak kullanabilirsiniz.') + '\n\n');
57
62
  }
58
63
  // baseUrl ".../v1" → device endpoint'leri için kök (".../v1" olmadan)
59
64
  function apiOrigin(baseUrl) {
@@ -135,8 +140,8 @@ export function runUpdate() {
135
140
  // ↑/↓ ok tuşlarıyla gezin, Enter ile seç. (1/2 tuşları da çalışır.)
136
141
  export function promptLoginMenu() {
137
142
  const items = [
138
- { label: 'Giriş yap', value: 'login' },
139
- { label: 'Çıkış', value: 'exit' },
143
+ { label: tt('Log in', 'Giriş yap'), value: 'login' },
144
+ { label: tt('Exit', 'Çıkış'), value: 'exit' },
140
145
  ];
141
146
  return new Promise((resolve) => {
142
147
  const stdin = process.stdin;
@@ -148,7 +153,7 @@ export function promptLoginMenu() {
148
153
  }
149
154
  let idx = 0;
150
155
  process.stdout.write('\n \x1b[1mWormClaude\x1b[0m\n');
151
- process.stdout.write(' \x1b[2m↑/↓ ile seç · Enter ile onayla\x1b[0m\n\n');
156
+ process.stdout.write(' \x1b[2m' + tt('↑/↓ to select · Enter to confirm', '↑/↓ ile seç · Enter ile onayla') + '\x1b[0m\n\n');
152
157
  const draw = (first) => {
153
158
  if (!first)
154
159
  process.stdout.write(`\x1b[${items.length}A`); // imleci listenin başına al
@@ -217,17 +222,17 @@ export async function deviceLogin() {
217
222
  start = await r.json();
218
223
  }
219
224
  catch (e) {
220
- process.stderr.write('Giriş başlatılamadı: ' + (e?.message || e) + '\n');
225
+ process.stderr.write(tt('Could not start login: ', 'Giriş başlatılamadı: ') + (e?.message || e) + '\n');
221
226
  process.exit(1);
222
227
  }
223
228
  const url = start.verification_uri_complete || start.verification_uri;
224
229
  const deviceCode = start.device_code;
225
230
  openBrowser(url);
226
- process.stdout.write('\n Tarayıcıda Google ile giriş yapın...\n');
227
- process.stdout.write(' \x1b[2m(tarayıcı açılmadıysa: ' + url + ')\x1b[0m\n\n');
231
+ process.stdout.write('\n ' + tt('Sign in with Google in your browser...', 'Tarayıcıda Google ile giriş yapın...') + '\n');
232
+ process.stdout.write(' \x1b[2m(' + tt('if the browser did not open: ', 'tarayıcı açılmadıysa: ') + url + ')\x1b[0m\n\n');
228
233
  const pollMs = Math.max(2, Number(start.interval) || 3) * 1000;
229
234
  const deadline = Date.now() + (Number(start.expires_in) || 600) * 1000;
230
- process.stdout.write(' Bekleniyor');
235
+ process.stdout.write(' ' + tt('Waiting', 'Bekleniyor'));
231
236
  while (Date.now() < deadline) {
232
237
  await sleep(pollMs);
233
238
  process.stdout.write('.');
@@ -240,28 +245,21 @@ export async function deviceLogin() {
240
245
  continue; // geçici ağ hatası — tekrar dene
241
246
  }
242
247
  if (d.status === 'approved') {
243
- // Tek kalıcı anahtar: yeni oluşturulduysa raw gelir. Zaten varsa (existing) raw
244
- // verilemez (hash'li saklanır) → kullanıcı Ayarlar'dan anahtarını yapıştırmalı.
245
- if (d.existing && !d.api_key) {
246
- process.stdout.write('\n\n \x1b[33mHesabında zaten bir API anahtarı var.\x1b[0m (' + (d.prefix || 'wc_live_…') + '…)\n' +
247
- ' Güvenlik gereği mevcut anahtar tekrar gösterilemez. Şunlardan birini yap:\n' +
248
- ' 1) Anahtarını web Ayarlar → API\'den kopyala, sonra: \x1b[36mwormclaude login --key <ANAHTAR>\x1b[0m\n' +
249
- ' 2) Web Ayarlar → API\'de \x1b[36mSıfırla\x1b[0m de (yeni anahtar üretir; eski geçersiz olur), sonra tekrar gir.\n\n');
250
- process.exit(1);
251
- }
248
+ // Gateway onayda anahtarı CLI'ye bağlar (yoksa oluşturur, varsa yeniler) → api_key hep dolu.
252
249
  saveStored({
253
250
  baseUrl: d.base_url || base,
254
251
  apiKey: d.api_key,
255
252
  model: d.model || 'wormclaude-v2',
256
253
  });
257
- process.stdout.write('\n\n \x1b[32m✓ Giriş başarılı!\x1b[0m Artık `wormclaude` yazarak kullanabilirsiniz.\n\n');
254
+ process.stdout.write('\n\n \x1b[32m' + tt('Signed in!', '✓ Giriş başarılı!') + '\x1b[0m ' +
255
+ tt('You can now use `wormclaude`.', 'Artık `wormclaude` yazarak kullanabilirsiniz.') + '\n\n');
258
256
  return;
259
257
  }
260
258
  if (d.status === 'expired') {
261
- process.stdout.write('\n\n Kodun süresi doldu. Tekrar deneyin: wormclaude login\n\n');
259
+ process.stdout.write('\n\n ' + tt('Code expired. Try again: wormclaude login', 'Kodun süresi doldu. Tekrar deneyin: wormclaude login') + '\n\n');
262
260
  process.exit(1);
263
261
  }
264
262
  }
265
- process.stdout.write('\n\n Süre doldu. Tekrar deneyin: wormclaude login\n\n');
263
+ process.stdout.write('\n\n ' + tt('Timed out. Try again: wormclaude login', 'Süre doldu. Tekrar deneyin: wormclaude login') + '\n\n');
266
264
  process.exit(1);
267
265
  }
package/dist/cli.js CHANGED
@@ -61,11 +61,15 @@ import { shouldAutoCompact, runCompact, isContextError } from './compact.js';
61
61
  import { shouldExtract, triggerMemory, loadMemoryContext } from './memory.js';
62
62
  // --- WORMCLAUDE SUBCOMMANDS (TUI oncesi) ---
63
63
  const _arg = (process.argv[2] || '').toLowerCase();
64
+ // Dil: VARSAYILAN İngilizce; kayıtlı dil varsa onu uygula. TÜM yollardan (subcommand + TUI) ÖNCE
65
+ // ayarla ki login/whoami/hata mesajları da doğru dilde olsun (eskiden subcommand'lar default'a düşüyordu).
66
+ setLang(loadLang() ?? 'en');
67
+ const _tt = (en, tr) => (getLang() === 'tr' ? tr : en);
64
68
  // Headless mod: wormclaude -p "<görev>" → TUI'siz çalıştır, stdout'a yaz, çık (scriptlenebilir + test).
65
69
  if (_arg === '-p' || _arg === '--print') {
66
70
  const _prompt = process.argv.slice(3).join(' ').trim();
67
71
  if (!_prompt) {
68
- console.error('Kullanım: wormclaude -p "<görev>"');
72
+ console.error(_tt('Usage: wormclaude -p "<task>"', 'Kullanım: wormclaude -p "<görev>"'));
69
73
  process.exit(1);
70
74
  }
71
75
  const { runHeadless } = await import('./headless.js');
@@ -84,11 +88,11 @@ if (_arg === 'login' || _arg === 'logout' || _arg === 'whoami' || _arg === '--ve
84
88
  }
85
89
  else if (_arg === 'logout') {
86
90
  auth.clearStored();
87
- console.log('Cikis yapildi.');
91
+ console.log(_tt('Logged out.', 'Çıkış yapıldı.'));
88
92
  }
89
93
  else if (_arg === 'whoami') {
90
94
  const c = auth.loadStored();
91
- console.log(c.apiKey ? ('Giris yapildi (' + (c.baseUrl || '') + ')') : 'Giris yapilmadi - wormclaude login');
95
+ console.log(c.apiKey ? (_tt('Logged in (', 'Giriş yapıldı (') + (c.baseUrl || '') + ')') : _tt('Not logged in - wormclaude login', 'Giriş yapılmadı - wormclaude login'));
92
96
  }
93
97
  else if (_arg === 'update') {
94
98
  await auth.runUpdate();
@@ -168,7 +172,7 @@ if (_needLogin) {
168
172
  setToolConfig(config); // Agent/alt-agent araçları aynı config'i kullanır
169
173
  setCheckpointStore(process.cwd()); // rewind deposu (/rewind, /checkpoints)
170
174
  const MAX_TURNS = Number(process.env.WORMCLAUDE_MAX_TURNS) || 90; // tur limiti
171
- setLang(loadLang() ?? 'tr'); // kayıtlı dili yükle (yoksa tr)
175
+ setLang(loadLang() ?? 'en'); // kayıtlı dili yükle (yoksa İngilizce)
172
176
  loadSkills(); // .wormclaude/skills/*.md yükle
173
177
  loadExtensions(); // extensions/<ad>/ (gömülü + kullanıcı + proje) yükle
174
178
  // Kalıcı hafıza: açılışta .wormclaude/memory.md + WORMCLAUDE.md'yi context'e yükle
package/dist/commands.js CHANGED
@@ -164,6 +164,25 @@ function formatFinding(x) {
164
164
  return JSON.stringify(x);
165
165
  }
166
166
  // /recon /scan /xss /sqli — ince runner'ı sürer. Zorunlu yetki onayı + trust 3+ teaser.
167
+ // Slash'sız komut tespiti: kullanıcı "recon target.com" (slash'sız) yazınca "/recon target.com" öner.
168
+ // FALSE-POZİTİF guard: ilk kelime tam komut adı + argüman var + soru DEĞİL ("recon nedir?" tetiklemez).
169
+ const _BARE_CMDS = new Set(['recon', 'scan', 'xss', 'sqli', 'exploit', 'harden', 'agent', 'agents']);
170
+ const _QUESTION_WORDS = new Set(['nedir', 'ne', 'nasıl', 'nasil', 'neden', 'mi', 'mu', 'mı', 'mü', 'what', 'how', 'why', 'is', 'are', 'about', 'açıkla', 'acikla', 'explain', 'hakkında', 'hakkinda', 'anlat']);
171
+ export function detectBareCommand(input) {
172
+ const s = (input || '').trim();
173
+ if (!s || s.startsWith('/') || s.includes('?') || s.includes('\n'))
174
+ return null;
175
+ const parts = s.split(/\s+/);
176
+ if (parts.length < 2)
177
+ return null; // tek kelime → düz mesaj olabilir
178
+ const first = parts[0].toLowerCase();
179
+ if (!_BARE_CMDS.has(first))
180
+ return null;
181
+ if (_QUESTION_WORDS.has(parts[1].toLowerCase()))
182
+ return null; // "recon nedir" → komut değil
183
+ const cmd = first === 'agents' ? 'agent' : (first === 'scan' ? 'scan' : first);
184
+ return '/' + cmd + ' ' + parts.slice(1).join(' ');
185
+ }
167
186
  async function pentestCmd(tool, arg, ctx) {
168
187
  if (tool === 'scan')
169
188
  tool = 'recon'; // genel tarama = keşif+başlıklar
@@ -173,7 +192,17 @@ async function pentestCmd(tool, arg, ctx) {
173
192
  scopeAck = true;
174
193
  parts.pop();
175
194
  }
176
- const target = parts.join(' ').trim();
195
+ // Ana sayfadaki kozmetik flag'leri (--scope authorized, --cve X, --emit yara,sigma) yok say → hedef temiz kalsın
196
+ const cleaned = [];
197
+ for (let i = 0; i < parts.length; i++) {
198
+ if (parts[i].startsWith('-')) {
199
+ if (parts[i + 1] && !parts[i + 1].startsWith('-'))
200
+ i++;
201
+ continue;
202
+ }
203
+ cleaned.push(parts[i]);
204
+ }
205
+ const target = cleaned.join(' ').trim();
177
206
  const label = PT_LABELS[tool] || tool;
178
207
  if (!target) {
179
208
  ctx.note(`${label}\nKullanım: /${tool} <hedef>\nÖrnek: /${tool} https://test.com/sayfa?id=1`);
package/dist/i18n.js CHANGED
@@ -100,6 +100,7 @@ const STR = {
100
100
  'tui.userCancel': 'kullanıcı iptal etti',
101
101
  'tui.cmdErr': 'Komut hatası: {0}',
102
102
  'tui.langSet': 'Dil değiştirildi: Türkçe',
103
+ 'tui.useSlash': 'Komutlar / ile başlar. Şunu mu demek istediniz: {0} · çalıştırmak için Enter\'a bas',
103
104
  },
104
105
  en: {
105
106
  'lang.title': 'Select language / Dil seçin',
@@ -166,6 +167,7 @@ const STR = {
166
167
  'tui.userCancel': 'user cancelled',
167
168
  'tui.cmdErr': 'Command error: {0}',
168
169
  'tui.langSet': 'Language changed: English',
170
+ 'tui.useSlash': 'Commands start with /. Did you mean: {0} · press Enter to run',
169
171
  },
170
172
  };
171
173
  // Komut açıklamaları (slash menüsü + /help)
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.151';
19
+ export const VERSION = '1.0.153';
package/dist/tui.js CHANGED
@@ -15,7 +15,7 @@ import { itemAnsi, markdownAnsi } from './ansi.js';
15
15
  import { theme, VERSION } from './theme.js';
16
16
  import { cleanModelText } from './textclean.js';
17
17
  import { stripInlineToolCalls, stripEchoBlocks } from './inlinetools.js';
18
- import { COMMANDS, runSlashCommand, getPendingPentestCommand, buildExploitPrompt, buildHardenPrompt } from './commands.js';
18
+ import { COMMANDS, runSlashCommand, getPendingPentestCommand, buildExploitPrompt, buildHardenPrompt, detectBareCommand } from './commands.js';
19
19
  import { cmdDesc, t, setLang, loadLang, getLang } from './i18n.js';
20
20
  import { getSkill, getSkills, buildSkillPrompt } from './skills.js';
21
21
  import { getExtCommand, getExtCommands, buildExtCommandPrompt } from './extensions.js';
@@ -878,6 +878,16 @@ export async function runTui() {
878
878
  runCommand(v);
879
879
  return;
880
880
  }
881
+ // Slash'sız komut mu? ("recon target.com" → "/recon target.com" öner, slash kullanımına yönlendir)
882
+ const _bare = detectBareCommand(v);
883
+ if (_bare) {
884
+ printItem({ kind: 'note', text: t('tui.useSlash', _bare) });
885
+ inputBuf = _bare;
886
+ inputCur = _bare.length;
887
+ cmdSel = 0;
888
+ refresh();
889
+ return;
890
+ }
881
891
  // 🖼 Görsel sürükle-bırak — girdide resim yolu varsa VL modeline gönder (vision turu)
882
892
  const _vis = extractImages(v);
883
893
  if (_vis.images.length) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wormclaude",
3
- "version": "1.0.151",
3
+ "version": "1.0.153",
4
4
  "description": "WormClaude CLI - uncensored security+code assistant (ink TUI, Claude-style)",
5
5
  "type": "module",
6
6
  "bin": {