Skip to content

fix(settings): use native pet paths and refine position reset - #35

Merged
LRainner merged 2 commits into
masterfrom
codex/fix-windows-pet-directory
Jul 31, 2026
Merged

fix(settings): use native pet paths and refine position reset#35
LRainner merged 2 commits into
masterfrom
codex/fix-windows-pet-directory

Conversation

@LRainner

@LRainner LRainner commented Jul 31, 2026

Copy link
Copy Markdown
Owner

Summary

This PR improves two related settings workflows:

  • Uses platform-native pet directory paths instead of a hard-coded Unix example.
  • Makes the default pet-directory action reliable and observable on Windows.
  • Resets only the pet animation/session state after restoring the default position.
  • Removes the redundant “Restore default position” entry from the tray menu; the action remains available in Settings.

Why

The extra-directory input always displayed /Users/me/Downloads/codex-pets, even on Windows. The adjacent action also exposed ~/.codex/pets in its label and passed that shell-style path from the frontend.

Although the backend special-cased that exact string, Windows still opened the directory by spawning explorer.exe and treated a successful process spawn as a successful folder open. Any backend rejection was discarded by the frontend, so failures appeared as a button that did nothing.

Separately, restoring the pet window position is a useful recovery action when a stale Codex session leaves the pet in an incorrect animation state.

Behavior

Pet directories

  • Settings requests native directory information from the Rust backend.
  • The extra-directory placeholder uses the current user's native path, for example C:\Users\Tester\Downloads\codex-pets on Windows.
  • The action is labeled “Open pet directory”; its tooltip contains the resolved default path.
  • The frontend no longer sends a ~ path or an arbitrary directory to the backend.
  • The backend resolves and creates the default .codex/pets directory itself.
  • Windows opens the directory through ShellExecuteW with the standard open verb.
  • Failures are surfaced in the Settings message area instead of becoming an unhandled promise rejection.

Position reset

  • Restoring the default position emits a reset event only to the main pet window.
  • The pet's retained sessions, timers, and reaction queue are cleared.
  • The live-status bubble is intentionally left unchanged.
  • The tray-menu copy of the position-reset action has been removed; the Settings button remains.

Compatibility and safety

  • macOS and Linux keep their existing native file-manager implementations.
  • Native path formatting comes from Rust Path handling rather than frontend OS detection.
  • The dedicated reveal command no longer accepts a caller-controlled path.
  • The default pet directory is created when it does not exist, matching the previous behavior.

Tests

  • npm.cmd run test:e2e — 8/8 passed, including native path display, directory invocation, and visible failure feedback.
  • cargo test --manifest-path src-tauri/Cargo.toml pet_directory_info_uses_native_paths_under_the_home_directory --lib — passed.
  • cargo check --manifest-path src-tauri/Cargo.toml — passed.
  • npm.cmd run build — passed.
  • cargo fmt --manifest-path src-tauri/Cargo.toml -- --check — passed.
  • git diff --check — passed.

Summary by CodeRabbit

  • New Features

    • Settings now displays native default and example pet-directory paths.
    • Added a button to open the default pet directory.
    • Pet reactions now reset correctly after resetting the pet’s position.
  • Bug Fixes

    • Directory-opening failures now show a clear error message.
    • Improved Windows file-manager launching and failure reporting.
  • Changes

    • Removed the tray menu option for resetting the pet’s position.

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e679c447-59f8-4770-9175-665806dc1c9b

📥 Commits

Reviewing files that changed from the base of the PR and between ce14fa8 and fbcdcdb.

📒 Files selected for processing (1)
  • src-tauri/src/lib.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • src-tauri/src/lib.rs

📝 Walkthrough

Walkthrough

The PR adds native pet-directory metadata and a dedicated reveal command, updates Windows directory launching with ShellExecuteW, and adds settings tests for success and failure paths. It also emits a pet-state reset event from position reset and removes the tray reset-position action.

Changes

Native pet directory access

Layer / File(s) Summary
Native directory commands and Windows launching
src-tauri/Cargo.toml, src-tauri/src/lib.rs, src-tauri/src/platform/windows.rs
Rust now returns platform-native pet-directory paths and reveals the default directory through ShellExecuteW. PetDirectoryInfo struct contains default and example paths. The reveal_path command is removed and replaced with reveal_pet_directory. Tests verify native path construction from a supplied home directory.
Settings metadata and error handling
src/settings.ts, src/settings.html, e2e/settings.e2e.ts
Settings loads returned paths during initialization and renders them as the extra-directory placeholder and default-directory button title. The button invokes reveal_pet_directory and displays a localized error on failure. E2E tests mock failed commands and verify successful rendering, invocation, and error display.

