wormclaude 1.0.99 → 1.0.101

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
@@ -11,7 +11,7 @@ export function loadConfig() {
11
11
  return {
12
12
  baseUrl: process.env.WORMCLAUDE_BASE_URL || stored.baseUrl || DEFAULT_BASE_URL,
13
13
  apiKey: process.env.WORMCLAUDE_API_KEY || stored.apiKey || '',
14
- model: process.env.WORMCLAUDE_MODEL || stored.model || 'wormclaude',
14
+ model: process.env.WORMCLAUDE_MODEL || stored.model || 'wormclaude-v2',
15
15
  };
16
16
  }
17
17
  // Kullanıcının doğrulama başvuru durumu (GET /v1/verify).
package/dist/auth.js CHANGED
@@ -219,7 +219,7 @@ export async function deviceLogin() {
219
219
  saveStored({
220
220
  baseUrl: d.base_url || base,
221
221
  apiKey: d.api_key,
222
- model: d.model || 'wormclaude',
222
+ model: d.model || 'wormclaude-v2',
223
223
  });
224
224
  process.stdout.write('\n\n \x1b[32m✓ Giriş başarılı!\x1b[0m Artık `wormclaude` yazarak kullanabilirsiniz.\n\n');
225
225
  return;
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import React, { useState, useRef, useEffect } from 'react';
2
+ import React, { useState, useRef, useEffect, useMemo } from 'react';
3
3
  import { render, Box, Text, useApp, useInput } from 'ink';
4
4
  import LineEditor from './lineeditor.js';
5
5
  import * as path from 'node:path';
@@ -679,6 +679,7 @@ function App() {
679
679
  let lastAnswer = ''; // modelin son (sentez) cevabı
680
680
  let lastToolSig = '';
681
681
  let sameToolCount = 0;
682
+ let taskIn = 0, taskOut = 0, taskCache = 0; // bu görevin GERÇEK token toplamı (tüm turlar; API usage'dan)
682
683
  while (iter < MAX_TURNS) {
683
684
  if (ac.signal.aborted) {
684
685
  push({ kind: 'note', text: t('note.interrupted') });
@@ -703,11 +704,25 @@ function App() {
703
704
  setTokens(0);
704
705
  setVerb(VERBS[Math.floor(Math.random() * VERBS.length)]);
705
706
  let toolCalls = [];
707
+ // Akış UI güncellemesi throttle + tail-cap: her chunk yerine ~60ms'de bir, ve
708
+ // sadece son TAIL_CHARS karakteri temizleyip göster. Aksi halde uzun çıktıda her
709
+ // token tüm metni cleanModelText + word-wrap'ten geçirir → O(n²) → donma.
710
+ // Tam metin zaten döngü sonunda bir kez temizlenip scrollback'e (push) gider.
711
+ const TAIL_CHARS = 4000;
712
+ let lastUi = 0;
713
+ const paintStream = () => {
714
+ const tail = assistantText.length > TAIL_CHARS ? assistantText.slice(-TAIL_CHARS) : assistantText;
715
+ setStreaming(cleanModelText(tail));
716
+ setTokens(Math.round(assistantText.length / 4));
717
+ };
706
718
  for await (const ev of streamChat(historyRef.current, allToolSchemas(), config, ac.signal)) {
707
719
  if (ev.type === 'text') {
708
720
  assistantText += ev.text;
709
- setStreaming(cleanModelText(assistantText));
710
- setTokens(Math.round(assistantText.length / 4));
721
+ const now = Date.now();
722
+ if (now - lastUi >= 60) {
723
+ lastUi = now;
724
+ paintStream();
725
+ }
711
726
  }
712
727
  else if (ev.type === 'error') {
713
728
  if (isContextError(ev.error))
@@ -718,6 +733,9 @@ function App() {
718
733
  else if (ev.type === 'done') {
719
734
  toolCalls = ev.toolCalls;
720
735
  usage.record(config.model, ev.usage); // billing: token/maliyet kaydı
736
+ taskIn += ev.usage?.input || 0; // bu görevin gerçek token toplamı
737
+ taskOut += ev.usage?.output || 0;
738
+ taskCache += ev.usage?.cacheRead || 0; // havuz hafıza (prefix-cache) isabeti
721
739
  }
722
740
  }
723
741
  setStreaming('');
@@ -818,6 +836,12 @@ function App() {
818
836
  }
819
837
  if (!done)
820
838
  push({ kind: 'note', text: t('note.maxTurns', MAX_TURNS) });
839
+ // Bu görevin GERÇEK token maliyeti (tüm turların toplamı, API usage'dan)
840
+ if (taskIn + taskOut > 0) {
841
+ const tot = (taskIn + taskOut).toLocaleString();
842
+ const cacheStr = taskCache > 0 ? ` (${taskCache.toLocaleString()} havuz-önbellek)` : '';
843
+ push({ kind: 'note', text: `⎿ Bu istek: ↑${taskIn.toLocaleString()} giriş${cacheStr} · ↓${taskOut.toLocaleString()} çıkış · toplam ${tot} token` });
844
+ }
821
845
  abortRef.current = null;
822
846
  setCtxTokens(Math.round(JSON.stringify(historyRef.current).length / 4));
823
847
  setBusy(false);
@@ -1040,11 +1064,15 @@ function App() {
1040
1064
  React.createElement(Box, { flexGrow: 1 }),
1041
1065
  React.createElement(StatusLine, { model: config.model, ctxTokens: 0 })));
1042
1066
  }
1067
+ // buildLines tüm geçmişi satıra çevirir (kod blokları highlight). Sadece items/cols
1068
+ // değişince hesapla — aksi halde her akış/scroll güncellemesinde tüm geçmiş yeniden
1069
+ // işlenir (uzun çıktıda donmaya katkı).
1070
+ const allLines = useMemo(() => buildLines(items, cols), [items, cols]);
1043
1071
  return (React.createElement(Box, { flexDirection: "column", height: rows, width: cols },
1044
1072
  React.createElement(Box, { flexDirection: "column", flexGrow: 1, overflow: "hidden" }, (() => {
1045
1073
  // Alt-screen + satır-pencere pager: tüm öğeleri satıra çevir, pencere göster.
1046
1074
  // (Kopyalama /kopyala komutuyla; resize'da kaskad olmaz.)
1047
- const all = buildLines(items, cols);
1075
+ const all = allLines;
1048
1076
  const reserve = busy ? 8 : 6; // busy'de artık spinner + giriş kutusu birlikte görünür
1049
1077
  const avail = Math.max(4, rows - reserve - (streaming ? 3 : 0) - 2);
1050
1078
  const maxScroll = Math.max(0, all.length - avail);
@@ -33,6 +33,42 @@ function toToolCall(obj, i) {
33
33
  function looksLikeCall(o) {
34
34
  return !!o && typeof o === 'object' && (typeof o.name === 'string' || typeof o.tool === 'string' || (o.function && typeof o.function === 'object'));
35
35
  }
36
+ /** Metindeki üst-düzey {…} JSON nesnelerini (string/escape duyarlı) çıkarır.
37
+ * Model çağrıları sarmasız ve BİRDEN FAZLA nesne olarak dökebilir: {…}{…} veya {…}\n{…}
38
+ * (abliterated coder davranışı). Her üst-düzey nesneyi ayrı parça olarak döndürür. */
39
+ function extractTopLevelJsonObjects(text) {
40
+ const objs = [];
41
+ let depth = 0, start = -1, inStr = false, esc = false;
42
+ for (let i = 0; i < text.length; i++) {
43
+ const c = text[i];
44
+ if (inStr) {
45
+ if (esc)
46
+ esc = false;
47
+ else if (c === '\\')
48
+ esc = true;
49
+ else if (c === '"')
50
+ inStr = false;
51
+ continue;
52
+ }
53
+ if (c === '"')
54
+ inStr = true;
55
+ else if (c === '{') {
56
+ if (depth === 0)
57
+ start = i;
58
+ depth++;
59
+ }
60
+ else if (c === '}') {
61
+ if (depth > 0) {
62
+ depth--;
63
+ if (depth === 0 && start >= 0) {
64
+ objs.push(text.slice(start, i + 1));
65
+ start = -1;
66
+ }
67
+ }
68
+ }
69
+ }
70
+ return objs;
71
+ }
36
72
  /** 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
73
  * (<tool_call>, ```json) veya mesajın TAMAMI tek JSON çağrısıysa onu alır. */
38
74
  export function recoverInlineToolCalls(text) {
@@ -65,11 +101,14 @@ export function recoverInlineToolCalls(text) {
65
101
  push(o);
66
102
  }
67
103
  }
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);
104
+ // 3) Sarmasız bir veya BİRDEN FAZLA üst-düzey JSON çağrısı.
105
+ // Model {..}{..} ya da {..}\n{..} dökebilir (abliterated coder) → hepsini tara.
106
+ if (!out.length) {
107
+ for (const frag of extractTopLevelJsonObjects(t)) {
108
+ const o = safeJsonParse(frag, null);
109
+ if (looksLikeCall(o))
110
+ push(o);
111
+ }
73
112
  }
74
113
  return out;
75
114
  }
@@ -80,8 +119,10 @@ export function stripInlineToolCalls(text) {
80
119
  s = s.replace(/```(?:json|tool_call|tool|function)?\s*\{[\s\S]*?\}\s*```/gi, (blk) => {
81
120
  return /"(name|tool|function)"/.test(blk) ? '' : blk; // yalnız çağrı-bloklarını sil
82
121
  });
83
- const tr = s.trim();
84
- if (tr.startsWith('{') && tr.endsWith('}') && /"(name|tool|function)"/.test(tr))
85
- return '';
122
+ // Sarmasız üst-düzey JSON çağrı nesnelerini sil (tek veya çoklu).
123
+ for (const frag of extractTopLevelJsonObjects(s)) {
124
+ if (/"(name|tool|function)"/.test(frag))
125
+ s = s.replace(frag, '');
126
+ }
86
127
  return s.trim();
87
128
  }
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.99';
19
+ export const VERSION = '1.0.101';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wormclaude",
3
- "version": "1.0.99",
3
+ "version": "1.0.101",
4
4
  "description": "WormClaude CLI - uncensored security+code assistant (ink TUI, Claude-style)",
5
5
  "type": "module",
6
6
  "bin": {