Repository navigation
feat(macOS): show T3 thread titles in Codex notifications - #62
Conversation
mylee04
left a comment
There was a problem hiding this comment.
Requesting changes for three correctness and platform gaps. The read-only lookup and fallback direction is sound, and the existing 28-test suite plus PR CI pass, but free-form titles can suppress macOS notifications, valid non-object cursor JSON can abort a matching lookup, and the documented behavior is not implemented consistently across supported platforms.
| continue | ||
|
|
||
| if resume_cursor.get("threadId") == codex_thread_id and isinstance(title, str): | ||
| title = " ".join(title.split()) |
There was a problem hiding this comment.
[P1] Please preserve notification delivery for free-form T3 titles. A title containing " reaches SUBTITLE and is interpolated directly into the osascript -e source at line 617; for example, Investigate "missing" notifications produces AppleScript error -2740, and stderr is discarded, so users without terminal-notifier silently lose the notification. Please pass the values through AppleScript argv or otherwise escape them safely, and add a regression test covering quotes.
| except (TypeError, json.JSONDecodeError): | ||
| continue | ||
|
|
||
| if resume_cursor.get("threadId") == codex_thread_id and isinstance(title, str): |
There was a problem hiding this comment.
[P2] json.loads() may successfully return a list, string, number, or None, after which .get() raises AttributeError and aborts the entire resolver before a later valid matching row is examined. I reproduced this by replacing the unrelated fixture value not-json with []; tests/test-codex-notify.sh then fails with T3 thread title was not used. Please skip non-dictionary cursor values before calling .get() and extend the fixture to cover this case.
|
|
||
| For Codex, Code-Notify configures `notify = ["/absolute/path/to/notifier.sh", "codex"]` and reads the JSON payload Codex appends on completion. | ||
| Codex currently exposes completion events through `notify`; approval and `request_permissions` prompts do not currently arrive through this hook. | ||
| When a Codex session runs through T3 Code, Code-Notify uses the payload's `thread-id` to resolve the matching title from T3 Code's local state. If T3 Code is unavailable or no matching thread exists, it falls back to the workspace name. |
There was a problem hiding this comment.
[P2] This platform-neutral claim does not match the implementation. The native Windows PowerShell runtime still resolves Codex context only from cwd, while the Linux notify-send path does not render the SUBTITLE where this title is placed. T3 Code itself supports Windows, macOS, and Linux, so please either implement and test the equivalent behavior on those delivery paths or explicitly scope this documentation and feature to the platforms where the title is actually shown.
Closes #61.
What this does
Adds optional, read-only T3 Code context resolution for macOS Codex completion notifications.
When a Codex notify payload on macOS contains a
thread-id, Code-Notify checks whether that Codex thread is associated with a local T3 Code thread. If it is, the T3 thread title is used as the notification context instead of the workspace basename.Standalone Codex behavior is unchanged.
How it works
T3 Code stores its local state in
~/.t3/userdata/state.sqlite. The resolver:thread-idfrom the existing Codex notify payload.resume_cursor_json.threadIdmatches the payload.projection_threads.Missing files, database locks, incompatible schemas, malformed or non-object JSON, unavailable Python, and unmatched threads all fall back to the existing workspace-name resolution.
Design decisions
sqlite3module, which Code-Notify already uses for Codex state inspection.Scope
This PR scopes visible T3 thread titles to macOS desktop notifications. Linux, WSL, and native Windows delivery remain unchanged. It does not modify T3 Code or change Code-Notify's default wording, emoji, suppression rules, or fallback behavior.
Testing
tests/test-codex-notify.shwith a temporary T3 SQLite fixture.osascriptfallback, missing-T3 fallback, existing CLI fallback, and Codex Desktop duplicate suppression.make test: 28 passed, 0 failed.