Reaction reset lifecycle

Layer / File(s) Summary
Position reset event and tray cleanup
src-tauri/src/lib.rs, src/main.ts
The reset_main_position function emits agent-cat-pet-state-reset after persisting coordinates. The tray reset-position menu item, layout entry, and click handler are removed. The main process adds a listener for agent-cat-pet-state-reset that calls reactions.reset().

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Settings as settings.ts
  participant Tauri as reveal_pet_directory
  participant Shell as ShellExecuteW
  Settings->>Tauri: invoke reveal_pet_directory
  Tauri->>Shell: ShellExecuteW(open, default directory)
  Shell-->>Tauri: return status code
  alt status <= 32
    Tauri-->>Settings: error with code
  else status > 32
    Tauri-->>Settings: success
  end
Loading

Possibly related PRs

  • LRainner/AgentCat#5: Introduced the Windows file-manager reveal implementation that this PR refactors to use ShellExecuteW.
  • LRainner/AgentCat#9: Extended the settings E2E mock and src-tauri/src/lib.rs command handling that this PR builds upon by replacing reveal_path.
  • LRainner/AgentCat#23: Added the reaction controller reset functionality that the new agent-cat-pet-state-reset event now triggers.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly describes the main changes: using native pet paths in settings and refining position reset behavior, which matches the core objectives.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 `@src-tauri/src/lib.rs`:
- Around line 479-480: Update reveal_pet_directory to call fs::create_dir_all
unconditionally for the path returned by default_pet_directory, rather than
gating creation on exists(). Propagate any error so an existing regular file at
the pet path cannot be passed to the platform helper.

In `@src/main.ts`:
- Line 209: Update the agent-cat-pet-state-reset listener registration in
main.ts to await its completion before reporting readiness, gate
reactions.reset() until registration succeeds, and disable the reset action when
registration fails. Ensure registration rejection is handled through the
existing error path rather than only logged.
🪄 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 Plus

Run ID: b1fef3e4-3f90-4186-ae0e-36d9ab6342c5

📥 Commits

Reviewing files that changed from the base of the PR and between 5265901 and ce14fa8.

📒 Files selected for processing (7)
  • e2e/settings.e2e.ts
  • src-tauri/Cargo.toml
  • src-tauri/src/lib.rs
  • src-tauri/src/platform/windows.rs
  • src/main.ts
  • src/settings.html
  • src/settings.ts

Comment thread src-tauri/src/lib.rs
Comment thread src/main.ts
void listen<AgentEvent>("codex-event", ({ payload }) => {
if (config?.codex.hooksEnabled) reactions.setAgentEvent(payload);
});
void listen("agent-cat-pet-state-reset", () => reactions.reset());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- candidate file map ---'
ast-grep outline src/main.ts --match 'void listen($_, $_)' --view expanded 2>/dev/null || true
printf '%s\n' '--- relevant source ---'
sed -n '160,235p' src/main.ts
printf '%s\n' '--- listener API and call sites ---'
rg -n -C 3 'agent-cat-pet-state-reset|listen\(|position reset|reset\(\)' src package.json package-lock.json pnpm-lock.yaml yarn.lock 2>/dev/null || true
printf '%s\n' '--- dependency versions ---'
rg -n '"`@tauri-apps/api`"|`@tauri-apps/api`' package.json package-lock.json pnpm-lock.yaml yarn.lock 2>/dev/null || true

Repository: LRainner/AgentCat

Length of output: 7366


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- reset event references ---'
rg -n -C 5 'agent-cat-pet-state-reset|save_main_position|reset' --glob '!package-lock.json' .
printf '%s\n' '--- main initialization ---'
sed -n '1,165p' src/main.ts
printf '%s\n' '--- package metadata ---'
sed -n '1,45p' package.json
printf '%s\n' '--- lockfile API package metadata ---'
sed -n '830,855p' package-lock.json
printf '%s\n' '--- listener registration patterns ---'
rg -n -C 2 'void listen|await listen|\.catch\(.*listen|onMoved' src

Repository: LRainner/AgentCat

Length of output: 20720


🌐 Web query:

@tauri-apps/api 2.11.1 event.listen Promise rejection registration failure implementation

💡 Result:

