beast-agent 2.42.0 → 2.44.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/assets/app.ico +0 -0
- package/assets/logo.png +0 -0
- package/assets/tray.png +0 -0
- package/package.json +1 -1
- package/src/main.js +51 -3
- package/src/renderer/i18n.js +2 -0
- package/src/renderer/index.html +35 -3
- package/src/renderer/renderer.js +170 -0
- package/src/renderer/style.css +226 -8
package/assets/app.ico
CHANGED
|
Binary file
|
package/assets/logo.png
ADDED
|
Binary file
|
package/assets/tray.png
CHANGED
|
Binary file
|
package/package.json
CHANGED
package/src/main.js
CHANGED
|
@@ -3774,7 +3774,7 @@ function toastNotify(title, body, target) {
|
|
|
3774
3774
|
const n = new Notification({
|
|
3775
3775
|
title: String(title || 'Beast Agent').slice(0, 120),
|
|
3776
3776
|
body: String(body || '').slice(0, 240),
|
|
3777
|
-
icon: path.join(__dirname, '..', 'assets', '
|
|
3777
|
+
icon: path.join(__dirname, '..', 'assets', 'logo.png'),
|
|
3778
3778
|
silent: false,
|
|
3779
3779
|
});
|
|
3780
3780
|
n.on('click', () => {
|
|
@@ -4342,6 +4342,34 @@ function researchViewAt(idx) {
|
|
|
4342
4342
|
return v;
|
|
4343
4343
|
}
|
|
4344
4344
|
|
|
4345
|
+
/* Ajanın DERİN ARAŞTIRMADA okuduğu sayfalar gizli havuzda açılır (hız için);
|
|
4346
|
+
panel GÖRÜNÜR açıksa sayfa canlı izlensin diye aynı adres görünür view'e de
|
|
4347
|
+
yansıtılır. 500ms debounce + son adres kazanır: paralel okumalar paneli
|
|
4348
|
+
boğmaz, gizli modda (visible=false) hiçbir ek yük bindirmez. */
|
|
4349
|
+
let __mirrorTimer = null;
|
|
4350
|
+
let __mirrorUrl = '';
|
|
4351
|
+
function browserMirror(url) {
|
|
4352
|
+
try {
|
|
4353
|
+
if (!browser.open || !browser.visible) return;
|
|
4354
|
+
if (!browser.view || browser.view.webContents.isDestroyed()) return;
|
|
4355
|
+
const u = String(url || '').trim();
|
|
4356
|
+
if (!/^https?:\/\//i.test(u)) return;
|
|
4357
|
+
__mirrorUrl = u;
|
|
4358
|
+
if (__mirrorTimer) return;
|
|
4359
|
+
__mirrorTimer = setTimeout(() => {
|
|
4360
|
+
__mirrorTimer = null;
|
|
4361
|
+
const target = __mirrorUrl;
|
|
4362
|
+
if (!target || !browser.open || !browser.visible || !browser.view) return;
|
|
4363
|
+
const wc = browser.view.webContents;
|
|
4364
|
+
if (!wc || wc.isDestroyed()) return;
|
|
4365
|
+
let cur = '';
|
|
4366
|
+
try { cur = wc.getURL() || ''; } catch {}
|
|
4367
|
+
if (cur === target) return;
|
|
4368
|
+
try { wc.loadURL(target).catch(() => {}); } catch {}
|
|
4369
|
+
}, 500);
|
|
4370
|
+
} catch {}
|
|
4371
|
+
}
|
|
4372
|
+
|
|
4345
4373
|
async function researchRead(rawUrl, signal) {
|
|
4346
4374
|
const url = String(rawUrl || '').trim();
|
|
4347
4375
|
if (!/^https?:\/\//i.test(url)) return { ok: false, url, error: 'geçersiz adres' };
|
|
@@ -4360,6 +4388,7 @@ async function researchRead(rawUrl, signal) {
|
|
|
4360
4388
|
wc.once('did-finish-load', onDone);
|
|
4361
4389
|
wc.on('did-fail-load', onFail);
|
|
4362
4390
|
wc.loadURL(url).catch(() => {});
|
|
4391
|
+
browserMirror(url); /* panel görünürse ajanın okuduğu sayfa canlı izlenir */
|
|
4363
4392
|
});
|
|
4364
4393
|
/* SPA hidrasyonu için kısa settle; metin boşsa bir kez daha dene */
|
|
4365
4394
|
await new Promise((r) => setTimeout(r, RESEARCH_SETTLE_MS));
|
|
@@ -4589,6 +4618,19 @@ async function browserSearchNow(query, signal, ctx) {
|
|
|
4589
4618
|
? { ok: false, blocked: true, engine: 'browser-google', query: q, error: 'unusual traffic (CAPTCHA)' }
|
|
4590
4619
|
: null;
|
|
4591
4620
|
}
|
|
4621
|
+
/* İZLEME: fetch() sayfayı değiştirmediği için panel google.com ana sayfasında
|
|
4622
|
+
kalıyordu — görünür moddayken gerçek sonuç sayfasına geç ki kullanıcı ajanın
|
|
4623
|
+
ne aradığını canlı görsün (gizli modda ek yük yok; zaten sonuç sayfasındaysa
|
|
4624
|
+
fallback reload'u yapılmaz). */
|
|
4625
|
+
if (browser.visible) {
|
|
4626
|
+
let cur = '';
|
|
4627
|
+
try { cur = wc.getURL() || ''; } catch {}
|
|
4628
|
+
if (!cur.startsWith('https://www.google.com/search')) {
|
|
4629
|
+
try {
|
|
4630
|
+
wc.loadURL('https://www.google.com/search?q=' + encodeURIComponent(q) + '&num=10&hl=tr&pws=0&aep=1').catch(() => {});
|
|
4631
|
+
} catch {}
|
|
4632
|
+
}
|
|
4633
|
+
}
|
|
4592
4634
|
flushBrowserStorage();
|
|
4593
4635
|
const out = { ok: true, engine: 'browser-google', query: q, results };
|
|
4594
4636
|
if (parsed.ai) out.ai = parsed.ai;
|
|
@@ -4931,6 +4973,10 @@ function createSplash() {
|
|
|
4931
4973
|
const bg = dark ? '#0d0d0f' : '#f7f7f8';
|
|
4932
4974
|
const fg = dark ? '#f2f2f4' : '#17171a';
|
|
4933
4975
|
const muted = dark ? '#9a9aa2' : '#707078';
|
|
4976
|
+
let logoUri = '';
|
|
4977
|
+
try {
|
|
4978
|
+
logoUri = 'data:image/png;base64,' + fs.readFileSync(path.join(__dirname, '..', 'assets', 'logo.png')).toString('base64');
|
|
4979
|
+
} catch {}
|
|
4934
4980
|
splash = new BrowserWindow({
|
|
4935
4981
|
width: 420,
|
|
4936
4982
|
height: 352,
|
|
@@ -4944,7 +4990,9 @@ function createSplash() {
|
|
|
4944
4990
|
});
|
|
4945
4991
|
const html = `<!doctype html><html><head><meta charset="utf-8"><style>
|
|
4946
4992
|
body{margin:0;height:100vh;display:flex;flex-direction:column;align-items:center;justify-content:center;background:${bg};font-family:'Segoe UI',sans-serif;color:${fg}}
|
|
4947
|
-
.logo{width:
|
|
4993
|
+
.logo{width:96px;height:96px;display:flex;align-items:center;justify-content:center}
|
|
4994
|
+
.logo img{width:100%;height:100%;object-fit:contain;border-radius:22px}
|
|
4995
|
+
.logo-fb{width:84px;height:84px;border-radius:20px;background:${fg};color:${bg};display:flex;align-items:center;justify-content:center;font-weight:900;font-size:44px}
|
|
4948
4996
|
.t{margin-top:16px;font-size:20px;color:${fg}}.t b{font-weight:900}
|
|
4949
4997
|
.v{margin-top:8px;font-size:12.5px;font-weight:800;letter-spacing:.6px;color:${muted};background:${muted}22;padding:2px 12px;border-radius:9px}
|
|
4950
4998
|
.s{margin-top:6px;font-size:12px;color:${muted}}
|
|
@@ -4955,7 +5003,7 @@ function createSplash() {
|
|
|
4955
5003
|
.bar>i{display:block;height:100%;width:40%;background:${fg};border-radius:2px;animation:sw 1.1s ease-in-out infinite}
|
|
4956
5004
|
@keyframes sw{0%{transform:translateX(-100%)}100%{transform:translateX(260%)}}
|
|
4957
5005
|
</style></head><body>
|
|
4958
|
-
<div class="logo">B</div>
|
|
5006
|
+
${logoUri ? `<div class="logo"><img src="${logoUri}" alt="Beast Agent"></div>` : '<div class="logo-fb">B</div>'}
|
|
4959
5007
|
<div class="t"><b>BEAST</b> Agent</div>
|
|
4960
5008
|
<div class="v">v${beastVersion()}</div>
|
|
4961
5009
|
<div class="s">hızlı · hafif · becerikli</div>
|
package/src/renderer/i18n.js
CHANGED
|
@@ -594,6 +594,7 @@
|
|
|
594
594
|
tipIde: 'IDE Modu — dosyalar + chat + preview',
|
|
595
595
|
tipStudio: 'Beast Studio — video yapma/düzenleme modu',
|
|
596
596
|
tipSandbox: 'Beast Sandbox — GitHub reposu indir & içinde çalış',
|
|
597
|
+
tipMcp: 'Beast MCP — dış araç sunucuları (Model Context Protocol)',
|
|
597
598
|
tipCodeHide: 'Editörü kapat',
|
|
598
599
|
tipCodeShow: 'Editörü göster',
|
|
599
600
|
ide_files: 'DOSYALAR',
|
|
@@ -1387,6 +1388,7 @@
|
|
|
1387
1388
|
tipIde: 'IDE Mode — files + chat + preview',
|
|
1388
1389
|
tipStudio: 'Beast Studio — video making/editing mode',
|
|
1389
1390
|
tipSandbox: 'Beast Sandbox — download a GitHub repo & work inside it',
|
|
1391
|
+
tipMcp: 'Beast MCP — external tool servers (Model Context Protocol)',
|
|
1390
1392
|
tipCodeHide: 'Hide editor',
|
|
1391
1393
|
tipCodeShow: 'Show editor',
|
|
1392
1394
|
ide_files: 'FILES',
|
package/src/renderer/index.html
CHANGED
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta http-equiv="Content-Security-Policy"
|
|
6
|
-
content="default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; media-src 'self' blob: file:; script-src 'self'" />
|
|
6
|
+
content="default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: file:; media-src 'self' blob: file:; script-src 'self'" />
|
|
7
7
|
<title>Beast Agent</title>
|
|
8
8
|
<link rel="stylesheet" href="style.css" />
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<div id="app">
|
|
12
12
|
<aside id="sidebar">
|
|
13
|
-
<div id="brand"><span class="brand-beast">BEAST</span><span class="brand-sub">Agent</span></div>
|
|
13
|
+
<div id="brand"><img id="brandLogo" src="../../assets/logo.png" alt="Beast Agent" draggable="false" /><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
16
|
<div id="watchPane">
|
|
@@ -103,6 +103,7 @@
|
|
|
103
103
|
<button id="studioBtn" class="dd-btn dd-icon-btn" title="Beast Studio — video yapma/düzenleme" data-i18n-title="tipStudio"><svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="6" width="13" height="12" rx="2"/><path d="M15 10l7-4v12l-7-4"/></svg></button>
|
|
104
104
|
<button id="finBtn" class="dd-btn dd-icon-btn" title="Beast Finance — MT5 trade paneli (bilgisayardaki MetaTrader 5 ile çalışır)"><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="M3 3v18h18"/><path d="M7 15l4-5 3 3 5-7"/></svg></button>
|
|
105
105
|
<button id="sbBtn" class="dd-btn dd-icon-btn" title="Beast Sandbox — GitHub reposu indir & içinde çalış" data-i18n-title="tipSandbox"><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="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/><polyline points="3.27 6.96 12 12.01 20.73 6.96"/><line x1="12" y1="22.08" x2="12" y2="12"/></svg></button>
|
|
106
|
+
<button id="mcpBtn" class="dd-btn dd-icon-btn" title="Beast MCP — dış araç sunucuları (Model Context Protocol)" data-i18n-title="tipMcp"><svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="7" rx="2"/><rect x="3" y="13" width="18" height="7" rx="2"/><line x1="7" y1="7.5" x2="7.01" y2="7.5"/><line x1="7" y1="16.5" x2="7.01" y2="16.5"/></svg></button>
|
|
106
107
|
<button id="railBtn" class="dd-btn dd-icon-btn" title="Paralel Ajan Konsolu" data-i18n-title="tipRail">▤</button>
|
|
107
108
|
<button id="dmBtn" class="dd-btn dd-icon-btn" title="Ajan DM — ajanlar arası konuşma" data-i18n-title="tipAgentDm">✉︎</button>
|
|
108
109
|
<button id="watchBtn" class="dd-btn dd-icon-btn" title="İzleyiciler (Watchers)" data-i18n-title="tipWatch">◎</button>
|
|
@@ -120,7 +121,7 @@
|
|
|
120
121
|
|
|
121
122
|
<div id="chatScroll">
|
|
122
123
|
<div id="empty">
|
|
123
|
-
<div id="emptyLogo"
|
|
124
|
+
<div id="emptyLogo"><img src="../../assets/logo.png" alt="Beast Agent" draggable="false" /></div>
|
|
124
125
|
<div id="emptyHint" data-i18n="emptyHint">Hızlı · hafif · becerikli. Ne yapalım?</div>
|
|
125
126
|
</div>
|
|
126
127
|
<div id="msgs"></div>
|
|
@@ -452,6 +453,37 @@
|
|
|
452
453
|
</div>
|
|
453
454
|
</section>
|
|
454
455
|
</div>
|
|
456
|
+
|
|
457
|
+
<div id="mcpRow">
|
|
458
|
+
<section id="mcpPanel">
|
|
459
|
+
<div id="mcpHead">
|
|
460
|
+
<span id="mcpTitle">BEAST MCP</span>
|
|
461
|
+
<span class="file-spacer"></span>
|
|
462
|
+
<button id="mcpReload" title="Durumu yenile">⟳︎</button>
|
|
463
|
+
</div>
|
|
464
|
+
<div id="mcpList"></div>
|
|
465
|
+
<div id="mcpFoot">
|
|
466
|
+
<button id="mcpAddBtn" title="mcp.json'a örnek bir server bloğu ekler">+ Yeni Server</button>
|
|
467
|
+
</div>
|
|
468
|
+
</section>
|
|
469
|
+
<section id="mcpDetail">
|
|
470
|
+
<div id="mcpDetailHead">
|
|
471
|
+
<span id="mcpDetailTitle">Detay</span>
|
|
472
|
+
<span id="mcpDetailState" class="mcp-badge"></span>
|
|
473
|
+
</div>
|
|
474
|
+
<div id="mcpDetailBody"></div>
|
|
475
|
+
<div id="mcpJsonWrap">
|
|
476
|
+
<div id="mcpJsonHead">
|
|
477
|
+
<span>mcp.json</span>
|
|
478
|
+
<span id="mcpJsonPath" title=""></span>
|
|
479
|
+
<span class="file-spacer"></span>
|
|
480
|
+
<span id="mcpMsg"></span>
|
|
481
|
+
<button id="mcpSave">Kaydet</button>
|
|
482
|
+
</div>
|
|
483
|
+
<textarea id="mcpJson" spellcheck="false"></textarea>
|
|
484
|
+
</div>
|
|
485
|
+
</section>
|
|
486
|
+
</div>
|
|
455
487
|
</main>
|
|
456
488
|
|
|
457
489
|
<aside id="rail">
|
package/src/renderer/renderer.js
CHANGED
|
@@ -150,6 +150,18 @@ const els = {
|
|
|
150
150
|
sbRunOut: $('#sbRunOut'),
|
|
151
151
|
sbRunOpen: $('#sbRunOpen'),
|
|
152
152
|
sbRunUrl: $('#sbRunUrl'),
|
|
153
|
+
mcpBtn: $('#mcpBtn'),
|
|
154
|
+
mcpRow: $('#mcpRow'),
|
|
155
|
+
mcpList: $('#mcpList'),
|
|
156
|
+
mcpReload: $('#mcpReload'),
|
|
157
|
+
mcpAddBtn: $('#mcpAddBtn'),
|
|
158
|
+
mcpDetailTitle: $('#mcpDetailTitle'),
|
|
159
|
+
mcpDetailState: $('#mcpDetailState'),
|
|
160
|
+
mcpDetailBody: $('#mcpDetailBody'),
|
|
161
|
+
mcpJson: $('#mcpJson'),
|
|
162
|
+
mcpJsonPath: $('#mcpJsonPath'),
|
|
163
|
+
mcpSave: $('#mcpSave'),
|
|
164
|
+
mcpMsg: $('#mcpMsg'),
|
|
153
165
|
stPanel: $('#stPanel'),
|
|
154
166
|
stTitle: $('#stTitle'),
|
|
155
167
|
stCwd: $('#stCwd'),
|
|
@@ -8358,6 +8370,7 @@ async function setIdeMode(on) {
|
|
|
8358
8370
|
if (on && studioModeOn()) await setStudioMode(false); /* Studio açıkken IDE'ye geçiş — Studio kapanır */
|
|
8359
8371
|
if (on && sbModeOn()) setSandboxMode(false); /* Sandbox açıkken IDE'ye geçiş — Sandbox kapanır */
|
|
8360
8372
|
if (on && financeModeOn()) setFinanceMode(false); /* Finance açıkken IDE'ye geçiş — Finance kapanır */
|
|
8373
|
+
if (on && mcpModeOn()) setMcpMode(false); /* MCP açıkken IDE'ye geçiş — MCP kapanır */
|
|
8361
8374
|
document.body.classList.toggle('ide-mode', !!on);
|
|
8362
8375
|
if (els.ideBtn) els.ideBtn.classList.toggle('on', !!on);
|
|
8363
8376
|
/* soldaki marka: chat modunda BEAST Agent, IDE modunda BEAST Code, Studio modunda BEAST Studio */
|
|
@@ -8433,6 +8446,7 @@ async function setStudioMode(on) {
|
|
|
8433
8446
|
if (on && ideModeOn()) await setIdeMode(false); /* IDE açıkken Studio'ya geçiş — IDE kapanır */
|
|
8434
8447
|
if (on && sbModeOn()) setSandboxMode(false); /* Sandbox açıkken Studio'ya geçiş — Sandbox kapanır */
|
|
8435
8448
|
if (on && financeModeOn()) setFinanceMode(false); /* Finance açıkken Studio'ya geçiş — Finance kapanır */
|
|
8449
|
+
if (on && mcpModeOn()) setMcpMode(false); /* MCP açıkken Studio'ya geçiş — MCP kapanır */
|
|
8436
8450
|
document.body.classList.toggle('studio-mode', !!on);
|
|
8437
8451
|
if (els.studioBtn) els.studioBtn.classList.toggle('on', !!on);
|
|
8438
8452
|
/* ALT TERMINAL: yalnız Beast Code'a özgü — Studio'ya geçişte kapanır */
|
|
@@ -9729,6 +9743,7 @@ async function setFinanceMode(on) {
|
|
|
9729
9743
|
if (on && ideModeOn()) await setIdeMode(false);
|
|
9730
9744
|
if (on && studioModeOn()) await setStudioMode(false);
|
|
9731
9745
|
if (on && sbModeOn()) setSandboxMode(false);
|
|
9746
|
+
if (on && mcpModeOn()) setMcpMode(false); /* MCP açıkken Finance'a geçiş — MCP kapanır */
|
|
9732
9747
|
document.body.classList.toggle('finance-mode', !!on);
|
|
9733
9748
|
if (els.finBtn) els.finBtn.classList.toggle('on', !!on);
|
|
9734
9749
|
const brandSub = document.querySelector('#brand .brand-sub');
|
|
@@ -12262,6 +12277,7 @@ function setSandboxMode(on) {
|
|
|
12262
12277
|
if (on && ideModeOn()) { setIdeMode(false); }
|
|
12263
12278
|
if (on && studioModeOn()) { setStudioMode(false); }
|
|
12264
12279
|
if (on && financeModeOn()) { setFinanceMode(false); }
|
|
12280
|
+
if (on && mcpModeOn()) setMcpMode(false); /* MCP açıkken Sandbox'a geçiş — MCP kapanır */
|
|
12265
12281
|
document.body.classList.toggle('sandbox-mode', !!on);
|
|
12266
12282
|
if (els.sbBtn) els.sbBtn.classList.toggle('on', !!on);
|
|
12267
12283
|
sbPreviewApply();
|
|
@@ -12282,6 +12298,160 @@ function setSandboxMode(on) {
|
|
|
12282
12298
|
}
|
|
12283
12299
|
}
|
|
12284
12300
|
|
|
12301
|
+
/* ================= BEAST MCP MODU =================
|
|
12302
|
+
Model Context Protocol sunucuları: tek panelde durum, araç listesi,
|
|
12303
|
+
aç/kapat, yeniden bağlan ve mcp.json düzenleme. Ana sohbeti bozmaz —
|
|
12304
|
+
diğer modlar gibi body.mcp-mode ile ayrı satır. */
|
|
12305
|
+
function mcpModeOn() {
|
|
12306
|
+
return document.body.classList.contains('mcp-mode');
|
|
12307
|
+
}
|
|
12308
|
+
|
|
12309
|
+
const MCP_STATE_TR = { up: 'BAĞLI', starting: 'BAĞLANIYOR', down: 'HATA', idle: 'BEKLEMEDE', disabled: 'KAPALI' };
|
|
12310
|
+
let mcpSel = '';
|
|
12311
|
+
let mcpTimer = null;
|
|
12312
|
+
|
|
12313
|
+
async function setMcpMode(on) {
|
|
12314
|
+
if (on && ideModeOn()) await setIdeMode(false);
|
|
12315
|
+
if (on && studioModeOn()) await setStudioMode(false);
|
|
12316
|
+
if (on && sbModeOn()) setSandboxMode(false);
|
|
12317
|
+
if (on && financeModeOn()) setFinanceMode(false);
|
|
12318
|
+
document.body.classList.toggle('mcp-mode', !!on);
|
|
12319
|
+
if (els.mcpBtn) els.mcpBtn.classList.toggle('on', !!on);
|
|
12320
|
+
const brandSub = document.querySelector('#brand .brand-sub');
|
|
12321
|
+
if (brandSub) brandSub.textContent = on ? 'MCP' : 'Agent';
|
|
12322
|
+
if (on) {
|
|
12323
|
+
await renderMcpPanel();
|
|
12324
|
+
if (!mcpTimer) {
|
|
12325
|
+
mcpTimer = setInterval(() => { if (mcpModeOn()) renderMcpPanel(); }, 5000);
|
|
12326
|
+
}
|
|
12327
|
+
} else if (mcpTimer) {
|
|
12328
|
+
clearInterval(mcpTimer);
|
|
12329
|
+
mcpTimer = null;
|
|
12330
|
+
}
|
|
12331
|
+
}
|
|
12332
|
+
|
|
12333
|
+
async function renderMcpPanel() {
|
|
12334
|
+
if (!els.mcpList || !mcpModeOn()) return;
|
|
12335
|
+
const st = await beast.mcpStatus().catch(() => ({ path: '', servers: [] }));
|
|
12336
|
+
const cfg = await beast.mcpConfigGet().catch(() => ({ path: '', raw: '' }));
|
|
12337
|
+
const servers = st.servers || [];
|
|
12338
|
+
if (!servers.length) {
|
|
12339
|
+
els.mcpList.innerHTML = '<div class="file-empty">Henüz MCP server yok — aşağıdaki mcp.json\'a ekle ya da “Yeni Server”e bas.</div>';
|
|
12340
|
+
} else {
|
|
12341
|
+
if (!servers.some((s) => s.name === mcpSel)) mcpSel = servers[0].name;
|
|
12342
|
+
els.mcpList.innerHTML = servers.map((s) => {
|
|
12343
|
+
const badge = MCP_STATE_TR[s.state] || s.state;
|
|
12344
|
+
return '<div class="mcp-card' + (s.name === mcpSel ? ' sel' : '') + '" data-n="' + escapeHtml(s.name) + '">' +
|
|
12345
|
+
'<div class="mc-top"><span class="mc-name">' + escapeHtml(s.name) + '</span>' +
|
|
12346
|
+
'<span class="mcp-badge ' + escapeHtml(s.state) + '">' + escapeHtml(badge) + '</span>' +
|
|
12347
|
+
'<span class="file-spacer"></span>' +
|
|
12348
|
+
(s.enabled && s.toolCount ? '<span class="mcp-badge">' + s.toolCount + ' araç</span>' : '') + '</div>' +
|
|
12349
|
+
'<div class="mc-cmd">' + escapeHtml((s.command || '') + ' ' + (s.args || []).join(' ')) + '</div>' +
|
|
12350
|
+
(s.lastError && s.state === 'down' ? '<div class="mc-err">' + escapeHtml(String(s.lastError).slice(0, 140)) + '</div>' : '') +
|
|
12351
|
+
'<div class="mc-actions">' +
|
|
12352
|
+
'<button class="mcp-tgl" data-n="' + escapeHtml(s.name) + '">' + (s.enabled ? '⏸ Durdur' : '▶ Başlat') + '</button>' +
|
|
12353
|
+
'<button class="mcp-ref" data-n="' + escapeHtml(s.name) + '">⟳ Yenile</button>' +
|
|
12354
|
+
'</div></div>';
|
|
12355
|
+
}).join('');
|
|
12356
|
+
}
|
|
12357
|
+
renderMcpDetail(servers.find((s) => s.name === mcpSel) || null);
|
|
12358
|
+
if (els.mcpJson && document.activeElement !== els.mcpJson) {
|
|
12359
|
+
els.mcpJson.value = cfg.raw || JSON.stringify({ servers: {} }, null, 2);
|
|
12360
|
+
}
|
|
12361
|
+
if (els.mcpJsonPath) {
|
|
12362
|
+
els.mcpJsonPath.textContent = cfg.path || '';
|
|
12363
|
+
els.mcpJsonPath.title = cfg.path || '';
|
|
12364
|
+
}
|
|
12365
|
+
|
|
12366
|
+
els.mcpList.querySelectorAll('.mcp-card').forEach((c) => c.addEventListener('click', (ev) => {
|
|
12367
|
+
if (ev.target.closest('button')) return;
|
|
12368
|
+
mcpSel = c.dataset.n;
|
|
12369
|
+
renderMcpPanel();
|
|
12370
|
+
}));
|
|
12371
|
+
els.mcpList.querySelectorAll('.mcp-ref').forEach((b) => b.addEventListener('click', async () => {
|
|
12372
|
+
b.disabled = true;
|
|
12373
|
+
mcpSel = b.dataset.n;
|
|
12374
|
+
await beast.mcpRefresh(b.dataset.n).catch(() => {});
|
|
12375
|
+
renderMcpPanel();
|
|
12376
|
+
}));
|
|
12377
|
+
els.mcpList.querySelectorAll('.mcp-tgl').forEach((b) => b.addEventListener('click', async () => {
|
|
12378
|
+
b.disabled = true;
|
|
12379
|
+
try {
|
|
12380
|
+
const obj = JSON.parse(els.mcpJson.value || '{}');
|
|
12381
|
+
const name = b.dataset.n;
|
|
12382
|
+
if (obj.servers && obj.servers[name]) {
|
|
12383
|
+
obj.servers[name].enabled = obj.servers[name].enabled === false;
|
|
12384
|
+
await beast.mcpConfigSet(JSON.stringify(obj)).catch(() => {});
|
|
12385
|
+
mcpSel = name;
|
|
12386
|
+
}
|
|
12387
|
+
} catch (e) {
|
|
12388
|
+
toast('JSON hatası: ' + String((e && e.message) || e));
|
|
12389
|
+
}
|
|
12390
|
+
renderMcpPanel();
|
|
12391
|
+
}));
|
|
12392
|
+
}
|
|
12393
|
+
|
|
12394
|
+
function renderMcpDetail(s) {
|
|
12395
|
+
if (els.mcpDetailTitle) els.mcpDetailTitle.textContent = s ? s.name : 'Detay';
|
|
12396
|
+
if (els.mcpDetailState) {
|
|
12397
|
+
els.mcpDetailState.className = 'mcp-badge' + (s ? ' ' + s.state : '');
|
|
12398
|
+
els.mcpDetailState.textContent = s ? (MCP_STATE_TR[s.state] || s.state) : '';
|
|
12399
|
+
}
|
|
12400
|
+
if (!els.mcpDetailBody) return;
|
|
12401
|
+
if (!s) {
|
|
12402
|
+
els.mcpDetailBody.innerHTML = '<div class="file-empty">Soldan bir server seç.</div>';
|
|
12403
|
+
return;
|
|
12404
|
+
}
|
|
12405
|
+
const rows = [
|
|
12406
|
+
['Komut', (s.command || '') + ' ' + (s.args || []).join(' ')],
|
|
12407
|
+
['Durum', (MCP_STATE_TR[s.state] || s.state) + (s.enabled ? '' : ' (kapalı)')],
|
|
12408
|
+
['Araç', s.enabled ? String(s.toolCount || 0) + ' araç' : '—'],
|
|
12409
|
+
s.timeoutMs ? ['Zaman aşımı', s.timeoutMs + ' ms'] : null,
|
|
12410
|
+
s.tools && s.tools.length ? ['İzinli liste', s.tools.join(', ')] : null,
|
|
12411
|
+
].filter(Boolean);
|
|
12412
|
+
let html = rows.map(([k, v]) =>
|
|
12413
|
+
'<div class="mcp-drow"><span class="mcp-dk">' + escapeHtml(k) + '</span><span>' + escapeHtml(String(v)) + '</span></div>'
|
|
12414
|
+
).join('');
|
|
12415
|
+
if (s.lastError && s.state === 'down') {
|
|
12416
|
+
html += '<div class="mcp-drow"><span class="mcp-dk">Hata</span><span style="color:var(--err)">' + escapeHtml(s.lastError) + '</span></div>';
|
|
12417
|
+
}
|
|
12418
|
+
if (s.toolNames && s.toolNames.length) {
|
|
12419
|
+
html += '<div class="mcp-dk" style="margin-top:10px">Araçlar</div><div class="mcp-tools">' +
|
|
12420
|
+
s.toolNames.map((t) => '<span class="mcp-tool">' + escapeHtml(t) + '</span>').join('') + '</div>';
|
|
12421
|
+
} else if (s.enabled) {
|
|
12422
|
+
html += '<div class="file-empty">Araç listesi için ⟳ Yenile (server ilk kullanımda bağlanır).</div>';
|
|
12423
|
+
}
|
|
12424
|
+
els.mcpDetailBody.innerHTML = html;
|
|
12425
|
+
}
|
|
12426
|
+
|
|
12427
|
+
if (els.mcpBtn) els.mcpBtn.addEventListener('click', () => setMcpMode(!mcpModeOn()));
|
|
12428
|
+
if (els.mcpReload) els.mcpReload.addEventListener('click', () => renderMcpPanel());
|
|
12429
|
+
if (els.mcpSave) els.mcpSave.addEventListener('click', async () => {
|
|
12430
|
+
const r = await beast.mcpConfigSet(els.mcpJson.value || '').catch(() => ({ ok: false, error: 'IPC' }));
|
|
12431
|
+
if (els.mcpMsg) {
|
|
12432
|
+
els.mcpMsg.textContent = r && r.ok ? 'Kaydedildi' : ('Hata: ' + ((r && r.error) || '?'));
|
|
12433
|
+
els.mcpMsg.style.color = r && r.ok ? '' : 'var(--err)';
|
|
12434
|
+
}
|
|
12435
|
+
if (r && r.ok) renderMcpPanel();
|
|
12436
|
+
});
|
|
12437
|
+
if (els.mcpAddBtn) els.mcpAddBtn.addEventListener('click', () => {
|
|
12438
|
+
if (!els.mcpJson) return;
|
|
12439
|
+
try {
|
|
12440
|
+
const obj = JSON.parse(els.mcpJson.value || '{}') || {};
|
|
12441
|
+
obj.servers = obj.servers || {};
|
|
12442
|
+
let i = 1;
|
|
12443
|
+
let name = 'yeni-server';
|
|
12444
|
+
while (obj.servers[name]) name = 'yeni-server' + (++i);
|
|
12445
|
+
obj.servers[name] = { command: 'npx', args: ['-y', '@modelcontextprotocol/server-filesystem', 'C:/'], enabled: false };
|
|
12446
|
+
els.mcpJson.value = JSON.stringify(obj, null, 2);
|
|
12447
|
+
els.mcpJson.focus();
|
|
12448
|
+
if (els.mcpMsg) {
|
|
12449
|
+
els.mcpMsg.textContent = 'örnek eklendi — komutu düzenleyip Kaydet';
|
|
12450
|
+
els.mcpMsg.style.color = '';
|
|
12451
|
+
}
|
|
12452
|
+
} catch {}
|
|
12453
|
+
});
|
|
12454
|
+
|
|
12285
12455
|
/* ---------- ÇALIŞTIRICI v2: butonlar DETERMİNİSTİK ----------
|
|
12286
12456
|
Proje tipi algılanır (package.json/requirements.txt/pyproject/Cargo.toml/
|
|
12287
12457
|
go.mod/hugo/jekyll/mkdocs/index.html); Başlat/Dev gerekirse bağımlılıkları
|
package/src/renderer/style.css
CHANGED
|
@@ -88,14 +88,26 @@ body {
|
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
#brand {
|
|
91
|
-
padding:
|
|
91
|
+
padding: 14px 16px 12px;
|
|
92
92
|
letter-spacing: 3px;
|
|
93
93
|
font-weight: 800;
|
|
94
94
|
text-align: center;
|
|
95
95
|
-webkit-app-region: drag;
|
|
96
|
+
display: flex;
|
|
97
|
+
align-items: center;
|
|
98
|
+
justify-content: center;
|
|
99
|
+
gap: 7px;
|
|
100
|
+
}
|
|
101
|
+
#brandLogo {
|
|
102
|
+
width: 26px;
|
|
103
|
+
height: 26px;
|
|
104
|
+
display: block;
|
|
105
|
+
flex: none;
|
|
106
|
+
box-shadow: 0 0 0 1px var(--border);
|
|
107
|
+
border-radius: 6px;
|
|
96
108
|
}
|
|
97
109
|
.brand-beast { color: var(--accent); font-size: 17px; }
|
|
98
|
-
.brand-sub { color: var(--muted); font-size: 11px;
|
|
110
|
+
.brand-sub { color: var(--muted); font-size: 11px; letter-spacing: 2px; }
|
|
99
111
|
|
|
100
112
|
#newChat {
|
|
101
113
|
margin: 4px 12px 10px;
|
|
@@ -860,12 +872,18 @@ body.term-dragging * { cursor: row-resize !important; }
|
|
|
860
872
|
gap: 10px;
|
|
861
873
|
}
|
|
862
874
|
#emptyLogo {
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
875
|
+
width: 132px;
|
|
876
|
+
height: 132px;
|
|
877
|
+
opacity: 0.95;
|
|
878
|
+
}
|
|
879
|
+
#emptyLogo img {
|
|
880
|
+
width: 100%;
|
|
881
|
+
height: 100%;
|
|
882
|
+
object-fit: contain;
|
|
883
|
+
display: block;
|
|
884
|
+
box-shadow: 0 0 0 1px var(--border);
|
|
885
|
+
border-radius: 26px;
|
|
886
|
+
filter: drop-shadow(0 12px 32px rgba(0, 0, 0, 0.28));
|
|
869
887
|
}
|
|
870
888
|
#emptyHint { color: var(--muted); }
|
|
871
889
|
|
|
@@ -4489,6 +4507,206 @@ body.sandbox-mode #sandboxRow { display: flex; flex-direction: row; }
|
|
|
4489
4507
|
padding: 0 16px;
|
|
4490
4508
|
text-align: center;
|
|
4491
4509
|
}
|
|
4510
|
+
|
|
4511
|
+
/* ---------- MCP MODU ---------- */
|
|
4512
|
+
body.mcp-mode #chatScroll,
|
|
4513
|
+
body.mcp-mode #composerWrap,
|
|
4514
|
+
body.mcp-mode #ideRow,
|
|
4515
|
+
body.mcp-mode #studioRow,
|
|
4516
|
+
body.mcp-mode #sandboxRow { display: none; }
|
|
4517
|
+
|
|
4518
|
+
#mcpRow { display: none; flex: 1; min-height: 0; }
|
|
4519
|
+
body.mcp-mode #mcpRow { display: flex; flex-direction: row; }
|
|
4520
|
+
|
|
4521
|
+
#mcpPanel {
|
|
4522
|
+
display: flex;
|
|
4523
|
+
flex-direction: column;
|
|
4524
|
+
min-height: 0;
|
|
4525
|
+
min-width: 280px;
|
|
4526
|
+
flex: 0 0 380px;
|
|
4527
|
+
background: var(--bg);
|
|
4528
|
+
overflow: hidden;
|
|
4529
|
+
}
|
|
4530
|
+
#mcpDetail {
|
|
4531
|
+
display: flex;
|
|
4532
|
+
flex-direction: column;
|
|
4533
|
+
flex: 1;
|
|
4534
|
+
min-width: 0;
|
|
4535
|
+
min-height: 0;
|
|
4536
|
+
background: var(--bg);
|
|
4537
|
+
border-left: 1px solid var(--border);
|
|
4538
|
+
}
|
|
4539
|
+
#mcpHead {
|
|
4540
|
+
flex: none;
|
|
4541
|
+
display: flex;
|
|
4542
|
+
align-items: center;
|
|
4543
|
+
gap: 8px;
|
|
4544
|
+
padding: 9px 12px;
|
|
4545
|
+
border-bottom: 1px solid var(--border);
|
|
4546
|
+
background: var(--panel);
|
|
4547
|
+
}
|
|
4548
|
+
#mcpTitle { font-size: 11px; font-weight: 800; letter-spacing: 1px; color: var(--accent); flex: none; }
|
|
4549
|
+
#mcpHead button {
|
|
4550
|
+
background: none;
|
|
4551
|
+
border: none;
|
|
4552
|
+
color: var(--muted);
|
|
4553
|
+
font-size: 14px;
|
|
4554
|
+
cursor: pointer;
|
|
4555
|
+
padding: 2px 7px;
|
|
4556
|
+
border-radius: 6px;
|
|
4557
|
+
}
|
|
4558
|
+
#mcpHead button:hover { background: var(--panel2); color: var(--text); }
|
|
4559
|
+
#mcpList {
|
|
4560
|
+
flex: 1;
|
|
4561
|
+
min-height: 0;
|
|
4562
|
+
overflow-y: auto;
|
|
4563
|
+
padding: 10px 12px;
|
|
4564
|
+
}
|
|
4565
|
+
#mcpFoot {
|
|
4566
|
+
flex: none;
|
|
4567
|
+
padding: 8px 12px;
|
|
4568
|
+
border-top: 1px solid var(--border);
|
|
4569
|
+
background: var(--panel);
|
|
4570
|
+
}
|
|
4571
|
+
#mcpFoot button {
|
|
4572
|
+
width: 100%;
|
|
4573
|
+
background: var(--panel2);
|
|
4574
|
+
border: 1px solid var(--border);
|
|
4575
|
+
color: var(--text);
|
|
4576
|
+
font-size: 12px;
|
|
4577
|
+
padding: 6px 10px;
|
|
4578
|
+
border-radius: 7px;
|
|
4579
|
+
cursor: pointer;
|
|
4580
|
+
}
|
|
4581
|
+
#mcpFoot button:hover { border-color: var(--accent); }
|
|
4582
|
+
|
|
4583
|
+
.mcp-card {
|
|
4584
|
+
border: 1px solid var(--border);
|
|
4585
|
+
border-radius: 9px;
|
|
4586
|
+
padding: 9px 10px;
|
|
4587
|
+
margin-bottom: 8px;
|
|
4588
|
+
background: var(--panel);
|
|
4589
|
+
cursor: pointer;
|
|
4590
|
+
}
|
|
4591
|
+
.mcp-card:hover { border-color: var(--accent); }
|
|
4592
|
+
.mcp-card.sel { border-color: var(--accent); background: var(--panel2); }
|
|
4593
|
+
.mcp-card .mc-top { display: flex; align-items: center; gap: 7px; }
|
|
4594
|
+
.mcp-card .mc-name { font-weight: 700; font-size: 13px; }
|
|
4595
|
+
.mcp-card .mc-cmd {
|
|
4596
|
+
font-family: Consolas, monospace;
|
|
4597
|
+
font-size: 11px;
|
|
4598
|
+
color: var(--muted);
|
|
4599
|
+
margin-top: 4px;
|
|
4600
|
+
overflow: hidden;
|
|
4601
|
+
text-overflow: ellipsis;
|
|
4602
|
+
white-space: nowrap;
|
|
4603
|
+
}
|
|
4604
|
+
.mcp-card .mc-err {
|
|
4605
|
+
color: var(--err);
|
|
4606
|
+
font-size: 11px;
|
|
4607
|
+
margin-top: 4px;
|
|
4608
|
+
overflow: hidden;
|
|
4609
|
+
text-overflow: ellipsis;
|
|
4610
|
+
white-space: nowrap;
|
|
4611
|
+
}
|
|
4612
|
+
.mcp-card .mc-actions { display: flex; gap: 6px; margin-top: 7px; }
|
|
4613
|
+
.mcp-card .mc-actions button {
|
|
4614
|
+
background: var(--panel2);
|
|
4615
|
+
border: 1px solid var(--border);
|
|
4616
|
+
color: var(--text);
|
|
4617
|
+
font-size: 11px;
|
|
4618
|
+
padding: 3px 9px;
|
|
4619
|
+
border-radius: 6px;
|
|
4620
|
+
cursor: pointer;
|
|
4621
|
+
}
|
|
4622
|
+
.mcp-card .mc-actions button:hover { border-color: var(--accent); }
|
|
4623
|
+
|
|
4624
|
+
.mcp-badge {
|
|
4625
|
+
flex: none;
|
|
4626
|
+
font-size: 9.5px;
|
|
4627
|
+
font-weight: 800;
|
|
4628
|
+
letter-spacing: 0.5px;
|
|
4629
|
+
padding: 1px 6px;
|
|
4630
|
+
border-radius: 4px;
|
|
4631
|
+
border: 1px solid var(--border);
|
|
4632
|
+
color: var(--muted);
|
|
4633
|
+
text-transform: uppercase;
|
|
4634
|
+
}
|
|
4635
|
+
.mcp-badge.up { color: #22c55e; border-color: #22c55e; }
|
|
4636
|
+
.mcp-badge.down { color: var(--err); border-color: var(--err); }
|
|
4637
|
+
.mcp-badge.starting { color: var(--accent); border-color: var(--accent); }
|
|
4638
|
+
|
|
4639
|
+
#mcpDetailHead {
|
|
4640
|
+
flex: none;
|
|
4641
|
+
display: flex;
|
|
4642
|
+
align-items: center;
|
|
4643
|
+
gap: 10px;
|
|
4644
|
+
padding: 9px 14px;
|
|
4645
|
+
border-bottom: 1px solid var(--border);
|
|
4646
|
+
background: var(--panel);
|
|
4647
|
+
}
|
|
4648
|
+
#mcpDetailTitle { font-weight: 700; font-size: 13px; }
|
|
4649
|
+
#mcpDetailState { margin-left: auto; }
|
|
4650
|
+
#mcpDetailBody { flex: 1; min-height: 0; overflow-y: auto; padding: 12px 14px; }
|
|
4651
|
+
.mcp-drow { display: flex; gap: 8px; margin-bottom: 6px; font-size: 12.5px; }
|
|
4652
|
+
.mcp-dk { color: var(--muted); min-width: 76px; flex: none; }
|
|
4653
|
+
.mcp-tools { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
|
|
4654
|
+
.mcp-tool {
|
|
4655
|
+
font-family: Consolas, monospace;
|
|
4656
|
+
font-size: 11px;
|
|
4657
|
+
border: 1px solid var(--border);
|
|
4658
|
+
background: var(--panel2);
|
|
4659
|
+
padding: 2px 7px;
|
|
4660
|
+
border-radius: 6px;
|
|
4661
|
+
}
|
|
4662
|
+
#mcpJsonWrap {
|
|
4663
|
+
flex: none;
|
|
4664
|
+
display: flex;
|
|
4665
|
+
flex-direction: column;
|
|
4666
|
+
max-height: 40%;
|
|
4667
|
+
border-top: 1px solid var(--border);
|
|
4668
|
+
background: var(--panel);
|
|
4669
|
+
}
|
|
4670
|
+
#mcpJsonHead {
|
|
4671
|
+
flex: none;
|
|
4672
|
+
display: flex;
|
|
4673
|
+
align-items: center;
|
|
4674
|
+
gap: 8px;
|
|
4675
|
+
padding: 7px 12px;
|
|
4676
|
+
font-size: 11px;
|
|
4677
|
+
color: var(--muted);
|
|
4678
|
+
}
|
|
4679
|
+
#mcpJsonPath {
|
|
4680
|
+
max-width: 45%;
|
|
4681
|
+
overflow: hidden;
|
|
4682
|
+
text-overflow: ellipsis;
|
|
4683
|
+
white-space: nowrap;
|
|
4684
|
+
font-family: Consolas, monospace;
|
|
4685
|
+
}
|
|
4686
|
+
#mcpSave {
|
|
4687
|
+
background: var(--panel2);
|
|
4688
|
+
border: 1px solid var(--border);
|
|
4689
|
+
color: var(--accent);
|
|
4690
|
+
font-size: 11px;
|
|
4691
|
+
padding: 3px 10px;
|
|
4692
|
+
border-radius: 6px;
|
|
4693
|
+
cursor: pointer;
|
|
4694
|
+
}
|
|
4695
|
+
#mcpSave:hover { border-color: var(--accent); }
|
|
4696
|
+
#mcpJson {
|
|
4697
|
+
flex: 1;
|
|
4698
|
+
min-height: 110px;
|
|
4699
|
+
resize: none;
|
|
4700
|
+
background: var(--bg);
|
|
4701
|
+
border: none;
|
|
4702
|
+
border-top: 1px solid var(--border);
|
|
4703
|
+
color: var(--text);
|
|
4704
|
+
font-family: Consolas, monospace;
|
|
4705
|
+
font-size: 12px;
|
|
4706
|
+
padding: 8px 12px;
|
|
4707
|
+
outline: none;
|
|
4708
|
+
white-space: pre;
|
|
4709
|
+
}
|
|
4492
4710
|
#sbRunBtns {
|
|
4493
4711
|
flex: none;
|
|
4494
4712
|
display: flex;
|