refactor: app logging - script-src access in release
This commit is contained in:
parent
52290f9ee5
commit
baee71dd8e
@ -21,7 +21,6 @@
|
||||
"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": "yarn workspace @janhq/web dev",
|
||||
"dev:web:tauri": "IS_TAURI=true yarn workspace @janhq/web dev",
|
||||
"dev:server": "yarn workspace @janhq/server dev",
|
||||
"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",
|
||||
|
||||
@ -21,9 +21,7 @@ tauri-build = { version = "2.0.2", features = [] }
|
||||
serde_json = "1.0"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
log = "0.4"
|
||||
tauri = { version = "2.1.0", features = [
|
||||
"protocol-asset",
|
||||
'macos-private-api',
|
||||
tauri = { version = "2.1.0", features = [ "protocol-asset", "macos-private-api",
|
||||
"test",
|
||||
] }
|
||||
tauri-plugin-log = "2.0.0-rc"
|
||||
@ -36,7 +34,6 @@ tauri-plugin-store = "2"
|
||||
hyper = { version = "0.14", features = ["server"] }
|
||||
reqwest = { version = "0.11", features = ["json"] }
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
tracing = "0.1.41"
|
||||
rmcp = { git = "https://github.com/modelcontextprotocol/rust-sdk", branch = "main", features = [
|
||||
"client",
|
||||
"transport-sse",
|
||||
|
||||
@ -2,18 +2,15 @@
|
||||
"$schema": "../gen/schemas/desktop-schema.json",
|
||||
"identifier": "default",
|
||||
"description": "enables the default permissions",
|
||||
"windows": [
|
||||
"main"
|
||||
],
|
||||
"windows": ["main"],
|
||||
"remote": {
|
||||
"urls": [
|
||||
"http://*"
|
||||
]
|
||||
"urls": ["http://*"]
|
||||
},
|
||||
"permissions": [
|
||||
"core:default",
|
||||
"shell:allow-spawn",
|
||||
"shell:allow-open",
|
||||
"log:default",
|
||||
{
|
||||
"identifier": "http:default",
|
||||
"allow": [
|
||||
@ -55,4 +52,4 @@
|
||||
},
|
||||
"store:default"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@ -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());
|
||||
|
||||
if !configuration_file.exists() {
|
||||
println!(
|
||||
log::info!(
|
||||
"App config not found, creating default config at {:?}",
|
||||
configuration_file
|
||||
);
|
||||
@ -46,7 +46,7 @@ pub fn get_app_configurations<R: Runtime>(app_handle: tauri::AppHandle<R>) -> Ap
|
||||
&configuration_file,
|
||||
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;
|
||||
@ -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(app_configurations) => app_configurations,
|
||||
Err(err) => {
|
||||
eprintln!(
|
||||
log::error!(
|
||||
"Failed to parse app config, returning default config instead. Error: {}",
|
||||
err
|
||||
);
|
||||
@ -64,7 +64,7 @@ pub fn get_app_configurations<R: Runtime>(app_handle: tauri::AppHandle<R>) -> Ap
|
||||
}
|
||||
},
|
||||
Err(err) => {
|
||||
eprintln!(
|
||||
log::error!(
|
||||
"Failed to read app config, returning default config instead. Error: {}",
|
||||
err
|
||||
);
|
||||
@ -79,7 +79,7 @@ pub fn update_app_configuration(
|
||||
configuration: AppConfiguration,
|
||||
) -> Result<(), String> {
|
||||
let configuration_file = get_configuration_file_path(app_handle);
|
||||
println!(
|
||||
log::info!(
|
||||
"update_app_configuration, configuration_file: {:?}",
|
||||
configuration_file
|
||||
);
|
||||
@ -136,7 +136,7 @@ pub fn read_theme(app_handle: tauri::AppHandle, theme_name: String) -> Result<St
|
||||
#[tauri::command]
|
||||
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| {
|
||||
eprintln!(
|
||||
log::error!(
|
||||
"Failed to get app data directory: {}. Using home directory instead.",
|
||||
err
|
||||
);
|
||||
@ -215,7 +215,7 @@ pub fn open_file_explorer(path: String) {
|
||||
#[tauri::command]
|
||||
pub fn install_extensions(app: AppHandle) {
|
||||
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> {
|
||||
let mut path = get_jan_extensions_path(app);
|
||||
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: Vec<serde_json::Value> = match contents {
|
||||
|
||||
@ -73,7 +73,7 @@ pub fn readdir_sync<R: Runtime>(
|
||||
}
|
||||
|
||||
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 paths: Vec<String> = entries
|
||||
.filter_map(|entry| entry.ok())
|
||||
|
||||
@ -17,7 +17,7 @@ pub async fn run_mcp_commands(
|
||||
app_path: String,
|
||||
servers_state: Arc<Mutex<HashMap<String, RunningService<RoleClient, ()>>>>,
|
||||
) -> Result<(), String> {
|
||||
println!(
|
||||
log::info!(
|
||||
"Load MCP configs from {}",
|
||||
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))?;
|
||||
|
||||
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 {
|
||||
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() {
|
||||
// Initialize
|
||||
let _server_info = service.peer_info();
|
||||
println!("Connected to server: {_server_info:#?}");
|
||||
log::info!("Connected to server: {_server_info:#?}");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -6,7 +6,6 @@ use std::net::SocketAddr;
|
||||
use std::sync::LazyLock;
|
||||
use tokio::sync::Mutex;
|
||||
use tokio::task::JoinHandle;
|
||||
use tracing::{debug, error, info};
|
||||
|
||||
/// Server handle type for managing the proxy server lifecycle
|
||||
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
|
||||
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) {
|
||||
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 {
|
||||
let removed_prefix_path = remove_prefix(original_path, prefix);
|
||||
|
||||
println!("Removed prefix path: {}", removed_prefix_path);
|
||||
// Special paths don't need the /v1 prefix
|
||||
if !original_path.contains(prefix)
|
||||
|| removed_prefix_path.contains("/healthz")
|
||||
@ -81,7 +79,7 @@ async fn proxy_request(
|
||||
|
||||
// Build the outbound request
|
||||
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);
|
||||
|
||||
@ -100,7 +98,7 @@ async fn proxy_request(
|
||||
match outbound_req.body(req.into_body()).send().await {
|
||||
Ok(response) => {
|
||||
let status = response.status();
|
||||
debug!("Received response with status: {}", status);
|
||||
log::debug!("Received response with status: {}", status);
|
||||
|
||||
let mut builder = Response::builder().status(status);
|
||||
|
||||
@ -113,7 +111,7 @@ async fn proxy_request(
|
||||
match response.bytes().await {
|
||||
Ok(bytes) => Ok(builder.body(Body::from(bytes)).unwrap()),
|
||||
Err(e) => {
|
||||
error!("Failed to read response body: {}", e);
|
||||
log::error!("Failed to read response body: {}", e);
|
||||
Ok(Response::builder()
|
||||
.status(StatusCode::INTERNAL_SERVER_ERROR)
|
||||
.body(Body::from("Error reading upstream response"))
|
||||
@ -122,7 +120,7 @@ async fn proxy_request(
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Proxy request failed: {}", e);
|
||||
log::error!("Proxy request failed: {}", e);
|
||||
Ok(Response::builder()
|
||||
.status(StatusCode::BAD_GATEWAY)
|
||||
.body(Body::from(format!("Upstream error: {}", e)))
|
||||
@ -175,12 +173,12 @@ pub async fn start_server(
|
||||
|
||||
// Create and start the server
|
||||
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
|
||||
let server_handle = tokio::spawn(async move {
|
||||
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>);
|
||||
}
|
||||
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() {
|
||||
handle.abort();
|
||||
info!("Proxy server stopped");
|
||||
log::info!("Proxy server stopped");
|
||||
} else {
|
||||
debug!("No server was running");
|
||||
log::debug!("No server was running");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
@ -11,6 +11,7 @@ use tauri_plugin_shell::process::CommandEvent;
|
||||
use tauri_plugin_shell::ShellExt;
|
||||
use tauri_plugin_store::StoreExt;
|
||||
|
||||
// MCP
|
||||
use super::{
|
||||
cmd::{get_jan_data_folder_path, get_jan_extensions_path},
|
||||
mcp::run_mcp_commands,
|
||||
@ -39,7 +40,7 @@ pub fn install_extensions(app: tauri::AppHandle, force: bool) -> Result<(), Stri
|
||||
// Attempt to remove extensions folder
|
||||
if extensions_path.exists() {
|
||||
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();
|
||||
|
||||
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 gz_decoder = GzDecoder::new(tar_gz);
|
||||
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);
|
||||
|
||||
println!("Installed extension to {:?}", extension_dir);
|
||||
log::info!("Installed extension to {:?}", extension_dir);
|
||||
}
|
||||
}
|
||||
fs::write(
|
||||
@ -186,7 +187,7 @@ pub fn setup_mcp(app: &App) {
|
||||
let servers = state.mcp_servers.clone();
|
||||
tauri::async_runtime::spawn(async move {
|
||||
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 {
|
||||
if let CommandEvent::Stdout(line_bytes) = event {
|
||||
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> {
|
||||
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())? {
|
||||
let entry = entry.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");
|
||||
|
||||
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()) {
|
||||
eprintln!("Failed to copy themes: {}", e);
|
||||
log::error!("Failed to copy themes: {}", e);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
mod core;
|
||||
use core::{
|
||||
cmd::get_jan_data_folder_path,
|
||||
setup::{self, setup_engine_binaries, setup_mcp, setup_sidecar},
|
||||
state::{generate_app_token, AppState},
|
||||
};
|
||||
@ -11,8 +12,8 @@ use tokio::sync::Mutex;
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
pub fn run() {
|
||||
tauri::Builder::default()
|
||||
.plugin(tauri_plugin_store::Builder::new().build())
|
||||
.plugin(tauri_plugin_http::init())
|
||||
.plugin(tauri_plugin_store::Builder::new().build())
|
||||
.plugin(tauri_plugin_shell::init())
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
// FS commands - Deperecate soon
|
||||
@ -47,25 +48,26 @@ pub fn run() {
|
||||
mcp_servers: Arc::new(Mutex::new(HashMap::new())),
|
||||
})
|
||||
.setup(|app| {
|
||||
if cfg!(debug_assertions) {
|
||||
app.handle().plugin(
|
||||
tauri_plugin_log::Builder::default()
|
||||
.level(log::LevelFilter::Info)
|
||||
.build(),
|
||||
)?;
|
||||
}
|
||||
|
||||
app.handle().plugin(
|
||||
tauri_plugin_log::Builder::default()
|
||||
.targets([
|
||||
tauri_plugin_log::Target::new(tauri_plugin_log::TargetKind::Folder {
|
||||
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
|
||||
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_sidecar(app).expect("Failed to setup sidecar");
|
||||
|
||||
setup_engine_binaries(app).expect("Failed to setup engine binaries");
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.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",
|
||||
"version": "0.1.0",
|
||||
"identifier": "jan.ai",
|
||||
"build": {
|
||||
"frontendDist": "../web/out",
|
||||
"devUrl": "http://localhost:3000",
|
||||
"beforeDevCommand": "yarn dev:web:tauri",
|
||||
"beforeBuildCommand": "yarn build:web"
|
||||
"beforeDevCommand": "IS_TAURI=true yarn dev:web",
|
||||
"beforeBuildCommand": "IS_TAURI=true yarn build:web"
|
||||
},
|
||||
"app": {
|
||||
"macOSPrivateApi": true,
|
||||
@ -27,9 +27,10 @@
|
||||
"csp": {
|
||||
"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",
|
||||
"font-src": ["https://fonts.gstatic.com"],
|
||||
"font-src": ["https://fonts.gstatic.com 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": {
|
||||
"enable": true,
|
||||
|
||||
@ -22,7 +22,8 @@ export const useLoadTheme = () => {
|
||||
|
||||
const setNativeTheme = useCallback(
|
||||
(nativeTheme: NativeThemeProps) => {
|
||||
if (!('setNativeThemeDark' in window.core.api)) return
|
||||
if (!window.electronAPI) return
|
||||
|
||||
if (nativeTheme === 'dark') {
|
||||
window?.core?.api?.setNativeThemeDark()
|
||||
setTheme('dark')
|
||||
@ -58,21 +59,20 @@ export const useLoadTheme = () => {
|
||||
setThemeOptions(themesOptions)
|
||||
|
||||
if (!selectedIdTheme.length) return setSelectedIdTheme('joi-light')
|
||||
|
||||
const theme: Theme = JSON.parse(
|
||||
await window.core.api.readTheme({
|
||||
theme: selectedIdTheme,
|
||||
themeName: selectedIdTheme,
|
||||
})
|
||||
)
|
||||
|
||||
setThemeData(theme)
|
||||
setNativeTheme(theme.nativeTheme)
|
||||
applyTheme(theme)
|
||||
}, [])
|
||||
}, [selectedIdTheme])
|
||||
|
||||
const configureTheme = useCallback(async () => {
|
||||
if (!themeData || !themeOptions) {
|
||||
await getThemes()
|
||||
getThemes()
|
||||
} else {
|
||||
applyTheme(themeData)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user