wormclaude 1.0.10 → 1.0.12
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 +14 -1
- package/dist/commands.js +43 -0
- package/dist/skills.js +17 -9
- package/dist/theme.js +1 -1
- package/dist/tools.js +17 -9
- package/package.json +1 -1
- package/skills/security-audit/{prompt.md → SKILL.md} +8 -0
- package/skills/security-audit/skill.json +0 -8
package/dist/cli.js
CHANGED
|
@@ -63,7 +63,20 @@ setLang(loadLang() ?? 'tr'); // kayıtlı dili yükle (yoksa tr)
|
|
|
63
63
|
loadSkills(); // .wormclaude/skills/*.md yükle
|
|
64
64
|
// Kalıcı hafıza: açılışta .wormclaude/memory.md + WORMCLAUDE.md'yi context'e yükle
|
|
65
65
|
const _memCtx = loadMemoryContext();
|
|
66
|
-
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
|
+
};
|
|
67
80
|
// FULLSCREEN (alternate screen) — WormClaude'un yöntemi: tüm ekranı ink yönetir,
|
|
68
81
|
// scrollback YOK, resize'da HER ŞEY yeniden çizilir → sarmalanma/kaskad olmaz.
|
|
69
82
|
// ?1049h alt-screen · ?1007h alternate-scroll (fare tekerleği → ok tuşu; seçim bozulmaz)
|
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
|
@@ -66,23 +66,31 @@ function scanSkillDir(dir) {
|
|
|
66
66
|
for (const e of entries) {
|
|
67
67
|
const full = path.join(dir, e.name);
|
|
68
68
|
if (e.isDirectory()) {
|
|
69
|
-
// Klasör skill'i:
|
|
69
|
+
// Klasör skill'i: SKILL.md (frontmatter + gövde) tercih edilir.
|
|
70
|
+
// skill.json yalnızca geriye-uyumluluk için fallback meta sağlar.
|
|
71
|
+
const raw = readFirst(full, ['SKILL.md', 'skill.md', 'prompt.md']);
|
|
70
72
|
let manifest = {};
|
|
71
73
|
try {
|
|
72
74
|
manifest = JSON.parse(fs.readFileSync(path.join(full, 'skill.json'), 'utf8'));
|
|
73
75
|
}
|
|
74
76
|
catch { }
|
|
75
|
-
const body =
|
|
76
|
-
|
|
77
|
+
const { fm, body } = parseFrontmatter(raw);
|
|
78
|
+
const rawName = fm.name || manifest.name || e.name;
|
|
79
|
+
if (!body.trim() && !rawName)
|
|
77
80
|
continue; // skill değil
|
|
78
|
-
const name = (
|
|
81
|
+
const name = String(rawName).trim().replace(/[^a-zA-Z0-9_-]/g, '-');
|
|
82
|
+
const ctx = (fm.context || manifest.context) === 'fork' ? 'fork' : 'inline';
|
|
83
|
+
const autoInvoke = fm.autoInvoke !== undefined ? fm.autoInvoke === 'true' : !!manifest.autoInvoke;
|
|
84
|
+
const tools = fm.tools
|
|
85
|
+
? fm.tools.split(',').map((s) => s.trim())
|
|
86
|
+
: Array.isArray(manifest.tools) ? manifest.tools : undefined;
|
|
79
87
|
pushSkill({
|
|
80
88
|
name,
|
|
81
|
-
description: manifest.description || body.split('\n').find((l) => l.trim())?.slice(0, 80) || name,
|
|
82
|
-
whenToUse: manifest.whenToUse,
|
|
83
|
-
context:
|
|
84
|
-
autoInvoke
|
|
85
|
-
tools
|
|
89
|
+
description: fm.description || manifest.description || body.split('\n').find((l) => l.trim())?.slice(0, 80) || name,
|
|
90
|
+
whenToUse: fm.whenToUse || manifest.whenToUse,
|
|
91
|
+
context: ctx,
|
|
92
|
+
autoInvoke,
|
|
93
|
+
tools,
|
|
86
94
|
body: body.trim(),
|
|
87
95
|
dir: full,
|
|
88
96
|
});
|
package/dist/theme.js
CHANGED
package/dist/tools.js
CHANGED
|
@@ -10,7 +10,7 @@ import { loadConfig } from './api.js';
|
|
|
10
10
|
import { runAgentLoop } from './agent.js';
|
|
11
11
|
import { tasks } from './tasks.js';
|
|
12
12
|
import { getMcpToolSchemas, callMcpTool } from './mcp.js';
|
|
13
|
-
import {
|
|
13
|
+
import { getSkills, getSkill, buildSkillPrompt } from './skills.js';
|
|
14
14
|
import * as computer from './computer.js';
|
|
15
15
|
// Agent/alt-agent araçlarının backend'e ulaşması için config. cli.tsx başlangıçta
|
|
16
16
|
// setToolConfig ile aynı (mutable) config nesnesini verir → /config değişiklikleri görülür.
|
|
@@ -480,23 +480,26 @@ export const toolSchemas = [
|
|
|
480
480
|
},
|
|
481
481
|
},
|
|
482
482
|
];
|
|
483
|
-
//
|
|
483
|
+
// TÜM skill'leri model'e tek bir 'Skill' aracı olarak sunar (Claude Code tarzı).
|
|
484
|
+
// Mevcut skiller araç açıklamasına enjekte edilir; model gerektiğinde kendisi çağırır.
|
|
484
485
|
function skillToolSchema() {
|
|
485
|
-
const
|
|
486
|
-
if (!
|
|
486
|
+
const all = getSkills();
|
|
487
|
+
if (!all.length)
|
|
487
488
|
return null;
|
|
488
|
-
const list =
|
|
489
|
+
const list = all.map((s) => `- ${s.name}: ${s.description}${s.whenToUse ? ` (when: ${s.whenToUse})` : ''}`).join('\n');
|
|
489
490
|
return {
|
|
490
491
|
type: 'function',
|
|
491
492
|
function: {
|
|
492
493
|
name: 'Skill',
|
|
493
|
-
description: '
|
|
494
|
-
'
|
|
494
|
+
description: 'Load a specialized skill (expert instructions + resources) when the user task matches one of the available skills below. ' +
|
|
495
|
+
'When a skill is relevant, call this IMMEDIATELY as your first action — do not just mention it in text. ' +
|
|
496
|
+
'Inline skills load their guidance straight into this conversation; fork skills run as a focused sub-agent and return a result. ' +
|
|
497
|
+
'Only use skills from this list:\n' + list,
|
|
495
498
|
parameters: {
|
|
496
499
|
type: 'object',
|
|
497
500
|
properties: {
|
|
498
|
-
name: { type: 'string', enum:
|
|
499
|
-
args: { type: 'string', description: 'Optional context/arguments for the skill' },
|
|
501
|
+
name: { type: 'string', enum: all.map((s) => s.name), description: 'The skill to load, from the available list' },
|
|
502
|
+
args: { type: 'string', description: 'Optional extra context/arguments for the skill' },
|
|
500
503
|
},
|
|
501
504
|
required: ['name'],
|
|
502
505
|
},
|
|
@@ -1159,6 +1162,11 @@ export async function executeTool(name, args) {
|
|
|
1159
1162
|
if (!sk)
|
|
1160
1163
|
return { ok: false, output: `Unknown skill: ${args.name}` };
|
|
1161
1164
|
const prompt = buildSkillPrompt(sk, String(args.args || ''));
|
|
1165
|
+
// inline skill (varsayılan): rehberi doğrudan ana konuşmaya yükle (Claude Code tarzı)
|
|
1166
|
+
if (sk.context !== 'fork') {
|
|
1167
|
+
return { ok: true, output: prompt };
|
|
1168
|
+
}
|
|
1169
|
+
// fork skill: odaklı alt-agent olarak çalıştır, yalnızca sonucu döndür
|
|
1162
1170
|
let tools = subAgentTools();
|
|
1163
1171
|
if (sk.tools && sk.tools.length)
|
|
1164
1172
|
tools = tools.filter((t) => sk.tools.includes(t.function.name));
|
package/package.json
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: security-audit
|
|
3
|
+
description: Pentest ve kod guvenlik analizi
|
|
4
|
+
whenToUse: kod guvenligi, zafiyet taramasi veya pentest istendiginde
|
|
5
|
+
context: fork
|
|
6
|
+
autoInvoke: true
|
|
7
|
+
tools: Read,Grep,Bash
|
|
8
|
+
---
|
|
1
9
|
Bir kod tabaninda guvenlik denetimi (audit) yap. Yetkili bir inceleme baglamindasin; amac zafiyetleri bulup somut duzeltme onermek.
|
|
2
10
|
|
|
3
11
|
Yontem:
|