Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
ef3f28e
refactor: rename BotBrowserConsole to BotBrowserLauncher
mykola-zalizniak Jan 31, 2026
c1ea18c
Merge branch 'botswin:main' into main
mykola-zalizniak Feb 1, 2026
3da0fcc
feat: add kernel management, proxy management, and setup scripts
mykola-zalizniak Feb 1, 2026
f088283
Merge remote-tracking branch 'refs/remotes/origin/main'
mykola-zalizniak Feb 1, 2026
36763df
Merge branch 'botswin:main' into main
mykola-zalizniak Feb 6, 2026
b5afba0
fix: enable macOS native Edit menu for Cmd+C/V/X/A keyboard shortcuts
mykola-zalizniak Feb 6, 2026
743b86a
chore: upgrade Neutralino runtime to 6.4.0
mykola-zalizniak Feb 6, 2026
1f84af1
chore: remove Neutralino binaries from repo, download via neu update
mykola-zalizniak Feb 6, 2026
d6cdb4d
fix: improve macOS clipboard support with JS fallback for Cmd+V paste
mykola-zalizniak Feb 6, 2026
d937de1
fix: expand macOS clipboard fallback to Cmd+C/X, auto-download Neutra…
mykola-zalizniak Feb 6, 2026
a979a8d
chore: upgrade Neutralino to 6.5.0 and simplify setup scripts
mykola-zalizniak Feb 6, 2026
8554ca8
fix: fix PowerShell setup script ZIP download corruption
mykola-zalizniak Feb 6, 2026
66c0367
Merge branch 'botswin:main' into main
mykola-zalizniak Feb 7, 2026
c577211
feat: enhance proxy workflow with IP check, quick change, and reusabl…
mykola-zalizniak Feb 7, 2026
781d6f9
Merge remote-tracking branch 'refs/remotes/origin/main'
mykola-zalizniak Feb 7, 2026
d95b21a
Merge branch 'botswin:main' into main
mykola-zalizniak Feb 7, 2026
9cc1f00
fix: correct checkbox color override and setup script stdin handling
mykola-zalizniak Feb 7, 2026
e50e1c4
Merge remote-tracking branch 'refs/remotes/origin/main'
mykola-zalizniak Feb 7, 2026
5a95bee
feat: improve profile deletion with auto-stop, group WebRTC settings,…
mykola-zalizniak Feb 11, 2026
10c2f9f
Merge branch 'botswin:main' into main
mykola-zalizniak Feb 11, 2026
c718a92
Merge branch 'botswin:main' into main
mykola-zalizniak Feb 24, 2026
b46ea50
feat: add port protection toggle, fix kernel auto-update cleanup and …
mykola-zalizniak Feb 24, 2026
e1fc4aa
fix: detect kernel assets by file extension to support renamed Window…
mykola-zalizniak Feb 25, 2026
de7b2d5
Merge branch 'botswin:main' into main
mykola-zalizniak Feb 25, 2026
6b13cf2
Merge branch 'botswin:main' into main
mykola-zalizniak Feb 28, 2026
eaf8fc7
fix: handle non-browser process exits, add crash detection, validate …
mykola-zalizniak Feb 28, 2026
76b3ac4
Merge branch 'botswin:main' into main
mykola-zalizniak Mar 3, 2026
50e572d
docs: add --bot-time-seed documentation, changelog 2026-03-03, value …
MSTU0 Mar 4, 2026
42e21da
Merge branch 'botswin:main' into main
mykola-zalizniak Mar 4, 2026
0d89219
feat: add proxy save/check, improve table layout and kernel date display
mykola-zalizniak Mar 4, 2026
dc0e4e8
feat: redesign profile editor with left nav, advanced config modes, a…
mykola-zalizniak Mar 4, 2026
f780ec7
Merge remote-tracking branch 'upstream/main'
mykola-zalizniak Mar 4, 2026
9ecfc86
Merge remote-tracking branch 'upstream/main'
mykola-zalizniak Mar 4, 2026
2bc2251
fix: replace Save IP with Save to proxy list, unify dropdown option l…
mykola-zalizniak Mar 4, 2026
a24a963
fix: include username and password in proxy duplicate detection
mykola-zalizniak Mar 5, 2026
2b07c86
Merge branch 'botswin:main' into main
mykola-zalizniak Mar 8, 2026
1404673
fix: prevent editing running profiles and remove auto-save IP on prox…
mykola-zalizniak Mar 8, 2026
48bd48d
feat(launcher): add automatic self-update with GitHub commit tracking
mykola-zalizniak Mar 8, 2026
fce219a
Merge branch 'botswin:main' into main
mykola-zalizniak Mar 9, 2026
efb7035
Merge branch 'botswin:main' into main
mykola-zalizniak Mar 9, 2026
5cfcd11
feat(launcher): improve table UX, add new CLI flags, and proxy input …
mykola-zalizniak Mar 9, 2026
19f9414
Merge branch 'botswin:main' into main
mykola-zalizniak Mar 11, 2026
0bc06ed
fix(launcher): auto-highlight new profiles/proxies and default noise …
mykola-zalizniak Mar 12, 2026
a960d3a
Merge branch 'botswin:main' into main
mykola-zalizniak Mar 12, 2026
5c6c2c5
Merge branch 'botswin:main' into main
mykola-zalizniak Mar 16, 2026
f15cc18
Merge branch 'botswin:main' into main
mykola-zalizniak Mar 23, 2026
ad7f00e
feat(launcher): add new CLI flags, clear user data, and unsaved chang…
mykola-zalizniak Mar 23, 2026
5bbe3fe
Merge branch 'botswin:main' into main
mykola-zalizniak Mar 26, 2026
6ab531d
feat(launcher): reorganize flag categories, add CLI preview, new 2026…
mykola-zalizniak Mar 26, 2026
fe35a9e
Merge branch 'botswin:main' into main
mykola-zalizniak Mar 27, 2026
e6ea29e
fix(launcher): prevent kernel update corruption and improve extraction
mykola-zalizniak Mar 27, 2026
3b675c5
Merge branch 'botswin:main' into main
mykola-zalizniak Mar 28, 2026
433e85e
Merge branch 'botswin:main' into main
mykola-zalizniak Mar 28, 2026
9126915
refactor(launcher): add ShellService, fix UI feedback patterns
mykola-zalizniak Mar 28, 2026
ea4ac28
Merge branch 'botswin:main' into main
mykola-zalizniak Apr 19, 2026
7469fee
Merge branch 'botswin:main' into main
mykola-zalizniak May 25, 2026
1a2c978
feat(launcher): add clear-proxy confirm, kernel column, fix multi-bui…
mykola-zalizniak May 25, 2026
c33409a
Merge branch 'botswin:main' into main
mykola-zalizniak Jun 12, 2026
72cf91f
feat(launcher): WebKit profile support, toolchain upgrade, safer Wind…
mykola-zalizniak Jun 13, 2026
2265ad0
Merge branch 'botswin:main' into main
mykola-zalizniak Jun 16, 2026
6b439a3
fix(launcher): CLI-flag honesty + tri-state Mobile + legacy-profile m…
mykola-zalizniak Jun 16, 2026
eb421fc
Merge branch 'botswin:main' into main
mykola-zalizniak Jun 21, 2026
30898ba
feat(launcher): expose --bot-video-fps, --proxy-pac-url, --disable-quic
mykola-zalizniak Jun 21, 2026
f53ca12
Merge branch 'botswin:main' into main
mykola-zalizniak Jun 26, 2026
685e038
fix: text-rects noise is off-by-default in BB kernel
mykola-zalizniak Jun 26, 2026
d368692
Merge branch 'botswin:main' into main
mykola-zalizniak Jun 30, 2026
74b1e55
feat(launcher): periodic kernel updates, startup maximize, larger pro…
mykola-zalizniak Jun 30, 2026
0d4bfdb
fix(launcher): auto force-touch for iOS profiles, not just Android
mykola-zalizniak Jun 30, 2026
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: 1 addition & 1 deletion launcher/neutralino.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"icon": "/dist/botbrowser-launcher/browser/favicon.ico",
"enableInspector": false,
"borderless": false,
"maximize": false,
"maximize": true,
"hidden": false,
"resizable": true,
"exitProcessOnClose": true,
Expand Down
12 changes: 6 additions & 6 deletions launcher/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ export class AppComponent implements AfterViewInit {
newProfile(): void {
this.#dialog
.open(EditBrowserProfileComponent, {
width: '860px',
width: '1100px',
maxWidth: '95vw',
})
.afterClosed()
Expand All @@ -239,7 +239,7 @@ export class AppComponent implements AfterViewInit {
}
this.#dialog
.open(EditBrowserProfileComponent, {
width: '860px',
width: '1100px',
maxWidth: '95vw',
data: browserProfile,
})
Expand Down Expand Up @@ -445,10 +445,10 @@ export class AppComponent implements AfterViewInit {

async ngAfterViewInit(): Promise<void> {
await this.refreshProfiles();
// Start kernel auto-update and auto-download tasks in the background
this.kernelService.performStartupTasks().catch(console.error);
// Check for launcher updates: once now, then every hour
this.updateService.startPeriodicCheck();
// Start kernel auto-update/auto-download: once now, then re-check every 10 minutes
this.kernelService.startPeriodicCheck(10 * 60 * 1000);
// Check for launcher updates: once now, then every 10 minutes
this.updateService.startPeriodicCheck(10 * 60 * 1000);
}

restartApp(): void {
Expand Down
4 changes: 2 additions & 2 deletions launcher/src/app/edit-browser-profile.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,10 @@ <h2 mat-dialog-title>{{ isEdit ? 'Edit' : 'Create' }} Browser Profile</h2>
<mat-label>Local DNS</mat-label>
<mat-select [(value)]="localDnsMode" (selectionChange)="onLocalDnsModeChange()">
<mat-option value="">Default (off)</mat-option>
<mat-option value="builtin">built-in resolver</mat-option>
<mat-option value="local">local machine resolver</mat-option>
<mat-option value="custom">custom DNS server</mat-option>
</mat-select>
<mat-hint>Default routes DNS through the proxy · built-in keeps DNS local</mat-hint>
<mat-hint>Default routes DNS through the proxy · local resolves DNS on this machine</mat-hint>
</mat-form-field>
@if (localDnsMode === 'custom') {
<mat-form-field class="flex-2">
Expand Down
2 changes: 1 addition & 1 deletion launcher/src/app/edit-browser-profile.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
}

mat-dialog-content {
max-height: 70vh;
max-height: 82vh;
overflow: hidden !important;
box-sizing: border-box;
padding: 0 !important;
Expand Down
20 changes: 11 additions & 9 deletions launcher/src/app/edit-browser-profile.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -376,14 +376,14 @@ export class EditBrowserProfileComponent implements OnInit, AfterViewInit, OnDes
(this.#injectedData?.launchOptions?.behavior as any)?.botNetworkInfoOverride,
});

// Local DNS mode: '' (kernel default = off) / built-in / custom server.
// Local DNS mode: '' (kernel default = off) / local (resolve on this machine) / custom server.
// Explicit-off is omitted: `--bot-local-dns=false` would match the kernel default, so we map it to ''.
localDnsMode: '' | 'builtin' | 'custom' = (() => {
localDnsMode: '' | 'local' | 'custom' = (() => {
const v =
this.#injectedData?.launchOptions?.proxy?.botLocalDns ??
(this.#injectedData?.launchOptions?.behavior as any)?.botLocalDns;
if (typeof v === 'string' && v) return 'custom';
if (v === true) return 'builtin';
if (v === true) return 'local';
return '';
})();
localDnsServer: string = (() => {
Expand Down Expand Up @@ -713,7 +713,7 @@ export class EditBrowserProfileComponent implements OnInit, AfterViewInit, OnDes
if (this.localDnsMode === '') {
this.proxyConfigGroup.patchValue({ botLocalDns: null });
this.localDnsServer = '';
} else if (this.localDnsMode === 'builtin') {
} else if (this.localDnsMode === 'local') {
this.proxyConfigGroup.patchValue({ botLocalDns: true });
this.localDnsServer = '';
} else if (this.localDnsServer) {
Expand Down Expand Up @@ -932,9 +932,9 @@ export class EditBrowserProfileComponent implements OnInit, AfterViewInit, OnDes
this.#savedScreenWxh = '';
this.#savedScreenJson = '';
// No launcher-side window/screen override on file change — leave it to BB.
// (botMobileForceTouch on the other hand has no implicit kernel default,
// so we keep the Android touch hint.)
if (this.#isAndroidProfile(basicInfo)) {
// (botMobileForceTouch has no implicit kernel default, so we enable it for
// touch-first mobile profiles — Android and iOS alike.)
if (this.#isTouchMobileProfile(basicInfo)) {
this.behaviorGroup.patchValue({ botMobileForceTouch: true });
this.behaviorGroup.markAsDirty();
}
Expand All @@ -950,8 +950,10 @@ export class EditBrowserProfileComponent implements OnInit, AfterViewInit, OnDes
);
}

#isAndroidProfile(basicInfo: BotProfileBasicInfo): boolean {
return basicInfo.userAgent.toLowerCase().includes('android');
// Touch-first mobile profiles (Android phones/tablets and iOS devices) default force-touch on.
// iPadOS UAs that masquerade as desktop Mac aren't detectable here and are left to the user.
#isTouchMobileProfile(basicInfo: BotProfileBasicInfo): boolean {
return /android|iphone|ipad|ipod/.test(basicInfo.userAgent.toLowerCase());
}

#validate(): boolean {
Expand Down
20 changes: 17 additions & 3 deletions launcher/src/app/shared/kernel.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export class KernelService {
#allReleases: KernelRelease[] = [];
#initialized = false;
#extractorAvailable: boolean | null = null; // null = not checked yet
#intervalId: ReturnType<typeof setInterval> | null = null;

async initialize(): Promise<void> {
if (this.#initialized) return;
Expand Down Expand Up @@ -126,14 +127,27 @@ export class KernelService {
}
}

// Called on app startup to perform auto-update tasks
/** Run the kernel auto-update routine now, then re-check periodically (default: hourly). */
startPeriodicCheck(intervalMs = 60 * 60 * 1000): void {
if (this.#intervalId) return;
this.performStartupTasks().catch(console.error);
this.#intervalId = setInterval(() => {
// Skip if a previous run or any download (auto or manual) is still in progress
if (this.isAutoUpdating() || this.hasActiveDownloads()) return;
this.performStartupTasks().catch(console.error);
}, intervalMs);
}

// Fetch releases and auto-update/-download kernels.
// Called on startup and on each periodic check; re-entrant calls are ignored.
async performStartupTasks(): Promise<void> {
await this.initialize();
if (this.isAutoUpdating()) return; // prevent overlapping runs

try {
this.isAutoUpdating.set(true);
await this.initialize();

// Fetch all releases
// Always re-fetch so newly published releases are detected on periodic runs
this.#allReleases = await this.#fetchAllReleases();

// Clean up old kernel versions (keep only the latest per major version)
Expand Down
6 changes: 3 additions & 3 deletions launcher/src/app/shared/update.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@ export class UpdateService {
#isWindows = false;
#intervalId: ReturnType<typeof setInterval> | null = null;

/** Start checking for updates: once immediately, then every hour. */
startPeriodicCheck(): void {
/** Start checking for updates: once immediately, then on an interval (default: hourly). */
startPeriodicCheck(intervalMs = 60 * 60 * 1000): void {
if (this.#intervalId) return;
this.checkForUpdate().catch(console.error);
this.#intervalId = setInterval(() => {
// Only check if idle (skip if already updating or update ready)
if (this.status() === 'idle') {
this.checkForUpdate().catch(console.error);
}
}, 60 * 60 * 1000);
}, intervalMs);
}

async checkForUpdate(): Promise<void> {
Expand Down
5 changes: 5 additions & 0 deletions launcher/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ import * as Neutralino from '@neutralinojs/lib';
Neutralino.init();
Neutralino.events.on('windowClose', () => Neutralino.app.exit());

// Maximize the window on startup (guarantees maximize even when useSavedState restores a smaller size)
Neutralino.events.on('ready', () => {
Neutralino.window.maximize().catch((err: unknown) => console.warn('maximize failed:', err));
});

// macOS: enable Cmd+C/V/X/A keyboard shortcuts
Neutralino.events.on('ready', () => {
if (NL_OS !== 'Darwin') return;
Expand Down