Skip to content

Tags: mithun50/openclaw-termux

Tags

v1.8.7

Toggle v1.8.7's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Merge pull request #109 from mithun50/copilot/fix-openclaw-2026-warn-…

…issue

fix: stop OpenClawX Node token_missing reconnect storm on gateway restart

v1.8.6

Toggle v1.8.6's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Merge pull request #96 from mithun50/fix/config-repair-gateway-mode-n…

…ode-update

fix: Config corruption, gateway.mode & Node.js update

v1.8.5

Toggle v1.8.5's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Merge pull request #84 from mithun50/fix/multi-bug-fixes-69-70-73-74-…

…82-83

fix: Resolve multiple bugs (#69, #70, #73, #74, #82, #83)

v1.8.4

Toggle v1.8.4's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Merge pull request #57 from mithun50/feature/issues-55-54-21

fix: Storage safety, gateway stability, auth UX, canvas, deps (#21, #54, #55, #56, #59, #60, #61, #63, #64, #65, #66, #67)

v1.8.3

Toggle v1.8.3's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Merge pull request #49 from mithun50/fix/multi-instance-guard-48

Merging multi-instance guard fix. Closes #48.

v1.8.2

Toggle v1.8.2's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Fix setup detection, DNS fallback, and NVIDIA config (#44, #45, #46) (#…

…47)

* Fix Ctrl key for arrows/special keys, add Configure menu, clickable URL, SSH package (#37, #38)

- Fix Ctrl+Arrow/Home/End/PgUp/PgDn sending raw sequences instead of
  xterm Ctrl-modified variants (e.g. \x1b[1;5A for Ctrl+Up)
- Make gateway dashboard URL clickable (opens WebDashboardScreen) with
  primary color + underline styling and open_in_new icon button
- Add "Configure" quick action card running `openclaw configure` in terminal
- Add OpenSSH as optional package (apt-get install openssh-client openssh-server)

Co-Authored-By: Mithun Gowda B <[email protected]>

* Add multi-provider AI model selection and SSH remote access

- Add AiProvider data model with 7 built-in providers (Anthropic, OpenAI,
  Google Gemini, OpenRouter, NVIDIA NIM, DeepSeek, xAI)
- Add ProviderConfigService to read/write provider config in openclaw.json
  using Node.js safe-merge pattern
- Add ProvidersScreen listing all providers with Active/Configured badges
- Add ProviderDetailScreen with API key form and model dropdown
- Add SshService for sshd lifecycle (start/stop, password, IP discovery)
- Add SshScreen with service control, password management, and connection
  info with copyable ssh commands
- Add AI Providers and SSH Access cards to dashboard

Co-Authored-By: Mithun Gowda B <[email protected]>

* Fix resolv.conf ENOENT after app upgrade (#40)

After upgrading to v1.7.3, Android may clear the app's files directory.
writeResolvConf() only created the config/ directory but other required
directories (tmp/, home/, lib/, proc/sys fakes) were missing, causing
proot bind-mount failures.

Call setupDirectories() instead of a bare mkdirs() so the entire
directory tree is recreated before writing resolv.conf. Also use the
two-argument File constructor for correctness.

Fixes #40

Co-Authored-By: Mithun Gowda B <[email protected]>

* Call setupDirs before writeResolv in gateway init and start (#40)

On a normal app launch (setup already complete), setupDirs was never
called. If Android cleared the files directory after an upgrade, the
config/ directory was missing when writeResolv ran.

Now both init() and start() call setupDirs() first, matching the
bootstrap flow. The Kotlin-side writeResolvConf() also calls
setupDirectories() internally as a safety net.

Co-Authored-By: Mithun Gowda B <[email protected]>

* Fix writeResolvConf: only mkdirs config dir, not full setupDirectories (#40)

setupDirectories() also runs setupLibtalloc() and setupFakeSysdata()
which can fail during first-time setup when rootfs hasn't been
extracted yet. writeResolvConf() only needs the config/ directory
to exist.

The Dart-side gateway_service.dart still calls setupDirs() before
writeResolv() for the upgrade/restart case where directories may
have been cleared by Android.

Co-Authored-By: Mithun Gowda B <[email protected]>

* Call setupDirectories in GatewayService before proot starts (#40)

After an app update, Android may clear all files. The background
GatewayService only called writeResolvConf() which creates config/
dir, but proot also needs tmp/, home/, lib/libtalloc.so.2, and
proc/sys fakes for bind mounts.

Now setupDirectories() runs before writeResolvConf() in the Android
service, matching the Dart-side fix in gateway_service.dart.

All paths now covered:
- First-time setup: bootstrap calls setupDirs then writeResolv
- App open (Dart): init/start call setupDirs then writeResolv
- Background service (Kotlin): setupDirectories then writeResolvConf
- writeResolvConf itself: mkdirs config dir as safety net

Co-Authored-By: Mithun Gowda B <[email protected]>

* Rewrite SSH to use native foreground service for persistent sshd

The previous implementation used single-shot runInProot() which can't
run daemons — proot uses --kill-on-exit so sshd dies when the command
finishes. Also pgrep/hostname -I don't work reliably inside proot.

Changes:
- Add SshForegroundService.kt: runs sshd -D (foreground mode) in a
  persistent proot process with wake lock and notification
- Add native bridge methods: startSshd, stopSshd, isSshdRunning,
  getSshdPort, getDeviceIps, setRootPassword
- getDeviceIps uses Android NetworkInterface (not proot hostname -I)
- setRootPassword runs chpasswd via processManager.runInProotSync
- Register SshForegroundService in AndroidManifest.xml
- Rewrite ssh_service.dart to use native methods
- Update ssh_screen.dart to fetch IPs from Android

Co-Authored-By: Mithun Gowda B <[email protected]>

* Fix Ctrl key for soft keyboard input in terminal and configure screens

CTRL/ALT toolbar buttons only worked with other toolbar buttons (arrows,
etc.), not with soft keyboard input. Keyboard chars went directly through
terminal.onOutput → pty.write(), bypassing the toolbar's modifier state.

Fix: Share CTRL/ALT state via ValueNotifier between toolbar and screen.
The onOutput handler now checks if modifiers are active and transforms
keyboard input (e.g., Ctrl+C sends byte 0x03). Both terminal_screen.dart
and configure_screen.dart are fixed.

Co-Authored-By: Mithun Gowda B <[email protected]>

* Fix Ctrl key in onboarding and package install screens, remove unused imports

Add ctrlNotifier/altNotifier to TerminalToolbar usage in
onboarding_screen.dart and package_install_screen.dart (build errors).
Remove unnecessary dart:typed_data imports (already provided by
package:flutter/services.dart).

Co-Authored-By: Mithun Gowda B <[email protected]>

* Fix resolv.conf ENOENT: use context.filesDir, make init() resilient (#40)

- writeResolvConf() now uses context.filesDir (Android-guaranteed path)
  instead of the String configDir which could point to a cleared directory
- gateway_service init() wraps writeResolv() in try-catch since it's
  non-critical when gateway is already running

Co-Authored-By: Mithun Gowda B <[email protected]>

* Run setupDirs + writeResolv unconditionally on app open (#40)

Previously these only ran when the gateway was already running.
After an app update, the gateway is not running but Android may have
cleared the files directory. Moving setupDirs/writeResolv before the
isGatewayRunning check ensures resolv.conf always exists before any
terminal or gateway operation.

Co-Authored-By: Mithun Gowda B <[email protected]>

* Ensure dirs + resolv.conf exist before every proot operation (#40)

getProotShellConfig() is called by all screens before starting proot
(terminal, configure, onboarding, package install). Adding setupDirs
and writeResolv here guarantees resolv.conf exists regardless of which
screen the user opens first after an app update.

Co-Authored-By: Mithun Gowda B <[email protected]>

* Ensure dirs + resolv.conf on every app launch via splash screen (#40)

The splash screen is the first screen on every app open — reinstall,
update, or normal launch. Running setupDirs + writeResolv here
guarantees the files exist before any screen can use proot.

Co-Authored-By: Mithun Gowda B <[email protected]>

* v1.8.0: AI Providers, SSH Access, Ctrl keys, Configure menu, resolv.conf fix

- Bump version to 1.8.0 (pubspec.yaml, constants.dart)
- Update CHANGELOG with all new features and bug fixes
- Update README with new features, file structure, and OpenSSH package

Co-Authored-By: Mithun Gowda B <[email protected]>

* Make resolv.conf creation bulletproof, never block gateway start (#40)

- writeResolvConf() now has a try/catch fallback: tries context.filesDir
  first, falls back to string-based configDir path
- gateway_service start() wraps setupDirs + writeResolv in individual
  try-catches so failures don't prevent gateway from starting (the
  GatewayService.kt foreground service also creates these files)

Co-Authored-By: Mithun Gowda B <[email protected]>

* v1.8.1: Bulletproof resolv.conf fix for update/reinstall/restart

Co-Authored-By: Mithun Gowda B <[email protected]>

* Prevent setupDirectories/writeResolvConf from crashing gateway/SSH start

Wrap both calls in try-catch in GatewayService.kt and SshForegroundService.kt
so the gateway/SSH process still starts even if directory setup fails.
GatewayService now logs warnings if setup fails for debugging.

Co-Authored-By: Mithun Gowda B <[email protected]>

* Add Dart-side resolv.conf fallback using dart:io (#40)

The Kotlin writeResolv method channel silently fails in some cases.
Added direct Dart file creation as fallback in both splash_screen
and terminal_service (getProotShellConfig). Uses dart:io Directory
and File APIs to create config/resolv.conf directly, bypassing the
method channel entirely.

Co-Authored-By: Mithun Gowda B <[email protected]>

* Fix retry setup crashing on resolv.conf ENOENT (#40)

bootstrap_service setupDirs/writeResolv were not wrapped in try-catch,
so the entire setup failed if writeResolv threw. Added try-catch and
Dart dart:io fallback to create resolv.conf directly.

Co-Authored-By: Mithun Gowda B <[email protected]>

* Add native setupDirs + writeResolv + dart:io fallback to all screens (#40)

Every screen and service now has 3 layers of defense:
1. NativeBridge.setupDirs() — Kotlin method channel
2. NativeBridge.writeResolv() — Kotlin method channel
3. dart:io File/Directory — direct Dart fallback

Applied to: terminal, configure, onboarding, package_install screens
and gateway_service init + start.

Co-Authored-By: Mithun Gowda B <[email protected]>

* Remove CI lint and Security workflows

These workflows check Node.js lint/test/audit which is not relevant
to the Flutter app. Only the flutter-build workflow is needed.

Co-Authored-By: Mithun Gowda B <[email protected]>

* Enhance build workflow: PR comments with artifact links, build summary

- Comment on PRs with build status, version, and direct artifact links
- Update existing bot comment instead of spamming new ones
- Comment on build failure with link to logs
- Add build summary table with file sizes to Actions step summary
- Add pull-requests: write permission for PR comments

Co-Authored-By: Mithun Gowda B <[email protected]>

* Fix setup detection, DNS fallback, and NVIDIA config (#44, #45, #46)

- Use fast filesystem check for openclaw in getInstallStatus() with proot
  exec fallback at 30s timeout (#44)
- Add inline resolv.conf creation in GatewayService before proot starts (#45)
- Update NVIDIA NIM default models, add custom model input field (#46)
- Add direct file-write fallback for provider config save (#46)

Co-Authored-By: Mithun Gowda B <[email protected]>

* Add screenshot capture to all terminal and log screens

New ScreenshotService utility captures visible terminal content as
high-res PNG via RepaintBoundary. Camera icon added to AppBar on
Terminal, Onboarding, Configure, Package Install, and Logs screens.
Images saved to app-specific external storage.

Co-Authored-By: Mithun Gowda B <[email protected]>

* Guarantee resolv.conf at every proot invocation (#45)

Add ensureResolvConf() in ProcessManager.commonProotFlags() — the
single chokepoint for ALL proot operations (install, gateway, sync).
This means resolv.conf is verified/created before every bind-mount,
regardless of which screen or service triggers proot.

Also add inline resolv.conf fallback to SshForegroundService for
parity with GatewayService.

Co-Authored-By: Mithun Gowda B <[email protected]>

* Also write resolv.conf to rootfs /etc/ as bind-mount fallback (#45)

ensureResolvConf() now writes to both locations:
1. $configDir/resolv.conf — used by proot --bind mount (primary)
2. $rootfsDir/etc/resolv.conf — fallback if bind-mount fails

This ensures DNS works regardless of how proot handles the bind.

Co-Authored-By: Mithun Gowda B <[email protected]>

* Write resolv.conf to both config dir and rootfs /etc/ at every entry point (#45)

- BootstrapManager.writeResolvConf() now writes to rootfs/ubuntu/etc/resolv.conf
- MainActivity.configureFlutterEngine() ensures dirs + resolv.conf on app start
- GatewayService.kt and SshForegroundService.kt inline fallbacks write to rootfs
- All Dart-side fallbacks (splash, terminal, onboarding, configure, package_install,
  gateway_service, bootstrap_service, terminal_service) write to rootfs /etc/
- Survives APK updates: dirs + resolv.conf recreated on every engine init

* Bump version to 1.8.2+13 and update changelog

v1.8.1

Toggle v1.8.1's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Fix/issue 40 resolv conf enoent (#43)

* Fix Ctrl key for arrows/special keys, add Configure menu, clickable URL, SSH package (#37, #38)

- Fix Ctrl+Arrow/Home/End/PgUp/PgDn sending raw sequences instead of
  xterm Ctrl-modified variants (e.g. \x1b[1;5A for Ctrl+Up)
- Make gateway dashboard URL clickable (opens WebDashboardScreen) with
  primary color + underline styling and open_in_new icon button
- Add "Configure" quick action card running `openclaw configure` in terminal
- Add OpenSSH as optional package (apt-get install openssh-client openssh-server)

Co-Authored-By: Mithun Gowda B <[email protected]>

* Add multi-provider AI model selection and SSH remote access

- Add AiProvider data model with 7 built-in providers (Anthropic, OpenAI,
  Google Gemini, OpenRouter, NVIDIA NIM, DeepSeek, xAI)
- Add ProviderConfigService to read/write provider config in openclaw.json
  using Node.js safe-merge pattern
- Add ProvidersScreen listing all providers with Active/Configured badges
- Add ProviderDetailScreen with API key form and model dropdown
- Add SshService for sshd lifecycle (start/stop, password, IP discovery)
- Add SshScreen with service control, password management, and connection
  info with copyable ssh commands
- Add AI Providers and SSH Access cards to dashboard

Co-Authored-By: Mithun Gowda B <[email protected]>

* Fix resolv.conf ENOENT after app upgrade (#40)

After upgrading to v1.7.3, Android may clear the app's files directory.
writeResolvConf() only created the config/ directory but other required
directories (tmp/, home/, lib/, proc/sys fakes) were missing, causing
proot bind-mount failures.

Call setupDirectories() instead of a bare mkdirs() so the entire
directory tree is recreated before writing resolv.conf. Also use the
two-argument File constructor for correctness.

Fixes #40

Co-Authored-By: Mithun Gowda B <[email protected]>

* Call setupDirs before writeResolv in gateway init and start (#40)

On a normal app launch (setup already complete), setupDirs was never
called. If Android cleared the files directory after an upgrade, the
config/ directory was missing when writeResolv ran.

Now both init() and start() call setupDirs() first, matching the
bootstrap flow. The Kotlin-side writeResolvConf() also calls
setupDirectories() internally as a safety net.

Co-Authored-By: Mithun Gowda B <[email protected]>

* Fix writeResolvConf: only mkdirs config dir, not full setupDirectories (#40)

setupDirectories() also runs setupLibtalloc() and setupFakeSysdata()
which can fail during first-time setup when rootfs hasn't been
extracted yet. writeResolvConf() only needs the config/ directory
to exist.

The Dart-side gateway_service.dart still calls setupDirs() before
writeResolv() for the upgrade/restart case where directories may
have been cleared by Android.

Co-Authored-By: Mithun Gowda B <[email protected]>

* Call setupDirectories in GatewayService before proot starts (#40)

After an app update, Android may clear all files. The background
GatewayService only called writeResolvConf() which creates config/
dir, but proot also needs tmp/, home/, lib/libtalloc.so.2, and
proc/sys fakes for bind mounts.

Now setupDirectories() runs before writeResolvConf() in the Android
service, matching the Dart-side fix in gateway_service.dart.

All paths now covered:
- First-time setup: bootstrap calls setupDirs then writeResolv
- App open (Dart): init/start call setupDirs then writeResolv
- Background service (Kotlin): setupDirectories then writeResolvConf
- writeResolvConf itself: mkdirs config dir as safety net

Co-Authored-By: Mithun Gowda B <[email protected]>

* Rewrite SSH to use native foreground service for persistent sshd

The previous implementation used single-shot runInProot() which can't
run daemons — proot uses --kill-on-exit so sshd dies when the command
finishes. Also pgrep/hostname -I don't work reliably inside proot.

Changes:
- Add SshForegroundService.kt: runs sshd -D (foreground mode) in a
  persistent proot process with wake lock and notification
- Add native bridge methods: startSshd, stopSshd, isSshdRunning,
  getSshdPort, getDeviceIps, setRootPassword
- getDeviceIps uses Android NetworkInterface (not proot hostname -I)
- setRootPassword runs chpasswd via processManager.runInProotSync
- Register SshForegroundService in AndroidManifest.xml
- Rewrite ssh_service.dart to use native methods
- Update ssh_screen.dart to fetch IPs from Android

Co-Authored-By: Mithun Gowda B <[email protected]>

* Fix Ctrl key for soft keyboard input in terminal and configure screens

CTRL/ALT toolbar buttons only worked with other toolbar buttons (arrows,
etc.), not with soft keyboard input. Keyboard chars went directly through
terminal.onOutput → pty.write(), bypassing the toolbar's modifier state.

Fix: Share CTRL/ALT state via ValueNotifier between toolbar and screen.
The onOutput handler now checks if modifiers are active and transforms
keyboard input (e.g., Ctrl+C sends byte 0x03). Both terminal_screen.dart
and configure_screen.dart are fixed.

Co-Authored-By: Mithun Gowda B <[email protected]>

* Fix Ctrl key in onboarding and package install screens, remove unused imports

Add ctrlNotifier/altNotifier to TerminalToolbar usage in
onboarding_screen.dart and package_install_screen.dart (build errors).
Remove unnecessary dart:typed_data imports (already provided by
package:flutter/services.dart).

Co-Authored-By: Mithun Gowda B <[email protected]>

* Fix resolv.conf ENOENT: use context.filesDir, make init() resilient (#40)

- writeResolvConf() now uses context.filesDir (Android-guaranteed path)
  instead of the String configDir which could point to a cleared directory
- gateway_service init() wraps writeResolv() in try-catch since it's
  non-critical when gateway is already running

Co-Authored-By: Mithun Gowda B <[email protected]>

* Run setupDirs + writeResolv unconditionally on app open (#40)

Previously these only ran when the gateway was already running.
After an app update, the gateway is not running but Android may have
cleared the files directory. Moving setupDirs/writeResolv before the
isGatewayRunning check ensures resolv.conf always exists before any
terminal or gateway operation.

Co-Authored-By: Mithun Gowda B <[email protected]>

* Ensure dirs + resolv.conf exist before every proot operation (#40)

getProotShellConfig() is called by all screens before starting proot
(terminal, configure, onboarding, package install). Adding setupDirs
and writeResolv here guarantees resolv.conf exists regardless of which
screen the user opens first after an app update.

Co-Authored-By: Mithun Gowda B <[email protected]>

* Ensure dirs + resolv.conf on every app launch via splash screen (#40)

The splash screen is the first screen on every app open — reinstall,
update, or normal launch. Running setupDirs + writeResolv here
guarantees the files exist before any screen can use proot.

Co-Authored-By: Mithun Gowda B <[email protected]>

* v1.8.0: AI Providers, SSH Access, Ctrl keys, Configure menu, resolv.conf fix

- Bump version to 1.8.0 (pubspec.yaml, constants.dart)
- Update CHANGELOG with all new features and bug fixes
- Update README with new features, file structure, and OpenSSH package

Co-Authored-By: Mithun Gowda B <[email protected]>

* Make resolv.conf creation bulletproof, never block gateway start (#40)

- writeResolvConf() now has a try/catch fallback: tries context.filesDir
  first, falls back to string-based configDir path
- gateway_service start() wraps setupDirs + writeResolv in individual
  try-catches so failures don't prevent gateway from starting (the
  GatewayService.kt foreground service also creates these files)

Co-Authored-By: Mithun Gowda B <[email protected]>

* v1.8.1: Bulletproof resolv.conf fix for update/reinstall/restart

Co-Authored-By: Mithun Gowda B <[email protected]>

* Prevent setupDirectories/writeResolvConf from crashing gateway/SSH start

Wrap both calls in try-catch in GatewayService.kt and SshForegroundService.kt
so the gateway/SSH process still starts even if directory setup fails.
GatewayService now logs warnings if setup fails for debugging.

Co-Authored-By: Mithun Gowda B <[email protected]>

* Add Dart-side resolv.conf fallback using dart:io (#40)

The Kotlin writeResolv method channel silently fails in some cases.
Added direct Dart file creation as fallback in both splash_screen
and terminal_service (getProotShellConfig). Uses dart:io Directory
and File APIs to create config/resolv.conf directly, bypassing the
method channel entirely.

Co-Authored-By: Mithun Gowda B <[email protected]>

* Fix retry setup crashing on resolv.conf ENOENT (#40)

bootstrap_service setupDirs/writeResolv were not wrapped in try-catch,
so the entire setup failed if writeResolv threw. Added try-catch and
Dart dart:io fallback to create resolv.conf directly.

Co-Authored-By: Mithun Gowda B <[email protected]>

* Add native setupDirs + writeResolv + dart:io fallback to all screens (#40)

Every screen and service now has 3 layers of defense:
1. NativeBridge.setupDirs() — Kotlin method channel
2. NativeBridge.writeResolv() — Kotlin method channel
3. dart:io File/Directory — direct Dart fallback

Applied to: terminal, configure, onboarding, package_install screens
and gateway_service init + start.

Co-Authored-By: Mithun Gowda B <[email protected]>

* Remove CI lint and Security workflows

These workflows check Node.js lint/test/audit which is not relevant
to the Flutter app. Only the flutter-build workflow is needed.

Co-Authored-By: Mithun Gowda B <[email protected]>

* Enhance build workflow: PR comments with artifact links, build summary

- Comment on PRs with build status, version, and direct artifact links
- Update existing bot comment instead of spamming new ones
- Comment on build failure with link to logs
- Add build summary table with file sizes to Actions step summary
- Add pull-requests: write permission for PR comments

Co-Authored-By: Mithun Gowda B <[email protected]>

v1.8.0

Toggle v1.8.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
v1.8.0: AI Providers, SSH Access, Ctrl keys, Configure menu, resolv.c…

…onf fix (#36-#40) (#42)

* Fix Ctrl key for arrows/special keys, add Configure menu, clickable URL, SSH package (#37, #38)

- Fix Ctrl+Arrow/Home/End/PgUp/PgDn sending raw sequences instead of
  xterm Ctrl-modified variants (e.g. \x1b[1;5A for Ctrl+Up)
- Make gateway dashboard URL clickable (opens WebDashboardScreen) with
  primary color + underline styling and open_in_new icon button
- Add "Configure" quick action card running `openclaw configure` in terminal
- Add OpenSSH as optional package (apt-get install openssh-client openssh-server)

Co-Authored-By: Mithun Gowda B <[email protected]>

* Add multi-provider AI model selection and SSH remote access

- Add AiProvider data model with 7 built-in providers (Anthropic, OpenAI,
  Google Gemini, OpenRouter, NVIDIA NIM, DeepSeek, xAI)
- Add ProviderConfigService to read/write provider config in openclaw.json
  using Node.js safe-merge pattern
- Add ProvidersScreen listing all providers with Active/Configured badges
- Add ProviderDetailScreen with API key form and model dropdown
- Add SshService for sshd lifecycle (start/stop, password, IP discovery)
- Add SshScreen with service control, password management, and connection
  info with copyable ssh commands
- Add AI Providers and SSH Access cards to dashboard

Co-Authored-By: Mithun Gowda B <[email protected]>

* Fix resolv.conf ENOENT after app upgrade (#40)

After upgrading to v1.7.3, Android may clear the app's files directory.
writeResolvConf() only created the config/ directory but other required
directories (tmp/, home/, lib/, proc/sys fakes) were missing, causing
proot bind-mount failures.

Call setupDirectories() instead of a bare mkdirs() so the entire
directory tree is recreated before writing resolv.conf. Also use the
two-argument File constructor for correctness.

Fixes #40

Co-Authored-By: Mithun Gowda B <[email protected]>

* Call setupDirs before writeResolv in gateway init and start (#40)

On a normal app launch (setup already complete), setupDirs was never
called. If Android cleared the files directory after an upgrade, the
config/ directory was missing when writeResolv ran.

Now both init() and start() call setupDirs() first, matching the
bootstrap flow. The Kotlin-side writeResolvConf() also calls
setupDirectories() internally as a safety net.

Co-Authored-By: Mithun Gowda B <[email protected]>

* Fix writeResolvConf: only mkdirs config dir, not full setupDirectories (#40)

setupDirectories() also runs setupLibtalloc() and setupFakeSysdata()
which can fail during first-time setup when rootfs hasn't been
extracted yet. writeResolvConf() only needs the config/ directory
to exist.

The Dart-side gateway_service.dart still calls setupDirs() before
writeResolv() for the upgrade/restart case where directories may
have been cleared by Android.

Co-Authored-By: Mithun Gowda B <[email protected]>

* Call setupDirectories in GatewayService before proot starts (#40)

After an app update, Android may clear all files. The background
GatewayService only called writeResolvConf() which creates config/
dir, but proot also needs tmp/, home/, lib/libtalloc.so.2, and
proc/sys fakes for bind mounts.

Now setupDirectories() runs before writeResolvConf() in the Android
service, matching the Dart-side fix in gateway_service.dart.

All paths now covered:
- First-time setup: bootstrap calls setupDirs then writeResolv
- App open (Dart): init/start call setupDirs then writeResolv
- Background service (Kotlin): setupDirectories then writeResolvConf
- writeResolvConf itself: mkdirs config dir as safety net

Co-Authored-By: Mithun Gowda B <[email protected]>

* Rewrite SSH to use native foreground service for persistent sshd

The previous implementation used single-shot runInProot() which can't
run daemons — proot uses --kill-on-exit so sshd dies when the command
finishes. Also pgrep/hostname -I don't work reliably inside proot.

Changes:
- Add SshForegroundService.kt: runs sshd -D (foreground mode) in a
  persistent proot process with wake lock and notification
- Add native bridge methods: startSshd, stopSshd, isSshdRunning,
  getSshdPort, getDeviceIps, setRootPassword
- getDeviceIps uses Android NetworkInterface (not proot hostname -I)
- setRootPassword runs chpasswd via processManager.runInProotSync
- Register SshForegroundService in AndroidManifest.xml
- Rewrite ssh_service.dart to use native methods
- Update ssh_screen.dart to fetch IPs from Android

Co-Authored-By: Mithun Gowda B <[email protected]>

* Fix Ctrl key for soft keyboard input in terminal and configure screens

CTRL/ALT toolbar buttons only worked with other toolbar buttons (arrows,
etc.), not with soft keyboard input. Keyboard chars went directly through
terminal.onOutput → pty.write(), bypassing the toolbar's modifier state.

Fix: Share CTRL/ALT state via ValueNotifier between toolbar and screen.
The onOutput handler now checks if modifiers are active and transforms
keyboard input (e.g., Ctrl+C sends byte 0x03). Both terminal_screen.dart
and configure_screen.dart are fixed.

Co-Authored-By: Mithun Gowda B <[email protected]>

* Fix Ctrl key in onboarding and package install screens, remove unused imports

Add ctrlNotifier/altNotifier to TerminalToolbar usage in
onboarding_screen.dart and package_install_screen.dart (build errors).
Remove unnecessary dart:typed_data imports (already provided by
package:flutter/services.dart).

Co-Authored-By: Mithun Gowda B <[email protected]>

* Fix resolv.conf ENOENT: use context.filesDir, make init() resilient (#40)

- writeResolvConf() now uses context.filesDir (Android-guaranteed path)
  instead of the String configDir which could point to a cleared directory
- gateway_service init() wraps writeResolv() in try-catch since it's
  non-critical when gateway is already running

Co-Authored-By: Mithun Gowda B <[email protected]>

* Run setupDirs + writeResolv unconditionally on app open (#40)

Previously these only ran when the gateway was already running.
After an app update, the gateway is not running but Android may have
cleared the files directory. Moving setupDirs/writeResolv before the
isGatewayRunning check ensures resolv.conf always exists before any
terminal or gateway operation.

Co-Authored-By: Mithun Gowda B <[email protected]>

* Ensure dirs + resolv.conf exist before every proot operation (#40)

getProotShellConfig() is called by all screens before starting proot
(terminal, configure, onboarding, package install). Adding setupDirs
and writeResolv here guarantees resolv.conf exists regardless of which
screen the user opens first after an app update.

Co-Authored-By: Mithun Gowda B <[email protected]>

* Ensure dirs + resolv.conf on every app launch via splash screen (#40)

The splash screen is the first screen on every app open — reinstall,
update, or normal launch. Running setupDirs + writeResolv here
guarantees the files exist before any screen can use proot.

Co-Authored-By: Mithun Gowda B <[email protected]>

* v1.8.0: AI Providers, SSH Access, Ctrl keys, Configure menu, resolv.conf fix

- Bump version to 1.8.0 (pubspec.yaml, constants.dart)
- Update CHANGELOG with all new features and bug fixes
- Update README with new features, file structure, and OpenSSH package

Co-Authored-By: Mithun Gowda B <[email protected]>

v1.7.3

Toggle v1.7.3's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
v1.7.3: Fix DNS reliability, add snapshot backup & storage access (#36)

* v1.7.3: Fix DNS reliability, add snapshot backup & storage access

- Fix #34: Write resolv.conf before every gateway start (Flutter + Android
  foreground service) so DNS never breaks from cache clearing
- Fix #35: Sync version strings across constants.dart, pubspec.yaml,
  package.json, and lib/index.js to 1.7.3
- Fix #27: Add config snapshot export/import under Settings > Maintenance,
  with dashboard quick action card
- Add Termux-style storage access: request MANAGE_EXTERNAL_STORAGE,
  bind-mount /sdcard into proot, save snapshots to /sdcard/Download/
- Bump version to 1.7.3+10

Co-Authored-By: Mithun Gowda B <[email protected]>

* Fix manifest merger conflict with camera_android_camerax

Add tools namespace and tools:replace="android:maxSdkVersion" on
WRITE_EXTERNAL_STORAGE to override the camera library's maxSdkVersion=28
with our maxSdkVersion=29.

Co-Authored-By: Mithun Gowda B <[email protected]>

* Fix empty /sdcard in proot: bind /storage tree and check permission properly

- Bind the whole /storage directory (not just /storage/emulated/0) so
  Android's FUSE symlinks and sub-mounts resolve correctly inside proot
- Check Environment.isExternalStorageManager() on Android 11+ instead of
  just canRead(), which returns true even without actual file access
- Create /sdcard symlink inside rootfs pointing to /storage/emulated/0
- Bind both /storage:/storage and /storage/emulated/0:/sdcard for
  maximum compatibility (matches Termux proot-distro behavior)

Co-Authored-By: Mithun Gowda B <[email protected]>

* Request storage permission on app launch

Automatically prompts for "All files access" (Android 11+) or
READ/WRITE_EXTERNAL_STORAGE (older) when the app starts, so /sdcard
is accessible in proot without needing to manually go to Settings.

Co-Authored-By: Mithun Gowda B <[email protected]>

* Add /sdcard bind mount to terminal proot session

The terminal builds its own proot args in Dart (terminal_service.dart)
separately from ProcessManager.kt. Added /storage and /sdcard bind
mounts to buildProotArgs() so the terminal shell also has access to
shared storage when permission is granted.

Co-Authored-By: Mithun Gowda B <[email protected]>

v1.7.2

Toggle v1.7.2's commit message
Bump version to 1.7.2+9

Co-Authored-By: Mithun Gowda B <[email protected]>