<feed xmlns='http://www.w3.org/2005/Atom'>
<title>rulesets/claude-templates/bin/cmail-action, branch main</title>
<subtitle>Claude Code skills, rules, and language bundles
</subtitle>
<id>https://git.cjennings.net/rulesets/atom?h=main</id>
<link rel='self' href='https://git.cjennings.net/rulesets/atom?h=main'/>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/'/>
<updated>2026-08-20T13:13:35+00:00</updated>
<entry>
<title>fix(cmail): install cmail-action on PATH instead of per-project copies</title>
<updated>2026-08-20T13:13:35+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-08-20T13:13:35+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/rulesets/commit/?id=23d1d998995a776b5c184c6719602b1aba2c1d41'/>
<id>urn:sha1:23d1d998995a776b5c184c6719602b1aba2c1d41</id>
<content type='text'>
protocols.org said cmail-action was symlinked into ~/.local/bin and on PATH from any project. It wasn't on any machine. The only copies were the per-project .ai/scripts/cmail-action.py the template sync delivers, so the documented invocation died with command not found.

The claim wasn't aspirational. A provisioning script used to create that symlink from ~/projects/claude-templates/, and that path went away when claude-templates became a subtree here. The doc outlived its mechanism.

The script has no project coupling (every path in it is under $HOME against a hardcoded bridge address). I moved it to claude-templates/bin/, which make install already links. The documented command is now true, and 17 copies collapse to one.

Its test moved to scripts/tests/ and needed an explicit SourceFileLoader, because dropping the .py suffix stops importlib inferring one from the extension. The test target gained a pytest pass over scripts/tests. Without it the move would have dropped 57 tests while still reporting green.

triage-intake's cmail gate now tests command -v cmail-action rather than a file path, so it checks what it runs. protocols.org names the repair when the command is missing, and names Proton Bridge as a precondition.
</content>
</entry>
</feed>
