feat: Experiment removing hardware permission
This commit is contained in:
parent
b2c5063e0b
commit
814024982e
@ -9,24 +9,53 @@ export PATH="$HOME/.cargo/bin:$PATH"
|
||||
export JAVA_HOME=/opt/homebrew/opt/openjdk@17/libexec/openjdk.jdk/Contents/Home
|
||||
export PATH="/opt/homebrew/opt/openjdk@17/bin:$PATH"
|
||||
|
||||
export ANDROID_HOME=~/Library/Android/sdk
|
||||
export ANDROID_NDK_ROOT=~/Library/Android/sdk/ndk/29.0.14033849
|
||||
export NDK_HOME=~/Library/Android/sdk/ndk/29.0.14033849
|
||||
export ANDROID_HOME="$HOME/Library/Android/sdk"
|
||||
export ANDROID_NDK_ROOT="$HOME/Library/Android/sdk/ndk/29.0.14033849"
|
||||
export NDK_HOME="$HOME/Library/Android/sdk/ndk/29.0.14033849"
|
||||
|
||||
# Add Android tools to PATH
|
||||
export PATH=$PATH:$ANDROID_HOME/platform-tools:$ANDROID_HOME/tools:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/emulator:$NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin
|
||||
|
||||
# Set up CC and CXX for Android compilation
|
||||
export CC_aarch64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android21-clang
|
||||
export CXX_aarch64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android21-clang++
|
||||
export AR_aarch64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-ar
|
||||
export RANLIB_aarch64_linux_android=$NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-ranlib
|
||||
export CC_aarch64_linux_android="$NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android21-clang"
|
||||
export CXX_aarch64_linux_android="$NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android21-clang++"
|
||||
export AR_aarch64_linux_android="$NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-ar"
|
||||
export RANLIB_aarch64_linux_android="$NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-ranlib"
|
||||
|
||||
# Additional environment variables for Rust cross-compilation
|
||||
export CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER="$NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android21-clang"
|
||||
|
||||
# Only set global CC and AR for Android builds (when TAURI_ANDROID_BUILD is set)
|
||||
if [ "$TAURI_ANDROID_BUILD" = "true" ]; then
|
||||
export CC="$NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android21-clang"
|
||||
export AR="$NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-ar"
|
||||
echo "Global CC and AR set for Android build"
|
||||
fi
|
||||
|
||||
# Create symlinks for Android tools if they don't exist
|
||||
mkdir -p ~/.local/bin
|
||||
if [ ! -f ~/.local/bin/aarch64-linux-android-ranlib ]; then
|
||||
ln -sf $NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-ranlib ~/.local/bin/aarch64-linux-android-ranlib
|
||||
fi
|
||||
if [ ! -f ~/.local/bin/aarch64-linux-android-clang ]; then
|
||||
ln -sf $NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android21-clang ~/.local/bin/aarch64-linux-android-clang
|
||||
fi
|
||||
if [ ! -f ~/.local/bin/aarch64-linux-android-clang++ ]; then
|
||||
ln -sf $NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android21-clang++ ~/.local/bin/aarch64-linux-android-clang++
|
||||
fi
|
||||
|
||||
# Fix the broken clang symlinks by ensuring base clang is available
|
||||
if [ ! -f ~/.local/bin/clang ]; then
|
||||
ln -sf $NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang ~/.local/bin/clang
|
||||
fi
|
||||
if [ ! -f ~/.local/bin/clang++ ]; then
|
||||
ln -sf $NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++ ~/.local/bin/clang++
|
||||
fi
|
||||
|
||||
# Create symlinks for target-specific ar tools
|
||||
if [ ! -f ~/.local/bin/aarch64-linux-android-ar ]; then
|
||||
ln -sf $NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-ar ~/.local/bin/aarch64-linux-android-ar
|
||||
fi
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
|
||||
echo "Android environment configured:"
|
||||
|
||||
@ -12,6 +12,8 @@
|
||||
"scripts": {
|
||||
"lint": "yarn workspace @janhq/web-app lint",
|
||||
"dev": "yarn dev:tauri",
|
||||
"ios": "yarn tauri ios dev",
|
||||
"android": "yarn tauri android dev",
|
||||
"build": "yarn build:web && yarn build:tauri",
|
||||
"test": "vitest run",
|
||||
"test:watch": "vitest",
|
||||
@ -24,9 +26,9 @@
|
||||
"serve:web-app": "yarn workspace @janhq/web-app serve:web",
|
||||
"build:serve:web-app": "yarn build:web-app && yarn serve:web-app",
|
||||
"dev:tauri": "yarn build:icon && yarn copy:assets:tauri && cross-env IS_CLEAN=true tauri dev",
|
||||
"dev:ios": "yarn copy:assets:mobile && RUSTC_WRAPPER= yarn tauri ios dev",
|
||||
"dev:android": "yarn copy:assets:mobile && yarn tauri android dev",
|
||||
"build:android": "yarn build && yarn copy:assets:mobile && yarn tauri android build --no-default-features --features mobile",
|
||||
"dev:ios": "yarn copy:assets:mobile && RUSTC_WRAPPER= yarn tauri ios dev --features mobile",
|
||||
"dev:android": "yarn copy:assets:mobile && TAURI_ANDROID_BUILD=true yarn tauri android dev --features mobile",
|
||||
"build:android": "yarn build && yarn copy:assets:mobile && TAURI_ANDROID_BUILD=true yarn tauri android build --no-default-features --features mobile",
|
||||
"build:ios": "yarn build && yarn copy:assets:mobile && yarn tauri ios build --no-default-features --features mobile",
|
||||
"build:ios:device": "yarn build && yarn copy:assets:mobile && yarn tauri ios build --no-default-features --features mobile --export-method debugging",
|
||||
"copy:assets:tauri": "cpx \"pre-install/*.tgz\" \"src-tauri/resources/pre-install/\" && cpx \"LICENSE\" \"src-tauri/resources/\"",
|
||||
|
||||
@ -7,6 +7,7 @@ ENABLE_SYSTEM_TRAY_ICON = "false"
|
||||
[target.aarch64-linux-android]
|
||||
linker = "aarch64-linux-android21-clang"
|
||||
ar = "llvm-ar"
|
||||
rustflags = ["-C", "link-arg=-fuse-ld=lld"]
|
||||
|
||||
[target.armv7-linux-androideabi]
|
||||
linker = "armv7a-linux-androideabi21-clang"
|
||||
@ -19,5 +20,3 @@ ar = "llvm-ar"
|
||||
[target.i686-linux-android]
|
||||
linker = "i686-linux-android21-clang"
|
||||
ar = "llvm-ar"
|
||||
|
||||
|
||||
|
||||
@ -23,10 +23,19 @@ default = [
|
||||
"tauri/tray-icon",
|
||||
"tauri/test",
|
||||
"tauri/custom-protocol",
|
||||
"hardware",
|
||||
"desktop",
|
||||
]
|
||||
hardware = ["dep:tauri-plugin-hardware"]
|
||||
mobile = []
|
||||
deep-link = ["dep:tauri-plugin-deep-link"]
|
||||
desktop = [
|
||||
"deep-link",
|
||||
"hardware"
|
||||
]
|
||||
mobile = [
|
||||
"tauri/protocol-asset",
|
||||
"tauri/test",
|
||||
"tauri/wry",
|
||||
]
|
||||
test-tauri = [
|
||||
"tauri/wry",
|
||||
"tauri/x11",
|
||||
@ -63,11 +72,11 @@ serde_json = "1.0"
|
||||
serde_yaml = "0.9.34"
|
||||
tar = "0.4"
|
||||
zip = "0.6"
|
||||
tauri-plugin-deep-link = { version = "2.3.4" }
|
||||
tauri-plugin-dialog = "2.2.1"
|
||||
tauri-plugin-deep-link = { version = "2", optional = true }
|
||||
tauri-plugin-hardware = { path = "./plugins/tauri-plugin-hardware", optional = true }
|
||||
tauri-plugin-http = { version = "2", features = ["unsafe-headers"] }
|
||||
tauri-plugin-llamacpp = { path = "./plugins/tauri-plugin-llamacpp" }
|
||||
tauri-plugin-http = { version = "2", features = ["unsafe-headers"] }
|
||||
tauri-plugin-log = "2.0.0-rc"
|
||||
tauri-plugin-opener = "2.2.7"
|
||||
tauri-plugin-os = "2.2.1"
|
||||
@ -97,8 +106,16 @@ windows-sys = { version = "0.60.2", features = ["Win32_Storage_FileSystem"] }
|
||||
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
|
||||
tauri-plugin-updater = "2"
|
||||
once_cell = "1.18"
|
||||
tauri-plugin-single-instance = { version = "2", features = ["deep-link"] }
|
||||
|
||||
tauri-plugin-single-instance = { version = "2.3.4", features = ["deep-link"] }
|
||||
[target.'cfg(any(target_os = "android", target_os = "ios"))'.dependencies]
|
||||
tauri-plugin-dialog = { version = "2.2.1", default-features = false }
|
||||
tauri-plugin-http = { version = "2", default-features = false }
|
||||
tauri-plugin-log = { version = "2.0.0-rc", default-features = false }
|
||||
tauri-plugin-opener = { version = "2.2.7", default-features = false }
|
||||
tauri-plugin-os = { version = "2.2.1", default-features = false }
|
||||
tauri-plugin-shell = { version = "2.2.0", default-features = false }
|
||||
tauri-plugin-store = { version = "2", default-features = false }
|
||||
|
||||
# Release profile optimizations for minimal binary size
|
||||
[profile.release]
|
||||
|
||||
@ -19,7 +19,6 @@
|
||||
"opener:default",
|
||||
"log:default",
|
||||
"dialog:default",
|
||||
"deep-link:default",
|
||||
"core:webview:allow-create-webview-window",
|
||||
"opener:allow-open-url",
|
||||
{
|
||||
@ -55,7 +54,6 @@
|
||||
]
|
||||
},
|
||||
"store:default",
|
||||
"llamacpp:default",
|
||||
"hardware:default"
|
||||
"llamacpp:default"
|
||||
]
|
||||
}
|
||||
|
||||
63
src-tauri/capabilities/desktop.json
Normal file
63
src-tauri/capabilities/desktop.json
Normal file
@ -0,0 +1,63 @@
|
||||
{
|
||||
"$schema": "../gen/schemas/desktop-schema.json",
|
||||
"identifier": "desktop",
|
||||
"description": "enables the default permissions for desktop platforms",
|
||||
"windows": ["main"],
|
||||
"remote": {
|
||||
"urls": ["http://*"]
|
||||
},
|
||||
"platforms": ["linux", "macOS", "windows"],
|
||||
"permissions": [
|
||||
"core:default",
|
||||
"core:webview:allow-set-webview-zoom",
|
||||
"core:window:allow-start-dragging",
|
||||
"core:window:allow-set-theme",
|
||||
"shell:allow-spawn",
|
||||
"shell:allow-open",
|
||||
"core:app:allow-set-app-theme",
|
||||
"core:window:allow-set-focus",
|
||||
"os:default",
|
||||
"opener:default",
|
||||
"log:default",
|
||||
"dialog:default",
|
||||
"core:webview:allow-create-webview-window",
|
||||
"opener:allow-open-url",
|
||||
"store:default",
|
||||
"llamacpp:default",
|
||||
"deep-link:default",
|
||||
"hardware:default",
|
||||
|
||||
{
|
||||
"identifier": "http:default",
|
||||
"allow": [
|
||||
{
|
||||
"url": "https://*:*"
|
||||
},
|
||||
{
|
||||
"url": "http://*:*"
|
||||
}
|
||||
],
|
||||
"deny": []
|
||||
},
|
||||
{
|
||||
"identifier": "shell:allow-execute",
|
||||
"allow": []
|
||||
},
|
||||
{
|
||||
"identifier": "opener:allow-open-url",
|
||||
"description": "opens the default permissions for the core module",
|
||||
"windows": ["*"],
|
||||
"allow": [
|
||||
{
|
||||
"url": "https://*"
|
||||
},
|
||||
{
|
||||
"url": "http://127.0.0.1:*"
|
||||
},
|
||||
{
|
||||
"url": "http://0.0.0.0:*"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
58
src-tauri/capabilities/mobile.json
Normal file
58
src-tauri/capabilities/mobile.json
Normal file
@ -0,0 +1,58 @@
|
||||
{
|
||||
"$schema": "../gen/schemas/mobile-schema.json",
|
||||
"identifier": "mobile",
|
||||
"description": "enables the default permissions for mobile platforms",
|
||||
"windows": ["main"],
|
||||
"remote": {
|
||||
"urls": ["http://*"]
|
||||
},
|
||||
"permissions": [
|
||||
"core:default",
|
||||
"core:webview:allow-set-webview-zoom",
|
||||
"core:window:allow-start-dragging",
|
||||
"core:window:allow-set-theme",
|
||||
"shell:allow-spawn",
|
||||
"shell:allow-open",
|
||||
"core:app:allow-set-app-theme",
|
||||
"core:window:allow-set-focus",
|
||||
"os:default",
|
||||
"opener:default",
|
||||
"log:default",
|
||||
"dialog:default",
|
||||
"core:webview:allow-create-webview-window",
|
||||
"opener:allow-open-url",
|
||||
"store:default",
|
||||
{
|
||||
"identifier": "http:default",
|
||||
"allow": [
|
||||
{
|
||||
"url": "https://*:*"
|
||||
},
|
||||
{
|
||||
"url": "http://*:*"
|
||||
}
|
||||
],
|
||||
"deny": []
|
||||
},
|
||||
{
|
||||
"identifier": "shell:allow-execute",
|
||||
"allow": []
|
||||
},
|
||||
{
|
||||
"identifier": "opener:allow-open-url",
|
||||
"description": "opens the default permissions for the core module",
|
||||
"windows": ["*"],
|
||||
"allow": [
|
||||
{
|
||||
"url": "https://*"
|
||||
},
|
||||
{
|
||||
"url": "http://127.0.0.1:*"
|
||||
},
|
||||
{
|
||||
"url": "http://0.0.0.0:*"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -3,6 +3,7 @@
|
||||
"identifier": "system-monitor-window",
|
||||
"description": "enables permissions for the system monitor window",
|
||||
"windows": ["system-monitor-window"],
|
||||
"platforms": ["linux", "macOS", "windows"],
|
||||
"permissions": [
|
||||
"core:default",
|
||||
"core:window:allow-start-dragging",
|
||||
|
||||
19
src-tauri/gen/android/app/src/main/assets/resources/LICENSE
Normal file
19
src-tauri/gen/android/app/src/main/assets/resources/LICENSE
Normal file
@ -0,0 +1,19 @@
|
||||
Jan
|
||||
|
||||
Copyright 2025 Menlo Research
|
||||
|
||||
This product includes software developed by Menlo Research (https://menlo.ai).
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
You may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Attribution is requested in user-facing documentation and materials, where appropriate.
|
||||
@ -45,7 +45,6 @@ pub fn get_vulkan_gpus(lib_path: &str) -> Vec<GpuInfo> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
fn parse_c_string_u8(buf: &[u8]) -> String {
|
||||
unsafe { std::ffi::CStr::from_ptr(buf.as_ptr() as *const std::ffi::c_char) }
|
||||
.to_str()
|
||||
|
||||
@ -58,8 +58,8 @@ pub fn get_app_configurations<R: Runtime>(app_handle: tauri::AppHandle<R>) -> Ap
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn update_app_configuration(
|
||||
app_handle: tauri::AppHandle,
|
||||
pub fn update_app_configuration<R: Runtime>(
|
||||
app_handle: tauri::AppHandle<R>,
|
||||
configuration: AppConfiguration,
|
||||
) -> Result<(), String> {
|
||||
let configuration_file = get_configuration_file_path(app_handle);
|
||||
@ -155,13 +155,13 @@ pub fn default_data_folder_path<R: Runtime>(app_handle: tauri::AppHandle<R>) ->
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn get_user_home_path(app: AppHandle) -> String {
|
||||
pub fn get_user_home_path<R: Runtime>(app: AppHandle<R>) -> String {
|
||||
return get_app_configurations(app.clone()).data_folder;
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn change_app_data_folder(
|
||||
app_handle: tauri::AppHandle,
|
||||
pub fn change_app_data_folder<R: Runtime>(
|
||||
app_handle: tauri::AppHandle<R>,
|
||||
new_data_folder: String,
|
||||
) -> Result<(), String> {
|
||||
// Get current data folder path
|
||||
|
||||
@ -3,12 +3,12 @@ use super::models::DownloadItem;
|
||||
use crate::core::app::commands::get_jan_data_folder_path;
|
||||
use crate::core::state::AppState;
|
||||
use std::collections::HashMap;
|
||||
use tauri::State;
|
||||
use tauri::{Runtime, State};
|
||||
use tokio_util::sync::CancellationToken;
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn download_files(
|
||||
app: tauri::AppHandle,
|
||||
pub async fn download_files<R: Runtime>(
|
||||
app: tauri::AppHandle<R>,
|
||||
state: State<'_, AppState>,
|
||||
items: Vec<DownloadItem>,
|
||||
task_id: &str,
|
||||
|
||||
@ -6,7 +6,7 @@ use reqwest::header::{HeaderMap, HeaderName, HeaderValue};
|
||||
use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
use std::time::Duration;
|
||||
use tauri::Emitter;
|
||||
use tauri::{Emitter, Runtime};
|
||||
use tokio::fs::File;
|
||||
use tokio::io::AsyncWriteExt;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
@ -25,7 +25,7 @@ pub fn err_to_string<E: std::fmt::Display>(e: E) -> String {
|
||||
async fn validate_downloaded_file(
|
||||
item: &DownloadItem,
|
||||
save_path: &Path,
|
||||
app: &tauri::AppHandle,
|
||||
app: &tauri::AppHandle<impl Runtime>,
|
||||
cancel_token: &CancellationToken,
|
||||
) -> Result<(), String> {
|
||||
// Skip validation if no verification data is provided
|
||||
@ -298,7 +298,7 @@ pub async fn _get_file_size(
|
||||
|
||||
/// Downloads multiple files in parallel with individual progress tracking
|
||||
pub async fn _download_files_internal(
|
||||
app: tauri::AppHandle,
|
||||
app: tauri::AppHandle<impl Runtime>,
|
||||
items: &[DownloadItem],
|
||||
headers: &HashMap<String, String>,
|
||||
task_id: &str,
|
||||
@ -423,7 +423,7 @@ pub async fn _download_files_internal(
|
||||
|
||||
/// Downloads a single file without blocking other downloads
|
||||
async fn download_single_file(
|
||||
app: tauri::AppHandle,
|
||||
app: tauri::AppHandle<impl Runtime>,
|
||||
item: &DownloadItem,
|
||||
header_map: &HeaderMap,
|
||||
save_path: &std::path::Path,
|
||||
|
||||
@ -1,24 +1,24 @@
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
use tauri::AppHandle;
|
||||
use tauri::{AppHandle, Runtime};
|
||||
|
||||
use crate::core::app::commands::get_jan_data_folder_path;
|
||||
use crate::core::setup;
|
||||
|
||||
#[tauri::command]
|
||||
pub fn get_jan_extensions_path(app_handle: tauri::AppHandle) -> PathBuf {
|
||||
pub fn get_jan_extensions_path<R: Runtime>(app_handle: tauri::AppHandle<R>) -> PathBuf {
|
||||
get_jan_data_folder_path(app_handle).join("extensions")
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn install_extensions(app: AppHandle) {
|
||||
pub fn install_extensions<R: Runtime>(app: AppHandle<R>) {
|
||||
if let Err(err) = setup::install_extensions(app, true) {
|
||||
log::error!("Failed to install extensions: {}", err);
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn get_active_extensions(app: AppHandle) -> Vec<serde_json::Value> {
|
||||
pub fn get_active_extensions<R: Runtime>(app: AppHandle<R>) -> Vec<serde_json::Value> {
|
||||
let mut path = get_jan_extensions_path(app);
|
||||
path.push("extensions.json");
|
||||
log::info!("get jan extensions, path: {:?}", path);
|
||||
|
||||
@ -124,7 +124,7 @@ pub fn readdir_sync<R: Runtime>(
|
||||
|
||||
#[tauri::command]
|
||||
pub fn write_yaml(
|
||||
app: tauri::AppHandle,
|
||||
app: tauri::AppHandle<impl Runtime>,
|
||||
data: serde_json::Value,
|
||||
save_path: &str,
|
||||
) -> Result<(), String> {
|
||||
@ -145,7 +145,7 @@ pub fn write_yaml(
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn read_yaml(app: tauri::AppHandle, path: &str) -> Result<serde_json::Value, String> {
|
||||
pub fn read_yaml<R: Runtime>(app: tauri::AppHandle<R>, path: &str) -> Result<serde_json::Value, String> {
|
||||
let jan_data_folder = crate::core::app::commands::get_jan_data_folder_path(app.clone());
|
||||
let path = jan_utils::normalize_path(&jan_data_folder.join(path));
|
||||
if !path.starts_with(&jan_data_folder) {
|
||||
@ -162,7 +162,7 @@ pub fn read_yaml(app: tauri::AppHandle, path: &str) -> Result<serde_json::Value,
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn decompress(app: tauri::AppHandle, path: &str, output_dir: &str) -> Result<(), String> {
|
||||
pub fn decompress<R: Runtime>(app: tauri::AppHandle<R>, path: &str, output_dir: &str) -> Result<(), String> {
|
||||
let jan_data_folder = crate::core::app::commands::get_jan_data_folder_path(app.clone());
|
||||
let path_buf = jan_utils::normalize_path(&jan_data_folder.join(path));
|
||||
|
||||
|
||||
@ -80,7 +80,7 @@ pub async fn deactivate_mcp_server(state: State<'_, AppState>, name: String) ->
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn restart_mcp_servers(app: AppHandle, state: State<'_, AppState>) -> Result<(), String> {
|
||||
pub async fn restart_mcp_servers<R: Runtime>(app: AppHandle<R>, state: State<'_, AppState>) -> Result<(), String> {
|
||||
let servers = state.mcp_servers.clone();
|
||||
// Stop the servers
|
||||
stop_mcp_servers(state.mcp_servers.clone()).await?;
|
||||
@ -119,7 +119,7 @@ pub async fn reset_mcp_restart_count(
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn get_connected_servers(
|
||||
_app: AppHandle,
|
||||
_app: AppHandle<impl Runtime>,
|
||||
state: State<'_, AppState>,
|
||||
) -> Result<Vec<String>, String> {
|
||||
let servers = state.mcp_servers.clone();
|
||||
@ -293,7 +293,7 @@ pub async fn cancel_tool_call(
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn get_mcp_configs(app: AppHandle) -> Result<String, String> {
|
||||
pub async fn get_mcp_configs<R: Runtime>(app: AppHandle<R>) -> Result<String, String> {
|
||||
let mut path = get_jan_data_folder_path(app);
|
||||
path.push("mcp_config.json");
|
||||
|
||||
@ -308,7 +308,7 @@ pub async fn get_mcp_configs(app: AppHandle) -> Result<String, String> {
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn save_mcp_configs(app: AppHandle, configs: String) -> Result<(), String> {
|
||||
pub async fn save_mcp_configs<R: Runtime>(app: AppHandle<R>, configs: String) -> Result<(), String> {
|
||||
let mut path = get_jan_data_folder_path(app);
|
||||
path.push("mcp_config.json");
|
||||
log::info!("save mcp configs, path: {:?}", path);
|
||||
|
||||
@ -767,7 +767,7 @@ pub async fn start_server(
|
||||
});
|
||||
|
||||
*handle_guard = Some(server_task);
|
||||
let actual_port = actual_addr.port();
|
||||
let actual_port = addr.port();
|
||||
log::info!("Jan API server started successfully on port {}", actual_port);
|
||||
Ok(actual_port)
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ use std::{
|
||||
};
|
||||
use tar::Archive;
|
||||
use tauri::{
|
||||
App, Emitter, Manager,
|
||||
App, Emitter, Manager, Runtime,
|
||||
};
|
||||
|
||||
#[cfg(desktop)]
|
||||
@ -25,7 +25,7 @@ use super::{
|
||||
mcp::helpers::run_mcp_commands, state::AppState,
|
||||
};
|
||||
|
||||
pub fn install_extensions(app: tauri::AppHandle, force: bool) -> Result<(), String> {
|
||||
pub fn install_extensions<R: Runtime>(app: tauri::AppHandle<R>, force: bool) -> Result<(), String> {
|
||||
let mut store_path = get_jan_data_folder_path(app.clone());
|
||||
store_path.push("store.json");
|
||||
let store = app.store(store_path).expect("Store not initialized");
|
||||
@ -201,10 +201,10 @@ pub fn extract_extension_manifest<R: Read>(
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
pub fn setup_mcp(app: &App) {
|
||||
pub fn setup_mcp<R: Runtime>(app: &App<R>) {
|
||||
let state = app.state::<AppState>();
|
||||
let servers = state.mcp_servers.clone();
|
||||
let app_handle: tauri::AppHandle = app.handle().clone();
|
||||
let app_handle = app.handle().clone();
|
||||
tauri::async_runtime::spawn(async move {
|
||||
if let Err(e) = run_mcp_commands(&app_handle, servers).await {
|
||||
log::error!("Failed to run mcp commands: {}", e);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
use tauri::{AppHandle, Manager, State};
|
||||
use tauri::{AppHandle, Manager, Runtime, State};
|
||||
use tauri_plugin_llamacpp::cleanup_llama_processes;
|
||||
|
||||
use crate::core::app::commands::{
|
||||
@ -11,7 +11,7 @@ use crate::core::mcp::helpers::clean_up_mcp_servers;
|
||||
use crate::core::state::AppState;
|
||||
|
||||
#[tauri::command]
|
||||
pub fn factory_reset(app_handle: tauri::AppHandle, state: State<'_, AppState>) {
|
||||
pub fn factory_reset<R: Runtime>(app_handle: tauri::AppHandle<R>, state: State<'_, AppState>) {
|
||||
// close window (not available on mobile platforms)
|
||||
#[cfg(not(any(target_os = "ios", target_os = "android")))]
|
||||
{
|
||||
@ -49,12 +49,12 @@ pub fn factory_reset(app_handle: tauri::AppHandle, state: State<'_, AppState>) {
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn relaunch(app: AppHandle) {
|
||||
pub fn relaunch<R: Runtime>(app: AppHandle<R>) {
|
||||
app.restart()
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn open_app_directory(app: AppHandle) {
|
||||
pub fn open_app_directory<R: Runtime>(app: AppHandle<R>) {
|
||||
let app_path = app.path().app_data_dir().unwrap();
|
||||
if cfg!(target_os = "windows") {
|
||||
std::process::Command::new("explorer")
|
||||
@ -96,7 +96,7 @@ pub fn open_file_explorer(path: String) {
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn read_logs(app: AppHandle) -> Result<String, String> {
|
||||
pub async fn read_logs<R: Runtime>(app: AppHandle<R>) -> Result<String, String> {
|
||||
let log_path = get_jan_data_folder_path(app).join("logs").join("app.log");
|
||||
if log_path.exists() {
|
||||
let content = fs::read_to_string(log_path).map_err(|e| e.to_string())?;
|
||||
|
||||
@ -8,54 +8,23 @@ use core::{
|
||||
};
|
||||
use jan_utils::generate_app_token;
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
#[cfg(not(any(target_os = "ios", target_os = "android")))]
|
||||
use tauri_plugin_deep_link::DeepLinkExt;
|
||||
use tauri::{Emitter, Manager, RunEvent};
|
||||
use tauri_plugin_llamacpp::cleanup_llama_processes;
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
#[cfg(desktop)]
|
||||
use crate::core::setup::setup_tray;
|
||||
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
#[cfg_attr(all(mobile, any(target_os = "android", target_os = "ios")), tauri::mobile_entry_point)]
|
||||
pub fn run() {
|
||||
#[cfg(desktop)]
|
||||
let mut builder = tauri::Builder::default();
|
||||
#[cfg(mobile)]
|
||||
let builder = tauri::Builder::default();
|
||||
#[cfg(desktop)]
|
||||
{
|
||||
builder = builder.plugin(tauri_plugin_single_instance::init(|_app, argv, _cwd| {
|
||||
println!("a new app instance was opened with {argv:?} and the deep link event was already triggered");
|
||||
// when defining deep link schemes at runtime, you must also check `argv` here
|
||||
let arg = argv.iter().find(|arg| arg.starts_with("jan://"));
|
||||
if let Some(deep_link) = arg {
|
||||
println!("deep link: {deep_link}");
|
||||
// handle the deep link, e.g., emit an event to the webview
|
||||
_app.app_handle().emit("deep-link", deep_link).unwrap();
|
||||
if let Some(window) = _app.app_handle().get_webview_window("main") {
|
||||
let _ = window.set_focus();
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
#[cfg(feature = "hardware")]
|
||||
let app = builder
|
||||
let mut app_builder = builder
|
||||
.plugin(tauri_plugin_os::init())
|
||||
.plugin(tauri_plugin_deep_link::init())
|
||||
.plugin(tauri_plugin_dialog::init())
|
||||
.plugin(tauri_plugin_opener::init())
|
||||
.plugin(tauri_plugin_http::init())
|
||||
.plugin(tauri_plugin_store::Builder::new().build())
|
||||
.plugin(tauri_plugin_shell::init())
|
||||
.plugin(tauri_plugin_llamacpp::init())
|
||||
.plugin(tauri_plugin_hardware::init());
|
||||
|
||||
#[cfg(not(feature = "hardware"))]
|
||||
let app = builder
|
||||
.plugin(tauri_plugin_os::init())
|
||||
.plugin(tauri_plugin_deep_link::init())
|
||||
.plugin(tauri_plugin_dialog::init())
|
||||
.plugin(tauri_plugin_opener::init())
|
||||
.plugin(tauri_plugin_http::init())
|
||||
@ -63,7 +32,17 @@ pub fn run() {
|
||||
.plugin(tauri_plugin_shell::init())
|
||||
.plugin(tauri_plugin_llamacpp::init());
|
||||
|
||||
let app = app
|
||||
#[cfg(feature = "deep-link")]
|
||||
{
|
||||
app_builder = app_builder.plugin(tauri_plugin_deep_link::init());
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
{
|
||||
app_builder = app_builder.plugin(tauri_plugin_hardware::init());
|
||||
}
|
||||
|
||||
let app = app_builder
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
// FS commands - Deperecate soon
|
||||
core::filesystem::commands::join_path,
|
||||
@ -138,24 +117,6 @@ pub fn run() {
|
||||
server_handle: Arc::new(Mutex::new(None)),
|
||||
tool_call_cancellations: Arc::new(Mutex::new(HashMap::new())),
|
||||
})
|
||||
.on_window_event(|window, event| match event {
|
||||
tauri::WindowEvent::CloseRequested { api, .. } => {
|
||||
if option_env!("ENABLE_SYSTEM_TRAY_ICON").unwrap_or("false") == "true" {
|
||||
#[cfg(target_os = "macos")]
|
||||
window
|
||||
.app_handle()
|
||||
.set_activation_policy(tauri::ActivationPolicy::Accessory)
|
||||
.unwrap();
|
||||
|
||||
#[cfg(not(any(target_os = "ios", target_os = "android")))]
|
||||
window.hide().unwrap();
|
||||
#[cfg(any(target_os = "ios", target_os = "android"))]
|
||||
let _ = window; // Use window to avoid unused variable warning
|
||||
api.prevent_close();
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
})
|
||||
.setup(|app| {
|
||||
app.handle().plugin(
|
||||
tauri_plugin_log::Builder::default()
|
||||
@ -177,15 +138,11 @@ pub fn run() {
|
||||
log::error!("Failed to install extensions: {}", e);
|
||||
}
|
||||
|
||||
#[cfg(desktop)]
|
||||
if option_env!("ENABLE_SYSTEM_TRAY_ICON").unwrap_or("false") == "true" {
|
||||
log::info!("Enabling system tray icon");
|
||||
let _ = setup_tray(app);
|
||||
}
|
||||
|
||||
#[cfg(all(not(any(target_os = "ios", target_os = "android")), any(windows, target_os = "linux")))]
|
||||
#[cfg(all(feature = "deep-link", any(windows, target_os = "linux")))]
|
||||
{
|
||||
app.deep_link().register_all()?;
|
||||
use tauri_plugin_deep_link::DeepLinkExt;
|
||||
// Register the deep-link scheme programmatically
|
||||
app.deep_link().register("jan")?;
|
||||
}
|
||||
setup_mcp(app);
|
||||
Ok(())
|
||||
@ -199,13 +156,6 @@ pub fn run() {
|
||||
// This is called when the app is actually exiting (e.g., macOS dock quit)
|
||||
// We can't prevent this, so run cleanup quickly
|
||||
let app_handle = app.clone();
|
||||
// Hide window immediately
|
||||
if let Some(window) = app_handle.get_webview_window("main") {
|
||||
#[cfg(not(any(target_os = "ios", target_os = "android")))]
|
||||
let _ = window.hide();
|
||||
#[cfg(any(target_os = "ios", target_os = "android"))]
|
||||
let _ = window; // Use window to avoid unused variable warning
|
||||
}
|
||||
tokio::task::block_in_place(|| {
|
||||
tauri::async_runtime::block_on(async {
|
||||
// Hide window immediately (not available on mobile platforms)
|
||||
|
||||
@ -1,13 +1,15 @@
|
||||
{
|
||||
"identifier": "jan.ai.app",
|
||||
"build": {
|
||||
"devUrl": null,
|
||||
"frontendDist": "../web-app/dist"
|
||||
},
|
||||
"app": {
|
||||
"security": {
|
||||
"capabilities": ["default"]
|
||||
"capabilities": ["mobile"]
|
||||
}
|
||||
},
|
||||
"plugins": {},
|
||||
"bundle": {
|
||||
"resources": ["resources/LICENSE", "resources/pre-install"],
|
||||
"externalBin": []
|
||||
|
||||
@ -72,8 +72,7 @@
|
||||
"windows": {
|
||||
"installMode": "passive"
|
||||
}
|
||||
},
|
||||
"deep-link": { "schemes": ["jan"] }
|
||||
}
|
||||
},
|
||||
"bundle": {
|
||||
"active": true,
|
||||
|
||||
@ -3,11 +3,13 @@
|
||||
"devUrl": null,
|
||||
"frontendDist": "../web-app/dist"
|
||||
},
|
||||
"identifier": "jan.ai.app.ios",
|
||||
"app": {
|
||||
"security": {
|
||||
"capabilities": ["default"]
|
||||
"capabilities": ["mobile"]
|
||||
}
|
||||
},
|
||||
"plugins": {},
|
||||
"bundle": {
|
||||
"active": true,
|
||||
"iOS": {
|
||||
|
||||
@ -1,8 +1,12 @@
|
||||
{
|
||||
"app": {
|
||||
"security": {
|
||||
"capabilities": ["default", "system-monitor-window"]
|
||||
}
|
||||
},
|
||||
"bundle": {
|
||||
"targets": ["deb", "appimage"],
|
||||
"resources": ["resources/pre-install/**/*", "resources/LICENSE"],
|
||||
"externalBin": ["resources/bin/uv"],
|
||||
"resources": ["resources/LICENSE"],
|
||||
"linux": {
|
||||
"appimage": {
|
||||
"bundleMediaFramework": false,
|
||||
|
||||
@ -1,7 +1,11 @@
|
||||
{
|
||||
"app": {
|
||||
"security": {
|
||||
"capabilities": ["default", "system-monitor-window"]
|
||||
}
|
||||
},
|
||||
"bundle": {
|
||||
"targets": ["app", "dmg"],
|
||||
"resources": ["resources/pre-install/**/*", "resources/LICENSE"],
|
||||
"externalBin": ["resources/bin/bun", "resources/bin/uv"]
|
||||
"resources": ["resources/LICENSE"]
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,10 @@
|
||||
{
|
||||
"app": {
|
||||
"security": {
|
||||
"capabilities": ["default"]
|
||||
}
|
||||
},
|
||||
|
||||
"bundle": {
|
||||
"targets": ["nsis"],
|
||||
"resources": ["resources/pre-install/**/*", "resources/lib/vulkan-1.dll", "resources/lib/vc_redist.x64.exe", "resources/LICENSE"],
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user