Prevent monitor status TCC prompts in Git-Same 3.2.0#21
Conversation
The non-sandboxed Tauri host read status.json from the App Group container, so macOS fired "Git-Same would like to access data from other apps" up to five times on launch and after each sync. The monitor now mirrors a real status.json into ~/.config/git-same/ finder/ (StatusFileWriter::new_with_mirrors) in addition to the container, and the host reads only that host-home copy via a shared tauri::State<HostIpc> resolved once at startup. ensure_legacy_symlinks no longer symlinks status.json (only finder.sock), and the host unlinks any leftover status.json symlink before reading so it never follows a link into the container during the upgrade window. The FinderSync extension, the socket, and all entitlements are unchanged, so no Apple re-sign or macOS-26 re-test is required.
Picks up patch-level updates cargo resolved: anyhow 1.0.103, aws-lc-rs 1.17.1, aws-lc-sys 0.42.0, camino 1.2.4, among others.
time 0.3.52 changed its sealed Parsable::parse trait method from one argument to two (added defaults: Option<Parsed>). cookie 0.18.1, pulled in transitively via tauri, calls the one-argument form and fails to compile against time >= 0.3.52. No fixed cookie release exists (0.18.1 is the latest and tauri pins cookie 0.18), so cap time below 0.3.52 in the git-same-app manifest and re-pin the lockfile to the latest compatible time 0.3.51. Remove the cap once cookie ships a fix.
Updates 6 crates.io packages (clap_complete, console, indicatif, inotify-sys, libredox, tauri) and 3 npm packages (@lucide/svelte, @tauri-apps/cli, vite) to their latest semver-compatible releases. The time <0.3.52 cap in git-same-app/Cargo.toml stays in place since tauri's transitive cookie 0.18.1 still hasn't shipped a fix.
Address findings from an xhigh code review of the status-mirror change: - Gate the Windows-hostile suffix assert in the IPC test so S1 CI passes. - Make status mirror writes best-effort (warn, not error) so an unwritable host dir cannot crash-loop the monitor under launchd. - Add core remove_symlink_if_present (NotFound-tolerant), reuse it from the host, and drop the duplicated app-side helper and its synthetic test. - Move the mirror policy into IpcConfig::status_writer so a custom IpcConfig can never clobber the real user's host status.json. - Drop the false state-guard clones in the Tauri handlers, single-parse the status snapshot, and filter watcher events to status.json. - Correct the ipc module docs to describe the mirror design.
The stale-status requirement suggestion said only to restart or wait, which never resolves an app/monitor version skew (a newer app reading an older monitor's status). Mention that a restart picks up the new monitor build so upgraders are not stuck waiting for a scan that cannot help.
Add monitor_version to FinderStatus, stamped in FinderStatus::new with the building crate's CARGO_PKG_VERSION, so each status records the monitor build that wrote it. The Tauri Monitor requirement check compares it against the app's own version and, when a readable status reports a different build, tells the user to restart the monitor. Informational only: it does not flip the check to failed, and the stale hint still takes priority when no status is readable. Old status files without the field parse as None.
After an app upgrade the previously installed monitor keeps running the old build (launchd KeepAlive keeps the process alive; nothing restarts it). The old monitor only symlinks the host status.json into the container and never writes the mirror the new host reads, so the host deletes the leftover symlink and then shows stale/absent status until a manual restart. On startup, detect that leftover symlink (a reliable signal an old monitor is running) via symlink_metadata, which does not follow the link into the app-group container, and best-effort restart the installed monitor on a background thread so the on-disk build takes over and starts mirroring. Skip when no LaunchAgent is installed so a monitor is never created implicitly. This complements the stale-status guidance text by making the common upgrade case self-heal without user action.
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
WalkthroughVersion 3.2.0 adds host-facing status mirroring, monitor version metadata, IPC configuration injection, filtered status watching, symlink migration handling, and monitor/app version-skew detection. ChangesHost IPC and monitor synchronization
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant Monitor
participant StatusFileWriter
participant HostStatusPath
participant StatusWatcher
participant TauriApp
Monitor->>StatusFileWriter: write FinderStatus
StatusFileWriter->>HostStatusPath: atomically write status.json
HostStatusPath->>StatusWatcher: notify status.json event
StatusWatcher->>TauriApp: emit status-updated snapshot
TauriApp->>HostStatusPath: read status snapshot
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Reviewer's GuideAdds host-facing status mirroring and monitor version reporting to keep the macOS app and monitor in sync without triggering TCC prompts, refactors IPC/status handling to be safer and more robust in the presence of legacy symlinks and corrupt files, wires the Tauri host to read from the mirrored host path, and bumps the project to the 3.2.0 release line with dependency and test updates. File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@crates/git-same-app/src/commands.rs`:
- Around line 1013-1026: Update the Monitor requirement’s passed condition in
the checks construction to also require monitor_version_mismatch to be false.
Preserve the existing running-agent and fresh-snapshot checks, while ensuring a
running, fresh monitor with a mismatched version is marked as failed.
In `@crates/git-same-core/src/ipc/status_file.rs`:
- Around line 117-129: Update remove_symlink_if_present to distinguish
symlink_metadata errors: return Ok(false) only for ErrorKind::NotFound, and
propagate all other inspection errors as AppError::path failures. Preserve the
existing symlink removal behavior and error handling.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: cbc0eccc-5949-45b2-81ab-179756176bec
⛔ Files ignored due to path filters (2)
Cargo.lockis excluded by!**/*.lockcrates/git-same-app/ui/pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (21)
Cargo.tomlcrates/git-same-app/Cargo.tomlcrates/git-same-app/src/commands.rscrates/git-same-app/src/commands_tests.rscrates/git-same-app/src/main.rscrates/git-same-app/src/status_stream.rscrates/git-same-app/src/status_stream_tests.rscrates/git-same-app/tauri.conf.jsoncrates/git-same-app/ui/package.jsoncrates/git-same-app/ui/src/lib/types.tscrates/git-same-cli/Cargo.tomlcrates/git-same-core/src/ipc/mod.rscrates/git-same-core/src/ipc/mod_tests.rscrates/git-same-core/src/ipc/status_file.rscrates/git-same-core/src/ipc/status_file_tests.rscrates/git-same-core/src/monitor/run.rscrates/git-same-core/src/monitor/socket_handler.rscrates/git-same-core/src/monitor/socket_handler_tests.rscrates/git-same-core/src/types/finder_status.rscrates/git-same-core/src/types/finder_status_tests.rsmacos/GitSameBadges/Info.plist
| checks.push(RequirementCheckDto { | ||
| name: "Monitor".to_string(), | ||
| passed: monitor_agent.as_ref().is_some_and(|agent| agent.running) | ||
| && snapshot.as_ref().is_some_and(|snapshot| !snapshot.stale), | ||
| message: monitor_requirement_message(monitor_agent.as_ref(), snapshot.as_ref()), | ||
| suggestion: monitor_requirement_suggestion(monitor_agent.as_ref(), snapshot.as_ref()), | ||
| message: monitor_requirement_message( | ||
| monitor_agent.as_ref(), | ||
| snapshot.as_ref(), | ||
| env!("CARGO_PKG_VERSION"), | ||
| ), | ||
| suggestion: monitor_requirement_suggestion( | ||
| monitor_agent.as_ref(), | ||
| snapshot.as_ref(), | ||
| env!("CARGO_PKG_VERSION"), | ||
| ), |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Mark monitor version skew as a failed requirement.
A running, fresh but mismatched monitor currently sets passed: true, contradicting the restart message and suggestion. Include monitor_version_mismatch in the pass condition.
Proposed fix
passed: monitor_agent.as_ref().is_some_and(|agent| agent.running)
- && snapshot.as_ref().is_some_and(|snapshot| !snapshot.stale),
+ && snapshot.as_ref().is_some_and(|snapshot| !snapshot.stale)
+ && monitor_version_mismatch(
+ snapshot.as_ref(),
+ env!("CARGO_PKG_VERSION"),
+ )
+ .is_none(),📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| checks.push(RequirementCheckDto { | |
| name: "Monitor".to_string(), | |
| passed: monitor_agent.as_ref().is_some_and(|agent| agent.running) | |
| && snapshot.as_ref().is_some_and(|snapshot| !snapshot.stale), | |
| message: monitor_requirement_message(monitor_agent.as_ref(), snapshot.as_ref()), | |
| suggestion: monitor_requirement_suggestion(monitor_agent.as_ref(), snapshot.as_ref()), | |
| message: monitor_requirement_message( | |
| monitor_agent.as_ref(), | |
| snapshot.as_ref(), | |
| env!("CARGO_PKG_VERSION"), | |
| ), | |
| suggestion: monitor_requirement_suggestion( | |
| monitor_agent.as_ref(), | |
| snapshot.as_ref(), | |
| env!("CARGO_PKG_VERSION"), | |
| ), | |
| checks.push(RequirementCheckDto { | |
| name: "Monitor".to_string(), | |
| passed: monitor_agent.as_ref().is_some_and(|agent| agent.running) | |
| && snapshot.as_ref().is_some_and(|snapshot| !snapshot.stale) | |
| && monitor_version_mismatch( | |
| snapshot.as_ref(), | |
| env!("CARGO_PKG_VERSION"), | |
| ) | |
| .is_none(), | |
| message: monitor_requirement_message( | |
| monitor_agent.as_ref(), | |
| snapshot.as_ref(), | |
| env!("CARGO_PKG_VERSION"), | |
| ), | |
| suggestion: monitor_requirement_suggestion( | |
| monitor_agent.as_ref(), | |
| snapshot.as_ref(), | |
| env!("CARGO_PKG_VERSION"), | |
| ), |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@crates/git-same-app/src/commands.rs` around lines 1013 - 1026, Update the
Monitor requirement’s passed condition in the checks construction to also
require monitor_version_mismatch to be false. Preserve the existing
running-agent and fresh-snapshot checks, while ensuring a running, fresh monitor
with a mismatched version is marked as failed.
| pub fn remove_symlink_if_present(path: &Path) -> Result<bool, AppError> { | ||
| match std::fs::symlink_metadata(path) { | ||
| Ok(meta) if meta.file_type().is_symlink() => match std::fs::remove_file(path) { | ||
| Ok(()) => Ok(true), | ||
| Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(true), | ||
| Err(e) => Err(AppError::path(format!( | ||
| "Failed to remove symlink '{}': {}", | ||
| path.display(), | ||
| e | ||
| ))), | ||
| }, | ||
| _ => Ok(false), | ||
| } |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Fail closed when symlink inspection fails.
Line 128 converts permission and I/O errors into Ok(false), allowing callers to continue reading even though the guard could not establish that the path is safe. Only NotFound should be treated as absent.
Proposed fix
match std::fs::symlink_metadata(path) {
Ok(meta) if meta.file_type().is_symlink() => match std::fs::remove_file(path) {
Ok(()) => Ok(true),
Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(true),
Err(e) => Err(AppError::path(format!(
"Failed to remove symlink '{}': {}",
path.display(),
e
))),
},
- _ => Ok(false),
+ Ok(_) => Ok(false),
+ Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(false),
+ Err(e) => Err(AppError::path(format!(
+ "Failed to inspect '{}': {}",
+ path.display(),
+ e
+ ))),
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| pub fn remove_symlink_if_present(path: &Path) -> Result<bool, AppError> { | |
| match std::fs::symlink_metadata(path) { | |
| Ok(meta) if meta.file_type().is_symlink() => match std::fs::remove_file(path) { | |
| Ok(()) => Ok(true), | |
| Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(true), | |
| Err(e) => Err(AppError::path(format!( | |
| "Failed to remove symlink '{}': {}", | |
| path.display(), | |
| e | |
| ))), | |
| }, | |
| _ => Ok(false), | |
| } | |
| pub fn remove_symlink_if_present(path: &Path) -> Result<bool, AppError> { | |
| match std::fs::symlink_metadata(path) { | |
| Ok(meta) if meta.file_type().is_symlink() => match std::fs::remove_file(path) { | |
| Ok(()) => Ok(true), | |
| Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(true), | |
| Err(e) => Err(AppError::path(format!( | |
| "Failed to remove symlink '{}': {}", | |
| path.display(), | |
| e | |
| ))), | |
| }, | |
| Ok(_) => Ok(false), | |
| Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(false), | |
| Err(e) => Err(AppError::path(format!( | |
| "Failed to inspect '{}': {}", | |
| path.display(), | |
| e | |
| ))), | |
| } | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@crates/git-same-core/src/ipc/status_file.rs` around lines 117 - 129, Update
remove_symlink_if_present to distinguish symlink_metadata errors: return
Ok(false) only for ErrorKind::NotFound, and propagate all other inspection
errors as AppError::path failures. Preserve the existing symlink removal
behavior and error handling.
There was a problem hiding this comment.
6 issues found across 23 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="crates/git-same-core/src/ipc/status_file.rs">
<violation number="1" location="crates/git-same-core/src/ipc/status_file.rs:128">
P2: The `_ => Ok(false)` wildcard catches I/O errors from `symlink_metadata` (e.g. `PermissionDenied`) and treats them the same as "path is a regular file." If the inspection fails for reasons other than `NotFound`, the function can't confirm the path isn't a symlink, so callers may proceed to read through a link they intended to guard against. Consider splitting the wildcard to propagate unexpected errors:
```rust
Ok(_) => Ok(false),
Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(false),
Err(e) => Err(AppError::path(format!(
"Failed to inspect '{}': {}",
path.display(),
e
))),
```</violation>
<violation number="2" location="crates/git-same-core/src/ipc/status_file.rs:209">
P2: A malformed legacy `status.json` directory now blocks mirror recovery: this migration no longer moves that entry aside, and the non-fatal mirror path leaves the monitor running with the host status permanently stale until the directory is removed. Preserving the prior aside behavior for non-file status entries would keep migration recoverable.</violation>
</file>
<file name="crates/git-same-core/src/ipc/status_file_tests.rs">
<violation number="1" location="crates/git-same-core/src/ipc/status_file_tests.rs:118">
P2: A symlinked mirror would pass this test, so the TCC-avoidance invariant is untested. Checking `symlink_metadata(...).file_type().is_file()` for both destinations would catch a regression that recreates the cross-container symlink.</violation>
</file>
<file name="crates/git-same-core/src/ipc/mod_tests.rs">
<violation number="1" location="crates/git-same-core/src/ipc/mod_tests.rs:107">
P2: The new path tests can fail intermittently under the default parallel test runner when workspace tests change `GIT_SAME_CONFIG_DIR` or `HOME` between these environment-dependent calls. A shared test-environment lock or dependency-injected path source would make the assertions deterministic.</violation>
</file>
<file name="crates/git-same-app/src/commands.rs">
<violation number="1" location="crates/git-same-app/src/commands.rs:1102">
P2: A monitor running a different build is still reported as a passing requirement, so the new restart guidance is hidden in the Requirements UI. Including `monitor_version_mismatch` in the `passed` calculation would make the skew actionable, or the new suggestion branch should be removed if skew is intentionally informational.</violation>
</file>
<file name="crates/git-same-app/Cargo.toml">
<violation number="1" location="crates/git-same-app/Cargo.toml:30">
P3: The `time` version cap `>=0.3, <0.3.52` is tighter than necessary and the rationale comment is slightly stale. `time` 0.3.53 (released 2026-07-01) already reverts the internal `Parsable::parse` breaking change from 0.3.52 to make the `cookie` crate compile again, so 0.3.53+ is now compatible. Consider relaxing the constraint to `>=0.3, !=0.3.52` or updating the comment to note that time 0.3.53 already resolved the issue, and that the cap can be relaxed now rather than waiting for a cookie release.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| } | ||
|
|
||
| Ok(()) | ||
| // Only the socket is symlinked; status.json is a real mirror file written |
There was a problem hiding this comment.
P2: A malformed legacy status.json directory now blocks mirror recovery: this migration no longer moves that entry aside, and the non-fatal mirror path leaves the monitor running with the host status permanently stale until the directory is removed. Preserving the prior aside behavior for non-file status entries would keep migration recoverable.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At crates/git-same-core/src/ipc/status_file.rs, line 209:
<comment>A malformed legacy `status.json` directory now blocks mirror recovery: this migration no longer moves that entry aside, and the non-fatal mirror path leaves the monitor running with the host status permanently stale until the directory is removed. Preserving the prior aside behavior for non-file status entries would keep migration recoverable.</comment>
<file context>
@@ -96,27 +186,31 @@ impl StatusFileWriter {
- }
-
- Ok(())
+ // Only the socket is symlinked; status.json is a real mirror file written
+ // by the monitor (see the doc comment on `ensure_legacy_symlinks`).
+ let legacy_sock = legacy_dir.join("finder.sock");
</file context>
| assert!(primary.exists()); | ||
| assert!(mirror.exists()); |
There was a problem hiding this comment.
P2: A symlinked mirror would pass this test, so the TCC-avoidance invariant is untested. Checking symlink_metadata(...).file_type().is_file() for both destinations would catch a regression that recreates the cross-container symlink.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At crates/git-same-core/src/ipc/status_file_tests.rs, line 118:
<comment>A symlinked mirror would pass this test, so the TCC-avoidance invariant is untested. Checking `symlink_metadata(...).file_type().is_file()` for both destinations would catch a regression that recreates the cross-container symlink.</comment>
<file context>
@@ -104,6 +104,120 @@ fn test_no_temp_file_remains_after_write() {
+ writer.write(&status).unwrap();
+
+ // Both files exist as real files with identical content.
+ assert!(primary.exists());
+ assert!(mirror.exists());
+ assert_eq!(
</file context>
| assert!(primary.exists()); | |
| assert!(mirror.exists()); | |
| let primary_meta = std::fs::symlink_metadata(&primary).unwrap(); | |
| let mirror_meta = std::fs::symlink_metadata(&mirror).unwrap(); | |
| assert!(primary_meta.file_type().is_file()); | |
| assert!(mirror_meta.file_type().is_file()); |
| fn test_host_status_path_matches_legacy_default_path() { | ||
| // The host reads from the non-container host path; it must resolve to the | ||
| // same directory as legacy_default_path (a distinct name for clarity). | ||
| let host = IpcConfig::host_status_path(); |
There was a problem hiding this comment.
P2: The new path tests can fail intermittently under the default parallel test runner when workspace tests change GIT_SAME_CONFIG_DIR or HOME between these environment-dependent calls. A shared test-environment lock or dependency-injected path source would make the assertions deterministic.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At crates/git-same-core/src/ipc/mod_tests.rs, line 107:
<comment>The new path tests can fail intermittently under the default parallel test runner when workspace tests change `GIT_SAME_CONFIG_DIR` or `HOME` between these environment-dependent calls. A shared test-environment lock or dependency-injected path source would make the assertions deterministic.</comment>
<file context>
@@ -99,3 +99,56 @@ fn test_legacy_default_path_ends_in_finder() {
+fn test_host_status_path_matches_legacy_default_path() {
+ // The host reads from the non-container host path; it must resolve to the
+ // same directory as legacy_default_path (a distinct name for clarity).
+ let host = IpcConfig::host_status_path();
+ let legacy = IpcConfig::legacy_default_path();
+ match (host, legacy) {
</file context>
| Some(_) if snapshot.is_some_and(|snapshot| snapshot.stale) => { | ||
| "Monitor running but status file is stale".to_string() | ||
| } | ||
| Some(_) if skew.is_some() => format!( |
There was a problem hiding this comment.
P2: A monitor running a different build is still reported as a passing requirement, so the new restart guidance is hidden in the Requirements UI. Including monitor_version_mismatch in the passed calculation would make the skew actionable, or the new suggestion branch should be removed if skew is intentionally informational.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At crates/git-same-app/src/commands.rs, line 1102:
<comment>A monitor running a different build is still reported as a passing requirement, so the new restart guidance is hidden in the Requirements UI. Including `monitor_version_mismatch` in the `passed` calculation would make the skew actionable, or the new suggestion branch should be removed if skew is intentionally informational.</comment>
<file context>
@@ -1049,6 +1099,11 @@ fn monitor_requirement_message(
Some(_) if snapshot.is_some_and(|snapshot| snapshot.stale) => {
"Monitor running but status file is stale".to_string()
}
+ Some(_) if skew.is_some() => format!(
+ "Monitor is running a different build ({}) than the app ({})",
+ skew.as_deref().unwrap_or_default(),
</file context>
| e | ||
| ))), | ||
| }, | ||
| _ => Ok(false), |
There was a problem hiding this comment.
P2: The _ => Ok(false) wildcard catches I/O errors from symlink_metadata (e.g. PermissionDenied) and treats them the same as "path is a regular file." If the inspection fails for reasons other than NotFound, the function can't confirm the path isn't a symlink, so callers may proceed to read through a link they intended to guard against. Consider splitting the wildcard to propagate unexpected errors:
Ok(_) => Ok(false),
Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(false),
Err(e) => Err(AppError::path(format!(
"Failed to inspect '{}': {}",
path.display(),
e
))),Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At crates/git-same-core/src/ipc/status_file.rs, line 128:
<comment>The `_ => Ok(false)` wildcard catches I/O errors from `symlink_metadata` (e.g. `PermissionDenied`) and treats them the same as "path is a regular file." If the inspection fails for reasons other than `NotFound`, the function can't confirm the path isn't a symlink, so callers may proceed to read through a link they intended to guard against. Consider splitting the wildcard to propagate unexpected errors:
```rust
Ok(_) => Ok(false),
Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(false),
Err(e) => Err(AppError::path(format!(
"Failed to inspect '{}': {}",
path.display(),
e
))),
```</comment>
<file context>
@@ -83,10 +89,94 @@ impl StatusFileWriter {
+ e
+ ))),
+ },
+ _ => Ok(false),
+ }
+}
</file context>
| _ => Ok(false), | |
| Ok(_) => Ok(false), | |
| Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(false), | |
| Err(e) => Err(AppError::path(format!( | |
| "Failed to inspect '{}': {}", | |
| path.display(), | |
| e | |
| ))), |
| # Pin: tauri's transitive `cookie` 0.18.1 calls time's Parsable::parse with the | ||
| # pre-0.3.52 one-arg signature; time 0.3.52 made it two-arg and fails to compile. | ||
| # No fixed cookie release exists yet. Remove this cap once cookie ships a fix. | ||
| time = ">=0.3, <0.3.52" |
There was a problem hiding this comment.
P3: The time version cap >=0.3, <0.3.52 is tighter than necessary and the rationale comment is slightly stale. time 0.3.53 (released 2026-07-01) already reverts the internal Parsable::parse breaking change from 0.3.52 to make the cookie crate compile again, so 0.3.53+ is now compatible. Consider relaxing the constraint to >=0.3, !=0.3.52 or updating the comment to note that time 0.3.53 already resolved the issue, and that the cap can be relaxed now rather than waiting for a cookie release.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At crates/git-same-app/Cargo.toml, line 30:
<comment>The `time` version cap `>=0.3, <0.3.52` is tighter than necessary and the rationale comment is slightly stale. `time` 0.3.53 (released 2026-07-01) already reverts the internal `Parsable::parse` breaking change from 0.3.52 to make the `cookie` crate compile again, so 0.3.53+ is now compatible. Consider relaxing the constraint to `>=0.3, !=0.3.52` or updating the comment to note that time 0.3.53 already resolved the issue, and that the cap can be relaxed now rather than waiting for a cookie release.</comment>
<file context>
@@ -24,6 +24,10 @@ serde = { workspace = true }
+# Pin: tauri's transitive `cookie` 0.18.1 calls time's Parsable::parse with the
+# pre-0.3.52 one-arg signature; time 0.3.52 made it two-arg and fails to compile.
+# No fixed cookie release exists yet. Remove this cap once cookie ships a fix.
+time = ">=0.3, <0.3.52"
tauri-plugin-dialog = "2"
tokio = { workspace = true }
</file context>
| time = ">=0.3, <0.3.52" | |
| time = ">=0.3, !=0.3.52" |
This adds host-facing atomic status mirroring through
IpcConfig, migrates legacy status symlinks safely, and keeps mirror failures non-fatal while primary writes still fail normally, preventing macOS cross-app access prompts in the Tauri host.It adds a backward-compatible optional
monitor_versionfield toFinderStatus, reports app/monitor build skew, and automatically restarts an already-installed stale monitor after upgrades so status recovers without manual intervention.It also bumps Git-Same to 3.2.0 and refreshes in-range Cargo and pnpm dependencies.
Validation passed with
cargo fmt --all -- --check,cargo test --workspace, andpnpm --dir crates/git-same-app/ui check.Summary by Sourcery
Add host-facing status mirroring and monitor version tracking to avoid macOS TCC prompts and handle monitor/app skew while bumping Git-Same to 3.2.0.
New Features:
Bug Fixes:
Enhancements:
Build:
Documentation:
Tests:
Summary by CodeRabbit