beast-agent 2.39.0 → 2.41.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.
Files changed (41) hide show
  1. package/package.json +1 -1
  2. package/src/agent/bots.js +2 -2
  3. package/src/agent/customtools.js +52 -2
  4. package/src/agent/defaulttools/mt5_barlar2/run.js +188 -0
  5. package/src/agent/defaulttools/mt5_barlar2/tool.json +23 -0
  6. package/src/agent/defaulttools/mt5_bekleyen/run.js +100 -0
  7. package/src/agent/defaulttools/mt5_bekleyen/tool.json +17 -0
  8. package/src/agent/defaulttools/mt5_durum/run.js +93 -0
  9. package/src/agent/defaulttools/mt5_durum/tool.json +10 -0
  10. package/src/agent/defaulttools/mt5_emir/run.js +98 -0
  11. package/src/agent/defaulttools/mt5_emir/tool.json +17 -0
  12. package/src/agent/defaulttools/mt5_emir_iptal/run.js +90 -0
  13. package/src/agent/defaulttools/mt5_emir_iptal/tool.json +12 -0
  14. package/src/agent/defaulttools/mt5_fiyat/run.js +87 -0
  15. package/src/agent/defaulttools/mt5_fiyat/tool.json +16 -0
  16. package/src/agent/defaulttools/mt5_gecmis/run.js +87 -0
  17. package/src/agent/defaulttools/mt5_gecmis/tool.json +12 -0
  18. package/src/agent/defaulttools/mt5_kapat/run.js +92 -0
  19. package/src/agent/defaulttools/mt5_kapat/tool.json +13 -0
  20. package/src/agent/defaulttools/mt5_m15_m5/m15m5.py +60 -0
  21. package/src/agent/defaulttools/mt5_m15_m5/run.js +73 -0
  22. package/src/agent/defaulttools/mt5_m15_m5/tool.json +10 -0
  23. package/src/agent/defaulttools/mt5_pozisyon_gecmis/run.js +144 -0
  24. package/src/agent/defaulttools/mt5_pozisyon_gecmis/tool.json +12 -0
  25. package/src/agent/defaulttools/mt5_shot/run.js +428 -0
  26. package/src/agent/defaulttools/mt5_shot/tool.json +20 -0
  27. package/src/agent/defaulttools/mt5_sltp/run.js +92 -0
  28. package/src/agent/defaulttools/mt5_sltp/tool.json +14 -0
  29. package/src/agent/engine.js +101 -16
  30. package/src/agent/financetools.js +1 -1
  31. package/src/agent/mt5/BeastFinance.mq5 +140 -3
  32. package/src/agent/mt5/BeastShot.tpl +0 -0
  33. package/src/agent/mt5setup.js +22 -0
  34. package/src/agent/opencode/agents.js +4 -3
  35. package/src/agent/seeds/mql5/SKILL.md +4 -2
  36. package/src/agent/tools.js +16 -0
  37. package/src/main.js +307 -39
  38. package/src/preload.js +6 -1
  39. package/src/renderer/index.html +6 -4
  40. package/src/renderer/renderer.js +115 -39
  41. package/src/renderer/style.css +27 -0
