Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
7d6e4d1
Mirror status.json to host dir to stop cross-app TCC prompts
manuelgruber Jun 27, 2026
54770e7
Cap time at <0.3.52 so tauri's cookie 0.18.1 keeps compiling
manuelgruber Jul 1, 2026
2219887
Bump version to 3.2.0 across workspace, app, and badges for release
manuelgruber Jul 1, 2026
cfd9f40
Bump Cargo and pnpm dependencies to latest in-range versions
manuelgruber Jul 1, 2026
939beff
Fix legacy status symlink errors to prevent container reads
manuelgruber Jul 2, 2026
92f0eac
Harden status mirroring and fix review findings on TCC branch
manuelgruber Jul 7, 2026
250ac7d
Stamp monitor build version in status so the app can flag skew
manuelgruber Jul 10, 2026
0bd9f6c
Auto-restart stale monitor on app launch to recover host status
manuelgruber Jul 10, 2026
73abf11
Fix monitor skew pass-state and harden IPC status read failures
manuelgruber Jul 24, 2026
0abbcf5
Preserve watcher rescans to prevent stale app status
manuelgruber Aug 10, 2026
6380efb
Fix TUI status refresh state to prevent sync freezes
manuelgruber Aug 11, 2026
e1d2c1a
Create legacy socket symlink on first start for dev fallback
manuelgruber Aug 11, 2026
2b7a3d1
Run monitor as app identity so FDA gates badges
manuelgruber Sep 9, 2026
210876f
Update vulnerable dependencies to resolve Dependabot findings
manuelgruber Sep 9, 2026
1d4a295
Assert test config isolation to protect user config
manuelgruber Sep 9, 2026
f4cc501
Fix CI failures blocking the 3.2.0 merge
manuelgruber Sep 9, 2026
087b51a
Fix PR review findings across IPC, TUI, and app
manuelgruber Sep 21, 2026
eaf1dc4
Gate macOS-only items so clippy passes off macOS
manuelgruber Sep 21, 2026
643ab4e
Derive plist path in test so Windows separators match
manuelgruber Sep 21, 2026
12ada56
Update acceptance matrix for the app-identity agent
manuelgruber Sep 21, 2026
01bb2b9
Bump vitest to 4.1.11 to clear Dependabot alerts
manuelgruber Sep 21, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions .claude/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ Git-Same is a Rust CLI + TUI + macOS Tauri app that discovers GitHub org/repo st

**Commands:** `init`, `setup`, `sync`, `status`, `scan`, `workspace {list,default}`, `reset`, `monitor` (alias: `daemon`), `refresh`.

**Why `monitor` is a CLI subcommand and not solely a Tauri-host responsibility:** the LaunchAgent invokes the managed helper as `git-same monitor --foreground --managed`, the cask installs it through the hidden `--install-agent` / `--remove-agent` modes, non-cask installs (`cargo install`, the homebrew formula) ship only the binary, `--status` / `--start` / `--stop` / `--uninstall` are the supported control surface, and a future Linux file-manager extension would talk to the same `gisa monitor` over the same Unix socket. The CLI handler is a thin shim (~140 lines); the loop itself lives in `git-same-core::monitor`.
**Why `monitor` is a CLI subcommand and not solely a Tauri-host responsibility:** the LaunchAgent invokes the managed program as `<program> monitor --foreground --managed`, the cask installs it through the hidden `--install-agent` / `--remove-agent` modes, non-cask installs (`cargo install`, the homebrew formula) ship only the binary, `--status` / `--start` / `--stop` / `--uninstall` are the supported control surface, and a future Linux file-manager extension would talk to the same `gisa monitor` over the same Unix socket. The CLI handler is a thin shim; the loop itself lives in `git-same-core::monitor`, and `monitor::Options::from_config` / `monitor::default_shutdown_signal` are shared with the app.

