beast-agent 1.2.2 → 1.2.3

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "beast-agent",
3
3
  "productName": "Beast Agent",
4
- "version": "1.2.2",
4
+ "version": "1.2.3",
5
5
  "description": "Ultra-fast local agent shell for Windows.",
6
6
  "author": "algokodcom (AlgoKod)",
7
7
  "license": "MIT",
@@ -1385,7 +1385,7 @@ class Engine {
1385
1385
  ? '# PROJE TALİMATLARI (workspace AGENTS/CLAUDE/CONTEXT dosyalarından — daima uy)\n' + proj + '\n'
1386
1386
  : '') +
1387
1387
  'WORKFLOW (her işte bu sıra):\n' +
1388
- '1) BAĞLAM: değiştirmeden önce ilgili dosyaları OKU — read_file satır numaralı döner (N: içerik); büyük dosyada devamını offset parametresiyle oku, ASLA baştan okuma; bir dosyayı aynı oturumda BİR KEZ okumak yeter — içeriği bağlamda zaten var. İçerik araması için grep (regex), dosya adı araması için glob kullan; varsayım yapma, mevcut stili/konvansiyonu takip et.\n' +
1388
+ '1) BAĞLAM: değiştirmeden önce ilgili dosyaları OKU — read_file satır numaralı döner (N: içerik); büyük dosyada devamını offset parametresiyle oku, ASLA baştan okuma; bir dosyayı aynı oturumda BİR KEZ okumak yeter — içeriği sonraki turlarda da bağlamda KALIR, edit yaptıktan sonra dosyayı yeniden okuma (güncel durum = son okuma + kendi editlerin). İçerik araması için grep (regex), dosya adı için glob kullan; varsayım yapma, mevcut stili/konvansiyonu takip et.\n' +
1389
1389
  '2) PLAN: 2+ adımlı işlerde İLK EYLEM todo_write olsun (2-6 madde); her adım bitince status:"done" ile GÜNCELLE — liste bitene kadar iş bitmiş sayılmaz.\n' +
1390
1390
  '3) EDİT: VAR OLAN dosyada önce edit_file kullan (old_string/new_string ile yalnız ilgili bölümü değiştir; birden çok eşleşme varsa bağlam ekle ya da replace_all); write_file yalnız YENİ dosya ya da tam yeniden yazım için. İlgisiz yeniden biçimleme/kayıt boşluk değişikliği YAPMA. edit_file/write_file sonucu additions/deletions döner ve değişiklik diske ANINDA uygulanır — doğrulamak için dosyayı TEKRAR OKUMA YASAK; sonraki editi önceki okuduğun içerik + kendi değişikliklerin üzerinden zincirle.\n' +
1391
1391
  '4) DOĞRULA: edit sonrası mümkünse derle/test et/lint çalıştır (run_command); hata varsa DÜZELT ve TEKRAR dene (en fazla 2 doğrulama turu) — kırmızı bırakma. Doğrulama read_file ile DEĞİL run_command ile yapılır.\n' +
@@ -1616,16 +1616,51 @@ class Engine {
1616
1616
  }
1617
1617
  return m;
1618
1618
  });
