From vibestack
Set up a self-contained GitHub Actions CI workflow for the current project. Detects language(s) from the codebase (TS/JS, Python, Go, Rust) and writes `.github/workflows/ci.yml` with lint, test, and build gates. Idempotent, skips if the workflow already exists unless the user asks to reconcile.
How this skill is triggered — by the user, by Claude, or both
Slash command
/vibestack:cicdThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Generate a self-contained `.github/workflows/ci.yml` tailored to the project's language stack. The workflow runs on every PR and on pushes to `main`, with lint + test + (optional) build gates.
Generate a self-contained .github/workflows/ci.yml tailored to the project's language stack. The workflow runs on every PR and on pushes to main, with lint + test + (optional) build gates.
Self-contained. No external reusable workflows, no shared repos. Each project owns its CI file outright.
Idempotent. If .github/workflows/ci.yml already exists, do not overwrite. Tell the user it exists, show its language coverage, and ask whether to reconcile (add missing language jobs) or leave it.
Read the repo root and identify which of the supported languages are in play. Look for these markers (a project can be polyglot, generate jobs for every language found):
| Language | Marker files |
|---|---|
| Node / TypeScript | package.json (check engines.node, scripts, lockfile for npm/pnpm/yarn/bun) |
| Python | pyproject.toml, requirements.txt, setup.py, Pipfile |
| Go | go.mod |
| Rust | Cargo.toml |
If none of these are present, tell the user the project's language stack isn't recognized and stop. Don't write a workflow that won't work.
If multiple languages are detected, generate a workflow with one job per language. The jobs run in parallel.
If .github/workflows/ci.yml exists:
setup-node, setup-python, setup-go, dtolnay/rust-toolchain).If no workflow exists, proceed to generate one.
Assemble .github/workflows/ci.yml from the snippets below. Use a single name: CI header and one job per detected language. Each job runs on ubuntu-latest.
Common header:
name: CI
on:
pull_request:
push:
branches: [main]
jobs:
Node / TypeScript job. Detect the package manager from the lockfile (pnpm-lock.yaml → pnpm; yarn.lock → yarn; bun.lockb → bun; otherwise → npm). Adjust the install + run lines accordingly. Use --if-present for scripts so the job doesn't fail when a script isn't defined.
node:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm' # change to pnpm/yarn if detected
- run: npm ci
- run: npm run lint --if-present
- run: npm run typecheck --if-present
- run: npm test --if-present
- run: npm run build --if-present
Python job. Default to pip + pyproject.toml. If poetry.lock is present use poetry; if uv.lock is present use uv. Run ruff if ruff appears in pyproject deps or ruff.toml/.ruff.toml exists. Run pytest unconditionally, the project will fail-fast if no tests exist, which is fine.
python:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: 'pip'
- run: pip install -e ".[dev]" || pip install -r requirements.txt
- run: ruff check .
if: ${{ hashFiles('ruff.toml', '.ruff.toml') != '' || contains(fromJSON('[true]'), false) }}
- run: pytest
(If the ruff conditional is too clever, just emit a plain ruff check . || true, getting a real ruff signal matters more than perfect conditional gating.)
Go job. Read go.mod for the module's Go version directive and use it.
go:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: 'go.mod'
- run: go vet ./...
- run: go test ./...
- run: go build ./...
Rust job.
rust:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy, rustfmt
- uses: Swatinem/rust-cache@v2
- run: cargo fmt --check
- run: cargo clippy -- -D warnings
- run: cargo test
- run: cargo build
Create .github/workflows/ if it doesn't exist, then write the assembled YAML to .github/workflows/ci.yml. Don't add a trailing newline beyond the standard single one.
Report:
npm ci resolved to.If the project uses an unusual setup (custom test commands, non-standard layout, monorepo with multiple packages), flag it, the generated workflow assumes the project root holds the package config. Suggest manual edits if that doesn't hold.
ci.yml.Keep the generated workflow lean. Projects grow into more later; they shouldn't start there.
npx claudepluginhub vibestackmd/vibestack --plugin vibestackProvides behavioral guidelines to reduce common LLM coding mistakes, focusing on simplicity, surgical changes, assumption surfacing, and verifiable success criteria.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.