wormclaude 1.0.101 → 1.0.103

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 CHANGED
@@ -3,12 +3,13 @@ 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';
6
+ import * as fs from 'node:fs';
6
7
  import { theme, VERSION } from './theme.js';
7
8
  import { loadConfig, streamChat, fetchAccount } from './api.js';
8
9
  import { stripInlineToolCalls } from './inlinetools.js';
9
10
  import { newTrace, flushTelemetry } from './telemetry.js';
10
11
  import { tier } from './program.js';
11
- import { allToolSchemas, executeToolCalls, executeTool, toolLabel, setToolConfig } from './tools.js';
12
+ import { allToolSchemas, executeToolCalls, executeTool, toolLabel, setToolConfig, setBashCwd } from './tools.js';
12
13
  import { sanitizeError, sanitizeOutput } from './errorsan.js';
13
14
  import { cleanModelText } from './textclean.js';
14
15
  import { MarkdownDisplay } from './markdown.js';
@@ -927,6 +928,26 @@ function App() {
927
928
  }
928
929
  return;
929
930
  }
931
+ // /cd <yol> — çalışma klasörünü (workspace) değiştir. Dosyalar artık buraya yazılır.
932
+ if (tok === '/cd' || tok === '/klasor' || tok === '/workspace') {
933
+ const en = getLang() === 'en';
934
+ const arg = v.slice(tok.length).trim().replace(/^["']|["']$/g, '');
935
+ if (!arg) {
936
+ push({ kind: 'note', text: (en ? 'Workspace: ' : 'Çalışma klasörü: ') + process.cwd() });
937
+ return;
938
+ }
939
+ try {
940
+ const target = path.isAbsolute(arg) ? arg : path.resolve(process.cwd(), arg);
941
+ fs.mkdirSync(target, { recursive: true });
942
+ process.chdir(target);
943
+ setBashCwd(target);
944
+ push({ kind: 'note', text: (en ? '✓ Workspace → ' : '✓ Çalışma klasörü → ') + target });
945
+ }
946
+ catch (e) {
947
+ push({ kind: 'note', text: (en ? 'cd failed: ' : 'Klasör değiştirilemedi: ') + (e?.message || String(e)) });
948
+ }
949
+ return;
950
+ }
930
951
  // /agent ve /multi-agent — tek / çoklu alt-agent
931
952
  if (tok === '/agent' || tok === '/multi-agent') {
932
953
  const task = v.slice(tok.length).trim();
package/dist/commands.js CHANGED
@@ -20,6 +20,7 @@ export const COMMANDS = [
20
20
  { name: '/help', desc: 'komutları ve ipuçlarını göster' },
21
21
  { name: '/clear', desc: 'sohbeti ve geçmişi temizle' },
22
22
  { name: '/kopyala', desc: 'son yanıtı panoya kopyala (/kopyala hepsi · tüm sohbet)' },
23
+ { name: '/cd', desc: 'çalışma klasörünü değiştir — dosyalar buraya yazılır: /cd <yol>' },
23
24
  { name: '/compact', desc: 'geçmişi modelle özetleyip bağlamı küçült' },
24
25
  { name: '/context', desc: 'bağlam / token kullanımını göster' },
25
26
  { name: '/cost', desc: 'oturum token tahminini göster' },
@@ -110,6 +110,21 @@ export function recoverInlineToolCalls(text) {
110
110
  push(o);
111
111
  }
112
112
  }
113
+ // 4) AskUserQuestion'ı JSON yerine DÜZ-METİN (prose) yazan model (abliterated):
114
+ // AskUserQuestion question "X" with options [A · B · C] → gerçek çağrıya çevir.
115
+ if (!out.length && /AskUserQuestion/i.test(t)) {
116
+ const m = t.match(/AskUserQuestion[\s\S]*?["“]([^"”]{3,}?)["”][\s\S]*?\[([^\]]+)\]/i);
117
+ if (m) {
118
+ const question = m[1].trim();
119
+ const options = m[2]
120
+ .split(/\s*[·•|,/]\s*|\s{2,}/)
121
+ .map((s) => s.trim().replace(/^["'“]|["'”]$/g, ''))
122
+ .filter(Boolean)
123
+ .map((label) => ({ label }));
124
+ if (options.length >= 2)
125
+ push({ name: 'AskUserQuestion', arguments: { question, options } });
126
+ }
127
+ }
113
128
  return out;
114
129
  }
115
130
  /** Kurtarılan çağrı bloklarını GÖRÜNTÜ/geçmiş metninden temizler (çirkin JSON kalmasın). */
@@ -124,5 +139,7 @@ export function stripInlineToolCalls(text) {
124
139
  if (/"(name|tool|function)"/.test(frag))
125
140
  s = s.replace(frag, '');
126
141
  }
142
+ // AskUserQuestion prose biçimi (interaktif seçiciye çevrildi → metni gizle).
143
+ s = s.replace(/AskUserQuestion[\s\S]*?\[[^\]]*\]\s*/gi, '');
127
144
  return s.trim();
128
145
  }
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.101';
19
+ export const VERSION = '1.0.103';
package/dist/tools.js CHANGED
@@ -33,6 +33,16 @@ const MAX_BASH_TIMEOUT_MS = 600000;
33
33
  let bashCwd;
34
34
  export function getBashCwd() { return bashCwd || process.cwd(); }
35
35
  export function setBashCwd(dir) { bashCwd = dir; }
36
+ // Göreli dosya yollarını AKTİF workspace'e (bashCwd) çözer; mutlak yol aynen kalır.
37
+ // Böylece model "index.html" gibi göreli yol verse bile dosya bilinen klasöre yazılır.
38
+ export function resolveWs(fp) {
39
+ try {
40
+ return path.isAbsolute(fp) ? fp : path.resolve(getBashCwd(), fp);
41
+ }
42
+ catch {
43
+ return fp;
44
+ }
45
+ }
36
46
  // Komutu çalıştırır ve sonrasında cwd değişikliğini (cd) yakalayıp bashCwd'yi günceller.
37
47
  // POSIX: pwd'yi temp dosyaya yazan, çıkış kodunu KORUYAN sarmalayıcı (hata propagasyonu bozulmaz).
38
48
  // Windows: komutu olduğu gibi çalıştır, sonra baştaki `cd <hedef>`'i regex ile yakala (best-effort).
@@ -1007,7 +1017,7 @@ export async function executeTool(name, args) {
1007
1017
  }
1008
1018
  }
1009
1019
  if (name === 'Read') {
1010
- const fp = args.file_path;
1020
+ const fp = resolveWs(args.file_path);
1011
1021
  if (!fs.existsSync(fp))
1012
1022
  return { ok: false, output: `Error: file does not exist: ${fp}` };
1013
1023
  if (fs.statSync(fp).isDirectory())
@@ -1027,7 +1037,7 @@ export async function executeTool(name, args) {
1027
1037
  return { ok: true, output: numbered.slice(0, 40000) };
1028
1038
  }
1029
1039
  if (name === 'Write') {
1030
- const fp = args.file_path;
1040
+ const fp = resolveWs(args.file_path);
1031
1041
  if (fs.existsSync(fp) && !readFiles.has(norm(fp)))
1032
1042
  return { ok: false, output: 'Error: existing file must be read first. Use the Read tool before overwriting.' };
1033
1043
  fs.mkdirSync(path.dirname(path.resolve(fp)), { recursive: true });
@@ -1043,7 +1053,7 @@ export async function executeTool(name, args) {
1043
1053
  return { ok: true, output: `Wrote ${fp} (${_wnew.length} chars)${diffStat(_wold, _wnew)}` };
1044
1054
  }
1045
1055
  if (name === 'Edit') {
1046
- const fp = args.file_path;
1056
+ const fp = resolveWs(args.file_path);
1047
1057
  if (!fs.existsSync(fp))
1048
1058
  return { ok: false, output: `Error: file does not exist: ${fp}` };
1049
1059
  if (!readFiles.has(norm(fp)))
@@ -1067,7 +1077,7 @@ export async function executeTool(name, args) {
1067
1077
  return { ok: true, output: `Edited ${fp}${args.replace_all ? ` (${count} occurrences)` : ''}${diffStat(_ebefore, c)}` };
1068
1078
  }
1069
1079
  if (name === 'Glob') {
1070
- const base = args.path || process.cwd();
1080
+ const base = args.path ? resolveWs(args.path) : getBashCwd();
1071
1081
  const all = [];
1072
1082
  walk(base, all);
1073
1083
  const rx = globToRegex(args.pattern);
@@ -1087,7 +1097,7 @@ export async function executeTool(name, args) {
1087
1097
  return { ok: true, output: shown.join('\n') + (truncated ? '\n(results truncated to 100 files)' : '') };
1088
1098
  }
1089
1099
  if (name === 'Grep') {
1090
- const base = args.path && fs.existsSync(args.path) ? args.path : process.cwd();
1100
+ const base = args.path && fs.existsSync(resolveWs(args.path)) ? resolveWs(args.path) : getBashCwd();
1091
1101
  const mode = args.output_mode || 'files_with_matches';
1092
1102
  const flags = (args['-i'] ? 'i' : '') + (args.multiline ? 's' : '');
1093
1103
  let rx;
@@ -1342,7 +1352,7 @@ export async function executeTool(name, args) {
1342
1352
  }
1343
1353
  }
1344
1354
  if (name === 'LSP') {
1345
- const base = args.path && fs.existsSync(args.path) ? args.path : process.cwd();
1355
+ const base = args.path && fs.existsSync(resolveWs(args.path)) ? resolveWs(args.path) : getBashCwd();
1346
1356
  const sym = String(args.symbol);
1347
1357
  const esc = sym.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
1348
1358
  const defRe = new RegExp(`\\b(function|class|def|const|let|var|interface|type|enum|struct|fn|func)\\s+${esc}\\b`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wormclaude",
3
- "version": "1.0.101",
3
+ "version": "1.0.103",
4
4
  "description": "WormClaude CLI - uncensored security+code assistant (ink TUI, Claude-style)",
5
5
  "type": "module",
6
6
  "bin": {