refactor: app logging - script-src access in release
This commit is contained in:
parent
7392b2f92b
commit
38c7355e43
@ -21,7 +21,6 @@
|
|||||||
"dev:electron": "yarn copy:assets && yarn workspace jan dev",
|
"dev:electron": "yarn copy:assets && yarn workspace jan dev",
|
||||||
"dev:web:standalone": "concurrently \"yarn workspace @janhq/web dev\" \"wait-on http://localhost:3000 && rsync -av --prune-empty-dirs --include '*/' --include 'dist/***' --include 'package.json' --include 'tsconfig.json' --exclude '*' ./extensions/ web/.next/static/extensions/\"",
|
"dev:web:standalone": "concurrently \"yarn workspace @janhq/web dev\" \"wait-on http://localhost:3000 && rsync -av --prune-empty-dirs --include '*/' --include 'dist/***' --include 'package.json' --include 'tsconfig.json' --exclude '*' ./extensions/ web/.next/static/extensions/\"",
|
||||||
"dev:web": "yarn workspace @janhq/web dev",
|
"dev:web": "yarn workspace @janhq/web dev",
|
||||||
"dev:web:tauri": "IS_TAURI=true yarn workspace @janhq/web dev",
|
|
||||||
"dev:server": "yarn workspace @janhq/server dev",
|
"dev:server": "yarn workspace @janhq/server dev",
|
||||||
"dev": "concurrently -n \"NEXT,ELECTRON\" -c \"yellow,blue\" --kill-others \"yarn dev:web\" \"yarn dev:electron\"",
|
"dev": "concurrently -n \"NEXT,ELECTRON\" -c \"yellow,blue\" --kill-others \"yarn dev:web\" \"yarn dev:electron\"",
|
||||||
"install:cortex:linux:darwin": "cd src-tauri/binaries && ./download.sh",
|
"install:cortex:linux:darwin": "cd src-tauri/binaries && ./download.sh",
|
||||||
|
|||||||
@ -21,9 +21,7 @@ tauri-build = { version = "2.0.2", features = [] }
|
|||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
tauri = { version = "2.1.0", features = [
|
tauri = { version = "2.1.0", features = [ "protocol-asset", "macos-private-api",
|
||||||
"protocol-asset",
|
|
||||||
'macos-private-api',
|
|
||||||
"test",
|
"test",
|
||||||
] }
|
] }
|
||||||
tauri-plugin-log = "2.0.0-rc"
|
tauri-plugin-log = "2.0.0-rc"
|
||||||
@ -36,7 +34,6 @@ tauri-plugin-store = "2"
|
|||||||
hyper = { version = "0.14", features = ["server"] }
|
hyper = { version = "0.14", features = ["server"] }
|
||||||
reqwest = { version = "0.11", features = ["json"] }
|
reqwest = { version = "0.11", features = ["json"] }
|
||||||
tokio = { version = "1", features = ["full"] }
|
tokio = { version = "1", features = ["full"] }
|
||||||
tracing = "0.1.41"
|
|
||||||
rmcp = { git = "https://github.com/modelcontextprotocol/rust-sdk", branch = "main", features = [
|
rmcp = { git = "https://github.com/modelcontextprotocol/rust-sdk", branch = "main", features = [
|
||||||
"client",
|
"client",
|
||||||
"transport-sse",
|
"transport-sse",
|
||||||
|
|||||||
@ -2,18 +2,15 @@
|
|||||||
"$schema": "../gen/schemas/desktop-schema.json",
|
"$schema": "../gen/schemas/desktop-schema.json",
|
||||||
"identifier": "default",
|
"identifier": "default",
|
||||||
"description": "enables the default permissions",
|
"description": "enables the default permissions",
|
||||||
"windows": [
|
"windows": ["main"],
|
||||||
"main"
|
|
||||||
],
|
|
||||||
"remote": {
|
"remote": {
|
||||||
"urls": [
|
"urls": ["http://*"]
|
||||||
"http://*"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"permissions": [
|
"permissions": [
|
||||||
"core:default",
|
"core:default",
|
||||||
"shell:allow-spawn",
|
"shell:allow-spawn",
|
||||||
"shell:allow-open",
|
"shell:allow-open",
|
||||||
|
"log:default",
|
||||||
{
|
{
|
||||||
"identifier": "http:default",
|
"identifier": "http:default",
|
||||||
"allow": [
|
"allow": [
|
||||||
|
|||||||
@ -35,7 +35,7 @@ pub fn get_app_configurations<R: Runtime>(app_handle: tauri::AppHandle<R>) -> Ap
|
|||||||
let default_data_folder = default_data_folder_path(app_handle.clone());
|
let default_data_folder = default_data_folder_path(app_handle.clone());
|
||||||
|
|
||||||
if !configuration_file.exists() {
|
if !configuration_file.exists() {
|
||||||
println!(
|
log::info!(
|
||||||
"App config not found, creating default config at {:?}",
|
"App config not found, creating default config at {:?}",
|
||||||
configuration_file
|
configuration_file
|
||||||
);
|
);
|
||||||
@ -46,7 +46,7 @@ pub fn get_app_configurations<R: Runtime>(app_handle: tauri::AppHandle<R>) -> Ap
|
|||||||
&configuration_file,
|
&configuration_file,
|
||||||
serde_json::to_string(&app_default_configuration).unwrap(),
|
serde_json::to_string(&app_default_configuration).unwrap(),
|
||||||
) {
|
) {
|
||||||
eprintln!("Failed to create default config: {}", err);
|
log::error!("Failed to create default config: {}", err);
|
||||||
}
|
}
|
||||||
|
|
||||||
return app_default_configuration;
|
return app_default_configuration;
|
||||||
@ -56,7 +56,7 @@ pub fn get_app_configurations<R: Runtime>(app_handle: tauri::AppHandle<R>) -> Ap
|
|||||||
Ok(content) => match serde_json::from_str::<AppConfiguration>(&content) {
|
Ok(content) => match serde_json::from_str::<AppConfiguration>(&content) {
|
||||||
Ok(app_configurations) => app_configurations,
|
Ok(app_configurations) => app_configurations,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!(
|
log::error!(
|
||||||
"Failed to parse app config, returning default config instead. Error: {}",
|
"Failed to parse app config, returning default config instead. Error: {}",
|
||||||
err
|
err
|
||||||
);
|
);
|
||||||
@ -64,7 +64,7 @@ pub fn get_app_configurations<R: Runtime>(app_handle: tauri::AppHandle<R>) -> Ap
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!(
|
log::error!(
|
||||||
"Failed to read app config, returning default config instead. Error: {}",
|
"Failed to read app config, returning default config instead. Error: {}",
|
||||||
err
|
err
|
||||||
);
|
);
|
||||||
@ -79,7 +79,7 @@ pub fn update_app_configuration(
|
|||||||
configuration: AppConfiguration,
|
configuration: AppConfiguration,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
let configuration_file = get_configuration_file_path(app_handle);
|
let configuration_file = get_configuration_file_path(app_handle);
|
||||||
println!(
|
log::info!(
|
||||||
"update_app_configuration, configuration_file: {:?}",
|
"update_app_configuration, configuration_file: {:?}",
|
||||||
configuration_file
|
configuration_file
|
||||||
);
|
);
|
||||||
@ -136,7 +136,7 @@ pub fn read_theme(app_handle: tauri::AppHandle, theme_name: String) -> Result<St
|
|||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn get_configuration_file_path<R: Runtime>(app_handle: tauri::AppHandle<R>) -> PathBuf {
|
pub fn get_configuration_file_path<R: Runtime>(app_handle: tauri::AppHandle<R>) -> PathBuf {
|
||||||
let app_path = app_handle.path().app_data_dir().unwrap_or_else(|err| {
|
let app_path = app_handle.path().app_data_dir().unwrap_or_else(|err| {
|
||||||
eprintln!(
|
log::error!(
|
||||||
"Failed to get app data directory: {}. Using home directory instead.",
|
"Failed to get app data directory: {}. Using home directory instead.",
|
||||||
err
|
err
|
||||||
);
|
);
|
||||||
@ -215,7 +215,7 @@ pub fn open_file_explorer(path: String) {
|
|||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn install_extensions(app: AppHandle) {
|
pub fn install_extensions(app: AppHandle) {
|
||||||
if let Err(err) = setup::install_extensions(app, true) {
|
if let Err(err) = setup::install_extensions(app, true) {
|
||||||
eprintln!("Failed to install extensions: {}", err);
|
log::error!("Failed to install extensions: {}", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,7 +223,7 @@ pub fn install_extensions(app: AppHandle) {
|
|||||||
pub fn get_active_extensions(app: AppHandle) -> Vec<serde_json::Value> {
|
pub fn get_active_extensions(app: AppHandle) -> Vec<serde_json::Value> {
|
||||||
let mut path = get_jan_extensions_path(app);
|
let mut path = get_jan_extensions_path(app);
|
||||||
path.push("extensions.json");
|
path.push("extensions.json");
|
||||||
println!("get jan extensions, path: {:?}", path);
|
log::info!("get jan extensions, path: {:?}", path);
|
||||||
|
|
||||||
let contents = fs::read_to_string(path);
|
let contents = fs::read_to_string(path);
|
||||||
let contents: Vec<serde_json::Value> = match contents {
|
let contents: Vec<serde_json::Value> = match contents {
|
||||||
|
|||||||
@ -73,7 +73,7 @@ pub fn readdir_sync<R: Runtime>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let path = resolve_path(app_handle, &args[0]);
|
let path = resolve_path(app_handle, &args[0]);
|
||||||
println!("Reading directory: {:?}", path);
|
log::error!("Reading directory: {:?}", path);
|
||||||
let entries = fs::read_dir(&path).map_err(|e| e.to_string())?;
|
let entries = fs::read_dir(&path).map_err(|e| e.to_string())?;
|
||||||
let paths: Vec<String> = entries
|
let paths: Vec<String> = entries
|
||||||
.filter_map(|entry| entry.ok())
|
.filter_map(|entry| entry.ok())
|
||||||
|
|||||||
@ -17,7 +17,7 @@ pub async fn run_mcp_commands(
|
|||||||
app_path: String,
|
app_path: String,
|
||||||
servers_state: Arc<Mutex<HashMap<String, RunningService<RoleClient, ()>>>>,
|
servers_state: Arc<Mutex<HashMap<String, RunningService<RoleClient, ()>>>>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
println!(
|
log::info!(
|
||||||
"Load MCP configs from {}",
|
"Load MCP configs from {}",
|
||||||
app_path.clone() + "/mcp_config.json"
|
app_path.clone() + "/mcp_config.json"
|
||||||
);
|
);
|
||||||
@ -29,7 +29,7 @@ pub async fn run_mcp_commands(
|
|||||||
.map_err(|e| format!("Failed to parse config: {}", e))?;
|
.map_err(|e| format!("Failed to parse config: {}", e))?;
|
||||||
|
|
||||||
if let Some(server_map) = mcp_servers.get("mcpServers").and_then(Value::as_object) {
|
if let Some(server_map) = mcp_servers.get("mcpServers").and_then(Value::as_object) {
|
||||||
println!("MCP Servers: {server_map:#?}");
|
log::info!("MCP Servers: {server_map:#?}");
|
||||||
|
|
||||||
for (name, config) in server_map {
|
for (name, config) in server_map {
|
||||||
if let Some((command, args)) = extract_command_args(config) {
|
if let Some((command, args)) = extract_command_args(config) {
|
||||||
@ -53,7 +53,7 @@ pub async fn run_mcp_commands(
|
|||||||
for (_, service) in servers_map.iter() {
|
for (_, service) in servers_map.iter() {
|
||||||
// Initialize
|
// Initialize
|
||||||
let _server_info = service.peer_info();
|
let _server_info = service.peer_info();
|
||||||
println!("Connected to server: {_server_info:#?}");
|
log::info!("Connected to server: {_server_info:#?}");
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,6 @@ use std::net::SocketAddr;
|
|||||||
use std::sync::LazyLock;
|
use std::sync::LazyLock;
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
use tokio::task::JoinHandle;
|
use tokio::task::JoinHandle;
|
||||||
use tracing::{debug, error, info};
|
|
||||||
|
|
||||||
/// Server handle type for managing the proxy server lifecycle
|
/// Server handle type for managing the proxy server lifecycle
|
||||||
type ServerHandle = JoinHandle<Result<(), Box<dyn std::error::Error + Send + Sync>>>;
|
type ServerHandle = JoinHandle<Result<(), Box<dyn std::error::Error + Send + Sync>>>;
|
||||||
@ -24,7 +23,7 @@ struct ProxyConfig {
|
|||||||
|
|
||||||
/// Removes a prefix from a path, ensuring proper formatting
|
/// Removes a prefix from a path, ensuring proper formatting
|
||||||
fn remove_prefix(path: &str, prefix: &str) -> String {
|
fn remove_prefix(path: &str, prefix: &str) -> String {
|
||||||
debug!("Processing path: {}, removing prefix: {}", path, prefix);
|
log::debug!("Processing path: {}, removing prefix: {}", path, prefix);
|
||||||
|
|
||||||
if !prefix.is_empty() && path.starts_with(prefix) {
|
if !prefix.is_empty() && path.starts_with(prefix) {
|
||||||
let result = path[prefix.len()..].to_string();
|
let result = path[prefix.len()..].to_string();
|
||||||
@ -42,7 +41,6 @@ fn remove_prefix(path: &str, prefix: &str) -> String {
|
|||||||
fn get_destination_path(original_path: &str, prefix: &str) -> String {
|
fn get_destination_path(original_path: &str, prefix: &str) -> String {
|
||||||
let removed_prefix_path = remove_prefix(original_path, prefix);
|
let removed_prefix_path = remove_prefix(original_path, prefix);
|
||||||
|
|
||||||
println!("Removed prefix path: {}", removed_prefix_path);
|
|
||||||
// Special paths don't need the /v1 prefix
|
// Special paths don't need the /v1 prefix
|
||||||
if !original_path.contains(prefix)
|
if !original_path.contains(prefix)
|
||||||
|| removed_prefix_path.contains("/healthz")
|
|| removed_prefix_path.contains("/healthz")
|
||||||
@ -81,7 +79,7 @@ async fn proxy_request(
|
|||||||
|
|
||||||
// Build the outbound request
|
// Build the outbound request
|
||||||
let upstream_url = build_upstream_url(&config.upstream, &path);
|
let upstream_url = build_upstream_url(&config.upstream, &path);
|
||||||
debug!("Proxying request to: {}", upstream_url);
|
log::debug!("Proxying request to: {}", upstream_url);
|
||||||
|
|
||||||
let mut outbound_req = client.request(req.method().clone(), &upstream_url);
|
let mut outbound_req = client.request(req.method().clone(), &upstream_url);
|
||||||
|
|
||||||
@ -100,7 +98,7 @@ async fn proxy_request(
|
|||||||
match outbound_req.body(req.into_body()).send().await {
|
match outbound_req.body(req.into_body()).send().await {
|
||||||
Ok(response) => {
|
Ok(response) => {
|
||||||
let status = response.status();
|
let status = response.status();
|
||||||
debug!("Received response with status: {}", status);
|
log::debug!("Received response with status: {}", status);
|
||||||
|
|
||||||
let mut builder = Response::builder().status(status);
|
let mut builder = Response::builder().status(status);
|
||||||
|
|
||||||
@ -113,7 +111,7 @@ async fn proxy_request(
|
|||||||
match response.bytes().await {
|
match response.bytes().await {
|
||||||
Ok(bytes) => Ok(builder.body(Body::from(bytes)).unwrap()),
|
Ok(bytes) => Ok(builder.body(Body::from(bytes)).unwrap()),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Failed to read response body: {}", e);
|
log::error!("Failed to read response body: {}", e);
|
||||||
Ok(Response::builder()
|
Ok(Response::builder()
|
||||||
.status(StatusCode::INTERNAL_SERVER_ERROR)
|
.status(StatusCode::INTERNAL_SERVER_ERROR)
|
||||||
.body(Body::from("Error reading upstream response"))
|
.body(Body::from("Error reading upstream response"))
|
||||||
@ -122,7 +120,7 @@ async fn proxy_request(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Proxy request failed: {}", e);
|
log::error!("Proxy request failed: {}", e);
|
||||||
Ok(Response::builder()
|
Ok(Response::builder()
|
||||||
.status(StatusCode::BAD_GATEWAY)
|
.status(StatusCode::BAD_GATEWAY)
|
||||||
.body(Body::from(format!("Upstream error: {}", e)))
|
.body(Body::from(format!("Upstream error: {}", e)))
|
||||||
@ -175,12 +173,12 @@ pub async fn start_server(
|
|||||||
|
|
||||||
// Create and start the server
|
// Create and start the server
|
||||||
let server = Server::bind(&addr).serve(make_svc);
|
let server = Server::bind(&addr).serve(make_svc);
|
||||||
info!("Proxy server started on http://{}", addr);
|
log::info!("Proxy server started on http://{}", addr);
|
||||||
|
|
||||||
// Spawn server task
|
// Spawn server task
|
||||||
let server_handle = tokio::spawn(async move {
|
let server_handle = tokio::spawn(async move {
|
||||||
if let Err(e) = server.await {
|
if let Err(e) = server.await {
|
||||||
error!("Server error: {}", e);
|
log::error!("Server error: {}", e);
|
||||||
return Err(Box::new(e) as Box<dyn std::error::Error + Send + Sync>);
|
return Err(Box::new(e) as Box<dyn std::error::Error + Send + Sync>);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -196,9 +194,9 @@ pub async fn stop_server() -> Result<(), Box<dyn std::error::Error + Send + Sync
|
|||||||
|
|
||||||
if let Some(handle) = handle_guard.take() {
|
if let Some(handle) = handle_guard.take() {
|
||||||
handle.abort();
|
handle.abort();
|
||||||
info!("Proxy server stopped");
|
log::info!("Proxy server stopped");
|
||||||
} else {
|
} else {
|
||||||
debug!("No server was running");
|
log::debug!("No server was running");
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@ -11,6 +11,7 @@ use tauri_plugin_shell::process::CommandEvent;
|
|||||||
use tauri_plugin_shell::ShellExt;
|
use tauri_plugin_shell::ShellExt;
|
||||||
use tauri_plugin_store::StoreExt;
|
use tauri_plugin_store::StoreExt;
|
||||||
|
|
||||||
|
// MCP
|
||||||
use super::{
|
use super::{
|
||||||
cmd::{get_jan_data_folder_path, get_jan_extensions_path},
|
cmd::{get_jan_data_folder_path, get_jan_extensions_path},
|
||||||
mcp::run_mcp_commands,
|
mcp::run_mcp_commands,
|
||||||
@ -39,7 +40,7 @@ pub fn install_extensions(app: tauri::AppHandle, force: bool) -> Result<(), Stri
|
|||||||
// Attempt to remove extensions folder
|
// Attempt to remove extensions folder
|
||||||
if extensions_path.exists() {
|
if extensions_path.exists() {
|
||||||
fs::remove_dir_all(&extensions_path).unwrap_or_else(|_| {
|
fs::remove_dir_all(&extensions_path).unwrap_or_else(|_| {
|
||||||
println!("Failed to remove existing extensions folder, it may not exist.");
|
log::info!("Failed to remove existing extensions folder, it may not exist.");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,7 +67,7 @@ pub fn install_extensions(app: tauri::AppHandle, force: bool) -> Result<(), Stri
|
|||||||
let path = entry.path();
|
let path = entry.path();
|
||||||
|
|
||||||
if path.extension().map_or(false, |ext| ext == "tgz") {
|
if path.extension().map_or(false, |ext| ext == "tgz") {
|
||||||
println!("Installing extension from {:?}", path);
|
log::info!("Installing extension from {:?}", path);
|
||||||
let tar_gz = File::open(&path).map_err(|e| e.to_string())?;
|
let tar_gz = File::open(&path).map_err(|e| e.to_string())?;
|
||||||
let gz_decoder = GzDecoder::new(tar_gz);
|
let gz_decoder = GzDecoder::new(tar_gz);
|
||||||
let mut archive = Archive::new(gz_decoder);
|
let mut archive = Archive::new(gz_decoder);
|
||||||
@ -132,7 +133,7 @@ pub fn install_extensions(app: tauri::AppHandle, force: bool) -> Result<(), Stri
|
|||||||
|
|
||||||
extensions_list.push(new_extension);
|
extensions_list.push(new_extension);
|
||||||
|
|
||||||
println!("Installed extension to {:?}", extension_dir);
|
log::info!("Installed extension to {:?}", extension_dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fs::write(
|
fs::write(
|
||||||
@ -186,7 +187,7 @@ pub fn setup_mcp(app: &App) {
|
|||||||
let servers = state.mcp_servers.clone();
|
let servers = state.mcp_servers.clone();
|
||||||
tauri::async_runtime::spawn(async move {
|
tauri::async_runtime::spawn(async move {
|
||||||
if let Err(e) = run_mcp_commands(app_path_str, servers).await {
|
if let Err(e) = run_mcp_commands(app_path_str, servers).await {
|
||||||
eprintln!("Failed to run mcp commands: {}", e);
|
log::error!("Failed to run mcp commands: {}", e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -252,7 +253,7 @@ pub fn setup_sidecar(app: &App) -> Result<(), String> {
|
|||||||
while let Some(event) = rx.recv().await {
|
while let Some(event) = rx.recv().await {
|
||||||
if let CommandEvent::Stdout(line_bytes) = event {
|
if let CommandEvent::Stdout(line_bytes) = event {
|
||||||
let line = String::from_utf8_lossy(&line_bytes);
|
let line = String::from_utf8_lossy(&line_bytes);
|
||||||
println!("Outputs: {:?}", line)
|
log::info!("Outputs: {:?}", line)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -268,7 +269,7 @@ pub fn setup_sidecar(app: &App) -> Result<(), String> {
|
|||||||
|
|
||||||
fn copy_dir_all(src: PathBuf, dst: PathBuf) -> Result<(), String> {
|
fn copy_dir_all(src: PathBuf, dst: PathBuf) -> Result<(), String> {
|
||||||
fs::create_dir_all(&dst).map_err(|e| e.to_string())?;
|
fs::create_dir_all(&dst).map_err(|e| e.to_string())?;
|
||||||
println!("Copying from {:?} to {:?}", src, dst);
|
log::info!("Copying from {:?} to {:?}", src, dst);
|
||||||
for entry in fs::read_dir(src).map_err(|e| e.to_string())? {
|
for entry in fs::read_dir(src).map_err(|e| e.to_string())? {
|
||||||
let entry = entry.map_err(|e| e.to_string())?;
|
let entry = entry.map_err(|e| e.to_string())?;
|
||||||
let ty = entry.file_type().map_err(|e| e.to_string())?;
|
let ty = entry.file_type().map_err(|e| e.to_string())?;
|
||||||
@ -293,10 +294,10 @@ pub fn setup_engine_binaries(app: &App) -> Result<(), String> {
|
|||||||
.join("resources");
|
.join("resources");
|
||||||
|
|
||||||
if let Err(e) = copy_dir_all(binaries_dir, app_data_dir.clone()) {
|
if let Err(e) = copy_dir_all(binaries_dir, app_data_dir.clone()) {
|
||||||
eprintln!("Failed to copy binaries: {}", e);
|
log::error!("Failed to copy binaries: {}", e);
|
||||||
}
|
}
|
||||||
if let Err(e) = copy_dir_all(themes_dir, app_data_dir.clone()) {
|
if let Err(e) = copy_dir_all(themes_dir, app_data_dir.clone()) {
|
||||||
eprintln!("Failed to copy themes: {}", e);
|
log::error!("Failed to copy themes: {}", e);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
mod core;
|
mod core;
|
||||||
use core::{
|
use core::{
|
||||||
|
cmd::get_jan_data_folder_path,
|
||||||
setup::{self, setup_engine_binaries, setup_mcp, setup_sidecar},
|
setup::{self, setup_engine_binaries, setup_mcp, setup_sidecar},
|
||||||
state::{generate_app_token, AppState},
|
state::{generate_app_token, AppState},
|
||||||
};
|
};
|
||||||
@ -11,8 +12,8 @@ use tokio::sync::Mutex;
|
|||||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||||
pub fn run() {
|
pub fn run() {
|
||||||
tauri::Builder::default()
|
tauri::Builder::default()
|
||||||
.plugin(tauri_plugin_store::Builder::new().build())
|
|
||||||
.plugin(tauri_plugin_http::init())
|
.plugin(tauri_plugin_http::init())
|
||||||
|
.plugin(tauri_plugin_store::Builder::new().build())
|
||||||
.plugin(tauri_plugin_shell::init())
|
.plugin(tauri_plugin_shell::init())
|
||||||
.invoke_handler(tauri::generate_handler![
|
.invoke_handler(tauri::generate_handler![
|
||||||
// FS commands - Deperecate soon
|
// FS commands - Deperecate soon
|
||||||
@ -47,25 +48,26 @@ pub fn run() {
|
|||||||
mcp_servers: Arc::new(Mutex::new(HashMap::new())),
|
mcp_servers: Arc::new(Mutex::new(HashMap::new())),
|
||||||
})
|
})
|
||||||
.setup(|app| {
|
.setup(|app| {
|
||||||
if cfg!(debug_assertions) {
|
app.handle().plugin(
|
||||||
app.handle().plugin(
|
tauri_plugin_log::Builder::default()
|
||||||
tauri_plugin_log::Builder::default()
|
.targets([
|
||||||
.level(log::LevelFilter::Info)
|
tauri_plugin_log::Target::new(tauri_plugin_log::TargetKind::Folder {
|
||||||
.build(),
|
path: get_jan_data_folder_path(app.handle().clone()).join("logs"),
|
||||||
)?;
|
file_name: Some("app".to_string()),
|
||||||
}
|
}),
|
||||||
|
if cfg!(debug_assertions) {
|
||||||
|
tauri_plugin_log::Target::new(tauri_plugin_log::TargetKind::Stdout)
|
||||||
|
},
|
||||||
|
])
|
||||||
|
.build(),
|
||||||
|
)?;
|
||||||
// Install extensions
|
// Install extensions
|
||||||
if let Err(e) = setup::install_extensions(app.handle().clone(), false) {
|
if let Err(e) = setup::install_extensions(app.handle().clone(), false) {
|
||||||
eprintln!("Failed to install extensions: {}", e);
|
log::error!("Failed to install extensions: {}", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
setup_mcp(app);
|
setup_mcp(app);
|
||||||
|
|
||||||
setup_sidecar(app).expect("Failed to setup sidecar");
|
setup_sidecar(app).expect("Failed to setup sidecar");
|
||||||
|
|
||||||
setup_engine_binaries(app).expect("Failed to setup engine binaries");
|
setup_engine_binaries(app).expect("Failed to setup engine binaries");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
.on_window_event(|window, event| match event {
|
.on_window_event(|window, event| match event {
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
{
|
{
|
||||||
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
|
"$schema": "https://schema.tauri.app/config/2",
|
||||||
"productName": "Jan",
|
"productName": "Jan",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"identifier": "jan.ai",
|
"identifier": "jan.ai",
|
||||||
"build": {
|
"build": {
|
||||||
"frontendDist": "../web/out",
|
"frontendDist": "../web/out",
|
||||||
"devUrl": "http://localhost:3000",
|
"devUrl": "http://localhost:3000",
|
||||||
"beforeDevCommand": "yarn dev:web:tauri",
|
"beforeDevCommand": "IS_TAURI=true yarn dev:web",
|
||||||
"beforeBuildCommand": "yarn build:web"
|
"beforeBuildCommand": "IS_TAURI=true yarn build:web"
|
||||||
},
|
},
|
||||||
"app": {
|
"app": {
|
||||||
"macOSPrivateApi": true,
|
"macOSPrivateApi": true,
|
||||||
@ -27,9 +27,10 @@
|
|||||||
"csp": {
|
"csp": {
|
||||||
"default-src": "'self' customprotocol: asset: http://localhost:* http://127.0.0.1:* ws://localhost:* ws://127.0.0.1:*",
|
"default-src": "'self' customprotocol: asset: http://localhost:* http://127.0.0.1:* ws://localhost:* ws://127.0.0.1:*",
|
||||||
"connect-src": "ipc: http://ipc.localhost",
|
"connect-src": "ipc: http://ipc.localhost",
|
||||||
"font-src": ["https://fonts.gstatic.com"],
|
"font-src": ["https://fonts.gstatic.com blob: data:"],
|
||||||
"img-src": "'self' asset: http://asset.localhost blob: data:",
|
"img-src": "'self' asset: http://asset.localhost blob: data:",
|
||||||
"style-src": "'unsafe-inline' 'self' https://fonts.googleapis.com"
|
"style-src": "'unsafe-inline' 'self' https://fonts.googleapis.com",
|
||||||
|
"script-src": "'self' asset: $APPDATA/**.*"
|
||||||
},
|
},
|
||||||
"assetProtocol": {
|
"assetProtocol": {
|
||||||
"enable": true,
|
"enable": true,
|
||||||
|
|||||||
@ -22,7 +22,8 @@ export const useLoadTheme = () => {
|
|||||||
|
|
||||||
const setNativeTheme = useCallback(
|
const setNativeTheme = useCallback(
|
||||||
(nativeTheme: NativeThemeProps) => {
|
(nativeTheme: NativeThemeProps) => {
|
||||||
if (!('setNativeThemeDark' in window.core.api)) return
|
if (!window.electronAPI) return
|
||||||
|
|
||||||
if (nativeTheme === 'dark') {
|
if (nativeTheme === 'dark') {
|
||||||
window?.core?.api?.setNativeThemeDark()
|
window?.core?.api?.setNativeThemeDark()
|
||||||
setTheme('dark')
|
setTheme('dark')
|
||||||
@ -58,21 +59,20 @@ export const useLoadTheme = () => {
|
|||||||
setThemeOptions(themesOptions)
|
setThemeOptions(themesOptions)
|
||||||
|
|
||||||
if (!selectedIdTheme.length) return setSelectedIdTheme('joi-light')
|
if (!selectedIdTheme.length) return setSelectedIdTheme('joi-light')
|
||||||
|
|
||||||
const theme: Theme = JSON.parse(
|
const theme: Theme = JSON.parse(
|
||||||
await window.core.api.readTheme({
|
await window.core.api.readTheme({
|
||||||
theme: selectedIdTheme,
|
themeName: selectedIdTheme,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
setThemeData(theme)
|
setThemeData(theme)
|
||||||
setNativeTheme(theme.nativeTheme)
|
setNativeTheme(theme.nativeTheme)
|
||||||
applyTheme(theme)
|
applyTheme(theme)
|
||||||
}, [])
|
}, [selectedIdTheme])
|
||||||
|
|
||||||
const configureTheme = useCallback(async () => {
|
const configureTheme = useCallback(async () => {
|
||||||
if (!themeData || !themeOptions) {
|
if (!themeData || !themeOptions) {
|
||||||
await getThemes()
|
getThemes()
|
||||||
} else {
|
} else {
|
||||||
applyTheme(themeData)
|
applyTheme(themeData)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user