mirror of
https://wget.la/https://github.com/leookun/cursor-byok
synced 2026-10-08 07:21:13 +08:00
feat: enhance desktop application startup diagnostics and logging
- Introduced a new `startup` module to capture and manage startup diagnostics. - Implemented logging functionality with daily rotation and error reporting for application startup failures. - Updated the main application run function to return an exit code based on startup success or failure. - Added new dependencies for logging and diagnostics in `Cargo.toml`. - Increased request timeout in the control service for improved stability. - Expanded maximum search results in the federation module for better search capabilities.
This commit is contained in:
Generated
+114
@@ -97,6 +97,28 @@ dependencies = [
|
|||||||
"x11rb",
|
"x11rb",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ashpd"
|
||||||
|
version = "0.11.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d2f3f79755c74fd155000314eb349864caa787c6592eace6c6882dad873d9c39"
|
||||||
|
dependencies = [
|
||||||
|
"async-fs",
|
||||||
|
"async-net",
|
||||||
|
"enumflags2",
|
||||||
|
"futures-channel",
|
||||||
|
"futures-util",
|
||||||
|
"rand 0.9.5",
|
||||||
|
"raw-window-handle",
|
||||||
|
"serde",
|
||||||
|
"serde_repr",
|
||||||
|
"url",
|
||||||
|
"wayland-backend",
|
||||||
|
"wayland-client",
|
||||||
|
"wayland-protocols",
|
||||||
|
"zbus",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "asn1-rs"
|
name = "asn1-rs"
|
||||||
version = "0.7.2"
|
version = "0.7.2"
|
||||||
@@ -186,6 +208,17 @@ dependencies = [
|
|||||||
"slab",
|
"slab",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-fs"
|
||||||
|
version = "2.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8034a681df4aed8b8edbd7fbe472401ecf009251c8b40556b304567052e294c5"
|
||||||
|
dependencies = [
|
||||||
|
"async-lock",
|
||||||
|
"blocking",
|
||||||
|
"futures-lite",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-io"
|
name = "async-io"
|
||||||
version = "2.6.0"
|
version = "2.6.0"
|
||||||
@@ -215,6 +248,17 @@ dependencies = [
|
|||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-net"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7"
|
||||||
|
dependencies = [
|
||||||
|
"async-io",
|
||||||
|
"blocking",
|
||||||
|
"futures-lite",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-process"
|
name = "async-process"
|
||||||
version = "2.5.0"
|
version = "2.5.0"
|
||||||
@@ -1132,6 +1176,7 @@ version = "0.1.5-beta.1"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"axum",
|
"axum",
|
||||||
"cursor-server",
|
"cursor-server",
|
||||||
|
"rfd",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tauri",
|
"tauri",
|
||||||
@@ -1145,6 +1190,7 @@ dependencies = [
|
|||||||
"tokio",
|
"tokio",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
"tracing-appender",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
@@ -1520,6 +1566,15 @@ dependencies = [
|
|||||||
"syn 3.0.3",
|
"syn 3.0.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dlib"
|
||||||
|
version = "0.5.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ab8ecd87370524b461f8557c119c405552c396ed91fc0a8eec68679eab26f94a"
|
||||||
|
dependencies = [
|
||||||
|
"libloading",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dlopen2"
|
name = "dlopen2"
|
||||||
version = "0.8.2"
|
version = "0.8.2"
|
||||||
@@ -4555,6 +4610,12 @@ dependencies = [
|
|||||||
"windows-sys 0.61.2",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pollster"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "portable-atomic"
|
name = "portable-atomic"
|
||||||
version = "1.15.0"
|
version = "1.15.0"
|
||||||
@@ -5196,6 +5257,30 @@ dependencies = [
|
|||||||
"web-sys",
|
"web-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rfd"
|
||||||
|
version = "0.15.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ef2bee61e6cffa4635c72d7d81a84294e28f0930db0ddcb0f66d10244674ebed"
|
||||||
|
dependencies = [
|
||||||
|
"ashpd",
|
||||||
|
"block2",
|
||||||
|
"dispatch2",
|
||||||
|
"js-sys",
|
||||||
|
"log",
|
||||||
|
"objc2",
|
||||||
|
"objc2-app-kit",
|
||||||
|
"objc2-core-foundation",
|
||||||
|
"objc2-foundation",
|
||||||
|
"pollster",
|
||||||
|
"raw-window-handle",
|
||||||
|
"urlencoding",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"wasm-bindgen-futures",
|
||||||
|
"web-sys",
|
||||||
|
"windows-sys 0.59.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ring"
|
name = "ring"
|
||||||
version = "0.17.14"
|
version = "0.17.14"
|
||||||
@@ -6289,6 +6374,12 @@ dependencies = [
|
|||||||
"serde_json",
|
"serde_json",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "symlink"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a7973cce6668464ea31f176d85b13c7ab3bba2cb3b77a2ed26abd7801688010a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.109"
|
version = "1.0.109"
|
||||||
@@ -7262,6 +7353,19 @@ dependencies = [
|
|||||||
"tracing-core",
|
"tracing-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-appender"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "050686193eb999b4bb3bc2acfa891a13da00f79734704c4b8b4ef1a10b368a3c"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-channel",
|
||||||
|
"symlink",
|
||||||
|
"thiserror 2.0.20",
|
||||||
|
"time",
|
||||||
|
"tracing-subscriber",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-attributes"
|
name = "tracing-attributes"
|
||||||
version = "0.1.31"
|
version = "0.1.31"
|
||||||
@@ -7636,6 +7740,12 @@ dependencies = [
|
|||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "urlencoding"
|
||||||
|
version = "2.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "urlpattern"
|
name = "urlpattern"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
@@ -7852,6 +7962,7 @@ dependencies = [
|
|||||||
"cc",
|
"cc",
|
||||||
"downcast-rs",
|
"downcast-rs",
|
||||||
"rustix",
|
"rustix",
|
||||||
|
"scoped-tls",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"wayland-sys",
|
"wayland-sys",
|
||||||
]
|
]
|
||||||
@@ -7910,6 +8021,8 @@ version = "0.31.11"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d8eab23fefc9e41f8e841df4a9c707e8a8c4ed26e944ef69297184de2785e3be"
|
checksum = "d8eab23fefc9e41f8e841df4a9c707e8a8c4ed26e944ef69297184de2785e3be"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"dlib",
|
||||||
|
"log",
|
||||||
"pkg-config",
|
"pkg-config",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -9028,6 +9141,7 @@ dependencies = [
|
|||||||
"endi",
|
"endi",
|
||||||
"enumflags2",
|
"enumflags2",
|
||||||
"serde",
|
"serde",
|
||||||
|
"url",
|
||||||
"winnow 1.0.4",
|
"winnow 1.0.4",
|
||||||
"zcheapstr",
|
"zcheapstr",
|
||||||
"zvariant_derive",
|
"zvariant_derive",
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ tauri-build = { version = "2", features = [] }
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
axum = "0.8"
|
axum = "0.8"
|
||||||
cursor-server = { path = "../../../server" }
|
cursor-server = { path = "../../../server" }
|
||||||
|
rfd = "0.15"
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
tauri = { version = "2", features = ["tray-icon"] }
|
tauri = { version = "2", features = ["tray-icon"] }
|
||||||
@@ -26,5 +27,6 @@ tauri-plugin-updater = "2"
|
|||||||
tokio = { version = "1", features = ["time"] }
|
tokio = { version = "1", features = ["time"] }
|
||||||
tokio-util = "0.7"
|
tokio-util = "0.7"
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
|
tracing-appender = "0.2"
|
||||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||||
url = "2"
|
url = "2"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use std::{
|
use std::{
|
||||||
process::Command,
|
process::{Command, ExitCode},
|
||||||
sync::{
|
sync::{
|
||||||
atomic::{AtomicBool, Ordering},
|
atomic::{AtomicBool, Ordering},
|
||||||
Mutex,
|
Mutex,
|
||||||
@@ -19,7 +19,6 @@ use tauri::{
|
|||||||
};
|
};
|
||||||
use tauri_plugin_opener::OpenerExt;
|
use tauri_plugin_opener::OpenerExt;
|
||||||
use tokio_util::sync::CancellationToken;
|
use tokio_util::sync::CancellationToken;
|
||||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
|
||||||
|
|
||||||
#[cfg(dev)]
|
#[cfg(dev)]
|
||||||
use cursor_server::config::ConsoleSource;
|
use cursor_server::config::ConsoleSource;
|
||||||
@@ -27,6 +26,7 @@ use cursor_server::{App, Config, Result};
|
|||||||
|
|
||||||
#[cfg(not(dev))]
|
#[cfg(not(dev))]
|
||||||
use crate::frontend;
|
use crate::frontend;
|
||||||
|
use crate::startup::{self, StartupDiagnostics};
|
||||||
use crate::tray;
|
use crate::tray;
|
||||||
|
|
||||||
pub(crate) const MAIN_WINDOW_LABEL: &str = "main";
|
pub(crate) const MAIN_WINDOW_LABEL: &str = "main";
|
||||||
@@ -141,16 +141,23 @@ fn create_main_window(
|
|||||||
builder.build()
|
builder.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run() {
|
pub fn run() -> ExitCode {
|
||||||
let started_by_autostart = std::env::args_os().any(|arg| arg == AUTOSTART_ARG);
|
let diagnostics = match StartupDiagnostics::initialize() {
|
||||||
|
Ok(diagnostics) => diagnostics,
|
||||||
|
Err(error) => {
|
||||||
|
startup::report_logging_failure(error.as_ref());
|
||||||
|
return ExitCode::FAILURE;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
tracing::info!(
|
||||||
|
version = env!("CARGO_PKG_VERSION"),
|
||||||
|
os = std::env::consts::OS,
|
||||||
|
architecture = std::env::consts::ARCH,
|
||||||
|
log_directory = %diagnostics.log_directory().display(),
|
||||||
|
"desktop starting"
|
||||||
|
);
|
||||||
|
|
||||||
tracing_subscriber::registry()
|
let started_by_autostart = std::env::args_os().any(|arg| arg == AUTOSTART_ARG);
|
||||||
.with(
|
|
||||||
tracing_subscriber::EnvFilter::try_from_default_env()
|
|
||||||
.unwrap_or_else(|_| "cursor_server=info".into()),
|
|
||||||
)
|
|
||||||
.with(tracing_subscriber::fmt::layer())
|
|
||||||
.init();
|
|
||||||
|
|
||||||
let app = tauri::Builder::default()
|
let app = tauri::Builder::default()
|
||||||
.invoke_handler(tauri::generate_handler![open_terminal_with_command])
|
.invoke_handler(tauri::generate_handler![open_terminal_with_command])
|
||||||
@@ -218,8 +225,14 @@ pub fn run() {
|
|||||||
tray::create(app)?;
|
tray::create(app)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
.build(tauri::generate_context!())
|
.build(tauri::generate_context!());
|
||||||
.expect("failed to build Cursor BYOK desktop app");
|
let app = match app {
|
||||||
|
Ok(app) => app,
|
||||||
|
Err(error) => {
|
||||||
|
diagnostics.report_fatal(&error);
|
||||||
|
return ExitCode::FAILURE;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
app.run(|app, event| match event {
|
app.run(|app, event| match event {
|
||||||
RunEvent::WindowEvent {
|
RunEvent::WindowEvent {
|
||||||
@@ -264,4 +277,6 @@ pub fn run() {
|
|||||||
} => tray::show_main_window(app),
|
} => tray::show_main_window(app),
|
||||||
_ => {}
|
_ => {}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ExitCode::SUCCESS
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
mod desktop;
|
mod desktop;
|
||||||
#[cfg(not(dev))]
|
#[cfg(not(dev))]
|
||||||
mod frontend;
|
mod frontend;
|
||||||
|
mod startup;
|
||||||
mod tray;
|
mod tray;
|
||||||
|
|
||||||
pub use desktop::run;
|
pub use desktop::run;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||||
|
|
||||||
fn main() {
|
fn main() -> std::process::ExitCode {
|
||||||
cursor_byok_desktop::run();
|
cursor_byok_desktop::run()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,139 @@
|
|||||||
|
//! Captures startup diagnostics before the database and desktop runtime initialize.
|
||||||
|
use std::{error::Error, path::PathBuf};
|
||||||
|
|
||||||
|
use rfd::{MessageButtons, MessageDialog, MessageLevel};
|
||||||
|
use tracing_appender::{
|
||||||
|
non_blocking::WorkerGuard,
|
||||||
|
rolling::{RollingFileAppender, Rotation},
|
||||||
|
};
|
||||||
|
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||||
|
|
||||||
|
const LOG_DIRECTORY_NAME: &str = "logs";
|
||||||
|
const LOG_FILE_PREFIX: &str = "cursor-byok";
|
||||||
|
const LOG_FILE_SUFFIX: &str = "log";
|
||||||
|
const RETAINED_LOG_FILES: usize = 15;
|
||||||
|
|
||||||
|
type BoxError = Box<dyn Error + Send + Sync>;
|
||||||
|
|
||||||
|
pub(crate) struct StartupDiagnostics {
|
||||||
|
log_directory: PathBuf,
|
||||||
|
_writer_guard: WorkerGuard,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StartupDiagnostics {
|
||||||
|
pub(crate) fn initialize() -> Result<Self, BoxError> {
|
||||||
|
let log_directory = cursor_server::config::managed_data_dir()?.join(LOG_DIRECTORY_NAME);
|
||||||
|
std::fs::create_dir_all(&log_directory)?;
|
||||||
|
|
||||||
|
let file_appender = RollingFileAppender::builder()
|
||||||
|
.rotation(Rotation::DAILY)
|
||||||
|
.filename_prefix(LOG_FILE_PREFIX)
|
||||||
|
.filename_suffix(LOG_FILE_SUFFIX)
|
||||||
|
.max_log_files(RETAINED_LOG_FILES)
|
||||||
|
.build(&log_directory)?;
|
||||||
|
let (file_writer, writer_guard) = tracing_appender::non_blocking(file_appender);
|
||||||
|
let filter = tracing_subscriber::EnvFilter::try_from_default_env()
|
||||||
|
.unwrap_or_else(|_| "cursor_byok_desktop=info,cursor_server=info".into());
|
||||||
|
|
||||||
|
tracing_subscriber::registry()
|
||||||
|
.with(filter)
|
||||||
|
.with(tracing_subscriber::fmt::layer())
|
||||||
|
.with(
|
||||||
|
tracing_subscriber::fmt::layer()
|
||||||
|
.with_ansi(false)
|
||||||
|
.with_writer(file_writer),
|
||||||
|
)
|
||||||
|
.try_init()?;
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
log_directory,
|
||||||
|
_writer_guard: writer_guard,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn log_directory(&self) -> &std::path::Path {
|
||||||
|
&self.log_directory
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn report_fatal(&self, error: &(dyn Error + 'static)) {
|
||||||
|
let details = error_chain(error);
|
||||||
|
tracing::error!(
|
||||||
|
error = %details,
|
||||||
|
log_directory = %self.log_directory.display(),
|
||||||
|
"desktop failed to start"
|
||||||
|
);
|
||||||
|
show_fatal_dialog(&details, Some(&self.log_directory));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn report_logging_failure(error: &(dyn Error + 'static)) {
|
||||||
|
let details = error_chain(error);
|
||||||
|
eprintln!("Cursor BYOK failed to initialize logging: {details}");
|
||||||
|
show_fatal_dialog(&details, None);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn show_fatal_dialog(details: &str, log_directory: Option<&std::path::Path>) {
|
||||||
|
let log_guidance = match log_directory {
|
||||||
|
Some(directory) => format!(
|
||||||
|
"日志目录 / Log directory:\n{}\n\n请将最新的日志文件发送给开发者。\nPlease send the latest log file to the developer.",
|
||||||
|
directory.display()
|
||||||
|
),
|
||||||
|
None => "日志系统也未能启动,因此没有生成日志文件。\nLogging also failed to initialize, so no log file was created."
|
||||||
|
.to_owned(),
|
||||||
|
};
|
||||||
|
let description = format!(
|
||||||
|
"Cursor BYOK 无法启动 / failed to start.\n\n错误 / Error:\n{details}\n\n{log_guidance}"
|
||||||
|
);
|
||||||
|
|
||||||
|
let _ = MessageDialog::new()
|
||||||
|
.set_level(MessageLevel::Error)
|
||||||
|
.set_title("Cursor BYOK 启动失败 / Startup Error")
|
||||||
|
.set_description(description)
|
||||||
|
.set_buttons(MessageButtons::Ok)
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn error_chain(error: &(dyn Error + 'static)) -> String {
|
||||||
|
let mut details = error.to_string();
|
||||||
|
let mut source = error.source();
|
||||||
|
while let Some(cause) = source {
|
||||||
|
details.push_str("\nCaused by: ");
|
||||||
|
details.push_str(&cause.to_string());
|
||||||
|
source = cause.source();
|
||||||
|
}
|
||||||
|
details
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct OuterError(std::io::Error);
|
||||||
|
|
||||||
|
impl fmt::Display for OuterError {
|
||||||
|
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
formatter.write_str("database initialization failed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Error for OuterError {
|
||||||
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
|
Some(&self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn fatal_report_includes_the_complete_error_chain() {
|
||||||
|
let error = OuterError(std::io::Error::new(
|
||||||
|
std::io::ErrorKind::PermissionDenied,
|
||||||
|
"database file is read-only",
|
||||||
|
));
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
error_chain(&error),
|
||||||
|
"database initialization failed\nCaused by: database file is read-only"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,7 +12,11 @@ if (!existsSync(vite)) run(['ci'], desktopRoot);
|
|||||||
run(['run', 'build:demo'], desktopRoot);
|
run(['run', 'build:demo'], desktopRoot);
|
||||||
|
|
||||||
function run(args, cwd) {
|
function run(args, cwd) {
|
||||||
const result = spawnSync(npm, args, { cwd, stdio: 'inherit' });
|
const result = spawnSync(npm, args, {
|
||||||
|
cwd,
|
||||||
|
stdio: 'inherit',
|
||||||
|
shell: process.platform === 'win32',
|
||||||
|
});
|
||||||
if (result.error) throw result.error;
|
if (result.error) throw result.error;
|
||||||
if (result.status !== 0) process.exit(result.status ?? 1);
|
if (result.status !== 0) process.exit(result.status ?? 1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
<!-- Defines stable Cursor prompt content embedded by the server. -->
|
|
||||||
You are an AI coding assistant, powered by {{FAKE_MODEL_NAME}}. You operate in Cursor.
|
You are an AI coding assistant, powered by {{FAKE_MODEL_NAME}}. You operate in Cursor.
|
||||||
|
|
||||||
Your main goal is to follow the USER's instructions, which are denoted by the <user_query> tag.
|
Your main goal is to follow the USER's instructions, which are denoted by the <user_query> tag.
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
<!-- Defines stable Cursor prompt content embedded by the server. -->
|
|
||||||
{{OPEN_FILES}}{{SELECTED_CONTEXT}}{{ACTION_CONTEXT}}<system_reminder>
|
{{OPEN_FILES}}{{SELECTED_CONTEXT}}{{ACTION_CONTEXT}}<system_reminder>
|
||||||
You are now in Agent mode. You have EXITED your previous mode. Continue with the task in the new mode.
|
You are now in Agent mode. You have EXITED your previous mode. Continue with the task in the new mode.
|
||||||
</system_reminder>
|
</system_reminder>
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
<!-- Defines stable Cursor prompt content embedded by the server. -->
|
|
||||||
You are an AI coding assistant, powered by {{FAKE_MODEL_NAME}}. You operate in Cursor.
|
You are an AI coding assistant, powered by {{FAKE_MODEL_NAME}}. You operate in Cursor.
|
||||||
|
|
||||||
Your main goal is to follow the USER's instructions, which are denoted by the <user_query> tag.
|
Your main goal is to follow the USER's instructions, which are denoted by the <user_query> tag.
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
<!-- Defines stable Cursor prompt content embedded by the server. -->
|
|
||||||
{{OPEN_FILES}}{{SELECTED_CONTEXT}}{{ACTION_CONTEXT}}<system_reminder>
|
{{OPEN_FILES}}{{SELECTED_CONTEXT}}{{ACTION_CONTEXT}}<system_reminder>
|
||||||
You are now in Ask mode. You have EXITED your previous mode. Continue with the task in the new mode.
|
You are now in Ask mode. You have EXITED your previous mode. Continue with the task in the new mode.
|
||||||
</system_reminder>
|
</system_reminder>
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
<!-- Defines stable Cursor prompt content embedded by the server. -->
|
|
||||||
You are compacting conversation history for future model turns.
|
You are compacting conversation history for future model turns.
|
||||||
Produce a concise plain-text summary that preserves durable context: user goals, constraints, facts, decisions, files, commands, errors, tool outcomes, and pending follow-ups.
|
Produce a concise plain-text summary that preserves durable context: user goals, constraints, facts, decisions, files, commands, errors, tool outcomes, and pending follow-ups.
|
||||||
Do not address the user. Do not mention compaction, summarization, or token limits.
|
Do not address the user. Do not mention compaction, summarization, or token limits.
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
<!-- Defines stable Cursor prompt content embedded by the server. -->
|
|
||||||
{{OPEN_FILES}}{{SELECTED_CONTEXT}}{{ACTION_CONTEXT}}<timestamp>{{TIMESTAMP}}</timestamp>
|
{{OPEN_FILES}}{{SELECTED_CONTEXT}}{{ACTION_CONTEXT}}<timestamp>{{TIMESTAMP}}</timestamp>
|
||||||
<user_query>
|
<user_query>
|
||||||
{{USER_QUERY}}
|
{{USER_QUERY}}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
<!-- Defines stable Cursor prompt content embedded by the server. -->
|
|
||||||
You are an AI coding assistant, powered by {{FAKE_MODEL_NAME}}. You operate in Cursor.
|
You are an AI coding assistant, powered by {{FAKE_MODEL_NAME}}. You operate in Cursor.
|
||||||
|
|
||||||
Your main goal is to follow the USER's instructions, which are denoted by the <user_query> tag.
|
Your main goal is to follow the USER's instructions, which are denoted by the <user_query> tag.
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
<!-- Defines stable Cursor prompt content embedded by the server. -->
|
|
||||||
{{OPEN_FILES}}{{SELECTED_CONTEXT}}{{ACTION_CONTEXT}}<system_reminder>
|
{{OPEN_FILES}}{{SELECTED_CONTEXT}}{{ACTION_CONTEXT}}<system_reminder>
|
||||||
You are now in Debug mode. You have EXITED your previous mode. Continue with the task in the new mode.
|
You are now in Debug mode. You have EXITED your previous mode. Continue with the task in the new mode.
|
||||||
</system_reminder>
|
</system_reminder>
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
<!-- Defines stable Cursor prompt content embedded by the server. -->
|
|
||||||
You are an AI coding assistant, powered by Cursor {{FAKE_MODEL_NAME}}. You operate in Cursor.
|
You are an AI coding assistant, powered by Cursor {{FAKE_MODEL_NAME}}. You operate in Cursor.
|
||||||
|
|
||||||
Your main goal is to follow the USER's instructions, which are denoted by the <user_query> tag.
|
Your main goal is to follow the USER's instructions, which are denoted by the <user_query> tag.
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
<!-- Defines stable Cursor prompt content embedded by the server. -->
|
|
||||||
{{OPEN_FILES}}{{SELECTED_CONTEXT}}{{ACTION_CONTEXT}}<system_reminder>
|
{{OPEN_FILES}}{{SELECTED_CONTEXT}}{{ACTION_CONTEXT}}<system_reminder>
|
||||||
You are now in Multitask mode. You have EXITED your previous mode. Continue with the task in the new mode.
|
You are now in Multitask mode. You have EXITED your previous mode. Continue with the task in the new mode.
|
||||||
</system_reminder>
|
</system_reminder>
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
<!-- Defines stable Cursor prompt content embedded by the server. -->
|
|
||||||
You are an AI coding assistant, powered by {{FAKE_MODEL_NAME}}. You operate in Cursor.
|
You are an AI coding assistant, powered by {{FAKE_MODEL_NAME}}. You operate in Cursor.
|
||||||
|
|
||||||
Your main goal is to follow the USER's instructions, which are denoted by the <user_query> tag.
|
Your main goal is to follow the USER's instructions, which are denoted by the <user_query> tag.
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
<!-- Defines stable Cursor prompt content embedded by the server. -->
|
|
||||||
{{OPEN_FILES}}{{SELECTED_CONTEXT}}{{ACTION_CONTEXT}}<system_reminder>
|
{{OPEN_FILES}}{{SELECTED_CONTEXT}}{{ACTION_CONTEXT}}<system_reminder>
|
||||||
You are now in Plan mode. You have EXITED your previous mode. Continue with the task in the new mode.
|
You are now in Plan mode. You have EXITED your previous mode. Continue with the task in the new mode.
|
||||||
</system_reminder>
|
</system_reminder>
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
<!-- Defines stable Cursor prompt content embedded by the server. -->
|
|
||||||
You are an AI coding assistant, powered by {{FAKE_MODEL_NAME}}. You operate in Cursor.
|
You are an AI coding assistant, powered by {{FAKE_MODEL_NAME}}. You operate in Cursor.
|
||||||
|
|
||||||
Your main goal is to follow the USER's instructions, which are denoted by the <user_query> tag.
|
Your main goal is to follow the USER's instructions, which are denoted by the <user_query> tag.
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
<!-- Defines stable Cursor prompt content embedded by the server. -->
|
|
||||||
{{OPEN_FILES}}{{SELECTED_CONTEXT}}{{ACTION_CONTEXT}}<system_reminder>
|
{{OPEN_FILES}}{{SELECTED_CONTEXT}}{{ACTION_CONTEXT}}<system_reminder>
|
||||||
You are currently working inside a Task subagent. Your parent agent has delegated a clearly bounded assignment to you. Complete that assignment directly with the tools available in this session. The Task tool is unavailable inside subagents, so delegation cannot be nested.
|
You are currently working inside a Task subagent. Your parent agent has delegated a clearly bounded assignment to you. Complete that assignment directly with the tools available in this session. The Task tool is unavailable inside subagents, so delegation cannot be nested.
|
||||||
</system_reminder>
|
</system_reminder>
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ impl ControlService {
|
|||||||
.header(OS_HEADER, std::env::consts::OS)
|
.header(OS_HEADER, std::env::consts::OS)
|
||||||
.header(APP_VERSION_HEADER, env!("CARGO_PKG_VERSION"))
|
.header(APP_VERSION_HEADER, env!("CARGO_PKG_VERSION"))
|
||||||
.header(LANGUAGE_HEADER, language)
|
.header(LANGUAGE_HEADER, language)
|
||||||
.timeout(std::time::Duration::from_secs(5));
|
.timeout(std::time::Duration::from_secs(60));
|
||||||
if let Some(disabled_ad_ids) = disabled_ad_ids.filter(|value| !value.is_empty()) {
|
if let Some(disabled_ad_ids) = disabled_ad_ids.filter(|value| !value.is_empty()) {
|
||||||
request = request.header(DISABLED_AD_IDS_HEADER, disabled_ad_ids);
|
request = request.header(DISABLED_AD_IDS_HEADER, disabled_ad_ids);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use crate::store::Store;
|
|||||||
use super::{catalog, SearchEngine, SearchHit};
|
use super::{catalog, SearchEngine, SearchHit};
|
||||||
|
|
||||||
const RRF_K: f64 = 60.0;
|
const RRF_K: f64 = 60.0;
|
||||||
const MAX_RESULTS: usize = 10;
|
const MAX_RESULTS: usize = 30;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct WebSearch {
|
pub struct WebSearch {
|
||||||
|
|||||||
@@ -28,7 +28,9 @@ impl Store {
|
|||||||
.max_connections(8)
|
.max_connections(8)
|
||||||
.connect_with(options)
|
.connect_with(options)
|
||||||
.await?;
|
.await?;
|
||||||
|
tracing::info!("running database migrations");
|
||||||
sqlx::migrate!("./migrations").run(&pool).await?;
|
sqlx::migrate!("./migrations").run(&pool).await?;
|
||||||
|
tracing::info!("database migrations completed");
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
pool,
|
pool,
|
||||||
writes: WriteCoordinator::default(),
|
writes: WriteCoordinator::default(),
|
||||||
|
|||||||
Reference in New Issue
Block a user