wormclaude 1.0.9 → 1.0.11
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/cli.js +18 -1
- package/dist/commands.js +43 -0
- package/dist/skills.js +21 -6
- package/dist/theme.js +1 -1
- package/package.json +3 -2
- package/skills/explain.md +14 -0
- package/skills/recon.md +16 -0
- package/skills/security-audit/prompt.md +18 -0
- package/skills/security-audit/skill.json +8 -0
package/dist/cli.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import React, { useState, useRef, useEffect } from 'react';
|
|
3
3
|
import { render, Box, Text, useApp, useInput } from 'ink';
|
|
4
4
|
import TextInput from 'ink-text-input';
|
|
5
|
+
import * as path from 'node:path';
|
|
5
6
|
import { theme, VERSION } from './theme.js';
|
|
6
7
|
import { loadConfig, streamChat } from './api.js';
|
|
7
8
|
import { allToolSchemas, executeToolCalls, executeTool, toolLabel, setToolConfig } from './tools.js';
|
|
@@ -62,7 +63,20 @@ setLang(loadLang() ?? 'tr'); // kayıtlı dili yükle (yoksa tr)
|
|
|
62
63
|
loadSkills(); // .wormclaude/skills/*.md yükle
|
|
63
64
|
// Kalıcı hafıza: açılışta .wormclaude/memory.md + WORMCLAUDE.md'yi context'e yükle
|
|
64
65
|
const _memCtx = loadMemoryContext();
|
|
65
|
-
const
|
|
66
|
+
const _envContext = () => {
|
|
67
|
+
const plat = process.platform === 'win32' ? 'Windows' : process.platform === 'darwin' ? 'macOS' : 'Linux';
|
|
68
|
+
const shell = process.platform === 'win32' ? 'PowerShell (cmd.exe altinda calisir)' : 'bash/sh';
|
|
69
|
+
const winNote = process.platform === 'win32'
|
|
70
|
+
? ' This is WINDOWS. Use Windows-correct commands. The Bash tool runs via cmd.exe so && chaining works, but do NOT assume a Unix shell: avoid grep/sed/awk/ls/cat — use the Read/Grep/Glob tools or PowerShell (Get-Content, Select-String, Get-ChildItem). Backslash paths are fine. AVOID interactive scaffolders that hang or are slow (create-react-app); prefer non-interactive, e.g. Vite: npm create vite@latest myapp -- --template react, then npm install. Always pass non-interactive flags (-y, --yes) when available.'
|
|
71
|
+
: ' Use POSIX shell commands.';
|
|
72
|
+
return `ENVIRONMENT: The user machine runs ${plat}. Bash tool shell: ${shell}. Current working directory: ${process.cwd()}.${winNote}`;
|
|
73
|
+
};
|
|
74
|
+
const _initHistory = () => {
|
|
75
|
+
const sys = [{ role: 'system', content: _envContext() }];
|
|
76
|
+
if (_memCtx)
|
|
77
|
+
sys.push({ role: 'system', content: _memCtx });
|
|
78
|
+
return sys;
|
|
79
|
+
};
|
|
66
80
|
// FULLSCREEN (alternate screen) — WormClaude'un yöntemi: tüm ekranı ink yönetir,
|
|
67
81
|
// scrollback YOK, resize'da HER ŞEY yeniden çizilir → sarmalanma/kaskad olmaz.
|
|
68
82
|
// ?1049h alt-screen · ?1007h alternate-scroll (fare tekerleği → ok tuşu; seçim bozulmaz)
|
|
@@ -253,6 +267,7 @@ function StatusLine({ model, ctxTokens }) {
|
|
|
253
267
|
const filled = Math.round(pct / 10);
|
|
254
268
|
const bar = '█'.repeat(filled) + '░'.repeat(10 - filled);
|
|
255
269
|
const barColor = pct > 85 ? theme.errorRed : pct > 60 ? theme.redBright : theme.grey;
|
|
270
|
+
const cwd = path.basename(process.cwd()) || process.cwd();
|
|
256
271
|
return (React.createElement(Box, null,
|
|
257
272
|
React.createElement(Text, { color: theme.greyDim },
|
|
258
273
|
' ',
|
|
@@ -264,6 +279,8 @@ function StatusLine({ model, ctxTokens }) {
|
|
|
264
279
|
" \u00B7 ",
|
|
265
280
|
model,
|
|
266
281
|
" \u00B7 "),
|
|
282
|
+
React.createElement(Text, { color: theme.grey }, cwd),
|
|
283
|
+
React.createElement(Text, { color: theme.greyDim }, " \u00B7 "),
|
|
267
284
|
React.createElement(Text, { color: barColor }, bar),
|
|
268
285
|
React.createElement(Text, { color: theme.greyDim },
|
|
269
286
|
" ",
|
package/dist/commands.js
CHANGED
|
@@ -35,10 +35,31 @@ export const COMMANDS = [
|
|
|
35
35
|
{ name: '/kill', desc: 'bir arka plan görevini durdur: /kill <id>' },
|
|
36
36
|
{ name: '/dream', desc: 'arka planda hafızayı konsolide et (.wormclaude/memory.md)' },
|
|
37
37
|
{ name: '/learn', desc: 'web-öğrenme datasını göster / aç-kapa (eğitim için)' },
|
|
38
|
+
{ name: '/copy', desc: 'son yaniti panoya kopyala (/copy all = tum sohbet)' },
|
|
38
39
|
{ name: '/export', desc: 'sohbeti dosyaya kaydet' },
|
|
39
40
|
{ name: '/resume', desc: 'en son kaydedilen oturumu yükle' },
|
|
40
41
|
{ name: '/quit', desc: 'çıkış' },
|
|
41
42
|
];
|
|
43
|
+
function _copyClipboard(text) {
|
|
44
|
+
try {
|
|
45
|
+
if (process.platform === 'win32')
|
|
46
|
+
execSync('clip', { input: text });
|
|
47
|
+
else if (process.platform === 'darwin')
|
|
48
|
+
execSync('pbcopy', { input: text });
|
|
49
|
+
else {
|
|
50
|
+
try {
|
|
51
|
+
execSync('xclip -selection clipboard', { input: text });
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
execSync('wl-copy', { input: text });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
42
63
|
// Tek seferlik tam yanıt (stream'i biriktirir, araç çağrısı yok)
|
|
43
64
|
async function complete(messages, config) {
|
|
44
65
|
let out = '';
|
|
@@ -494,6 +515,28 @@ export async function runSlashCommand(input, ctx) {
|
|
|
494
515
|
})();
|
|
495
516
|
return true;
|
|
496
517
|
}
|
|
518
|
+
case '/copy': {
|
|
519
|
+
const hist = ctx.getHistory().filter((m) => m.role !== 'system');
|
|
520
|
+
const all = arg === 'all' || arg === 'hepsi' || arg === 'tum' || arg === 'tümü';
|
|
521
|
+
let text = '';
|
|
522
|
+
if (all) {
|
|
523
|
+
const NL = String.fromCharCode(10);
|
|
524
|
+
text = hist.map((m) => `## ${m.role}` + NL + (typeof m.content === 'string' ? m.content : JSON.stringify(m.content))).join(NL + NL);
|
|
525
|
+
}
|
|
526
|
+
else {
|
|
527
|
+
const lastA = [...hist].reverse().find((m) => m.role === 'assistant');
|
|
528
|
+
text = lastA ? (typeof lastA.content === 'string' ? lastA.content : JSON.stringify(lastA.content)) : '';
|
|
529
|
+
}
|
|
530
|
+
if (!text.trim()) {
|
|
531
|
+
ctx.note('Kopyalanacak içerik yok.');
|
|
532
|
+
return true;
|
|
533
|
+
}
|
|
534
|
+
const ok = _copyClipboard(text);
|
|
535
|
+
ctx.note(ok
|
|
536
|
+
? `Panoya kopyalandı (${text.length} karakter, ${all ? 'tüm sohbet' : 'son yanıt'}). Tümü için: /copy all`
|
|
537
|
+
: 'Pano aracı yok (win: clip · mac: pbcopy · linux: xclip/wl-copy). /export ile dosyaya kaydedebilirsin.');
|
|
538
|
+
return true;
|
|
539
|
+
}
|
|
497
540
|
case '/export': {
|
|
498
541
|
fs.mkdirSync(SESSION_DIR, { recursive: true });
|
|
499
542
|
const file = path.join(SESSION_DIR, `session-${tsStamp()}.json`);
|
package/dist/skills.js
CHANGED
|
@@ -11,9 +11,12 @@ import { execSync } from 'node:child_process';
|
|
|
11
11
|
import * as fs from 'node:fs';
|
|
12
12
|
import * as os from 'node:os';
|
|
13
13
|
import * as path from 'node:path';
|
|
14
|
+
import { fileURLToPath } from 'node:url';
|
|
14
15
|
import { getLang } from './i18n.js';
|
|
15
16
|
let SKILLS = [];
|
|
16
17
|
const SKILLS_DIR = path.join(process.cwd(), '.wormclaude', 'skills');
|
|
18
|
+
// Pakete gomulu skill'ler (npm paketiyle gelir): <pkg>/skills (dist'in bir ust dizini)
|
|
19
|
+
const BUNDLED_DIR = path.join(path.dirname(fileURLToPath(import.meta.url)), '..', 'skills');
|
|
17
20
|
export function getSkillsDir() { return SKILLS_DIR; }
|
|
18
21
|
function parseFrontmatter(raw) {
|
|
19
22
|
if (!raw.startsWith('---'))
|
|
@@ -40,15 +43,28 @@ function readFirst(dir, names) {
|
|
|
40
43
|
}
|
|
41
44
|
export function loadSkills() {
|
|
42
45
|
SKILLS = [];
|
|
46
|
+
// Once gomulu (paket) skill'ler, sonra proje (.wormclaude/skills) — proje ayni adi override eder.
|
|
47
|
+
scanSkillDir(BUNDLED_DIR);
|
|
48
|
+
scanSkillDir(SKILLS_DIR);
|
|
49
|
+
return SKILLS;
|
|
50
|
+
}
|
|
51
|
+
function pushSkill(sk) {
|
|
52
|
+
const i = SKILLS.findIndex((x) => x.name === sk.name);
|
|
53
|
+
if (i >= 0)
|
|
54
|
+
SKILLS[i] = sk;
|
|
55
|
+
else
|
|
56
|
+
SKILLS.push(sk);
|
|
57
|
+
}
|
|
58
|
+
function scanSkillDir(dir) {
|
|
43
59
|
let entries = [];
|
|
44
60
|
try {
|
|
45
|
-
entries = fs.readdirSync(
|
|
61
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
46
62
|
}
|
|
47
63
|
catch {
|
|
48
|
-
return
|
|
64
|
+
return;
|
|
49
65
|
}
|
|
50
66
|
for (const e of entries) {
|
|
51
|
-
const full = path.join(
|
|
67
|
+
const full = path.join(dir, e.name);
|
|
52
68
|
if (e.isDirectory()) {
|
|
53
69
|
// Klasör skill'i: skill.json + prompt.md
|
|
54
70
|
let manifest = {};
|
|
@@ -60,7 +76,7 @@ export function loadSkills() {
|
|
|
60
76
|
if (!body && !manifest.name)
|
|
61
77
|
continue; // skill değil
|
|
62
78
|
const name = (manifest.name || e.name).trim().replace(/[^a-zA-Z0-9_-]/g, '-');
|
|
63
|
-
|
|
79
|
+
pushSkill({
|
|
64
80
|
name,
|
|
65
81
|
description: manifest.description || body.split('\n').find((l) => l.trim())?.slice(0, 80) || name,
|
|
66
82
|
whenToUse: manifest.whenToUse,
|
|
@@ -84,7 +100,7 @@ export function loadSkills() {
|
|
|
84
100
|
const name = (fm.name || e.name.replace(/\.md$/, '')).trim().replace(/[^a-zA-Z0-9_-]/g, '-');
|
|
85
101
|
if (!name)
|
|
86
102
|
continue;
|
|
87
|
-
|
|
103
|
+
pushSkill({
|
|
88
104
|
name,
|
|
89
105
|
description: fm.description || body.split('\n').find((l) => l.trim())?.slice(0, 80) || name,
|
|
90
106
|
whenToUse: fm.whenToUse,
|
|
@@ -95,7 +111,6 @@ export function loadSkills() {
|
|
|
95
111
|
});
|
|
96
112
|
}
|
|
97
113
|
}
|
|
98
|
-
return SKILLS;
|
|
99
114
|
}
|
|
100
115
|
export function getSkills() { return SKILLS; }
|
|
101
116
|
export function getSkill(name) { return SKILLS.find((s) => s.name === name); }
|
package/dist/theme.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wormclaude",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.11",
|
|
4
4
|
"description": "WormClaude CLI - uncensored security+code assistant (ink TUI, Claude-style)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"dev": "tsx src/cli.tsx",
|
|
11
|
-
"build": "tsc",
|
|
11
|
+
"build": "tsc && node scripts/copy-skills.mjs",
|
|
12
12
|
"start": "node dist/cli.js",
|
|
13
13
|
"prepublishOnly": "npm run build"
|
|
14
14
|
},
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
},
|
|
28
28
|
"files": [
|
|
29
29
|
"dist",
|
|
30
|
+
"skills",
|
|
30
31
|
"README.md"
|
|
31
32
|
],
|
|
32
33
|
"engines": {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: explain
|
|
3
|
+
description: kodu satir satir acikla
|
|
4
|
+
context: inline
|
|
5
|
+
---
|
|
6
|
+
Verilen kodu net ve adim adim acikla.
|
|
7
|
+
|
|
8
|
+
- Once bir cumleyle kodun GENEL amacini soyle (ne ise yariyor).
|
|
9
|
+
- Sonra mantiksal bloklari sirayla ele al; her bloğun ne yaptigini ve NEDEN orada oldugunu acikla.
|
|
10
|
+
- Onemli satirlarda: degisken/fonksiyonun rolu, akis (donguler, kosullar), girdi/cikti.
|
|
11
|
+
- Dilin/cerceve'nin onemli kavramlarini (kapanis, async, pointer, decorator vb.) kisa kenar notuyla acikla.
|
|
12
|
+
- Varsa gizli tuzaklari, kenar durumlari, performans veya guvenlik etkilerini belirt.
|
|
13
|
+
- Gereksiz teori anlatma; kodun gercekten yaptigina bagli kal. Seviyeyi kullanicinin sorusuna gore ayarla (yeni baslayan ise daha sade).
|
|
14
|
+
- Sonunda 1-2 satirla ozetle: "kisaca bu kod ...".
|
package/skills/recon.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: recon
|
|
3
|
+
description: hedefte pasif kesif yap
|
|
4
|
+
context: fork
|
|
5
|
+
---
|
|
6
|
+
Verilen hedef uzerinde SADECE pasif kesif (OSINT) yap — hedefe dogrudan saldirgan trafik gonderme. Yetkili bir degerlendirme baglaminda calistigini varsay.
|
|
7
|
+
|
|
8
|
+
Toplanacaklar:
|
|
9
|
+
- **Alan adi / DNS**: whois (sahip, kayit tarihi, ad sunuculari), A/AAAA/MX/TXT/NS kayitlari, SPF/DMARC.
|
|
10
|
+
- **Subdomain'ler**: pasif kaynaklardan (sertifika seffafligi/crt.sh, public DNS veri setleri). Brute-force YAPMA.
|
|
11
|
+
- **IP / ASN**: hangi blok, hosting/CDN saglayicisi, acik kaynaklardaki gecmis kayitlar.
|
|
12
|
+
- **Teknoloji izleri**: pasif parmak izi (HTTP basliklari acik kaynaklarda, builtwith tarzi veriler, public JS).
|
|
13
|
+
- **Maruz kalan varliklar**: public kod depolari, sizan kimlik bilgileri, pastebin/leak, dizinler, eski/arsiv sayfalar (wayback).
|
|
14
|
+
- **Insan/organizasyon**: public calisan/e-posta formatlari (yalnizca acik kaynaklardan, sosyal muhendislik icin degil).
|
|
15
|
+
|
|
16
|
+
Cikti: bulgulari kategorize edilmis, kaynagiyla birlikte ozetle. Saldiri yuzeyi acisindan one cikan noktalari ve bir sonraki (yetkili, aktif) adimda nereye bakilmasi gerektigini belirt. Pasif sinirin disina cikma.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
Bir kod tabaninda guvenlik denetimi (audit) yap. Yetkili bir inceleme baglamindasin; amac zafiyetleri bulup somut duzeltme onermek.
|
|
2
|
+
|
|
3
|
+
Yontem:
|
|
4
|
+
1. **Kapsami cikar**: Glob/Read ile dilleri, cerceveleri, giris noktalarini (HTTP route'lari, CLI, job'lar), dis baglantilari (DB, dosya, ag, shell, deserialization) belirle.
|
|
5
|
+
2. **Guven sinirlarini izle**: kullanici/dis girdinin nereye aktigini Grep ile ara — SQL, HTML/render, OS komutu, dosya yolu, redirect, template, eval.
|
|
6
|
+
3. **Sinif sinif tara** ve her bulguyu kanitla (dosya:satir):
|
|
7
|
+
- Injection: SQLi, komut enjeksiyonu, SSTI, LDAP/NoSQL.
|
|
8
|
+
- XSS / cikti kodlama eksikligi, tehlikeli `innerHTML`/`render`.
|
|
9
|
+
- Erisim kontrolu: IDOR, eksik authz, guvenlik-belirsizlikle (security by obscurity).
|
|
10
|
+
- Auth/oturum: zayif token, JWT dogrulama hatasi, parola saklama (duz/ MD5).
|
|
11
|
+
- Sirlar: kodda gomulu API key/parola/.env sizintisi.
|
|
12
|
+
- Path traversal / guvensiz dosya islemleri / guvensiz deserialization.
|
|
13
|
+
- SSRF, acik redirect, CORS yanlis yapilandirmasi.
|
|
14
|
+
- Bagimlilik: bilinen zafiyetli/eski paketler.
|
|
15
|
+
4. **Onceliklendir**: her bulgu icin Kritik/Yuksek/Orta/Dusuk + gercek etki (saldirgan ne kazanir).
|
|
16
|
+
5. **Duzeltme ver**: her bulgu icin somut, guvenli kod ornegi.
|
|
17
|
+
|
|
18
|
+
Cikti: kisa ozet + bulgu listesi (konum, sinif, siddet, etki, duzeltme). Tahminde bulunma; iddiani kodla destekle. Yikici komut calistirma — sadece oku/ara/analiz et.
|