@@ -136,12 +136,14 @@ const els = {
136
136
  sbInput: $('#sbInput'),
137
137
  sbStop: $('#sbStop'),
138
138
  sbRunCwd: $('#sbRunCwd'),
139
+ sbRunKind: $('#sbRunKind'),
139
140
  sbRunInstall: $('#sbRunInstall'),
140
141
  sbRunStart: $('#sbRunStart'),
141
142
  sbRunDev: $('#sbRunDev'),
142
143
  sbRunStop: $('#sbRunStop'),
143
144
  sbRunCmd: $('#sbRunCmd'),
144
145
  sbRunGo: $('#sbRunGo'),
146
+ sbRunSave: $('#sbRunSave'),
145
147
  sbRunOut: $('#sbRunOut'),
146
148
  sbRunOpen: $('#sbRunOpen'),
147
149
  sbRunUrl: $('#sbRunUrl'),
@@ -5253,9 +5255,17 @@ function dmMsgHtml(m) {
5253
5255
  const who = m.group
5254
5256
  ? dmName(m.fromTitle, m.from)
5255
5257
  : `${dmName(m.fromTitle, m.from)} → ${dmName(m.toTitle, m.to)}`;
5258
+ const rawImg = String(m.image || '');
5259
+ const img = /^data:image\//i.test(rawImg)
5260
+ ? `<img class="dmt-img" src="${escapeHtml(rawImg)}" alt="görsel" loading="lazy">`
5261
+ : m.imageOmitted
5262
+ ? '<div class="dmt-img-note">görsel (bütçe) kaydedilmedi</div>'
5263
+ : '';
5256
5264
  return (
5257
5265
  `<div class="dmt-msg"><span class="dm-who">${who}</span>` +
5258
- `${escapeHtml(String(m.text || ''))}<span class="dm-at">${dmTime(m.at)}</span></div>`
5266
+ `${escapeHtml(String(m.text || ''))}` +
5267
+ img +
5268
+ `<span class="dm-at">${dmTime(m.at)}</span></div>`
5259
5269
  );
5260
5270
  }
5261
5271
 
@@ -5788,6 +5798,8 @@ function onEvent(ev) {
5788
5798
  toTitle: ev.toTitle,
5789
5799
  topic: ev.topic,
5790
5800
  text: ev.text,
5801
+ ...(ev.image ? { image: ev.image } : {}),
5802
+ ...(ev.imageOmitted ? { imageOmitted: true } : {}),
5791
5803
  ...(ev.group ? { group: ev.group, groupTitle: ev.groupTitle } : {}),
5792
5804
  ...(ev.closed ? { closed: true, closedAt: ev.closedAt } : {}),
5793
5805
  };
@@ -11954,6 +11966,7 @@ let sbCloning = false;
11954
11966
  const sbTreeState = { cache: new Map(), open: new Set(['']), path: '' };
11955
11967
  let sbRunUrl = '';
11956
11968
  let sbRunRunning = false;
11969
+ let sbRunInfo = null;
11957
11970
 
11958
11971
  function sbModeOn() {
11959
11972
  return document.body.classList.contains('sandbox-mode');
@@ -12085,7 +12098,7 @@ async function loadSandboxList() {
12085
12098
  for (const it of sbItems) {
12086
12099
  const o = document.createElement('option');
12087
12100
  o.value = it.folder;
12088
- o.textContent = it.name + (it.busy ? ' ●' : '');
12101
+ o.textContent = it.name + (it.busy ? ' ●' : '') + (it.running ? ' ▶' : '');
12089
12102
  sel.appendChild(o);
12090
12103
  }
12091
12104
  if (sbFolder && sbItems.some((x) => x.folder === sbFolder)) sel.value = sbFolder;
@@ -12130,6 +12143,31 @@ async function sbSelectCurrent() {
12130
12143
  sbLine('t-err', (r && r.error) || 'oturum açılamadı');
12131
12144
  }
12132
12145
  sbSetBusy(!!(r && r.busy));
12146
+ /* yönetilen süreç durumu: repo değişince arka plandaki süreç + tampon çıktı geri yüklenir */
12147
+ sbRunInfo = null;
12148
+ const st = await beast.sandboxProcState({ folder: sbFolder }).catch(() => null);
12149
+ if (st && st.ok) {
12150
+ sbRunUrl = st.url || '';
12151
+ sbRunRunning = !!st.running;
12152
+ if (els.sbRunStop) els.sbRunStop.hidden = !sbRunRunning;
12153
+ if (els.sbRunOpen) els.sbRunOpen.disabled = !sbRunUrl;
12154
+ if (els.sbRunUrl) els.sbRunUrl.textContent = sbRunUrl || '';
12155
+ for (const l of st.lines || []) sbRunLine(l);
12156
+ }
12157
+ /* proje tipi algıla: butonlar hangi komutu çalıştıracağını bilir */
12158
+ const det = await beast.sandboxDetect({ folder: sbFolder }).catch(() => null);
12159
+ if (det && det.ok && det.info) {
12160
+ sbRunInfo = det.info;
12161
+ if (els.sbRunKind) els.sbRunKind.textContent = det.info.label || '';
12162
+ if (els.sbRunCmd) {
12163
+ els.sbRunCmd.placeholder = det.info.run
12164
+ ? 'özel komut (algılanan: ' + det.info.run + ')…'
12165
+ : 'özel komut: python main.py, cargo run, node index.js…';
12166
+ }
12167
+ if (!sbRunRunning && !(st && (st.lines || []).length)) {
12168
+ sbRunLine('ℹ ' + (det.info.label || 'proje') + ' · kur: ' + (det.info.install || '—') + ' · çalıştır: ' + (det.info.run || '—'), 't-dim');
12169
+ }
12170
+ }
12133
12171
  /* sol konsol: seçilen reponun klasörü — oturum açıldıktan sonra da garanti tazele */
12134
12172
  sbTreeState.cache.clear();
12135
12173
  if (sbModeOn()) renderFileTree().catch(() => {});
@@ -12232,26 +12270,24 @@ function setSandboxMode(on) {
12232
12270
  }
12233
12271
  }
12234
12272
 
12235
- /* ---------- ÇALIŞTIRICI: butonlar KOMUT DEĞİL AJANA TALİMATTIR ----------
12236
- Her proje farklı çalışır; komutu kullanıcı bilemez, AJAN bilir:
12237
- paket bildirim dosyasına + README'ye bakıp doğru komutu bulur, uzun süreli
12238
- süreci panel_run aracıyla ÇALIŞTIR panelinde (turu kilitlemeden) başlatır. */
12239
- function sbInstruct(text) {
12273
+ /* ---------- ÇALIŞTIRICI v2: butonlar DETERMİNİSTİK ----------
12274
+ Proje tipi algılanır (package.json/requirements.txt/pyproject/Cargo.toml/
12275
+ go.mod/index.html) ve Kur/Başlat/Dev butonları algılanan komutu DOĞRUDAN
12276
+ çalıştırır; süreç panelde canlı akar, repo başına ayrı yuvada koşar. */
12277
+ async function sbRunLaunch(mode) {
12240
12278
  if (!sbFolder) { toast('Önce repo indir ya da seç'); return; }
12241
- sbLine('t-cmd', 'sen> ' + text);
12242
- sbSetBusy(true);
12243
- beast.sandboxSend({ folder: sbFolder, msg: text }).then((r) => {
12244
- if (r && r.ok) {
12245
- if (r.sessionId) sbSessionId = r.sessionId;
12246
- if (r.queued) sbLine('t-dim', '⏳ kuyrukta (' + r.count + ') — iş bitince gönderilir');
12247
- } else {
12248
- sbSetBusy(false);
12249
- sbLine('t-err', (r && r.error) || 'gönderilemedi');
12250
- }
12251
- }).catch((e) => {
12252
- sbSetBusy(false);
12253
- sbLine('t-err', String((e && e.message) || e));
12254
- });
12279
+ if (sbRunRunning) { toast('Bu repoda süreç çalışıyor — önce ■ Durdur'); return; }
12280
+ const call = mode === 'install'
12281
+ ? beast.sandboxInstall({ folder: sbFolder })
12282
+ : beast.sandboxStart({ folder: sbFolder, mode: mode === 'dev' ? 'dev' : 'run' });
12283
+ const r = await call.catch((e) => ({ ok: false, error: String((e && e.message) || e) }));
12284
+ if (!r || !r.ok) {
12285
+ sbRunLine('[hata] ' + ((r && r.error) || 'başlatılamadı'), 't-err');
12286
+ return;
12287
+ }
12288
+ sbRunRunning = true;
12289
+ if (els.sbRunStop) els.sbRunStop.hidden = false;
12290
+ sbBadge(sbFolder, true);
12255
12291
  }
12256
12292
 
12257
12293
  function sbRunLine(text, cls) {
@@ -12264,8 +12300,28 @@ function sbRunLine(text, cls) {
12264
12300
  return div;
12265
12301
  }
12266
12302
 
12267
- /* süreç çıktısı akışı: sessionId'siz global olaylar — en üstte yönlendirilir */
12303
+ /* repo listesindeki rozet: ▶ = bu repoda süreç çalışıyor */
12304
+ function sbBadge(folder, on) {
12305
+ if (!els.sbRepo || !folder) return;
12306
+ for (const o of Array.from(els.sbRepo.options)) {
12307
+ if (o.value !== folder) continue;
12308
+ const it = sbItems.find((x) => x.folder === folder);
12309
+ const name = it ? it.name : o.textContent.replace(/ (?:●|▶)+$/g, '');
12310
+ o.textContent = name + (it && it.busy ? ' ●' : '') + (on ? ' ▶' : '');
12311
+ return;
12312
+ }
12313
+ }
12314
+
12315
+ /* süreç çıktısı akışı: klasör etiketli olaylar — seçili repo paneli süzer,
12316
+ arka plandaki repolar yalnızca rozetlerini günceller */
12268
12317
  function sbRunIngest(ev) {
12318
+ const folder = String(ev.folder || '');
12319
+ const mine = !folder || !sbFolder || folder === sbFolder;
12320
+ if (!mine) {
12321
+ if (ev.type === 'sb-run-url') sbBadge(folder, true);
12322
+ if (ev.type === 'sb-run-end') sbBadge(folder, false);
12323
+ return;
12324
+ }
12269
12325
  if (ev.type === 'sb-run') {
12270
12326
  sbRunLine(ev.data);
12271
12327
  return;
@@ -12275,11 +12331,15 @@ function sbRunIngest(ev) {
12275
12331
  sbRunLine('🌐 dev server: ' + sbRunUrl, 't-dim');
12276
12332
  if (els.sbRunOpen) els.sbRunOpen.disabled = !sbRunUrl;
12277
12333
  if (els.sbRunUrl) els.sbRunUrl.textContent = sbRunUrl;
12334
+ sbBadge(folder || sbFolder, true);
12335
+ /* sağdaki dahili tarayıcıda otomatik açılır — sandbox modundayken */
12336
+ if (sbModeOn() && sbRunUrl) beast.sandboxOpenUrl(sbRunUrl).catch(() => {});
12278
12337
  return;
12279
12338
  }
12280
12339
  if (ev.type === 'sb-run-end') {
12281
12340
  sbRunRunning = false;
12282
12341
  if (els.sbRunStop) els.sbRunStop.hidden = true;
12342
+ sbBadge(folder || sbFolder, false);
12283
12343
  }
12284
12344
  }
12285
12345
 
@@ -12293,6 +12353,8 @@ function sbRunExec(cmd) {
12293
12353
  sbRunRunning = false;
12294
12354
  if (els.sbRunStop) els.sbRunStop.hidden = true;
12295
12355
  sbRunLine('[hata] ' + ((r && r.error) || 'çalıştırılamadı'), 't-err');
12356
+ } else {
12357
+ sbBadge(sbFolder, true);
12296
12358
  }
12297
12359
  }).catch((e) => {
12298
12360
  sbRunRunning = false;
@@ -12360,17 +12422,10 @@ if (els.sbStop) {
12360
12422
  }).catch(() => {});
12361
12423
  });
12362
12424
  }
12363
- /* ÇALIŞTIRICI butonları — KOMUT DEĞİL AJANA TALİMAT (komutu ajan bulur):
12364
- uzun süreli süreci panel_run ile ÇALIŞTIR paneline bırakır, tur kilitlenmez */
12365
- if (els.sbRunInstall) els.sbRunInstall.addEventListener('click', () =>
12366
- 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.')
12367
- );
12368
- if (els.sbRunStart) els.sbRunStart.addEventListener('click', () =>
12369
- 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.')
12370
- );
12371
- if (els.sbRunDev) els.sbRunDev.addEventListener('click', () =>
12372
- 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.')
12373
- );
12425
+ /* ÇALIŞTIRICI butonları: algılanan komutu doğrudan çalıştırır */
12426
+ if (els.sbRunInstall) els.sbRunInstall.addEventListener('click', () => sbRunLaunch('install'));
12427
+ if (els.sbRunStart) els.sbRunStart.addEventListener('click', () => sbRunLaunch('run'));
12428
+ if (els.sbRunDev) els.sbRunDev.addEventListener('click', () => sbRunLaunch('dev'));
12374
12429
  if (els.sbRunGo) els.sbRunGo.addEventListener('click', () => {
12375
12430
  const c = els.sbRunCmd.value.trim();
12376
12431
  if (!c) { toast('Komut yaz'); return; }
@@ -12385,17 +12440,38 @@ if (els.sbRunCmd) {
12385
12440
  }
12386
12441
  });
12387
12442
  }
