beast-agent 2.40.0 → 2.42.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/package.json +1 -1
- package/src/agent/engine.js +50 -0
- package/src/agent/opencode/agents.js +4 -3
- package/src/agent/tools.js +16 -0
- package/src/main.js +482 -38
- package/src/preload.js +7 -1
- package/src/renderer/index.html +11 -4
- package/src/renderer/renderer.js +270 -40
- package/src/renderer/style.css +74 -3
package/src/preload.js
CHANGED
|
@@ -185,8 +185,14 @@ contextBridge.exposeInMainWorld('beast', {
|
|
|
185
185
|
sandboxOpen: (payload) => ipcRenderer.invoke('sandbox:open', payload),
|
|
186
186
|
sandboxTree: (payload) => ipcRenderer.invoke('sandbox:tree', payload),
|
|
187
187
|
sandboxRun: (payload) => ipcRenderer.invoke('sandbox:run', payload),
|
|
188
|
-
sandboxRunStop: () => ipcRenderer.invoke('sandbox:runstop'),
|
|
188
|
+
sandboxRunStop: (payload) => ipcRenderer.invoke('sandbox:runstop', payload),
|
|
189
|
+
sandboxDetect: (payload) => ipcRenderer.invoke('sandbox:detect', payload),
|
|
190
|
+
sandboxInstall: (payload) => ipcRenderer.invoke('sandbox:install', payload),
|
|
191
|
+
sandboxStart: (payload) => ipcRenderer.invoke('sandbox:start', payload),
|
|
192
|
+
sandboxProcState: (payload) => ipcRenderer.invoke('sandbox:procstate', payload),
|
|
193
|
+
sandboxCfgSet: (payload) => ipcRenderer.invoke('sandbox:cfg:set', payload),
|
|
189
194
|
sandboxOpenUrl: (url) => ipcRenderer.invoke('sandbox:openurl', url),
|
|
195
|
+
sbPreviewSet: (payload) => ipcRenderer.invoke('sbpreview:set', payload),
|
|
190
196
|
waStart: () => ipcRenderer.invoke('wa:start'),
|
|
191
197
|
waStop: () => ipcRenderer.invoke('wa:stop'),
|
|
192
198
|
waReset: () => ipcRenderer.invoke('wa:reset'),
|
package/src/renderer/index.html
CHANGED
|
@@ -419,28 +419,35 @@
|
|
|
419
419
|
<div id="sbStatus" hidden></div>
|
|
420
420
|
<div id="sbInputRow">
|
|
421
421
|
<textarea id="sbInput" rows="1" spellcheck="false" autocomplete="off" placeholder="Sandbox mesajı — ajan bu repo klasöründe çalışır…"></textarea>
|
|
422
|
+
<button id="sbSend" title="Gönder (Enter)"><svg viewBox="0 0 24 24" width="13" height="13" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg></button>
|
|
422
423
|
<button id="sbStop" title="Çalışan mesajı durdur" hidden data-i18n-title="bc_stop"><svg viewBox="0 0 24 24" width="13" height="13" fill="currentColor" stroke="none"><rect x="6" y="6" width="12" height="12" rx="2"/></svg></button>
|
|
423
424
|
</div>
|
|
424
425
|
</section>
|
|
425
426
|
|
|
427
|
+
<div id="sbSplit" title="Sürükleyerek boyutlandır"></div>
|
|
428
|
+
|
|
426
429
|
<section id="sbRun">
|
|
427
430
|
<div id="sbRunHead">
|
|
428
431
|
<span id="sbRunTitle">ÇALIŞTIR</span>
|
|
432
|
+
<span id="sbRunKind"></span>
|
|
429
433
|
<span id="sbRunCwd" title="">—</span>
|
|
434
|
+
<span class="file-spacer"></span>
|
|
435
|
+
<button id="sbRunView" class="on" title="Görsel önizleme açık — çıktıya dön">Görsel</button>
|
|
430
436
|
</div>
|
|
431
437
|
<div id="sbRunBtns">
|
|
432
|
-
<button id="
|
|
433
|
-
<button id="
|
|
434
|
-
<button id="sbRunDev" title="Ajana talimat: geliştirme modunda başlat (dev)"><svg viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:-2px;margin-right:3px"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg>Dev</button>
|
|
438
|
+
<button id="sbRunStart" title="Başlat — gerekirse bağımlılıkları kurar, sonra çalıştırır (adres panelde canlı önizlemede açılır)"><svg viewBox="0 0 24 24" width="12" height="12" fill="currentColor" stroke="none" style="vertical-align:-2px;margin-right:3px"><polygon points="6 3 20 12 6 21 6 3"/></svg>Başlat</button>
|
|
439
|
+
<button id="sbRunDev" title="Geliştirme modunda başlat (gerekirse önce kurar)"><svg viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:-2px;margin-right:3px"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg>Dev</button>
|
|
435
440
|
<button id="sbRunStop" title="Süreci durdur" hidden><svg viewBox="0 0 24 24" width="12" height="12" fill="currentColor" stroke="none" style="vertical-align:-2px;margin-right:3px"><rect x="6" y="6" width="12" height="12" rx="2"/></svg>Durdur</button>
|
|
436
441
|
</div>
|
|
437
442
|
<div id="sbRunCustom">
|
|
438
443
|
<input id="sbRunCmd" placeholder="özel komut: python main.py, cargo run, node index.js…" spellcheck="false" autocomplete="off" />
|
|
439
444
|
<button id="sbRunGo" title="Çalıştır"><svg viewBox="0 0 24 24" width="12" height="12" fill="currentColor" stroke="none"><polygon points="6 3 20 12 6 21 6 3"/></svg></button>
|
|
445
|
+
<button id="sbRunSave" title="Yazılan komutu bu reponun başlatma komutu olarak kaydet"><svg viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/><polyline points="17 21 17 13 7 13 7 21"/><polyline points="7 3 7 8 15 8"/></svg></button>
|
|
440
446
|
</div>
|
|
447
|
+
<div id="sbPreviewHost" hidden><div id="sbPreviewHint">🌐 canlı önizleme — Başlat/Dev ile sunucu açılınca burada görünür</div></div>
|
|
441
448
|
<div id="sbRunOut"></div>
|
|
442
449
|
<div id="sbRunFoot">
|
|
443
|
-
<button id="sbRunOpen" title="
|
|
450
|
+
<button id="sbRunOpen" title="Önizlemeyi sağdaki dahili tarayıcıda aç" disabled><svg viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:-2px;margin-right:3px"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg><span id="sbRunOpenLabel">Tarayıcıda aç</span></button>
|
|
444
451
|
<span id="sbRunUrl" title=""></span>
|
|
445
452
|
</div>
|
|
446
453
|
</section>
|
package/src/renderer/renderer.js
CHANGED
|
@@ -135,13 +135,18 @@ const els = {
|
|
|
135
135
|
sbStatus: $('#sbStatus'),
|
|
136
136
|
sbInput: $('#sbInput'),
|
|
137
137
|
sbStop: $('#sbStop'),
|
|
138
|
+
sbSend: $('#sbSend'),
|
|
139
|
+
sbSplit: $('#sbSplit'),
|
|
140
|
+
sbRun: $('#sbRun'),
|
|
138
141
|
sbRunCwd: $('#sbRunCwd'),
|
|
139
|
-
|
|
142
|
+
sbRunView: $('#sbRunView'),
|
|
143
|
+
sbRunKind: $('#sbRunKind'),
|
|
140
144
|
sbRunStart: $('#sbRunStart'),
|
|
141
145
|
sbRunDev: $('#sbRunDev'),
|
|
142
146
|
sbRunStop: $('#sbRunStop'),
|
|
143
147
|
sbRunCmd: $('#sbRunCmd'),
|
|
144
148
|
sbRunGo: $('#sbRunGo'),
|
|
149
|
+
sbRunSave: $('#sbRunSave'),
|
|
145
150
|
sbRunOut: $('#sbRunOut'),
|
|
146
151
|
sbRunOpen: $('#sbRunOpen'),
|
|
147
152
|
sbRunUrl: $('#sbRunUrl'),
|
|
@@ -5998,6 +6003,7 @@ function onEvent(ev) {
|
|
|
5998
6003
|
/* IDE modunda tarayıcı açılır/kapanır/genişlik değişirse row yeniden bölünür —
|
|
5999
6004
|
editör + Beast Code ORTAK kırpılıp ORTAK açılır (kullanıcı payı korunur) */
|
|
6000
6005
|
if (ideModeOn()) ideSplitApplyFrac();
|
|
6006
|
+
if (sbModeOn()) sbSplitApplyFrac();
|
|
6001
6007
|
if (shown) {
|
|
6002
6008
|
els.browserBtn.classList.add('on');
|
|
6003
6009
|
if (ev.url && document.activeElement !== els.bbUrl) {
|
|
@@ -11964,6 +11970,11 @@ let sbCloning = false;
|
|
|
11964
11970
|
const sbTreeState = { cache: new Map(), open: new Set(['']), path: '' };
|
|
11965
11971
|
let sbRunUrl = '';
|
|
11966
11972
|
let sbRunRunning = false;
|
|
11973
|
+
let sbRunInfo = null;
|
|
11974
|
+
let sbAutoAssist = null; /* butonla başlatılan süreç hızlı çökerse: 'install' | 'run' */
|
|
11975
|
+
let sbPreviewOn = true; /* ÇALIŞTIR içi görsel önizleme tercihi */
|
|
11976
|
+
let sbPreviewShown = false;
|
|
11977
|
+
let sbPreviewSuspend = false; /* ayırıcı sürüklenirken native view gizli tutulur */
|
|
11967
11978
|
|
|
11968
11979
|
function sbModeOn() {
|
|
11969
11980
|
return document.body.classList.contains('sandbox-mode');
|
|
@@ -12095,7 +12106,7 @@ async function loadSandboxList() {
|
|
|
12095
12106
|
for (const it of sbItems) {
|
|
12096
12107
|
const o = document.createElement('option');
|
|
12097
12108
|
o.value = it.folder;
|
|
12098
|
-
o.textContent = it.name + (it.busy ? ' ●' : '');
|
|
12109
|
+
o.textContent = it.name + (it.busy ? ' ●' : '') + (it.running ? ' ▶' : '');
|
|
12099
12110
|
sel.appendChild(o);
|
|
12100
12111
|
}
|
|
12101
12112
|
if (sbFolder && sbItems.some((x) => x.folder === sbFolder)) sel.value = sbFolder;
|
|
@@ -12140,6 +12151,32 @@ async function sbSelectCurrent() {
|
|
|
12140
12151
|
sbLine('t-err', (r && r.error) || 'oturum açılamadı');
|
|
12141
12152
|
}
|
|
12142
12153
|
sbSetBusy(!!(r && r.busy));
|
|
12154
|
+
/* yönetilen süreç durumu: repo değişince arka plandaki süreç + tampon çıktı geri yüklenir */
|
|
12155
|
+
sbRunInfo = null;
|
|
12156
|
+
const st = await beast.sandboxProcState({ folder: sbFolder }).catch(() => null);
|
|
12157
|
+
if (st && st.ok) {
|
|
12158
|
+
sbRunUrl = st.url || '';
|
|
12159
|
+
sbRunRunning = !!st.running;
|
|
12160
|
+
if (els.sbRunStop) els.sbRunStop.hidden = !sbRunRunning;
|
|
12161
|
+
if (els.sbRunOpen) els.sbRunOpen.disabled = !sbRunUrl;
|
|
12162
|
+
if (els.sbRunUrl) els.sbRunUrl.textContent = sbRunUrl || '';
|
|
12163
|
+
for (const l of st.lines || []) sbRunLine(l);
|
|
12164
|
+
}
|
|
12165
|
+
/* proje tipi algıla: butonlar hangi komutu çalıştıracağını bilir */
|
|
12166
|
+
const det = await beast.sandboxDetect({ folder: sbFolder }).catch(() => null);
|
|
12167
|
+
if (det && det.ok && det.info) {
|
|
12168
|
+
sbRunInfo = det.info;
|
|
12169
|
+
if (els.sbRunKind) els.sbRunKind.textContent = det.info.label || '';
|
|
12170
|
+
if (els.sbRunCmd) {
|
|
12171
|
+
els.sbRunCmd.placeholder = det.info.run
|
|
12172
|
+
? 'özel komut (algılanan: ' + det.info.run + ')…'
|
|
12173
|
+
: 'özel komut: python main.py, cargo run, node index.js…';
|
|
12174
|
+
}
|
|
12175
|
+
if (!sbRunRunning && !(st && (st.lines || []).length)) {
|
|
12176
|
+
sbRunLine('ℹ ' + (det.info.label || 'proje') + ' · kur: ' + (det.info.install || '—') + ' · çalıştır: ' + (det.info.run || '—'), 't-dim');
|
|
12177
|
+
}
|
|
12178
|
+
}
|
|
12179
|
+
sbPreviewApply();
|
|
12143
12180
|
/* sol konsol: seçilen reponun klasörü — oturum açıldıktan sonra da garanti tazele */
|
|
12144
12181
|
sbTreeState.cache.clear();
|
|
12145
12182
|
if (sbModeOn()) renderFileTree().catch(() => {});
|
|
@@ -12155,7 +12192,8 @@ function sbInputResize() {
|
|
|
12155
12192
|
|
|
12156
12193
|
function sbRunCurrent() {
|
|
12157
12194
|
const msg = els.sbInput.value.trim();
|
|
12158
|
-
if (!msg ||
|
|
12195
|
+
if (!msg || sbCloning) return;
|
|
12196
|
+
if (!sbFolder) { toast('Önce repo indir ya da seç'); return; }
|
|
12159
12197
|
els.sbInput.value = '';
|
|
12160
12198
|
sbInputResize();
|
|
12161
12199
|
sbLine('t-cmd', 'sen> ' + msg);
|
|
@@ -12226,6 +12264,7 @@ function setSandboxMode(on) {
|
|
|
12226
12264
|
if (on && financeModeOn()) { setFinanceMode(false); }
|
|
12227
12265
|
document.body.classList.toggle('sandbox-mode', !!on);
|
|
12228
12266
|
if (els.sbBtn) els.sbBtn.classList.toggle('on', !!on);
|
|
12267
|
+
sbPreviewApply();
|
|
12229
12268
|
/* marka + sol konsol başlığı: moduna göre BEAST Agent/Code/Studio/Sandbox */
|
|
12230
12269
|
const brandSub = document.querySelector('#brand .brand-sub');
|
|
12231
12270
|
if (brandSub) brandSub.textContent = on ? 'Sandbox' : 'Agent';
|
|
@@ -12233,6 +12272,7 @@ function setSandboxMode(on) {
|
|
|
12233
12272
|
if (ftp && on) ftp.textContent = 'REPO DOSYALARI';
|
|
12234
12273
|
if (on) {
|
|
12235
12274
|
loadSandboxList();
|
|
12275
|
+
sbSplitRestore();
|
|
12236
12276
|
sbTreeState.cache.clear();
|
|
12237
12277
|
renderFileTree().catch(() => {});
|
|
12238
12278
|
} else if (!ideModeOn() && !studioModeOn()) {
|
|
@@ -12242,26 +12282,27 @@ function setSandboxMode(on) {
|
|
|
12242
12282
|
}
|
|
12243
12283
|
}
|
|
12244
12284
|
|
|
12245
|
-
/* ---------- ÇALIŞTIRICI: butonlar
|
|
12246
|
-
|
|
12247
|
-
|
|
12248
|
-
|
|
12249
|
-
function
|
|
12285
|
+
/* ---------- ÇALIŞTIRICI v2: butonlar DETERMİNİSTİK ----------
|
|
12286
|
+
Proje tipi algılanır (package.json/requirements.txt/pyproject/Cargo.toml/
|
|
12287
|
+
go.mod/hugo/jekyll/mkdocs/index.html); Başlat/Dev gerekirse bağımlılıkları
|
|
12288
|
+
ÖNCE kurar (npm install && npm run dev gibi), süreç panelde canlı akar. */
|
|
12289
|
+
async function sbRunLaunch(mode) {
|
|
12250
12290
|
if (!sbFolder) { toast('Önce repo indir ya da seç'); return; }
|
|
12251
|
-
|
|
12252
|
-
|
|
12253
|
-
beast.
|
|
12254
|
-
|
|
12255
|
-
|
|
12256
|
-
|
|
12257
|
-
|
|
12258
|
-
|
|
12259
|
-
|
|
12260
|
-
|
|
12261
|
-
|
|
12262
|
-
|
|
12263
|
-
|
|
12264
|
-
|
|
12291
|
+
if (sbRunRunning) { toast('Bu repoda süreç çalışıyor — önce ■ Durdur'); return; }
|
|
12292
|
+
sbAutoAssist = mode;
|
|
12293
|
+
const r = await beast.sandboxStart({ folder: sbFolder, mode: mode === 'dev' ? 'dev' : 'run' })
|
|
12294
|
+
.catch((e) => ({ ok: false, error: String((e && e.message) || e) }));
|
|
12295
|
+
if (!r || !r.ok) {
|
|
12296
|
+
sbAutoAssist = null;
|
|
12297
|
+
const err = (r && r.error) || 'başlatılamadı';
|
|
12298
|
+
sbRunLine('[hata] ' + err, 't-err');
|
|
12299
|
+
/* algılama komut bulamadıysa ajan devralır: repo yapısından doğru komutu bulur */
|
|
12300
|
+
if (/algılanamadı/.test(err)) sbAskAgent(mode);
|
|
12301
|
+
return;
|
|
12302
|
+
}
|
|
12303
|
+
sbRunRunning = true;
|
|
12304
|
+
if (els.sbRunStop) els.sbRunStop.hidden = false;
|
|
12305
|
+
sbBadge(sbFolder, true);
|
|
12265
12306
|
}
|
|
12266
12307
|
|
|
12267
12308
|
function sbRunLine(text, cls) {
|
|
@@ -12274,8 +12315,28 @@ function sbRunLine(text, cls) {
|
|
|
12274
12315
|
return div;
|
|
12275
12316
|
}
|
|
12276
12317
|
|
|
12277
|
-
/*
|
|
12318
|
+
/* repo listesindeki rozet: ▶ = bu repoda süreç çalışıyor */
|
|
12319
|
+
function sbBadge(folder, on) {
|
|
12320
|
+
if (!els.sbRepo || !folder) return;
|
|
12321
|
+
for (const o of Array.from(els.sbRepo.options)) {
|
|
12322
|
+
if (o.value !== folder) continue;
|
|
12323
|
+
const it = sbItems.find((x) => x.folder === folder);
|
|
12324
|
+
const name = it ? it.name : o.textContent.replace(/ (?:●|▶)+$/g, '');
|
|
12325
|
+
o.textContent = name + (it && it.busy ? ' ●' : '') + (on ? ' ▶' : '');
|
|
12326
|
+
return;
|
|
12327
|
+
}
|
|
12328
|
+
}
|
|
12329
|
+
|
|
12330
|
+
/* süreç çıktısı akışı: klasör etiketli olaylar — seçili repo paneli süzer,
|
|
12331
|
+
arka plandaki repolar yalnızca rozetlerini günceller */
|
|
12278
12332
|
function sbRunIngest(ev) {
|
|
12333
|
+
const folder = String(ev.folder || '');
|
|
12334
|
+
const mine = !folder || !sbFolder || folder === sbFolder;
|
|
12335
|
+
if (!mine) {
|
|
12336
|
+
if (ev.type === 'sb-run-url') sbBadge(folder, true);
|
|
12337
|
+
if (ev.type === 'sb-run-end') sbBadge(folder, false);
|
|
12338
|
+
return;
|
|
12339
|
+
}
|
|
12279
12340
|
if (ev.type === 'sb-run') {
|
|
12280
12341
|
sbRunLine(ev.data);
|
|
12281
12342
|
return;
|
|
@@ -12285,26 +12346,106 @@ function sbRunIngest(ev) {
|
|
|
12285
12346
|
sbRunLine('🌐 dev server: ' + sbRunUrl, 't-dim');
|
|
12286
12347
|
if (els.sbRunOpen) els.sbRunOpen.disabled = !sbRunUrl;
|
|
12287
12348
|
if (els.sbRunUrl) els.sbRunUrl.textContent = sbRunUrl;
|
|
12349
|
+
sbBadge(folder || sbFolder, true);
|
|
12350
|
+
/* ÇALIŞTIR panelinde canlı önizleme otomatik açılır */
|
|
12351
|
+
sbPreviewApply();
|
|
12288
12352
|
return;
|
|
12289
12353
|
}
|
|
12290
12354
|
if (ev.type === 'sb-run-end') {
|
|
12291
12355
|
sbRunRunning = false;
|
|
12292
12356
|
if (els.sbRunStop) els.sbRunStop.hidden = true;
|
|
12357
|
+
sbBadge(folder || sbFolder, false);
|
|
12358
|
+
const assist = sbAutoAssist;
|
|
12359
|
+
sbAutoAssist = null;
|
|
12360
|
+
if (ev.quickFail && assist) {
|
|
12361
|
+
const kind = ev.kind === 'install' ? 'install' : 'run';
|
|
12362
|
+
sbRunLine('[hata] komut başarısız bitti — ajan doğru komutu arıyor…', 't-err');
|
|
12363
|
+
sbAskAgent(kind);
|
|
12364
|
+
}
|
|
12365
|
+
}
|
|
12366
|
+
}
|
|
12367
|
+
|
|
12368
|
+
/* ---------- ÇALIŞTIR içi CANLI ÖNİZLEME: DOM dikdörtgenini main'e bildir ---------- */
|
|
12369
|
+
function sbPreviewLayout() {
|
|
12370
|
+
if (!sbPreviewShown || sbPreviewSuspend) return;
|
|
12371
|
+
const host = document.getElementById('sbPreviewHost');
|
|
12372
|
+
if (!host) return;
|
|
12373
|
+
const r = host.getBoundingClientRect();
|
|
12374
|
+
if (!r.width || !r.height) return;
|
|
12375
|
+
beast.sbPreviewSet({
|
|
12376
|
+
url: sbRunUrl,
|
|
12377
|
+
visible: true,
|
|
12378
|
+
bounds: { x: r.left, y: r.top, width: r.width, height: r.height },
|
|
12379
|
+
}).catch(() => {});
|
|
12380
|
+
}
|
|
12381
|
+
|
|
12382
|
+
function sbPreviewApply() {
|
|
12383
|
+
const show = sbPreviewOn && sbModeOn() && !!sbFolder && !!sbRunUrl && !sbPreviewSuspend;
|
|
12384
|
+
sbPreviewShown = show;
|
|
12385
|
+
const host = document.getElementById('sbPreviewHost');
|
|
12386
|
+
if (host) host.hidden = !show;
|
|
12387
|
+
if (els.sbRunOut) els.sbRunOut.hidden = show;
|
|
12388
|
+
if (show) {
|
|
12389
|
+
sbPreviewLayout();
|
|
12390
|
+
/* görünür olunca yerleşim oturana kadar birkaç kez tazele */
|
|
12391
|
+
setTimeout(sbPreviewLayout, 50);
|
|
12392
|
+
setTimeout(sbPreviewLayout, 250);
|
|
12393
|
+
} else {
|
|
12394
|
+
beast.sbPreviewSet({ visible: false }).catch(() => {});
|
|
12395
|
+
}
|
|
12396
|
+
}
|
|
12397
|
+
|
|
12398
|
+
function sbPreviewToggle() {
|
|
12399
|
+
sbPreviewOn = !sbPreviewOn;
|
|
12400
|
+
if (els.sbRunView) {
|
|
12401
|
+
els.sbRunView.classList.toggle('on', sbPreviewOn);
|
|
12402
|
+
els.sbRunView.textContent = sbPreviewOn ? 'Görsel' : 'Çıktı';
|
|
12403
|
+
els.sbRunView.title = sbPreviewOn ? 'Görsel önizleme açık — çıktıya dön' : 'Çıktı görünümü — görsele dön';
|
|
12293
12404
|
}
|
|
12405
|
+
sbPreviewApply();
|
|
12406
|
+
}
|
|
12407
|
+
|
|
12408
|
+
/* Başlat/Dev başarısız olunca ajanı devreye sokar: repo yapısına göre
|
|
12409
|
+
DOĞRU komutu bulup panel_run ile başlatmasını ister (otomatik devralma). */
|
|
12410
|
+
function sbAskAgent(kind) {
|
|
12411
|
+
if (!sbFolder) return;
|
|
12412
|
+
const repoName = (sbItems.find((x) => x.folder === sbFolder) || {}).name || 'repo';
|
|
12413
|
+
const msg = kind === 'install'
|
|
12414
|
+
? `Kur butonu bu repoda başarısız oldu. ${repoName} reposunun dosyalarını incele (README, requirements.txt, package.json, pyproject.toml, Gemfile, mkdocs/hugo ayarları, alt klasörler) ve DOĞRU kurulum komutunu bulup panel_run ile ÇALIŞTIR panelinde çalıştır. Sonucu tek cümleyle bildir.`
|
|
12415
|
+
: `Başlat/Dev butonu bu repoda başarısız oldu. ${repoName} reposunun yapısını incele (README, package.json scripts, hugo/mkdocs/jekyll ayarları, main/app.py, Cargo.toml, go.mod…) ve GERÇEK çalıştırma komutunu bulup panel_run ile ÇALIŞTIR panelinde başlat. Web adresi çıkarsa kullanıcıya bildir.`;
|
|
12416
|
+
sbLine('t-sys', '⚙ ajan devrede — doğru komutu bulup başlatacak…');
|
|
12417
|
+
sbSetBusy(true);
|
|
12418
|
+
beast.sandboxSend({ folder: sbFolder, msg }).then((r) => {
|
|
12419
|
+
if (r && r.ok) {
|
|
12420
|
+
if (r.sessionId) sbSessionId = r.sessionId;
|
|
12421
|
+
if (r.queued) sbLine('t-dim', '⏳ kuyrukta (' + r.count + ') — iş bitince gönderilir');
|
|
12422
|
+
} else {
|
|
12423
|
+
sbSetBusy(false);
|
|
12424
|
+
sbLine('t-err', (r && r.error) || 'gönderilemedi');
|
|
12425
|
+
}
|
|
12426
|
+
}).catch((e) => {
|
|
12427
|
+
sbSetBusy(false);
|
|
12428
|
+
sbLine('t-err', String((e && e.message) || e));
|
|
12429
|
+
});
|
|
12294
12430
|
}
|
|
12295
12431
|
|
|
12296
12432
|
function sbRunExec(cmd) {
|
|
12297
12433
|
if (!sbFolder) { toast('Önce repo indir ya da seç'); return; }
|
|
12298
12434
|
if (sbRunRunning) { toast('Zaten çalışıyor — önce ■ ile durdur'); return; }
|
|
12299
12435
|
sbRunRunning = true;
|
|
12436
|
+
sbAutoAssist = 'run';
|
|
12300
12437
|
if (els.sbRunStop) els.sbRunStop.hidden = false;
|
|
12301
12438
|
beast.sandboxRun({ folder: sbFolder, cmd }).then((r) => {
|
|
12302
12439
|
if (!r || !r.ok) {
|
|
12440
|
+
sbAutoAssist = null;
|
|
12303
12441
|
sbRunRunning = false;
|
|
12304
12442
|
if (els.sbRunStop) els.sbRunStop.hidden = true;
|
|
12305
12443
|
sbRunLine('[hata] ' + ((r && r.error) || 'çalıştırılamadı'), 't-err');
|
|
12444
|
+
} else {
|
|
12445
|
+
sbBadge(sbFolder, true);
|
|
12306
12446
|
}
|
|
12307
12447
|
}).catch((e) => {
|
|
12448
|
+
sbAutoAssist = null;
|
|
12308
12449
|
sbRunRunning = false;
|
|
12309
12450
|
if (els.sbRunStop) els.sbRunStop.hidden = true;
|
|
12310
12451
|
sbRunLine('[hata] ' + String((e && e.message) || e), 't-err');
|
|
@@ -12360,6 +12501,10 @@ if (els.sbInput) {
|
|
|
12360
12501
|
}
|
|
12361
12502
|
});
|
|
12362
12503
|
}
|
|
12504
|
+
if (els.sbSend) els.sbSend.addEventListener('click', () => {
|
|
12505
|
+
sbRunCurrent();
|
|
12506
|
+
if (els.sbInput) els.sbInput.focus();
|
|
12507
|
+
});
|
|
12363
12508
|
if (els.sbStop) {
|
|
12364
12509
|
els.sbStop.addEventListener('click', () => {
|
|
12365
12510
|
beast.sandboxStop({ folder: sbFolder }).then((r) => {
|
|
@@ -12370,17 +12515,9 @@ if (els.sbStop) {
|
|
|
12370
12515
|
}).catch(() => {});
|
|
12371
12516
|
});
|
|
12372
12517
|
}
|
|
12373
|
-
/* ÇALIŞTIRICI
|
|
12374
|
-
|
|
12375
|
-
if (els.
|
|
12376
|
-
sbInstruct('Bu projeyi KUR — paket bildirim dosyasına (package.json, requirements.txt, Cargo.toml, go.mod, pom.xml vb.) göre doğru kurulum komutunu bul ve çalıştır (run_command); sonucu 1-2 satırla raporla.')
|
|
12377
|
-
);
|
|
12378
|
-
if (els.sbRunStart) els.sbRunStart.addEventListener('click', () =>
|
|
12379
|
-
sbInstruct('Bu projeyi ÇALIŞTIR — README/package.json scripts\u2019e göre doğru başlatma komutunu bul; uzun süreli sunucu/süreçse panel_run ile ÇALIŞTIR panelinde başlat (tur kilitleme), adresini/çalıştığını kullanıcıya bildir.')
|
|
12380
|
-
);
|
|
12381
|
-
if (els.sbRunDev) els.sbRunDev.addEventListener('click', () =>
|
|
12382
|
-
sbInstruct('Bu projeyi GELİŞTİRME modunda başlat — package.json scripts\u2019e bak (npm run dev, vite, expo start, ng serve vb. hangisi varsa) ve panel_run ile ÇALIŞTIR panelinde başlat; adresini kullanıcıya bildir.')
|
|
12383
|
-
);
|
|
12518
|
+
/* ÇALIŞTIRICI butonları: Başlat/Dev algılanan komutu (gerekirse kurup) çalıştırır */
|
|
12519
|
+
if (els.sbRunStart) els.sbRunStart.addEventListener('click', () => sbRunLaunch('run'));
|
|
12520
|
+
if (els.sbRunDev) els.sbRunDev.addEventListener('click', () => sbRunLaunch('dev'));
|
|
12384
12521
|
if (els.sbRunGo) els.sbRunGo.addEventListener('click', () => {
|
|
12385
12522
|
const c = els.sbRunCmd.value.trim();
|
|
12386
12523
|
if (!c) { toast('Komut yaz'); return; }
|
|
@@ -12395,17 +12532,110 @@ if (els.sbRunCmd) {
|
|
|
12395
12532
|
}
|
|
12396
12533
|
});
|
|
12397
12534
|
}
|
|
12535
|
+
if (els.sbRunSave) els.sbRunSave.addEventListener('click', async () => {
|
|
12536
|
+
if (!sbFolder) { toast('Önce repo seç'); return; }
|
|
12537
|
+
const c = els.sbRunCmd ? els.sbRunCmd.value.trim() : '';
|
|
12538
|
+
if (!c) { toast('Kaydetmek için komut yaz'); return; }
|
|
12539
|
+
const r = await beast.sandboxCfgSet({ folder: sbFolder, run: c }).catch(() => null);
|
|
12540
|
+
if (r && r.ok) {
|
|
12541
|
+
toast('kaydedildi — Başlat/Dev artık bu komutu kullanır');
|
|
12542
|
+
const det = await beast.sandboxDetect({ folder: sbFolder }).catch(() => null);
|
|
12543
|
+
if (det && det.ok && det.info) {
|
|
12544
|
+
sbRunInfo = det.info;
|
|
12545
|
+
if (els.sbRunCmd) els.sbRunCmd.placeholder = 'özel komut (algılanan: ' + (det.info.run || c) + ')…';
|
|
12546
|
+
}
|
|
12547
|
+
} else {
|
|
12548
|
+
toast((r && r.error) || 'kaydedilemedi');
|
|
12549
|
+
}
|
|
12550
|
+
});
|
|
12398
12551
|
if (els.sbRunStop) {
|
|
12399
12552
|
els.sbRunStop.addEventListener('click', () => {
|
|
12400
|
-
beast.sandboxRunStop().then((r) => {
|
|
12401
|
-
if (r && r.ok)
|
|
12553
|
+
beast.sandboxRunStop({ folder: sbFolder }).then((r) => {
|
|
12554
|
+
if (r && r.ok) {
|
|
12555
|
+
sbRunLine('⏹ durduruldu', 't-dim');
|
|
12556
|
+
sbRunRunning = false;
|
|
12557
|
+
if (els.sbRunStop) els.sbRunStop.hidden = true;
|
|
12558
|
+
sbBadge(sbFolder, false);
|
|
12559
|
+
}
|
|
12402
12560
|
}).catch(() => {});
|
|
12403
12561
|
});
|
|
12404
12562
|
}
|
|
12405
12563
|
if (els.sbRunOpen) {
|
|
12406
|
-
els.sbRunOpen.addEventListener('click', () => {
|
|
12407
|
-
|
|
12408
|
-
|
|
12409
|
-
|
|
12564
|
+
els.sbRunOpen.addEventListener('click', async () => {
|
|
12565
|
+
if (!sbRunUrl) { toast('Adres henüz yakalanmadı — Başlat/Dev ile sunucuyu çalıştır'); return; }
|
|
12566
|
+
const r = await beast.sandboxOpenUrl(sbRunUrl).catch(() => null);
|
|
12567
|
+
if (!r || !r.ok) toast('Açılamadı: ' + ((r && r.error) || 'bilinmeyen hata'));
|
|
12568
|
+
});
|
|
12569
|
+
}
|
|
12570
|
+
if (els.sbRunView) els.sbRunView.addEventListener('click', sbPreviewToggle);
|
|
12571
|
+
|
|
12572
|
+
/* görsel önizleme boyutu her yerleşim değişiminde main'e bildirilir
|
|
12573
|
+
(ayırıcı, tarayıcı dock'u, pencere boyutu, mod geçişi) */
|
|
12574
|
+
if (window.ResizeObserver) {
|
|
12575
|
+
const host = document.getElementById('sbPreviewHost');
|
|
12576
|
+
if (host) new ResizeObserver(() => sbPreviewLayout()).observe(host);
|
|
12577
|
+
}
|
|
12578
|
+
|
|
12579
|
+
/* ---------- sohbet/çalıştır ayırıcı (Beast Code ideSplit ile aynı desen) ----------
|
|
12580
|
+
Orantılı model: kaydedilen değer sohbet panelinin sandboxRow içindeki PAYI (0-1);
|
|
12581
|
+
sürükle-bırak anında --sbSplit yazar, bırakınca localStorage'a kaydeder. */
|
|
12582
|
+
let sbSplitFrac = 0;
|
|
12583
|
+
|
|
12584
|
+
function sbSplitApplyFrac() {
|
|
12585
|
+
const rowW = els.sandboxRow && els.sandboxRow.clientWidth ? els.sandboxRow.clientWidth : window.innerWidth - 250;
|
|
12586
|
+
/* kayıt yoksa eski varsayılan görünüm korunur: sohbet 480px, çalıştır kalanı */
|
|
12587
|
+
if (!sbSplitFrac) {
|
|
12588
|
+
const w = Math.max(280, Math.min(rowW - 480, Math.max(320, rowW - 300)));
|
|
12589
|
+
document.body.style.setProperty('--sbSplit', Math.round(w) + 'px');
|
|
12590
|
+
return;
|
|
12591
|
+
}
|
|
12592
|
+
sbSplitFrac = Math.max(0.2, Math.min(sbSplitFrac, 0.8));
|
|
12593
|
+
const w = Math.max(280, Math.min(Math.round(rowW * sbSplitFrac), Math.max(320, rowW - 300)));
|
|
12594
|
+
document.body.style.setProperty('--sbSplit', w + 'px');
|
|
12595
|
+
}
|
|
12596
|
+
|
|
12597
|
+
function sbSplitSave() {
|
|
12598
|
+
try { localStorage.setItem('beast.sbSplit', String(sbSplitFrac)); } catch {}
|
|
12599
|
+
}
|
|
12600
|
+
|
|
12601
|
+
function sbSplitRestore() {
|
|
12602
|
+
let saved = 0;
|
|
12603
|
+
try { saved = parseFloat(localStorage.getItem('beast.sbSplit')) || 0; } catch {}
|
|
12604
|
+
sbSplitFrac = saved > 0.05 && saved < 0.95 ? saved : 0;
|
|
12605
|
+
sbSplitApplyFrac();
|
|
12606
|
+
}
|
|
12607
|
+
|
|
12608
|
+
if (els.sbSplit) {
|
|
12609
|
+
els.sbSplit.addEventListener('mousedown', (e) => {
|
|
12610
|
+
e.preventDefault();
|
|
12611
|
+
els.sbSplit.classList.add('dragging');
|
|
12612
|
+
/* native önizleme view'i fare olaylarını yutabilir — sürükleme boyunca gizle,
|
|
12613
|
+
bırakınca geri getir (IDE'deki ayırıcı da aynı nedenle DOM üstünde çizilir) */
|
|
12614
|
+
sbPreviewSuspend = true;
|
|
12615
|
+
if (sbPreviewShown) beast.sbPreviewSet({ visible: false }).catch(() => {});
|
|
12616
|
+
const rightEdge = els.sbRun ? els.sbRun.getBoundingClientRect().right : window.innerWidth;
|
|
12617
|
+
const rowW = Math.max(600, els.sandboxRow && els.sandboxRow.clientWidth ? els.sandboxRow.clientWidth : window.innerWidth - 250);
|
|
12618
|
+
const move = (ev) => {
|
|
12619
|
+
const w = Math.max(280, Math.min(rightEdge - ev.clientX, rowW - 300));
|
|
12620
|
+
sbSplitFrac = Math.max(0.2, Math.min(w / rowW, 0.8));
|
|
12621
|
+
document.body.style.setProperty('--sbSplit', Math.round(w) + 'px');
|
|
12622
|
+
sbPreviewLayout();
|
|
12623
|
+
};
|
|
12624
|
+
const up = () => {
|
|
12625
|
+
document.removeEventListener('mousemove', move);
|
|
12626
|
+
document.removeEventListener('mouseup', up);
|
|
12627
|
+
els.sbSplit.classList.remove('dragging');
|
|
12628
|
+
sbSplitSave();
|
|
12629
|
+
sbPreviewSuspend = false;
|
|
12630
|
+
sbPreviewApply();
|
|
12631
|
+
};
|
|
12632
|
+
document.addEventListener('mousemove', move);
|
|
12633
|
+
document.addEventListener('mouseup', up);
|
|
12634
|
+
});
|
|
12635
|
+
window.addEventListener('resize', () => {
|
|
12636
|
+
if (sbModeOn()) {
|
|
12637
|
+
sbSplitApplyFrac();
|
|
12638
|
+
sbPreviewLayout();
|
|
12639
|
+
}
|
|
12410
12640
|
});
|
|
12411
12641
|
}
|
package/src/renderer/style.css
CHANGED
|
@@ -4271,7 +4271,7 @@ body.sandbox-mode #sandboxRow { display: flex; flex-direction: row; }
|
|
|
4271
4271
|
flex-direction: column;
|
|
4272
4272
|
min-height: 0;
|
|
4273
4273
|
min-width: 300px;
|
|
4274
|
-
flex:
|
|
4274
|
+
flex: 1 1 auto;
|
|
4275
4275
|
background: var(--bg);
|
|
4276
4276
|
overflow: hidden;
|
|
4277
4277
|
}
|
|
@@ -4280,10 +4280,20 @@ body.sandbox-mode #sandboxRow { display: flex; flex-direction: row; }
|
|
|
4280
4280
|
flex-direction: column;
|
|
4281
4281
|
min-height: 0;
|
|
4282
4282
|
min-width: 240px;
|
|
4283
|
-
flex:
|
|
4283
|
+
flex: 0 0 var(--sbSplit, 480px);
|
|
4284
4284
|
background: var(--bg);
|
|
4285
4285
|
overflow: hidden;
|
|
4286
|
-
|
|
4286
|
+
}
|
|
4287
|
+
#sbSplit {
|
|
4288
|
+
flex: none;
|
|
4289
|
+
width: 6px;
|
|
4290
|
+
cursor: col-resize;
|
|
4291
|
+
background: var(--border);
|
|
4292
|
+
opacity: 0.55;
|
|
4293
|
+
transition: opacity 0.15s;
|
|
4294
|
+
}
|
|
4295
|
+
#sbSplit:hover {
|
|
4296
|
+
opacity: 1;
|
|
4287
4297
|
}
|
|
4288
4298
|
|
|
4289
4299
|
#sbHead {
|
|
@@ -4394,9 +4404,31 @@ body.sandbox-mode #sandboxRow { display: flex; flex-direction: row; }
|
|
|
4394
4404
|
padding: 7px 9px;
|
|
4395
4405
|
border-radius: 8px;
|
|
4396
4406
|
font-family: inherit;
|
|
4407
|
+
overflow-y: hidden;
|
|
4408
|
+
max-height: 140px;
|
|
4409
|
+
line-height: 1.45;
|
|
4410
|
+
display: block;
|
|
4397
4411
|
}
|
|
4398
4412
|
#sbInput:focus { border-color: var(--accent); outline: none; }
|
|
4399
4413
|
#sbInput.expand { overflow-y: auto; }
|
|
4414
|
+
#sbInputRow button {
|
|
4415
|
+
flex: none;
|
|
4416
|
+
background: var(--panel2);
|
|
4417
|
+
border: 1px solid var(--border);
|
|
4418
|
+
color: var(--text);
|
|
4419
|
+
border-radius: 7px;
|
|
4420
|
+
cursor: pointer;
|
|
4421
|
+
font-size: 11px;
|
|
4422
|
+
padding: 6px 9px;
|
|
4423
|
+
line-height: 1;
|
|
4424
|
+
margin-bottom: 1px;
|
|
4425
|
+
}
|
|
4426
|
+
#sbInputRow button:hover { border-color: var(--accent); }
|
|
4427
|
+
#sbSend { color: var(--accent); }
|
|
4428
|
+
#sbSend:hover { background: var(--accent-dim); }
|
|
4429
|
+
#sbStop { color: var(--err); }
|
|
4430
|
+
#sbStop[hidden] { display: none; }
|
|
4431
|
+
#sbStop:hover { border-color: var(--err); }
|
|
4400
4432
|
|
|
4401
4433
|
/* ---------- ÇALIŞTIR bölmesi ---------- */
|
|
4402
4434
|
#sbRunHead {
|
|
@@ -4409,6 +4441,18 @@ body.sandbox-mode #sandboxRow { display: flex; flex-direction: row; }
|
|
|
4409
4441
|
background: var(--panel);
|
|
4410
4442
|
}
|
|
4411
4443
|
#sbRunTitle { font-size: 11px; font-weight: 800; letter-spacing: 1px; color: var(--accent); flex: none; }
|
|
4444
|
+
#sbRunKind {
|
|
4445
|
+
flex: none;
|
|
4446
|
+
font-size: 10px;
|
|
4447
|
+
font-weight: 700;
|
|
4448
|
+
letter-spacing: 0.5px;
|
|
4449
|
+
text-transform: uppercase;
|
|
4450
|
+
color: var(--muted);
|
|
4451
|
+
border: 1px solid var(--border);
|
|
4452
|
+
border-radius: 4px;
|
|
4453
|
+
padding: 1px 6px;
|
|
4454
|
+
}
|
|
4455
|
+
#sbRunKind:empty { display: none; }
|
|
4412
4456
|
#sbRunCwd {
|
|
4413
4457
|
color: var(--muted);
|
|
4414
4458
|
font-family: Consolas, monospace;
|
|
@@ -4418,6 +4462,33 @@ body.sandbox-mode #sandboxRow { display: flex; flex-direction: row; }
|
|
|
4418
4462
|
text-overflow: ellipsis;
|
|
4419
4463
|
white-space: nowrap;
|
|
4420
4464
|
}
|
|
4465
|
+
#sbRunHead button {
|
|
4466
|
+
flex: none;
|
|
4467
|
+
background: var(--panel2);
|
|
4468
|
+
border: 1px solid var(--border);
|
|
4469
|
+
color: var(--muted);
|
|
4470
|
+
font-size: 11px;
|
|
4471
|
+
padding: 3px 9px;
|
|
4472
|
+
border-radius: 6px;
|
|
4473
|
+
cursor: pointer;
|
|
4474
|
+
}
|
|
4475
|
+
#sbRunHead button:hover { color: var(--text); border-color: var(--accent); }
|
|
4476
|
+
#sbRunHead button.on { color: var(--accent); border-color: var(--accent); }
|
|
4477
|
+
#sbPreviewHost {
|
|
4478
|
+
flex: 1;
|
|
4479
|
+
min-height: 0;
|
|
4480
|
+
display: flex;
|
|
4481
|
+
align-items: center;
|
|
4482
|
+
justify-content: center;
|
|
4483
|
+
background: var(--bg);
|
|
4484
|
+
}
|
|
4485
|
+
#sbPreviewHost[hidden] { display: none; }
|
|
4486
|
+
#sbPreviewHint {
|
|
4487
|
+
color: var(--muted);
|
|
4488
|
+
font-size: 12px;
|
|
4489
|
+
padding: 0 16px;
|
|
4490
|
+
text-align: center;
|
|
4491
|
+
}
|
|
4421
4492
|
#sbRunBtns {
|
|
4422
4493
|
flex: none;
|
|
4423
4494
|
display: flex;
|