Repository navigation
refactor: ui-module full cliclack consolidation + auth.rs final sweep #252
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
6f217f0
563eeb5
97c3fec
5fa882d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,175 @@ | ||
| # Tauri 2 — Mobile & Tablet Build Research | ||
|
|
||
| > Research summary: top open-source Tauri 2 projects that ship to Android/iOS | ||
| > (phones + tablets) and the setup/config/plugins they use. | ||
|
|
||
| ## 1. Does Tauri support tablets? | ||
|
|
||
| Yes. **Tauri v2** (stable since Aug 2024) is the first version with first-class | ||
| mobile support. Tablets run standard Android/iPadOS, so they use the same build | ||
| path as phones — no tablet-specific flag needed. | ||
|
|
||
| | Version | Mobile | | ||
| |---|---| | ||
| | Tauri v1 | Desktop only (no mobile) | | ||
| | Tauri v2 | Android + iOS (arm + x86-64 device targets) | | ||
|
|
||
| - Android: minSdk 24 (Android 7+; many apps target 30/Android 12+) | ||
| - iOS/iPadOS: 9+ (iPad supported) | ||
| - WebView: system Android System WebView / iOS WKWebView | ||
|
|
||
| ## 2. How the UI adapts to mobile vs desktop | ||
|
|
||
| Tauri ships **no** UI framework — it is a webview shell. Adaptation is your web | ||
| code's job (same as any website): | ||
|
|
||
| - **Responsive CSS**: media queries (`@media (max-width: 768px)`), Flexbox/Grid, | ||
| `clamp()`/`vw`, frameworks (Tailwind, UnoCSS, Bootstrap). | ||
| - **Platform detection (JS)**: | ||
| ```js | ||
| import { platform } from '@tauri-apps/plugin-os' | ||
| const os = await platform() // 'android' | 'ios' | 'linux' | ... | ||
| ``` | ||
| Compile-time flag in some projects: `process.env.__TAURI_MOBILE__`. | ||
| - **Native feel**: `env(safe-area-inset-*)` for notches/gesture bars; ≥44px touch | ||
| targets; momentum scroll; swipe/gesture handlers. | ||
| - **Tauri hooks**: `plugin-device` (screen size, DPR), `Window` API (resize, | ||
| fullscreen, safe-area), `plugin-shell` / deep links, notifications. | ||
|
Comment on lines
+34
to
+37
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '\n== File excerpt ==\n'
nl -ba TAURI_MOBILE_RESEARCH.md | sed -n '28,42p'
printf '\n== Repo search for plugin-device ==\n'
rg -n --hidden --no-ignore-vcs 'plugin-device|device-info|tauri-plugin-device' .
printf '\n== File inventory for related docs ==\n'
git ls-files | rg 'TAURI_MOBILE_RESEARCH\.md|tauri|plugin'Repository: getappz/agentflare Length of output: 216 🌐 Web query:
💡 Result: There is no official Tauri v2 plugin named Citations:
🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '\n== File excerpt ==\n'
awk 'NR>=28 && NR<=42 { printf "%4d %s\n", NR, $0 }' TAURI_MOBILE_RESEARCH.md
printf '\n== Related references in repo ==\n'
rg -n --hidden --no-ignore-vcs 'plugin-device|device-info|plugin-os|os info|Window API|plugin-shell' TAURI_MOBILE_RESEARCH.md .Repository: getappz/agentflare Length of output: 1617 Name the actual device-info plugin or remove this bullet. 🤖 Prompt for AI Agents |
||
|
|
||
| ## 3. Top projects to learn setup/config/plugins from | ||
|
|
||
| | Project | Stars | Stack | Mobile | Why | | ||
| |---|---|---|---|---| | ||
| | **HuLa** | 7.4k | Rust + Vue3 + Vite7 + UnoCSS | Android 12+, iOS 9+, desktop | Best real production example: one codebase → desktop + phone + tablet | | ||
| | **quantum** | 529 | Tauri + SolidStart (TS) | iOS, Android, desktop | Scaffold template w/ tuned release Cargo profile | | ||
| | **vscode-android** | ~small | React + TS + Vite + Tailwind | Android | Cleanest concrete `tauri.conf.json` + `capabilities/android.json` | | ||
| | **bastion** | — | React (shared web) | iOS + Android | `__TAURI_MOBILE__` detection + per-platform `tauri.*.conf.json` | | ||
| | **two** | 11 | SvelteKit + Tauri | iOS, Android | Minimal Svelte mobile reference | | ||
| | **brenogonzaga/tauri-plugin-*** | 15–19 | Rust plugins | iOS + Android | Cross-platform mobile plugins: stt, tts, audio-recorder | | ||
|
|
||
| ### How each adapts UI | ||
| - **HuLa**: separate `locales/*/mobile_*.json` + `public/Mobile/*.png`; one Vue app, | ||
| responsive via UnoCSS breakpoints; ships `docs/android_startup_guide.md`. | ||
| - **bastion**: `if (process.env.__TAURI_MOBILE__)` swaps nav drawer ↔ sidebar; | ||
| same React frontend for android/ios. | ||
| - **vscode-android**: Tailwind responsive + 44px touch targets + gestures + fullscreen. | ||
|
|
||
| ## 4. Concrete setup you can copy (from `vscode-android`) | ||
|
|
||
| ### `src-tauri/Cargo.toml` | ||
| ```toml | ||
| [package] | ||
| name = "vscode-android" | ||
| version = "1.0.0" | ||
| edition = "2021" | ||
|
|
||
| [lib] | ||
| name = "vscode_android_lib" | ||
| crate-type = ["staticlib", "cdylib", "rlib"] | ||
|
|
||
| [dependencies] | ||
| tauri = { version = "^2", features = [] } | ||
| tauri-build = { version = "^2" } | ||
| tauri-plugin-fs = "^2" | ||
| tauri-plugin-http = "^2" | ||
| tauri-plugin-shell = "^2" | ||
| tauri-plugin-store = "^2" | ||
| tauri-plugin-websocket = "^2" | ||
| serde = { version = "1.0", features = ["derive"] } | ||
| serde_json = "1.0" | ||
| tokio = { version = "1.36", features = ["full"] } | ||
|
|
||
| [profile.release] | ||
| codegen-units = 1 | ||
| lto = true | ||
| opt-level = "s" | ||
| strip = true | ||
| panic = "abort" # from quantum's tuned release profile | ||
| ``` | ||
|
|
||
| ### `tauri.conf.json` | ||
| ```json | ||
| { | ||
| "$schema": "https://schema.tauri.app/config/2", | ||
| "productName": "VSCode Android", | ||
| "version": "1.0.0", | ||
| "identifier": "com.vscode.android", | ||
| "build": { | ||
| "frontendDist": "../dist", | ||
| "devUrl": "http://localhost:1420", | ||
| "beforeDevCommand": "npm run dev", | ||
| "beforeBuildCommand": "npm run build" | ||
| }, | ||
| "app": { | ||
| "windows": [{ "title": "VSCode Android", "width": 1920, "height": 1080, "resizable": true }], | ||
| "security": { | ||
| "csp": "default-src 'self'; connect-src 'self' https://api.github.com wss://*; img-src 'self' data: https://*; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'" | ||
| } | ||
|
Comment on lines
+105
to
+107
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win Do not present this CSP as a hardened copy-paste baseline.
🤖 Prompt for AI Agents |
||
| }, | ||
| "bundle": { | ||
| "active": true, | ||
| "icon": ["icons/32x32.png", "icons/128x128.png", "icons/128x128@2x.png", "icons/icon.icns", "icons/icon.ico"], | ||
| "android": { "minSdkVersion": 24 } | ||
| }, | ||
| "plugins": { | ||
| "http": { "scope": ["https://api.github.com", "https://github.com", "wss://*"] }, | ||
| "websocket": { "scope": ["wss://*.github.dev", "wss://api.github.com"] }, | ||
| "store": { "path": "store.bin" } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ### `src-tauri/capabilities/android.json` | ||
| ```json | ||
| { | ||
| "identifier": "android-capability", | ||
| "description": "Capability for Android platform", | ||
| "windows": ["main"], | ||
| "permissions": ["core:default", "fs:allow-read-text-file", "websocket:default"], | ||
| "platforms": ["android"] | ||
|
Comment on lines
+114
to
+129
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
# Locate the referenced doc and related Tauri config files
git ls-files | rg '(^|/)(TAURI_MOBILE_RESEARCH\.md|tauri\.conf(\.[jt]s|\.json)?|android\.json|capabilities/.*\.json)$'
# Show the relevant section of TAURI_MOBILE_RESEARCH.md
if git ls-files --error-unmatch TAURI_MOBILE_RESEARCH.md >/dev/null 2>&1; then
echo '--- TAURI_MOBILE_RESEARCH.md (around lines 100-140) ---'
sed -n '100,140p' TAURI_MOBILE_RESEARCH.md
fi
# Show any capability files mentioning http/websocket/store
echo '--- capability files mentioning http/websocket/store ---'
for f in $(git ls-files | rg 'capabilities/.*\.json$'); do
if rg -n '"(http|websocket|store)"|http:default|websocket:default|fs:allow-read-text-file' "$f" >/dev/null; then
echo "### $f"
rg -n '"(http|websocket|store)"|http:default|websocket:default|fs:allow-read-text-file' "$f"
fi
done
# Show any tauri config files mentioning plugins/http/websocket/store
echo '--- tauri config files mentioning plugins/http/websocket/store ---'
for f in $(git ls-files | rg 'tauri\.conf(\.[jt]s|\.json)?$|TAURI_MOBILE_RESEARCH\.md$'); do
if rg -n '"plugins"|http\.scope|websocket\.scope|store\.bin|http:default|websocket:default' "$f" >/dev/null; then
echo "### $f"
rg -n '"plugins"|http\.scope|websocket\.scope|store\.bin|http:default|websocket:default' "$f"
fi
doneRepository: getappz/agentflare Length of output: 1952 🌐 Web query:
💡 Result: In Tauri v2, managing plugin access is handled through a system of Capabilities and Permissions defined in your Citations:
Move the URL allowlists into capability permissions. Tauri v2 keeps HTTP/WebSocket scopes in capability permission entries, not under 🤖 Prompt for AI Agents |
||
| } | ||
| ``` | ||
| Mirror with `capabilities/ios.json` (`"platforms": ["ios"]`), and platform | ||
| overrides via `tauri.android.conf.json` / `tauri.ios.conf.json`. | ||
|
|
||
| ## 5. Build & signing commands | ||
|
|
||
| ```bash | ||
| # init mobile projects (generates src-tauri/gen/android|ios) | ||
| cargo tauri android init | ||
| cargo tauri ios init | ||
|
|
||
| # dev on device/simulator | ||
| cargo tauri android dev | ||
| cargo tauri ios dev --open | ||
|
|
||
| # release builds | ||
| cargo tauri android build # unsigned APK | ||
| cargo tauri android build --apk # APK | ||
| cargo tauri android build --aab # AAB for Play Store | ||
| cargo tauri ios build | ||
| ``` | ||
|
|
||
| Android signing is configured in `tauri.conf.json` (`bundle.android.*`) or via | ||
| `src-tauri/gen/android/gradle.properties` + `build.gradle.kts` signingConfigs. | ||
|
Comment on lines
+153
to
+154
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '--- TAURI_MOBILE_RESEARCH.md excerpt ---'
nl -ba TAURI_MOBILE_RESEARCH.md | sed -n '145,165p'
echo
echo '--- search for Android signing references in repo ---'
python3 - <<'PY'
import os
from pathlib import Path
targets = []
for p in Path('.').rglob('*'):
if p.is_file() and p.suffix in {'.md', '.json', '.json5', '.toml', '.ts', '.js', '.kts', '.kt', '.rs', '.yml', '.yaml'}:
try:
text = p.read_text(errors='ignore')
except Exception:
continue
if any(k in text for k in ['keystore.properties', 'signingConfigs', 'bundle.android', 'android.signing', 'signing']):
targets.append(str(p))
for p in targets[:200]:
print(p)
PYRepository: getappz/agentflare Length of output: 237 🏁 Script executed: python3 - <<'PY'
from pathlib import Path
path = Path("TAURI_MOBILE_RESEARCH.md")
text = path.read_text(errors="ignore").splitlines()
for i in range(145, 166):
if 1 <= i <= len(text):
print(f"{i:4d}: {text[i-1]}")
PYRepository: getappz/agentflare Length of output: 1174 🌐 Web query:
💡 Result: To configure Android signing for a Tauri application, you do not use tauri.conf.json directly for keystore credentials; instead, you configure the native Android Gradle project generated by Tauri [1][2]. Tauri's official documentation provides a standard approach using a keystore.properties file and Gradle signingConfigs [1][2]. 1. Create a keystore.properties File In your project directory, create a file named src-tauri/gen/android/keystore.properties. This file should contain the necessary information to access your Java Keystore (JKS) [1][2]: password= keyAlias= storeFile= Note: For CI/CD pipelines, these values are typically injected via environment variables rather than stored in a plaintext file [1][2][3]. 2. Configure Gradle (build.gradle.kts) Edit the file at src-tauri/gen/android/app/build.gradle.kts to load these properties and configure the release signing config [1][2]. Add the signingConfigs block before the buildTypes block: signingConfigs { create("release") { val keystorePropertiesFile = rootProject.file("keystore.properties") val keystoreProperties = Properties if (keystorePropertiesFile.exists) { keystoreProperties.load(FileInputStream(keystorePropertiesFile)) } keyAlias = keystoreProperties["keyAlias"] as String keyPassword = keystoreProperties["password"] as String storeFile = file(keystoreProperties["storeFile"] as String) storePassword = keystoreProperties["password"] as String } } Then, apply this configuration in the buildTypes block: buildTypes { getByName("release") { signingConfig = signingConfigs.getByName("release") } } Tauri configuration files (tauri.conf.json or tauri.android.conf.json) are primarily used for application metadata, window settings, and other bundle configurations, but they do not manage the native Android keystore signing process [4][5]. Always refer to the official Tauri Android signing documentation for the most accurate, up-to-date implementation details [2]. Citations:
Fix the Android signing workflow. Tauri’s Android docs use 🤖 Prompt for AI Agents |
||
|
|
||
| ## 6. Recommendation | ||
|
|
||
| - **Fork as a production base** → **HuLa** (monorepo, `.cargo/config.toml`, | ||
| `docs/android_startup_guide.md`, mobile locales, desktop+tablet+phone+iOS). | ||
| - **Minimal clean config reference** → copy `tauri.conf.json` + | ||
| `capabilities/android.json` + `Cargo.toml` from **vscode-android**. | ||
| - **Cross-platform mobile features** → **brenogonzaga** plugins (stt / tts / | ||
| audio-recorder). | ||
| - **Tuned release binary size** → **quantum**'s `panic="abort"`, `lto`, | ||
| `opt-level="s"`, `strip`, `codegen-units=1` profile. | ||
|
|
||
| ## 7. Sources | ||
|
|
||
| - https://github.com/HuLaSpark/HuLa | ||
| - https://github.com/atilafassina/quantum | ||
| - https://github.com/swadhinbiswas/vscode-android | ||
| - https://github.com/Calmingstorm/bastion | ||
| - https://github.com/minosiants/two | ||
| - https://github.com/brenogonzaga/tauri-plugin-stt (et al.) | ||
| - https://v2.tauri.app/reference/config/ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ | ||
| agentflare · Optimize AI CLI agents for cost & performance | ||
| ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,6 +16,20 @@ | |
|
|
||
| set -eu | ||
|
|
||
| # --- branding banner (mirror of assets/banner.txt; keep in sync) --- | ||
| print_banner() { | ||
| # Suppress for non-interactive, NO_COLOR, or quiet install. | ||
| case "${AGENTFLARE_QUIET_INSTALL:-}" in 1|true) return 0 ;; esac | ||
| if [ -t 1 ] && [ -z "${NO_COLOR+x}" ]; then | ||
| CY=$'\033[2;36m'; MG=$'\033[1;35m'; RS=$'\033[0m' | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Check the shebang of install.sh to determine shell compatibility
head -1 install.shRepository: getappz/agentflare Length of output: 166 🏁 Script executed: sed -n '1,40p' install.sh | cat -nRepository: getappz/agentflare Length of output: 2227
🧰 Tools🪛 Shellcheck (0.11.0)[warning] 24-24: In POSIX sh, $'..' is undefined. (SC3003) [warning] 24-24: In POSIX sh, $'..' is undefined. (SC3003) [warning] 24-24: In POSIX sh, $'..' is undefined. (SC3003) 🤖 Prompt for AI Agents |
||
| else | ||
| CY=""; MG=""; RS="" | ||
| fi | ||
| printf '%s\n' "${CY}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RS}" | ||
| printf '%s\n' "${MG} agentflare · Optimize AI CLI agents for cost & performance${RS}" | ||
| printf '%s\n' "${CY}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RS}" | ||
| } | ||
|
|
||
| REPO="getappz/agentflare" | ||
| INSTALL_DIR="${AGENTFLARE_INSTALL_DIR:-$HOME/.local/bin}" | ||
| # Resolve the script's directory when invoked as a file. When piped via | ||
|
|
@@ -34,7 +48,7 @@ SCRIPT_DIR="$( | |
| fi | ||
| )" | ||
|
|
||
| echo "agentflare installer" | ||
| print_banner | ||
|
|
||
| finish() { | ||
| case ":$PATH:" in | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| //! `agentflare about` — show the branding banner, version, and where to go next. | ||
| //! | ||
| //! Also the target of a bare `agentflare` invocation (no subcommand), per the | ||
| //! "invisible once configured" design: the splash appears on explicit request, | ||
| //! never on the stdio/MCP path. | ||
|
|
||
| use clap::Args; | ||
|
|
||
| use crate::banner::print_banner; | ||
| use crate::cli::AGENTFLARE_VERSION; | ||
|
|
||
| #[derive(Args)] | ||
| #[command(about = "Show agentflare version and branding")] | ||
| pub struct AboutArgs {} | ||
|
|
||
| pub fn run(_args: AboutArgs) { | ||
| print_banner(); | ||
| println!(); | ||
| println!(" version {}", AGENTFLARE_VERSION.as_str()); | ||
| println!(); | ||
| println!( | ||
| " Get started: agentflare init --agent <claude-code|codex|cursor|windsurf|vscode-copilot|cline|continue>" | ||
| ); | ||
| println!(" Docs: https://github.com/getappz/agentflare"); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: getappz/agentflare
Length of output: 260
🏁 Script executed:
Repository: getappz/agentflare
Length of output: 413
🏁 Script executed:
Repository: getappz/agentflare
Length of output: 223
🌐 Web query:
Tauri v2 iOS deployment target minimum version config.schema.json💡 Result:
In Tauri v2, you can configure the minimum iOS deployment target using the
bundle.iOS.minimumSystemVersionsetting in yourtauri.conf.jsonfile [1][2]. Configuration Details: - Path:bundle > iOS > minimumSystemVersion[1][2] - Type:string[1] - Purpose: Maps to theIPHONEOS_DEPLOYMENT_TARGETvalue for your iOS build [1][2]. - Default: While early versions defaulted to13.0[2][3], recent updates have moved this default to14.0[1][4]. Example usage intauri.conf.json: { "bundle": { "iOS": { "minimumSystemVersion": "15.0" } } } This setting ensures your application correctly specifies its minimum supported iOS version during the build process [1][2]. If you are using platform-specific configuration files, you can also place this setting withintauri.ios.conf.json[5][6].Citations:
🏁 Script executed:
Repository: getappz/agentflare
Length of output: 5670
🏁 Script executed:
Repository: getappz/agentflare
Length of output: 5631
Align the iOS minimum with Tauri v2
TAURI_MOBILE_RESEARCH.md#L18-L19and the HuLa row at#L43-L44still sayiOS 9+, but Tauri v2’s iOS floor is14.0. Update both spots so the guide doesn’t point readers to an obsolete target.📍 Affects 1 file
TAURI_MOBILE_RESEARCH.md#L18-L19(this comment)TAURI_MOBILE_RESEARCH.md#L43-L44🤖 Prompt for AI Agents