beast-agent 0.29.0 → 1.0.0
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 +6 -3
- package/src/agent/engine.js +554 -33
- package/src/agent/llm.js +52 -3
- package/src/agent/obscura.js +26 -10
- package/src/agent/skills.js +87 -29
- package/src/agent/tools.js +519 -7
- package/src/main.js +48 -7
- package/src/preload.js +2 -0
- package/src/renderer/i18n.js +11 -7
- package/src/renderer/index.html +5 -2
- package/src/renderer/renderer.js +246 -8
- package/src/renderer/style.css +60 -4
- package/.env.example +0 -8
- package/config.example.yaml +0 -39
- package/eng.traineddata +0 -0
- package/scripts/fix-electron.js +0 -126
- package/scripts/release.js +0 -121
- package/scripts/swap-electron.js +0 -40
- package/store/skills.json +0 -5
- package/tests/approval.test.js +0 -56
- package/tests/bg-jobs.test.js +0 -379
- package/tests/bots-name.test.js +0 -42
- package/tests/bus.test.js +0 -46
- package/tests/computeruse-context.test.js +0 -69
- package/tests/cron.test.js +0 -95
- package/tests/engine.test.js +0 -203
- package/tests/eval.test.js +0 -91
- package/tests/fallout.test.js +0 -188
- package/tests/llm.test.js +0 -205
- package/tests/memory.test.js +0 -33
- package/tests/memoryloop.test.js +0 -26
- package/tests/notegen.test.js +0 -63
- package/tests/obscura.test.js +0 -124
- package/tests/owner.test.js +0 -32
- package/tests/python.test.js +0 -76
- package/tests/research.test.js +0 -116
- package/tests/scenarios.json +0 -81
- package/tests/sessioncode.test.js +0 -50
- package/tests/setup.js +0 -9
- package/tests/tokens.test.js +0 -42
- package/tests/tools.test.js +0 -84
- package/tests/usage.test.js +0 -44
- package/tests/v11.test.js +0 -76
- package/tests/watchers.test.js +0 -206
- package/tests/watext.test.js +0 -53
- package/tests/whatsapp.test.js +0 -103
- package/tests/wherewasi.test.js +0 -40
package/src/preload.js
CHANGED
|
@@ -76,6 +76,8 @@ contextBridge.exposeInMainWorld('beast', {
|
|
|
76
76
|
obscuraSetEnabled: (v) => ipcRenderer.invoke('obscura:setEnabled', v),
|
|
77
77
|
searchOrderGet: () => ipcRenderer.invoke('searchorder:get'),
|
|
78
78
|
searchOrderSet: (chain) => ipcRenderer.invoke('searchorder:set', chain),
|
|
79
|
+
sessionsOrderGet: () => ipcRenderer.invoke('sessions:order:get'),
|
|
80
|
+
sessionsOrderSet: (order) => ipcRenderer.invoke('sessions:order:set', order),
|
|
79
81
|
tinyfishGet: () => ipcRenderer.invoke('tinyfish:get'),
|
|
80
82
|
tinyfishSet: (key) => ipcRenderer.invoke('tinyfish:set', key),
|
|
81
83
|
tinyfishClear: () => ipcRenderer.invoke('tinyfish:clear'),
|
package/src/renderer/i18n.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
'use strict';
|
|
1
|
+
'use strict';
|
|
2
2
|
|
|
3
3
|
/* Hafif i18n (TR/EN):
|
|
4
4
|
- data-i18n → textContent
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
tipNet: 'İnternet durumu',
|
|
22
22
|
tip_net_online: 'İnternet: bağlı',
|
|
23
23
|
tip_net_offline: 'İnternet: yok — bağlantı dönünce işler otomatik sürer',
|
|
24
|
+
sess_drag: 'Sürükleyerek sırayı değiştir',
|
|
24
25
|
tipWatch: 'İzleyiciler (Watchers)',
|
|
25
26
|
tipCron: 'Cron Görevler',
|
|
26
27
|
tip_light: 'Açık tema',
|
|
@@ -262,12 +263,13 @@
|
|
|
262
263
|
us_where_off_toast: 'Açılış özeti kapandı',
|
|
263
264
|
ws_calls: 'çağrı',
|
|
264
265
|
ws_token: 'token',
|
|
266
|
+
td_hide: 'Görev listesini gizle (yeni güncellemede yine görünür)',
|
|
265
267
|
ws_h2: 'Web Arama',
|
|
266
268
|
ws_sub: 'Arama zinciri: 1) dahili tarayıcı (direk Google) 2) Obscura (stealth headless → DuckDuckGo) 3) TinyFish (anahtar varsa) 4) python çoklu-motor (ddgs / DDG+Bing+Mojeek) — otomatik. Sıra ve aç/kapa aşağıdan değiştirilir.',
|
|
267
269
|
oc_h2: 'Obscura (Stealth Tarayıcı)',
|
|
268
|
-
oc_sub: 'Rust tabanlı gizli headless tarayıcı (anti-detect + V8, Chromium\u2019suz).
|
|
270
|
+
oc_sub: 'Rust tabanlı gizli headless tarayıcı (anti-detect + V8, Chromium\u2019suz). Paket içinde hazır gelir; ilk açılışta %APPDATA%\\beast\\obscura\'ya açılır; DuckDuckGo aramasını bot korumasını aşarak yapar.',
|
|
269
271
|
oc_status_ok: 'Obscura kurulu ve hazır.',
|
|
270
|
-
oc_status_missing: 'Obscura
|
|
272
|
+
oc_status_missing: 'Obscura paket içinde hazır — ilk açılışta otomatik kurulur.',
|
|
271
273
|
oc_install: 'Kur / Güncelle',
|
|
272
274
|
oc_install_running: 'Kuruluyor…',
|
|
273
275
|
oc_installing: 'İndiriliyor… (≈74 MB, bağlantıya göre birkaç dakika)',
|
|
@@ -323,7 +325,7 @@
|
|
|
323
325
|
us_where_off_toast: 'Açılış özeti kapandı',
|
|
324
326
|
ws_h2: 'Web Arama',
|
|
325
327
|
oc_status_ok: 'Obscura kurulu ve hazır.',
|
|
326
|
-
oc_status_missing: 'Obscura
|
|
328
|
+
oc_status_missing: 'Obscura paket içinde hazır — ilk açılışta otomatik kurulur.',
|
|
327
329
|
ws_save: 'Kaydet',
|
|
328
330
|
ws_clear: 'Anahtarı Sil',
|
|
329
331
|
ws_key_note: 'Anahtar maskeli tutulur; yenisini yazıp kaydettiğinde eskisinin yerine geçer. Boş kaydet: mevcut anahtar korunur.',
|
|
@@ -575,6 +577,7 @@
|
|
|
575
577
|
tipNet: 'Internet status',
|
|
576
578
|
tip_net_online: 'Internet: connected',
|
|
577
579
|
tip_net_offline: 'Internet: offline — work resumes automatically once the connection returns',
|
|
580
|
+
sess_drag: 'Drag to reorder',
|
|
578
581
|
tipWatch: 'Watchers',
|
|
579
582
|
tipCron: 'Cron Jobs',
|
|
580
583
|
tip_light: 'Light theme',
|
|
@@ -815,12 +818,13 @@
|
|
|
815
818
|
us_where_off_toast: 'Startup summary off',
|
|
816
819
|
ws_calls: 'calls',
|
|
817
820
|
ws_token: 'tokens',
|
|
821
|
+
td_hide: 'Hide todo list (reappears on next update)',
|
|
818
822
|
ws_h2: 'Web Search',
|
|
819
823
|
ws_sub: 'Search chain: 1) built-in browser (direct Google) 2) Obscura (stealth headless → DuckDuckGo) 3) TinyFish (if a key is set) 4) python multi-engine (ddgs / DDG+Bing+Mojeek) — automatic. Order and on/off are editable below.',
|
|
820
824
|
oc_h2: 'Obscura (Stealth Browser)',
|
|
821
|
-
oc_sub: 'Rust-based stealth headless browser (anti-detect + V8, no Chromium).
|
|
825
|
+
oc_sub: 'Rust-based stealth headless browser (anti-detect + V8, no Chromium). It ships inside the package and is extracted to %APPDATA%\\beast\\obscura at first launch; it searches DuckDuckGo past bot protection.',
|
|
822
826
|
oc_status_ok: 'Obscura is installed and ready.',
|
|
823
|
-
oc_status_missing: 'Obscura
|
|
827
|
+
oc_status_missing: 'Obscura ships inside the package — it is extracted automatically at first launch.',
|
|
824
828
|
oc_install: 'Install / Update',
|
|
825
829
|
oc_install_running: 'Installing…',
|
|
826
830
|
oc_installing: 'Downloading… (≈74 MB, may take a few minutes)',
|
|
@@ -938,7 +942,7 @@
|
|
|
938
942
|
us_where_off_toast: 'Startup summary off',
|
|
939
943
|
ws_h2: 'Web Search',
|
|
940
944
|
oc_status_ok: 'Obscura is installed and ready.',
|
|
941
|
-
oc_status_missing: 'Obscura
|
|
945
|
+
oc_status_missing: 'Obscura ships inside the package — it is extracted automatically at first launch.',
|
|
942
946
|
ws_save: 'Save',
|
|
943
947
|
ws_clear: 'Delete Key',
|
|
944
948
|
ws_key_note: 'Key is kept masked; saving a new one replaces the old. Save empty: existing key kept.',
|
package/src/renderer/index.html
CHANGED
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
<button id="storeBtn" title="Skills Store" data-i18n-title="tipStore"><svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 7h16l-1.3 12.1a2 2 0 0 1-2 1.9H7.3a2 2 0 0 1-2-1.9L4 7z"/><path d="M8 10V6a4 4 0 0 1 8 0v4"/></svg></button>
|
|
42
42
|
<button id="gitBtn" title="GitHub Trending" data-i18n-title="tipGithub"><svg viewBox="0 0 24 24" width="15" height="15" fill="currentColor" aria-hidden="true"><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg></button>
|
|
43
43
|
<button id="ideBtn" title="IDE Modu" data-i18n-title="tipIde"><svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M8 6l-5 6 5 6"/><path d="M16 6l5 6-5 6"/><path d="M13.5 4l-3 16"/></svg></button>
|
|
44
|
+
<span id="netDot" class="net-on" title="İnternet: bağlı" data-i18n-title="tipNet"><svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 8.82a15 15 0 0 1 20 0"/><path d="M5 12.85a10 10 0 0 1 14 0"/><path d="M8.53 16.11a6 6 0 0 1 6.95 0"/><line x1="12" y1="20" x2="12.01" y2="20"/><line class="net-slash" x1="4" y1="4" x2="20" y2="20"/></svg></span>
|
|
44
45
|
</div>
|
|
45
46
|
</aside>
|
|
46
47
|
|
|
@@ -77,7 +78,6 @@
|
|
|
77
78
|
<button id="termCBtn" class="dd-btn dd-icon-btn" title="CMD terminali" data-i18n-title="tipTermC">❯︎</button>
|
|
78
79
|
<button id="browserBtn" class="dd-btn dd-icon-btn" title="Dahili tarayıcı" data-i18n-title="tipBrowser">⧉</button>
|
|
79
80
|
<button id="eyeBtn" class="dd-btn dd-icon-btn" title="Ajan tarayıcısı görünür/gizli — göz açıkken aramalar panelde izlenir, kapalıyken gizli çalışır" data-i18n-title="tipEye"><svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7-10-7-10-7z"/><circle cx="12" cy="12" r="3"/><line class="eye-slash" x1="4" y1="4" x2="20" y2="20"/></svg></button>
|
|
80
|
-
<span id="netDot" class="dd-btn dd-icon-btn net-on" title="İnternet: bağlı" data-i18n-title="tipNet"><svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12.55a11 11 0 0 1 14.08 0"/><path d="M8.53 16.11a6 6 0 0 1 6.95 0"/><line x1="12" y1="20" x2="12.01" y2="20"/><line class="net-slash" x1="4" y1="4" x2="20" y2="20"/></svg></span>
|
|
81
81
|
<div class="drag-spacer"></div>
|
|
82
82
|
</header>
|
|
83
83
|
|
|
@@ -112,7 +112,10 @@
|
|
|
112
112
|
<code id="codePath" title="">—</code>
|
|
113
113
|
<button id="codeSave" title="Kaydet (Ctrl+S)">Kaydet</button>
|
|
114
114
|
</div>
|
|
115
|
-
<
|
|
115
|
+
<div id="codeBody">
|
|
116
|
+
<div id="codeGutter" aria-hidden="true"></div>
|
|
117
|
+
<textarea id="codeTa" spellcheck="false" wrap="off"></textarea>
|
|
118
|
+
</div>
|
|
116
119
|
</section>
|
|
117
120
|
|
|
118
121
|
<div id="ideSplit" title="Sürükleyerek boyutlandır"></div>
|
package/src/renderer/renderer.js
CHANGED
|
@@ -78,6 +78,7 @@ const els = {
|
|
|
78
78
|
bcTodoWrap: $('#bcTodoWrap'),
|
|
79
79
|
codeTabs: $('#codeTabs'),
|
|
80
80
|
codeTa: $('#codeTa'),
|
|
81
|
+
codeGutter: $('#codeGutter'),
|
|
81
82
|
codePath: $('#codePath'),
|
|
82
83
|
codeSave: $('#codeSave'),
|
|
83
84
|
ideRow: $('#ideRow'),
|
|
@@ -280,8 +281,14 @@ function renderTodos(items) {
|
|
|
280
281
|
})
|
|
281
282
|
.join('');
|
|
282
283
|
els.todoPanel.innerHTML =
|
|
283
|
-
`<div class="td-head"><span>GÖREVLER</span
|
|
284
|
+
`<div class="td-head"><span>GÖREVLER</span>` +
|
|
285
|
+
`<span class="td-right"><span class="td-count">${done}/${list.length}</span>` +
|
|
286
|
+
`<button class="td-x" title="${_t('td_hide')}">×</button></span></div>` + rows;
|
|
284
287
|
els.todoPanel.hidden = false;
|
|
288
|
+
/* X yalnız BU listeyi gizler — kalıcı kapanma yok: bir sonraki görev
|
|
289
|
+
güncellemesi (yeni görev eklendi / görev yapıldı) paneli yeniden gösterir */
|
|
290
|
+
const x = els.todoPanel.querySelector('.td-x');
|
|
291
|
+
if (x) x.addEventListener('click', () => { els.todoPanel.hidden = true; });
|
|
285
292
|
}
|
|
286
293
|
function setBusy(b) {
|
|
287
294
|
busy = b;
|
|
@@ -482,7 +489,41 @@ function finishToolCard(callId, ok, result) {
|
|
|
482
489
|
|
|
483
490
|
/* ---------------- sessions sidebar ---------------- */
|
|
484
491
|
|
|
492
|
+
/* sol panel sohbet listesi: kullanıcı ELLE sıralayabilir (sürükle-bırak).
|
|
493
|
+
sessionOrder: session id'lerinin tercih sırası — settings.json'da kalıcı.
|
|
494
|
+
Listede olmayan oturumlar engine sırasıyla (son mesaja göre) arkada gelir. */
|
|
495
|
+
let sessionOrder = [];
|
|
496
|
+
let sessionOrderLoaded = null;
|
|
497
|
+
function loadSessionOrder() {
|
|
498
|
+
if (!sessionOrderLoaded) {
|
|
499
|
+
sessionOrderLoaded = beast
|
|
500
|
+
.sessionsOrderGet()
|
|
501
|
+
.then((r) => { sessionOrder = (r && Array.isArray(r.order) ? r.order : []).map(String); })
|
|
502
|
+
.catch(() => {});
|
|
503
|
+
}
|
|
504
|
+
return sessionOrderLoaded;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
function reorderSessions(dragId, targetId) {
|
|
508
|
+
const idx = (id) => sessionOrder.indexOf(id);
|
|
509
|
+
const dp = idx(dragId);
|
|
510
|
+
const tp = idx(targetId);
|
|
511
|
+
sessionOrder = sessionOrder.filter((x) => x !== dragId);
|
|
512
|
+
const ti = sessionOrder.indexOf(targetId);
|
|
513
|
+
if (ti === -1) {
|
|
514
|
+
/* hedef hiç elle sıralanmamış: listeden görünür konumunu korumak mümkün değil — sona ekle */
|
|
515
|
+
sessionOrder.push(targetId, dragId);
|
|
516
|
+
} else if (dp !== -1 && dp < tp) {
|
|
517
|
+
sessionOrder.splice(ti + 1, 0, dragId); /* aşağı sürüklendi → hedefin ALTINA */
|
|
518
|
+
} else {
|
|
519
|
+
sessionOrder.splice(ti, 0, dragId); /* yukarı sürüklendi → hedefin ÜSTÜNE */
|
|
520
|
+
}
|
|
521
|
+
beast.sessionsOrderSet(sessionOrder).catch(() => {});
|
|
522
|
+
refreshSessions();
|
|
523
|
+
}
|
|
524
|
+
|
|
485
525
|
async function renderSessions(list) {
|
|
526
|
+
await loadSessionOrder();
|
|
486
527
|
let waSet = new Set();
|
|
487
528
|
let tgSet = new Set();
|
|
488
529
|
try {
|
|
@@ -492,13 +533,19 @@ async function renderSessions(list) {
|
|
|
492
533
|
tgSet = new Set(await beast.tgListSessions());
|
|
493
534
|
} catch {}
|
|
494
535
|
els.sessList.innerHTML = '';
|
|
536
|
+
/* elle sıra: sessionOrder'daki id'ler önde (o sırayla), diğerleri engine sırasıyla arkada */
|
|
537
|
+
const rank = new Map(sessionOrder.map((id, i) => [id, i]));
|
|
538
|
+
const withRank = list.map((s, i) => ({ s, r: rank.has(s.id) ? rank.get(s.id) : 1e6 + i }));
|
|
539
|
+
withRank.sort((a, b) => a.r - b.r);
|
|
495
540
|
/* aktif botun oturumları — botlar arası geçişte liste de o bota göre değişir.
|
|
496
541
|
KATI KURAL: her oturum yalnız BAĞLI OLDUĞU botun listesinde görünür;
|
|
497
542
|
bot kaydı olmayan (eski) oturumlar Beast (varsayılan sahip) altında görünür. */
|
|
498
|
-
for (const s of
|
|
543
|
+
for (const { s } of withRank) {
|
|
499
544
|
if ((s.botId || 'beast') !== activeBotId) continue;
|
|
500
545
|
const row = document.createElement('div');
|
|
501
546
|
row.className = 'sess' + (s.id === activeId ? ' active' : '');
|
|
547
|
+
row.title = _t('sess_drag');
|
|
548
|
+
row.draggable = true;
|
|
502
549
|
row.innerHTML =
|
|
503
550
|
(waSet.has(s.id) ? '<span class="sess-wa" title="WhatsApp">W</span>' : '') +
|
|
504
551
|
(tgSet.has(s.id) ? '<span class="sess-tg" title="Telegram">T</span>' : '') +
|
|
@@ -516,12 +563,40 @@ async function renderSessions(list) {
|
|
|
516
563
|
const created = await beast.createSession();
|
|
517
564
|
await openSession(created.id);
|
|
518
565
|
}
|
|
566
|
+
sessionOrder = sessionOrder.filter((x) => x !== s.id);
|
|
519
567
|
refreshSessions();
|
|
520
568
|
});
|
|
569
|
+
/* sürükle-bırak: yukarı/aşağı yer değiştirme */
|
|
570
|
+
row.addEventListener('dragstart', (e) => {
|
|
571
|
+
dragSid = s.id;
|
|
572
|
+
row.classList.add('dragging');
|
|
573
|
+
try { e.dataTransfer.effectAllowed = 'move'; e.dataTransfer.setData('text/plain', s.id); } catch {}
|
|
574
|
+
});
|
|
575
|
+
row.addEventListener('dragend', () => {
|
|
576
|
+
dragSid = null;
|
|
577
|
+
row.classList.remove('dragging');
|
|
578
|
+
els.sessList.querySelectorAll('.drag-over').forEach((x) => x.classList.remove('drag-over'));
|
|
579
|
+
});
|
|
580
|
+
row.addEventListener('dragover', (e) => {
|
|
581
|
+
if (!dragSid || dragSid === s.id) return;
|
|
582
|
+
e.preventDefault();
|
|
583
|
+
try { e.dataTransfer.dropEffect = 'move'; } catch {}
|
|
584
|
+
row.classList.add('drag-over');
|
|
585
|
+
});
|
|
586
|
+
row.addEventListener('dragleave', () => row.classList.remove('drag-over'));
|
|
587
|
+
row.addEventListener('drop', (e) => {
|
|
588
|
+
e.preventDefault();
|
|
589
|
+
row.classList.remove('drag-over');
|
|
590
|
+
if (!dragSid || dragSid === s.id) return;
|
|
591
|
+
reorderSessions(dragSid, s.id);
|
|
592
|
+
dragSid = null;
|
|
593
|
+
});
|
|
521
594
|
els.sessList.appendChild(row);
|
|
522
595
|
}
|
|
523
596
|
}
|
|
524
597
|
|
|
598
|
+
let dragSid = null;
|
|
599
|
+
|
|
525
600
|
async function refreshSessions() {
|
|
526
601
|
await renderSessions(await beast.listSessions());
|
|
527
602
|
renderBotCards(); // bot kartlarındaki numara/sayı etiketleri de tazelensin
|
|
@@ -816,7 +891,7 @@ async function renderWebSearchPane() {
|
|
|
816
891
|
'<h2>' + _t('oc_h2') + '</h2>' +
|
|
817
892
|
'<div class="sub">' + _t('oc_sub') + '</div>' +
|
|
818
893
|
'<div id="ocStatus" class="sub" style="text-align:left;margin-top:8px"></div>' +
|
|
819
|
-
'<label class="mem-label" style="display:flex;align-items:center;gap:8px;cursor:pointer">' +
|
|
894
|
+
'<label class="mem-label" style="display:flex;align-items:center;justify-content:center;gap:8px;cursor:pointer">' +
|
|
820
895
|
'<input id="ocEnabled" type="checkbox" style="width:auto" /> <span>' + _t('oc_enabled') + '</span></label>' +
|
|
821
896
|
'<div id="ocProg" class="oc-prog" hidden>' +
|
|
822
897
|
'<div class="oc-prog-bar"><div class="oc-prog-fill" style="width:0%"></div></div>' +
|
|
@@ -3831,11 +3906,18 @@ function onEvent(ev) {
|
|
|
3831
3906
|
addToolCard(ev.callId, ev.name, ev.args);
|
|
3832
3907
|
setStatus(ev.name + '…');
|
|
3833
3908
|
termAgentEvent(ev);
|
|
3909
|
+
/* ajan dosya yazarsa açık IDE sekmesini izlemeye al */
|
|
3910
|
+
if (ev.name === 'write_file' && ev.args && ev.args.path) codeWriteWatch.set(ev.callId, ev.args.path);
|
|
3834
3911
|
break;
|
|
3835
3912
|
case 'tool-end':
|
|
3836
3913
|
finishToolCard(ev.callId, ev.ok, ev.result);
|
|
3837
3914
|
setStatus('düşünüyor…');
|
|
3838
3915
|
termAgentEvent(ev);
|
|
3916
|
+
if (codeWriteWatch.has(ev.callId)) {
|
|
3917
|
+
const wp = codeWriteWatch.get(ev.callId);
|
|
3918
|
+
codeWriteWatch.delete(ev.callId);
|
|
3919
|
+
codeReloadIfOpen(wp);
|
|
3920
|
+
}
|
|
3839
3921
|
break;
|
|
3840
3922
|
case 'todos':
|
|
3841
3923
|
renderTodos(ev.todos);
|
|
@@ -5618,6 +5700,7 @@ async function setIdeMode(on) {
|
|
|
5618
5700
|
ideSplitRestore();
|
|
5619
5701
|
await loadIdeTree();
|
|
5620
5702
|
bcBanner();
|
|
5703
|
+
codeGutterRender(); /* dosya açık olmasa bile rakamlar görünür */
|
|
5621
5704
|
}
|
|
5622
5705
|
}
|
|
5623
5706
|
|
|
@@ -5749,9 +5832,103 @@ async function renderFileTree() {
|
|
|
5749
5832
|
Dosya tıklaması MODAL değil, codePane içinde SEKME açar.
|
|
5750
5833
|
Yanında Beast Code chat'i, onun sağındaki preview tarayıcı durur. */
|
|
5751
5834
|
|
|
5752
|
-
const codeTabs = []; /* { rel, content, dirty } */
|
|
5835
|
+
const codeTabs = []; /* { rel, content, dirty, base } — base: temiz (disk) içerik, diff bununla */
|
|
5753
5836
|
let codeActive = -1;
|
|
5754
5837
|
|
|
5838
|
+
/* ---------- editör gutter: satır numaraları + değişiklik işaretleri ---------- */
|
|
5839
|
+
/* base ↔ mevcut içerik diff'i: eklenen/değişen satırlar YEŞİL, silinenler
|
|
5840
|
+
kısmen/kırmızı çizgiyle (VS Code gutter stili). LCS; satır adedi aşılırsa
|
|
5841
|
+
bölge-bütününü değişmiş sayar (büyük dosyalarda takılmaz). */
|
|
5842
|
+
function codeDiffLines(baseText, curText) {
|
|
5843
|
+
const added = new Set();
|
|
5844
|
+
const dels = new Map();
|
|
5845
|
+
if (typeof baseText !== 'string') return { added, dels };
|
|
5846
|
+
const a = baseText.split('\n');
|
|
5847
|
+
const b = String(curText || '').split('\n');
|
|
5848
|
+
let p = 0;
|
|
5849
|
+
while (p < a.length && p < b.length && a[p] === b[p]) p++;
|
|
5850
|
+
let ea = a.length - 1;
|
|
5851
|
+
let eb = b.length - 1;
|
|
5852
|
+
while (ea >= p && eb >= p && a[ea] === b[eb]) { ea--; eb--; }
|
|
5853
|
+
const midA = a.slice(p, ea + 1);
|
|
5854
|
+
const midB = b.slice(p, eb + 1);
|
|
5855
|
+
const n = midA.length;
|
|
5856
|
+
const m = midB.length;
|
|
5857
|
+
if (!n && !m) return { added, dels };
|
|
5858
|
+
const pushDel = (at, count) => {
|
|
5859
|
+
if (!count) return;
|
|
5860
|
+
const line = Math.min(Math.max(1, at), b.length || 1);
|
|
5861
|
+
dels.set(line, (dels.get(line) || 0) + count);
|
|
5862
|
+
};
|
|
5863
|
+
if (n * m > 400000 || n > 1500 || m > 1500) {
|
|
5864
|
+
for (let k = 0; k < m; k++) added.add(p + k + 1);
|
|
5865
|
+
pushDel(p + m + 1, n);
|
|
5866
|
+
return { added, dels };
|
|
5867
|
+
}
|
|
5868
|
+
const w = m + 1;
|
|
5869
|
+
const dp = new Int32Array((n + 1) * w);
|
|
5870
|
+
for (let i = n - 1; i >= 0; i--) {
|
|
5871
|
+
for (let j = m - 1; j >= 0; j--) {
|
|
5872
|
+
dp[i * w + j] =
|
|
5873
|
+
midA[i] === midB[j]
|
|
5874
|
+
? dp[(i + 1) * w + j + 1] + 1
|
|
5875
|
+
: Math.max(dp[(i + 1) * w + j], dp[i * w + j + 1]);
|
|
5876
|
+
}
|
|
5877
|
+
}
|
|
5878
|
+
let i = 0;
|
|
5879
|
+
let j = 0;
|
|
5880
|
+
let pendingDel = 0;
|
|
5881
|
+
while (i < n && j < m) {
|
|
5882
|
+
if (midA[i] === midB[j]) {
|
|
5883
|
+
pushDel(p + j + 1, pendingDel);
|
|
5884
|
+
pendingDel = 0;
|
|
5885
|
+
i++; j++;
|
|
5886
|
+
} else if (dp[(i + 1) * w + j] >= dp[i * w + j + 1]) {
|
|
5887
|
+
pendingDel++; i++;
|
|
5888
|
+
} else {
|
|
5889
|
+
pushDel(p + j + 1, pendingDel);
|
|
5890
|
+
pendingDel = 0;
|
|
5891
|
+
added.add(p + j + 1);
|
|
5892
|
+
j++;
|
|
5893
|
+
}
|
|
5894
|
+
}
|
|
5895
|
+
while (i < n) { pendingDel++; i++; }
|
|
5896
|
+
while (j < m) {
|
|
5897
|
+
pushDel(p + j + 1, pendingDel);
|
|
5898
|
+
pendingDel = 0;
|
|
5899
|
+
added.add(p + j + 1);
|
|
5900
|
+
j++;
|
|
5901
|
+
}
|
|
5902
|
+
pushDel(p + m + 1, pendingDel);
|
|
5903
|
+
return { added, dels };
|
|
5904
|
+
}
|
|
5905
|
+
|
|
5906
|
+
function codeGutterRender() {
|
|
5907
|
+
const g = els.codeGutter;
|
|
5908
|
+
const ta = els.codeTa;
|
|
5909
|
+
if (!g || !ta) return;
|
|
5910
|
+
const hasFile = codeActive >= 0 && codeTabs[codeActive];
|
|
5911
|
+
const t = hasFile ? codeTabs[codeActive] : null;
|
|
5912
|
+
const diff = hasFile ? codeDiffLines(t.base, ta.value) : null;
|
|
5913
|
+
/* dosya açık olmasa bile rakamlar HEP görünür (boş editörde 50 satır iskeleti) */
|
|
5914
|
+
const count = hasFile
|
|
5915
|
+
? ta.value.split('\n').length
|
|
5916
|
+
: 50;
|
|
5917
|
+
let html = '';
|
|
5918
|
+
for (let i = 1; i <= count; i++) {
|
|
5919
|
+
const isAdd = diff && diff.added.has(i);
|
|
5920
|
+
const delN = diff && diff.dels.get(i);
|
|
5921
|
+
html +=
|
|
5922
|
+
`<div class="cl${isAdd ? ' add' : ''}${delN ? ' del' : ''}${hasFile ? '' : ' idle'}"` +
|
|
5923
|
+
(delN ? ` title="${delN} satır silindi"` : '') +
|
|
5924
|
+
`>${i}</div>`;
|
|
5925
|
+
}
|
|
5926
|
+
g.innerHTML = html;
|
|
5927
|
+
g.scrollTop = ta.scrollTop;
|
|
5928
|
+
}
|
|
5929
|
+
|
|
5930
|
+
let codeGutterTimer = null;
|
|
5931
|
+
|
|
5755
5932
|
function codeRenderTabs() {
|
|
5756
5933
|
const bar = els.codeTabs;
|
|
5757
5934
|
if (!bar) return;
|
|
@@ -5786,6 +5963,7 @@ function codeActivate(i) {
|
|
|
5786
5963
|
els.codeTa.value = '';
|
|
5787
5964
|
els.codePath.textContent = '\u2014';
|
|
5788
5965
|
codeRenderTabs();
|
|
5966
|
+
codeGutterRender();
|
|
5789
5967
|
return;
|
|
5790
5968
|
}
|
|
5791
5969
|
codeActive = i;
|
|
@@ -5794,6 +5972,7 @@ function codeActivate(i) {
|
|
|
5794
5972
|
els.codePath.textContent = t.rel;
|
|
5795
5973
|
els.codePath.title = (ideState.path || '') + '\\' + t.rel.replace(/\//g, '\\');
|
|
5796
5974
|
codeRenderTabs();
|
|
5975
|
+
codeGutterRender();
|
|
5797
5976
|
}
|
|
5798
5977
|
|
|
5799
5978
|
async function codeOpen(rel) {
|
|
@@ -5807,7 +5986,7 @@ async function codeOpen(rel) {
|
|
|
5807
5986
|
toast((r && r.error) || 'okunamad\u0131');
|
|
5808
5987
|
return;
|
|
5809
5988
|
}
|
|
5810
|
-
codeTabs.push({ rel, content: r.content || '', dirty: false });
|
|
5989
|
+
codeTabs.push({ rel, content: r.content || '', dirty: false, base: r.content || '' });
|
|
5811
5990
|
codeActivate(codeTabs.length - 1);
|
|
5812
5991
|
els.codeTa.focus();
|
|
5813
5992
|
}
|
|
@@ -5839,13 +6018,44 @@ async function codeSave() {
|
|
|
5839
6018
|
const r = await beast.ideWrite(t.rel, t.content).catch(() => null);
|
|
5840
6019
|
if (r && r.ok) {
|
|
5841
6020
|
t.dirty = false;
|
|
6021
|
+
t.base = t.content; /* kaydedildi → diff sıfırlanır (VS Code davranışı) */
|
|
5842
6022
|
codeRenderTabs();
|
|
6023
|
+
codeGutterRender();
|
|
5843
6024
|
toast(_t('ide_saved'));
|
|
5844
6025
|
} else {
|
|
5845
6026
|
toast((r && r.error) || 'kaydedilemedi');
|
|
5846
6027
|
}
|
|
5847
6028
|
}
|
|
5848
6029
|
|
|
6030
|
+
/* ajan dosyayı YAZINCA açık sekmeyi tazele: eski içerik base olur →
|
|
6031
|
+
ajanın değiştirdiği satırlar gutter'da yeşil/kırmızı görünür */
|
|
6032
|
+
const codeWriteWatch = new Map(); /* callId → path */
|
|
6033
|
+
async function codeReloadIfOpen(p) {
|
|
6034
|
+
const abs = String(p || '').replace(/\//g, '\\');
|
|
6035
|
+
const root = String(ideState.path || '').replace(/\//g, '\\').replace(/\\+$/, '');
|
|
6036
|
+
let rel = null;
|
|
6037
|
+
if (root && abs.toLowerCase().startsWith(root.toLowerCase() + '\\')) {
|
|
6038
|
+
rel = abs.slice(root.length + 1).replace(/\\/g, '/');
|
|
6039
|
+
} else {
|
|
6040
|
+
const cand = abs.toLowerCase();
|
|
6041
|
+
const hit = codeTabs.find((t) => cand.endsWith('\\' + t.rel.replace(/\//g, '\\').toLowerCase()) || cand === t.rel.replace(/\//g, '\\').toLowerCase());
|
|
6042
|
+
if (!hit) return;
|
|
6043
|
+
rel = hit.rel;
|
|
6044
|
+
}
|
|
6045
|
+
const i = codeTabs.findIndex((t) => t.rel === rel);
|
|
6046
|
+
if (i < 0) return;
|
|
6047
|
+
const t = codeTabs[i];
|
|
6048
|
+
if (t.dirty) return; /* kullanıcının kaydedilmemiş düzenlemesini EZME */
|
|
6049
|
+
const r = await beast.ideRead(t.rel).catch(() => null);
|
|
6050
|
+
if (!r || !r.ok) return;
|
|
6051
|
+
t.base = t.content; /* eski disk içeriği = diff tabanı */
|
|
6052
|
+
t.content = r.content || ''; /* ajanın yazdığı yeni içerik */
|
|
6053
|
+
if (i === codeActive) {
|
|
6054
|
+
els.codeTa.value = t.content;
|
|
6055
|
+
}
|
|
6056
|
+
codeGutterRender();
|
|
6057
|
+
}
|
|
6058
|
+
|
|
5849
6059
|
$('#ideBtn').addEventListener('click', () => setIdeMode(!ideModeOn()));
|
|
5850
6060
|
$('#filePick').addEventListener('click', async () => {
|
|
5851
6061
|
const r = await beast.ideSetRoot().catch(() => null);
|
|
@@ -5872,6 +6082,12 @@ if (els.codeTa) {
|
|
|
5872
6082
|
codeTabs[codeActive].dirty = true;
|
|
5873
6083
|
const el = els.codeTabs.children[codeActive];
|
|
5874
6084
|
if (el) el.classList.add('dirty');
|
|
6085
|
+
/* gutter diff'i hafif gecikmeli — her tuşta LCS koşmasın */
|
|
6086
|
+
clearTimeout(codeGutterTimer);
|
|
6087
|
+
codeGutterTimer = setTimeout(codeGutterRender, 120);
|
|
6088
|
+
});
|
|
6089
|
+
els.codeTa.addEventListener('scroll', () => {
|
|
6090
|
+
if (els.codeGutter) els.codeGutter.scrollTop = els.codeTa.scrollTop;
|
|
5875
6091
|
});
|
|
5876
6092
|
els.codeTa.addEventListener('keydown', (e) => {
|
|
5877
6093
|
if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 's') {
|
|
@@ -6230,9 +6446,25 @@ function bcIngest(ev) {
|
|
|
6230
6446
|
break;
|
|
6231
6447
|
case 'tool-start':
|
|
6232
6448
|
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);
|
|
6233
6451
|
break;
|
|
6234
6452
|
case 'tool-end':
|
|
6235
6453
|
bcToolBoxEnd(ev.callId, ev.ok, ev.result);
|
|
6454
|
+
if (codeWriteWatch.has(ev.callId)) {
|
|
6455
|
+
const wp = codeWriteWatch.get(ev.callId);
|
|
6456
|
+
codeWriteWatch.delete(ev.callId);
|
|
6457
|
+
codeReloadIfOpen(wp);
|
|
6458
|
+
}
|
|
6459
|
+
break;
|
|
6460
|
+
case 'bc-mode':
|
|
6461
|
+
/* OpenCode disiplini çalışma modu: başlıkta rozet + panelde bilgi satırı */
|
|
6462
|
+
if (els.bcTitle) {
|
|
6463
|
+
els.bcTitle.textContent =
|
|
6464
|
+
ev.mode === 'plan' ? 'BEAST CODE · PLAN' :
|
|
6465
|
+
ev.mode === 'build' ? 'BEAST CODE · BUILD' : 'BEAST CODE';
|
|
6466
|
+
}
|
|
6467
|
+
bcLine('t-dim', '[' + (ev.body || ev.mode || 'mod değişti') + ']');
|
|
6236
6468
|
break;
|
|
6237
6469
|
case 'done':
|
|
6238
6470
|
bcFlushStream();
|
|
@@ -6251,13 +6483,13 @@ function bcIngest(ev) {
|
|
|
6251
6483
|
break;
|
|
6252
6484
|
case 'status':
|
|
6253
6485
|
/* 'idle' = engine oturumu GERÇEKTEN bıraktı (finally bloğu, her yolda gelir) —
|
|
6254
|
-
done kaçsa bile panel kilitli kalmaz,
|
|
6486
|
+
done kaçsa bile panel kilitli kalmaz, ⏳ otomatik kalkar, ring durur */
|
|
6255
6487
|
if (ev.status === 'idle') {
|
|
6256
6488
|
bcCloseToolGroup();
|
|
6257
6489
|
bcSetBusy(false);
|
|
6258
6490
|
bcRefreshPreview();
|
|
6259
6491
|
}
|
|
6260
|
-
break;
|
|
6492
|
+
break;
|
|
6261
6493
|
}
|
|
6262
6494
|
}
|
|
6263
6495
|
|
|
@@ -6271,7 +6503,12 @@ function bcRunCurrent() {
|
|
|
6271
6503
|
/* sürüyor/serbest kararını main'deki gerçek engine.isBusy verir —
|
|
6272
6504
|
panel bayat kilitli kaldıysa ilk mesajla kendini düzeltir */
|
|
6273
6505
|
beast.beastcodeSend(msg).then((r) => {
|
|
6274
|
-
if (r && r.ok) {
|
|
6506
|
+
if (r && r.ok && r.mode) {
|
|
6507
|
+
/* /plan · /build · /auto: mod değişimi — tur AÇILMAZ, kilit anında açılır
|
|
6508
|
+
(bilgi satırı bc-mode olayıyla düşer, başlık rozeti güncellenir) */
|
|
6509
|
+
bcSessionId = r.sessionId;
|
|
6510
|
+
bcSetBusy(false);
|
|
6511
|
+
} else if (r && r.ok) {
|
|
6275
6512
|
bcSessionId = r.sessionId;
|
|
6276
6513
|
} else if (r && r.busy) {
|
|
6277
6514
|
/* iş gerçekten sürüyor — kilit açılmaz, bilgi satırı düşer */
|
|
@@ -6306,6 +6543,7 @@ if (els.bcNew) els.bcNew.addEventListener('click', async () => {
|
|
|
6306
6543
|
bcCloseToolGroup();
|
|
6307
6544
|
bcHideTodos();
|
|
6308
6545
|
bcFlushStream();
|
|
6546
|
+
if (els.bcTitle) els.bcTitle.textContent = 'BEAST CODE';
|
|
6309
6547
|
bcLine('t-sys', 'yeni oturum — sonraki mesaj taze başlar');
|
|
6310
6548
|
}
|
|
6311
6549
|
});
|
package/src/renderer/style.css
CHANGED
|
@@ -119,6 +119,9 @@ body {
|
|
|
119
119
|
}
|
|
120
120
|
.sess:hover { background: var(--panel2); color: var(--text); }
|
|
121
121
|
.sess.active { background: var(--panel2); color: var(--text); box-shadow: inset 2px 0 0 var(--accent); }
|
|
122
|
+
/* sürükle-bırak sıralama görselleri */
|
|
123
|
+
.sess.dragging { opacity: 0.35; }
|
|
124
|
+
.sess.drag-over { box-shadow: inset 0 2px 0 var(--accent); }
|
|
122
125
|
.sess-wa {
|
|
123
126
|
width: 15px;
|
|
124
127
|
height: 15px;
|
|
@@ -288,11 +291,15 @@ body.browser-open #topbar { width: auto; }
|
|
|
288
291
|
/* göz ikonu: gizli modda çapraz çizgi + soluk, görünür modda normal */
|
|
289
292
|
#eyeBtn .eye-slash { display: none; }
|
|
290
293
|
#eyeBtn:not(.on) .eye-slash { display: block; }
|
|
291
|
-
#eyeBtn:not(.on) { opacity: 0.55; }
|
|
292
294
|
#eyeBtn.on { background: var(--accent-dim); color: var(--accent); }
|
|
293
295
|
|
|
294
|
-
/* internet göstergesi (
|
|
295
|
-
#netDot {
|
|
296
|
+
/* internet göstergesi (sol alt sideFoot satırında, ortalanmış): bağlı = YEŞİL wifi, kopuk = KIRMIZI */
|
|
297
|
+
#netDot {
|
|
298
|
+
display: inline-flex;
|
|
299
|
+
align-items: center;
|
|
300
|
+
padding: 3px 7px;
|
|
301
|
+
cursor: default;
|
|
302
|
+
}
|
|
296
303
|
#netDot.net-on { color: #22c55e; }
|
|
297
304
|
#netDot.net-off { color: #ef4444; }
|
|
298
305
|
#netDot.net-off .net-slash { display: block; }
|
|
@@ -934,6 +941,18 @@ body.term-open #settingsOverlay { right: var(--tw, 520px); }
|
|
|
934
941
|
margin-bottom: 5px;
|
|
935
942
|
}
|
|
936
943
|
#todoPanel .td-count { letter-spacing: 0; font-weight: 700; color: var(--text); }
|
|
944
|
+
#todoPanel .td-right { display: flex; align-items: center; gap: 8px; }
|
|
945
|
+
/* sağ köşe kapatma (×): yalnız bu listeyi gizler — yeni güncellemede yine görünür */
|
|
946
|
+
#todoPanel .td-x {
|
|
947
|
+
border: none;
|
|
948
|
+
background: none;
|
|
949
|
+
color: var(--muted);
|
|
950
|
+
font-size: 14px;
|
|
951
|
+
line-height: 1;
|
|
952
|
+
padding: 0 3px;
|
|
953
|
+
cursor: pointer;
|
|
954
|
+
}
|
|
955
|
+
#todoPanel .td-x:hover { color: var(--err); }
|
|
937
956
|
#todoPanel .td-row {
|
|
938
957
|
display: flex;
|
|
939
958
|
align-items: baseline;
|
|
@@ -2424,6 +2443,41 @@ body.ide-mode #codePane { display: flex; }
|
|
|
2424
2443
|
line-height: 1.4;
|
|
2425
2444
|
}
|
|
2426
2445
|
#codeSave:hover { color: var(--accent); border-color: var(--accent); background: var(--panel2); }
|
|
2446
|
+
#codeBody { flex: 1; display: flex; min-height: 0; }
|
|
2447
|
+
#codeGutter {
|
|
2448
|
+
flex: none;
|
|
2449
|
+
width: 56px;
|
|
2450
|
+
overflow: hidden;
|
|
2451
|
+
user-select: none;
|
|
2452
|
+
font-family: Consolas, "Cascadia Mono", monospace;
|
|
2453
|
+
font-size: 12.5px;
|
|
2454
|
+
line-height: 20px;
|
|
2455
|
+
padding: 12px 0;
|
|
2456
|
+
background: var(--panel);
|
|
2457
|
+
border-right: 1px solid var(--border);
|
|
2458
|
+
text-align: right;
|
|
2459
|
+
color: var(--muted);
|
|
2460
|
+
}
|
|
2461
|
+
#codeGutter .cl { height: 20px; padding-right: 8px; position: relative; }
|
|
2462
|
+
/* VS Code tarzı değişiklik işaretleri: değişen satır YEŞİL, silinen kırmızı çizgi */
|
|
2463
|
+
#codeGutter .cl.add {
|
|
2464
|
+
background: rgba(34, 197, 94, 0.16);
|
|
2465
|
+
box-shadow: inset 2px 0 0 #22c55e;
|
|
2466
|
+
color: #16a34a;
|
|
2467
|
+
font-weight: 700;
|
|
2468
|
+
}
|
|
2469
|
+
#codeGutter .cl.del { box-shadow: inset 2px 0 0 #ef4444; }
|
|
2470
|
+
#codeGutter .cl.del::after {
|
|
2471
|
+
content: '';
|
|
2472
|
+
position: absolute;
|
|
2473
|
+
left: 0;
|
|
2474
|
+
right: 0;
|
|
2475
|
+
bottom: 0;
|
|
2476
|
+
height: 2px;
|
|
2477
|
+
background: #ef4444;
|
|
2478
|
+
}
|
|
2479
|
+
/* dosya açık değilken boş editör iskelet rakamları daha sönük */
|
|
2480
|
+
#codeGutter .cl.idle { opacity: 0.45; }
|
|
2427
2481
|
#codeTa {
|
|
2428
2482
|
flex: 1;
|
|
2429
2483
|
resize: none;
|
|
@@ -2434,7 +2488,9 @@ body.ide-mode #codePane { display: flex; }
|
|
|
2434
2488
|
padding: 12px 14px;
|
|
2435
2489
|
font-family: Consolas, "Cascadia Mono", monospace;
|
|
2436
2490
|
font-size: 12.5px;
|
|
2437
|
-
line-height:
|
|
2491
|
+
line-height: 20px;
|
|
2492
|
+
white-space: pre;
|
|
2493
|
+
overflow: auto;
|
|
2438
2494
|
}
|
|
2439
2495
|
/* dikey scrollbar hep görünür, tutulabilir ve imleç değişsin */
|
|
2440
2496
|
#codeTa::-webkit-scrollbar {
|
package/.env.example
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
# Beast Agent API anahtarları örneği.
|
|
2
|
-
# Kullanım: bu dosyayı %APPDATA%\beast\.env olarak kopyala ve anahtarlarını gir.
|
|
3
|
-
# Bu dosya config.yaml'daki key_env alanlarıyla eşleşir;
|
|
4
|
-
# key_env yoksa <PROVIDER_ID>_API_KEY denenir (örn. zhipu -> ZHIPU_API_KEY).
|
|
5
|
-
|
|
6
|
-
OPENCODE_API_KEY=
|
|
7
|
-
ZHIPU_API_KEY=
|
|
8
|
-
OPENAI_API_KEY=
|
package/config.example.yaml
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
# Beast Agent sağlayıcı yapılandırması örneği.
|
|
2
|
-
# Kullanım: bu dosyayı %APPDATA%\beast\config.yaml olarak kopyala ve düzenle.
|
|
3
|
-
# (Taşınabilir kullanım için BEAST_DATA ortam değişkeni ile başka klasöre alabilirsin.)
|
|
4
|
-
|
|
5
|
-
# ÖNERİLEN: OpenCode Zen — ücretsiz modeller, kredi kartı gerekmez (opencode.ai/auth)
|
|
6
|
-
providers:
|
|
7
|
-
opencode:
|
|
8
|
-
name: OpenCode Zen
|
|
9
|
-
base_url: https://opencode.ai/zen/v1
|
|
10
|
-
key_env: OPENCODE_API_KEY
|
|
11
|
-
models:
|
|
12
|
-
glm-5.2: {}
|
|
13
|
-
kimi-k2.7-code: {}
|
|
14
|
-
deepseek-v4-flash-free: {}
|
|
15
|
-
big-pickle: {}
|
|
16
|
-
minimax-m3: {}
|
|
17
|
-
# OpenCode Go aboneliğin varsa base_url: https://opencode.ai/zen/go/v1 kullan.
|
|
18
|
-
|
|
19
|
-
zhipu:
|
|
20
|
-
name: Zhipu AI
|
|
21
|
-
base_url: https://api.z.ai/api/paas/v4
|
|
22
|
-
key_env: ZHIPU_API_KEY
|
|
23
|
-
models:
|
|
24
|
-
glm-4.6: {}
|
|
25
|
-
glm-4.5-air: {}
|
|
26
|
-
|
|
27
|
-
openai:
|
|
28
|
-
name: OpenAI
|
|
29
|
-
base_url: https://api.openai.com/v1
|
|
30
|
-
key_env: OPENAI_API_KEY
|
|
31
|
-
models:
|
|
32
|
-
gpt-4o-mini: {}
|
|
33
|
-
gpt-4o: {}
|
|
34
|
-
|
|
35
|
-
model:
|
|
36
|
-
provider: opencode # varsayılan provider id (yoksa ilk provider kullanılır)
|
|
37
|
-
default: glm-5.2 # varsayılan model
|
|
38
|
-
# base_url: ... # istersen aktif provider'ın URL'ini override et
|
|
39
|
-
# key_env: ... # istersen anahtarı farklı env'den oku
|