beast-agent 2.4.5 → 2.5.1

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/src/main.js CHANGED
@@ -3404,7 +3404,7 @@ function isDevServerUrl(url) {
3404
3404
  /* Tarayıcı state: visible=false → ajanlar GİZLİ kullanır (headless);
3405
3405
  göz ikonuyla görünür mod açılır. open=view aktif, visible=panelde görünürlük */
3406
3406
  const browser = { view: null, open: false, visible: false, width: 0, attached: false, started: false, phone: false, mobile: false, mobileRect: null, deviceKey: 'iphone14', bottomInset: 0, desktopUA: '' };
3407
- browser.mobile = settings.browserMobile === true; // mobil önizleme tercihi kalıcı
3407
+ browser.mobile = false; // mobil önizleme (telefon silueti) şimdilik devre dışı
3408
3408
  if (PHONE_DEVICES[settings.browserDevice]) browser.deviceKey = settings.browserDevice;
3409
3409
 
3410
3410
  function browserEmit(payload) {
@@ -4584,19 +4584,37 @@ function resyncBrowserUi() {
4584
4584
  }
4585
4585
  }
4586
4586
 
4587
- win.on('resize', layoutBrowser);
4587
+ win.on('resize', () => {
4588
+ layoutBrowser();
4589
+ /* resize sürerken son boyutu yakala: maximize/restore bitiminde dock KESİN
4590
+ yeni pencere boyutuna otursun (BrowserView bayat bounds bırakmasın) */
4591
+ clearTimeout(win._bzRzT);
4592
+ win._bzRzT = setTimeout(() => { try { layoutBrowser(); } catch {} }, 120);
4593
+ });
4588
4594
  win.on('maximize', () => {
4589
4595
  layoutBrowser();
4590
4596
  resyncBrowserUi();
4597
+ setTimeout(() => { try { layoutBrowser(); resyncBrowserUi(); } catch {} }, 80);
4598
+ setTimeout(() => { try { layoutBrowser(); resyncBrowserUi(); } catch {} }, 300);
4591
4599
  try { if (win && !win.isDestroyed()) win.webContents.send('agent:event', { type: 'win-max', maximized: true }); } catch {}
4592
4600
  });
4593
4601
  win.on('unmaximize', () => {
4594
4602
  layoutBrowser();
4595
4603
  resyncBrowserUi();
4604
+ setTimeout(() => { try { layoutBrowser(); resyncBrowserUi(); } catch {} }, 80);
4605
+ setTimeout(() => { try { layoutBrowser(); resyncBrowserUi(); } catch {} }, 300);
4596
4606
  try { if (win && !win.isDestroyed()) win.webContents.send('agent:event', { type: 'win-max', maximized: false }); } catch {}
4597
4607
  });
4598
- win.on('enter-full-screen', () => { layoutBrowser(); resyncBrowserUi(); });
4599
- win.on('leave-full-screen', () => { layoutBrowser(); resyncBrowserUi(); });
4608
+ win.on('enter-full-screen', () => {
4609
+ layoutBrowser(); resyncBrowserUi();
4610
+ setTimeout(() => { try { layoutBrowser(); resyncBrowserUi(); } catch {} }, 80);
4611
+ setTimeout(() => { try { layoutBrowser(); resyncBrowserUi(); } catch {} }, 300);
4612
+ });
4613
+ win.on('leave-full-screen', () => {
4614
+ layoutBrowser(); resyncBrowserUi();
4615
+ setTimeout(() => { try { layoutBrowser(); resyncBrowserUi(); } catch {} }, 80);
4616
+ setTimeout(() => { try { layoutBrowser(); resyncBrowserUi(); } catch {} }, 300);
4617
+ });
4600
4618
  win.on('show', layoutBrowser);
4601
4619
  // X'e basınca gizle — tepside yaşamaya devam, WhatsApp bağlantısı sürer
4602
4620
  win.on('close', (e) => {
@@ -6201,9 +6219,10 @@ function empatiCfg() {
6201
6219
  return empati.mergeCfg(settings.empati || {});
6202
6220
  }
6203
6221
 
6204
- /* EMPATİ HAFIZASI: sohbet akışını kaydet + kullanıcı ilgi alanlarını öğren.
6205
- - user mesajı → hafızaya yaz + sık kelimelerden ilgi etiketi öğren
6206
- - assistant cevabı hafızaya yaz (konuşmanın iki yanı da kalsın)
6222
+ /* EMPATİ HAFIZASI: sohbet akışını kaydet (ilgi çıkarımının ham verisi).
6223
+ - user/assistant mesajı → hafızaya yaz (konuşmanın iki yanı da kalsın)
6224
+ İlgi alanları burada MESAJ BAŞINA öğrenilmez gece yansımasında
6225
+ (günde bir) LLM bu birikimden konu etiketleri çıkarır (nightref adım 3b).
6207
6226
  Beast Code/Studio iş mesajları, /komutlar ve bağlam enjeksiyonları kayda girmez. */
6208
6227
  function empatiRememberFromEvent(ev) {
6209
6228
  if (!ev || ev.type !== 'message' || !ev.message || !ev.message.role) return;
@@ -6222,7 +6241,6 @@ function empatiRememberFromEvent(ev) {
6222
6241
  if (bc) return; /* kod işi — ilgi alanını bulanıklaştırır */
6223
6242
  if (m.role === 'user') {
6224
6243
  empati.rememberConversation(txt, 'sohbet');
6225
- empati.learnInterests(txt);
6226
6244
  } else {
6227
6245
  empati.rememberConversation(txt, 'beast');
6228
6246
  }
@@ -6261,7 +6279,9 @@ async function empatiSignalSelf() {
6261
6279
  }
6262
6280
 
6263
6281
  async function empatiSignalNews() {
6264
- const topics = String(empatiCfg().newsTopics || '').split(',').map((s) => s.trim()).filter(Boolean);
6282
+ /* haber konuları İlgi Alanları'ndan OTOMATİK türetilir — seçime gerek yok */
6283
+ const topics = String(empati.combinedInterests(empatiCfg()) || '')
6284
+ .split(',').map((s) => s.trim()).filter((s) => s.length > 2);
6265
6285
  if (!topics.length) return [];
6266
6286
  return empati.fetchNews(topics);
6267
6287
  }
@@ -6309,6 +6329,16 @@ function empatiLlmCompose(prompt) {
6309
6329
  KENDİSİNİN attığını bilir — aynı oturum, kesintisiz bağlam. */
6310
6330
  const PROACTIVE_MARK = '🫡 *Beast proaktif:*';
6311
6331
 
6332
+ /* bildirimin ALTINA YAZILAN KAYNAK: haberin gerçek linki varsa o, yoksa kaynak adı.
6333
+ Kullanıcı "bu proje neymiş?" diye sorduğunda linkten bulabilsin. */
6334
+ function empatiSourceLine(ev) {
6335
+ if (!ev) return '';
6336
+ const url = String(ev.url || '').trim();
6337
+ if (/^https?:\/\//i.test(url)) return '🔗 ' + url;
6338
+ const src = String(ev.source || '').trim();
6339
+ return src ? '🔗 kaynak: ' + src.slice(0, 80) : '';
6340
+ }
6341
+
6312
6342
  function empatiInjectToSession(sid, out) {
6313
6343
  try {
6314
6344
  if (!sid || engine.isBusy(sid)) return; /* tur ortasında geçmişi karıştırma — bildirim kanala zaten gitti */
@@ -6316,6 +6346,20 @@ function empatiInjectToSession(sid, out) {
6316
6346
  } catch {}
6317
6347
  }
6318
6348
 
6349
+ /* kanala giden metin + Beast'in İÇ bağlamı ayrıdır: kullanıcı linki silse bile
6350
+ model olayın başlığını, detayını ve linkini KENDİSİ görür — "bu neymiş?"
6351
+ sorusuna insansı cevap verebilir */
6352
+ function empatiInjectText(ev, out) {
6353
+ if (!ev) return out;
6354
+ return (
6355
+ out + '\n\n[BAĞLAM — kullanıcı bu bildirimi sorarsa bununla cevapla]\n' +
6356
+ 'Olay: ' + String(ev.title || '').slice(0, 200) + '\n' +
6357
+ (ev.detail ? 'Detay: ' + String(ev.detail).slice(0, 200) + '\n' : '') +
6358
+ (ev.url ? 'Link: ' + String(ev.url) + '\n' : '') +
6359
+ 'Kaynak: ' + String(ev.source || '').slice(0, 80)
6360
+ );
6361
+ }
6362
+
6319
6363
  /* Oturum yoksa oluştur (processTgMessage/processDcMessage ile aynı kalıp) */
6320
6364
  function ensureTgSession(chatId) {
6321
6365
  let sid = tgChats.get(chatId);
@@ -6354,16 +6398,18 @@ function empatiDesktopSid() {
6354
6398
  Hiçbir entegrasyon yazılamazsa masaüstü chat UI (toast) kalır. */
6355
6399
  function empatiNotify(text, ev) {
6356
6400
  const cfg = empatiCfg();
6401
+ const src = empatiSourceLine(ev);
6402
+ const out = PROACTIVE_MARK + '\n' + text + (src ? '\n' + src : '');
6403
+ const inject = empatiInjectText(ev, out);
6357
6404
  const senders = [];
6358
6405
  const tryWa = () => {
6359
6406
  try {
6360
6407
  const own = waOwnerNum();
6361
6408
  if (own && wa && wa.connected) {
6362
6409
  const jid = own + '@s.whatsapp.net';
6363
- const out = PROACTIVE_MARK + '\n' + text;
6364
6410
  senders.push(() =>
6365
6411
  Promise.resolve(sendWaSafe(jid, out))
6366
- .then(() => empatiInjectToSession(ensureWaSession(jid), out))
6412
+ .then(() => empatiInjectToSession(ensureWaSession(jid), inject))
6367
6413
  .catch(() => {})
6368
6414
  );
6369
6415
  }
@@ -6372,11 +6418,10 @@ function empatiNotify(text, ev) {
6372
6418
  const tryTg = () => {
6373
6419
  try {
6374
6420
  if (tg && tg.connected) {
6375
- const out = PROACTIVE_MARK + '\n' + text;
6376
6421
  for (const id of tgOwnerIds()) {
6377
6422
  senders.push(() =>
6378
6423
  Promise.resolve(sendTgSafe(id, out))
6379
- .then(() => empatiInjectToSession(ensureTgSession(String(id)), out))
6424
+ .then(() => empatiInjectToSession(ensureTgSession(String(id)), inject))
6380
6425
  .catch(() => {})
6381
6426
  );
6382
6427
  }
@@ -6386,11 +6431,11 @@ function empatiNotify(text, ev) {
6386
6431
  const tryDc = () => {
6387
6432
  try {
6388
6433
  if (dc && dc.connected) {
6389
- const out = '🫡 **Beast proaktif:**\n' + text;
6434
+ const outDc = out.replace('🫡 *Beast proaktif:*', '🫡 **Beast proaktif:**');
6390
6435
  for (const id of dcOwnerIds()) {
6391
6436
  senders.push(() =>
6392
- Promise.resolve(sendDcSafe(id, out))
6393
- .then(() => empatiInjectToSession(ensureDcSession(String(id)), out))
6437
+ Promise.resolve(sendDcSafe(id, outDc))
6438
+ .then(() => empatiInjectToSession(ensureDcSession(String(id)), inject))
6394
6439
  .catch(() => {})
6395
6440
  );
6396
6441
  }
@@ -6409,8 +6454,8 @@ function empatiNotify(text, ev) {
6409
6454
  metin güncel sohbete de asistan mesajı olarak işlenir */
6410
6455
  try {
6411
6456
  if (!sent && win && !win.isDestroyed()) {
6412
- empatiInjectToSession(empatiDesktopSid(), PROACTIVE_MARK + '\n' + text);
6413
- win.webContents.send('agent:event', { type: 'proactive', id: ev.id, level: ev.level, title: ev.title, text });
6457
+ empatiInjectToSession(empatiDesktopSid(), inject);
6458
+ win.webContents.send('agent:event', { type: 'proactive', id: ev.id, level: ev.level, title: ev.title, text: out });
6414
6459
  }
6415
6460
  } catch {}
6416
6461
  }
@@ -6798,7 +6843,8 @@ function termShellSpawn() {
6798
6843
  }
6799
6844
 
6800
6845
  ipcMain.handle('terminal:toggle', () => {
6801
- if (browser.open) setBrowserOpen(false);
6846
+ /* terminal artık tarayıcıyla AYNI alanı paylaşmıyor (Beast Code'da kod
6847
+ bölmesinde) — açılışı/kapanışı tarayıcıya DOKUNMAZ */
6802
6848
  return { ok: true, cwd: termShellCwd || (engine && engine.workspace) || settings.workspace || app.getPath('home') };
6803
6849
  });
6804
6850
 
@@ -6895,11 +6941,23 @@ function bcGetSession(folder) {
6895
6941
  JSON.stringify({ t: 'meta2', bgOf: '', title: 'Beast Code', at: new Date().toISOString() }) + '\n'
6896
6942
  );
6897
6943
  } catch {}
6944
+ bcMarkWs(s, folder);
6898
6945
  engine.cache.set(s.id, s);
6899
6946
  bcSessions.set(folder, s.id);
6900
6947
  return s;
6901
6948
  }
6902
6949
 
6950
+ /* Beast Code oturumuna çalışma klasörünü işle: sohbet geçmişi listesinde
6951
+ hangi klasörde çalışıldığı görünür; oturum tekrar açılınca aynı klasöre
6952
+ bağlanır. Kayıt oturum dosyasına bcws satırı olarak YAZILIR. */
6953
+ function bcMarkWs(s, folder) {
6954
+ try {
6955
+ if (s.bcWs === folder) return;
6956
+ s.bcWs = folder;
6957
+ fs.appendFileSync(engine._file(s.id), JSON.stringify({ t: 'bcws', ws: folder, at: new Date().toISOString() }) + '\n');
6958
+ } catch {}
6959
+ }
6960
+
6903
6961
  /* Beast Code motoru: TAMAMEN BEAST MOTORU — opencode'in döngü mantığı
6904
6962
  (compaction, prune, prompt-cache, doom-loop, yetim onarım, proje
6905
6963
  talimatları) engine.js'e native port edildi; köprü/alt süreç yok. */
@@ -7071,6 +7129,85 @@ ipcMain.handle('beastcode:new', async () => {
7071
7129
  return { ok: true };
7072
7130
  });
7073
7131
 
7132
+ /* ---------------- Beast Code SOHBET GEÇMİŞİ ----------------
7133
+ Soldaki dosya panelinin alt yarısında eski Beast Code oturumları listelenir.
7134
+ Ana sohbet geçmişinden (bgTitle gizli oturumlar) ve Studio'dan TAMAMEN AYRIDIR.
7135
+ Oturuma tıklayınca panele açılır, kaldığı yerden devam edilir. */
7136
+ ipcMain.handle('bc:history', async () => {
7137
+ try {
7138
+ return { ok: true, items: engine.listBcSessions(100) };
7139
+ } catch (e) {
7140
+ return { ok: false, error: String((e && e.message) || e), items: [] };
7141
+ }
7142
+ });
7143
+
7144
+ function bcMsgText(m) {
7145
+ const t = Array.isArray(m && m.content)
7146
+ ? m.content.filter((p) => p && p.type === 'text').map((p) => String(p.text || '')).join('\n')
7147
+ : String((m && m.content) || '');
7148
+ return t.replace(/\s+/g, ' ').trim();
7149
+ }
7150
+
7151
+ ipcMain.handle('bc:open', async (_e, payload) => {
7152
+ const id = String((payload && payload.id) || '');
7153
+ if (!engine) return { ok: false, error: 'ajan hazır değil' };
7154
+ if (!id) return { ok: false, error: 'oturum belirtilmedi' };
7155
+ let s;
7156
+ try { s = engine._load(id); } catch { return { ok: false, error: 'oturum açılamadı' }; }
7157
+ if (s.bgTitle && s.bgTitle !== 'Beast Code') return { ok: false, error: 'bu oturum Beast Code oturumu değil' };
7158
+ /* mevcut klasöre bağlan: sonraki mesajlar BU oturumda sürer */
7159
+ const ws = ideRoot();
7160
+ s.workspace = ws;
7161
+ s.bcCode = true;
7162
+ bcMarkWs(s, ws);
7163
+ engine.cache.set(s.id, s);
7164
+ bcSessions.set(ws, s.id);
7165
+ const msgs = [];
7166
+ for (const m of s.messages || []) {
7167
+ if (m.tool_calls) continue;
7168
+ const txt = bcMsgText(m);
7169
+ if (!txt) continue;
7170
+ msgs.push({ role: m.role === 'assistant' ? 'assistant' : 'user', text: txt.slice(0, 4000) });
7171
+ }
7172
+ return {
7173
+ ok: true,
7174
+ sessionId: s.id,
7175
+ busy: !!engine.isBusy(s.id),
7176
+ mode: s.bcMode || '',
7177
+ messages: msgs.slice(-200),
7178
+ };
7179
+ });
7180
+
7181
+ /* TEK oturum silme (soldaki geçmiş listesindeki × butonu) */
7182
+ ipcMain.handle('bc:delete', async (_e, payload) => {
7183
+ const id = String((payload && payload.id) || '');
7184
+ if (!engine || !id) return { ok: false, error: 'oturum belirtilmedi' };
7185
+ let s;
7186
+ try { s = engine._load(id); } catch { return { ok: false, error: 'oturum açılamadı' }; }
7187
+ if (s.bgTitle && s.bgTitle !== 'Beast Code') return { ok: false, error: 'yalnız Beast Code oturumu silinir' };
7188
+ if (engine.isBusy(id)) return { ok: false, error: 'oturum çalışıyor — önce ■ ile durdur' };
7189
+ for (const [folder, sid] of [...bcSessions.entries()]) {
7190
+ if (String(sid) === id) bcSessions.delete(folder);
7191
+ }
7192
+ try { engine.deleteSession(id); } catch {}
7193
+ return { ok: true };
7194
+ });
7195
+
7196
+ /* TÜM Beast Code oturumlarını sil — çalışanlar atlanır */
7197
+ ipcMain.handle('bc:deleteAll', async () => {
7198
+ if (!engine) return { ok: false, error: 'ajan hazır değil' };
7199
+ let deleted = 0;
7200
+ let skipped = 0;
7201
+ for (const it of engine.listBcSessions(200)) {
7202
+ if (engine.isBusy(it.id)) { skipped++; continue; }
7203
+ for (const [folder, sid] of [...bcSessions.entries()]) {
7204
+ if (String(sid) === it.id) bcSessions.delete(folder);
7205
+ }
7206
+ try { engine.deleteSession(it.id); deleted++; } catch {}
7207
+ }
7208
+ return { ok: true, deleted, skipped };
7209
+ });
7210
+
7074
7211
  /* ---------------- Beast Studio paneli (video yapma/düzenleme modu) ----------------
7075
7212
  Beast Code ile AYRI ve ÖZEL dünya: kendi çalışma klasörü (studioRoot), kendi
7076
7213
  gizli engine oturumları (klasör bazlı), kendi sohbet kuyruğu. Studio
@@ -7901,27 +8038,8 @@ ipcMain.handle('ide:previewFile', async (_e, rel) => {
7901
8038
  ipcMain.handle('ide:preview', async () => {
7902
8039
  try {
7903
8040
  const root = ideRoot();
7904
- /* MOBİL UYGULAMA PROJESİ (expo/react-native): statik sunucu değil,
7905
- `npm run web` başlat telefon silueti içinde canlı önizleme */
7906
- const mob = ideMobileProject(root);
7907
- if (mob.mobile) {
7908
- let url = '';
7909
- /* ajanın kendi dev sunucusu canlıysa öncelikli */
7910
- if (bcLastServerUrl && isDevServerUrl(bcLastServerUrl)) {
7911
- const alive = await probeDevUrl(bcLastServerUrl, 800).catch(() => false);
7912
- if (alive) url = bcLastServerUrl;
7913
- }
7914
- if (!url) {
7915
- const r = await mobilePreviewStart(root);
7916
- if (!r.ok) return { ok: false, error: r.error };
7917
- url = r.url;
7918
- }
7919
- setBrowserMobile(true); /* siluet + görünür tarayıcı */
7920
- try { browser.view.webContents.loadURL(url).catch(() => {}); } catch {}
7921
- browserEmit({ open: true, width: browserShownWidth(browserW()), url, mobile: true, phoneRect: browser.mobileRect });
7922
- bcTellMobileServe(url);
7923
- return { ok: true, url, mobile: true };
7924
- }
8041
+ /* MOBİL ÖNİZLEME kaldırıldı: mobil projeler de normal tarayıcı dock'unda
8042
+ açılır ajanın dev sunucusu varsa o adres, yoksa dahili statik sunucu. */
7925
8043
  const pick = (name) => {
7926
8044
  const p = path.join(root, name);
7927
8045
  try { return fs.existsSync(p) ? p : null; } catch { return null; }
@@ -7982,10 +8100,7 @@ ipcMain.handle('ide:previewUrl', async (_e, url) => {
7982
8100
  } else {
7983
8101
  return { ok: false, error: 'yalnız localhost adresleri önizlenebilir' };
7984
8102
  }
7985
- /* Expo/Metro dev sunucusu telefon modu OTOMATİK (mobil uygulama canlı önizleme) */
7986
- if (/^https?:\/\/(?:localhost|127\.0\.0\.1):(8081|19000|19001|19002|3000|5173)\//i.test(target)) {
7987
- if (!browser.phone) setBrowserPhone(true);
7988
- }
8103
+ /* mobil önizleme otomatik telefon modu kaldırıldı önizleme normal dockta açılır */
7989
8104
  /* forceVisible: otomatik ve GÖRÜNÜR açılır */
7990
8105
  setBrowserOpen(true, true);
7991
8106
  browser.view.webContents.loadURL(target).catch(() => {});
package/src/preload.js CHANGED
@@ -81,6 +81,10 @@ contextBridge.exposeInMainWorld('beast', {
81
81
  bcUndo: (sessionId, todoId) => ipcRenderer.invoke('bc:undo', { sessionId, todoId }),
82
82
  beastcodeStop: () => ipcRenderer.invoke('beastcode:stop'),
83
83
  beastcodeNew: () => ipcRenderer.invoke('beastcode:new'),
84
+ bcHistory: () => ipcRenderer.invoke('bc:history'),
85
+ bcOpen: (id) => ipcRenderer.invoke('bc:open', { id }),
86
+ bcDelete: (id) => ipcRenderer.invoke('bc:delete', { id }),
87
+ bcDeleteAll: () => ipcRenderer.invoke('bc:deleteAll'),
84
88
  studioSend: (msg, attachments) => ipcRenderer.invoke('studio:send', { msg, attachments }),
85
89
  studioStop: () => ipcRenderer.invoke('studio:stop'),
86
90
  studioNew: () => ipcRenderer.invoke('studio:new'),
@@ -69,7 +69,7 @@
69
69
  tab_notes: 'Oturum Notları',
70
70
  tab_history: 'Oturum Geçmişi',
71
71
  tab_agents: 'Paralel Ajanlar',
72
- tab_tts: 'Sesli Yanıt',
72
+ tab_tts: 'Sesli Yanıt',
73
73
  tab_install: 'Kurulum',
74
74
  tab_email: 'E-posta',
75
75
  tab_integrations: 'Entegrasyonlar',
@@ -131,7 +131,7 @@
131
131
  em_notify_tg: 'Telegram',
132
132
  em_notify_dc: 'Discord',
133
133
  em_notify_sub: 'Seçmezsen ekli ve bağlı entegrasyonların hepsine yazar; hiçbiri bağlı değilse masaüstü sohbete düşer.',
134
- em_interests: 'İlgi alanların — haber filtresi buna göre ağırlıklandırılır',
134
+ em_interests: 'İlgi Alanları',
135
135
  em_interests_ph: 'örn: yapay zeka, yazılım, trading, open source',
136
136
  em_news: 'Haber kaynağı (Google News)',
137
137
  em_news_topics_ph: 'haber konuları, virgülle: yapay zeka, ekonomi…',
@@ -148,10 +148,12 @@
148
148
  em_st_ignored: 'yok sayıldı',
149
149
  em_lv_high: 'YÜKSEK',
150
150
  em_lv_medium: 'ORTA',
151
- em_interests_auto: 'Bunlara ek olarak sohbetlerinden öğrenilen ilgi alanları da otomatik devreye girer.',
151
+ em_interests_auto: 'Konuşmalarından çıkarılan ilgi alanları otomatik eklenir; Google News haber taraması bu ilgilere göre seçimsiz otomatik yapılır.',
152
+ em_behavior: 'Ajan Davranışı',
153
+ em_behavior_ph: 'örn: bana kanka diye hitap et, kısa ve espirili yaz, emoji kullanma, soru sorarak bitir…',
152
154
  em_scan_busy: 'Tarama hâlâ çalışıyor — birkaç saniye sonra tekrar dene.',
153
155
  em_mem_h2: 'Empati Hafızası',
154
- em_mem_sub: 'Konuşmalarınız burada birikir; sohbetlerinden ilgi alanların öğrenilir. Tarama ve bildirim mesajları bu hafızayla sana göre kişiselleşir.',
156
+ em_mem_sub: 'Konuşmalarınız burada birikir; gece yansımasında (günde bir) bu kayıtlardan ilgi alanların çıkarılır. Tarama ve bildirim mesajları bu hafızayla sana göre kişiselleşir.',
155
157
  em_mem_learned: 'Sohbetlerden öğrenilen ilgi alanları',
156
158
  em_mem_no_learned: 'Henüz öğrenilen ilgi yok — sohbet ettikçe burada birikir.',
157
159
  em_mem_recent: 'Son konuşma kayıtları',
@@ -258,7 +260,7 @@
258
260
  tts_sub: 'Açık olursa WhatsApp cevapları metnin yanı sıra sesli not olarak da gönderilir.',
259
261
  tts_active: 'Aktif',
260
262
  tts_save: 'TTS Kaydet',
261
- tts_test: 'Test sesi çal',
263
+ tts_test: 'Test sesi çal',
262
264
  stt_download_now: 'Şimdi indir / hazırla',
263
265
  tts_note: 'Edge TTS: ücretsiz yerel motor — anahtar gerekmez (Ahmet/Emel vb.). OpenAI motoru: uyumlu speech API (tts-1, tts-1-hd; sesler alloy, echo, fable, onyx, nova, shimmer).',
264
266
  tts_engine: 'Motor',
@@ -583,6 +585,8 @@
583
585
  bc_ph: 'Beast Code mesajı yaz — Enter ile gönder…',
584
586
  st_ph: 'Beast Studio mesajı yaz — Enter ile gönder…',
585
587
  bc_new: 'Yeni oturum',
588
+ bc_hist: 'SOHBET GEÇMİŞİ',
589
+ bc_hist_clear: 'Tüm geçmişi sil',
586
590
  bc_clear: 'Çıktıyı temizle',
587
591
  bc_stop: 'Çalışan mesajı durdur',
588
592
  store_title: 'SKILLS STORE',
@@ -690,7 +694,7 @@
690
694
  tab_notes: 'Session Notes',
691
695
  tab_history: 'Session History',
692
696
  tab_agents: 'Parallel Agents',
693
- tab_tts: 'Voice Reply',
697
+ tab_tts: 'Voice Reply',
694
698
  tab_install: 'Setup',
695
699
  tab_email: 'E-mail',
696
700
  tab_integrations: 'Integrations',
@@ -752,7 +756,7 @@
752
756
  em_notify_tg: 'Telegram',
753
757
  em_notify_dc: 'Discord',
754
758
  em_notify_sub: 'If left empty, it writes to all connected integrations; with none connected it lands in the desktop chat.',
755
- em_interests: 'Your interests — news filtering is weighted by these',
759
+ em_interests: 'Interest Areas',
756
760
  em_interests_ph: 'e.g. AI, software, trading, open source',
757
761
  em_news: 'News source (Google News)',
758
762
  em_news_topics_ph: 'news topics, comma separated: AI, economy…',
@@ -769,10 +773,12 @@
769
773
  em_st_ignored: 'ignored',
770
774
  em_lv_high: 'HIGH',
771
775
  em_lv_medium: 'MEDIUM',
772
- em_interests_auto: 'On top of these, interest areas learned from your chats kick in automatically.',
776
+ em_interests_auto: 'Interest areas inferred from your chats are added automatically; Google News scanning runs automatically from these no manual topic selection.',
777
+ em_behavior: 'Agent Behavior',
778
+ em_behavior_ph: 'e.g. call me bro, keep it short and witty, no emojis, end with a question…',
773
779
  em_scan_busy: 'A scan is still running — try again in a few seconds.',
774
780
  em_mem_h2: 'Empathy Memory',
775
- em_mem_sub: 'Your conversations accumulate here; interest areas are learned from your chats. Scans and notification texts are personalized with this memory.',
781
+ em_mem_sub: 'Your conversations accumulate here; your interest areas are inferred from them at the night reflection (once a day). Scans and notification texts are personalized with this memory.',
776
782
  em_mem_learned: 'Interest areas learned from chats',
777
783
  em_mem_no_learned: 'No learned interests yet — they accumulate as you chat.',
778
784
  em_mem_recent: 'Recent conversation records',
@@ -879,7 +885,7 @@
879
885
  tts_sub: 'When on, WhatsApp replies are also sent as voice notes alongside text.',
880
886
  tts_active: 'Active',
881
887
  tts_save: 'Save TTS',
882
- tts_test: 'Play test sound',
888
+ tts_test: 'Play test sound',
883
889
  stt_download_now: 'Download / prepare now',
884
890
  tts_note: 'Edge TTS: free local engine — no key needed (Ahmet/Emel etc.). OpenAI engine: compatible speech API (tts-1, tts-1-hd; voices alloy, echo, fable, onyx, nova, shimmer).',
885
891
  tts_engine: 'Engine',
@@ -1262,6 +1268,8 @@
1262
1268
  bc_ph: 'Type a message for Beast Code — press Enter to send…',
1263
1269
  st_ph: 'Type a message for Beast Studio — press Enter to send…',
1264
1270
  bc_new: 'New session',
1271
+ bc_hist: 'CHAT HISTORY',
1272
+ bc_hist_clear: 'Clear all history',
1265
1273
  bc_clear: 'Clear output',
1266
1274
  bc_stop: 'Stop running message',
1267
1275
  store_title: 'SKILLS STORE',
@@ -35,6 +35,14 @@
35
35
  <div id="filePanelPath" title="">—</div>
36
36
  <div id="tasksPanel" hidden></div>
37
37
  <div id="fileTree"></div>
38
+ <div id="bcHistWrap">
39
+ <div id="bcHistHead">
40
+ <span id="bcHistTitle" data-i18n="bc_hist">SOHBET GEÇMİŞİ</span>
41
+ <button id="bcHistRefresh" title="Yenile">&#x27F3;</button>
42
+ <button id="bcHistClear" title="Tüm geçmişi sil" data-i18n-title="bc_hist_clear"><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="M3 6h18"/><path d="M8 6V4a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v2"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/><path d="M10 11v6"/><path d="M14 11v6"/></svg></button>
43
+ </div>
44
+ <div id="bcHistList"></div>
45
+ </div>
38
46
  </aside>
39
47
  <div id="sideFoot">
40
48
  <button id="gearBtn" title="Ayarlar" data-i18n-title="tipGear">&#x2699;&#xFE0E;</button>
@@ -419,7 +427,6 @@
419
427
  <button id="bbReload" title="Yenile" data-i18n-title="tip_bb_reload">&#x21BB;</button>
420
428
  <input id="bbUrl" placeholder="adres yaz veya ara…" autocomplete="off" spellcheck="false" data-i18n-ph="bb_ph" />
421
429
  <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>
422
- <button id="bbMobile" title="Mobil önizleme — telefon silueti (Expo/Metro dev server)" data-i18n-title="tip_bb_mobile"><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="5" y="1.5" width="14" height="21" rx="3.5"/><line x1="9.5" y1="4.5" x2="14.5" y2="4.5"/><line x1="10.5" y1="19.5" x2="13.5" y2="19.5"/></svg></button>
423
430
  <button id="bbOpenExt" title="Tarayıcıda aç" data-i18n-title="tip_bb_open">&#x2197;</button>
424
431
  <button id="bbClose" title="Kapat" data-i18n-title="btn_close">&#x00D7;</button>
425
432
  </div>
@@ -448,17 +455,6 @@
448
455
  <input type="file" id="fileInput" multiple hidden
449
456
  accept="image/*,.txt,.md,.json,.csv,.log,.js,.ts,.py,.ps1,.bat,.cmd,.html,.css,.yaml,.yml,.xml,.ini" />
450
457
 
451
- <!-- mobil önizleme cihaz seçici: telefonun ALTINDA yüzen modern picker -->
452
- <select id="bbDevice" title="Cihaz ölçüleri" hidden>
453
- <option value="iphone15promax">iPhone 15 Pro Max · 430×932</option>
454
- <option value="iphone15pro">iPhone 15 Pro · 393×852</option>
455
- <option value="iphone14">iPhone 14 · 390×844</option>
456
- <option value="iphonese">iPhone SE · 375×667</option>
457
- <option value="pixel8">Pixel 8 · 412×915</option>
458
- <option value="galaxys23">Galaxy S23 · 360×780</option>
459
- <option value="android">Android · 360×800</option>
460
- </select>
461
-
462
458
  <script src="i18n.js"></script>
463
459
  <script src="handsfree.js"></script>
464
460
  <script src="renderer.js"></script>