원클릭으로
publish
Validate the Jekyll site with Playwright and publish if it passes. Use when the user wants to build, preview, and push site changes.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Validate the Jekyll site with Playwright and publish if it passes. Use when the user wants to build, preview, and push site changes.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
| name | publish |
| description | Validate the Jekyll site with Playwright and publish if it passes. Use when the user wants to build, preview, and push site changes. |
| allowed-tools | Bash, Read, Write |
Validate the Jekyll site with Playwright and publish if it passes.
Run a clean Jekyll build and fail fast on errors:
bundle exec jekyll build 2>&1
If the build exits non-zero or prints Error: / Liquid Exception, stop and report the error. Do not proceed.
Grep the built _site for known formatting regressions before the browser pass. These
are deterministic and cheap; any hit stops the publish.
# TOC id-leak: post.html builds the Table of Contents from heading HTML. If the title
# extraction regresses, entries render as `some-id">Title` instead of `Title`. The tell
# is a second `">` inside a TOC <li> link. Must be zero.
leak=$(grep -rho '<li><a href="#[^<]*</a></li>' _site/ctf/ | grep -cE '">[^<]*">')
echo "TOC id-leak entries: $leak" # must be 0
# Unrendered pipe tables: a kramdown table that didn't parse leaves a literal `|---|`
# separator row in the HTML body. Must be zero.
badtbl=$(grep -rlE '\|[[:space:]]*-{3,}' _site/ctf/ | wc -l)
echo "pages with unrendered tables: $badtbl" # must be 0
# Broken local images: every /assets img referenced by a built page must exist on disk.
If leak or badtbl is non-zero, stop and fix the template/source — do not publish.
The TOC generator lives in _layouts/post.html; titles come from heading inner-HTML with
the id"> opening prefix removed via remove_first (not a "> split, which breaks on
headings that contain inline <code>/links).
Start the dev server in the background:
bundle exec jekyll serve --no-watch --skip-initial-build &
sleep 3
Run a Playwright script to check the site. Write it to a temp file and execute it:
cat > /tmp/validate-site.js << 'EOF'
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
const page = await browser.newPage();
const base = 'http://localhost:4000';
const errors = [];
const checks = [
{ url: '/', label: 'Home' },
{ url: '/articles/projects/', label: 'Projects nav' },
];
// Also check any page passed as CLI args
const extra = process.argv.slice(2);
for (const u of extra) checks.push({ url: u, label: u });
for (const { url, label } of checks) {
await page.goto(base + url, { waitUntil: 'networkidle' });
// Screenshot for visual review
const slug = label.replace(/[^a-z0-9]/gi, '-').toLowerCase();
await page.screenshot({ path: `/tmp/preview-${slug}.png`, fullPage: false });
// Check no Jekyll error page
const title = await page.title();
if (title.includes('404') || title.includes('Error')) {
errors.push(`${label}: got error page (title: "${title}")`);
}
// Check nav contains Projects
const hasProjects = await page.locator('text=Projects').count();
if (hasProjects === 0) {
errors.push(`${label}: "Projects" not found in nav`);
}
}
await browser.close();
if (errors.length > 0) {
console.error('VALIDATION FAILED:\n' + errors.join('\n'));
process.exit(1);
} else {
console.log('All checks passed.');
console.log('Screenshots saved to /tmp/preview-*.png');
}
})();
EOF
node /tmp/validate-site.js $ARGUMENTS
Read and display each screenshot at /tmp/preview-*.png so the user can visually confirm the nav and layout look correct.
kill $(lsof -t -i:4000) 2>/dev/null || true
Only proceed after the user explicitly confirms the screenshots look correct.
git add -A
git status
Show the user the staged files, then ask for confirmation before committing. Use conventional commit format:
git commit -m "$(cat <<'EOF'
feat(articles): publish <article title>
<one-sentence summary of what was added/changed>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
EOF
)"
git push