beast-agent 2.12.0 → 2.14.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 +1 -1
- package/src/agent/android.js +265 -0
- package/src/agent/engine.js +79 -0
- package/src/agent/headroom.js +279 -0
- package/src/agent/llm.js +20 -2
- package/src/main.js +209 -0
- package/src/preload.js +8 -0
- package/src/renderer/i18n.js +7 -3
- package/src/renderer/index.html +20 -0
- package/src/renderer/renderer.js +289 -83
- package/src/renderer/style.css +118 -0
package/src/agent/llm.js
CHANGED
|
@@ -347,6 +347,18 @@ function sessionHeaderId(body) {
|
|
|
347
347
|
return _sessionFallback;
|
|
348
348
|
}
|
|
349
349
|
|
|
350
|
+
/* Headroom proxy yönlendirme: providerId -> yerel proxy portu haritası.
|
|
351
|
+
main (agent/headroom.js) ayarlardan açıldığında kurar; null = düz bağlan. */
|
|
352
|
+
let _headroomRoutes = null;
|
|
353
|
+
function setHeadroomRoutes(map) {
|
|
354
|
+
_headroomRoutes = map && Object.keys(map).length ? map : null;
|
|
355
|
+
}
|
|
356
|
+
function headroomUrlFor(sel) {
|
|
357
|
+
if (!_headroomRoutes || !sel) return '';
|
|
358
|
+
const port = Number(_headroomRoutes[String(sel.providerId || '')] || 0);
|
|
359
|
+
return port ? 'http://127.0.0.1:' + port + '/v1/chat/completions' : '';
|
|
360
|
+
}
|
|
361
|
+
|
|
350
362
|
async function openChat(sel, body, { stream, signal, drops } = {}) {
|
|
351
363
|
const d = drops || {};
|
|
352
364
|
const payload = {
|
|
@@ -368,7 +380,10 @@ async function openChat(sel, body, { stream, signal, drops } = {}) {
|
|
|
368
380
|
if (body.cacheKey && wantsCacheKey(sel) && !d.noCacheKey) {
|
|
369
381
|
payload.prompt_cache_key = String(body.cacheKey);
|
|
370
382
|
}
|
|
371
|
-
|
|
383
|
+
/* Headroom açıkken istek yerel sıkıştırma proxy'sinden geçer (aynı gövde+başlıklar);
|
|
384
|
+
yoksa sağlayıcıya düz bağlan */
|
|
385
|
+
const target = headroomUrlFor(sel) || sel.url;
|
|
386
|
+
return fetch(target, {
|
|
372
387
|
method: 'POST',
|
|
373
388
|
signal,
|
|
374
389
|
headers: {
|
|
@@ -558,7 +573,9 @@ async function chatStreamAuto(sel, body, opts = {}) {
|
|
|
558
573
|
let last = first;
|
|
559
574
|
for (let i = 0; i < 2; i++) {
|
|
560
575
|
const msgs2 = body.messages.slice();
|
|
561
|
-
|
|
576
|
+
const asst = { role: 'assistant', content: full };
|
|
577
|
+
if (first.reasoning) asst.reasoning_content = first.reasoning; /* thinking geri-besleme */
|
|
578
|
+
msgs2.push(asst);
|
|
562
579
|
msgs2.push({ role: 'user', content: CONTINUE_PROMPT });
|
|
563
580
|
let cont;
|
|
564
581
|
try {
|
|
@@ -624,6 +641,7 @@ module.exports = {
|
|
|
624
641
|
capsFor,
|
|
625
642
|
resetCaps,
|
|
626
643
|
learnCaps,
|
|
644
|
+
setHeadroomRoutes,
|
|
627
645
|
PARAM_LABELS,
|
|
628
646
|
isNetworkError,
|
|
629
647
|
wantsCacheKey,
|
package/src/main.js
CHANGED
|
@@ -26,7 +26,10 @@ const watchers = require('./agent/watchers');
|
|
|
26
26
|
const usageMod = require('./agent/usage');
|
|
27
27
|
const bus = require('./agent/bus');
|
|
28
28
|
const computeruse = require('./agent/computeruse');
|
|
29
|
+
const android = require('./agent/android');
|
|
29
30
|
const log = require('./agent/logger');
|
|
31
|
+
const headroom = require('./agent/headroom');
|
|
32
|
+
const QRCode = require('qrcode'); /* Expo Go QR (bc-expurl) — whatsapp ile aynı paket */
|
|
30
33
|
|
|
31
34
|
/* #3 otomatik updater: sessiz — indirir, kapanışta kurar, kullanıcıya soru sormaz.
|
|
32
35
|
Paketlenmemiş (npm start) modda devre dışı; Update sekmesi ve /update komutu kontrol eder. */
|
|
@@ -3107,7 +3110,18 @@ function reloadBackend() {
|
|
|
3107
3110
|
/* BC canlı önizleme: ajan bir dev server başlattıysa adresi yakala —
|
|
3108
3111
|
preview butonu ve otomatik açılış DAİMA bu sunucuyu öncelikli kullanır */
|
|
3109
3112
|
if (ev.type === 'bc-preview' && /^https?:\/\/(?:localhost|127\.0\.0\.1)(?::\d{2,5})?/i.test(String(ev.url || ''))) {
|
|
3113
|
+
/* klasör değiştiyse eski sunucu bayat: KAPAT, en yeniye geç */
|
|
3114
|
+
try {
|
|
3115
|
+
if (bcLastServerUrl && bcLastServerRoot && path.relative(bcLastServerRoot, ideRoot()) !== '') {
|
|
3116
|
+
bcKillServer(bcLastServerUrl);
|
|
3117
|
+
}
|
|
3118
|
+
} catch {}
|
|
3110
3119
|
bcLastServerUrl = String(ev.url);
|
|
3120
|
+
try { bcLastServerRoot = ideRoot(); } catch { bcLastServerRoot = ''; }
|
|
3121
|
+
}
|
|
3122
|
+
/* Expo Go QR: ajanın dev sunucusu exp:// adresi yazdıysa QR üretip panele bas */
|
|
3123
|
+
if (ev.type === 'bc-expurl') {
|
|
3124
|
+
bcExpQrMake(String(ev.url || '')).catch(() => {});
|
|
3111
3125
|
}
|
|
3112
3126
|
/* WA canlı iş takibi: oturum bir WhatsApp sohbetine bağlıysa araç
|
|
3113
3127
|
hareketlerini (terminal, web, dosya…) kısa satırla bildir.
|
|
@@ -3288,6 +3302,30 @@ function reloadBackend() {
|
|
|
3288
3302
|
/* PANEL RUN köprüsü: ajanın panel_run aracı → ÇALIŞTIR panelindeki yönetilen
|
|
3289
3303
|
süreç koşucusu (sandbox:run IPC ile aynı makine). */
|
|
3290
3304
|
engine.sbRunHook = sbRunStartManaged;
|
|
3305
|
+
|
|
3306
|
+
/* HEADROOM (opsiyonel token sıkıştırma proxy'si): engine zincirinden provider
|
|
3307
|
+
listesi alınır; durum değişince renderer'a 'headroom-status' düşer */
|
|
3308
|
+
headroom.setProviderGetter(() => {
|
|
3309
|
+
const seen = new Map();
|
|
3310
|
+
for (const c of (engine && engine.cfg && engine.cfg.chain) || []) {
|
|
3311
|
+
if (!c || !c.providerId || !c.url || seen.has(c.providerId)) continue;
|
|
3312
|
+
seen.set(c.providerId, {
|
|
3313
|
+
id: String(c.providerId),
|
|
3314
|
+
name: String(c.providerName || c.providerId),
|
|
3315
|
+
baseUrl: String(c.url).replace(/\/chat\/completions$/, ''),
|
|
3316
|
+
});
|
|
3317
|
+
}
|
|
3318
|
+
return [...seen.values()];
|
|
3319
|
+
});
|
|
3320
|
+
headroom.setStatusSink((st) => {
|
|
3321
|
+
try {
|
|
3322
|
+
if (win && !win.isDestroyed()) win.webContents.send('agent:event', { type: 'headroom-status', status: st });
|
|
3323
|
+
} catch {}
|
|
3324
|
+
});
|
|
3325
|
+
/* ayarlardan açık kaldıysa: uygulama açılışında arka planda başlat */
|
|
3326
|
+
if (settings.headroom && settings.headroom.enabled) {
|
|
3327
|
+
setTimeout(() => { headroom.setEnabled(true).catch(() => {}); }, 4000);
|
|
3328
|
+
}
|
|
3291
3329
|
return engine.publicState();
|
|
3292
3330
|
}
|
|
3293
3331
|
|
|
@@ -3516,6 +3554,7 @@ app.whenReady().then(() => {
|
|
|
3516
3554
|
flushBrowserStorage(); // x.com/google oturumları (cookies) diske yazılsın
|
|
3517
3555
|
try { toolsMod.disposeShellSessions(); } catch {} // kalıcı shell oturumlarını kapat
|
|
3518
3556
|
try { require('./agent/mcp').stopAll(); } catch {} // MCP server süreçlerini kapat
|
|
3557
|
+
try { headroom.stopAll(); } catch {} // headroom proxy süreçlerini kapat
|
|
3519
3558
|
});
|
|
3520
3559
|
|
|
3521
3560
|
if (process.argv.includes('--smoke')) {
|
|
@@ -6248,12 +6287,73 @@ ipcMain.handle('install:status', async () => {
|
|
|
6248
6287
|
/* 8) Edge TTS (bulut) */
|
|
6249
6288
|
rows.push({ id: 'edge', name: 'Edge TTS — seslendirme', state: 'cloud', detail: 'bulut — kurulum gerekmez' });
|
|
6250
6289
|
|
|
6290
|
+
/* 9) Headroom CLI — arka plan paket kurulumu burada görünür;
|
|
6291
|
+
aç/kapat Token Sıkıştırma sekmesinde */
|
|
6292
|
+
{
|
|
6293
|
+
const st = headroom.probe();
|
|
6294
|
+
let state = 'optional';
|
|
6295
|
+
if (st.installed) state = 'ok';
|
|
6296
|
+
else if (st.installing) state = 'loading';
|
|
6297
|
+
if (st.failed) state = 'failed';
|
|
6298
|
+
rows.push({
|
|
6299
|
+
id: 'headroom',
|
|
6300
|
+
name: 'Headroom CLI — token sıkıştırma motoru',
|
|
6301
|
+
state,
|
|
6302
|
+
detail: st.installing
|
|
6303
|
+
? 'arka planda kuruluyor — uv tool install headroom-ai[proxy]'
|
|
6304
|
+
: st.failed
|
|
6305
|
+
? (st.error || 'kurulum başarısız')
|
|
6306
|
+
: st.installed
|
|
6307
|
+
? 'kurulu — aç/kapat: Token Sıkıştırma sekmesi'
|
|
6308
|
+
: 'kurulu değil — Token Sıkıştırma sekmesinden açınca otomatik kurulur',
|
|
6309
|
+
...(st.installing ? pctFields('headroom') : {}),
|
|
6310
|
+
});
|
|
6311
|
+
}
|
|
6312
|
+
|
|
6313
|
+
/* 10) Android Emülatörü — opsiyonel; varsa Beast Code mobil uygulamaları emülatörde açar */
|
|
6314
|
+
{
|
|
6315
|
+
const st = android.probe();
|
|
6316
|
+
let state = 'optional';
|
|
6317
|
+
if (st.sdk) state = 'ok';
|
|
6318
|
+
else if (st.installing) state = 'loading';
|
|
6319
|
+
if (st.failed) state = 'failed';
|
|
6320
|
+
rows.push({
|
|
6321
|
+
id: 'android',
|
|
6322
|
+
name: 'Android Emülatörü — mobil uygulamalar emülatörde çalışır',
|
|
6323
|
+
state,
|
|
6324
|
+
canInstall: true,
|
|
6325
|
+
detail: st.installing
|
|
6326
|
+
? (st.stage || 'arka planda kuruluyor — JDK + SDK + sistem imajı (~1.5GB, internete göre 5-20 dk)')
|
|
6327
|
+
: st.failed
|
|
6328
|
+
? (st.error || 'kurulum başarısız')
|
|
6329
|
+
: st.sdk
|
|
6330
|
+
? 'hazır — SDK: ' + st.sdkPath
|
|
6331
|
+
: 'kurulu değil — KUR ile arka planda kurulur (istekge bağlı)',
|
|
6332
|
+
...(st.installing ? pctFields('android') : {}),
|
|
6333
|
+
});
|
|
6334
|
+
}
|
|
6335
|
+
|
|
6251
6336
|
return rows;
|
|
6252
6337
|
});
|
|
6253
6338
|
|
|
6254
6339
|
/* cua-driver kurulumunu şimdi başlat (Kurulum sekmesi otomatiği + elle tetikleme) */
|
|
6255
6340
|
ipcMain.handle('cua:install', () => require('./agent/computeruse').autoInstall());
|
|
6256
6341
|
|
|
6342
|
+
/* HEADROOM (opsiyonel token sıkıştırma): aç/kapa + durum */
|
|
6343
|
+
ipcMain.handle('headroom:toggle', async (_e, on) => {
|
|
6344
|
+
settings.headroom = { ...(settings.headroom || {}), enabled: !!on };
|
|
6345
|
+
saveSettings();
|
|
6346
|
+
const r = await headroom.setEnabled(!!on).catch((e) => ({ ok: false, error: String((e && e.message) || e) }));
|
|
6347
|
+
return r;
|
|
6348
|
+
});
|
|
6349
|
+
ipcMain.handle('headroom:status', () => headroom.probe());
|
|
6350
|
+
ipcMain.handle('headroom:stats', () => headroom.stats());
|
|
6351
|
+
|
|
6352
|
+
/* ANDROID EMÜLATÖR (opsiyonel): durum + arka plan kurulum + AVD başlatma */
|
|
6353
|
+
ipcMain.handle('android:status', async () => ({ ok: true, ...(await android.probe()), avds: await android.listAvds() }));
|
|
6354
|
+
ipcMain.handle('android:install', () => android.autoInstall());
|
|
6355
|
+
ipcMain.handle('android:startAvd', async (_e, name) => android.startAvd(name));
|
|
6356
|
+
|
|
6257
6357
|
/* embedding modelini şimdi indir (mem0 arama yolu ısıtılır) */
|
|
6258
6358
|
ipcMain.handle('embed:prefetch', () => {
|
|
6259
6359
|
try {
|
|
@@ -8063,6 +8163,14 @@ ipcMain.handle('ide:setroot', async () => {
|
|
|
8063
8163
|
properties: ['openDirectory'],
|
|
8064
8164
|
});
|
|
8065
8165
|
if (r.canceled || !r.filePaths || !r.filePaths[0]) return { ok: false, canceled: true };
|
|
8166
|
+
/* klasör değişti: eski klasörün dev server'ı bayat — kill + unut */
|
|
8167
|
+
try {
|
|
8168
|
+
if (bcLastServerUrl) {
|
|
8169
|
+
bcKillServer(bcLastServerUrl);
|
|
8170
|
+
bcLastServerUrl = '';
|
|
8171
|
+
bcLastServerRoot = '';
|
|
8172
|
+
}
|
|
8173
|
+
} catch {}
|
|
8066
8174
|
settings.ideRoot = r.filePaths[0];
|
|
8067
8175
|
saveSettings();
|
|
8068
8176
|
ideWatchStart(); // yeni kökte izleme yeniden kurulur
|
|
@@ -8686,10 +8794,60 @@ ipcMain.handle('sandbox:openurl', async (_e, url) => {
|
|
|
8686
8794
|
ve "clean URL" yolları file://'da çalışmaz. Her preview http://127.0.0.1 üzerinden
|
|
8687
8795
|
servis edilir; ajan kendi dev sunucusunu başlattıysa o adres önceliklidir. */
|
|
8688
8796
|
let bcLastServerUrl = ''; /* ajanın başlattığı dev server adresi (bc-preview'dan yakalanır) */
|
|
8797
|
+
let bcLastServerRoot = ''; /* adresin yakalandığı workspace kökü — klasör değişince bayat sayılır */
|
|
8798
|
+
|
|
8799
|
+
/* dev server'ı port'tan bulup süreç AĞACINI kapat (best-effort).
|
|
8800
|
+
Ajan arka planda başlattığı sunucular izlenmez — port üzerinden bulunur. */
|
|
8801
|
+
function bcKillServer(url) {
|
|
8802
|
+
try {
|
|
8803
|
+
const m = /:(\d{2,5})(?:\/|$)/.exec(String(url || ''));
|
|
8804
|
+
if (!m) return false;
|
|
8805
|
+
const port = m[1];
|
|
8806
|
+
const { execSync } = require('child_process');
|
|
8807
|
+
const out = String(execSync(
|
|
8808
|
+
'netstat -ano | findstr ":' + port + '" | findstr LISTENING',
|
|
8809
|
+
{ timeout: 6000, stdio: 'pipe', encoding: 'utf8', windowsHide: true }
|
|
8810
|
+
));
|
|
8811
|
+
const pids = new Set();
|
|
8812
|
+
for (const line of out.split(/\r?\n/)) {
|
|
8813
|
+
const p = /\s(\d+)\s*$/.exec(String(line).trim());
|
|
8814
|
+
if (p) pids.add(p[1]);
|
|
8815
|
+
}
|
|
8816
|
+
let killed = 0;
|
|
8817
|
+
for (const pid of pids) {
|
|
8818
|
+
if (Number(pid) === process.pid) continue; /* kendimize dokunma */
|
|
8819
|
+
try {
|
|
8820
|
+
spawn('taskkill', ['/pid', String(pid), '/T', '/F'], { windowsHide: true });
|
|
8821
|
+
killed++;
|
|
8822
|
+
} catch {}
|
|
8823
|
+
}
|
|
8824
|
+
try { log.info('bc', 'bayat dev server kapatıldı (port ' + port + ', ' + killed + ' süreç)'); } catch {}
|
|
8825
|
+
return killed > 0;
|
|
8826
|
+
} catch {
|
|
8827
|
+
return false; /* port boş / netstat hata — yok say */
|
|
8828
|
+
}
|
|
8829
|
+
}
|
|
8689
8830
|
const bcStatic = { server: null, root: '', base: '' };
|
|
8690
8831
|
/* MOBİL PROJE önizleme: npm run web (expo start --web) süreci + canlı adres */
|
|
8691
8832
|
const bcMobile = { proc: null, url: '', root: '' };
|
|
8692
8833
|
|
|
8834
|
+
/* ---------- EXPO GO QR (yalnız Beast Code) ----------
|
|
8835
|
+
Ajan expo start çıktısında exp://<LAN-IP>:<port> yazınca QR'e çevrilir ve
|
|
8836
|
+
renderer'a { type:'bc-exp-qr', qr, url } düşer — telefonda Expo Go okutulur. */
|
|
8837
|
+
let bcLastExpUrl = '';
|
|
8838
|
+
let bcLastExpQr = '';
|
|
8839
|
+
|
|
8840
|
+
function bcExpQrMake(url) {
|
|
8841
|
+
if (!url || url === bcLastExpUrl) return Promise.resolve();
|
|
8842
|
+
bcLastExpUrl = url;
|
|
8843
|
+
return QRCode.toDataURL(url, { width: 240, margin: 1, errorCorrectionLevel: 'M' }).then((qr) => {
|
|
8844
|
+
bcLastExpQr = qr;
|
|
8845
|
+
if (win && !win.isDestroyed()) win.webContents.send('agent:event', { type: 'bc-exp-qr', qr, url });
|
|
8846
|
+
});
|
|
8847
|
+
}
|
|
8848
|
+
|
|
8849
|
+
ipcMain.handle('ide:expqr', () => ({ ok: true, qr: bcLastExpQr, url: bcLastExpUrl }));
|
|
8850
|
+
|
|
8693
8851
|
/* workspace bir MOBİL UYGULAMA projesi mi? (expo / react-native / app.json) */
|
|
8694
8852
|
function ideMobileProject(root) {
|
|
8695
8853
|
try {
|
|
@@ -8714,6 +8872,49 @@ function ideMobileProject(root) {
|
|
|
8714
8872
|
}
|
|
8715
8873
|
}
|
|
8716
8874
|
|
|
8875
|
+
/* Beast Code PROJE TİPİ algılama: preview butonu ajana hangi talimatı vereceğini
|
|
8876
|
+
bununla seçer. kind: expo | react-native | web | static | unknown */
|
|
8877
|
+
function ideProjectInfo(root) {
|
|
8878
|
+
const out = { kind: 'unknown', name: '', cmd: '' };
|
|
8879
|
+
try {
|
|
8880
|
+
const pkgPath = path.join(root, 'package.json');
|
|
8881
|
+
let pkg = null;
|
|
8882
|
+
try { if (fs.existsSync(pkgPath)) pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8')); } catch {}
|
|
8883
|
+
if (!pkg) {
|
|
8884
|
+
out.kind = fs.existsSync(path.join(root, 'index.html')) ? 'static' : 'unknown';
|
|
8885
|
+
return out;
|
|
8886
|
+
}
|
|
8887
|
+
out.name = String(pkg.name || '');
|
|
8888
|
+
const deps = { ...(pkg.dependencies || {}), ...(pkg.devDependencies || {}) };
|
|
8889
|
+
const scripts = pkg.scripts || {};
|
|
8890
|
+
const hasAppJson = fs.existsSync(path.join(root, 'app.json')) || fs.existsSync(path.join(root, 'app.config.js'));
|
|
8891
|
+
if (deps.expo || (hasAppJson && (deps['react-native'] || deps['react-dom']))) {
|
|
8892
|
+
out.kind = 'expo';
|
|
8893
|
+
out.cmd = scripts.web ? 'npm run web' : deps.expo ? 'npx expo start --web' : String(scripts.start || '');
|
|
8894
|
+
} else if (deps['react-native']) {
|
|
8895
|
+
out.kind = 'react-native';
|
|
8896
|
+
out.cmd = String(scripts.start || scripts.ios || '') || 'npx react-native start';
|
|
8897
|
+
} else if (deps.next) {
|
|
8898
|
+
out.kind = 'web';
|
|
8899
|
+
out.cmd = String(scripts.dev || scripts.start || '') || 'npx next dev';
|
|
8900
|
+
} else if (deps.vite || deps['react-scripts'] || deps['@angular/core'] || deps['vue']) {
|
|
8901
|
+
out.kind = 'web';
|
|
8902
|
+
out.cmd = String(scripts.dev || scripts.start || scripts.serve || '');
|
|
8903
|
+
} else if (scripts.dev) {
|
|
8904
|
+
out.kind = 'web';
|
|
8905
|
+
out.cmd = 'npm run dev';
|
|
8906
|
+
} else if (scripts.start) {
|
|
8907
|
+
out.kind = 'web';
|
|
8908
|
+
out.cmd = 'npm start';
|
|
8909
|
+
} else {
|
|
8910
|
+
out.kind = fs.existsSync(path.join(root, 'index.html')) ? 'static' : 'unknown';
|
|
8911
|
+
}
|
|
8912
|
+
} catch {}
|
|
8913
|
+
return out;
|
|
8914
|
+
}
|
|
8915
|
+
|
|
8916
|
+
ipcMain.handle('ide:projinfo', () => ({ ok: true, ...ideProjectInfo(ideRoot()) }));
|
|
8917
|
+
|
|
8717
8918
|
function killMobilePreview() {
|
|
8718
8919
|
const p = bcMobile.proc;
|
|
8719
8920
|
if (p) {
|
|
@@ -8902,6 +9103,13 @@ ipcMain.handle('ide:preview', async () => {
|
|
|
8902
9103
|
if (!entry) return { ok: false, error: 'workspace kökünde index.html yok — önce agent\'a siteyi yazdır' };
|
|
8903
9104
|
/* forceVisible: preview'a basınca tarayıcı ikonuna basmaya gerek kalmasın */
|
|
8904
9105
|
setBrowserOpen(true, true);
|
|
9106
|
+
/* KLASÖR UYUŞMAZLIĞI: kayıtlı dev server ESKİ klasörün artıklarıysa
|
|
9107
|
+
kill et ve unut — yeni klasör kendi sunucusuyla başlasın */
|
|
9108
|
+
if (bcLastServerUrl && bcLastServerRoot && path.relative(bcLastServerRoot, root) !== '') {
|
|
9109
|
+
bcKillServer(bcLastServerUrl);
|
|
9110
|
+
bcLastServerUrl = '';
|
|
9111
|
+
bcLastServerRoot = '';
|
|
9112
|
+
}
|
|
8905
9113
|
let url = '';
|
|
8906
9114
|
if (bcLastServerUrl) {
|
|
8907
9115
|
url = bcLastServerUrl; /* ajanın kendi dev sunucusu öncelikli */
|
|
@@ -8964,6 +9172,7 @@ ipcMain.handle('custom:set', (_e, list) => {
|
|
|
8964
9172
|
settings.customProviders = Array.isArray(list) ? list : [];
|
|
8965
9173
|
saveSettings();
|
|
8966
9174
|
engine.setCustomProviders(settings.customProviders);
|
|
9175
|
+
headroom.syncProviders(); /* headroom açıksa proxy setini yeni listeye uydur */
|
|
8967
9176
|
return engine.publicState();
|
|
8968
9177
|
});
|
|
8969
9178
|
|
package/src/preload.js
CHANGED
|
@@ -222,6 +222,14 @@ contextBridge.exposeInMainWorld('beast', {
|
|
|
222
222
|
idePreview: () => ipcRenderer.invoke('ide:preview'),
|
|
223
223
|
idePreviewFile: (rel) => ipcRenderer.invoke('ide:previewFile', rel),
|
|
224
224
|
idePreviewUrl: (url) => ipcRenderer.invoke('ide:previewUrl', url),
|
|
225
|
+
ideProjInfo: () => ipcRenderer.invoke('ide:projinfo'),
|
|
226
|
+
ideExpQr: () => ipcRenderer.invoke('ide:expqr'),
|
|
227
|
+
headroomToggle: (on) => ipcRenderer.invoke('headroom:toggle', !!on),
|
|
228
|
+
headroomStatus: () => ipcRenderer.invoke('headroom:status'),
|
|
229
|
+
headroomStats: () => ipcRenderer.invoke('headroom:stats'),
|
|
230
|
+
androidStatus: () => ipcRenderer.invoke('android:status'),
|
|
231
|
+
androidInstall: () => ipcRenderer.invoke('android:install'),
|
|
232
|
+
androidStartAvd: (name) => ipcRenderer.invoke('android:startAvd', name),
|
|
225
233
|
agentsClearAll: () => ipcRenderer.invoke('agents:clearAll'),
|
|
226
234
|
ideDelete: (rel) => ipcRenderer.invoke('ide:delete', rel),
|
|
227
235
|
onWaEvent: (cb) => ipcRenderer.on('wa:event', (_e, ev) => cb(ev)),
|
package/src/renderer/i18n.js
CHANGED
|
@@ -64,6 +64,7 @@
|
|
|
64
64
|
set_title: 'AYARLAR',
|
|
65
65
|
tab_lang: 'Dil',
|
|
66
66
|
lang_sub: 'Arayüz dili — uygulama dili ve sesli komut dili buradan değişir',
|
|
67
|
+
tab_headroom: 'Token Sıkıştırma',
|
|
67
68
|
tab_provider: 'Provider',
|
|
68
69
|
tab_fallout: 'Fallout',
|
|
69
70
|
tab_memory: 'Memory',
|
|
@@ -163,7 +164,7 @@
|
|
|
163
164
|
em_mem_clear: 'Hafızayı Temizle',
|
|
164
165
|
em_mem_cleared: 'Empati hafızası temizlendi',
|
|
165
166
|
tab_cron: 'Cron',
|
|
166
|
-
tab_usage: 'Maliyet
|
|
167
|
+
tab_usage: 'Maliyet',
|
|
167
168
|
tab_logs: 'Log',
|
|
168
169
|
tab_dash: 'Dashboard',
|
|
169
170
|
tab_limits: 'Limit',
|
|
@@ -539,6 +540,8 @@
|
|
|
539
540
|
bot_plugin_sub: 'Aktif plugin\u2019leri seç (değişiklik loglanır).',
|
|
540
541
|
bot_watcher_sub: 'Bu botun oturumlarına bağlı izleyiciler.',
|
|
541
542
|
bot_no_watchers: 'Bu bota ait izleyici yok.',
|
|
543
|
+
w_pane: 'İZLEYİCİLER',
|
|
544
|
+
w_empty: 'Kayıtlı izleyici yok.',
|
|
542
545
|
bot_stats_sub: 'Bu botun kullanım özeti.',
|
|
543
546
|
bot_stat_numbers: 'Numara',
|
|
544
547
|
bot_stat_sessions: 'Sohbet',
|
|
@@ -696,6 +699,7 @@
|
|
|
696
699
|
set_title: 'SETTINGS',
|
|
697
700
|
tab_lang: 'Language',
|
|
698
701
|
lang_sub: 'Interface language — app UI and voice command language',
|
|
702
|
+
tab_headroom: 'Token Compression',
|
|
699
703
|
tab_provider: 'Provider',
|
|
700
704
|
tab_fallout: 'Fallout',
|
|
701
705
|
tab_memory: 'Memory',
|
|
@@ -795,7 +799,7 @@
|
|
|
795
799
|
em_mem_clear: 'Clear Memory',
|
|
796
800
|
em_mem_cleared: 'Empathy memory cleared',
|
|
797
801
|
tab_cron: 'Cron',
|
|
798
|
-
tab_usage: 'Cost
|
|
802
|
+
tab_usage: 'Cost',
|
|
799
803
|
tab_logs: 'Logs',
|
|
800
804
|
tab_dash: 'Dashboard',
|
|
801
805
|
tab_limits: 'Limit',
|
|
@@ -1033,6 +1037,7 @@
|
|
|
1033
1037
|
cr_ran: 'Started',
|
|
1034
1038
|
cr_toggle_pause: 'Pause',
|
|
1035
1039
|
w_empty: 'No saved watchers — add from the form above.',
|
|
1040
|
+
w_pane: 'WATCHERS',
|
|
1036
1041
|
wa_vazgec: 'Cancel',
|
|
1037
1042
|
wa_kaydet: 'save',
|
|
1038
1043
|
wa_updated: 'Updated',
|
|
@@ -1063,7 +1068,6 @@
|
|
|
1063
1068
|
cr_modal_empty: 'Kayıtlı cron görev yok — Ayarlar → Cron sekmesinden ekle.',
|
|
1064
1069
|
cr_ran: 'Çalıştırıldı',
|
|
1065
1070
|
cr_toggle_pause: 'Duraklat',
|
|
1066
|
-
w_empty: 'Kayıtlı izleyici yok — yukarıdaki formla ekle.',
|
|
1067
1071
|
wa_vazgec: 'Vazgeç',
|
|
1068
1072
|
wa_kaydet: 'kaydet',
|
|
1069
1073
|
wa_updated: 'Güncellendi',
|
package/src/renderer/index.html
CHANGED
|
@@ -13,6 +13,14 @@
|
|
|
13
13
|
<div id="brand"><span class="brand-beast">BEAST</span><span class="brand-sub">Agent</span></div>
|
|
14
14
|
<button id="newChat" title="Yeni sohbet" data-i18n="newChat">+ Yeni Sohbet</button>
|
|
15
15
|
<div id="sessList"></div>
|
|
16
|
+
<div id="watchPane">
|
|
17
|
+
<div id="watchPaneHead">
|
|
18
|
+
<span id="watchPaneTitle" data-i18n="w_pane">İZLEYİCİLER</span>
|
|
19
|
+
<span class="file-spacer"></span>
|
|
20
|
+
<button id="watchPaneOpen" title="İzleyicileri yönet">+</button>
|
|
21
|
+
</div>
|
|
22
|
+
<div id="watchPaneList"></div>
|
|
23
|
+
</div>
|
|
16
24
|
<div id="botBar">
|
|
17
25
|
<div id="botBarHead">
|
|
18
26
|
<span id="botBarTitle" data-i18n="bot_head">BOTLAR</span>
|
|
@@ -164,11 +172,21 @@
|
|
|
164
172
|
<button id="codeShow" title="Editörü göster" data-i18n-title="tipCodeShow" hidden>▣︎</button>
|
|
165
173
|
<button id="bcNew" title="Yeni oturum" data-i18n-title="bc_new">*</button>
|
|
166
174
|
<button id="bcClear" title="Çıktıyı temizle" data-i18n-title="bc_clear">Temizle</button>
|
|
175
|
+
<button id="bcQrBtn" title="Expo Go QR" hidden>▣︎</button>
|
|
167
176
|
</div>
|
|
168
177
|
<div id="bcOut"></div>
|
|
169
178
|
<div id="bcTodoWrap" hidden></div>
|
|
170
179
|
<div id="bcStatus" hidden></div>
|
|
171
180
|
<div id="bcChips" hidden></div>
|
|
181
|
+
<div id="bcQrCard" hidden>
|
|
182
|
+
<div class="bq-head">
|
|
183
|
+
<span>EXPO GO QR</span>
|
|
184
|
+
<button id="bcQrClose" title="Kapat">×</button>
|
|
185
|
+
</div>
|
|
186
|
+
<img id="bcQrImg" alt="Expo QR" draggable="false" />
|
|
187
|
+
<div id="bcQrUrl" title=""></div>
|
|
188
|
+
<div class="bq-hint">Telefonda <b>Expo Go</b> ile okut — tünel modunda her ağdan çalışır</div>
|
|
189
|
+
</div>
|
|
172
190
|
<div id="bcInputRow">
|
|
173
191
|
<button id="bcAttach" title="Dosya / resim ekle" data-i18n-title="tipAttach">+</button>
|
|
174
192
|
<button id="bcMic" title="Sesli komut — konuş, bırakınca yazıya çevirsin" data-i18n-title="tipMic"><svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="2" width="6" height="12" rx="3"/><path d="M19 10v2a7 7 0 0 1-14 0v-2"/><path d="M12 19v3"/></svg></button>
|
|
@@ -297,6 +315,7 @@
|
|
|
297
315
|
<button class="tab" data-tab="empati" data-i18n="tab_empati">Empati Loop</button>
|
|
298
316
|
<button class="tab" data-tab="cron" data-i18n="tab_cron">Cron</button>
|
|
299
317
|
<button class="tab" data-tab="usage" data-i18n="tab_usage">Maliyet · Limit</button>
|
|
318
|
+
<button class="tab" data-tab="headroom" data-i18n="tab_headroom">Token Sıkıştırma</button>
|
|
300
319
|
<button class="tab" data-tab="logs" data-i18n="tab_logs">Log</button>
|
|
301
320
|
<button class="tab" data-tab="dash" data-i18n="tab_dash">Dashboard</button>
|
|
302
321
|
<button class="tab" data-tab="sec" data-i18n="tab_security">Güvenlik</button>
|
|
@@ -322,6 +341,7 @@
|
|
|
322
341
|
<div id="tab-events" class="pane" hidden></div>
|
|
323
342
|
<div id="tab-empati" class="pane" hidden></div>
|
|
324
343
|
<div id="tab-usage" class="pane" hidden></div>
|
|
344
|
+
<div id="tab-headroom" class="pane" hidden></div>
|
|
325
345
|
<div id="tab-logs" class="pane" hidden></div>
|
|
326
346
|
<div id="tab-dash" class="pane" hidden></div>
|
|
327
347
|
<div id="tab-sec" class="pane" hidden></div>
|