beast-agent 1.2.1 → 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.1",
4
+ "version": "1.2.3",
5
5
  "description": "Ultra-fast local agent shell for Windows.",
6
6
  "author": "algokodcom (AlgoKod)",
7
7
  "license": "MIT",
@@ -108,7 +108,17 @@ step('5/5 OneDrive yedek (beast-v' + next + ')');
108
108
  try {
109
109
  const dest = path.join(ONE_DRIVE_DIR, 'beast-v' + next);
110
110
  fs.mkdirSync(dest, { recursive: true });
111
- run(`robocopy "${ROOT}" "${dest}" /E /XD node_modules dist "beast agent web" .git /NFL /NDL /NJH`);
111
+ /* robocopy 0-7 arası TÜM çıkış kodları başarıdır (1 = dosya kopyalandı);
112
+ execSync 0 dışını hata sanır — kodu burada yut, gerçek hatada (>7) dur */
113
+ try {
114
+ execSync(
115
+ `robocopy "${ROOT}" "${dest}" /E /XD node_modules dist "beast agent web" .git /NFL /NDL /NJH`,
116
+ { cwd: ROOT, stdio: 'pipe' }
117
+ );
118
+ } catch (e) {
119
+ const code = e && e.status;
120
+ if (!(typeof code === 'number' && code < 8)) throw e;
121
+ }
112
122
  const info = path.join(dest, `YEDEK-BILGI-v${next}.txt`);
113
123
  fs.writeFileSync(info, `BEAST AGENT v${next} — ${new Date().toLocaleString('tr-TR')}\nKaynak: ${ROOT}\nGitHub: https://github.com/algokodcom/beast-agent/releases/tag/${tag}\nnpm: https://www.npmjs.com/package/beast-agent\n`);
114
124
  ok(dest);
@@ -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) {
@@ -133,7 +133,7 @@
133
133
  <div id="bcStatus" hidden></div>
134
134
  <div id="bcInputRow">
135
135
  <span id="bcPrompt">code&gt;</span>
136
- <input id="bcInput" spellcheck="false" autocomplete="off" placeholder="Beast Code mesajı yaz — Enter ile gönder…" data-i18n-ph="bc_ph" />
136
+ <textarea id="bcInput" rows="1" spellcheck="false" autocomplete="off" placeholder="Beast Code mesajı yaz — Enter ile gönder…" data-i18n-ph="bc_ph"></textarea>
137
137
  <button id="bcStop" title="Çalışan mesajı durdur" hidden data-i18n-title="bc_stop">&#x25A0;&#xFE0E;</button>
138
138
  </div>
139
139
  </div>
@@ -6800,10 +6800,24 @@ function bcIngest(ev) {
6800
6800
  }
6801
6801
  }
6802
6802
 
6803
+ /* Beast Code input otomatik büyür: textarea'da satır sonuna gelince alan
6804
+ aşağı açılır; 140px (≈6 satır) tavanını aşarsa iç scroll'a döner */
6805
+ function bcInputResize() {
6806
+ const ta = els.bcInput;
6807
+ if (!ta) return;
6808
+ ta.style.height = 'auto';
6809
+ const max = 140;
6810
+ const h = Math.min(ta.scrollHeight, max);
6811
+ ta.style.height = h + 'px';
6812
+ ta.classList.toggle('expand', ta.scrollHeight > max);
6813
+ }
6814
+
6803
6815
  function bcRunCurrent() {
6804
6816
  const msg = els.bcInput.value.trim();
6805
6817
  if (!msg) return;
6806
6818
  els.bcInput.value = '';
6819
+ bcInputResize();
6820
+ els.bcInput.focus();
6807
6821
  bcLine('t-cmd', 'code> ' + msg);
6808
6822
  bcHideTodos(); /* yeni sorgu = eski todo list temizlenir; agent yeniden basacak */
6809
6823
  bcSetBusy(true);
@@ -6830,9 +6844,13 @@ function bcRunCurrent() {
6830
6844
  });
6831
6845
  }
6832
6846
 
6833
- if (els.bcInput) els.bcInput.addEventListener('keydown', (e) => {
6834
- if (e.key === 'Enter') { e.preventDefault(); bcRunCurrent(); }
6835
- });
6847
+ if (els.bcInput) {
6848
+ els.bcInput.addEventListener('input', bcInputResize);
6849
+ els.bcInput.addEventListener('keydown', (e) => {
6850
+ /* Enter gönderir, Shift+Enter alt satıra iner (klasik chat input'u) */
6851
+ if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); bcRunCurrent(); }
6852
+ });
6853
+ }
6836
6854
  if (els.bcStop) els.bcStop.addEventListener('click', () => beast.beastcodeStop().catch(() => {}));
6837
6855
  if (els.bcClear) els.bcClear.addEventListener('click', () => {
6838
6856
  els.bcOut.innerHTML = '';
@@ -974,13 +974,12 @@ body.term-open #settingsOverlay { right: var(--tw, 520px); }
974
974
  user-select: none;
975
975
  }
976
976
  .diff-code { flex: 1; padding-right: 10px; }
977
- /* kırmızı: silinen/eski (sol) — yeşil: eklenen/yeni (sağ) */
978
- .diff-line.del { background: rgba(239, 68, 68, 0.13); }
979
- .diff-line.del .diff-code { color: #fca5a5; }
980
- .diff-line.del .diff-num { color: #f87171; opacity: 0.8; }
981
- .diff-line.add { background: rgba(34, 197, 94, 0.12); }
982
- .diff-line.add .diff-code { color: #86efac; }
983
- .diff-line.add .diff-num { color: #4ade80; opacity: 0.8; }
977
+ /* kırmızı: silinen/eski (sol) — yeşil: eklenen/yeni (sağ)
978
+ YAZI rengi normal kalır (siyah) yalnız ARKA PLAN renkli */
979
+ .diff-line.del { background: rgba(239, 68, 68, 0.18); }
980
+ .diff-line.del .diff-code, .diff-line.del .diff-num { color: var(--text); }
981
+ .diff-line.add { background: rgba(34, 197, 94, 0.2); }
982
+ .diff-line.add .diff-code, .diff-line.add .diff-num { color: var(--text); }
984
983
  .diff-line.ctx .diff-code { color: var(--muted); }
985
984
  .diff-line.space { background: rgba(128, 128, 128, 0.06); }
986
985
  .diff-more {
@@ -2218,13 +2217,15 @@ body.ide-mode #bcPanel { display: flex; }
2218
2217
  #bcInputRow {
2219
2218
  flex: none;
2220
2219
  display: flex;
2221
- align-items: center;
2220
+ align-items: flex-end;
2222
2221
  gap: 6px;
2223
2222
  padding: 10px 12px;
2224
2223
  border-top: 1px solid var(--border);
2225
2224
  background: var(--panel);
2226
2225
  }
2227
- #bcPrompt { color: var(--accent); font-family: Consolas, monospace; font-size: 12px; font-weight: 700; flex: none; }
2226
+ #bcPrompt { color: var(--accent); font-family: Consolas, monospace; font-size: 12px; font-weight: 700; flex: none; padding-bottom: 7px; }
2227
+ /* otomatik büyüyen chat input'u: satır sonunda alt satıra iner, alan açılır;
2228
+ tavanı (140px ≈ 6 satır) aşarsa kendi içinde scroll'a döner */
2228
2229
  #bcInput {
2229
2230
  flex: 1;
2230
2231
  min-width: 0;
@@ -2236,7 +2237,13 @@ body.ide-mode #bcPanel { display: flex; }
2236
2237
  font-family: Consolas, monospace;
2237
2238
  font-size: 12.5px;
2238
2239
  outline: none;
2240
+ resize: none;
2241
+ overflow-y: hidden;
2242
+ max-height: 140px;
2243
+ line-height: 1.45;
2244
+ display: block;
2239
2245
  }
2246
+ #bcInput.expand { overflow-y: auto; }
2240
2247
  #bcInput:focus { border-color: var(--accent); }
2241
2248
  #bcStop {
2242
2249
  flex: none;
@@ -2248,6 +2255,7 @@ body.ide-mode #bcPanel { display: flex; }
2248
2255
  font-size: 11px;
2249
2256
  padding: 4px 8px;
2250
2257
  line-height: 1;
2258
+ margin-bottom: 3px;
2251
2259
  }
2252
2260
  #bcStop[hidden] { display: none; }
2253
2261
  #bcStop:hover { border-color: var(--err); }