beast-agent 1.5.0 → 1.5.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "beast-agent",
3
3
  "productName": "Beast Agent",
4
- "version": "1.5.0",
4
+ "version": "1.5.2",
5
5
  "description": "Ultra-fast local agent shell for Windows.",
6
6
  "author": "algokodcom (AlgoKod)",
7
7
  "license": "MIT",
package/src/main.js CHANGED
@@ -2747,8 +2747,7 @@ function falloutResume() {
2747
2747
  if (!f.enabled || f.autoResume === false) return;
2748
2748
  const st = JSON.parse(fs.readFileSync(FALLOUT_CRASH_FILE, 'utf8'));
2749
2749
  if (!st || !st.sessionId) return;
2750
- const exists = engine.listSessions().some((s) => s.id === st.sessionId);
2751
- const sid = exists ? st.sessionId : engine.createSession().id;
2750
+ const sid = reuseOrLatestSession(st.sessionId);
2752
2751
  const when = st.at ? new Date(st.at).toLocaleString('tr-TR') : '?';
2753
2752
  setTimeout(() => {
2754
2753
  try {
@@ -2795,7 +2794,8 @@ function whereWasISummary() {
2795
2794
  function maybeRunWhereWasI() {
2796
2795
  try {
2797
2796
  const cfg = settings.whereWasI || {};
2798
- if (cfg.enabled === false) return;
2797
+ /* DEFAULT KAPALI: yalnız Ayarlar → Maliyet · Limit'ten açıldıysa göster */
2798
+ if (cfg.enabled !== true) return;
2799
2799
  const sum = whereWasISummary();
2800
2800
  if (!sum) return;
2801
2801
  settingsLog(`nerede-kaldım: ${String(sum.text).split('\n')[0]}`);
@@ -2993,37 +2993,17 @@ function browserWidthFor(w) {
2993
2993
  return Math.max(380, Math.min(800, Math.floor(w * 0.46)));
2994
2994
  }
2995
2995
 
2996
- function browserShownWidth(w) {
2997
- /* telefon modunda dock genişliği KORUNUR 390x844 telefon ekranı
2998
- görüntünün ORTASINDA, cihaz çerçevesiyle gösterilir (DevTools gibi) */
2999
- return Math.min(browser.width, Math.max(320, w - 320));
2996
+ /* emit'lerdeki genişlik HEP gösterilen genişlik olmalı (telefon modunda 430)
2997
+ yoksa yüklenme bitince dock eski genişliğine döner, daralan solda boşluk bırakır */
2998
+ function browserW() {
2999
+ try { return win.getContentSize()[0]; } catch { return 0; }
3000
3000
  }
3001
3001
 
3002
- /* telefon modu görüntü parametreleri: mobil ekran emülasyonu + sığma ölçeği */
3003
- function applyPhoneEmulation() {
3004
- try {
3005
- const wc = browser.view && browser.view.webContents;
3006
- if (!wc) return;
3007
- if (!browser.phone) {
3008
- wc.disableDeviceEmulation();
3009
- return;
3010
- }
3011
- let w = 800;
3012
- let h = 900;
3013
- try { [w, h] = win.getContentSize(); } catch {}
3014
- const viewW = browserShownWidth(w);
3015
- const viewH = Math.max(240, h - BROWSER_TOOLBAR_H - 8);
3016
- const PW = 390;
3017
- const PH = 844;
3018
- const scale = Math.max(0.3, Math.min(1, (viewW - 20) / PW, (viewH - 12) / PH));
3019
- wc.enableDeviceEmulation({
3020
- screenPosition: 'mobile',
3021
- screenOrientation: { type: 'portraitPrimary', angle: 0 },
3022
- viewSize: { width: PW, height: PH },
3023
- deviceScaleFactor: 2,
3024
- scale,
3025
- });
3026
- } catch {}
3002
+ function browserShownWidth(w) {
3003
+ const avail = Math.max(320, w - 320);
3004
+ /* TELEFON MODU: dock KENDİSİ daralır (~430px) — sayfa mobil düzenle
3005
+ kenarlara tam oturur; kapatınca kullanıcı genişliği geri gelir */
3006
+ return browser.phone ? Math.min(430, avail) : Math.min(browser.width, avail);
3027
3007
  }
3028
3008
 
3029
3009
  function layoutBrowser() {
@@ -3048,7 +3028,6 @@ function layoutBrowser() {
3048
3028
  try {
3049
3029
  view.setBounds({ x: Math.max(0, w - shownWidth), y: BROWSER_TOOLBAR_H, width: shownWidth, height: Math.max(0, h - BROWSER_TOOLBAR_H) });
3050
3030
  view.setVisible(browser.open && browser.visible);
3051
- if (browser.phone) applyPhoneEmulation(); // pencere boyutlanınca telefon ölçeği tazelensin
3052
3031
  } catch {}
3053
3032
  }
3054
3033
 
@@ -3085,7 +3064,7 @@ function ensureBrowser() {
3085
3064
  // Tarayıcı kapalıyken olayların UI'ı geri açmamasını garantile
3086
3065
  const notify = (extra) => {
3087
3066
  if (browser.open && win && !win.isDestroyed()) {
3088
- browserEmit({ open: true, width: browser.width, ...extra });
3067
+ browserEmit({ open: true, width: browserShownWidth(browserW()), ...extra });
3089
3068
  }
3090
3069
  };
3091
3070
  wc.on('did-navigate', (_e, url) => notify({ url, loading: false }));
@@ -3101,7 +3080,6 @@ function ensureBrowser() {
3101
3080
  browser.view = null;
3102
3081
  });
3103
3082
  browser.view = view;
3104
- if (browser.phone) applyPhoneEmulation(); // tarayıcı telefon modunda doğarsa emülasyonu uygula
3105
3083
  return view;
3106
3084
  }
3107
3085
 
@@ -3146,7 +3124,7 @@ function setBrowserOpen(v, forceVisible) {
3146
3124
  layoutBrowser();
3147
3125
  let url = '';
3148
3126
  try { url = browser.view.webContents.getURL(); } catch {}
3149
- browserEmit({ open: true, width: browser.width, url });
3127
+ browserEmit({ open: true, width: browserShownWidth(browserW()), url });
3150
3128
  }
3151
3129
 
3152
3130
  /* --- Paralel ajan trafik düzeni: ajanlar aynı saniyede sorgu atınca Google
@@ -3210,7 +3188,7 @@ async function browserNavigateNow(raw, signal, ctx) {
3210
3188
  let title = '';
3211
3189
  let finalUrl = url;
3212
3190
  try { title = wc.getTitle(); finalUrl = wc.getURL() || url; } catch {}
3213
- browserEmit({ open: true, width: browser.width, url: finalUrl });
3191
+ browserEmit({ open: true, width: browserShownWidth(browserW()), url: finalUrl });
3214
3192
  flushBrowserStorage(); // oturum çerezleri diske — ani kapanışta kaybolmasın
3215
3193
  /* açılışta snapshot da göm — model ayrı snapshot çağırmadan ref'lere başlar */
3216
3194
  let snap = null;
@@ -4922,8 +4900,12 @@ ipcMain.handle('setup:skip', () => {
4922
4900
  return { ok: true };
4923
4901
  });
4924
4902
 
4925
- /* #5 "nerede kaldım" */
4926
- ipcMain.handle('wherewasi:get', () => whereWasISummary());
4903
+ /* #5 "nerede kaldım": get → gerçek ayar durumu (checkbox doğru görünsün) */
4904
+ ipcMain.handle('wherewasi:get', () => {
4905
+ const cfg = settings.whereWasI || {};
4906
+ const sum = whereWasISummary();
4907
+ return { enabled: cfg.enabled === true, ...(sum || {}) };
4908
+ });
4927
4909
  ipcMain.handle('wherewasi:set', (_e, cfg) => {
4928
4910
  settings.whereWasI = { enabled: !!(cfg && cfg.enabled) };
4929
4911
  saveSettings();
@@ -5208,6 +5190,24 @@ function cronEmit() {
5208
5190
  hangi kanaldan ajanla iletişimde belli değil). */
5209
5191
  const cronAnswerPending = new Map();
5210
5192
 
5193
+ /* OTOMATİK YENİ SOHBET YOK: cron/izleyici/fallout tetiklendiğinde oturum
5194
+ seçimi — kayıtlı id geçerliyse O, değilse EN GÜNCEL oturum kullanılır.
5195
+ Hiç oturum yoksa (ilk kurulum) yeni açılır. Böylece soldaki sohbet
5196
+ geçmişine "+ Yeni Sohbet" olmadan hayalet sohbetler düşmez. */
5197
+ function reuseOrLatestSession(preferredId) {
5198
+ const sid = String(preferredId || '');
5199
+ if (sid) {
5200
+ try {
5201
+ if (engine._load(sid)) return sid;
5202
+ } catch {}
5203
+ }
5204
+ try {
5205
+ const list = engine.listSessions(); // updatedAt'e göre yeni→eski sıralı
5206
+ if (list.length) return String(list[0].id);
5207
+ } catch {}
5208
+ return engine.createSession().id;
5209
+ }
5210
+
5211
5211
  /* Yansıtma hedefleri: bağlı WA (owner numarası), Telegram ve Discord
5212
5212
  (owner işaretli kayıt; tek kayıt varsa o). Cron oturumunun KENDİ
5213
5213
  kanalına yansıtmayız — cevabı zaten kendi akışından alır (çift yok). */
@@ -5256,11 +5256,8 @@ function cronMirrorTargets(cronSid) {
5256
5256
 
5257
5257
  function cronFire(job) {
5258
5258
  try {
5259
- let sid = job.sessionId;
5260
- const exists = sid && engine.listSessions().some((s) => s.id === sid);
5261
- if (!exists) {
5262
- const s = engine.createSession();
5263
- sid = s.id;
5259
+ const sid = reuseOrLatestSession(job.sessionId);
5260
+ if (sid !== String(job.sessionId || '')) {
5264
5261
  cron.update(job.id, { sessionId: sid });
5265
5262
  }
5266
5263
  cronAnswerPending.set(String(sid), job);
@@ -5276,10 +5273,8 @@ function cronFire(job) {
5276
5273
  function watcherFire(w, value) {
5277
5274
  try {
5278
5275
  watcherLog(`tetiklendi id=${w.id} name="${w.name}" kind=${w.kind} op=${w.op} value=${value}`);
5279
- let sid = w.sessionId;
5280
- const exists = sid && engine.listSessions().some((s) => s.id === sid);
5281
- if (!exists) {
5282
- sid = engine.createSession().id;
5276
+ const sid = reuseOrLatestSession(w.sessionId);
5277
+ if (sid !== String(w.sessionId || '')) {
5283
5278
  watchers.patch(w.id, { sessionId: sid });
5284
5279
  }
5285
5280
  const target =
@@ -5372,7 +5367,7 @@ ipcMain.handle('browser:shown:set', (_e, v) => {
5372
5367
  if (browser.open) {
5373
5368
  browser.visible = !!v;
5374
5369
  layoutBrowser();
5375
- browserEmit({ open: true, width: browser.width });
5370
+ browserEmit({ open: true, width: browserShownWidth(browserW()) });
5376
5371
  }
5377
5372
  return { shown: !!v };
5378
5373
  });
@@ -5429,7 +5424,7 @@ function setBrowserPhone(on) {
5429
5424
  if (url && /^https?:/i.test(url)) wc.loadURL(url).catch(() => {});
5430
5425
  }
5431
5426
  } catch {}
5432
- applyPhoneEmulation(); // açık: 390x844 cihaz ortalanır kapalı: emülasyon kapanır
5427
+ /* dock daralır/genişler layout + renderer --bw tazelenir */
5433
5428
  if (browser.open && win && !win.isDestroyed()) {
5434
5429
  layoutBrowser();
5435
5430
  const [w] = win.getContentSize();
@@ -6196,7 +6191,7 @@ ipcMain.handle('ide:previewFile', async (_e, rel) => {
6196
6191
  const url = base + '/' + relPath;
6197
6192
  setBrowserOpen(true, true);
6198
6193
  browser.view.webContents.loadURL(url).catch(() => {});
6199
- browserEmit({ open: true, width: browser.width, url });
6194
+ browserEmit({ open: true, width: browserShownWidth(browserW()), url });
6200
6195
  return { ok: true, url };
6201
6196
  } catch (e) {
6202
6197
  return { ok: false, error: String((e && e.message) || e) };
@@ -6234,7 +6229,7 @@ ipcMain.handle('ide:preview', async () => {
6234
6229
  url = base + '/';
6235
6230
  }
6236
6231
  browser.view.webContents.loadURL(url).catch(() => {});
6237
- browserEmit({ open: true, width: browser.width, url });
6232
+ browserEmit({ open: true, width: browserShownWidth(browserW()), url });
6238
6233
  if (!bcLastServerUrl) bcTellServe(url.replace(/\/$/, ''));
6239
6234
  return { ok: true, url };
6240
6235
  } catch (e) {
@@ -374,7 +374,6 @@
374
374
  <button id="bbReload" title="Yenile" data-i18n-title="tip_bb_reload">&#x21BB;</button>
375
375
  <input id="bbUrl" placeholder="adres yaz veya ara…" autocomplete="off" spellcheck="false" data-i18n-ph="bb_ph" />
376
376
  <button id="bbPhone" title="Telefon modu — mobil versiyon / web versiyonu" data-i18n-title="tip_bb_phone"><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="7" y="2" width="10" height="20" rx="2.5"/><line x1="11" y1="18" x2="13" y2="18"/></svg></button>
377
- <button id="bbShot" title="Ekran görüntüsünü sohbete ekle" data-i18n-title="tip_bb_shot">&#x25A3;</button>
378
377
  <button id="bbOpenExt" title="Tarayıcıda aç" data-i18n-title="tip_bb_open">&#x2197;</button>
379
378
  <button id="bbClose" title="Kapat" data-i18n-title="btn_close">&#x00D7;</button>
380
379
  </div>
@@ -56,7 +56,6 @@ const els = {
56
56
  bbReload: $('#bbReload'),
57
57
  bbUrl: $('#bbUrl'),
58
58
  bbOpenExt: $('#bbOpenExt'),
59
- bbShot: $('#bbShot'),
60
59
  bbClose: $('#bbClose'),
61
60
  bbResize: $('#bbResize'),
62
61
  bbPhone: $('#bbPhone'),
@@ -1059,7 +1058,7 @@ async function renderUsagePane() {
1059
1058
  } catch {
1060
1059
  rep = { today: { total: {}, models: [] }, month: { total: {}, models: [] } };
1061
1060
  }
1062
- const wwi = await beast.whereWasIGet().catch(() => ({ enabled: true }));
1061
+ const wwi = await beast.whereWasIGet().catch(() => ({ enabled: false }));
1063
1062
  const t = rep.today.total || {};
1064
1063
  const mo = rep.month.total || {};
1065
1064
  const card = (label, v) =>
@@ -5326,28 +5325,6 @@ async function init() {
5326
5325
  const u = els.bbUrl.value.trim();
5327
5326
  if (/^https?:\/\//i.test(u)) beast.openExternal(u);
5328
5327
  });
5329
- els.bbShot.addEventListener('click', async () => {
5330
- try {
5331
- setStatus('ekran görüntüsü alınıyor…');
5332
- const r = await beast.browserScreenshot();
5333
- setStatus('');
5334
- if (r && r.ok) {
5335
- pending.push({
5336
- type: 'image',
5337
- name: 'screenshot-' + new Date().toISOString().slice(11, 19).replace(/:/g, '') + '.jpg',
5338
- dataUrl: r.image,
5339
- });
5340
- renderChips();
5341
- scrollDown();
5342
- toast('Görüntü eklendi — mesajına iliştirilecek');
5343
- } else {
5344
- toast((r && r.error) || 'Ekran görüntüsü alınamadı');
5345
- }
5346
- } catch (e) {
5347
- setStatus('');
5348
- toast(String((e && e.message) || e));
5349
- }
5350
- });
5351
5328
  els.bbUrl.addEventListener('keydown', (e) => {
5352
5329
  if (e.key === 'Enter') {
5353
5330
  const v = els.bbUrl.value.trim();
@@ -6753,7 +6730,8 @@ async function renderTasksPanel() {
6753
6730
  const undoMap = new Map((r.undo || []).map((u) => [u.id, u.files]));
6754
6731
  let html =
6755
6732
  '<div class="tsk-head"><span>G\u00D6REVLER</span>' +
6756
- '<button id="tskUndoLast" ' + (r.lastTodoId ? '' : 'disabled') + ' title="Kay\u0131tl\u0131 son g\u00F6revi geri al">\u21B6 Son G\u00F6revi Geri Al</button>' +
6733
+ '<button id="tskUndoLast" class="tsk-undo-last" ' + (r.lastTodoId ? '' : 'disabled') +
6734
+ ' title="Son g\u00F6revi geri al">\u21B6</button>' +
6757
6735
  '<button id="tskClose" title="Kapat">\u00D7</button></div>';
6758
6736
  if (!(r.todos || []).length) {
6759
6737
  html += '<div class="tsk-empty">g\u00F6rev listesi yok</div>';
@@ -1495,6 +1495,9 @@ body.browser-open #settingsDialog { width: min(70vw, calc(100vw - var(--bw, 480p
1495
1495
  margin-bottom: 8px;
1496
1496
  cursor: pointer;
1497
1497
  background: var(--panel);
1498
+ /* button elementleri body'den renk miras almaz — dark modda siyah kalmasın */
1499
+ color: var(--text);
1500
+ font-family: inherit;
1498
1501
  }
1499
1502
  .prov-row:hover { border-color: var(--accent); }
1500
1503
  /* dil kartları: aktif seçim vurgusu */
@@ -2497,11 +2500,14 @@ body.ide-mode #bcPanel { display: flex; }
2497
2500
  .bc-todoitem.done { color: var(--muted); }
2498
2501
  .bc-todoitem.done .bc-todocheck { color: var(--ok, var(--accent)); }
2499
2502
  .bc-todoitem.done .bc-todotext { text-decoration: line-through; }
2503
+ #filePanelTitle { display: none; } /* başlık kaldırıldı — başlıkta yalnız ikonlar */
2504
+ #filePanel .file-spacer { display: none; }
2500
2505
  #filePanelHead {
2501
2506
  display: flex;
2502
2507
  align-items: center;
2508
+ justify-content: space-evenly;
2503
2509
  gap: 6px;
2504
- padding: 10px 10px;
2510
+ padding: 10px 6px;
2505
2511
  border-bottom: 1px solid var(--border);
2506
2512
  }
2507
2513
  #filePanelTitle { font-size: 11px; letter-spacing: 2px; color: var(--muted); font-weight: 800; }
@@ -2518,7 +2524,7 @@ body.ide-mode #bcPanel { display: flex; }
2518
2524
  }
2519
2525
  #filePanelHead button:hover { color: var(--text); background: var(--panel2); }
2520
2526
  #filePreview { border-color: var(--accent); color: var(--accent); font-weight: 700; }
2521
- #filePanelPath {
2527
+ #filePanelPath {
2522
2528
  font-family: var(--mono, monospace);
2523
2529
  font-size: 10px;
2524
2530
  color: var(--muted);
@@ -2569,6 +2575,14 @@ body.ide-mode #bcPanel { display: flex; }
2569
2575
  }
2570
2576
  .tsk-head button:hover { color: var(--text); border-color: var(--accent); }
2571
2577
  .tsk-head button[disabled] { opacity: 0.35; cursor: default; }
2578
+ /* başlıktaki tek ikonluk geri-al butonu — görev ikonuyla aynı boyda */
2579
+ .tsk-head .tsk-undo-last {
2580
+ color: var(--accent);
2581
+ border-color: var(--accent);
2582
+ padding: 2px 7px;
2583
+ font-size: 12px;
2584
+ }
2585
+ .tsk-head .tsk-undo-last:hover { color: var(--err); border-color: var(--err); }
2572
2586
  .tsk-row {
2573
2587
  display: flex;
2574
2588
  align-items: center;