**Why an app-owned LaunchAgent execs `Git-Same.app/Contents/MacOS/git-same-app` and not the helper copy:** macOS TCC attributes a launchd-spawned process to its bundle only when the executable is the bundle's `CFBundleExecutable`. A copy of `Contents/Helpers/git-same` under `~/Library/Application Support` is a separate, path-based TCC identity, so a Full Disk Access grant for "Git-Same" never reaches a monitor started through it. `monitor_agent::source` therefore classifies an app-bundle caller as an **in-place** install: nothing is copied, and the rendered plist names the bundle executable. `crates/git-same-app/src/monitor_mode.rs` runs the same core loop headlessly (no Tauri, no window, no Dock icon) when argv[1] is `monitor`. CLI owners (cargo, the formula) keep the copy-into-managed-root install and its path-based identity. The expected program is derived from `owner_kind`, not persisted, so an agent installed by an older build is re-rendered onto the bundle executable the next time the app runs its startup recovery.


### Engine modules (`crates/git-same-core/src/`)

Expand Down Expand Up @@ -114,7 +117,9 @@ Three non-obvious traps in `macos/GitSameBadges/`. Each one silently breaks badg

3. **Google Drive's FinderSync poisons the badge-rendering pipeline.** When `com.google.drivefs.finderhelper.findersync` is enabled, peer FinderSync extensions render no badge image even after Finder calls `setBadgeIdentifier`. Confirmed in this environment: badges only began appearing after the user disabled Google Drive in System Settings → Login Items & Extensions. Other peers (Keka, Synology, Dropbox) coexist fine. There is no code fix; document the workaround and surface it in the in-app self-check if you can.

`scan_roots` and `show_ambient`: defaults are `["~"]` / `false`. Never re-enable `show_ambient = true` with `~` in `scan_roots`: Finder refuses to call `requestBadgeIdentifier` on extensions whose `directoryURLs` contain the home folder (separate issue from the three above).
4. **Full Disk Access is per executable, and the extension is not the process that needs it.** The appex does zero I/O outside its app-group container and has never triggered a TCC prompt. The monitor is what walks workspace roots, reads `/Volumes`, watches FSEvents, and writes `Icon\r`, so it is the process that needs FDA. `git-same-core::macos::full_disk_access::probe()` (opens the user TCC.db; success proves the grant, EPERM means denied, never prompts) is stamped into `status.json` as `full_disk_access` by the monitor and read by the app, whose `enable_finder_extension` command refuses to set the pluginkit election until the gate passes. macOS applies a new grant on process start: the app must be relaunched and the monitor restarted (the app does the latter automatically).

`scan_roots` and `show_ambient`: defaults are `["~"]` / `false`. Never re-enable `show_ambient = true` with `~` in `scan_roots`: Finder refuses to call `requestBadgeIdentifier` on extensions whose `directoryURLs` contain the home folder (separate issue from the four above).

## Workspace folder branding (macOS)

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/S1-Test-CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ jobs:
prefix-key: v1-rust-no-bin

- name: Install cargo-tarpaulin
uses: taiki-e/install-action@v2
uses: taiki-e/install-action@v2.87.8
with:
tool: cargo-tarpaulin

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/S2-Release-GitHub.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ jobs:
prefix-key: v1-rust-no-bin

- name: Install cargo-tarpaulin
uses: taiki-e/install-action@v2
uses: taiki-e/install-action@v2.87.8
with:
tool: cargo-tarpaulin

Expand Down
8 changes: 5 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ members = [
resolver = "2"

[workspace.package]
version = "3.1.2"
version = "3.2.0"
edition = "2021"
authors = ["Manuel Gruber"]
license = "MIT"
Expand Down
2 changes: 2 additions & 0 deletions crates/git-same-app/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ tauri = { version = "2", features = [] }
tauri-plugin-dialog = "2"
tokio = { workspace = true }
toml = { workspace = true }
tracing = { workspace = true }
tracing-subscriber = { workspace = true }

[dev-dependencies]
tempfile = { workspace = true }
Loading
Loading