<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Ruff on Start AI Tools - Presented by Intent Solutions</title><link>https://startaitools.com/tags/ruff/</link><description>Recent content in Ruff on Start AI Tools - Presented by Intent Solutions</description><generator>Hugo</generator><language>en-US</language><copyright>Intent Solutions. All rights reserved.</copyright><lastBuildDate>Wed, 27 May 2026 20:52:37 -0600</lastBuildDate><atom:link href="https://startaitools.com/tags/ruff/index.xml" rel="self" type="application/rss+xml"/><item><title>CI gap: shellcheck + ruff caught 4 findings</title><link>https://startaitools.com/posts/plugin-scripts-lint-gap-shellcheck-ruff/</link><pubDate>Tue, 26 May 2026 08:00:00 -0500</pubDate><guid>https://startaitools.com/posts/plugin-scripts-lint-gap-shellcheck-ruff/</guid><description>&lt;p&gt;The CI matrix ran lint-staged and the main workflow against TS/JS/JSON/MD/YAML. Good coverage there. But &lt;code&gt;plugin/skills/**/*.{sh,py}&lt;/code&gt; — the shell and Python scripts inside plugin archetypes and skill scaffolding — got behavior tests (&lt;code&gt;test_run_sh.sh&lt;/code&gt;, &lt;code&gt;test_verify.py&lt;/code&gt;, &lt;code&gt;test_bank.py&lt;/code&gt;) but nothing ran shellcheck or ruff on them. A quoting bug, an unused import, or a quote-injection footgun could land without signal.&lt;/p&gt;
&lt;p&gt;I didn&amp;rsquo;t see the gap until bead &lt;code&gt;nwh&lt;/code&gt; forced the look.&lt;/p&gt;
&lt;p&gt;Added &lt;code&gt;plugin-scripts-lint&lt;/code&gt; job to &lt;code&gt;.github/workflows/ci.yml&lt;/code&gt;. Two steps: shellcheck on &lt;code&gt;plugin/skills/**/*.sh&lt;/code&gt;, ruff on &lt;code&gt;plugin/skills/**/*.py&lt;/code&gt;. Each step does &lt;code&gt;shopt -s globstar nullglob&lt;/code&gt;, expands the glob into a bash array, and &lt;code&gt;exit 0&lt;/code&gt;s with a &amp;ldquo;no files&amp;rdquo; message when the array is empty — explicit guard, not &amp;ldquo;trust the glob&amp;rdquo;:&lt;/p&gt;</description></item></channel></rss>