Skip to content

Latest commit

 

History

History
97 lines (76 loc) · 5.58 KB

File metadata and controls

97 lines (76 loc) · 5.58 KB

Platform support

Platform Telemetry and analysis Watch window
macOS Supported iTerm2, tmux, or Terminal.app
Linux Supported tmux, gnome-terminal, konsole, or xterm
Windows Python runtime and CI supported Windows Terminal or start

CI runs tests on all three platforms and Python 3.10–3.14. Native Windows hook launch is not exercised end to end in CI. Claude’s documented shell-free exec form is used, and the hook path requires python3 on PATH; its hook condition filters tool calls, not operating systems.

Session identity

Claude Code exports the live session id as CLAUDE_CODE_SESSION_ID. CLAUDE_SESSION_ID is only a ${...} placeholder that Claude Code substitutes into hook command strings, so it never reaches the process environment. trigger-tree reads CLAUDE_CODE_SESSION_ID first and falls back to CLAUDE_SESSION_ID and TT_SESSION_ID for clients or hook wiring that do set those. Hook events themselves take the id from the payload on stdin, so capture never depended on the variable; tt doctor's current-session liveness check did (issue #21).

Codex exports no session id at all, so its lifecycle hooks take the id from the payload and tt doctor cannot identify a live Codex session. The current-session check therefore runs on Claude Code only; under Codex the liveness line falls back to recency. To keep that from reading as a clean bill of health, every liveness line names the clients that have actually recorded, so telemetry from one client cannot pass as another client's hooks working.

Doctor on Codex-only and legacy-console installs

The Codex upload archive ships hooks/hooks.json without hooks/claude-hooks.json. tt doctor checks the Codex routes everywhere and the Claude Code routes only when that manifest or .claude-plugin/plugin.json is installed. A failure names the file and client that lack routes. On a console that cannot encode its glyphs, such as CP1250 on a Czech Windows install, doctor prints ASCII substitutes instead of crashing (issue #46). Whether a glyph renders is a separate matter of terminal font coverage.

Surviving a stale install

Codex persists a hook's resolved command, so an upgrade can leave it pointing at a version directory that no longer exists. The interpreter then exits before any trigger-tree code runs, and Codex treats a non-zero UserPromptSubmit hook as a blocking error, which stops the session. The Codex hook commands therefore check the script exists and exit 0 when it does not, so a stale path degrades to no telemetry rather than a broken session.

Claude Code's manifest uses the documented shell-free exec form, chosen so Windows needs no shell, and that form cannot express the same guard. Claude re-resolves its plugin root per invocation, so the stale-path case has not been observed there; if it is, the fix is a manifest change rather than a code change.

Invoking the skill

Claude Code uses /tt <command>. Codex uses @trigger-tree <command>, and plain-language requests reach the same workflows. A Codex marketplace install resolves its manifest's ./skills/ to the repository's Claude skill, which asserts --client claude; the scripts therefore treat the install location as authoritative and report codex regardless of the flag, so a wrongly loaded skill cannot mislabel a session.

Agent persona capture

Persona definitions are read from .claude/agents/*.md only, and only when the file carries YAML frontmatter: a project-level agents/ directory is documentation in this tool's inventory, so scanning it counted READMEs and templates as personas.

Claude Code launches subagents through an Agent tool call whose input carries subagent_type; that name is the only field recorded. Verified against real transcripts rather than assumed, after issue #21. The Codex adapter routes Agent and Task the same way, but whether Codex surfaces a subagent launch as a hook-visible tool call is unverified, so treat Codex persona counts as unsupported until observed. tt doctor reports persona definitions found while capture is off, so silence is never mistaken for an unused persona.

Instruction-adherence capture

Claude Code PostToolUse hooks capture supported Edit, Write, and MultiEdit calls. Codex lifecycle hooks normalize its edit surface (apply_patch, Edit, or Write) into the same path-only event. Tool availability can change by client or host: hosted tools, unsupported MCP edit shapes, and other operations that bypass local lifecycle hooks are invisible.

Codex also requires explicit hook trust in the interactive TUI. Until all trigger-tree hooks are trusted, capture may be empty; non-interactive codex exec does not persist that trust, and a changed hook requires review again. tt doctor reports these gaps. Unavailable capture produces capture-disabled and is excluded from rates rather than becoming unobserved.

Audit fixes in 1.30.3

Codex-only archives resolve version metadata from the Codex manifest. Git roots are decoded as UTF-8, and tips/report diagnostics escape characters a legacy console cannot encode. Codex command outcomes use an observed exit code where available; uninterpretable responses remain unknown. MCP path fields alone no longer imply a read: only the supported filesystem read/search operations are classified.

Telemetry writers reject existing symlinks and Windows reparse points, including directory junctions. These checks do not guarantee containment against concurrent directory replacement. The Windows-specific junction regression runs only on Windows; passing the macOS suite does not establish native Windows hook delivery.