beast-agent 1.0.1 → 1.1.1
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/src/agent/engine.js +46 -0
- package/src/main.js +20 -0
- package/src/preload.js +1 -0
- package/src/renderer/renderer.js +45 -2
package/package.json
CHANGED
package/src/agent/engine.js
CHANGED
|
@@ -1333,6 +1333,7 @@ class Engine {
|
|
|
1333
1333
|
'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.\n' +
|
|
1334
1334
|
'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.\n' +
|
|
1335
1335
|
'5) RAPOR: 1-3 satır — ne değişti + doğrulama sonucu (ör. "npm test ✓ 154/154"). Uzun açıklama yok.\n' +
|
|
1336
|
+
'CANLI ÖNİZLEME: web sitesi/app üretirsen son adımda ÇALIŞIR halde bırak (dev server ayakta ya da index.html yazılmış) — panel iş bitince ürettiğin şeyi dahili tarayıcıda otomatik canlı açar.\n' +
|
|
1336
1337
|
'HIZ KURALLARI:\n' +
|
|
1337
1338
|
'- Kodu ve dosyaları DOĞRUDAN write_file ile yaz; basit dosya oluşturma/düzenleme için Python scripti yazma; python_run yalnız gerçek hesap/veri işleme gerekiyorsa.\n' +
|
|
1338
1339
|
'- Bağımsız araç çağrılarını AYNI TURDA paralel ver (birden çok read_file tek turda).\n' +
|
|
@@ -2786,6 +2787,9 @@ class Engine {
|
|
|
2786
2787
|
let usageTotal = 0; // en yüksek görülen total_tokens — compaction tetiği
|
|
2787
2788
|
let compacted = false; // run başına en fazla 1 compaction
|
|
2788
2789
|
const recentSigs = []; // doom-loop dedektörü: son araç imzaları
|
|
2790
|
+
/* Beast Code canlı önizleme: run boyunca üretilen eserleri topla —
|
|
2791
|
+
iş bitince dahili tarayıcıda CANLI açılır (site/dev server/HTML) */
|
|
2792
|
+
const bcArtifacts = session.bcCode ? { html: [], serverUrl: null } : null;
|
|
2789
2793
|
for (let turn = 0; turn < MAX_TURNS; turn++) {
|
|
2790
2794
|
/* SÜRE SINIRI YOK — ama sonsuz tur da yok: bg ajan son 3 tura gelirken
|
|
2791
2795
|
"raporu yaz ve bitir" uyarısı alır; MAX_TURNS sert tavan olarak kalır. */
|
|
@@ -2872,6 +2876,20 @@ class Engine {
|
|
|
2872
2876
|
this._clearCrash();
|
|
2873
2877
|
this._maybeCompact(sid);
|
|
2874
2878
|
this._pruneSession(session); // opencode port: eski araç çıktıları temizlenir (fork edilen prune)
|
|
2879
|
+
/* Beast Code canlı önizleme: iş bitince üretilen site/app dahili
|
|
2880
|
+
tarayıcıda otomatik açılır (dev server öncelikli, sonra HTML) */
|
|
2881
|
+
if (bcArtifacts && (bcArtifacts.serverUrl || bcArtifacts.html.length)) {
|
|
2882
|
+
const url =
|
|
2883
|
+
bcArtifacts.serverUrl ||
|
|
2884
|
+
'file:///' +
|
|
2885
|
+
path
|
|
2886
|
+
.resolve(
|
|
2887
|
+
this._sessionWorkspace(sid),
|
|
2888
|
+
bcArtifacts.html[bcArtifacts.html.length - 1]
|
|
2889
|
+
)
|
|
2890
|
+
.replace(/\\/g, '/');
|
|
2891
|
+
emit({ type: 'bc-preview', url });
|
|
2892
|
+
}
|
|
2875
2893
|
emit({ type: 'done', usage: res.usage || null, meta: res.meta || null });
|
|
2876
2894
|
this._bgFinish(sid, 'done');
|
|
2877
2895
|
this.flushPendingReports(sid);
|
|
@@ -2920,6 +2938,34 @@ class Engine {
|
|
|
2920
2938
|
} else {
|
|
2921
2939
|
out = await this._execTool(name, args, ctrl.signal, sid);
|
|
2922
2940
|
}
|
|
2941
|
+
/* Beast Code eser takibi: yazılan HTML + başlatılan dev server */
|
|
2942
|
+
if (bcArtifacts) {
|
|
2943
|
+
try {
|
|
2944
|
+
if (
|
|
2945
|
+
(name === 'write_file' || name === 'edit_file') &&
|
|
2946
|
+
args && args.path && /\.html?$/i.test(String(args.path))
|
|
2947
|
+
) {
|
|
2948
|
+
bcArtifacts.html.push(String(args.path));
|
|
2949
|
+
}
|
|
2950
|
+
if (name === 'run_command') {
|
|
2951
|
+
const cmdStr = String((args && args.command) || '');
|
|
2952
|
+
const hay = cmdStr + '\n' + String(out || '').slice(0, 6000);
|
|
2953
|
+
const m = /https?:\/\/(?:localhost|127\.0\.0\.1)(?::\d{2,5})?[^\s'"<>]*/i.exec(hay);
|
|
2954
|
+
if (m) {
|
|
2955
|
+
bcArtifacts.serverUrl = m[0].replace(/[)\].,;:'"]+$/, '');
|
|
2956
|
+
} else {
|
|
2957
|
+
let port = 0;
|
|
2958
|
+
const hs = /python\s+-m\s+http\.server(?:[^\n]*?(\d{2,5}))?/i.exec(cmdStr);
|
|
2959
|
+
if (hs) port = Number(hs[1]) || 8000;
|
|
2960
|
+
else if (/\bvite\b/i.test(cmdStr)) port = 5173;
|
|
2961
|
+
else if (/\bnext dev\b/i.test(cmdStr)) port = 3000;
|
|
2962
|
+
else if (/\bng serve\b/i.test(cmdStr)) port = 4200;
|
|
2963
|
+
else if (/\b(npm (run )?(dev|start)|npx serve|live-server)\b/i.test(cmdStr)) port = 3000;
|
|
2964
|
+
if (port) bcArtifacts.serverUrl = 'http://localhost:' + port;
|
|
2965
|
+
}
|
|
2966
|
+
}
|
|
2967
|
+
} catch {}
|
|
2968
|
+
}
|
|
2923
2969
|
// Ekran görüntüsü gibi araçlar görseli sonraki tura enjekte eder
|
|
2924
2970
|
let injectedImage = null;
|
|
2925
2971
|
try {
|
package/src/main.js
CHANGED
|
@@ -5607,6 +5607,26 @@ ipcMain.handle('ide:preview', () => { try {
|
|
|
5607
5607
|
}
|
|
5608
5608
|
});
|
|
5609
5609
|
|
|
5610
|
+
/* BEAST CODE otomatik canlı önizleme: iş bitince üretilen site/app dahili
|
|
5611
|
+
tarayıcıda GÖRÜNÜR açılır. Yalnız localhost + file:// kabul edilir —
|
|
5612
|
+
dış adresler güvenlik için reddedilir. */
|
|
5613
|
+
ipcMain.handle('ide:previewUrl', (_e, url) => {
|
|
5614
|
+
try {
|
|
5615
|
+
const u = String(url || '');
|
|
5616
|
+
const okUrl =
|
|
5617
|
+
/^https?:\/\/(?:localhost|127\.0\.0\.1)(?::\d{2,5})?(?:\/|$)/i.test(u) ||
|
|
5618
|
+
/^file:\/\/\//i.test(u);
|
|
5619
|
+
if (!okUrl) return { ok: false, error: 'yalnız localhost/file:// adresleri önizlenebilir' };
|
|
5620
|
+
/* forceVisible: preview'a basmaya gerek kalmasın — otomatik ve GÖRÜNÜR açılır */
|
|
5621
|
+
setBrowserOpen(true, true);
|
|
5622
|
+
browser.view.webContents.loadURL(u).catch(() => {});
|
|
5623
|
+
browserEmit({ open: true, width: browser.width, url: u });
|
|
5624
|
+
return { ok: true, url: u };
|
|
5625
|
+
} catch (e) {
|
|
5626
|
+
return { ok: false, error: String((e && e.message) || e) };
|
|
5627
|
+
}
|
|
5628
|
+
});
|
|
5629
|
+
|
|
5610
5630
|
ipcMain.handle('custom:set', (_e, list) => {
|
|
5611
5631
|
settings.customProviders = Array.isArray(list) ? list : [];
|
|
5612
5632
|
saveSettings();
|
package/src/preload.js
CHANGED
|
@@ -179,6 +179,7 @@ contextBridge.exposeInMainWorld('beast', {
|
|
|
179
179
|
ideWrite: (rel, content) => ipcRenderer.invoke('ide:write', { rel, content }),
|
|
180
180
|
idePreview: () => ipcRenderer.invoke('ide:preview'),
|
|
181
181
|
idePreviewFile: (rel) => ipcRenderer.invoke('ide:previewFile', rel),
|
|
182
|
+
idePreviewUrl: (url) => ipcRenderer.invoke('ide:previewUrl', url),
|
|
182
183
|
ideDelete: (rel) => ipcRenderer.invoke('ide:delete', rel),
|
|
183
184
|
onWaEvent: (cb) => ipcRenderer.on('wa:event', (_e, ev) => cb(ev)),
|
|
184
185
|
onEvent: (cb) => ipcRenderer.on('agent:event', (_e, ev) => cb(ev)),
|
package/src/renderer/renderer.js
CHANGED
|
@@ -5828,6 +5828,21 @@ async function renderFileTree() {
|
|
|
5828
5828
|
await build('', 0, tree);
|
|
5829
5829
|
}
|
|
5830
5830
|
|
|
5831
|
+
/* Ağaç otomatik tazeleme: ajan dosya/klasör ürettikçe soldaki panel KENDİ
|
|
5832
|
+
kendisi yenilenir — elle yenileme yok. Açık klasörler (ideState.open)
|
|
5833
|
+
korunur; debounce paralel araç patlamalarını tek çizime indirir. */
|
|
5834
|
+
let ideTreeTimer = null;
|
|
5835
|
+
function ideRefreshTree() {
|
|
5836
|
+
if (ideTreeTimer) return;
|
|
5837
|
+
ideTreeTimer = setTimeout(() => {
|
|
5838
|
+
ideTreeTimer = null;
|
|
5839
|
+
try {
|
|
5840
|
+
ideState.cache.clear();
|
|
5841
|
+
renderFileTree().catch(() => {});
|
|
5842
|
+
} catch {}
|
|
5843
|
+
}, 600);
|
|
5844
|
+
}
|
|
5845
|
+
|
|
5831
5846
|
/* ---------- sekmeli kod editörü (VS Code düzeni) ----------
|
|
5832
5847
|
Dosya tıklaması MODAL değil, codePane içinde SEKME açar.
|
|
5833
5848
|
Yanında Beast Code chat'i, onun sağındaki preview tarayıcı durur. */
|
|
@@ -6278,6 +6293,25 @@ function bcRefreshPreview() {
|
|
|
6278
6293
|
beast.idePreview().catch(() => {});
|
|
6279
6294
|
}
|
|
6280
6295
|
|
|
6296
|
+
/* BEAST CODE canlı önizleme: engine iş sonunda eser tespit ederse
|
|
6297
|
+
(dev server / HTML) dahili tarayıcı otomatik GÖRÜNÜR açılır —
|
|
6298
|
+
kullanıcı preview tuşuna basmak zorunda kalmaz */
|
|
6299
|
+
function bcAutoPreview(url) {
|
|
6300
|
+
const u = String(url || '');
|
|
6301
|
+
if (
|
|
6302
|
+
!u ||
|
|
6303
|
+
!(
|
|
6304
|
+
/^https?:\/\/(?:localhost|127\.0\.0\.1)(?::\d{2,5})?(?:\/|$)/i.test(u) ||
|
|
6305
|
+
/^file:\/\/\//i.test(u)
|
|
6306
|
+
)
|
|
6307
|
+
) {
|
|
6308
|
+
return;
|
|
6309
|
+
}
|
|
6310
|
+
bcPrevAt = Date.now(); /* ardından gelen done/idle çift yenilemesin */
|
|
6311
|
+
beast.idePreviewUrl(u).catch(() => {});
|
|
6312
|
+
bcLine('t-dim', '[canlı önizleme açıldı — ' + u + ']');
|
|
6313
|
+
}
|
|
6314
|
+
|
|
6281
6315
|
/* ---------- Beast Code araç kutuları ----------
|
|
6282
6316
|
Ard arda gelen araç çağrıları TEK kutuda toplanır. Kural: engine mesajı
|
|
6283
6317
|
tool_calls İÇERİYORSA (iş turu) grup AÇIK kalır — aradaki ara yazılar kutu
|
|
@@ -6446,8 +6480,8 @@ function bcIngest(ev) {
|
|
|
6446
6480
|
break;
|
|
6447
6481
|
case 'tool-start':
|
|
6448
6482
|
bcToolBoxStart(ev.callId, ev.name, ev.args);
|
|
6449
|
-
/* ajan dosya yazarsa açık IDE sekmesini izlemeye al */
|
|
6450
|
-
if (ev.name === 'write_file' && ev.args && ev.args.path) codeWriteWatch.set(ev.callId, ev.args.path);
|
|
6483
|
+
/* ajan dosya yazarsa/editlerse açık IDE sekmesini izlemeye al */
|
|
6484
|
+
if ((ev.name === 'write_file' || ev.name === 'edit_file') && ev.args && ev.args.path) codeWriteWatch.set(ev.callId, ev.args.path);
|
|
6451
6485
|
break;
|
|
6452
6486
|
case 'tool-end':
|
|
6453
6487
|
bcToolBoxEnd(ev.callId, ev.ok, ev.result);
|
|
@@ -6456,6 +6490,14 @@ function bcIngest(ev) {
|
|
|
6456
6490
|
codeWriteWatch.delete(ev.callId);
|
|
6457
6491
|
codeReloadIfOpen(wp);
|
|
6458
6492
|
}
|
|
6493
|
+
/* dosya/klasör üreten araçlardan sonra soldaki ağaç otomatik tazelensin */
|
|
6494
|
+
if (ev.name === 'write_file' || ev.name === 'edit_file' || ev.name === 'run_command' || ev.name === 'python_run') {
|
|
6495
|
+
ideRefreshTree();
|
|
6496
|
+
}
|
|
6497
|
+
break;
|
|
6498
|
+
case 'bc-preview':
|
|
6499
|
+
/* iş bitince üretilen site/app dahili tarayıcıda CANLI açılır */
|
|
6500
|
+
bcAutoPreview(ev.url);
|
|
6459
6501
|
break;
|
|
6460
6502
|
case 'bc-mode':
|
|
6461
6503
|
/* OpenCode disiplini çalışma modu: başlıkta rozet + panelde bilgi satırı */
|
|
@@ -6472,6 +6514,7 @@ function bcIngest(ev) {
|
|
|
6472
6514
|
bcSetBusy(false);
|
|
6473
6515
|
/* iptal/durdurma SEBEBİ panelde de görünür */
|
|
6474
6516
|
bcLine(ev.aborted ? 't-err' : 't-dim', ev.aborted ? '[durduruldu — sebep: ' + (ev.reason || 'sebep belirtilmedi') + ']' : '(tamamlandı)');
|
|
6517
|
+
ideRefreshTree(); /* son güvenlik tazelemesi — izlenmeyen yoldan üretilen dosyalar da düşsün */
|
|
6475
6518
|
bcRefreshPreview();
|
|
6476
6519
|
if (ideModeOn() && els.bcInput) els.bcInput.focus();
|
|
6477
6520
|
break;
|