fix: resolve codacy high severity findings
This commit is contained in:
14
.github/workflows/ci.yml
vendored
14
.github/workflows/ci.yml
vendored
@@ -28,7 +28,7 @@ jobs:
|
||||
fetch-depth: 0 # Full history for CodeScene
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa
|
||||
with:
|
||||
version: 10
|
||||
|
||||
@@ -65,7 +65,7 @@ jobs:
|
||||
|
||||
- name: Upload frontend coverage to Codecov
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
|
||||
uses: codecov/codecov-action@v5
|
||||
uses: codecov/codecov-action@75cd11691c0faa626561e295848008c8a7dddffe
|
||||
with:
|
||||
use_oidc: true
|
||||
fail_ci_if_error: true
|
||||
@@ -143,7 +143,7 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8
|
||||
with:
|
||||
components: rustfmt, clippy, llvm-tools-preview
|
||||
|
||||
@@ -159,7 +159,7 @@ jobs:
|
||||
${{ runner.os }}-cargo-${{ env.RUST_TARGET_CACHE_VERSION }}-
|
||||
|
||||
- name: Install cargo-llvm-cov
|
||||
uses: taiki-e/install-action@cargo-llvm-cov
|
||||
uses: taiki-e/install-action@e5de28abeb52d916c5e5875d54b21a9e738b61ec
|
||||
|
||||
- name: Rust tests + coverage (≥85% lines)
|
||||
run: |
|
||||
@@ -175,7 +175,7 @@ jobs:
|
||||
|
||||
- name: Upload Rust coverage to Codecov
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
|
||||
uses: codecov/codecov-action@v5
|
||||
uses: codecov/codecov-action@75cd11691c0faa626561e295848008c8a7dddffe
|
||||
with:
|
||||
use_oidc: true
|
||||
fail_ci_if_error: true
|
||||
@@ -213,7 +213,7 @@ jobs:
|
||||
file
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa
|
||||
with:
|
||||
version: 10
|
||||
|
||||
@@ -224,7 +224,7 @@ jobs:
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Setup Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8
|
||||
with:
|
||||
components: clippy
|
||||
|
||||
|
||||
4
.github/workflows/deploy-docs.yml
vendored
4
.github/workflows/deploy-docs.yml
vendored
@@ -33,7 +33,7 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa
|
||||
with:
|
||||
version: 10
|
||||
|
||||
@@ -44,7 +44,7 @@ jobs:
|
||||
cache: pnpm
|
||||
|
||||
- name: Setup Bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6
|
||||
with:
|
||||
bun-version: latest
|
||||
|
||||
|
||||
22
.github/workflows/release-stable.yml
vendored
22
.github/workflows/release-stable.yml
vendored
@@ -82,7 +82,7 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa
|
||||
with:
|
||||
version: 10
|
||||
|
||||
@@ -93,12 +93,12 @@ jobs:
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Setup Bun (required for bundle-qmd.sh)
|
||||
uses: oven-sh/setup-bun@v2
|
||||
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6
|
||||
with:
|
||||
bun-version: latest
|
||||
|
||||
- name: Setup Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8
|
||||
with:
|
||||
targets: ${{ matrix.target }}
|
||||
|
||||
@@ -292,7 +292,7 @@ jobs:
|
||||
rpm
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa
|
||||
with:
|
||||
version: 10
|
||||
|
||||
@@ -303,7 +303,7 @@ jobs:
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Setup Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8
|
||||
with:
|
||||
targets: x86_64-unknown-linux-gnu
|
||||
|
||||
@@ -389,7 +389,7 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa
|
||||
with:
|
||||
version: 10
|
||||
|
||||
@@ -400,7 +400,7 @@ jobs:
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Setup Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8
|
||||
with:
|
||||
targets: x86_64-pc-windows-msvc
|
||||
|
||||
@@ -682,7 +682,7 @@ jobs:
|
||||
echo "stable-latest.json:"; cat stable-latest.json
|
||||
|
||||
- name: Publish GitHub Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65
|
||||
with:
|
||||
tag_name: ${{ needs.version.outputs.tag }}
|
||||
name: Tolaria ${{ needs.version.outputs.display_version }}
|
||||
@@ -740,7 +740,7 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa
|
||||
with:
|
||||
version: 10
|
||||
|
||||
@@ -751,7 +751,7 @@ jobs:
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Setup Bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6
|
||||
with:
|
||||
bun-version: latest
|
||||
|
||||
@@ -780,7 +780,7 @@ jobs:
|
||||
cp _site/alpha/latest.json _site/latest-canary.json
|
||||
|
||||
- name: Deploy to GitHub Pages
|
||||
uses: peaceiris/actions-gh-pages@v4
|
||||
uses: peaceiris/actions-gh-pages@e9c66a37f080288a11235e32cbe2dc5fb3a679cc
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
publish_dir: ./_site
|
||||
|
||||
22
.github/workflows/release.yml
vendored
22
.github/workflows/release.yml
vendored
@@ -143,7 +143,7 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa
|
||||
with:
|
||||
version: 10
|
||||
|
||||
@@ -154,12 +154,12 @@ jobs:
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Setup Bun (required for bundle-qmd.sh)
|
||||
uses: oven-sh/setup-bun@v2
|
||||
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6
|
||||
with:
|
||||
bun-version: latest
|
||||
|
||||
- name: Setup Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8
|
||||
with:
|
||||
targets: ${{ matrix.target }}
|
||||
|
||||
@@ -348,7 +348,7 @@ jobs:
|
||||
rpm
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa
|
||||
with:
|
||||
version: 10
|
||||
|
||||
@@ -359,7 +359,7 @@ jobs:
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Setup Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8
|
||||
with:
|
||||
targets: x86_64-unknown-linux-gnu
|
||||
|
||||
@@ -445,7 +445,7 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa
|
||||
with:
|
||||
version: 10
|
||||
|
||||
@@ -456,7 +456,7 @@ jobs:
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Setup Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8
|
||||
with:
|
||||
targets: x86_64-pc-windows-msvc
|
||||
|
||||
@@ -730,7 +730,7 @@ jobs:
|
||||
echo "alpha-latest.json:"; cat alpha-latest.json
|
||||
|
||||
- name: Publish GitHub Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65
|
||||
with:
|
||||
tag_name: ${{ needs.version.outputs.tag }}
|
||||
name: Tolaria ${{ needs.version.outputs.display_version }}
|
||||
@@ -786,7 +786,7 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa
|
||||
with:
|
||||
version: 10
|
||||
|
||||
@@ -797,7 +797,7 @@ jobs:
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Setup Bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6
|
||||
with:
|
||||
bun-version: latest
|
||||
|
||||
@@ -826,7 +826,7 @@ jobs:
|
||||
cp _site/alpha/latest.json _site/latest-canary.json
|
||||
|
||||
- name: Deploy to GitHub Pages
|
||||
uses: peaceiris/actions-gh-pages@v4
|
||||
uses: peaceiris/actions-gh-pages@e9c66a37f080288a11235e32cbe2dc5fb3a679cc
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
publish_dir: ./_site
|
||||
|
||||
10
.semgrepignore
Normal file
10
.semgrepignore
Normal file
@@ -0,0 +1,10 @@
|
||||
tests/
|
||||
e2e/
|
||||
node_modules/
|
||||
dist/
|
||||
coverage/
|
||||
test-results/
|
||||
src-tauri/target/
|
||||
target/
|
||||
src-tauri/gen/apple/assets/mcp-server/index.js
|
||||
src-tauri/gen/apple/assets/mcp-server/ws-bridge.js
|
||||
23
src-tauri/Cargo.lock
generated
23
src-tauri/Cargo.lock
generated
@@ -1079,7 +1079,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2908,15 +2908,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.78"
|
||||
version = "0.10.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f38c4372413cdaaf3cc79dd92d29d7d9f5ab09b51b10dded508fb90bb70b9222"
|
||||
checksum = "bf0b434746ee2832f4f0baf10137e1cabb18cbe6912c69e2e33263c45250f542"
|
||||
dependencies = [
|
||||
"bitflags 2.11.0",
|
||||
"cfg-if",
|
||||
"foreign-types 0.3.2",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"openssl-macros",
|
||||
"openssl-sys",
|
||||
]
|
||||
@@ -2940,9 +2939,9 @@ checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.114"
|
||||
version = "0.9.115"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13ce1245cd07fcc4cfdb438f7507b0c7e4f3849a69fd84d52374c66d83741bb6"
|
||||
checksum = "158fe5b292746440aa6e7a7e690e55aeb72d41505e2804c23c6973ad0e9c9781"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
@@ -3454,7 +3453,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"socket2",
|
||||
"tracing",
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3888,7 +3887,7 @@ dependencies = [
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3945,7 +3944,7 @@ dependencies = [
|
||||
"security-framework",
|
||||
"security-framework-sys",
|
||||
"webpki-root-certs",
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3956,9 +3955,9 @@ checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f"
|
||||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
version = "0.103.12"
|
||||
version = "0.103.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8279bb85272c9f10811ae6a6c547ff594d6a7f3c6c6b02ee9726d1d0dcfcdd06"
|
||||
checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"rustls-pki-types",
|
||||
@@ -5109,7 +5108,7 @@ dependencies = [
|
||||
"getrandom 0.4.1",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -641,6 +641,22 @@ mod tests {
|
||||
use std::ffi::OsString;
|
||||
use std::process::Command;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn current_test_binary() -> PathBuf {
|
||||
std::fs::read_link("/proc/self/exe").unwrap()
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn current_test_binary() -> PathBuf {
|
||||
let pid = std::process::id().to_string();
|
||||
let output = Command::new("/bin/ps")
|
||||
.args(["-p", pid.as_str(), "-o", "comm="])
|
||||
.output()
|
||||
.unwrap();
|
||||
let path = String::from_utf8(output.stdout).unwrap();
|
||||
PathBuf::from(path.trim())
|
||||
}
|
||||
|
||||
macro_rules! chat_request {
|
||||
($message:expr, None, None $(,)?) => {
|
||||
ChatStreamRequest {
|
||||
@@ -1185,7 +1201,7 @@ mod tests {
|
||||
use std::io::Read;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
let mut child = Command::new(std::env::current_exe().unwrap())
|
||||
let mut child = Command::new(current_test_binary())
|
||||
.arg("stdin_probe_parent_child")
|
||||
.arg("--ignored")
|
||||
.arg("--nocapture")
|
||||
@@ -1231,7 +1247,7 @@ mod tests {
|
||||
return;
|
||||
}
|
||||
|
||||
let fake_bin = std::env::current_exe().unwrap();
|
||||
let fake_bin = current_test_binary();
|
||||
let args = vec![
|
||||
"stdin_probe_mock_claude_child".to_string(),
|
||||
"--ignored".to_string(),
|
||||
|
||||
@@ -469,6 +469,22 @@ mod tests {
|
||||
use crate::ai_agents::AiAgentPermissionMode;
|
||||
use std::ffi::OsStr;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn current_test_binary() -> PathBuf {
|
||||
std::fs::read_link("/proc/self/exe").unwrap()
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn current_test_binary() -> PathBuf {
|
||||
let pid = std::process::id().to_string();
|
||||
let output = std::process::Command::new("/bin/ps")
|
||||
.args(["-p", pid.as_str(), "-o", "comm="])
|
||||
.output()
|
||||
.unwrap();
|
||||
let path = String::from_utf8(output.stdout).unwrap();
|
||||
PathBuf::from(path.trim())
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn executable_script(dir: &Path, name: &str, body: &str) -> PathBuf {
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
@@ -798,7 +814,7 @@ exit 2
|
||||
use std::io::Read;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
let mut child = std::process::Command::new(std::env::current_exe().unwrap())
|
||||
let mut child = std::process::Command::new(current_test_binary())
|
||||
.arg("codex_stdin_probe_parent_child")
|
||||
.arg("--ignored")
|
||||
.arg("--nocapture")
|
||||
|
||||
@@ -309,6 +309,32 @@ fn colrv1_fontconfig_file_path() -> Option<std::path::PathBuf> {
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(all(desktop, target_os = "linux"))]
|
||||
fn launched_appimage_path() -> Result<std::path::PathBuf, String> {
|
||||
if let Some(appimage) = std::env::var_os("APPIMAGE").filter(|value| !value.is_empty()) {
|
||||
return Ok(std::path::PathBuf::from(appimage));
|
||||
}
|
||||
|
||||
std::fs::read_link("/proc/self/exe")
|
||||
.map_err(|e| format!("failed to resolve /proc/self/exe ({e})"))
|
||||
}
|
||||
|
||||
#[cfg(all(desktop, target_os = "linux"))]
|
||||
fn launched_process_args() -> Vec<std::ffi::OsString> {
|
||||
use std::os::unix::ffi::OsStringExt;
|
||||
|
||||
let Ok(cmdline) = std::fs::read("/proc/self/cmdline") else {
|
||||
return Vec::new();
|
||||
};
|
||||
|
||||
cmdline
|
||||
.split(|byte| *byte == 0)
|
||||
.filter(|arg| !arg.is_empty())
|
||||
.skip(1)
|
||||
.map(|arg| std::ffi::OsString::from_vec(arg.to_vec()))
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(all(desktop, target_os = "linux"))]
|
||||
fn apply_wayland_client_preload() {
|
||||
use std::os::unix::process::CommandExt;
|
||||
@@ -320,18 +346,16 @@ fn apply_wayland_client_preload() {
|
||||
return;
|
||||
};
|
||||
|
||||
let exe = match std::env::current_exe() {
|
||||
let exe = match launched_appimage_path() {
|
||||
Ok(exe) => exe,
|
||||
Err(e) => {
|
||||
eprintln!(
|
||||
"Tolaria AppImage Wayland preload skipped: failed to resolve executable ({e})"
|
||||
);
|
||||
eprintln!("Tolaria AppImage Wayland preload skipped: {e}");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let error = std::process::Command::new(exe)
|
||||
.args(std::env::args_os().skip(1))
|
||||
.args(launched_process_args())
|
||||
.env("LD_PRELOAD", preload_path)
|
||||
.env("TOLARIA_APPIMAGE_WAYLAND_PRELOAD_ATTEMPTED", "1")
|
||||
.exec();
|
||||
|
||||
@@ -224,14 +224,13 @@ fn node_binary_name() -> &'static str {
|
||||
/// Resolve the path to `mcp-server/`.
|
||||
///
|
||||
/// In dev mode, uses `CARGO_MANIFEST_DIR` (set at compile time).
|
||||
/// In release mode, navigates from the current executable.
|
||||
/// In release mode, uses platform resource roots exposed by the launcher.
|
||||
pub(crate) fn mcp_server_dir() -> Result<PathBuf, String> {
|
||||
let dev_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
||||
.join("..")
|
||||
.join("mcp-server");
|
||||
let exe = std::env::current_exe().map_err(|e| format!("Cannot find executable: {e}"))?;
|
||||
let appdir = std::env::var_os("APPDIR").map(PathBuf::from);
|
||||
let candidates = mcp_server_dir_candidates(&dev_path, &exe, appdir.as_deref());
|
||||
let resource_roots = runtime_resource_roots();
|
||||
let candidates = mcp_server_dir_candidates(&dev_path, &resource_roots);
|
||||
if let Some(path) = candidates
|
||||
.iter()
|
||||
.find(|path| mcp_server_dir_has_files(path))
|
||||
@@ -249,29 +248,13 @@ pub(crate) fn mcp_server_dir() -> Result<PathBuf, String> {
|
||||
))
|
||||
}
|
||||
|
||||
fn mcp_server_dir_candidates(
|
||||
dev_path: &Path,
|
||||
exe_path: &Path,
|
||||
appdir: Option<&Path>,
|
||||
) -> Vec<PathBuf> {
|
||||
fn mcp_server_dir_candidates(dev_path: &Path, resource_roots: &[PathBuf]) -> Vec<PathBuf> {
|
||||
let mut candidates = vec![dev_path.to_path_buf()];
|
||||
|
||||
if let Some(exe_dir) = exe_path.parent() {
|
||||
candidates.push(exe_dir.join("mcp-server"));
|
||||
if let Some(bundle_root) = exe_dir.parent() {
|
||||
candidates.push(bundle_root.join("Resources").join("mcp-server"));
|
||||
candidates.extend(linux_package_mcp_server_dirs(bundle_root));
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(appdir) = appdir {
|
||||
candidates.push(
|
||||
appdir
|
||||
.join("usr")
|
||||
.join("lib")
|
||||
.join("tolaria")
|
||||
.join("mcp-server"),
|
||||
);
|
||||
for root in resource_roots {
|
||||
candidates.push(root.join("mcp-server"));
|
||||
candidates.push(root.join("resources").join("mcp-server"));
|
||||
candidates.extend(linux_package_mcp_server_dirs(root));
|
||||
}
|
||||
|
||||
candidates.extend(linux_package_mcp_server_dirs(Path::new("/usr/local")));
|
||||
@@ -279,6 +262,28 @@ fn mcp_server_dir_candidates(
|
||||
candidates
|
||||
}
|
||||
|
||||
fn runtime_resource_roots() -> Vec<PathBuf> {
|
||||
let mut roots = Vec::new();
|
||||
|
||||
if let Some(resource_path) = non_empty_env_path("RESOURCEPATH") {
|
||||
roots.push(resource_path);
|
||||
}
|
||||
|
||||
if let Some(appdir) = non_empty_env_path("APPDIR") {
|
||||
roots.push(appdir.join("usr"));
|
||||
roots.push(appdir.join("usr").join("lib").join("tolaria"));
|
||||
roots.push(appdir.join("usr").join("lib").join("Tolaria"));
|
||||
}
|
||||
|
||||
roots
|
||||
}
|
||||
|
||||
fn non_empty_env_path(key: &str) -> Option<PathBuf> {
|
||||
std::env::var_os(key)
|
||||
.filter(|value| !value.is_empty())
|
||||
.map(PathBuf::from)
|
||||
}
|
||||
|
||||
fn linux_package_mcp_server_dirs(root: &Path) -> Vec<PathBuf> {
|
||||
vec![
|
||||
root.join("Tolaria").join("mcp-server"),
|
||||
@@ -739,32 +744,36 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mcp_server_dir_candidates_prefer_exe_dir_before_macos_resources() {
|
||||
fn mcp_server_dir_candidates_prefer_resource_root_before_linux_packages() {
|
||||
let dev_path = Path::new("/repo/mcp-server");
|
||||
let exe_path = Path::new("/Users/tester/AppData/Local/Tolaria/tolaria.exe");
|
||||
let candidates = mcp_server_dir_candidates(dev_path, exe_path, None);
|
||||
let resource_roots = vec![PathBuf::from(
|
||||
"/Applications/Tolaria.app/Contents/Resources",
|
||||
)];
|
||||
let candidates = mcp_server_dir_candidates(dev_path, &resource_roots);
|
||||
|
||||
let windows_dir = PathBuf::from("/Users/tester/AppData/Local/Tolaria/mcp-server");
|
||||
let macos_dir = PathBuf::from("/Users/tester/AppData/Local/Resources/mcp-server");
|
||||
let windows_pos = candidates
|
||||
let resource_dir = PathBuf::from("/Applications/Tolaria.app/Contents/Resources/mcp-server");
|
||||
let linux_pos = candidates
|
||||
.iter()
|
||||
.position(|path| path == &windows_dir)
|
||||
.unwrap();
|
||||
let macos_pos = candidates
|
||||
.iter()
|
||||
.position(|path| path == &macos_dir)
|
||||
.position(|path| path == &PathBuf::from("/usr/local/Tolaria/mcp-server"))
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(candidates[0], dev_path);
|
||||
assert!(windows_pos < macos_pos);
|
||||
assert_eq!(candidates[1], resource_dir);
|
||||
assert!(1 < linux_pos);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mcp_server_dir_candidates_include_linux_package_resource_roots() {
|
||||
let dev_path = Path::new("/repo/mcp-server");
|
||||
let exe_path = Path::new("/usr/local/tolaria/tolaria");
|
||||
let candidates = mcp_server_dir_candidates(dev_path, exe_path, None);
|
||||
let resource_roots = vec![PathBuf::from("/opt/tolaria")];
|
||||
let candidates = mcp_server_dir_candidates(dev_path, &resource_roots);
|
||||
let expected = [
|
||||
PathBuf::from("/opt/tolaria/Tolaria/mcp-server"),
|
||||
PathBuf::from("/opt/tolaria/Tolaria/resources/mcp-server"),
|
||||
PathBuf::from("/opt/tolaria/lib/Tolaria/mcp-server"),
|
||||
PathBuf::from("/opt/tolaria/lib/Tolaria/resources/mcp-server"),
|
||||
PathBuf::from("/opt/tolaria/lib/tolaria/mcp-server"),
|
||||
PathBuf::from("/opt/tolaria/lib/tolaria/resources/mcp-server"),
|
||||
PathBuf::from("/usr/local/Tolaria/mcp-server"),
|
||||
PathBuf::from("/usr/local/Tolaria/resources/mcp-server"),
|
||||
PathBuf::from("/usr/local/lib/Tolaria/mcp-server"),
|
||||
@@ -783,8 +792,7 @@ mod tests {
|
||||
#[test]
|
||||
fn mcp_server_dir_candidates_include_deb_capitalized_lib_root() {
|
||||
let dev_path = Path::new("/repo/mcp-server");
|
||||
let exe_path = Path::new("/usr/bin/tolaria");
|
||||
let candidates = mcp_server_dir_candidates(dev_path, exe_path, None);
|
||||
let candidates = mcp_server_dir_candidates(dev_path, &[]);
|
||||
|
||||
assert!(candidates.contains(&PathBuf::from("/usr/lib/Tolaria/mcp-server")));
|
||||
}
|
||||
@@ -792,9 +800,8 @@ mod tests {
|
||||
#[test]
|
||||
fn mcp_server_dir_candidates_include_linux_appimage_resource_root() {
|
||||
let dev_path = Path::new("/repo/mcp-server");
|
||||
let exe_path = Path::new("/tmp/.mount_tolaria/usr/bin/tolaria");
|
||||
let appdir = Path::new("/tmp/.mount_tolaria");
|
||||
let candidates = mcp_server_dir_candidates(dev_path, exe_path, Some(appdir));
|
||||
let resource_roots = vec![PathBuf::from("/tmp/.mount_tolaria/usr")];
|
||||
let candidates = mcp_server_dir_candidates(dev_path, &resource_roots);
|
||||
|
||||
assert!(candidates.contains(&PathBuf::from(
|
||||
"/tmp/.mount_tolaria/usr/lib/tolaria/resources/mcp-server"
|
||||
|
||||
@@ -41,7 +41,8 @@ function renderWithPrioritySort(entries: VaultEntry[]) {
|
||||
}
|
||||
|
||||
function expectVisibleNoteOrder(expectedTitles: string[]) {
|
||||
const items = screen.getAllByText(new RegExp(expectedTitles.join('|')))
|
||||
const expectedTitleSet = new Set(expectedTitles)
|
||||
const items = screen.getAllByText((content) => expectedTitleSet.has(content))
|
||||
expect(items.map((item) => item.textContent)).toEqual(expectedTitles)
|
||||
}
|
||||
|
||||
@@ -75,10 +76,7 @@ describe('useNoteListSort (via NoteList)', () => {
|
||||
makeEntry({ path: '/c.md', title: 'Charlie', modifiedAt: 2000 }),
|
||||
]
|
||||
renderNoteList({ entries, selection: { kind: 'filter', filter: 'all' } })
|
||||
const items = screen.getAllByText(/Alpha|Beta|Charlie/)
|
||||
expect(items[0].textContent).toBe('Beta')
|
||||
expect(items[1].textContent).toBe('Charlie')
|
||||
expect(items[2].textContent).toBe('Alpha')
|
||||
expectVisibleNoteOrder(['Beta', 'Charlie', 'Alpha'])
|
||||
})
|
||||
|
||||
it('reads sort from type document for sectionGroup selection', () => {
|
||||
@@ -90,10 +88,7 @@ describe('useNoteListSort (via NoteList)', () => {
|
||||
makeEntry({ path: '/b.md', title: 'Beta', modifiedAt: 2000 }),
|
||||
]
|
||||
renderNoteList({ entries, selection: { kind: 'sectionGroup', type: 'Note', label: 'Notes' } })
|
||||
const items = screen.getAllByText(/Alpha|Beta|Charlie/)
|
||||
expect(items[0].textContent).toBe('Alpha')
|
||||
expect(items[1].textContent).toBe('Beta')
|
||||
expect(items[2].textContent).toBe('Charlie')
|
||||
expectVisibleNoteOrder(['Alpha', 'Beta', 'Charlie'])
|
||||
})
|
||||
|
||||
it('shows type title as header for sectionGroup selection', () => {
|
||||
|
||||
Reference in New Issue
Block a user