In Tauri v2 (including version 2.11.1), an "event.listen not allowed" or "registration failure" error when calling event.listen is primarily a security and permission configuration issue [1][2][3][4]. Because Tauri v2 implements a strict Access Control List (ACL) system, the listen function must be explicitly permitted in your application's capability configuration [1][2]. If you encounter an "event.listen not allowed" rejection, verify the following: 1. Capability Permissions: Ensure that the required permissions are defined in your src-tauri/capabilities/*.json files [1][3][4]. Specifically, you must include core:event:allow-listen (and often core:event:default) in the permissions array for the relevant window [1][2][3]. Example configuration: { "permissions": ["core:default", "core:event:allow-listen"] } 2. Window Scoping: If you are creating secondary windows (e.g., using WebviewWindow), the capability file must explicitly list that window identifier in its windows array, or use a wildcard (e.g., "*") if appropriate [2][4]. 3. Build and Generation State: If you have confirmed your permissions are correct but still see the error (or a "Plugin not found" error), it may be due to stale generated files [5][6]. Tauri generates internal ACL schemas; if these are out of sync, the application may fail to recognize the permissions [5]. Try clearing your gen directory and rebuilding the application [6]. 4. Proper Usage: Ensure you are awaiting the listen Promise correctly [7][8]. The listen function is asynchronous and returns a Promise that resolves to an unlisten function [9][8]. If you invoke unlisten() before the listen Promise has resolved, the listener registration may be cancelled immediately, leading to functional failures that can be mistaken for registration errors [7][8]. Always await the handle before storing or calling it [7][8].

Citations:


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- Tauri capabilities ---'
fd -t f -i 'capabilit' src-tauri | sort
for file in $(fd -t f -i 'capabilit' src-tauri | sort); do
  printf '\n--- %s ---\n' "$file"
  cat -n "$file"
done
printf '%s\n' '--- window and event setup ---'
rg -n -C 6 'create_tao|WebviewWindow|window|capabilities|emit_to|agent-cat-config|reset_main_position' src-tauri --glob '*.rs' --glob '*.json' --glob '*.toml'
printf '%s\n' '--- frontend entry points ---'
rg -n -C 3 'main.ts|settings.ts|status.ts|reset-position|invoke<AppConfig>\("reset_main_position"\)' index.html src-tauri src --glob '*.html' --glob '*.json' --glob '*.rs' --glob '*.ts'

Repository: LRainner/AgentCat

Length of output: 50374


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- capability files excluding generated schemas ---'
find src-tauri -path '*/gen' -prune -o -type f \( -iname '*capabilit*' -o -iname 'tauri*.json' \) -print | sort
while IFS= read -r file; do
  case "$file" in
    src-tauri/gen/*) continue ;;
  esac
  printf '\n--- %s ---\n' "$file"
  cat -n "$file"
done < <(find src-tauri -path '*/gen' -prune -o -type f \( -iname '*capabilit*' -o -iname 'tauri*.json' \) -print | sort)
printf '%s\n' '--- relevant Rust and frontend entry references ---'
rg -n -C 4 'emit_to|reset_main_position|WebviewWindow|settings|status|agent-cat-pet-state-reset' src-tauri/src src-tauri/tauri*.json src/*.html --glob '!src-tauri/gen/**'

Repository: LRainner/AgentCat

Length of output: 316


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- Tauri configuration ---'
cat -n src-tauri/tauri.conf.json
printf '%s\n' '--- relevant Rust symbols ---'
rg -n -C 8 'emit_to|reset_main_position|WebviewWindow|settings|status|agent-cat-pet-state-reset' src-tauri/src src-tauri/tauri.conf.json src-tauri/tauri.ci.conf.json --glob '!src-tauri/gen/**'
printf '%s\n' '--- HTML entry points ---'
rg -n -C 4 'main.ts|settings.ts|status.ts' src --glob '*.html'

Repository: LRainner/AgentCat

Length of output: 45187


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- settings startup and reset action ---'
sed -n '1,90p' src/settings.ts
sed -n '520,625p' src/settings.ts
printf '%s\n' '--- main setup tail ---'
sed -n '700,775p' src-tauri/src/lib.rs
printf '%s\n' '--- relevant generated capability permissions ---'
rg -n -C 3 '"core:event:(allow-listen|default)"|event.*listen|allow-listen' src-tauri/gen --glob '*.json' --glob '*.toml' | head -120

Repository: LRainner/AgentCat

Length of output: 50373


Await and handle the reset listener registration.

If registration fails or the event arrives before registration completes, the settings window can report success while reactions.reset() does not run. Gate the reset action on listener readiness and disable it when registration fails. Logging a rejection alone does not prevent this state.

🤖 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 `@src/main.ts` at line 209, Update the agent-cat-pet-state-reset listener
registration in main.ts to await its completion before reporting readiness, gate
reactions.reset() until registration succeeds, and disable the reset action when
registration fails. Ensure registration rejection is handled through the
existing error path rather than only logged.

@LRainner
LRainner merged commit cf429bd into master Jul 31, 2026
8 checks passed
@LRainner
LRainner deleted the codex/fix-windows-pet-directory branch July 31, 2026 13:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant