Skip to content
cccskills
FreePublished on GitHub

git

Git operation rules for this repository — branch guard, commit granularity, package commit order, Conventional Commits message format, and pre-commit checks. Use whenever creating commits or asked to "commit". Trigger keywords: commit, git commit, stage, staging, commit message, conventional commits.

The English summary is being prepared. Showing the original description.

markuplint/markuplint630 stars(GitHub 630 + cccskills 0)

Run score Not tested

See how to install

Files included (1)

  • SKILL.md10.6 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

Branch guard (run first)

Check the current branch before any commit:

git branch --show-current

On dev, v6, v4, main, or a prerelease branch (v5-rc and the like), stop. dev and v6 are rejected by husky; main and the prerelease branches are unguarded only so lerna version can write release commits. The one exception is the release skill's recovery commit in its "Version bump" step (finishing Lerna's last two steps by hand on the release branch). Branch work happens in a Claude Code–managed worktree (Branch Topology and Branch & Worktree Policy in the root CLAUDE.md).

On a topic branch, proceed. The verification gates below differ between the two lines, so tell them apart from the working tree (a crates/ directory means the v6 line), not the branch name.

Commit creation

Start every commit from a fresh git status — the staging area may have changed since you last looked.

  • If files are already staged, the user prepared that set. Do not git add, git restore, or otherwise touch the staging area; read git diff --staged and write the message from those files alone, then run git commit (the user approves the command).
  • If nothing is staged, stage by the granularity below — one commit per package, dependencies first (npx lerna list --graph when the order is unclear).

If the OS, application settings, or context suggest a language other than English is being used, give a translation and explanation of the commit message in that language immediately before running the commit command.

Pre-commit content check

Before git commit, scan git diff --staged for:

  1. Secrets and project-external identifiers — API keys, tokens, passwords, unrelated company or client names
  2. Sample-value conventions — sample domains/IPs/emails must use reserved values (RFC 2606/6761 domains like example.com / *.example / *.test, TEST-NET IPs, user@example.com). Real unrelated domains and plausible made-up domains are not acceptable; rewrite to reserved values rather than unstaging.

Package commit order (dependency-first)

When committing changes that span multiple packages, always commit from leaves to root (dependencies before dependents). Use npx lerna list --graph for the full dependency tree.

