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 +1 -1
- package/scripts/release.js +11 -1
- package/src/agent/engine.js +41 -6
- package/src/agent/tools.js +23 -1
- package/src/renderer/index.html +1 -1
- package/src/renderer/renderer.js +21 -3
- package/src/renderer/style.css +17 -9
package/package.json
CHANGED
package/scripts/release.js
CHANGED
|
@@ -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
|
-
|
|
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);
|
package/src/agent/engine.js
CHANGED
|
@@ -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
|
|
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
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
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 (
|
|
1663
|
+
if (content !== null) rest.content = content;
|
|
1629
1664
|
flat[k] = rest;
|
|
1630
1665
|
}
|
|
1631
1666
|
}
|
package/src/agent/tools.js
CHANGED
|
@@ -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 =
|
|
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) {
|
package/src/renderer/index.html
CHANGED
|
@@ -133,7 +133,7 @@
|
|
|
133
133
|
<div id="bcStatus" hidden></div>
|
|
134
134
|
<div id="bcInputRow">
|
|
135
135
|
<span id="bcPrompt">code></span>
|
|
136
|
-
<
|
|
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">■︎</button>
|
|
138
138
|
</div>
|
|
139
139
|
</div>
|
package/src/renderer/renderer.js
CHANGED
|
@@ -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)
|
|
6834
|
-
|
|
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 = '';
|
package/src/renderer/style.css
CHANGED
|
@@ -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
|
-
|
|
979
|
-
.diff-line.del
|
|
980
|
-
.diff-line.del .diff-num { color:
|
|
981
|
-
.diff-line.add { background: rgba(34, 197, 94, 0.
|
|
982
|
-
.diff-line.add .diff-code { color:
|
|
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:
|
|
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); }
|