beast-agent 0.20.0 → 0.21.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/package.json +1 -1
- package/scripts/release.js +21 -34
- package/src/agent/engine.js +223 -40
- package/src/main.js +232 -3
- package/src/preload.js +10 -0
- package/src/renderer/i18n.js +20 -0
- package/src/renderer/index.html +45 -1
- package/src/renderer/renderer.js +796 -2
- package/src/renderer/style.css +524 -2
package/src/main.js
CHANGED
|
@@ -2193,9 +2193,9 @@ function setBrowserOpen(v, forceVisible) {
|
|
|
2193
2193
|
}
|
|
2194
2194
|
|
|
2195
2195
|
// AÇMA — görünürlük: kullanıcı kendi açtıysa (forceVisible) MUTLAKA görünür;
|
|
2196
|
-
// ajan açtıysa göz
|
|
2196
|
+
// ajan açtıysa DA VARSAYILAN GÖRÜNÜR (göz ikonuyla gizli mod seçilmedikçe)
|
|
2197
2197
|
browser.open = true;
|
|
2198
|
-
browser.visible = forceVisible === true ? true : settings.browserHeadless
|
|
2198
|
+
browser.visible = forceVisible === true ? true : settings.browserHeadless !== true;
|
|
2199
2199
|
ensureBrowser();
|
|
2200
2200
|
if (!browser.started) {
|
|
2201
2201
|
browser.started = true;
|
|
@@ -2770,7 +2770,8 @@ function createWindow() {
|
|
|
2770
2770
|
icon: path.join(__dirname, '..', 'assets', 'app.ico'),
|
|
2771
2771
|
titleBarStyle: 'hidden',
|
|
2772
2772
|
titleBarOverlay: {
|
|
2773
|
-
|
|
2773
|
+
/* transparent Windows'ta beyaz buton arka planı veriyor — tema rengiyle başlat */
|
|
2774
|
+
color: dark ? '#0d0d0f' : '#f7f7f8',
|
|
2774
2775
|
symbolColor: dark ? '#9a9aa2' : '#707078',
|
|
2775
2776
|
height: 46,
|
|
2776
2777
|
},
|
|
@@ -3993,6 +3994,74 @@ ipcMain.handle('terminal:stop', () => {
|
|
|
3993
3994
|
return { ok: true };
|
|
3994
3995
|
});
|
|
3995
3996
|
|
|
3997
|
+
/* ---------------- Beast Code paneli (IDE modu ortası) ----------------
|
|
3998
|
+
IDE modunda ortadaki sohbet yerine Beast'in KENDİ ajanı çalışır:
|
|
3999
|
+
varsayılan model zinciri + soldaki dosya panelindeki klasör.
|
|
4000
|
+
Yazışma SOLDAKİ KLASÖRE BAĞLIDIR: her klasörün kendi gizli engine
|
|
4001
|
+
oturumu vardır (klasör değişince sohbet de değişir); sohbet geçmişi
|
|
4002
|
+
listesine karışmaz. Olayları renderer zaten agent:event ile alır,
|
|
4003
|
+
panele orada akıtılır. */
|
|
4004
|
+
const bcSessions = new Map(); /* klasör yolu → sessionId */
|
|
4005
|
+
|
|
4006
|
+
function bcGetSession(folder) {
|
|
4007
|
+
let sid = bcSessions.get(folder);
|
|
4008
|
+
if (sid) {
|
|
4009
|
+
try {
|
|
4010
|
+
const s = engine.cache.get(sid);
|
|
4011
|
+
if (s) return s;
|
|
4012
|
+
} catch {}
|
|
4013
|
+
bcSessions.delete(folder);
|
|
4014
|
+
}
|
|
4015
|
+
const s = engine._load(engine.createSession().id);
|
|
4016
|
+
s.messages = s.messages || [];
|
|
4017
|
+
s.bgTitle = 'Beast Code'; /* _view.isBg → sohbet geçmişi listesinde gizli */
|
|
4018
|
+
s.bcCode = true; /* engine: her işte todo planı çıkar (BEAST CODE MODU bloğu) */
|
|
4019
|
+
try {
|
|
4020
|
+
fs.appendFileSync(
|
|
4021
|
+
engine._file(s.id),
|
|
4022
|
+
JSON.stringify({ t: 'meta2', bgOf: '', title: 'Beast Code', at: new Date().toISOString() }) + '\n'
|
|
4023
|
+
);
|
|
4024
|
+
} catch {}
|
|
4025
|
+
engine.cache.set(s.id, s);
|
|
4026
|
+
bcSessions.set(folder, s.id);
|
|
4027
|
+
return s;
|
|
4028
|
+
}
|
|
4029
|
+
|
|
4030
|
+
ipcMain.handle('beastcode:send', (_e, payload) => {
|
|
4031
|
+
const text = String((payload && payload.msg) || '').trim();
|
|
4032
|
+
if (!text) return { ok: false, error: 'boş mesaj' };
|
|
4033
|
+
if (!engine) return { ok: false, error: 'ajan hazır değil' };
|
|
4034
|
+
if (!engine.publicState().hasModel) return { ok: false, error: 'model yok — Ayarlar → Provider sekmesinden ekle' };
|
|
4035
|
+
const ws = ideRoot();
|
|
4036
|
+
if (engine.isBusy(bcSessions.get(ws))) return { ok: false, busy: true, error: 'önceki mesaj sürüyor — ■ ile durdurabilirsin' };
|
|
4037
|
+
const s = bcGetSession(ws);
|
|
4038
|
+
s.workspace = ws; /* soldaki klasörde çalış */
|
|
4039
|
+
s.bcCode = true; /* todo disiplini + iş sonu hızlı kapanış (engine) */
|
|
4040
|
+
engine.cache.set(s.id, s);
|
|
4041
|
+
const ok = engine.send(s.id, text);
|
|
4042
|
+
if (!ok) return { ok: false, error: 'mesaj gönderilemedi' };
|
|
4043
|
+
return { ok: true, sessionId: s.id };
|
|
4044
|
+
});
|
|
4045
|
+
|
|
4046
|
+
ipcMain.handle('beastcode:stop', () => {
|
|
4047
|
+
const sid = bcSessions.get(ideRoot());
|
|
4048
|
+
if (!sid) return { ok: false };
|
|
4049
|
+
let r = false;
|
|
4050
|
+
try { r = engine.interrupt(sid); } catch {}
|
|
4051
|
+
return { ok: !!r };
|
|
4052
|
+
});
|
|
4053
|
+
|
|
4054
|
+
ipcMain.handle('beastcode:new', () => {
|
|
4055
|
+
const ws = ideRoot();
|
|
4056
|
+
const sid = bcSessions.get(ws);
|
|
4057
|
+
if (sid && engine.isBusy(sid)) return { ok: false, error: 'mesaj sürüyor — önce ■ ile durdur' };
|
|
4058
|
+
if (sid) {
|
|
4059
|
+
try { engine.deleteSession(sid); } catch {}
|
|
4060
|
+
bcSessions.delete(ws);
|
|
4061
|
+
}
|
|
4062
|
+
return { ok: true };
|
|
4063
|
+
});
|
|
4064
|
+
|
|
3996
4065
|
/* düşünme (reasoning) seviyesi */
|
|
3997
4066
|
ipcMain.handle('think:set', (_e, v) => {
|
|
3998
4067
|
setThinkLevel(v);
|
|
@@ -4110,6 +4179,166 @@ ipcMain.handle('store:remove', (_e, id) =>
|
|
|
4110
4179
|
|
|
4111
4180
|
ipcMain.handle('store:export', (_e, id) => storeMod.exportEntry(id));
|
|
4112
4181
|
|
|
4182
|
+
/* ---------- IDE MODU (sol: dosya gezgini · orta: chat · sağ: preview) ---------- */
|
|
4183
|
+
|
|
4184
|
+
const IDE_TEXT_EXT = new Set([
|
|
4185
|
+
'.html', '.htm', '.css', '.js', '.mjs', '.cjs', '.ts', '.jsx', '.tsx', '.json',
|
|
4186
|
+
'.md', '.txt', '.csv', '.py', '.ps1', '.bat', '.cmd', '.sh', '.yaml', '.yml',
|
|
4187
|
+
'.xml', '.ini', '.svg', '.gitignore',
|
|
4188
|
+
]);
|
|
4189
|
+
const IDE_MAX_BYTES = 400 * 1024;
|
|
4190
|
+
|
|
4191
|
+
function ideRoot() {
|
|
4192
|
+
/* kullanıcı panelde başka klasör seçtiyse o kök alınır; yoksa agent workspace'i */
|
|
4193
|
+
return path.resolve(settings.ideRoot || settings.workspace || app.getPath('home'));
|
|
4194
|
+
}
|
|
4195
|
+
|
|
4196
|
+
ipcMain.handle('ide:setroot', async () => {
|
|
4197
|
+
try {
|
|
4198
|
+
const r = await dialog.showOpenDialog({
|
|
4199
|
+
title: 'Klasör seç — dosya paneli ve preview bu klasörü kullanır',
|
|
4200
|
+
defaultPath: ideRoot(),
|
|
4201
|
+
properties: ['openDirectory'],
|
|
4202
|
+
});
|
|
4203
|
+
if (r.canceled || !r.filePaths || !r.filePaths[0]) return { ok: false, canceled: true };
|
|
4204
|
+
settings.ideRoot = r.filePaths[0];
|
|
4205
|
+
saveSettings();
|
|
4206
|
+
return { ok: true, root: settings.ideRoot };
|
|
4207
|
+
} catch (e) {
|
|
4208
|
+
return { ok: false, error: String((e && e.message) || e) };
|
|
4209
|
+
}
|
|
4210
|
+
});
|
|
4211
|
+
|
|
4212
|
+
/* rel yol → workspace içinde kal (path traversal kilidi) */
|
|
4213
|
+
function ideSafe(rel) {
|
|
4214
|
+
const root = ideRoot();
|
|
4215
|
+
const p = path.resolve(root, String(rel || ''));
|
|
4216
|
+
if (p !== root && !p.startsWith(root + path.sep)) return null;
|
|
4217
|
+
return p;
|
|
4218
|
+
}
|
|
4219
|
+
|
|
4220
|
+
ipcMain.handle('ide:tree', (_e, rel) => {
|
|
4221
|
+
const p = ideSafe(rel);
|
|
4222
|
+
if (!p) return { ok: false, error: 'geçersiz yol' };
|
|
4223
|
+
try {
|
|
4224
|
+
const entries = fs.readdirSync(p, { withFileTypes: true })
|
|
4225
|
+
.filter((e) => e.name !== 'node_modules' && e.name !== '.git')
|
|
4226
|
+
.map((e) => {
|
|
4227
|
+
let size = 0;
|
|
4228
|
+
try { if (e.isFile()) size = fs.statSync(path.join(p, e.name)).size; } catch {}
|
|
4229
|
+
return { name: e.name, dir: e.isDirectory(), size };
|
|
4230
|
+
})
|
|
4231
|
+
.sort((a, b) => (a.dir === b.dir ? a.name.localeCompare(b.name) : a.dir ? -1 : 1));
|
|
4232
|
+
return { ok: true, workspace: ideRoot(), entries };
|
|
4233
|
+
} catch (e) {
|
|
4234
|
+
return { ok: false, error: String((e && e.message) || e) };
|
|
4235
|
+
}
|
|
4236
|
+
});
|
|
4237
|
+
|
|
4238
|
+
ipcMain.handle('ide:read', (_e, rel) => {
|
|
4239
|
+
const p = ideSafe(rel);
|
|
4240
|
+
if (!p) return { ok: false, error: 'geçersiz yol' };
|
|
4241
|
+
const ext = path.extname(p).toLowerCase();
|
|
4242
|
+
if (ext && !IDE_TEXT_EXT.has(ext)) return { ok: false, error: 'metin dosyası değil — düzenlenemez' };
|
|
4243
|
+
try {
|
|
4244
|
+
const st = fs.statSync(p);
|
|
4245
|
+
if (st.isDirectory()) return { ok: false, error: 'klasör' };
|
|
4246
|
+
if (st.size > IDE_MAX_BYTES) return { ok: false, error: 'dosya çok büyük (max 400KB)' };
|
|
4247
|
+
const buf = fs.readFileSync(p);
|
|
4248
|
+
if (buf.slice(0, 4096).includes(0)) return { ok: false, error: 'ikili (binary) dosya' };
|
|
4249
|
+
return { ok: true, content: buf.toString('utf8') };
|
|
4250
|
+
} catch (e) {
|
|
4251
|
+
return { ok: false, error: String((e && e.message) || e) };
|
|
4252
|
+
}
|
|
4253
|
+
});
|
|
4254
|
+
|
|
4255
|
+
ipcMain.handle('ide:write', (_e, p) => {
|
|
4256
|
+
const target = ideSafe(p && p.rel);
|
|
4257
|
+
if (!target) return { ok: false, error: 'geçersiz yol' };
|
|
4258
|
+
const ext = path.extname(target).toLowerCase();
|
|
4259
|
+
if (ext && !IDE_TEXT_EXT.has(ext)) return { ok: false, error: 'metin dosyası değil — yazılamaz' };
|
|
4260
|
+
try {
|
|
4261
|
+
const body = String((p && p.content) ?? '');
|
|
4262
|
+
if (Buffer.byteLength(body, 'utf8') > IDE_MAX_BYTES) return { ok: false, error: 'içerik çok büyük (max 400KB)' };
|
|
4263
|
+
fs.writeFileSync(target, body, 'utf8');
|
|
4264
|
+
return { ok: true };
|
|
4265
|
+
} catch (e) {
|
|
4266
|
+
return { ok: false, error: String((e && e.message) || e) };
|
|
4267
|
+
}
|
|
4268
|
+
});
|
|
4269
|
+
|
|
4270
|
+
/* Sağ tık menüsü: dosya/klasör sil (onay diyaloglu) */
|
|
4271
|
+
ipcMain.handle('ide:delete', async (_e, rel) => {
|
|
4272
|
+
const p = ideSafe(rel);
|
|
4273
|
+
if (!p || p === ideRoot()) return { ok: false, error: 'geçersiz yol' };
|
|
4274
|
+
try {
|
|
4275
|
+
const st = fs.statSync(p);
|
|
4276
|
+
const isDir = st.isDirectory();
|
|
4277
|
+
const owner = win && !win.isDestroyed() ? win : undefined;
|
|
4278
|
+
const r = owner
|
|
4279
|
+
? await dialog.showMessageBox(owner, {
|
|
4280
|
+
type: 'warning',
|
|
4281
|
+
title: 'Sil',
|
|
4282
|
+
message: `"${rel}" ${isDir ? 'klasörünü (içi dahil)' : 'dosyasını'} silmek istiyor musun?`,
|
|
4283
|
+
buttons: ['Sil', 'Vazgeç'],
|
|
4284
|
+
defaultId: 1,
|
|
4285
|
+
cancelId: 1,
|
|
4286
|
+
})
|
|
4287
|
+
: { response: 1 };
|
|
4288
|
+
if (r.response !== 0) return { ok: false, canceled: true };
|
|
4289
|
+
fs.rmSync(p, { recursive: true, force: true });
|
|
4290
|
+
return { ok: true };
|
|
4291
|
+
} catch (e) {
|
|
4292
|
+
return { ok: false, error: String((e && e.message) || e) };
|
|
4293
|
+
}
|
|
4294
|
+
});
|
|
4295
|
+
|
|
4296
|
+
/* Sağ tık menüsü: HTML dosyasını dahili tarayıcıda GÖRÜNÜR aç */
|
|
4297
|
+
ipcMain.handle('ide:previewFile', (_e, rel) => {
|
|
4298
|
+
try {
|
|
4299
|
+
const p = ideSafe(rel);
|
|
4300
|
+
if (!p) return { ok: false, error: 'geçersiz yol' };
|
|
4301
|
+
if (!/\.html?$/i.test(p)) return { ok: false, error: 'önizleme yalnız .html/.htm dosyaları için' };
|
|
4302
|
+
setBrowserOpen(true, true);
|
|
4303
|
+
const url = 'file:///' + p.replace(/\\/g, '/');
|
|
4304
|
+
browser.view.webContents.loadURL(url).catch(() => {});
|
|
4305
|
+
browserEmit({ open: true, width: browser.width, url });
|
|
4306
|
+
return { ok: true };
|
|
4307
|
+
} catch (e) {
|
|
4308
|
+
return { ok: false, error: String((e && e.message) || e) };
|
|
4309
|
+
}
|
|
4310
|
+
});
|
|
4311
|
+
|
|
4312
|
+
/* PREVIEW: workspace kökündeki entry sayfayı (index.html → ilk *.html) sağdaki
|
|
4313
|
+
dahili tarayıcıda aç. file:// yükleme browserNavigate'i BYPASS eder — o https
|
|
4314
|
+
olmayan adresi aramaya çevirir. */
|
|
4315
|
+
ipcMain.handle('ide:preview', () => { try {
|
|
4316
|
+
const root = ideRoot();
|
|
4317
|
+
const pick = (name) => {
|
|
4318
|
+
const p = path.join(root, name);
|
|
4319
|
+
try { return fs.existsSync(p) ? p : null; } catch { return null; }
|
|
4320
|
+
};
|
|
4321
|
+
let entry = pick('index.html');
|
|
4322
|
+
if (!entry) {
|
|
4323
|
+
const htmls = fs
|
|
4324
|
+
.readdirSync(root, { withFileTypes: true })
|
|
4325
|
+
.filter((e) => e.isFile() && /\.html?$/i.test(e.name))
|
|
4326
|
+
.map((e) => e.name);
|
|
4327
|
+
entry = htmls.length ? path.join(root, htmls.sort()[0]) : null;
|
|
4328
|
+
}
|
|
4329
|
+
if (!entry) return { ok: false, error: 'workspace kökünde index.html yok — önce agent\'a siteyi yazdır' };
|
|
4330
|
+
/* forceVisible: preview'a basınca tarayıcı ikonuna basmaya gerek kalmasın —
|
|
4331
|
+
dahili tarayıcı otomatik ve GÖRÜNÜR açılır */
|
|
4332
|
+
setBrowserOpen(true, true);
|
|
4333
|
+
const url = 'file:///' + entry.replace(/\\/g, '/');
|
|
4334
|
+
browser.view.webContents.loadURL(url).catch(() => {});
|
|
4335
|
+
browserEmit({ open: true, width: browser.width, url });
|
|
4336
|
+
return { ok: true, url };
|
|
4337
|
+
} catch (e) {
|
|
4338
|
+
return { ok: false, error: String((e && e.message) || e) };
|
|
4339
|
+
}
|
|
4340
|
+
});
|
|
4341
|
+
|
|
4113
4342
|
ipcMain.handle('custom:set', (_e, list) => {
|
|
4114
4343
|
settings.customProviders = Array.isArray(list) ? list : [];
|
|
4115
4344
|
saveSettings();
|
package/src/preload.js
CHANGED
|
@@ -64,6 +64,9 @@ contextBridge.exposeInMainWorld('beast', {
|
|
|
64
64
|
terminalToggle: () => ipcRenderer.invoke('terminal:toggle'),
|
|
65
65
|
terminalRun: (cmd, shell) => ipcRenderer.invoke('terminal:run', { cmd, shell }),
|
|
66
66
|
terminalStop: () => ipcRenderer.invoke('terminal:stop'),
|
|
67
|
+
beastcodeSend: (msg) => ipcRenderer.invoke('beastcode:send', { msg }),
|
|
68
|
+
beastcodeStop: () => ipcRenderer.invoke('beastcode:stop'),
|
|
69
|
+
beastcodeNew: () => ipcRenderer.invoke('beastcode:new'),
|
|
67
70
|
thinkSet: (v) => ipcRenderer.invoke('think:set', v),
|
|
68
71
|
exaGet: () => ipcRenderer.invoke('exa:get'),
|
|
69
72
|
exaSet: (key) => ipcRenderer.invoke('exa:set', key),
|
|
@@ -144,6 +147,13 @@ contextBridge.exposeInMainWorld('beast', {
|
|
|
144
147
|
storeLike: (id) => ipcRenderer.invoke('store:like', id),
|
|
145
148
|
storeRemove: (id) => ipcRenderer.invoke('store:remove', id),
|
|
146
149
|
storeExport: (id) => ipcRenderer.invoke('store:export', id),
|
|
150
|
+
ideTree: (rel) => ipcRenderer.invoke('ide:tree', rel),
|
|
151
|
+
ideSetRoot: () => ipcRenderer.invoke('ide:setroot'),
|
|
152
|
+
ideRead: (rel) => ipcRenderer.invoke('ide:read', rel),
|
|
153
|
+
ideWrite: (rel, content) => ipcRenderer.invoke('ide:write', { rel, content }),
|
|
154
|
+
idePreview: () => ipcRenderer.invoke('ide:preview'),
|
|
155
|
+
idePreviewFile: (rel) => ipcRenderer.invoke('ide:previewFile', rel),
|
|
156
|
+
ideDelete: (rel) => ipcRenderer.invoke('ide:delete', rel),
|
|
147
157
|
onWaEvent: (cb) => ipcRenderer.on('wa:event', (_e, ev) => cb(ev)),
|
|
148
158
|
onEvent: (cb) => ipcRenderer.on('agent:event', (_e, ev) => cb(ev)),
|
|
149
159
|
});
|
package/src/renderer/i18n.js
CHANGED
|
@@ -451,6 +451,16 @@
|
|
|
451
451
|
p_zen_fail: 'Model kurulumu başarısız',
|
|
452
452
|
bot_num_ro_hint: 'Numara ekleme/kişi adı Ayarlar → Entegrasyonlar (WhatsApp izin listesi) üzerinden yapılır; burada yalnızca bağlı numaralar görünür.',
|
|
453
453
|
tipStore: 'Skills Store',
|
|
454
|
+
tipIde: 'IDE Modu — dosyalar + chat + preview',
|
|
455
|
+
ide_files: 'DOSYALAR',
|
|
456
|
+
ide_pick: 'Klasör seç',
|
|
457
|
+
ide_refresh: 'Yenile',
|
|
458
|
+
ide_preview: '▶ Preview',
|
|
459
|
+
ide_saved: 'Kaydedildi — preview\u2019ı yenile',
|
|
460
|
+
bc_ph: 'Beast Code mesajı yaz — Enter ile gönder…',
|
|
461
|
+
bc_new: 'Yeni oturum',
|
|
462
|
+
bc_clear: 'Çıktıyı temizle',
|
|
463
|
+
bc_stop: 'Çalışan mesajı durdur',
|
|
454
464
|
store_title: 'SKILLS STORE',
|
|
455
465
|
store_tab_trending: 'Trending',
|
|
456
466
|
store_tab_stars: 'Stars',
|
|
@@ -997,6 +1007,16 @@
|
|
|
997
1007
|
p_zen_fail: 'Model setup failed',
|
|
998
1008
|
bot_num_ro_hint: 'Add numbers / person names via Settings → Integrations (WhatsApp allow list); only linked numbers are shown here.',
|
|
999
1009
|
tipStore: 'Skills Store',
|
|
1010
|
+
tipIde: 'IDE Mode — files + chat + preview',
|
|
1011
|
+
ide_files: 'FILES',
|
|
1012
|
+
ide_pick: 'Choose folder',
|
|
1013
|
+
ide_refresh: 'Refresh',
|
|
1014
|
+
ide_preview: '▶ Preview',
|
|
1015
|
+
ide_saved: 'Saved — refresh the preview',
|
|
1016
|
+
bc_ph: 'Type a message for Beast Code — press Enter to send…',
|
|
1017
|
+
bc_new: 'New session',
|
|
1018
|
+
bc_clear: 'Clear output',
|
|
1019
|
+
bc_stop: 'Stop running message',
|
|
1000
1020
|
store_title: 'SKILLS STORE',
|
|
1001
1021
|
store_tab_trending: 'Trending',
|
|
1002
1022
|
store_tab_stars: 'Stars',
|
package/src/renderer/index.html
CHANGED
|
@@ -23,11 +23,23 @@
|
|
|
23
23
|
</div>
|
|
24
24
|
<div id="botList"></div>
|
|
25
25
|
</div>
|
|
26
|
+
<aside id="filePanel">
|
|
27
|
+
<div id="filePanelHead">
|
|
28
|
+
<span id="filePanelTitle" data-i18n="ide_files">DOSYALAR</span>
|
|
29
|
+
<span class="file-spacer"></span>
|
|
30
|
+
<button id="filePick" title="Klasör seç" data-i18n-title="ide_pick"><svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7z"/></svg></button>
|
|
31
|
+
<button id="fileRefresh" title="Yenile" data-i18n-title="ide_refresh">⟳</button>
|
|
32
|
+
<button id="filePreview" title="Preview" data-i18n="ide_preview">▶ Preview</button>
|
|
33
|
+
</div>
|
|
34
|
+
<div id="filePanelPath" title="">—</div>
|
|
35
|
+
<div id="fileTree"></div>
|
|
36
|
+
</aside>
|
|
26
37
|
<div id="sideFoot">
|
|
27
38
|
<button id="gearBtn" title="Ayarlar" data-i18n-title="tipGear">⚙︎</button>
|
|
28
39
|
<button id="themeBtn" title="Koyu tema">☾</button>
|
|
29
40
|
<button id="langBtn" title="Dil değiştir / Switch language" data-i18n-title="tipLang"><svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="12" cy="12" r="9"/><path d="M3 12h18"/><path d="M12 3c2.6 2.6 2.6 15.4 0 18M12 3c-2.6 2.6-2.6 15.4 0 18"/></svg></button>
|
|
30
41
|
<button id="storeBtn" title="Skills Store" data-i18n-title="tipStore"><svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 7h16l-1.3 12.1a2 2 0 0 1-2 1.9H7.3a2 2 0 0 1-2-1.9L4 7z"/><path d="M8 10V6a4 4 0 0 1 8 0v4"/></svg></button>
|
|
42
|
+
<button id="ideBtn" title="IDE Modu" data-i18n-title="tipIde"><svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M8 6l-5 6 5 6"/><path d="M16 6l5 6-5 6"/><path d="M13.5 4l-3 16"/></svg></button>
|
|
31
43
|
</div>
|
|
32
44
|
</aside>
|
|
33
45
|
|
|
@@ -65,7 +77,7 @@
|
|
|
65
77
|
<button id="termGBtn" class="dd-btn dd-icon-btn" title="Git Bash terminali" data-i18n-title="tipTermG">◈</button>
|
|
66
78
|
<button id="termCBtn" class="dd-btn dd-icon-btn" title="CMD terminali" data-i18n-title="tipTermC">❯︎</button>
|
|
67
79
|
<button id="browserBtn" class="dd-btn dd-icon-btn" title="Dahili tarayıcı" data-i18n-title="tipBrowser">⧉</button>
|
|
68
|
-
<button id="eyeBtn" class="dd-btn dd-icon-btn" title="Ajan tarayıcısı görünür/gizli — göz açıkken aramalar panelde izlenir, kapalıyken gizli çalışır" data-i18n-title="tipEye"><svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7-10-7-10-7z"/><circle cx="12" cy="12" r="3"/></svg></button>
|
|
80
|
+
<button id="eyeBtn" class="dd-btn dd-icon-btn" title="Ajan tarayıcısı görünür/gizli — göz açıkken aramalar panelde izlenir, kapalıyken gizli çalışır" data-i18n-title="tipEye"><svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7-10-7-10-7z"/><circle cx="12" cy="12" r="3"/><line class="eye-slash" x1="4" y1="4" x2="20" y2="20"/></svg></button>
|
|
69
81
|
<div class="drag-spacer"></div>
|
|
70
82
|
</header>
|
|
71
83
|
|
|
@@ -90,6 +102,36 @@
|
|
|
90
102
|
<button id="sendBtn" title="Gönder" data-i18n-title="tipSend">➤︎</button>
|
|
91
103
|
</div>
|
|
92
104
|
</div>
|
|
105
|
+
|
|
106
|
+
<div id="ideRow">
|
|
107
|
+
<section id="codePane">
|
|
108
|
+
<div id="codeTabsBar">
|
|
109
|
+
<div id="codeTabs"></div>
|
|
110
|
+
<code id="codePath" title="">—</code>
|
|
111
|
+
<button id="codeSave" title="Kaydet (Ctrl+S)">Kaydet</button>
|
|
112
|
+
</div>
|
|
113
|
+
<textarea id="codeTa" spellcheck="false"></textarea>
|
|
114
|
+
</section>
|
|
115
|
+
|
|
116
|
+
<div id="ideSplit" title="Sürükleyerek boyutlandır"></div>
|
|
117
|
+
|
|
118
|
+
<div id="bcPanel">
|
|
119
|
+
<div id="bcHead">
|
|
120
|
+
<span id="bcTitle">BEAST CODE</span>
|
|
121
|
+
<span id="bcCwd" title=""></span>
|
|
122
|
+
<span class="file-spacer"></span>
|
|
123
|
+
<button id="bcNew" title="Yeni oturum" data-i18n-title="bc_new">+</button>
|
|
124
|
+
<button id="bcClear" title="Çıktıyı temizle" data-i18n-title="bc_clear">Temizle</button>
|
|
125
|
+
</div>
|
|
126
|
+
<div id="bcOut"></div>
|
|
127
|
+
<div id="bcTodoWrap" hidden></div>
|
|
128
|
+
<div id="bcInputRow">
|
|
129
|
+
<span id="bcPrompt">code></span>
|
|
130
|
+
<input id="bcInput" spellcheck="false" autocomplete="off" placeholder="Beast Code mesajı yaz — Enter ile gönder…" data-i18n-ph="bc_ph" />
|
|
131
|
+
<button id="bcStop" title="Çalışan mesajı durdur" hidden data-i18n-title="bc_stop">■︎</button>
|
|
132
|
+
</div>
|
|
133
|
+
</div>
|
|
134
|
+
</div>
|
|
93
135
|
</main>
|
|
94
136
|
|
|
95
137
|
<aside id="rail">
|
|
@@ -279,6 +321,8 @@
|
|
|
279
321
|
|
|
280
322
|
<div id="toast"></div>
|
|
281
323
|
|
|
324
|
+
<div id="fileCtxMenu" hidden></div>
|
|
325
|
+
|
|
282
326
|
<input type="file" id="fileInput" multiple hidden
|
|
283
327
|
accept="image/*,.txt,.md,.json,.csv,.log,.js,.ts,.py,.ps1,.bat,.cmd,.html,.css,.yaml,.yml,.xml,.ini" />
|
|
284
328
|
|