From ffc29fa077cd002d3354b42c37e1ddb2648445cb Mon Sep 17 00:00:00 2001 From: Jesse Vincent Date: Thu, 18 Jun 2026 15:15:54 -0700 Subject: [PATCH] fix(writing-skills): run graphviz without a shell in render-graphs.js MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `dot` availability check shelled out to `which dot`, which is not a command on Windows, so render-graphs.js reported graphviz as missing on Windows even when it was installed. Replace it with a direct `dot -V` probe via execFileSync. Also switch the SVG render call from execSync to execFileSync('dot', ['-Tsvg']). Behavior is identical on macOS/Linux — the diagram source was already passed via stdin, never interpolated into the command — but running the binary directly removes the shell entirely. --- skills/writing-skills/render-graphs.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/skills/writing-skills/render-graphs.js b/skills/writing-skills/render-graphs.js index 1d670fbb..14988965 100755 --- a/skills/writing-skills/render-graphs.js +++ b/skills/writing-skills/render-graphs.js @@ -15,7 +15,7 @@ const fs = require('fs'); const path = require('path'); -const { execSync } = require('child_process'); +const { execFileSync } = require('child_process'); function extractDotBlocks(markdown) { const blocks = []; @@ -69,7 +69,7 @@ ${bodies.join('\n\n')} function renderToSvg(dotContent) { try { - return execSync('dot -Tsvg', { + return execFileSync('dot', ['-Tsvg'], { input: dotContent, encoding: 'utf-8', maxBuffer: 10 * 1024 * 1024 @@ -107,9 +107,10 @@ function main() { process.exit(1); } - // Check if dot is available + // Check if dot is available. Run the binary directly rather than probing + // with `which`, which is not a command on Windows. try { - execSync('which dot', { encoding: 'utf-8' }); + execFileSync('dot', ['-V'], { stdio: 'ignore' }); } catch { console.error('Error: graphviz (dot) not found. Install with:'); console.error(' brew install graphviz # macOS');