1619
+ /* opencode file-state portu: read_file sonuçları bağlamda YAŞAR —
1620
+ 1200 char'a kırpma modeli "unuttu" diye tekrar tekrar okumaya
1621
+ zorluyordu. Her dosyanın yalnız EN SON okuması tam tutulur (diskte
1622
+ zaten TOOL_OUT_KEEP*6 ile sınırlı); daha eski okumalar stub'a iner. */
1623
+ const READ_KEEP = TOOL_OUT_KEEP * 6; /* depolama tavanıyla hizalı */
1624
+ const readPathOf = (m) => {
1625
+ const s = String(m.content || '');
1626
+ try {
1627
+ const j = JSON.parse(s);
1628
+ if (j && j.path) return String(j.path);
1629
+ } catch {}
1630
+ const mm = /"path"\s*:\s*"((?:[^"\\]|\\.)*)"/.exec(s.slice(0, 600));
1631
+ return mm ? mm[1] : null;
1632
+ };
1633
+ const lastRead = new Map(); /* dosya yolu → flat'teki en son okuma indeksi */
1634
+ for (let k = 0; k < flat.length; k++) {
1635
+ const m = flat[k];
1636
+ if (m.role === 'tool' && m.name === 'read_file') {
1637
+ const p = readPathOf(m);
1638
+ if (p) lastRead.set(p, k);
1639
+ }
1640
+ }
1619
1641
  for (let k = 0; k < flat.length; k++) {
1620
1642
  const m = flat[k];
1621
1643
  if (m.role !== 'tool') continue;
1622
- const tooLong = String(m.content || '').length > TOOL_OUT_KEEP * 2;
1623
- /* diffView UI-only metadata'dır — sağlayıcıya GİTMEZ (bilinmeyen alan
1624
- reddi + token israfı önlenir); kırpma ile aynı kopyada birleştirilir */
1625
- if (tooLong || m.diffView) {
1644
+ const len = String(m.content || '').length;
1645
+ let content;
1646
+ if (m.name === 'read_file') {
1647
+ const p = readPathOf(m);
1648
+ if (p && lastRead.get(p) !== k) {
1649
+ content =
1650
+ '[aynı dosyanın daha YENİ bir okuması bağlamda — bu ESKİ okuma bağlam tasarrufu için kırpıldı; en son okumayı esas al]';
1651
+ } else if (len > READ_KEEP) {
1652
+ content = String(m.content).slice(0, READ_KEEP) + '\n…[kırpıldı — devam için offset ile oku]';
1653
+ } else {
1654
+ content = null; /* TAM KORUNUR — kırpma yok */
1655
+ }
1656
+ } else {
1657
+ content = len > TOOL_OUT_KEEP * 2 ? String(m.content).slice(0, TOOL_OUT_KEEP) + '\n…[kırpıldı]' : null;
1658
+ }
1659
+ /* diffView UI-only metadata'dır — sağlayıcıya GİTMEZ */
1660
+ if (content !== null || m.diffView) {
1626
1661
  const rest = { ...m };
1627
1662
  delete rest.diffView;
1628
- if (tooLong) rest.content = String(m.content).slice(0, TOOL_OUT_KEEP) + '\n…[kırpıldı]';
1663
+ if (content !== null) rest.content = content;
1629
1664
  flat[k] = rest;
1630
1665
  }
1631
1666
  }
@@ -1302,6 +1302,25 @@ function diffRegion(before, after) {
1302
1302
  return { before: capDiffText(beforeRegion), after: capDiffText(afterRegion), startLine: start + 1 };
1303
1303
  }
1304
1304
 
1305
+ /* ---------- read_file disk-cache (opencode file-state portu) ----------
1306
+ mtime+size değişmemişse dosya yeniden diskten OKUNMAZ — cache'ten döner.
1307
+ edit_file/write_file kendi yazdıklarından sonra cache'i düşürür; böylece
1308
+ sonraki okuma daima güncel içerik verir. */
1309
+ const _readCache = new Map(); /* abs → { mtimeMs, size, raw } */
1310
+
1311
+ function readCacheGet(abs, st) {
1312
+ const hit = _readCache.get(abs);
1313
+ if (hit && hit.mtimeMs === st.mtimeMs && hit.size === st.size) return hit.raw;
1314
+ const raw = fs.readFileSync(abs, 'utf8');
1315
+ if (_readCache.size > 200) _readCache.delete(_readCache.keys().next().value);
1316
+ _readCache.set(abs, { mtimeMs: st.mtimeMs, size: st.size, raw });
1317
+ return raw;
1318
+ }
1319
+
1320
+ function readCacheDrop(abs) {
1321
+ _readCache.delete(abs);
1322
+ }
1323
+
1305
1324
  const definitions = [
1306
1325
  {
1307
1326
  type: 'function',
@@ -1558,6 +1577,7 @@ async function exec(name, args, ctx) {
1558
1577
  }
1559
1578
  fs.mkdirSync(path.dirname(filePath), { recursive: true });
1560
1579
  fs.writeFileSync(filePath, newS, 'utf8');
1580
+ readCacheDrop(filePath);
1561
1581
  const counts = diffLineCounts('', newS);
1562
1582
  const out = { ok: true, path: filePath, note: 'Edit applied successfully.', replacements: 1, ...counts };
1563
1583
  if (ctx.wantDiff) out.diffView = { path: filePath, before: '', after: capDiffText(newS), startLine: 1, ...counts };
@@ -1573,6 +1593,7 @@ async function exec(name, args, ctx) {
1573
1593
  const rep = ocReplace(contentOld, oldN, newN, !!(args.replace_all || args.replaceAll));
1574
1594
  const contentNew = rep.result;
1575
1595
  fs.writeFileSync(filePath, contentNew, 'utf8');
1596
+ readCacheDrop(filePath); /* sonraki read_file taze içerik okusun */
1576
1597
  const counts = diffLineCounts(contentOld, contentNew);
1577
1598
  const out = {
1578
1599
  ok: true,
@@ -1612,7 +1633,7 @@ async function exec(name, args, ctx) {
1612
1633
  return JSON.stringify({ ok: false, error: 'pdf okuma hata: ' + String((e2 && e2.message) || e2) });
1613
1634
  }
1614
1635
  }
1615
- let raw = fs.readFileSync(abs, 'utf8');
1636
+ let raw = readCacheGet(abs, st);
1616
1637
  /* opencode read.ts port: satır numaralı çıktı (`N: içerik`), offset/limit
1617
1638
  penceresi (1-indexed), 2000 satır varsayılan, uzun satır kırpma */
1618
1639
  const allLines = raw.split('\n');
@@ -1661,6 +1682,7 @@ async function exec(name, args, ctx) {
1661
1682
  const before = existed && !fs.statSync(abs).isDirectory() ? fs.readFileSync(abs, 'utf8') : '';
1662
1683
  fs.mkdirSync(path.dirname(abs), { recursive: true });
1663
1684
  fs.writeFileSync(abs, content, 'utf8');
1685
+ readCacheDrop(abs); /* sonraki read_file taze içerik okusun */
1664
1686
  const counts = diffLineCounts(before, content);
1665
1687
  const out = { ok: true, path: abs, bytes: Buffer.byteLength(content), ...counts };
1666
1688
  if (ctx.wantDiff) {