TierPackages
0shared, ml-ast, i18n, cli-utils, config-presets, test-tools
1types
2ml-spec
3html-spec, react-spec, vue-spec, svelte-spec, htmx-spec, alpine-spec
4parser-utils, selector
5ml-config
6html-parser
7Framework parsers (jsx, vue, svelte, pug, astro, alpine, ejs, erb, htmx, liquid, markdown, mdx, mustache, nunjucks, php, smarty, tagged-template-literal) — mdx-parser depends on markdown-parser, so commit markdown first
8ml-core
9rules, file-resolver
10pretenders, create-rule
11markuplint
12language-server
  • Within the same tier, order does not matter
  • Root config changes (.oxlintrc.json, .oxfmtrc.json, tsconfig.base.json, CI) should be committed before any package changes
  • Single-package changes do not need ordering -- just commit that package
  • The package set differs between the two lines (the v6 line drops htmx-parser and rule-textlint, and adds core — the napi addon that markuplint depends on, so commit it before Tier 11). The table above describes the dev line; on any branch, npx lerna list --graph is the source of truth
  • If unsure, verify with npx lerna list --graph
  • crates/* changes are outside the Lerna graph. Commit them before the packages that consume them (core, then markuplint)

Commit message format

  • You must write in English
  • You must use the imperative mood
  • You must use conventional commits
    • You must use the types defined by @commitlint/config-conventional:
      • build
      • chore
      • ci
      • docs
      • feat
      • fix
      • perf
      • refactor
      • revert
      • style
      • test
    • Scopes are dynamically generated from Lerna packages (see .commitlintrc.js)
      • Package names have -markuplint / markuplint- prefixes stripped
      • Additional scopes:
        • crates — the Rust workspace on the v6 line. Its crates are not Lerna packages, and the per-crate names would collide with the JS packages (core, rules, types, …), so they share this one scope
        • release
        • deps
        • changelog
        • github
        • lint
        • website
      • Scope is optional — omit it when changes span multiple packages or don't belong to one
  • The message body's lines must not be longer than 100 characters
  • The subject must not be sentence-case, start-case, pascal-case, upper-case
  • A breaking-change marker — a ! after the type, or a BREAKING CHANGE: / BREAKING-CHANGE: footer — is written only on the next-major line (v6: a checkout with crates/Cargo.toml). On the stable line (dev) yarn release runs lerna version --conventional-commits on a fixed-version workspace, so one such commit since the last tag makes the next release a major, the number the next-major line owns; the no-breaking-change-on-stable-line rule in .commitlintrc.js rejects it at commit time, and the breaking-change question of yarn commit (commitizen) is answered "no" there
    • A change to what an @experimental API, option or output does may ship from the stable line (the compatibility policy in the product-manager skill). Say so in the last paragraph of the body, which starts with Behavior change (experimental): and names the affected data and the before → after in one or two sentences. The release skill collects these paragraphs with git log --grep for the release notes, and conventional-changelog does not read the phrase as breaking
    • A breaking change of a stable API is made on the next-major line, with the marker. When the user has approved the exception of shipping one from the stable line (the same policy), the paragraph starts with Behavior change (stable, approved): instead — still without the marker — and the migration guide is in the PR body and on the website

Commit message safety guidelines

  • For simple, single-line commits, use single quotes (git commit -m 'type(scope): subject line')
  • Do not use multiple -m flags for a multi-line message (causes commitlint parse errors)

Heredoc Format (every multi-line message)

Use heredoc with command substitution to pass any multi-line commit message. This ensures:

  • Special characters (like exclamation marks) are preserved correctly
  • Multi-line messages are properly formatted
  • commitlint can parse the message correctly

Format — a behavior change of an experimental API on the stable line:

git commit -m "$(cat <<'EOF'
fix(scope): subject line

What changed and why, as in any commit.

Behavior change (experimental): the `filePath` of a wrapper component in the pretenders
JSON is now the component's own location, not the last hop's. Regenerate committed JSON.
EOF
)"

Format — a breaking change on the next-major line:

git commit -m "$(cat <<'EOF'
type(scope)!: subject line

BREAKING CHANGE: Rename all compiler-related types and functions

Type renames:
- OldName -> NewName
- Another -> Change
EOF
)"

Important notes:

  • Use <<'EOF' (with quotes) to prevent variable expansion
  • Close with ) after EOF to complete command substitution
  • The entire message must be wrapped in "$(cat <<'EOF' ... EOF)"

Pre-commit verification for spec changes

When committing changes to spec packages (Tier 2–3), run the full test suite:

yarn test
yarn lint-check

yarn lint auto-fixes files, and the fixes would land unstaged; use the non-mutating yarn lint-check here.

Spec data propagates to @markuplint/rules and @markuplint/ml-spec tests. Package-level tests alone will miss cross-package regressions.

Pre-commit verification for crates/ changes (v6 line)

yarn test, yarn lint and lint-staged cover the TypeScript workspace only — nothing in them touches Rust, so a staged crates/ change can look clean and still break CI (.github/workflows/rust.yml). When the diff includes crates/, run all three from crates/ before committing:

cargo fmt --check
cargo clippy --locked -- -D warnings
cargo test --locked

cargo clippy runs with -D warnings in CI, so a warning is a failure. See crates/CLAUDE.md for the rest of the v6 workspace's constraints.

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

Maintenance of the nu-validator coverage benchmark: defend the invariants (nu-only = 0, xref audit green), follow up a nu-validator upstream update (submodule bump / Docker image drift), and regression-check after markuplint rule or spec changes. Use when updating the validator submodule, when a bench refresh surfaces new nu-only entries, when excluded-ids entries go stale, or for the periodic health check. Trigger keywords: bench maintain, bench maintenance, nu update, submodule bump, validator update, bench refresh, nu-only regression, stale excluded-ids, image digest.

The English summary is being prepared. Showing the original description.

markuplint/markuplint630Updated Oct 26, 2026

Enable an existing or newly-added markuplint rule on the nu-validator bench by editing tests/external/bench/config.ts. Covers the flat-rule case (rules: { '<name>': true }) and the severity override case (rules: { '<name>': { severity: 'error' } }) that bench-virtual-rule does not. Use when a rule exists in the registry but the relevant nu fixtures stay nu-only because the rule is not enabled in the bench config, or when a rule's default severity is warning but the spec text it mirrors is a MUST / MUST NOT. Trigger keywords: enable bench rule, bench config flat rule, severity override bench, rule not flagging on bench, warning vs error in bench, escalate severity bench, no-contradictory-aria-prop bench, bench coverage missing rule.

The English summary is being prepared. Showing the original description.

markuplint/markuplint630Updated Oct 26, 2026

Set up the nu-validator benchmark environment — initialise the validator submodule, ensure Docker is running, populate the gitignored raw snapshots via yarn bench:update. Also covers Docker / nu-runner troubleshooting. Use when bench commands fail with "no snapshots found", "Docker daemon not reachable", port 28888 conflicts, or healthcheck timeouts; or when refreshing the bench after a long break. Trigger keywords: bench setup, bench Docker, validator submodule, no snapshots found, Docker daemon not reachable, healthcheck times out, port 28888, yarn bench:update first time, bench install, fresh clone bench.

The English summary is being prepared. Showing the original description.

markuplint/markuplint630Updated Oct 26, 2026

Triage one nu-only fixture from tests/external/snapshots/diff/nu-only.json by reading the spec, then drive its verdict to match-error, match-clean, or nu-over by either fixing markuplint or recording an excluded-ids.json entry. The core per-fixture operation of the nu-validator coverage benchmark. Use when a bench refresh surfaces new nu-only entries, when checking a coverage-claim ("markuplint misses X" / "over-detects Y") against the bench, or when classifying a specific fixture. Trigger keywords: nu-only, ml-only, coverage gap, bench triage, verdict, match-error, match-clean, nu-over, excluded-ids, declare nu over-detection, claim audit, audit fixture, mark-up valid per spec, spec-cited exclusion.

The English summary is being prepared. Showing the original description.

markuplint/markuplint630Updated Oct 26, 2026

Mirror a preset virtual rule (selectors under `nodeRules` in preset.html-standard.jsonc and similar) into bench/config.ts so the benchmark exercises it. Use when a new disallowed-element / similar selector lands in a preset and the matching nu fixtures remain stuck at nu-only despite the new rule existing in markuplint. Trigger keywords: virtual rule, nodeRules, disallowed-element, preset html-standard, bench config mirror, rule does not fire on bench, preset rule not exercised.

The English summary is being prepared. Showing the original description.

markuplint/markuplint630Updated Oct 26, 2026

Sync benchmark cross-reference blocks onto GitHub Issue bodies via `yarn bench:xref`, manage `tests/external/bench/issue-xref.config.ts` mappings, and run the pre-release checklist. Use when adding / removing / updating a primary or secondary mapping, when an issue closes upstream, when the xref CLI's output disagrees with what's on the issue body, or before cutting a release that touches a rule the benchmark covers. Trigger keywords: bench-xref, issue-xref, xref CLI, GitHub issue body, primary mapping, secondary mapping, umbrella block, pre-release checklist, bench-xref-audit workflow, marker version.

The English summary is being prepared. Showing the original description.

markuplint/markuplint630Updated Oct 26, 2026

See all skills by markuplint

Report a problem with this skill