mirror of
https://github.com/l0ng-ai/tty7.git
synced 2026-09-22 08:02:24 +00:00
Every agent takes the hook as a command *line*, so a shell parses it again before anything runs. The path went in double-quoted, and inside double quotes `sh` still expands `$`, a backtick and a backslash — so an install under `/opt/build$stage` reached the shell as `/opt/build/tty7`. The hook then never fired: no error, no log line, just an agent that quietly stopped reporting its status for good. Checked against a real `sh` first, because the failure is invisible from the code: the double-quoted form resolves the program to `.../q/tool`, the single-quoted one to `.../q$stage/tool`. Then checked again through the generated OpenCode plugin under node with a stubbed `$`, which is the path that actually ships — the assembled command re-parses to the full path, dollar segment intact. Which shell is the target's, not ours: a hook installed on a remote machine runs there. Only a local Windows target keeps the double-quoted form, which is what `cmd.exe` wants and what the PATH-resolvable case avoids needing. `shell_quote` had been written out twice already, in `daemon::install` and `daemon::shell_integration`. Rather than add a third copy this moves the one implementation to `core::shells`, where a core module may reach it without depending on the daemon, and both old homes now re-export it.