wormclaude 1.0.21 → 1.0.22

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/ansi.js ADDED
@@ -0,0 +1,166 @@
1
+ // Geçmiş öğelerini doğrudan terminal scrollback'ine yazmak için ANSI string üreticisi.
2
+ // ink <Static> resize'da her şeyi yeniden bastığından (kademe/çift banner), geçmiş artık
3
+ // stdout'a BİR KEZ yazılır; ink yalnız canlı footer'ı yönetir. Böylece doğal kaydırma +
4
+ // metin seçip kopyalama çalışır. Markdown + sözdizimi vurgusu burada ANSI'ye çevrilir.
5
+ import { theme } from './theme.js';
6
+ import { highlight } from './highlight.js';
7
+ import { t } from './i18n.js';
8
+ const RESET = '\x1b[0m';
9
+ function hexAnsi(hex) {
10
+ if (!hex)
11
+ return '';
12
+ const m = /^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(hex);
13
+ if (!m)
14
+ return '';
15
+ return `\x1b[38;2;${parseInt(m[1], 16)};${parseInt(m[2], 16)};${parseInt(m[3], 16)}m`;
16
+ }
17
+ const paint = (s, hex, bold = false, dim = false, italic = false) => `${bold ? '\x1b[1m' : ''}${dim ? '\x1b[2m' : ''}${italic ? '\x1b[3m' : ''}${hexAnsi(hex)}${s}${RESET}`;
18
+ // ── Satır kaydırma (görsel genişliğe göre basit sarma) ──
19
+ function wrap(text, width) {
20
+ const out = [];
21
+ for (const para of String(text).split('\n')) {
22
+ if (!para) {
23
+ out.push('');
24
+ continue;
25
+ }
26
+ let line = '';
27
+ for (const word of para.split(' ')) {
28
+ const cand = line ? line + ' ' + word : word;
29
+ if (cand.length <= width) {
30
+ line = cand;
31
+ continue;
32
+ }
33
+ if (line)
34
+ out.push(line);
35
+ if (word.length > width) {
36
+ let w = word;
37
+ while (w.length > width) {
38
+ out.push(w.slice(0, width));
39
+ w = w.slice(width);
40
+ }
41
+ line = w;
42
+ }
43
+ else
44
+ line = word;
45
+ }
46
+ out.push(line);
47
+ }
48
+ return out;
49
+ }
50
+ // ── Inline markdown → ANSI (**bold** `code` *italik* [t](u)) ──
51
+ function inlineAnsi(text) {
52
+ return text
53
+ .replace(/`([^`]+)`/g, (_m, c) => paint(c, theme.green))
54
+ .replace(/\*\*([^*]+)\*\*/g, (_m, c) => paint(c, undefined, true))
55
+ .replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_m, a, b) => `${a}${paint(' (' + b + ')', theme.redBright)}`);
56
+ }
57
+ const WORM_ROWS = [
58
+ '██╗ ██╗ ██████╗ ██████╗ ███╗ ███╗',
59
+ '██║ ██║██╔═══██╗██╔══██╗████╗ ████║',
60
+ '██║ █╗ ██║██║ ██║██████╔╝██╔████╔██║',
61
+ '██║███╗██║██║ ██║██╔══██╗██║╚██╔╝██║',
62
+ '╚███╔███╔╝╚██████╔╝██║ ██║██║ ╚═╝ ██║',
63
+ ' ╚══╝╚══╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝',
64
+ ];
65
+ const CLAUDE_ROWS = [
66
+ ' ██████╗██╗ █████╗ ██╗ ██╗██████╗ ███████╗',
67
+ '██╔════╝██║ ██╔══██╗██║ ██║██╔══██╗██╔════╝',
68
+ '██║ ██║ ███████║██║ ██║██║ ██║█████╗ ',
69
+ '██║ ██║ ██╔══██║██║ ██║██║ ██║██╔══╝ ',
70
+ '╚██████╗███████╗██║ ██║╚██████╔╝██████╔╝███████╗',
71
+ ' ╚═════╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚══════╝',
72
+ ];
73
+ /** Banner'ı ANSI olarak üretir (dar ekranda tek kelime, geniş ekranda yan yana). */
74
+ export function bannerAnsi(cols) {
75
+ if (cols < 46)
76
+ return paint('WORMCLAUDE', theme.red, true) + '\n' + paint(' ' + t('banner.subtitle'), theme.greyDim);
77
+ const rows = cols >= 88 ? WORM_ROWS.map((w, i) => w + CLAUDE_ROWS[i]) : [...WORM_ROWS, ...CLAUDE_ROWS];
78
+ return rows.map((r) => paint(r, theme.red, true)).join('\n') + '\n' + paint(' ' + t('banner.subtitle'), theme.greyDim);
79
+ }
80
+ // ── Markdown bloğu → ANSI (kod blokları sözdizimi-vurgulu) ──
81
+ function markdownAnsi(text, cols) {
82
+ const W = Math.max(20, cols - 2);
83
+ const lines = text.split('\n');
84
+ const out = [];
85
+ let inCode = false, fence = '', lang = '', code = [];
86
+ const fenceRe = /^ *(`{3,}|~{3,}) *(\w*)? *$/;
87
+ const flushCode = () => {
88
+ if (lang)
89
+ out.push(paint(' ' + lang, theme.greyDim));
90
+ for (const toks of highlight(code.join('\n'), lang)) {
91
+ out.push(paint('│ ', theme.greyDim) + (toks.length ? toks.map((tk) => paint(tk.text, tk.color)).join('') : ' '));
92
+ }
93
+ code = [];
94
+ lang = '';
95
+ fence = '';
96
+ };
97
+ for (const line of lines) {
98
+ if (inCode) {
99
+ const fm = line.match(fenceRe);
100
+ if (fm && fm[1][0] === fence[0] && fm[1].length >= fence.length) {
101
+ inCode = false;
102
+ flushCode();
103
+ }
104
+ else
105
+ code.push(line);
106
+ continue;
107
+ }
108
+ const fm = line.match(fenceRe);
109
+ if (fm) {
110
+ inCode = true;
111
+ fence = fm[1];
112
+ lang = (fm[2] || '').trim();
113
+ continue;
114
+ }
115
+ const hm = line.match(/^ *(#{1,4}) +(.*)/);
116
+ const um = line.match(/^([ \t]*)([-*+]) +(.*)/);
117
+ const om = line.match(/^([ \t]*)(\d+)\. +(.*)/);
118
+ if (hm) {
119
+ const lvl = hm[1].length, inner = inlineAnsi(hm[2]);
120
+ out.push(lvl <= 2 ? paint(inner, theme.redBright, true) : lvl === 3 ? paint(inner, theme.white, true) : paint(inner, theme.grey, false, false, true));
121
+ }
122
+ else if (um || om) {
123
+ const [, ws, marker, itemText] = (um || om);
124
+ const prefix = om ? `${marker}. ` : '• ';
125
+ out.push(' '.repeat(ws.length) + paint(prefix, theme.grey) + inlineAnsi(itemText));
126
+ }
127
+ else if (line.trim() === '') {
128
+ out.push('');
129
+ }
130
+ else {
131
+ for (const w of wrap(line, W))
132
+ out.push(inlineAnsi(w));
133
+ }
134
+ }
135
+ if (inCode)
136
+ flushCode();
137
+ return out.join('\n');
138
+ }
139
+ /** Bir geçmiş öğesini scrollback'e yazılacak ANSI string'e çevirir (üstte 1 boş satır). */
140
+ export function itemAnsi(it, cols) {
141
+ const W = Math.max(24, cols - 2);
142
+ if (it.kind === 'banner')
143
+ return '\n' + bannerAnsi(cols);
144
+ if (it.kind === 'user') {
145
+ const inner = W - 4;
146
+ const top = paint('╭' + '─'.repeat(W - 2) + '╮', theme.greyDim);
147
+ const bot = paint('╰' + '─'.repeat(W - 2) + '╯', theme.greyDim);
148
+ const body = wrap('› ' + (it.text || ''), inner).map((ln) => paint('│ ', theme.greyDim) + paint(ln.padEnd(inner), theme.white) + paint(' │', theme.greyDim));
149
+ return '\n' + [top, ...body, bot].join('\n');
150
+ }
151
+ if (it.kind === 'assistant') {
152
+ const md = markdownAnsi(it.text || '', cols).split('\n');
153
+ return '\n' + md.map((ln, i) => (i === 0 ? paint('⏺ ', theme.redBright, true) + ln : ' ' + ln)).join('\n');
154
+ }
155
+ if (it.kind === 'tool') {
156
+ const n = (it.result || '').split('\n').length, chars = (it.result || '').length;
157
+ const head = paint('⏺ ', theme.redBright, true) + paint(it.label || '', theme.white);
158
+ const sub = paint(' ⎿ ', theme.greyDim) + (it.ok
159
+ ? paint(`${n} ${t('common.lines') || 'satır'} (${chars})`, theme.grey)
160
+ : paint('✗ ' + (it.result || '').slice(0, 160), theme.errorRed));
161
+ return '\n' + head + '\n' + sub;
162
+ }
163
+ if (it.kind === 'note')
164
+ return '\n' + wrap(it.text || '', W).map((ln) => paint(ln, theme.greyDim)).join('\n');
165
+ return '';
166
+ }
package/dist/cli.js CHANGED
@@ -788,10 +788,9 @@ function App() {
788
788
  runAgent(v);
789
789
  }
790
790
  const { cols, rows } = useDimensions();
791
- // İlk açılış: dil seçimi
791
+ // İlk açılış: dil seçimi (banner stdout'a basıldı; burada yalnız seçim footer'ı)
792
792
  if (lang === null) {
793
- return (React.createElement(Box, { flexDirection: "column", height: rows, width: cols },
794
- React.createElement(Banner, null),
793
+ return (React.createElement(Box, { flexDirection: "column", width: cols },
795
794
  React.createElement(Box, { flexDirection: "column", marginTop: 1, paddingX: 1 },
796
795
  React.createElement(Text, { color: theme.redBright, bold: true }, t('lang.title')),
797
796
  React.createElement(Box, { flexDirection: "column", marginTop: 1 },
@@ -803,14 +802,11 @@ function App() {
803
802
  t('lang.en'))),
804
803
  React.createElement(Text, { color: theme.greyDim },
805
804
  " ",
806
- t('lang.hint'))),
807
- React.createElement(Box, { flexGrow: 1 }),
808
- React.createElement(StatusLine, { model: config.model, ctxTokens: 0 })));
805
+ t('lang.hint')))));
809
806
  }
