fix(probe): let T3 Code's Claude chats join Relay on Linux
Stacked on #2041. On Linux, T3 Code's Claude chats still looked like automation to the core, so they never joined the roster. Fixes #2045 for Linux; Windows is not covered.
is_t3_app now also matches T3 Code's Linux main executable:
.deb:/opt/T3 Code (<Channel>)/t3code. The stable and preview builds install asT3 Code (Beta), nightly asT3 Code (Nightly). Channel names use the same rule as the macOS bundles.- AppImage:
$TMPDIR/.mount_<random>/t3code, where the running AppImage mounts itself (/tmpby default).
T3's backend server runs from the same executable (ELECTRON_RUN_AS_NODE) and starts each Claude chat, so the walk matches at the chat's parent. The other guards from #2041 are unchanged: same UID, kind: interactive, stream-json input, no terminal, no -p/--print, and the walk stops at an intermediate or unreadable Claude session. The existing chat and claude -p tests now run against the macOS, .deb and AppImage executables. There is a new test for a parent owned by another user, and the path test has Linux cases that should be rejected: helpers, /usr/bin/t3code, ~/.local/bin/t3code, a non-/opt install, an extracted squashfs-root and an empty mount id.
Evidence (linuyc, Arch, x86_64; T3 Code 0.1.6 AppImage, Claude Code 2.1.280):
- Ran live: the stable AppImage, checked against
latest-linux.yml, on Hyprland in a hidden special workspace (--ozone-platform=headlesssegfaults in Electron). A real Claude chat sent from the UI ran with this ancestry, read from/proc:
Registry record:claude --output-format stream-json --verbose --input-format stream-json … (no -p) tty_nr=0, fd0=socket └ /tmp/.mount_T3-CodmajGcH/t3code --require …/compileCache.cjs …/apps/server/dist/bin.mjs (backend server) └ /tmp/.mount_T3-CodmajGcH/t3code --user-data-dir=… (main) └ Hyprlandkind: interactive,entrypoint: sdk-ts. A temporary test that was not committed ranis_t3_chatwith the realSystemProcesseson that pid. The result wastrue, andfalsewithkind: sdk. - Taken from the packages, not run: the
.debpath. The stable, preview and nightly.debfiles all checked out against their release manifests. Theirpostinstand.desktopfiles point to/opt/T3 Code (Beta)/t3code(stable and preview) or/opt/T3 Code (Nightly)/t3code. The nightly AppImage also containst3codeand runs through the same AppImage runtime, but I didn't run it.
Not covered:
- The Nix package (
t3code-desktop): Electron there runs from the Nix store, so it won't match. - T3's web/CLI server (
t3): it runs undernode, so it can't be told apart from an SDK run. - Matching an AppImage mount by name is no stronger than macOS's
~/Applicationscheck. The process guards are what keep automation out.
Tests: relay::claude 170 passed, relay::local 91 passed (1 ignored), cargo fmt --check is clean, and clippy reports nothing in the touched files. Clippy --all-targets stops on an existing non_octal_unix_permissions error in opencode_existing/native_tests.rs, which this PR doesn't touch. PROBE_VERSION is not bumped.
🤖 Generated with Claude Code
![View with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v3-3x.png)
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Need help on this PR? Tag @codesmith-bot with what you need.
Agent Relay sessions
claudesessioned0bac14· opened viagh pr create· last active 2026-10-31