12443
+ if (els.sbRunSave) els.sbRunSave.addEventListener('click', async () => {
12444
+ if (!sbFolder) { toast('Önce repo seç'); return; }
12445
+ const c = els.sbRunCmd ? els.sbRunCmd.value.trim() : '';
12446
+ if (!c) { toast('Kaydetmek için komut yaz'); return; }
12447
+ const r = await beast.sandboxCfgSet({ folder: sbFolder, run: c }).catch(() => null);
12448
+ if (r && r.ok) {
12449
+ toast('kaydedildi — Başlat/Dev artık bu komutu kullanır');
12450
+ const det = await beast.sandboxDetect({ folder: sbFolder }).catch(() => null);
12451
+ if (det && det.ok && det.info) {
12452
+ sbRunInfo = det.info;
12453
+ if (els.sbRunCmd) els.sbRunCmd.placeholder = 'özel komut (algılanan: ' + (det.info.run || c) + ')…';
12454
+ }
12455
+ } else {
12456
+ toast((r && r.error) || 'kaydedilemedi');
12457
+ }
12458
+ });
12388
12459
  if (els.sbRunStop) {
12389
12460
  els.sbRunStop.addEventListener('click', () => {
12390
- beast.sandboxRunStop().then((r) => {
12391
- if (r && r.ok) sbRunLine('⏹ durduruldu', 't-dim');
12461
+ beast.sandboxRunStop({ folder: sbFolder }).then((r) => {
12462
+ if (r && r.ok) {
12463
+ sbRunLine('⏹ durduruldu', 't-dim');
12464
+ sbRunRunning = false;
12465
+ if (els.sbRunStop) els.sbRunStop.hidden = true;
12466
+ sbBadge(sbFolder, false);
12467
+ }
12392
12468
  }).catch(() => {});
12393
12469
  });
12394
12470
  }
12395
12471
  if (els.sbRunOpen) {
12396
- els.sbRunOpen.addEventListener('click', () => {
12397
- /* Tarayıcıda aç da AJANA TALİMAT: ajan çalışma adresini bulup kendi
12398
- browser_open aracıyla dahili tarayıcıda açar */
12399
- sbInstruct('Bu projenin web arayüzü çalışıyorsa adresini tespit et (çıktılar/README/port taraması) ve browser_open aracıyla DAHİLİ TARAYICIDA aç.')
12472
+ els.sbRunOpen.addEventListener('click', async () => {
12473
+ if (!sbRunUrl) { toast('Adres henüz yakalanmadı — Başlat/Dev ile sunucuyu çalıştır'); return; }
12474
+ const r = await beast.sandboxOpenUrl(sbRunUrl).catch(() => null);
12475
+ if (!r || !r.ok) toast('Açılamadı: ' + ((r && r.error) || 'bilinmeyen hata'));
12400
12476
  });
12401
12477
  }
@@ -2224,6 +2224,21 @@ body.browser-open #settingsDialog { width: min(70vw, calc(100vw - var(--bw, 480p
2224
2224
  color: var(--muted);
2225
2225
  margin-top: 2px;
2226
2226
  }
2227
+ /* ajan DM görseli (mt5_shot / ekran görüntüsü paylaşımı) */
2228
+ .dmt-msg .dmt-img {
2229
+ display: block;
2230
+ max-width: 100%;
2231
+ max-height: 260px;
2232
+ border-radius: 6px;
2233
+ margin-top: 5px;
2234
+ border: 1px solid var(--border, rgba(255,255,255,0.12));
2235
+ }
2236
+ .dmt-msg .dmt-img-note {
2237
+ font-size: 10px;
2238
+ color: var(--muted);
2239
+ font-style: italic;
2240
+ margin-top: 3px;
2241
+ }
2227
2242
  /* ajan adının yanındaki KOD rozeti (oturum id) */
2228
2243
  .dm-code {
2229
2244
  font-size: 9px; font-weight: 700; letter-spacing: 0.5px;
@@ -4394,6 +4409,18 @@ body.sandbox-mode #sandboxRow { display: flex; flex-direction: row; }
4394
4409
  background: var(--panel);
4395
4410
  }
4396
4411
  #sbRunTitle { font-size: 11px; font-weight: 800; letter-spacing: 1px; color: var(--accent); flex: none; }
4412
+ #sbRunKind {
4413
+ flex: none;
4414
+ font-size: 10px;
4415
+ font-weight: 700;
4416
+ letter-spacing: 0.5px;
4417
+ text-transform: uppercase;
4418
+ color: var(--muted);
4419
+ border: 1px solid var(--border);
4420
+ border-radius: 4px;
4421
+ padding: 1px 6px;
4422
+ }
4423
+ #sbRunKind:empty { display: none; }
4397
4424
  #sbRunCwd {
4398
4425
  color: var(--muted);
4399
4426
  font-family: Consolas, monospace;