810
- // Açılış: klasöre güven sorusu (WormClaude tarzı)
807
+ // Açılış: klasöre güven sorusu (banner stdout'ta; burada yalnız soru footer'ı)
811
808
  if (!started) {
812
- return (React.createElement(Box, { flexDirection: "column", height: rows, width: cols },
813
- React.createElement(Banner, null),
809
+ return (React.createElement(Box, { flexDirection: "column", width: cols },
814
810
  React.createElement(Box, { flexDirection: "column", marginTop: 1, paddingX: 1 },
815
811
  React.createElement(Text, { color: theme.redBright, bold: true }, t('trust.accessing')),
816
812
  React.createElement(Text, null, " "),
@@ -828,9 +824,7 @@ function App() {
828
824
  t('trust.no'))),
829
825
  React.createElement(Text, { color: theme.greyDim },
830
826
  " ",
831
- t('trust.hint'))),
832
- React.createElement(Box, { flexGrow: 1 }),
833
- React.createElement(StatusLine, { model: config.model, ctxTokens: 0 })));
827
+ t('trust.hint')))));
834
828
  }
835
829
  return (React.createElement(Box, { flexDirection: "column", width: cols },
836
830
  React.createElement(Static, { items: items }, (item, i) => React.createElement(RenderItem, { key: i, item: item })),
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.21';
19
+ export const VERSION = '1.0.22';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wormclaude",
3
- "version": "1.0.21",
3
+ "version": "1.0.22",
4
4
  "description": "WormClaude CLI - uncensored security+code assistant (ink TUI, Claude-style)",
5
5
  "type": "module",
6
6
  "bin": {