Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/chrome/src/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ import {
createConfigExport,
parseConfigImport,
} from './config-transfer.js';
import { installDownloadDirectoryRouting } from './download-directory.js';

/**
* WebBrain Service Worker (Background Script)
Expand All @@ -71,6 +72,7 @@ const providerManager = new ProviderManager();
const agent = new Agent(providerManager);
const userMemoryStore = createUserMemoryStore(chrome.storage.local);
const profileSync = new ProfileSyncManager(chrome.storage.local);
installDownloadDirectoryRouting(chrome);
const scheduler = new ScheduledJobManager({
api: chrome,
agent,
Expand Down
2 changes: 2 additions & 0 deletions src/chrome/src/config-transfer.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export const DEFAULT_CONFIG_SETTINGS = Object.freeze({
planBeforeAct: true,
planReviewMode: 'confidence',
planReviewConfidenceThreshold: 75,
downloadDirectory: '',
notifySound: true,
completionConfetti: true,
tracingEnabled: false,
Expand Down Expand Up @@ -109,6 +110,7 @@ const STRING_KEYS = new Set([
'autoScreenshot',
'planBeforeActMode',
'planReviewMode',
'downloadDirectory',
'providerFilter',
'activeProvider',
'profileText',
Expand Down
73 changes: 73 additions & 0 deletions src/chrome/src/download-directory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
export const DOWNLOAD_DIRECTORY_STORAGE_KEY = 'downloadDirectory';

/**
* Browser download paths are always relative to the browser/OS Downloads
* directory. Keep the stored preference in that portable form so an empty
* value naturally means "use the system default".
*/
export function normalizeDownloadDirectory(value) {
const raw = String(value ?? '').trim().replace(/\\/g, '/');
if (!raw) return '';
if (raw.startsWith('/') || raw.startsWith('~') || /^[a-zA-Z]:\//.test(raw)) return '';

const parts = raw.split('/').map((part) => part.trim());
if (parts.some((part) => !part || part === '.' || part === '..')) return '';
if (parts.some((part) => /[\u0000-\u001f\u007f<>:"|?*]/.test(part))) return '';
return parts.join('/');
}

export function filenameInDownloadDirectory(directory, filename) {
const normalizedDirectory = normalizeDownloadDirectory(directory);
if (!normalizedDirectory) return '';

let basename = String(filename ?? '')
.replace(/\\/g, '/')
.split('/')
.pop()
.replace(/[\u0000-\u001f\u007f<>:"|?*]/g, '_')
.trim();
basename = basename.replace(/^\.+|\.+$/g, '').trim();
if (!basename) return '';
if (/^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\.|$)/i.test(basename)) {
basename = `_${basename}`;
}
return `${normalizedDirectory}/${basename}`;
}

export function createDownloadDirectoryListener(api) {
let directory = '';
let changedBeforeReady = false;
const ready = Promise.resolve(api.storage.local.get(DOWNLOAD_DIRECTORY_STORAGE_KEY))
.then((stored) => {
if (!changedBeforeReady) {
directory = normalizeDownloadDirectory(stored?.[DOWNLOAD_DIRECTORY_STORAGE_KEY]);
}
})
.catch(() => {});

api.storage?.onChanged?.addListener?.((changes, area) => {
if (area !== 'local' || !changes[DOWNLOAD_DIRECTORY_STORAGE_KEY]) return;
changedBeforeReady = true;
directory = normalizeDownloadDirectory(changes[DOWNLOAD_DIRECTORY_STORAGE_KEY].newValue);
});

return function routeWebBrainDownload(downloadItem, suggest) {
if (downloadItem?.byExtensionId !== api.runtime.id) {
suggest();
return undefined;
}

ready.then(() => {
const filename = filenameInDownloadDirectory(directory, downloadItem.filename);
suggest(filename ? { filename } : undefined);
});
return true;
};
}

export function installDownloadDirectoryRouting(api) {
if (!api?.downloads?.onDeterminingFilename?.addListener) return null;
const listener = createDownloadDirectoryListener(api);
api.downloads.onDeterminingFilename.addListener(listener);
return listener;
}
4 changes: 4 additions & 0 deletions src/chrome/src/ui/locales/ar.js
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,10 @@ export default {
"st.display.theme.system": "النظام",
"st.display.theme.light": "فاتح",
"st.display.theme.dark": "داكن",
"st.display.download_directory.label": "دليل التنزيل",
"st.display.download_directory.desc": "مجلد فرعي اختياري داخل مجلد التنزيلات في المتصفح أو النظام. اتركه فارغًا لاستخدام الإعداد الافتراضي للنظام.",
"st.display.download_directory.placeholder": "الإعداد الافتراضي للنظام",
"st.display.download_directory.error": "استخدم مجلدًا نسبيًا مثل WebBrain أو Work/WebBrain. لا يُسمح بالمسارات المطلقة أو “..”.",
"st.display.strict_secret.label": "المعالجة الصارمة للأسرار",
"st.display.strict_secret.desc": "رفض اقتباس بيانات الاعتماد (كلمات المرور، مفاتيح API، الرموز، رموز OTP) في الملخّصات أو نص المساعد — حتى عندما تطلبها صراحةً. مفيد إذا كنت تشارك ملفات التتبّع أو تشارك شاشتك بانتظام. مُعطّل افتراضيًا: يعمل WebBrain داخل متصفّحك الخاص، لذا يُظهر لك الوكيل افتراضيًا القيم التي تطلبها ويُبقي ملخّصات `done` مرتّبة فقط.",
"st.display.request_timeout.label": "مهلة طلب LLM",
Expand Down
4 changes: 4 additions & 0 deletions src/chrome/src/ui/locales/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,10 @@ export default {
'st.display.theme.system': 'System',
'st.display.theme.light': 'Light',
'st.display.theme.dark': 'Dark',
'st.display.download_directory.label': 'Download directory',
'st.display.download_directory.desc': 'Optional subfolder inside your browser or system Downloads directory. Leave blank to use the system default.',
'st.display.download_directory.placeholder': 'System default',
'st.display.download_directory.error': 'Use a relative folder such as WebBrain or Work/WebBrain. Absolute paths and “..” are not allowed.',
'st.display.search.placeholder': 'Search General settings',
'st.display.search.empty': 'No General settings match.',
'st.display.advanced': 'Advanced',
Expand Down
4 changes: 4 additions & 0 deletions src/chrome/src/ui/locales/es.js
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,10 @@ export default {
"st.display.theme.system": "Sistema",
"st.display.theme.light": "Claro",
"st.display.theme.dark": "Oscuro",
"st.display.download_directory.label": "Directorio de descargas",
"st.display.download_directory.desc": "Subcarpeta opcional dentro del directorio de descargas del navegador o del sistema. Déjala en blanco para usar el valor predeterminado del sistema.",
"st.display.download_directory.placeholder": "Predeterminado del sistema",
"st.display.download_directory.error": "Usa una carpeta relativa como WebBrain o Work/WebBrain. No se permiten rutas absolutas ni “..”.",
"st.display.strict_secret.label": "Manejo estricto de secretos",
"st.display.strict_secret.desc": "Se niega a citar credenciales (contraseñas, claves de API, tokens, OTPs) en resúmenes o texto del asistente, incluso cuando se las pidas explícitamente. Útil si compartes a menudo archivos de traza o tu pantalla. Desactivado por defecto: WebBrain se ejecuta en tu propio navegador, así que por defecto el agente te muestra los valores que pides y solo mantiene ordenados los resúmenes de `done`.",
"st.display.request_timeout.label": "Tiempo de espera de la petición al LLM",
Expand Down
4 changes: 4 additions & 0 deletions src/chrome/src/ui/locales/fr.js
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,10 @@ export default {
"st.display.theme.system": "Système",
"st.display.theme.light": "Clair",
"st.display.theme.dark": "Sombre",
"st.display.download_directory.label": "Dossier de téléchargement",
"st.display.download_directory.desc": "Sous-dossier facultatif dans le dossier Téléchargements du navigateur ou du système. Laissez vide pour utiliser la valeur par défaut du système.",
"st.display.download_directory.placeholder": "Valeur par défaut du système",
"st.display.download_directory.error": "Utilisez un dossier relatif comme WebBrain ou Work/WebBrain. Les chemins absolus et « .. » ne sont pas autorisés.",
"st.display.strict_secret.label": "Gestion stricte des secrets",
"st.display.strict_secret.desc": "Refuse de citer les identifiants (mots de passe, clés d'API, jetons, OTPs) dans les résumés ou le texte de l'assistant — même lorsque vous le demandez explicitement. Utile si vous partagez régulièrement des fichiers de trace ou votre écran. Désactivé par défaut : webbrain s'exécute dans votre propre navigateur, donc par défaut l'agent vous montre les valeurs que vous demandez et se contente de garder les résumés `done` propres.",
"st.display.request_timeout.label": "Délai d'attente des requêtes LLM",
Expand Down
4 changes: 4 additions & 0 deletions src/chrome/src/ui/locales/he.js
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,10 @@ export default {
"st.display.theme.system": "מערכת",
"st.display.theme.light": "אוֹר",
"st.display.theme.dark": "כֵּהֶה",
"st.display.download_directory.label": "תיקיית הורדות",
"st.display.download_directory.desc": "תיקיית משנה אופציונלית בתוך תיקיית ההורדות של הדפדפן או המערכת. השאירו ריק כדי להשתמש בברירת המחדל של המערכת.",
"st.display.download_directory.placeholder": "ברירת המחדל של המערכת",
"st.display.download_directory.error": "השתמשו בתיקייה יחסית כמו WebBrain או Work/WebBrain. נתיבים מוחלטים ו-”..“ אינם מותרים.",
"st.display.search.placeholder": "חפש בהגדרות כלליות",
"st.display.search.empty": "אין הגדרות כלליות תואמות.",
"st.display.advanced": "מִתקַדֵם",
Expand Down
4 changes: 4 additions & 0 deletions src/chrome/src/ui/locales/id.js
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,10 @@ export default {
"st.display.theme.system": "Sistem",
"st.display.theme.light": "Terang",
"st.display.theme.dark": "Gelap",
"st.display.download_directory.label": "Direktori unduhan",
"st.display.download_directory.desc": "Subfolder opsional di dalam direktori Unduhan browser atau sistem. Biarkan kosong untuk menggunakan pengaturan bawaan sistem.",
"st.display.download_directory.placeholder": "Bawaan sistem",
"st.display.download_directory.error": "Gunakan folder relatif seperti WebBrain atau Work/WebBrain. Jalur absolut dan “..” tidak diizinkan.",
"st.display.strict_secret.label": "Penanganan rahasia ketat",
"st.display.strict_secret.desc": "Menolak mengutip kredensial (kata sandi, kunci API, token, OTP) dalam ringkasan atau teks asisten — bahkan saat Anda memintanya secara eksplisit. Berguna jika Anda kerap berbagi berkas jejak atau berbagi layar. Nonaktif secara bawaan: webbrain berjalan di peramban Anda sendiri, jadi secara bawaan agen menampilkan nilai yang Anda minta dan hanya menjaga ringkasan `done` tetap rapi.",
"st.display.request_timeout.label": "Batas waktu permintaan LLM",
Expand Down
4 changes: 4 additions & 0 deletions src/chrome/src/ui/locales/ja.js
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,10 @@ export default {
"st.display.theme.system": "システム",
"st.display.theme.light": "ライト",
"st.display.theme.dark": "ダーク",
"st.display.download_directory.label": "ダウンロード先",
"st.display.download_directory.desc": "ブラウザーまたはシステムのダウンロードフォルダー内に作成する任意のサブフォルダーです。空欄の場合はシステムの既定値を使用します。",
"st.display.download_directory.placeholder": "システムの既定値",
"st.display.download_directory.error": "WebBrain や Work/WebBrain のような相対フォルダーを指定してください。絶対パスと「..」は使用できません。",
"st.display.strict_secret.label": "資格情報の厳格な取り扱い",
"st.display.strict_secret.desc": "要約やアシスタントの文章の中で資格情報(パスワード、API キー、トークン、OTP)を引用することを、たとえ明示的に求めた場合でも拒否します。トレースファイルを共有したり画面を共有したりすることが多い場合に便利です。デフォルトはオフ: WebBrain はあなた自身のブラウザ内で動くため、既定ではエージェントは求めた値を表示し、`done` の要約だけをすっきりと保ちます。",
"st.display.request_timeout.label": "LLM リクエストのタイムアウト",
Expand Down
4 changes: 4 additions & 0 deletions src/chrome/src/ui/locales/ko.js
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,10 @@ export default {
"st.display.theme.system": "시스템",
"st.display.theme.light": "라이트",
"st.display.theme.dark": "다크",
"st.display.download_directory.label": "다운로드 디렉터리",
"st.display.download_directory.desc": "브라우저 또는 시스템 다운로드 디렉터리 안의 선택적 하위 폴더입니다. 비워 두면 시스템 기본값을 사용합니다.",
"st.display.download_directory.placeholder": "시스템 기본값",
"st.display.download_directory.error": "WebBrain 또는 Work/WebBrain 같은 상대 폴더를 사용하세요. 절대 경로와 “..”는 허용되지 않습니다.",
"st.display.strict_secret.label": "엄격한 비밀 정보 처리",
"st.display.strict_secret.desc": "요약이나 어시스턴트 텍스트에 자격 증명(비밀번호, API 키, 토큰, OTP)을 인용하기를 거부합니다 — 명시적으로 요청하더라도 마찬가지입니다. 트레이스 파일을 자주 공유하거나 화면을 공유한다면 유용합니다. 기본값은 꺼짐: WebBrain은 사용자 본인의 브라우저에서 실행되므로, 기본적으로 에이전트는 요청한 값을 보여 주고 `done` 요약만 깔끔하게 유지합니다.",
"st.display.request_timeout.label": "LLM 요청 시간 제한",
Expand Down
4 changes: 4 additions & 0 deletions src/chrome/src/ui/locales/ms.js
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,10 @@ export default {
"st.display.theme.system": "Sistem",
"st.display.theme.light": "Cerah",
"st.display.theme.dark": "Gelap",
"st.display.download_directory.label": "Direktori muat turun",
"st.display.download_directory.desc": "Subfolder pilihan dalam direktori Muat Turun pelayar atau sistem. Biarkan kosong untuk menggunakan lalai sistem.",
"st.display.download_directory.placeholder": "Lalai sistem",
"st.display.download_directory.error": "Gunakan folder relatif seperti WebBrain atau Work/WebBrain. Laluan mutlak dan “..” tidak dibenarkan.",
"st.display.strict_secret.label": "Pengendalian rahsia ketat",
"st.display.strict_secret.desc": "Enggan memetik kelayakan (kata laluan, kunci API, token, OTP) dalam ringkasan atau teks pembantu — walaupun apabila anda secara jelas memintanya. Berguna jika anda kerap berkongsi fail jejak atau berkongsi skrin. Dimatikan secara lalai: webbrain berjalan dalam pelayar anda sendiri, jadi secara lalai ejen menunjukkan kepada anda nilai yang anda minta dan hanya memastikan ringkasan `done` kemas.",
"st.display.request_timeout.label": "Tamat masa permintaan LLM",
Expand Down
4 changes: 4 additions & 0 deletions src/chrome/src/ui/locales/pl.js
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,10 @@ export default {
'st.display.theme.system': 'Systemowy',
'st.display.theme.light': 'Jasny',
'st.display.theme.dark': 'Ciemny',
'st.display.download_directory.label': 'Katalog pobierania',
'st.display.download_directory.desc': 'Opcjonalny podfolder w katalogu Pobrane przeglądarki lub systemu. Pozostaw puste, aby użyć ustawienia domyślnego systemu.',
'st.display.download_directory.placeholder': 'Domyślne systemu',
'st.display.download_directory.error': 'Użyj folderu względnego, np. WebBrain lub Work/WebBrain. Ścieżki bezwzględne i „..” są niedozwolone.',
'st.display.verbose.label': 'Tryb szczegółowy',
'st.display.verbose.desc': 'Pokazuj pełne szczegóły wywołań narzędzi, argumenty i surowe wyniki JSON. Domyślnie wyłączony dla czystszego czatu.',
'st.display.selection_shortcut.label': 'Skrót zaznaczenia',
Expand Down
4 changes: 4 additions & 0 deletions src/chrome/src/ui/locales/ru.js
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,10 @@ export default {
"st.display.theme.system": "Системная",
"st.display.theme.light": "Светлая",
"st.display.theme.dark": "Тёмная",
"st.display.download_directory.label": "Каталог загрузок",
"st.display.download_directory.desc": "Необязательная подпапка в каталоге загрузок браузера или системы. Оставьте пустым, чтобы использовать системное значение по умолчанию.",
"st.display.download_directory.placeholder": "Системное значение",
"st.display.download_directory.error": "Используйте относительную папку, например WebBrain или Work/WebBrain. Абсолютные пути и «..» не допускаются.",
"st.display.strict_secret.label": "Строгая обработка секретов",
"st.display.strict_secret.desc": "Отказываться цитировать учётные данные (пароли, API-ключи, токены, OTP) в сводках или тексте ассистента — даже когда вы явно об этом просите. Полезно, если вы регулярно делитесь файлами трасс или демонстрируете экран. По умолчанию выключено: webbrain работает в вашем собственном браузере, поэтому по умолчанию агент показывает запрошенные вами значения и просто держит сводки `done` аккуратными.",
"st.display.request_timeout.label": "Тайм-аут запроса к LLM",
Expand Down
4 changes: 4 additions & 0 deletions src/chrome/src/ui/locales/th.js
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,10 @@ export default {
"st.display.theme.system": "ระบบ",
"st.display.theme.light": "สว่าง",
"st.display.theme.dark": "มืด",
"st.display.download_directory.label": "ไดเรกทอรีดาวน์โหลด",
"st.display.download_directory.desc": "โฟลเดอร์ย่อยภายในไดเรกทอรีดาวน์โหลดของเบราว์เซอร์หรือระบบ เว้นว่างไว้เพื่อใช้ค่าเริ่มต้นของระบบ",
"st.display.download_directory.placeholder": "ค่าเริ่มต้นของระบบ",
"st.display.download_directory.error": "ใช้โฟลเดอร์แบบสัมพัทธ์ เช่น WebBrain หรือ Work/WebBrain ไม่อนุญาตพาธแบบสัมบูรณ์และ “..”",
"st.display.strict_secret.label": "การจัดการความลับอย่างเข้มงวด",
"st.display.strict_secret.desc": "ปฏิเสธการอ้างอิงข้อมูลรับรอง (รหัสผ่าน คีย์ API โทเค็น OTP) ในบทสรุปหรือข้อความของผู้ช่วย — แม้คุณจะขอโดยตรง มีประโยชน์หากคุณแชร์ไฟล์ trace หรือแชร์หน้าจอเป็นประจำ ปิดเป็นค่าเริ่มต้น: WebBrain ทำงานในเบราว์เซอร์ของคุณเอง ดังนั้นโดยค่าเริ่มต้นเอเจนต์จะแสดงค่าที่คุณขอ และเพียงทำให้บทสรุป `done` เป็นระเบียบ",
"st.display.request_timeout.label": "เวลารอคำขอ LLM",
Expand Down
Loading